using Content.Shared._DV.Body.Components; using Content.Shared.GameTicking; using Content.Shared.Humanoid; using Content.Shared.Item; using JetBrains.Annotations; using Robust.Shared.Physics.Components; namespace Content.Shared._DV.Body.Systems; /// /// Used to relay or subscribe to events if a character's scale is 1.0 or below. /// This is only used for the height slider scale. /// public sealed partial class SmallCharacterSystem : EntitySystem { private const float NO_PENALTY = 1.0f; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnSpawn); } private void OnSpawn(PlayerSpawnCompleteEvent ev) { if (TryComp(ev.Mob, out var profile)) ApplySmallCharacter(ev.Mob, profile.Height); } [PublicAPI] public float ApplyPullSpeedPenalty(Entity puller, EntityUid? pulledEntity) { // Ignore if they aren't pulling anything... if (!pulledEntity.HasValue) return NO_PENALTY; // Ignore if they aren't a small character in the first place if (!Resolve(puller, ref puller.Comp, false)) return NO_PENALTY; // If the pulled entity has the component that ignores the penalty if (HasComp(pulledEntity)) return NO_PENALTY; // Ignore if it's an item that can be held or stored. It would be weird to // slow by X% from pulling a piece of paper or a gun when you can just hold it // and not suffer from a penalty. if (HasComp(pulledEntity)) return NO_PENALTY; // Ignore if the object is floating in the air. if (TryComp(pulledEntity, out var pulledPhysics) && pulledPhysics.BodyStatus == BodyStatus.InAir) return NO_PENALTY; return puller.Comp.PullSpeedPenalty; } #region Static Members /// /// Gets the move-speed penalty as a float. Should be applied multiplicatively. /// Caps at 1 so we don't make bigger characters faster when pulling. /// /// [PublicAPI] public static float GetPullSpeedPenaltyFromScale(float scale = 1.0f) { return Math.Min(scale * scale, 1); } /// /// Calculates a well-formed display string of the pull speed penalty. /// Used primarily in the character editor to get the well-formed percent /// without having to duplicate formulas. /// /// /// [PublicAPI] public static string GetPullSpeedPenaltyDisplayFromScale(float scale = 1.0f) { return $"{Math.Round((1 - GetPullSpeedPenaltyFromScale(scale)) * 100)}%"; } #endregion #region Private Members private void ApplySmallCharacter(EntityUid uid, float scale = 1) { if (scale >= 1) return; // The character scale is stored in the HumanoidProfileComponent if you ever // need it. var comp = EnsureComp(uid); comp.PullSpeedPenalty = GetPullSpeedPenaltyFromScale(scale); Dirty(uid, comp); } #endregion }