add beam wand (thanks lexy)
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
using Terraria.GameContent.ItemDropRules;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Items.Global
|
||||
{
|
||||
// Adds BeamAttackWand to Eye of Cthulhu treasure bag loot table.
|
||||
public class EyeOfCthulhuBagLoot : GlobalItem
|
||||
{
|
||||
public override void ModifyItemLoot(Item item, ItemLoot itemLoot)
|
||||
{
|
||||
if (item.type == ItemID.EyeOfCthulhuBossBag)
|
||||
{
|
||||
// 1 in 3 chance (adjust if too common)
|
||||
itemLoot.Add(ItemDropRule.Common(ModContent.ItemType<Weapons.Magic.BeamAttackWand>(), 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using ForgottenWawiTech.Content.Projectiles;
|
||||
using ForgottenWawiTech.Content.Players;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Items.Weapons.Magic
|
||||
{
|
||||
// A post-Eye of Cthulhu melee/magic hybrid style weapon that swings like a sword and
|
||||
// emits a flurry of short-lived beam projectiles toward the cursor during the swing.
|
||||
// Beams have reduced damage (50% of item base) and very short lifetime.
|
||||
public class BeamAttackWand : ModItem
|
||||
{
|
||||
public override void SetStaticDefaults()
|
||||
{
|
||||
// DisplayName.SetDefault("Beam Attack Wand"); // tML auto localizes; optional if using hjson.
|
||||
// Tooltip.SetDefault("Swings and releases a flurry of brief energy beams");
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
Item.width = 32;
|
||||
Item.height = 32;
|
||||
Item.useStyle = ItemUseStyleID.Swing;
|
||||
Item.useAnimation = 28; // frames the swing lasts
|
||||
Item.useTime = 28; // one use per full animation
|
||||
Item.autoReuse = true;
|
||||
Item.UseSound = SoundID.Item1;
|
||||
Item.damage = 25;
|
||||
Item.knockBack = 4.5f;
|
||||
Item.DamageType = DamageClass.Magic; // treat beams as melee for synergy
|
||||
Item.rare = ItemRarityID.Blue; // around early game progression
|
||||
Item.value = Item.buyPrice(silver: 50);
|
||||
Item.shoot = ModContent.ProjectileType<BeamAttackWandBeam>();
|
||||
Item.shootSpeed = 12f; // base speed of beams
|
||||
Item.noMelee = false;
|
||||
Item.mana = 3;
|
||||
}
|
||||
|
||||
// No recipe: obtained from Eye of Cthulhu treasure bag (see GlobalItem loot class)
|
||||
|
||||
public override void HoldItem(Player player)
|
||||
{
|
||||
// Emit beams only while the item is mid-swing
|
||||
if (player.itemAnimation > 0 && player.HeldItem.type == Item.type && player.whoAmI == Main.myPlayer)
|
||||
{
|
||||
var modPlayer = player.GetModPlayer<BeamAttackWandPlayer>();
|
||||
modPlayer.BeamEmissionTimer--;
|
||||
if (modPlayer.BeamEmissionTimer <= 0)
|
||||
{
|
||||
// Kirby-style beam: a sweeping whip that leaves a multi-beam arc.
|
||||
// We'll spawn several beams at once in a tight angular spread around a smoothed central swing rotation.
|
||||
float targetRot = player.itemRotation + (player.direction == -1 ? MathHelper.Pi : 0f);
|
||||
if (modPlayer.LastBeamRot == 0f)
|
||||
modPlayer.LastBeamRot = targetRot;
|
||||
// Smooth aggressively so the arc persists briefly (lower factor = larger persistence)
|
||||
float smoothedRot = modPlayer.LastBeamRot + MathHelper.WrapAngle(targetRot - modPlayer.LastBeamRot) * 0.25f;
|
||||
modPlayer.LastBeamRot = smoothedRot;
|
||||
|
||||
// Determine swing progress (0..1) to slightly widen arc near middle of swing
|
||||
float swingProgress = 1f - (player.itemAnimation / (float)player.itemAnimationMax);
|
||||
// Arc width scales up mid-swing then back down
|
||||
float baseArc = 0.30f; // radians total small arc
|
||||
float arcWidth = baseArc * (float)(1.0 - System.Math.Pow(2 * swingProgress - 1, 2)); // bell curve widen
|
||||
|
||||
int beamsThisBurst = 4; // number of simultaneous beams
|
||||
int beamDamage = (int)(Item.damage * 0.45f); // slight reduction since multiple per tick
|
||||
for (int i = 0; i < beamsThisBurst; i++)
|
||||
{
|
||||
// Evenly distribute within arc centered on smoothedRot
|
||||
float lerp = beamsThisBurst == 1 ? 0f : i / (float)(beamsThisBurst - 1);
|
||||
float offset = MathHelper.Lerp(-arcWidth * 0.5f, arcWidth * 0.5f, lerp);
|
||||
float beamRot = smoothedRot + offset;
|
||||
Vector2 dir = beamRot.ToRotationVector2();
|
||||
if (dir.HasNaNs()) dir = new Vector2(player.direction, 0f);
|
||||
dir = dir.SafeNormalize(new Vector2(player.direction, 0f));
|
||||
|
||||
// Stagger spawn distance to create a whip chain illusion (front beams slightly further)
|
||||
float distance = 14f + 3f * i;
|
||||
Vector2 spawnPos = player.Center + dir * distance + new Vector2(0f, -4f);
|
||||
Vector2 velocity = dir * Item.shootSpeed * (1f + i * 0.05f); // slight incremental speed
|
||||
|
||||
Projectile.NewProjectile(player.GetSource_ItemUse(Item), spawnPos, velocity,
|
||||
Item.shoot, beamDamage, Item.knockBack, player.whoAmI);
|
||||
}
|
||||
|
||||
// Emit burst every 3 ticks to keep DPS reasonable while visually dense
|
||||
modPlayer.BeamEmissionTimer = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,119 @@
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace ForgottenWawiTech.Content.NPCs.Enemies.AvalianInvasion
|
||||
{
|
||||
public class AvalianEliteCommando : ModNPC
|
||||
{
|
||||
private int attackTimer = 0;
|
||||
private int teleportTimer = 0;
|
||||
|
||||
public override void SetStaticDefaults()
|
||||
{
|
||||
Main.npcFrameCount[Type] = 8;
|
||||
NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0)
|
||||
{
|
||||
Velocity = 1f
|
||||
};
|
||||
NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
NPC.width = 38;
|
||||
NPC.height = 48;
|
||||
NPC.damage = 70;
|
||||
NPC.defense = 30;
|
||||
NPC.lifeMax = 800;
|
||||
NPC.HitSound = SoundID.NPCHit1;
|
||||
NPC.DeathSound = SoundID.NPCDeath6;
|
||||
NPC.value = Item.buyPrice(0, 0, 50, 0);
|
||||
NPC.knockBackResist = 0.1f;
|
||||
NPC.aiStyle = NPCAIStyleID.Bat;
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
Player target = Main.player[NPC.target];
|
||||
if (target.active && !target.dead)
|
||||
{
|
||||
attackTimer++;
|
||||
teleportTimer++;
|
||||
|
||||
// Fast movement
|
||||
Vector2 toPlayer = Vector2.Normalize(target.Center - NPC.Center);
|
||||
float distanceToPlayer = Vector2.Distance(NPC.Center, target.Center);
|
||||
|
||||
// Teleport mechanic every 180 frames (3 seconds)
|
||||
if (teleportTimer >= 180 && distanceToPlayer > 200f)
|
||||
{
|
||||
teleportTimer = 0;
|
||||
|
||||
// Teleport dust effect
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric);
|
||||
}
|
||||
|
||||
// Teleport near player
|
||||
Vector2 teleportPos = target.Center + new Vector2(Main.rand.Next(-200, 200), -150);
|
||||
NPC.position = teleportPos;
|
||||
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric);
|
||||
}
|
||||
}
|
||||
|
||||
// Rapid fire attack every 30 frames (0.5 seconds)
|
||||
if (attackTimer >= 30)
|
||||
{
|
||||
attackTimer = 0;
|
||||
|
||||
if (Main.netMode != NetmodeID.MultiplayerClient)
|
||||
{
|
||||
Vector2 shootDirection = Vector2.Normalize(target.Center - NPC.Center);
|
||||
|
||||
// Triple shot spread
|
||||
for (int i = -1; i <= 1; i++)
|
||||
{
|
||||
Vector2 perturbedSpeed = shootDirection.RotatedBy(MathHelper.ToRadians(15 * i));
|
||||
Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center,
|
||||
perturbedSpeed * 14f, ProjectileID.MartianTurretBolt,
|
||||
NPC.damage / 3, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Aggressive movement
|
||||
if (distanceToPlayer > 150f)
|
||||
{
|
||||
NPC.velocity = toPlayer * 6f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void HitEffect(NPC.HitInfo hit)
|
||||
{
|
||||
if (NPC.life <= 0)
|
||||
{
|
||||
// Epic death effects
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather);
|
||||
}
|
||||
for (int i = 0; i < 15; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float SpawnChance(NPCSpawnInfo spawnInfo)
|
||||
{
|
||||
return 0f; // Controlled by invasion system
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace ForgottenWawiTech.Content.NPCs.Enemies.AvalianInvasion
|
||||
{
|
||||
public class AvalianRifleman : ModNPC
|
||||
{
|
||||
private int shootTimer = 0;
|
||||
|
||||
public override void SetStaticDefaults()
|
||||
{
|
||||
Main.npcFrameCount[Type] = 6;
|
||||
NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0)
|
||||
{
|
||||
Velocity = 1f
|
||||
};
|
||||
NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
NPC.width = 34;
|
||||
NPC.height = 42;
|
||||
NPC.damage = 55;
|
||||
NPC.defense = 20;
|
||||
NPC.lifeMax = 400;
|
||||
NPC.HitSound = SoundID.NPCHit1;
|
||||
NPC.DeathSound = SoundID.NPCDeath6;
|
||||
NPC.value = Item.buyPrice(0, 0, 10, 0);
|
||||
NPC.knockBackResist = 0.3f;
|
||||
NPC.aiStyle = NPCAIStyleID.Bat; // Flying ranged enemy
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
// Ranged attack behavior
|
||||
Player target = Main.player[NPC.target];
|
||||
if (target.active && !target.dead)
|
||||
{
|
||||
shootTimer++;
|
||||
|
||||
// Keep distance from player
|
||||
float distanceToPlayer = Vector2.Distance(NPC.Center, target.Center);
|
||||
if (distanceToPlayer < 300f)
|
||||
{
|
||||
// Move away
|
||||
Vector2 awayDirection = Vector2.Normalize(NPC.Center - target.Center);
|
||||
NPC.velocity = awayDirection * 3f;
|
||||
}
|
||||
|
||||
// Shoot every 90 frames (1.5 seconds)
|
||||
if (shootTimer >= 90)
|
||||
{
|
||||
shootTimer = 0;
|
||||
|
||||
if (Main.netMode != NetmodeID.MultiplayerClient)
|
||||
{
|
||||
Vector2 shootDirection = Vector2.Normalize(target.Center - NPC.Center);
|
||||
Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center,
|
||||
shootDirection * 10f, ProjectileID.BulletHighVelocity,
|
||||
NPC.damage / 2, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void HitEffect(NPC.HitInfo hit)
|
||||
{
|
||||
if (NPC.life <= 0)
|
||||
{
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float SpawnChance(NPCSpawnInfo spawnInfo)
|
||||
{
|
||||
return 0f; // Controlled by invasion system
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace ForgottenWawiTech.Content.NPCs.Enemies.AvalianInvasion
|
||||
{
|
||||
public class AvalianScout : ModNPC
|
||||
{
|
||||
public override void SetStaticDefaults()
|
||||
{
|
||||
Main.npcFrameCount[Type] = 6; // Animation frames
|
||||
NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0)
|
||||
{
|
||||
Velocity = 1f
|
||||
};
|
||||
NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
NPC.width = 32;
|
||||
NPC.height = 40;
|
||||
NPC.damage = 45;
|
||||
NPC.defense = 15;
|
||||
NPC.lifeMax = 250;
|
||||
NPC.HitSound = SoundID.NPCHit1;
|
||||
NPC.DeathSound = SoundID.NPCDeath6;
|
||||
NPC.value = Item.buyPrice(0, 0, 5, 0);
|
||||
NPC.knockBackResist = 0.5f;
|
||||
NPC.aiStyle = NPCAIStyleID.Fighter; // Basic fighter AI
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
// Add subtle hover/flight behavior
|
||||
if (NPC.velocity.Y > -2f && NPC.velocity.Y < 2f)
|
||||
{
|
||||
NPC.velocity.Y += Main.rand.NextFloat(-0.1f, 0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
public override void HitEffect(NPC.HitInfo hit)
|
||||
{
|
||||
// Feather particles on hit
|
||||
if (NPC.life <= 0)
|
||||
{
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather,
|
||||
Main.rand.NextFloat(-2f, 2f), Main.rand.NextFloat(-2f, 2f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float SpawnChance(NPCSpawnInfo spawnInfo)
|
||||
{
|
||||
// Only spawn during Avalian Invasion event
|
||||
return 0f; // Controlled by invasion system
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace ForgottenWawiTech.Content.NPCs.Enemies.AvalianInvasion
|
||||
{
|
||||
public class AvalianTechnician : ModNPC
|
||||
{
|
||||
private int laserTimer = 0;
|
||||
|
||||
public override void SetStaticDefaults()
|
||||
{
|
||||
Main.npcFrameCount[Type] = 6;
|
||||
NPCID.Sets.NPCBestiaryDrawModifiers value = new NPCID.Sets.NPCBestiaryDrawModifiers(0)
|
||||
{
|
||||
Velocity = 1f
|
||||
};
|
||||
NPCID.Sets.NPCBestiaryDrawOffset.Add(Type, value);
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
NPC.width = 36;
|
||||
NPC.height = 44;
|
||||
NPC.damage = 40;
|
||||
NPC.defense = 12;
|
||||
NPC.lifeMax = 300;
|
||||
NPC.HitSound = SoundID.NPCHit1;
|
||||
NPC.DeathSound = SoundID.NPCDeath6;
|
||||
NPC.value = Item.buyPrice(0, 0, 15, 0);
|
||||
NPC.knockBackResist = 0.4f;
|
||||
NPC.aiStyle = NPCAIStyleID.Bat;
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
Player target = Main.player[NPC.target];
|
||||
if (target.active && !target.dead)
|
||||
{
|
||||
laserTimer++;
|
||||
|
||||
// Circle around player
|
||||
float distanceToPlayer = Vector2.Distance(NPC.Center, target.Center);
|
||||
if (distanceToPlayer > 400f)
|
||||
{
|
||||
// Move closer
|
||||
Vector2 toPlayer = Vector2.Normalize(target.Center - NPC.Center);
|
||||
NPC.velocity = toPlayer * 4f;
|
||||
}
|
||||
else if (distanceToPlayer < 350f)
|
||||
{
|
||||
// Orbit
|
||||
Vector2 toPlayer = target.Center - NPC.Center;
|
||||
Vector2 perpendicular = new Vector2(-toPlayer.Y, toPlayer.X);
|
||||
perpendicular.Normalize();
|
||||
NPC.velocity = perpendicular * 3f;
|
||||
}
|
||||
|
||||
// Fire laser every 60 frames (1 second)
|
||||
if (laserTimer >= 60)
|
||||
{
|
||||
laserTimer = 0;
|
||||
|
||||
if (Main.netMode != NetmodeID.MultiplayerClient)
|
||||
{
|
||||
Vector2 shootDirection = Vector2.Normalize(target.Center - NPC.Center);
|
||||
Projectile.NewProjectile(NPC.GetSource_FromAI(), NPC.Center,
|
||||
shootDirection * 12f, ProjectileID.DeathLaser,
|
||||
NPC.damage / 2, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void HitEffect(NPC.HitInfo hit)
|
||||
{
|
||||
if (NPC.life <= 0)
|
||||
{
|
||||
// Tech parts and feathers
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Feather);
|
||||
}
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Dust.NewDust(NPC.position, NPC.width, NPC.height, DustID.Electric);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float SpawnChance(NPCSpawnInfo spawnInfo)
|
||||
{
|
||||
return 0f; // Controlled by invasion system
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Terraria.ModLoader;
|
||||
using Terraria;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Players
|
||||
{
|
||||
// Tracks per-tick emission cooldown for BeamAttackWand while swinging.
|
||||
public class BeamAttackWandPlayer : ModPlayer
|
||||
{
|
||||
public int BeamEmissionTimer = 0;
|
||||
public float LastBeamRot; // smoothed rotation used to cluster beams
|
||||
|
||||
public override void ResetEffects()
|
||||
{
|
||||
// If not holding the wand, allow immediate beam spawn next time it's used and reset rotation smoothing.
|
||||
if (Player.HeldItem.type != ModContent.ItemType<Items.Weapons.Magic.BeamAttackWand>())
|
||||
{
|
||||
BeamEmissionTimer = 0;
|
||||
LastBeamRot = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Terraria;
|
||||
using Terraria.ID;
|
||||
using Terraria.ModLoader;
|
||||
using Terraria.GameContent;
|
||||
|
||||
namespace ForgottenWawiTech.Content.Projectiles
|
||||
{
|
||||
// Short-lived beam projectile emitted rapidly by BeamAttackWand.
|
||||
// Simple straight projectile with minor dust and fade-out.
|
||||
public class BeamAttackWandBeam : ModProjectile
|
||||
{
|
||||
private const int FrameCount = 3;
|
||||
public override void SetStaticDefaults()
|
||||
{
|
||||
Main.projFrames[Type] = FrameCount; // 3 vertical frames
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
{
|
||||
Projectile.width = 28; // frame width
|
||||
Projectile.height = 28; // frame height
|
||||
Projectile.friendly = true;
|
||||
Projectile.penetrate = 1; // single hit per beam
|
||||
Projectile.timeLeft = 15; // very short duration
|
||||
Projectile.DamageType = DamageClass.Melee;
|
||||
Projectile.tileCollide = true;
|
||||
Projectile.light = 0.4f;
|
||||
Projectile.alpha = 40;
|
||||
}
|
||||
|
||||
public override void AI()
|
||||
{
|
||||
// Frame animation: advance every 4 ticks for subtle flicker
|
||||
Projectile.frameCounter++;
|
||||
if (Projectile.frameCounter >= 4)
|
||||
{
|
||||
Projectile.frameCounter = 0;
|
||||
Projectile.frame = (Projectile.frame + 1) % FrameCount;
|
||||
}
|
||||
|
||||
// Slight acceleration forward for a snappy feel
|
||||
Projectile.velocity *= 1.02f;
|
||||
|
||||
// Simple fade: become more transparent near end
|
||||
if (Projectile.timeLeft < 6)
|
||||
Projectile.alpha += 25;
|
||||
|
||||
// Spawn light dust
|
||||
if (Main.rand.NextBool(3))
|
||||
{
|
||||
int d = Dust.NewDust(Projectile.position, Projectile.width, Projectile.height, DustID.PurpleTorch,
|
||||
Projectile.velocity.X * 0.2f, Projectile.velocity.Y * 0.2f, 150, default, 0.9f);
|
||||
Main.dust[d].noGravity = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnTileCollide(Vector2 oldVelocity)
|
||||
{
|
||||
// So beams feel crisp: slight bounce spark then die
|
||||
Projectile.timeLeft = 5;
|
||||
Projectile.velocity *= 0.4f;
|
||||
return false; // don't kill immediately; fade
|
||||
}
|
||||
|
||||
public override bool PreDraw(ref Color lightColor)
|
||||
{
|
||||
Texture2D tex = TextureAssets.Projectile[Type].Value;
|
||||
int frameHeight = tex.Height / FrameCount;
|
||||
Rectangle frameRect = new(0, frameHeight * Projectile.frame, tex.Width, frameHeight);
|
||||
Vector2 origin = new(tex.Width / 2f, frameHeight / 2f);
|
||||
float baseScale = 1f;
|
||||
float stretchX = 0.6f + Projectile.velocity.Length() / 30f; // elongate horizontally
|
||||
Color drawColor = Color.White * (1f - Projectile.alpha / 255f);
|
||||
|
||||
// Slight additive trail effect: draw faint previous frame positions
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
Vector2 trailPos = Projectile.Center - Projectile.velocity * i * 0.8f;
|
||||
float trailAlpha = (0.4f - i * 0.12f) * (1f - Projectile.alpha / 255f);
|
||||
Main.EntitySpriteDraw(tex, trailPos - Main.screenPosition, frameRect,
|
||||
drawColor * trailAlpha, Projectile.rotation, origin,
|
||||
new Vector2(stretchX, baseScale), SpriteEffects.None);
|
||||
}
|
||||
|
||||
// Main frame (bright)
|
||||
Main.EntitySpriteDraw(tex, Projectile.Center - Main.screenPosition, frameRect,
|
||||
drawColor, Projectile.rotation, origin,
|
||||
new Vector2(stretchX, baseScale), SpriteEffects.None);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
Reference in New Issue
Block a user