using Content.Shared._Stalker.Weight; using Content.Shared.Movement.Systems; namespace Content.Server._Stalker.Weight; public sealed partial class STWeightSystem : EntitySystem { [Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifier = default!; public override void Initialize() { base.Initialize(); InitializeModifier(); InitializeThrowing(); SubscribeLocalEvent(OnParentChanged); SubscribeLocalEvent(OnRefreshMovementSpeedModifiers); } private void OnParentChanged(Entity weight, ref EntParentChangedMessage args) { UpdateWeight(weight); TryUpdateWeight(args.OldParent); } private void OnRefreshMovementSpeedModifiers(Entity weight, ref RefreshMovementSpeedModifiersEvent args) { args.ModifySpeed(weight.Comp.MovementSpeedModifier, weight.Comp.MovementSpeedModifier); } private void SetMovementSpeedModifiers(Entity weight, float modifier) { weight.Comp.MovementSpeedModifier = modifier; _movementSpeedModifier.RefreshMovementSpeedModifiers(weight); } private void SetInsideWeight(Entity weight, float inside) { var ev = new GetWeightModifiersEvent(inside, weight.Comp.Self); RaiseLocalEvent(weight, ev); weight.Comp.InsideWeight = ev.Inside; // Update movement speed var speedModifier = Math.Clamp(1 - (weight.Comp.Total - weight.Comp.Overload) / (weight.Comp.TotalMaximum - weight.Comp.TotalOverload), 0f, 1f); SetMovementSpeedModifiers(weight, speedModifier); } private void UpdateWeight(Entity weight) { if (!TryComp(weight, out var transform)) return; var newInside = 0f; var enumerator = transform.ChildEnumerator; while (enumerator.MoveNext(out var uid)) { if (!TryGetWeight(uid, out var childWeight)) continue; newInside += childWeight; } SetInsideWeight(weight, newInside); // Call update the weight of the parent component if there is one TryUpdateParent(weight); } public void SetWeightLimits(Entity weight, float newOverload, float newMaximum) { weight.Comp.Maximum = newMaximum; weight.Comp.Overload = newOverload; UpdateWeight(weight); } public bool TrySetWeightLimits(EntityUid uid, float newOverload, float newMaximum, STWeightComponent? weight = null) { if (!Resolve(uid, ref weight)) return false; if (newMaximum == weight.Maximum && newOverload == weight.Overload) return false; SetWeightLimits((uid, weight), newOverload, newMaximum); return true; } public bool TryUpdateWeight(EntityUid? uid) { if (uid is not { } target) return false; if (!TryComp(uid, out var comp)) return false; UpdateWeight((target, comp)); return true; } private bool TryGetWeight(EntityUid uid, out float weight) { weight = 0f; if (!TryComp(uid, out var comp)) return false; weight = comp.Total; return true; } private bool TryUpdateParent(Entity weight) { var parent = Transform(weight).ParentUid; if (!TryComp(parent, out var comp)) return false; UpdateWeight((parent, comp)); return true; } }