using Content.Shared.Actions; using Content.Shared.Actions.Components; using Content.Shared.Cloning.Events; using Content.Shared.Gravity; using Content.Shared.Movement.Components; using Content.Shared.Popups; using Content.Shared.Standing; using Content.Shared.Stunnable; using Content.Shared.Throwing; using Robust.Shared.Audio.Systems; using Robust.Shared.Physics.Events; namespace Content.Shared.Movement.Systems; public sealed partial class SharedJumpAbilitySystem : EntitySystem { [Dependency] private readonly ThrowingSystem _throwing = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedGravitySystem _gravity = default!; [Dependency] private readonly SharedActionsSystem _actions = default!; [Dependency] private readonly SharedStunSystem _stun = default!; [Dependency] private readonly StandingStateSystem _standing = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnGravityJump); SubscribeLocalEvent(OnLeaperCollide); SubscribeLocalEvent(OnLeaperLand); SubscribeLocalEvent(OnLeaperStopThrow); SubscribeLocalEvent(OnClone); } private void OnInit(Entity entity, ref MapInitEvent args) { if (!TryComp(entity, out ActionsComponent? comp)) return; _actions.AddAction(entity, ref entity.Comp.ActionEntity, entity.Comp.Action, component: comp); } private void OnShutdown(Entity entity, ref ComponentShutdown args) { _actions.RemoveAction(entity.Owner, entity.Comp.ActionEntity); } private void OnLeaperCollide(Entity entity, ref StartCollideEvent args) { _stun.TryKnockdown(entity.Owner, entity.Comp.KnockdownDuration, force: true); RemCompDeferred(entity); } private void OnLeaperLand(Entity entity, ref LandEvent args) { RemCompDeferred(entity); } private void OnLeaperStopThrow(Entity entity, ref StopThrowEvent args) { RemCompDeferred(entity); } private void OnGravityJump(Entity entity, ref GravityJumpEvent args) { if (_gravity.IsWeightless(args.Performer) || _standing.IsDown(args.Performer)) { if (entity.Comp.JumpFailedPopup != null) _popup.PopupClient(Loc.GetString(entity.Comp.JumpFailedPopup.Value), args.Performer, args.Performer); return; } var xform = Transform(args.Performer); var throwing = xform.LocalRotation.ToWorldVec() * entity.Comp.JumpDistance; var direction = xform.Coordinates.Offset(throwing); // to make the character jump in the direction he's looking _throwing.TryThrow(args.Performer, direction, entity.Comp.JumpThrowSpeed); _audio.PlayPredicted(entity.Comp.JumpSound, args.Performer, args.Performer); if (entity.Comp.CanCollide) { EnsureComp(entity, out var leaperComp); leaperComp.KnockdownDuration = entity.Comp.CollideKnockdown; Dirty(entity.Owner, leaperComp); } args.Handled = true; } private void OnClone(Entity ent, ref CloningEvent args) { if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name)) return; var targetComp = Factory.GetComponent(); targetComp.Action = ent.Comp.Action; targetComp.CanCollide = ent.Comp.CanCollide; targetComp.JumpSound = ent.Comp.JumpSound; targetComp.CollideKnockdown = ent.Comp.CollideKnockdown; targetComp.JumpDistance = ent.Comp.JumpDistance; targetComp.JumpThrowSpeed = ent.Comp.JumpThrowSpeed; AddComp(args.CloneUid, targetComp, true); } }