-using System.Numerics;
using Robust.Shared.GameStates;
-using Robust.Shared.Physics.Components;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.Weapons.Melee.Components;
/// This is used for a melee weapon that throws whatever gets hit by it in a line
/// until it hits a wall or a time limit is exhausted.
/// </summary>
-[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(fieldDeltas: true)]
[Access(typeof(MeleeThrowOnHitSystem))]
public sealed partial class MeleeThrowOnHitComponent : Component
{
/// </summary>
[DataField, AutoNetworkedField]
public bool ActivateOnThrown;
+
+ /// <summary>
+ /// Whether the entity can apply knockback this instance of being thrown.
+ /// If true, the entity cannot apply knockback.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ [ViewVariables(VVAccess.ReadOnly)]
+ public bool ThrowOnCooldown;
+
+ /// <summary>
+ /// Whether this item has hit anyone while it was thrown.
+ /// </summary>
+ [DataField, AutoNetworkedField]
+ [ViewVariables(VVAccess.ReadOnly)]
+ public bool HitWhileThrown;
}
/// <summary>
{
SubscribeLocalEvent<MeleeThrowOnHitComponent, MeleeHitEvent>(OnMeleeHit);
SubscribeLocalEvent<MeleeThrowOnHitComponent, ThrowDoHitEvent>(OnThrowHit);
+ SubscribeLocalEvent<MeleeThrowOnHitComponent, ThrownEvent>(OnThrow);
+ SubscribeLocalEvent<MeleeThrowOnHitComponent, LandEvent>(OnLand);
+ }
+
+ private void OnThrow(Entity<MeleeThrowOnHitComponent> ent, ref ThrownEvent args)
+ {
+ if (_delay.IsDelayed(ent.Owner))
+ return;
+
+ ent.Comp.HitWhileThrown = false;
+ ent.Comp.ThrowOnCooldown = false;
+
+ DirtyField(ent, ent.Comp, nameof(MeleeThrowOnHitComponent.HitWhileThrown));
+ DirtyField(ent, ent.Comp, nameof(MeleeThrowOnHitComponent.ThrowOnCooldown));
+ }
+
+ private void OnLand(Entity<MeleeThrowOnHitComponent> ent, ref LandEvent args)
+ {
+ if (ent.Comp.HitWhileThrown && !_delay.IsDelayed(ent.Owner))
+ _delay.TryResetDelay(ent.Owner);
+
+ ent.Comp.ThrowOnCooldown = true;
+ DirtyField(ent, ent.Comp, nameof(MeleeThrowOnHitComponent.ThrowOnCooldown));
}
private void OnMeleeHit(Entity<MeleeThrowOnHitComponent> weapon, ref MeleeHitEvent args)
if (!weapon.Comp.ActivateOnThrown)
return;
+ if (weapon.Comp.ThrowOnCooldown)
+ return;
+
if (!TryComp<PhysicsComponent>(args.Thrown, out var weaponPhysics))
return;
+ weapon.Comp.HitWhileThrown = true;
+ DirtyField(weapon, weapon.Comp, nameof(MeleeThrowOnHitComponent.HitWhileThrown));
+
ThrowOnHitHelper(weapon, args.Component.Thrower, args.Target, weaponPhysics.LinearVelocity);
}