Skip to content

Commit

Permalink
Merge pull request #778 from ProjectStarlight/flail-variants
Browse files Browse the repository at this point in the history
Frost flail
  • Loading branch information
ScalarVector1 authored Jan 13, 2025
2 parents c3612c6 + 2243f64 commit 3c77966
Show file tree
Hide file tree
Showing 9 changed files with 213 additions and 4,030 deletions.
Binary file added Assets/Items/Snow/FrostFlail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/Items/Snow/FrostFlailChain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/Items/Snow/FrostFlailProjectile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/Items/Snow/FrostFlailShard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Assets/Misc/AlphaCrack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 38 additions & 13 deletions Content/Items/BaseTypes/AbstractHeavyFlail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,23 @@ public override bool CanShoot(Player player)
internal abstract class AbstractHeavyFlailProjectile : ModProjectile
{
public abstract Asset<Texture2D> ChainAsset { get; }
protected static Asset<Texture2D> BallAsset;
protected Asset<Texture2D> BallAsset;

readonly List<Vector2> chainPos = [];
readonly List<Vector2> chainTarget = [];

protected bool slowing;

/// <summary>
/// The maximum length this flail can extend out to if it has room
/// The maximum length this flail can extend out to if it has room.
/// </summary>
public virtual int MaxLength { get; set; } = 200;

/// <summary>
/// The amount of times alternate chain styles should be repeated at the end of the chain.
/// </summary>
public virtual int AlternateStyleRepeats => 3;

public ref float Timer => ref Projectile.ai[0];
public ref float State => ref Projectile.ai[1];
public ref float Length => ref Projectile.ai[2];
Expand All @@ -55,11 +60,6 @@ internal abstract class AbstractHeavyFlailProjectile : ModProjectile
/// </summary>
public virtual void OnImpact(bool wasTile) { }

public override void SetStaticDefaults()
{
BallAsset = ModContent.Request<Texture2D>(Texture);
}

public override void SetDefaults()
{
Projectile.friendly = true;
Expand All @@ -68,6 +68,8 @@ public override void SetDefaults()
Projectile.tileCollide = true;
Projectile.timeLeft = 180;
Projectile.penetrate = -1;

BallAsset = ModContent.Request<Texture2D>(Texture);
}

public override void AI()
Expand Down Expand Up @@ -233,7 +235,7 @@ public override bool OnTileCollide(Vector2 oldVelocity)
{
var hitbox = new Rectangle((int)chainPos[k].X - 4, (int)chainPos[k].Y - 4, 8, 8);

if (hitbox.Intersects(projHitbox))
if (hitbox.Intersects(targetHitbox))
return true;
}
}
Expand All @@ -252,22 +254,45 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)

public override bool PreDraw(ref Color lightColor)
{
int extraStyles = (ChainAsset.Height() - 44) / 22;

if (State == 0)
{
int max = (int)(Vector2.Distance(Owner.Center, Projectile.Center) / ChainAsset.Width());

for (int k = 0; k < max; k++)
{
var pos = Vector2.Lerp(Projectile.Center, Owner.Center, k / (float)max);
Main.EntitySpriteDraw(ChainAsset.Value, pos - Main.screenPosition, null, new Color(Lighting.GetSubLight(pos)), Owner.Center.DirectionTo(pos).ToRotation() - 1.57f, ChainAsset.Size() / 2f, 1f, 0, 0);
var pos = Vector2.Lerp(Owner.Center, Projectile.Center, k / (float)max);
Rectangle source = new Rectangle(0, 0, 8, 22);

if (k > 1)
{
source.Y += 22;

if (extraStyles > 0 && (k + 3) >= (max - extraStyles * AlternateStyleRepeats))
source.Y += 22 * (extraStyles - (max - (k + 3)) / AlternateStyleRepeats);
}

Main.EntitySpriteDraw(ChainAsset.Value, pos - Main.screenPosition, source, new Color(Lighting.GetSubLight(pos)), Owner.Center.DirectionTo(pos).ToRotation() - 1.57f, new Vector2(4, 11), 1f, 0, 0);
}
}

for (int k = 0; k < chainPos.Count; k++)
for (int k = 1; k < chainPos.Count; k++)
{
Vector2 prev = k > 0 ? chainPos[k - 1] : Owner.Center;
Vector2 prev = chainPos[k - 1];
Vector2 curr = chainPos[k];
Main.EntitySpriteDraw(ChainAsset.Value, curr - Main.screenPosition, null, new Color(Lighting.GetSubLight(curr)), curr.DirectionTo(prev).ToRotation() - 1.57f, ChainAsset.Size() / 2f, 1f, 0, 0);

Rectangle source = new Rectangle(0, 0, 8, 22);

if (k > 1)
{
source.Y += 22;

if (extraStyles > 0 && (k + 3) >= (chainPos.Count - extraStyles * AlternateStyleRepeats))
source.Y += 22 * (extraStyles - (chainPos.Count - (k + 3)) / AlternateStyleRepeats);
}

Main.EntitySpriteDraw(ChainAsset.Value, curr - Main.screenPosition, source, new Color(Lighting.GetSubLight(curr)), curr.DirectionTo(prev).ToRotation() - 1.57f, new Vector2(4, 11), 1f, 0, 0);
}

Vector2 ballPos = Projectile.oldPosition + Projectile.Size / 2f;
Expand Down
19 changes: 11 additions & 8 deletions Content/Items/Forest/Weapons.HeavyFlail.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,20 @@ internal class HeavyFlailProjectile : AbstractHeavyFlailProjectile

public override void OnImpact(bool wasTile)
{
Helpers.Helper.PlayPitched("Impacts/StoneStrike", 1, 0, Projectile.Center);
if (wasTile)
{
Helpers.Helper.PlayPitched("Impacts/StoneStrike", 1, 0, Projectile.Center);

if (Owner == Main.LocalPlayer)
CameraSystem.shake += 10;
if (Owner == Main.LocalPlayer)
CameraSystem.shake += 10;

for (int k = 0; k < 32; k++)
{
Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Stone);
}
for (int k = 0; k < 32; k++)
{
Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Stone);
}

Projectile.NewProjectile(null, Projectile.Center + Vector2.UnitY * 8, Vector2.Zero, ModContent.ProjectileType<HeavyFlailCrack>(), 0, 0);
Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center + Vector2.UnitY * 8, Vector2.Zero, ModContent.ProjectileType<HeavyFlailCrack>(), 0, 0);
}
}
}

