diff --git a/Sources/Everglow.Function/Templates/Weapons/HandholdProjectile.cs b/Sources/Everglow.Function/Templates/Weapons/HandheldProjectile.cs
similarity index 64%
rename from Sources/Everglow.Function/Templates/Weapons/HandholdProjectile.cs
rename to Sources/Everglow.Function/Templates/Weapons/HandheldProjectile.cs
index a969a25f91..4ce1f9f684 100644
--- a/Sources/Everglow.Function/Templates/Weapons/HandholdProjectile.cs
+++ b/Sources/Everglow.Function/Templates/Weapons/HandheldProjectile.cs
@@ -1,11 +1,12 @@
+using Everglow.Commons.Utilities;
using Terraria.DataStructures;
namespace Everglow.Commons.Templates.Weapons;
///
-/// Handhold projectile.
+/// Handheld projectile.
///
-public abstract class HandholdProjectile : ModProjectile
+public abstract class HandheldProjectile : ModProjectile
{
///
/// The rotation of texture.
@@ -35,11 +36,54 @@ public abstract class HandholdProjectile : ModProjectile
public float DepartLength = 50;
public Vector2 ArmRootPos = Vector2.zeroVector;
+ ///
+ /// World-space cursor of the owner. Main.MouseWorld already accounts for local gravity.
+ ///
+ protected Vector2 AimPosition
+ {
+ get
+ {
+ Player player = Main.player[Projectile.owner];
+ player.ListenMouseWorld();
+ return Projectile.owner == Main.myPlayer ? Main.MouseWorld : player.MouseWorld();
+ }
+ }
+
+ protected Vector2 GravityDrawOffset => DrawOffset * new Vector2(1, Main.player[Projectile.owner].gravDir);
+
+ private bool rotationInitialized;
+
public override void OnSpawn(IEntitySource source)
{
- base.OnSpawn(source);
+ InitializeRotation();
+ }
+
+ private void InitializeRotation()
+ {
+ rotationInitialized = true;
+ // Spawn velocity is synchronized by Terraria, unlike the observer's cursor.
+ Projectile.rotation = Projectile.velocity.SafeNormalize(Vector2.UnitX * Main.player[Projectile.owner].direction).ToRotation() + MathHelper.PiOver4;
}
+ public override bool PreAI()
+ {
+ Player player = Main.player[Projectile.owner];
+ if (!player.active || player.dead)
+ {
+ Projectile.Kill();
+ return false;
+ }
+ // Received projectiles do not run OnSpawn.
+ if (!rotationInitialized)
+ {
+ InitializeRotation();
+ }
+ player.ListenMouseWorld();
+ return true;
+ }
+
+ public override bool ShouldUpdatePosition() => false;
+
public override void SetDefaults()
{
Projectile.width = 32;
@@ -69,13 +113,13 @@ public virtual void HeldProjectileAI()
{
Player player = Main.player[Projectile.owner];
player.heldProj = Projectile.whoAmI;
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f);
- Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
+ Vector2 mouseToPlayer = AimPosition - ArmRootPos;
+ mouseToPlayer = mouseToPlayer.SafeNormalize(Vector2.UnitX * player.direction);
if (player.controlUseItem)
{
- float addRot = -MathF.Asin(Vector3.Cross(new Vector3(mouseToPlayer, 0), new Vector3(new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75), 0)).Z);
+ float addRot = MathHelper.WrapAngle(mouseToPlayer.ToRotation() + MathHelper.PiOver4 - Projectile.rotation);
addRot *= LerpFactorOfRotation;
if (Math.Abs(addRot) > MaxRotationSpeed)
{
@@ -102,7 +146,7 @@ public virtual void HeldProjectileAI()
public virtual void RemoveExtraSameProjectiles(Player owner)
{
- if (owner.ownedProjectileCounts[Projectile.type] > 1)
+ if (Projectile.owner == Main.myPlayer && owner.ownedProjectileCounts[Projectile.type] > 1)
{
int count = owner.ownedProjectileCounts[Projectile.type];
for (int a = Main.projectile.Length - 1; a >= 0; a--)
@@ -137,12 +181,12 @@ public virtual void DrawBaseTexture(Color lightColor)
Player player = Main.player[Projectile.owner];
var texMain = (Texture2D)ModContent.Request(Texture);
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
- Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + DrawOffset, null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
+ Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + GravityDrawOffset, null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
}
}
diff --git a/Sources/Everglow.UnitTests/Function/HandheldProjectileTest.cs b/Sources/Everglow.UnitTests/Function/HandheldProjectileTest.cs
new file mode 100644
index 0000000000..9f599fed61
--- /dev/null
+++ b/Sources/Everglow.UnitTests/Function/HandheldProjectileTest.cs
@@ -0,0 +1,172 @@
+using System.Reflection;
+using Everglow.Commons;
+using Everglow.Commons.Templates.Weapons;
+using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic;
+using Microsoft.Xna.Framework;
+using Terraria;
+using Terraria.ModLoader;
+
+namespace Everglow.UnitTests.Function;
+
+[TestClass]
+[DoNotParallelize]
+public class HandheldProjectileTest
+{
+ private Player[] originalPlayers = null!;
+ private int originalMyPlayer;
+ private Vector2 originalScreenPosition;
+ private int originalMouseX;
+ private int originalMouseY;
+ private EverglowPlayer? originalModPlayer;
+ private Player owner = null!;
+ private EverglowPlayer modPlayer = null!;
+ private TestProjectile held = null!;
+
+ private static readonly PropertyInfo InstanceProperty = typeof(ContentInstance).GetProperty("Instance")!;
+ private static readonly FieldInfo MouseWorldField = typeof(EverglowPlayer).GetField("mouseWorld", BindingFlags.Instance | BindingFlags.NonPublic)!;
+
+ [TestInitialize]
+ public void Initialize()
+ {
+ Program.SavePath = string.Empty;
+ originalPlayers = Main.player;
+ originalMyPlayer = Main.myPlayer;
+ originalScreenPosition = Main.screenPosition;
+ originalMouseX = Main.mouseX;
+ originalMouseY = Main.mouseY;
+ originalModPlayer = ContentInstance.Instance;
+
+ owner = new Player { whoAmI = 1, active = true, controlUseItem = true, itemTimeMax = 30 };
+ owner.Center = new Vector2(100, 100);
+ Main.player = new Player[Main.maxPlayers + 1];
+ Main.player[0] = new Player { whoAmI = 0 };
+ Main.player[1] = owner;
+ Main.myPlayer = 0;
+ Main.screenPosition = Vector2.Zero;
+ Main.mouseX = 300;
+ Main.mouseY = 100;
+
+ modPlayer = (EverglowPlayer)new EverglowPlayer().NewInstance(owner);
+ InstanceProperty.SetValue(null, modPlayer);
+ typeof(Player).GetField("modPlayers", BindingFlags.Instance | BindingFlags.NonPublic)!.SetValue(owner, new ModPlayer[] { modPlayer });
+ held = (TestProjectile)new TestProjectile().NewInstance(new Projectile { owner = 1, active = true });
+ held.SetDefaults();
+ held.Projectile.rotation = MathHelper.PiOver4;
+ }
+
+ [TestCleanup]
+ public void Cleanup()
+ {
+ Main.player = originalPlayers;
+ Main.myPlayer = originalMyPlayer;
+ Main.screenPosition = originalScreenPosition;
+ Main.mouseX = originalMouseX;
+ Main.mouseY = originalMouseY;
+ InstanceProperty.SetValue(null, originalModPlayer);
+ }
+
+ [TestMethod]
+ public void RemoteOwner_AimsAtSynchronizedMouseInsteadOfLocalMouse()
+ {
+ MouseWorldField.SetValue(modPlayer, new Vector2(96, 298));
+ held.HeldProjectileAI();
+ Assert.AreEqual(96f, held.Projectile.Center.X, 0.001f);
+ Assert.AreEqual(148f, held.Projectile.Center.Y, 0.001f);
+ }
+
+ [TestMethod]
+ public void InvertedGravity_MirrorsArmRootOffset()
+ {
+ owner.gravDir = -1;
+ MouseWorldField.SetValue(modPlayer, new Vector2(296, 102));
+ held.HeldProjectileAI();
+ Assert.AreEqual(new Vector2(96, 102), held.ArmRootPos);
+ }
+
+ [TestMethod]
+ public void AimAtArmRoot_DoesNotProduceNonFinitePosition()
+ {
+ Main.myPlayer = 1;
+ Main.mouseX = 96;
+ Main.mouseY = 98;
+ MouseWorldField.SetValue(modPlayer, new Vector2(96, 98));
+ held.HeldProjectileAI();
+ Assert.IsTrue(float.IsFinite(held.Projectile.rotation));
+ Assert.IsTrue(float.IsFinite(held.Projectile.Center.X));
+ Assert.IsTrue(float.IsFinite(held.Projectile.Center.Y));
+ }
+
+ [TestMethod]
+ public void SpawnDirection_UsesNetworkedVelocityInsteadOfObserverMouse()
+ {
+ held.Projectile.velocity = new Vector2(0, -12);
+ held.OnSpawn(new Terraria.DataStructures.EntitySource_Misc("Test"));
+ Assert.AreEqual(-MathHelper.PiOver4, held.Projectile.rotation, 0.001f);
+ }
+
+ [TestMethod]
+ public void LocalOwner_RequestsMouseSynchronizationBeforeDerivedAI()
+ {
+ Main.myPlayer = 1;
+ Assert.IsTrue(held.PreAI());
+ var listenField = typeof(EverglowPlayer).GetField("listenMouseWorld", BindingFlags.Instance | BindingFlags.NonPublic)!;
+ Assert.IsTrue((bool)listenField.GetValue(modPlayer)!);
+ }
+
+ [TestMethod]
+ public void OppositeAim_TurnsToTheOtherSide()
+ {
+ MouseWorldField.SetValue(modPlayer, new Vector2(-104, 98));
+ held.HeldProjectileAI();
+ Assert.AreEqual(46f, held.Projectile.Center.X, 0.001f);
+ Assert.AreEqual(98f, held.Projectile.Center.Y, 0.001f);
+ Assert.AreEqual(-1, owner.direction);
+ }
+
+ [TestMethod]
+ public void RemoteOwnerGravity_IsIndependentOfObserverGravity()
+ {
+ Main.player[0].gravDir = -1;
+ MouseWorldField.SetValue(modPlayer, new Vector2(96, 298));
+ held.HeldProjectileAI();
+ Assert.AreEqual(148f, held.Projectile.Center.Y, 0.001f);
+ }
+
+ [TestMethod]
+ public void InvertedGravity_MirrorsDrawOffset()
+ {
+ owner.gravDir = -1;
+ held.DrawOffset = new Vector2(-6, -8);
+ Assert.AreEqual(new Vector2(-6, 8), held.DrawOffsetInWorld);
+ }
+
+ [TestMethod]
+ public void CrystalBeforeParentSync_WaitsWithoutDereferencingMissingParent()
+ {
+ var crystal = (YggdrasilAmberLaser_crystal)new YggdrasilAmberLaser_crystal().NewInstance(new Projectile { owner = 1, timeLeft = 900 });
+ crystal.AI();
+ Assert.IsFalse(crystal.EndAI);
+ }
+
+ [TestMethod]
+ public void ReceivedProjectile_InitializesDirectionWithoutOnSpawn()
+ {
+ held.Projectile.velocity = new Vector2(0, -12);
+ held.PreAI();
+ Assert.AreEqual(-MathHelper.PiOver4, held.Projectile.rotation, 0.001f);
+ }
+
+ [TestMethod]
+ public void ReceivedCrystal_InitializesTrackWithoutOnSpawn()
+ {
+ var projectile = new Projectile { owner = 1, timeLeft = 900, Center = new Vector2(120, 140) };
+ var crystal = (YggdrasilAmberLaser_crystal)new YggdrasilAmberLaser_crystal().NewInstance(projectile);
+ crystal.AI();
+ Assert.AreEqual(new Vector2(120, 140), crystal.CrystalTrack[0]);
+ }
+
+ private sealed class TestProjectile : HandheldProjectile
+ {
+ public Vector2 DrawOffsetInWorld => GravityDrawOffset;
+ }
+}
diff --git a/Sources/Modules/Example/Test/HandholdProj.cs b/Sources/Modules/Example/Test/HandholdProj.cs
index 48dc26e939..77f2c730c4 100644
--- a/Sources/Modules/Example/Test/HandholdProj.cs
+++ b/Sources/Modules/Example/Test/HandholdProj.cs
@@ -2,7 +2,7 @@
namespace Everglow.Example.Test;
-public class HandholdProj : HandholdProjectile
+public class HandholdProj : HandheldProjectile
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MiscsProjectiles;
}
diff --git a/Sources/Modules/Example/Test/HandholdProj2.cs b/Sources/Modules/Example/Test/HandholdProj2.cs
index ac6085102f..0a9e09470a 100644
--- a/Sources/Modules/Example/Test/HandholdProj2.cs
+++ b/Sources/Modules/Example/Test/HandholdProj2.cs
@@ -2,13 +2,12 @@
namespace Everglow.Example.Test;
-public class HandholdProj2 : HandholdProjectile
+public class HandholdProj2 : HandheldProjectile
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MiscsProjectiles;
public override void SetDef()
{
TextureRotation = 1.204f;
- base.SetDef();
}
}
diff --git a/Sources/Modules/Myth/LanternMoon/Items/Weapons/GildingRevolver.cs b/Sources/Modules/Myth/LanternMoon/Items/Weapons/GildingRevolver.cs
index aab54dea20..b83a95697c 100644
--- a/Sources/Modules/Myth/LanternMoon/Items/Weapons/GildingRevolver.cs
+++ b/Sources/Modules/Myth/LanternMoon/Items/Weapons/GildingRevolver.cs
@@ -35,6 +35,11 @@ public override void SetDefaults()
public override void HoldItem(Player player)
{
+ if (player.whoAmI != Main.myPlayer)
+ {
+ return;
+ }
+ player.ListenMouseWorld();
if (player.ownedProjectileCounts[ModContent.ProjectileType()] <= 0)
{
Projectile.NewProjectile(Item.GetSource_FromAI(), player.Center, Vector2.zeroVector, ModContent.ProjectileType(), 0, 0, player.whoAmI);
diff --git a/Sources/Modules/Myth/LanternMoon/Items/Weapons/KeroseneLanternFlameThrower.cs b/Sources/Modules/Myth/LanternMoon/Items/Weapons/KeroseneLanternFlameThrower.cs
index 92cb07a5af..2a621ebdb4 100644
--- a/Sources/Modules/Myth/LanternMoon/Items/Weapons/KeroseneLanternFlameThrower.cs
+++ b/Sources/Modules/Myth/LanternMoon/Items/Weapons/KeroseneLanternFlameThrower.cs
@@ -40,6 +40,11 @@ public override void SetDefaults()
public override void HoldItem(Player player)
{
+ if (player.whoAmI != Main.myPlayer)
+ {
+ return;
+ }
+ player.ListenMouseWorld();
if (UIBar is not null && UIBar.Active)
{
return;
diff --git a/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/GildingRevolver_Hold.cs b/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/GildingRevolver_Hold.cs
index 8c800b77d4..fac67ad62b 100644
--- a/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/GildingRevolver_Hold.cs
+++ b/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/GildingRevolver_Hold.cs
@@ -1,11 +1,10 @@
using Everglow.Commons.Templates.Weapons;
using Everglow.Myth.LanternMoon.Items.Weapons;
using Terraria.Audio;
-using Terraria.DataStructures;
namespace Everglow.Myth.LanternMoon.Projectiles.Weapons;
-public class GildingRevolver_Hold : HandholdProjectile
+public class GildingRevolver_Hold : HandheldProjectile
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.RangedProjectiles;
@@ -41,17 +40,13 @@ public override void SetDef()
ProjectileID.Sets.HeldProjDoesNotUsePlayerGfxOffY[Type] = true;
}
- public override void OnSpawn(IEntitySource source)
- {
- }
-
public override void AI()
{
if (ReloadCooling <= 0)
{
if (NormalBulletTimer < 120)
{
- NormalBulletTimer += 6 * (5f / Main.LocalPlayer.itemTimeMax);
+ NormalBulletTimer += 6 * (5f / Math.Max(Main.player[Projectile.owner].itemTimeMax, 1));
}
if (NormalBulletTimer > 120)
@@ -87,7 +82,7 @@ public override void AI()
{
if (proj is not null && proj.active && proj.type == ModContent.ProjectileType() && proj.owner == Projectile.owner)
{
- if ((Main.MouseWorld - proj.Center).Length() < 70)
+ if ((AimPosition - proj.Center).Length() < 70)
{
MouseInLanternZone = true;
break;
@@ -102,14 +97,14 @@ public override void HeldProjectileAI()
Player player = Main.player[Projectile.owner];
player.heldProj = Projectile.whoAmI;
int dir = 1;
- if (Main.MouseWorld.X < player.MountedCenter.X)
+ if (AimPosition.X < player.MountedCenter.X)
{
dir = -1;
}
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
- Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
+ Vector2 mouseToPlayer = AimPosition - ArmRootPos;
+ mouseToPlayer = mouseToPlayer.SafeNormalize(Vector2.UnitX * player.direction);
Projectile.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4;
Projectile.Center = player.MountedCenter + mouseToPlayer * 12;
Item item = player.HeldItem;
@@ -158,6 +153,10 @@ public override void HeldProjectileAI()
private void Shoot()
{
+ if (Projectile.owner != Main.myPlayer)
+ {
+ return;
+ }
Player player = Main.player[Projectile.owner];
var item = player.HeldItem;
if (item is not null
@@ -166,48 +165,50 @@ private void Shoot()
&& gildingRevolver.ShootType >= 0)
{
Vector2 vel = (Projectile.rotation - MathHelper.PiOver4).ToRotationVector2().RotatedByRandom(0.02f) * item.shootSpeed;
- Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + DrawOffset, vel, gildingRevolver.ShootType, item.damage, item.knockBack, Projectile.owner);
+ Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + GravityDrawOffset, vel, gildingRevolver.ShootType, item.damage, item.knockBack, Projectile.owner);
UsedBulletsCount++;
if (NormalBulletsCount == 6 || NormalBulletsCount == 3)
{
vel = (Projectile.rotation - MathHelper.PiOver4).ToRotationVector2().RotatedByRandom(0.02f) * item.shootSpeed / 4f;
- Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + DrawOffset, vel, ModContent.ProjectileType(), item.damage, item.knockBack, Projectile.owner);
+ Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + GravityDrawOffset, vel, ModContent.ProjectileType(), item.damage, item.knockBack, Projectile.owner);
}
}
}
private void ShootPhantom()
{
- SoundEngine.PlaySound(SoundID.Item101);
+ SoundEngine.PlaySound(SoundID.Item101, Projectile.Center);
+ if (Projectile.owner != Main.myPlayer)
+ {
+ return;
+ }
Player player = Main.player[Projectile.owner];
Item item = player.HeldItem;
if (item is null)
{
return;
}
- Vector2 vel = (Main.MouseWorld - Projectile.Center).NormalizeSafe().RotatedByRandom(0.03f) * item.shootSpeed * 1.5f;
- Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + DrawOffset, vel, ModContent.ProjectileType(), (int)(item.damage * 0.7f), item.knockBack, Projectile.owner);
+ Vector2 vel = (AimPosition - Projectile.Center).NormalizeSafe().RotatedByRandom(0.03f) * item.shootSpeed * 1.5f;
+ Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + GravityDrawOffset, vel, ModContent.ProjectileType(), (int)(item.damage * 0.7f), item.knockBack, Projectile.owner);
}
private void Shoot_RightClick()
{
+ if (Projectile.owner != Main.myPlayer)
+ {
+ return;
+ }
Player player = Main.player[Projectile.owner];
Item item = player.HeldItem;
if (item is null)
{
return;
}
- Vector2 vel = (Main.MouseWorld - Projectile.Center).NormalizeSafe() * item.shootSpeed * 1.5f;
- Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + DrawOffset, vel, ModContent.ProjectileType(), item.damage, item.knockBack, Projectile.owner);
+ Vector2 vel = (AimPosition - Projectile.Center).NormalizeSafe() * item.shootSpeed * 1.5f;
+ Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * -2 + GravityDrawOffset, vel, ModContent.ProjectileType(), item.damage, item.knockBack, Projectile.owner);
UsedBulletsCount++;
}
- public override bool PreDraw(ref Color lightColor)
- {
- DrawBaseTexture(lightColor);
- return false;
- }
-
public override void DrawBaseTexture(Color lightColor)
{
Player player = Main.player[Projectile.owner];
@@ -220,12 +221,12 @@ public override void DrawBaseTexture(Color lightColor)
{
var texMain = ModAsset.GildingRevolver_Hold.Value;
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
- Vector2 drawCenter = Projectile.Center - Main.screenPosition + DrawOffset;
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
+ Vector2 drawCenter = Projectile.Center - Main.screenPosition + GravityDrawOffset;
Main.spriteBatch.Draw(texMain, drawCenter, null, lightColor, rot, texMain.Size() * 0.5f, 1f, se, 0);
}
diff --git a/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/KeroseneLanternFlameThrower_Hold.cs b/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/KeroseneLanternFlameThrower_Hold.cs
index 64aa7a5dfa..8fa0342400 100644
--- a/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/KeroseneLanternFlameThrower_Hold.cs
+++ b/Sources/Modules/Myth/LanternMoon/Projectiles/Weapons/KeroseneLanternFlameThrower_Hold.cs
@@ -2,17 +2,21 @@
using Everglow.Commons.Graphics;
using Everglow.Commons.Templates.Weapons;
using Everglow.Myth.LanternMoon.Items.Weapons;
+using ReLogic.Utilities;
using Terraria.Audio;
-using Terraria.DataStructures;
namespace Everglow.Myth.LanternMoon.Projectiles.Weapons;
-public class KeroseneLanternFlameThrower_Hold : HandholdProjectile, IWarpProjectile_warpStyle2
+public class KeroseneLanternFlameThrower_Hold : HandheldProjectile, IWarpProjectile_warpStyle2
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.RangedProjectiles;
public int Timer = 0;
+ private SlotId beginSoundSlot = SlotId.Invalid;
+ private SlotId cycleSoundSlot = SlotId.Invalid;
+ private bool playedEndSound;
+
public struct SubProj
{
public Vector2 Pos;
@@ -33,17 +37,16 @@ public override void SetDef()
DrawOffset = new Vector2(-6, -8);
}
- public override void OnSpawn(IEntitySource source)
- {
- SoundEngine.PlaySound(new SoundStyle(ModAsset.Flamethrower_begin_Mod), Projectile.Center);
- }
-
public override void AI()
{
+ if (Timer == 0)
+ {
+ beginSoundSlot = SoundEngine.PlaySound(new SoundStyle(ModAsset.Flamethrower_begin_Mod), Projectile.Center);
+ }
Timer++;
float shootSpeed = GetShootSpeed();
Vector2 vel = (Projectile.rotation - MathHelper.PiOver4).ToRotationVector2() * shootSpeed;
- Vector2 pos = Projectile.Center + vel.NormalizeSafe() * (32 - shootSpeed) + DrawOffset;
+ Vector2 pos = Projectile.Center + vel.NormalizeSafe() * (32 - shootSpeed) + GravityDrawOffset;
var sub = new SubProj
{
Pos = pos,
@@ -77,17 +80,18 @@ public override void HeldProjectileAI()
if (player.wet)
{
Projectile.Kill();
+ return;
}
player.heldProj = Projectile.whoAmI;
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f);
int dir = 1;
- if (Main.MouseWorld.X < player.MountedCenter.X)
+ if (AimPosition.X < player.MountedCenter.X)
{
dir = -1;
}
- Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos;
+ Vector2 mouseToPlayer = AimPosition - ArmRootPos;
mouseToPlayer = mouseToPlayer.NormalizeSafe();
float powerRate = 1;
if (player.HeldItem is not null && player.HeldItem.type == ModContent.ItemType())
@@ -97,9 +101,10 @@ public override void HeldProjectileAI()
}
if (player.controlUseItem)
{
+ playedEndSound = false;
if (Timer % (int)(45 * 2.5f / (powerRate + 2)) == (int)(15 * 2.5f / (powerRate + 2)))
{
- SoundEngine.PlaySound(new SoundStyle(ModAsset.Flamethrower_cycle_Mod).WithPitchOffset(powerRate), Projectile.Center);
+ cycleSoundSlot = SoundEngine.PlaySound(new SoundStyle(ModAsset.Flamethrower_cycle_Mod).WithPitchOffset(powerRate), Projectile.Center);
}
float addRot = -MathF.Asin(Vector3.Cross(new Vector3(mouseToPlayer, 0), new Vector3(new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75), 0)).Z);
addRot *= LerpFactorOfRotation;
@@ -111,16 +116,24 @@ public override void HeldProjectileAI()
Projectile.Center = ArmRootPos + new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75) * DepartLength;
Projectile.timeLeft = player.itemTimeMax;
float shootSpeed = GetShootSpeed();
- if (Math.Abs(addRot) > 0.02f
- || Timer % 2 == 1)
+ if (Projectile.owner == Main.myPlayer && (Math.Abs(addRot) > 0.02f
+ || Timer % 2 == 1))
{
Vector2 vel = (Projectile.rotation - MathHelper.PiOver4).ToRotationVector2() * shootSpeed;
- Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * 60 + DrawOffset, vel, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner);
+ Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), Projectile.Center + vel.NormalizeSafe() * 60 + GravityDrawOffset, vel, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner);
}
}
- else
+ else if (!playedEndSound)
{
- SoundEngine.StopTrackedSounds();
+ playedEndSound = true;
+ if (SoundEngine.TryGetActiveSound(beginSoundSlot, out var beginSound))
+ {
+ beginSound.Stop();
+ }
+ if (SoundEngine.TryGetActiveSound(cycleSoundSlot, out var cycleSound))
+ {
+ cycleSound.Stop();
+ }
SoundEngine.PlaySound(new SoundStyle(ModAsset.Flamethrower_end_Mod).WithPitchOffset(Math.Clamp(powerRate, -1, 0)), Projectile.Center);
}
player.direction = dir;
@@ -138,25 +151,18 @@ public float GetShootSpeed()
return 12f;
}
- public override bool PreDraw(ref Color lightColor)
- {
- DrawBaseTexture(lightColor);
-
- return false;
- }
-
public override void DrawBaseTexture(Color lightColor)
{
Player player = Main.player[Projectile.owner];
var texMain = ModAsset.KeroseneLanternFlameThrower_Hold.Value;
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
- Vector2 drawCenter = Projectile.Center - Main.screenPosition + DrawOffset;
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
+ Vector2 drawCenter = Projectile.Center - Main.screenPosition + GravityDrawOffset;
var bars0 = new List();
var bars1 = new List();
@@ -235,24 +241,16 @@ public void CreateTrailVertex(List bars0, List bars1, List= 0)
+ float width = 1f;
+ if (i >= ShootProjPos.Count - 5)
{
- width = 1f;
- if (i >= ShootProjPos.Count - 5)
- {
- width = 1 - MathF.Cos((ShootProjPos.Count - i) / 5f * MathHelper.Pi);
- width *= 0.5f;
- }
+ width = 1 - MathF.Cos((ShootProjPos.Count - i) / 5f * MathHelper.Pi);
+ width *= 0.5f;
}
// timeValue, animate the trail.
float timeValue = Timer * 0.05f;
- Vector2 drawPos = Projectile.Center;
- if (i >= 0)
- {
- drawPos = ShootProjPos[i].Pos;
- }
+ Vector2 drawPos = ShootProjPos[i].Pos;
Color drawColor = GetTrailColor(i, style);
drawPos += offset;
bars0.Add(drawPos + new Vector2(0, 1).RotatedBy(MathHelper.TwoPi * 2f / 3f) * trailWidth, drawColor, ModifyWarpTexCoordinate(factor, timeValue, 0, width));
diff --git a/Sources/Modules/Myth/TheTusk/Projectiles/Weapon/ToothBow.cs b/Sources/Modules/Myth/TheTusk/Projectiles/Weapon/ToothBow.cs
index b47ce3936c..83b29cc9c5 100644
--- a/Sources/Modules/Myth/TheTusk/Projectiles/Weapon/ToothBow.cs
+++ b/Sources/Modules/Myth/TheTusk/Projectiles/Weapon/ToothBow.cs
@@ -3,7 +3,7 @@
namespace Everglow.Myth.TheTusk.Projectiles.Weapon;
-public class ToothBow : HandholdProjectile
+public class ToothBow : HandheldProjectile
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.RangedProjectiles;
@@ -16,22 +16,17 @@ public override void SetDef()
DepartLength = 20;
}
- public override void AI()
- {
- base.AI();
- }
-
public override void HeldProjectileAI()
{
Player player = Main.player[Projectile.owner];
player.heldProj = Projectile.whoAmI;
int dir = 1;
- if (Main.MouseWorld.X < player.MountedCenter.X)
+ if (AimPosition.X < player.MountedCenter.X)
{
dir = -1;
}
- ArmRootPos = player.MountedCenter + new Vector2(-4 * dir, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * dir, -2 * player.gravDir);
float backValue = (player.itemTimeMax - player.itemTime) / (float)player.itemTimeMax;
Player.CompositeArmStretchAmount compositeArmStretchAmount = Player.CompositeArmStretchAmount.Full;
if (backValue < 0.5f)
@@ -68,8 +63,8 @@ public override void HeldProjectileAI()
player.SetCompositeArmFront(true, compositeArmStretchAmount, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir + MathF.PI * 0.5f);
}
player.SetCompositeArmBack(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f);
- Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
+ Vector2 mouseToPlayer = AimPosition - ArmRootPos;
+ mouseToPlayer = mouseToPlayer.SafeNormalize(Vector2.UnitX * player.direction);
if (player.controlUseItem)
{
float addRot = -MathF.Asin(Vector3.Cross(new Vector3(mouseToPlayer, 0), new Vector3(new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75), 0)).Z);
@@ -86,37 +81,34 @@ public override void HeldProjectileAI()
else
{
SoundEngine.PlaySound(SoundID.Item5, Projectile.Center);
- Projectile.NewProjectileDirect(Terraria.Entity.InheritSource(Projectile), Projectile.Center, new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75) * 30f, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, player.whoAmI);
+ if (Projectile.owner == Main.myPlayer)
+ {
+ Projectile.NewProjectileDirect(Terraria.Entity.InheritSource(Projectile), Projectile.Center, new Vector2(0, 1).RotatedBy(Projectile.rotation - Math.PI * 0.75) * 30f, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, player.whoAmI);
+ }
Projectile.Kill();
+ return;
}
player.direction = dir;
}
- public override bool PreDraw(ref Color lightColor)
- {
- DrawBaseTexture(lightColor);
-
- return false;
- }
-
public override void DrawBaseTexture(Color lightColor)
{
Player player = Main.player[Projectile.owner];
var texMain = ModAsset.ToothBow_bow.Value;
var texArrow = ModAsset.ToothBow_BloodArrow.Value;
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
float backValue = (player.itemTimeMax - player.itemTime) / (float)player.itemTimeMax * 20;
- Vector2 drawCenter = Projectile.Center - Main.screenPosition + DrawOffset;
+ Vector2 drawCenter = Projectile.Center - Main.screenPosition + GravityDrawOffset;
Main.spriteBatch.Draw(texArrow, drawCenter + new Vector2(5 - backValue, 0).RotatedBy(rot), null, lightColor, rot, texArrow.Size() / 2f, 0.75f, se, 0);
Main.spriteBatch.Draw(texMain, drawCenter, null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
- if (Main.MouseWorld.X < player.MountedCenter.X)
+ if (AimPosition.X < player.MountedCenter.X)
{
player.direction = -1;
}
diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/Legacies/AncientSyringe.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/Legacies/AncientSyringe.cs
index 878ab16538..90e9b0588d 100644
--- a/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/Legacies/AncientSyringe.cs
+++ b/Sources/Modules/Yggdrasil/KelpCurtain/Items/Weapons/Legacies/AncientSyringe.cs
@@ -32,10 +32,7 @@ public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source,
{
if (Main.myPlayer == player.whoAmI)
{
- var p0 = Projectile.NewProjectileDirect(player.GetSource_ItemUse(Item), player.Center, Vector2.Zero, type, player.GetWeaponDamage(Item), Item.knockBack, player.whoAmI);
- Vector2 mouseToPlayer = Main.MouseWorld - player.MountedCenter;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
- p0.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4;
+ Projectile.NewProjectileDirect(source, player.Center, velocity, type, damage, knockback, player.whoAmI);
}
}
return false;
diff --git a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs
index adc32994ce..48879fd369 100644
--- a/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs
+++ b/Sources/Modules/Yggdrasil/KelpCurtain/Projectiles/Legacies/AncientSyringe_proj.cs
@@ -6,7 +6,7 @@
namespace Everglow.Yggdrasil.KelpCurtain.Projectiles.Legacies;
-public class AncientSyringe_proj : HandholdProjectile
+public class AncientSyringe_proj : HandheldProjectile
{
public override string LocalizationCategory => LocalizationUtils.Categories.MagicProjectiles;
@@ -15,11 +15,11 @@ public override void SetDef()
DepartLength = 110;
Projectile.usesLocalNPCImmunity = true;
Projectile.localNPCHitCooldown = 20;
- base.SetDef();
}
public override void OnSpawn(IEntitySource source)
{
+ base.OnSpawn(source);
Player player = Main.player[Projectile.owner];
int timeMax = (int)(player.itemTimeMax / player.meleeSpeed);
player.itemTime = timeMax;
@@ -27,6 +27,11 @@ public override void OnSpawn(IEntitySource source)
public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
{
+ target.AddBuff(ModContent.BuffType(), 480);
+ if (Main.dedServ)
+ {
+ return;
+ }
int times = 10;
for (int x = 0; x < times; x++)
{
@@ -60,13 +65,6 @@ public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
};
Ins.VFXManager.Add(blood);
}
- target.AddBuff(ModContent.BuffType(), 480);
- base.OnHitNPC(target, hit, damageDone);
- }
-
- public override void AI()
- {
- base.AI();
}
public override void HeldProjectileAI()
@@ -75,12 +73,13 @@ public override void HeldProjectileAI()
if (player.HeldItem.type != ModContent.ItemType())
{
Projectile.Kill();
+ return;
}
player.heldProj = Projectile.whoAmI;
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
- Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
+ Vector2 mouseToPlayer = AimPosition - ArmRootPos;
+ mouseToPlayer = mouseToPlayer.SafeNormalize(Vector2.UnitX * player.direction);
int timeMax = (int)(player.itemTimeMax / player.meleeSpeed);
if (Projectile.localNPCHitCooldown > timeMax - 1)
{
@@ -120,6 +119,7 @@ public override void HeldProjectileAI()
if (!player.controlUseItem)
{
Projectile.Kill();
+ return;
}
if (Projectile.Center.X < ArmRootPos.X)
{
@@ -136,13 +136,13 @@ public override bool PreDraw(ref Color lightColor)
Player player = Main.player[Projectile.owner];
var texMain = (Texture2D)ModContent.Request(Texture);
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
- Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + DrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
+ Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + GravityDrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
int timeMax = (int)(player.itemTimeMax / player.meleeSpeed);
float duration = player.itemTime / (float)timeMax;
duration *= 1.5f;
@@ -154,11 +154,11 @@ public override bool PreDraw(ref Color lightColor)
duration = MathF.Sin(duration * MathHelper.Pi);
Texture2D star = Commons.ModAsset.StarSlash_black.Value;
Color drawC = new Color(0.7f * lightColor.R / 255f, 2f * lightColor.G / 255f, 0.2f * lightColor.B / 255f, 0);
- Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + DrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, Color.White, MathHelper.PiOver2, star.Size() / 2f, 0.5f * duration, se, 0);
- Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + DrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, Color.White, 0, star.Size() / 2f, 0.5f * duration, se, 0);
+ Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + GravityDrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, Color.White, MathHelper.PiOver2, star.Size() / 2f, 0.5f * duration, se, 0);
+ Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + GravityDrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, Color.White, 0, star.Size() / 2f, 0.5f * duration, se, 0);
star = Commons.ModAsset.StarSlash.Value;
- Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + DrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, drawC, MathHelper.PiOver2, star.Size() / 2f, 0.5f * duration, se, 0);
- Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + DrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, drawC, 0, star.Size() / 2f, 0.5f * duration, se, 0);
+ Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + GravityDrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, drawC, MathHelper.PiOver2, star.Size() / 2f, 0.5f * duration, se, 0);
+ Main.spriteBatch.Draw(star, Projectile.Center - Main.screenPosition + GravityDrawOffset + new Vector2(24, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, drawC, 0, star.Size() / 2f, 0.5f * duration, se, 0);
return false;
}
}
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/AmberMagicOrb.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/AmberMagicOrb.cs
index 271831e46c..fde1819caa 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/AmberMagicOrb.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/AmberMagicOrb.cs
@@ -18,7 +18,6 @@ public override void SetDefaults()
Item.rare = ItemRarityID.Blue;
Item.UseSound = SoundID.Item1;
Item.value = 4514;
- Item.autoReuse = false;
Item.DamageType = DamageClass.Magic;
Item.mana = 18;
Item.noUseGraphic = true;
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/Auburn/RodSpear.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/Auburn/RodSpear.cs
index 28e48412f6..1cb9bdef73 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/Auburn/RodSpear.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/Auburn/RodSpear.cs
@@ -22,7 +22,7 @@ public override void SetDefaults()
Item.crit = 4;
Item.knockBack = 4f;
- Item.value = ItemRarityID.Green;
+ Item.rare = ItemRarityID.Green;
Item.value = Item.buyPrice(silver: 20);
Item.shoot = ModContent.ProjectileType();
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/HandgunOfEnlightment.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/HandgunOfEnlightment.cs
index 27db31c6a1..f9bfe3e400 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/HandgunOfEnlightment.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/HandgunOfEnlightment.cs
@@ -27,7 +27,7 @@ public override void SetDefaults()
Item.shootSpeed = 16f;
Item.useAmmo = AmmoID.Bullet;
- Item.value = ItemRarityID.Green;
+ Item.rare = ItemRarityID.Green;
Item.value = Item.buyPrice(silver: 3);
}
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/LightBeamStaff.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/LightBeamStaff.cs
index 983c639af1..6f405789a4 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/LightBeamStaff.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/LightSeeker/LightBeamStaff.cs
@@ -26,7 +26,7 @@ public override void SetDefaults()
Item.noMelee = true;
Item.mana = 5;
- Item.value = ItemRarityID.Green;
+ Item.rare = ItemRarityID.Green;
Item.value = Item.buyPrice(silver: 8);
Item.shoot = ModContent.ProjectileType();
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/YggdrasilAmberLaser.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/YggdrasilAmberLaser.cs
index 11d90c0fb2..7f1f856a25 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/YggdrasilAmberLaser.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Items/Weapons/YggdrasilAmberLaser.cs
@@ -1,5 +1,4 @@
using Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic;
-using Terraria.DataStructures;
namespace Everglow.Yggdrasil.YggdrasilTown.Items.Weapons;
@@ -32,9 +31,4 @@ public override void SetDefaults()
Item.shoot = ModContent.ProjectileType();
Item.shootSpeed = 12;
}
-
- public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback)
- {
- return base.Shoot(player, source, position, velocity, type, damage, knockback);
- }
}
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/AmberMagicOrb.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/AmberMagicOrb.cs
index 14e8ddf1b7..356e03c8c1 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/AmberMagicOrb.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/AmberMagicOrb.cs
@@ -1,35 +1,18 @@
using Everglow.Commons.Templates.Weapons;
-using Terraria.DataStructures;
namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic;
-public class AmberMagicOrb : HandholdProjectile
+public class AmberMagicOrb : HandheldProjectile
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles;
public override void SetDef()
{
DepartLength = 60;
- Projectile.usesLocalNPCImmunity = true;
- Projectile.localNPCHitCooldown = 20;
TextureRotation = 5 / 18f * MathHelper.Pi;
Projectile.usesLocalNPCImmunity = true;
Projectile.localNPCHitCooldown = 5;
Projectile.ArmorPenetration = 45;
- base.SetDef();
- }
-
- public override void OnSpawn(IEntitySource source)
- {
- Player player = Main.player[Projectile.owner];
- Vector2 mouseToPlayer = Main.MouseWorld - player.Center;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
- Projectile.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4;
- }
-
- public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
- {
- base.OnHitNPC(target, hit, damageDone);
}
public override void AI()
@@ -45,12 +28,13 @@ public override void HeldProjectileAI()
if (player.HeldItem.type != ModContent.ItemType())
{
Projectile.Kill();
+ return;
}
player.heldProj = Projectile.whoAmI;
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
- Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
+ Vector2 mouseToPlayer = AimPosition - ArmRootPos;
+ mouseToPlayer = mouseToPlayer.SafeNormalize(Vector2.UnitX * player.direction);
Projectile.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4;
player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f);
@@ -91,14 +75,14 @@ public override bool PreDraw(ref Color lightColor)
var texMain = (Texture2D)ModContent.Request(Texture);
var texGlow = ModAsset.AmberMagicOrb_glow.Value;
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
- Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + DrawOffset, null, lightColor, rot + (float)Main.time * 0.25f, texMain.Size() / 2f, 1f, se, 0);
- Main.spriteBatch.Draw(texGlow, Projectile.Center - Main.screenPosition + DrawOffset, null, new Color(1f, 1f, 1f, 0), rot + (float)Main.time * 0.25f, texGlow.Size() / 2f, 1f, se, 0);
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
+ Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + GravityDrawOffset, null, lightColor, rot + (float)Main.time * 0.25f, texMain.Size() / 2f, 1f, se, 0);
+ Main.spriteBatch.Draw(texGlow, Projectile.Center - Main.screenPosition + GravityDrawOffset, null, new Color(1f, 1f, 1f, 0), rot + (float)Main.time * 0.25f, texGlow.Size() / 2f, 1f, se, 0);
var bars = new List();
for (int t = 0; t < 3; t++)
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightBeamStaff_proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightBeamStaff_proj.cs
index 09455522da..4d8b116fc9 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightBeamStaff_proj.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/LightBeamStaff_proj.cs
@@ -1,16 +1,16 @@
-using Everglow.Commons.DataStructures;
using Everglow.Commons.Templates.Weapons;
-using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons;
using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons.LightSeeker;
using Terraria.Audio;
using Terraria.DataStructures;
namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic;
-public class LightBeamStaff_proj : HandholdProjectile
+public class LightBeamStaff_proj : HandheldProjectile
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles;
+ private bool playedSpawnSound;
+
public override void SetDef()
{
DepartLength = 60;
@@ -19,28 +19,25 @@ public override void SetDef()
Projectile.localNPCHitCooldown = 5;
Projectile.ArmorPenetration = 45;
Projectile.friendly = false;
- base.SetDef();
}
public override void OnSpawn(IEntitySource source)
{
- SoundEngine.PlaySound(SoundID.Shimmer1.WithPitchOffset(1), Projectile.Center);
- Player player = Main.player[Projectile.owner];
- Vector2 mouseToPlayer = Main.MouseWorld - player.Center;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
- Projectile.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4;
- Projectile.NewProjectile(Projectile.GetSource_FromAI(), Projectile.Center + Projectile.velocity * 2, Projectile.velocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner);
- }
-
- public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
- {
- base.OnHitNPC(target, hit, damageDone);
+ base.OnSpawn(source);
+ if (Projectile.owner == Main.myPlayer)
+ {
+ Projectile.NewProjectile(Projectile.GetSource_FromAI(), Projectile.Center + Projectile.velocity * 2, Projectile.velocity, ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner);
+ }
}
public override void AI()
{
+ if (!playedSpawnSound)
+ {
+ playedSpawnSound = true;
+ SoundEngine.PlaySound(SoundID.Shimmer1.WithPitchOffset(1), Projectile.Center);
+ }
HeldProjectileAI();
- Player player = Main.player[Projectile.owner];
}
public override void HeldProjectileAI()
@@ -49,9 +46,10 @@ public override void HeldProjectileAI()
if (player.HeldItem.type != ModContent.ItemType())
{
Projectile.Kill();
+ return;
}
player.heldProj = Projectile.whoAmI;
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
int timeMax = (int)(player.itemTimeMax / player.meleeSpeed);
if (Projectile.localNPCHitCooldown > timeMax - 1)
@@ -61,6 +59,7 @@ public override void HeldProjectileAI()
if (player.itemTime == 1)
{
Projectile.Kill();
+ return;
}
player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f);
DepartLength = 60;
@@ -82,12 +81,12 @@ public override bool PreDraw(ref Color lightColor)
Player player = Main.player[Projectile.owner];
var texMain = (Texture2D)ModContent.Request(Texture);
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
lightColor = Lighting.GetColor(Projectile.Center.ToTileCoordinates());
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
var texMain_glow = ModAsset.LightBeamStaff_glow.Value;
float duration = player.itemTime / (float)player.itemTimeMax;
duration *= 1.5f;
@@ -98,9 +97,9 @@ public override bool PreDraw(ref Color lightColor)
}
duration = MathF.Sin(duration * MathHelper.Pi);
- Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + DrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
+ Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + GravityDrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
var powerColor = new Color(duration + 0.3f, duration * duration, duration * duration, 0);
- Main.spriteBatch.Draw(texMain_glow, Projectile.Center - Main.screenPosition + DrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, powerColor, rot, texMain_glow.Size() / 2f, 1f, se, 0);
+ Main.spriteBatch.Draw(texMain_glow, Projectile.Center - Main.screenPosition + GravityDrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, powerColor, rot, texMain_glow.Size() / 2f, 1f, se, 0);
return false;
}
}
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_crystal.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_crystal.cs
index 07159888a0..dc4d4c4199 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_crystal.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_crystal.cs
@@ -1,3 +1,4 @@
+using System.IO;
using Everglow.Commons.DataStructures;
using Everglow.Yggdrasil.YggdrasilTown.Buffs;
using Everglow.Yggdrasil.YggdrasilTown.Dusts;
@@ -19,11 +20,26 @@ public override void SetDefaults()
Projectile.width = 10;
Projectile.height = 10;
Projectile.aiStyle = -1;
+ Projectile.hide = true;
CrystalTrack = new Vector2[50];
}
public Projectile LaserOwner;
+ private int laserOwnerIdentity = -1;
+ private bool trackInitialized;
+
+ public override void SendExtraAI(BinaryWriter writer)
+ {
+ writer.Write(LaserOwner?.identity ?? laserOwnerIdentity);
+ }
+
+ public override void ReceiveExtraAI(BinaryReader reader)
+ {
+ laserOwnerIdentity = reader.ReadInt32();
+ LaserOwner = null;
+ }
+
public Vector2[] CrystalTrack = new Vector2[50];
public bool EndAI = false;
@@ -31,18 +47,23 @@ public override void SetDefaults()
public override void OnSpawn(IEntitySource source)
{
CrystalTrack[0] = Projectile.Center;
+ trackInitialized = true;
Projectile.ai[0] = 0;
- Projectile.hide = true;
}
public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
{
target.AddBuff(ModContent.BuffType(), 6);
- base.OnHitNPC(target, hit, damageDone);
}
public override void AI()
{
+ // Network-created projectiles skip OnSpawn.
+ if (!trackInitialized)
+ {
+ CrystalTrack[0] = Projectile.Center;
+ trackInitialized = true;
+ }
if (Projectile.timeLeft < 60)
{
int length = 0;
@@ -66,6 +87,26 @@ public override void AI()
}
}
++Projectile.ai[0];
+ if (LaserOwner == null)
+ {
+ if (laserOwnerIdentity < 0)
+ {
+ return;
+ }
+ foreach (var candidate in Main.ActiveProjectiles)
+ {
+ if (candidate.owner == Projectile.owner && candidate.identity == laserOwnerIdentity
+ && candidate.ModProjectile is YggdrasilAmberLaser_proj)
+ {
+ LaserOwner = candidate;
+ break;
+ }
+ }
+ if (LaserOwner == null)
+ {
+ return;
+ }
+ }
if (!LaserOwner.active)
{
EndAI = true;
@@ -134,7 +175,7 @@ public override void AI()
return false;
}
float value = 0;
- if (Collision.CheckAABBvLineCollision(targetHitbox.TopLeft(), targetHitbox.Size(), CrystalTrack.ToArray()[i], CrystalTrack.ToArray()[i + 1], 20, ref value))
+ if (Collision.CheckAABBvLineCollision(targetHitbox.TopLeft(), targetHitbox.Size(), CrystalTrack[i], CrystalTrack[i + 1], 20, ref value))
{
return true;
}
@@ -142,10 +183,6 @@ public override void AI()
return false;
}
- public override void ModifyHitNPC(NPC target, ref NPC.HitModifiers modifiers)
- {
- }
-
public override void DrawBehind(int index, List behindNPCsAndTiles, List behindNPCs, List behindProjectiles, List overPlayers, List overWiresUI)
{
behindNPCsAndTiles.Add(index);
@@ -179,12 +216,12 @@ public override bool PreDraw(ref Color lightColor)
}
if (CrystalTrack[i + 1] != Vector2.zeroVector)
{
- Vector2 normal = (CrystalTrack.ToArray()[i + 1] - CrystalTrack.ToArray()[i]).SafeNormalize(Vector2.zeroVector).RotatedBy(MathHelper.PiOver2);
- AddVertex(bars, CrystalTrack.ToArray()[i] + normal * width, new Vector3(i * 0.3f, 1, 0));
- AddVertex(bars, CrystalTrack.ToArray()[i] - normal * width, new Vector3(i * 0.3f, 0f, 0));
+ Vector2 normal = (CrystalTrack[i + 1] - CrystalTrack[i]).SafeNormalize(Vector2.zeroVector).RotatedBy(MathHelper.PiOver2);
+ AddVertex(bars, CrystalTrack[i] + normal * width, new Vector3(i * 0.3f, 1, 0));
+ AddVertex(bars, CrystalTrack[i] - normal * width, new Vector3(i * 0.3f, 0f, 0));
- AddVertex2(barsReflect, CrystalTrack.ToArray()[i] + normal * width, new Vector3(i * 0.3f, 1, 0));
- AddVertex2(barsReflect, CrystalTrack.ToArray()[i] - normal * width, new Vector3(i * 0.3f, 0f, 0));
+ AddVertex2(barsReflect, CrystalTrack[i] + normal * width, new Vector3(i * 0.3f, 1, 0));
+ AddVertex2(barsReflect, CrystalTrack[i] - normal * width, new Vector3(i * 0.3f, 0f, 0));
}
}
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs
index 8088069a58..a5e80fc873 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Magic/YggdrasilAmberLaser_proj.cs
@@ -4,14 +4,15 @@
using Everglow.Yggdrasil.YggdrasilTown.Items.Weapons;
using Everglow.Yggdrasil.YggdrasilTown.VFXs;
using Terraria.Audio;
-using Terraria.DataStructures;
namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Magic;
-public class YggdrasilAmberLaser_proj : HandholdProjectile
+public class YggdrasilAmberLaser_proj : HandheldProjectile
{
public override string LocalizationCategory => Everglow.Commons.Utilities.LocalizationUtils.Categories.MagicProjectiles;
+ private bool playedSpawnSound;
+
public override void SetDef()
{
DepartLength = 60;
@@ -19,30 +20,31 @@ public override void SetDef()
Projectile.usesLocalNPCImmunity = true;
Projectile.localNPCHitCooldown = 5;
Projectile.ArmorPenetration = 45;
- base.SetDef();
}
public Vector2 EndPoint = Vector2.Zero;
public bool Crystalized = false;
- public override void OnSpawn(IEntitySource source)
- {
- SoundEngine.PlaySound(SoundID.Shimmer1.WithPitchOffset(1), Projectile.Center);
- Player player = Main.player[Projectile.owner];
- Vector2 mouseToPlayer = Main.MouseWorld - player.Center;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
- Projectile.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4;
- EndPoint = Vector2.Zero;
- }
-
- public override void OnHitNPC(NPC target, NPC.HitInfo hit, int damageDone)
- {
- base.OnHitNPC(target, hit, damageDone);
- }
-
public override void AI()
{
+ if (!playedSpawnSound)
+ {
+ playedSpawnSound = true;
+ SoundEngine.PlaySound(SoundID.Shimmer1.WithPitchOffset(1), Projectile.Center);
+ }
HeldProjectileAI();
+ if (!Projectile.active)
+ {
+ return;
+ }
+ Vector2 direction = (Projectile.rotation - MathHelper.PiOver4).ToRotationVector2();
+ int step = -6;
+ while (step < 200 && !Collision.SolidCollision(Projectile.Center + direction * step * 8, 0, 0))
+ {
+ step++;
+ }
+ MaxStep = step;
+ EndPoint = Projectile.Center + direction * step * 8;
Player player = Main.player[Projectile.owner];
int timeMax = (int)(player.itemTimeMax / player.meleeSpeed);
float duration = player.itemTime / (float)timeMax;
@@ -59,7 +61,7 @@ public override void AI()
}
if (EndPoint != Vector2.Zero)
{
- if (!Crystalized)
+ if (!Crystalized && Projectile.owner == Main.myPlayer)
{
Crystalized = true;
var projectile = Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), EndPoint, Vector2.zeroVector, ModContent.ProjectileType(), Projectile.damage / 2, 0, Projectile.owner);
@@ -67,8 +69,13 @@ public override void AI()
if (yALc != null)
{
yALc.LaserOwner = Projectile;
+ projectile.netUpdate = true;
}
}
+ if (Main.dedServ)
+ {
+ return;
+ }
for (int g = 0; g < 10; g++)
{
Vector2 newVelocity = new Vector2(0, Main.rand.NextFloat(0f, 12f)).RotatedByRandom(MathHelper.TwoPi);
@@ -105,7 +112,7 @@ public override void AI()
return false;
}
bool k = Collision.CheckAABBvLineCollision(targetHitbox.TopLeft(), new Vector2(targetHitbox.Width, targetHitbox.Height), Projectile.Center, EndPoint);
- if (k)
+ if (k && !Main.dedServ)
{
for (int g = 0; g < 10; g++)
{
@@ -133,9 +140,10 @@ public override void HeldProjectileAI()
if (player.HeldItem.type != ModContent.ItemType())
{
Projectile.Kill();
+ return;
}
player.heldProj = Projectile.whoAmI;
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
int timeMax = (int)(player.itemTimeMax / player.meleeSpeed);
if (Projectile.localNPCHitCooldown > timeMax - 1)
@@ -145,6 +153,7 @@ public override void HeldProjectileAI()
if (player.itemTime == 1)
{
Projectile.Kill();
+ return;
}
player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f);
DepartLength = 60;
@@ -159,7 +168,7 @@ public override void HeldProjectileAI()
{
player.direction = 1;
}
- if (EndPoint != Vector2.zeroVector)
+ if (!Main.dedServ && EndPoint != Vector2.zeroVector)
{
int duplicateTimes = 1;
for (int i = 0; i < duplicateTimes; i++)
@@ -196,12 +205,12 @@ public override bool PreDraw(ref Color lightColor)
Player player = Main.player[Projectile.owner];
var texMain = (Texture2D)ModContent.Request(Texture);
SpriteEffects se = SpriteEffects.None;
- if (player.direction == -1)
+ if (player.direction * player.gravDir == -1)
{
se = SpriteEffects.FlipVertically;
}
- float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction;
+ float rot = Projectile.rotation - (float)(Math.PI * 0.25) + TextureRotation * player.direction * player.gravDir;
var texMain_glow = ModAsset.YggdrasilAmberLaser_glow_proj.Value;
float duration = player.itemTime / (float)player.itemTimeMax;
duration *= 1.5f;
@@ -212,9 +221,9 @@ public override bool PreDraw(ref Color lightColor)
}
duration = MathF.Sin(duration * MathHelper.Pi);
- Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + DrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
+ Main.spriteBatch.Draw(texMain, Projectile.Center - Main.screenPosition + GravityDrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, lightColor, rot, texMain.Size() / 2f, 1f, se, 0);
var powerColor = new Color(duration, duration * duration, duration * duration, 0);
- Main.spriteBatch.Draw(texMain_glow, Projectile.Center - Main.screenPosition + DrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, powerColor, rot, texMain_glow.Size() / 2f, 1f, se, 0);
+ Main.spriteBatch.Draw(texMain_glow, Projectile.Center - Main.screenPosition + GravityDrawOffset - new Vector2(54, 0).RotatedBy(Projectile.rotation - MathHelper.PiOver4), null, powerColor, rot, texMain_glow.Size() / 2f, 1f, se, 0);
SpriteBatchState sBS = Main.spriteBatch.GetState().Value;
Main.spriteBatch.End();
@@ -252,8 +261,6 @@ public override bool PreDraw(ref Color lightColor)
};
Ins.VFXManager.Add(somg);
}
- MaxStep = step;
- EndPoint = Projectile.Center + MaxStep * mouseToPlayer * 8;
}
var bars = new List();
step = -6;
diff --git a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.cs b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.cs
index 0f5456e067..8dc235cd19 100644
--- a/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.cs
+++ b/Sources/Modules/Yggdrasil/YggdrasilTown/Projectiles/Ranged/PearShapedNeedle_HeldProj.cs
@@ -3,7 +3,7 @@
namespace Everglow.Yggdrasil.YggdrasilTown.Projectiles.Ranged;
-public class PearShapedNeedle_HeldProj : HandholdProjectile
+public class PearShapedNeedle_HeldProj : HandheldProjectile
{
public float Timer = 0;
@@ -36,12 +36,13 @@ public override void HeldProjectileAI()
if (player.HeldItem.type != ModContent.ItemType())
{
Projectile.Kill();
+ return;
}
player.heldProj = Projectile.whoAmI;
- ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2);
+ ArmRootPos = player.MountedCenter + new Vector2(-4 * player.direction, -2 * player.gravDir);
- Vector2 mouseToPlayer = Main.MouseWorld - ArmRootPos;
- mouseToPlayer = Vector2.Normalize(mouseToPlayer);
+ Vector2 mouseToPlayer = AimPosition - ArmRootPos;
+ mouseToPlayer = mouseToPlayer.SafeNormalize(Vector2.UnitX * player.direction);
Projectile.rotation = mouseToPlayer.ToRotation() + MathHelper.PiOver4;
player.SetCompositeArmFront(true, Player.CompositeArmStretchAmount.Full, (Projectile.rotation - MathF.PI * 0.25f) * player.gravDir - MathF.PI * 0.5f);
@@ -171,7 +172,6 @@ public float GetReflectValue(float rotation)
public override void OnKill(int timeLeft)
{
ReleaseNeedles();
- base.OnKill(timeLeft);
}
public bool NeedleReady(int k)
@@ -211,6 +211,10 @@ public void ReleaseNeedles()
if (NeedleReady(k))
{
succeed = true;
+ if (Projectile.owner != Main.myPlayer)
+ {
+ continue;
+ }
Projectile.NewProjectileDirect(Projectile.GetSource_FromAI(), GetNeedleWorldPos(k), GetReleaseVel(k).NormalizeSafe(), ModContent.ProjectileType(), Projectile.damage, Projectile.knockBack, Projectile.owner);
if (k > 0)
{