using Content.Shared.Chemistry.Components; using Content.Shared.EntityEffects; using Content.Shared.Movement.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Content.Server.EntityEffects.Effects; /// /// Default metabolism for stimulants and tranqs. Attempts to find a MovementSpeedModifier on the target, /// adding one if not there and to change the movespeed /// public sealed partial class MovespeedModifier : EntityEffect { /// /// How much the entities' walk speed is multiplied by. /// [DataField] public float WalkSpeedModifier { get; set; } = 1; /// /// How much the entities' run speed is multiplied by. /// [DataField] public float SprintSpeedModifier { get; set; } = 1; /// /// How long the modifier applies (in seconds). /// Is scaled by reagent amount if used with an EntityEffectReagentArgs. /// [DataField] public float StatusLifetime = 2f; protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) { return Loc.GetString("reagent-effect-guidebook-movespeed-modifier", ("chance", Probability), ("walkspeed", WalkSpeedModifier), ("time", StatusLifetime)); } /// /// Remove reagent at set rate, changes the movespeed modifiers and adds a MovespeedModifierMetabolismComponent if not already there. /// public override void Effect(EntityEffectBaseArgs args) { var status = args.EntityManager.EnsureComponent(args.TargetEntity); // Only refresh movement if we need to. var modified = !status.WalkSpeedModifier.Equals(WalkSpeedModifier) || !status.SprintSpeedModifier.Equals(SprintSpeedModifier); status.WalkSpeedModifier = WalkSpeedModifier; status.SprintSpeedModifier = SprintSpeedModifier; // only going to scale application time var statusLifetime = StatusLifetime; if (args is EntityEffectReagentArgs reagentArgs) { statusLifetime *= reagentArgs.Scale.Float(); } IncreaseTimer(status, statusLifetime, args.EntityManager, args.TargetEntity); if (modified) args.EntityManager.System().RefreshMovementSpeedModifiers(args.TargetEntity); } private void IncreaseTimer(MovespeedModifierMetabolismComponent status, float time, IEntityManager entityManager, EntityUid uid) { var gameTiming = IoCManager.Resolve(); var offsetTime = Math.Max(status.ModifierTimer.TotalSeconds, gameTiming.CurTime.TotalSeconds); status.ModifierTimer = TimeSpan.FromSeconds(offsetTime + time); entityManager.Dirty(uid, status); } }