using Content.Shared.Clothing.Components; using Content.Shared.Clothing.EntitySystems; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Robust.Client.GameObjects; using Robust.Shared.Map; using Robust.Shared.Physics.Components; using Robust.Shared.Timing; namespace Content.Client.Movement.Systems; public sealed class JetpackSystem : SharedJetpackSystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly ClothingSystem _clothing = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnJetpackAppearance); } protected override bool CanEnable(EntityUid uid, JetpackComponent component) { // No predicted atmos so you'd have to do a lot of funny to get this working. return false; } private void OnJetpackAppearance(EntityUid uid, JetpackComponent component, ref AppearanceChangeEvent args) { Appearance.TryGetData(uid, JetpackVisuals.Enabled, out var enabled, args.Component); var state = "icon" + (enabled ? "-on" : ""); args.Sprite?.LayerSetState(0, state); if (TryComp(uid, out var clothing)) _clothing.SetEquippedPrefix(uid, enabled ? "on" : null, clothing); } public override void Update(float frameTime) { base.Update(frameTime); if (!_timing.IsFirstTimePredicted) return; // TODO: Please don't copy-paste this I beg // make a generic particle emitter system / actual particles instead. var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp)) { if (_timing.CurTime < comp.TargetTime) continue; comp.TargetTime = _timing.CurTime + TimeSpan.FromSeconds(comp.EffectCooldown); CreateParticles(uid); } } private void CreateParticles(EntityUid uid) { // Don't show particles unless the user is moving. if (Container.TryGetContainingContainer(uid, out var container) && TryComp(container.Owner, out var body) && body.LinearVelocity.LengthSquared() < 1f) { return; } var uidXform = Transform(uid); var coordinates = uidXform.Coordinates; var gridUid = coordinates.GetGridUid(EntityManager); if (_mapManager.TryGetGrid(gridUid, out var grid)) { coordinates = new EntityCoordinates(gridUid.Value, grid.WorldToLocal(coordinates.ToMapPos(EntityManager, _transform))); } else if (uidXform.MapUid != null) { coordinates = new EntityCoordinates(uidXform.MapUid.Value, _transform.GetWorldPosition(uidXform)); } else { return; } Spawn("JetpackEffect", coordinates); } }