using Robust.Shared.Physics.Systems;
using Robust.Shared.Random;
-namespace Content.Server.Shuttles.Systems
+namespace Content.Server.Shuttles.Systems;
+
+[UsedImplicitly]
+public sealed partial class ShuttleSystem : SharedShuttleSystem
{
- [UsedImplicitly]
- public sealed partial class ShuttleSystem : SharedShuttleSystem
+ [Dependency] private readonly IMapManager _mapManager = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly AirlockSystem _airlock = default!;
+ [Dependency] private readonly DockingSystem _dockSystem = default!;
+ [Dependency] private readonly DoorSystem _doors = default!;
+ [Dependency] private readonly FixtureSystem _fixtures = default!;
+ [Dependency] private readonly MapLoaderSystem _loader = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly SharedPhysicsSystem _physics = default!;
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
+ [Dependency] private readonly ShuttleConsoleSystem _console = default!;
+ [Dependency] private readonly StunSystem _stuns = default!;
+ [Dependency] private readonly ThrusterSystem _thruster = default!;
+ [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+
+ private ISawmill _sawmill = default!;
+
+ public const float TileMassMultiplier = 0.5f;
+
+ public const float ShuttleLinearDamping = 0.05f;
+ public const float ShuttleAngularDamping = 0.05f;
+
+ public override void Initialize()
{
- [Dependency] private readonly IMapManager _mapManager = default!;
- [Dependency] private readonly IRobustRandom _random = default!;
- [Dependency] private readonly AirlockSystem _airlock = default!;
- [Dependency] private readonly DockingSystem _dockSystem = default!;
- [Dependency] private readonly DoorSystem _doors = default!;
- [Dependency] private readonly FixtureSystem _fixtures = default!;
- [Dependency] private readonly MapLoaderSystem _loader = default!;
- [Dependency] private readonly SharedAudioSystem _audio = default!;
- [Dependency] private readonly SharedPhysicsSystem _physics = default!;
- [Dependency] private readonly SharedTransformSystem _transform = default!;
- [Dependency] private readonly ShuttleConsoleSystem _console = default!;
- [Dependency] private readonly StunSystem _stuns = default!;
- [Dependency] private readonly ThrusterSystem _thruster = default!;
- [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
-
- private ISawmill _sawmill = default!;
-
- public const float TileMassMultiplier = 0.5f;
-
- public const float ShuttleLinearDamping = 0.05f;
- public const float ShuttleAngularDamping = 0.05f;
-
- public override void Initialize()
- {
- base.Initialize();
- _sawmill = Logger.GetSawmill("shuttles");
+ base.Initialize();
+ _sawmill = Logger.GetSawmill("shuttles");
- InitializeFTL();
- InitializeGridFills();
- InitializeIFF();
- InitializeImpact();
+ InitializeFTL();
+ InitializeGridFills();
+ InitializeIFF();
+ InitializeImpact();
- SubscribeLocalEvent<ShuttleComponent, ComponentAdd>(OnShuttleAdd);
- SubscribeLocalEvent<ShuttleComponent, ComponentStartup>(OnShuttleStartup);
- SubscribeLocalEvent<ShuttleComponent, ComponentShutdown>(OnShuttleShutdown);
+ SubscribeLocalEvent<ShuttleComponent, ComponentAdd>(OnShuttleAdd);
+ SubscribeLocalEvent<ShuttleComponent, ComponentStartup>(OnShuttleStartup);
+ SubscribeLocalEvent<ShuttleComponent, ComponentShutdown>(OnShuttleShutdown);
- SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
+ SubscribeLocalEvent<RoundRestartCleanupEvent>(OnRoundRestart);
- SubscribeLocalEvent<GridInitializeEvent>(OnGridInit);
- SubscribeLocalEvent<GridFixtureChangeEvent>(OnGridFixtureChange);
- }
+ SubscribeLocalEvent<GridInitializeEvent>(OnGridInit);
+ SubscribeLocalEvent<GridFixtureChangeEvent>(OnGridFixtureChange);
+ }
- public override void Update(float frameTime)
- {
- base.Update(frameTime);
- UpdateHyperspace(frameTime);
- }
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ UpdateHyperspace(frameTime);
+ }
+
+ private void OnRoundRestart(RoundRestartCleanupEvent ev)
+ {
+ CleanupHyperspace();
+ }
- private void OnRoundRestart(RoundRestartCleanupEvent ev)
+ private void OnShuttleAdd(EntityUid uid, ShuttleComponent component, ComponentAdd args)
+ {
+ // Easier than doing it in the comp and they don't have constructors.
+ for (var i = 0; i < component.LinearThrusters.Length; i++)
{
- CleanupHyperspace();
+ component.LinearThrusters[i] = new List<EntityUid>();
}
+ }
+
+ private void OnGridFixtureChange(GridFixtureChangeEvent args)
+ {
+ // Look this is jank but it's a placeholder until we design it.
+ if (args.NewFixtures.Count == 0)
+ return;
+
+ var uid = args.NewFixtures[0].Body.Owner;
+ var manager = Comp<FixturesComponent>(uid);
- private void OnShuttleAdd(EntityUid uid, ShuttleComponent component, ComponentAdd args)
+ foreach (var fixture in args.NewFixtures)
{
- // Easier than doing it in the comp and they don't have constructors.
- for (var i = 0; i < component.LinearThrusters.Length; i++)
- {
- component.LinearThrusters[i] = new List<ThrusterComponent>();
- }
+ _physics.SetDensity(uid, fixture, TileMassMultiplier, false, manager);
+ _fixtures.SetRestitution(uid, fixture, 0.1f, false, manager);
}
- private void OnGridFixtureChange(GridFixtureChangeEvent args)
- {
- // Look this is jank but it's a placeholder until we design it.
- if (args.NewFixtures.Count == 0)
- return;
+ _fixtures.FixtureUpdate(uid, manager: manager);
+ }
- var uid = args.NewFixtures[0].Body.Owner;
- var manager = Comp<FixturesComponent>(uid);
+ private void OnGridInit(GridInitializeEvent ev)
+ {
+ if (HasComp<MapComponent>(ev.EntityUid))
+ return;
- foreach (var fixture in args.NewFixtures)
- {
- _physics.SetDensity(uid, fixture, TileMassMultiplier, false, manager);
- _fixtures.SetRestitution(uid, fixture, 0.1f, false, manager);
- }
+ EntityManager.EnsureComponent<ShuttleComponent>(ev.EntityUid);
+ }
- _fixtures.FixtureUpdate(uid, manager: manager);
+ private void OnShuttleStartup(EntityUid uid, ShuttleComponent component, ComponentStartup args)
+ {
+ if (!EntityManager.HasComponent<MapGridComponent>(uid))
+ {
+ return;
}
- private void OnGridInit(GridInitializeEvent ev)
+ if (!EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
{
- if (HasComp<MapComponent>(ev.EntityUid))
- return;
-
- EntityManager.EnsureComponent<ShuttleComponent>(ev.EntityUid);
+ return;
}
- private void OnShuttleStartup(EntityUid uid, ShuttleComponent component, ComponentStartup args)
+ if (component.Enabled)
{
- if (!EntityManager.HasComponent<MapGridComponent>(uid))
- {
- return;
- }
-
- if (!EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
- {
- return;
- }
-
- if (component.Enabled)
- {
- Enable(uid, physicsComponent);
- }
+ Enable(uid, physicsComponent);
}
+ }
+
+ public void Toggle(EntityUid uid, ShuttleComponent component)
+ {
+ if (!EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
+ return;
+
+ component.Enabled = !component.Enabled;
- public void Toggle(EntityUid uid, ShuttleComponent component)
+ if (component.Enabled)
{
- if (!EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
- return;
-
- component.Enabled = !component.Enabled;
-
- if (component.Enabled)
- {
- Enable(uid, physicsComponent);
- }
- else
- {
- Disable(uid, physicsComponent);
- }
+ Enable(uid, physicsComponent);
}
-
- private void Enable(EntityUid uid, PhysicsComponent component)
+ else
{
- FixturesComponent? manager = null;
-
- _physics.SetBodyType(uid, BodyType.Dynamic, manager: manager, body: component);
- _physics.SetBodyStatus(component, BodyStatus.InAir);
- _physics.SetFixedRotation(uid, false, manager: manager, body: component);
- _physics.SetLinearDamping(component, ShuttleLinearDamping);
- _physics.SetAngularDamping(component, ShuttleAngularDamping);
+ Disable(uid, physicsComponent);
}
+ }
- private void Disable(EntityUid uid, PhysicsComponent component)
- {
- FixturesComponent? manager = null;
+ private void Enable(EntityUid uid, PhysicsComponent component)
+ {
+ FixturesComponent? manager = null;
- _physics.SetBodyType(uid, BodyType.Static, manager: manager, body: component);
- _physics.SetBodyStatus(component, BodyStatus.OnGround);
- _physics.SetFixedRotation(uid, true, manager: manager, body: component);
- }
+ _physics.SetBodyType(uid, BodyType.Dynamic, manager: manager, body: component);
+ _physics.SetBodyStatus(component, BodyStatus.InAir);
+ _physics.SetFixedRotation(uid, false, manager: manager, body: component);
+ _physics.SetLinearDamping(component, ShuttleLinearDamping);
+ _physics.SetAngularDamping(component, ShuttleAngularDamping);
+ }
- private void OnShuttleShutdown(EntityUid uid, ShuttleComponent component, ComponentShutdown args)
- {
- // None of the below is necessary for any cleanup if we're just deleting.
- if (EntityManager.GetComponent<MetaDataComponent>(uid).EntityLifeStage >= EntityLifeStage.Terminating) return;
+ private void Disable(EntityUid uid, PhysicsComponent component)
+ {
+ FixturesComponent? manager = null;
+
+ _physics.SetBodyType(uid, BodyType.Static, manager: manager, body: component);
+ _physics.SetBodyStatus(component, BodyStatus.OnGround);
+ _physics.SetFixedRotation(uid, true, manager: manager, body: component);
+ }
- if (!EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
- {
- return;
- }
+ private void OnShuttleShutdown(EntityUid uid, ShuttleComponent component, ComponentShutdown args)
+ {
+ // None of the below is necessary for any cleanup if we're just deleting.
+ if (EntityManager.GetComponent<MetaDataComponent>(uid).EntityLifeStage >= EntityLifeStage.Terminating)
+ return;
- Disable(uid, physicsComponent);
+ if (!EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
+ {
+ return;
}
+
+ Disable(uid, physicsComponent);
}
}
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Robust.Shared.Physics.Systems;
+using Robust.Shared.Timing;
using Robust.Shared.Utility;
-namespace Content.Server.Shuttles.Systems
-{
- public sealed class ThrusterSystem : EntitySystem
- {
- [Dependency] private readonly IMapManager _mapManager = default!;
- [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
- [Dependency] private readonly AmbientSoundSystem _ambient = default!;
- [Dependency] private readonly FixtureSystem _fixtureSystem = default!;
- [Dependency] private readonly DamageableSystem _damageable = default!;
- [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+namespace Content.Server.Shuttles.Systems;
- // Essentially whenever thruster enables we update the shuttle's available impulses which are used for movement.
- // This is done for each direction available.
+public sealed class ThrusterSystem : EntitySystem
+{
+ [Dependency] private readonly IGameTiming _timing = default!;
+ [Dependency] private readonly IMapManager _mapManager = default!;
+ [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!;
+ [Dependency] private readonly AmbientSoundSystem _ambient = default!;
+ [Dependency] private readonly FixtureSystem _fixtureSystem = default!;
+ [Dependency] private readonly DamageableSystem _damageable = default!;
+ [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
- public const string BurnFixture = "thruster-burn";
+ // Essentially whenever thruster enables we update the shuttle's available impulses which are used for movement.
+ // This is done for each direction available.
- private readonly HashSet<ThrusterComponent> _activeThrusters = new();
+ public const string BurnFixture = "thruster-burn";
- // Used for accumulating burn if someone touches a firing thruster.
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent<ThrusterComponent, ActivateInWorldEvent>(OnActivateThruster);
+ SubscribeLocalEvent<ThrusterComponent, ComponentInit>(OnThrusterInit);
+ SubscribeLocalEvent<ThrusterComponent, ComponentShutdown>(OnThrusterShutdown);
+ SubscribeLocalEvent<ThrusterComponent, MapInitEvent>(OnThrusterMapInit);
+ SubscribeLocalEvent<ThrusterComponent, PowerChangedEvent>(OnPowerChange);
+ SubscribeLocalEvent<ThrusterComponent, AnchorStateChangedEvent>(OnAnchorChange);
+ SubscribeLocalEvent<ThrusterComponent, ReAnchorEvent>(OnThrusterReAnchor);
+ SubscribeLocalEvent<ThrusterComponent, MoveEvent>(OnRotate);
+ SubscribeLocalEvent<ThrusterComponent, IsHotEvent>(OnIsHotEvent);
+ SubscribeLocalEvent<ThrusterComponent, StartCollideEvent>(OnStartCollide);
+ SubscribeLocalEvent<ThrusterComponent, EndCollideEvent>(OnEndCollide);
+
+ SubscribeLocalEvent<ThrusterComponent, ExaminedEvent>(OnThrusterExamine);
+
+ SubscribeLocalEvent<ThrusterComponent, RefreshPartsEvent>(OnRefreshParts);
+ SubscribeLocalEvent<ThrusterComponent, UpgradeExamineEvent>(OnUpgradeExamine);
+
+ SubscribeLocalEvent<ShuttleComponent, TileChangedEvent>(OnShuttleTileChange);
+ }
- private float _accumulator;
+ private void OnThrusterExamine(EntityUid uid, ThrusterComponent component, ExaminedEvent args)
+ {
+ // Powered is already handled by other power components
+ var enabled = Loc.GetString(component.Enabled ? "thruster-comp-enabled" : "thruster-comp-disabled");
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<ThrusterComponent, ActivateInWorldEvent>(OnActivateThruster);
- SubscribeLocalEvent<ThrusterComponent, ComponentInit>(OnThrusterInit);
- SubscribeLocalEvent<ThrusterComponent, ComponentShutdown>(OnThrusterShutdown);
- SubscribeLocalEvent<ThrusterComponent, PowerChangedEvent>(OnPowerChange);
- SubscribeLocalEvent<ThrusterComponent, AnchorStateChangedEvent>(OnAnchorChange);
- SubscribeLocalEvent<ThrusterComponent, ReAnchorEvent>(OnThrusterReAnchor);
- SubscribeLocalEvent<ThrusterComponent, MoveEvent>(OnRotate);
- SubscribeLocalEvent<ThrusterComponent, IsHotEvent>(OnIsHotEvent);
- SubscribeLocalEvent<ThrusterComponent, StartCollideEvent>(OnStartCollide);
- SubscribeLocalEvent<ThrusterComponent, EndCollideEvent>(OnEndCollide);
-
- SubscribeLocalEvent<ThrusterComponent, ExaminedEvent>(OnThrusterExamine);
-
- SubscribeLocalEvent<ThrusterComponent, RefreshPartsEvent>(OnRefreshParts);
- SubscribeLocalEvent<ThrusterComponent, UpgradeExamineEvent>(OnUpgradeExamine);
-
- SubscribeLocalEvent<ShuttleComponent, TileChangedEvent>(OnShuttleTileChange);
- }
+ args.PushMarkup(enabled);
- private void OnThrusterExamine(EntityUid uid, ThrusterComponent component, ExaminedEvent args)
+ if (component.Type == ThrusterType.Linear &&
+ EntityManager.TryGetComponent(uid, out TransformComponent? xform) &&
+ xform.Anchored)
{
- // Powered is already handled by other power components
- var enabled = Loc.GetString(component.Enabled ? "thruster-comp-enabled" : "thruster-comp-disabled");
-
- args.PushMarkup(enabled);
+ var nozzleDir = Loc.GetString("thruster-comp-nozzle-direction",
+ ("direction", xform.LocalRotation.Opposite().ToWorldVec().GetDir().ToString().ToLowerInvariant()));
- if (component.Type == ThrusterType.Linear &&
- EntityManager.TryGetComponent(uid, out TransformComponent? xform) &&
- xform.Anchored)
- {
- var nozzleDir = Loc.GetString("thruster-comp-nozzle-direction",
- ("direction", xform.LocalRotation.Opposite().ToWorldVec().GetDir().ToString().ToLowerInvariant()));
-
- args.PushMarkup(nozzleDir);
+ args.PushMarkup(nozzleDir);
- var exposed = NozzleExposed(xform);
+ var exposed = NozzleExposed(xform);
- var nozzleText = Loc.GetString(exposed ? "thruster-comp-nozzle-exposed" : "thruster-comp-nozzle-not-exposed");
+ var nozzleText = Loc.GetString(exposed ? "thruster-comp-nozzle-exposed" : "thruster-comp-nozzle-not-exposed");
- args.PushMarkup(nozzleText);
- }
+ args.PushMarkup(nozzleText);
}
+ }
- private void OnIsHotEvent(EntityUid uid, ThrusterComponent component, IsHotEvent args)
- {
- args.IsHot = component.Type != ThrusterType.Angular && component.IsOn;
- }
+ private void OnIsHotEvent(EntityUid uid, ThrusterComponent component, IsHotEvent args)
+ {
+ args.IsHot = component.Type != ThrusterType.Angular && component.IsOn;
+ }
- private void OnShuttleTileChange(EntityUid uid, ShuttleComponent component, ref TileChangedEvent args)
- {
- // If the old tile was space but the new one isn't then disable all adjacent thrusters
- if (args.NewTile.IsSpace(_tileDefManager) || !args.OldTile.IsSpace(_tileDefManager)) return;
+ private void OnShuttleTileChange(EntityUid uid, ShuttleComponent component, ref TileChangedEvent args)
+ {
+ // If the old tile was space but the new one isn't then disable all adjacent thrusters
+ if (args.NewTile.IsSpace(_tileDefManager) || !args.OldTile.IsSpace(_tileDefManager))
+ return;
- var tilePos = args.NewTile.GridIndices;
- var grid = _mapManager.GetGrid(uid);
- var xformQuery = GetEntityQuery<TransformComponent>();
- var thrusterQuery = GetEntityQuery<ThrusterComponent>();
+ var tilePos = args.NewTile.GridIndices;
+ var grid = _mapManager.GetGrid(uid);
+ var xformQuery = GetEntityQuery<TransformComponent>();
+ var thrusterQuery = GetEntityQuery<ThrusterComponent>();
- for (var x = -1; x <= 1; x++)
+ for (var x = -1; x <= 1; x++)
+ {
+ for (var y = -1; y <= 1; y++)
{
- for (var y = -1; y <= 1; y++)
- {
- if (x != 0 && y != 0) continue;
+ if (x != 0 && y != 0)
+ continue;
- var checkPos = tilePos + new Vector2i(x, y);
- var enumerator = grid.GetAnchoredEntitiesEnumerator(checkPos);
+ var checkPos = tilePos + new Vector2i(x, y);
+ var enumerator = grid.GetAnchoredEntitiesEnumerator(checkPos);
- while (enumerator.MoveNext(out var ent))
- {
- if (!thrusterQuery.TryGetComponent(ent.Value, out var thruster) || !thruster.RequireSpace) continue;
+ while (enumerator.MoveNext(out var ent))
+ {
+ if (!thrusterQuery.TryGetComponent(ent.Value, out var thruster) || !thruster.RequireSpace)
+ continue;
- // Work out if the thruster is facing this direction
- var xform = xformQuery.GetComponent(ent.Value);
- var direction = xform.LocalRotation.ToWorldVec();
+ // Work out if the thruster is facing this direction
+ var xform = xformQuery.GetComponent(ent.Value);
+ var direction = xform.LocalRotation.ToWorldVec();
- if (new Vector2i((int) direction.X, (int) direction.Y) != new Vector2i(x, y)) continue;
+ if (new Vector2i((int) direction.X, (int) direction.Y) != new Vector2i(x, y))
+ continue;
- DisableThruster(ent.Value, thruster, xform.GridUid);
- }
+ DisableThruster(ent.Value, thruster, xform.GridUid);
}
}
}
+ }
- private void OnActivateThruster(EntityUid uid, ThrusterComponent component, ActivateInWorldEvent args)
- {
- component.Enabled ^= true;
- }
+ private void OnActivateThruster(EntityUid uid, ThrusterComponent component, ActivateInWorldEvent args)
+ {
+ component.Enabled ^= true;
+ }
+
+ /// <summary>
+ /// If the thruster rotates change the direction where the linear thrust is applied
+ /// </summary>
+ private void OnRotate(EntityUid uid, ThrusterComponent component, ref MoveEvent args)
+ {
+ // TODO: Disable visualizer for old direction
- /// <summary>
- /// If the thruster rotates change the direction where the linear thrust is applied
- /// </summary>
- private void OnRotate(EntityUid uid, ThrusterComponent component, ref MoveEvent args)
+ if (!component.Enabled ||
+ component.Type != ThrusterType.Linear ||
+ !EntityManager.TryGetComponent(uid, out TransformComponent? xform) ||
+ !EntityManager.TryGetComponent(xform.GridUid, out ShuttleComponent? shuttleComponent))
{
- // TODO: Disable visualizer for old direction
+ return;
+ }
- if (!component.Enabled ||
- component.Type != ThrusterType.Linear ||
- !EntityManager.TryGetComponent(uid, out TransformComponent? xform) ||
- !_mapManager.TryGetGrid(xform.GridUid, out var grid) ||
- !EntityManager.TryGetComponent(grid.Owner, out ShuttleComponent? shuttleComponent))
- {
- return;
- }
+ var canEnable = CanEnable(uid, component);
- var canEnable = CanEnable(uid, component);
+ // If it's not on then don't enable it inadvertantly (given we don't have an old rotation)
+ if (!canEnable && !component.IsOn)
+ return;
- // If it's not on then don't enable it inadvertantly (given we don't have an old rotation)
- if (!canEnable && !component.IsOn) return;
+ // Enable it if it was turned off but new tile is valid
+ if (!component.IsOn && canEnable)
+ {
+ EnableThruster(uid, component);
+ return;
+ }
- // Enable it if it was turned off but new tile is valid
- if (!component.IsOn && canEnable)
- {
- EnableThruster(uid, component);
- return;
- }
+ // Disable if new tile invalid
+ if (component.IsOn && !canEnable)
+ {
+ DisableThruster(uid, component, xform, args.OldRotation);
+ return;
+ }
- // Disable if new tile invalid
- if (component.IsOn && !canEnable)
- {
- DisableThruster(uid, component, xform, args.OldRotation);
- return;
- }
+ var oldDirection = (int) args.OldRotation.GetCardinalDir() / 2;
+ var direction = (int) args.NewRotation.GetCardinalDir() / 2;
- var oldDirection = (int) args.OldRotation.GetCardinalDir() / 2;
- var direction = (int) args.NewRotation.GetCardinalDir() / 2;
+ shuttleComponent.LinearThrust[oldDirection] -= component.Thrust;
+ DebugTools.Assert(shuttleComponent.LinearThrusters[oldDirection].Contains(uid));
+ shuttleComponent.LinearThrusters[oldDirection].Remove(uid);
- shuttleComponent.LinearThrust[oldDirection] -= component.Thrust;
- DebugTools.Assert(shuttleComponent.LinearThrusters[oldDirection].Contains(component));
- shuttleComponent.LinearThrusters[oldDirection].Remove(component);
+ shuttleComponent.LinearThrust[direction] += component.Thrust;
+ DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(uid));
+ shuttleComponent.LinearThrusters[direction].Add(uid);
+ }
- shuttleComponent.LinearThrust[direction] += component.Thrust;
- DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component));
- shuttleComponent.LinearThrusters[direction].Add(component);
+ private void OnAnchorChange(EntityUid uid, ThrusterComponent component, ref AnchorStateChangedEvent args)
+ {
+ if (args.Anchored && CanEnable(uid, component))
+ {
+ EnableThruster(uid, component);
}
-
- private void OnAnchorChange(EntityUid uid, ThrusterComponent component, ref AnchorStateChangedEvent args)
+ else
{
- if (args.Anchored && CanEnable(uid, component))
- {
- EnableThruster(uid, component);
- }
- else
- {
- DisableThruster(uid, component);
- }
+ DisableThruster(uid, component);
}
+ }
- private void OnThrusterReAnchor(EntityUid uid, ThrusterComponent component, ref ReAnchorEvent args)
- {
- DisableThruster(uid, component, args.OldGrid);
+ private void OnThrusterReAnchor(EntityUid uid, ThrusterComponent component, ref ReAnchorEvent args)
+ {
+ DisableThruster(uid, component, args.OldGrid);
- if (CanEnable(uid, component))
- EnableThruster(uid, component);
- }
+ if (CanEnable(uid, component))
+ EnableThruster(uid, component);
+ }
- private void OnThrusterInit(EntityUid uid, ThrusterComponent component, ComponentInit args)
- {
- _ambient.SetAmbience(uid, false);
+ private void OnThrusterMapInit(EntityUid uid, ThrusterComponent component, MapInitEvent args)
+ {
+ if (component.NextFire < _timing.CurTime)
+ component.NextFire = _timing.CurTime;
+ }
- if (!component.Enabled)
- {
- return;
- }
+ private void OnThrusterInit(EntityUid uid, ThrusterComponent component, ComponentInit args)
+ {
+ _ambient.SetAmbience(uid, false);
- if (CanEnable(uid, component))
- {
- EnableThruster(uid, component);
- }
+ if (!component.Enabled)
+ {
+ return;
}
- private void OnThrusterShutdown(EntityUid uid, ThrusterComponent component, ComponentShutdown args)
+ if (CanEnable(uid, component))
{
- DisableThruster(uid, component);
+ EnableThruster(uid, component);
}
+ }
- private void OnPowerChange(EntityUid uid, ThrusterComponent component, ref PowerChangedEvent args)
+ private void OnThrusterShutdown(EntityUid uid, ThrusterComponent component, ComponentShutdown args)
+ {
+ DisableThruster(uid, component);
+ }
+
+ private void OnPowerChange(EntityUid uid, ThrusterComponent component, ref PowerChangedEvent args)
+ {
+ if (args.Powered && CanEnable(uid, component))
{
- if (args.Powered && CanEnable(uid, component))
- {
- EnableThruster(uid, component);
- }
- else
- {
- DisableThruster(uid, component);
- }
+ EnableThruster(uid, component);
+ }
+ else
+ {
+ DisableThruster(uid, component);
}
+ }
- /// <summary>
- /// Tries to enable the thruster and turn it on. If it's already enabled it does nothing.
- /// </summary>
- public void EnableThruster(EntityUid uid, ThrusterComponent component, TransformComponent? xform = null)
+ /// <summary>
+ /// Tries to enable the thruster and turn it on. If it's already enabled it does nothing.
+ /// </summary>
+ public void EnableThruster(EntityUid uid, ThrusterComponent component, TransformComponent? xform = null)
+ {
+ if (component.IsOn ||
+ !Resolve(uid, ref xform))
{
- if (component.IsOn ||
- !Resolve(uid, ref xform) ||
- !_mapManager.TryGetGrid(xform.GridUid, out var grid)) return;
+ return;
+ }
- component.IsOn = true;
+ component.IsOn = true;
- if (!EntityManager.TryGetComponent(grid.Owner, out ShuttleComponent? shuttleComponent)) return;
+ if (!EntityManager.TryGetComponent(xform.GridUid, out ShuttleComponent? shuttleComponent))
+ return;
- // Logger.DebugS("thruster", $"Enabled thruster {uid}");
+ // Logger.DebugS("thruster", $"Enabled thruster {uid}");
- switch (component.Type)
- {
- case ThrusterType.Linear:
- var direction = (int) xform.LocalRotation.GetCardinalDir() / 2;
-
- shuttleComponent.LinearThrust[direction] += component.Thrust;
- DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(component));
- shuttleComponent.LinearThrusters[direction].Add(component);
-
- // Don't just add / remove the fixture whenever the thruster fires because perf
- if (EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent) &&
- component.BurnPoly.Count > 0)
- {
- var shape = new PolygonShape();
- shape.SetVertices(component.BurnPoly);
- _fixtureSystem.TryCreateFixture(uid, shape, BurnFixture, hard: false, collisionLayer: (int) CollisionGroup.FullTileMask);
- }
-
- break;
- case ThrusterType.Angular:
- shuttleComponent.AngularThrust += component.Thrust;
- DebugTools.Assert(!shuttleComponent.AngularThrusters.Contains(component));
- shuttleComponent.AngularThrusters.Add(component);
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
+ switch (component.Type)
+ {
+ case ThrusterType.Linear:
+ var direction = (int) xform.LocalRotation.GetCardinalDir() / 2;
- if (EntityManager.TryGetComponent(uid, out AppearanceComponent? appearance))
- {
- _appearance.SetData(uid, ThrusterVisualState.State, true, appearance);
- }
+ shuttleComponent.LinearThrust[direction] += component.Thrust;
+ DebugTools.Assert(!shuttleComponent.LinearThrusters[direction].Contains(uid));
+ shuttleComponent.LinearThrusters[direction].Add(uid);
- if (EntityManager.TryGetComponent(uid, out PointLightComponent? pointLightComponent))
- {
- pointLightComponent.Enabled = true;
- }
+ // Don't just add / remove the fixture whenever the thruster fires because perf
+ if (EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent) &&
+ component.BurnPoly.Count > 0)
+ {
+ var shape = new PolygonShape();
+ shape.SetVertices(component.BurnPoly);
+ _fixtureSystem.TryCreateFixture(uid, shape, BurnFixture, hard: false, collisionLayer: (int) CollisionGroup.FullTileMask, body: physicsComponent);
+ }
- _ambient.SetAmbience(uid, true);
+ break;
+ case ThrusterType.Angular:
+ shuttleComponent.AngularThrust += component.Thrust;
+ DebugTools.Assert(!shuttleComponent.AngularThrusters.Contains(uid));
+ shuttleComponent.AngularThrusters.Add(uid);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
}
- public void DisableThruster(EntityUid uid, ThrusterComponent component, TransformComponent? xform = null, Angle? angle = null)
+ if (EntityManager.TryGetComponent(uid, out AppearanceComponent? appearance))
{
- if (!Resolve(uid, ref xform)) return;
- DisableThruster(uid, component, xform.GridUid, xform);
+ _appearance.SetData(uid, ThrusterVisualState.State, true, appearance);
}
- /// <summary>
- /// Tries to disable the thruster.
- /// </summary>
- public void DisableThruster(EntityUid uid, ThrusterComponent component, EntityUid? gridId, TransformComponent? xform = null, Angle? angle = null)
+ if (EntityManager.TryGetComponent(uid, out PointLightComponent? pointLightComponent))
{
- if (!component.IsOn ||
- !Resolve(uid, ref xform) ||
- !_mapManager.TryGetGrid(gridId, out var grid)) return;
+ pointLightComponent.Enabled = true;
+ }
- component.IsOn = false;
+ _ambient.SetAmbience(uid, true);
+ }
- if (!EntityManager.TryGetComponent(grid.Owner, out ShuttleComponent? shuttleComponent)) return;
+ public void DisableThruster(EntityUid uid, ThrusterComponent component, TransformComponent? xform = null, Angle? angle = null)
+ {
+ if (!Resolve(uid, ref xform)) return;
+ DisableThruster(uid, component, xform.GridUid, xform);
+ }
- // Logger.DebugS("thruster", $"Disabled thruster {uid}");
+ /// <summary>
+ /// Tries to disable the thruster.
+ /// </summary>
+ public void DisableThruster(EntityUid uid, ThrusterComponent component, EntityUid? gridId, TransformComponent? xform = null, Angle? angle = null)
+ {
+ if (!component.IsOn ||
+ !Resolve(uid, ref xform))
+ {
+ return;
+ }
- switch (component.Type)
- {
- case ThrusterType.Linear:
- angle ??= xform.LocalRotation;
- var direction = (int) angle.Value.GetCardinalDir() / 2;
-
- shuttleComponent.LinearThrust[direction] -= component.Thrust;
- DebugTools.Assert(shuttleComponent.LinearThrusters[direction].Contains(component));
- shuttleComponent.LinearThrusters[direction].Remove(component);
- break;
- case ThrusterType.Angular:
- shuttleComponent.AngularThrust -= component.Thrust;
- DebugTools.Assert(shuttleComponent.AngularThrusters.Contains(component));
- shuttleComponent.AngularThrusters.Remove(component);
- break;
- default:
- throw new ArgumentOutOfRangeException();
- }
+ component.IsOn = false;
- if (EntityManager.TryGetComponent(uid, out AppearanceComponent? appearance))
- {
- _appearance.SetData(uid, ThrusterVisualState.State, false, appearance);
- }
+ if (!EntityManager.TryGetComponent(gridId, out ShuttleComponent? shuttleComponent))
+ return;
- if (EntityManager.TryGetComponent(uid, out PointLightComponent? pointLightComponent))
- {
- pointLightComponent.Enabled = false;
- }
+ // Logger.DebugS("thruster", $"Disabled thruster {uid}");
- _ambient.SetAmbience(uid, false);
+ switch (component.Type)
+ {
+ case ThrusterType.Linear:
+ angle ??= xform.LocalRotation;
+ var direction = (int) angle.Value.GetCardinalDir() / 2;
+
+ shuttleComponent.LinearThrust[direction] -= component.Thrust;
+ DebugTools.Assert(shuttleComponent.LinearThrusters[direction].Contains(uid));
+ shuttleComponent.LinearThrusters[direction].Remove(uid);
+ break;
+ case ThrusterType.Angular:
+ shuttleComponent.AngularThrust -= component.Thrust;
+ DebugTools.Assert(shuttleComponent.AngularThrusters.Contains(uid));
+ shuttleComponent.AngularThrusters.Remove(uid);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
- if (EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
- {
- _fixtureSystem.DestroyFixture(uid, BurnFixture, body: physicsComponent);
- }
+ if (EntityManager.TryGetComponent(uid, out AppearanceComponent? appearance))
+ {
+ _appearance.SetData(uid, ThrusterVisualState.State, false, appearance);
+ }
- _activeThrusters.Remove(component);
- component.Colliding.Clear();
+ if (EntityManager.TryGetComponent(uid, out PointLightComponent? pointLightComponent))
+ {
+ pointLightComponent.Enabled = false;
}
- public bool CanEnable(EntityUid uid, ThrusterComponent component)
+ _ambient.SetAmbience(uid, false);
+
+ if (EntityManager.TryGetComponent(uid, out PhysicsComponent? physicsComponent))
{
- if (!component.Enabled) return false;
- if (component.LifeStage > ComponentLifeStage.Running) return false;
+ _fixtureSystem.DestroyFixture(uid, BurnFixture, body: physicsComponent);
+ }
- var xform = Transform(uid);
+ component.Colliding.Clear();
+ }
- if (!xform.Anchored ||!this.IsPowered(uid, EntityManager))
- {
- return false;
- }
+ public bool CanEnable(EntityUid uid, ThrusterComponent component)
+ {
+ if (!component.Enabled)
+ return false;
- if (!component.RequireSpace)
- return true;
+ if (component.LifeStage > ComponentLifeStage.Running)
+ return false;
- return NozzleExposed(xform);
- }
+ var xform = Transform(uid);
- private bool NozzleExposed(TransformComponent xform)
+ if (!xform.Anchored ||!this.IsPowered(uid, EntityManager))
{
- if (xform.GridUid == null)
- return true;
+ return false;
+ }
- var (x, y) = xform.LocalPosition + xform.LocalRotation.Opposite().ToWorldVec();
- var tile = _mapManager.GetGrid(xform.GridUid.Value).GetTileRef(new Vector2i((int) Math.Floor(x), (int) Math.Floor(y)));
+ if (!component.RequireSpace)
+ return true;
- return tile.Tile.IsSpace();
- }
+ return NozzleExposed(xform);
+ }
- #region Burning
+ private bool NozzleExposed(TransformComponent xform)
+ {
+ if (xform.GridUid == null)
+ return true;
- public override void Update(float frameTime)
- {
- base.Update(frameTime);
+ var (x, y) = xform.LocalPosition + xform.LocalRotation.Opposite().ToWorldVec();
+ var tile = _mapManager.GetGrid(xform.GridUid.Value).GetTileRef(new Vector2i((int) Math.Floor(x), (int) Math.Floor(y)));
- _accumulator += frameTime;
+ return tile.Tile.IsSpace();
+ }
- if (_accumulator < 1) return;
+ #region Burning
- _accumulator -= 1;
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
- foreach (var comp in _activeThrusters.ToArray())
- {
- MetaDataComponent? metaData = null;
+ var query = EntityQueryEnumerator<ThrusterComponent>();
+ var curTime = _timing.CurTime;
- if (!comp.Firing || comp.Damage == null || Paused(comp.Owner, metaData) || Deleted(comp.Owner, metaData)) continue;
+ while (query.MoveNext(out var comp))
+ {
+ if (!comp.Firing || comp.Colliding.Count == 0 || comp.Damage == null || comp.NextFire < curTime)
+ continue;
- DebugTools.Assert(comp.Colliding.Count > 0);
+ comp.NextFire += TimeSpan.FromSeconds(1);
- foreach (var uid in comp.Colliding.ToArray())
- {
- _damageable.TryChangeDamage(uid, comp.Damage);
- }
+ foreach (var uid in comp.Colliding.ToArray())
+ {
+ _damageable.TryChangeDamage(uid, comp.Damage);
}
}
+ }
- private void OnStartCollide(EntityUid uid, ThrusterComponent component, ref StartCollideEvent args)
- {
- if (args.OurFixture.ID != BurnFixture) return;
+ private void OnStartCollide(EntityUid uid, ThrusterComponent component, ref StartCollideEvent args)
+ {
+ if (args.OurFixture.ID != BurnFixture)
+ return;
- _activeThrusters.Add(component);
- component.Colliding.Add((args.OtherFixture.Body).Owner);
- }
+ component.Colliding.Add(args.OtherEntity);
+ }
- private void OnEndCollide(EntityUid uid, ThrusterComponent component, ref EndCollideEvent args)
- {
- if (args.OurFixture.ID != BurnFixture) return;
+ private void OnEndCollide(EntityUid uid, ThrusterComponent component, ref EndCollideEvent args)
+ {
+ if (args.OurFixture.ID != BurnFixture)
+ return;
- component.Colliding.Remove((args.OtherFixture.Body).Owner);
+ component.Colliding.Remove(args.OtherEntity);
+ }
- if (component.Colliding.Count == 0)
- {
- _activeThrusters.Remove(component);
- }
- }
+ /// <summary>
+ /// Considers a thrust direction as being active.
+ /// </summary>
+ public void EnableLinearThrustDirection(ShuttleComponent component, DirectionFlag direction)
+ {
+ if ((component.ThrustDirections & direction) != 0x0)
+ return;
- /// <summary>
- /// Considers a thrust direction as being active.
- /// </summary>
- public void EnableLinearThrustDirection(ShuttleComponent component, DirectionFlag direction)
- {
- if ((component.ThrustDirections & direction) != 0x0) return;
+ component.ThrustDirections |= direction;
- component.ThrustDirections |= direction;
+ var index = GetFlagIndex(direction);
+ var appearanceQuery = GetEntityQuery<AppearanceComponent>();
+ var thrusterQuery = GetEntityQuery<ThrusterComponent>();
- var index = GetFlagIndex(direction);
+ foreach (var uid in component.LinearThrusters[index])
+ {
+ if (!thrusterQuery.TryGetComponent(uid, out var comp))
+ continue;
- foreach (var comp in component.LinearThrusters[index])
- {
- comp.Firing = true;
- _appearance.SetData(comp.Owner, ThrusterVisualState.Thrusting, true);
- }
+ comp.Firing = true;
+ appearanceQuery.TryGetComponent(uid, out var appearance);
+ _appearance.SetData(uid, ThrusterVisualState.Thrusting, true, appearance);
}
+ }
- /// <summary>
- /// Disables a thrust direction.
- /// </summary>
- public void DisableLinearThrustDirection(ShuttleComponent component, DirectionFlag direction)
- {
- if ((component.ThrustDirections & direction) == 0x0) return;
+ /// <summary>
+ /// Disables a thrust direction.
+ /// </summary>
+ public void DisableLinearThrustDirection(ShuttleComponent component, DirectionFlag direction)
+ {
+ if ((component.ThrustDirections & direction) == 0x0)
+ return;
- component.ThrustDirections &= ~direction;
+ component.ThrustDirections &= ~direction;
- var index = GetFlagIndex(direction);
+ var index = GetFlagIndex(direction);
+ var appearanceQuery = GetEntityQuery<AppearanceComponent>();
+ var thrusterQuery = GetEntityQuery<ThrusterComponent>();
- foreach (var comp in component.LinearThrusters[index])
- {
- comp.Firing = false;
- _appearance.SetData(comp.Owner, ThrusterVisualState.Thrusting, false);
- }
+ foreach (var uid in component.LinearThrusters[index])
+ {
+ if (!thrusterQuery.TryGetComponent(uid, out var comp))
+ continue;
+
+ appearanceQuery.TryGetComponent(uid, out var appearance);
+ comp.Firing = false;
+ _appearance.SetData(uid, ThrusterVisualState.Thrusting, false, appearance);
}
+ }
- public void DisableLinearThrusters(ShuttleComponent component)
+ public void DisableLinearThrusters(ShuttleComponent component)
+ {
+ foreach (DirectionFlag dir in Enum.GetValues(typeof(DirectionFlag)))
{
- foreach (DirectionFlag dir in Enum.GetValues(typeof(DirectionFlag)))
- {
- DisableLinearThrustDirection(component, dir);
- }
-
- DebugTools.Assert(component.ThrustDirections == DirectionFlag.None);
+ DisableLinearThrustDirection(component, dir);
}
- public void SetAngularThrust(ShuttleComponent component, bool on)
+ DebugTools.Assert(component.ThrustDirections == DirectionFlag.None);
+ }
+
+ public void SetAngularThrust(ShuttleComponent component, bool on)
+ {
+ var appearanceQuery = GetEntityQuery<AppearanceComponent>();
+ var thrusterQuery = GetEntityQuery<ThrusterComponent>();
+
+ if (on)
{
- if (on)
+ foreach (var uid in component.AngularThrusters)
{
- foreach (var comp in component.AngularThrusters)
- {
- comp.Firing = true;
- _appearance.SetData(comp.Owner, ThrusterVisualState.Thrusting, true);
- }
+ if (!thrusterQuery.TryGetComponent(uid, out var comp))
+ continue;
+
+ appearanceQuery.TryGetComponent(uid, out var appearance);
+ comp.Firing = true;
+ _appearance.SetData(uid, ThrusterVisualState.Thrusting, true, appearance);
}
- else
+ }
+ else
+ {
+ foreach (var uid in component.AngularThrusters)
{
- foreach (var comp in component.AngularThrusters)
- {
- comp.Firing = false;
- _appearance.SetData(comp.Owner, ThrusterVisualState.Thrusting, false);
- }
+ if (!thrusterQuery.TryGetComponent(uid, out var comp))
+ continue;
+
+ appearanceQuery.TryGetComponent(uid, out var appearance);
+ comp.Firing = false;
+ _appearance.SetData(uid, ThrusterVisualState.Thrusting, false, appearance);
}
}
+ }
- private void OnRefreshParts(EntityUid uid, ThrusterComponent component, RefreshPartsEvent args)
- {
- var thrustRating = args.PartRatings[component.MachinePartThrust];
+ private void OnRefreshParts(EntityUid uid, ThrusterComponent component, RefreshPartsEvent args)
+ {
+ var thrustRating = args.PartRatings[component.MachinePartThrust];
- component.Thrust = component.BaseThrust * MathF.Pow(component.PartRatingThrustMultiplier, thrustRating - 1);
- }
+ component.Thrust = component.BaseThrust * MathF.Pow(component.PartRatingThrustMultiplier, thrustRating - 1);
+ }
- private void OnUpgradeExamine(EntityUid uid, ThrusterComponent component, UpgradeExamineEvent args)
- {
- args.AddPercentageUpgrade("thruster-comp-upgrade-thrust", component.Thrust / component.BaseThrust);
- }
+ private void OnUpgradeExamine(EntityUid uid, ThrusterComponent component, UpgradeExamineEvent args)
+ {
+ args.AddPercentageUpgrade("thruster-comp-upgrade-thrust", component.Thrust / component.BaseThrust);
+ }
- #endregion
+ #endregion
- private int GetFlagIndex(DirectionFlag flag)
- {
- return (int) Math.Log2((int) flag);
- }
+ private int GetFlagIndex(DirectionFlag flag)
+ {
+ return (int) Math.Log2((int) flag);
}
}