Expand Down
164 changes: 164 additions & 0 deletions Content/Items/Snow/Weapons.FrostFlail.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
using StarlightRiver.Content.Items.BaseTypes;
using StarlightRiver.Content.Items.Forest;
using StarlightRiver.Content.Tiles.Misc;
using StarlightRiver.Core.Systems.CameraSystem;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Terraria.ID;

namespace StarlightRiver.Content.Items.Snow
{
internal class FrostFlail : AbstractHeavyFlail
{
public override string Texture => AssetDirectory.SnowItem + Name;

public override int ProjType => ModContent.ProjectileType<FrostFlailProjectile>();

public override void SetStaticDefaults()
{
DisplayName.SetDefault("Frost Flail");
Tooltip.SetDefault("Hold to swing a monstrous ball of ice\nCreates icy shards on impact, inflicting frostburn");
}

public override void SetDefaults()
{
base.SetDefaults();
Item.rare = ItemRarityID.Blue;
Item.damage = 14;
}

public override void AddRecipes()
{
Recipe recipe = CreateRecipe();
recipe.AddIngredient(ItemID.IceBlock, 99);
recipe.AddIngredient(ModContent.ItemType<HeavyFlail>(), 1);
recipe.AddTile(TileID.Anvils);
recipe.Register();
}
}

internal class FrostFlailProjectile : AbstractHeavyFlailProjectile
{
public override string Texture => AssetDirectory.SnowItem + Name;

public override Asset<Texture2D> ChainAsset => Assets.Items.Snow.FrostFlailChain;

public override int MaxLength => 160;

public override void AI()
{
base.AI();

for (int k = 0; k < 2; k++)
{
Dust.NewDust(Projectile.Center - Vector2.One * 20, 40, 40, DustID.IceTorch);
}
}

public override void OnImpact(bool wasTile)
{
if (wasTile)
{
Helpers.Helper.PlayPitched("Magic/FrostHit", 1, 0, Projectile.Center);

if (Owner == Main.LocalPlayer)
CameraSystem.shake += 8;

for (int k = 0; k < 30; k++)
{
Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.Ice);
}

for (int k = 0; k < 10; k++)
{
Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.SnowSpray, 0, -1);
}

for (int k = 0; k < 3; k++)
{
Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center, Vector2.One.RotatedByRandom(6.28f) * 3, ModContent.ProjectileType<FrostFlailShard>(), Projectile.damage / 2, 0, Projectile.owner);
}

Projectile.NewProjectile(Projectile.GetSource_FromThis(), Projectile.Center + Vector2.UnitY * 8, Vector2.Zero, ModContent.ProjectileType<FrostFlailCrack>(), 0, 0);
}
}
}

internal class FrostFlailCrack : ModProjectile, IDrawOverTiles
{
public override string Texture => AssetDirectory.Invisible;

public override void SetDefaults()
{
Projectile.tileCollide = false;
Projectile.penetrate = -1;
Projectile.timeLeft = 200;
}

public override bool PreDraw(ref Color lightColor)
{
return false;
}

public void DrawOverTiles(SpriteBatch spriteBatch)
{
float prog = Projectile.timeLeft > 100 ? 1f : Projectile.timeLeft / 100f;

Color color = Color.Lerp(new Color(150, 240, 255), new Color(50, 80, 150), prog);
color *= prog;
color.A = 0;
var tex = Assets.Misc.AlphaCrack.Value;

spriteBatch.Draw(tex, Projectile.Center - Main.screenPosition, null, color, 0, tex.Size() / 2, Projectile.scale, SpriteEffects.None, 0);
spriteBatch.Draw(tex, Projectile.Center - Main.screenPosition, null, new Color(255, 255, 255, 0) * prog * 0.25f, 0, tex.Size() / 2, Projectile.scale, SpriteEffects.None, 0);
}
}

internal class FrostFlailShard : ModProjectile
{
public override string Texture => AssetDirectory.SnowItem + Name;

public override void SetDefaults()
{
Projectile.width = 18;
Projectile.height = 18;
Projectile.tileCollide = true;
Projectile.timeLeft = 120;
Projectile.friendly = true;
Projectile.aiStyle = -1;
Projectile.penetrate = 15;
}

public override void AI()
{
Projectile.velocity.Y += 0.4f;
Projectile.rotation += Projectile.velocity.X * 0.1f;

Projectile.velocity.X *= 0.99f;

if (Projectile.timeLeft < 30)
Projectile.alpha = (int)((1 - Projectile.timeLeft / 30f) * 255);

if (Main.rand.NextBool(10))
Dust.NewDust(Projectile.position, 18, 18, DustID.IceTorch);
}

public override bool OnTileCollide(Vector2 oldVelocity)
{
if (Projectile.penetrate <= 0)
return true;

Projectile.velocity.Y += oldVelocity.Y * -0.8f;

return false;
}

public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
{
target.AddBuff(BuffID.Frostburn, 60);
}
}
}
Loading

0 comments on commit 3c77966

Please sign in to comment.