Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions Content/Guardian/GuardianShieldAnchor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public class GuardianShieldAnchor : OrchidModGuardianAnchor
public float networkedRotation => Projectile.ai[2];

// ...

public bool IsRotationLocked;
private float LockedRotation;
public override void SafeSetDefaults()
{
Projectile.width = 20;
Expand Down Expand Up @@ -108,6 +109,7 @@ public override void AI()
}

float addedDistance = 0f;

if (Projectile.ai[1] > 0f)
{ // Shield bash
if (isSlamming == 0)
Expand Down Expand Up @@ -142,9 +144,12 @@ public override void AI()

if (Projectile.ai[1] <= 0f)
{
guardianItem.SlamEnd(owner, Projectile);
Projectile.ai[1] = 0f;
isSlamming = 0;
Projectile.friendly = false;
IsRotationLocked = false;
Projectile.netUpdate = true;
}
}

Expand Down Expand Up @@ -245,13 +250,15 @@ public override void AI()
{
aimedLocation = Main.MouseWorld - owner.Center.Floor();
aimedLocation.Normalize();

aimedLocation = Vector2.UnitX.RotatedBy(IsRotationLocked ? LockedRotation : OrchidModGuardianShield.GetSnappedAngle(guardianItem, owner,aimedLocation.ToRotation()));
Projectile.velocity = aimedLocation * float.Epsilon;
aimedLocation *= (guardianItem.distance + addedDistance) * -1f;

Projectile.rotation = aimedLocation.ToRotation();
if (guardianItem.shouldFlip)
{
if (aimedLocation.X < 0)
if (aimedLocation.X < 0 || (isSlamming is 1 or 2 && IsRotationLocked && -Vector2.UnitX.RotatedBy(LockedRotation).X < 0))
{
Projectile.spriteDirection = -1;
}
Expand Down Expand Up @@ -284,6 +291,12 @@ public override void AI()
if (isSlamming == 1) // Slam() is called here so the projectile has the time to reposition properly before effects such as projectile spawns are called
{
isSlamming = 2;
if (guardianItem.lockSlamRotation)
{
IsRotationLocked = true;
LockedRotation = Projectile.rotation + MathHelper.Pi;
Projectile.netUpdate = true;
}
guardianItem.Slam(owner, Projectile);
guardian.GuardianCounterTime = 0;
}
Expand Down
36 changes: 36 additions & 0 deletions Content/Guardian/OrchidModGuardianShield.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using OrchidMod.Common;
Expand Down Expand Up @@ -28,6 +29,8 @@ public virtual void SlamHitFirst(Player player, Projectile shield, NPC npc) { }
public virtual void SlamHit(Player player, Projectile shield, NPC npc) { }
/// <summary>Called on the first frame of a slam.</summary>
public virtual void Slam(Player player, Projectile shield) { }
/// <summary>Called on the last frame of a slam.</summary>
public virtual void SlamEnd(Player player, Projectile shield) { }
/// <summary>Called when an enemy collides with the shield during a block. Will be called once per frame per enemy colliding with it.</summary>
public virtual void Push(Player player, Projectile shield, NPC npc) { }
/// <summary>Called once per block when the first enemy or projectile is blocked. This is called after <c>Push</c> or <c>Block</c>, but before <c>Block</c> destroys the projectile.</summary>
Expand All @@ -49,6 +52,23 @@ public virtual void BlockStart(Player player, Projectile shield) { }
/// <summary>Causes the shield's held sprite to flip when facing right.</summary>
public bool shouldFlip = false;
public bool slamAutoReuse = true;
/// <summary>
/// If true, the shield will be rotated in discrete steps, instead of a single continuous circle. Defaults to false.
/// </summary>
public bool useDiscreteAim = false;
/// <summary>
/// The amount of steps per half-rotation that the shield will snap to, if <c>useDiscreteAim</c> is true.
/// <br/> A value of <c>0</c> results in only a single possible angle, directly in front of the player. Otherwise, there will be twice as many snap points as this value.
/// </summary>
public int discreteAimIncrements;
/// <summary>
/// The angle, in pi/2 increments, that the base angle will be rotated by.
/// </summary>
public int discreteAimRotation;
/// <summary>
/// If true, slams performed with the shield will be locked to the rotation they started with, rather than being free to rotate mid-slam.
/// </summary>
public bool lockSlamRotation;

public sealed override void SetDefaults()
{
Expand All @@ -61,6 +81,10 @@ public sealed override void SetDefaults()
Item.useStyle = ItemUseStyleID.Thrust;
Item.useTime = 30;
Item.knockBack = 6f;
useDiscreteAim = false;
discreteAimIncrements = 2;
discreteAimRotation = 0;
lockSlamRotation = false;

OrchidGlobalItemPerEntity orchidItem = Item.GetGlobalItem<OrchidGlobalItemPerEntity>();
orchidItem.guardianWeapon = true;
Expand Down Expand Up @@ -243,5 +267,17 @@ public override void ModifyTooltips(List<TooltipLine> tooltips)
OverrideColor = new Color(175, 255, 175)
});
}

public static float GetSnappedAngle(OrchidModGuardianShield shield, Player player, float originalAngle)
{
if (!shield.useDiscreteAim) return originalAngle;
if (shield.discreteAimIncrements == 0) return -player.direction * MathHelper.PiOver2 * shield.discreteAimRotation + (player.direction == -1 ? MathHelper.Pi : 0f);
else
{
float angleIncrement = MathHelper.Pi / shield.discreteAimIncrements;
return (float)Math.Round((Vector2.Normalize(Main.MouseWorld - player.MountedCenter.Floor()).ToRotation() + MathHelper.PiOver2 * shield.discreteAimRotation) / angleIncrement) * angleIncrement - MathHelper.PiOver2 * shield.discreteAimRotation;
}

}
}
}