Space Ninjas auto-toggle internals after spawning (#25083)

* fix engine version

* actually fix engine version

* Automatically activated breathing masks

* weh

* who needed that component anyway

* check if internals are already running

* Update Content.Server/Atmos/Components/BreathToolComponent.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* Update Content.Server/Body/Systems/InternalsSystem.cs

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>

* prediction

* record struct event

* remove delayed activation, instead ensure that masks spawn last

* leftover

* engine version

* re-implement

---------

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
Errant
2024-05-03 03:24:21 +02:00
committed by GitHub
parent 192de3d9cb
commit f64dd5f45f
7 changed files with 65 additions and 20 deletions

View File

@@ -2,7 +2,4 @@ using Content.Shared.Station;
namespace Content.Client.Station; namespace Content.Client.Station;
public sealed class StationSpawningSystem : SharedStationSpawningSystem public sealed class StationSpawningSystem : SharedStationSpawningSystem;
{
}

View File

@@ -12,9 +12,10 @@ namespace Content.Server.Atmos.Components
/// <summary> /// <summary>
/// Tool is functional only in allowed slots /// Tool is functional only in allowed slots
/// </summary> /// </summary>
[DataField("allowedSlots")] [DataField]
public SlotFlags AllowedSlots = SlotFlags.MASK | SlotFlags.HEAD; public SlotFlags AllowedSlots = SlotFlags.MASK | SlotFlags.HEAD;
public bool IsFunctional; public bool IsFunctional;
public EntityUid? ConnectedInternalsEntity; public EntityUid? ConnectedInternalsEntity;
} }
} }

View File

@@ -8,6 +8,7 @@ using Content.Shared.DoAfter;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Internals; using Content.Shared.Internals;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Roles;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Utility; using Robust.Shared.Utility;
@@ -23,17 +24,29 @@ public sealed class InternalsSystem : EntitySystem
[Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!;
public const SlotFlags InventorySlots = SlotFlags.POCKET | SlotFlags.BELT; private EntityQuery<InternalsComponent> _internalsQuery;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_internalsQuery = GetEntityQuery<InternalsComponent>();
SubscribeLocalEvent<InternalsComponent, InhaleLocationEvent>(OnInhaleLocation); SubscribeLocalEvent<InternalsComponent, InhaleLocationEvent>(OnInhaleLocation);
SubscribeLocalEvent<InternalsComponent, ComponentStartup>(OnInternalsStartup); SubscribeLocalEvent<InternalsComponent, ComponentStartup>(OnInternalsStartup);
SubscribeLocalEvent<InternalsComponent, ComponentShutdown>(OnInternalsShutdown); SubscribeLocalEvent<InternalsComponent, ComponentShutdown>(OnInternalsShutdown);
SubscribeLocalEvent<InternalsComponent, GetVerbsEvent<InteractionVerb>>(OnGetInteractionVerbs); SubscribeLocalEvent<InternalsComponent, GetVerbsEvent<InteractionVerb>>(OnGetInteractionVerbs);
SubscribeLocalEvent<InternalsComponent, InternalsDoAfterEvent>(OnDoAfter); SubscribeLocalEvent<InternalsComponent, InternalsDoAfterEvent>(OnDoAfter);
SubscribeLocalEvent<StartingGearEquippedEvent>(OnStartingGear);
}
private void OnStartingGear(ref StartingGearEquippedEvent ev)
{
if (!_internalsQuery.TryComp(ev.Entity, out var internals) || internals.BreathToolEntity == null)
return;
ToggleInternals(ev.Entity, ev.Entity, force: false, internals);
} }
private void OnGetInteractionVerbs( private void OnGetInteractionVerbs(
@@ -217,7 +230,7 @@ public sealed class InternalsSystem : EntitySystem
if (component.BreathToolEntity is null || !AreInternalsWorking(component)) if (component.BreathToolEntity is null || !AreInternalsWorking(component))
return 2; return 2;
// If pressure in the tank is below low pressure threshhold, flash warning on internals UI // If pressure in the tank is below low pressure threshold, flash warning on internals UI
if (TryComp<GasTankComponent>(component.GasTankEntity, out var gasTank) if (TryComp<GasTankComponent>(component.GasTankEntity, out var gasTank)
&& gasTank.IsLowPressure) && gasTank.IsLowPressure)
{ {

View File

@@ -59,6 +59,7 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
/// <inheritdoc/> /// <inheritdoc/>
public override void Initialize() public override void Initialize()
{ {
base.Initialize();
Subs.CVar(_configurationManager, CCVars.ICRandomCharacters, e => _randomizeCharacters = e, true); Subs.CVar(_configurationManager, CCVars.ICRandomCharacters, e => _randomizeCharacters = e, true);
_spawnerCallbacks = new Dictionary<SpawnPriorityPreference, Action<PlayerSpawningEvent>>() _spawnerCallbacks = new Dictionary<SpawnPriorityPreference, Action<PlayerSpawningEvent>>()
@@ -181,7 +182,7 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
if (prototype?.StartingGear != null) if (prototype?.StartingGear != null)
{ {
var startingGear = _prototypeManager.Index<StartingGearPrototype>(prototype.StartingGear); var startingGear = _prototypeManager.Index<StartingGearPrototype>(prototype.StartingGear);
EquipStartingGear(entity.Value, startingGear); EquipStartingGear(entity.Value, startingGear, raiseEvent: false);
} }
// Run loadouts after so stuff like storage loadouts can get // Run loadouts after so stuff like storage loadouts can get
@@ -217,11 +218,14 @@ public sealed class StationSpawningSystem : SharedStationSpawningSystem
} }
// Handle any extra data here. // Handle any extra data here.
EquipStartingGear(entity.Value, startingGear); EquipStartingGear(entity.Value, startingGear, raiseEvent: false);
} }
} }
} }
var gearEquippedEv = new StartingGearEquippedEvent(entity.Value);
RaiseLocalEvent(entity.Value, ref gearEquippedEv, true);
if (profile != null) if (profile != null)
{ {
if (prototype != null) if (prototype != null)

View File

@@ -151,7 +151,6 @@ public partial class InventorySystem : EntitySystem
slotDefinitions = null; slotDefinitions = null;
return false; return false;
} }
slotDefinitions = inv.Slots; slotDefinitions = inv.Slots;
return true; return true;
} }

