From 4bcf3c3c0e89c8fdeef442571e8014c35f9624f0 Mon Sep 17 00:00:00 2001 From: Fildrance Date: Fri, 27 Sep 2024 10:22:17 +0300 Subject: [PATCH 01/88] Station AI ability to electricute doors (#32012) * Boom! Emergency access! * Emergency access sound * locale * Updated sounds * bleh * Door electrify base * feat: popups on attempt to activate AI action when wires cut * refactor: use SharedApcPowerReceiverComponent to check if AI can interact with door * refactor: added icon and sound for door overcharge * meta.json should use tabs not spaces * refactor: extracted sounds for airlock overcharge to static field in system * refactor: cleanup, ScarKy0 mentions for resources * refactor: removed unused textures * feat: now notification is displayed when AI attempting to interact with door which have wire cut * StationAiWhitelistComponent is properly gating BUI OnMessageAttempt, SharedPowerReceiverSystem.IsPowered is now used to check if device powered * refactor: use PlayLocal to play electrify sound only for AI player * refactor: SetBoltsDown now uses TrySetBoltDown, checks for power. * bolts now check for power using SharedPowerReceiverSystem * electrify localization and louder electrify sounds * extracted ShowDeviceNotRespondingPopup, reverted airlocks not opening/closing when ai wire was cut * refactor: cleanup * New sprites and fixes * Copyright * even more sprite changes * refactore: cleanup, rename overcharge => electrify --------- Co-authored-by: ScarKy0 Co-authored-by: pa.pecherskij Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> --- .../StationAi/StationAiSystem.Airlock.cs | 67 ++++++++++++++--- .../Systems/AdminVerbSystem.Tools.cs | 10 +-- .../Completions/AttemptElectrocute.cs | 1 + .../Doors/WireActions/DoorBoltWireAction.cs | 1 - .../Electrocution/ElectrocutionSystem.cs | 11 +++ Content.Server/Power/PowerWireAction.cs | 2 + Content.Server/Remotes/DoorRemoteSystem.cs | 2 +- .../Doors/Components/AirlockComponent.cs | 13 ++++ .../Doors/Systems/SharedAirlockSystem.cs | 23 +++++- .../Doors/Systems/SharedDoorSystem.Bolts.cs | 15 +++- .../Doors/Systems/SharedDoorSystem.cs | 2 + .../Components/ElectrifiedComponent.cs | 58 ++++++++------ .../SharedElectrocutionSystem.cs | 14 ++++ .../SharedPowerReceiverSystem.cs | 4 +- .../SharedStationAiSystem.Airlock.cs | 71 +++++++++++++++++- .../StationAi/SharedStationAiSystem.Held.cs | 62 ++++++++++----- .../StationAi/SharedStationAiSystem.cs | 41 ++++++---- .../Audio/Machines/airlock_electrify_off.ogg | Bin 0 -> 9989 bytes .../Audio/Machines/airlock_electrify_on.ogg | Bin 0 -> 10481 bytes .../Audio/Machines/airlock_emergencyoff.ogg | Bin 0 -> 7952 bytes .../Audio/Machines/airlock_emergencyon.ogg | Bin 0 -> 10094 bytes Resources/Audio/Machines/attributions.yml | 9 +++ .../Locale/en-US/silicons/station-ai.ftl | 8 ++ .../Actions/actions_ai.rsi/bolt_door.png | Bin 0 -> 372 bytes .../actions_ai.rsi/door_overcharge_off.png | Bin 0 -> 614 bytes .../actions_ai.rsi/door_overcharge_on.png | Bin 0 -> 495 bytes .../Actions/actions_ai.rsi/emergency_off.png | Bin 0 -> 876 bytes .../Actions/actions_ai.rsi/emergency_on.png | Bin 0 -> 767 bytes .../Actions/actions_ai.rsi/meta.json | 66 ++++++++++------ .../Actions/actions_ai.rsi/unbolt_door.png | Bin 0 -> 588 bytes 30 files changed, 371 insertions(+), 109 deletions(-) rename {Content.Server => Content.Shared}/Electrocution/Components/ElectrifiedComponent.cs (65%) create mode 100644 Resources/Audio/Machines/airlock_electrify_off.ogg create mode 100644 Resources/Audio/Machines/airlock_electrify_on.ogg create mode 100644 Resources/Audio/Machines/airlock_emergencyoff.ogg create mode 100644 Resources/Audio/Machines/airlock_emergencyon.ogg create mode 100644 Resources/Textures/Interface/Actions/actions_ai.rsi/bolt_door.png create mode 100644 Resources/Textures/Interface/Actions/actions_ai.rsi/door_overcharge_off.png create mode 100644 Resources/Textures/Interface/Actions/actions_ai.rsi/door_overcharge_on.png create mode 100644 Resources/Textures/Interface/Actions/actions_ai.rsi/emergency_off.png create mode 100644 Resources/Textures/Interface/Actions/actions_ai.rsi/emergency_on.png create mode 100644 Resources/Textures/Interface/Actions/actions_ai.rsi/unbolt_door.png diff --git a/Content.Client/Silicons/StationAi/StationAiSystem.Airlock.cs b/Content.Client/Silicons/StationAi/StationAiSystem.Airlock.cs index bf6b65a969..d5bc764b34 100644 --- a/Content.Client/Silicons/StationAi/StationAiSystem.Airlock.cs +++ b/Content.Client/Silicons/StationAi/StationAiSystem.Airlock.cs @@ -1,4 +1,5 @@ using Content.Shared.Doors.Components; +using Content.Shared.Electrocution; using Content.Shared.Silicons.StationAi; using Robust.Shared.Utility; @@ -6,25 +7,69 @@ namespace Content.Client.Silicons.StationAi; public sealed partial class StationAiSystem { + private readonly ResPath _aiActionsRsi = new ResPath("/Textures/Interface/Actions/actions_ai.rsi"); + private void InitializeAirlock() { SubscribeLocalEvent(OnDoorBoltGetRadial); + SubscribeLocalEvent(OnEmergencyAccessGetRadial); + SubscribeLocalEvent(OnDoorElectrifiedGetRadial); } private void OnDoorBoltGetRadial(Entity ent, ref GetStationAiRadialEvent args) { - args.Actions.Add(new StationAiRadial() - { - Sprite = ent.Comp.BoltsDown ? - new SpriteSpecifier.Rsi( - new ResPath("/Textures/Structures/Doors/Airlocks/Standard/basic.rsi"), "open") : - new SpriteSpecifier.Rsi( - new ResPath("/Textures/Structures/Doors/Airlocks/Standard/basic.rsi"), "closed"), - Tooltip = ent.Comp.BoltsDown ? Loc.GetString("bolt-open") : Loc.GetString("bolt-close"), - Event = new StationAiBoltEvent() + args.Actions.Add( + new StationAiRadial { - Bolted = !ent.Comp.BoltsDown, + Sprite = ent.Comp.BoltsDown + ? new SpriteSpecifier.Rsi(_aiActionsRsi, "unbolt_door") + : new SpriteSpecifier.Rsi(_aiActionsRsi, "bolt_door"), + Tooltip = ent.Comp.BoltsDown + ? Loc.GetString("bolt-open") + : Loc.GetString("bolt-close"), + Event = new StationAiBoltEvent + { + Bolted = !ent.Comp.BoltsDown, + } } - }); + ); + } + + private void OnEmergencyAccessGetRadial(Entity ent, ref GetStationAiRadialEvent args) + { + args.Actions.Add( + new StationAiRadial + { + Sprite = ent.Comp.EmergencyAccess + ? new SpriteSpecifier.Rsi(_aiActionsRsi, "emergency_off") + : new SpriteSpecifier.Rsi(_aiActionsRsi, "emergency_on"), + Tooltip = ent.Comp.EmergencyAccess + ? Loc.GetString("emergency-access-off") + : Loc.GetString("emergency-access-on"), + Event = new StationAiEmergencyAccessEvent + { + EmergencyAccess = !ent.Comp.EmergencyAccess, + } + } + ); + } + + private void OnDoorElectrifiedGetRadial(Entity ent, ref GetStationAiRadialEvent args) + { + args.Actions.Add( + new StationAiRadial + { + Sprite = ent.Comp.Enabled + ? new SpriteSpecifier.Rsi(_aiActionsRsi, "door_overcharge_off") + : new SpriteSpecifier.Rsi(_aiActionsRsi, "door_overcharge_on"), + Tooltip = ent.Comp.Enabled + ? Loc.GetString("electrify-door-off") + : Loc.GetString("electrify-door-on"), + Event = new StationAiElectrifiedEvent + { + Electrified = !ent.Comp.Enabled, + } + } + ); } } diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs index fef8a031d9..56cf287850 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs @@ -90,22 +90,22 @@ public sealed partial class AdminVerbSystem args.Verbs.Add(bolt); } - if (TryComp(args.Target, out var airlock)) + if (TryComp(args.Target, out var airlockComp)) { Verb emergencyAccess = new() { - Text = airlock.EmergencyAccess ? "Emergency Access Off" : "Emergency Access On", + Text = airlockComp.EmergencyAccess ? "Emergency Access Off" : "Emergency Access On", Category = VerbCategory.Tricks, Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/AdminActions/emergency_access.png")), Act = () => { - _airlockSystem.ToggleEmergencyAccess(args.Target, airlock); + _airlockSystem.SetEmergencyAccess((args.Target, airlockComp), !airlockComp.EmergencyAccess); }, Impact = LogImpact.Medium, - Message = Loc.GetString(airlock.EmergencyAccess + Message = Loc.GetString(airlockComp.EmergencyAccess ? "admin-trick-emergency-access-off-description" : "admin-trick-emergency-access-on-description"), - Priority = (int) (airlock.EmergencyAccess ? TricksVerbPriorities.EmergencyAccessOff : TricksVerbPriorities.EmergencyAccessOn), + Priority = (int) (airlockComp.EmergencyAccess ? TricksVerbPriorities.EmergencyAccessOff : TricksVerbPriorities.EmergencyAccessOn), }; args.Verbs.Add(emergencyAccess); } diff --git a/Content.Server/Construction/Completions/AttemptElectrocute.cs b/Content.Server/Construction/Completions/AttemptElectrocute.cs index 05f0977b66..5c97d5e90f 100644 --- a/Content.Server/Construction/Completions/AttemptElectrocute.cs +++ b/Content.Server/Construction/Completions/AttemptElectrocute.cs @@ -1,4 +1,5 @@ using Content.Server.Electrocution; +using Content.Shared.Electrocution; using Content.Shared.Construction; namespace Content.Server.Construction.Completions; diff --git a/Content.Server/Doors/WireActions/DoorBoltWireAction.cs b/Content.Server/Doors/WireActions/DoorBoltWireAction.cs index fc1cf50cd8..80555f68f9 100644 --- a/Content.Server/Doors/WireActions/DoorBoltWireAction.cs +++ b/Content.Server/Doors/WireActions/DoorBoltWireAction.cs @@ -2,7 +2,6 @@ using Content.Server.Doors.Systems; using Content.Server.Wires; using Content.Shared.Doors; using Content.Shared.Doors.Components; -using Content.Shared.Doors.Systems; using Content.Shared.Wires; namespace Content.Server.Doors; diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index 67e60c9de4..88404c4aa9 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -488,4 +488,15 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem } _audio.PlayPvs(electrified.ShockNoises, targetUid, AudioParams.Default.WithVolume(electrified.ShockVolume)); } + + public void SetElectrifiedWireCut(Entity ent, bool value) + { + if (ent.Comp.IsWireCut == value) + { + return; + } + + ent.Comp.IsWireCut = value; + Dirty(ent); + } } diff --git a/Content.Server/Power/PowerWireAction.cs b/Content.Server/Power/PowerWireAction.cs index ac34966036..cebb7de8ec 100644 --- a/Content.Server/Power/PowerWireAction.cs +++ b/Content.Server/Power/PowerWireAction.cs @@ -1,4 +1,5 @@ using Content.Server.Electrocution; +using Content.Shared.Electrocution; using Content.Server.Power.Components; using Content.Server.Wires; using Content.Shared.Power; @@ -104,6 +105,7 @@ public sealed partial class PowerWireAction : BaseWireAction && !EntityManager.TryGetComponent(used, out electrified)) return; + _electrocutionSystem.SetElectrifiedWireCut((used, electrified), setting); electrified.Enabled = setting; } diff --git a/Content.Server/Remotes/DoorRemoteSystem.cs b/Content.Server/Remotes/DoorRemoteSystem.cs index 6716065087..de327bd084 100644 --- a/Content.Server/Remotes/DoorRemoteSystem.cs +++ b/Content.Server/Remotes/DoorRemoteSystem.cs @@ -74,7 +74,7 @@ namespace Content.Shared.Remotes case OperatingMode.ToggleEmergencyAccess: if (airlockComp != null) { - _airlock.ToggleEmergencyAccess(args.Target.Value, airlockComp); + _airlock.SetEmergencyAccess((args.Target.Value, airlockComp), !airlockComp.EmergencyAccess); _adminLogger.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User):player} used {ToPrettyString(args.Used)} on {ToPrettyString(args.Target.Value)} to set emergency access {(airlockComp.EmergencyAccess ? "on" : "off")}"); } diff --git a/Content.Shared/Doors/Components/AirlockComponent.cs b/Content.Shared/Doors/Components/AirlockComponent.cs index 6577b1942a..6b3fcfad7e 100644 --- a/Content.Shared/Doors/Components/AirlockComponent.cs +++ b/Content.Shared/Doors/Components/AirlockComponent.cs @@ -1,5 +1,6 @@ using Content.Shared.DeviceLinking; using Content.Shared.Doors.Systems; +using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -23,6 +24,18 @@ public sealed partial class AirlockComponent : Component [ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField] public bool EmergencyAccess = false; + + /// + /// Sound to play when the airlock emergency access is turned on. + /// + [DataField] + public SoundSpecifier EmergencyOnSound = new SoundPathSpecifier("/Audio/Machines/airlock_emergencyon.ogg"); + + /// + /// Sound to play when the airlock emergency access is turned off. + /// + [DataField] + public SoundSpecifier EmergencyOffSound = new SoundPathSpecifier("/Audio/Machines/airlock_emergencyoff.ogg"); /// /// Pry modifier for a powered airlock. diff --git a/Content.Shared/Doors/Systems/SharedAirlockSystem.cs b/Content.Shared/Doors/Systems/SharedAirlockSystem.cs index 5a9cde74ee..e404a91bdd 100644 --- a/Content.Shared/Doors/Systems/SharedAirlockSystem.cs +++ b/Content.Shared/Doors/Systems/SharedAirlockSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Doors.Components; +using Robust.Shared.Audio.Systems; using Content.Shared.Popups; using Content.Shared.Prying.Components; using Content.Shared.Wires; @@ -10,7 +11,9 @@ public abstract class SharedAirlockSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] protected readonly SharedAppearanceSystem Appearance = default!; + [Dependency] protected readonly SharedAudioSystem Audio = default!; [Dependency] protected readonly SharedDoorSystem DoorSystem = default!; + [Dependency] protected readonly SharedPopupSystem Popup = default!; [Dependency] private readonly SharedWiresSystem _wiresSystem = default!; public override void Initialize() @@ -131,11 +134,23 @@ public abstract class SharedAirlockSystem : EntitySystem Appearance.SetData(uid, DoorVisuals.EmergencyLights, component.EmergencyAccess); } - public void ToggleEmergencyAccess(EntityUid uid, AirlockComponent component) + public void SetEmergencyAccess(Entity ent, bool value, EntityUid? user = null, bool predicted = false) { - component.EmergencyAccess = !component.EmergencyAccess; - Dirty(uid, component); // This only runs on the server apparently so we need this. - UpdateEmergencyLightStatus(uid, component); + if(!ent.Comp.Powered) + return; + + if (ent.Comp.EmergencyAccess == value) + return; + + ent.Comp.EmergencyAccess = value; + Dirty(ent, ent.Comp); // This only runs on the server apparently so we need this. + UpdateEmergencyLightStatus(ent, ent.Comp); + + var sound = ent.Comp.EmergencyAccess ? ent.Comp.EmergencyOnSound : ent.Comp.EmergencyOffSound; + if (predicted) + Audio.PlayPredicted(sound, ent, user: user); + else + Audio.PlayPvs(sound, ent); } public void SetAutoCloseDelayModifier(AirlockComponent component, float value) diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.Bolts.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.Bolts.cs index 35681bfd82..13050616e1 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.Bolts.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.Bolts.cs @@ -77,8 +77,20 @@ public abstract partial class SharedDoorSystem public void SetBoltsDown(Entity ent, bool value, EntityUid? user = null, bool predicted = false) { + TrySetBoltDown(ent, value, user, predicted); + } + + public bool TrySetBoltDown( + Entity ent, + bool value, + EntityUid? user = null, + bool predicted = false + ) + { + if (!_powerReceiver.IsPowered(ent.Owner)) + return false; if (ent.Comp.BoltsDown == value) - return; + return false; ent.Comp.BoltsDown = value; Dirty(ent, ent.Comp); @@ -89,6 +101,7 @@ public abstract partial class SharedDoorSystem Audio.PlayPredicted(sound, ent, user: user); else Audio.PlayPvs(sound, ent); + return true; } private void OnStateChanged(Entity entity, ref DoorStateChangedEvent args) diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 2319d5e916..3d9a721473 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -9,6 +9,7 @@ using Content.Shared.Emag.Systems; using Content.Shared.Interaction; using Content.Shared.Physics; using Content.Shared.Popups; +using Content.Shared.Power.EntitySystems; using Content.Shared.Prying.Components; using Content.Shared.Prying.Systems; using Content.Shared.Stunnable; @@ -42,6 +43,7 @@ public abstract partial class SharedDoorSystem : EntitySystem [Dependency] private readonly PryingSystem _pryingSystem = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; [Dependency] private readonly SharedMapSystem _mapSystem = default!; + [Dependency] private readonly SharedPowerReceiverSystem _powerReceiver = default!; [ValidatePrototypeId] diff --git a/Content.Server/Electrocution/Components/ElectrifiedComponent.cs b/Content.Shared/Electrocution/Components/ElectrifiedComponent.cs similarity index 65% rename from Content.Server/Electrocution/Components/ElectrifiedComponent.cs rename to Content.Shared/Electrocution/Components/ElectrifiedComponent.cs index 5755e98091..52eb76ca54 100644 --- a/Content.Server/Electrocution/Components/ElectrifiedComponent.cs +++ b/Content.Shared/Electrocution/Components/ElectrifiedComponent.cs @@ -1,121 +1,131 @@ +using Robust.Shared.GameStates; using Robust.Shared.Audio; -namespace Content.Server.Electrocution; +namespace Content.Shared.Electrocution; /// /// Component for things that shock users on touch. /// -[RegisterComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class ElectrifiedComponent : Component { - [DataField("enabled")] + [DataField, AutoNetworkedField] public bool Enabled = true; /// /// Should player get damage on collide /// - [DataField("onBump")] + [DataField, AutoNetworkedField] public bool OnBump = true; /// /// Should player get damage on attack /// - [DataField("onAttacked")] + [DataField, AutoNetworkedField] public bool OnAttacked = true; /// /// When true - disables power if a window is present in the same tile /// - [DataField("noWindowInTile")] + [DataField, AutoNetworkedField] public bool NoWindowInTile = false; /// /// Should player get damage on interact with empty hand /// - [DataField("onHandInteract")] + [DataField, AutoNetworkedField] public bool OnHandInteract = true; /// /// Should player get damage on interact while holding an object in their hand /// - [DataField("onInteractUsing")] + [DataField, AutoNetworkedField] public bool OnInteractUsing = true; /// /// Indicates if the entity requires power to function /// - [DataField("requirePower")] + [DataField, AutoNetworkedField] public bool RequirePower = true; /// /// Indicates if the entity uses APC power /// - [DataField("usesApcPower")] + [DataField, AutoNetworkedField] public bool UsesApcPower = false; /// /// Identifier for the high voltage node. /// - [DataField("highVoltageNode")] + [DataField, AutoNetworkedField] public string? HighVoltageNode; /// /// Identifier for the medium voltage node. /// - [DataField("mediumVoltageNode")] + [DataField, AutoNetworkedField] public string? MediumVoltageNode; /// /// Identifier for the low voltage node. /// - [DataField("lowVoltageNode")] + [DataField, AutoNetworkedField] public string? LowVoltageNode; /// /// Damage multiplier for HV electrocution /// - [DataField] + [DataField, AutoNetworkedField] public float HighVoltageDamageMultiplier = 3f; /// /// Shock time multiplier for HV electrocution /// - [DataField] + [DataField, AutoNetworkedField] public float HighVoltageTimeMultiplier = 1.5f; /// /// Damage multiplier for MV electrocution /// - [DataField] + [DataField, AutoNetworkedField] public float MediumVoltageDamageMultiplier = 2f; /// /// Shock time multiplier for MV electrocution /// - [DataField] + [DataField, AutoNetworkedField] public float MediumVoltageTimeMultiplier = 1.25f; - [DataField("shockDamage")] + [DataField, AutoNetworkedField] public float ShockDamage = 7.5f; /// /// Shock time, in seconds. /// - [DataField("shockTime")] + [DataField, AutoNetworkedField] public float ShockTime = 8f; - [DataField("siemensCoefficient")] + [DataField, AutoNetworkedField] public float SiemensCoefficient = 1f; - [DataField("shockNoises")] + [DataField, AutoNetworkedField] public SoundSpecifier ShockNoises = new SoundCollectionSpecifier("sparks"); - [DataField("playSoundOnShock")] + [DataField, AutoNetworkedField] + public SoundPathSpecifier AirlockElectrifyDisabled = new("/Audio/Machines/airlock_electrify_on.ogg"); + + [DataField, AutoNetworkedField] + public SoundPathSpecifier AirlockElectrifyEnabled = new("/Audio/Machines/airlock_electrify_off.ogg"); + + [DataField, AutoNetworkedField] public bool PlaySoundOnShock = true; - [DataField("shockVolume")] + [DataField, AutoNetworkedField] public float ShockVolume = 20; - [DataField] + [DataField, AutoNetworkedField] public float Probability = 1f; + + [DataField, AutoNetworkedField] + public bool IsWireCut = false; } diff --git a/Content.Shared/Electrocution/SharedElectrocutionSystem.cs b/Content.Shared/Electrocution/SharedElectrocutionSystem.cs index b228a987af..e36e4a804b 100644 --- a/Content.Shared/Electrocution/SharedElectrocutionSystem.cs +++ b/Content.Shared/Electrocution/SharedElectrocutionSystem.cs @@ -23,6 +23,20 @@ namespace Content.Shared.Electrocution Dirty(uid, insulated); } + /// + /// Sets electrified value of component and marks dirty if required. + /// + public void SetElectrified(Entity ent, bool value) + { + if (ent.Comp.Enabled == value) + { + return; + } + + ent.Comp.Enabled = value; + Dirty(ent, ent.Comp); + } + /// Entity being electrocuted. /// Source entity of the electrocution. /// How much shock damage the entity takes. diff --git a/Content.Shared/Power/EntitySystems/SharedPowerReceiverSystem.cs b/Content.Shared/Power/EntitySystems/SharedPowerReceiverSystem.cs index 2bc2af7831..b7ba2a31c5 100644 --- a/Content.Shared/Power/EntitySystems/SharedPowerReceiverSystem.cs +++ b/Content.Shared/Power/EntitySystems/SharedPowerReceiverSystem.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using Content.Shared.Examine; using Content.Shared.Power.Components; namespace Content.Shared.Power.EntitySystems; @@ -8,6 +7,9 @@ public abstract class SharedPowerReceiverSystem : EntitySystem { public abstract bool ResolveApc(EntityUid entity, [NotNullWhen(true)] ref SharedApcPowerReceiverComponent? component); + /// + /// Checks if entity is APC-powered device, and if it have power. + /// public bool IsPowered(Entity entity) { if (!ResolveApc(entity.Owner, ref entity.Comp)) diff --git a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Airlock.cs b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Airlock.cs index ff6fc1ece0..37e5cd6e6a 100644 --- a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Airlock.cs +++ b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Airlock.cs @@ -1,5 +1,6 @@ using Content.Shared.Doors.Components; using Robust.Shared.Serialization; +using Content.Shared.Electrocution; namespace Content.Shared.Silicons.StationAi; @@ -10,16 +11,84 @@ public abstract partial class SharedStationAiSystem private void InitializeAirlock() { SubscribeLocalEvent(OnAirlockBolt); + SubscribeLocalEvent(OnAirlockEmergencyAccess); + SubscribeLocalEvent(OnElectrified); } + /// + /// Attempts to bolt door. If wire was cut (AI or for bolts) or its not powered - notifies AI and does nothing. + /// private void OnAirlockBolt(EntityUid ent, DoorBoltComponent component, StationAiBoltEvent args) { - _doors.SetBoltsDown((ent, component), args.Bolted, args.User, predicted: true); + if (component.BoltWireCut) + { + ShowDeviceNotRespondingPopup(args.User); + return; + } + + var setResult = _doors.TrySetBoltDown((ent, component), args.Bolted, args.User, predicted: true); + if (!setResult) + { + ShowDeviceNotRespondingPopup(args.User); + } + } + + /// + /// Attempts to bolt door. If wire was cut (AI) or its not powered - notifies AI and does nothing. + /// + private void OnAirlockEmergencyAccess(EntityUid ent, AirlockComponent component, StationAiEmergencyAccessEvent args) + { + if (!PowerReceiver.IsPowered(ent)) + { + ShowDeviceNotRespondingPopup(args.User); + return; + } + + _airlocks.SetEmergencyAccess((ent, component), args.EmergencyAccess, args.User, predicted: true); + } + + /// + /// Attempts to bolt door. If wire was cut (AI or for one of power-wires) or its not powered - notifies AI and does nothing. + /// + private void OnElectrified(EntityUid ent, ElectrifiedComponent component, StationAiElectrifiedEvent args) + { + if ( + component.IsWireCut + || !PowerReceiver.IsPowered(ent) + ) + { + ShowDeviceNotRespondingPopup(args.User); + return; + } + + _electrify.SetElectrified((ent, component), args.Electrified); + var soundToPlay = component.Enabled + ? component.AirlockElectrifyDisabled + : component.AirlockElectrifyEnabled; + _audio.PlayLocal(soundToPlay, ent, args.User); } } +/// Event for StationAI attempt at bolting/unbolting door. [Serializable, NetSerializable] public sealed class StationAiBoltEvent : BaseStationAiAction { + /// Marker, should be door bolted or unbolted. public bool Bolted; } + +/// Event for StationAI attempt at setting emergency access for door on/off. +[Serializable, NetSerializable] +public sealed class StationAiEmergencyAccessEvent : BaseStationAiAction +{ + /// Marker, should door have emergency access on or off. + public bool EmergencyAccess; +} + +/// Event for StationAI attempt at electrifying/de-electrifying door. +[Serializable, NetSerializable] +public sealed class StationAiElectrifiedEvent : BaseStationAiAction +{ + /// Marker, should door be electrified or no. + public bool Electrified; +} diff --git a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs index c59c472307..e067cf3efa 100644 --- a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs +++ b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.Held.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Actions.Events; using Content.Shared.IdentityManagement; using Content.Shared.Interaction.Events; +using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Serialization; using Robust.Shared.Utility; @@ -13,9 +14,9 @@ public abstract partial class SharedStationAiSystem /* * Added when an entity is inserted into a StationAiCore. */ - - //TODO: Fix this, please - private const string JobNameLocId = "job-name-station-ai"; + + //TODO: Fix this, please + private const string JobNameLocId = "job-name-station-ai"; private void InitializeHeld() { @@ -26,10 +27,10 @@ public abstract partial class SharedStationAiSystem SubscribeLocalEvent(OnHeldInteraction); SubscribeLocalEvent(OnHeldRelay); SubscribeLocalEvent(OnCoreJump); - SubscribeLocalEvent(OnTryGetIdentityShortInfo); + SubscribeLocalEvent(OnTryGetIdentityShortInfo); } - - private void OnTryGetIdentityShortInfo(TryGetIdentityShortInfoEvent args) + + private void OnTryGetIdentityShortInfo(TryGetIdentityShortInfoEvent args) { if (args.Handled) { @@ -40,7 +41,7 @@ public abstract partial class SharedStationAiSystem { return; } - args.Title = $"{Name(args.ForActor)} ({Loc.GetString(JobNameLocId)})"; + args.Title = $"{Name(args.ForActor)} ({Loc.GetString(JobNameLocId)})"; args.Handled = true; } @@ -108,41 +109,56 @@ public abstract partial class SharedStationAiSystem return; if (TryComp(ev.Actor, out StationAiHeldComponent? aiComp) && - (!ValidateAi((ev.Actor, aiComp)) || - !HasComp(ev.Target))) + (!TryComp(ev.Target, out StationAiWhitelistComponent? whitelistComponent) || + !ValidateAi((ev.Actor, aiComp)))) { + if (whitelistComponent is { Enabled: false }) + { + ShowDeviceNotRespondingPopup(ev.Actor); + } ev.Cancel(); } } private void OnHeldInteraction(Entity ent, ref InteractionAttemptEvent args) { - // Cancel if it's not us or something with a whitelist. - args.Cancelled = ent.Owner != args.Target && - args.Target != null && - (!TryComp(args.Target, out StationAiWhitelistComponent? whitelist) || !whitelist.Enabled); + // Cancel if it's not us or something with a whitelist, or whitelist is disabled. + args.Cancelled = (!TryComp(args.Target, out StationAiWhitelistComponent? whitelistComponent) + || !whitelistComponent.Enabled) + && ent.Owner != args.Target + && args.Target != null; + if (whitelistComponent is { Enabled: false }) + { + ShowDeviceNotRespondingPopup(ent.Owner); + } } private void OnTargetVerbs(Entity ent, ref GetVerbsEvent args) { - if (!args.CanComplexInteract || - !ent.Comp.Enabled || - !HasComp(args.User) || - !HasComp(args.Target)) + if (!args.CanComplexInteract + || !HasComp(args.User)) { return; } var user = args.User; + var target = args.Target; var isOpen = _uiSystem.IsUiOpen(target, AiUi.Key, user); - args.Verbs.Add(new AlternativeVerb() + var verb = new AlternativeVerb { Text = isOpen ? Loc.GetString("ai-close") : Loc.GetString("ai-open"), - Act = () => + Act = () => { + // no need to show menu if device is not powered. + if (!PowerReceiver.IsPowered(ent.Owner)) + { + ShowDeviceNotRespondingPopup(user); + return; + } + if (isOpen) { _uiSystem.CloseUi(ent.Owner, AiUi.Key, user); @@ -152,7 +168,13 @@ public abstract partial class SharedStationAiSystem _uiSystem.OpenUi(ent.Owner, AiUi.Key, user); } } - }); + }; + args.Verbs.Add(verb); + } + + private void ShowDeviceNotRespondingPopup(EntityUid toEntity) + { + _popup.PopupClient(Loc.GetString("ai-device-not-responding"), toEntity, PopupType.MediumCaution); } } diff --git a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs index 17c592879c..baef62c3da 100644 --- a/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs +++ b/Content.Shared/Silicons/StationAi/SharedStationAiSystem.cs @@ -4,14 +4,18 @@ using Content.Shared.Administration.Managers; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; using Content.Shared.Doors.Systems; +using Content.Shared.Electrocution; using Content.Shared.Interaction; using Content.Shared.Item.ItemToggle; using Content.Shared.Mind; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; +using Content.Shared.Popups; using Content.Shared.Power; +using Content.Shared.Power.EntitySystems; using Content.Shared.StationAi; using Content.Shared.Verbs; +using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; using Robust.Shared.Map.Components; using Robust.Shared.Network; @@ -24,23 +28,28 @@ namespace Content.Shared.Silicons.StationAi; public abstract partial class SharedStationAiSystem : EntitySystem { - [Dependency] private readonly ISharedAdminManager _admin = default!; - [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly INetManager _net = default!; - [Dependency] private readonly ItemSlotsSystem _slots = default!; - [Dependency] private readonly ItemToggleSystem _toggles = default!; - [Dependency] private readonly ActionBlockerSystem _blocker = default!; - [Dependency] private readonly MetaDataSystem _metadata = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; - [Dependency] private readonly SharedContainerSystem _containers = default!; - [Dependency] private readonly SharedDoorSystem _doors = default!; - [Dependency] private readonly SharedEyeSystem _eye = default!; + [Dependency] private readonly ISharedAdminManager _admin = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly INetManager _net = default!; + [Dependency] private readonly ItemSlotsSystem _slots = default!; + [Dependency] private readonly ItemToggleSystem _toggles = default!; + [Dependency] private readonly ActionBlockerSystem _blocker = default!; + [Dependency] private readonly MetaDataSystem _metadata = default!; + [Dependency] private readonly SharedAirlockSystem _airlocks = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly SharedContainerSystem _containers = default!; + [Dependency] private readonly SharedDoorSystem _doors = default!; + [Dependency] private readonly SharedElectrocutionSystem _electrify = default!; + [Dependency] private readonly SharedEyeSystem _eye = default!; [Dependency] protected readonly SharedMapSystem Maps = default!; - [Dependency] private readonly SharedMindSystem _mind = default!; - [Dependency] private readonly SharedMoverController _mover = default!; - [Dependency] private readonly SharedTransformSystem _xforms = default!; - [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!; - [Dependency] private readonly StationAiVisionSystem _vision = default!; + [Dependency] private readonly SharedMindSystem _mind = default!; + [Dependency] private readonly SharedMoverController _mover = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedPowerReceiverSystem PowerReceiver = default!; + [Dependency] private readonly SharedTransformSystem _xforms = default!; + [Dependency] private readonly SharedUserInterfaceSystem _uiSystem = default!; + [Dependency] private readonly StationAiVisionSystem _vision = default!; // StationAiHeld is added to anything inside of an AI core. // StationAiHolder indicates it can hold an AI positronic brain (e.g. holocard / core). diff --git a/Resources/Audio/Machines/airlock_electrify_off.ogg b/Resources/Audio/Machines/airlock_electrify_off.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c88d00299e9215a647c144f514a18d7dc5af7a87 GIT binary patch literal 9989 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 Jb<1i8_&>kkeoz7lH{C` zpdcB^AcFEXc<#OD-S^i2@72?*cUN~+SJhXwt3k!wTphpy{(f`}{|s{UZ)ZW6A#V0g zMwZT(Q;-M6e=m6fxf;|#R4#Y^`?=hCNfBvKA0k)1_`jZR>_3b|K>8C)2a8)OPUcV> zOCzl-_D}_=kbsbYz#Rb*C^yQ~#MRi+&K&yC&dt)v-p1HdzO7+I{D0t|!Br}XaE2Q@Zlzm$X-#f8jvuj=ZbL3kg$9#o(IJbRa=xGY(3&Mw#%)`wYD38aS)K| z-~ynr;PNbi)TqnOD3~RP9_-#QId!q*r8*Ju?-?wYE+`b!VlFolr_P}RbSi9bkfar(#=yRF;K70Q>QLaZz@p# zB=9+X(BJKc=fcTlyHXtr0W#Pm;+J4qtk<)?N@QUN1QlZeCYL6G62`E?VzL!-&8$i- zQ)(=VYHWKe_QIcmOzP%TJC>pB&jAqS!w< z@!?-txa-o}a1>vMlgJ}ykx$Nd!S=}IK{r~d|4`}LznpLh2mpW!GIcmIb%WMG@sB!* zYCB6$IxA0trnt1o|NQt~;RRHLCCx0}%7;KW>iLyfd_cDJnFO*VeBWWnvc|d_A8S`iKk}?Iqq+kS` zV^~ck>tuKiuCp9T#xIzD0`AorN?ysYrv^tM=oGH%dW}E){)RaL*t2gNxtp*%g@m3>0Je3xBu+koU|SsS@5i6Dq#K2Z?G z;ngeY&ZQFa)|l!EU0w_tg@j@LL=@;$s7cg)Jcg?v2}*S8f#rcw@lVI?vJX<+82(2a z++$LsE#-;o1=K@)HllW3zb z!B46Fj}e4_9Q?1yaisnf&D0&uu2{jYJi^z%FQRfFGEDVQO+;CpMt_*bb(GdrT}*#e z)O1wSbllB!y2ezm)>EhE?|}IeHVc!k|A?H+5Mh;wSdx#y`A_6za7TOL;Zl3b9KzFv?;^k0!<5t^46nim|p8XUnL5^oujTv(rF(^I1>Hj%m zK}Y~j3bxQcquh|M4>weO|KZ5mP2VAQUY!Q@WCH(=1>$31WpYAMkFXASRfiT z09%Pd^$31rLLnvcQq>0}2yO)Q2;!yrlfy7f>I1M(OaXoOzoq&Q-RA}XXbS}VA-F|M z9s=ZCz@h{DV62EDHHRYA!$E4(Nh;;ZIFWu4Q8f+CUMkIT4b53vWz8B6Wh!OmLk&%; zhnh5+qw&g`)wY8orqddlbF`Y{HKwz)UfS`l3&P4e;OhiPb)Ag&G@P*2PyCyeGW8WJ zG0n*uQ8gD$HBD0;4NV<4Q=Jn{?FmmskgBdcO{1wETp|G^HsAB7q z+EB9D>A2Y-;E@aK%`Mt!C}?P~+iY;`tFdLuF5GD1>1{3Rso2?UxLxJSqNeFOht^-x z2KBHte37nq5?Em?)m(Dc12P!-Au(vrR1a>ev||M4IuCedo{L9d%#*>B7M7$G7HwA8 z@wOFjBGfcJ_2Wzz?&#~#*)80O(3=d;D%@z`>1_f934ZRhXL>Kdq(3VL64EM4h&_$F zP6!9BXFDCwB$tj|v)_>reu@OK0lCBmRS!Iqg%`_590K66tWv9!^K?L6$Wa^691TG{ z7U##v4kolJ(uxH=#?uMah*0QCjip3dz|bQo{7j50(mE48fwC^o9W&a7=FlQ7`Ozb~ zRt247x?vQ?IvoRP9QxOMG>zl4>n$tCCJo zI0uGa5m{bMYi%dEavf<|aw)u^gH|sB6s~S9nmb{2Nzk*Eo=A2^mQ0MH!a;(u?T7K? z*E|2x+{lW*bHb?PQaDd}Tns3DWkxql0zF~`vWh{4fjjhU>T~0*KteL=ZS~5GvyJHS zm~Qc<3`Ot@;T&0iqy=UjA8Y{bLui_DnL;kZ_I@yGK*5sSsZWB35YZ>WRp6wAfWb8T z?h|lS4@kgZ9TO4+92ih92|_hT0gkExj`tf``F);667jKo!XY3nWJ>aA3fymxu|h=WK@1Pnf_1 z{mCQGNQ_7XgP<-NLOc`!N=U8(U(li@t{@aJ9eui1B~?>!f|9@qAw>=l3T7qkiMqT1 zumv7y>ne|M08#h=oIV?rD`8G<)F-jVBm!nerT{XY&QyOg1OW|r4DegkCjoZk2#^5Q zdzt=Vhe3~A5>Uu>C^!ehxLgv@C?WvhaR4i#GBp!tzvv7wXJP>_FLNeR0zVTi2kV5Q zV^E+tP^AJV63})XT9*X0?iLh;hK;BjIS8vxU0GyF#}n&P7R-cEvFIcS;_8)TYa~dp z?ym=c&$#$N88+iXF)n&S9ubo(C48Wu8N&pFsEtAeS5svPU>%8Ijgw1%S$cpU*~|JP z3?zWBoghJCmFcoeb&mK?Ve+35;r~a80a{ufAcry_`aDmUL^++6cotW=ZM{+W-&}&NsPmFgXAPBaW69Bp= zQx++~%>kkW1_R*(Ml@O%ndFQ@@o-?`FH^^uE|MSQjn9FZKv{uOBndE8W0#_)?#sh4 z6S{Bt!H`3OuSQ{_K`3xZ$COdAV9p2%j8A&wVlaSot-+&P^TVnqjKZox`-2%`!sxB& zgf20#Xy*X<$d@?=#pP7C4liE$nguMj5m(l}ycnQBUu0aOh2;SfMAaomSOP#d{Fw`g z`u7~U%ptS6~dF1WP$I$obD4ni7<8 zRo@>eYyl<>gGdkuR;-suo>Hz=s3? z9H*={VG~`@j?{p7#egU$a-&-ms8ESV<)-os9rWX9K@7Dz%6cu;C`?Ty%@`@zR*cp{ za!31(I2BjB^?}zxC;=cq&LZp!hfvdZfr0{XU_eG$%aGtx9GqoJAtDl@PXW#&me>G! zKo?1L@DmbBszTo^BT3-N(`Q}yJ|yAcRd0#cgj#U*Kf6K$pg1hS9T4g$AAc%4_phWX zbsq^OA7aS<+=?LpGXTVpLRndpB_hZouSJnZQ^ZilQlUZk0>C1~=NjO{jvE{tY!;E- zwuH_8z$752eHn-2ihS7-5d68S;9QOW+?wHvf5?}&=1Varw@Wo{a1C<{3yTR0iwcQ| z%*{-G9vv9!?5MA;tg5c4Ze;&;P7;i{3&%?iw50#&y=6bgXW(`8bDcqG>IwU+eUn=e zOYn_&AVyQ9{JchB(I;u6ZT4X8TbJx7IQ$5CjKz`}mq*`XFsJp={I|8bK-s>Qc=LkG ze$@RzX}j-D-`_0CAE_0vvwpwG@)aOCUs8hz+%tE`?Xxcgpn9Xav1As(eH#rsW9962 z6Z{esyq4t~l0g}ZKMndVClwF%LVmxdrIHg+3Tuf~KbXx20LtT1^$>&ozqTnVitZcL zvk@lF-|lsLoFlc&`o-S44*G;wyS)9Q6JqFT{QKOnI~Q_l+74yRugOKbZ(_#IGw#=w zDC>^s#gYS0PeHw_Y1iZuoe2-cGh{`>d380#zZXtcY`y4V?? zAcB=JoaEsc;g}qvsp)Yy$kp+(e|1)H|BkB^E72O7bxvJ!ZM+6tbcpVV3lBm1a78oj zx)Gl-N;Py`r~|Z-$`8p}S+z&CCKZw;$uBLpN&>)D>@ zx+w#{<7p_5a>u0ndQ&WUfmlhIBz`5a%ViLzHw)j?MZSEM9Mj$O+J4)Ccv{UFf6Z?~@}2pV)bDWxD%^5N4um+2 zH2xcQl||A$1WWjbAE$hV#|Sr9Et*NmTMy&BYUw%nW}ON=I;ps}lhd3F&H&$nvlw7QOECp+{m~q6bRhpV?pX;3WHg6tYe~yiV2YZ%b zbFQ)#$~R@h*3(h6v%j6kxmjGscxsleIOu9aVNd$%^D?u4xo^L`s6O>YPZBVr)rZX_ z4vq7kh>cb`!v_}Q_#t7M3XF<%sMeq+i7tZ zDXY8p+^Rj%v-F(aty^Gn=EaaZ&w^q50&Yo~DmnF_j~GoC;q!M=7kH_@oy0nb=!yAH zZGn+v+Pl|Rs*?{Toe?U+8pf8Mox{wj*=S=l2ca`RY(O^b*xWY7#{K@3AxdS`$F*g4 zpXP4ljLmMhdnzrHO}t%dQ=%{&+v2q1oL&b4f5VeFT)HbjTl|1y@&V+*o0zU5;*6vS zokon|O=5|uW6>2uiUoLKA}28aXqkl~HuA~%`QXsh@hk6c?XansPC{JbFn!Go`^NdY=mI?Y7hOT6!ZU;+@f#{cF@91*96Qy8{(CBD z$GDC~*&)sT*|)p&BQyi~k-c=G28*0-LCqA!WCtEJN}hYlXgKU2W!ta$FlWE#jb8-R@mCob5se{E)6Jx$Y~ z6cx>ShHc8%pjFo&Mu@qk?5s9Hxt{)&xenXlNx)QS-|wN5jX+~Y>1OsAZCb@|jV}P^ zHJ(&<)Gre(tU*El^8FCmiJP)oc98_y{fD--yieCL3LAEjy`@$z9PPAQtfW7;nYP&2 z*FLu6mY+#A^8t(dF0>K2yTjdVqggWtv?Rdh&GlQsFLIDJl?r!*)=wVol_@h%wMzP~ zBwaV?|6*`UgjJwqWva?v4Yxv5nKMd$s{?JzKI|y^8)jwmqOgwT6f)XRb)Iy}jO)?P z;JTFg6I<>LZtj@!8x5jsJGw&yPL4dTu{%xK16KK zHMhFib9l|(7o?z009zMthEhVoS9~HdAF{)tLBaT-H$J3I^2^*5u@@{$ zDh#upKV#Sqsqg3f2yjSnQy5Wr)S@fk{_LekBZK0eYj~`nD3O2LlRH$S(s>?auPWRd zef2&X=?hs*+i=Esj+$}u4$wgxwi1+jDTXJ)vUGMr>3DXn@0{3IyGU~1npHHGed}*e zN5d=AO-X172u8mslWH|}Ukied2@E=(mxTtjO0yD{d@$5c3TLb`8vRhKtR?qCcELCO zwPE0O59&^ApGX~bJHEKxPG&Ql=(+t=+mRvsEzy2Q$7Q^pQb3Tu8VX5&Qbiw){)LZG zWjOeFJ1G{~u*e$dVQDDLnaLq=LREbvwK>{aee<~a}wPR zeQTpSy)ljVJk<~Bq<}V@{0I5e8f(TkXvG<~H*L+MERR-#o{OlB?Bq10#tN~ECB#&Y zKV;T^71!lrJ1b_Nv)OW?TiSA+zjC z+MOEF=pc1bzAjL0*NewTFV03%qSepaP+M@wX0R~ZPhOeGQc-Ew&t4Y0SA-bLG7mR! z9>J2k{Us)v7003f0ha`o=-UC#T{Txa<|3-=*TR2$qKYiZluq7#s7a7dU{;L^Jqj4; zf7BQOZ+>B|#hW3UUS3BK*Xv-3YeSjxCi~&S>B?}d(I^zsw7!h{IR3W^o4gm3Fv&>* zle?m9zSG)_K?)w{2tJk>e6cOUr}zZsb*{hhYdZ5K$6Eh*=-~eAo7lgSnQo1eXO0Kk z=*O{*3mxSIOuEW_n%0+r!}EU5zbY;XHAuO=sC16@mv5@Q@koy6USh{Eh2zix&#h-k zi=>CTN33*+mvSt&P?joyn?L&%uH`Y|FVr9^2@4W6f9fCqUgZ@QGW=M?S7ZQtYy(NVXoe^5~|o$ZfC1 zZ!E*5neXtltoeIZTkiU_zt}mP`<&SFt@=)0ih#^Mo_(hUjsSQ0mUp8E0%&nhyDm~0 z*H6bNd2izZWyj0~+46UpqSLnqBL#-4`-r0(4GMY?iRj+|5)#Ya6l;FY!kjQS<>4l- zYqLOERA<xzJ1%11Ij7eyM5x}G+`ZaM-VNT2Q#qFDCEM|s2|R}5culTxWV zVUp`I)|ac6bN&MVg@#)p@>?<^*Iwt>XilO!mHXGF9`V;1fuE{a(i1-Ar{27i@OCK( z6195bG?D3Jy#DEH#~qf4D&2yYPDy>;+P8=NJF!o#dDL&b*j)>|zJ!k${_js|5ggs!KwZ(GLgt(NSi7X}&%9ryDWJi+k|11NN^kq{U}p7g6Ge;n z0k%aC4sh?332HfXfp;TXKC$^Q?i@}dR?ki6S9)W%YV+qbco|F7=&|HXPy=!)Z!S{^LO~Q|4k-5U6G2-`@zGqLyPyw=F_$X<>&z5y$ zym|9+?us`1BgefJDCKR_n7<2st{kkVD%YYhDh|opPR*s%&4}|iE z*Q>O?4_wtLh2w_&!fU_Y(}tGlYPUxFk;bSaN?xSH`dM!L*zu?EP9*WZ9kQ%XD+_&& zo1eH*pdkYRu!!hAG#9PcTO5->38Crt=58Ap<3nD?Tg1(c>JsG8w1IX_YzVsM) zA3;bBcro;Iiv(X#MSV?}-aU#L6n|9a8&Fdiqvk{l$%PLMQShyArijt2$$gh=PV_!- zZ^+xbTe+@o8Cp0T9p0Vixcw55_QC3nUa?If5d=(AK37r{>{8k~=yZS%Pm>6{Tn~sugGMrIq#1j|qCo zHzHbzpWz#@?C&(lCLDb`EWPOSA_VRx!i}-hPf57LqA#SOzpxMJ8ka>6?+_VS>|y3zwX(Kl#%97Fp8L?U;H>1o!ofez`(mLpQnVzw z{xl}iWWoVZY~R7V*Ke-GUi&!6Hg1HFH!z*X!-)0$_qL90;t#j>yWxI2SZX)?3}t2p zUeZuJ=4h|Ru=&#I9Hd@JeOZ-R|Gf< z`|Y(}ML@pneUsh0uO=@mp^^Q?I+SuRkt1Up)tr+fLoR?T|BXFTx_YmS$zEd?3IzOqXE9^}dE zKvl=xueG*v{8o|B?r;{(68D>HeR;9$g?i6E0VC9tqqM%!Jh?m)&(&SSrSvN}xq!dP3*a$7?!o7c3EkliBbKY5N-Vph6*CqB=0R=R!T>$I|um+Y+tw{>zVc z$4|^4Q@~6iJNA$YCje1z2~L|24jwGZN!dL=>^a?ukN>=_U5yC5ho@Xrhc|6K)~M+6 z*_gfh4k57&^*aOP$eQ9tj@PTqgCFpNSOmna?5?DKvadEZ*B+gQ8vsNq#u0y!ocIhBkJSa>hV&)`omnv z9PapIc*GNIb?)(M4!PHoi=8!{6S(d6%ZPObF;`M@pweF^e5WIjd&Xq#zPPDp{y~W} zH{eyTkrXCyLF!N>$@u+R^k>|Am>ztkeOq3xrbAyi44%`ghhR+N)0@@XCSOILPL91` zh+ocr-AG?xQ6UR>@#~Gg;C=^2agf~c8`X6S$Q5>j9weS&yVT4T{kIw z9!Gv;PGM)*qgFgSSmuLYd~%DxI7N1Z)~{y6!rut1iGb9X`1k@R=TMf?PEsD*E58qm>c_RIBjr%B&xX6#(ee=p;ENT{IVd@>+CuRu~X{k6D{(>TA=!{y|o92H} zKGp~>xU)o#TcRx{!MYm!*VNYGlf!51Qm6&Y?k{og#f#4$NrxO3TgGoJA|=j5^n-~i zIfg9(FLwFAUmZoO1ENwB~kL}&pNYPskW|`JUqrKCg^8jdv9^7BBvRg9B(r*ZIG?wy-zC| zG7z%Ht2RT4XNDXRw|HA8mL31J7Q3Cqj}?0@>g2VD$a{JRwucw1g3t1msZT?38M=P8 zu}R#u8>#upo!ZY|K>;X<`mpn!9N#NDC1J(O+|@rCVhd92xl3o{5Qb+UkFzCD|Bz!2 zxkcw8hwa^?60P!MeJk`$GmBTBVy{7f z`3~d#uwNev{VJg5u3KhtDlG2x?`_7hfj3%BH*)b$A3KK-)8m-x_(g~v4t_)SAHwD! z6t|Qn^GYnogB*TG`KF$9FrD2>mbr}*882=>5_C@#PT5u+RNwdeaJ{Nbk9s+nQcsZm zr^1uFEsnfGX9wJwl7U8b6nEd0Ng8mLyPbV4&|PgJ?)oe*t`SzO@_v95tcM;2JX019 zoByW8yK~JuJ;}Eo6#+W{jvN5IiJP!2Oqy+NFltIJM3e}Q#t z-Djhur$Gk(C>Wl8=;@Pdiv_KfzYxy#Zm6e>kYO88nRUo@e=a_k=x_0OS^v8m=0sFy zyp4A1#RvC2^*Y2zL2UWZsZD+7M5{z?&b@t^tY=TpUh6q3Lfe&Nvw0O<7MR520e_7M*JnagXUdyddQ1&8S!{`slm)hyw z#x=$N{_SZc-fo9%i?HSGZN+(GkwZG8d1IdosYkV_QAWRb{(T6OFglOsh*6~j z(d)Obvsw^6onz;UP?9Pgm^q$!%PocImD_qrt=m|?V_`a&J?wccEUeSZ!hyHa`D=Xg zddt1$ZBAGs$Nu{bTzv)_zP?(Hm3iDQuctZOEI@-#+bH;aPTn z+N9Tin2s_?FxH8!BCz>wiMHJHRjJ$`$cK5sBl;ko=$QhSWh@_|_ z4doJrD0DSl)zK-ZPNj1?`tRYK_dWmj_xrrR=d)+q&tA`7Yp=DwYwfkUhJ<(k4*q(g zrDq4;!8>a(O)P0!TtHa7cnafQ{p*wM*v#NE<|q;aUrzGuz>Y5>}ifPQxj7Y6H60wnm#)?C^0ZBI)r8)ofH3 zT`q5{BVE8N)!$LTa}bX@Ofm|186B#DnT*cAJDPcrG5{X9`chftuN}kttU^@vvf}tw zVe6KjrjZW2i>##DKQ9c7uDnD!9Db<5tKDbHH=v;M^aTN$H^gDhvp{q=!$*NA?*NK)cR(jM=Ebl=N+yf3Hwj;8y4P2Zw=;IB5dXY8xE&8SYpfWN>h{{_8F zdtTXdt1^kS17~p%BsK|6Dp#AHTkcr7HM}mYs429jDXO=@u(v^W<`d+8ym&Xj4=b$v zA8o65e(?X@n4#SUz(ls}iluhN>e#b&y5bB;GZyX!I8^$QRya`j>5i3L;VXWXQqfRbhG&u9m8ycG84pJGsl7nH zr1zZc;GY~QjPG-lEfma-b|@5)YO4m(oZ5J?T&LO=^j+9sA*t$t7h3B*Q26@H6(uyv z;1%gLUh$me_ZKXxHWl}^Sv^B5G9DI1T#@oaqi;dQ@9#*7=l&BuOysvMqpF>!_S5!c z5d)O8Dz)-76OPH{@fqFp3eBTgYgkpOZfrF@LBjqS&1nE>lo=HN-OWIG7R430hYfo4 zFWffmH57MeZ}csjsJ}s3Ez3YCHncz}KHB)YB)-ndAwtkN?6XL~W3%Xj*@!|;r3Gc% z5Y=XaH8t`uv*vhmHY7!PpGbUkDcx^0 zacpGI*vQe%a}WF{u>KV}fPyA%CMJ0SnT)RD)OEH}vkv|{a$=Rba;Ud*betM=Tm}vA zd^C6cWPVrC-rd~AL)q`Ha^jFmu*VX=A&cN4PVoJt;0H~?zL)lRH~kebvtctflK79v z5r>GjRn`lKT>QTyhp(UYd}-DK$6Oun+=V;xLoy1hPL{l_DwFbbPf`5~V#n zxC3w*-He;6aea=r_;!5^sZ+deD?LHppd;NVU)7ARTd5HEqPTp}@m2*-)#>o53WdOo zTC@mA=qFP;kgbd{l>h={+0yiM9=nhJI-A|YctvHitWFnu^jS%2r1da}r&1|&0o9|A z-bGEjZS$%)b-+d+fF{Jy&sN_&$Q~$qAd1oH&og&Y(sfd_?^g;QQFIwOZhpty!rhb8 ztH`guZMrl{(=THmra)n(N^4I$NaXL}mX)zn2!AZp#2>ITE=YQvg_vwu_@PBfjVZm#WV zs4uFknP~bTbHi|=Ii|XgA^*s$ACYl#tOw@AcBtGH!z1V>Ch}yip#P@4@L)7x?wSV*=27^;p{oANl(6S5B z>S(U>)1p;dmSzb;3eirhYm2IDCK{p_-8eg8>(1HZcRYB^($9Nt^q6Iq@5s@z>Ytkp zdRvho#^cUy)T<^`zeh_D;Z#Gd%$~sRuTuRHk2+)jSoY#eV);2)sjg!P8<-dyiapFy ztwlKQQVfV%<4PVBgAQ5(h5a+F!jnPNieJa-pz_>U;aa?V2Awp|EXVHRJOx%Loj1rP zl?vQg5v9CgcEtJ0djY@DDpXiuM!Z3v@T$&xKACd@DW>BUL4A%=f{S7TVl~dMkh5h8 zDwLd9M(b}QAeRr?I8;?AcsN!yB36P56(<&>Ny#^wF-%1(DinMj>77a*QAVAG3p#0t z)h)5`85yq%c!<@>)La&;_INJ)c5$AVRcaQ?k=~Tcaz?vivCgNneIgmd#q3B6v@66a zmlbK$>Er9%m`L%Fnb}osrvL>N&u5970ef>5OLVr z9Afu5hEd{fTNy~%-nP=KigUK5(>b?oBy}76tmyQPVJk^pfr^uXQOEiSIvr_YgzAo& zuqC==bYRkCZz-@tQQS#Gd55SbP)!|BtxyW2XbV)4Uj#~l$hNBSa<&F)fqgdm^fWh? z0X?0bb}Po);BuXf}`d%Ld3Y4$u-jO%3LxIkWVtQjkS!6A=^y9k+eL zYcGy6C2P}%O`UWR6t>phEbv(b@D6S0-Ao?Qg=`WqRm+iFs}M@SZL2p_bCemWX>tag z#i??(lFDcs=&ZVJg*u8YBA|M&G!=CM-k_MkX1%4MIl3T0OyIFmwQUfCDx!M#p!oec ze3UbButS_PSyrS{-Wqx*jhD+t;*d&Jak9vE9qYvep3gfPf<~l85(UAk(`PlSw!wFq+m?0|V)ngl;c>g(4orO%Tw6zfQlLxtXr z0<>eIM%n@Tn~F5#p3>DUD}7yr5;`5h2Sqf`hjlWZ%{I^#K#j^ea@r?l)iN`Ubk_F=2F=Yt*8I#loT7y=~^cEp?FfJ}GS zQ-LhTjkCP|vu4TSyR=wLb&2wKWy3`y1HD(C zJ-PDa;n=gMoh@D08_R0n`6bSm>auumE_HBsB5q^q>*5=GO^(JYj&Epx+w;_7*ZYfm zPrdQ^e8=KXYoG>vJ|=SC5ViBhjy13L-)wtbQG1A%vqWKN`Xh_6dv0k$h2s^+4udbO zd9YJO!&5WY`05voaLGwW>uSb6l*GQ?l=A1>tODU1e-e(GkW3+wm$jsFiBF!{Fyr4$ z(qus$V0cCU?N6sOMUOqR?ncxa7#Ju6*O~xcuW?XshNg(%AA$oDb>QB`gTFC=fx_}Fh*D+Qu46gp^YIMCFye`f4befg_X;`JY% zmbzUJqMws!`{=Mw5A;{U2qtpDCA=45Qlejh$0h9mxtlgAav`ZgKq>Yh5j2o5=0_TZ zFo*z|tQY8?3E6Zl0Eft89B_U1k^w}YNAb{Ii00-Y9QL5x5A|rHa6Jm(G6{s25Q_~M zETyA4FnNfBm^M6Iejo=X(@4Xon!x=9U^h}K5}5_@L)J*X2$Pr60Y(tB{rZUOlqrB6 zKnw;eRi4mxmz=Pz4gNK{OF}07%#(I`heT%{jFI{BI!XoVLYsr6*a7U21XS9jgxzQZ zlLX-bB0N+(TJw`}#fjgp1kD-K{@h)a;LPA@!|xiv|1ByTmrQZn4{r07VRF|ONC18- z5xgGbVNIYJGWHjM?+BA*(kH4q652*#3d^~<(kAx;uZ%x5LgLyH(P#o~ogIy`*fn}*FxFt9` z4cU61KKCYQ!~L%*AEDQC%gH;+K|E=ShcmucpoE zei55oe3X;9fVMxdr+6$Rq`s;_vZ~|2Smyf`#+yno>y=d{P?jIddO8xEuk`(jGtfayqD2v zMA&erIo9aHovmxtpQ=nrPnSb7Srid}(sGT&Xq1J&d!^o1m?8?lL|s!k#KFBV=dOU_ z`LNA0nN@m5BgPA-Pn>3?Z0CsZg)8wvIe(T0P;Cc%g!b?>_aB(i}uB}^UiZfAu zcyJld`CUvGzqCEY@_k-)W^Yf68_q~w)|Ar< zcQUg{RVZhhJr`2s+M1eilgV?1awJB|wq49m&*Yfa^WCPJ&J8~F@CVVgG@7btBU#8% z7tR^ICT$`k43{wcB7CnPl;`FVMo+>Q_(~Qn&u#xqp48>8vO`fqAx{Q#f56iPDc=>C zI>PNd;Vyip8Fw4^x;CZ_0YXcio=c<_B29sYqbZ2gML5`dMp^Xn>ZX_T9DkE*d?opZ z&36gV@nlt}OxTc=20W!|GzrU`i$mH|SGX>4nb%jbV_{2Y1a1)Hp3mw~ZqWn>{Y$zA z=W;;R3eJ1>y*Mr}tkd@oxuj#0QuG5OrU)K9#KwsiKUhXP?I!iDR~Ks4v`CD~nmmu# zaghM&8png|_-t;d8*w=|Ps)Ew8VP$EiA7S9mHp*m@8iw8PImA9Ag%tWeY?&JYX#9< zw?BGAKmOpJz9Ma(vSIPGdbolyr3H5gp5Ek;3nveM^p~+SNhZ<2Kq!GU6NrAEAG+Y! za{Au(wZHr-4{pl7K7Sgcd#lnGl8m|=)uR7UefcSQ4b7X_8zCwn68xCUU~*?*EKP|8 zj{A})R%7t^p~Pk>Qt|~jE)6GWJ{vKvGH!+Bl46LK@YkA0C3?xk1okEf5iI%o z{GM{*a@M4MU;a!==2oKbGICiF|3mJms&eDJ_DiQ`1BHrASk5V!!I+S}^Xhl+MBk{?Ku z9Hd|^=o|wz4EAn+b$?>VwVcK_a+1udsXtwX)-jiGW0d>My(uIerIr8eY9C~KSty2f0D4}HT8$AGxr^}O;1Zqw_ zKeFm{OYG!R;SS@VO5=0UdoJ`9nkIMMQyN=eSy`VRYam}QJ^9H0r8|t_3{|-E*PCFi z7=^oThx_)X%ZUl)MT^bj6(<$oI__|OU&E-o%C~iMu9Lfk^IgVWhi*i+4P`8SVbMkw zZLIURcXR z{$y;vH`8=Y$K$>6hN(vJD{{j6v+}I>kzY5cI{Pl|IZ9UPv@rAUwN!n#uBARMr=w?E z>J`H!?}ZC{Zv6^ zyJG9-v#YCyI<6Xjd^t5hC?MgvWdFg$d~0dAEpeI^F^A}K@RpHux|i_&{N|uWm(2tR z!qk=`)r*vF-BGsV>*qpyn&K^Yp?b*?*W?b7 z_3b`8hWqoeHzhkue_glI*)C6OvF%y5jqFN?xd+Y_PLp5n*=h5#)WuLK%OOg!^O`Mh z;djW|MkUuqoRKa3PLRMQLo4ak@q@Yp6ybq~d4cKku%pqr*qi3cPiGS#`HN4$kFICU z2~ln>tA;GM-BB1DKX-q3(s1Q#hWyVJ?~RkvBT7u)_7@J=Qa{Zf5p|XLFm>e#FE}}l z9^J+LYh21ytFJR_@tqweznQNdD6h?TX6e++(g^QHx?AkQZs&^&!c7`#Dn|O-WQ!Mz zOwob4w&B|7$`X7H2ym`C^^#l?*j)H1ec&hMejzJ0oU-i11K&Bf$*^hk<-m}%j?!e> z!<>U}L~d-E%k5r{g2P614Y26ZDE|EX-Y=dW=cbQ7kooTPUVr|_J==z=s?Deewgq>* zVxlBiS7X>Vcw^g=y4$ZH?&K}0b$3n9Kkeiz{m46NoJDlm7i=Ri8*TWla79`0j>TB@ zCFq*kc z$?bQV=06Br{UEn@_puN)3uaROsj6cxE3Q8p)0W?N>$yT{aK1&^)(3Cjnz==Pl(;!? zt;jU1j<7Jyayc`przbJzmj0fvDnYUCCKZX8fyq_NJhxECJ6m&mt=k7)8=0Cg@*dSS Y)Lf}KqamXo7Nx|@V3)fW?GMEMAE{iGzyJUM literal 0 HcmV?d00001 diff --git a/Resources/Audio/Machines/airlock_emergencyon.ogg b/Resources/Audio/Machines/airlock_emergencyon.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6c8b54a28459d7eccf88ef87b5ee70ef8e6d056b GIT binary patch literal 10094 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 S-x{R=0000nBwn9J$=>&3iNRcK1$* zE;JOU#=TC)?$HO#C3>wzWG9C`9Jb_C?1(-<;=2AR3U?0?!2rZZg{*(RUaW}9{R=zR z6gy%&kRp#JQvUyD{go9F7BkQS+`s?{Q#&O2%4WHB?n>S!z(#~xdXP)tn(7DJYPJcm z5rK?B-uU>Ar&htmPpomcK#N;xpDed=DdPQ}I6cU?Vr$psmO096TyP_sYTxpgK7NDt_sJTV`Q|C-!d0Njn<>moo*k+1Gf3)>aaN&o=k zq3pT{o&4O^=Ou=X)7)V?mZGu_Tw*q!3Ct zR??;Is;E6an_ox(j+}xn2%y@5m=pp6kUi)2Fv#ppA`lxK>bTIC(wVi zrSY}gbz|W`Rh8VXA)-1v;r++gk#+1&f0}ji1!`lT=Y>Ma%m4rY07*qoM6N<$f(mgE AQ~&?~ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Actions/actions_ai.rsi/door_overcharge_on.png b/Resources/Textures/Interface/Actions/actions_ai.rsi/door_overcharge_on.png new file mode 100644 index 0000000000000000000000000000000000000000..ea654d8634b7be6024065ec69cc939a230589dd8 GIT binary patch literal 495 zcmVq3o(U;s4rk=ULbh}gD+rhV<}k1!oo78 zLaZ&cj?a)6P&-kuQ-X>hcBkLLT;}#>e`XDck`I=<+ufV*`(|z@F=mdxjBa}^!}vAw z>x=Dt{6s`8mHh0mYnE18`SZu?#Oxl8&G_b79j~4u03h<6{ZVnB0<{2gPviv5rIaEm z18@xTx6fK>E(Iz9+&##b7c+A{=oRZJSx{$y+`HDah!zlXPtayTl>wi7zDI*70kQ5O z4g+hkSy+fwI(1*|H9RZ)WXwc>?Vhe7QoQrs9kWn(jLLviS57)Q*~+iIy({lK61?ho z&*#B8DS_7ce9Uh|Fax#|o0yY_-j(1y1-$k|%*iEENnEHec#omW0m!AgYhri>K=H8O zDW0=zYJd~+d&xav*mq|^6o4Flj26Orf&KHH`NrhBADW*B7PQ9 zH?<9f`q|V5Q_(K8&`4`U{07tLrsBd6qDDvrAqqyjDfF|kv4R_IXiZwEZp_&G@WtuO zeQz?UpeH`x``fWpL9uN5jq`PtDrJa-deYn7^=z5h z$zt2|290G!215)u7-#}q+ThdQ=GZc`lf|~_4G@&!e0rK)dGO4SKNZJ&POi1hC$=Io zL`2g+p?hdTaXOu~&fKynIw zq?vOFM~AA!{h3)-=Cu{;NT1J>pIG^KEiX0AoWoE74yqCh#f4QXibXE$H!I`_!#SWu zq-Zq@z=44u^^dbIrxyOEC&w5v2rIzR&=-QJ*A3cAAkmBY%pyA~bM%e)eA4))$0v@U z-|vUGMg%7~&{@Uqsmzhww?K}gxFi8w1dib0l_dru1l6oKie}__3(!J89a@+*oFxI} zyN?Rz{Y2_D=tUs;HTzc5ekyWD$U`}pG^63LmMIy+}(mI!Vq${v! z@7~2uP_tP$1(SyCIj{;}x*i+$D{5(A?CpR}EoThmNT@$2*7WW- z_)m_E3S&zJOnjZm-ERrE8OSd|1G`x&QIP)NUlapZPEY8{Nq<&lVuhYDHftzI=jvij0vg3 z2Uv);d}*H#m>pfTj)0%gx>b5}7`R8$bm1w@tKAV}vaUQkoXXpl&=C~Yz)d4?WKVi6k`3j2I zvd$8Q|Ns7>h(%ZS5#<1oXIfrA`Tz0sZVX2dl?|7+7crP8)nE}X20Egbpni1E5bc0F zFW)h!hzr5_j6nDANVj9?xdY*!oYz9o@~Hy4VA{!%fg$8Hi4NG6Y0s##?lL?vf-HBR zafqO$$RPW}WiY*Te-V(}O_~Fc!Ojeb<;bCMl8AIlCGkv zX8D>qeGCS^2}C&r1}F5xpvhF_KRwN6L|5P@z|64g!(WEF({~ur6~lmq zg#}heo;Yy=ryg8pGomYi0d$4Pmd>0x6RRcZ>FHP+c%|e3oN%04_)P&smG%J7hiRp|mk2n4sk#z=X{KAcY_e zFaRs2QI>0Ll1B6mCv1&+mfTgx5 zIAMMK!N?FH#E0R#?cY9v*`8ed7;-D#ePZC}fD|3aufE1<4+|j|&aShBv)A=pgIffl z`H|QN%Y#a^7=obu)TZNj&BvPt&;iI`^fZCZa#8?Z2Y`b9?fcIRyn_GWIKEW_#SzGs zgXECag7kvSAlm`-03cKk?Eq|+gR&tAQ{o7s z9DvPo`(#-#8k?xpwyzBO$X<07&5pSM~q2=p7MlHod!M aqW}PyZhV8E5WCI*0000 Date: Fri, 27 Sep 2024 07:23:24 +0000 Subject: [PATCH 02/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5ccd9dd6e1..13886c6876 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Fix being able to throw items while your cursor is off-screen. - type: Fix - id: 6947 - time: '2024-07-21T06:13:28.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30164 - author: metalgearsloth changes: - message: Reset the scroll bar in the ghost warp menu whenever you search for a @@ -3937,3 +3930,15 @@ id: 7446 time: '2024-09-27T07:12:10.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32478 +- author: Fildrance, ScarKy0 + changes: + - message: AI now can electrify doors and set them to emergency access. Setting + door to emergency access will now play sound effect for everyone around, while + electrifying door will play sound effect only for AI + type: Add + - message: AI will now be notified when trying to interact with door without power + or when respective wires were messed up with + type: Fix + id: 7447 + time: '2024-09-27T07:22:17.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32012 From bbf84d0346b40cc9d10a298002974f66061978a7 Mon Sep 17 00:00:00 2001 From: LittleNorthStar Date: Fri, 27 Sep 2024 20:03:54 +1000 Subject: [PATCH 03/88] Feature/grey trenchcoat for detective loadout (#32380) * Detective grey coat available in loadout * Revert "Detective grey coat available in loadout" This reverts commit 3697e15518b300cbc110872dc92d7905b7ef2605. * Reapply "Detective grey coat available in loadout" This reverts commit 8e5f43a035d70a7076ba26d43ed683b135af1d99. * Hoping I got this right? * Fixing a oversight * Update Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- Resources/Prototypes/Loadouts/Jobs/Security/detective.yml | 5 +++++ Resources/Prototypes/Loadouts/loadout_groups.yml | 1 + 2 files changed, 6 insertions(+) diff --git a/Resources/Prototypes/Loadouts/Jobs/Security/detective.yml b/Resources/Prototypes/Loadouts/Jobs/Security/detective.yml index e8afa5a203..15fdd073b5 100644 --- a/Resources/Prototypes/Loadouts/Jobs/Security/detective.yml +++ b/Resources/Prototypes/Loadouts/Jobs/Security/detective.yml @@ -46,3 +46,8 @@ id: DetectiveCoat equipment: outerClothing: ClothingOuterCoatDetectiveLoadout + +- type: loadout + id: DetectiveCoatGrey + equipment: + outerClothing: ClothingOuterCoatDetectiveLoadoutGrey diff --git a/Resources/Prototypes/Loadouts/loadout_groups.yml b/Resources/Prototypes/Loadouts/loadout_groups.yml index fe17ea0fff..9bf0b4eb3d 100644 --- a/Resources/Prototypes/Loadouts/loadout_groups.yml +++ b/Resources/Prototypes/Loadouts/loadout_groups.yml @@ -1054,6 +1054,7 @@ loadouts: - DetectiveArmorVest - DetectiveCoat + - DetectiveCoatGrey - type: loadoutGroup id: SecurityCadetJumpsuit From 4e860952d7f47fbb50e5eefb17b36f230760255d Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 27 Sep 2024 10:05:01 +0000 Subject: [PATCH 04/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 13886c6876..ae6d046ae6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Reset the scroll bar in the ghost warp menu whenever you search for a - role. Previously it remained at your previous position and you would have to - scroll up to see the first entry. - type: Tweak - id: 6948 - time: '2024-07-21T06:38:45.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30159 - author: Blackern5000 changes: - message: The syndicate agent's cyborg weapons module now uses syndicate weaponry @@ -3942,3 +3933,10 @@ id: 7447 time: '2024-09-27T07:22:17.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32012 +- author: LittleNorthStar + changes: + - message: Noir trenchcoat to detective loadout + type: Add + id: 7448 + time: '2024-09-27T10:03:55.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32380 From 7d4ea967e0e18da2e63895749701a66d97fa49c0 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Fri, 27 Sep 2024 19:04:22 +0000 Subject: [PATCH 05/88] remove thief figurine objective (#32413) * make figurine objective just 1 * remove the objective entirely --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Prototypes/Entities/Objects/Fun/figurines.yml | 2 -- Resources/Prototypes/Objectives/objectiveGroups.yml | 1 - Resources/Prototypes/Objectives/stealTargetGroups.yml | 7 ------- Resources/Prototypes/Objectives/thief.yml | 11 ----------- 4 files changed, 21 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Fun/figurines.yml b/Resources/Prototypes/Entities/Objects/Fun/figurines.yml index e48ac9d84a..5f962b90c8 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/figurines.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/figurines.yml @@ -17,8 +17,6 @@ - type: Tag tags: - Figurine - - type: StealTarget - stealGroup: Figurines - type: UseDelay delay: 10 - type: Speech diff --git a/Resources/Prototypes/Objectives/objectiveGroups.yml b/Resources/Prototypes/Objectives/objectiveGroups.yml index e72de0d94a..3c59ab9a18 100644 --- a/Resources/Prototypes/Objectives/objectiveGroups.yml +++ b/Resources/Prototypes/Objectives/objectiveGroups.yml @@ -63,7 +63,6 @@ StampStealCollectionObjective: 1 DoorRemoteStealCollectionObjective: 1 TechnologyDiskStealCollectionObjective: 1 #rnd - FigurineStealCollectionObjective: 0.3 #service IDCardsStealCollectionObjective: 1 LAMPStealCollectionObjective: 2 #only for moth diff --git a/Resources/Prototypes/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Objectives/stealTargetGroups.yml index 09619bf986..b21e0dc2de 100644 --- a/Resources/Prototypes/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Objectives/stealTargetGroups.yml @@ -86,13 +86,6 @@ # Thief Collection -- type: stealTargetGroup - id: Figurines - name: steal-target-groups-figurines - sprite: - sprite: Objects/Fun/figurines.rsi - state: figurine_spawner - - type: stealTargetGroup id: HeadCloak name: steal-target-groups-heads-cloaks diff --git a/Resources/Prototypes/Objectives/thief.yml b/Resources/Prototypes/Objectives/thief.yml index 7a46d0f5e9..5798071f02 100644 --- a/Resources/Prototypes/Objectives/thief.yml +++ b/Resources/Prototypes/Objectives/thief.yml @@ -53,17 +53,6 @@ # Collections -- type: entity - parent: BaseThiefStealCollectionObjective - id: FigurineStealCollectionObjective - components: - - type: StealCondition - stealGroup: Figurines - minCollectionSize: 10 - maxCollectionSize: 18 #will be limited to the number of figures on the station anyway. - - type: Objective - difficulty: 0.25 - - type: entity parent: BaseThiefStealCollectionObjective id: HeadCloakStealCollectionObjective From b5a73261602dd9e8a07e1c6a581e3b20daa7a58f Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 27 Sep 2024 19:05:30 +0000 Subject: [PATCH 06/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index ae6d046ae6..c7ddf001b9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Blackern5000 - changes: - - message: The syndicate agent's cyborg weapons module now uses syndicate weaponry - rather than NT weaponry. - type: Tweak - id: 6949 - time: '2024-07-21T07:04:33.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/26947 - author: Winkarst-cpu changes: - message: Added ambience to the camera routers and telecommunication servers. @@ -3940,3 +3932,10 @@ id: 7448 time: '2024-09-27T10:03:55.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32380 +- author: deltanedas + changes: + - message: Removed the thief figurines objective. + type: Remove + id: 7449 + time: '2024-09-27T19:04:22.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32413 From 7485411ab2a2570f70cf37135647c22ad557c5d3 Mon Sep 17 00:00:00 2001 From: beck-thompson <107373427+beck-thompson@users.noreply.github.com> Date: Fri, 27 Sep 2024 21:40:24 -0700 Subject: [PATCH 07/88] Predict appraisal tool verb! (#32496) * First commit * Network :( --- .../Cargo/Systems/ClientPriceGunSystem.cs | 21 +++++++ .../Cargo/Components/PriceGunComponent.cs | 10 --- .../Cargo/Systems/PriceGunSystem.cs | 61 ++++--------------- .../Cargo/Components/PriceGunComponent.cs | 11 ++++ Content.Shared/Cargo/SharedPriceGunSystem.cs | 55 +++++++++++++++++ 5 files changed, 98 insertions(+), 60 deletions(-) create mode 100644 Content.Client/Cargo/Systems/ClientPriceGunSystem.cs delete mode 100644 Content.Server/Cargo/Components/PriceGunComponent.cs create mode 100644 Content.Shared/Cargo/Components/PriceGunComponent.cs create mode 100644 Content.Shared/Cargo/SharedPriceGunSystem.cs diff --git a/Content.Client/Cargo/Systems/ClientPriceGunSystem.cs b/Content.Client/Cargo/Systems/ClientPriceGunSystem.cs new file mode 100644 index 0000000000..f173932478 --- /dev/null +++ b/Content.Client/Cargo/Systems/ClientPriceGunSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.Timing; +using Content.Shared.Cargo.Systems; + +namespace Content.Client.Cargo.Systems; + +/// +/// This handles... +/// +public sealed class ClientPriceGunSystem : SharedPriceGunSystem +{ + [Dependency] private readonly UseDelaySystem _useDelay = default!; + + protected override bool GetPriceOrBounty(EntityUid priceGunUid, EntityUid target, EntityUid user) + { + if (!TryComp(priceGunUid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((priceGunUid, useDelay))) + return false; + + // It feels worse if the cooldown is predicted but the popup isn't! So only do the cooldown reset on the server. + return true; + } +} diff --git a/Content.Server/Cargo/Components/PriceGunComponent.cs b/Content.Server/Cargo/Components/PriceGunComponent.cs deleted file mode 100644 index 7207beae99..0000000000 --- a/Content.Server/Cargo/Components/PriceGunComponent.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Content.Server.Cargo.Components; - -/// -/// This is used for the price gun, which calculates the price of any object it appraises. -/// -[RegisterComponent] -public sealed partial class PriceGunComponent : Component -{ - -} diff --git a/Content.Server/Cargo/Systems/PriceGunSystem.cs b/Content.Server/Cargo/Systems/PriceGunSystem.cs index 19fe07bd25..94f9f9cba9 100644 --- a/Content.Server/Cargo/Systems/PriceGunSystem.cs +++ b/Content.Server/Cargo/Systems/PriceGunSystem.cs @@ -1,73 +1,34 @@ -using Content.Server.Cargo.Components; using Content.Server.Popups; using Content.Shared.IdentityManagement; -using Content.Shared.Interaction; using Content.Shared.Timing; -using Content.Shared.Verbs; +using Content.Shared.Cargo.Systems; namespace Content.Server.Cargo.Systems; -/// -/// This handles... -/// -public sealed class PriceGunSystem : EntitySystem +public sealed class PriceGunSystem : SharedPriceGunSystem { [Dependency] private readonly UseDelaySystem _useDelay = default!; [Dependency] private readonly PricingSystem _pricingSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; [Dependency] private readonly CargoSystem _bountySystem = default!; - /// - public override void Initialize() + protected override bool GetPriceOrBounty(EntityUid priceGunUid, EntityUid target, EntityUid user) { - SubscribeLocalEvent(OnAfterInteract); - SubscribeLocalEvent>(OnUtilityVerb); - } - - private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent args) - { - if (!args.CanAccess || !args.CanInteract || args.Using == null) - return; - - if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay))) - return; - - var price = _pricingSystem.GetPrice(args.Target); - - var verb = new UtilityVerb() - { - Act = () => - { - _popupSystem.PopupEntity(Loc.GetString("price-gun-pricing-result", ("object", Identity.Entity(args.Target, EntityManager)), ("price", $"{price:F2}")), args.User, args.User); - _useDelay.TryResetDelay((uid, useDelay)); - }, - Text = Loc.GetString("price-gun-verb-text"), - Message = Loc.GetString("price-gun-verb-message", ("object", Identity.Entity(args.Target, EntityManager))) - }; - - args.Verbs.Add(verb); - } - - private void OnAfterInteract(EntityUid uid, PriceGunComponent component, AfterInteractEvent args) - { - if (!args.CanReach || args.Target == null || args.Handled) - return; - - if (!TryComp(uid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((uid, useDelay))) - return; + if (!TryComp(priceGunUid, out UseDelayComponent? useDelay) || _useDelay.IsDelayed((priceGunUid, useDelay))) + return false; // Check if we're scanning a bounty crate - if (_bountySystem.IsBountyComplete(args.Target.Value, out _)) + if (_bountySystem.IsBountyComplete(target, out _)) { - _popupSystem.PopupEntity(Loc.GetString("price-gun-bounty-complete"), args.User, args.User); + _popupSystem.PopupEntity(Loc.GetString("price-gun-bounty-complete"), user, user); } else // Otherwise appraise the price { - double price = _pricingSystem.GetPrice(args.Target.Value); - _popupSystem.PopupEntity(Loc.GetString("price-gun-pricing-result", ("object", Identity.Entity(args.Target.Value, EntityManager)), ("price", $"{price:F2}")), args.User, args.User); + var price = _pricingSystem.GetPrice(target); + _popupSystem.PopupEntity(Loc.GetString("price-gun-pricing-result", ("object", Identity.Entity(target, EntityManager)), ("price", $"{price:F2}")), user, user); } - _useDelay.TryResetDelay((uid, useDelay)); - args.Handled = true; + _useDelay.TryResetDelay((priceGunUid, useDelay)); + return true; } } diff --git a/Content.Shared/Cargo/Components/PriceGunComponent.cs b/Content.Shared/Cargo/Components/PriceGunComponent.cs new file mode 100644 index 0000000000..7024f1195a --- /dev/null +++ b/Content.Shared/Cargo/Components/PriceGunComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Cargo.Components; + +/// +/// This is used for the price gun, which calculates the price of any object it appraises. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class PriceGunComponent : Component +{ +} diff --git a/Content.Shared/Cargo/SharedPriceGunSystem.cs b/Content.Shared/Cargo/SharedPriceGunSystem.cs new file mode 100644 index 0000000000..779d55055a --- /dev/null +++ b/Content.Shared/Cargo/SharedPriceGunSystem.cs @@ -0,0 +1,55 @@ +using Content.Shared.Cargo.Components; +using Content.Shared.IdentityManagement; +using Content.Shared.Interaction; +using Content.Shared.Verbs; + +namespace Content.Shared.Cargo.Systems; + +/// +/// The price gun system! If this component is on an entity, you can scan objects (Click or use verb) to see their price. +/// +public abstract class SharedPriceGunSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent>(OnUtilityVerb); + SubscribeLocalEvent(OnAfterInteract); + } + + private void OnUtilityVerb(EntityUid uid, PriceGunComponent component, GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || args.Using == null) + return; + + var verb = new UtilityVerb() + { + Act = () => + { + GetPriceOrBounty(uid, args.Target, args.User); + }, + Text = Loc.GetString("price-gun-verb-text"), + Message = Loc.GetString("price-gun-verb-message", ("object", Identity.Entity(args.Target, EntityManager))) + }; + + args.Verbs.Add(verb); + } + + private void OnAfterInteract(Entity entity, ref AfterInteractEvent args) + { + if (!args.CanReach || args.Target == null || args.Handled) + return; + + args.Handled |= GetPriceOrBounty(entity, args.Target.Value, args.User); + } + + /// + /// Find the price or confirm if the item is a bounty. Will give a popup of the result to the passed user. + /// + /// + /// + /// This is abstract for prediction. When the bounty system / cargo systems that are necessary are moved to shared, + /// combine all the server, client, and shared stuff into one non abstract file. + /// + protected abstract bool GetPriceOrBounty(EntityUid priceGunUid, EntityUid target, EntityUid user); +} From caac678fa6e5c5a8f0602dd5b4ffbf1eea3b34ef Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 28 Sep 2024 04:41:31 +0000 Subject: [PATCH 08/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index c7ddf001b9..00de9b4308 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: Winkarst-cpu - changes: - - message: Added ambience to the camera routers and telecommunication servers. - type: Add - - message: Now server's and router's ambience stops once they are unpowered. - type: Fix - id: 6950 - time: '2024-07-21T07:22:02.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30091 - author: Scott Dimeling changes: - message: Reduced the number of botanists in some stations, for optimal _workflow_ @@ -3939,3 +3930,10 @@ id: 7449 time: '2024-09-27T19:04:22.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32413 +- author: Beck Thompson + changes: + - message: The appraisal tool verb is now predicted! + type: Fix + id: 7450 + time: '2024-09-28T04:40:24.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32496 From dd376e4e84da25d37e693ce0c85f8794bbe151a4 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:16:54 +1000 Subject: [PATCH 09/88] Optimise drains (#32230) * Optimise drains If it's still a problem then we do what I did for rmc14 and just dump all the active drains onto a job to getentitiesinrange in parallel. * Fixes --- .../Fluids/EntitySystems/DrainSystem.cs | 40 +++++++------------ .../Fluids/Components/DrainComponent.cs | 2 +- 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/Content.Server/Fluids/EntitySystems/DrainSystem.cs b/Content.Server/Fluids/EntitySystems/DrainSystem.cs index 091f384986..69d15b8d00 100644 --- a/Content.Server/Fluids/EntitySystems/DrainSystem.cs +++ b/Content.Server/Fluids/EntitySystems/DrainSystem.cs @@ -1,5 +1,4 @@ using Content.Server.DoAfter; -using Content.Server.Fluids.Components; using Content.Server.Popups; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Audio; @@ -13,9 +12,7 @@ using Content.Shared.Fluids.Components; using Content.Shared.Interaction; using Content.Shared.Tag; using Content.Shared.Verbs; -using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; -using Robust.Shared.Collections; using Robust.Shared.Prototypes; using Robust.Shared.Random; using Robust.Shared.Utility; @@ -32,19 +29,27 @@ public sealed class DrainSystem : SharedDrainSystem [Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly DoAfterSystem _doAfterSystem = default!; [Dependency] private readonly PuddleSystem _puddleSystem = default!; - [Dependency] private readonly TransformSystem _transform = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + private readonly HashSet> _puddles = new(); + public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnDrainMapInit); SubscribeLocalEvent>(AddEmptyVerb); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnInteract); SubscribeLocalEvent(OnDoAfter); } + private void OnDrainMapInit(Entity ent, ref MapInitEvent args) + { + // Randomise puddle drains so roundstart ones don't all dump at the same time. + ent.Comp.Accumulator = _random.NextFloat(ent.Comp.DrainFrequency); + } + private void AddEmptyVerb(Entity entity, ref GetVerbsEvent args) { if (!args.CanAccess || !args.CanInteract || args.Using == null) @@ -118,9 +123,6 @@ public sealed class DrainSystem : SharedDrainSystem { base.Update(frameTime); var managerQuery = GetEntityQuery(); - var xformQuery = GetEntityQuery(); - var puddleQuery = GetEntityQuery(); - var puddles = new ValueList<(Entity Entity, string Solution)>(); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var drain)) @@ -158,22 +160,10 @@ public sealed class DrainSystem : SharedDrainSystem // This will ensure that UnitsPerSecond is per second... var amount = drain.UnitsPerSecond * drain.DrainFrequency; - if (!xformQuery.TryGetComponent(uid, out var xform)) - continue; + _puddles.Clear(); + _lookup.GetEntitiesInRange(Transform(uid).Coordinates, drain.Range, _puddles); - puddles.Clear(); - - foreach (var entity in _lookup.GetEntitiesInRange(_transform.GetMapCoordinates(uid, xform), drain.Range)) - { - // No InRangeUnobstructed because there's no collision group that fits right now - // and these are placed by mappers and not buildable/movable so shouldnt really be a problem... - if (puddleQuery.TryGetComponent(entity, out var puddle)) - { - puddles.Add(((entity, puddle), puddle.SolutionName)); - } - } - - if (puddles.Count == 0) + if (_puddles.Count == 0) { _ambientSoundSystem.SetAmbience(uid, false); continue; @@ -181,13 +171,13 @@ public sealed class DrainSystem : SharedDrainSystem _ambientSoundSystem.SetAmbience(uid, true); - amount /= puddles.Count; + amount /= _puddles.Count; - foreach (var (puddle, solution) in puddles) + foreach (var puddle in _puddles) { // Queue the solution deletion if it's empty. EvaporationSystem might also do this // but queuedelete should be pretty safe. - if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, solution, ref puddle.Comp.Solution, out var puddleSolution)) + if (!_solutionContainerSystem.ResolveSolution(puddle.Owner, puddle.Comp.SolutionName, ref puddle.Comp.Solution, out var puddleSolution)) { EntityManager.QueueDeleteEntity(puddle); continue; diff --git a/Content.Shared/Fluids/Components/DrainComponent.cs b/Content.Shared/Fluids/Components/DrainComponent.cs index 50cb5f5195..3064721bf3 100644 --- a/Content.Shared/Fluids/Components/DrainComponent.cs +++ b/Content.Shared/Fluids/Components/DrainComponent.cs @@ -52,7 +52,7 @@ public sealed partial class DrainComponent : Component /// drain puddles from. /// [DataField] - public float Range = 2f; + public float Range = 2.5f; /// /// How often in seconds the drain checks for puddles around it. From a371de16d3f0a735f8ac44c4606e6bbae9e7379d Mon Sep 17 00:00:00 2001 From: Futuristic-OK <141568243+Futuristic-OK@users.noreply.github.com> Date: Sat, 28 Sep 2024 12:07:51 +0600 Subject: [PATCH 10/88] Some new hairstyles! (#31010) * Add files via upload png of hairs * Update meta.json hairs meta * Update human_hair.yml hairs yml * Update human-hair.ftl hairs named * second try * fix meta * Add files via upload * Add files via upload fix again * Add files via upload again again * Add files via upload again again fix again * Add files via upload i hate yourself * Add files via upload fixxxxx! * Add files via upload aaagaaaaiiin * dd dddddd * Add files via upload fix again * Add files via upload ddsdssddssddsdsds * Update human-hair.ftl * Update human-hair.ftl screw this im just going to update it myself webops time * Update human_hair.yml * Update meta.json * Rename capsdaughter.png to longbow.png * Rename artist.png to shaped.png --------- Co-authored-by: Ubaser <134914314+UbaserB@users.noreply.github.com> --- .../Locale/en-US/accessories/human-hair.ftl | 2 ++ .../Mobs/Customization/Markings/human_hair.yml | 14 ++++++++++++++ .../Customization/human_hair.rsi/longbow.png | Bin 0 -> 2061 bytes .../Mobs/Customization/human_hair.rsi/meta.json | 8 ++++++++ .../Mobs/Customization/human_hair.rsi/shaped.png | Bin 0 -> 437 bytes 5 files changed, 24 insertions(+) create mode 100644 Resources/Textures/Mobs/Customization/human_hair.rsi/longbow.png create mode 100644 Resources/Textures/Mobs/Customization/human_hair.rsi/shaped.png diff --git a/Resources/Locale/en-US/accessories/human-hair.ftl b/Resources/Locale/en-US/accessories/human-hair.ftl index 9575cd5c2f..58314f9bb2 100644 --- a/Resources/Locale/en-US/accessories/human-hair.ftl +++ b/Resources/Locale/en-US/accessories/human-hair.ftl @@ -97,6 +97,7 @@ marking-HumanHairJensen = Jensen Hair marking-HumanHairJoestar = Joestar marking-HumanHairKeanu = Keanu Hair marking-HumanHairKusanagi = Kusanagi Hair +marking-HumanHairLongBow = Long Bow marking-HumanHairLong = Long Hair 1 marking-HumanHairLong2 = Long Hair 2 marking-HumanHairLong3 = Long Hair 3 @@ -147,6 +148,7 @@ marking-HumanHairSpikyponytail = Ponytail (Spiky) marking-HumanHairPoofy = Poofy marking-HumanHairQuiff = Quiff marking-HumanHairRonin = Ronin +marking-HumanHairShaped = Shaped marking-HumanHairShaved = Shaved marking-HumanHairShavedpart = Shaved Part marking-HumanHairShortbangs = Short Bangs diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml index bd7bed25f6..578c6837c0 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/human_hair.yml @@ -1363,3 +1363,17 @@ sprites: - sprite: Mobs/Customization/human_hair.rsi state: classiclong3 +- type: marking + id: HumanHairShaped + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: Mobs/Customization/human_hair.rsi + state: shaped +- type: marking + id: HumanHairLongBow + bodyPart: Hair + markingCategory: Hair + sprites: + - sprite: Mobs/Customization/human_hair.rsi + state: longbow diff --git a/Resources/Textures/Mobs/Customization/human_hair.rsi/longbow.png b/Resources/Textures/Mobs/Customization/human_hair.rsi/longbow.png new file mode 100644 index 0000000000000000000000000000000000000000..40705175a4796ec6423476df0350915dd87f3d1a GIT binary patch literal 2061 zcmV+o2=e!dP)4Tx04R}TU|=$Eba8TJ5@2A+%_}Jia(7aQh>TKTKhMC%z{~&!iOIzUjsXEa zAa-7UUMd3y_;!tf5kz0s1(}5@j~8$y7ZjBM=|4bhl#*JU%)r2C0Ay#EmlOcS8Rr1m zB1zd`_688UC?v=k$UXvO^QA-BS3v9}2>S_$T?F(5ko^UuJ{`5*&HCkwr=x>4m6b}&A=Rk1yGK!r+h#^37X;B%J$;f0(n2#`HjsydP|5649mOltF zlU@df1v(52{8JHPYK9C90{RRL`{n=uz{XGg#6{pT000JxNklJOFfW_-5rKxPCf$O?V z)3mVcc^-6KPu2flsy75dz--%&)Y-N@QItF|t)I00D+$1zuh;9aZ5y8F0YF&JTLjCp znCE#ApFRL+ng-AFU|E)O|9{Ii6rKP1^C#-{I{N*7NC5aR67om~%d(hhnp3Z9ng&hN zU|AMhTU(RvUs?d}yryYkzPql=bX_O$ocxm@odVo>G5`6%qw6}ky1D`Y#K(uMz|(9N z_(M{G@*t=ZUU^}4brq|ttM`7VfpiM+e4mDLxlGQ_&vTy%#3&FQ&nxl(+zo)P>xO^R z+MJ)CGt07A*0X`@x}jbESFKjr?(QzDR;!VE%d)0&oCK*9;OgqSPNuzZP)bR;TqZKP zs)~NUkN6BwE|<}4Hc>8@BlV_fCPu3W=@gKC)8ey&Gy@6Dn*OqAKiBB>dXW$pLp=xr z_Wk?!iPw9*p43B7o&_Eo{OyyYR4PrZm&IHQFzYFrrU}pUP$(2q-OuspbNV#&dOh~) z)vHKd{5v423;-u5Cs1n{YFRvXuKGoJ$U##8~~j>vp->$*fb@yk|HZM#h4qrw=GZfXXx|YcmP)6!`r4bEF)f@8j3w_fNuH4}u(?=i$@N zj#S%EJ3C4l-nZLQ_7fHA z_xqs}^?F^Y{pIB)48wR(Bz^esfxUeBGAuiegEw#9gnW2^U%q@ntyT-${rK?%@7}#j z?0e?705^Vlc_~epw=I=Q;al26z@2v-2c1p_&z?O4r4+AUzYg0R930^2=m?!o2Zmvw zR;xi2Z59#-LGF;_I8p|AI~CDnY*I?mYPA3W-EJ2L2L}M|obPtK0DxAj1xl$jS0F(E z9`c-k3`7DlDU$@lFbJg-l}ZHw&~CTM`uciUu2d>mUtdSN-6p(DDV0vW#0ZEJNP;Q> zS(^Y51OWhGZ*LF#`}+WZ{r!FH?d?Ub%W?%I-vd+(rfHu9?wDzs1OT?Sw#d@b5&&Rn zX$f0fTSUCh+si;o02PC2+9$y@O%k{H_U&6D{ule^LOkIKPk2HSQVkZq?=#=`Q7jhW z`#xU0cmYDlZyk6TV{AAah8&8;B8tVLG6&@weBWocx3^eaT*U3|EpBdZP$(3zxVQ*P zY3@QW##j&p_xk3XR7Fr)4-lQ_eqLQ&p-?D*5Q5XwQw#=!+?K=!g8@4|Jp~~Ig+c** zLzWN{is1XcQvXV7@x4F35<41=?kz&*eN<-BQr+|C&jA28H#Y$8_9I#P7|}Ehqkq>6j*pKq9*>pmDG6|Pc82BUsUR5g^O*TBLVOtF4E5lh zp*Te6=V>a8pAk?&q5%Bq&#UtslSGh71*r&dT{rw41VN-cFK}HqvKTANG4YrjH^hxo zO6N`l&V_S}*Uv&?1T-2AGHF++(P+%Y00>OxLMfHvD0NU$RMqo5lu9Lh`}U1Z>-=|u z^8o(i2FUMCBu2pY_BOk|zK+!Kjn9RJ1$m}9fpZWyV;hYIxxT)RoNt(hL;?6_XQR;| z-EKF`t6#rL01_JPx$Z%IT!RA_YBb zuxh{)T?_D@y?%f%cg?4vq>pYp{LMK@4)eO#Gb#5#H95Z&JqOwi`3*{+VwX_50K+g0 f!!QiP_y_&~D;cqYy-Y+D00000NkvXXu0mjfo=w2% literal 0 HcmV?d00001 From 9f5b6af82d3d84688d21290fe7e09ca1be16b964 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 28 Sep 2024 06:08:57 +0000 Subject: [PATCH 11/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 00de9b4308..087b371132 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Scott Dimeling - changes: - - message: Reduced the number of botanists in some stations, for optimal _workflow_ - type: Tweak - id: 6951 - time: '2024-07-21T07:23:28.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29581 - author: metalgearsloth changes: - message: Escape pods won't show up on shuttle map anymore. @@ -3937,3 +3930,10 @@ id: 7450 time: '2024-09-28T04:40:24.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32496 +- author: Pyvik + changes: + - message: Added 2 new hairstyles. + type: Add + id: 7451 + time: '2024-09-28T06:07:51.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31010 From bed968465c94516732e5b1528e2efb704cadbeaf Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:02:43 +1000 Subject: [PATCH 12/88] Fix multiple door issues (#32483) * Fix multiple door issues - Doors should no longer cycle open-and-closed anymore (at least nowhere near as easily). - Door sprites shouldn't flicker as much (needs my engine PRs to remove all but one of them). * woops conversion --- .../Doors/Systems/SharedDoorSystem.cs | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 3d9a721473..4d88663ca0 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -23,6 +23,7 @@ using Robust.Shared.Timing; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; using Robust.Shared.Map.Components; +using Robust.Shared.Physics; namespace Content.Shared.Doors.Systems; @@ -49,21 +50,13 @@ public abstract partial class SharedDoorSystem : EntitySystem [ValidatePrototypeId] public const string DoorBumpTag = "DoorBumpOpener"; - /// - /// A body must have an intersection percentage larger than this in order to be considered as colliding with a - /// door. Used for safety close-blocking and crushing. - /// - /// - /// The intersection percentage relies on WORLD AABBs. So if this is too small, and the grid is rotated 45 - /// degrees, then an entity outside of the airlock may be crushed. - /// - public const float IntersectPercentage = 0.2f; - /// /// A set of doors that are currently opening, closing, or just queued to open/close after some delay. /// private readonly HashSet> _activeDoors = new(); + private readonly HashSet> _doorIntersecting = new(); + public override void Initialize() { base.Initialize(); @@ -163,7 +156,6 @@ public abstract partial class SharedDoorSystem : EntitySystem _activeDoors.Add(ent); RaiseLocalEvent(ent, new DoorStateChangedEvent(door.State)); - AppearanceSystem.SetData(ent, DoorVisuals.State, door.State); } protected bool SetState(EntityUid uid, DoorState state, DoorComponent? door = null) @@ -211,6 +203,7 @@ public abstract partial class SharedDoorSystem : EntitySystem door.State = state; Dirty(uid, door); RaiseLocalEvent(uid, new DoorStateChangedEvent(state)); + AppearanceSystem.SetData(uid, DoorVisuals.State, door.State); return true; } @@ -557,20 +550,25 @@ public abstract partial class SharedDoorSystem : EntitySystem if (!TryComp(xform.GridUid, out var mapGridComp)) yield break; var tileRef = _mapSystem.GetTileRef(xform.GridUid.Value, mapGridComp, xform.Coordinates); - var doorWorldBounds = _entityLookup.GetWorldBounds(tileRef); + + _doorIntersecting.Clear(); + + _entityLookup.GetLocalEntitiesIntersecting(xform.GridUid.Value, tileRef.GridIndices, _doorIntersecting, gridComp: mapGridComp); // TODO SLOTH fix electro's code. // ReSharper disable once InconsistentNaming - var doorAABB = _entityLookup.GetWorldAABB(uid); - foreach (var otherPhysics in PhysicsSystem.GetCollidingEntities(Transform(uid).MapID, doorWorldBounds)) + foreach (var otherPhysics in _doorIntersecting) { if (otherPhysics.Comp == physics) continue; + if (!otherPhysics.Comp.CanCollide) + continue; + //TODO: Make only shutters ignore these objects upon colliding instead of all airlocks // Excludes Glasslayer for windows, GlassAirlockLayer for windoors, TableLayer for tables - if (!otherPhysics.Comp.CanCollide || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassAirlockLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.TableLayer) + if (otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassAirlockLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.TableLayer) continue; //If the colliding entity is a slippable item ignore it by the airlock @@ -584,9 +582,6 @@ public abstract partial class SharedDoorSystem : EntitySystem if ((physics.CollisionMask & otherPhysics.Comp.CollisionLayer) == 0 && (otherPhysics.Comp.CollisionMask & physics.CollisionLayer) == 0) continue; - if (_entityLookup.GetWorldAABB(otherPhysics.Owner).IntersectPercentage(doorAABB) < IntersectPercentage) - continue; - yield return otherPhysics.Owner; } } @@ -614,7 +609,7 @@ public abstract partial class SharedDoorSystem : EntitySystem var otherUid = args.OtherEntity; if (Tags.HasTag(otherUid, DoorBumpTag)) - TryOpen(uid, door, otherUid, quiet: door.State == DoorState.Denying); + TryOpen(uid, door, otherUid, quiet: door.State == DoorState.Denying, predicted: true); } #endregion @@ -714,7 +709,7 @@ public abstract partial class SharedDoorSystem : EntitySystem var (uid, door, physics) = ent; if (door.BumpOpen) { - foreach (var other in PhysicsSystem.GetContactingEntities(uid, physics, approximate: true)) + foreach (var other in PhysicsSystem.GetContactingEntities(uid, physics)) { if (Tags.HasTag(other, DoorBumpTag) && TryOpen(uid, door, other, quiet: true)) break; From 8b692d118d4438fc6d9bbfef1427d46ba44f6877 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 28 Sep 2024 09:03:49 +0000 Subject: [PATCH 13/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 087b371132..bce89288e4 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Escape pods won't show up on shuttle map anymore. - type: Tweak - id: 6952 - time: '2024-07-21T07:23:44.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29758 - author: IProduceWidgets changes: - message: an arabian lamp! @@ -3937,3 +3930,10 @@ id: 7451 time: '2024-09-28T06:07:51.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31010 +- author: metalgearsloth + changes: + - message: Fix a lot of jankiness around airlocks. + type: Fix + id: 7452 + time: '2024-09-28T09:02:43.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32483 From 0a7b23cd4db598e2f0215e582bd840773093d528 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sat, 28 Sep 2024 19:31:27 +1000 Subject: [PATCH 14/88] Update submodule to 236.0.0 (#32500) --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index c86cb0b795..1c3ea968e4 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit c86cb0b7951cc4a662c7292138c5f45d868c5f58 +Subproject commit 1c3ea968e4ab66d57ffe014f6ee207e4d0d2c403 From 1b9d77a76078668ceb15acebf777fae05167ea83 Mon Sep 17 00:00:00 2001 From: MilenVolf <63782763+MilenVolf@users.noreply.github.com> Date: Sun, 29 Sep 2024 02:27:47 +0300 Subject: [PATCH 15/88] Replace obsolete Tile Access methods (#32508) * Replace obsolete SetTile * Remove obsolete GetTileRef & GetAllTiles * Forgor * Apply suggested `GetMapOrInvalid` --- Content.IntegrationTests/Pair/TestPair.Helpers.cs | 4 ++-- Content.Server/Decals/DecalSystem.cs | 4 ++-- .../EntitySystems/ExplosionSystem.GridMap.cs | 2 +- .../EntitySystems/ExplosionSystem.Processing.cs | 7 +++++-- .../Explosion/EntitySystems/ExplosionSystem.cs | 3 ++- Content.Server/ImmovableRod/ImmovableRodSystem.cs | 3 ++- Content.Server/Parallax/BiomeSystem.cs | 2 +- .../Pointing/EntitySystems/PointingSystem.cs | 14 ++++++++++---- .../Power/EntitySystems/CableSystem.Placer.cs | 7 +++++-- .../Procedural/DungeonSystem.Commands.cs | 12 +++++------- .../EntitySystems/EventHorizonSystem.cs | 3 ++- Content.Server/SubFloor/SubFloorHideSystem.cs | 2 +- .../Systems/Debris/BlobFloorPlanBuilderSystem.cs | 7 ++++--- .../Debris/SimpleFloorPlanPopulatorSystem.cs | 3 ++- Content.Shared/Friction/TileFrictionController.cs | 3 ++- Content.Shared/Sound/SharedEmitSoundSystem.cs | 3 ++- .../SubFloor/SharedSubFloorHideSystem.cs | 15 ++++++++------- Content.Shared/Tiles/FloorTileSystem.cs | 5 +++-- 18 files changed, 59 insertions(+), 40 deletions(-) diff --git a/Content.IntegrationTests/Pair/TestPair.Helpers.cs b/Content.IntegrationTests/Pair/TestPair.Helpers.cs index 588cf0d80e..4604cd8296 100644 --- a/Content.IntegrationTests/Pair/TestPair.Helpers.cs +++ b/Content.IntegrationTests/Pair/TestPair.Helpers.cs @@ -35,9 +35,9 @@ public sealed partial class TestPair mapData.GridCoords = new EntityCoordinates(mapData.Grid, 0, 0); var plating = tileDefinitionManager[tile]; var platingTile = new Tile(plating.TileId); - mapData.Grid.Comp.SetTile(mapData.GridCoords, platingTile); + Server.System().SetTile(mapData.Grid.Owner, mapData.Grid.Comp, mapData.GridCoords, platingTile); mapData.MapCoords = new MapCoordinates(0, 0, mapData.MapId); - mapData.Tile = mapData.Grid.Comp.GetAllTiles().First(); + mapData.Tile = Server.System().GetAllTiles(mapData.Grid.Owner, mapData.Grid.Comp).First(); }); TestMap = mapData; diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index 519f7a133e..718475754f 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -35,7 +35,7 @@ namespace Content.Server.Decals [Dependency] private readonly IConfigurationManager _conf = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly MapSystem _mapSystem = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; private readonly Dictionary> _dirtyChunks = new(); private readonly Dictionary>> _previousSentChunks = new(); @@ -106,7 +106,7 @@ namespace Content.Server.Decals return; // Transfer decals over to the new grid. - var enumerator = Comp(ev.Grid).GetAllTilesEnumerator(); + var enumerator = _mapSystem.GetAllTilesEnumerator(ev.Grid, Comp(ev.Grid)); var oldChunkCollection = oldComp.ChunkCollection.ChunkCollection; var chunkCollection = newComp.ChunkCollection.ChunkCollection; diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs index 29477c16b2..b08b66474b 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs @@ -29,7 +29,7 @@ public sealed partial class ExplosionSystem Dictionary edges = new(); _gridEdges[ev.EntityUid] = edges; - foreach (var tileRef in grid.GetAllTiles()) + foreach (var tileRef in _map.GetAllTiles(ev.EntityUid, grid)) { if (IsEdge(grid, tileRef.GridIndices, out var dir)) edges.Add(tileRef.GridIndices, dir); diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index 97d52e436a..5f14858f1f 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -666,6 +666,7 @@ sealed class Explosion private readonly IEntityManager _entMan; private readonly ExplosionSystem _system; + private readonly SharedMapSystem _mapSystem; public readonly EntityUid VisualEnt; @@ -688,11 +689,13 @@ sealed class Explosion IEntityManager entMan, IMapManager mapMan, EntityUid visualEnt, - EntityUid? cause) + EntityUid? cause, + SharedMapSystem mapSystem) { VisualEnt = visualEnt; Cause = cause; _system = system; + _mapSystem = mapSystem; ExplosionType = explosionType; _tileSetIntensity = tileSetIntensity; Epicenter = epicenter; @@ -899,7 +902,7 @@ sealed class Explosion { if (list.Count > 0 && _entMan.EntityExists(grid.Owner)) { - grid.SetTiles(list); + _mapSystem.SetTiles(grid.Owner, grid, list); } } _tileUpdateDict.Clear(); diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index 818953ed4b..42b66b5479 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -389,7 +389,8 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem EntityManager, _mapManager, visualEnt, - queued.Cause); + queued.Cause, + _map); } private void CameraShake(float range, MapCoordinates epicenter, float totalIntensity) diff --git a/Content.Server/ImmovableRod/ImmovableRodSystem.cs b/Content.Server/ImmovableRod/ImmovableRodSystem.cs index f9873b0d6a..0d3d69c1bc 100644 --- a/Content.Server/ImmovableRod/ImmovableRodSystem.cs +++ b/Content.Server/ImmovableRod/ImmovableRodSystem.cs @@ -25,6 +25,7 @@ public sealed class ImmovableRodSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SharedMapSystem _map = default!; public override void Update(float frameTime) { @@ -39,7 +40,7 @@ public sealed class ImmovableRodSystem : EntitySystem if (!TryComp(trans.GridUid, out var grid)) continue; - grid.SetTile(trans.Coordinates, Tile.Empty); + _map.SetTile(trans.GridUid.Value, grid, trans.Coordinates, Tile.Empty); } } diff --git a/Content.Server/Parallax/BiomeSystem.cs b/Content.Server/Parallax/BiomeSystem.cs index 1d7ea2a440..22b531eb7c 100644 --- a/Content.Server/Parallax/BiomeSystem.cs +++ b/Content.Server/Parallax/BiomeSystem.cs @@ -962,7 +962,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem } } - grid.SetTiles(tiles); + _mapSystem.SetTiles(gridUid, grid, tiles); tiles.Clear(); component.LoadedChunks.Remove(chunk); diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs index d5ad1fb123..23c70d78f4 100644 --- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs +++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs @@ -40,6 +40,7 @@ namespace Content.Server.Pointing.EntitySystems [Dependency] private readonly VisibilitySystem _visibilitySystem = default!; [Dependency] private readonly SharedMindSystem _minds = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SharedMapSystem _map = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly ExamineSystemShared _examine = default!; @@ -73,8 +74,13 @@ namespace Content.Server.Pointing.EntitySystems } // TODO: FOV - private void SendMessage(EntityUid source, IEnumerable viewers, EntityUid pointed, string selfMessage, - string viewerMessage, string? viewerPointedAtMessage = null) + private void SendMessage( + EntityUid source, + IEnumerable viewers, + EntityUid pointed, + string selfMessage, + string viewerMessage, + string? viewerPointedAtMessage = null) { var netSource = GetNetEntity(source); @@ -226,8 +232,8 @@ namespace Content.Server.Pointing.EntitySystems if (_mapManager.TryFindGridAt(mapCoordsPointed, out var gridUid, out var grid)) { - position = $"EntId={gridUid} {grid.WorldToTile(mapCoordsPointed.Position)}"; - tileRef = grid.GetTileRef(grid.WorldToTile(mapCoordsPointed.Position)); + position = $"EntId={gridUid} {_map.WorldToTile(gridUid, grid, mapCoordsPointed.Position)}"; + tileRef = _map.GetTileRef(gridUid, grid, _map.WorldToTile(gridUid, grid, mapCoordsPointed.Position)); } var tileDef = _tileDefinitionManager[tileRef?.Tile.TypeId ?? 0]; diff --git a/Content.Server/Power/EntitySystems/CableSystem.Placer.cs b/Content.Server/Power/EntitySystems/CableSystem.Placer.cs index 263d626ef5..a5cf54fae0 100644 --- a/Content.Server/Power/EntitySystems/CableSystem.Placer.cs +++ b/Content.Server/Power/EntitySystems/CableSystem.Placer.cs @@ -11,6 +11,8 @@ namespace Content.Server.Power.EntitySystems; public sealed partial class CableSystem { [Dependency] private readonly IAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SharedMapSystem _map = default!; private void InitializeCablePlacer() { @@ -26,11 +28,12 @@ public sealed partial class CableSystem if (component.CablePrototypeId == null) return; - if(!TryComp(args.ClickLocation.GetGridUid(EntityManager), out var grid)) + if(!TryComp(_transform.GetGrid(args.ClickLocation), out var grid)) return; + var gridUid = _transform.GetGrid(args.ClickLocation)!.Value; var snapPos = grid.TileIndicesFor(args.ClickLocation); - var tileDef = (ContentTileDefinition) _tileManager[grid.GetTileRef(snapPos).Tile.TypeId]; + var tileDef = (ContentTileDefinition) _tileManager[_map.GetTileRef(gridUid, grid,snapPos).Tile.TypeId]; if (!tileDef.IsSubFloor || !tileDef.Sturdy) return; diff --git a/Content.Server/Procedural/DungeonSystem.Commands.cs b/Content.Server/Procedural/DungeonSystem.Commands.cs index 51a6a57bbe..09e881686e 100644 --- a/Content.Server/Procedural/DungeonSystem.Commands.cs +++ b/Content.Server/Procedural/DungeonSystem.Commands.cs @@ -1,8 +1,6 @@ -using System.Threading.Tasks; using Content.Server.Administration; using Content.Shared.Administration; using Content.Shared.Procedural; -using Content.Shared.Procedural.DungeonGenerators; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -44,7 +42,7 @@ public sealed partial class DungeonSystem } var position = new Vector2i(posX, posY); - var dungeonUid = _mapManager.GetMapEntityId(mapId); + var dungeonUid = _maps.GetMapOrInvalid(mapId); if (!TryComp(dungeonUid, out var dungeonGrid)) { @@ -118,7 +116,7 @@ public sealed partial class DungeonSystem } var mapId = new MapId(mapInt); - var mapUid = _mapManager.GetMapEntityId(mapId); + var mapUid = _maps.GetMapOrInvalid(mapId); if (!_prototype.TryIndex(args[1], out var pack)) { @@ -156,7 +154,7 @@ public sealed partial class DungeonSystem } } - grid.SetTiles(tiles); + _maps.SetTiles(mapUid, grid, tiles); shell.WriteLine(Loc.GetString("cmd-dungen_pack_vis")); } @@ -174,7 +172,7 @@ public sealed partial class DungeonSystem } var mapId = new MapId(mapInt); - var mapUid = _mapManager.GetMapEntityId(mapId); + var mapUid =_maps.GetMapOrInvalid(mapId); if (!_prototype.TryIndex(args[1], out var preset)) { @@ -197,7 +195,7 @@ public sealed partial class DungeonSystem } } - grid.SetTiles(tiles); + _maps.SetTiles(mapUid, grid, tiles); shell.WriteLine(Loc.GetString("cmd-dungen_pack_vis")); } diff --git a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs index 3bf820535f..bf5a45549c 100644 --- a/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs +++ b/Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs @@ -32,6 +32,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem [Dependency] private readonly SharedContainerSystem _containerSystem = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedTransformSystem _xformSystem = default!; + [Dependency] private readonly SharedMapSystem _mapSystem = default!; [Dependency] private readonly TagSystem _tagSystem = default!; #endregion Dependencies @@ -254,7 +255,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem var ev = new TilesConsumedByEventHorizonEvent(tiles, gridId, grid, hungry, eventHorizon); RaiseLocalEvent(hungry, ref ev); - grid.SetTiles(tiles); + _mapSystem.SetTiles(gridId, grid, tiles); } /// diff --git a/Content.Server/SubFloor/SubFloorHideSystem.cs b/Content.Server/SubFloor/SubFloorHideSystem.cs index 2767f500f9..497d7788d7 100644 --- a/Content.Server/SubFloor/SubFloorHideSystem.cs +++ b/Content.Server/SubFloor/SubFloorHideSystem.cs @@ -19,7 +19,7 @@ public sealed class SubFloorHideSystem : SharedSubFloorHideSystem var xform = Transform(uid); if (TryComp(xform.GridUid, out var grid) - && HasFloorCover(grid, grid.TileIndicesFor(xform.Coordinates))) + && HasFloorCover(xform.GridUid.Value, grid, Map.TileIndicesFor(xform.GridUid.Value, grid, xform.Coordinates))) { args.Cancel(); } diff --git a/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs b/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs index a09416e593..ba0a3a7132 100644 --- a/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs +++ b/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs @@ -15,6 +15,7 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinition = default!; [Dependency] private readonly TileSystem _tiles = default!; + [Dependency] private readonly SharedMapSystem _map = default!; /// public override void Initialize() @@ -25,10 +26,10 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem private void OnBlobFloorPlanBuilderStartup(EntityUid uid, BlobFloorPlanBuilderComponent component, ComponentStartup args) { - PlaceFloorplanTiles(component, Comp(uid)); + PlaceFloorplanTiles(uid, component, Comp(uid)); } - private void PlaceFloorplanTiles(BlobFloorPlanBuilderComponent comp, MapGridComponent grid) + private void PlaceFloorplanTiles(EntityUid gridUid, BlobFloorPlanBuilderComponent comp, MapGridComponent grid) { // NO MORE THAN TWO ALLOCATIONS THANK YOU VERY MUCH. // TODO: Just put these on a field instead then? @@ -82,7 +83,7 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem } } - grid.SetTiles(taken.Select(x => (x.Key, x.Value)).ToList()); + _map.SetTiles(gridUid, grid, taken.Select(x => (x.Key, x.Value)).ToList()); } } diff --git a/Content.Server/Worldgen/Systems/Debris/SimpleFloorPlanPopulatorSystem.cs b/Content.Server/Worldgen/Systems/Debris/SimpleFloorPlanPopulatorSystem.cs index ae1c6b5c00..a575e055ef 100644 --- a/Content.Server/Worldgen/Systems/Debris/SimpleFloorPlanPopulatorSystem.cs +++ b/Content.Server/Worldgen/Systems/Debris/SimpleFloorPlanPopulatorSystem.cs @@ -13,6 +13,7 @@ public sealed class SimpleFloorPlanPopulatorSystem : BaseWorldSystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinition = default!; + [Dependency] private readonly SharedMapSystem _map = default!; /// public override void Initialize() @@ -25,7 +26,7 @@ public sealed class SimpleFloorPlanPopulatorSystem : BaseWorldSystem { var placeables = new List(4); var grid = Comp(uid); - var enumerator = grid.GetAllTilesEnumerator(); + var enumerator = _map.GetAllTilesEnumerator(uid, grid); while (enumerator.MoveNext(out var tile)) { var coords = grid.GridTileToLocal(tile.Value.GridIndices); diff --git a/Content.Shared/Friction/TileFrictionController.cs b/Content.Shared/Friction/TileFrictionController.cs index 930de07dab..eb109caa42 100644 --- a/Content.Shared/Friction/TileFrictionController.cs +++ b/Content.Shared/Friction/TileFrictionController.cs @@ -22,6 +22,7 @@ namespace Content.Shared.Friction [Dependency] private readonly SharedGravitySystem _gravity = default!; [Dependency] private readonly SharedMoverController _mover = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SharedMapSystem _map = default!; private EntityQuery _frictionQuery; private EntityQuery _xformQuery; @@ -185,7 +186,7 @@ namespace Content.Shared.Friction : DefaultFriction; } - var tile = grid.GetTileRef(xform.Coordinates); + var tile = _map.GetTileRef(xform.GridUid.Value, grid, xform.Coordinates); // If it's a map but on an empty tile then just assume it has gravity. if (tile.Tile.IsEmpty && diff --git a/Content.Shared/Sound/SharedEmitSoundSystem.cs b/Content.Shared/Sound/SharedEmitSoundSystem.cs index 8733edf485..8040910dc3 100644 --- a/Content.Shared/Sound/SharedEmitSoundSystem.cs +++ b/Content.Shared/Sound/SharedEmitSoundSystem.cs @@ -35,6 +35,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem [Dependency] private readonly SharedAmbientSoundSystem _ambient = default!; [Dependency] private readonly SharedAudioSystem _audioSystem = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; + [Dependency] private readonly SharedMapSystem _map = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; public override void Initialize() @@ -86,7 +87,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem return; } - var tile = grid.GetTileRef(xform.Coordinates); + var tile = _map.GetTileRef(xform.GridUid.Value, grid, xform.Coordinates); // Handle maps being grids (we'll still emit the sound). if (xform.GridUid != xform.MapUid && tile.IsSpace(_tileDefMan)) diff --git a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs index cebc84ecb9..c90a28a513 100644 --- a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs +++ b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs @@ -17,6 +17,7 @@ namespace Content.Shared.SubFloor { [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly SharedAmbientSoundSystem _ambientSoundSystem = default!; + [Dependency] protected readonly SharedMapSystem Map = default!; [Dependency] protected readonly SharedAppearanceSystem Appearance = default!; public override void Initialize() @@ -92,7 +93,7 @@ namespace Content.Shared.SubFloor if (args.NewTile.Tile.IsEmpty) return; // Anything that was here will be unanchored anyways. - UpdateTile(Comp(args.NewTile.GridUid), args.NewTile.GridIndices); + UpdateTile(args.NewTile.GridUid, Comp(args.NewTile.GridUid), args.NewTile.GridIndices); } /// @@ -104,25 +105,25 @@ namespace Content.Shared.SubFloor return; if (xform.Anchored && TryComp(xform.GridUid, out var grid)) - component.IsUnderCover = HasFloorCover(grid, grid.TileIndicesFor(xform.Coordinates)); + component.IsUnderCover = HasFloorCover(xform.GridUid.Value, grid, Map.TileIndicesFor(xform.GridUid.Value, grid, xform.Coordinates)); else component.IsUnderCover = false; UpdateAppearance(uid, component); } - public bool HasFloorCover(MapGridComponent grid, Vector2i position) + public bool HasFloorCover(EntityUid gridUid, MapGridComponent grid, Vector2i position) { // TODO Redo this function. Currently wires on an asteroid are always "below the floor" - var tileDef = (ContentTileDefinition) _tileDefinitionManager[grid.GetTileRef(position).Tile.TypeId]; + var tileDef = (ContentTileDefinition) _tileDefinitionManager[Map.GetTileRef(gridUid, grid, position).Tile.TypeId]; return !tileDef.IsSubFloor; } - private void UpdateTile(MapGridComponent grid, Vector2i position) + private void UpdateTile(EntityUid gridUid, MapGridComponent grid, Vector2i position) { - var covered = HasFloorCover(grid, position); + var covered = HasFloorCover(gridUid, grid, position); - foreach (var uid in grid.GetAnchoredEntities(position)) + foreach (var uid in Map.GetAnchoredEntities(gridUid, grid, position)) { if (!TryComp(uid, out SubFloorHideComponent? hideComp)) continue; diff --git a/Content.Shared/Tiles/FloorTileSystem.cs b/Content.Shared/Tiles/FloorTileSystem.cs index f031292f23..3acd5051c9 100644 --- a/Content.Shared/Tiles/FloorTileSystem.cs +++ b/Content.Shared/Tiles/FloorTileSystem.cs @@ -36,6 +36,7 @@ public sealed class FloorTileSystem : EntitySystem [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly TileSystem _tile = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SharedMapSystem _map = default!; private static readonly Vector2 CheckRange = new(1f, 1f); @@ -132,7 +133,7 @@ public sealed class FloorTileSystem : EntitySystem return; } - var tile = mapGrid.GetTileRef(location); + var tile = _map.GetTileRef(gridUid, mapGrid, location); var baseTurf = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId]; if (HasBaseTurf(currentTileDefinition, baseTurf.ID)) @@ -176,7 +177,7 @@ public sealed class FloorTileSystem : EntitySystem var random = new System.Random((int) _timing.CurTick.Value); var variant = _tile.PickVariant((ContentTileDefinition) _tileDefinitionManager[tileId], random); - mapGrid.SetTile(location.Offset(new Vector2(offset, offset)), new Tile(tileId, 0, variant)); + _map.SetTile(gridUid, mapGrid,location.Offset(new Vector2(offset, offset)), new Tile(tileId, 0, variant)); _audio.PlayPredicted(placeSound, location, user); } From a5840b925b089e5e82cbddc8439498a6b216ae5d Mon Sep 17 00:00:00 2001 From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Date: Sun, 29 Sep 2024 03:25:21 +0300 Subject: [PATCH 16/88] Fix RA0032 (#32514) --- .../Audio/ContentAudioSystem.LobbyMusic.cs | 7 +++---- Content.Client/Entry/EntryPoint.cs | 3 +-- .../Systems/AdminVerbSystem.Tools.cs | 5 ++--- .../Administration/Systems/AdminVerbSystem.cs | 5 +---- .../AtmosphereSystem.HighPressureDelta.cs | 2 +- .../AtmosphereSystem.Monstermos.cs | 2 +- .../Atmos/EntitySystems/AtmosphereSystem.cs | 5 +---- Content.Server/Body/Systems/LungSystem.cs | 5 ++--- Content.Server/Connection/ConnectionManager.cs | 7 +++---- Content.Server/GameTicking/GameTicker.CVars.cs | 18 +++++++++--------- .../GameTicking/GameTicker.GamePreset.cs | 8 ++++---- .../GameTicking/GameTicker.Player.cs | 11 +++-------- .../GameTicking/GameTicker.Replays.cs | 4 ++-- .../GameTicking/GameTicker.RoundFlow.cs | 2 +- Content.Server/GameTicking/GameTicker.cs | 5 ----- Content.Server/Ghost/GhostSystem.cs | 8 +++----- Content.Server/MassMedia/Systems/NewsSystem.cs | 3 --- Content.Server/Medical/CryoPodSystem.cs | 7 +------ .../EntitySystems/SmokingSystem.Vape.cs | 5 ++--- .../ParticleAcceleratorSystem.ControlBox.cs | 6 ++---- .../Physics/Controllers/ChaoticJumpSystem.cs | 3 +-- .../Power/EntitySystems/CableSystem.cs | 3 +-- Content.Server/Store/Systems/StoreSystem.Ui.cs | 3 +-- Content.Shared/Anomaly/SharedAnomalySystem.cs | 3 +-- Content.Shared/Roles/Jobs/SharedJobSystem.cs | 10 ++++------ .../Tools/Systems/SharedToolSystem.Welder.cs | 2 +- .../Tools/Systems/SharedToolSystem.cs | 1 - 27 files changed, 51 insertions(+), 92 deletions(-) diff --git a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs index 9864dbcb2a..7d7d77f51a 100644 --- a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs @@ -20,7 +20,6 @@ public sealed partial class ContentAudioSystem { [Dependency] private readonly IBaseClient _client = default!; [Dependency] private readonly ClientGameTicker _gameTicker = default!; - [Dependency] private readonly IStateManager _stateManager = default!; [Dependency] private readonly IResourceCache _resourceCache = default!; private readonly AudioParams _lobbySoundtrackParams = new(-5f, 1, 0, 0, 0, false, 0f); @@ -71,7 +70,7 @@ public sealed partial class ContentAudioSystem Subs.CVar(_configManager, CCVars.LobbyMusicEnabled, LobbyMusicCVarChanged); Subs.CVar(_configManager, CCVars.LobbyMusicVolume, LobbyMusicVolumeCVarChanged); - _stateManager.OnStateChanged += StateManagerOnStateChanged; + _state.OnStateChanged += StateManagerOnStateChanged; _client.PlayerLeaveServer += OnLeave; @@ -115,7 +114,7 @@ public sealed partial class ContentAudioSystem private void LobbyMusicCVarChanged(bool musicEnabled) { - if (musicEnabled && _stateManager.CurrentState is LobbyState) + if (musicEnabled && _state.CurrentState is LobbyState) { StartLobbyMusic(); } @@ -234,7 +233,7 @@ public sealed partial class ContentAudioSystem private void ShutdownLobbyMusic() { - _stateManager.OnStateChanged -= StateManagerOnStateChanged; + _state.OnStateChanged -= StateManagerOnStateChanged; _client.PlayerLeaveServer -= OnLeave; diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index c4c18f154a..cd73d3397d 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -69,7 +69,6 @@ namespace Content.Client.Entry [Dependency] private readonly IResourceManager _resourceManager = default!; [Dependency] private readonly IReplayLoadManager _replayLoad = default!; [Dependency] private readonly ILogManager _logManager = default!; - [Dependency] private readonly ContentReplayPlaybackManager _replayMan = default!; [Dependency] private readonly DebugMonitorManager _debugMonitorManager = default!; public override void Init() @@ -191,7 +190,7 @@ namespace Content.Client.Entry _resourceManager, ReplayConstants.ReplayZipFolder.ToRootedPath()); - _replayMan.LastLoad = (null, ReplayConstants.ReplayZipFolder.ToRootedPath()); + _playbackMan.LastLoad = (null, ReplayConstants.ReplayZipFolder.ToRootedPath()); _replayLoad.LoadAndStartReplay(reader); } else if (_gameController.LaunchState.FromLauncher) diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs index 56cf287850..70fcfccc4e 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs @@ -52,7 +52,6 @@ public sealed partial class AdminVerbSystem [Dependency] private readonly StationJobsSystem _stationJobsSystem = default!; [Dependency] private readonly JointSystem _jointSystem = default!; [Dependency] private readonly BatterySystem _batterySystem = default!; - [Dependency] private readonly SharedTransformSystem _xformSystem = default!; [Dependency] private readonly MetaDataSystem _metaSystem = default!; [Dependency] private readonly GunSystem _gun = default!; @@ -327,7 +326,7 @@ public sealed partial class AdminVerbSystem Act = () => { var (mapUid, gridUid) = _adminTestArenaSystem.AssertArenaLoaded(player); - _xformSystem.SetCoordinates(args.Target, new EntityCoordinates(gridUid ?? mapUid, Vector2.One)); + _transformSystem.SetCoordinates(args.Target, new EntityCoordinates(gridUid ?? mapUid, Vector2.One)); }, Impact = LogImpact.Medium, Message = Loc.GetString("admin-trick-send-to-test-arena-description"), @@ -533,7 +532,7 @@ public sealed partial class AdminVerbSystem if (shuttle is null) return; - _xformSystem.SetCoordinates(args.User, new EntityCoordinates(shuttle.Value, Vector2.Zero)); + _transformSystem.SetCoordinates(args.User, new EntityCoordinates(shuttle.Value, Vector2.Zero)); }, Impact = LogImpact.Low, Message = Loc.GetString("admin-trick-locate-cargo-shuttle-description"), diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.cs b/Content.Server/Administration/Systems/AdminVerbSystem.cs index 5aa05ce28b..2ab27e4388 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.cs @@ -35,10 +35,8 @@ using Robust.Shared.Toolshed; using Robust.Shared.Utility; using System.Linq; using Content.Server.Silicons.Laws; -using Content.Shared.Silicons.Laws; using Content.Shared.Silicons.Laws.Components; using Robust.Server.Player; -using Content.Shared.Mind; using Robust.Shared.Physics.Components; using static Content.Shared.Configurable.ConfigurationComponent; @@ -63,7 +61,6 @@ namespace Content.Server.Administration.Systems [Dependency] private readonly ArtifactSystem _artifactSystem = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly PrayerSystem _prayerSystem = default!; - [Dependency] private readonly EuiManager _eui = default!; [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly ToolshedManager _toolshed = default!; [Dependency] private readonly RejuvenateSystem _rejuvenate = default!; @@ -294,7 +291,7 @@ namespace Content.Server.Administration.Systems Act = () => { var ui = new AdminLogsEui(); - _eui.OpenEui(ui, player); + _euiManager.OpenEui(ui, player); ui.SetLogFilter(search:args.Target.Id.ToString()); }, Impact = LogImpact.Low diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.HighPressureDelta.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.HighPressureDelta.cs index b96dd0ac48..0b43c92414 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.HighPressureDelta.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.HighPressureDelta.cs @@ -210,7 +210,7 @@ namespace Content.Server.Atmos.EntitySystems MovedByPressureComponent.ProbabilityOffset); // Can we yeet the thing (due to probability, strength, etc.) - if (moveProb > MovedByPressureComponent.ProbabilityOffset && _robustRandom.Prob(MathF.Min(moveProb / 100f, 1f)) + if (moveProb > MovedByPressureComponent.ProbabilityOffset && _random.Prob(MathF.Min(moveProb / 100f, 1f)) && !float.IsPositiveInfinity(component.MoveResist) && (physics.BodyType != BodyType.Static && (maxForce >= (component.MoveResist * MovedByPressureComponent.MoveForcePushRatio))) diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs index 08193027d6..d703a98154 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs @@ -689,7 +689,7 @@ namespace Content.Server.Atmos.EntitySystems var chance = MathHelper.Clamp(0.01f + (sum / SpacingMaxWind) * 0.3f, 0.003f, 0.3f); - if (sum > 20 && _robustRandom.Prob(chance)) + if (sum > 20 && _random.Prob(chance)) PryTile(mapGrid, tile.GridIndices); } diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs index 13d8f73dc5..f27f7411bf 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs @@ -14,7 +14,6 @@ using Robust.Shared.Containers; using Robust.Shared.Map; using Robust.Shared.Physics.Systems; using Robust.Shared.Prototypes; -using Robust.Shared.Random; using System.Linq; namespace Content.Server.Atmos.EntitySystems; @@ -27,7 +26,6 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem { [Dependency] private readonly IMapManager _mapManager = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; - [Dependency] private readonly IRobustRandom _robustRandom = default!; [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly InternalsSystem _internals = default!; @@ -39,7 +37,6 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly TileSystem _tile = default!; [Dependency] private readonly MapSystem _map = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] public readonly PuddleSystem Puddle = default!; private const float ExposedUpdateDelay = 1f; @@ -124,6 +121,6 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem private void CacheDecals() { - _burntDecals = _prototypeManager.EnumeratePrototypes().Where(x => x.Tags.Contains("burnt")).Select(x => x.ID).ToArray(); + _burntDecals = _protoMan.EnumeratePrototypes().Where(x => x.Tags.Contains("burnt")).Select(x => x.ID).ToArray(); } } diff --git a/Content.Server/Body/Systems/LungSystem.cs b/Content.Server/Body/Systems/LungSystem.cs index 901d61f8fc..859618ae1a 100644 --- a/Content.Server/Body/Systems/LungSystem.cs +++ b/Content.Server/Body/Systems/LungSystem.cs @@ -14,7 +14,6 @@ public sealed class LungSystem : EntitySystem [Dependency] private readonly AtmosphereSystem _atmos = default!; [Dependency] private readonly InternalsSystem _internals = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; - [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; public static string LungSolutionName = "Lung"; @@ -29,7 +28,7 @@ public sealed class LungSystem : EntitySystem private void OnGotUnequipped(Entity ent, ref GotUnequippedEvent args) { - _atmosphereSystem.DisconnectInternals(ent); + _atmos.DisconnectInternals(ent); } private void OnGotEquipped(Entity ent, ref GotEquippedEvent args) @@ -93,7 +92,7 @@ public sealed class LungSystem : EntitySystem if (moles <= 0) continue; - var reagent = _atmosphereSystem.GasReagents[i]; + var reagent = _atmos.GasReagents[i]; if (reagent is null) continue; diff --git a/Content.Server/Connection/ConnectionManager.cs b/Content.Server/Connection/ConnectionManager.cs index 1b142830f1..2c1f9fb36f 100644 --- a/Content.Server/Connection/ConnectionManager.cs +++ b/Content.Server/Connection/ConnectionManager.cs @@ -46,7 +46,6 @@ namespace Content.Server.Connection /// public sealed partial class ConnectionManager : IConnectionManager { - [Dependency] private readonly IServerDbManager _dbManager = default!; [Dependency] private readonly IPlayerManager _plyMgr = default!; [Dependency] private readonly IServerNetManager _netMgr = default!; [Dependency] private readonly IServerDbManager _db = default!; @@ -205,7 +204,7 @@ namespace Content.Server.Connection return null; } - var adminData = await _dbManager.GetAdminDataForAsync(e.UserId); + var adminData = await _db.GetAdminDataForAsync(e.UserId); if (_cfg.GetCVar(CCVars.PanicBunkerEnabled) && adminData == null) { @@ -213,7 +212,7 @@ namespace Content.Server.Connection var customReason = _cfg.GetCVar(CCVars.PanicBunkerCustomReason); var minMinutesAge = _cfg.GetCVar(CCVars.PanicBunkerMinAccountAge); - var record = await _dbManager.GetPlayerRecordByUserId(userId); + var record = await _db.GetPlayerRecordByUserId(userId); var validAccountAge = record != null && record.FirstSeenTime.CompareTo(DateTimeOffset.UtcNow - TimeSpan.FromMinutes(minMinutesAge)) <= 0; var bypassAllowed = _cfg.GetCVar(CCVars.BypassBunkerWhitelist) && await _db.GetWhitelistStatusAsync(userId); @@ -317,7 +316,7 @@ namespace Content.Server.Connection var maxPlaytimeMinutes = _cfg.GetCVar(CCVars.BabyJailMaxOverallMinutes); // Wait some time to lookup data - var record = await _dbManager.GetPlayerRecordByUserId(userId); + var record = await _db.GetPlayerRecordByUserId(userId); // No player record = new account or the DB is having a skill issue if (record == null) diff --git a/Content.Server/GameTicking/GameTicker.CVars.cs b/Content.Server/GameTicking/GameTicker.CVars.cs index 60ffa660f5..bb68459740 100644 --- a/Content.Server/GameTicking/GameTicker.CVars.cs +++ b/Content.Server/GameTicking/GameTicker.CVars.cs @@ -36,7 +36,7 @@ namespace Content.Server.GameTicking private void InitializeCVars() { - Subs.CVar(_configurationManager, CCVars.GameLobbyEnabled, value => + Subs.CVar(_cfg, CCVars.GameLobbyEnabled, value => { LobbyEnabled = value; foreach (var (userId, status) in _playerGameStatuses) @@ -47,23 +47,23 @@ namespace Content.Server.GameTicking LobbyEnabled ? PlayerGameStatus.NotReadyToPlay : PlayerGameStatus.ReadyToPlay; } }, true); - Subs.CVar(_configurationManager, CCVars.GameDummyTicker, value => DummyTicker = value, true); - Subs.CVar(_configurationManager, CCVars.GameLobbyDuration, value => LobbyDuration = TimeSpan.FromSeconds(value), true); - Subs.CVar(_configurationManager, CCVars.GameDisallowLateJoins, + Subs.CVar(_cfg, CCVars.GameDummyTicker, value => DummyTicker = value, true); + Subs.CVar(_cfg, CCVars.GameLobbyDuration, value => LobbyDuration = TimeSpan.FromSeconds(value), true); + Subs.CVar(_cfg, CCVars.GameDisallowLateJoins, value => { DisallowLateJoin = value; UpdateLateJoinStatus(); }, true); - Subs.CVar(_configurationManager, CCVars.AdminLogsServerName, value => + Subs.CVar(_cfg, CCVars.AdminLogsServerName, value => { // TODO why tf is the server name on admin logs ServerName = value; }, true); - Subs.CVar(_configurationManager, CCVars.DiscordRoundUpdateWebhook, value => + Subs.CVar(_cfg, CCVars.DiscordRoundUpdateWebhook, value => { if (!string.IsNullOrWhiteSpace(value)) { _discord.GetWebhook(value, data => _webhookIdentifier = data.ToIdentifier()); } }, true); - Subs.CVar(_configurationManager, CCVars.DiscordRoundEndRoleWebhook, value => + Subs.CVar(_cfg, CCVars.DiscordRoundEndRoleWebhook, value => { DiscordRoundEndRole = value; @@ -72,9 +72,9 @@ namespace Content.Server.GameTicking DiscordRoundEndRole = null; } }, true); - Subs.CVar(_configurationManager, CCVars.RoundEndSoundCollection, value => RoundEndSoundCollection = value, true); + Subs.CVar(_cfg, CCVars.RoundEndSoundCollection, value => RoundEndSoundCollection = value, true); #if EXCEPTION_TOLERANCE - Subs.CVar(_configurationManager, CCVars.RoundStartFailShutdownCount, value => RoundStartFailShutdownCount = value, true); + Subs.CVar(_cfg, CCVars.RoundStartFailShutdownCount, value => RoundStartFailShutdownCount = value, true); #endif } } diff --git a/Content.Server/GameTicking/GameTicker.GamePreset.cs b/Content.Server/GameTicking/GameTicker.GamePreset.cs index 5642e84f90..d1a8b062c4 100644 --- a/Content.Server/GameTicking/GameTicker.GamePreset.cs +++ b/Content.Server/GameTicking/GameTicker.GamePreset.cs @@ -41,9 +41,9 @@ namespace Content.Server.GameTicking DelayStart(TimeSpan.FromSeconds(PresetFailedCooldownIncrease)); } - if (_configurationManager.GetCVar(CCVars.GameLobbyFallbackEnabled)) + if (_cfg.GetCVar(CCVars.GameLobbyFallbackEnabled)) { - var fallbackPresets = _configurationManager.GetCVar(CCVars.GameLobbyFallbackPreset).Split(","); + var fallbackPresets = _cfg.GetCVar(CCVars.GameLobbyFallbackPreset).Split(","); var startFailed = true; foreach (var preset in fallbackPresets) @@ -86,7 +86,7 @@ namespace Content.Server.GameTicking private void InitializeGamePreset() { - SetGamePreset(LobbyEnabled ? _configurationManager.GetCVar(CCVars.GameLobbyDefaultPreset) : "sandbox"); + SetGamePreset(LobbyEnabled ? _cfg.GetCVar(CCVars.GameLobbyDefaultPreset) : "sandbox"); } public void SetGamePreset(GamePresetPrototype? preset, bool force = false) @@ -190,7 +190,7 @@ namespace Content.Server.GameTicking private void IncrementRoundNumber() { var playerIds = _playerGameStatuses.Keys.Select(player => player.UserId).ToArray(); - var serverName = _configurationManager.GetCVar(CCVars.AdminLogsServerName); + var serverName = _cfg.GetCVar(CCVars.AdminLogsServerName); // TODO FIXME AAAAAAAAAAAAAAAAAAAH THIS IS BROKEN // Task.Run as a terrible dirty workaround to avoid synchronization context deadlock from .Result here. diff --git a/Content.Server/GameTicking/GameTicker.Player.cs b/Content.Server/GameTicking/GameTicker.Player.cs index 61cdf6f855..f376408130 100644 --- a/Content.Server/GameTicking/GameTicker.Player.cs +++ b/Content.Server/GameTicking/GameTicker.Player.cs @@ -1,5 +1,3 @@ -using System.Linq; -using Content.Server.Database; using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.GameTicking; @@ -9,7 +7,6 @@ using Content.Shared.Preferences; using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared.Audio; -using Robust.Shared.Audio.Systems; using Robust.Shared.Enums; using Robust.Shared.Player; using Robust.Shared.Timing; @@ -21,8 +18,6 @@ namespace Content.Server.GameTicking public sealed partial class GameTicker { [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly IServerDbManager _dbManager = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; private void InitializePlayer() { @@ -64,7 +59,7 @@ namespace Content.Server.GameTicking // timer time must be > tick length Timer.Spawn(0, () => _playerManager.JoinGame(args.Session)); - var record = await _dbManager.GetPlayerRecordByUserId(args.Session.UserId); + var record = await _db.GetPlayerRecordByUserId(args.Session.UserId); var firstConnection = record != null && Math.Abs((record.FirstSeenTime - record.LastSeenTime).TotalMinutes) < 1; @@ -74,8 +69,8 @@ namespace Content.Server.GameTicking RaiseNetworkEvent(GetConnectionStatusMsg(), session.Channel); - if (firstConnection && _configurationManager.GetCVar(CCVars.AdminNewPlayerJoinSound)) - _audioSystem.PlayGlobal(new SoundPathSpecifier("/Audio/Effects/newplayerping.ogg"), + if (firstConnection && _cfg.GetCVar(CCVars.AdminNewPlayerJoinSound)) + _audio.PlayGlobal(new SoundPathSpecifier("/Audio/Effects/newplayerping.ogg"), Filter.Empty().AddPlayers(_adminManager.ActiveAdmins), false, audioParams: new AudioParams { Volume = -5f }); diff --git a/Content.Server/GameTicking/GameTicker.Replays.cs b/Content.Server/GameTicking/GameTicker.Replays.cs index 9109fbf96a..7efa52bd00 100644 --- a/Content.Server/GameTicking/GameTicker.Replays.cs +++ b/Content.Server/GameTicking/GameTicker.Replays.cs @@ -127,8 +127,8 @@ public sealed partial class GameTicker metadata["gamemode"] = new ValueDataNode(CurrentPreset != null ? Loc.GetString(CurrentPreset.ModeTitle) : string.Empty); metadata["roundEndPlayers"] = _serialman.WriteValue(_replayRoundPlayerInfo); metadata["roundEndText"] = new ValueDataNode(_replayRoundText); - metadata["server_id"] = new ValueDataNode(_configurationManager.GetCVar(CCVars.ServerId)); - metadata["server_name"] = new ValueDataNode(_configurationManager.GetCVar(CCVars.AdminLogsServerName)); + metadata["server_id"] = new ValueDataNode(_cfg.GetCVar(CCVars.ServerId)); + metadata["server_name"] = new ValueDataNode(_cfg.GetCVar(CCVars.AdminLogsServerName)); metadata["roundId"] = new ValueDataNode(RoundId.ToString()); } diff --git a/Content.Server/GameTicking/GameTicker.RoundFlow.cs b/Content.Server/GameTicking/GameTicker.RoundFlow.cs index ca087c46ed..0c7668d354 100644 --- a/Content.Server/GameTicking/GameTicker.RoundFlow.cs +++ b/Content.Server/GameTicking/GameTicker.RoundFlow.cs @@ -364,7 +364,7 @@ namespace Content.Server.GameTicking var listOfPlayerInfo = new List(); // Grab the great big book of all the Minds, we'll need them for this. var allMinds = EntityQueryEnumerator(); - var pvsOverride = _configurationManager.GetCVar(CCVars.RoundEndPVSOverrides); + var pvsOverride = _cfg.GetCVar(CCVars.RoundEndPVSOverrides); while (allMinds.MoveNext(out var mindId, out var mind)) { // TODO don't list redundant observer roles? diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index fa1e01c7a8..f8ba7e1d7d 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -8,19 +8,15 @@ using Content.Server.Maps; using Content.Server.Players.PlayTimeTracking; using Content.Server.Preferences.Managers; using Content.Server.ServerUpdates; -using Content.Server.Shuttles.Systems; using Content.Server.Station.Systems; using Content.Shared.Chat; -using Content.Shared.Damage; using Content.Shared.GameTicking; using Content.Shared.Mind; -using Content.Shared.Mobs.Systems; using Content.Shared.Roles; using Robust.Server; using Robust.Server.GameObjects; using Robust.Server.GameStates; using Robust.Shared.Audio.Systems; -using Robust.Shared.Configuration; using Robust.Shared.Console; using Robust.Shared.Map; using Robust.Shared.Prototypes; @@ -39,7 +35,6 @@ namespace Content.Server.GameTicking [Dependency] private readonly IBanManager _banManager = default!; [Dependency] private readonly IBaseServer _baseServer = default!; [Dependency] private readonly IChatManager _chatManager = default!; - [Dependency] private readonly IConfigurationManager _configurationManager = default!; [Dependency] private readonly IConsoleHost _consoleHost = default!; [Dependency] private readonly IGameMapManager _gameMapManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index 945b0ff998..85fec0d7d1 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -46,11 +46,9 @@ namespace Content.Server.Ghost [Dependency] private readonly JobSystem _jobs = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly MindSystem _minds = default!; - [Dependency] private readonly SharedMindSystem _mindSystem = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; - [Dependency] private readonly GameTicker _ticker = default!; [Dependency] private readonly TransformSystem _transformSystem = default!; [Dependency] private readonly VisibilitySystem _visibilitySystem = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; @@ -170,7 +168,7 @@ namespace Content.Server.Ghost // Allow this entity to be seen by other ghosts. var visibility = EnsureComp(uid); - if (_ticker.RunLevel != GameRunLevel.PostRound) + if (_gameTicker.RunLevel != GameRunLevel.PostRound) { _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); @@ -277,7 +275,7 @@ namespace Content.Server.Ghost return; } - _mindSystem.UnVisit(actor.PlayerSession); + _mind.UnVisit(actor.PlayerSession); } #region Warp @@ -455,7 +453,7 @@ namespace Content.Server.Ghost spawnPosition = null; // If it's bad, look for a valid point to spawn - spawnPosition ??= _ticker.GetObserverSpawnPoint(); + spawnPosition ??= _gameTicker.GetObserverSpawnPoint(); // Make sure the new point is valid too if (!IsValidSpawnPosition(spawnPosition)) diff --git a/Content.Server/MassMedia/Systems/NewsSystem.cs b/Content.Server/MassMedia/Systems/NewsSystem.cs index 3ac4ecc37b..641f2074b8 100644 --- a/Content.Server/MassMedia/Systems/NewsSystem.cs +++ b/Content.Server/MassMedia/Systems/NewsSystem.cs @@ -4,7 +4,6 @@ using Content.Server.CartridgeLoader; using Content.Server.CartridgeLoader.Cartridges; using Content.Server.Chat.Managers; using Content.Server.GameTicking; -using Content.Server.Interaction; using Content.Server.MassMedia.Components; using Content.Server.Popups; using Content.Server.Station.Systems; @@ -27,7 +26,6 @@ public sealed class NewsSystem : SharedNewsSystem { [Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!; [Dependency] private readonly IGameTiming _timing = default!; - [Dependency] private readonly InteractionSystem _interaction = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly CartridgeLoaderSystem _cartridgeLoaderSystem = default!; @@ -35,7 +33,6 @@ public sealed class NewsSystem : SharedNewsSystem [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly StationSystem _station = default!; [Dependency] private readonly GameTicker _ticker = default!; - [Dependency] private readonly AccessReaderSystem _accessReader = default!; [Dependency] private readonly IChatManager _chatManager = default!; public override void Initialize() diff --git a/Content.Server/Medical/CryoPodSystem.cs b/Content.Server/Medical/CryoPodSystem.cs index a1c1f1f9ce..fc9ab081d2 100644 --- a/Content.Server/Medical/CryoPodSystem.cs +++ b/Content.Server/Medical/CryoPodSystem.cs @@ -1,16 +1,13 @@ using Content.Server.Administration.Logs; -using Content.Server.Atmos; using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Components; using Content.Server.Atmos.Piping.Unary.EntitySystems; using Content.Server.Body.Components; using Content.Server.Body.Systems; using Content.Server.Medical.Components; -using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.NodeGroups; using Content.Server.NodeContainer.Nodes; -using Content.Server.Power.Components; using Content.Server.Temperature.Components; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Atmos; @@ -18,7 +15,6 @@ using Content.Shared.UserInterface; using Content.Shared.Chemistry; using Content.Shared.Chemistry.Components; using Content.Shared.Chemistry.Components.SolutionManager; -using Content.Shared.Chemistry.Reagent; using Content.Shared.Climbing.Systems; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; @@ -46,7 +42,6 @@ public sealed partial class CryoPodSystem : SharedCryoPodSystem [Dependency] private readonly ItemSlotsSystem _itemSlotsSystem = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly BloodstreamSystem _bloodstreamSystem = default!; - [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!; [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly UserInterfaceSystem _uiSystem = default!; [Dependency] private readonly SharedToolSystem _toolSystem = default!; @@ -196,7 +191,7 @@ public sealed partial class CryoPodSystem : SharedCryoPodSystem } // TODO: This should be a state my dude - _userInterfaceSystem.ServerSendUiMessage( + _uiSystem.ServerSendUiMessage( entity.Owner, HealthAnalyzerUiKey.Key, new HealthAnalyzerScannedUserMessage(GetNetEntity(entity.Comp.BodyContainer.ContainedEntity), diff --git a/Content.Server/Nutrition/EntitySystems/SmokingSystem.Vape.cs b/Content.Server/Nutrition/EntitySystems/SmokingSystem.Vape.cs index f7650f599b..c3d41cead6 100644 --- a/Content.Server/Nutrition/EntitySystems/SmokingSystem.Vape.cs +++ b/Content.Server/Nutrition/EntitySystems/SmokingSystem.Vape.cs @@ -27,7 +27,6 @@ namespace Content.Server.Nutrition.EntitySystems [Dependency] private readonly FoodSystem _foodSystem = default!; [Dependency] private readonly ExplosionSystem _explosionSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; - [Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!; private void InitializeVapes() { @@ -127,7 +126,7 @@ namespace Content.Server.Nutrition.EntitySystems || args.Args.Target == null) return; - var environment = _atmosphereSystem.GetContainingMixture(args.Args.Target.Value, true, true); + var environment = _atmos.GetContainingMixture(args.Args.Target.Value, true, true); if (environment == null) { return; @@ -139,7 +138,7 @@ namespace Content.Server.Nutrition.EntitySystems var merger = new GasMixture(1) { Temperature = args.Solution.Temperature }; merger.SetMoles(entity.Comp.GasType, args.Solution.Volume.Value / entity.Comp.ReductionFactor); - _atmosphereSystem.Merge(environment, merger); + _atmos.Merge(environment, merger); args.Solution.RemoveAllSolution(); diff --git a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs index 404eb00fef..90a5cb2ea0 100644 --- a/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs +++ b/Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs @@ -9,7 +9,6 @@ using Content.Shared.CCVar; using Content.Shared.Power; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; -using Robust.Shared.Timing; using Robust.Shared.Player; namespace Content.Server.ParticleAccelerator.EntitySystems; @@ -18,7 +17,6 @@ public sealed partial class ParticleAcceleratorSystem { [Dependency] private readonly IAdminManager _adminManager = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - [Dependency] private readonly IGameTiming _timing = default!; private void InitializeControlBoxSystem() { @@ -175,7 +173,7 @@ public sealed partial class ParticleAcceleratorSystem if (strength >= alertMinPowerState) { var pos = Transform(uid); - if (_timing.CurTime > comp.EffectCooldown) + if (_gameTiming.CurTime > comp.EffectCooldown) { _chat.SendAdminAlert(player, Loc.GetString("particle-accelerator-admin-power-strength-warning", @@ -186,7 +184,7 @@ public sealed partial class ParticleAcceleratorSystem Filter.Empty().AddPlayers(_adminManager.ActiveAdmins), false, AudioParams.Default.WithVolume(-8f)); - comp.EffectCooldown = _timing.CurTime + comp.CooldownDuration; + comp.EffectCooldown = _gameTiming.CurTime + comp.CooldownDuration; } } } diff --git a/Content.Server/Physics/Controllers/ChaoticJumpSystem.cs b/Content.Server/Physics/Controllers/ChaoticJumpSystem.cs index ee4b776cf0..3f2493b43f 100644 --- a/Content.Server/Physics/Controllers/ChaoticJumpSystem.cs +++ b/Content.Server/Physics/Controllers/ChaoticJumpSystem.cs @@ -18,7 +18,6 @@ public sealed class ChaoticJumpSystem : VirtualController [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; - [Dependency] private readonly SharedTransformSystem _xform = default!; public override void Initialize() { @@ -73,6 +72,6 @@ public sealed class ChaoticJumpSystem : VirtualController Spawn(component.Effect, transform.Coordinates); - _xform.SetWorldPosition(uid, targetPos); + _transform.SetWorldPosition(uid, targetPos); } } diff --git a/Content.Server/Power/EntitySystems/CableSystem.cs b/Content.Server/Power/EntitySystems/CableSystem.cs index 62eb08d7cb..d0f45b54fc 100644 --- a/Content.Server/Power/EntitySystems/CableSystem.cs +++ b/Content.Server/Power/EntitySystems/CableSystem.cs @@ -17,7 +17,6 @@ public sealed partial class CableSystem : EntitySystem [Dependency] private readonly SharedToolSystem _toolSystem = default!; [Dependency] private readonly StackSystem _stack = default!; [Dependency] private readonly ElectrocutionSystem _electrocutionSystem = default!; - [Dependency] private readonly IAdminLogManager _adminLogs = default!; public override void Initialize() { @@ -51,7 +50,7 @@ public sealed partial class CableSystem : EntitySystem if (_electrocutionSystem.TryDoElectrifiedAct(uid, args.User)) return; - _adminLogs.Add(LogType.CableCut, LogImpact.Medium, $"The {ToPrettyString(uid)} at {xform.Coordinates} was cut by {ToPrettyString(args.User)}."); + _adminLogger.Add(LogType.CableCut, LogImpact.Medium, $"The {ToPrettyString(uid)} at {xform.Coordinates} was cut by {ToPrettyString(args.User)}."); Spawn(cable.CableDroppedOnCutPrototype, xform.Coordinates); QueueDel(uid); diff --git a/Content.Server/Store/Systems/StoreSystem.Ui.cs b/Content.Server/Store/Systems/StoreSystem.Ui.cs index 247055c2a7..95e5711984 100644 --- a/Content.Server/Store/Systems/StoreSystem.Ui.cs +++ b/Content.Server/Store/Systems/StoreSystem.Ui.cs @@ -30,7 +30,6 @@ public sealed partial class StoreSystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly StackSystem _stack = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; private void InitializeUi() { @@ -260,7 +259,7 @@ public sealed partial class StoreSystem //log dat shit. _admin.Add(LogType.StorePurchase, LogImpact.Low, - $"{ToPrettyString(buyer):player} purchased listing \"{ListingLocalisationHelpers.GetLocalisedNameOrEntityName(listing, _prototypeManager)}\" from {ToPrettyString(uid)}"); + $"{ToPrettyString(buyer):player} purchased listing \"{ListingLocalisationHelpers.GetLocalisedNameOrEntityName(listing, _proto)}\" from {ToPrettyString(uid)}"); listing.PurchaseAmount++; //track how many times something has been purchased _audio.PlayEntity(component.BuySuccessSound, msg.Actor, uid); //cha-ching! diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index 07beb1444d..00d97c1a46 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -33,7 +33,6 @@ public abstract class SharedAnomalySystem : EntitySystem [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] protected readonly SharedPopupSystem Popup = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; - [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() @@ -372,7 +371,7 @@ public abstract class SharedAnomalySystem : EntitySystem if (tilerefs.Count == 0) break; - var tileref = _random.Pick(tilerefs); + var tileref = Random.Pick(tilerefs); var distance = MathF.Sqrt(MathF.Pow(tileref.X - xform.LocalPosition.X, 2) + MathF.Pow(tileref.Y - xform.LocalPosition.Y, 2)); //cut outer & inner circle diff --git a/Content.Shared/Roles/Jobs/SharedJobSystem.cs b/Content.Shared/Roles/Jobs/SharedJobSystem.cs index ce4428d9fe..939a57baad 100644 --- a/Content.Shared/Roles/Jobs/SharedJobSystem.cs +++ b/Content.Shared/Roles/Jobs/SharedJobSystem.cs @@ -15,8 +15,6 @@ public abstract class SharedJobSystem : EntitySystem { [Dependency] private readonly IPrototypeManager _prototypes = default!; [Dependency] private readonly SharedPlayerSystem _playerSystem = default!; - - [Dependency] private readonly IPrototypeManager _protoManager = default!; private readonly Dictionary _inverseTrackerLookup = new(); public override void Initialize() @@ -37,7 +35,7 @@ public abstract class SharedJobSystem : EntitySystem _inverseTrackerLookup.Clear(); // This breaks if you have N trackers to 1 JobId but future concern. - foreach (var job in _protoManager.EnumeratePrototypes()) + foreach (var job in _prototypes.EnumeratePrototypes()) { _inverseTrackerLookup.Add(job.PlayTimeTracker, job.ID); } @@ -50,7 +48,7 @@ public abstract class SharedJobSystem : EntitySystem /// public string GetJobPrototype(string trackerProto) { - DebugTools.Assert(_protoManager.HasIndex(trackerProto)); + DebugTools.Assert(_prototypes.HasIndex(trackerProto)); return _inverseTrackerLookup[trackerProto]; } @@ -60,7 +58,7 @@ public abstract class SharedJobSystem : EntitySystem public bool TryGetDepartment(string jobProto, [NotNullWhen(true)] out DepartmentPrototype? departmentPrototype) { // Not that many departments so we can just eat the cost instead of storing the inverse lookup. - var departmentProtos = _protoManager.EnumeratePrototypes().ToList(); + var departmentProtos = _prototypes.EnumeratePrototypes().ToList(); departmentProtos.Sort((x, y) => string.Compare(x.ID, y.ID, StringComparison.Ordinal)); foreach (var department in departmentProtos) @@ -85,7 +83,7 @@ public abstract class SharedJobSystem : EntitySystem { // not sorting it since there should only be 1 primary department for a job. // this is enforced by the job tests. - var departmentProtos = _protoManager.EnumeratePrototypes(); + var departmentProtos = _prototypes.EnumeratePrototypes(); foreach (var department in departmentProtos) { diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs index 60eafce474..a6c3c4779d 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.Welder.cs @@ -55,7 +55,7 @@ public abstract partial class SharedToolSystem if (!Resolve(uid, ref welder, ref solutionContainer)) return default; - if (!SolutionContainer.TryGetSolution( + if (!SolutionContainerSystem.TryGetSolution( (uid, solutionContainer), welder.FuelSolutionName, out _, diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.cs b/Content.Shared/Tools/Systems/SharedToolSystem.cs index 86b91dcda4..4c7383a38c 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.cs @@ -31,7 +31,6 @@ public abstract partial class SharedToolSystem : EntitySystem [Dependency] private readonly SharedTransformSystem _transformSystem = default!; [Dependency] private readonly TileSystem _tiles = default!; [Dependency] private readonly TurfSystem _turfs = default!; - [Dependency] protected readonly SharedSolutionContainerSystem SolutionContainer = default!; public const string CutQuality = "Cutting"; public const string PulseQuality = "Pulsing"; From d806db264aa306d1d08442ae7b74e7760b2acc15 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:13:22 +1300 Subject: [PATCH 17/88] Fix currency duplication bug (#32524) --- .../Implants/SubdermalImplantSystem.cs | 6 +-- Content.Server/Stack/StackSystem.cs | 14 +++++ .../Store/Components/CurrencyComponent.cs | 11 ++++ .../Store/Systems/StoreSystem.Ui.cs | 6 ++- Content.Server/Store/Systems/StoreSystem.cs | 51 ++++++++++++------- 5 files changed, 66 insertions(+), 22 deletions(-) diff --git a/Content.Server/Implants/SubdermalImplantSystem.cs b/Content.Server/Implants/SubdermalImplantSystem.cs index 7c69ec8ea5..6e277dd29f 100644 --- a/Content.Server/Implants/SubdermalImplantSystem.cs +++ b/Content.Server/Implants/SubdermalImplantSystem.cs @@ -74,14 +74,12 @@ public sealed class SubdermalImplantSystem : SharedSubdermalImplantSystem return; // same as store code, but message is only shown to yourself - args.Handled = _store.TryAddCurrency(_store.GetCurrencyValue(args.Used, currency), uid, store); - - if (!args.Handled) + if (!_store.TryAddCurrency((args.Used, currency), (uid, store))) return; + args.Handled = true; var msg = Loc.GetString("store-currency-inserted-implant", ("used", args.Used)); _popup.PopupEntity(msg, args.User, args.User); - QueueDel(args.Used); } private void OnFreedomImplant(EntityUid uid, SubdermalImplantComponent component, UseFreedomImplantEvent args) diff --git a/Content.Server/Stack/StackSystem.cs b/Content.Server/Stack/StackSystem.cs index b9553a6b84..bc1800ffd1 100644 --- a/Content.Server/Stack/StackSystem.cs +++ b/Content.Server/Stack/StackSystem.cs @@ -100,6 +100,13 @@ namespace Content.Server.Stack /// public List SpawnMultiple(string entityPrototype, int amount, EntityCoordinates spawnPosition) { + if (amount <= 0) + { + Log.Error( + $"Attempted to spawn an invalid stack: {entityPrototype}, {amount}. Trace: {Environment.StackTrace}"); + return new(); + } + var spawns = CalculateSpawns(entityPrototype, amount); var spawnedEnts = new List(); @@ -116,6 +123,13 @@ namespace Content.Server.Stack /// public List SpawnMultiple(string entityPrototype, int amount, EntityUid target) { + if (amount <= 0) + { + Log.Error( + $"Attempted to spawn an invalid stack: {entityPrototype}, {amount}. Trace: {Environment.StackTrace}"); + return new(); + } + var spawns = CalculateSpawns(entityPrototype, amount); var spawnedEnts = new List(); diff --git a/Content.Server/Store/Components/CurrencyComponent.cs b/Content.Server/Store/Components/CurrencyComponent.cs index cfe9b76c8b..eb4ca1c0e3 100644 --- a/Content.Server/Store/Components/CurrencyComponent.cs +++ b/Content.Server/Store/Components/CurrencyComponent.cs @@ -8,6 +8,11 @@ namespace Content.Server.Store.Components; /// Identifies a component that can be inserted into a store /// to increase its balance. /// +/// +/// Note that if this entity is a stack of items, then this is meant to represent the value per stack item, not +/// the whole stack. This also means that in general, the actual value should not be modified from the initial +/// prototype value because otherwise stack merging/splitting may modify the total value. +/// [RegisterComponent] public sealed partial class CurrencyComponent : Component { @@ -16,6 +21,12 @@ public sealed partial class CurrencyComponent : Component /// The string is the currency type that will be added. /// The FixedPoint2 is the value of each individual currency entity. /// + /// + /// Note that if this entity is a stack of items, then this is meant to represent the value per stack item, not + /// the whole stack. This also means that in general, the actual value should not be modified from the initial + /// prototype value + /// because otherwise stack merging/splitting may modify the total value. + /// [ViewVariables(VVAccess.ReadWrite)] [DataField("price", customTypeSerializer: typeof(PrototypeIdDictionarySerializer))] public Dictionary Price = new(); diff --git a/Content.Server/Store/Systems/StoreSystem.Ui.cs b/Content.Server/Store/Systems/StoreSystem.Ui.cs index 95e5711984..f1c0cb1e90 100644 --- a/Content.Server/Store/Systems/StoreSystem.Ui.cs +++ b/Content.Server/Store/Systems/StoreSystem.Ui.cs @@ -283,6 +283,9 @@ public sealed partial class StoreSystem /// private void OnRequestWithdraw(EntityUid uid, StoreComponent component, StoreRequestWithdrawMessage msg) { + if (msg.Amount <= 0) + return; + //make sure we have enough cash in the bank and we actually support this currency if (!component.Balance.TryGetValue(msg.Currency, out var currentAmount) || currentAmount < msg.Amount) return; @@ -306,7 +309,8 @@ public sealed partial class StoreSystem var cashId = proto.Cash[value]; var amountToSpawn = (int) MathF.Floor((float) (amountRemaining / value)); var ents = _stack.SpawnMultiple(cashId, amountToSpawn, coordinates); - _hands.PickupOrDrop(buyer, ents.First()); + if (ents.FirstOrDefault() is {} ent) + _hands.PickupOrDrop(buyer, ent); amountRemaining -= value * amountToSpawn; } diff --git a/Content.Server/Store/Systems/StoreSystem.cs b/Content.Server/Store/Systems/StoreSystem.cs index c13a9583be..7bdf550301 100644 --- a/Content.Server/Store/Systems/StoreSystem.cs +++ b/Content.Server/Store/Systems/StoreSystem.cs @@ -92,14 +92,12 @@ public sealed partial class StoreSystem : EntitySystem if (ev.Cancelled) return; - args.Handled = TryAddCurrency(GetCurrencyValue(uid, component), args.Target.Value, store); + if (!TryAddCurrency((uid, component), (args.Target.Value, store))) + return; - if (args.Handled) - { - var msg = Loc.GetString("store-currency-inserted", ("used", args.Used), ("target", args.Target)); - _popup.PopupEntity(msg, args.Target.Value, args.User); - QueueDel(args.Used); - } + args.Handled = true; + var msg = Loc.GetString("store-currency-inserted", ("used", args.Used), ("target", args.Target)); + _popup.PopupEntity(msg, args.Target.Value, args.User); } private void OnImplantActivate(EntityUid uid, StoreComponent component, OpenUplinkImplantEvent args) @@ -111,6 +109,10 @@ public sealed partial class StoreSystem : EntitySystem /// Gets the value from an entity's currency component. /// Scales with stacks. /// + /// + /// If this result is intended to be used with , + /// consider using instead to ensure that the currency is consumed in the process. + /// /// /// /// The value of the currency @@ -121,19 +123,34 @@ public sealed partial class StoreSystem : EntitySystem } /// - /// Tries to add a currency to a store's balance. + /// Tries to add a currency to a store's balance. Note that if successful, this will consume the currency in the process. /// - /// - /// - /// The currency to add - /// The store to add it to - /// Whether or not the currency was succesfully added - [PublicAPI] - public bool TryAddCurrency(EntityUid currencyEnt, EntityUid storeEnt, StoreComponent? store = null, CurrencyComponent? currency = null) + public bool TryAddCurrency(Entity currency, Entity store) { - if (!Resolve(currencyEnt, ref currency) || !Resolve(storeEnt, ref store)) + if (!Resolve(currency.Owner, ref currency.Comp)) return false; - return TryAddCurrency(GetCurrencyValue(currencyEnt, currency), storeEnt, store); + + if (!Resolve(store.Owner, ref store.Comp)) + return false; + + var value = currency.Comp.Price; + if (TryComp(currency.Owner, out StackComponent? stack) && stack.Count != 1) + { + value = currency.Comp.Price + .ToDictionary(v => v.Key, p => p.Value * stack.Count); + } + + if (!TryAddCurrency(value, store, store.Comp)) + return false; + + // Avoid having the currency accidentally be re-used. E.g., if multiple clients try to use the currency in the + // same tick + currency.Comp.Price.Clear(); + if (stack != null) + _stack.SetCount(currency.Owner, 0, stack); + + QueueDel(currency); + return true; } /// From 6b49a510d15c7d39a084a6c7604b8a7b5df7f661 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 29 Sep 2024 12:14:30 +0000 Subject: [PATCH 18/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index bce89288e4..a8efb0bd53 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: IProduceWidgets - changes: - - message: an arabian lamp! - type: Add - id: 6953 - time: '2024-07-21T07:24:28.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27270 - author: osjarw changes: - message: NPCs no longer get stuck trying to pick up anchored pipes. @@ -3937,3 +3930,10 @@ id: 7452 time: '2024-09-28T09:02:43.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32483 +- author: ElectroJr + changes: + - message: Fixed a store currency duplication bug/exploit. + type: Fix + id: 7453 + time: '2024-09-29T12:13:22.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32524 From f1f1fc1dc3cb5543af9b52850b253a88cc62b949 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:19:00 +1300 Subject: [PATCH 19/88] Add interaction rate limits (#32527) * Move PlayerRateLimitManager to shared * Add interaction rate limits * uncap tests --- Content.Client/Chat/Managers/ChatManager.cs | 10 ++ Content.Client/Chat/Managers/IChatManager.cs | 4 +- Content.Client/IoC/ClientContentIoC.cs | 8 +- .../RateLimiting/PlayerRateLimitManager.cs | 23 ++++ Content.IntegrationTests/PoolManager.Cvars.cs | 4 +- .../Administration/Systems/BwoinkSystem.cs | 11 +- .../Chat/Managers/ChatManager.RateLimit.cs | 21 ++- Content.Server/Chat/Managers/ChatManager.cs | 1 + Content.Server/Chat/Managers/IChatManager.cs | 9 +- Content.Server/Chat/Systems/ChatSystem.cs | 1 + Content.Server/IoC/ServerContentIoC.cs | 6 +- .../RateLimiting/PlayerRateLimitManager.cs | 122 ++---------------- Content.Shared/CCVar/CCVars.cs | 47 +++++-- Content.Shared/Chat/ISharedChatManager.cs | 8 ++ .../Interaction/SharedInteractionSystem.cs | 32 ++++- .../RateLimiting/RateLimitRegistration.cs | 76 +++++++++++ .../SharedPlayerRateLimitManager.cs | 55 ++++++++ .../en-US/interaction/interaction-system.ftl | 3 +- 18 files changed, 277 insertions(+), 164 deletions(-) create mode 100644 Content.Client/Players/RateLimiting/PlayerRateLimitManager.cs create mode 100644 Content.Shared/Chat/ISharedChatManager.cs create mode 100644 Content.Shared/Players/RateLimiting/RateLimitRegistration.cs create mode 100644 Content.Shared/Players/RateLimiting/SharedPlayerRateLimitManager.cs diff --git a/Content.Client/Chat/Managers/ChatManager.cs b/Content.Client/Chat/Managers/ChatManager.cs index e428d30f20..68707e021c 100644 --- a/Content.Client/Chat/Managers/ChatManager.cs +++ b/Content.Client/Chat/Managers/ChatManager.cs @@ -21,6 +21,16 @@ internal sealed class ChatManager : IChatManager _sawmill.Level = LogLevel.Info; } + public void SendAdminAlert(string message) + { + // See server-side manager. This just exists for shared code. + } + + public void SendAdminAlert(EntityUid player, string message) + { + // See server-side manager. This just exists for shared code. + } + public void SendMessage(string text, ChatSelectChannel channel) { var str = text.ToString(); diff --git a/Content.Client/Chat/Managers/IChatManager.cs b/Content.Client/Chat/Managers/IChatManager.cs index 6464ca1019..62a97c6bd8 100644 --- a/Content.Client/Chat/Managers/IChatManager.cs +++ b/Content.Client/Chat/Managers/IChatManager.cs @@ -2,10 +2,8 @@ using Content.Shared.Chat; namespace Content.Client.Chat.Managers { - public interface IChatManager + public interface IChatManager : ISharedChatManager { - void Initialize(); - public void SendMessage(string text, ChatSelectChannel channel); } } diff --git a/Content.Client/IoC/ClientContentIoC.cs b/Content.Client/IoC/ClientContentIoC.cs index 1fd237cf3e..e643552f70 100644 --- a/Content.Client/IoC/ClientContentIoC.cs +++ b/Content.Client/IoC/ClientContentIoC.cs @@ -18,8 +18,11 @@ using Content.Client.Viewport; using Content.Client.Voting; using Content.Shared.Administration.Logs; using Content.Client.Lobby; +using Content.Client.Players.RateLimiting; using Content.Shared.Administration.Managers; +using Content.Shared.Chat; using Content.Shared.Players.PlayTimeTracking; +using Content.Shared.Players.RateLimiting; namespace Content.Client.IoC { @@ -31,6 +34,7 @@ namespace Content.Client.IoC collection.Register(); collection.Register(); + collection.Register(); collection.Register(); collection.Register(); collection.Register(); @@ -47,10 +51,12 @@ namespace Content.Client.IoC collection.Register(); collection.Register(); collection.Register(); - collection.Register(); + collection.Register(); collection.Register(); collection.Register(); collection.Register(); + collection.Register(); + collection.Register(); } } } diff --git a/Content.Client/Players/RateLimiting/PlayerRateLimitManager.cs b/Content.Client/Players/RateLimiting/PlayerRateLimitManager.cs new file mode 100644 index 0000000000..e79eadd92b --- /dev/null +++ b/Content.Client/Players/RateLimiting/PlayerRateLimitManager.cs @@ -0,0 +1,23 @@ +using Content.Shared.Players.RateLimiting; +using Robust.Shared.Player; + +namespace Content.Client.Players.RateLimiting; + +public sealed class PlayerRateLimitManager : SharedPlayerRateLimitManager +{ + public override RateLimitStatus CountAction(ICommonSession player, string key) + { + // TODO Rate-Limit + // Add support for rate limit prediction + // I.e., dont mis-predict just because somebody is clicking too quickly. + return RateLimitStatus.Allowed; + } + + public override void Register(string key, RateLimitRegistration registration) + { + } + + public override void Initialize() + { + } +} diff --git a/Content.IntegrationTests/PoolManager.Cvars.cs b/Content.IntegrationTests/PoolManager.Cvars.cs index bcd48f8238..23f0ded7df 100644 --- a/Content.IntegrationTests/PoolManager.Cvars.cs +++ b/Content.IntegrationTests/PoolManager.Cvars.cs @@ -36,7 +36,9 @@ public static partial class PoolManager (CCVars.ConfigPresetDevelopment.Name, "false"), (CCVars.AdminLogsEnabled.Name, "false"), (CCVars.AutosaveEnabled.Name, "false"), - (CVars.NetBufferSize.Name, "0") + (CVars.NetBufferSize.Name, "0"), + (CCVars.InteractionRateLimitCount.Name, "9999999"), + (CCVars.InteractionRateLimitPeriod.Name, "0.1"), }; public static async Task SetupCVars(RobustIntegrationTest.IntegrationInstance instance, PoolSettings settings) diff --git a/Content.Server/Administration/Systems/BwoinkSystem.cs b/Content.Server/Administration/Systems/BwoinkSystem.cs index 893de4aba5..1efc0a9d56 100644 --- a/Content.Server/Administration/Systems/BwoinkSystem.cs +++ b/Content.Server/Administration/Systems/BwoinkSystem.cs @@ -15,6 +15,7 @@ using Content.Shared.Administration; using Content.Shared.CCVar; using Content.Shared.GameTicking; using Content.Shared.Mind; +using Content.Shared.Players.RateLimiting; using JetBrains.Annotations; using Robust.Server.Player; using Robust.Shared; @@ -104,12 +105,10 @@ namespace Content.Server.Administration.Systems _rateLimit.Register( RateLimitKey, - new RateLimitRegistration - { - CVarLimitPeriodLength = CCVars.AhelpRateLimitPeriod, - CVarLimitCount = CCVars.AhelpRateLimitCount, - PlayerLimitedAction = PlayerRateLimitedAction - }); + new RateLimitRegistration(CCVars.AhelpRateLimitPeriod, + CCVars.AhelpRateLimitCount, + PlayerRateLimitedAction) + ); } private void PlayerRateLimitedAction(ICommonSession obj) diff --git a/Content.Server/Chat/Managers/ChatManager.RateLimit.cs b/Content.Server/Chat/Managers/ChatManager.RateLimit.cs index 45e7d2e20d..ccb38166a6 100644 --- a/Content.Server/Chat/Managers/ChatManager.RateLimit.cs +++ b/Content.Server/Chat/Managers/ChatManager.RateLimit.cs @@ -1,6 +1,6 @@ -using Content.Server.Players.RateLimiting; using Content.Shared.CCVar; using Content.Shared.Database; +using Content.Shared.Players.RateLimiting; using Robust.Shared.Player; namespace Content.Server.Chat.Managers; @@ -12,15 +12,13 @@ internal sealed partial class ChatManager private void RegisterRateLimits() { _rateLimitManager.Register(RateLimitKey, - new RateLimitRegistration - { - CVarLimitPeriodLength = CCVars.ChatRateLimitPeriod, - CVarLimitCount = CCVars.ChatRateLimitCount, - CVarAdminAnnounceDelay = CCVars.ChatRateLimitAnnounceAdminsDelay, - PlayerLimitedAction = RateLimitPlayerLimited, - AdminAnnounceAction = RateLimitAlertAdmins, - AdminLogType = LogType.ChatRateLimited, - }); + new RateLimitRegistration(CCVars.ChatRateLimitPeriod, + CCVars.ChatRateLimitCount, + RateLimitPlayerLimited, + CCVars.ChatRateLimitAnnounceAdminsDelay, + RateLimitAlertAdmins, + LogType.ChatRateLimited) + ); } private void RateLimitPlayerLimited(ICommonSession player) @@ -30,8 +28,7 @@ internal sealed partial class ChatManager private void RateLimitAlertAdmins(ICommonSession player) { - if (_configurationManager.GetCVar(CCVars.ChatRateLimitAnnounceAdmins)) - SendAdminAlert(Loc.GetString("chat-manager-rate-limit-admin-announcement", ("player", player.Name))); + SendAdminAlert(Loc.GetString("chat-manager-rate-limit-admin-announcement", ("player", player.Name))); } public RateLimitStatus HandleRateLimit(ICommonSession player) diff --git a/Content.Server/Chat/Managers/ChatManager.cs b/Content.Server/Chat/Managers/ChatManager.cs index 02f718daef..75c46abe37 100644 --- a/Content.Server/Chat/Managers/ChatManager.cs +++ b/Content.Server/Chat/Managers/ChatManager.cs @@ -12,6 +12,7 @@ using Content.Shared.CCVar; using Content.Shared.Chat; using Content.Shared.Database; using Content.Shared.Mind; +using Content.Shared.Players.RateLimiting; using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Player; diff --git a/Content.Server/Chat/Managers/IChatManager.cs b/Content.Server/Chat/Managers/IChatManager.cs index 76fa91d847..23211c28fa 100644 --- a/Content.Server/Chat/Managers/IChatManager.cs +++ b/Content.Server/Chat/Managers/IChatManager.cs @@ -1,17 +1,14 @@ using System.Diagnostics.CodeAnalysis; -using Content.Server.Players; -using Content.Server.Players.RateLimiting; using Content.Shared.Administration; using Content.Shared.Chat; +using Content.Shared.Players.RateLimiting; using Robust.Shared.Network; using Robust.Shared.Player; namespace Content.Server.Chat.Managers { - public interface IChatManager + public interface IChatManager : ISharedChatManager { - void Initialize(); - /// /// Dispatch a server announcement to every connected player. /// @@ -26,8 +23,6 @@ namespace Content.Server.Chat.Managers void SendHookOOC(string sender, string message); void SendAdminAnnouncement(string message, AdminFlags? flagBlacklist = null, AdminFlags? flagWhitelist = null); void SendAdminAnnouncementMessage(ICommonSession player, string message, bool suppressLog = true); - void SendAdminAlert(string message); - void SendAdminAlert(EntityUid player, string message); void ChatMessageToOne(ChatChannel channel, string message, string wrappedMessage, EntityUid source, bool hideChat, INetChannel client, Color? colorOverride = null, bool recordReplay = false, string? audioPath = null, float audioVolume = 0, NetUserId? author = null); diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 24937ea4b9..624c18130b 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -20,6 +20,7 @@ using Content.Shared.Ghost; using Content.Shared.IdentityManagement; using Content.Shared.Mobs.Systems; using Content.Shared.Players; +using Content.Shared.Players.RateLimiting; using Content.Shared.Radio; using Content.Shared.Whitelist; using Robust.Server.Player; diff --git a/Content.Server/IoC/ServerContentIoC.cs b/Content.Server/IoC/ServerContentIoC.cs index 3851f145c4..d7f6b85eb6 100644 --- a/Content.Server/IoC/ServerContentIoC.cs +++ b/Content.Server/IoC/ServerContentIoC.cs @@ -14,8 +14,6 @@ using Content.Server.Mapping; using Content.Server.Maps; using Content.Server.MoMMI; using Content.Server.NodeContainer.NodeGroups; -using Content.Server.Objectives; -using Content.Server.Players; using Content.Server.Players.JobWhitelist; using Content.Server.Players.PlayTimeTracking; using Content.Server.Players.RateLimiting; @@ -26,8 +24,10 @@ using Content.Server.Voting.Managers; using Content.Server.Worldgen.Tools; using Content.Shared.Administration.Logs; using Content.Shared.Administration.Managers; +using Content.Shared.Chat; using Content.Shared.Kitchen; using Content.Shared.Players.PlayTimeTracking; +using Content.Shared.Players.RateLimiting; namespace Content.Server.IoC { @@ -36,6 +36,7 @@ namespace Content.Server.IoC public static void Register() { IoCManager.Register(); + IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); @@ -68,6 +69,7 @@ namespace Content.Server.IoC IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); + IoCManager.Register(); IoCManager.Register(); } } diff --git a/Content.Server/Players/RateLimiting/PlayerRateLimitManager.cs b/Content.Server/Players/RateLimiting/PlayerRateLimitManager.cs index 59f086f9c3..a3b4d4a536 100644 --- a/Content.Server/Players/RateLimiting/PlayerRateLimitManager.cs +++ b/Content.Server/Players/RateLimiting/PlayerRateLimitManager.cs @@ -1,6 +1,7 @@ using System.Runtime.InteropServices; using Content.Server.Administration.Logs; using Content.Shared.Database; +using Content.Shared.Players.RateLimiting; using Robust.Server.Player; using Robust.Shared.Configuration; using Robust.Shared.Enums; @@ -10,26 +11,7 @@ using Robust.Shared.Utility; namespace Content.Server.Players.RateLimiting; -/// -/// General-purpose system to rate limit actions taken by clients, such as chat messages. -/// -/// -/// -/// Different categories of rate limits must be registered ahead of time by calling . -/// Once registered, you can simply call to count a rate-limited action for a player. -/// -/// -/// This system is intended for rate limiting player actions over short periods, -/// to ward against spam that can cause technical issues such as admin client load. -/// It should not be used for in-game actions or similar. -/// -/// -/// Rate limits are reset when a client reconnects. -/// This should not be an issue for the reasonably short rate limit periods this system is intended for. -/// -/// -/// -public sealed class PlayerRateLimitManager +public sealed class PlayerRateLimitManager : SharedPlayerRateLimitManager { [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; @@ -39,18 +21,7 @@ public sealed class PlayerRateLimitManager private readonly Dictionary _registrations = new(); private readonly Dictionary> _rateLimitData = new(); - /// - /// Count and validate an action performed by a player against rate limits. - /// - /// The player performing the action. - /// The key string that was previously used to register a rate limit category. - /// Whether the action counted should be blocked due to surpassing rate limits or not. - /// - /// is not a connected player - /// OR is not a registered rate limit category. - /// - /// - public RateLimitStatus CountAction(ICommonSession player, string key) + public override RateLimitStatus CountAction(ICommonSession player, string key) { if (player.Status == SessionStatus.Disconnected) throw new ArgumentException("Player is not connected"); @@ -74,7 +45,8 @@ public sealed class PlayerRateLimitManager return RateLimitStatus.Allowed; // Breached rate limits, inform admins if configured. - if (registration.AdminAnnounceDelay is { } cvarAnnounceDelay) + // Negative delays can be used to disable admin announcements. + if (registration.AdminAnnounceDelay is {TotalSeconds: >= 0} cvarAnnounceDelay) { if (datum.NextAdminAnnounce < time) { @@ -85,7 +57,7 @@ public sealed class PlayerRateLimitManager if (!datum.Announced) { - registration.Registration.PlayerLimitedAction(player); + registration.Registration.PlayerLimitedAction?.Invoke(player); _adminLog.Add( registration.Registration.AdminLogType, LogImpact.Medium, @@ -97,17 +69,7 @@ public sealed class PlayerRateLimitManager return RateLimitStatus.Blocked; } - /// - /// Register a new rate limit category. - /// - /// - /// The key string that will be referred to later with . - /// Must be unique and should probably just be a constant somewhere. - /// - /// The data specifying the rate limit's parameters. - /// has already been registered. - /// is invalid. - public void Register(string key, RateLimitRegistration registration) + public override void Register(string key, RateLimitRegistration registration) { if (_registrations.ContainsKey(key)) throw new InvalidOperationException($"Key already registered: {key}"); @@ -135,7 +97,7 @@ public sealed class PlayerRateLimitManager if (registration.CVarAdminAnnounceDelay != null) { _cfg.OnValueChanged( - registration.CVarLimitCount, + registration.CVarAdminAnnounceDelay, i => data.AdminAnnounceDelay = TimeSpan.FromSeconds(i), invokeImmediately: true); } @@ -143,10 +105,7 @@ public sealed class PlayerRateLimitManager _registrations.Add(key, data); } - /// - /// Initialize the manager's functionality at game startup. - /// - public void Initialize() + public override void Initialize() { _playerManager.PlayerStatusChanged += PlayerManagerOnPlayerStatusChanged; } @@ -189,66 +148,3 @@ public sealed class PlayerRateLimitManager public TimeSpan NextAdminAnnounce; } } - -/// -/// Contains all data necessary to register a rate limit with . -/// -public sealed class RateLimitRegistration -{ - /// - /// CVar that controls the period over which the rate limit is counted, measured in seconds. - /// - public required CVarDef CVarLimitPeriodLength { get; init; } - - /// - /// CVar that controls how many actions are allowed in a single rate limit period. - /// - public required CVarDef CVarLimitCount { get; init; } - - /// - /// An action that gets invoked when this rate limit has been breached by a player. - /// - /// - /// This can be used for informing players or taking administrative action. - /// - public required Action PlayerLimitedAction { get; init; } - - /// - /// CVar that controls the minimum delay between admin notifications, measured in seconds. - /// This can be omitted to have no admin notification system. - /// - /// - /// If set, must be set too. - /// - public CVarDef? CVarAdminAnnounceDelay { get; init; } - - /// - /// An action that gets invoked when a rate limit was breached and admins should be notified. - /// - /// - /// If set, must be set too. - /// - public Action? AdminAnnounceAction { get; init; } - - /// - /// Log type used to log rate limit violations to the admin logs system. - /// - public LogType AdminLogType { get; init; } = LogType.RateLimited; -} - -/// -/// Result of a rate-limited operation. -/// -/// -public enum RateLimitStatus : byte -{ - /// - /// The action was not blocked by the rate limit. - /// - Allowed, - - /// - /// The action was blocked by the rate limit. - /// - Blocked, -} diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index be97dd93a8..14bb760f40 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -906,8 +906,8 @@ namespace Content.Shared.CCVar /// After the period has passed, the count resets. /// /// - public static readonly CVarDef AhelpRateLimitPeriod = - CVarDef.Create("ahelp.rate_limit_period", 2, CVar.SERVERONLY); + public static readonly CVarDef AhelpRateLimitPeriod = + CVarDef.Create("ahelp.rate_limit_period", 2f, CVar.SERVERONLY); /// /// How many ahelp messages are allowed in a single rate limit period. @@ -1840,8 +1840,8 @@ namespace Content.Shared.CCVar /// After the period has passed, the count resets. /// /// - public static readonly CVarDef ChatRateLimitPeriod = - CVarDef.Create("chat.rate_limit_period", 2, CVar.SERVERONLY); + public static readonly CVarDef ChatRateLimitPeriod = + CVarDef.Create("chat.rate_limit_period", 2f, CVar.SERVERONLY); /// /// How many chat messages are allowed in a single rate limit period. @@ -1851,19 +1851,12 @@ namespace Content.Shared.CCVar /// divided by . /// /// - /// public static readonly CVarDef ChatRateLimitCount = CVarDef.Create("chat.rate_limit_count", 10, CVar.SERVERONLY); /// - /// If true, announce when a player breached chat rate limit to game administrators. - /// - /// - public static readonly CVarDef ChatRateLimitAnnounceAdmins = - CVarDef.Create("chat.rate_limit_announce_admins", true, CVar.SERVERONLY); - - /// - /// Minimum delay (in seconds) between announcements from . + /// Minimum delay (in seconds) between notifying admins about chat message rate limit violations. + /// A negative value disables admin announcements. /// public static readonly CVarDef ChatRateLimitAnnounceAdminsDelay = CVarDef.Create("chat.rate_limit_announce_admins_delay", 15, CVar.SERVERONLY); @@ -2059,6 +2052,34 @@ namespace Content.Shared.CCVar public static readonly CVarDef ToggleWalk = CVarDef.Create("control.toggle_walk", false, CVar.CLIENTONLY | CVar.ARCHIVE); + /* + * Interactions + */ + + // The rationale behind the default limit is simply that I can easily get to 7 interactions per second by just + // trying to spam toggle a light switch or lever (though the UseDelay component limits the actual effect of the + // interaction). I don't want to accidentally spam admins with alerts just because somebody is spamming a + // key manually, nor do we want to alert them just because the player is having network issues and the server + // receives multiple interactions at once. But we also want to try catch people with modified clients that spam + // many interactions on the same tick. Hence, a very short period, with a relatively high count. + + /// + /// Maximum number of interactions that a player can perform within seconds + /// + public static readonly CVarDef InteractionRateLimitCount = + CVarDef.Create("interaction.rate_limit_count", 5, CVar.SERVER | CVar.REPLICATED); + + /// + public static readonly CVarDef InteractionRateLimitPeriod = + CVarDef.Create("interaction.rate_limit_period", 0.5f, CVar.SERVER | CVar.REPLICATED); + + /// + /// Minimum delay (in seconds) between notifying admins about interaction rate limit violations. A negative + /// value disables admin announcements. + /// + public static readonly CVarDef InteractionRateLimitAnnounceAdminsDelay = + CVarDef.Create("interaction.rate_limit_announce_admins_delay", 120, CVar.SERVERONLY); + /* * STORAGE */ diff --git a/Content.Shared/Chat/ISharedChatManager.cs b/Content.Shared/Chat/ISharedChatManager.cs new file mode 100644 index 0000000000..39c1d85dd2 --- /dev/null +++ b/Content.Shared/Chat/ISharedChatManager.cs @@ -0,0 +1,8 @@ +namespace Content.Shared.Chat; + +public interface ISharedChatManager +{ + void Initialize(); + void SendAdminAlert(string message); + void SendAdminAlert(EntityUid player, string message); +} diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 8539b9d282..43dd97762c 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -2,6 +2,8 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using Content.Shared.ActionBlocker; using Content.Shared.Administration.Logs; +using Content.Shared.CCVar; +using Content.Shared.Chat; using Content.Shared.CombatMode; using Content.Shared.Database; using Content.Shared.Ghost; @@ -16,8 +18,8 @@ using Content.Shared.Item; using Content.Shared.Movement.Components; using Content.Shared.Movement.Pulling.Systems; using Content.Shared.Physics; +using Content.Shared.Players.RateLimiting; using Content.Shared.Popups; -using Content.Shared.Silicons.StationAi; using Content.Shared.Storage; using Content.Shared.Tag; using Content.Shared.Timing; @@ -25,6 +27,7 @@ using Content.Shared.UserInterface; using Content.Shared.Verbs; using Content.Shared.Wall; using JetBrains.Annotations; +using Robust.Shared.Configuration; using Robust.Shared.Containers; using Robust.Shared.Input; using Robust.Shared.Input.Binding; @@ -64,6 +67,9 @@ namespace Content.Shared.Interaction [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly TagSystem _tagSystem = default!; [Dependency] private readonly SharedUserInterfaceSystem _ui = default!; + [Dependency] private readonly SharedPlayerRateLimitManager _rateLimit = default!; + [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly ISharedChatManager _chat = default!; private EntityQuery _ignoreUiRangeQuery; private EntityQuery _fixtureQuery; @@ -80,8 +86,8 @@ namespace Content.Shared.Interaction public const float InteractionRange = 1.5f; public const float InteractionRangeSquared = InteractionRange * InteractionRange; - public const float MaxRaycastRange = 100f; + public const string RateLimitKey = "Interaction"; public delegate bool Ignored(EntityUid entity); @@ -119,9 +125,22 @@ namespace Content.Shared.Interaction new PointerInputCmdHandler(HandleTryPullObject)) .Register(); + _rateLimit.Register(RateLimitKey, + new RateLimitRegistration(CCVars.InteractionRateLimitPeriod, + CCVars.InteractionRateLimitCount, + null, + CCVars.InteractionRateLimitAnnounceAdminsDelay, + RateLimitAlertAdmins) + ); + InitializeBlocking(); } + private void RateLimitAlertAdmins(ICommonSession session) + { + _chat.SendAdminAlert(Loc.GetString("interaction-rate-limit-admin-announcement", ("player", session.Name))); + } + public override void Shutdown() { CommandBinds.Unregister(); @@ -1250,8 +1269,11 @@ namespace Content.Shared.Interaction return InRangeUnobstructed(user, wearer) && _containerSystem.IsInSameOrParentContainer(user, wearer); } - protected bool ValidateClientInput(ICommonSession? session, EntityCoordinates coords, - EntityUid uid, [NotNullWhen(true)] out EntityUid? userEntity) + protected bool ValidateClientInput( + ICommonSession? session, + EntityCoordinates coords, + EntityUid uid, + [NotNullWhen(true)] out EntityUid? userEntity) { userEntity = null; @@ -1281,7 +1303,7 @@ namespace Content.Shared.Interaction return false; } - return true; + return _rateLimit.CountAction(session!, RateLimitKey) == RateLimitStatus.Allowed; } /// diff --git a/Content.Shared/Players/RateLimiting/RateLimitRegistration.cs b/Content.Shared/Players/RateLimiting/RateLimitRegistration.cs new file mode 100644 index 0000000000..6bcf15d30b --- /dev/null +++ b/Content.Shared/Players/RateLimiting/RateLimitRegistration.cs @@ -0,0 +1,76 @@ +using Content.Shared.Database; +using Robust.Shared.Configuration; +using Robust.Shared.Player; + +namespace Content.Shared.Players.RateLimiting; + +/// +/// Contains all data necessary to register a rate limit with . +/// +public sealed class RateLimitRegistration( + CVarDef cVarLimitPeriodLength, + CVarDef cVarLimitCount, + Action? playerLimitedAction, + CVarDef? cVarAdminAnnounceDelay = null, + Action? adminAnnounceAction = null, + LogType adminLogType = LogType.RateLimited) +{ + /// + /// CVar that controls the period over which the rate limit is counted, measured in seconds. + /// + public readonly CVarDef CVarLimitPeriodLength = cVarLimitPeriodLength; + + /// + /// CVar that controls how many actions are allowed in a single rate limit period. + /// + public readonly CVarDef CVarLimitCount = cVarLimitCount; + + /// + /// An action that gets invoked when this rate limit has been breached by a player. + /// + /// + /// This can be used for informing players or taking administrative action. + /// + public readonly Action? PlayerLimitedAction = playerLimitedAction; + + /// + /// CVar that controls the minimum delay between admin notifications, measured in seconds. + /// This can be omitted to have no admin notification system. + /// If the cvar is set to 0, there every breach will be reported. + /// If the cvar is set to a negative number, admin announcements are disabled. + /// + /// + /// If set, must be set too. + /// + public readonly CVarDef? CVarAdminAnnounceDelay = cVarAdminAnnounceDelay; + + /// + /// An action that gets invoked when a rate limit was breached and admins should be notified. + /// + /// + /// If set, must be set too. + /// + public readonly Action? AdminAnnounceAction = adminAnnounceAction; + + /// + /// Log type used to log rate limit violations to the admin logs system. + /// + public readonly LogType AdminLogType = adminLogType; +} + +/// +/// Result of a rate-limited operation. +/// +/// +public enum RateLimitStatus : byte +{ + /// + /// The action was not blocked by the rate limit. + /// + Allowed, + + /// + /// The action was blocked by the rate limit. + /// + Blocked, +} diff --git a/Content.Shared/Players/RateLimiting/SharedPlayerRateLimitManager.cs b/Content.Shared/Players/RateLimiting/SharedPlayerRateLimitManager.cs new file mode 100644 index 0000000000..addb1dee37 --- /dev/null +++ b/Content.Shared/Players/RateLimiting/SharedPlayerRateLimitManager.cs @@ -0,0 +1,55 @@ +using Robust.Shared.Player; + +namespace Content.Shared.Players.RateLimiting; + +/// +/// General-purpose system to rate limit actions taken by clients, such as chat messages. +/// +/// +/// +/// Different categories of rate limits must be registered ahead of time by calling . +/// Once registered, you can simply call to count a rate-limited action for a player. +/// +/// +/// This system is intended for rate limiting player actions over short periods, +/// to ward against spam that can cause technical issues such as admin client load. +/// It should not be used for in-game actions or similar. +/// +/// +/// Rate limits are reset when a client reconnects. +/// This should not be an issue for the reasonably short rate limit periods this system is intended for. +/// +/// +/// +public abstract class SharedPlayerRateLimitManager +{ + /// + /// Count and validate an action performed by a player against rate limits. + /// + /// The player performing the action. + /// The key string that was previously used to register a rate limit category. + /// Whether the action counted should be blocked due to surpassing rate limits or not. + /// + /// is not a connected player + /// OR is not a registered rate limit category. + /// + /// + public abstract RateLimitStatus CountAction(ICommonSession player, string key); + + /// + /// Register a new rate limit category. + /// + /// + /// The key string that will be referred to later with . + /// Must be unique and should probably just be a constant somewhere. + /// + /// The data specifying the rate limit's parameters. + /// has already been registered. + /// is invalid. + public abstract void Register(string key, RateLimitRegistration registration); + + /// + /// Initialize the manager's functionality at game startup. + /// + public abstract void Initialize(); +} diff --git a/Resources/Locale/en-US/interaction/interaction-system.ftl b/Resources/Locale/en-US/interaction/interaction-system.ftl index a4c380abca..3c0c3ae8b4 100644 --- a/Resources/Locale/en-US/interaction/interaction-system.ftl +++ b/Resources/Locale/en-US/interaction/interaction-system.ftl @@ -1,2 +1,3 @@ shared-interaction-system-in-range-unobstructed-cannot-reach = You can't reach there! -interaction-system-user-interaction-cannot-reach = You can't reach there! \ No newline at end of file +interaction-system-user-interaction-cannot-reach = You can't reach there! +interaction-rate-limit-admin-announcement = Player { $player } breached interaction rate limits. They may be using macros, auto-clickers, or a modified client. Though they may just be spamming buttons or having network issues. From 6bc383c0ef45f52a8c3a8f4ac4aa291cf6c6d0df Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 29 Sep 2024 12:20:08 +0000 Subject: [PATCH 20/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a8efb0bd53..e20c83dbaa 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: osjarw - changes: - - message: NPCs no longer get stuck trying to pick up anchored pipes. - type: Fix - id: 6954 - time: '2024-07-21T07:28:37.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30061 - author: The Hands Leader - JoJo cat changes: - message: Train map is back into rotation @@ -3937,3 +3930,11 @@ id: 7453 time: '2024-09-29T12:13:22.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32524 +- author: ElectroJr + changes: + - message: There is now a rate limit for most interactions. It should not be noticeable + most of the time, but may lead to mispredicts when spam-clicking. + type: Tweak + id: 7454 + time: '2024-09-29T12:19:00.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32527 From 1dc9541aedf20ee3692859823616629f9d7a0058 Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Sun, 29 Sep 2024 05:22:57 -0700 Subject: [PATCH 21/88] Fixes HoS's energy shotgun not being marked as restricted contraband (#32521) * the 12^21th contraband marking fix one step closer to release * sometimes you just make mistakes --- .../Entities/Objects/Weapons/Guns/Battery/battery_guns.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 7db085eb0a..2241c4092a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -720,7 +720,7 @@ - type: entity name: energy shotgun - parent: [BaseWeaponBattery, BaseGunWieldable] + parent: [BaseWeaponBattery, BaseGunWieldable, BaseGrandTheftContraband] id: WeaponEnergyShotgun description: A one-of-a-kind prototype energy weapon that uses various shotgun configurations. It offers the possibility of both lethal and non-lethal shots, making it a versatile weapon. components: From cc9202bbb29c3ef9a825113eb1f0eda0f81c3221 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 29 Sep 2024 12:24:03 +0000 Subject: [PATCH 22/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e20c83dbaa..075946bfe9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: The Hands Leader - JoJo cat - changes: - - message: Train map is back into rotation - type: Tweak - id: 6955 - time: '2024-07-21T07:44:18.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30145 - author: Plykiya changes: - message: Syndicate traitor reinforcements are now specialized to be medics, spies, @@ -3938,3 +3931,10 @@ id: 7454 time: '2024-09-29T12:19:00.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32527 +- author: ArtisticRoomba + changes: + - message: HoS's energy shotgun is now correctly marked as grand theft contraband. + type: Tweak + id: 7455 + time: '2024-09-29T12:22:57.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32521 From d0c4d5a93ab76e9d3a12f0f3a299066d4efe9f76 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Sun, 29 Sep 2024 15:23:53 +0200 Subject: [PATCH 23/88] Add webhook for votekicks (#32513) * Initial commit * Localization --- .../Discord/WebhookMessages/VoteWebhooks.cs | 183 ++++++++++++++++++ Content.Server/IoC/ServerContentIoC.cs | 2 + .../Managers/VoteManager.DefaultVotes.cs | 17 +- Content.Server/Voting/VoteCommands.cs | 170 +--------------- Content.Shared/CCVar/CCVars.cs | 6 + .../commands/custom-vote-command.ftl | 5 - .../en-US/discord/vote-notifications.ftl | 11 ++ 7 files changed, 224 insertions(+), 170 deletions(-) create mode 100644 Content.Server/Discord/WebhookMessages/VoteWebhooks.cs delete mode 100644 Resources/Locale/en-US/administration/commands/custom-vote-command.ftl create mode 100644 Resources/Locale/en-US/discord/vote-notifications.ftl diff --git a/Content.Server/Discord/WebhookMessages/VoteWebhooks.cs b/Content.Server/Discord/WebhookMessages/VoteWebhooks.cs new file mode 100644 index 0000000000..74953d10fa --- /dev/null +++ b/Content.Server/Discord/WebhookMessages/VoteWebhooks.cs @@ -0,0 +1,183 @@ +using Content.Server.GameTicking; +using Content.Server.Voting; +using Robust.Server; +using Robust.Shared.Configuration; +using Robust.Shared.Utility; +using System.Diagnostics; +using System.Text.Json; +using System.Text.Json.Nodes; + +namespace Content.Server.Discord.WebhookMessages; + +public sealed class VoteWebhooks : IPostInjectInit +{ + [Dependency] private readonly IConfigurationManager _cfg = default!; + [Dependency] private readonly IEntitySystemManager _entSys = default!; + [Dependency] private readonly DiscordWebhook _discord = default!; + [Dependency] private readonly IBaseServer _baseServer = default!; + + private ISawmill _sawmill = default!; + + public WebhookState? CreateWebhookIfConfigured(VoteOptions voteOptions, string? webhookUrl = null, string? customVoteName = null, string? customVoteMessage = null) + { + // All this webhook code is complete garbage. + // I tried to clean it up somewhat, at least to fix the glaring bugs in it. + // Jesus christ man what is with our code review process. + + if (string.IsNullOrEmpty(webhookUrl)) + return null; + + // Set up the webhook payload + var serverName = _baseServer.ServerName; + + var fields = new List(); + + foreach (var voteOption in voteOptions.Options) + { + var newVote = new WebhookEmbedField + { + Name = voteOption.text, + Value = Loc.GetString("custom-vote-webhook-option-pending") + }; + fields.Add(newVote); + } + + var gameTicker = _entSys.GetEntitySystemOrNull(); + _sawmill = Logger.GetSawmill("discord"); + + var runLevel = gameTicker != null ? Loc.GetString($"game-run-level-{gameTicker.RunLevel}") : ""; + var runId = gameTicker != null ? gameTicker.RoundId : 0; + + var voteName = customVoteName ?? Loc.GetString("custom-vote-webhook-name"); + var description = customVoteMessage ?? voteOptions.Title; + + var payload = new WebhookPayload() + { + Username = voteName, + Embeds = new List + { + new() + { + Title = voteOptions.InitiatorText, + Color = 13438992, // #CD1010 + Description = description, + Footer = new WebhookEmbedFooter + { + Text = Loc.GetString( + "custom-vote-webhook-footer", + ("serverName", serverName), + ("roundId", runId), + ("runLevel", runLevel)), + }, + + Fields = fields, + }, + }, + }; + + var state = new WebhookState + { + WebhookUrl = webhookUrl, + Payload = payload, + }; + + CreateWebhookMessage(state, payload); + + return state; + } + + public void UpdateWebhookIfConfigured(WebhookState? state, VoteFinishedEventArgs finished) + { + if (state == null) + return; + + var embed = state.Payload.Embeds![0]; + embed.Color = 2353993; // #23EB49 + + for (var i = 0; i < finished.Votes.Count; i++) + { + var oldName = embed.Fields[i].Name; + var newValue = finished.Votes[i].ToString(); + embed.Fields[i] = new WebhookEmbedField { Name = oldName, Value = newValue, Inline = true }; + } + + state.Payload.Embeds[0] = embed; + + UpdateWebhookMessage(state, state.Payload, state.MessageId); + } + + public void UpdateCancelledWebhookIfConfigured(WebhookState? state, string? customCancelReason = null) + { + if (state == null) + return; + + var embed = state.Payload.Embeds![0]; + embed.Color = 13356304; // #CBCD10 + if (customCancelReason == null) + embed.Description += "\n\n" + Loc.GetString("custom-vote-webhook-cancelled"); + else + embed.Description += "\n\n" + customCancelReason; + + for (var i = 0; i < embed.Fields.Count; i++) + { + var oldName = embed.Fields[i].Name; + embed.Fields[i] = new WebhookEmbedField { Name = oldName, Value = Loc.GetString("custom-vote-webhook-option-cancelled"), Inline = true }; + } + + state.Payload.Embeds[0] = embed; + + UpdateWebhookMessage(state, state.Payload, state.MessageId); + } + + // Sends the payload's message. + public async void CreateWebhookMessage(WebhookState state, WebhookPayload payload) + { + try + { + if (await _discord.GetWebhook(state.WebhookUrl) is not { } identifier) + return; + + state.Identifier = identifier.ToIdentifier(); + _sawmill.Debug(JsonSerializer.Serialize(payload)); + + var request = await _discord.CreateMessage(identifier.ToIdentifier(), payload); + var content = await request.Content.ReadAsStringAsync(); + state.MessageId = ulong.Parse(JsonNode.Parse(content)?["id"]!.GetValue()!); + } + catch (Exception e) + { + _sawmill.Error($"Error while sending vote webhook to Discord: {e}"); + } + } + + // Edits a pre-existing payload message, given an ID + public async void UpdateWebhookMessage(WebhookState state, WebhookPayload payload, ulong id) + { + if (state.MessageId == 0) + { + _sawmill.Warning("Failed to deliver update to custom vote webhook: message ID was zero. This likely indicates a previous connection error sending the original message."); + return; + } + + DebugTools.Assert(state.Identifier != default); + + try + { + await _discord.EditMessage(state.Identifier, id, payload); + } + catch (Exception e) + { + _sawmill.Error($"Error while updating vote webhook on Discord: {e}"); + } + } + + public sealed class WebhookState + { + public required string WebhookUrl; + public required WebhookPayload Payload; + public WebhookIdentifier Identifier; + public ulong MessageId; + } + + void IPostInjectInit.PostInject() { } +} diff --git a/Content.Server/IoC/ServerContentIoC.cs b/Content.Server/IoC/ServerContentIoC.cs index d7f6b85eb6..902e16d531 100644 --- a/Content.Server/IoC/ServerContentIoC.cs +++ b/Content.Server/IoC/ServerContentIoC.cs @@ -7,6 +7,7 @@ using Content.Server.Chat.Managers; using Content.Server.Connection; using Content.Server.Database; using Content.Server.Discord; +using Content.Server.Discord.WebhookMessages; using Content.Server.EUI; using Content.Server.GhostKick; using Content.Server.Info; @@ -64,6 +65,7 @@ namespace Content.Server.IoC IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); + IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); IoCManager.Register(); diff --git a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs index 0f7d238518..736ff48817 100644 --- a/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs +++ b/Content.Server/Voting/Managers/VoteManager.DefaultVotes.cs @@ -2,6 +2,7 @@ using System.Linq; using Content.Server.Administration; using Content.Server.Administration.Managers; using Content.Server.Database; +using Content.Server.Discord.WebhookMessages; using Content.Server.GameTicking; using Content.Server.GameTicking.Presets; using Content.Server.Maps; @@ -27,6 +28,7 @@ namespace Content.Server.Voting.Managers [Dependency] private readonly ILogManager _logManager = default!; [Dependency] private readonly IBanManager _bans = default!; [Dependency] private readonly IServerDbManager _dbManager = default!; + [Dependency] private readonly VoteWebhooks _voteWebhooks = default!; private VotingSystem? _votingSystem; private RoleSystem? _roleSystem; @@ -449,10 +451,13 @@ namespace Content.Server.Voting.Managers var vote = CreateVote(options); _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"Votekick for {located.Username} ({targetEntityName}) due to {reason} started, initiated by {initiator}."); + // Create Discord webhook + var webhookState = _voteWebhooks.CreateWebhookIfConfigured(options, _cfg.GetCVar(CCVars.DiscordVotekickWebhook), Loc.GetString("votekick-webhook-name"), options.Title + "\n" + Loc.GetString("votekick-webhook-description", ("initiator", initiatorName), ("target", targetSession))); + // Time out the vote now that we know it will happen TimeoutStandardVote(StandardVoteType.Votekick); - vote.OnFinished += (_, _) => + vote.OnFinished += (_, eventArgs) => { var votesYes = vote.VotesPerOption["yes"]; @@ -487,6 +492,7 @@ namespace Content.Server.Voting.Managers { _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"Votekick for {located.Username} attempted to pass, but an admin was online. Yes: {votesYes} / No: {votesNo}. Yes: {yesVotersString} / No: {noVotersString}"); AnnounceCancelledVotekickForVoters(targetEntityName); + _voteWebhooks.UpdateCancelledWebhookIfConfigured(webhookState, Loc.GetString("votekick-webhook-cancelled-admin-online")); return; } // Check if the target is an antag and the vote reason is raiding (this is to prevent false positives) @@ -494,6 +500,7 @@ namespace Content.Server.Voting.Managers { _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"Votekick for {located.Username} due to {reason} finished, created by {initiator}, but was cancelled due to the target being an antagonist."); AnnounceCancelledVotekickForVoters(targetEntityName); + _voteWebhooks.UpdateCancelledWebhookIfConfigured(webhookState, Loc.GetString("votekick-webhook-cancelled-antag-target")); return; } // Check if the target is an admin/de-admined admin @@ -501,6 +508,7 @@ namespace Content.Server.Voting.Managers { _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"Votekick for {located.Username} due to {reason} finished, created by {initiator}, but was cancelled due to the target being a de-admined admin."); AnnounceCancelledVotekickForVoters(targetEntityName); + _voteWebhooks.UpdateCancelledWebhookIfConfigured(webhookState, Loc.GetString("votekick-webhook-cancelled-admin-target")); return; } else @@ -515,6 +523,9 @@ namespace Content.Server.Voting.Managers severity = NoteSeverity.High; } + // Discord webhook, success + _voteWebhooks.UpdateWebhookIfConfigured(webhookState, eventArgs); + uint minutes = (uint)_cfg.GetCVar(CCVars.VotekickBanDuration); _bans.CreateServerBan(targetUid, target, null, null, targetHWid, minutes, severity, reason); @@ -522,6 +533,10 @@ namespace Content.Server.Voting.Managers } else { + + // Discord webhook, failure + _voteWebhooks.UpdateWebhookIfConfigured(webhookState, eventArgs); + _adminLogger.Add(LogType.Vote, LogImpact.Extreme, $"Votekick failed: Yes: {votesYes} / No: {votesNo}. Yes: {yesVotersString} / No: {noVotersString}"); _chatManager.DispatchServerAnnouncement(Loc.GetString("ui-vote-votekick-failure", ("target", targetEntityName), ("reason", reason))); } diff --git a/Content.Server/Voting/VoteCommands.cs b/Content.Server/Voting/VoteCommands.cs index 7dbb41b50f..d4c236f394 100644 --- a/Content.Server/Voting/VoteCommands.cs +++ b/Content.Server/Voting/VoteCommands.cs @@ -1,11 +1,8 @@ using System.Linq; -using System.Text.Json; -using System.Text.Json.Nodes; using Content.Server.Administration; using Content.Server.Administration.Logs; using Content.Server.Chat.Managers; -using Content.Server.Discord; -using Content.Server.GameTicking; +using Content.Server.Discord.WebhookMessages; using Content.Server.Voting.Managers; using Content.Shared.Administration; using Content.Shared.CCVar; @@ -76,11 +73,9 @@ namespace Content.Server.Voting { [Dependency] private readonly IVoteManager _voteManager = default!; [Dependency] private readonly IAdminLogManager _adminLogger = default!; - [Dependency] private readonly IConfigurationManager _cfg = default!; - [Dependency] private readonly DiscordWebhook _discord = default!; - [Dependency] private readonly GameTicker _gameTicker = default!; - [Dependency] private readonly IBaseServer _baseServer = default!; [Dependency] private readonly IChatManager _chatManager = default!; + [Dependency] private readonly VoteWebhooks _voteWebhooks = default!; + [Dependency] private readonly IConfigurationManager _cfg = default!; private ISawmill _sawmill = default!; @@ -120,7 +115,7 @@ namespace Content.Server.Voting var vote = _voteManager.CreateVote(options); - var webhookState = CreateWebhookIfConfigured(options); + var webhookState = _voteWebhooks.CreateWebhookIfConfigured(options, _cfg.GetCVar(CCVars.DiscordVoteWebhook)); vote.OnFinished += (_, eventArgs) => { @@ -136,12 +131,12 @@ namespace Content.Server.Voting _chatManager.DispatchServerAnnouncement(Loc.GetString("cmd-customvote-on-finished-win", ("winner", args[(int) eventArgs.Winner]))); } - UpdateWebhookIfConfigured(webhookState, eventArgs); + _voteWebhooks.UpdateWebhookIfConfigured(webhookState, eventArgs); }; vote.OnCancelled += _ => { - UpdateCancelledWebhookIfConfigured(webhookState); + _voteWebhooks.UpdateCancelledWebhookIfConfigured(webhookState); }; } @@ -156,159 +151,6 @@ namespace Content.Server.Voting var n = args.Length - 1; return CompletionResult.FromHint(Loc.GetString("cmd-customvote-arg-option-n", ("n", n))); } - - private WebhookState? CreateWebhookIfConfigured(VoteOptions voteOptions) - { - // All this webhook code is complete garbage. - // I tried to clean it up somewhat, at least to fix the glaring bugs in it. - // Jesus christ man what is with our code review process. - - var webhookUrl = _cfg.GetCVar(CCVars.DiscordVoteWebhook); - if (string.IsNullOrEmpty(webhookUrl)) - return null; - - // Set up the webhook payload - var serverName = _baseServer.ServerName; - - var fields = new List(); - - foreach (var voteOption in voteOptions.Options) - { - var newVote = new WebhookEmbedField - { - Name = voteOption.text, - Value = Loc.GetString("custom-vote-webhook-option-pending") - }; - fields.Add(newVote); - } - - var runLevel = Loc.GetString($"game-run-level-{_gameTicker.RunLevel}"); - - var payload = new WebhookPayload() - { - Username = Loc.GetString("custom-vote-webhook-name"), - Embeds = new List - { - new() - { - Title = voteOptions.InitiatorText, - Color = 13438992, // #CD1010 - Description = voteOptions.Title, - Footer = new WebhookEmbedFooter - { - Text = Loc.GetString( - "custom-vote-webhook-footer", - ("serverName", serverName), - ("roundId", _gameTicker.RoundId), - ("runLevel", runLevel)), - }, - - Fields = fields, - }, - }, - }; - - var state = new WebhookState - { - WebhookUrl = webhookUrl, - Payload = payload, - }; - - CreateWebhookMessage(state, payload); - - return state; - } - - private void UpdateWebhookIfConfigured(WebhookState? state, VoteFinishedEventArgs finished) - { - if (state == null) - return; - - var embed = state.Payload.Embeds![0]; - embed.Color = 2353993; // #23EB49 - - for (var i = 0; i < finished.Votes.Count; i++) - { - var oldName = embed.Fields[i].Name; - var newValue = finished.Votes[i].ToString(); - embed.Fields[i] = new WebhookEmbedField { Name = oldName, Value = newValue, Inline = true}; - } - - state.Payload.Embeds[0] = embed; - - UpdateWebhookMessage(state, state.Payload, state.MessageId); - } - - private void UpdateCancelledWebhookIfConfigured(WebhookState? state) - { - if (state == null) - return; - - var embed = state.Payload.Embeds![0]; - embed.Color = 13356304; // #CBCD10 - embed.Description += "\n\n" + Loc.GetString("custom-vote-webhook-cancelled"); - - for (var i = 0; i < embed.Fields.Count; i++) - { - var oldName = embed.Fields[i].Name; - embed.Fields[i] = new WebhookEmbedField { Name = oldName, Value = Loc.GetString("custom-vote-webhook-option-cancelled"), Inline = true}; - } - - state.Payload.Embeds[0] = embed; - - UpdateWebhookMessage(state, state.Payload, state.MessageId); - } - - // Sends the payload's message. - private async void CreateWebhookMessage(WebhookState state, WebhookPayload payload) - { - try - { - if (await _discord.GetWebhook(state.WebhookUrl) is not { } identifier) - return; - - state.Identifier = identifier.ToIdentifier(); - - _sawmill.Debug(JsonSerializer.Serialize(payload)); - - var request = await _discord.CreateMessage(identifier.ToIdentifier(), payload); - var content = await request.Content.ReadAsStringAsync(); - state.MessageId = ulong.Parse(JsonNode.Parse(content)?["id"]!.GetValue()!); - } - catch (Exception e) - { - _sawmill.Error($"Error while sending vote webhook to Discord: {e}"); - } - } - - // Edits a pre-existing payload message, given an ID - private async void UpdateWebhookMessage(WebhookState state, WebhookPayload payload, ulong id) - { - if (state.MessageId == 0) - { - _sawmill.Warning("Failed to deliver update to custom vote webhook: message ID was zero. This likely indicates a previous connection error sending the original message."); - return; - } - - DebugTools.Assert(state.Identifier != default); - - try - { - await _discord.EditMessage(state.Identifier, id, payload); - } - catch (Exception e) - { - _sawmill.Error($"Error while updating vote webhook on Discord: {e}"); - } - } - - private sealed class WebhookState - { - public required string WebhookUrl; - public required WebhookPayload Payload; - public WebhookIdentifier Identifier; - public ulong MessageId; - } } [AnyCommand] diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 14bb760f40..a4f315d62c 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -465,6 +465,12 @@ namespace Content.Shared.CCVar public static readonly CVarDef DiscordVoteWebhook = CVarDef.Create("discord.vote_webhook", string.Empty, CVar.SERVERONLY); + /// + /// URL of the Discord webhook which will relay all votekick votes. If left empty, disables the webhook. + /// + public static readonly CVarDef DiscordVotekickWebhook = + CVarDef.Create("discord.votekick_webhook", string.Empty, CVar.SERVERONLY); + /// URL of the Discord webhook which will relay round restart messages. /// public static readonly CVarDef DiscordRoundUpdateWebhook = diff --git a/Resources/Locale/en-US/administration/commands/custom-vote-command.ftl b/Resources/Locale/en-US/administration/commands/custom-vote-command.ftl deleted file mode 100644 index 221f0629a5..0000000000 --- a/Resources/Locale/en-US/administration/commands/custom-vote-command.ftl +++ /dev/null @@ -1,5 +0,0 @@ -custom-vote-webhook-name = Custom Vote Held -custom-vote-webhook-footer = server: { $serverName }, round: { $roundId } { $runLevel } -custom-vote-webhook-cancelled = **Vote cancelled** -custom-vote-webhook-option-pending = TBD -custom-vote-webhook-option-cancelled = N/A diff --git a/Resources/Locale/en-US/discord/vote-notifications.ftl b/Resources/Locale/en-US/discord/vote-notifications.ftl new file mode 100644 index 0000000000..f6779cac83 --- /dev/null +++ b/Resources/Locale/en-US/discord/vote-notifications.ftl @@ -0,0 +1,11 @@ +custom-vote-webhook-name = Custom Vote Held +custom-vote-webhook-footer = server: { $serverName }, round: { $roundId } { $runLevel } +custom-vote-webhook-cancelled = **Vote cancelled** +custom-vote-webhook-option-pending = TBD +custom-vote-webhook-option-cancelled = N/A + +votekick-webhook-name = Votekick Held +votekick-webhook-description = Initiator: { $initiator }; Target: { $target } +votekick-webhook-cancelled-admin-online = **Vote cancelled due to admins online** +votekick-webhook-cancelled-admin-target = **Vote cancelled due to target being admin** +votekick-webhook-cancelled-antag-target = **Vote cancelled due to target being antag** From 4aed72820725c9384b593c135d1ca791f78ef0da Mon Sep 17 00:00:00 2001 From: Ilya246 <57039557+Ilya246@users.noreply.github.com> Date: Sun, 29 Sep 2024 19:18:09 +0400 Subject: [PATCH 24/88] make conveyor belt assemblies cheaper (#32444) cheapening --- Resources/Prototypes/Recipes/Lathes/cargo.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Recipes/Lathes/cargo.yml b/Resources/Prototypes/Recipes/Lathes/cargo.yml index 630dc1d062..82050985b8 100644 --- a/Resources/Prototypes/Recipes/Lathes/cargo.yml +++ b/Resources/Prototypes/Recipes/Lathes/cargo.yml @@ -3,7 +3,7 @@ result: ConveyorBeltAssembly completetime: 4 materials: - Steel: 500 + Steel: 250 Plastic: 50 - type: latheRecipe From f6ceaa7d101e5422ada05a54c5ced6048b13ba84 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 29 Sep 2024 15:19:15 +0000 Subject: [PATCH 25/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 075946bfe9..8544b0fdae 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,15 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: Syndicate traitor reinforcements are now specialized to be medics, spies, - or thieves. - type: Add - - message: Reinforcement radios with options now have a radial menu, similar to - RCDs. - type: Tweak - id: 6956 - time: '2024-07-21T10:32:25.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29853 - author: Cojoke-dot changes: - message: Dead Space Dragons no long despawn @@ -3938,3 +3927,10 @@ id: 7455 time: '2024-09-29T12:22:57.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32521 +- author: Ilya246 + changes: + - message: Steel cost of conveyor belt assemblies halved. + type: Tweak + id: 7456 + time: '2024-09-29T15:18:09.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32444 From 16325007d5fc3e80ef86cd3bd06f436f185e679a Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Sun, 29 Sep 2024 23:37:31 +0200 Subject: [PATCH 26/88] Fix mutation system debug assert (#32530) --- Content.Server/Botany/Systems/MutationSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Botany/Systems/MutationSystem.cs b/Content.Server/Botany/Systems/MutationSystem.cs index 07a24d19f6..37b68d9475 100644 --- a/Content.Server/Botany/Systems/MutationSystem.cs +++ b/Content.Server/Botany/Systems/MutationSystem.cs @@ -27,7 +27,7 @@ public sealed class MutationSystem : EntitySystem { foreach (var mutation in _randomMutations.mutations) { - if (Random(mutation.BaseOdds * severity)) + if (Random(Math.Min(mutation.BaseOdds * severity, 1.0f))) { if (mutation.AppliesToPlant) { From 5c0b127456a14af309b58fab0d12fbbc8598a6da Mon Sep 17 00:00:00 2001 From: Celene <4323352+CuteMoonGod@users.noreply.github.com> Date: Mon, 30 Sep 2024 00:36:47 +0200 Subject: [PATCH 27/88] Execution System uses the identity of an entity; added "the" to execution message (#32536) * Exec.System now uses IdentityManagement; added the where necessary * Included attacker in check for Identity --------- Co-authored-by: Celene --- Content.Shared/Execution/SharedExecutionSystem.cs | 7 ++++--- Resources/Locale/en-US/execution/execution.ftl | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Content.Shared/Execution/SharedExecutionSystem.cs b/Content.Shared/Execution/SharedExecutionSystem.cs index c34cecc3da..b6d52cf352 100644 --- a/Content.Shared/Execution/SharedExecutionSystem.cs +++ b/Content.Shared/Execution/SharedExecutionSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.CombatMode; using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.DoAfter; +using Content.Shared.IdentityManagement; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; @@ -155,7 +156,7 @@ public sealed class SharedExecutionSystem : EntitySystem if (predict) { _popup.PopupClient( - Loc.GetString(locString, ("attacker", attacker), ("victim", victim), ("weapon", weapon)), + Loc.GetString(locString, ("attacker", Identity.Entity(attacker, EntityManager)), ("victim", Identity.Entity(victim, EntityManager)), ("weapon", weapon)), attacker, attacker, PopupType.MediumCaution @@ -164,7 +165,7 @@ public sealed class SharedExecutionSystem : EntitySystem else { _popup.PopupEntity( - Loc.GetString(locString, ("attacker", attacker), ("victim", victim), ("weapon", weapon)), + Loc.GetString(locString, ("attacker", Identity.Entity(attacker, EntityManager)), ("victim", Identity.Entity(victim, EntityManager)), ("weapon", weapon)), attacker, attacker, PopupType.MediumCaution @@ -175,7 +176,7 @@ public sealed class SharedExecutionSystem : EntitySystem private void ShowExecutionExternalPopup(string locString, EntityUid attacker, EntityUid victim, EntityUid weapon) { _popup.PopupEntity( - Loc.GetString(locString, ("attacker", attacker), ("victim", victim), ("weapon", weapon)), + Loc.GetString(locString, ("attacker", Identity.Entity(attacker, EntityManager)), ("victim", Identity.Entity(victim, EntityManager)), ("weapon", weapon)), attacker, Filter.PvsExcept(attacker), true, diff --git a/Resources/Locale/en-US/execution/execution.ftl b/Resources/Locale/en-US/execution/execution.ftl index 08f9a06dd4..1eb914a147 100644 --- a/Resources/Locale/en-US/execution/execution.ftl +++ b/Resources/Locale/en-US/execution/execution.ftl @@ -6,12 +6,12 @@ execution-verb-message = Use your weapon to execute someone. # victim (the person being executed) # weapon (the weapon used for the execution) -execution-popup-melee-initial-internal = You ready {THE($weapon)} against {$victim}'s throat. -execution-popup-melee-initial-external = {$attacker} readies {POSS-ADJ($attacker)} {$weapon} against the throat of {$victim}. -execution-popup-melee-complete-internal = You slit the throat of {$victim}! -execution-popup-melee-complete-external = {$attacker} slits the throat of {$victim}! +execution-popup-melee-initial-internal = You ready {THE($weapon)} against {THE($victim)}'s throat. +execution-popup-melee-initial-external = { CAPITALIZE(THE($attacker)) } readies {POSS-ADJ($attacker)} {$weapon} against the throat of {THE($victim)}. +execution-popup-melee-complete-internal = You slit the throat of {THE($victim)}! +execution-popup-melee-complete-external = { CAPITALIZE(THE($attacker)) } slits the throat of {THE($victim)}! execution-popup-self-initial-internal = You ready {THE($weapon)} against your own throat. -execution-popup-self-initial-external = {$attacker} readies {POSS-ADJ($attacker)} {$weapon} against their own throat. +execution-popup-self-initial-external = { CAPITALIZE(THE($attacker)) } readies {POSS-ADJ($attacker)} {$weapon} against their own throat. execution-popup-self-complete-internal = You slit your own throat! -execution-popup-self-complete-external = {$attacker} slits their own throat! \ No newline at end of file +execution-popup-self-complete-external = { CAPITALIZE(THE($attacker)) } slits their own throat! From dd15a6862c6ea15f15a77b30d885a9319870676c Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 29 Sep 2024 22:37:53 +0000 Subject: [PATCH 28/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 8544b0fdae..a57c812450 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: Dead Space Dragons no long despawn - type: Fix - id: 6957 - time: '2024-07-21T10:46:33.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29842 - author: slarticodefast changes: - message: Fixed microwave construction. @@ -3934,3 +3927,10 @@ id: 7456 time: '2024-09-29T15:18:09.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32444 +- author: CuteMoonGod + changes: + - message: Fixed execution system showing character name instead of their identity + type: Fix + id: 7457 + time: '2024-09-29T22:36:47.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32536 From 7cf04dcb201e1a615e4a175ff929cca9554134d2 Mon Sep 17 00:00:00 2001 From: drakewill-CRL <46307022+drakewill-CRL@users.noreply.github.com> Date: Mon, 30 Sep 2024 01:14:07 -0400 Subject: [PATCH 29/88] Use archived gas mixture in gas exchange comparison (#32088) The comparison for doing gas exchange used current and not archived moles. This could lead to update order-dependent gas spreading effects. To fix this, convert TileAtmosphere's MolesArchived and TemperatureArchived to a AirArchived, and use that in the comparison method. --------- Co-authored-by: PraxisMapper Co-authored-by: Kevin Zheng --- .../EntitySystems/AtmosphereSystem.Gases.cs | 11 +++++++ .../AtmosphereSystem.GridAtmosphere.cs | 2 +- .../EntitySystems/AtmosphereSystem.LINDA.cs | 29 ++++++++++--------- .../AtmosphereSystem.Monstermos.cs | 2 +- .../AtmosphereSystem.Processing.cs | 4 +-- .../AtmosphereSystem.Superconductivity.cs | 10 +++++-- Content.Server/Atmos/TileAtmosphere.cs | 16 +++++----- 7 files changed, 47 insertions(+), 27 deletions(-) diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs index 70c4639e48..f38ec3fef6 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs @@ -281,6 +281,17 @@ namespace Content.Server.Atmos.EntitySystems return true; } + /// + /// Compares two TileAtmospheres to see if they are within acceptable ranges for group processing to be enabled. + /// + public GasCompareResult CompareExchange(TileAtmosphere sample, TileAtmosphere otherSample) + { + if (sample.AirArchived == null || otherSample.AirArchived == null) + return GasCompareResult.NoExchange; + + return CompareExchange(sample.AirArchived, otherSample.AirArchived); + } + /// /// Compares two gas mixtures to see if they are within acceptable ranges for group processing to be enabled. /// diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs index 3983234dea..b11eb5dc3e 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs @@ -270,7 +270,7 @@ public sealed partial class AtmosphereSystem { DebugTools.AssertNotNull(tile.Air); DebugTools.Assert(tile.Air?.Immutable == false); - Array.Clear(tile.MolesArchived); + tile.AirArchived = null; tile.ArchivedCycle = 0; var count = 0; diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.LINDA.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.LINDA.cs index fb2375899d..55b38924c0 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.LINDA.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.LINDA.cs @@ -54,7 +54,7 @@ namespace Content.Server.Atmos.EntitySystems } shouldShareAir = true; - } else if (CompareExchange(tile.Air, enemyTile.Air) != GasCompareResult.NoExchange) + } else if (CompareExchange(tile, enemyTile) != GasCompareResult.NoExchange) { AddActiveTile(gridAtmosphere, enemyTile); if (ExcitedGroups) @@ -117,9 +117,8 @@ namespace Content.Server.Atmos.EntitySystems private void Archive(TileAtmosphere tile, int fireCount) { if (tile.Air != null) - tile.Air.Moles.AsSpan().CopyTo(tile.MolesArchived.AsSpan()); + tile.AirArchived = new GasMixture(tile.Air); - tile.TemperatureArchived = tile.Temperature; tile.ArchivedCycle = fireCount; } @@ -184,10 +183,10 @@ namespace Content.Server.Atmos.EntitySystems /// public float GetHeatCapacityArchived(TileAtmosphere tile) { - if (tile.Air == null) + if (tile.AirArchived == null) return tile.HeatCapacity; - return GetHeatCapacityCalculation(tile.MolesArchived!, tile.Space); + return GetHeatCapacity(tile.AirArchived); } /// @@ -195,10 +194,11 @@ namespace Content.Server.Atmos.EntitySystems /// public float Share(TileAtmosphere tileReceiver, TileAtmosphere tileSharer, int atmosAdjacentTurfs) { - if (tileReceiver.Air is not {} receiver || tileSharer.Air is not {} sharer) + if (tileReceiver.Air is not {} receiver || tileSharer.Air is not {} sharer || + tileReceiver.AirArchived == null || tileSharer.AirArchived == null) return 0f; - var temperatureDelta = tileReceiver.TemperatureArchived - tileSharer.TemperatureArchived; + var temperatureDelta = tileReceiver.AirArchived.Temperature - tileSharer.AirArchived.Temperature; var absTemperatureDelta = Math.Abs(temperatureDelta); var oldHeatCapacity = 0f; var oldSharerHeatCapacity = 0f; @@ -249,12 +249,12 @@ namespace Content.Server.Atmos.EntitySystems // Transfer of thermal energy (via changed heat capacity) between self and sharer. if (!receiver.Immutable && newHeatCapacity > Atmospherics.MinimumHeatCapacity) { - receiver.Temperature = ((oldHeatCapacity * receiver.Temperature) - (heatCapacityToSharer * tileReceiver.TemperatureArchived) + (heatCapacitySharerToThis * tileSharer.TemperatureArchived)) / newHeatCapacity; + receiver.Temperature = ((oldHeatCapacity * receiver.Temperature) - (heatCapacityToSharer * tileReceiver.AirArchived.Temperature) + (heatCapacitySharerToThis * tileSharer.AirArchived.Temperature)) / newHeatCapacity; } if (!sharer.Immutable && newSharerHeatCapacity > Atmospherics.MinimumHeatCapacity) { - sharer.Temperature = ((oldSharerHeatCapacity * sharer.Temperature) - (heatCapacitySharerToThis * tileSharer.TemperatureArchived) + (heatCapacityToSharer * tileReceiver.TemperatureArchived)) / newSharerHeatCapacity; + sharer.Temperature = ((oldSharerHeatCapacity * sharer.Temperature) - (heatCapacitySharerToThis * tileSharer.AirArchived.Temperature) + (heatCapacityToSharer * tileReceiver.AirArchived.Temperature)) / newSharerHeatCapacity; } // Thermal energy of the system (self and sharer) is unchanged. @@ -273,7 +273,7 @@ namespace Content.Server.Atmos.EntitySystems var moles = receiver.TotalMoles; var theirMoles = sharer.TotalMoles; - return (tileReceiver.TemperatureArchived * (moles + movedMoles)) - (tileSharer.TemperatureArchived * (theirMoles - movedMoles)) * Atmospherics.R / receiver.Volume; + return (tileReceiver.AirArchived.Temperature * (moles + movedMoles)) - (tileSharer.AirArchived.Temperature * (theirMoles - movedMoles)) * Atmospherics.R / receiver.Volume; } /// @@ -281,10 +281,11 @@ namespace Content.Server.Atmos.EntitySystems /// public float TemperatureShare(TileAtmosphere tileReceiver, TileAtmosphere tileSharer, float conductionCoefficient) { - if (tileReceiver.Air is not { } receiver || tileSharer.Air is not { } sharer) + if (tileReceiver.Air is not { } receiver || tileSharer.Air is not { } sharer || + tileReceiver.AirArchived == null || tileSharer.AirArchived == null) return 0f; - var temperatureDelta = tileReceiver.TemperatureArchived - tileSharer.TemperatureArchived; + var temperatureDelta = tileReceiver.AirArchived.Temperature - tileSharer.AirArchived.Temperature; if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider) { var heatCapacity = GetHeatCapacityArchived(tileReceiver); @@ -310,10 +311,10 @@ namespace Content.Server.Atmos.EntitySystems /// public float TemperatureShare(TileAtmosphere tileReceiver, float conductionCoefficient, float sharerTemperature, float sharerHeatCapacity) { - if (tileReceiver.Air is not {} receiver) + if (tileReceiver.Air is not {} receiver || tileReceiver.AirArchived == null) return 0; - var temperatureDelta = tileReceiver.TemperatureArchived - sharerTemperature; + var temperatureDelta = tileReceiver.AirArchived.Temperature - sharerTemperature; if (MathF.Abs(temperatureDelta) > Atmospherics.MinimumTemperatureDeltaToConsider) { var heatCapacity = GetHeatCapacityArchived(tileReceiver); diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs index d703a98154..e6466c8157 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Monstermos.cs @@ -355,7 +355,7 @@ namespace Content.Server.Atmos.EntitySystems continue; DebugTools.Assert(otherTile2.AdjacentBits.IsFlagSet(direction.GetOpposite())); - if (otherTile2.Air != null && CompareExchange(otherTile2.Air, tile.Air) == GasCompareResult.NoExchange) + if (otherTile2.Air != null && CompareExchange(otherTile2, tile) == GasCompareResult.NoExchange) continue; AddActiveTile(gridAtmosphere, otherTile2); diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs index 85b1a93e20..59320ba67b 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs @@ -231,7 +231,7 @@ namespace Content.Server.Atmos.EntitySystems tile.MapAtmosphere = false; atmos.MapTiles.Remove(tile); tile.Air = null; - Array.Clear(tile.MolesArchived); + tile.AirArchived = null; tile.ArchivedCycle = 0; tile.LastShare = 0f; tile.Space = false; @@ -261,7 +261,7 @@ namespace Content.Server.Atmos.EntitySystems return; tile.Air = null; - Array.Clear(tile.MolesArchived); + tile.AirArchived = null; tile.ArchivedCycle = 0; tile.LastShare = 0f; tile.Hotspot = new Hotspot(); diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Superconductivity.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Superconductivity.cs index 8ed92a9d0e..46a554054b 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Superconductivity.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Superconductivity.cs @@ -131,7 +131,10 @@ namespace Content.Server.Atmos.EntitySystems private void TemperatureShareMutualSolid(TileAtmosphere tile, TileAtmosphere other, float conductionCoefficient) { - var deltaTemperature = (tile.TemperatureArchived - other.TemperatureArchived); + if (tile.AirArchived == null || other.AirArchived == null) + return; + + var deltaTemperature = (tile.AirArchived.Temperature - other.AirArchived.Temperature); if (MathF.Abs(deltaTemperature) > Atmospherics.MinimumTemperatureDeltaToConsider && tile.HeatCapacity != 0f && other.HeatCapacity != 0f) { @@ -145,11 +148,14 @@ namespace Content.Server.Atmos.EntitySystems public void RadiateToSpace(TileAtmosphere tile) { + if (tile.AirArchived == null) + return; + // Considering 0ºC as the break even point for radiation in and out. if (tile.Temperature > Atmospherics.T0C) { // Hardcoded space temperature. - var deltaTemperature = (tile.TemperatureArchived - Atmospherics.TCMB); + var deltaTemperature = (tile.AirArchived.Temperature - Atmospherics.TCMB); if ((tile.HeatCapacity > 0) && (MathF.Abs(deltaTemperature) > Atmospherics.MinimumTemperatureDeltaToConsider)) { var heat = tile.ThermalConductivity * deltaTemperature * (tile.HeatCapacity * diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index 0026dbbf4f..46a85990fa 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -22,9 +22,6 @@ namespace Content.Server.Atmos [ViewVariables] public float Temperature { get; set; } = Atmospherics.T20C; - [ViewVariables] - public float TemperatureArchived { get; set; } = Atmospherics.T20C; - [ViewVariables] public TileAtmosphere? PressureSpecificTarget { get; set; } @@ -93,12 +90,16 @@ namespace Content.Server.Atmos [Access(typeof(AtmosphereSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends public GasMixture? Air { get; set; } + /// + /// Like Air, but a copy stored each atmos tick before tile processing takes place. This lets us update Air + /// in-place without affecting the results based on update order. + /// + [ViewVariables] + public GasMixture? AirArchived; + [DataField("lastShare")] public float LastShare; - [ViewVariables] - public readonly float[] MolesArchived = new float[Atmospherics.AdjustedNumberOfGases]; - GasMixture IGasMixtureHolder.Air { get => Air ?? new GasMixture(Atmospherics.CellVolume){ Temperature = Temperature }; @@ -139,6 +140,7 @@ namespace Content.Server.Atmos GridIndex = gridIndex; GridIndices = gridIndices; Air = mixture; + AirArchived = Air != null ? Air.Clone() : null; Space = space; if(immutable) @@ -153,7 +155,7 @@ namespace Content.Server.Atmos NoGridTile = other.NoGridTile; MapAtmosphere = other.MapAtmosphere; Air = other.Air?.Clone(); - Array.Copy(other.MolesArchived, MolesArchived, MolesArchived.Length); + AirArchived = Air != null ? Air.Clone() : null; } public TileAtmosphere() From c419e58300e0a4825106c197887e6cedc7d101f3 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 30 Sep 2024 05:15:13 +0000 Subject: [PATCH 30/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a57c812450..5ee4bc482e 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: slarticodefast - changes: - - message: Fixed microwave construction. - type: Fix - id: 6958 - time: '2024-07-21T16:20:09.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30232 - author: Sphiral&Kezu changes: - message: 'Added a variety of new wall based storages: Shelfs! Build some today!' @@ -3934,3 +3927,10 @@ id: 7457 time: '2024-09-29T22:36:47.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32536 +- author: drakewill-CRL + changes: + - message: Fix error in gas exchange processing order. + type: Fix + id: 7458 + time: '2024-09-30T05:14:07.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32088 From bc059f0b6d0fedc6511d76c76595fb02935bf1c6 Mon Sep 17 00:00:00 2001 From: qwerltaz <69696513+qwerltaz@users.noreply.github.com> Date: Mon, 30 Sep 2024 11:56:05 +0200 Subject: [PATCH 31/88] AI can use fire alarm (#32467) * ai can use fire alarm * ai wire --- .../Prototypes/Entities/Structures/Wallmounts/fire_alarm.yml | 1 + Resources/Prototypes/Wires/layouts.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/fire_alarm.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/fire_alarm.yml index 917a94ddc9..03bc3e4a8d 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/fire_alarm.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/fire_alarm.yml @@ -104,6 +104,7 @@ collection: MetalGlassBreak params: volume: -4 + - type: StationAiWhitelist placement: mode: SnapgridCenter snap: diff --git a/Resources/Prototypes/Wires/layouts.yml b/Resources/Prototypes/Wires/layouts.yml index 955bae0104..cb211cf843 100644 --- a/Resources/Prototypes/Wires/layouts.yml +++ b/Resources/Prototypes/Wires/layouts.yml @@ -90,6 +90,7 @@ - type: wireLayout id: FireAlarm wires: + - !type:AiInteractWireAction - !type:PowerWireAction - !type:AtmosMonitorDeviceNetWire alarmOnPulse: true From 717f82f9da59b9498b505bb059652d7f8b36f574 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 30 Sep 2024 09:57:11 +0000 Subject: [PATCH 32/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 5ee4bc482e..cbefc51e29 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Sphiral&Kezu - changes: - - message: 'Added a variety of new wall based storages: Shelfs! Build some today!' - type: Add - id: 6959 - time: '2024-07-21T17:16:58.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27858 - author: valquaint, slarticodefast changes: - message: Fixed borgs being unable to state laws with an activated flashlight. @@ -3934,3 +3927,10 @@ id: 7458 time: '2024-09-30T05:14:07.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32088 +- author: qwerltaz + changes: + - message: AI can now use fire alarms. + type: Add + id: 7459 + time: '2024-09-30T09:56:05.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32467 From 38f59d2038913e76d14bfc975841b5ffded72bb8 Mon Sep 17 00:00:00 2001 From: BramvanZijp <56019239+BramvanZijp@users.noreply.github.com> Date: Mon, 30 Sep 2024 19:38:22 +0200 Subject: [PATCH 33/88] Swap the advanced tool borg modules omnitool for jaws and a power drill (#32487) --- .../Entities/Objects/Specific/Robotics/borg_modules.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml index 3b3a539664..17775b7e25 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml @@ -237,9 +237,10 @@ - state: icon-tools-adv - type: ItemBorgModule items: - - Omnitool + - JawsOfLife + - PowerDrill + - Multitool - WelderExperimental - - NetworkConfigurator - RemoteSignaller - GasAnalyzer - GeigerCounter From db198d28130ffcd37abbc18af64e0bd07d80aacc Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 30 Sep 2024 17:39:29 +0000 Subject: [PATCH 34/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index cbefc51e29..a3cdbb4e53 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: valquaint, slarticodefast - changes: - - message: Fixed borgs being unable to state laws with an activated flashlight. - type: Fix - id: 6960 - time: '2024-07-22T03:55:35.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30183 - author: Lank changes: - message: Darts can now pop balloons. Keep them away from any monkeys. @@ -3934,3 +3927,12 @@ id: 7459 time: '2024-09-30T09:56:05.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32467 +- author: BramvanZijp + changes: + - message: The Engineering Cyborg's Advanced Tool Module now has jaws of life and + a power drill instead of an omnitool, with a multitool replacing the network + configurator. + type: Tweak + id: 7460 + time: '2024-09-30T17:38:22.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32487 From 55ae02f320e8a4b365f6520f6dc19e2c2101dff7 Mon Sep 17 00:00:00 2001 From: Charlie Date: Tue, 1 Oct 2024 03:27:33 +0800 Subject: [PATCH 35/88] fix index stepping to avoid pushing front layers into back layers (#32553) Co-authored-by: charlie --- Content.Client/Clothing/ClientClothingSystem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Client/Clothing/ClientClothingSystem.cs b/Content.Client/Clothing/ClientClothingSystem.cs index 27d77eda49..3462fc9236 100644 --- a/Content.Client/Clothing/ClientClothingSystem.cs +++ b/Content.Client/Clothing/ClientClothingSystem.cs @@ -320,7 +320,8 @@ public sealed class ClientClothingSystem : ClothingSystem if (layerData.State is not null && inventory.SpeciesId is not null && layerData.State.EndsWith(inventory.SpeciesId)) continue; - _displacement.TryAddDisplacement(displacementData, sprite, index, key, revealedLayers); + if (_displacement.TryAddDisplacement(displacementData, sprite, index, key, revealedLayers)) + index++; } } From 2f286afd956899ab480a875e10c93ed085f8bf43 Mon Sep 17 00:00:00 2001 From: pofitlo Date: Tue, 1 Oct 2024 00:44:44 +0400 Subject: [PATCH 36/88] Syndicate business card (#32162) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add card * Update Resources/Locale/en-US/paper/syndicate-business-card.ftl Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com> * fix * Update Resources/Prototypes/Entities/Objects/Misc/business card.yml Co-authored-by: Эдуард <36124833+Ertanic@users.noreply.github.com> * add logo * swap the "funny 'c'" * improve logo (a little) and also fight with the funny 'c' * fix * oh... i think... mabe i done with this?... * add * smaller cards * fix * Update synicate_card.png * fix typo * fix * fix * Update Resources/Prototypes/Entities/Objects/Misc/business_card.yml --------- Co-authored-by: lzk <124214523+lzk228@users.noreply.github.com> Co-authored-by: Эдуард <36124833+Ertanic@users.noreply.github.com> Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../en-US/paper/syndicate-business-card.ftl | 2 + .../Locale/en-US/store/uplink-catalog.ftl | 3 + .../Prototypes/Catalog/uplink_catalog.yml | 11 ++ .../Entities/Objects/Misc/business_card.yml | 26 +++++ .../Paper/paper_background_black.svg | 40 ++++++++ .../paper_background_black.svg.96dpi.png | Bin 0 -> 2126 bytes .../paper_background_black.svg.96dpi.png.yml | 2 + .../Paper/paper_heading_syndicate_logo.svg | 94 ++++++++++++++++++ ...paper_heading_syndicate_logo.svg.96dpi.png | Bin 0 -> 6658 bytes ...r_heading_syndicate_logo.svg.96dpi.png.yml | 2 + .../Objects/Misc/bureaucracy.rsi/meta.json | 5 +- .../Misc/bureaucracy.rsi/syndicate_card.png | Bin 0 -> 395 bytes 12 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 Resources/Locale/en-US/paper/syndicate-business-card.ftl create mode 100644 Resources/Prototypes/Entities/Objects/Misc/business_card.yml create mode 100644 Resources/Textures/Interface/Paper/paper_background_black.svg create mode 100644 Resources/Textures/Interface/Paper/paper_background_black.svg.96dpi.png create mode 100644 Resources/Textures/Interface/Paper/paper_background_black.svg.96dpi.png.yml create mode 100644 Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg create mode 100644 Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg.96dpi.png create mode 100644 Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg.96dpi.png.yml create mode 100644 Resources/Textures/Objects/Misc/bureaucracy.rsi/syndicate_card.png diff --git a/Resources/Locale/en-US/paper/syndicate-business-card.ftl b/Resources/Locale/en-US/paper/syndicate-business-card.ftl new file mode 100644 index 0000000000..b4c8c8c43c --- /dev/null +++ b/Resources/Locale/en-US/paper/syndicate-business-card.ftl @@ -0,0 +1,2 @@ +syndicate-business-card-base = {" "} It's nothing personal, it's just business + diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 45d7ad2816..806a008491 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -445,3 +445,6 @@ uplink-backpack-syndicate-desc = A lightweight explosion-proof backpack for hold uplink-combat-bakery-name = Combat Bakery Kit uplink-combat-bakery-desc = A kit of clandestine baked weapons. Contains a baguette sword, a pair of throwing croissants, and a syndicate microwave board for making more. Once the job is done, eat the evidence. + +uplink-business-card-name = Syndicate business card. +uplink-business-card-desc = A business card that you can give to someone to demonstrate your involvement in the syndicate or leave at the crime scene in order to make fun of the detective. You can buy no more than three of them. diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index c84e88d077..83c739e6c5 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -1805,6 +1805,17 @@ categories: - UplinkPointless +- type: listing + id: UplinkSyndicateBusinessCard + name: uplink-business-card-name + description: uplink-business-card-desc + productEntity: SyndicateBusinessCard + categories: + - UplinkPointless + conditions: + - !type:ListingLimitedStockCondition + stock: 3 + # Job Specific - type: listing diff --git a/Resources/Prototypes/Entities/Objects/Misc/business_card.yml b/Resources/Prototypes/Entities/Objects/Misc/business_card.yml new file mode 100644 index 0000000000..a04351693a --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Misc/business_card.yml @@ -0,0 +1,26 @@ +- type: entity + id: SyndicateBusinessCard + name: syndicate business card + parent: Paper + description: A black card with the syndicate's logo. There's something written on the back. + components: + - type: Sprite + sprite: Objects/Misc/bureaucracy.rsi + layers: + - state: syndicate_card + - state: syndicate_card + map: ["enum.PaperVisualLayers.Writing"] + visible: false + - state: paper_stamp-generic + map: ["enum.PaperVisualLayers.Stamp"] + visible: false + - type: Paper + content: syndicate-business-card-base + - type: PaperVisuals + headerImagePath: "/Textures/Interface/Paper/paper_heading_syndicate_logo.svg.96dpi.png" + headerMargin: 0.0, 0.0, 0.0, 2.0 + backgroundImagePath: "/Textures/Interface/Paper/paper_background_black.svg.96dpi.png" + backgroundPatchMargin: 16.0, 16.0, 16.0, 16.0 + contentMargin: 4.0, 4.0, 4.0, 4.0 + maxWritableArea: 400.0, 256.0 + diff --git a/Resources/Textures/Interface/Paper/paper_background_black.svg b/Resources/Textures/Interface/Paper/paper_background_black.svg new file mode 100644 index 0000000000..7c208901f4 --- /dev/null +++ b/Resources/Textures/Interface/Paper/paper_background_black.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + diff --git a/Resources/Textures/Interface/Paper/paper_background_black.svg.96dpi.png b/Resources/Textures/Interface/Paper/paper_background_black.svg.96dpi.png new file mode 100644 index 0000000000000000000000000000000000000000..47e74fc873b22e60801786dc7efd5eb65c55136d GIT binary patch literal 2126 zcmZ`)c{JPG7XC%WbZbu4kP<_QnTAUZH6%q)QZOKWaxh_O*FHEYY$M%{RSz4ymmXYF(L+UxB7eS7b-*Gb3NS@QEq@&N$AkG4WN zu+KZk!o$VhBN&E8006qLQv3atIX)# z;Y^7<1}=GWo7AmcxvIFswKGupG-OUm;04(cc0s9lWR=)`-?QLM!lLIZw}ql>#*d1X z1VkxI()qE4PT_Z=9_l+_9N(S}6*#RQ9OCTHKmKo}L~46=9lpsf48p4>n+`$s-6$nX z+M@iN(Ars*hfS2k?!BtMv$-{V7Mb7=RMY2&3yIq;9_2c^s|p8;rbiUt_zX}Rwsf|U zzUA}IzXX`OzF@uaV@(~mm-~(2LV%iqSQ{#-qgMXSpXPD(-IT5YG+G`6HyHa6xFPkto;Gi#xvcZ)m|*?r;iwy{J3 zN5`x5byY6g!h6fgEerqzx{n3)Kvh7BZR8F|U%JS>!Yc@Y7-SivzRetoD`cFX|qj2X2)yiPA}np9c)u5HPTu6%QL-Nz1~+G@O_!YAIq5Lk(Q02 z7w6AXI8`m~7dUfnJ?V2p1#MUI?`VqHnt{tJ+pKYoLw_Pjs59dc~v zUly9BFJ7GI&@}vXNJPK2afXVSiAwc*KEcRFEXp^vR&*!QgQBNQL-nI;Bis*MrEbQF zWtIP;=+L;vGGhW1!xGIUUXBM8i@OZsB`zOyCpyRBI~+)ld*>}75)Cq(G31CEnR)I` zpI?zpW zFP54a9{KB@WWaY_DP`UbY*s7G*a?a8DJ_H=E6DZ&e+$k_U;YO2vpUQxz~5 zP)I0&OQcRlB#XF|0^}tPXeD6y&JFTeo4H=#L4dDS!UiCplgsmn^>JBKH`78(hyyq< z4W=fO`ktE#NnJ|Ox*~LZx6eCidM34qI6$T1Dq#USyzjW(Fjf7wW`)Xq>rWIB;38)e zIQZHD?8Ss2f$!Yx{{f^r2;~dDu{9G*6ZtQY+o!LP<5;vRj5Rv|4-J+_#PFH_lfotd z2eZjI{Il{u-n;E(tP&Tzfiw+vO^pWowA*QGW^TvEkY#66KdNvH^(H%yofm;`x1QjD zmI4fR+$C~aD`<2T-3LlK*MP^5qT3`K)$8E? z8H#hI8+x}o992W#TDsLMaXwJv_NznQg^Xb82pKP4H*@{NJ2lki0bjP?EVR^3;x zXJu1I%U8~-l8v>?Px=Iflr_q2r`46EX<+@@wa!2IF<~^(#?|w31WY#4_BrW0zAseN z^4=n9HJpC4rzLq#F3ti=|AdxbcEur2bg(Dzy5pIpNrQ?FmWa;u;SF1IEuo z?yC6xkb^HW?a%rsfCW-C-KPg$l@stzD5t?&NX$IhuEy?)D@g*;!^wW;e~_3wNv=_W zKl^aarpBi}@^rQ7W5xA0zh{J4yHg76Wgw^_N!3`*+a+s7tAnBKsuSbCJ3nlU(;yln zYF%Pi9S>LdQ2~V2yd+$DwACqd*>UouDD4y=RI~#fO%aiZ)y%fam|rtLS72Y`HQQv5 z6EF+s_bGY#nAl?|8Y{eyT#o6{XKsF+T(FVb<$_F$FVbP<!R(bEmQ~oQfAP15(iUL1`Jq71uv(=zi4OLtgv$>I6;Fai;@brW_W6!D YR<-7b)h;*S*&hvnzG#Q4GshAC27rIZfdBvi literal 0 HcmV?d00001 diff --git a/Resources/Textures/Interface/Paper/paper_background_black.svg.96dpi.png.yml b/Resources/Textures/Interface/Paper/paper_background_black.svg.96dpi.png.yml new file mode 100644 index 0000000000..5c43e23305 --- /dev/null +++ b/Resources/Textures/Interface/Paper/paper_background_black.svg.96dpi.png.yml @@ -0,0 +1,2 @@ +sample: + filter: true diff --git a/Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg b/Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg new file mode 100644 index 0000000000..e7ba27f8cd --- /dev/null +++ b/Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg.96dpi.png b/Resources/Textures/Interface/Paper/paper_heading_syndicate_logo.svg.96dpi.png new file mode 100644 index 0000000000000000000000000000000000000000..21e85b65d847ca69adbcae83e597317938040388 GIT binary patch literal 6658 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 Date: Tue, 1 Oct 2024 02:24:36 +0400 Subject: [PATCH 37/88] Add camera bug (#30250) * Add camera bug * Update camera_bug.png * fix * change * Update Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/camera_bug.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> * Update Resources/Prototypes/Catalog/uplink_catalog.yml --------- Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Locale/en-US/store/uplink-catalog.ftl | 3 +++ .../Prototypes/Catalog/uplink_catalog.yml | 10 +++++++ .../Devices/Syndicate_Gadgets/camera_bug.yml | 25 ++++++++++++++++++ .../Devices/camera_bug.rsi/camera_bug.png | Bin 0 -> 502 bytes .../Objects/Devices/camera_bug.rsi/meta.json | 14 ++++++++++ 5 files changed, 52 insertions(+) create mode 100644 Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/camera_bug.yml create mode 100644 Resources/Textures/Objects/Devices/camera_bug.rsi/camera_bug.png create mode 100644 Resources/Textures/Objects/Devices/camera_bug.rsi/meta.json diff --git a/Resources/Locale/en-US/store/uplink-catalog.ftl b/Resources/Locale/en-US/store/uplink-catalog.ftl index 806a008491..e0864de41b 100644 --- a/Resources/Locale/en-US/store/uplink-catalog.ftl +++ b/Resources/Locale/en-US/store/uplink-catalog.ftl @@ -443,6 +443,9 @@ uplink-barber-scissors-desc = A good tool to give your fellow agent a nice hairc uplink-backpack-syndicate-name = Syndicate backpack uplink-backpack-syndicate-desc = A lightweight explosion-proof backpack for holding various traitor goods +uplink-cameraBug-name = Camera bug +uplink-cameraBug-desc = A portable device that allows you to view the station's cameras. + uplink-combat-bakery-name = Combat Bakery Kit uplink-combat-bakery-desc = A kit of clandestine baked weapons. Contains a baguette sword, a pair of throwing croissants, and a syndicate microwave board for making more. Once the job is done, eat the evidence. diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 83c739e6c5..8d7f835603 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -1085,6 +1085,16 @@ categories: - UplinkDisruption +- type: listing + id: UplinkCameraBug + name: uplink-cameraBug-name + description: uplink-cameraBug-desc + productEntity: CameraBug + cost: + Telecrystal: 4 + categories: + - UplinkDisruption + # Allies - type: listing diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/camera_bug.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/camera_bug.yml new file mode 100644 index 0000000000..6e10d5274a --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/camera_bug.yml @@ -0,0 +1,25 @@ +- type: entity + id: CameraBug + parent: [ BaseItem, BaseSyndicateContraband ] + name: camera bug + description: An illegal syndicate device that allows you to hack into the station's camera network. + components: + - type: Sprite + sprite: Objects/Devices/camera_bug.rsi + layers: + - state: camera_bug + - type: Item + - type: ActivatableUI + requireActiveHand: false + inHandsOnly: true + key: enum.SurveillanceCameraMonitorUiKey.Key + - type: UserInterface + interfaces: + enum.SurveillanceCameraMonitorUiKey.Key: + type: SurveillanceCameraMonitorBoundUserInterface + - type: DeviceNetwork + deviceNetId: Wired + receiveFrequencyId: SurveillanceCamera + transmitFrequencyId: SurveillanceCamera + - type: WiredNetworkConnection + - type: SurveillanceCameraMonitor \ No newline at end of file diff --git a/Resources/Textures/Objects/Devices/camera_bug.rsi/camera_bug.png b/Resources/Textures/Objects/Devices/camera_bug.rsi/camera_bug.png new file mode 100644 index 0000000000000000000000000000000000000000..ba8255fc146d3892476395103840edf7361c461f GIT binary patch literal 502 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0gFjQK~z{r?UlVw z0znYR|8SrY%n~35ghDJJdWDdviLp1a^aU)e?d?oxd<1J-TdjNnI}5cq6B;ZeLJS%% zibgoj%(}qk;&CUzoW=f<&CJbCW@cwU4iYyG5i*7PCj^Cb9 z+kr$fEi|8y9q4y}q+2(<_}KB(0SZcTSuHwl3E64B?=Q@*xIaYAy3oF1@tMI&t%L02 z5D?N43Qns^rBbLpRf9$H;T}rrA}((qxKF?|xTHdIWfd_cgwtr8+lW!cjQtW)@(k-C8tU+Z ztWd$L8!O1GIbm_ewSbn<71|JLJJD(zc#<`QS1Z zQFtN5+0oA63|JYp1)dIyy$Jo~UCa!jTR_PhjRwCt6*i0Y<0Z6quO@p2C^-eR4|`Ds s{go%582$S$K7YiEk3=GoNd6hX7bc#c( Date: Mon, 30 Sep 2024 22:25:44 +0000 Subject: [PATCH 38/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a3cdbb4e53..dfa6f67546 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Lank - changes: - - message: Darts can now pop balloons. Keep them away from any monkeys. - type: Add - id: 6961 - time: '2024-07-22T05:38:56.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30088 - author: Plykiya changes: - message: You can now eat or drink and swap hands without it being interrupted. @@ -3936,3 +3929,11 @@ id: 7460 time: '2024-09-30T17:38:22.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32487 +- author: pofitlo-Git + changes: + - message: Added a camera bug in the syndicate uplink that cost 4 TC and allow you + watch all cameras on station. + type: Add + id: 7461 + time: '2024-09-30T22:24:37.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30250 From 5681db31a9d1214e453f848e8cceac47e846d600 Mon Sep 17 00:00:00 2001 From: kosticia Date: Tue, 1 Oct 2024 01:40:31 +0300 Subject: [PATCH 39/88] Changing the thief's objective to stealing ID cards. (#32411) * Changed thief ID objection * Update Resources/Prototypes/Objectives/thief.yml --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- Resources/Prototypes/Objectives/thief.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Objectives/thief.yml b/Resources/Prototypes/Objectives/thief.yml index 5798071f02..2dbb2cc339 100644 --- a/Resources/Prototypes/Objectives/thief.yml +++ b/Resources/Prototypes/Objectives/thief.yml @@ -118,7 +118,7 @@ - type: StealCondition stealGroup: IDCard minCollectionSize: 5 - maxCollectionSize: 15 + maxCollectionSize: 10 verifyMapExistence: false - type: Objective difficulty: 0.7 From edc110907ee159df7853da719b2188345ef30006 Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 30 Sep 2024 22:41:38 +0000 Subject: [PATCH 40/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index dfa6f67546..fcd23b07ef 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: You can now eat or drink and swap hands without it being interrupted. - type: Tweak - id: 6962 - time: '2024-07-22T09:17:57.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30060 - author: IProduceWidgets changes: - message: Zookeepers can now possess Nonlethal shotguns according to spacelaw. @@ -3937,3 +3930,11 @@ id: 7461 time: '2024-09-30T22:24:37.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30250 +- author: kosticia + changes: + - message: The maximum number of ID cards required to complete a thief's objective + has been changed from 15 to 10. + type: Tweak + id: 7462 + time: '2024-09-30T22:40:31.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32411 From 3b682d4d68c82b218a3727961241e519a91677f1 Mon Sep 17 00:00:00 2001 From: Golinth Date: Mon, 30 Sep 2024 22:13:16 -0500 Subject: [PATCH 41/88] Added Firebots - Real (#32482) * Add Firebots Had to add OnActivateInWorld to the spray system to get the bot to work. Checks for the flammable component and if the onFire boolean is true. * Make SpraySystem actually use useDelay got rid of that TODO * Added firebot speech Fire detected! --- .../Fluids/EntitySystems/SpraySystem.cs | 48 ++++++++++++------ .../Queries/Considerations/TargetOnFireCon.cs | 9 ++++ .../NPC/Systems/NPCUtilitySystem.cs | 7 +++ .../interaction-popup-component.ftl | 2 + Resources/Locale/en-US/npc/firebot.ftl | 1 + .../Entities/Clothing/Head/helmets.yml | 2 + .../Prototypes/Entities/Mobs/NPCs/silicon.yml | 47 +++++++++++++++++ .../Objects/Misc/fire_extinguisher.yml | 3 ++ Resources/Prototypes/NPCs/firebot.yml | 44 ++++++++++++++++ Resources/Prototypes/NPCs/utility_queries.yml | 21 ++++++++ .../Recipes/Crafting/Graphs/bots/firebot.yml | 33 ++++++++++++ .../Prototypes/Recipes/Crafting/bots.yml | 13 +++++ Resources/Prototypes/tags.yml | 6 +++ .../Mobs/Silicon/Bots/firebot.rsi/firebot.png | Bin 0 -> 4614 bytes .../Mobs/Silicon/Bots/firebot.rsi/meta.json | 20 ++++++++ 15 files changed, 241 insertions(+), 15 deletions(-) create mode 100644 Content.Server/NPC/Queries/Considerations/TargetOnFireCon.cs create mode 100644 Resources/Locale/en-US/npc/firebot.ftl create mode 100644 Resources/Prototypes/NPCs/firebot.yml create mode 100644 Resources/Prototypes/Recipes/Crafting/Graphs/bots/firebot.yml create mode 100644 Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/firebot.png create mode 100644 Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/meta.json diff --git a/Content.Server/Fluids/EntitySystems/SpraySystem.cs b/Content.Server/Fluids/EntitySystems/SpraySystem.cs index fe179be402..a1f195bf43 100644 --- a/Content.Server/Fluids/EntitySystems/SpraySystem.cs +++ b/Content.Server/Fluids/EntitySystems/SpraySystem.cs @@ -14,6 +14,7 @@ using Robust.Shared.Audio.Systems; using Robust.Shared.Physics.Components; using Robust.Shared.Prototypes; using System.Numerics; +using Robust.Shared.Map; namespace Content.Server.Fluids.EntitySystems; @@ -35,6 +36,19 @@ public sealed class SpraySystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnAfterInteract); + SubscribeLocalEvent(OnActivateInWorld); + } + + private void OnActivateInWorld(Entity entity, ref UserActivateInWorldEvent args) + { + if (args.Handled) + return; + + args.Handled = true; + + var targetMapPos = _transform.GetMapCoordinates(GetEntityQuery().GetComponent(args.Target)); + + Spray(entity, args.User, targetMapPos); } private void OnAfterInteract(Entity entity, ref AfterInteractEvent args) @@ -44,29 +58,36 @@ public sealed class SpraySystem : EntitySystem args.Handled = true; + var clickPos = _transform.ToMapCoordinates(args.ClickLocation); + + Spray(entity, args.User, clickPos); + } + + public void Spray(Entity entity, EntityUid user, MapCoordinates mapcoord) + { if (!_solutionContainer.TryGetSolution(entity.Owner, SprayComponent.SolutionName, out var soln, out var solution)) return; - var ev = new SprayAttemptEvent(args.User); + var ev = new SprayAttemptEvent(user); RaiseLocalEvent(entity, ref ev); if (ev.Cancelled) return; - if (!TryComp(entity, out var useDelay) - || _useDelay.IsDelayed((entity, useDelay))) + if (TryComp(entity, out var useDelay) + && _useDelay.IsDelayed((entity, useDelay))) return; if (solution.Volume <= 0) { - _popupSystem.PopupEntity(Loc.GetString("spray-component-is-empty-message"), entity.Owner, args.User); + _popupSystem.PopupEntity(Loc.GetString("spray-component-is-empty-message"), entity.Owner, user); return; } var xformQuery = GetEntityQuery(); - var userXform = xformQuery.GetComponent(args.User); + var userXform = xformQuery.GetComponent(user); var userMapPos = _transform.GetMapCoordinates(userXform); - var clickMapPos = args.ClickLocation.ToMap(EntityManager, _transform); + var clickMapPos = mapcoord; var diffPos = clickMapPos.Position - userMapPos.Position; if (diffPos == Vector2.Zero || diffPos == Vector2Helpers.NaN) @@ -88,8 +109,6 @@ public sealed class SpraySystem : EntitySystem var amount = Math.Max(Math.Min((solution.Volume / entity.Comp.TransferAmount).Int(), entity.Comp.VaporAmount), 1); var spread = entity.Comp.VaporSpread / amount; - // TODO: Just use usedelay homie. - var cooldownTime = 0f; for (var i = 0; i < amount; i++) { @@ -131,20 +150,19 @@ public sealed class SpraySystem : EntitySystem // impulse direction is defined in world-coordinates, not local coordinates var impulseDirection = rotation.ToVec(); var time = diffLength / entity.Comp.SprayVelocity; - cooldownTime = MathF.Max(time, cooldownTime); - _vapor.Start(ent, vaporXform, impulseDirection * diffLength, entity.Comp.SprayVelocity, target, time, args.User); + _vapor.Start(ent, vaporXform, impulseDirection * diffLength, entity.Comp.SprayVelocity, target, time, user); - if (TryComp(args.User, out var body)) + if (TryComp(user, out var body)) { - if (_gravity.IsWeightless(args.User, body)) - _physics.ApplyLinearImpulse(args.User, -impulseDirection.Normalized() * entity.Comp.PushbackAmount, body: body); + if (_gravity.IsWeightless(user, body)) + _physics.ApplyLinearImpulse(user, -impulseDirection.Normalized() * entity.Comp.PushbackAmount, body: body); } } _audio.PlayPvs(entity.Comp.SpraySound, entity, entity.Comp.SpraySound.Params.WithVariation(0.125f)); - _useDelay.SetLength(entity.Owner, TimeSpan.FromSeconds(cooldownTime)); - _useDelay.TryResetDelay((entity, useDelay)); + if (useDelay != null) + _useDelay.TryResetDelay((entity, useDelay)); } } diff --git a/Content.Server/NPC/Queries/Considerations/TargetOnFireCon.cs b/Content.Server/NPC/Queries/Considerations/TargetOnFireCon.cs new file mode 100644 index 0000000000..d86dbc06ec --- /dev/null +++ b/Content.Server/NPC/Queries/Considerations/TargetOnFireCon.cs @@ -0,0 +1,9 @@ +namespace Content.Server.NPC.Queries.Considerations; + +/// +/// Returns 1f if the target is on fire or 0f if not. +/// +public sealed partial class TargetOnFireCon : UtilityConsideration +{ + +} diff --git a/Content.Server/NPC/Systems/NPCUtilitySystem.cs b/Content.Server/NPC/Systems/NPCUtilitySystem.cs index 8dff93648b..60bc5cdfd8 100644 --- a/Content.Server/NPC/Systems/NPCUtilitySystem.cs +++ b/Content.Server/NPC/Systems/NPCUtilitySystem.cs @@ -1,3 +1,4 @@ +using Content.Server.Atmos.Components; using Content.Server.Fluids.EntitySystems; using Content.Server.NPC.Queries; using Content.Server.NPC.Queries.Considerations; @@ -351,6 +352,12 @@ public sealed class NPCUtilitySystem : EntitySystem return 0f; } + case TargetOnFireCon: + { + if (TryComp(targetUid, out FlammableComponent? fire) && fire.OnFire) + return 1f; + return 0f; + } default: throw new NotImplementedException(); } diff --git a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl index 10773d6de8..a180b698fa 100644 --- a/Resources/Locale/en-US/interaction/interaction-popup-component.ftl +++ b/Resources/Locale/en-US/interaction/interaction-popup-component.ftl @@ -60,6 +60,7 @@ petting-success-honkbot = You pet {THE($target)} on {POSS-ADJ($target)} slippery petting-success-mimebot = You pet {THE($target)} on {POSS-ADJ($target)} cold metal head. petting-success-cleanbot = You pet {THE($target)} on {POSS-ADJ($target)} damp metal head. petting-success-medibot = You pet {THE($target)} on {POSS-ADJ($target)} sterile metal head. +petting-success-firebot = You pet {THE($target)} on {POSS-ADJ($target)} warm metal head. petting-success-generic-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} metal head. petting-success-salvage-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} dirty metal head. petting-success-engineer-cyborg = You pet {THE($target)} on {POSS-ADJ($target)} reflective metal head. @@ -73,6 +74,7 @@ petting-failure-honkbot = You reach out to pet {THE($target)}, but {SUBJECT($tar petting-failure-cleanbot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy mopping! petting-failure-mimebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy miming! petting-failure-medibot = You reach out to pet {THE($target)}, but {POSS-ADJ($target)} syringe nearly stabs your hand! +petting-failure-firebot = You reach out to pet {THE($target)}, but {SUBJECT($target)} sprays you in the face before you can get close! petting-failure-generic-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy stating laws! petting-failure-salvage-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy drilling! petting-failure-engineer-cyborg = You reach out to pet {THE($target)}, but {SUBJECT($target)} {CONJUGATE-BE($target)} busy repairing! diff --git a/Resources/Locale/en-US/npc/firebot.ftl b/Resources/Locale/en-US/npc/firebot.ftl new file mode 100644 index 0000000000..758874ceaa --- /dev/null +++ b/Resources/Locale/en-US/npc/firebot.ftl @@ -0,0 +1 @@ +firebot-fire-detected = Fire detected! diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml index 625ef7a056..11643c076d 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml @@ -249,6 +249,7 @@ - type: Tag tags: - WhitelistChameleon + - FireHelmet - type: HideLayerClothing slots: - Hair @@ -281,6 +282,7 @@ - type: Tag tags: - WhitelistChameleon + - FireHelmet - type: HideLayerClothing slots: - Hair diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index d5b4366e2b..7d988c6fe9 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -108,6 +108,53 @@ - type: NoSlip - type: Insulated +- type: entity + parent: MobSiliconBase + id: MobFireBot + name: firebot + description: A little fire extinguishing bot. He looks rather anxious. + components: + - type: Sprite + sprite: Mobs/Silicon/Bots/firebot.rsi + state: firebot + - type: Construction + graph: FireBot + node: bot + - type: SentienceTarget + flavorKind: station-event-random-sentience-flavor-mechanical + - type: HTN + rootTask: + task: FirebotCompound + - type: SolutionContainerManager + solutions: + spray: + maxVol: 10 + reagents: + - ReagentId: Water + Quantity: 10 + - type: SolutionRegeneration + solution: spray + generated: + reagents: + - ReagentId: Water + Quantity: 10 + - type: Spray + transferAmount: 10 + pushbackAmount: 60 + spraySound: + path: /Audio/Effects/extinguish.ogg + sprayedPrototype: ExtinguisherSpray + vaporAmount: 1 + vaporSpread: 90 + sprayVelocity: 3.0 + - type: UseDelay + delay: 4 + - type: InteractionPopup + interactSuccessString: petting-success-firebot + interactFailureString: petting-failure-firebot + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg + - type: entity parent: MobSiliconBase id: MobHonkBot diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index 0389db27ea..b306da6442 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -62,6 +62,9 @@ - Rolling speedModifier: 0.5 # its very big, awkward to use - type: Appearance + - type: Tag + tags: + - FireExtinguisher - type: GenericVisualizer visuals: enum.ToggleVisuals.Toggled: diff --git a/Resources/Prototypes/NPCs/firebot.yml b/Resources/Prototypes/NPCs/firebot.yml new file mode 100644 index 0000000000..acea6498bd --- /dev/null +++ b/Resources/Prototypes/NPCs/firebot.yml @@ -0,0 +1,44 @@ +- type: htnCompound + id: FirebotCompound + branches: + - tasks: + - !type:HTNCompoundTask + task: DouseFireTargetCompound + - tasks: + - !type:HTNCompoundTask + task: IdleCompound + +- type: htnCompound + id: DouseFireTargetCompound + branches: + - tasks: + - !type:HTNPrimitiveTask + operator: !type:UtilityOperator + proto: NearbyOnFire + + - !type:HTNPrimitiveTask + operator: !type:SpeakOperator + speech: firebot-fire-detected + hidden: true + + - !type:HTNPrimitiveTask + operator: !type:MoveToOperator + pathfindInPlanning: true + removeKeyOnFinish: false + targetKey: TargetCoordinates + pathfindKey: TargetPathfind + rangeKey: InteractRange + + - !type:HTNPrimitiveTask + preconditions: + - !type:TargetInRangePrecondition + targetKey: Target + rangeKey: InteractRange + operator: !type:InteractWithOperator + targetKey: Target + services: + - !type:UtilityService + id: FireService + proto: NearbyOnFire + key: Target + diff --git a/Resources/Prototypes/NPCs/utility_queries.yml b/Resources/Prototypes/NPCs/utility_queries.yml index 06bc0a9a9e..e10a0ed30c 100644 --- a/Resources/Prototypes/NPCs/utility_queries.yml +++ b/Resources/Prototypes/NPCs/utility_queries.yml @@ -144,6 +144,27 @@ - !type:TargetAccessibleCon curve: !type:BoolCurve +- type: utilityQuery + id: NearbyOnFire + query: + - !type:ComponentQuery + components: + - type: Flammable + # why does Flammable even have a required damage + damage: + types: + burn: 0 + considerations: + - !type:TargetDistanceCon + curve: !type:PresetCurve + preset: TargetDistance + - !type:TargetAccessibleCon + curve: !type:BoolCurve + - !type:TargetInLOSOrCurrentCon + curve: !type:BoolCurve + - !type:TargetOnFireCon + curve: !type:BoolCurve + - type: utilityQuery id: NearbyPuddles query: diff --git a/Resources/Prototypes/Recipes/Crafting/Graphs/bots/firebot.yml b/Resources/Prototypes/Recipes/Crafting/Graphs/bots/firebot.yml new file mode 100644 index 0000000000..977ffd4093 --- /dev/null +++ b/Resources/Prototypes/Recipes/Crafting/Graphs/bots/firebot.yml @@ -0,0 +1,33 @@ +- type: constructionGraph + id: FireBot + start: start + graph: + - node: start + edges: + - to: bot + steps: + - tag: FireExtinguisher + icon: + sprite: Objects/Misc/fire_extinguisher.rsi + state: fire_extinguisher_open + name: fire extinguisher + - tag: FireHelmet + icon: + sprite: Clothing/Head/Helmets/firehelmet.rsi + state: icon + name: fire helmet + doAfter: 2 + - tag: ProximitySensor + icon: + sprite: Objects/Misc/proximity_sensor.rsi + state: icon + name: proximity sensor + doAfter: 2 + - tag: BorgArm + icon: + sprite: Mobs/Silicon/drone.rsi + state: l_hand + name: borg arm + doAfter: 2 + - node: bot + entity: MobFireBot diff --git a/Resources/Prototypes/Recipes/Crafting/bots.yml b/Resources/Prototypes/Recipes/Crafting/bots.yml index 3031f4a780..21b524a060 100644 --- a/Resources/Prototypes/Recipes/Crafting/bots.yml +++ b/Resources/Prototypes/Recipes/Crafting/bots.yml @@ -11,6 +11,19 @@ sprite: Mobs/Silicon/Bots/cleanbot.rsi state: cleanbot +- type: construction + name: firebot + id: firebot + graph: FireBot + startNode: start + targetNode: bot + category: construction-category-utilities + objectType: Item + description: This bot puts out fires wherever it goes. + icon: + sprite: Mobs/Silicon/Bots/firebot.rsi + state: firebot + - type: construction name: honkbot id: honkbot diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 2a07d061d3..86ade97d4e 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -617,6 +617,12 @@ - type: Tag id: FirelockElectronics +- type: Tag + id: FireExtinguisher + +- type: Tag + id: FireHelmet + - type: Tag id: Flare diff --git a/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/firebot.png b/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/firebot.png new file mode 100644 index 0000000000000000000000000000000000000000..70ee9313d2d62bc1847b1bc663f2205e85a9685e GIT binary patch literal 4614 zcmeHKdsGu=7N39u;pQeTtDFd<}2d?f*531%S`bg?p-nS@#Lo`D2WQPgUE zAU?3&F1Avu7Q3aQt754Yg!)3aYCYBZ#8yO)>uT|VT8jH6AmZ7cv&VC`|B-VhGjkum z@7~|N_dD~wr%O!=2^AAb5eH7j`hU6Z&BhVe-~Z}+W!Q$g$g#-L%h3<+iZe6Fh-rx})`R)4 zZqF-iqp4M**kM24HtJ6V>|C7fXPMWuZD!l!pg*@~tk1i+=|onms#ALQ`0d+k=E0{2 zHXmJ3#S@j_m|xkrWpjs=4)LeZQp+I0wJRTm)<`EnGtS+~ue%6Ayv2-CsnaNx&r$-3 zl+RnENN$)E_3iBREi=c2PS-h(=r;cA6Mo5-BHix)+& zc-w!lY1Zpm{U_h`ZTzubb4oq6V|H53z@O_K6E9yXytvPX@sO zzTZ2iRuIAb1)CaE6n~v@f5Wu@Qxtt)}G(ynJ=6OuX`Gt#aN1V^N!D7 z`;IMl&G1b{ku^2e+_pFD`+S2HH`m6<)_%NIH_qpd>AtogyZN<%s;~C%e&~1tQI(%> ziEM5T8zTJE!w(PF7UG4!wx@i4Alf;?xpmp_S))MfAlcaq#RB3;D3ugv(X%GqpNcX>-yrCcp$DMD1qsQT~KLSni~Z zc$zA)8v?v3_&FSB$AvX=Q+*ZbSP3tn`sL$Wx=ZA7nV%YXmvdv9tup1 z#qRY2WWQj^F~;X)y%3v6<4vb`Ai%u`_XX=`xqFR)l~#+ZY-FA%JdH}h_pFaoHj<%m z@1w+sQVAl8LQqmfBbbCXAO;epkOT~);v_UiU^289l*Y<(gq5T{Pyk%O030-d#v~$= zMo82^A{a%A5E&ImBQgR*MW~U&&;+s<#55-Zx{@&Wj>-c?0Vu*iNMvG6h8W^8DS{C) z0+C^2BSJ_}EP<4u2C+fxg`!A2(dM)epqz|_FwsK0)#O!p2*)SuGzvZ{5IvXZ%mily z4qyftD`j)B&sBQHLZ@?thflE-m7+44NFo)*qhg8VxzTjm$%0<=po&F;ILxc@6b1+B z0BQ+Orvd=49AtwloixGOoO+whtl)csf<2x+YAqNjir@$p!O;LzgkrczhNBX_I35>E z@i-|WlHj6V_BM(!7W^-3&-lRduA(P1ELgw5E9#o5blTDN*7a&;yu$>;-m$<5vMU9a z$fqf9oB*p!MdlDz6Aku{?uLCPXMU#{#4@ANh)LrRi3E!W6^us_Z+j(>vN)8EC*!49 z7fC(ntj)-|2q!(+1b75ofd=(*1&``3)#w+aaplmSIsnQLkqqfY8DH3)tkAP#Jj+%t z{4YM_UV~m+4DjocfvpSdgumT{+uEQU>1Pu2r@>2Zv(bY%SOEK_L#(mw@ zN7qX+@KVNo-SvN?EAaVYinf9;AQw0)Wsi(q0*+aJhPRSb-UAo(SXo;Ho?fvh&tM@a zw9#|%%EpF90--;r(W?D#yfXCFfg>Z@uC#))bd^RmS)X(Hc4qZdU-6L6wfBaq>@LR* z4LtZRul)QzWyRkX<(@4r;5pdAc*5Rw19Zz;it`@ykI0Z-9k%pgRYv8vjUO$&|Fpzj zn$=d+KJqc!&g*xuYSEJXh$%H#b<;xY!9zcN^ZGx2NDa6OK}jaHW3as}{N&8qrag(f zek{+BUlB(7YIcP6Pux84Sli&gj0r`@AgJo-%ea*mps7TFza1?}jjF zfwejR`h@y>uRUGCjUGKKvhzae(y;N@ zqkhAdOubf~!#_1GJ*rb3dpu@n!^!jf8p>Ro3t!27dNLceg`HCt#na ztLu(thn?B8`_95Qn!gFUf9|F`I~nbmF8= c=&I{czc!!93dg%_s;AZ(b*idrN_O#o0LjaybN~PV literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/meta.json b/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/meta.json new file mode 100644 index 0000000000..e13b42deee --- /dev/null +++ b/Resources/Textures/Mobs/Silicon/Bots/firebot.rsi/meta.json @@ -0,0 +1,20 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation/commit/eba0d62005e7754dd8b1c88e45cd949c360774d5", + "states": [ + { + "name": "firebot", + "delays": [ + [ + 0.5, + 0.2 + ] + ] + } + ] +} From a73780bc57e2409862cfe5dc7862c877fd169b10 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 1 Oct 2024 03:14:22 +0000 Subject: [PATCH 42/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index fcd23b07ef..20c02f6d81 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: IProduceWidgets - changes: - - message: Zookeepers can now possess Nonlethal shotguns according to spacelaw. - type: Tweak - id: 6963 - time: '2024-07-22T09:33:03.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30237 - author: Plykiya changes: - message: Bag sounds can now only be heard from half the distance and is quieter @@ -3938,3 +3931,11 @@ id: 7462 time: '2024-09-30T22:40:31.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32411 +- author: Golinth + changes: + - message: Firebots can now be constructed by scientists - the bots wander the station + looking for fires to put out with their built-in extinguisher. + type: Add + id: 7463 + time: '2024-10-01T03:13:16.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32482 From ba68fb2ddbbda039b2072e905abd6ce4ea62d58a Mon Sep 17 00:00:00 2001 From: ScarKy0 <106310278+ScarKy0@users.noreply.github.com> Date: Tue, 1 Oct 2024 06:03:37 +0200 Subject: [PATCH 43/88] Update binary key to use AI icon (#32327) * Init * uplink icon --- Resources/Prototypes/Catalog/uplink_catalog.yml | 2 +- .../Entities/Objects/Devices/encryption_keys.yml | 4 ++-- .../Devices/encryption_keys.rsi/ai_label.png | Bin 0 -> 5737 bytes .../Devices/encryption_keys.rsi/meta.json | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 Resources/Textures/Objects/Devices/encryption_keys.rsi/ai_label.png diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 8d7f835603..a91aab53c8 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -773,7 +773,7 @@ id: UplinkBinaryTranslatorKey name: uplink-binary-translator-key-name description: uplink-binary-translator-key-desc - icon: { sprite: /Textures/Objects/Devices/encryption_keys.rsi, state: borg_label } + icon: { sprite: /Textures/Objects/Devices/encryption_keys.rsi, state: ai_label } productEntity: EncryptionKeyBinarySyndicate cost: Telecrystal: 1 diff --git a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml index 25d81a6f83..7393532654 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml @@ -227,7 +227,7 @@ - type: Sprite layers: - state: crypt_silver - - state: borg_label + - state: ai_label - type: entity parent: [ EncryptionKey, BaseSyndicateContraband ] @@ -242,7 +242,7 @@ - type: Sprite layers: - state: crypt_red - - state: borg_label + - state: ai_label - type: entity parent: EncryptionKey diff --git a/Resources/Textures/Objects/Devices/encryption_keys.rsi/ai_label.png b/Resources/Textures/Objects/Devices/encryption_keys.rsi/ai_label.png new file mode 100644 index 0000000000000000000000000000000000000000..02409127a3fdaf41b992c5fc769d6402031b1de7 GIT binary patch literal 5737 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 Duz8jW literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Devices/encryption_keys.rsi/meta.json b/Resources/Textures/Objects/Devices/encryption_keys.rsi/meta.json index 6ae7bca9dd..a6222e988f 100644 --- a/Resources/Textures/Objects/Devices/encryption_keys.rsi/meta.json +++ b/Resources/Textures/Objects/Devices/encryption_keys.rsi/meta.json @@ -35,6 +35,7 @@ {"name": "sec_label"}, {"name": "service_label"}, {"name": "synd_label"}, - {"name": "borg_label"} + {"name": "borg_label"}, + {"name": "ai_label"} ] } From 6a1815aeafbd4996abca1e4f6ade614f24bb53c3 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 1 Oct 2024 04:04:43 +0000 Subject: [PATCH 44/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 20c02f6d81..04f65e3367 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: Bag sounds can now only be heard from half the distance and is quieter - in general. - type: Tweak - id: 6964 - time: '2024-07-22T09:54:15.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30225 - author: osjarw changes: - message: Syringes are now 0.5 seconds faster. @@ -3939,3 +3931,10 @@ id: 7463 time: '2024-10-01T03:13:16.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32482 +- author: ScarKy0 + changes: + - message: Binary encryption key now uses an AI icon + type: Tweak + id: 7464 + time: '2024-10-01T04:03:37.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32327 From f79de12509002743dcae02984b99d60656f32025 Mon Sep 17 00:00:00 2001 From: BramvanZijp <56019239+BramvanZijp@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:13:59 +0200 Subject: [PATCH 45/88] Prevent borgs from being able to be briefly toggled off. (#32485) * Prevent borgs from being able to be briefly toggled off. * Use the pre-existing component instead of making an unneccesary duplicate. --- Content.Shared/Item/ItemToggle/ItemToggleSystem.cs | 2 +- .../Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs b/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs index 98029f97d5..d5bbaac12c 100644 --- a/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs +++ b/Content.Shared/Item/ItemToggle/ItemToggleSystem.cs @@ -71,7 +71,7 @@ public sealed class ItemToggleSystem : EntitySystem private void OnActivateVerb(Entity ent, ref GetVerbsEvent args) { - if (!args.CanAccess || !args.CanInteract) + if (!args.CanAccess || !args.CanInteract || !ent.Comp.OnActivate) return; var user = args.User; diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 955ddfd2e3..54bd58af78 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -121,6 +121,7 @@ cellSlotId: cell_slot fitsInCharger: true - type: ItemToggle + onActivate: false # You should not be able to turn off a borg temporarily. activated: false # gets activated when a mind is added onUse: false # no item-borg toggling sorry - type: ItemTogglePointLight From d82c666e8030ee117f1e3740094410d462c4ba7d Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 1 Oct 2024 15:15:06 +0000 Subject: [PATCH 46/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 04f65e3367..625ed1613b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: osjarw - changes: - - message: Syringes are now 0.5 seconds faster. - type: Tweak - id: 6965 - time: '2024-07-22T10:20:36.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29825 - author: Errant changes: - message: Replay observers now always spawn on the station. @@ -3938,3 +3931,10 @@ id: 7464 time: '2024-10-01T04:03:37.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32327 +- author: BramvanZijp + changes: + - message: Fixed borgs being able to be briefly disabled by others. + type: Fix + id: 7465 + time: '2024-10-01T15:13:59.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32485 From 23f4bc1d7a39b1e4d3e441c587449604314dcd90 Mon Sep 17 00:00:00 2001 From: TakoDragon <69509841+BackeTako@users.noreply.github.com> Date: Tue, 1 Oct 2024 23:07:48 +0200 Subject: [PATCH 47/88] Gay Boykissers (#32584) --- .../Prototypes/Entities/Clothing/Neck/pins.yml | 16 ++++++++++++++++ .../Markers/Spawners/Random/maintenance.yml | 1 + .../Loadouts/Miscellaneous/trinkets.yml | 6 ++++++ .../Prototypes/Loadouts/loadout_groups.yml | 1 + .../Neck/Misc/pins.rsi/gay-equipped.png | Bin 0 -> 179 bytes .../Clothing/Neck/Misc/pins.rsi/gay.png | Bin 0 -> 317 bytes .../Clothing/Neck/Misc/pins.rsi/meta.json | 9 ++++++++- 7 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay-equipped.png create mode 100644 Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay.png diff --git a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml index eb948d299c..9f0ff79b20 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml @@ -72,6 +72,22 @@ neck: - state: bi-equipped +- type: entity + parent: ClothingNeckPinBase + id: ClothingNeckGayPin + name: gay pin + description: Be gay~ do crime. + components: + - type: Sprite + sprite: Clothing/Neck/Misc/pins.rsi + layers: + - state: gay + - type: Clothing + sprite: Clothing/Neck/Misc/pins.rsi + clothingVisuals: + neck: + - state: gay-equipped + - type: entity parent: ClothingNeckPinBase id: ClothingNeckIntersexPin diff --git a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml index 0aaaaf99b5..3f735cf98b 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/Random/maintenance.yml @@ -144,6 +144,7 @@ - id: ClothingNeckAromanticPin - id: ClothingNeckAsexualPin - id: ClothingNeckBisexualPin + - id: ClothingNeckGayPin - id: ClothingNeckIntersexPin - id: ClothingNeckLesbianPin - id: ClothingNeckNonBinaryPin diff --git a/Resources/Prototypes/Loadouts/Miscellaneous/trinkets.yml b/Resources/Prototypes/Loadouts/Miscellaneous/trinkets.yml index c91108124f..ea70828ce4 100644 --- a/Resources/Prototypes/Loadouts/Miscellaneous/trinkets.yml +++ b/Resources/Prototypes/Loadouts/Miscellaneous/trinkets.yml @@ -95,6 +95,12 @@ back: - ClothingNeckBisexualPin +- type: loadout + id: ClothingNeckGayPin + storage: + back: + - ClothingNeckGayPin + - type: loadout id: ClothingNeckIntersexPin storage: diff --git a/Resources/Prototypes/Loadouts/loadout_groups.yml b/Resources/Prototypes/Loadouts/loadout_groups.yml index 9bf0b4eb3d..1483fc3c11 100644 --- a/Resources/Prototypes/Loadouts/loadout_groups.yml +++ b/Resources/Prototypes/Loadouts/loadout_groups.yml @@ -18,6 +18,7 @@ - ClothingNeckAromanticPin - ClothingNeckAsexualPin - ClothingNeckBisexualPin + - ClothingNeckGayPin - ClothingNeckIntersexPin - ClothingNeckLesbianPin - ClothingNeckNonBinaryPin diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay-equipped.png new file mode 100644 index 0000000000000000000000000000000000000000..d5127a021865ca0397b1ccd2e2d78f5ae13e4e4f GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D$|ay?xfLn`LH zJ?F@K$U(s2qUQ}}zJkDWA>O_gXiu*J%1KD=Rc^J z{VrEVE?36y_UEl{48H~&ZCAP5bJXzv#Gm$6(QmdKI;Vst0GWGr A;s5{u literal 0 HcmV?d00001 diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json index 46b0496399..aab069b547 100644 --- a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json +++ b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "PixelTK leaves his mark on upstream", + "copyright": "PixelTK leaves his mark on upstream, BackeTako made the gay", "size": { "x": 32, "y": 32 @@ -28,6 +28,13 @@ "name": "bi-equipped", "directions": 4 }, + { + "name": "gay" + }, + { + "name": "gay-equipped", + "directions": 4 + }, { "name": "inter" }, From bfb2f60090ac4b13d5726a818f782add040b9a9b Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 1 Oct 2024 21:08:56 +0000 Subject: [PATCH 48/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 625ed1613b..880e212c69 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Errant - changes: - - message: Replay observers now always spawn on the station. - type: Fix - id: 6966 - time: '2024-07-22T19:32:30.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30252 - author: Cojoke-dot changes: - message: You can now read the volume of a gas tank in its examine text @@ -3938,3 +3931,10 @@ id: 7465 time: '2024-10-01T15:13:59.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32485 +- author: BackeTako + changes: + - message: Gay Pin + type: Add + id: 7466 + time: '2024-10-01T21:07:48.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32584 From f3fe5af240d9053f5ea89ba220218bfa4a02723c Mon Sep 17 00:00:00 2001 From: TakoDragon <69509841+BackeTako@users.noreply.github.com> Date: Tue, 1 Oct 2024 23:44:47 +0200 Subject: [PATCH 49/88] Reinforced walls sprite see throu top (#32578) fixed a gap --- .../Walls/solid.rsi/reinf_over0.png | Bin 1233 -> 1226 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Resources/Textures/Structures/Walls/solid.rsi/reinf_over0.png b/Resources/Textures/Structures/Walls/solid.rsi/reinf_over0.png index eb81655efaaeefce2c7b75a0276b9ce2ba9b2d9b..338d7c8de01ea0e35fdfca6ad52e486fc24470df 100644 GIT binary patch delta 1193 zcmV;a1Xlae3CanOF@J0G{Uoz`HVl?d3%vfg1t9 z<8%6@41YK|K1NNJ;W*Cc%79+4hkn1Gi46G+a9tO=VPH0!acgN&QOHvuU#-<;87to} zVkk07vl%K1WCB>4=VMv$Hv_0&z!tcCEDN|Sf~;mgIX(vPxajRd6h%CS;|ekXf$t*> zLj=B$nk>V0UBq!#?TX_VO-;j{=i%=5HtGI~0DtlnxPMyo?$>MFI1ZvHLLA4L13+@~ z-EJ3mx3|<`xq(c;a=FBLr-S8ki65t@h@$AlBQ1W20`e4KH9d>(5jg<}Q3V1V2w*po zk7dD^uLH;#kk{+K+!V;`^|RUR)$^GLK$P7ec?zWU`d`=AFKYXeBxO7RqJW$MX}w<8 zb$=`ti>*QkKq7Y!hr?H0Ao~WrCz#Uf1K&rh)k3gi@6Y-HO|F{mwwN{bb%Yk!H?6^qzEd#G-jG6fPY72Xfm0+sSIh&=I2s|Ow&xX!Odp#^|Zkt z2r>fcm(vFGC|d>yVUkLFgx+$9n5LPTc2`$d#y06^j$Xs9Z@)hhGZ%J*?}bd>QUe5!w%N_z+HJa5Zm5JeIG8;>)71RfBE zfV6kuC4T|)A*3S}LQH}8imGWJ0wS+|f)E4%?^la?`w;#B@P^AWjAd0s00000NkvXX Hu0mjfE}|=u delta 1200 zcmV;h1W)_Q3DF6VF@K9mL_t(|ob8)YZ=y;R$N$o+*aZ>NT;fYh%yvmyeQo>_ee6f= zmoUESeeiZ;s6G%AV~bFwo4|c&hXUHx=8WFK-CsgZRB+_<%y8zMe@pnExw^WFDcARU zy%Od6zbF^;#ImeU&v6_FmStru6(Jm8Sr#Uf2^OA*nx=ht-hXg7gl*f2?e%)3u_e;g z99eiC+U+(Lo(D;iHXi>B1~3dGW2p$^fSRVE-|wTY>!@oQN~KcfkR%B|Y#ZN>j{zXD zRD_rUjJmD^02aOvtyar?rl=|c--n{AkYzcsRD_8Dh9tfHq*WLu2Y_VJ3twL|OB#>- z4SS+eE~6w#Yk!tXVH~h43gdw4>!O#pRD@at8I48*0ALsf0Dd>S2~rx#1C|O~mW7{p zcQ~^wJcl9f$K$ngo6ROhqfzF)!C+AQRG4LWhGF12456qhE-o%mDVG7fML@UPMYURm zmdX|f#AHYa2RM!c+qRR;PL^eaVYqRX*E9`^qCim;E`MVS;Q$r^f14)09UntcRRGu+ z0RW&V3W6ZuGPV#7_(}xuhP((~Uthv@w8lG zKA*$3Z8(lY-p^AZM?gLtS(xUjl*>u#df94m*~{~Q?11TX3IOmt4*<4`0JfJG!3o?P z0K7b>-+zmMv(r;lWEqa*999H$IvsSo-Hc`ABfxcC=!SvGWWueaMP(;Xfqb@Bm1Qh^ ze-}fMDa>YQSCAdR!aQ$_!k-ABegRwH^0p{&Sp-?mes+2a;APR92~%I zByayv5Xi-do12?B-?!fe7Ab`I|8tne+x% ztJUw<8w`RV(;)rrdV_h276C$tq|zFp&lDo2X=bL~?d@&xMN(f?h_GqL10fvn6^#(n zAsnnm=!b11@O?Orvlam?&seQi+{PBd0hVQ9JRUk4@55dH%*p3g1U22tAp O0000 Date: Tue, 1 Oct 2024 21:45:55 +0000 Subject: [PATCH 50/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 880e212c69..640bb92ba1 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: You can now read the volume of a gas tank in its examine text - type: Tweak - id: 6967 - time: '2024-07-22T21:41:42.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29771 - author: Cojoke-dot changes: - message: Throwing a jetpack mid-flight will no longer freeze your character @@ -3938,3 +3931,10 @@ id: 7466 time: '2024-10-01T21:07:48.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32584 +- author: BackeTako + changes: + - message: Reinforced walls sprite see throu top + type: Fix + id: 7467 + time: '2024-10-01T21:44:47.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32578 From ec8b7b238a129e106f622704f77cf44a86843099 Mon Sep 17 00:00:00 2001 From: Zylofan <80375291+Zylofan@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:55:56 -0400 Subject: [PATCH 51/88] fixed it so blue bandana head and mask sprite is not reversed on vox (#32569) --- .../Bandanas/blue.rsi/equipped-HELMET-vox.png | Bin 578 -> 552 bytes .../Bandanas/blue.rsi/equipped-MASK-vox.png | Bin 552 -> 578 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Resources/Textures/Clothing/Head/Bandanas/blue.rsi/equipped-HELMET-vox.png b/Resources/Textures/Clothing/Head/Bandanas/blue.rsi/equipped-HELMET-vox.png index 726643237272c5e94fdb3654f409910742f35833..6bc5266367f4bfd767d5360aaa3a51198603d8fb 100644 GIT binary patch delta 505 zcmX@avVvuTW&JHr7srr_Id5kj^g8Sy&{n_Db?plFg>l8g{Bbq1^AD+i)U1)!mpc-@ zUd(2N#8fe@`omKsbV|)||?~$d~(woztRz_nx>5-+sSNdHePF z?%C&5Hk^1onfpw7ensWJ_<6~8B8NU33N^9hL}mFfNIqbGaOwHw|2p%h{nu1zQ(&C^ z=GhIVnol~@TBZNwYb#BOt7X-gaeK|aKW|Tn3U2;erP^?%+vnq>w{sZ|$L+|C-?LXV z!FBuJS6{*$w1BQHWE42g>QFBu4t6_)hr*c?#&ly!#=O@>VF#Wu%}UAdiFo+tboBgr z8**(W#8$sv8TIsQ#nq4LXUsk>Vu@Jriz^}MPvrG!+KR64`@U~@_Pi!+U7JxvMXAol zsn;aBp9?24P2=#iRk$c}<4)O`g}(I$Q4UvU$rUX=-8tcY#<9&Sr$#JtOSz`HnRf>B z_D*#qGvC6gM}W$qa6$# hkC_zu&^e!&_A&bE{4Ln;ZB@zu1fH&bF6*2UngC1q=STnm delta 532 zcmZ3%a)@PuW&IaV7srr_Id5m}_de_(a(w^N&TAQ^0&5mOP*8F$DEw$&_(i{lKb>@EufN{QgWaspIv5PxSsE;r z7|vW2+OWC))%JOL+NXe|U1L{foUxH|m`w zFA6!7PiKkPW?VV3u=WQ3?TN})%CD~S&6TfYeruRu+Z+>{u!PK6!iP zv;8)AB)-o6sp@fgo*c85IOAOwu6tkhPWE*861X6}UQple>hjF{Gt(O;1#H`1C$qTJ z;byaXiXsb=6YB*T6Z$w9id`6HC^H?95oCbNDZJzFhcw7&P9`}_QN z_F9J*GUwku(Nmnv;MEy8bBbh;BfI$a>&;hore6PF<73EeHSOHTnDjkg)z-~aNxoL` zY@(&5S87Ruy|@f}ZuIIEdTWnh0_wRNXyd=bPs7%-vz>^3Yh` zo@KhZFWP@+pW7DpA<*W#Y;&CTM%`Q6Jttk$u(ru{;F=`Fc7e}jiK^U>J=QTlzB6V9 zGXEEy$XA+k?>~c!;%kPx4qY5Eirk8@Sit7P=iElKb>@EufN{QgWaspIv5PxSsE;r z7|vW2+OWC))%JOL+NXe|U1L{foUxH|m`w zFA6!7PiKkPW?VV3u=WQ3?TN})%CD~S&6TfYeruRu+Z+>{u!PK6!iP zv;8)AB)-o6sp@fgo*c85IOAOwu6tkhPWE*861X6}UQple>hjF{Gt(O;1#H`1C$qTJ z;byaXiXsb=6YB*T6Z$w9id`6HC^H?95oCbNDZJzFhcw7&P9`}_QN z_F9J*GUwku(Nmnv;MEy8bBbh;BfI$a>&;hore6PF<73EeHSOHTnDjkg)z-~aNxoL` zY@(&5S87Ruy|@f}ZuIIEdTWnh0_wRNXyd=bPs7%-vz>^3Yh` zo@KhZFWP@+pW7DpA<*W#Y;&CTM%`Q6Jttk$u(ru{;F=`Fc7e}jiK^U>J=QTlzB6V9 zGXEEy$XA+k?>~c!;%kPx4qY5Eirk8@Sit7P=iEl8g{Bbq1^AD+i)U1)!mpc-@ zUd(2N#8fe@`omKsbV|)||?~$d~(woztRz_nx>5-+sSNdHePF z?%C&5Hk^1onfpw7ensWJ_<6~8B8NU33N^9hL}mFfNIqbGaOwHw|2p%h{nu1zQ(&C^ z=GhIVnol~@TBZNwYb#BOt7X-gaeK|aKW|Tn3U2;erP^?%+vnq>w{sZ|$L+|C-?LXV z!FBuJS6{*$w1BQHWE42g>QFBu4t6_)hr*c?#&ly!#=O@>VF#Wu%}UAdiFo+tboBgr z8**(W#8$sv8TIsQ#nq4LXUsk>Vu@Jriz^}MPvrG!+KR64`@U~@_Pi!+U7JxvMXAol zsn;aBp9?24P2=#iRk$c}<4)O`g}(I$Q4UvU$rUX=-8tcY#<9&Sr$#JtOSz`HnRf>B z_D*#qGvC6gM}W$qa6$# hkC_zu&^e!&_A&bE{4Ln;ZB@zu1fH&bF6*2UngC1q=STnm From 8833cf624ad94cbb189f2308af4cb34301a04edd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 2 Oct 2024 01:29:00 +0200 Subject: [PATCH 52/88] Update Credits (#32516) Co-authored-by: PJBot --- Resources/Credits/GitHub.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Credits/GitHub.txt b/Resources/Credits/GitHub.txt index 21d0f430bd..b18c4646ed 100644 --- a/Resources/Credits/GitHub.txt +++ b/Resources/Credits/GitHub.txt @@ -1 +1 @@ -0x6273, 12rabbits, 13spacemen, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 3nderall, 4310v343k, 4dplanner, 612git, 778b, Ablankmann, abregado, Absolute-Potato, achookh, Acruid, actioninja, actually-reb, ada-please, adamsong, Adeinitas, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aerocrux, Aeshus, Aexolott, Aexxie, africalimedrop, Afrokada, Agoichi, Ahion, aiden, AJCM-git, AjexRose, Alekshhh, alexkar598, AlexMorgan3817, alexumandxgabriel08x, Alithsko, ALMv1, Alpha-Two, AlphaQwerty, Altoids1, amylizzle, ancientpower, Andre19926, AndrewEyeke, AndreyCamper, Anzarot121, Appiah, ar4ill, ArchPigeon, ArchRBX, areitpog, Arendian, arimah, Arkanic, ArkiveDev, armoks, Arteben, ArthurMousatov, ArtisticRoomba, artur, AruMoon, ArZarLordOfMango, as334, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, august-sun, AutoOtter, avghdev, Awlod, AzzyIsNotHere, BackeTako, BananaFlambe, Baptr0b0t, BasedUser, beck-thompson, bellwetherlogic, benev0, benjamin-burges, BGare, bhenrich, bhespiritu, bibbly, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, BlitzTheSquishy, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, BombasterDS, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, BriBrooo, Bright0, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, bvelliquette, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, capnsockless, CaptainSqrBeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, CatTheSystem, Centronias, chairbender, Charlese2, ChaseFlorom, chavonadelal, Cheackraze, cheesePizza2, cheeseplated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, civilCornball, Clement-O, clyf, Clyybber, CMDR-Piboy314, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, CookieMasterT, coolboy911, coolmankid12345, Coolsurf6, corentt, CormosLemming, crazybrain23, creadth, CrigCrag, croilbird, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, dakimasu, DakotaGay, DamianX, DangerRevolution, daniel-cr, DanSAussieITS, Daracke, Darkenson, DawBla, Daxxi3, dch-GH, de0rix, Deahaka, dean, DEATHB4DEFEAT, DeathCamel58, Deatherd, deathride58, DebugOk, Decappi, Decortex, Deeeeja, deepdarkdepths, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, dexlerxd, dffdff2423, DieselMohawk, digitalic, Dimastra, DinoWattz, DisposableCrewmember42, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DoctorBeard, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, Dynexust, Easypoller, echo, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, Emisse, emmafornash, EmoGarbage404, Endecc, eoineoineoin, eris, erohrs2, ERORR404V1, Errant-4, ertanic, esguard, estacaoespacialpirata, eugene, exincore, exp111, f0x-n3rd, FacePluslll, Fahasor, FairlySadPanda, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, FillerVK, FinnishPaladin, FirinMaLazors, Fishfish458, FL-OZ, Flareguy, flashgnash, FluffiestFloof, FluidRock, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, Fouin, foxhorn, freeman2651, freeze2222, Froffy025, Fromoriss, froozigiusz, FrostMando, FungiFellow, FunTust, Futuristic-OK, GalacticChimp, Gaxeer, gbasood, Geekyhobo, genderGeometries, GeneralGaws, Genkail, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, gituhabu, GlassEclipse, GNF54, godisdeadLOL, goet, Goldminermac, Golinth, GoodWheatley, Gorox221, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, Hardly3D, harikattar, he1acdvv, Hebi, Henry, HerCoyote23, hitomishirichan, hiucko, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, Hreno, hubismal, Hugal31, Huxellberger, Hyenh, i-justuser-i, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imrenq, imweax, indeano, Injazz, Insineer, IntegerTempest, Interrobang01, IProduceWidgets, ItsMeThom, Itzbenz, iztokbajcar, Jackal298, Jackrost, jacksonzck, Jackw2As, jacob, jamessimo, janekvap, Jark255, Jaskanbe, JasperJRoth, jerryimmouse, JerryImMouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, JoeHammad1844, joelsgp, JohnGinnane, johnku1, joshepvodka, jproads, Jrpl, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, KaiShibaa, kalane15, kalanosh, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, Kimpes, KingFroozy, kira-er, Kirillcas, Kirus59, Kistras, Kit0vras, KittenColony, klaypexx, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, koteq, KrasnoshchekovPavel, Krunklehorn, Kukutis96513, Kupie, kxvvv, kyupolaris, kzhanik, lajolico, Lamrr, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, leander-0, leonardo-dabepis, leonsfriedrich, LeoSantich, LetterN, lettern, Level10Cybermancer, LEVELcat, lever1209, Lgibb18, lgruthes, LightVillet, liltenhead, LinkUyx, LittleBuilderJane, lizelive, localcc, lokachop, Lomcastar, LordCarve, LordEclipse, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luizwritescode, Lukasz825700516, luminight, lunarcomets, luringens, lvvova1, Lyndomen, lyroth001, lzimann, lzk228, M3739, mac6na6na, MACMAN2003, Macoron, Magicalus, magmodius, MagnusCrowe, malchanceux, MaloTV, ManelNavola, Mangohydra, marboww, Markek1, Matz05, max, MaxNox7, maylokana, MehimoNemo, MeltedPixel, MemeProof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, MilenVolf, milon, Minty642, Mirino97, mirrorcult, misandrie, MishaUnity, MissKay1994, MisterMecky, Mith-randalf, MjrLandWhale, mkanke-real, MLGTASTICa, moderatelyaware, modern-nm, mokiros, Moneyl, Moomoobeef, moony, Morb0, mr-bo-jangles, Mr0maks, MrFippik, mrrobdemo, MureixloI, musicmanvr, MWKane, Myakot, Myctai, N3X15, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, NazrinNya, neutrino-laser, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, NIXC, NkoKirkto, nmajask, noctyrnal, nok-ko, NonchalantNoob, NoobyLegion, Nopey, not-gavnaed, notafet, notquitehadouken, NotSoDana, noudoit, noverd, NuclearWinter, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, och-och, OctoRocket, OldDanceJacket, OliverOtter, onoira, OnyxTheBrave, OrangeMoronage9622, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, paigemaeforrest, pali6, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, peccneck, Peptide90, peptron1, PeterFuto, PetMudstone, pewter-wiz, Pgriha, Phantom-Lily, Phill101, phunnyguy, pigeonpeas, PilgrimViis, Pill-U, Pireax, Pissachu, pissdemon, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, pok27, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, ProfanedBane, ProPandaBear, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykzz, PuceTint, PuroSlavKing, PursuitInAshes, Putnam3145, quatre, QueerNB, QuietlyWhisper, qwerltaz, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, RiceMar1244, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, RobbyTheFish, Rockdtben, Rohesie, rok-povsic, rolfero, RomanNovo, rosieposieeee, Roudenn, router, RumiTiger, S1rFl0, S1ss3l, Saakra, saga3152, saintmuntzer, Salex08, sam, samgithubaccount, SaphireLattice, SapphicOverload, Sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, scrato, Scribbles0, scruq445, scuffedjays, ScumbagDog, Segonist, sephtasm, Serkket, sewerpig, sh18rw, ShadeAware, ShadowCommander, Shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SignalWalker, siigiil, Simyon264, sirdragooon, Sirionaut, Sk1tch, SkaldetSkaeg, Skarletto, Skrauz, Skyedra, SlamBamActionman, slarticodefast, Slava0135, Slyfox333, snebl, snicket, sniperchance, Snowni, snowsignal, SolidusSnek, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, SpaceManiac, SpaceyLady, spanky-spanky, spartak, SpartanKadence, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, Stealthbomber16, stellar-novas, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, superjj18, Supernorn, SweptWasTaken, Sybil, SYNCHRONIC, Szunti, Tainakov, takemysoult, TaralGit, Taran, taurie, Tayrtahn, tday93, TekuNut, telyonok, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, TGODiamond, TGRCdev, tgrkzus, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, theashtronaut, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, TheIntoxicatedCat, thekilk, themias, Theomund, theOperand, TherapyGoth, TheShuEd, thetolbean, thevinter, TheWaffleJesus, Thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, Titian3, tk-a369, tkdrg, tmtmtl30, TokenStyle, Tollhouse, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, Tornado-Technology, tosatur, TotallyLemon, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, TyAshley, Tyler-IN, Tyzemol, UbaserB, ubis1, UBlueberry, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, Unkn0wnGh0st333, unusualcrow, Uriende, UristMcDorf, user424242420, Vaaankas, valentfingerov, Varen, VasilisThePikachu, veliebm, VelonacepsCalyxEggs, veprolet, veritable-calamity, Veritius, Vermidia, vero5123, Verslebas, VigersRay, violet754, Visne, VMSolidus, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, vulppine, wafehling, Warentan, WarMechanic, Watermelon914, waylon531, weaversam8, wertanchik, whateverusername0, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, wrexbe, wtcwr68, xkreksx, xprospero, xRiriq, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, Yousifb26, youtissoum, YuriyKiss, zach-hill, Zadeon, zamp, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zero, ZeroDiamond, zerorulez, ZeWaka, zionnBE, ZNixian, ZoldorfTheWizard, Zonespace27, Zumorica, Zymem, zzylex +0x6273, 12rabbits, 13spacemen, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 3nderall, 4310v343k, 4dplanner, 612git, 778b, Ablankmann, abregado, Absolute-Potato, achookh, Acruid, actioninja, actually-reb, ada-please, adamsong, Adeinitas, Admiral-Obvious-001, adrian, Adrian16199, Ady4ik, Aerocrux, Aeshus, Aexolott, Aexxie, africalimedrop, Afrokada, Agoichi, Ahion, aiden, AJCM-git, AjexRose, Alekshhh, alexkar598, AlexMorgan3817, alexumandxgabriel08x, Alithsko, ALMv1, Alpha-Two, AlphaQwerty, Altoids1, amylizzle, ancientpower, Andre19926, AndrewEyeke, AndreyCamper, Anzarot121, Appiah, ar4ill, ArchPigeon, ArchRBX, areitpog, Arendian, arimah, Arkanic, ArkiveDev, armoks, Arteben, ArthurMousatov, ArtisticRoomba, artur, AruMoon, ArZarLordOfMango, as334, AsikKEsel, AsnDen, asperger-sind, aspiringLich, astriloqua, august-sun, AutoOtter, avghdev, Awlod, AzzyIsNotHere, BackeTako, BananaFlambe, Baptr0b0t, BasedUser, beck-thompson, bellwetherlogic, benev0, benjamin-burges, BGare, bhenrich, bhespiritu, bibbly, BIGZi0348, bingojohnson, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, BlitzTheSquishy, bloodrizer, Bloody2372, blueDev2, Boaz1111, BobdaBiscuit, BobTheSleder, boiled-water-tsar, BombasterDS, botanySupremist, brainfood1183, BramvanZijp, Brandon-Huu, BriBrooo, Bright0, brndd, bryce0110, BubblegumBlue, buletsponge, buntobaggins, bvelliquette, byondfuckery, c0rigin, c4llv07e, CaasGit, Caconym27, Calecute, Callmore, capnsockless, CaptainSqrBeard, Carbonhell, Carolyn3114, Carou02, carteblanche4me, CatTheSystem, Centronias, chairbender, Charlese2, ChaseFlorom, chavonadelal, Cheackraze, cheesePizza2, cheeseplated, Chief-Engineer, chillyconmor, christhirtle, chromiumboy, Chronophylos, Chubbicous, Chubbygummibear, Ciac32, civilCornball, Clement-O, clyf, Clyybber, CMDR-Piboy314, cohanna, Cohnway, Cojoke-dot, ColdAutumnRain, Colin-Tel, collinlunn, ComicIronic, CookieMasterT, coolboy911, coolmankid12345, Coolsurf6, corentt, CormosLemming, crazybrain23, creadth, CrigCrag, croilbird, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, DadeKuma, Daemon, daerSeebaer, dahnte, dakamakat, dakimasu, DakotaGay, DamianX, DangerRevolution, daniel-cr, DanSAussieITS, Daracke, Darkenson, DawBla, Daxxi3, dch-GH, de0rix, Deahaka, dean, DEATHB4DEFEAT, DeathCamel58, Deatherd, deathride58, DebugOk, Decappi, Decortex, Deeeeja, deepdarkdepths, degradka, Delete69, deltanedas, DenisShvalov, DerbyX, derek, dersheppard, Deserty0, Detintinto, DevilishMilk, dexlerxd, dffdff2423, DieselMohawk, digitalic, Dimastra, DinoWattz, DisposableCrewmember42, DjfjdfofdjfjD, doc-michael, docnite, Doctor-Cpu, DoctorBeard, DogZeroX, dolgovmi, dontbetank, Doomsdrayk, Doru991, DoubleRiceEddiedd, DoutorWhite, dragonryan06, drakewill-CRL, Drayff, dreamlyjack, DrEnzyme, dribblydrone, DrMelon, drongood12, DrSingh, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, dukevanity, duskyjay, Dutch-VanDerLinde, dvir001, Dynexust, Easypoller, echo, eclips_e, eden077, EEASAS, Efruit, efzapa, Ekkosangen, ElectroSR, elsie, elthundercloud, Elysium206, Emisse, emmafornash, EmoGarbage404, Endecc, eoineoineoin, eris, erohrs2, ERORR404V1, Errant-4, ertanic, esguard, estacaoespacialpirata, eugene, exincore, exp111, f0x-n3rd, FacePluslll, Fahasor, FairlySadPanda, FATFSAAM2, Feluk6174, ficcialfaint, Fiftyllama, Fildrance, FillerVK, FinnishPaladin, FirinMaLazors, Fishfish458, FL-OZ, Flareguy, flashgnash, FluffiestFloof, FluidRock, foboscheshir, FoLoKe, fooberticus, ForestNoises, forgotmyotheraccount, forkeyboards, forthbridge, Fortune117, Fouin, foxhorn, freeman2651, freeze2222, Froffy025, Fromoriss, froozigiusz, FrostMando, FungiFellow, FunTust, Futuristic-OK, GalacticChimp, Gaxeer, gbasood, Geekyhobo, genderGeometries, GeneralGaws, Genkail, geraeumig, Ghagliiarghii, Git-Nivrak, githubuser508, gituhabu, GlassEclipse, GNF54, godisdeadLOL, goet, Goldminermac, Golinth, GoodWheatley, Gorox221, graevy, GraniteSidewalk, GreaseMonk, greenrock64, GreyMario, GTRsound, gusxyz, Gyrandola, h3half, hamurlik, Hanzdegloker, HappyRoach, Hardly3D, harikattar, he1acdvv, Hebi, Henry, HerCoyote23, hitomishirichan, hiucko, Hmeister-fake, Hmeister-real, Hobbitmax, hobnob, HoidC, Holinka4ever, holyssss, HoofedEar, Hoolny, hord-brayden, Hreno, hubismal, Hugal31, Huxellberger, Hyenh, i-justuser-i, iacore, IamVelcroboy, Ian321, icekot8, icesickleone, iczero, iglov, IgorAnt028, igorsaux, ike709, illersaver, Illiux, Ilushkins33, Ilya246, IlyaElDunaev, imrenq, imweax, indeano, Injazz, Insineer, IntegerTempest, Interrobang01, IProduceWidgets, ItsMeThom, Itzbenz, iztokbajcar, Jackal298, Jackrost, jacksonzck, Jackw2As, jacob, jamessimo, janekvap, Jark255, Jaskanbe, JasperJRoth, jerryimmouse, JerryImMouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JimGamemaster, jimmy12or, JIPDawg, jjtParadox, JoeHammad1844, joelsgp, JohnGinnane, johnku1, Jophire, joshepvodka, jproads, Jrpl, juliangiebel, JustArt1m, JustCone14, justdie12, justin, justintether, JustinTrotter, justtne, K-Dynamic, k3yw, Kadeo64, Kaga-404, KaiShibaa, kalane15, kalanosh, Kanashi-Panda, katzenminer, kbailey-git, Keelin, Keer-Sar, KEEYNy, keikiru, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, Kimpes, KingFroozy, kira-er, Kirillcas, Kirus59, Kistras, Kit0vras, KittenColony, klaypexx, Kmc2000, Ko4ergaPunk, kognise, kokoc9n, komunre, KonstantinAngelov, koteq, KrasnoshchekovPavel, Krunklehorn, Kukutis96513, Kupie, kxvvv, kyupolaris, kzhanik, lajolico, Lamrr, LankLTE, laok233, lapatison, larryrussian, lawdog4817, Lazzi0706, leander-0, leonardo-dabepis, leonsfriedrich, LeoSantich, LetterN, lettern, Level10Cybermancer, LEVELcat, lever1209, Lgibb18, lgruthes, LightVillet, liltenhead, LinkUyx, LittleBuilderJane, LittleNorthStar, lizelive, localcc, lokachop, Lomcastar, LordCarve, LordEclipse, LucasTheDrgn, luckyshotpictures, LudwigVonChesterfield, luizwritescode, Lukasz825700516, luminight, lunarcomets, luringens, lvvova1, Lyndomen, lyroth001, lzimann, lzk228, M3739, mac6na6na, MACMAN2003, Macoron, Magicalus, magmodius, MagnusCrowe, malchanceux, MaloTV, ManelNavola, Mangohydra, marboww, Markek1, Matz05, max, MaxNox7, maylokana, MehimoNemo, MeltedPixel, MemeProof, MendaxxDev, Menshin, Mephisto72, MerrytheManokit, Mervill, metalgearsloth, MetalSage, MFMessage, mhamsterr, michaelcu, micheel665, MilenVolf, MilonPL, Minty642, Mirino97, mirrorcult, misandrie, MishaUnity, MissKay1994, MisterMecky, Mith-randalf, MjrLandWhale, mkanke-real, MLGTASTICa, moderatelyaware, modern-nm, mokiros, Moneyl, Moomoobeef, moony, Morb0, mr-bo-jangles, Mr0maks, MrFippik, mrrobdemo, MureixloI, musicmanvr, MWKane, Myakot, Myctai, N3X15, nails-n-tape, Nairodian, Naive817, NakataRin, namespace-Memory, Nannek, NazrinNya, neutrino-laser, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, NIXC, NkoKirkto, nmajask, noctyrnal, nok-ko, NonchalantNoob, NoobyLegion, Nopey, not-gavnaed, notafet, notquitehadouken, NotSoDana, noudoit, noverd, NuclearWinter, nukashimika, nuke-haus, NULL882, nullarmo, nyeogmi, Nylux, Nyranu, och-och, OctoRocket, OldDanceJacket, OliverOtter, onoira, OnyxTheBrave, OrangeMoronage9622, osjarw, Ostaf, othymer, OttoMaticode, Owai-Seek, packmore, paigemaeforrest, pali6, Pangogie, panzer-iv1, partyaddict, patrikturi, PaulRitter, peccneck, Peptide90, peptron1, PeterFuto, PetMudstone, pewter-wiz, Pgriha, Phantom-Lily, Phill101, phunnyguy, pigeonpeas, PilgrimViis, Pill-U, Pireax, Pissachu, pissdemon, PixeltheAertistContrib, PixelTheKermit, PJB3005, Plasmaguy, plinyvic, Plykiya, poeMota, pofitlo, pointer-to-null, pok27, PolterTzi, PoorMansDreams, PopGamer45, portfiend, potato1234x, PotentiallyTom, ProfanedBane, ProPandaBear, PrPleGoo, ps3moira, Pspritechologist, Psychpsyo, psykzz, PuceTint, PuroSlavKing, PursuitInAshes, Putnam3145, quatre, QueerNB, QuietlyWhisper, qwerltaz, RadioMull, Radosvik, Radrark, Rainbeon, Rainfey, Raitononai, Ramlik, RamZ, randy10122, Rane, Ranger6012, Rapidgame7, ravage123321, rbertoche, Redfire1331, Redict, RedlineTriad, redmushie, RednoWCirabrab, RemberBM, RemieRichards, RemTim, rene-descartes2021, Renlou, retequizzle, RiceMar1244, rich-dunne, RieBi, riggleprime, RIKELOLDABOSS, rinary1, Rinkashikachi, riolume, RobbyTheFish, Rockdtben, Rohesie, rok-povsic, rolfero, RomanNovo, rosieposieeee, Roudenn, router, RumiTiger, S1rFl0, S1ss3l, Saakra, saga3152, saintmuntzer, Salex08, sam, samgithubaccount, SaphireLattice, SapphicOverload, Sarahon, sativaleanne, SaveliyM360, sBasalto, ScalyChimp, ScarKy0, scrato, Scribbles0, scruq445, scuffedjays, ScumbagDog, Segonist, sephtasm, Serkket, sewerpig, sh18rw, ShadeAware, ShadowCommander, Shadowtheprotogen546, shaeone, shampunj, shariathotpatrol, SignalWalker, siigiil, Simyon264, sirdragooon, Sirionaut, Sk1tch, SkaldetSkaeg, Skarletto, Skrauz, Skyedra, SlamBamActionman, slarticodefast, Slava0135, Slyfox333, snebl, snicket, sniperchance, Snowni, snowsignal, SolidusSnek, SonicHDC, SoulFN, SoulSloth, Soundwavesghost, Soydium, SpaceManiac, SpaceyLady, spanky-spanky, spartak, SpartanKadence, SpeltIncorrectyl, Spessmann, SphiraI, SplinterGP, spoogemonster, sporekto, ssdaniel24, stalengd, stanberytrask, Stanislav4ix, StanTheCarpenter, Stealthbomber16, stellar-novas, stopbreaking, stopka-html, StrawberryMoses, Stray-Pyramid, strO0pwafel, Strol20, StStevens, Subversionary, sunbear-dev, superjj18, Supernorn, SweptWasTaken, Sybil, SYNCHRONIC, Szunti, Tainakov, takemysoult, TaralGit, Taran, taurie, Tayrtahn, tday93, TekuNut, telyonok, TemporalOroboros, tentekal, terezi4real, Terraspark4941, texcruize, TGODiamond, TGRCdev, tgrkzus, ThatOneGoblin25, thatrandomcanadianguy, TheArturZh, theashtronaut, thecopbennet, TheCze, TheDarkElites, thedraccx, TheEmber, TheIntoxicatedCat, thekilk, themias, Theomund, theOperand, TherapyGoth, TheShuEd, thetolbean, thevinter, TheWaffleJesus, Thinbug0, ThunderBear2006, timothyteakettle, TimrodDX, timurjavid, tin-man-tim, Titian3, tk-a369, tkdrg, tmtmtl30, TokenStyle, Tollhouse, tom-leys, tomasalves8, Tomeno, Tonydatguy, topy, Tornado-Technology, tosatur, TotallyLemon, tropicalhibi, truepaintgit, Truoizys, Tryded, TsjipTsjip, Tunguso4ka, TurboTrackerss14, TyAshley, Tyler-IN, Tyzemol, UbaserB, ubis1, UBlueberry, UKNOWH, UltimateJester, Unbelievable-Salmon, underscorex5, UnicornOnLSD, Unisol, Unkn0wnGh0st333, unusualcrow, Uriende, UristMcDorf, user424242420, Vaaankas, valentfingerov, Varen, VasilisThePikachu, veliebm, VelonacepsCalyxEggs, veprolet, veritable-calamity, Veritius, Vermidia, vero5123, Verslebas, VigersRay, violet754, Visne, VMSolidus, voidnull000, volotomite, volundr-, Voomra, Vordenburg, vorkathbruh, vulppine, wafehling, Warentan, WarMechanic, Watermelon914, waylon531, weaversam8, wertanchik, whateverusername0, Willhelm53, WilliamECrew, willicassi, Winkarst-cpu, wirdal, wixoaGit, WlarusFromDaSpace, wrexbe, wtcwr68, xkreksx, xprospero, xRiriq, YanehCheck, yathxyz, Ygg01, YotaXP, youarereadingthis, Yousifb26, youtissoum, YuriyKiss, zach-hill, Zadeon, zamp, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zero, ZeroDiamond, zerorulez, ZeWaka, zionnBE, ZNixian, ZoldorfTheWizard, Zonespace27, Zumorica, Zylofan, Zymem, zzylex From 20aa14e4f7c9907b8c96acde38dae2a2dd6264e5 Mon Sep 17 00:00:00 2001 From: Scribbles0 <91828755+Scribbles0@users.noreply.github.com> Date: Tue, 1 Oct 2024 18:45:54 -0700 Subject: [PATCH 53/88] Cog update (#32585) * ai core upgrades * fix distro color --- Resources/Maps/cog.yml | 425 ++++++++++++++++++++++++++++++----------- 1 file changed, 318 insertions(+), 107 deletions(-) diff --git a/Resources/Maps/cog.yml b/Resources/Maps/cog.yml index 562b27f87f..7bc328d798 100644 --- a/Resources/Maps/cog.yml +++ b/Resources/Maps/cog.yml @@ -805,8 +805,6 @@ entities: 5555: -28,58 5779: 31,-8 5786: 31,-2 - 5798: 0,-4 - 5799: -2,-4 6198: 3,-46 6200: 3,-40 6258: 58,-27 @@ -13373,6 +13371,29 @@ entities: - 4266 - 32067 - 32069 + - uid: 32231 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -4.5,-1.5 + parent: 12 + - type: DeviceList + devices: + - 32227 + - 32226 + - 32234 + - 32225 + - 32224 + - 32235 + - uid: 32232 + components: + - type: Transform + pos: -3.5,-9.5 + parent: 12 + - type: DeviceList + devices: + - 32229 + - 10069 - proto: AirAlarmVox entities: - uid: 7822 @@ -13412,16 +13433,6 @@ entities: - type: Transform pos: 38.5,-32.5 parent: 12 - - uid: 7195 - components: - - type: Transform - anchored: True - pos: 0.5,-3.5 - parent: 12 - - type: Physics - bodyType: Static - - type: Lock - locked: True - uid: 8863 components: - type: Transform @@ -18395,6 +18406,12 @@ entities: - type: Transform pos: -9.5,-16.5 parent: 12 + - uid: 145 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,-5.5 + parent: 12 - uid: 247 components: - type: Transform @@ -24190,17 +24207,12 @@ entities: - uid: 2217 components: - type: Transform - pos: -0.5,-10.5 + pos: -0.5,0.5 parent: 12 - uid: 2218 components: - type: Transform - pos: -0.5,-9.5 - parent: 12 - - uid: 2219 - components: - - type: Transform - pos: -0.5,-8.5 + pos: -0.5,-0.5 parent: 12 - uid: 2220 components: @@ -24215,7 +24227,7 @@ entities: - uid: 2222 components: - type: Transform - pos: -0.5,-4.5 + pos: -1.5,-1.5 parent: 12 - uid: 2223 components: @@ -24265,18 +24277,13 @@ entities: - uid: 2232 components: - type: Transform - pos: -0.5,-3.5 + pos: 0.5,-1.5 parent: 12 - uid: 2233 components: - type: Transform pos: -0.5,-2.5 parent: 12 - - uid: 2234 - components: - - type: Transform - pos: -0.5,-1.5 - parent: 12 - uid: 2262 components: - type: Transform @@ -36062,6 +36069,11 @@ entities: - type: Transform pos: -20.5,-62.5 parent: 12 + - uid: 20074 + components: + - type: Transform + pos: -0.5,-1.5 + parent: 12 - uid: 20257 components: - type: Transform @@ -43702,6 +43714,11 @@ entities: - type: Transform pos: -63.5,-53.5 parent: 12 + - uid: 32230 + components: + - type: Transform + pos: 1.5,-5.5 + parent: 12 - proto: CableApcStack entities: - uid: 16561 @@ -56175,6 +56192,11 @@ entities: - type: Transform pos: -2.5,-9.5 parent: 12 + - uid: 2234 + components: + - type: Transform + pos: 1.5,-5.5 + parent: 12 - uid: 2246 components: - type: Transform @@ -62365,11 +62387,6 @@ entities: - type: Transform pos: -47.5,17.5 parent: 12 - - uid: 20074 - components: - - type: Transform - pos: 2.5,-5.5 - parent: 12 - uid: 20343 components: - type: Transform @@ -103019,6 +103036,13 @@ entities: rot: 3.141592653589793 rad pos: 0.5,67.5 parent: 12 + - uid: 32228 + components: + - type: Transform + pos: -4.5,-4.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' - proto: GasPipeBend entities: - uid: 928 @@ -103223,12 +103247,6 @@ entities: parent: 12 - type: AtmosPipeColor color: '#990000FF' - - uid: 2124 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -2.5,-1.5 - parent: 12 - uid: 2168 components: - type: Transform @@ -103907,23 +103925,22 @@ entities: rot: -1.5707963267948966 rad pos: 37.5,-32.5 parent: 12 - - uid: 7188 - components: - - type: Transform - pos: -1.5,-1.5 - parent: 12 - uid: 7189 components: - type: Transform rot: -1.5707963267948966 rad - pos: 1.5,-1.5 + pos: 0.5,-3.5 parent: 12 - - uid: 7190 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 7194 components: - type: Transform rot: 1.5707963267948966 rad - pos: 0.5,-1.5 + pos: -0.5,-3.5 parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' - uid: 7205 components: - type: Transform @@ -106210,6 +106227,14 @@ entities: rot: 1.5707963267948966 rad pos: 0.5,68.5 parent: 12 + - uid: 32223 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -4.5,-5.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' - proto: GasPipeFourway entities: - uid: 2577 @@ -106259,6 +106284,20 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' + - uid: 7188 + components: + - type: Transform + pos: -1.5,-5.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 7190 + components: + - type: Transform + pos: -0.5,-6.5 + parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' - uid: 10894 components: - type: Transform @@ -107744,6 +107783,13 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' + - uid: 2124 + components: + - type: Transform + pos: -1.5,-2.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' - uid: 2128 components: - type: Transform @@ -112564,6 +112610,41 @@ entities: parent: 12 - type: AtmosPipeColor color: '#990000FF' + - uid: 7185 + components: + - type: Transform + pos: -0.5,-4.5 + parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 7186 + components: + - type: Transform + pos: 0.5,-2.5 + parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 7192 + components: + - type: Transform + pos: -1.5,-3.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 7193 + components: + - type: Transform + pos: 0.5,-0.5 + parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 7196 + components: + - type: Transform + pos: -0.5,-5.5 + parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' - uid: 7204 components: - type: Transform @@ -114582,6 +114663,13 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' + - uid: 10033 + components: + - type: Transform + pos: -1.5,-0.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' - uid: 10034 components: - type: Transform @@ -114766,13 +114854,6 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 10066 - components: - - type: Transform - pos: -0.5,-7.5 - parent: 12 - - type: AtmosPipeColor - color: '#0055CCFF' - uid: 10067 components: - type: Transform @@ -129244,6 +129325,65 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' + - uid: 32216 + components: + - type: Transform + pos: -1.5,-4.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32217 + components: + - type: Transform + pos: -1.5,-6.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32218 + components: + - type: Transform + pos: -1.5,-7.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32219 + components: + - type: Transform + pos: -1.5,-8.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32220 + components: + - type: Transform + pos: -1.5,-9.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32221 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -2.5,-5.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32222 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -3.5,-5.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32233 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -0.5,-5.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' - proto: GasPipeTJunction entities: - uid: 103 @@ -130207,6 +130347,22 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' + - uid: 7191 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: 0.5,-1.5 + parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 7195 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: -1.5,-1.5 + parent: 12 + - type: AtmosPipeColor + color: '#990000FF' - uid: 7206 components: - type: Transform @@ -130611,13 +130767,6 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 10033 - components: - - type: Transform - pos: -0.5,-6.5 - parent: 12 - - type: AtmosPipeColor - color: '#0055CCFF' - uid: 10064 components: - type: Transform @@ -130634,6 +130783,14 @@ entities: parent: 12 - type: AtmosPipeColor color: '#0055CCFF' + - uid: 10066 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -0.5,-7.5 + parent: 12 + - type: AtmosPipeColor + color: '#0055CCFF' - uid: 10070 components: - type: Transform @@ -132652,18 +132809,6 @@ entities: rot: -1.5707963267948966 rad pos: 36.5,-32.5 parent: 12 - - uid: 7191 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: -1.5,-3.5 - parent: 12 - - uid: 7192 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 0.5,-3.5 - parent: 12 - uid: 9038 components: - type: Transform @@ -132994,19 +133139,6 @@ entities: targetPressure: 4500 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 7193 - components: - - type: Transform - pos: -1.5,-2.5 - parent: 12 - - type: GasPressurePump - targetPressure: 4500 - - uid: 7194 - components: - - type: Transform - rot: 3.141592653589793 rad - pos: 0.5,-2.5 - parent: 12 - uid: 7212 components: - type: Transform @@ -133638,11 +133770,6 @@ entities: - 32066 - type: AtmosPipeColor color: '#0055CCFF' - - uid: 7186 - components: - - type: Transform - pos: 1.5,-0.5 - parent: 12 - uid: 7327 components: - type: Transform @@ -133819,6 +133946,9 @@ entities: rot: 3.141592653589793 rad pos: -0.5,-10.5 parent: 12 + - type: DeviceNetwork + deviceLists: + - 32232 - type: AtmosPipeColor color: '#0055CCFF' - uid: 10073 @@ -135226,6 +135356,38 @@ entities: - 32066 - type: AtmosPipeColor color: '#0055CCFF' + - uid: 32224 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 1.5,-1.5 + parent: 12 + - type: DeviceNetwork + deviceLists: + - 32231 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 32225 + components: + - type: Transform + pos: 0.5,0.5 + parent: 12 + - type: DeviceNetwork + deviceLists: + - 32231 + - type: AtmosPipeColor + color: '#0055CCFF' + - uid: 32235 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,-7.5 + parent: 12 + - type: DeviceNetwork + deviceLists: + - 32231 + - type: AtmosPipeColor + color: '#0055CCFF' - proto: GasVentPumpVox entities: - uid: 6688 @@ -135634,11 +135796,6 @@ entities: - 28365 - type: AtmosPipeColor color: '#990000FF' - - uid: 7185 - components: - - type: Transform - pos: -2.5,-0.5 - parent: 12 - uid: 7519 components: - type: Transform @@ -136864,6 +137021,49 @@ entities: parent: 12 - type: AtmosPipeColor color: '#990000FF' + - uid: 32226 + components: + - type: Transform + pos: -1.5,0.5 + parent: 12 + - type: DeviceNetwork + deviceLists: + - 32231 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32227 + components: + - type: Transform + rot: 1.5707963267948966 rad + pos: -2.5,-1.5 + parent: 12 + - type: DeviceNetwork + deviceLists: + - 32231 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32229 + components: + - type: Transform + rot: 3.141592653589793 rad + pos: -1.5,-10.5 + parent: 12 + - type: DeviceNetwork + deviceLists: + - 32232 + - type: AtmosPipeColor + color: '#990000FF' + - uid: 32234 + components: + - type: Transform + rot: -1.5707963267948966 rad + pos: 0.5,-5.5 + parent: 12 + - type: DeviceNetwork + deviceLists: + - 32231 + - type: AtmosPipeColor + color: '#990000FF' - proto: GasVentScrubberVox entities: - uid: 7844 @@ -147563,7 +147763,7 @@ entities: - type: Transform pos: -0.5,-8.5 parent: 12 - - uid: 145 + - uid: 2219 components: - type: Transform pos: -0.5,-4.5 @@ -159531,7 +159731,7 @@ entities: - uid: 24354 components: - type: Transform - pos: 39.5,45.5 + pos: 39.5,46.5 parent: 12 - uid: 24355 components: @@ -173430,16 +173630,6 @@ entities: - type: Transform pos: 36.5,-32.5 parent: 12 - - uid: 7196 - components: - - type: Transform - anchored: True - pos: -1.5,-3.5 - parent: 12 - - type: Physics - bodyType: Static - - type: Lock - locked: True - uid: 20776 components: - type: Transform @@ -174058,7 +174248,7 @@ entities: setupAvailableNetworks: - SurveillanceCameraCommand nameSet: True - id: AI core entrance + id: AI core entrance hall - uid: 32075 components: - type: Transform @@ -174070,6 +174260,20 @@ entities: - SurveillanceCameraCommand nameSet: True id: Gravity Gen + - uid: 32214 + components: + - type: Transform + pos: -10.5,-6.5 + parent: 12 + - type: SurveillanceCamera + id: AI core entrance + - uid: 32215 + components: + - type: Transform + pos: 3.5,-7.5 + parent: 12 + - type: SurveillanceCamera + id: AI core power room - proto: SurveillanceCameraEngineering entities: - uid: 4167 @@ -181447,6 +181651,13 @@ entities: - type: Transform pos: -0.5,-44.5 parent: 12 +- proto: VendingMachineHappyHonk + entities: + - uid: 32236 + components: + - type: Transform + pos: 39.5,45.5 + parent: 12 - proto: VendingMachineHydrobe entities: - uid: 10333 From 42a1e02261ac872a926a40aa78697eff75d06671 Mon Sep 17 00:00:00 2001 From: Zylofan <80375291+Zylofan@users.noreply.github.com> Date: Tue, 1 Oct 2024 22:56:49 -0400 Subject: [PATCH 54/88] Seismic charge now craftable (#32459) * when tryInsertBlueprint is called it now also calls UpdateMaterialWhitelist on the ent so that it can accept new materials if needed. * Changed the previous commit to now just have sharedMaterialStorageSystem subscribe to TechnologyDatabaseModifiedEvent which will call UpdateMaterialWhitelist. * Empty-Commit --- Content.Shared/Materials/SharedMaterialStorageSystem.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Content.Shared/Materials/SharedMaterialStorageSystem.cs b/Content.Shared/Materials/SharedMaterialStorageSystem.cs index dc4858fd74..01539936b9 100644 --- a/Content.Shared/Materials/SharedMaterialStorageSystem.cs +++ b/Content.Shared/Materials/SharedMaterialStorageSystem.cs @@ -8,6 +8,7 @@ using JetBrains.Annotations; using Robust.Shared.Prototypes; using Robust.Shared.Timing; using Robust.Shared.Utility; +using Content.Shared.Research.Components; namespace Content.Shared.Materials; @@ -34,6 +35,7 @@ public abstract class SharedMaterialStorageSystem : EntitySystem SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(OnDatabaseModified); } public override void Update(float frameTime) @@ -312,6 +314,11 @@ public abstract class SharedMaterialStorageSystem : EntitySystem args.Handled = TryInsertMaterialEntity(args.User, args.Used, uid, component); } + private void OnDatabaseModified(Entity ent, ref TechnologyDatabaseModifiedEvent args) + { + UpdateMaterialWhitelist(ent); + } + public int GetSheetVolume(MaterialPrototype material) { if (material.StackEntity == null) From c0d8d58629bb19d5fdbe66ade2c125946d1d67a4 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 02:57:55 +0000 Subject: [PATCH 55/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 640bb92ba1..be9445a27b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: Throwing a jetpack mid-flight will no longer freeze your character - type: Fix - id: 6968 - time: '2024-07-22T22:24:26.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30223 - author: Flareguy changes: - message: Added vox sprites for a few headwear items, including radiation suits @@ -3938,3 +3931,10 @@ id: 7467 time: '2024-10-01T21:44:47.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32578 +- author: Zylo + changes: + - message: Seismic charges being uncraftable + type: Fix + id: 7468 + time: '2024-10-02T02:56:49.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32459 From 360585276dae40c1ca27d34c96ea4c4680ce7e98 Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Wed, 2 Oct 2024 05:22:09 +0200 Subject: [PATCH 56/88] fix voice mask chameleon menu (#32546) --- Resources/Prototypes/Entities/Clothing/Masks/specific.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Prototypes/Entities/Clothing/Masks/specific.yml b/Resources/Prototypes/Entities/Clothing/Masks/specific.yml index 90c648c9d8..d8da80611c 100644 --- a/Resources/Prototypes/Entities/Clothing/Masks/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/Masks/specific.yml @@ -35,6 +35,8 @@ - Snout - type: UserInterface interfaces: + enum.ChameleonUiKey.Key: + type: ChameleonBoundUserInterface enum.VoiceMaskUIKey.Key: type: VoiceMaskBoundUserInterface From b050e8332e36b0d2727a9cbc754de9812eac7c6b Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 03:23:15 +0000 Subject: [PATCH 57/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index be9445a27b..b55c96186a 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Flareguy - changes: - - message: Added vox sprites for a few headwear items, including radiation suits - and the paramedic helmet. - type: Add - id: 6969 - time: '2024-07-23T02:18:33.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30150 - author: Cojoke-dot changes: - message: You can no longer use telescreens and televisions while blind or asleep. @@ -3938,3 +3930,10 @@ id: 7468 time: '2024-10-02T02:56:49.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32459 +- author: slarticodefast + changes: + - message: Fixed the chameleon settings menu not showing up for the voice mask. + type: Fix + id: 7469 + time: '2024-10-02T03:22:09.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32546 From 4ca2a2bb8fe99ee056046e8d751ed3fbeb25a22e Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:00:48 +1000 Subject: [PATCH 58/88] Fix sensors blocking doors (#32591) --- Content.Shared/Doors/Systems/SharedDoorSystem.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 4d88663ca0..80e7ff9669 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -552,8 +552,7 @@ public abstract partial class SharedDoorSystem : EntitySystem var tileRef = _mapSystem.GetTileRef(xform.GridUid.Value, mapGridComp, xform.Coordinates); _doorIntersecting.Clear(); - - _entityLookup.GetLocalEntitiesIntersecting(xform.GridUid.Value, tileRef.GridIndices, _doorIntersecting, gridComp: mapGridComp); + _entityLookup.GetLocalEntitiesIntersecting(xform.GridUid.Value, tileRef.GridIndices, _doorIntersecting, gridComp: mapGridComp, flags: (LookupFlags.All & ~LookupFlags.Sensors)); // TODO SLOTH fix electro's code. // ReSharper disable once InconsistentNaming From cfc723e3f8a3c22fd72172faf4b8ae8eacb826a7 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 05:01:54 +0000 Subject: [PATCH 59/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b55c96186a..2917fee060 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: You can no longer use telescreens and televisions while blind or asleep. - type: Fix - id: 6970 - time: '2024-07-23T02:33:41.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30260 - author: Cojoke-dot changes: - message: Fix one of the QSI popups @@ -3937,3 +3930,10 @@ id: 7469 time: '2024-10-02T03:22:09.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32546 +- author: metalgearsloth + changes: + - message: Fix physics sensors (e.g. proximity triggers) being able to block doors. + type: Fix + id: 7470 + time: '2024-10-02T05:00:48.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32591 From 2a07e4666a87be5bbe5002621c6245de1d246f94 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Tue, 1 Oct 2024 22:27:01 -0700 Subject: [PATCH 60/88] Fix quick-swap stacks of items (#32560) * remove picking up stack on quick swap * better --- Content.Shared/Interaction/SmartEquipSystem.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Content.Shared/Interaction/SmartEquipSystem.cs b/Content.Shared/Interaction/SmartEquipSystem.cs index 4feb0445f8..746bc994ee 100644 --- a/Content.Shared/Interaction/SmartEquipSystem.cs +++ b/Content.Shared/Interaction/SmartEquipSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Hands.EntitySystems; using Content.Shared.Input; using Content.Shared.Inventory; using Content.Shared.Popups; +using Content.Shared.Stacks; using Content.Shared.Storage; using Content.Shared.Storage.EntitySystems; using Content.Shared.Whitelist; @@ -151,8 +152,13 @@ public sealed class SmartEquipSystem : EntitySystem _hands.TryDrop(uid, hands.ActiveHand, handsComp: hands); _storage.Insert(slotItem, handItem.Value, out var stacked, out _); - if (stacked != null) - _hands.TryPickup(uid, stacked.Value, handsComp: hands); + // if the hand item stacked with the things in inventory, but there's no more space left for the rest + // of the stack, place the stack back in hand rather than dropping it on the floor + if (stacked != null && !_storage.CanInsert(slotItem, handItem.Value, out _)) + { + if (TryComp(handItem.Value, out var handStack) && handStack.Count > 0) + _hands.TryPickup(uid, handItem.Value, handsComp: hands); + } return; } From 95f20f13dca544dfd1fe8d68755a17f73f6245a4 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 05:28:07 +0000 Subject: [PATCH 61/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 2917fee060..a89e8ed4ce 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: Fix one of the QSI popups - type: Fix - id: 6971 - time: '2024-07-23T03:23:04.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30265 - author: Errant changes: - message: Players are now notified when trying to insert an incompatible magazine @@ -3937,3 +3930,11 @@ id: 7470 time: '2024-10-02T05:00:48.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32591 +- author: Plykiya + changes: + - message: You can now quick-swap uneven stacks of items into your inventory without + it getting "stuck" in your hands. + type: Fix + id: 7471 + time: '2024-10-02T05:27:01.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32560 From 2df61e4e71b6959561adf388e63aad3f571e4307 Mon Sep 17 00:00:00 2001 From: Preston Smith <92108534+thetolbean@users.noreply.github.com> Date: Wed, 2 Oct 2024 00:30:58 -0500 Subject: [PATCH 62/88] Added LV cables to Marathon SMES room (#32574) Added LV cables to SMES room, powering light and computers. --- Resources/Maps/marathon.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Resources/Maps/marathon.yml b/Resources/Maps/marathon.yml index 7a23a84c70..fa6faec647 100644 --- a/Resources/Maps/marathon.yml +++ b/Resources/Maps/marathon.yml @@ -30953,6 +30953,31 @@ entities: - type: Transform pos: 19.5,-39.5 parent: 30 + - uid: 22544 + components: + - type: Transform + pos: -11.5,-44.5 + parent: 30 + - uid: 22547 + components: + - type: Transform + pos: -10.5,-44.5 + parent: 30 + - uid: 22550 + components: + - type: Transform + pos: -9.5,-44.5 + parent: 30 + - uid: 22551 + components: + - type: Transform + pos: -8.5,-44.5 + parent: 30 + - uid: 22552 + components: + - type: Transform + pos: -7.5,-44.5 + parent: 30 - proto: CableApcStack entities: - uid: 1637 From 936917cd05375f997f5bf3260c4bc009d8b9cbcc Mon Sep 17 00:00:00 2001 From: TakoDragon <69509841+BackeTako@users.noreply.github.com> Date: Wed, 2 Oct 2024 07:33:35 +0200 Subject: [PATCH 63/88] Hydroponics doors (#32575) * spriting done * yml hydro updates * Named wrong thing and forgot it inherets --- .../Structures/Doors/Airlocks/access.yml | 4 +- .../Structures/Doors/Airlocks/airlocks.yml | 20 ++ .../Structures/Doors/Airlocks/assembly.yml | 19 ++ .../Structures/Doors/airlock_groups.yml | 3 + .../Glass/hydroponics.rsi/assembly.png | Bin 0 -> 1268 bytes .../Glass/hydroponics.rsi/bolted_unlit.png | Bin 0 -> 144 bytes .../Airlocks/Glass/hydroponics.rsi/closed.png | Bin 0 -> 1373 bytes .../Glass/hydroponics.rsi/closed_unlit.png | Bin 0 -> 144 bytes .../Glass/hydroponics.rsi/closing.png | Bin 0 -> 2462 bytes .../Glass/hydroponics.rsi/closing_unlit.png | Bin 0 -> 432 bytes .../Glass/hydroponics.rsi/deny_unlit.png | Bin 0 -> 321 bytes .../Glass/hydroponics.rsi/emergency_unlit.png | Bin 0 -> 588 bytes .../Airlocks/Glass/hydroponics.rsi/meta.json | 195 ++++++++++++++++++ .../Airlocks/Glass/hydroponics.rsi/open.png | Bin 0 -> 365 bytes .../Glass/hydroponics.rsi/opening.png | Bin 0 -> 2451 bytes .../Glass/hydroponics.rsi/opening_unlit.png | Bin 0 -> 284 bytes .../Glass/hydroponics.rsi/panel_closing.png | Bin 0 -> 445 bytes .../Glass/hydroponics.rsi/panel_open.png | Bin 0 -> 315 bytes .../Glass/hydroponics.rsi/panel_opening.png | Bin 0 -> 470 bytes .../Airlocks/Glass/hydroponics.rsi/sparks.png | Bin 0 -> 697 bytes .../Glass/hydroponics.rsi/sparks_broken.png | Bin 0 -> 183 bytes .../Glass/hydroponics.rsi/sparks_damaged.png | Bin 0 -> 184 bytes .../Glass/hydroponics.rsi/sparks_open.png | Bin 0 -> 175 bytes .../Airlocks/Glass/hydroponics.rsi/welded.png | Bin 0 -> 296 bytes .../Standard/hydroponics.rsi/assembly.png | Bin 0 -> 944 bytes .../Standard/hydroponics.rsi/bolted_unlit.png | Bin 0 -> 144 bytes .../Standard/hydroponics.rsi/closed.png | Bin 0 -> 1047 bytes .../Standard/hydroponics.rsi/closed_unlit.png | Bin 0 -> 144 bytes .../Standard/hydroponics.rsi/closing.png | Bin 0 -> 2037 bytes .../hydroponics.rsi/closing_unlit.png | Bin 0 -> 432 bytes .../Standard/hydroponics.rsi/deny_unlit.png | Bin 0 -> 321 bytes .../hydroponics.rsi/emergency_unlit.png | Bin 0 -> 588 bytes .../Standard/hydroponics.rsi/meta.json | 195 ++++++++++++++++++ .../Standard/hydroponics.rsi/open.png | Bin 0 -> 365 bytes .../Standard/hydroponics.rsi/opening.png | Bin 0 -> 2004 bytes .../hydroponics.rsi/opening_unlit.png | Bin 0 -> 284 bytes .../hydroponics.rsi/panel_closing.png | Bin 0 -> 445 bytes .../Standard/hydroponics.rsi/panel_open.png | Bin 0 -> 315 bytes .../hydroponics.rsi/panel_opening.png | Bin 0 -> 470 bytes .../Standard/hydroponics.rsi/sparks.png | Bin 0 -> 697 bytes .../hydroponics.rsi/sparks_broken.png | Bin 0 -> 183 bytes .../hydroponics.rsi/sparks_damaged.png | Bin 0 -> 184 bytes .../Standard/hydroponics.rsi/sparks_open.png | Bin 0 -> 175 bytes .../Standard/hydroponics.rsi/welded.png | Bin 0 -> 296 bytes 44 files changed, 434 insertions(+), 2 deletions(-) create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/assembly.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/bolted_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closed.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closed_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closing.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closing_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/deny_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/emergency_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/meta.json create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/open.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/opening.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/opening_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/panel_closing.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/panel_open.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/panel_opening.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_broken.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_damaged.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_open.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/welded.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/assembly.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/bolted_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closed.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closed_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closing.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closing_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/deny_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/emergency_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/meta.json create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/open.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/opening.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/opening_unlit.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/panel_closing.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/panel_open.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/panel_opening.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_broken.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_damaged.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_open.png create mode 100644 Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/welded.png diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml index c7951993f1..71feb1d4e6 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml @@ -65,7 +65,7 @@ board: [ DoorElectronicsBar ] - type: entity - parent: AirlockServiceLocked + parent: AirlockHydroponics id: AirlockHydroponicsLocked suffix: Hydroponics, Locked components: @@ -531,7 +531,7 @@ board: [ DoorElectronicsJanitor ] - type: entity - parent: AirlockServiceGlassLocked + parent: AirlockHydroponicsGlass id: AirlockHydroGlassLocked suffix: Hydroponics, Locked components: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml index 3de6555be1..cf6d5a89df 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/airlocks.yml @@ -40,6 +40,16 @@ - type: Wires layoutId: AirlockCargo +- type: entity + parent: Airlock + id: AirlockHydroponics + suffix: Hydroponics + components: + - type: Sprite + sprite: Structures/Doors/Airlocks/Standard/hydroponics.rsi + - type: Wires + layoutId: AirlockService + - type: entity parent: Airlock id: AirlockMedical @@ -197,6 +207,16 @@ - type: Wires layoutId: AirlockCargo +- type: entity + parent: AirlockGlass + id: AirlockHydroponicsGlass + suffix: Hydroponics + components: + - type: Sprite + sprite: Structures/Doors/Airlocks/Glass/hydroponics.rsi + - type: Wires + layoutId: AirlockService + - type: entity parent: AirlockGlass id: AirlockMedicalGlass diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml index c464c70a15..98508b21bc 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/assembly.yml @@ -138,6 +138,25 @@ sprite: Structures/Doors/Airlocks/Standard/freezer.rsi state: "assembly" +#Hydroponics +- type: entity + parent: AirlockAssembly + id: AirlockAssemblyHydroponics + suffix: Hydroponics + components: + - type: Sprite + sprite: Structures/Doors/Airlocks/Standard/hydroponics.rsi + state: "assembly" + +- type: entity + parent: AirlockAssembly + id: AirlockAssemblyHydroponicsGlass + suffix: Hydroponics, Glass + components: + - type: Sprite + sprite: Structures/Doors/Airlocks/Glass/hydroponics.rsi + state: "assembly" + #Maintenance - type: entity parent: AirlockAssembly diff --git a/Resources/Prototypes/Entities/Structures/Doors/airlock_groups.yml b/Resources/Prototypes/Entities/Structures/Doors/airlock_groups.yml index e8f000514a..9beedb5e49 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/airlock_groups.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/airlock_groups.yml @@ -9,6 +9,7 @@ command: Structures/Doors/Airlocks/Standard/command.rsi engineering: Structures/Doors/Airlocks/Standard/engineering.rsi freezer: Structures/Doors/Airlocks/Standard/freezer.rsi + hydroponics: Structures/Doors/Airlocks/Standard/hydroponics.rsi maintenance: Structures/Doors/Airlocks/Standard/maint.rsi medical: Structures/Doors/Airlocks/Standard/medical.rsi science: Structures/Doors/Airlocks/Standard/science.rsi @@ -27,6 +28,7 @@ science: Structures/Doors/Airlocks/Glass/science.rsi engineering: Structures/Doors/Airlocks/Glass/engineering.rsi glass: Structures/Doors/Airlocks/Glass/glass.rsi + hydroponics: Structures/Doors/Airlocks/Glass/hydroponics.rsi maintenance: Structures/Doors/Airlocks/Glass/maint.rsi medical: Structures/Doors/Airlocks/Glass/medical.rsi security: Structures/Doors/Airlocks/Glass/security.rsi @@ -74,6 +76,7 @@ engineering: Engineering freezer: Civilian glass: Civilian + hydroponics: Civilian maintenance: Civilian medical: Medical science: Science diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/assembly.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/assembly.png new file mode 100644 index 0000000000000000000000000000000000000000..f84c6150fdf61f3ac37fa1a488911d569b306d5f GIT binary patch literal 1268 zcmVPx(u1Q2eR9JCV5fMHAyw8a~HX`OgCy%ZHltNOu<1nQHK;ZkU_`B z7~TFD$Y}pqDMKk6Zft`gvVS%hgF(A8DQ?}cY>d$%z0IXsSDDo5SyL~XL>FW3s%C#A zFJ5wYrqO_8u1OSjsCXo-KC^ETi9LMGFm zXgaobcvFF;JJ!z2ZBhsL-2=Tx7EWF8y9as!WL&pD*^o_Y@WG9q4r$sbhu=NWTOWMo zeabyF7ywtr!9>M7*q%One34WiIAGb62oa-Tq zfgB6&)`OgLL2Up4kcdSqZLB?*h(#+k8L*nBhhb>T02K!Sde210f|(KU@<(^1mYWoP zHm4sRv$6INfUK`StfZDpb@pFAcNKuP9?)5lyBbmsI78@B z+2}3Bdg3`8L?! z%l9|_Ew)3XB_)Oi#&1iSwpxA#YK^AxaWq>j81ehDrl{5dDh>ejZiJee8r^ERar1;> zA3_MKtE=%(b2F}Wb%Bu7j5kS2U6we7q}1sW$pld-F<8>7EnLgU-7YY4e24z~vNGmXdNsDI<-%=5@6pTpJG zjbgF0`yK#dDe`QTx)wZ59Hy<^7feVu>XDu7>(N&!0BR0mDe^qxbSrA8L(|2Qm>&1>^ z$JdRB3ay3|_mbws{7=8wl68&B?{lx72U0s@ru|AoGViurg+dP|`MAvhAl?kLPx)7fD1xR9J}% z>|%OhV$8U3F@|Nq;G!lp-q121= z9nN1{P@m-FoPOW?KF|BU{eGEUyLROOptZFX;cyrLkW3~40J&Ta{}&jBf!%Hg0Ps8y zQ4|3HW~F#tPYeLC(rZUYM+Y2sJ8EicWs*DbI1D+mwk zlMUPrZa6GX`FA1{Lu5LV7iA~m#`cmT#W*_m`4FfY1wIGNbv-czr__!YhJ!l7!(HAy zK~?DtOL73{Z1F+riNZwKdUUqMgW~HJ~`@xnU~+1iB49{&(BH=3khiZHIrSMi#dv_6agV5zP6gl(uWYDDivYt z4Fiw>NLJQ%Go6}qSXtXmok1$P*%&0vqk~}u03e;3tGBYYXgW2gTO2mCUK9zabO2Nw z0O(t0NJZrec)7hr)wIDIC1a)^iA;SQ>lXulRlOR>V1D8&C-gQ-f(#oT}RY7PLJIV*np^$$Gr$moDJ zi1Xj=c=NG`_u$%%v`UCf9D&p{qziy@?ceqR{C>aOE(iif=3jx5OEm_Z777KbPQbc0vm+SL3Hm`Hyy> z!U7eSdHh;_L^g8^Sk7!Xt&2~Q^0LO|43M0;t{VfDm6f3WN@%$bjF01Bc{xVf+o9z$ z>%0}>06^b`P-q|m03ie(j|X9o2df;1?L@z?sm4Go)2b3zwi`ie8UpvkHy{&7bbYZ* zD+ECR$8q2|4lK(;5Ck0;)A_Y82LL1QeT<4nyU`Lk@|u<`ls`(B0n)YHXA(?cWTPwp3iX3?F;{Be`D=fSw2F zz|)c{&v&IjZIzi9+Sp7+TdTB^oibsKqa>SF)_{srR8-p|S{pOnT<8W7au1z3x$m>L zC5BlnL$2of&Di4Dt@DNgUT&{yW6`3Pd$79kUWeHPQx*W;x$=CEQVUR2ATk}n;Vv%# zp!doPCoYHMcLRfgwdridN+E%Bhc4;{pc1!p=Japh|G4@~bWx(>%9AkwFi(C_p940w z+07iODGFUow!*=9z22PmR#fa#Q7ix{6;<ievJPEX+L5Biskn_2mBw!qy`)9YF+o zL9K`u%JyO$RGjB|m_$(o&-1w5=adDsGlRBK@j{1EWqYxMD-{<-5scCGJdsEgbp9`J fIPyEY@_POc>dd6yc8=kv00000NkvXXu0mjfbR}{0 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closed_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closed_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..c78d01c42d084dd5be78e8a33a599a90cc86107f GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJa8DPP>^Ss#&mpghvZkX~#s0-h3N2b6`K?}O)meqDd+l#VI$hWM`6MlQ q&#%(rqf#%I&Hk(pG?9U!&gT+u#1#>y1s3nVf%u-TelF{r5}E)5_cy%& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closing.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closing.png new file mode 100644 index 0000000000000000000000000000000000000000..567e59aaef1771499eadcb4fd7366eede18e144b GIT binary patch literal 2462 zcmV;P31Rk$P)Px;SV=@dRCt{2n}19j=N*SXHV0?mNNgvVFnUlYaYLp6g*Zx-Nez`!DO;2<(Po=8 zRcp1Win9GN2~A~MD_SLrn6hZA)JEAfX`7-=lTu|PQMzu+w5^J|WpQD~DN6)u3YP@1 z6JVJEpMkJHj@O*eclP~y&q(Q4LV~;Z-sia=_Ivl<2N%!t%K#tf?Xoae>c<6KI{|o>)*wF&vuHc9ZU&rHeUlf4s6JU0bGE)P` z5?OyA{(M{3-?UtmTmWdVIeP*C{AB?uE^17|YOgta!VLf~{ow!(_q9245(GhT34-8K z6Qk*(#a*9Duv*(#bt$y30nD*(0EpiH$V~rK%4wH}(^I0>I@&H{BSV#IVh}E7&CSI9 z#bUE8n^-d^KunGoh3nzGca+N^aSKG+orV`LxMEf+Ia9Rf08tdd>}U)iIymPj zct>MEa~(|=HSYhW=RYkkD}}FSGj_1|ZFf;)R(Us~yiEF?xp6a&ii!%$AR~3-W?XX} zO&2w8>k}pQ^J!pu@)O*=owD6UjoBD{i21bid*&->+qP|v&4w-w9>}|%mWvu!Tv!^T z>5^|>S(cSffVlMng3rC@=xiuEqJD=#%OxK-o^GPzQivIeM8Gs3eG!24lHlV$GZ=F< zH#djY6}GZyx+uAeziUU}P!|TSzKh-8eT9mPl6mbXKSSV97s`dsuE+i^h|~+Gju(aX z*$G%F@|Ma;7F$|U|Ja`ZwzQE@Xoz+@L+od|Vy=qO&hRVz7 z+0eU7mKmj%{FFpG#eS%jxdKG1ZL_bc2LAV4VoZ7A7cr(ep;dE_-D zZ5JgI09>EN)9JbBVY=$;>z4swdAYEk9vLG$>T(i;$fDXN=Y-IO-)T0 z9v(LAVul$Cg%FELFM$}2<805$8_D5s>Xz;Z7LNNYdzj&V`o_A-}iyYe6U!0>jtwS@R(BTe1Oe z6g)N<254127EOD<)Q+sYo=p5xt<5Dhu6g#Wn|^$X z?66f2qg())gMD$RKkMKdbur51>v&uo>IVQYljEb6<&{-anXNP)&7!wI$~k*xYHVaE zhqo{N?KdaKN2_UiD7kxPzjfxHRX;xlNLMwvYVCBzOF^a^kYdsv&O2W0th~b>`Az~YmmH>>fBa7?A2;_rv-jzooFqHaiCedB>6!~F zX?{Ovd1KIn4?g@icCUXM;cz&!{GGq-!J#kopHc3(Q4gcsNF;)5|NRaEwT)TrjJk+h zFBoRZ`*Np}Gg+sQW>%hL;v44rc3IcS=CD7jojDg{OnG0b z4`MX3^71~}(vtdh{=g)8G}lTf+u@OqtJcmAmqN@}-uh`~y;}`PBP%b@#IN%QCV|y? z7Bbk;@X+EaPXcLYhl^e&urda?@hC_(&`mK}L`Ye*J(S$?DxUzTPc7T!qQ#UK^L*#? z0nz1}Ey41}PwvEL2kxC$?W`rZQ!_zqq^g74tLi`JXWVcv0l?p{zk?zE!s*v{{rZPA zJ(S!ZUH@7)usXR$`n1zUiz(lRIez`?ukQA}^;$CeVYzSDvx{1tS)C0fHL=X3?)~X+ zp5><9>3`h$X3xQn7F_O&!m5W+E+C~8MsEEpE3s_G#VAvr#CAQ|^JLC#rLqxVJ(y)F zmZHPMD3|n2zJkan!KjNFro0%EQzvD2R$eU=uVm$0N0SQx6TN{fOPOfp%C24y8yeh@@koQwKjHp z=-~oDEEYp36v9Mrz_N>8COP=ASZwwG1N4;L@pJ(2`=uw*si~;~E%SSr<*LQgjkuU$ c%H!$(2NANZSX=tPZ~y=R07*qoM6N<$f)@(Ht^fc4 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closing_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/closing_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..2a71f76d5d0c792fe84b136920ab32a386dfc7a5 GIT binary patch literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^2|(UR&i(je0cL#ec*0}-@j8|{(iQzwzWT#=l!&5f jT;0h840aHhFykh_!rG~;5AeP$1@S#y{an^LB{Ts5_a?jl literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/deny_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/deny_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..7c56263f83958a17893b3db0b04ce3078c15cea0 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^2|(x;TbZ%z1lzVbEa*5x0l` zFLCLtQfk)goBm*9Wqa5)W5IyH?gg7O+Vq@#{gzqI_j{ICbSF<}<0|vo?Y_6yOll7; z+AsO(r`@v>Kf7}$KR*umYV~i&zP&s*_xJv-=38t1deYzEyLbMqy6^o$Z`IbavsGXD zr!(F8`6z;|L6RYjVFqIYc7~Z}LvrZvRZ(vk567Q>-*~3QX2MKG<^wzo#tdf|3@{iQ zO7s8d*3Gv+{xi?r|HRuDl15mS!8LAhWr_IppL3FmClFnFq60fUCY M)78&qol`;+0G5h<`v3p{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/emergency_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/emergency_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..817f2fb3f95c53ee8720a7c5be418b6208a6a7e6 GIT binary patch literal 588 zcmV-S0<-;zP)EX>4Tx04R}tkv&MmKpe$iQ?*4Z4t5Z6$WV2$AS$ApR-p(LLaorMgUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwM<*vm7b)?7X`w}o2gm(*ckglc4iIW3rdb_hfTr7K zG9DAtnN>0H3ISaRVg@5Jvy3@OO2Bh`-NVP%yC~1{KKJM7QL`2Ud?N8IGfbO!gLrDw zHaPDShgm^ZiO-2gO}ZfQBiEG%zj4mHEbz>*nM%$Rhl#~}8!K(h3Z_OpNgPo%o$`fr zgH_I3oV8MgHSft^7|QA^%Uq{9h&UFp1PLM(R8T|-HlnoZq*zGOe$2x^;QA$UDdZ}G zkz)a6Xpmh$_#gc4*2+zcHN#J&iAq7)K38aGjOH1{N)-j{YiSY zrA3Z_-fiIGx}_<5z~v6m|76If>`H!`LM{iqpV2pEfWBLxd#%x1b04Py{D4^000SaNLh0L z01FcU01FcV0GgZ_00007bV*G`2j&6>2?sl(`5Ny4002lyL_t(&-tEhw4S+xZ1i>Rg zVKDSSXPx$CrLy>R9J=Wm$6F2P!xv0CIRI_#&nT86bk83lvI2Kp)MWV3%V8G#1{x1h3-NZ z^(90aDs&JW&Q|w;L)D=qHKMpA_XgT;x@7r3a?j!CHni5C03za26fCq4M_5l3a2c?s3S`-Jsw<|Cao{@zEc*%HzQs<_!0Z7J^ z{9KPAw29a4G?^u-(a>(Exe=HzmMEo+3d|SF{G4Aw7>35$aFz6n0`KixTBmnL+i>q? zy?Nf@Xb6Bl&^%A8j^B``DbZ+Xe+za3yEe4mhV__%trlq5ex82;NtIgqiS>0000000 LNkvXXu0mjf=V+ts literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/opening.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/opening.png new file mode 100644 index 0000000000000000000000000000000000000000..084547837bfd45621af48034bfc5f2e11ed39579 GIT binary patch literal 2451 zcmV;E32gR>P)Px;O-V#SRCt{2n{R9r=N-qtzFcxn;*8i3hm1L?TiifJk|r2|nAD~cRap^XOH*yq zgw|dE|z=;D+ zM)S`G!wmw|Mj~58-=dBLHCV=yVRol8e^|(9++6Kp=qBH|{VqY3~3t zE>^i#J;afb5rhwg(co%ZDYC@}PnkD&Kaq+fdM}z4agD==jk<*k)#%vOhKrR0z^{P@ zlyGC3aj}zY#6#TN6GwO=f6(Rru zv(yZecAzusVwG#fLjZt_!vlF6;*hKNRQ19Gso}ZjN;fP`OEl11f7p+X{x(e@0C=$= zJ>S|~QtMchzPkCxr{quk;_v{-eKSnu#)w9vj%YOMV0E#|Rfg3=1hTI*d4*n1edokf zY`mttvMP~#l%Nd@kA14zqve?x9j=tu*)#v`Gykai`B6`qH~SGZ7vs)kb(xBdSK7(d z^U%aek~FzuCY*wWmr>f*r2^+EwS zH8wGIU5d=ji{=YJgaCltk|gJ1xxJ#rzq4R*ro8O6# zKlvvPesSQ8a)X@zS8xn&qLg?EqeuARlN!2Wh(=nuIkvMM7%cnIQ^gUvQoHfpT!R8L0+-&&;nYvd7+H5 zR{goH*?-!B@-pPr`uBBqCM`QmxbWaw@eps^${wA!`5$31wK8B?XhJG2sb5S1GgEg| zpNkb06(En7M_FsnjT?Bmv=rCc+o7suf=P=R7am+I9-?ZbOb7tTEiJSIF#t%CgocI& zj5IXhiQkWn5_PVNiP_lLn9({Qrib=J>i}5Dg$LJ)N8T|Yo@&Yyk}uava_a^7U;RC# z(N5L6c&Z7ZPzZj%AAY|dE|&|TP)JqFER!}H%Iad3s|>4$*nH$L0N~nBeg^NsV@O6j zReOQ=;4utd{Sdpq_qM92Z;KB%`xnrre4Tc0s>Yp!L`QoV48KYi)++F(3);dK2A>vc1M^AMABF-WdDMDIm$;7|)L z_lMDY{p;Pk-S59M7yhK&z3Y`Hv|_Z`P?E`vxOD$de|2V>cBlS+_glw-{LTn+-we~} zY^a_~Z@)FJGOQks*M3u%0am77jkJ`I&>FK?YM5cNG-m159ttI>>x^)%dWe&K-dvj= zfZRKQ)~r-0%6F4qjq!KVXgFD7iD}h^H<#5z3s3L)r?H z7Nah_xvU-zt@iXpLjAeOBOXt7wpXh?orP(&Jzef%m21_*VPtNDrJxlV9!#??b})^2 zh~3@YxjR;R;%Q;&mFLA|arr^!gsn_H4@bwPw)|N|6Fu>?810qk$u#3)7t@G`(Bj{j z*Yh~&8ZU+id|Q0EUYlYu*J8wT=l=}Ao}PGGh~4m3MtbEJ zIWt*Z>|`48Q2jnY8LLuyz4CT2SzPR9>UoF&5WjR9FYR?>=tIgb})^)6oXmFL-qTBVx*X?wI0>) z1BwxOuYA#JHU#&01 zd9UcdZDbnp_#cTSu@nC~ R=nVh>002ovPDHLkV1f&Cxzqpv literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/opening_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/opening_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..84933bd5ed9cd40a972aee792b227f9aec95f233 GIT binary patch literal 284 zcmeAS@N?(olHy`uVBq!ia0vp^2|(X)s_s z#KIwr!I-V$V11^#dUpKLjjy-9DY|#Kuw+Jjzzl{&rWQ^CH3uAwt;hGhNWR~>|B3$l qhyP2a-~C|qG6v`^C}^l(vC57yE3)EC^YOwKkf5ilpUXO@geCx+nr^EA literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/panel_closing.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/panel_closing.png new file mode 100644 index 0000000000000000000000000000000000000000..db7be0bc4a0ec0b2bc29e8718fb6b71796846f16 GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^2|(qk=b{5eiK-()1~xQ&@cMV`(mao8yQ?TZq;#^Y}m${ zacWZ!Yev-i>$j948lYsxftl|YY`yljZkp{(pFL*+-lj#WWzI6YweB*{ESZG)8eLCP zH-4D=_wruJUKQWqugks*3w-~bxAmsS_S>R@6K&4#1!`fty>^f8^xkc+O+xqazTJA; z{=7~2>uGDRIhyR%SJ)ONH}BrkKUz=f@~-S!d-avVtb5`KJrkcF_ZOUaf4N)v?bouY zpX0AZna`Cr-@$dKByUdGcPkF5{Og%j`&-%%FXZlavSVWw{8-KzzB@7SM0TXvt!o+A zif+H$q2jsc@9*!WwR0M*e5Y<-(ETyu&`qBj{lx9nl5Os{*Qk05m8bu?%XoF&`KQ?? l*%zfe7FQS8+W~`WRsIyAi(3!btSA5lf~TvW%Q~loCIEIM%9sEE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/panel_open.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/panel_open.png new file mode 100644 index 0000000000000000000000000000000000000000..24eb2aedc2248aeb772b38f63ff992254e7aaec0 GIT binary patch literal 315 zcmV-B0mS}^P)G_@Zv*NK(#C83< z0hCg#mPY_q%Og#e`P2l!*GQEjpT`0MYBKbMv^%3TIE=g7KF`WXCR28pn>(x2n zemoXytpJ?bfcIZ;wOEjBHdt%rI!S!%PGhZ=2c^1AoGrxJR_5RoDx&OEP+E*gAHf&mPbH>ZE8FCH9e&*rpCoP%1 zIy_fR`1DT4EhW}ImG2+Fy>#^EcBOlIu{N4r8M|lHdv8DdMa^XX`Q)41s%D;5@l3t_ z>U!DiCu(!NfiicFek|lsbn*16WPNgF)9u86nlDcO+<9uZb*sRm>zlTKo#3wDtk_cV zGUiQg0fX*;t18(yxo?DbZh3Nv5#oCg`Gddm{r7*~nV;{o)~0;#=kiD}oLj`YgzrYV zCx61j+EYJuRBRcZ$AIaEWtl7E0M--(oM3v-T6o|50rvB z?(X|$_9K~q!b>Jme`5^XKVF&j%`2QtMsN-@c!MQ;uYX{&xPXV-MV4h*a7^*H)mTo% z^duKBlw8QrI7#Az6a!+!k42gRM*{jVXw(2^)BtAG0A@rO5W6r+TTo*dR0c>itn&u= ziYhf*#29dhKzXbye)sb`x`T#9jF|@skRQx^J~1)&r}u;k?=m8#VH_qLszE1c7I|*U z-vi17+kNaSpCz%9yQ#rS&sN2x0`#dRVZ$Zo3 z(YozxD(tDJ*Nd^#9ngM11*`#hZL|qqUX-aA#5S}G^!n=WLLU@GQ4~c{6dSK|xP5Tx z!-H@vnhtn%y49-Lc3NyR!WG{&^FjpmIbAy+o5nPrx)V}}E%fz`bB+BtcI@^)8^rTf zBx((Ky3EXU1aLM2IGxVm^KA+58-UdY;QHA(FXNaPN!aD?zV8}<6&DioA6qwm%&S`B zG(?rf)v;@BC^IYu=$f%ZGhhqXw5SF!qXsa;V!%*uXSl{qZh&O*G5ePMUQntINQ83i z$upoRb}H)fv5TKDu*ZP$-hvmY3!Atq6ENBh(WYFFM67|7l05p#?E1nmayZKasmvEs z4%uF#@2=U$hCc&#<3^>qaoRUjD5t(Q@!@5>eLn%YPa&y@Wk6F&Jf;Amr=S&p`TF~H zKQmyzZBbK@-3j_NfaCqFrZteLVgLD`ViBgsl+FQ!832*%0DhkaTq4i015y-4Q4~c{ f6h%=KHvsSpwHV1KmpgiI00000NkvXXu0mjf++aJ5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_broken.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_broken.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5d774588ae44eab5608571cb6aafad7375e158 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^2|(DFD66%%n7hj|c25u0=Hbzuz>&Md dbBcZ?)Aw7<0^jOhxdW|Y@O1TaS?83{1ORW&Jrn={ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_damaged.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_damaged.png new file mode 100644 index 0000000000000000000000000000000000000000..f16a028dee5bbe41a7f4e35f686043e8a112ce4e GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeK3?y%aJ*@^(YymzYu0Z<#e`9lQK{p_au_VYZ zn8D%MjWi%9!PCVtL_+fI!HvAl4m=D8Hh=XH6ZQR;XyVo{y01gP^_0k+pXD$8l*-N4 z&iUk!V5<=?maE{?*yyS)-udN6;H*Pi5*L(-Fs)pAdDY$x8SUGCM{GTG-~v& dN}IerjGt7Q1>7HnEC$-e;OXk;vd$@?2>`@EK-2&L literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_open.png b/Resources/Textures/Structures/Doors/Airlocks/Glass/hydroponics.rsi/sparks_open.png new file mode 100644 index 0000000000000000000000000000000000000000..630eabb976ecf11fa59ba29f03502b02bde399aa GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^2|(GM)~O;5D{Ad0LZe;7N97KJC6BX-upNVgWUu;=WLfz+qP_d4j_bJ3vh=hfa5r9 z0qVN81qdO4*#ozUc?-;6LK?t17pG~m0|2;<_}}aJ8%Xzkw*de?p>!O_N2;HSWO<%5 ub^zoJEX!gGaL3n-QrC61fn;4*wm#k_G(h}nBOLz#0000Px&YDq*vR9J=0mrrOEXBftRvmJNbbxYk<(@GfQ)IgSET$>J9iZm(Ypa!x<(vz2- zdJqp@#9m4d9((CQdg!G>FFjakT0(P3D`*jdW8-du7_<#xkl?QF))KPLs7w#rZ=9W( z-I?9kKMySIeBb*%&-2Zn?|nb1P$)P6^?Dru$8m^)X_}IMOjXtB#J?d)64`7P0Qt3# zD*!w>mt}l>oLn}`&Rx6Q;0M(zwR)YoxjAl4-9r6JZA<*-7tOr8XCFs$30-OOhmlC< z=H-W|@9h9!;bgV#9S{b(f$S3WtK^b>?nKS5VBRyEqM21xc63c1hg%i_Gt;F&;zY5~ z4BXbUb|iPg8*o6+xj(>lJ^98+D`}e-ZsBA#FeW(s+%wZ9)P9wOS3C|r{P75r(<1>B zrfEv1X-Z)x{P3DcbR!N>TDcKBHjatJ3t`&?VjHm5*Zx}rN@n*zYoOB#t@Sl`zM#Fe zX;H71yAdgw-B{~uEi0|r6?abH!qHhESP#Tk;ol7fhgaOo*YXJbxB23kPeNA^wiSno zhjI8dr1Z$Qj+_c6K5bNa_nm{>UU}R~aQ8UN%gdp);H3kz0iL|Jl`Ge7a_E)w=(_HX z8-~IBqf^Lz$wk=yL2xsytFNgz@CHKWW&{uisu;Vsy(E=Eufp*gbB=LqkKM)$m#Q zNZTAmQ5YB);LhkMKb<&%q9_2!6?+)@kB5PTr}i-U5F%^v5_xSa8yjPe_j45ghtkI# zYw%J_PQ@O^FwUcC8UUG02E#C@*r$;8e!ABQtA=HxM&p-@96J3`U{38<`M&sTtk!J) z^Djvqo(iqFWuw;l5lnq{uG4fZL~(R9;O*mjMHI*XqaP?6wb%(Sq8fTN6BETk%Rm$^ z9Gwk)0aaCX;+_qJ)EHRE(J{ZOQ}FN)lhKwxkXzp0|*oC4iCLR)cq)K z*&ApQF6eI};=miPx&(Md!>R9JRkc5Ff@ck>bFjpdyrAQ`1|^Ak$LAs3u!7rP$rr5g+2YyZ@R$ zwSFOR@9+G6-|z37ob&tL6PlcyYy+gzX)2Wp0L^9-fOfmhK_L_h5sSqD&@>IxGy#yD z;-m950RFxhV`gTCcr3=T>dN~#gWt4HntSLm_XpV|N^^)TOj|0B|npKy1l&I`|-)U>7BqkV#kU8Bhld0G1((3HYiqoC=n%`( z)9iS-BwzG^*lQyK$g)f_nWU0Tva70$$g9Ca#iF53}** z8DA2$RvN>&gsQ3lM59p*!=To>;NlA9KF_uRmf!u5q382~-Eh@tu=Cv&PQ8B4H>Qj$ z6z58=dN2r=eG2mLTnw1w1N0gn#P{5LAK1@!0?zNZAoLpFuW$GuTkC!h7Ij)Qh*hJ} zckm$H(8=v;Mq&l3x2nv}Wd=&(^66{74cJTE`DG0M9z)SCMG}jJvM&j5ixmhG-)l9! z;sBvcCe!xbin?7YobcX^oPEC^j?K63BWapOWdTO#JAZ{(i7I|UuZR~;dp8atu4x)! z(=^dEjo%g$wt)9!2%8Y!>*P4?-AH@Pf_S`B8J*Yje*l_o))~~* RD?002ovPDHLkV1fqc4Zi>Y literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closed_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closed_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..c78d01c42d084dd5be78e8a33a599a90cc86107f GIT binary patch literal 144 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJa8DPP>^Ss#&mpghvZkX~#s0-h3N2b6`K?}O)meqDd+l#VI$hWM`6MlQ q&#%(rqf#%I&Hk(pG?9U!&gT+u#1#>y1s3nVf%u-TelF{r5}E)5_cy%& literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closing.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closing.png new file mode 100644 index 0000000000000000000000000000000000000000..9963ddf614cd1d544acb70d42f11bd2aeb658679 GIT binary patch literal 2037 zcmVPx+uSrBfRCt{2n{j9xRUF5^skdhBve~9vTq(Dj+0Zi9cIzS=Dq3NKZN*l`>VE_M zXUNzef`|nbg#A$(Egy%_FjLV&*de(%X{DWR8`FafUfI4cu<5_s${sZaNTxcVJi9?I@Hfq zQHD_M{&Wif;P$&qc&)!5srh+ay?PasM<=Da(A@p|_aj(ekIh@Qyq{&c z6mkKeBN_w%1gk?*T+En+)e#LE6Y%=?2hls!<;f)Iy6)3;-Df5y)5VS}!-a)e1pwny zzlrphQmf6SA}+$KxhiG?(hp|Jt&l4(T`Fb*{DH=DE9A;cmny)x7cOU|AI#*Qb*s%q z0f2LdE(7ppJ&4><(C-lGXPhh-GcH}JOwx51D<)w9)W0CFmLklA3QLwtDei@LK9J&K z#-v%kr+aQ>{kMNaoO^?EEg+o>i!%aEzaV_=XT-d)RL<%R?N2WdR+VU zckF%gOyyjJ%T>X;2862Po^wOhaYUohwFxL^rPFCBJKI7Sk1co#-q{wiJSNk{iu=cP zp#G`t*y+FLx{DceW8G%dR2$zb6E~Bnt*vzo;;D(7Ny}q0T`aj7VE&&!i>?7~xR^29 z!vA40V|<_c7u4F?>e*`Oa_nHqmDjAb2`F<_#A+yAtIee%RzvA3 z*J`K?7Z&EKUk#0EDFFFP#BREnF$pWCr79#BREA1Fn1Mggh-3W+kjf;DOpr%R{f>^F zzD@+ILzOWBM9j+~yu##zOc%PZen*E6z5I7Uh>E-Xyn zwr$(80Fcev`?1LIoT$&|Lw$Wc0APN89!@+&xl2pN3TS(KI}(Wmw~Gif5{V!lH#UKk zKp^0HR-Pw^zjeU4BY1eK-m!-W_pc8(RNtR-Vqp)723TS{`%5!>;$%fh5NNW*^Vu zV%q~o3_d+DW88*zM1#36zyiB!8#qi`P0FLEonOS+(6L!;sX7=vr%6rzz za-m;MR6Qz5H=^sG9`%CltRiICAhm18;a;OD|}9Ip#6v*_~yg+flV@^+bcGo~9JqFk17 zRxTpUyw3-0dj4A8{j}4pJWD1%8ja?D|H%*gpwtwf1g{4#SJO0%{Cg6i#WO8;{e+7#<}HE znz_=;^Y;PibQ;ss(-=EEf^S~^s%+eJI$aS=r7*wlMpoV~6Au8}&bI&n9@YWRn2ZD;3e&+L~p#5HH6L!s>%~e!m~h&CN(OH{($_3{3JEl=k4^Hu(MgV6(m! z7h+bXlDa>a_lrlFcIvXUQt6h9XbZ2$!a{ep)a@ua)>?ZcTPS8^;?E!)4g&xJfdG=3 zb|?i7A|AY4P1BIfoJ6Q#oQTWRmBU4oP>MFI_CYY)3|JT7))kAM7G?t9Y-kdc)a z>FI_CYY)3|JT5$ASN(oKxtF<_CqQOao+OmL^dL;KPD3Y_Wx1Fov8z~t=MG(Fx&W)H znq|%C#IzK8`a1LEL_K)9fRR!luK-qS^FAa@5_Tb^t z4@6;XoX16!NlGC(b^4Fp%*vZ(;tN@&j>+T#z}>-6E;0zfkqax6)b#tyP)JU_R6{3a zmWj8LcGJU-ODYnHATbDR9hk}eou~^d6EGh9NF-9cCFyono@LvS-sW@5gLS(z9*-ju ziQw*F$gvA6lRWtGczosa0W9TqJRJanLF3(GD#d>H;WVC3bIs!EJT4+kI-dSNQKp5F T&m6Cm00000NkvXXu0mjfJd5xL literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closing_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/closing_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..2a71f76d5d0c792fe84b136920ab32a386dfc7a5 GIT binary patch literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^2|(UR&i(je0cL#ec*0}-@j8|{(iQzwzWT#=l!&5f jT;0h840aHhFykh_!rG~;5AeP$1@S#y{an^LB{Ts5_a?jl literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/deny_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/deny_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..7c56263f83958a17893b3db0b04ce3078c15cea0 GIT binary patch literal 321 zcmeAS@N?(olHy`uVBq!ia0vp^2|(x;TbZ%z1lzVbEa*5x0l` zFLCLtQfk)goBm*9Wqa5)W5IyH?gg7O+Vq@#{gzqI_j{ICbSF<}<0|vo?Y_6yOll7; z+AsO(r`@v>Kf7}$KR*umYV~i&zP&s*_xJv-=38t1deYzEyLbMqy6^o$Z`IbavsGXD zr!(F8`6z;|L6RYjVFqIYc7~Z}LvrZvRZ(vk567Q>-*~3QX2MKG<^wzo#tdf|3@{iQ zO7s8d*3Gv+{xi?r|HRuDl15mS!8LAhWr_IppL3FmClFnFq60fUCY M)78&qol`;+0G5h<`v3p{ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/emergency_unlit.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/emergency_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..817f2fb3f95c53ee8720a7c5be418b6208a6a7e6 GIT binary patch literal 588 zcmV-S0<-;zP)EX>4Tx04R}tkv&MmKpe$iQ?*4Z4t5Z6$WV2$AS$ApR-p(LLaorMgUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwM<*vm7b)?7X`w}o2gm(*ckglc4iIW3rdb_hfTr7K zG9DAtnN>0H3ISaRVg@5Jvy3@OO2Bh`-NVP%yC~1{KKJM7QL`2Ud?N8IGfbO!gLrDw zHaPDShgm^ZiO-2gO}ZfQBiEG%zj4mHEbz>*nM%$Rhl#~}8!K(h3Z_OpNgPo%o$`fr zgH_I3oV8MgHSft^7|QA^%Uq{9h&UFp1PLM(R8T|-HlnoZq*zGOe$2x^;QA$UDdZ}G zkz)a6Xpmh$_#gc4*2+zcHN#J&iAq7)K38aGjOH1{N)-j{YiSY zrA3Z_-fiIGx}_<5z~v6m|76If>`H!`LM{iqpV2pEfWBLxd#%x1b04Py{D4^000SaNLh0L z01FcU01FcV0GgZ_00007bV*G`2j&6>2?sl(`5Ny4002lyL_t(&-tEhw4S+xZ1i>Rg zVKDSSXPx$CrLy>R9J=Wm$6F2P!xv0CIRI_#&nT86bk83lvI2Kp)MWV3%V8G#1{x1h3-NZ z^(90aDs&JW&Q|w;L)D=qHKMpA_XgT;x@7r3a?j!CHni5C03za26fCq4M_5l3a2c?s3S`-Jsw<|Cao{@zEc*%HzQs<_!0Z7J^ z{9KPAw29a4G?^u-(a>(Exe=HzmMEo+3d|SF{G4Aw7>35$aFz6n0`KixTBmnL+i>q? zy?Nf@Xb6Bl&^%A8j^B``DbZ+Xe+za3yEe4mhV__%trlq5ex82;NtIgqiS>0000000 LNkvXXu0mjf=V+ts literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/opening.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/opening.png new file mode 100644 index 0000000000000000000000000000000000000000..81aa75f7a5a943437c16b1b3f1d22ee509650667 GIT binary patch literal 2004 zcmV;_2P^oAP)Px+j!8s8RCt{2n_p;CR~*N`iPxsBakHsrmXc-J8d{{aS~DEm*g8?@=dnoM1fehx$1Yry&vUa!$$_DNa6ti||v?x(a7o;xL)NQ4j%#uB1=Qj6W z?)jT!Yri1$-gEBn^Yxr0_ug~A*VEqKUI2iut}difDFDFy{5$}lP$)o_JRT34nwkIr z(P$LOWD)>SUtiD6OsCTx^S)3hL~XXzizrvrhXyPU{^p?!0O0RqP1v<-7XnR9*tltv ze!$(iIb`SOaq;3sObtvS^jQeoKPk4~7<}k@45^H*}izrvrhn7mEkmye! z?C)7F(i%dbE~sy3^BJUXr;A4XGYFyCwQ#u_eb4q_blo`cIS|GgX-pn3D!DX1w9P{q zBz`k?IyaKA9K5f;yJ&139jI�DW6}kQ&?1G&>qQlp)`!>UZ$aOd9!saKv4H*$ zfIf4iFVV!|IZIK}*IeV=NCKf&<8LVs)9FOV>qV3+;=>C7qf_ISfuPZw-|j)*NRKVh zEc1VSbZT7R=3$x#Bb`or(&@B^)r%mU=A-mzYW)>9~z6?*pFP>SxbLXYvw0l8cbGcz-ocy$b4z5WGqxtvPef5MB|ht}CqyaQgpVIvyqfM+^_ zmV<6y2AZCD8lAqohW&}jMReQrC$)&4Jl$6OqZeqXGuFC!nVspRP7W_-HV;?Chj!&! z@$B3Y`4bQF0NFMu56u65%ksO}*w|>>pVT6H?#dOsyml?ddVBG}T#JM0Bpxr8V>q}X zJ~T^DMme2`0l??;Ash}P6%ON3B!Xt2PZS3LXm4*X*qsoUCilSZ1Srdk6IaBCVFEJw zE@=1fSq^%X??Q)7v0U3(bVTYgec@HhBxLekh{sPL5{Uo+{C+>;@i;R1BZgYM%*Dmt zLg{58`MbSwe}Tn|na#>Ii`9px@9Uld0E`_!iG~*kY*z^<<5@iT@eFnzJ!EMMwT3X- zKW@18WvMk8&vG+q9!<;W%LC#RRw^g+M7q_Od3Oon57!7WMZL)8 zvii`X(I`^Gz~-UiPZ8;yhP?^%!;4at?k`sZC=Px!8pU4=KM66NMC(O1m(_$mz<7_E8@he3FnBVLFNBv7<~bs}GM|JUyFbyF#EE=UU zj3eU7#5;-hdRQit$BQZ^jSp{kWQQTKJmH_Igb##TL;BrirI@uS?ev!y0I12tJIRv7 zt^l)E<&~9*camFHUImlIi)yBukFu!<+DyEYShDi6m^@xoF=>31od8vt_*Lezs``Gw zsyNcosor$+oHJGKU29wD0egID<-bu7sd6`UBFDjWdJ{;c< zAQCl2la-gvWbvY!>E^@p*bA2mqM3Ln(PZVP8&61OvU*X;r19YmY-lcK^eZfqm0#(q z>U}^p-xsJAX`LNGDVcaDxn0000X)s_s z#KIwr!I-V$V11^#dUpKLjjy-9DY|#Kuw+Jjzzl{&rWQ^CH3uAwt;hGhNWR~>|B3$l qhyP2a-~C|qG6v`^C}^l(vC57yE3)EC^YOwKkf5ilpUXO@geCx+nr^EA literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/panel_closing.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/panel_closing.png new file mode 100644 index 0000000000000000000000000000000000000000..db7be0bc4a0ec0b2bc29e8718fb6b71796846f16 GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^2|(qk=b{5eiK-()1~xQ&@cMV`(mao8yQ?TZq;#^Y}m${ zacWZ!Yev-i>$j948lYsxftl|YY`yljZkp{(pFL*+-lj#WWzI6YweB*{ESZG)8eLCP zH-4D=_wruJUKQWqugks*3w-~bxAmsS_S>R@6K&4#1!`fty>^f8^xkc+O+xqazTJA; z{=7~2>uGDRIhyR%SJ)ONH}BrkKUz=f@~-S!d-avVtb5`KJrkcF_ZOUaf4N)v?bouY zpX0AZna`Cr-@$dKByUdGcPkF5{Og%j`&-%%FXZlavSVWw{8-KzzB@7SM0TXvt!o+A zif+H$q2jsc@9*!WwR0M*e5Y<-(ETyu&`qBj{lx9nl5Os{*Qk05m8bu?%XoF&`KQ?? l*%zfe7FQS8+W~`WRsIyAi(3!btSA5lf~TvW%Q~loCIEIM%9sEE literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/panel_open.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/panel_open.png new file mode 100644 index 0000000000000000000000000000000000000000..24eb2aedc2248aeb772b38f63ff992254e7aaec0 GIT binary patch literal 315 zcmV-B0mS}^P)G_@Zv*NK(#C83< z0hCg#mPY_q%Og#e`P2l!*GQEjpT`0MYBKbMv^%3TIE=g7KF`WXCR28pn>(x2n zemoXytpJ?bfcIZ;wOEjBHdt%rI!S!%PGhZ=2c^1AoGrxJR_5RoDx&OEP+E*gAHf&mPbH>ZE8FCH9e&*rpCoP%1 zIy_fR`1DT4EhW}ImG2+Fy>#^EcBOlIu{N4r8M|lHdv8DdMa^XX`Q)41s%D;5@l3t_ z>U!DiCu(!NfiicFek|lsbn*16WPNgF)9u86nlDcO+<9uZb*sRm>zlTKo#3wDtk_cV zGUiQg0fX*;t18(yxo?DbZh3Nv5#oCg`Gddm{r7*~nV;{o)~0;#=kiD}oLj`YgzrYV zCx61j+EYJuRBRcZ$AIaEWtl7E0M--(oM3v-T6o|50rvB z?(X|$_9K~q!b>Jme`5^XKVF&j%`2QtMsN-@c!MQ;uYX{&xPXV-MV4h*a7^*H)mTo% z^duKBlw8QrI7#Az6a!+!k42gRM*{jVXw(2^)BtAG0A@rO5W6r+TTo*dR0c>itn&u= ziYhf*#29dhKzXbye)sb`x`T#9jF|@skRQx^J~1)&r}u;k?=m8#VH_qLszE1c7I|*U z-vi17+kNaSpCz%9yQ#rS&sN2x0`#dRVZ$Zo3 z(YozxD(tDJ*Nd^#9ngM11*`#hZL|qqUX-aA#5S}G^!n=WLLU@GQ4~c{6dSK|xP5Tx z!-H@vnhtn%y49-Lc3NyR!WG{&^FjpmIbAy+o5nPrx)V}}E%fz`bB+BtcI@^)8^rTf zBx((Ky3EXU1aLM2IGxVm^KA+58-UdY;QHA(FXNaPN!aD?zV8}<6&DioA6qwm%&S`B zG(?rf)v;@BC^IYu=$f%ZGhhqXw5SF!qXsa;V!%*uXSl{qZh&O*G5ePMUQntINQ83i z$upoRb}H)fv5TKDu*ZP$-hvmY3!Atq6ENBh(WYFFM67|7l05p#?E1nmayZKasmvEs z4%uF#@2=U$hCc&#<3^>qaoRUjD5t(Q@!@5>eLn%YPa&y@Wk6F&Jf;Amr=S&p`TF~H zKQmyzZBbK@-3j_NfaCqFrZteLVgLD`ViBgsl+FQ!832*%0DhkaTq4i015y-4Q4~c{ f6h%=KHvsSpwHV1KmpgiI00000NkvXXu0mjf++aJ5 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_broken.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_broken.png new file mode 100644 index 0000000000000000000000000000000000000000..fb5d774588ae44eab5608571cb6aafad7375e158 GIT binary patch literal 183 zcmeAS@N?(olHy`uVBq!ia0vp^2|(DFD66%%n7hj|c25u0=Hbzuz>&Md dbBcZ?)Aw7<0^jOhxdW|Y@O1TaS?83{1ORW&Jrn={ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_damaged.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_damaged.png new file mode 100644 index 0000000000000000000000000000000000000000..f16a028dee5bbe41a7f4e35f686043e8a112ce4e GIT binary patch literal 184 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeK3?y%aJ*@^(YymzYu0Z<#e`9lQK{p_au_VYZ zn8D%MjWi%9!PCVtL_+fI!HvAl4m=D8Hh=XH6ZQR;XyVo{y01gP^_0k+pXD$8l*-N4 z&iUk!V5<=?maE{?*yyS)-udN6;H*Pi5*L(-Fs)pAdDY$x8SUGCM{GTG-~v& dN}IerjGt7Q1>7HnEC$-e;OXk;vd$@?2>`@EK-2&L literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_open.png b/Resources/Textures/Structures/Doors/Airlocks/Standard/hydroponics.rsi/sparks_open.png new file mode 100644 index 0000000000000000000000000000000000000000..630eabb976ecf11fa59ba29f03502b02bde399aa GIT binary patch literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^2|(GM)~O;5D{Ad0LZe;7N97KJC6BX-upNVgWUu;=WLfz+qP_d4j_bJ3vh=hfa5r9 z0qVN81qdO4*#ozUc?-;6LK?t17pG~m0|2;<_}}aJ8%Xzkw*de?p>!O_N2;HSWO<%5 ub^zoJEX!gGaL3n-QrC61fn;4*wm#k_G(h}nBOLz#0000 Date: Wed, 2 Oct 2024 05:34:42 +0000 Subject: [PATCH 64/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a89e8ed4ce..d2510cbac2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Errant - changes: - - message: Players are now notified when trying to insert an incompatible magazine - into a gun. - type: Add - id: 6972 - time: '2024-07-23T06:36:06.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29046 - author: TheKittehJesus changes: - message: The Syndicate Assault Borg can now wield their double esword @@ -3938,3 +3930,10 @@ id: 7471 time: '2024-10-02T05:27:01.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32560 +- author: BackeTako + changes: + - message: New hydroponics doors + type: Add + id: 7472 + time: '2024-10-02T05:33:35.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32575 From 542817807dbcf2b482623b776811a2c9eee0d0cb Mon Sep 17 00:00:00 2001 From: TakoDragon <69509841+BackeTako@users.noreply.github.com> Date: Wed, 2 Oct 2024 07:35:48 +0200 Subject: [PATCH 65/88] Red circuit floor (#32557) * red circuit added * index colour begone --- Resources/Locale/en-US/tiles/tiles.ftl | 1 + .../Entities/Objects/Misc/tiles.yml | 24 ++++++++++++++++++ .../Entities/Structures/Machines/lathe.yml | 1 + Resources/Prototypes/Recipes/Lathes/misc.yml | 7 +++++ .../Prototypes/Stacks/floor_tile_stacks.yml | 6 +++++ Resources/Prototypes/Tiles/floors.yml | 12 +++++++++ .../Textures/Objects/Tiles/tile.rsi/meta.json | 11 ++++++++ .../Tiles/tile.rsi/rcircuit-inhand-left.png | Bin 0 -> 384 bytes .../Tiles/tile.rsi/rcircuit-inhand-right.png | Bin 0 -> 401 bytes .../Objects/Tiles/tile.rsi/rcircuit.png | Bin 0 -> 429 bytes Resources/Textures/Tiles/attributions.yml | 2 +- Resources/Textures/Tiles/blue_circuit.png | Bin 360 -> 769 bytes Resources/Textures/Tiles/green_circuit.png | Bin 360 -> 846 bytes Resources/Textures/Tiles/red_circuit.png | Bin 0 -> 774 bytes 14 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 Resources/Textures/Objects/Tiles/tile.rsi/rcircuit-inhand-left.png create mode 100644 Resources/Textures/Objects/Tiles/tile.rsi/rcircuit-inhand-right.png create mode 100644 Resources/Textures/Objects/Tiles/tile.rsi/rcircuit.png create mode 100644 Resources/Textures/Tiles/red_circuit.png diff --git a/Resources/Locale/en-US/tiles/tiles.ftl b/Resources/Locale/en-US/tiles/tiles.ftl index 35cea19f78..b520235614 100644 --- a/Resources/Locale/en-US/tiles/tiles.ftl +++ b/Resources/Locale/en-US/tiles/tiles.ftl @@ -90,6 +90,7 @@ tiles-reinforced-glass-floor = reinforced glass floor tiles-metal-foam = metal foam floor tiles-green-circuit-floor = green circuit floor tiles-blue-circuit-floor = blue circuit floor +tiles-red-circuit-floor = red circuit floor tiles-snow = snow tiles-snow-plating = snowed plating tiles-snow-dug = dug snow diff --git a/Resources/Prototypes/Entities/Objects/Misc/tiles.yml b/Resources/Prototypes/Entities/Objects/Misc/tiles.yml index 1e5f2573fd..9032268958 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/tiles.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/tiles.yml @@ -1286,6 +1286,22 @@ - type: Stack stackType: FloorTileBCircuit +- type: entity + name: red circuit floor + parent: FloorTileItemBase + id: FloorTileItemRCircuit + components: + - type: Sprite + state: rcircuit + - type: Item + heldPrefix: rcircuit + - type: FloorTile + outputs: + - Plating + - FloorRedCircuit + - type: Stack + stackType: FloorTileRCircuit + # Circuits stacks - type: entity @@ -1304,6 +1320,14 @@ - type: Stack count: 4 +- type: entity + parent: FloorTileItemRCircuit + id: FloorTileItemRCircuit4 + suffix: 4 + components: + - type: Stack + count: 4 + # Terrain - type: entity name: grass tile diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 666550cd8a..846441cb39 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -442,6 +442,7 @@ - UniformPrinterMachineCircuitboard - FloorGreenCircuit - FloorBlueCircuit + - FloorRedCircuit - MicrowaveMachineCircuitboard - ReagentGrinderMachineCircuitboard - ElectricGrillMachineCircuitboard diff --git a/Resources/Prototypes/Recipes/Lathes/misc.yml b/Resources/Prototypes/Recipes/Lathes/misc.yml index 0f043df9f8..a0e74fc34e 100644 --- a/Resources/Prototypes/Recipes/Lathes/misc.yml +++ b/Resources/Prototypes/Recipes/Lathes/misc.yml @@ -199,6 +199,13 @@ materials: Steel: 100 +- type: latheRecipe + id: FloorRedCircuit + result: FloorTileItemRCircuit4 + completetime: 2 + materials: + Steel: 100 + - type: latheRecipe id: HandheldStationMap result: HandheldStationMapEmpty diff --git a/Resources/Prototypes/Stacks/floor_tile_stacks.yml b/Resources/Prototypes/Stacks/floor_tile_stacks.yml index de03fcba19..65fd672e1a 100644 --- a/Resources/Prototypes/Stacks/floor_tile_stacks.yml +++ b/Resources/Prototypes/Stacks/floor_tile_stacks.yml @@ -538,6 +538,12 @@ spawn: FloorTileItemBCircuit maxCount: 30 +- type: stack + id: FloorTileRCircuit + name: red-circuit floor + spawn: FloorTileItemRCircuit + maxCount: 30 + - type: stack id: FloorTileGrass name: grass floor tile diff --git a/Resources/Prototypes/Tiles/floors.yml b/Resources/Prototypes/Tiles/floors.yml index 2d552cc33e..c98ee6d582 100644 --- a/Resources/Prototypes/Tiles/floors.yml +++ b/Resources/Prototypes/Tiles/floors.yml @@ -1422,6 +1422,18 @@ itemDrop: FloorTileItemBCircuit heatCapacity: 10000 +- type: tile + id: FloorRedCircuit + name: tiles-red-circuit-floor + sprite: /Textures/Tiles/red_circuit.png + baseTurf: Plating + isSubfloor: false + deconstructTools: [ Prying ] + footstepSounds: + collection: FootstepHull + itemDrop: FloorTileItemRCircuit + heatCapacity: 10000 + # Terrain - type: tile id: FloorAsphalt diff --git a/Resources/Textures/Objects/Tiles/tile.rsi/meta.json b/Resources/Textures/Objects/Tiles/tile.rsi/meta.json index 7db50200ed..7562d0f9b1 100644 --- a/Resources/Textures/Objects/Tiles/tile.rsi/meta.json +++ b/Resources/Textures/Objects/Tiles/tile.rsi/meta.json @@ -159,6 +159,9 @@ { "name": "bcircuit" }, + { + "name": "rcircuit" + }, { "name": "carpet-black" }, @@ -472,6 +475,14 @@ "name": "gold-inhand-left", "directions": 4 }, + { + "name": "rcircuit-inhand-right", + "directions": 4 + }, + { + "name": "rcircuit-inhand-left", + "directions": 4 + }, { "name": "reinforced-inhand-right", "directions": 4 diff --git a/Resources/Textures/Objects/Tiles/tile.rsi/rcircuit-inhand-left.png b/Resources/Textures/Objects/Tiles/tile.rsi/rcircuit-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..06a279199c033322d0941b5ead62a4d0ac598670 GIT binary patch literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%ztvp>ELn`LH zy=9np$U&s#q5G8C3pB1rxIAuBn$E!Ga@2A~0M{gA6(_GQlfW9*=^Pg)7VC&kbWPlF z{q&7<|EEs-Ya_LG%UNS)pt%eT2mW7LU7av%Sz4Oe%)Y-bZ=U|O^-I0ezVdUif8WK< zJb3-ooX;mUHr^}~H%Z@iH`2&Ur}$ia-R@bpxM%nruiHN(x_;-TvjqYs+V<-8O0Pto zvV57YeOv$8w=aJ$cUZbE64@Zh_wSH-qTj^d63+Gf?A3KO2EYGg9hswaF^^I8r|tzc zkp+AU+!$XmWRc9c_KWGjlT}Eiq4O*Y)~=eD3M$=d#Wzp$Py>W20RF literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Tiles/tile.rsi/rcircuit-inhand-right.png b/Resources/Textures/Objects/Tiles/tile.rsi/rcircuit-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..44703f72f7df667297f0d6785f773c677b4baba8 GIT binary patch literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=jKx9jP7LeL$-D%zy**tVLn`LH zy=9wq*g=5xf#(O`p2yieg^Lfl>Luz!jyp%h-aXs=;p^|0A1!y~uQ0p))%3r6sQc&pQQ|j4 zx2CN2@mqE9mbr=g)d_2jZibe=j@#U@>_qA=`xAvbe_VVqA$QyB54Ppfn;TyKQ}CU5 z`tR-PbjIHgPUeag#OSRP_wH2xekAIT&HSf{cEXjFZ*^kiZFVm9KfXz4_ZgO@t1g;; z7L#BWYv5}*#&m)4LIi^q!>pf5SJ+?M@8Vx<#7%h1cZfO)}2h7tx76lGG}4(txe zj4v26K#Ig3|`Px$XGugsR9J=WRy$6^KoEVPR8FYHmyRAKfnBp0H3(>buyuTyD<_xw-iAokkdNW z6`pQy6g#cQx;ncDoE^H(v)NTgx&=0bTt#mWl-+Q#{UOhM$NLGmzR;HeI0TE}?SW!f zpzH=^Op>MIlO#)Fll?;A%z#OV(xycUH8b~zS7DR=m@7LW1n3$Xuhy{_QkbH`wA?;{Uo9TODCMQ)s2fIUk{_`H`11J?s|M%HHyOsv5YcSV z#&9-h2cG-=JU`!Lf#=Q!ZI%x_SN)UWly++(GRgih-(--+UJ|&RpM24iwixqal$Nl7 zh~m6pER0(5iht&t3|evs?CSUib8%j`-{sk%8x` ztvP1K@3bH)k5N0ud6DGDo)}8E*!Gc#Spz|~-EzaMN<+ga4Wrb~#!Ha@m2A{zpfoAq)Jx}4eCH`QF(RP zH`?ubJRP7mtu$E?S2E`UVn9`a)G=Tzsu@Ut$SWJoUn~F|#v&(eHR*k|q~y)*6J0$l+kwJ2UKnw(xGQJxb9uU>eJt=s>qWyr({{Jf(t?f&4i8xR-j9Stl zA~Wlzv&fB)%ExZ3qUv7u@};63Jvwv^py5!t+9*}SaLR;))_UjOgbW5hP++iqIC2JsW$c-Z2hZ-0k=WT&0ME8`c>Wo# r?wP|&05_G*kLriseRId>Kl1nia=KE49-V9C00000NkvXXu0mjfDD<45 diff --git a/Resources/Textures/Tiles/green_circuit.png b/Resources/Textures/Tiles/green_circuit.png index 1628c20ae775e19e5302c426977026e22dd425d0..0638d7bde5c123877451a89155723f532bd9f837 100644 GIT binary patch delta 835 zcmV-J1HAm`0?r1I7=H)?0002|8116~0004VQb$4nuFf3k0009BNkl1atYFbuo) z=`K=67M_LK*>C>W`S|GrMhaE|E>Lxm&P=l|R`w3NGeX@BsycfKOdb>I0*FWPsP z4#<?6r}xikV51~GC2~)HFYa(m2M&XCPf9Zu+q10{&b1$Np%evt- zg;A5UV*rRc;Iy`6rUAuis#u8JLOi9vWz#)NLUe4>EBm=zs_ImY19s|2XGe!U(azPQ z+14ftjNTx@8WwORb1vw3C}yc-IKYSjV=)*c~ZqjSauS1NnsUM7;a%A#2v5QGD@SF77ZomA- zAMZKRRwOP3W0>ma{HXvmb(<%iong2fgBOUcq4}WzJRXn08bF>5^-UK|h@_IYiV@K8 zl00`YL}!+kwJ2UKnw(xGQJxb9uU>eJt=s>qWyr({{Jf(t?f&4i8xR-j9Stl zA~Wlzv&fB)%ExZ3qUv7u@};63Jvwv^py5!t+9*}SaLR;))_UjOgbW5hP++iqIC2JsW$c-Z2hZ-0k=WT&0ME8`c>Wo# r?wP|&05_G*kLriseRId>Kl1nia=KE49-V9C00000NkvXXu0mjf!b_RY diff --git a/Resources/Textures/Tiles/red_circuit.png b/Resources/Textures/Tiles/red_circuit.png new file mode 100644 index 0000000000000000000000000000000000000000..44e33bdee31b020f23aa1faaf34c5a65ba79accc GIT binary patch literal 774 zcmV+h1Nr=kP)Px%z)3_wR7i={R=tkeKoI^wu0X<=&gf*(08JvLf{>RmmY>6+@N-Zgo&%kDi9o1M z$~^$GxTC`uDc4?#!Q)}p5E3axMk{N^JF`3gvz1=IiyWMmgDa38Qm5stSDVkH0g+OQ zNrkUh8;h`7t!_6PkBjBC3xd$!zwQZNuQoyG^VZ{H8H9dzJkbe+zwCCjYtcQEI3k)6 z0JG_w$k}x6bv(Xc5=R~|o6ecv>v+jF@j4#kz{A_yPXOrkyIX6GMouG#u!^(kJlQ4} zI?)BhR0_mBi6a?Rw)Jtbq>JeUc{HDCIW0#rX%FPaWyg~wrCUt<=z2=%YI;anBk7hK zW|bNmgnkhEW;PZ<{!=iumPavC1&|$2bRmaGxyb8ycC#VLNgR>ZG9FZ?D##W97AA)> zu9PL8O5K%1$g$_-&h@jLmct!FhJh_D@+Yt4AoNvim6N4H)%1|c_^5AoJkjDl0bu{S z=R{HtVS`w$$}l(l9^h_zKY!)@e)hkDe{MlFJ*2f-y;iHcZFjxe48IKJ*KNDBt0alp zZMzDgMN-6B1zLf(w9A|GU>y46(7!ew zig`dVi6fQ%+NOLS$g(nJ6=_i&0KjE$fYEKtN-n8KqpcMdn7sk2vE&wTC6lH!qN()E zKwh*8sf%g`a^Pgglk5$pZMDP#QYU{CT>Lb}r1#a9;=OB9>@5j@# zdRWMpPxkbzB<0BDaZ)k|d;KouvP@w!!TFst91VC&v8n1Q>L5Fwg3vcJ4A*0D1K1jx z9~OX@-41wwNELc$LL`-ZRh$*de-;TQo>g2l|NlJr1%`q<>F8&d?f?J)07*qoM6N<$ Ef&mt6G5`Po literal 0 HcmV?d00001 From c4c786f08d71bdac6c1fcb8841c4f4901e7304d3 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 05:36:54 +0000 Subject: [PATCH 66/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d2510cbac2..c8caa34c37 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: TheKittehJesus - changes: - - message: The Syndicate Assault Borg can now wield their double esword - type: Fix - id: 6973 - time: '2024-07-23T08:13:18.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30229 - author: Scribbles0 changes: - message: Handless mobs can no longer wipe devices like positronic brains or pAIs. @@ -3937,3 +3930,10 @@ id: 7472 time: '2024-10-02T05:33:35.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32575 +- author: BackeTako + changes: + - message: Red circuit tile + type: Add + id: 7473 + time: '2024-10-02T05:35:48.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32557 From dd12ac1f8a3482a4b36d72780511cb0c00838072 Mon Sep 17 00:00:00 2001 From: ArchRBX <5040911+ArchRBX@users.noreply.github.com> Date: Wed, 2 Oct 2024 07:17:57 +0100 Subject: [PATCH 67/88] MedTek Cartridge (#32450) * initial commit * adds cartridge to cmo's locker * tidies up yml, adds default scanner sound, makes it so the silent property silences the scanner sound too * fixes ert medic pda not having it preinstalled * adds attribution * removes redundant dependencies * fix agent pda --------- Co-authored-by: archrbx --- .../Cartridges/MedTekCartridgeComponent.cs | 6 +++ .../Cartridges/MedTekCartridgeSystem.cs | 31 ++++++++++++++ .../Components/HealthAnalyzerComponent.cs | 2 +- .../Medical/HealthAnalyzerSystem.cs | 5 +-- .../en-US/cartridge-loader/cartridges.ftl | 2 + .../Catalog/Fills/Lockers/heads.yml | 1 + .../Entities/Objects/Devices/cartridges.yml | 19 +++++++++ .../Entities/Objects/Devices/pda.yml | 40 ++++++++++-------- .../Devices/cartridge.rsi/cart-med.png | Bin 0 -> 289 bytes .../Objects/Devices/cartridge.rsi/meta.json | 5 ++- 10 files changed, 89 insertions(+), 22 deletions(-) create mode 100644 Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeComponent.cs create mode 100644 Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeSystem.cs create mode 100644 Resources/Textures/Objects/Devices/cartridge.rsi/cart-med.png diff --git a/Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeComponent.cs b/Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeComponent.cs new file mode 100644 index 0000000000..1a49b4d1f7 --- /dev/null +++ b/Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeComponent.cs @@ -0,0 +1,6 @@ +namespace Content.Server.CartridgeLoader.Cartridges; + +[RegisterComponent] +public sealed partial class MedTekCartridgeComponent : Component +{ +} diff --git a/Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeSystem.cs b/Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeSystem.cs new file mode 100644 index 0000000000..4d1b71dad0 --- /dev/null +++ b/Content.Server/CartridgeLoader/Cartridges/MedTekCartridgeSystem.cs @@ -0,0 +1,31 @@ +using Content.Server.Medical.Components; +using Content.Shared.CartridgeLoader; + +namespace Content.Server.CartridgeLoader.Cartridges; + +public sealed class MedTekCartridgeSystem : EntitySystem +{ + [Dependency] private readonly CartridgeLoaderSystem _cartridgeLoaderSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnCartridgeAdded); + SubscribeLocalEvent(OnCartridgeRemoved); + } + + private void OnCartridgeAdded(Entity ent, ref CartridgeAddedEvent args) + { + var healthAnalyzer = EnsureComp(args.Loader); + } + + private void OnCartridgeRemoved(Entity ent, ref CartridgeRemovedEvent args) + { + // only remove when the program itself is removed + if (!_cartridgeLoaderSystem.HasProgram(args.Loader)) + { + RemComp(args.Loader); + } + } +} diff --git a/Content.Server/Medical/Components/HealthAnalyzerComponent.cs b/Content.Server/Medical/Components/HealthAnalyzerComponent.cs index 85956b6029..34b7af0212 100644 --- a/Content.Server/Medical/Components/HealthAnalyzerComponent.cs +++ b/Content.Server/Medical/Components/HealthAnalyzerComponent.cs @@ -54,7 +54,7 @@ public sealed partial class HealthAnalyzerComponent : Component /// Sound played on scanning end /// [DataField] - public SoundSpecifier? ScanningEndSound; + public SoundSpecifier ScanningEndSound = new SoundPathSpecifier("/Audio/Items/Medical/healthscanner.ogg"); /// /// Whether to show up the popup diff --git a/Content.Server/Medical/HealthAnalyzerSystem.cs b/Content.Server/Medical/HealthAnalyzerSystem.cs index 82f8075902..60a492a755 100644 --- a/Content.Server/Medical/HealthAnalyzerSystem.cs +++ b/Content.Server/Medical/HealthAnalyzerSystem.cs @@ -13,11 +13,9 @@ using Content.Shared.Item.ItemToggle.Components; using Content.Shared.MedicalScanner; using Content.Shared.Mobs.Components; using Content.Shared.Popups; -using Content.Shared.PowerCell; using Robust.Server.GameObjects; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Medical; @@ -104,7 +102,8 @@ public sealed class HealthAnalyzerSystem : EntitySystem if (args.Handled || args.Cancelled || args.Target == null || !_cell.HasDrawCharge(uid, user: args.User)) return; - _audio.PlayPvs(uid.Comp.ScanningEndSound, uid); + if (!uid.Comp.Silent) + _audio.PlayPvs(uid.Comp.ScanningEndSound, uid); OpenUserInterface(args.User, uid); BeginAnalyzingEntity(uid, args.Target.Value); diff --git a/Resources/Locale/en-US/cartridge-loader/cartridges.ftl b/Resources/Locale/en-US/cartridge-loader/cartridges.ftl index 804da0992f..ceeac1be3c 100644 --- a/Resources/Locale/en-US/cartridge-loader/cartridges.ftl +++ b/Resources/Locale/en-US/cartridge-loader/cartridges.ftl @@ -22,6 +22,8 @@ log-probe-label-number = # astro-nav-program-name = AstroNav +med-tek-program-name = MedTek + # Wanted list cartridge wanted-list-program-name = Wanted list wanted-list-label-no-records = It's all right, cowboy diff --git a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml index 2ca2b0f740..82660f8f13 100644 --- a/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml +++ b/Resources/Prototypes/Catalog/Fills/Lockers/heads.yml @@ -219,6 +219,7 @@ - id: MedicalTechFabCircuitboard - id: MedkitFilled - id: RubberStampCMO + - id: MedTekCartridge # Hardsuit table, used for suit storage as well - type: entityTable diff --git a/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml b/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml index aee26b0776..0ab0b687dc 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/cartridges.yml @@ -117,6 +117,25 @@ - type: StealTarget stealGroup: WantedListCartridge +- type: entity + parent: BaseItem + id: MedTekCartridge + name: MedTek cartridge + description: A program that provides medical diagnostic tools. + components: + - type: Sprite + sprite: Objects/Devices/cartridge.rsi + state: cart-med + - type: Icon + sprite: Objects/Devices/cartridge.rsi + state: cart-med + - type: Cartridge + programName: med-tek-program-name + icon: + sprite: Objects/Specific/Medical/healthanalyzer.rsi + state: icon + - type: MedTekCartridge + - type: entity parent: BaseItem id: AstroNavCartridge diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index c6952fdd6a..dfc1c6fa5b 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -131,12 +131,13 @@ id: BaseMedicalPDA abstract: true components: - - type: ItemToggle - onUse: false - - type: HealthAnalyzer - scanDelay: 1 - scanningEndSound: - path: "/Audio/Items/Medical/healthscanner.ogg" + - type: CartridgeLoader + uiKey: enum.PdaUiKey.Key + preinstalled: + - CrewManifestCartridge + - NotekeeperCartridge + - NewsReaderCartridge + - MedTekCartridge - type: entity parent: BasePDA @@ -169,7 +170,7 @@ parent: BaseMedicalPDA id: MedicalInternPDA name: medical intern PDA - description: Why isn't it white? Has a built-in health analyzer. + description: Why isn't it white? components: - type: Pda id: MedicalInternIDCard @@ -569,7 +570,7 @@ parent: BaseMedicalPDA id: CMOPDA name: chief medical officer PDA - description: Extraordinarily shiny and sterile. Has a built-in health analyzer. + description: Extraordinarily shiny and sterile. components: - type: Pda id: CMOIDCard @@ -585,7 +586,7 @@ parent: BaseMedicalPDA id: MedicalPDA name: medical PDA - description: Shiny and sterile. Has a built-in health analyzer. + description: Shiny and sterile. components: - type: Pda id: MedicalIDCard @@ -612,7 +613,7 @@ parent: BaseMedicalPDA id: ParamedicPDA name: paramedic PDA - description: Shiny and sterile. Has a built-in rapid health analyzer. + description: Shiny and sterile. components: - type: Pda id: ParamedicIDCard @@ -905,14 +906,18 @@ id: ERTMedicPDA name: ERT Medic PDA suffix: Medic - description: Red for firepower, it's shiny and sterile. Has a built-in rapid health analyzer. + description: Red for firepower, it's shiny and sterile. components: - type: Pda id: ERTMedicIDCard - - type: HealthAnalyzer - scanDelay: 1 - scanningEndSound: - path: "/Audio/Items/Medical/healthscanner.ogg" + - type: CartridgeLoader + uiKey: enum.PdaUiKey.Key + preinstalled: + - CrewManifestCartridge + - NotekeeperCartridge + - NewsReaderCartridge + - MedTekCartridge + - WantedListCartridge - type: entity parent: ERTLeaderPDA @@ -1019,7 +1024,7 @@ parent: BaseMedicalPDA id: BrigmedicPDA name: brigmedic PDA - description: I wonder whose pulse is on the screen? I hope he doesnt stop... PDA has a built-in health analyzer. + description: I wonder whose pulse is on the screen? I hope it doesn't stop... components: - type: Pda id: BrigmedicIDCard @@ -1089,7 +1094,7 @@ parent: BaseMedicalPDA id: SeniorPhysicianPDA name: senior physician PDA - description: Smells faintly like iron and chemicals. Has a built-in health analyzer. + description: Smells faintly like iron and chemicals. components: - type: Pda id: SeniorPhysicianIDCard @@ -1145,6 +1150,7 @@ uiKey: enum.PdaUiKey.Key preinstalled: - NotekeeperCartridge + - MedTekCartridge cartridgeSlot: priority: -1 name: Cartridge diff --git a/Resources/Textures/Objects/Devices/cartridge.rsi/cart-med.png b/Resources/Textures/Objects/Devices/cartridge.rsi/cart-med.png new file mode 100644 index 0000000000000000000000000000000000000000..69be9eb42e11831d11bae3da472d4f4e3265f36b GIT binary patch literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCilI0(?STIXOAi)zzh>q#PU^;^N{g=59|-O*Pti+jjLalY>u{m6Z()3#3%B_W z2ne`dJZPc!^nd;K$rGl97-!CZ%ic0oAY`gpMlFNMRdaTSV|+8K_n)7-CYis5p`xse z)q=^xv+aa;L&t44OG0&Aw39pF%dyP$(^-2}fC28Hc>*SPy Q)-y18y85}Sb4q9e08CtGF8}}l literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Devices/cartridge.rsi/meta.json b/Resources/Textures/Objects/Devices/cartridge.rsi/meta.json index e7415fe1c2..b79f46d08d 100644 --- a/Resources/Textures/Objects/Devices/cartridge.rsi/meta.json +++ b/Resources/Textures/Objects/Devices/cartridge.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from vgstation at https://github.com/vgstation-coders/vgstation13/commit/1cdfb0230cc96d0ba751fa002d04f8aa2f25ad7d and tgstation at tgstation at https://github.com/tgstation/tgstation/commit/0c15d9dbcf0f2beb230eba5d9d889ef2d1945bb8, cart-log made by Skarletto (github), cart-sec made by dieselmohawk (discord), cart-nav made by ArchRBX (github)", + "copyright": "Taken from vgstation at https://github.com/vgstation-coders/vgstation13/commit/1cdfb0230cc96d0ba751fa002d04f8aa2f25ad7d and tgstation at tgstation at https://github.com/tgstation/tgstation/commit/0c15d9dbcf0f2beb230eba5d9d889ef2d1945bb8, cart-log made by Skarletto (github), cart-sec made by dieselmohawk (discord), cart-nav, cart-med made by ArchRBX (github)", "size": { "x": 32, "y": 32 @@ -55,6 +55,9 @@ { "name": "cart-m" }, + { + "name": "cart-med" + }, { "name": "cart-mi" }, From 5a229e7a2bbe0121decf02f83aacaac6589565ed Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 06:19:03 +0000 Subject: [PATCH 68/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index c8caa34c37..dbe9731f76 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Scribbles0 - changes: - - message: Handless mobs can no longer wipe devices like positronic brains or pAIs. - type: Fix - id: 6974 - time: '2024-07-23T17:47:08.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30149 - author: Quantus changes: - message: Reagent grinders can no longer auto-grind when unpowered. @@ -3937,3 +3930,14 @@ id: 7473 time: '2024-10-02T05:35:48.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32557 +- author: ArchRBX + changes: + - message: The MedTek PDA cartridge has now been added, providing health analyzer + functionality to PDA's + type: Add + - message: The MedTek cartridge has been added to the CMO locker, and comes preinstalled + on medical PDA's, replacing the built-in analyzer functionality on these PDA's + type: Add + id: 7474 + time: '2024-10-02T06:17:57.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32450 From ea3b14faac15591cdc69feb26991bb4c2ae9eed5 Mon Sep 17 00:00:00 2001 From: Toly65 <88860967+Toly65@users.noreply.github.com> Date: Wed, 2 Oct 2024 10:37:49 +0100 Subject: [PATCH 69/88] Bandaid fix to entityeffects on plant trays (#32576) prevented the bioluminescent and slippery effects from being applied to the plant (and thus the plant tray) --- Resources/Prototypes/Hydroponics/randomMutations.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Resources/Prototypes/Hydroponics/randomMutations.yml b/Resources/Prototypes/Hydroponics/randomMutations.yml index 8f409a5eaf..88df438ce9 100644 --- a/Resources/Prototypes/Hydroponics/randomMutations.yml +++ b/Resources/Prototypes/Hydroponics/randomMutations.yml @@ -3,6 +3,7 @@ mutations: - name: Bioluminescent baseOdds: 0.036 + appliesToPlant: false effect: !type:Glow - name: Sentient baseOdds: 0.0072 @@ -11,6 +12,7 @@ effect: !type:MakeSentient # existing effect. - name: Slippery baseOdds: 0.036 + appliesToPlant: false effect: !type:Slipify - name: ChangeSpecies baseOdds: 0.036 @@ -176,4 +178,4 @@ - name: ChangeHarvest baseOdds: 0.036 persists: false - effect: !type:PlantMutateHarvest \ No newline at end of file + effect: !type:PlantMutateHarvest From 7b39d146d38106c7035f7392d20861c3179bf556 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 09:38:55 +0000 Subject: [PATCH 70/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index dbe9731f76..ea076e32ea 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Quantus - changes: - - message: Reagent grinders can no longer auto-grind when unpowered. - type: Fix - id: 6975 - time: '2024-07-23T21:02:07.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30267 - author: BombasterDS changes: - message: Fixed items disappearing after shelfs and mannequin disassembling @@ -3941,3 +3934,13 @@ id: 7474 time: '2024-10-02T06:17:57.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32450 +- author: Toly65 + changes: + - message: fixed slippery and bioluminescent effects persisting on planters after + the plant has been harvested + type: Fix + - message: removed the slippery and bioluminescent visuals from planters temporararily + type: Remove + id: 7475 + time: '2024-10-02T09:37:49.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32576 From edc83b2fab1fcd81cde9278b5715226565b5dbb2 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Wed, 2 Oct 2024 12:53:19 +0200 Subject: [PATCH 71/88] cleanup and fix dinky star (#32594) * cleanup dinky star * fix * oh --- .../Entities/Clothing/Neck/misc.yml | 16 +++++++++++++++ .../Entities/Objects/Misc/dinkystar.yml | 19 ------------------ .../{star-equipped.png => equipped-NECK.png} | Bin .../Neck/Misc/dinkystar.rsi/meta.json | 2 +- 4 files changed, 17 insertions(+), 20 deletions(-) delete mode 100644 Resources/Prototypes/Entities/Objects/Misc/dinkystar.yml rename Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/{star-equipped.png => equipped-NECK.png} (100%) diff --git a/Resources/Prototypes/Entities/Clothing/Neck/misc.yml b/Resources/Prototypes/Entities/Clothing/Neck/misc.yml index 8dfc709bc4..af2af7a420 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/misc.yml @@ -78,3 +78,19 @@ event: !type:StethoscopeActionEvent checkCanInteract: false priority: -1 + +- type: entity + parent: ClothingNeckBase + id: Dinkystar + name: star sticker + description: A dinky lil star for only the hardest working security officers! It's not even sticky anymore. + components: + - type: Sprite + sprite: Clothing/Neck/Misc/dinkystar.rsi + state: icon + - type: Item + size: Tiny + - type: Tag + tags: + - Trash + - WhitelistChameleon diff --git a/Resources/Prototypes/Entities/Objects/Misc/dinkystar.yml b/Resources/Prototypes/Entities/Objects/Misc/dinkystar.yml deleted file mode 100644 index 7703cf2eea..0000000000 --- a/Resources/Prototypes/Entities/Objects/Misc/dinkystar.yml +++ /dev/null @@ -1,19 +0,0 @@ -- type: entity - parent: ClothingNeckBase - id: Dinkystar - name: star sticker - description: A dinky lil star for only the hardest working security officers! It's not even sticky anymore. - components: - - type: Sprite - sprite: Clothing/Neck/Misc/dinkystar.rsi - state: icon - - type: Clothing - sprite: Clothing/Neck/Misc/dinkystar.rsi - clothingVisuals: - neck: - - state: star-equipped - - type: Item - size: Tiny - - type: Tag - tags: - - Trash diff --git a/Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/star-equipped.png b/Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/star-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/meta.json b/Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/meta.json index ae8a2141db..0ed35562ca 100644 --- a/Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/meta.json +++ b/Resources/Textures/Clothing/Neck/Misc/dinkystar.rsi/meta.json @@ -11,7 +11,7 @@ "name": "icon" }, { - "name": "star-equipped", + "name": "equipped-NECK", "directions": 4 } ] From 612732fb84ac5721c90338834690a148c8e2b925 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 10:54:25 +0000 Subject: [PATCH 72/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index ea076e32ea..c2043e95b6 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: BombasterDS - changes: - - message: Fixed items disappearing after shelfs and mannequin disassembling - type: Fix - id: 6976 - time: '2024-07-24T08:57:03.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30313 - author: Cojoke-dot changes: - message: Fix infinite QSI linking range @@ -3944,3 +3937,10 @@ id: 7475 time: '2024-10-02T09:37:49.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32576 +- author: lzk228 + changes: + - message: Star sticker can be used in chameleon menu. + type: Fix + id: 7476 + time: '2024-10-02T10:53:19.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32594 From c55e311c7e599111efd4231937e7d8e49734fc09 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Wed, 2 Oct 2024 13:23:32 +0200 Subject: [PATCH 73/88] Cleanup pins.yml (#32593) * Cleanup pins.yml * oh my * forgor --- .../Entities/Clothing/Neck/pins.yml | 112 +++++------------- .../Neck/Misc/autismpin.rsi/meta.json | 18 --- .../Neck/Misc/goldautismpin.rsi/meta.json | 18 --- ...aro-equipped.png => aro-equipped-NECK.png} | Bin ...ex-equipped.png => asex-equipped-NECK.png} | Bin .../autism-equipped-NECK.png} | Bin .../{autismpin.rsi => pins.rsi}/autism.png | Bin .../{bi-equipped.png => bi-equipped-NECK.png} | Bin ...gay-equipped.png => gay-equipped-NECK.png} | Bin .../goldautism-equipped-NECK.png} | Bin .../goldautism.png | Bin ...r-equipped.png => inter-equipped-NECK.png} | Bin ...les-equipped.png => les-equipped-NECK.png} | Bin ...bt-equipped.png => lgbt-equipped-NECK.png} | Bin .../Clothing/Neck/Misc/pins.rsi/meta.json | 36 ++++-- ...non-equipped.png => non-equipped-NECK.png} | Bin ...pan-equipped.png => pan-equipped-NECK.png} | Bin ...s-equipped.png => trans-equipped-NECK.png} | Bin 18 files changed, 53 insertions(+), 131 deletions(-) delete mode 100644 Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/meta.json delete mode 100644 Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/meta.json rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{aro-equipped.png => aro-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{asex-equipped.png => asex-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/{autismpin.rsi/autism-equipped.png => pins.rsi/autism-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/{autismpin.rsi => pins.rsi}/autism.png (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{bi-equipped.png => bi-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{gay-equipped.png => gay-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/{goldautismpin.rsi/goldautism-equipped.png => pins.rsi/goldautism-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/{goldautismpin.rsi => pins.rsi}/goldautism.png (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{inter-equipped.png => inter-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{les-equipped.png => les-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{lgbt-equipped.png => lgbt-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{non-equipped.png => non-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{pan-equipped.png => pan-equipped-NECK.png} (100%) rename Resources/Textures/Clothing/Neck/Misc/pins.rsi/{trans-equipped.png => trans-equipped-NECK.png} (100%) diff --git a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml index 9f0ff79b20..a7dcf03f28 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/pins.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/pins.yml @@ -7,6 +7,10 @@ components: - type: Item size: Tiny + - type: Sprite + sprite: Clothing/Neck/Misc/pins.rsi + - type: Clothing + sprite: Clothing/Neck/Misc/pins.rsi - type: entity parent: ClothingNeckPinBase @@ -15,14 +19,9 @@ description: Be gay do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: lgbt + state: lgbt - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: lgbt-equipped + equippedPrefix: lgbt - type: entity parent: ClothingNeckPinBase @@ -31,14 +30,9 @@ description: Be aro do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: aro + state: aro - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: aro-equipped + equippedPrefix: aro - type: entity parent: ClothingNeckPinBase @@ -47,14 +41,9 @@ description: Be ace do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: asex + state: asex - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: asex-equipped + equippedPrefix: asex - type: entity parent: ClothingNeckPinBase @@ -63,14 +52,9 @@ description: Be bi do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: bi + state: bi - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: bi-equipped + equippedPrefix: bi - type: entity parent: ClothingNeckPinBase @@ -79,14 +63,9 @@ description: Be gay~ do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: gay + state: gay - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: gay-equipped + equippedPrefix: gay - type: entity parent: ClothingNeckPinBase @@ -95,14 +74,9 @@ description: Be intersex do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: inter + state: inter - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: inter-equipped + equippedPrefix: inter - type: entity parent: ClothingNeckPinBase @@ -111,14 +85,9 @@ description: Be lesbian do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: les + state: les - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: les-equipped + equippedPrefix: les - type: entity parent: ClothingNeckPinBase @@ -127,14 +96,9 @@ description: "01100010 01100101 00100000 01100101 01101110 01100010 01111001 00100000 01100100 01101111 00100000 01100011 01110010 01101001 01101101 01100101" components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: non + state: non - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: non-equipped + equippedPrefix: non - type: entity parent: ClothingNeckPinBase @@ -143,14 +107,9 @@ description: Be pan do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: pan + state: pan - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: pan-equipped + equippedPrefix: pan - type: entity parent: ClothingNeckPinBase @@ -159,14 +118,9 @@ description: Be trans do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/pins.rsi - layers: - - state: trans + state: trans - type: Clothing - sprite: Clothing/Neck/Misc/pins.rsi - clothingVisuals: - neck: - - state: trans-equipped + equippedPrefix: trans - type: entity parent: ClothingNeckPinBase @@ -175,14 +129,9 @@ description: Be autism do crime. components: - type: Sprite - sprite: Clothing/Neck/Misc/autismpin.rsi - layers: - - state: autism + state: autism - type: Clothing - sprite: Clothing/Neck/Misc/autismpin.rsi - clothingVisuals: - neck: - - state: autism-equipped + equippedPrefix: autism - type: entity parent: ClothingNeckPinBase @@ -191,11 +140,6 @@ description: Be autism do warcrime. components: - type: Sprite - sprite: Clothing/Neck/Misc/goldautismpin.rsi - layers: - - state: goldautism + state: goldautism - type: Clothing - sprite: Clothing/Neck/Misc/goldautismpin.rsi - clothingVisuals: - neck: - - state: goldautism-equipped + equippedPrefix: goldautism diff --git a/Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/meta.json b/Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/meta.json deleted file mode 100644 index e82672f071..0000000000 --- a/Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/meta.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-NC-4.0", - "copyright": "Terraspark's work", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "autism" - }, - { - "name": "autism-equipped", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/meta.json b/Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/meta.json deleted file mode 100644 index 6848744ab8..0000000000 --- a/Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/meta.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": 1, - "license": "CC-BY-NC-4.0", - "copyright": "Terraspark's work", - "size": { - "x": 32, - "y": 32 - }, - "states": [ - { - "name": "goldautism" - }, - { - "name": "goldautism-equipped", - "directions": 4 - } - ] -} diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/aro-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/aro-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/aro-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/aro-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/asex-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/asex-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/asex-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/asex-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/autism-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/autism-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/autism-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/autism-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/autism.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/autism.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/autismpin.rsi/autism.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/autism.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/bi-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/bi-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/bi-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/bi-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/gay-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/goldautism-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/goldautism-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/goldautism-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/goldautism-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/goldautism.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/goldautism.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/goldautismpin.rsi/goldautism.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/goldautism.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/inter-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/inter-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/inter-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/inter-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/les-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/les-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/les-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/les-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/lgbt-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/lgbt-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/lgbt-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/lgbt-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json index aab069b547..0619f962df 100644 --- a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json +++ b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "PixelTK leaves his mark on upstream, BackeTako made the gay", + "copyright": "PixelTK leaves his mark on upstream, BackeTako made the gay, autism pins by Terraspark", "size": { "x": 32, "y": 32 @@ -11,70 +11,84 @@ "name": "aro" }, { - "name": "aro-equipped", + "name": "aro-equipped-NECK", "directions": 4 }, { "name": "asex" }, { - "name": "asex-equipped", + "name": "asex-equipped-NECK", + "directions": 4 + }, + { + "name": "autism" + }, + { + "name": "autism-equipped-NECK", "directions": 4 }, { "name": "bi" }, { - "name": "bi-equipped", + "name": "bi-equipped-NECK", "directions": 4 }, { "name": "gay" }, { - "name": "gay-equipped", + "name": "gay-equipped-NECK", + "directions": 4 + }, + { + "name": "goldautism" + }, + { + "name": "goldautism-equipped-NECK", "directions": 4 }, { "name": "inter" }, { - "name": "inter-equipped", + "name": "inter-equipped-NECK", "directions": 4 }, { "name": "les" }, { - "name": "les-equipped", + "name": "les-equipped-NECK", "directions": 4 }, { "name": "lgbt" }, { - "name": "lgbt-equipped", + "name": "lgbt-equipped-NECK", "directions": 4 }, { "name": "non" }, { - "name": "non-equipped", + "name": "non-equipped-NECK", "directions": 4 }, { "name": "pan" }, { - "name": "pan-equipped", + "name": "pan-equipped-NECK", "directions": 4 }, { "name": "trans" }, { - "name": "trans-equipped", + "name": "trans-equipped-NECK", "directions": 4 } ] diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/non-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/non-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/non-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/non-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/pan-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/pan-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/pan-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/pan-equipped-NECK.png diff --git a/Resources/Textures/Clothing/Neck/Misc/pins.rsi/trans-equipped.png b/Resources/Textures/Clothing/Neck/Misc/pins.rsi/trans-equipped-NECK.png similarity index 100% rename from Resources/Textures/Clothing/Neck/Misc/pins.rsi/trans-equipped.png rename to Resources/Textures/Clothing/Neck/Misc/pins.rsi/trans-equipped-NECK.png From 8b14e2534d2c5a25838efb06c1e8f6c751f9c6b6 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Wed, 2 Oct 2024 11:44:11 +0000 Subject: [PATCH 74/88] fix instigator not existing (#32597) Co-authored-by: deltanedas <@deltanedas:kde.org> --- Resources/Prototypes/GameRules/unknown_shuttles.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/GameRules/unknown_shuttles.yml b/Resources/Prototypes/GameRules/unknown_shuttles.yml index 7e40e3a1f2..afbd552af3 100644 --- a/Resources/Prototypes/GameRules/unknown_shuttles.yml +++ b/Resources/Prototypes/GameRules/unknown_shuttles.yml @@ -20,6 +20,7 @@ - id: UnknownShuttleMeatZone - id: UnknownShuttleMicroshuttle - id: UnknownShuttleSpacebus + - id: UnknownShuttleInstigator - type: entityTable id: UnknownShuttlesFreelanceTable From 9b4df5b452b6755bbc8902ef2e84a3e5a8460df7 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 11:45:17 +0000 Subject: [PATCH 75/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index c2043e95b6..b037eba772 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: Fix infinite QSI linking range - type: Fix - id: 6977 - time: '2024-07-24T20:57:45.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30332 - author: deltanedas changes: - message: Borgs can no longer unlock the robotics console or other borgs. @@ -3944,3 +3937,10 @@ id: 7476 time: '2024-10-02T10:53:19.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32594 +- author: deltanedas + changes: + - message: Fixed the Instigator shuttle event never happening. + type: Fix + id: 7477 + time: '2024-10-02T11:44:12.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32597 From 8961dd35a581270f22e4431a6d665002e0d9d30d Mon Sep 17 00:00:00 2001 From: FluffMe Date: Wed, 2 Oct 2024 14:00:31 +0200 Subject: [PATCH 76/88] Fix accidental erase of paper contents by spamming save action (#32598) Fix spammable paper save issue --- Content.Client/Paper/UI/PaperWindow.xaml.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Content.Client/Paper/UI/PaperWindow.xaml.cs b/Content.Client/Paper/UI/PaperWindow.xaml.cs index 02c4ed64c3..3522aabc66 100644 --- a/Content.Client/Paper/UI/PaperWindow.xaml.cs +++ b/Content.Client/Paper/UI/PaperWindow.xaml.cs @@ -319,6 +319,8 @@ namespace Content.Client.Paper.UI private void RunOnSaved() { + // Prevent further saving while text processing still in + SaveButton.Disabled = true; OnSaved?.Invoke(Rope.Collapse(Input.TextRope)); } From 58c8a07d2cba0510deee5655ec0cfc2fd1c66a30 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 12:01:37 +0000 Subject: [PATCH 77/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index b037eba772..e54ffe7c72 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: deltanedas - changes: - - message: Borgs can no longer unlock the robotics console or other borgs. - type: Tweak - id: 6978 - time: '2024-07-25T03:54:52.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/27888 - author: themias changes: - message: Fixed the ripley control panel not loading @@ -3944,3 +3937,10 @@ id: 7477 time: '2024-10-02T11:44:12.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32597 +- author: FluffMe + changes: + - message: Fixed accidental erase of paper contents by spamming save action. + type: Fix + id: 7478 + time: '2024-10-02T12:00:31.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32598 From 4ad4fd42b1164d73ffc9d6d47aef8a1e2cb3b796 Mon Sep 17 00:00:00 2001 From: Flareguy <78941145+Flareguy@users.noreply.github.com> Date: Wed, 2 Oct 2024 07:14:44 -0500 Subject: [PATCH 78/88] Steel tile variantization fix (#32596) steel tile variantization fix --- Resources/Textures/Tiles/steel.png | Bin 952 -> 1354 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Resources/Textures/Tiles/steel.png b/Resources/Textures/Tiles/steel.png index b7792ef138e88ca6793940d036c5b691d57314e7..e41e7a1804ec882a34898b4c3fe62675bf9a9f03 100644 GIT binary patch delta 920 zcmV;J184lW2g(Yt!2y4RgM*2NhJ=KKczAexe0+a@e~XEUf`Wp8fPjaEg@uHKr@B^i z00009a7bBm000ia000ia0czHX2><{CH%UZ6R9Hv7mW@v2FbsrS4wn5XEcgB|doyEa zV^0>HPC{oPXyVV)Y3ej=J@%JhuWzRkdnPjWmpv01f6u>XO7VZJ{*1U>64>_F3xYHJ zA#lB3Z;XSn?We{gA46pi)SnuE+TWXA)K8uUKDvRo&pR^=RMG&|D5{G6)Oh5jzHL!L z1C>X<=^@{E8K5F3rMjQCBMfuy4B&PX$~bN`Pj%swV@5Xa4+=lIJsO zU_dWLC2jzhSi*nG)4*j67XvpLsCqO|`7n^co`^qG*EdO@K=BWRiGqSAR9alEU#cr=mvj{4+B$g8eqgW%=J-M$^f@Z znASF24HO=Eb#=sZ162?C#)p9%W)E;h8)3$OGd@w^x1TSzq;#Z@lv1CBqIY0hv<# ze17lol7GL8AJ20IYWRem=TGuI{+-VziUs1tc!M#qoaYN4J&}4(c++!U+f+?4CWNyn z3+y~!_}CRO;@ElDb3Q&Kw2fH;*lQzr{^NH%5bJ-?#S5=p9Wy9ddDmNbJI`wY_dWhZ zlCm;je14i4U{~Jt7T(Tt732zqfqtGZ{QR<}pz*G^@OGZ7AWKwW=lR0V2Z|+i-u0Zv zf@y*;O%rzhLs0J%bvn-%e(DVaop(Lwhaf`*XxHGU0VzTS{axG1t!X zh1YyMvjm-YJ?9~aAujo$3Ip>zm4SYqFMPP+3}fY8&v~vGhmzC8<5o9BN?#p)Oc{RgiT2P!%+^E|5`LMhkF6&S~a1UE-;Hs4e8mfAugk@9|C z#~kwezr3Au1onAu_`tiSD2Is+%d)IYG-wX3oZFI1B(7)*q?A%{a|qZdSf*U5Y*^P& zk-n+}FUN-9PGw#MJfZ_LFAeu|8h0Ugtpqn81kMqKR9<>IaB!?rah^*O770v`4$OQL z7;O_Q&p~kWSf!Ca1veiAE|SL(!F}q$!8t@UcsXj7E<7Q2f}2AC#2cEkLL8Plt`K$L z*2(n)Hy?xRGM_TfukYu1EpPeo|AAV60pd Date: Wed, 2 Oct 2024 15:52:14 +0200 Subject: [PATCH 79/88] Disable bioluminescence plant mutations because it breaks the engine (#32561) No fun allowed Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- Resources/Prototypes/Hydroponics/randomMutations.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Resources/Prototypes/Hydroponics/randomMutations.yml b/Resources/Prototypes/Hydroponics/randomMutations.yml index 88df438ce9..77ae2288f3 100644 --- a/Resources/Prototypes/Hydroponics/randomMutations.yml +++ b/Resources/Prototypes/Hydroponics/randomMutations.yml @@ -1,10 +1,11 @@ - type: RandomPlantMutationList id: RandomPlantMutations - mutations: - - name: Bioluminescent - baseOdds: 0.036 - appliesToPlant: false - effect: !type:Glow + mutations: + # disabled until 50 morbillion point lights don't cause the renderer to die + #- name: Bioluminescent + # baseOdds: 0.036 + # appliesToPlant: false + # effect: !type:Glow - name: Sentient baseOdds: 0.0072 appliesToProduce: false From 440742f8f7cebebcf85fdcc17083c28f331a0923 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 2 Oct 2024 13:53:20 +0000 Subject: [PATCH 80/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e54ffe7c72..1e5ad4afbc 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: themias - changes: - - message: Fixed the ripley control panel not loading - type: Fix - id: 6979 - time: '2024-07-25T05:23:53.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30325 - author: Timur2011 changes: - message: Space adders are now butcherable. @@ -3944,3 +3937,11 @@ id: 7478 time: '2024-10-02T12:00:31.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32598 +- author: PJB3005 + changes: + - message: Removed bioluminescence plant mutations due to it breaking the rendering + engine. + type: Remove + id: 7479 + time: '2024-10-02T13:52:14.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32561 From 2d644095e342cfb5727765210bafce7c339252c0 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Thu, 3 Oct 2024 02:11:56 +0200 Subject: [PATCH 81/88] Fix borg hands showing up in stripping menu (#32606) * Fix borg hands showing up in stripping menu Borgs can't drop their items anyways, and the amount of hands borgs have causes the UI to just bug out. * Add more checks --- Content.Client/Inventory/StrippableBoundUserInterface.cs | 2 +- Content.Shared/Hands/Components/HandsComponent.cs | 6 ++++++ Content.Shared/Strip/SharedStrippableSystem.cs | 9 +++++++++ .../Entities/Mobs/Cyborgs/base_borg_chassis.yml | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs index 97172f8de8..2ce07758c9 100644 --- a/Content.Client/Inventory/StrippableBoundUserInterface.cs +++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs @@ -98,7 +98,7 @@ namespace Content.Client.Inventory } } - if (EntMan.TryGetComponent(Owner, out var handsComp)) + if (EntMan.TryGetComponent(Owner, out var handsComp) && handsComp.CanBeStripped) { // good ol hands shit code. there is a GuiHands comparer that does the same thing... but these are hands // and not gui hands... which are different... diff --git a/Content.Shared/Hands/Components/HandsComponent.cs b/Content.Shared/Hands/Components/HandsComponent.cs index f218455c0b..b3cb51ae35 100644 --- a/Content.Shared/Hands/Components/HandsComponent.cs +++ b/Content.Shared/Hands/Components/HandsComponent.cs @@ -80,6 +80,12 @@ public sealed partial class HandsComponent : Component [DataField] public DisplacementData? HandDisplacement; + + /// + /// If false, hands cannot be stripped, and they do not show up in the stripping menu. + /// + [DataField] + public bool CanBeStripped = true; } [Serializable, NetSerializable] diff --git a/Content.Shared/Strip/SharedStrippableSystem.cs b/Content.Shared/Strip/SharedStrippableSystem.cs index a68bf755d4..e1c3d8ef0d 100644 --- a/Content.Shared/Strip/SharedStrippableSystem.cs +++ b/Content.Shared/Strip/SharedStrippableSystem.cs @@ -118,6 +118,9 @@ public abstract class SharedStrippableSystem : EntitySystem !Resolve(target, ref targetStrippable)) return; + if (!target.Comp.CanBeStripped) + return; + if (!_handsSystem.TryGetHand(target.Owner, handId, out var handSlot)) return; @@ -349,6 +352,9 @@ public abstract class SharedStrippableSystem : EntitySystem !Resolve(target, ref target.Comp)) return false; + if (!target.Comp.CanBeStripped) + return false; + if (user.Comp.ActiveHand == null) return false; @@ -449,6 +455,9 @@ public abstract class SharedStrippableSystem : EntitySystem if (!Resolve(target, ref target.Comp)) return false; + if (!target.Comp.CanBeStripped) + return false; + if (!_handsSystem.TryGetHand(target, handName, out var handSlot, target.Comp)) { _popupSystem.PopupCursor(Loc.GetString("strippable-component-item-slot-free-message", ("owner", Identity.Name(target, EntityManager, user)))); diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 54bd58af78..c65db8fe19 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -85,6 +85,7 @@ - type: Hands showInHands: false disableExplosionRecursion: true + canBeStripped: false - type: ComplexInteraction - type: IntrinsicRadioReceiver - type: IntrinsicRadioTransmitter From 052d7c4d2e77c1857d742427163ce34428286236 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 3 Oct 2024 00:13:04 +0000 Subject: [PATCH 82/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 1e5ad4afbc..6e273a5042 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,15 +1,4 @@ Entries: -- author: Timur2011 - changes: - - message: Space adders are now butcherable. - type: Add - - message: Snakes now drop snake meat when butchered. - type: Fix - - message: Snakes now appear lying when in critical state. - type: Tweak - id: 6980 - time: '2024-07-25T10:52:18.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29629 - author: Plykiya changes: - message: You can now build atmos gas pipes through things like walls. @@ -3945,3 +3934,10 @@ id: 7479 time: '2024-10-02T13:52:14.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32561 +- author: PJB3005 + changes: + - message: Fixed borg "hands" showing up in their stripping menu. + type: Fix + id: 7480 + time: '2024-10-03T00:11:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32606 From c68e5a667ccd2266f4c9f6580a71b1a6361f404b Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Thu, 3 Oct 2024 03:01:58 -0700 Subject: [PATCH 83/88] Various item contraband fixes (#32614) * fixes current contraband issues: xray cannon, hos's trench coats, stinger grenades * yet another contraband addition --- .../Prototypes/Entities/Clothing/OuterClothing/coats.yml | 6 +++--- .../Entities/Clothing/OuterClothing/wintercoats.yml | 4 ++-- .../Entities/Objects/Weapons/Guns/Battery/battery_guns.yml | 2 +- .../Entities/Objects/Weapons/Throwable/clusterbang.yml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml index 973af52221..21c91faadc 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml @@ -90,7 +90,7 @@ damageCoefficient: 0.9 - type: entity - parent: [ClothingOuterArmorHoS, ClothingOuterStorageBase] + parent: [ClothingOuterArmorHoS, ClothingOuterStorageBase, BaseSecurityCommandContraband] id: ClothingOuterCoatHoSTrench name: head of security's armored trenchcoat description: A greatcoat enhanced with a special alloy for some extra protection and style for those with a commanding presence. @@ -376,7 +376,7 @@ sprite: Clothing/OuterClothing/Coats/windbreaker_paramedic.rsi - type: entity - parent: ClothingOuterStorageBase + parent: [ClothingOuterStorageBase, BaseSyndicateContraband] id: ClothingOuterCoatSyndieCap name: syndicate's coat description: The syndicate's coat is made of durable fabric, with gilded patterns. @@ -387,7 +387,7 @@ sprite: Clothing/OuterClothing/Coats/syndicate/coatsyndiecap.rsi - type: entity - parent: ClothingOuterCoatHoSTrench + parent: [BaseSyndicateContraband, ClothingOuterCoatHoSTrench] # BaseSyndicateContraband as first parent so contraband system takes that as priority, yeah I know id: ClothingOuterCoatSyndieCapArmored name: syndicate's armored coat description: The syndicate's armored coat is made of durable fabric, with gilded patterns. diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml index e7f5a59472..4bf1ec87fd 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml @@ -359,7 +359,7 @@ ########################################################## - type: entity - parent: [ClothingOuterArmorHoS, ClothingOuterWinterCoatToggleable, BaseCommandContraband] + parent: [ClothingOuterArmorHoS, ClothingOuterWinterCoatToggleable, BaseSecurityCommandContraband] id: ClothingOuterWinterHoS name: head of security's armored winter coat description: A sturdy, utilitarian winter coat designed to protect a head of security from any brig-bound threats and hypothermic events. @@ -373,7 +373,7 @@ ########################################################## - type: entity - parent: [ClothingOuterWinterCoatToggleable, BaseCommandContraband] + parent: [ClothingOuterWinterCoatToggleable, BaseSecurityCommandContraband] id: ClothingOuterWinterHoSUnarmored name: head of security's winter coat description: A sturdy coat, a warm coat, but not an armored coat. diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml index 2241c4092a..92c952671f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Battery/battery_guns.yml @@ -380,7 +380,7 @@ - type: entity name: x-ray cannon - parent: [BaseWeaponBattery, BaseGunWieldable] + parent: [BaseWeaponBattery, BaseGunWieldable, BaseSecurityContraband] id: WeaponXrayCannon description: An experimental weapon that uses concentrated x-ray energy against its target. components: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/clusterbang.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/clusterbang.yml index b4f540ae53..b041349d26 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/clusterbang.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/clusterbang.yml @@ -116,7 +116,7 @@ cluster-payload: !type:Container - type: entity - parent: [GrenadeBase, BaseSyndicateContraband] + parent: [GrenadeBase, BaseSecurityContraband] id: GrenadeStinger name: stinger grenade description: Nothing to see here, please disperse. From 3e85d28e9d930ad509b22323666d210c70e24c8f Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 3 Oct 2024 10:03:05 +0000 Subject: [PATCH 84/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 6e273a5042..d3f37b4012 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: You can now build atmos gas pipes through things like walls. - type: Tweak - id: 6981 - time: '2024-07-25T23:26:06.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/28707 - author: Ilya246 changes: - message: Nuclear operative reinforcements now come with full nuclear operative @@ -3941,3 +3934,11 @@ id: 7480 time: '2024-10-03T00:11:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32606 +- author: ArtisticRoomba + changes: + - message: X-ray cannons and stinger grenades are now security restricted. HoS's + armored trench coat and its variants are security and command restricted. + type: Fix + id: 7481 + time: '2024-10-03T10:01:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32614 From bc76cd876f61839c519bf35bd09bb6a2f23b5c44 Mon Sep 17 00:00:00 2001 From: Vasilis Date: Thu, 3 Oct 2024 12:32:10 +0200 Subject: [PATCH 85/88] Remove sentience from clean and medi bot (#32383) There is no point in these silicon being sentient, they have basically zero role play potential and are not meant to be controlled by players. The janibot can be played somewhat but at that point we have janitor borgs which are way better at this. You can only clean floors and even then it does a terrible job at doing that and only that. A player playing as a janibot will get bored quickly. No amount of RP will save you. A player taking over a mediborg just makes it useless as you cant inject anymore. And again, medical borg. There's no point in adding the feature. It's too much work then its worth when we have borgs. They don't have ghost role info for a reason. They are not meant to be played. --- Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml index 7d988c6fe9..612e49baec 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml @@ -258,8 +258,6 @@ - type: Construction graph: CleanBot node: bot - - type: SentienceTarget - flavorKind: station-event-random-sentience-flavor-mechanical - type: Absorbent pickupAmount: 10 - type: UseDelay @@ -331,8 +329,6 @@ - type: Construction graph: MediBot node: bot - - type: SentienceTarget - flavorKind: station-event-random-sentience-flavor-mechanical - type: Anchorable - type: InteractionPopup interactSuccessString: petting-success-medibot From 568fb235fa3b4f7771b50216022a3dad2a7435bc Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 3 Oct 2024 10:33:16 +0000 Subject: [PATCH 86/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d3f37b4012..7fb7753bdb 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,4 @@ Entries: -- author: Ilya246 - changes: - - message: Nuclear operative reinforcements now come with full nuclear operative - gear (and a toy carp) at no additional cost. - type: Tweak - - message: Nuclear operative reinforcements now get nuclear operative names. - type: Tweak - id: 6982 - time: '2024-07-25T23:37:54.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30173 - author: Cojoke-dot changes: - message: Engineering goggles and other similar-looking eyewear now help block @@ -3942,3 +3932,11 @@ id: 7481 time: '2024-10-03T10:01:58.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32614 +- author: Myra + changes: + - message: Medibots and Janibots can no longer become sentient via the sentience + event. + type: Remove + id: 7482 + time: '2024-10-03T10:32:11.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32383 From a8982b88affc0d6c9b61fb9a59f46fab5614d5c2 Mon Sep 17 00:00:00 2001 From: eoineoineoin Date: Thu, 3 Oct 2024 15:01:01 +0100 Subject: [PATCH 87/88] Allow users to drag-reorder action bar (#32552) * Avoid rebuilding all buttons on action state change Allows for drag events to continue when actions change * Remove excess action buttons --------- Co-authored-by: Eoin Mcloughlin --- .../Systems/Actions/ActionUIController.cs | 4 --- .../Actions/Controls/ActionButtonContainer.cs | 34 +++++++++---------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs index 1dffeb8d2d..a6c1cfc94f 100644 --- a/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs +++ b/Content.Client/UserInterface/Systems/Actions/ActionUIController.cs @@ -398,10 +398,6 @@ public sealed class ActionUIController : UIController, IOnStateChanged (ActionButton) GetChild(index); } - private void BuildActionButtons(int count) + public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes) { + var uniqueCount = Math.Min(system.GetClientActions().Count(), actionTypes.Length + 1); var keys = ContentKeyFunctions.GetHotbarBoundKeys(); - Children.Clear(); - for (var index = 0; index < count; index++) + for (var i = 0; i < uniqueCount; i++) { - Children.Add(MakeButton(index)); + if (i >= ChildCount) + { + AddChild(MakeButton(i)); + } + + if (!actionTypes.TryGetValue(i, out var action)) + action = null; + ((ActionButton) GetChild(i)).UpdateData(action, system); + } + + for (var i = ChildCount - 1; i >= uniqueCount; i--) + { + RemoveChild(GetChild(i)); } ActionButton MakeButton(int index) @@ -55,20 +67,6 @@ public class ActionButtonContainer : GridContainer } } - public void SetActionData(ActionsSystem system, params EntityUid?[] actionTypes) - { - var uniqueCount = Math.Min(system.GetClientActions().Count(), actionTypes.Length + 1); - if (ChildCount != uniqueCount) - BuildActionButtons(uniqueCount); - - for (var i = 0; i < uniqueCount; i++) - { - if (!actionTypes.TryGetValue(i, out var action)) - action = null; - ((ActionButton) GetChild(i)).UpdateData(action, system); - } - } - public void ClearActionData() { foreach (var button in Children) From 1c41d3381f7127a73b6ef51a535838aeb0217858 Mon Sep 17 00:00:00 2001 From: PJBot Date: Thu, 3 Oct 2024 14:02:07 +0000 Subject: [PATCH 88/88] Automatic changelog update --- Resources/Changelog/Changelog.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 7fb7753bdb..1c6155ae0a 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: Engineering goggles and other similar-looking eyewear now help block - identity. - type: Tweak - - message: Radiation suit's hood now blocks identity. - type: Fix - id: 6983 - time: '2024-07-26T05:26:05.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/30305 - author: Moomoobeef changes: - message: Some radio channel colors have been tweaked in order to be more easily @@ -3940,3 +3930,10 @@ id: 7482 time: '2024-10-03T10:32:11.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32383 +- author: eoineoineoin + changes: + - message: Action bar can be reconfigured again + type: Fix + id: 7483 + time: '2024-10-03T14:01:01.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32552