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.Map.Components; 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 ClothingSystem _clothing = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedMapSystem _mapSystem = 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) { var uidXform = Transform(uid); // Don't show particles unless the user is moving. if (Container.TryGetContainingContainer((uid, uidXform, null), out var container) && TryComp(container.Owner, out var body) && body.LinearVelocity.LengthSquared() < 1f) { return; } var coordinates = uidXform.Coordinates; var gridUid = _transform.GetGrid(coordinates); if (TryComp(gridUid, out var grid)) { coordinates = new EntityCoordinates(gridUid.Value, _mapSystem.WorldToLocal(gridUid.Value, grid, _transform.ToMapCoordinates(coordinates).Position)); } else if (uidXform.MapUid != null) { coordinates = new EntityCoordinates(uidXform.MapUid.Value, _transform.GetWorldPosition(uidXform)); } else { return; } Spawn("JetpackEffect", coordinates); } }