View File

@@ -0,0 +1,10 @@
namespace Content.Shared.Roles;
/// <summary>
/// Raised directed on an entity when a new starting gear prototype has been equipped.
/// </summary>
[ByRefEvent]
public record struct StartingGearEquippedEvent(EntityUid Entity)
{
public readonly EntityUid Entity = Entity;
}

View File

@@ -17,12 +17,24 @@ public abstract class SharedStationSpawningSystem : EntitySystem
[Dependency] private readonly SharedStorageSystem _storage = default!; [Dependency] private readonly SharedStorageSystem _storage = default!;
[Dependency] private readonly SharedTransformSystem _xformSystem = default!; [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
private EntityQuery<HandsComponent> _handsQuery;
private EntityQuery<InventoryComponent> _inventoryQuery;
private EntityQuery<StorageComponent> _storageQuery;
private EntityQuery<TransformComponent> _xformQuery;
public override void Initialize()
{
base.Initialize();
_handsQuery = GetEntityQuery<HandsComponent>();
_inventoryQuery = GetEntityQuery<InventoryComponent>();
_storageQuery = GetEntityQuery<StorageComponent>();
_xformQuery = GetEntityQuery<TransformComponent>();
}
/// <summary> /// <summary>
/// Equips starting gear onto the given entity. /// <see cref="EquipStartingGear(Robust.Shared.GameObjects.EntityUid,System.Nullable{Robust.Shared.Prototypes.ProtoId{Content.Shared.Roles.StartingGearPrototype}},bool)"/>
/// </summary> /// </summary>
/// <param name="entity">Entity to load out.</param> public void EquipStartingGear(EntityUid entity, ProtoId<StartingGearPrototype>? startingGear, bool raiseEvent = true)
/// <param name="startingGear">Starting gear to use.</param>
public void EquipStartingGear(EntityUid entity, ProtoId<StartingGearPrototype>? startingGear)
{ {
PrototypeManager.TryIndex(startingGear, out var gearProto); PrototypeManager.TryIndex(startingGear, out var gearProto);
EquipStartingGear(entity, gearProto); EquipStartingGear(entity, gearProto);
@@ -33,11 +45,14 @@ public abstract class SharedStationSpawningSystem : EntitySystem
/// </summary> /// </summary>
/// <param name="entity">Entity to load out.</param> /// <param name="entity">Entity to load out.</param>
/// <param name="startingGear">Starting gear to use.</param> /// <param name="startingGear">Starting gear to use.</param>
public void EquipStartingGear(EntityUid entity, StartingGearPrototype? startingGear) /// <param name="raiseEvent">Should we raise the event for equipped. Set to false if you will call this manually</param>
public void EquipStartingGear(EntityUid entity, StartingGearPrototype? startingGear, bool raiseEvent = true)
{ {
if (startingGear == null) if (startingGear == null)
return; return;
var xform = _xformQuery.GetComponent(entity);
if (InventorySystem.TryGetSlots(entity, out var slotDefinitions)) if (InventorySystem.TryGetSlots(entity, out var slotDefinitions))
{ {
foreach (var slot in slotDefinitions) foreach (var slot in slotDefinitions)
@@ -45,16 +60,16 @@ public abstract class SharedStationSpawningSystem : EntitySystem
var equipmentStr = startingGear.GetGear(slot.Name); var equipmentStr = startingGear.GetGear(slot.Name);
if (!string.IsNullOrEmpty(equipmentStr)) if (!string.IsNullOrEmpty(equipmentStr))
{ {
var equipmentEntity = EntityManager.SpawnEntity(equipmentStr, EntityManager.GetComponent<TransformComponent>(entity).Coordinates); var equipmentEntity = EntityManager.SpawnEntity(equipmentStr, xform.Coordinates);
InventorySystem.TryEquip(entity, equipmentEntity, slot.Name, silent: true, force:true); InventorySystem.TryEquip(entity, equipmentEntity, slot.Name, silent: true, force:true);
} }
} }
} }
if (TryComp(entity, out HandsComponent? handsComponent)) if (_handsQuery.TryComp(entity, out var handsComponent))
{ {
var inhand = startingGear.Inhand; var inhand = startingGear.Inhand;
var coords = EntityManager.GetComponent<TransformComponent>(entity).Coordinates; var coords = xform.Coordinates;
foreach (var prototype in inhand) foreach (var prototype in inhand)
{ {
var inhandEntity = EntityManager.SpawnEntity(prototype, coords); var inhandEntity = EntityManager.SpawnEntity(prototype, coords);
@@ -70,7 +85,7 @@ public abstract class SharedStationSpawningSystem : EntitySystem
{ {
var coords = _xformSystem.GetMapCoordinates(entity); var coords = _xformSystem.GetMapCoordinates(entity);
var ents = new ValueList<EntityUid>(); var ents = new ValueList<EntityUid>();
TryComp(entity, out InventoryComponent? inventoryComp); _inventoryQuery.TryComp(entity, out var inventoryComp);
foreach (var (slot, entProtos) in startingGear.Storage) foreach (var (slot, entProtos) in startingGear.Storage)
{ {
@@ -84,7 +99,7 @@ public abstract class SharedStationSpawningSystem : EntitySystem
if (inventoryComp != null && if (inventoryComp != null &&
InventorySystem.TryGetSlotEntity(entity, slot, out var slotEnt, inventoryComponent: inventoryComp) && InventorySystem.TryGetSlotEntity(entity, slot, out var slotEnt, inventoryComponent: inventoryComp) &&
TryComp(slotEnt, out StorageComponent? storage)) _storageQuery.TryComp(slotEnt, out var storage))
{ {
foreach (var ent in ents) foreach (var ent in ents)
{ {
@@ -93,5 +108,11 @@ public abstract class SharedStationSpawningSystem : EntitySystem
} }
} }
} }
if (raiseEvent)
{
var ev = new StartingGearEquippedEvent(entity);
RaiseLocalEvent(entity, ref ev, true);
}
} }
} }