diff --git a/Content.Client/Clothing/MagbootsSystem.cs b/Content.Client/Clothing/MagbootsSystem.cs index 220d8db819..b832a3559b 100644 --- a/Content.Client/Clothing/MagbootsSystem.cs +++ b/Content.Client/Clothing/MagbootsSystem.cs @@ -1,5 +1,4 @@ using Content.Shared.Clothing; -using Content.Shared.Movement.EntitySystems; namespace Content.Client.Clothing { diff --git a/Content.Client/Movement/Components/ClimbableComponent.cs b/Content.Client/Movement/Components/ClimbableComponent.cs index 730c333693..1c695ac792 100644 --- a/Content.Client/Movement/Components/ClimbableComponent.cs +++ b/Content.Client/Movement/Components/ClimbableComponent.cs @@ -1,3 +1,4 @@ +using Content.Client.Movement.Systems; using Content.Shared.Climbing; namespace Content.Client.Movement.Components; diff --git a/Content.Client/Movement/Components/ClimbingComponent.cs b/Content.Client/Movement/Components/ClimbingComponent.cs index e68592bd77..ef5ada9529 100644 --- a/Content.Client/Movement/Components/ClimbingComponent.cs +++ b/Content.Client/Movement/Components/ClimbingComponent.cs @@ -1,4 +1,5 @@ -using Content.Shared.Climbing; +using Content.Client.Movement.Systems; +using Content.Shared.Climbing; namespace Content.Client.Movement.Components; diff --git a/Content.Client/Movement/ClimbSystem.cs b/Content.Client/Movement/Systems/ClimbSystem.cs similarity index 97% rename from Content.Client/Movement/ClimbSystem.cs rename to Content.Client/Movement/Systems/ClimbSystem.cs index f8b1afc3cf..0354ee020e 100644 --- a/Content.Client/Movement/ClimbSystem.cs +++ b/Content.Client/Movement/Systems/ClimbSystem.cs @@ -4,12 +4,12 @@ using Content.Shared.Climbing; using Content.Shared.DragDrop; using Robust.Shared.GameStates; -namespace Content.Client.Movement; +namespace Content.Client.Movement.Systems; public sealed class ClimbSystem : SharedClimbSystem { [Dependency] private readonly InteractionSystem _interactionSystem = default!; - + public override void Initialize() { base.Initialize(); diff --git a/Content.Client/Movement/Systems/JetpackSystem.cs b/Content.Client/Movement/Systems/JetpackSystem.cs new file mode 100644 index 0000000000..0a9b850e16 --- /dev/null +++ b/Content.Client/Movement/Systems/JetpackSystem.cs @@ -0,0 +1,80 @@ +using Content.Client.Clothing; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; +using Content.Shared.Weapons.Ranged.Systems; +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Shared.GameStates; +using Robust.Shared.Map; +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!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnJetpackAppearance); + } + + protected override bool CanEnable(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) + { + args.Component.TryGetData(JetpackVisuals.Enabled, out bool enabled); + + var state = "icon" + (enabled ? "-on" : ""); + args.Sprite?.LayerSetState(0, state); + + if (TryComp(uid, out var clothing)) + clothing.EquippedPrefix = enabled ? "on" : null; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + if (!_timing.IsFirstTimePredicted) return; + + foreach (var comp in EntityQuery()) + { + comp.Accumulator += frameTime; + + if (comp.Accumulator < comp.EffectCooldown) continue; + comp.Accumulator -= comp.EffectCooldown; + CreateParticles(comp.Owner); + } + } + + private void CreateParticles(EntityUid uid) + { + var uidXform = Transform(uid); + var coordinates = uidXform.Coordinates; + var gridUid = coordinates.GetGridUid(EntityManager); + + if (_mapManager.TryGetGrid(gridUid, out var grid)) + { + coordinates = new EntityCoordinates(grid.GridEntityId, grid.WorldToLocal(coordinates.ToMapPos(EntityManager))); + } + else if (uidXform.MapUid != null) + { + coordinates = new EntityCoordinates(uidXform.MapUid.Value, uidXform.WorldPosition); + } + else + { + return; + } + + var ent = Spawn("JetpackEffect", coordinates); + var xform = Transform(ent); + xform.Coordinates = coordinates; + } +} diff --git a/Content.Client/Nutrition/Components/HungerComponent.cs b/Content.Client/Nutrition/Components/HungerComponent.cs index 989c07d93a..4dea387b44 100644 --- a/Content.Client/Nutrition/Components/HungerComponent.cs +++ b/Content.Client/Nutrition/Components/HungerComponent.cs @@ -1,5 +1,5 @@ using Content.Shared.Movement.Components; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Content.Shared.Nutrition.Components; using Robust.Shared.GameObjects; diff --git a/Content.Client/Physics/Controllers/MoverController.cs b/Content.Client/Physics/Controllers/MoverController.cs index 6e37d22a4c..6db507f00e 100644 --- a/Content.Client/Physics/Controllers/MoverController.cs +++ b/Content.Client/Physics/Controllers/MoverController.cs @@ -1,6 +1,7 @@ using Content.Shared.MobState.Components; using Content.Shared.Movement; using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; using Content.Shared.Pulling.Components; using Robust.Client.Player; using Robust.Shared.Map; diff --git a/Content.Client/Spawners/TimedDespawnSystem.cs b/Content.Client/Spawners/TimedDespawnSystem.cs new file mode 100644 index 0000000000..e899eff099 --- /dev/null +++ b/Content.Client/Spawners/TimedDespawnSystem.cs @@ -0,0 +1,11 @@ +using Content.Shared.Spawners.EntitySystems; + +namespace Content.Client.Spawners; + +public sealed class TimedDespawnSystem : SharedTimedDespawnSystem +{ + protected override bool CanDelete(EntityUid uid) + { + return uid.IsClientSide(); + } +} diff --git a/Content.Server/Atmos/Components/GasTankComponent.cs b/Content.Server/Atmos/Components/GasTankComponent.cs index 5fa613dacf..53d45f9499 100644 --- a/Content.Server/Atmos/Components/GasTankComponent.cs +++ b/Content.Server/Atmos/Components/GasTankComponent.cs @@ -145,6 +145,10 @@ namespace Content.Server.Atmos.Components if (internals == null) return; IsConnected = internals.TryConnectTank(Owner); EntitySystem.Get().SetToggled(ToggleAction, IsConnected); + + // Couldn't toggle! + if (!IsConnected) return; + _connectStream?.Stop(); if (_connectSound != null) @@ -158,6 +162,7 @@ namespace Content.Server.Atmos.Components if (!IsConnected) return; IsConnected = false; EntitySystem.Get().SetToggled(ToggleAction, false); + GetInternalsComponent(owner)?.DisconnectTank(); _disconnectStream?.Stop(); diff --git a/Content.Server/Body/Systems/BodySystem.cs b/Content.Server/Body/Systems/BodySystem.cs index ea6e9d82d3..9aa05dd1ec 100644 --- a/Content.Server/Body/Systems/BodySystem.cs +++ b/Content.Server/Body/Systems/BodySystem.cs @@ -5,7 +5,7 @@ using Content.Server.Kitchen.Components; using Content.Server.Mind.Components; using Content.Shared.Body.Components; using Content.Shared.MobState.Components; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Events; using Robust.Shared.Timing; namespace Content.Server.Body.Systems diff --git a/Content.Server/Chemistry/ReagentEffects/MovespeedModifier.cs b/Content.Server/Chemistry/ReagentEffects/MovespeedModifier.cs index 75fc19b3f2..b779255f88 100644 --- a/Content.Server/Chemistry/ReagentEffects/MovespeedModifier.cs +++ b/Content.Server/Chemistry/ReagentEffects/MovespeedModifier.cs @@ -1,6 +1,6 @@ using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Reagent; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Robust.Shared.Timing; namespace Content.Server.Chemistry.ReagentEffects diff --git a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs index eedea8fa55..e50e903ffb 100644 --- a/Content.Server/Disposal/Tube/DisposalTubeSystem.cs +++ b/Content.Server/Disposal/Tube/DisposalTubeSystem.cs @@ -3,6 +3,7 @@ using Content.Server.UserInterface; using Content.Server.Hands.Components; using Content.Shared.Destructible; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Verbs; using Content.Shared.Popups; using Robust.Server.GameObjects; diff --git a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs index 27024ed7a8..4e7a68d20d 100644 --- a/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs +++ b/Content.Server/Disposal/Unit/EntitySystems/DisposalUnitSystem.cs @@ -18,6 +18,7 @@ using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Item; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Throwing; using Content.Shared.Verbs; using Robust.Server.GameObjects; diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index 92b62f384d..37773a02c0 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -11,7 +11,7 @@ using Content.Shared.Examine; using Content.Shared.Follower; using Content.Shared.Ghost; using Content.Shared.MobState.Components; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Events; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Player; diff --git a/Content.Server/Magic/MagicSystem.cs b/Content.Server/Magic/MagicSystem.cs index f7974e9593..f482272829 100644 --- a/Content.Server/Magic/MagicSystem.cs +++ b/Content.Server/Magic/MagicSystem.cs @@ -16,6 +16,7 @@ using Content.Shared.Doors.Systems; using Content.Shared.Interaction.Events; using Content.Shared.Maps; using Content.Shared.Physics; +using Content.Shared.Spawners.Components; using Content.Shared.Storage; using Robust.Shared.Audio; using Robust.Shared.Map; diff --git a/Content.Server/Medical/MedicalScannerSystem.cs b/Content.Server/Medical/MedicalScannerSystem.cs index cd8c42dbda..468630c90c 100644 --- a/Content.Server/Medical/MedicalScannerSystem.cs +++ b/Content.Server/Medical/MedicalScannerSystem.cs @@ -14,6 +14,7 @@ using Content.Shared.DragDrop; using Content.Shared.Interaction; using Content.Shared.MobState.Components; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Preferences; using Content.Shared.Verbs; using Robust.Shared.Containers; diff --git a/Content.Server/Movement/Systems/JetpackSystem.cs b/Content.Server/Movement/Systems/JetpackSystem.cs new file mode 100644 index 0000000000..f7aa205113 --- /dev/null +++ b/Content.Server/Movement/Systems/JetpackSystem.cs @@ -0,0 +1,48 @@ +using Content.Server.Atmos.Components; +using Content.Server.Atmos.EntitySystems; +using Content.Server.Movement.Components; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; +using Robust.Shared.Collections; +using Robust.Shared.GameStates; + +namespace Content.Server.Movement.Systems; + +public sealed class JetpackSystem : SharedJetpackSystem +{ + private const float UpdateCooldown = 0.5f; + + protected override bool CanEnable(JetpackComponent component) + { + return TryComp(component.Owner, out var gasTank) && !(gasTank.Air.Pressure < component.VolumeUsage); + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var toDisable = new ValueList(); + + foreach (var (active, comp, gasTank) in EntityQuery()) + { + active.Accumulator += frameTime; + if (active.Accumulator < UpdateCooldown) continue; + + active.Accumulator -= UpdateCooldown; + + if (gasTank.Air.Pressure < comp.VolumeUsage) + { + toDisable.Add(comp); + continue; + } + + gasTank.RemoveAirVolume(comp.VolumeUsage); + gasTank.UpdateUserInterface(); + } + + foreach (var comp in toDisable) + { + SetEnabled(comp, false); + } + } +} diff --git a/Content.Server/Nutrition/Components/HungerComponent.cs b/Content.Server/Nutrition/Components/HungerComponent.cs index daa85433c6..f52c28b203 100644 --- a/Content.Server/Nutrition/Components/HungerComponent.cs +++ b/Content.Server/Nutrition/Components/HungerComponent.cs @@ -4,7 +4,7 @@ using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.MobState.Components; using Content.Shared.Movement.Components; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Content.Shared.Nutrition.Components; using Robust.Shared.Random; diff --git a/Content.Server/Nutrition/EntitySystems/ThirstSystem.cs b/Content.Server/Nutrition/EntitySystems/ThirstSystem.cs index cfbcf9d72f..f31ccc4446 100644 --- a/Content.Server/Nutrition/EntitySystems/ThirstSystem.cs +++ b/Content.Server/Nutrition/EntitySystems/ThirstSystem.cs @@ -1,6 +1,5 @@ using Content.Server.Nutrition.Components; using JetBrains.Annotations; -using Content.Shared.Movement.EntitySystems; using Robust.Shared.Random; using Content.Shared.MobState.Components; using Content.Shared.Movement.Components; @@ -8,6 +7,7 @@ using Content.Shared.Alert; using Content.Server.Administration.Logs; using Content.Shared.Database; using Content.Shared.Damage; +using Content.Shared.Movement.Systems; namespace Content.Server.Nutrition.EntitySystems { diff --git a/Content.Server/Physics/Controllers/MoverController.cs b/Content.Server/Physics/Controllers/MoverController.cs index a0d99f2c52..4f230f9a23 100644 --- a/Content.Server/Physics/Controllers/MoverController.cs +++ b/Content.Server/Physics/Controllers/MoverController.cs @@ -4,6 +4,7 @@ using Content.Server.Shuttles.Systems; using Content.Shared.Vehicle.Components; using Content.Shared.Movement; using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; using Content.Shared.Shuttles.Components; using Robust.Shared.Map; using Robust.Shared.Player; diff --git a/Content.Server/Resist/EscapeInventorySystem.cs b/Content.Server/Resist/EscapeInventorySystem.cs index aa8dbaab9e..6fc67a3dab 100644 --- a/Content.Server/Resist/EscapeInventorySystem.cs +++ b/Content.Server/Resist/EscapeInventorySystem.cs @@ -2,12 +2,12 @@ using Content.Shared.Movement; using Content.Server.DoAfter; using Robust.Shared.Containers; using Content.Server.Popups; -using Content.Shared.Movement.EntitySystems; using Robust.Shared.Player; using Content.Shared.Storage; using Content.Shared.Inventory; using Content.Shared.Hands.Components; using Content.Shared.ActionBlocker; +using Content.Shared.Movement.Events; namespace Content.Server.Resist; diff --git a/Content.Server/Resist/ResistLockerSystem.cs b/Content.Server/Resist/ResistLockerSystem.cs index 3d65d91c12..8506d3c3a3 100644 --- a/Content.Server/Resist/ResistLockerSystem.cs +++ b/Content.Server/Resist/ResistLockerSystem.cs @@ -5,6 +5,7 @@ using Content.Server.Lock; using Robust.Shared.Player; using Robust.Shared.Containers; using Content.Server.Popups; +using Content.Shared.Movement.Events; namespace Content.Server.Resist; diff --git a/Content.Server/Spawners/EntitySystems/TimedDespawnSystem.cs b/Content.Server/Spawners/EntitySystems/TimedDespawnSystem.cs index 172d57b436..66b3742e04 100644 --- a/Content.Server/Spawners/EntitySystems/TimedDespawnSystem.cs +++ b/Content.Server/Spawners/EntitySystems/TimedDespawnSystem.cs @@ -1,19 +1,11 @@ -using Content.Server.Spawners.Components; +using Content.Shared.Spawners.EntitySystems; namespace Content.Server.Spawners.EntitySystems; -public sealed class TimedDespawnSystem : EntitySystem +public sealed class TimedDespawnSystem : SharedTimedDespawnSystem { - public override void Update(float frameTime) + protected override bool CanDelete(EntityUid uid) { - base.Update(frameTime); - - foreach (var entity in EntityQuery()) - { - entity.Lifetime -= frameTime; - - if (entity.Lifetime <= 0) - EntityManager.QueueDeleteEntity(entity.Owner); - } + return true; } } diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs index 38da912647..95cae59875 100644 --- a/Content.Server/Storage/EntitySystems/StorageSystem.cs +++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs @@ -28,6 +28,7 @@ using Content.Server.Popups; using Content.Shared.Destructible; using static Content.Shared.Storage.SharedStorageComponent; using Content.Shared.ActionBlocker; +using Content.Shared.Movement.Events; namespace Content.Server.Storage.EntitySystems { diff --git a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs index dc4d21dc08..4d3ff2619e 100644 --- a/Content.Shared/ActionBlocker/ActionBlockerSystem.cs +++ b/Content.Shared/ActionBlocker/ActionBlockerSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Item; using Content.Shared.Movement; using Content.Shared.Movement.Components; +using Content.Shared.Movement.Events; using Content.Shared.Speech; using Content.Shared.Throwing; using JetBrains.Annotations; diff --git a/Content.Shared/Administration/AdminFrozenSystem.cs b/Content.Shared/Administration/AdminFrozenSystem.cs index cb443aabf0..184b81affa 100644 --- a/Content.Shared/Administration/AdminFrozenSystem.cs +++ b/Content.Shared/Administration/AdminFrozenSystem.cs @@ -2,6 +2,7 @@ using Content.Shared.ActionBlocker; using Content.Shared.Interaction.Events; using Content.Shared.Item; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Physics.Pull; using Content.Shared.Pulling; using Content.Shared.Pulling.Components; diff --git a/Content.Shared/Buckle/SharedBuckleSystem.cs b/Content.Shared/Buckle/SharedBuckleSystem.cs index 6a9ad32114..7adaac5b09 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Buckle.Components; using Content.Shared.Interaction.Events; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Standing; using Content.Shared.Throwing; using Robust.Shared.Physics.Dynamics; diff --git a/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs b/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs index 462a6c0d16..00746ef99d 100644 --- a/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs +++ b/Content.Shared/Chemistry/MetabolismMovespeedModifierSystem.cs @@ -2,7 +2,7 @@ using Content.Shared.Chemistry.Components; using Robust.Shared.GameStates; using Robust.Shared.Timing; using Content.Shared.Movement.Components; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using static Content.Shared.Chemistry.Components.MovespeedModifierMetabolismComponent; namespace Content.Shared.Chemistry diff --git a/Content.Shared/Climbing/SharedClimbSystem.cs b/Content.Shared/Climbing/SharedClimbSystem.cs index a230642cbe..53e20541f9 100644 --- a/Content.Shared/Climbing/SharedClimbSystem.cs +++ b/Content.Shared/Climbing/SharedClimbSystem.cs @@ -1,5 +1,6 @@ using Content.Shared.DragDrop; using Content.Shared.Movement; +using Content.Shared.Movement.Events; namespace Content.Shared.Climbing; diff --git a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs index ee759cc96d..1da05a3970 100644 --- a/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs +++ b/Content.Shared/Clothing/ClothingSpeedModifierSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Robust.Shared.Containers; using Robust.Shared.GameStates; diff --git a/Content.Shared/Cuffs/SharedCuffableSystem.cs b/Content.Shared/Cuffs/SharedCuffableSystem.cs index 895ba9b831..da28608950 100644 --- a/Content.Shared/Cuffs/SharedCuffableSystem.cs +++ b/Content.Shared/Cuffs/SharedCuffableSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Interaction.Events; using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Physics.Pull; using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Events; diff --git a/Content.Shared/Damage/Systems/SlowOnDamageSystem.cs b/Content.Shared/Damage/Systems/SlowOnDamageSystem.cs index 0d6222b194..833883c144 100644 --- a/Content.Shared/Damage/Systems/SlowOnDamageSystem.cs +++ b/Content.Shared/Damage/Systems/SlowOnDamageSystem.cs @@ -1,6 +1,6 @@ using Content.Shared.Damage.Components; using Content.Shared.FixedPoint; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; namespace Content.Shared.Damage { diff --git a/Content.Shared/Follower/FollowerSystem.cs b/Content.Shared/Follower/FollowerSystem.cs index 42537d6e47..32ca86ce7c 100644 --- a/Content.Shared/Follower/FollowerSystem.cs +++ b/Content.Shared/Follower/FollowerSystem.cs @@ -1,7 +1,7 @@ using Content.Shared.Database; using Content.Shared.Follower.Components; using Content.Shared.Ghost; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Events; using Content.Shared.Verbs; namespace Content.Shared.Follower; diff --git a/Content.Shared/Friction/SharedTileFrictionController.cs b/Content.Shared/Friction/SharedTileFrictionController.cs index 122df273a9..1576265260 100644 --- a/Content.Shared/Friction/SharedTileFrictionController.cs +++ b/Content.Shared/Friction/SharedTileFrictionController.cs @@ -1,6 +1,7 @@ using Content.Shared.CCVar; using Content.Shared.Movement; using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; using JetBrains.Annotations; using Robust.Shared.Configuration; using Robust.Shared.GameStates; diff --git a/Content.Shared/Inventory/InventorySystem.Equip.cs b/Content.Shared/Inventory/InventorySystem.Equip.cs index c3169fc5aa..88498a3ffe 100644 --- a/Content.Shared/Inventory/InventorySystem.Equip.cs +++ b/Content.Shared/Inventory/InventorySystem.Equip.cs @@ -8,7 +8,7 @@ using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using Content.Shared.Inventory.Events; using Content.Shared.Item; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Content.Shared.Popups; using Content.Shared.Strip.Components; using Robust.Shared.Audio; diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index 6cbe1a7e6f..35d25c0610 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -1,7 +1,7 @@ using Content.Shared.Damage; using Content.Shared.Electrocution; using Content.Shared.Explosion; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Content.Shared.Slippery; namespace Content.Shared.Inventory; diff --git a/Content.Shared/MobState/EntitySystems/MobStateSystem.cs b/Content.Shared/MobState/EntitySystems/MobStateSystem.cs index 3884e2b8cf..0fdfbf905d 100644 --- a/Content.Shared/MobState/EntitySystems/MobStateSystem.cs +++ b/Content.Shared/MobState/EntitySystems/MobStateSystem.cs @@ -8,6 +8,7 @@ using Content.Shared.Item; using Content.Shared.MobState.Components; using Content.Shared.MobState.State; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Pulling.Events; using Content.Shared.Speech; using Content.Shared.Standing; diff --git a/Content.Shared/Movement/Components/ActiveJetpackComponent.cs b/Content.Shared/Movement/Components/ActiveJetpackComponent.cs new file mode 100644 index 0000000000..b3318e23a0 --- /dev/null +++ b/Content.Shared/Movement/Components/ActiveJetpackComponent.cs @@ -0,0 +1,13 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Movement.Components; + +/// +/// Added to an enabled jetpack. Tracks gas usage on server / effect spawning on client. +/// +[RegisterComponent, NetworkedComponent] +public sealed class ActiveJetpackComponent : Component +{ + public float EffectCooldown = 0.3f; + public float Accumulator = 0f; +} diff --git a/Content.Shared/Movement/Components/JetpackComponent.cs b/Content.Shared/Movement/Components/JetpackComponent.cs new file mode 100644 index 0000000000..7ea8dc16cf --- /dev/null +++ b/Content.Shared/Movement/Components/JetpackComponent.cs @@ -0,0 +1,24 @@ +using Content.Shared.Actions.ActionTypes; +using Content.Shared.Atmos; +using Robust.Shared.GameStates; + +namespace Content.Shared.Movement.Components; + +[RegisterComponent, NetworkedComponent] +public sealed class JetpackComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField("volumeUsage")] + public float VolumeUsage = Atmospherics.BreathVolume; + + [ViewVariables, DataField("toggleAction", required: true)] + public InstantAction ToggleAction = new(); + + [ViewVariables(VVAccess.ReadWrite), DataField("acceleration")] + public float Acceleration = 1f; + + [ViewVariables(VVAccess.ReadWrite), DataField("friction")] + public float Friction = 0.3f; + + [ViewVariables(VVAccess.ReadWrite), DataField("weightlessModifier")] + public float WeightlessModifier = 1.2f; +} diff --git a/Content.Shared/Movement/Components/JetpackUserComponent.cs b/Content.Shared/Movement/Components/JetpackUserComponent.cs new file mode 100644 index 0000000000..05d99cf660 --- /dev/null +++ b/Content.Shared/Movement/Components/JetpackUserComponent.cs @@ -0,0 +1,14 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Movement.Components; + +/// +/// Added to someone using a jetpack for movement purposes +/// +[RegisterComponent, NetworkedComponent] +public sealed class JetpackUserComponent : Component +{ + public float Acceleration = 1f; + public float Friction = 0.3f; + public float WeightlessModifier = 1.2f; +} diff --git a/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs b/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs index 0a43d1045a..7a6990e598 100644 --- a/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs +++ b/Content.Shared/Movement/Components/MovementSpeedModifierComponent.cs @@ -1,4 +1,4 @@ -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Robust.Shared.GameStates; namespace Content.Shared.Movement.Components diff --git a/Content.Shared/Movement/EntitySystems/SharedMobMoverSystem.cs b/Content.Shared/Movement/EntitySystems/SharedMobMoverSystem.cs deleted file mode 100644 index c0cccf795c..0000000000 --- a/Content.Shared/Movement/EntitySystems/SharedMobMoverSystem.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Content.Shared.CCVar; -using Content.Shared.Movement.Components; -using Robust.Shared.Configuration; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Dynamics; - -namespace Content.Shared.Movement.EntitySystems -{ - public sealed class SharedMobMoverSystem : EntitySystem - { - private bool _pushingEnabled; - - public override void Initialize() - { - base.Initialize(); - Get().KinematicControllerCollision += OnMobCollision; - IoCManager.Resolve().OnValueChanged(CCVars.MobPushing, SetPushing, true); - } - - private void SetPushing(bool value) - { - _pushingEnabled = value; - } - - public override void Shutdown() - { - base.Shutdown(); - IoCManager.Resolve().UnsubValueChanged(CCVars.MobPushing, SetPushing); - Get().KinematicControllerCollision -= OnMobCollision; - } - - /// - /// Fake pushing for player collisions. - /// - private void OnMobCollision(Fixture ourFixture, Fixture otherFixture, float frameTime, Vector2 worldNormal) - { - if (!_pushingEnabled) return; - - var otherBody = otherFixture.Body; - - if (otherBody.BodyType != BodyType.Dynamic || !otherFixture.Hard) return; - - if (!EntityManager.TryGetComponent(ourFixture.Body.Owner, out IMobMoverComponent? mobMover) || worldNormal == Vector2.Zero) return; - - otherBody.ApplyLinearImpulse(-worldNormal * mobMover.PushStrength * frameTime); - } - } -} diff --git a/Content.Shared/Movement/Events/RelayMoveInputEvent.cs b/Content.Shared/Movement/Events/RelayMoveInputEvent.cs new file mode 100644 index 0000000000..7f4f08fe31 --- /dev/null +++ b/Content.Shared/Movement/Events/RelayMoveInputEvent.cs @@ -0,0 +1,13 @@ +using Robust.Shared.Players; + +namespace Content.Shared.Movement.Events; + +public sealed class RelayMoveInputEvent : EntityEventArgs +{ + public ICommonSession Session { get; } + + public RelayMoveInputEvent(ICommonSession session) + { + Session = session; + } +} \ No newline at end of file diff --git a/Content.Shared/Movement/RelayMovementEntityEvent.cs b/Content.Shared/Movement/Events/RelayMovementEntityEvent.cs similarity index 84% rename from Content.Shared/Movement/RelayMovementEntityEvent.cs rename to Content.Shared/Movement/Events/RelayMovementEntityEvent.cs index 226aee739e..2208cdda97 100644 --- a/Content.Shared/Movement/RelayMovementEntityEvent.cs +++ b/Content.Shared/Movement/Events/RelayMovementEntityEvent.cs @@ -1,4 +1,4 @@ -namespace Content.Shared.Movement +namespace Content.Shared.Movement.Events { public sealed class RelayMovementEntityEvent : EntityEventArgs { diff --git a/Content.Shared/Movement/Events/ToggleJetpackEvent.cs b/Content.Shared/Movement/Events/ToggleJetpackEvent.cs new file mode 100644 index 0000000000..d344c7a9c3 --- /dev/null +++ b/Content.Shared/Movement/Events/ToggleJetpackEvent.cs @@ -0,0 +1,8 @@ +using Content.Shared.Actions; + +namespace Content.Shared.Movement.Events; + +/// +/// Raised on a jetpack whenever it is toggled. +/// +public sealed class ToggleJetpackEvent : InstantActionEvent {} diff --git a/Content.Shared/Movement/UpdateCanMoveEvent.cs b/Content.Shared/Movement/Events/UpdateCanMoveEvent.cs similarity index 90% rename from Content.Shared/Movement/UpdateCanMoveEvent.cs rename to Content.Shared/Movement/Events/UpdateCanMoveEvent.cs index a7509f1d78..d9772c1cf4 100644 --- a/Content.Shared/Movement/UpdateCanMoveEvent.cs +++ b/Content.Shared/Movement/Events/UpdateCanMoveEvent.cs @@ -1,6 +1,6 @@ using Content.Shared.Movement.Components; -namespace Content.Shared.Movement; +namespace Content.Shared.Movement.Events; /// /// Raised whenever needs to be updated. Cancel this event to prevent a diff --git a/Content.Shared/Movement/Events/WeightlessMoveEvent.cs b/Content.Shared/Movement/Events/WeightlessMoveEvent.cs new file mode 100644 index 0000000000..73eac0d306 --- /dev/null +++ b/Content.Shared/Movement/Events/WeightlessMoveEvent.cs @@ -0,0 +1,14 @@ +namespace Content.Shared.Movement.Events; + +/// +/// Raised on an entity to check if it can move while weightless. +/// +[ByRefEvent] +public struct CanWeightlessMoveEvent +{ + public bool CanMove = false; + + public CanWeightlessMoveEvent() + { + } +} diff --git a/Content.Shared/Movement/MobMovementProfileEvent.cs b/Content.Shared/Movement/MobMovementProfileEvent.cs new file mode 100644 index 0000000000..ffc928327e --- /dev/null +++ b/Content.Shared/Movement/MobMovementProfileEvent.cs @@ -0,0 +1,35 @@ +namespace Content.Shared.Movement; + +/// +/// Contains all of the relevant data for mob movement. +/// Raised on a mob if something wants to overwrite its movement characteristics. +/// +[ByRefEvent] +public struct MobMovementProfileEvent +{ + /// + /// Should we use this profile instead of the entity's default? + /// + public bool Override = false; + + public readonly bool Touching; + public readonly bool Weightless; + + public float Friction; + public float WeightlessModifier; + public float Acceleration; + + public MobMovementProfileEvent( + bool touching, + bool weightless, + float friction, + float weightlessModifier, + float acceleration) + { + Touching = touching; + Weightless = weightless; + Friction = friction; + WeightlessModifier = weightlessModifier; + Acceleration = acceleration; + } +} diff --git a/Content.Shared/Movement/EntitySystems/MovementIgnoreGravitySystem.cs b/Content.Shared/Movement/Systems/MovementIgnoreGravitySystem.cs similarity index 86% rename from Content.Shared/Movement/EntitySystems/MovementIgnoreGravitySystem.cs rename to Content.Shared/Movement/Systems/MovementIgnoreGravitySystem.cs index 4ecae7ca24..4ea0e08b97 100644 --- a/Content.Shared/Movement/EntitySystems/MovementIgnoreGravitySystem.cs +++ b/Content.Shared/Movement/Systems/MovementIgnoreGravitySystem.cs @@ -1,8 +1,7 @@ -using Content.Shared.Alert; -using Content.Shared.Movement.Components; +using Content.Shared.Movement.Components; using Robust.Shared.GameStates; -namespace Content.Shared.Movement.EntitySystems; +namespace Content.Shared.Movement.Systems; public sealed class MovementIgnoreGravitySystem : EntitySystem { diff --git a/Content.Shared/Movement/EntitySystems/MovementSpeedModifierSystem.cs b/Content.Shared/Movement/Systems/MovementSpeedModifierSystem.cs similarity index 80% rename from Content.Shared/Movement/EntitySystems/MovementSpeedModifierSystem.cs rename to Content.Shared/Movement/Systems/MovementSpeedModifierSystem.cs index 61413582eb..e6c14faf35 100644 --- a/Content.Shared/Movement/EntitySystems/MovementSpeedModifierSystem.cs +++ b/Content.Shared/Movement/Systems/MovementSpeedModifierSystem.cs @@ -3,26 +3,13 @@ using Content.Shared.Movement.Components; using Robust.Shared.GameStates; using Robust.Shared.Serialization; -namespace Content.Shared.Movement.EntitySystems +namespace Content.Shared.Movement.Systems { public sealed class MovementSpeedModifierSystem : EntitySystem { - private readonly HashSet _needsRefresh = new(); - - public override void Update(float frameTime) - { - foreach (var uid in _needsRefresh) - { - RecalculateMovementSpeedModifiers(uid); - } - - _needsRefresh.Clear(); - } - public override void Initialize() { base.Initialize(); - UpdatesOutsidePrediction = true; SubscribeLocalEvent(OnGetState); SubscribeLocalEvent(OnHandleState); } @@ -47,23 +34,18 @@ namespace Content.Shared.Movement.EntitySystems component.SprintSpeedModifier = state.SprintSpeedModifier; } - public void RefreshMovementSpeedModifiers(EntityUid uid) - { - _needsRefresh.Add(uid); - } - - private void RecalculateMovementSpeedModifiers(EntityUid uid, MovementSpeedModifierComponent? move = null) + public void RefreshMovementSpeedModifiers(EntityUid uid, MovementSpeedModifierComponent? move = null) { if (!Resolve(uid, ref move, false)) return; var ev = new RefreshMovementSpeedModifiersEvent(); - RaiseLocalEvent(uid, ev, false); + RaiseLocalEvent(uid, ev); move.WalkSpeedModifier = ev.WalkSpeedModifier; move.SprintSpeedModifier = ev.SprintSpeedModifier; - move.Dirty(); + Dirty(move); } [Serializable, NetSerializable] diff --git a/Content.Shared/Movement/Systems/SharedJetpackSystem.cs b/Content.Shared/Movement/Systems/SharedJetpackSystem.cs new file mode 100644 index 0000000000..3a871c88c0 --- /dev/null +++ b/Content.Shared/Movement/Systems/SharedJetpackSystem.cs @@ -0,0 +1,124 @@ +using Content.Shared.Actions; +using Content.Shared.Interaction.Events; +using Content.Shared.Inventory; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Events; +using Robust.Shared.Containers; +using Robust.Shared.Serialization; + +namespace Content.Shared.Movement.Systems; + +public abstract class SharedJetpackSystem : EntitySystem +{ + [Dependency] protected readonly SharedContainerSystem Container = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnJetpackGetAction); + SubscribeLocalEvent(OnJetpackDropped); + SubscribeLocalEvent(OnJetpackToggle); + SubscribeLocalEvent(OnJetpackUserCanWeightless); + SubscribeLocalEvent(OnJetpackUserMovement); + } + + private void OnJetpackDropped(EntityUid uid, JetpackComponent component, DroppedEvent args) + { + SetEnabled(component, false, args.User); + } + + private void OnJetpackUserMovement(EntityUid uid, JetpackUserComponent component, ref MobMovementProfileEvent args) + { + // Only overwrite jetpack movement if they're offgrid. + if (args.Override || !args.Weightless) return; + + args.Override = true; + args.Acceleration = component.Acceleration; + args.WeightlessModifier = component.WeightlessModifier; + args.Friction = component.Friction; + } + + private void OnJetpackUserCanWeightless(EntityUid uid, JetpackUserComponent component, ref CanWeightlessMoveEvent args) + { + args.CanMove = true; + } + + private void SetupUser(EntityUid uid, JetpackComponent component) + { + var user = EnsureComp(uid); + user.Acceleration = component.Acceleration; + user.Friction = component.Friction; + user.WeightlessModifier = component.WeightlessModifier; + } + + private void OnJetpackToggle(EntityUid uid, JetpackComponent component, ToggleJetpackEvent args) + { + if (args.Handled) return; + + SetEnabled(component, !IsEnabled(uid)); + } + + private void OnJetpackGetAction(EntityUid uid, JetpackComponent component, GetItemActionsEvent args) + { + args.Actions.Add(component.ToggleAction); + } + + private bool IsEnabled(EntityUid uid) + { + return HasComp(uid); + } + + public void SetEnabled(JetpackComponent component, bool enabled, EntityUid? user = null) + { + if (IsEnabled(component.Owner) == enabled || + enabled && !CanEnable(component)) return; + + if (enabled) + { + EnsureComp(component.Owner); + } + else + { + RemComp(component.Owner); + } + + if (user == null) + { + Container.TryGetContainingContainer(component.Owner, out var container); + user = container?.Owner; + } + + // Can't activate if no one's using. + if (user == null && enabled) return; + + if (user != null) + { + if (enabled) + { + SetupUser(user.Value, component); + } + else + { + RemComp(user.Value); + } + } + + TryComp(component.Owner, out var appearance); + appearance?.SetData(JetpackVisuals.Enabled, enabled); + Dirty(component); + } + + protected abstract bool CanEnable(JetpackComponent component); + + [Serializable, NetSerializable] + protected sealed class JetpackComponentState : ComponentState + { + public bool Enabled; + } +} + +[Serializable, NetSerializable] +public enum JetpackVisuals : byte +{ + Enabled, +} diff --git a/Content.Shared/Movement/EntitySystems/SharedMoverSystem.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs similarity index 59% rename from Content.Shared/Movement/EntitySystems/SharedMoverSystem.cs rename to Content.Shared/Movement/Systems/SharedMoverController.Input.cs index 88926bab17..b84a295682 100644 --- a/Content.Shared/Movement/EntitySystems/SharedMoverSystem.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -1,47 +1,43 @@ -using System.Diagnostics.CodeAnalysis; using Content.Shared.MobState.Components; using Content.Shared.Movement.Components; +using Content.Shared.Movement.Events; using Content.Shared.Vehicle.Components; using Robust.Shared.Containers; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Players; -namespace Content.Shared.Movement.EntitySystems +namespace Content.Shared.Movement.Systems { /// /// Handles converting inputs into movement. /// - public sealed class SharedMoverSystem : EntitySystem + public abstract partial class SharedMoverController { - public override void Initialize() + private void InitializeInput() { - base.Initialize(); - - var moveUpCmdHandler = new MoverDirInputCmdHandler(Direction.North); - var moveLeftCmdHandler = new MoverDirInputCmdHandler(Direction.West); - var moveRightCmdHandler = new MoverDirInputCmdHandler(Direction.East); - var moveDownCmdHandler = new MoverDirInputCmdHandler(Direction.South); + var moveUpCmdHandler = new MoverDirInputCmdHandler(this, Direction.North); + var moveLeftCmdHandler = new MoverDirInputCmdHandler(this, Direction.West); + var moveRightCmdHandler = new MoverDirInputCmdHandler(this, Direction.East); + var moveDownCmdHandler = new MoverDirInputCmdHandler(this, Direction.South); CommandBinds.Builder .Bind(EngineKeyFunctions.MoveUp, moveUpCmdHandler) .Bind(EngineKeyFunctions.MoveLeft, moveLeftCmdHandler) .Bind(EngineKeyFunctions.MoveRight, moveRightCmdHandler) .Bind(EngineKeyFunctions.MoveDown, moveDownCmdHandler) - .Bind(EngineKeyFunctions.Walk, new WalkInputCmdHandler()) - .Register(); + .Bind(EngineKeyFunctions.Walk, new WalkInputCmdHandler(this)) + .Register(); } - /// - public override void Shutdown() + private void ShutdownInput() { - CommandBinds.Unregister(); - base.Shutdown(); + CommandBinds.Unregister(); } private void HandleDirChange(ICommonSession? session, Direction dir, ushort subTick, bool state) { - if (!TryGetAttachedComponent(session, out var moverComp)) + if (!TryComp(session?.AttachedEntity, out var moverComp)) return; var owner = session?.AttachedEntity; @@ -71,9 +67,9 @@ namespace Content.Shared.Movement.EntitySystems moverComp.SetVelocityDirection(dir, subTick, state); } - private static void HandleRunChange(ICommonSession? session, ushort subTick, bool walking) + private void HandleRunChange(ICommonSession? session, ushort subTick, bool walking) { - if (!TryGetAttachedComponent(session, out var moverComp)) + if (!TryComp(session?.AttachedEntity, out var moverComp)) { return; } @@ -81,68 +77,42 @@ namespace Content.Shared.Movement.EntitySystems moverComp.SetSprinting(subTick, walking); } - private static bool TryGetAttachedComponent(ICommonSession? session, [NotNullWhen(true)] out T? component) - where T : class, IComponent - { - component = default; - - var ent = session?.AttachedEntity; - - var entMan = IoCManager.Resolve(); - - if (ent == null || !entMan.EntityExists(ent.Value)) - return false; - - if (!entMan.TryGetComponent(ent.Value, out T? comp)) - return false; - - component = comp; - return true; - } - private sealed class MoverDirInputCmdHandler : InputCmdHandler { + private SharedMoverController _controller; private readonly Direction _dir; - public MoverDirInputCmdHandler(Direction dir) + public MoverDirInputCmdHandler(SharedMoverController controller, Direction dir) { + _controller = controller; _dir = dir; } public override bool HandleCmdMessage(ICommonSession? session, InputCmdMessage message) { - if (message is not FullInputCmdMessage full) - { - return false; - } + if (message is not FullInputCmdMessage full) return false; - Get().HandleDirChange(session, _dir, message.SubTick, full.State == BoundKeyState.Down); + _controller.HandleDirChange(session, _dir, message.SubTick, full.State == BoundKeyState.Down); return false; } } private sealed class WalkInputCmdHandler : InputCmdHandler { + private SharedMoverController _controller; + + public WalkInputCmdHandler(SharedMoverController controller) + { + _controller = controller; + } + public override bool HandleCmdMessage(ICommonSession? session, InputCmdMessage message) { - if (message is not FullInputCmdMessage full) - { - return false; - } + if (message is not FullInputCmdMessage full) return false; - HandleRunChange(session, full.SubTick, full.State == BoundKeyState.Down); + _controller.HandleRunChange(session, full.SubTick, full.State == BoundKeyState.Down); return false; } } } - - public sealed class RelayMoveInputEvent : EntityEventArgs - { - public ICommonSession Session { get; } - - public RelayMoveInputEvent(ICommonSession session) - { - Session = session; - } - } } diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Pushing.cs b/Content.Shared/Movement/Systems/SharedMoverController.Pushing.cs new file mode 100644 index 0000000000..02e45725a4 --- /dev/null +++ b/Content.Shared/Movement/Systems/SharedMoverController.Pushing.cs @@ -0,0 +1,56 @@ +using Content.Shared.CCVar; +using Content.Shared.Movement.Components; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Dynamics; + +namespace Content.Shared.Movement.Systems; + +public abstract partial class SharedMoverController +{ + private bool _pushingEnabled; + + private void InitializePushing() + { + _configManager.OnValueChanged(CCVars.MobPushing, SetPushing, true); + } + + private void SetPushing(bool value) + { + if (_pushingEnabled == value) return; + + _pushingEnabled = value; + + if (_pushingEnabled) + { + _physics.KinematicControllerCollision += OnMobCollision; + } + else + { + _physics.KinematicControllerCollision -= OnMobCollision; + } + } + + private void ShutdownPushing() + { + if (_pushingEnabled) + _physics.KinematicControllerCollision -= OnMobCollision; + + _configManager.UnsubValueChanged(CCVars.MobPushing, SetPushing); + } + + /// + /// Fake pushing for player collisions. + /// + private void OnMobCollision(Fixture ourFixture, Fixture otherFixture, float frameTime, Vector2 worldNormal) + { + if (!_pushingEnabled) return; + + var otherBody = otherFixture.Body; + + if (otherBody.BodyType != BodyType.Dynamic || !otherFixture.Hard) return; + + if (!EntityManager.TryGetComponent(ourFixture.Body.Owner, out IMobMoverComponent? mobMover) || worldNormal == Vector2.Zero) return; + + otherBody.ApplyLinearImpulse(-worldNormal * mobMover.PushStrength * frameTime); + } +} diff --git a/Content.Shared/Movement/SharedMoverController.cs b/Content.Shared/Movement/Systems/SharedMoverController.cs similarity index 82% rename from Content.Shared/Movement/SharedMoverController.cs rename to Content.Shared/Movement/Systems/SharedMoverController.cs index 8139d34ff6..ae94221d93 100644 --- a/Content.Shared/Movement/SharedMoverController.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.cs @@ -6,6 +6,7 @@ using Content.Shared.Inventory; using Content.Shared.Maps; using Content.Shared.MobState.Components; using Content.Shared.Movement.Components; +using Content.Shared.Movement.Events; using Content.Shared.Pulling.Components; using Content.Shared.Tag; using Robust.Shared.Audio; @@ -16,14 +17,15 @@ using Robust.Shared.Physics.Controllers; using Robust.Shared.Player; using Robust.Shared.Utility; -namespace Content.Shared.Movement +namespace Content.Shared.Movement.Systems { /// /// Handles player and NPC mob movement. /// NPCs are handled server-side only. /// - public abstract class SharedMoverController : VirtualController + public abstract partial class SharedMoverController : VirtualController { + [Dependency] private readonly IConfigurationManager _configManager = default!; [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly InventorySystem _inventory = default!; @@ -86,17 +88,18 @@ namespace Content.Shared.Movement public override void Initialize() { base.Initialize(); - var configManager = IoCManager.Resolve(); + InitializeInput(); + InitializePushing(); // Hello - configManager.OnValueChanged(CCVars.RelativeMovement, SetRelativeMovement, true); - configManager.OnValueChanged(CCVars.MinimumFrictionSpeed, SetMinimumFrictionSpeed, true); - configManager.OnValueChanged(CCVars.MobFriction, SetFrictionVelocity, true); - configManager.OnValueChanged(CCVars.MobWeightlessFriction, SetWeightlessFrictionVelocity, true); - configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true); - configManager.OnValueChanged(CCVars.MobAcceleration, SetMobAcceleration, true); - configManager.OnValueChanged(CCVars.MobWeightlessAcceleration, SetMobWeightlessAcceleration, true); - configManager.OnValueChanged(CCVars.MobWeightlessFrictionNoInput, SetWeightlessFrictionNoInput, true); - configManager.OnValueChanged(CCVars.MobWeightlessModifier, SetMobWeightlessModifier, true); + _configManager.OnValueChanged(CCVars.RelativeMovement, SetRelativeMovement, true); + _configManager.OnValueChanged(CCVars.MinimumFrictionSpeed, SetMinimumFrictionSpeed, true); + _configManager.OnValueChanged(CCVars.MobFriction, SetFrictionVelocity, true); + _configManager.OnValueChanged(CCVars.MobWeightlessFriction, SetWeightlessFrictionVelocity, true); + _configManager.OnValueChanged(CCVars.StopSpeed, SetStopSpeed, true); + _configManager.OnValueChanged(CCVars.MobAcceleration, SetMobAcceleration, true); + _configManager.OnValueChanged(CCVars.MobWeightlessAcceleration, SetMobWeightlessAcceleration, true); + _configManager.OnValueChanged(CCVars.MobWeightlessFrictionNoInput, SetWeightlessFrictionNoInput, true); + _configManager.OnValueChanged(CCVars.MobWeightlessModifier, SetMobWeightlessModifier, true); UpdatesBefore.Add(typeof(SharedTileFrictionController)); } @@ -113,16 +116,17 @@ namespace Content.Shared.Movement public override void Shutdown() { base.Shutdown(); - var configManager = IoCManager.Resolve(); - configManager.UnsubValueChanged(CCVars.RelativeMovement, SetRelativeMovement); - configManager.UnsubValueChanged(CCVars.MinimumFrictionSpeed, SetMinimumFrictionSpeed); - configManager.UnsubValueChanged(CCVars.StopSpeed, SetStopSpeed); - configManager.UnsubValueChanged(CCVars.MobFriction, SetFrictionVelocity); - configManager.UnsubValueChanged(CCVars.MobWeightlessFriction, SetWeightlessFrictionVelocity); - configManager.UnsubValueChanged(CCVars.MobAcceleration, SetMobAcceleration); - configManager.UnsubValueChanged(CCVars.MobWeightlessAcceleration, SetMobWeightlessAcceleration); - configManager.UnsubValueChanged(CCVars.MobWeightlessFrictionNoInput, SetWeightlessFrictionNoInput); - configManager.UnsubValueChanged(CCVars.MobWeightlessModifier, SetMobWeightlessModifier); + ShutdownInput(); + ShutdownPushing(); + _configManager.UnsubValueChanged(CCVars.RelativeMovement, SetRelativeMovement); + _configManager.UnsubValueChanged(CCVars.MinimumFrictionSpeed, SetMinimumFrictionSpeed); + _configManager.UnsubValueChanged(CCVars.StopSpeed, SetStopSpeed); + _configManager.UnsubValueChanged(CCVars.MobFriction, SetFrictionVelocity); + _configManager.UnsubValueChanged(CCVars.MobWeightlessFriction, SetWeightlessFrictionVelocity); + _configManager.UnsubValueChanged(CCVars.MobAcceleration, SetMobAcceleration); + _configManager.UnsubValueChanged(CCVars.MobWeightlessAcceleration, SetMobWeightlessAcceleration); + _configManager.UnsubValueChanged(CCVars.MobWeightlessFrictionNoInput, SetWeightlessFrictionNoInput); + _configManager.UnsubValueChanged(CCVars.MobWeightlessModifier, SetMobWeightlessModifier); } public override void UpdateAfterSolve(bool prediction, float frameTime) @@ -187,13 +191,21 @@ namespace Content.Shared.Movement UsedMobMovement[mover.Owner] = true; var weightless = mover.Owner.IsWeightless(physicsComponent, mapManager: _mapManager, entityManager: EntityManager); var (walkDir, sprintDir) = mover.VelocityDir; - bool touching = true; + var touching = false; // Handle wall-pushes. if (weightless) { - // No gravity: is our entity touching anything? - touching = xform.GridUid != null || IsAroundCollider(_physics, xform, mobMover, physicsComponent); + if (xform.GridUid != null) + touching = true; + + if (!touching) + { + var ev = new CanWeightlessMoveEvent(); + RaiseLocalEvent(xform.Owner, ref ev); + // No gravity: is our entity touching anything? + touching = ev.CanMove || IsAroundCollider(_physics, xform, mobMover, physicsComponent); + } if (!touching) { @@ -233,6 +245,22 @@ namespace Content.Shared.Movement accel = _mobAcceleration; } + var profile = new MobMovementProfileEvent( + touching, + weightless, + friction, + weightlessModifier, + accel); + + RaiseLocalEvent(xform.Owner, ref profile); + + if (profile.Override) + { + friction = profile.Friction; + weightlessModifier = profile.WeightlessModifier; + accel = profile.Acceleration; + } + Friction(frameTime, friction, ref velocity); if (xform.GridUid != EntityUid.Invalid) @@ -242,7 +270,7 @@ namespace Content.Shared.Movement { // This should have its event run during island solver soooo xform.DeferUpdates = true; - xform.LocalRotation = xform.GridUid != EntityUid.Invalid + xform.LocalRotation = xform.GridUid != null ? total.ToWorldAngle() : worldTotal.ToWorldAngle(); xform.DeferUpdates = false; @@ -257,7 +285,7 @@ namespace Content.Shared.Movement worldTotal *= weightlessModifier; - if (touching) + if (!weightless || touching) Accelerate(ref velocity, in worldTotal, accel, frameTime); _physics.SetLinearVelocity(physicsComponent, velocity); diff --git a/Content.Shared/Movement/EntitySystems/SlowContactsSystem.cs b/Content.Shared/Movement/Systems/SlowContactsSystem.cs similarity index 91% rename from Content.Shared/Movement/EntitySystems/SlowContactsSystem.cs rename to Content.Shared/Movement/Systems/SlowContactsSystem.cs index 12b171ae9d..fb7010a2d0 100644 --- a/Content.Shared/Movement/EntitySystems/SlowContactsSystem.cs +++ b/Content.Shared/Movement/Systems/SlowContactsSystem.cs @@ -1,7 +1,7 @@ using Content.Shared.Movement.Components; using Robust.Shared.Physics.Dynamics; -namespace Content.Shared.Movement.EntitySystems; +namespace Content.Shared.Movement.Systems; public sealed class SlowContactsSystem : EntitySystem { @@ -52,7 +52,7 @@ public sealed class SlowContactsSystem : EntitySystem Logger.ErrorS("slowscontacts", $"The entity {otherUid} left a body ({uid}) it was never in."); _statusCapableInContact[otherUid]--; if (_statusCapableInContact[otherUid] == 0) - EntityManager.RemoveComponent(otherUid); + EntityManager.RemoveComponentDeferred(otherUid); _speedModifierSystem.RefreshMovementSpeedModifiers(otherUid); } @@ -65,8 +65,8 @@ public sealed class SlowContactsSystem : EntitySystem if (!_statusCapableInContact.ContainsKey(otherUid)) _statusCapableInContact[otherUid] = 0; _statusCapableInContact[otherUid]++; - if (!EntityManager.HasComponent(otherUid)) - EntityManager.AddComponent(otherUid); + + EnsureComp(otherUid); _speedModifierSystem.RefreshMovementSpeedModifiers(otherUid); } } diff --git a/Content.Shared/Nutrition/EntitySystems/SharedHungerSystem.cs b/Content.Shared/Nutrition/EntitySystems/SharedHungerSystem.cs index c9fa348ccf..0d6c5b17d3 100644 --- a/Content.Shared/Nutrition/EntitySystems/SharedHungerSystem.cs +++ b/Content.Shared/Nutrition/EntitySystems/SharedHungerSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Content.Shared.Nutrition.Components; namespace Content.Shared.Nutrition.EntitySystems diff --git a/Content.Shared/PAI/SharedPAISystem.cs b/Content.Shared/PAI/SharedPAISystem.cs index 8884b195d9..0e25d83824 100644 --- a/Content.Shared/PAI/SharedPAISystem.cs +++ b/Content.Shared/PAI/SharedPAISystem.cs @@ -4,6 +4,7 @@ using Content.Shared.DragDrop; using Content.Shared.Interaction.Events; using Content.Shared.Item; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Robust.Shared.Serialization; namespace Content.Shared.PAI diff --git a/Content.Shared/Pulling/Systems/SharedPullableSystem.cs b/Content.Shared/Pulling/Systems/SharedPullableSystem.cs index 846b12486a..d535c21a67 100644 --- a/Content.Shared/Pulling/Systems/SharedPullableSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullableSystem.cs @@ -1,7 +1,7 @@ using Content.Shared.ActionBlocker; -using Content.Shared.Movement.EntitySystems; using Content.Shared.Pulling.Components; using Content.Shared.MobState.Components; +using Content.Shared.Movement.Events; namespace Content.Shared.Pulling.Systems { diff --git a/Content.Shared/Pulling/Systems/SharedPullerSystem.cs b/Content.Shared/Pulling/Systems/SharedPullerSystem.cs index 24d2392b0d..eb1c68baf4 100644 --- a/Content.Shared/Pulling/Systems/SharedPullerSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullerSystem.cs @@ -1,6 +1,6 @@ using Content.Shared.Alert; using Content.Shared.Hands; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Systems; using Content.Shared.Physics.Pull; using Content.Shared.Pulling.Components; using JetBrains.Annotations; diff --git a/Content.Shared/Shuttles/Systems/SharedShuttleConsoleSystem.cs b/Content.Shared/Shuttles/Systems/SharedShuttleConsoleSystem.cs index 506fa84f10..28a0cf9c7c 100644 --- a/Content.Shared/Shuttles/Systems/SharedShuttleConsoleSystem.cs +++ b/Content.Shared/Shuttles/Systems/SharedShuttleConsoleSystem.cs @@ -1,5 +1,6 @@ using Content.Shared.ActionBlocker; using Content.Shared.Movement; +using Content.Shared.Movement.Events; using Content.Shared.Shuttles.Components; using Robust.Shared.Serialization; diff --git a/Content.Server/Spawners/Components/TimedDespawnComponent.cs b/Content.Shared/Spawners/Components/TimedDespawnComponent.cs similarity index 88% rename from Content.Server/Spawners/Components/TimedDespawnComponent.cs rename to Content.Shared/Spawners/Components/TimedDespawnComponent.cs index b5f6e9568c..3eb6ca7e9a 100644 --- a/Content.Server/Spawners/Components/TimedDespawnComponent.cs +++ b/Content.Shared/Spawners/Components/TimedDespawnComponent.cs @@ -1,4 +1,4 @@ -namespace Content.Server.Spawners.Components; +namespace Content.Shared.Spawners.Components; /// /// Put this component on something you would like to despawn after a certain amount of time diff --git a/Content.Shared/Spawners/EntitySystems/SharedTimedDespawnSystem.cs b/Content.Shared/Spawners/EntitySystems/SharedTimedDespawnSystem.cs new file mode 100644 index 0000000000..3129ca0fdc --- /dev/null +++ b/Content.Shared/Spawners/EntitySystems/SharedTimedDespawnSystem.cs @@ -0,0 +1,28 @@ +using Content.Shared.Spawners.Components; +using Robust.Shared.Timing; + +namespace Content.Shared.Spawners.EntitySystems; + +public abstract class SharedTimedDespawnSystem : EntitySystem +{ + [Dependency] private readonly IGameTiming _timing = default!; + + public override void Update(float frameTime) + { + base.Update(frameTime); + + if (!_timing.IsFirstTimePredicted) return; + + foreach (var comp in EntityQuery()) + { + if (!CanDelete(comp.Owner)) continue; + + comp.Lifetime -= frameTime; + + if (comp.Lifetime <= 0) + EntityManager.QueueDeleteEntity(comp.Owner); + } + } + + protected abstract bool CanDelete(EntityUid uid); +} diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index e0c0c5bca4..9d0a3e4fb7 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -6,7 +6,8 @@ using Content.Shared.Interaction.Events; using Content.Shared.Inventory.Events; using Content.Shared.Item; using Content.Shared.Movement; -using Content.Shared.Movement.EntitySystems; +using Content.Shared.Movement.Events; +using Content.Shared.Movement.Systems; using Content.Shared.Standing; using Content.Shared.StatusEffect; using Content.Shared.Throwing; @@ -31,7 +32,7 @@ namespace Content.Shared.Stunnable SubscribeLocalEvent(OnKnockRemove); SubscribeLocalEvent(OnSlowInit); - SubscribeLocalEvent(OnSlowRemove); + SubscribeLocalEvent(OnSlowRemove); SubscribeLocalEvent(UpdateCanMove); SubscribeLocalEvent(UpdateCanMove); @@ -105,7 +106,7 @@ namespace Content.Shared.Stunnable _movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid); } - private void OnSlowRemove(EntityUid uid, SlowedDownComponent component, ComponentRemove args) + private void OnSlowRemove(EntityUid uid, SlowedDownComponent component, ComponentShutdown args) { _movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid); } diff --git a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs index e90671fd1c..343ae8850e 100644 --- a/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs +++ b/Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs @@ -384,11 +384,11 @@ public abstract partial class SharedGunSystem : EntitySystem { public List<(EntityCoordinates coordinates, Angle angle, SpriteSpecifier Sprite, float Distance)> Sprites = new(); } +} - public enum EffectLayers : byte - { - Unshaded, - } +public enum EffectLayers : byte +{ + Unshaded, } [Serializable, NetSerializable] diff --git a/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml new file mode 100644 index 0000000000..335ab35b14 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Tools/jetpacks.yml @@ -0,0 +1,235 @@ +- type: entity + id: JetpackEffect + noSpawn: true + components: + - type: TimedDespawn + lifetime: 2 + - type: Sprite + netsync: false + drawdepth: Effects + noRot: true + layers: + - shader: unshaded + map: ["enum.EffectLayers.Unshaded"] + sprite: Effects/atmospherics.rsi + state: freon_old + - type: EffectVisuals + - type: AnimationPlayer + +- type: entity + parent: GasTankBase + abstract: true + id: BaseJetpack + name: Jetpack + description: It's a jetpack. + components: + - type: Sprite + sprite: Objects/Tanks/Jetpacks/blue.rsi + state: icon + netsync: false + - type: Item + size: 100 + - type: UserInterface + interfaces: + - key: enum.SharedGasTankUiKey.Key + type: GasTankBoundUserInterface + - type: Clothing + sprite: Objects/Tanks/Jetpacks/blue.rsi + QuickEquip: false + size: 100 + Slots: + - Back + - type: GasTank + outputPressure: 21.27825 + air: + volume: 70 + temperature: 293.15 + - type: Jetpack + toggleAction: + icon: + sprite: Objects/Tanks/Jetpacks/blue.rsi + state: icon + iconOn: + sprite: Objects/Tanks/Jetpacks/blue.rsi + state: icon-on + name: action-name-jetpack-toggle + description: action-decription-jetpack-toggle + itemIconStyle: NoItem + event: !type:ToggleJetpackEvent + - type: Appearance + +#Empty blue +- type: entity + id: JetpackBlue + parent: BaseJetpack + name: jetpack + suffix: Empty + components: + - type: Sprite + sprite: Objects/Tanks/Jetpacks/blue.rsi + - type: Clothing + sprite: Objects/Tanks/Jetpacks/blue.rsi + Slots: + - Back + +# Filled blue +- type: entity + id: JetpackBlueFilled + parent: JetpackBlue + name: jetpack + suffix: Filled + components: + - type: GasTank + outputPressure: 21.27825 + air: + volume: 70 + temperature: 293.15 + moles: + - 22.6293856 + +#Empty black +- type: entity + id: JetpackBlack + parent: BaseJetpack + name: jetpack + suffix: Empty + components: + - type: Sprite + sprite: Objects/Tanks/Jetpacks/black.rsi + - type: Clothing + sprite: Objects/Tanks/Jetpacks/black.rsi + Slots: + - Back + +# Filled black +- type: entity + id: JetpackBlackFilled + parent: JetpackBlack + name: jetpack + suffix: Filled + components: + - type: GasTank + outputPressure: 21.27825 + air: + volume: 70 + temperature: 293.15 + moles: + - 22.6293856 + +#Empty captain +- type: entity + id: JetpackCaptain + parent: BaseJetpack + name: captain's jetpack + suffix: Empty + components: + - type: Sprite + sprite: Objects/Tanks/Jetpacks/captain.rsi + - type: Clothing + size: 30 + sprite: Objects/Tanks/Jetpacks/captain.rsi + Slots: + - Back + +# Filled captain +- type: entity + id: JetpackCaptainFilled + parent: JetpackCaptain + name: captain's jetpack + suffix: Filled + components: + - type: GasTank + outputPressure: 21.27825 + air: + volume: 70 + temperature: 293.15 + moles: + - 22.6293856 + +#Empty mini +- type: entity + id: JetpackMini + parent: BaseJetpack + name: mini jetpack + suffix: Empty + components: + - type: Sprite + sprite: Objects/Tanks/Jetpacks/mini.rsi + - type: Clothing + size: 50 + sprite: Objects/Tanks/Jetpacks/mini.rsi + Slots: + - Back + +# Filled mini +- type: entity + id: JetpackMiniFilled + parent: JetpackMini + name: mini jetpack + suffix: Filled + components: + - type: GasTank + outputPressure: 21.27825 + air: + temperature: 293.15 + volume: 2 + moles: + - 0.323460326 + +#Empty security +- type: entity + id: JetpackSecurity + parent: BaseJetpack + name: security jetpack + suffix: Empty + components: + - type: Sprite + sprite: Objects/Tanks/Jetpacks/security.rsi + - type: Clothing + sprite: Objects/Tanks/Jetpacks/security.rsi + Slots: + - Back + +#Filled security +- type: entity + id: JetpackSecurityFilled + parent: JetpackSecurity + name: security jetpack + suffix: Filled + components: + - type: GasTank + outputPressure: 21.27825 + air: + volume: 70 + temperature: 293.15 + moles: + - 22.6293856 + +#Empty void +- type: entity + id: JetpackVoid + parent: BaseJetpack + name: void jetpack + suffix: Empty + components: + - type: Sprite + sprite: Objects/Tanks/Jetpacks/void.rsi + - type: Clothing + sprite: Objects/Tanks/Jetpacks/void.rsi + Slots: + - Back + +# Filled void +- type: entity + id: JetpackVoidFilled + parent: JetpackVoid + name: void jetpack + suffix: Filled + components: + - type: GasTank + outputPressure: 21.27825 + air: + volume: 70 + temperature: 293.15 + moles: + - 22.6293856 diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..9041766c9c Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/icon-on.png b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/icon-on.png new file mode 100644 index 0000000000..4c57b04fa4 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/icon-on.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/icon.png b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/icon.png new file mode 100644 index 0000000000..749f104b1e Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/inhand-left.png b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/inhand-left.png new file mode 100644 index 0000000000..9f27af40ed Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/inhand-right.png b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/inhand-right.png new file mode 100644 index 0000000000..5056a919c8 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/meta.json b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/meta.json new file mode 100644 index 0000000000..d57c3cdf00 --- /dev/null +++ b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/1592a112e3d33eec4a0704b518a138d5a976f455", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "directions": 1 + }, + { + "name": "icon-on", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "on-equipped-BACKPACK", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/on-equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/on-equipped-BACKPACK.png new file mode 100644 index 0000000000..fdfc1f64a2 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/black.rsi/on-equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..3add132719 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/icon-on.png b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/icon-on.png new file mode 100644 index 0000000000..290d3717bd Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/icon-on.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/icon.png b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/icon.png new file mode 100644 index 0000000000..059b976513 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/inhand-left.png b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/inhand-left.png new file mode 100644 index 0000000000..da57d6dee3 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/inhand-right.png b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/inhand-right.png new file mode 100644 index 0000000000..c9664e5679 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/meta.json b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/meta.json new file mode 100644 index 0000000000..d57c3cdf00 --- /dev/null +++ b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/1592a112e3d33eec4a0704b518a138d5a976f455", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "directions": 1 + }, + { + "name": "icon-on", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "on-equipped-BACKPACK", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/on-equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/on-equipped-BACKPACK.png new file mode 100644 index 0000000000..e6efe984f8 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/blue.rsi/on-equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..aeaa182522 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/icon-on.png b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/icon-on.png new file mode 100644 index 0000000000..3357878a2c Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/icon-on.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/icon.png b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/icon.png new file mode 100644 index 0000000000..323f0606a2 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/inhand-left.png b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/inhand-left.png new file mode 100644 index 0000000000..1f36a81f55 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/inhand-right.png b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/inhand-right.png new file mode 100644 index 0000000000..2abcd6a09b Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/meta.json b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/meta.json new file mode 100644 index 0000000000..d57c3cdf00 --- /dev/null +++ b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/1592a112e3d33eec4a0704b518a138d5a976f455", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "directions": 1 + }, + { + "name": "icon-on", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "on-equipped-BACKPACK", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/on-equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/on-equipped-BACKPACK.png new file mode 100644 index 0000000000..351623cf28 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/captain.rsi/on-equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..d775e61dc7 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/icon-on.png b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/icon-on.png new file mode 100644 index 0000000000..0657c4bfd4 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/icon-on.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/icon.png b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/icon.png new file mode 100644 index 0000000000..f635f9f66f Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/inhand-left.png b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/inhand-left.png new file mode 100644 index 0000000000..9f27af40ed Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/inhand-right.png b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/inhand-right.png new file mode 100644 index 0000000000..5056a919c8 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/meta.json b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/meta.json new file mode 100644 index 0000000000..d9ea7ada5f --- /dev/null +++ b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/meta.json @@ -0,0 +1,64 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/1592a112e3d33eec4a0704b518a138d5a976f455", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "directions": 1 + }, + { + "name": "icon-on", + "directions": 1, + "delays": [ + [ + 0.5, + 0.1, + 0.1 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "on-equipped-BACKPACK", + "directions": 4, + "delays": [ + [ + 0.5, + 0.2, + 0.1 + ], + [ + 0.5, + 0.2, + 0.1 + ], + [ + 0.5, + 0.2, + 0.1 + ], + [ + 0.5, + 0.2, + 0.1 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/on-equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/on-equipped-BACKPACK.png new file mode 100644 index 0000000000..4348c5463c Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/mini.rsi/on-equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..b8961eaa77 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/icon-on.png b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/icon-on.png new file mode 100644 index 0000000000..4a7f4ed64c Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/icon-on.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/icon.png b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/icon.png new file mode 100644 index 0000000000..926a586a63 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/inhand-left.png b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/inhand-left.png new file mode 100644 index 0000000000..97d9e6f889 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/inhand-right.png b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/inhand-right.png new file mode 100644 index 0000000000..f19970f2dd Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/meta.json b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/meta.json new file mode 100644 index 0000000000..d57c3cdf00 --- /dev/null +++ b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/1592a112e3d33eec4a0704b518a138d5a976f455", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "directions": 1 + }, + { + "name": "icon-on", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "on-equipped-BACKPACK", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ], + [ + 0.2, + 0.2 + ] + ] + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/on-equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/on-equipped-BACKPACK.png new file mode 100644 index 0000000000..0ae456cf0d Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/security.rsi/on-equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/equipped-BACKPACK.png new file mode 100644 index 0000000000..5481a4fcd4 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/equipped-BACKPACK.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/icon-on.png b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/icon-on.png new file mode 100644 index 0000000000..8f7ae047c4 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/icon-on.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/icon.png b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/icon.png new file mode 100644 index 0000000000..fe5a89a6f0 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/icon.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/inhand-left.png b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/inhand-left.png new file mode 100644 index 0000000000..cfa34df1c2 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/inhand-left.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/inhand-right.png b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/inhand-right.png new file mode 100644 index 0000000000..ede83bd77d Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/inhand-right.png differ diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/meta.json b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/meta.json new file mode 100644 index 0000000000..8011c87a0e --- /dev/null +++ b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/meta.json @@ -0,0 +1,41 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/1592a112e3d33eec4a0704b518a138d5a976f455", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon", + "directions": 1 + }, + { + "name": "icon-on", + "directions": 1, + "delays": [ + [ + 0.2, + 0.2 + ] + ] + }, + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "equipped-BACKPACK", + "directions": 4 + }, + { + "name": "on-equipped-BACKPACK", + "directions": 4 + } + ] +} \ No newline at end of file diff --git a/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/on-equipped-BACKPACK.png b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/on-equipped-BACKPACK.png new file mode 100644 index 0000000000..5481a4fcd4 Binary files /dev/null and b/Resources/Textures/Objects/Tanks/Jetpacks/void.rsi/on-equipped-BACKPACK.png differ