From 8c8ccc9625b45a1c5cd50e03a3d14bb73ed5eae9 Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Fri, 24 Jul 2026 00:34:05 -0700 Subject: [PATCH 01/35] Fix not being able to stack atmos devices (#44886) --- .../Recipes/Construction/atmospherics.yml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Resources/Prototypes/Recipes/Construction/atmospherics.yml b/Resources/Prototypes/Recipes/Construction/atmospherics.yml index 4d8554d74c..d0a6b0b584 100644 --- a/Resources/Prototypes/Recipes/Construction/atmospherics.yml +++ b/Resources/Prototypes/Recipes/Construction/atmospherics.yml @@ -22,6 +22,13 @@ conditions: - !type:NoUnstackableInTile +# we allow stacking for shit like radiators on top of atmosdevices +# for now (trademark patent pending) +- type: construction + abstract: true + parent: BaseAtmos + id: BaseGasDeviceStackable + - type: construction abstract: true parent: BaseGasDevice @@ -35,6 +42,13 @@ graph: GasBinary placementMode: AlignAtmosPipeLayers # most binary devices support layers +- type: construction + abstract: true + parent: BaseGasDeviceStackable + id: BaseGasBinaryStackable + graph: GasBinary + placementMode: AlignAtmosPipeLayers + - type: construction abstract: true parent: BaseGasDevice @@ -370,13 +384,13 @@ placementMode: SnapgridCenter - type: construction - parent: BaseGasBinary + parent: BaseGasBinaryStackable id: HeatExchanger targetNode: radiator placementMode: SnapgridCenter - type: construction - parent: BaseGasBinary + parent: BaseGasBinaryStackable id: HeatExchangerBend name: construction-recipe-heat-exchanger-bend targetNode: bendradiator From 6f26e69ef9a008e811814ea8a5b684ab202fab04 Mon Sep 17 00:00:00 2001 From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Sat, 25 Jul 2026 21:30:43 +0200 Subject: [PATCH 02/35] Fix windoors not closing if an entity is on the same tile yet not touching the windoor (#44081) * fix the thing to be good :) * Review changes * The curse of doing review comments in order --- .../Doors/Components/DoorComponent.cs | 14 ++++++ .../Doors/Systems/SharedDoorSystem.cs | 48 ++++++++++++++----- .../Doors/Windoors/base_structurewindoors.yml | 2 + 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/Content.Shared/Doors/Components/DoorComponent.cs b/Content.Shared/Doors/Components/DoorComponent.cs index 714e45b604..d7926b8be4 100644 --- a/Content.Shared/Doors/Components/DoorComponent.cs +++ b/Content.Shared/Doors/Components/DoorComponent.cs @@ -301,6 +301,20 @@ public sealed partial class DoorComponent : Component [DataField] public bool ClickOpen = true; + /// + /// If true, the door closing check will try to match only entities intersecting the door's first fixture. + /// If false, the door will check the full tile the door is on. + /// + [DataField] + public bool CheckFixtureCollision; + + /// + /// If true, the door will be able to close over entities with the MachineLayer fixture layer. + /// Useful for windoors or other thin doors. + /// + [DataField] + public bool AllowMachineLayer; + [DataField(customTypeSerializer: typeof(ConstantSerializer))] public int OpenDrawDepth = (int) DrawDepth.DrawDepth.Doors; diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index ed82ebae97..cd6382c403 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -23,7 +23,9 @@ using Robust.Shared.Timing; using Robust.Shared.Audio.Systems; using Robust.Shared.Network; using Robust.Shared.Map.Components; +using Robust.Shared.Physics; using Robust.Shared.Prototypes; +using Robust.Shared.Utility; namespace Content.Shared.Doors.Systems; @@ -54,8 +56,6 @@ public abstract partial class SharedDoorSystem : EntitySystem /// private readonly HashSet> _activeDoors = new(); - private readonly HashSet> _doorIntersecting = new(); - public override void Initialize() { base.Initialize(); @@ -450,7 +450,7 @@ public abstract partial class SharedDoorSystem : EntitySystem if (!HasAccess(uid, user, door)) return false; - return !ev.PerformCollisionCheck || !GetColliding(uid).Any(); + return !ev.PerformCollisionCheck || !GetColliding(uid, null, null, door.CheckFixtureCollision, door.PerformCollisionCheck).Any(); } public void StartClosing(EntityUid uid, DoorComponent? door = null, EntityUid? user = null, bool predicted = false) @@ -522,7 +522,7 @@ public abstract partial class SharedDoorSystem : EntitySystem } /// - /// Crushes everyone colliding with us by more than %. + /// Crushes everyone colliding with the door. /// public void Crush(EntityUid uid, DoorComponent? door = null, PhysicsComponent? physics = null) { @@ -532,9 +532,9 @@ public abstract partial class SharedDoorSystem : EntitySystem if (!door.CanCrush) return; - // Find entities and apply curshing effects + // Find entities and apply crushing effects var stunTime = door.DoorStunTime + door.OpenTimeOne; - foreach (var entity in GetColliding(uid, physics)) + foreach (var entity in GetColliding(uid, physics, null, door.CheckFixtureCollision, door.AllowMachineLayer)) { door.CurrentlyCrushing.Add(entity); if (door.CrushDamage != null) @@ -552,11 +552,17 @@ public abstract partial class SharedDoorSystem : EntitySystem } /// - /// Get all entities that collide with this door by more than percent.\ + /// Checks if there are any entities colliding with the door, passing them back out to use e.g. to prevent closing. /// - public IEnumerable GetColliding(EntityUid uid, PhysicsComponent? physics = null) + /// The door entity to check. + /// The door's . + /// If true, the door will do a more exact check based on its first fixture. + /// The door's . + /// The door will be able to close over . + /// The list of entities inside the door. + public IEnumerable GetColliding(EntityUid uid, PhysicsComponent? physics = null, FixturesComponent? fixtures = null, bool checkFixtureCollision = false, bool allowMachineLayer = false) { - if (!Resolve(uid, ref physics)) + if (!Resolve(uid, ref physics) || !Resolve(uid, ref fixtures)) yield break; var xform = Transform(uid); @@ -566,13 +572,27 @@ public abstract partial class SharedDoorSystem : EntitySystem yield break; var tileRef = _mapSystem.GetTileRef(xform.GridUid.Value, mapGridComp, xform.Coordinates); - _doorIntersecting.Clear(); - _entityLookup.GetLocalEntitiesIntersecting(xform.GridUid.Value, tileRef.GridIndices, _doorIntersecting, gridComp: mapGridComp, flags: (LookupFlags.All & ~LookupFlags.Sensors)); + var doorIntersecting = new HashSet>(); + + if (checkFixtureCollision && fixtures.Fixtures.TryFirstOrNull(out var fixture)) + { + var fixtureToWorld = PhysicsSystem.GetPhysicsTransform(uid, xform); + + _entityLookup.GetEntitiesIntersecting(xform.MapID, + fixture.Value.Value.Shape, + fixtureToWorld, + doorIntersecting, + flags: LookupFlags.All & ~(LookupFlags.Sensors | LookupFlags.Contained)); + } + else + { + _entityLookup.GetLocalEntitiesIntersecting(xform.GridUid.Value, tileRef.GridIndices, doorIntersecting, gridComp: mapGridComp, flags: LookupFlags.All & ~(LookupFlags.Sensors | LookupFlags.Contained)); + } // TODO SLOTH fix electro's code. // ReSharper disable once InconsistentNaming - foreach (var otherPhysics in _doorIntersecting) + foreach (var otherPhysics in doorIntersecting) { if (otherPhysics.Comp == physics) continue; @@ -593,6 +613,10 @@ public abstract partial class SharedDoorSystem : EntitySystem if (otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.ConveyorMask) continue; + // We want windoors to be able to close over machines + if (allowMachineLayer && otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.MachineLayer) + continue; + if ((physics.CollisionMask & otherPhysics.Comp.CollisionLayer) == 0 && (otherPhysics.Comp.CollisionMask & physics.CollisionLayer) == 0) continue; diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml index eed3cd6f15..86d0d2bc8b 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml @@ -107,6 +107,8 @@ path: /Audio/Machines/windoor_open.ogg denySound: path: /Audio/Machines/airlock_deny.ogg + checkFixtureCollision: true + allowMachineLayer: true - type: Airlock keepOpenIfClicked: true openPanelVisible: true From d158047dfda051d8e8f06b281edc0e991f897ba6 Mon Sep 17 00:00:00 2001 From: Mehnix <56132549+Mehnix@users.noreply.github.com> Date: Sat, 25 Jul 2026 22:08:19 +0100 Subject: [PATCH 03/35] Artifact trigger continuation popup (#44909) * Continuation popup * Update from Comments Whitespace Remove server conditions * refactor: xml-doc dots, whitespaces, minor cleanups --------- Co-authored-by: Fildrance --- .../Components/XenoArtifactComponent.cs | 24 +++++++++++++++++++ .../SharedXenoArtifactSystem.Unlock.cs | 10 ++++---- .../Artifact/SharedXenoArtifactSystem.XAT.cs | 8 +++++-- .../xenoarchaeology/artifact-component.ftl | 1 + 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Content.Shared/Xenoarchaeology/Artifact/Components/XenoArtifactComponent.cs b/Content.Shared/Xenoarchaeology/Artifact/Components/XenoArtifactComponent.cs index ce037c7c2e..144dccc546 100644 --- a/Content.Shared/Xenoarchaeology/Artifact/Components/XenoArtifactComponent.cs +++ b/Content.Shared/Xenoarchaeology/Artifact/Components/XenoArtifactComponent.cs @@ -166,6 +166,30 @@ public sealed partial class XenoArtifactComponent : Component /// [DataField] public EntProtoId SelfActivateAction = "ActionArtifactActivate"; + + /// + /// Message shown on artifact unlock beginning. + /// + [DataField] + public LocId? UnlockBeginMsg = "artifact-unlock-state-begin"; + + /// + /// Message shown on trigger being applied successfully whilst the artifact is unlocking. + /// + [DataField] + public LocId? UnlockContinueMsg = "artifact-unlock-state-continue"; + + /// + /// Message shown on artifact unlocking ending successfully. + /// + [DataField] + public LocId? UnlockSuccessMsg = "artifact-unlock-state-end-success"; + + /// + /// Message shown on artifact unlocking ending with failure. + /// + [DataField] + public LocId? UnlockFailureMsg = "artifact-unlock-state-end-failure"; } /// diff --git a/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.Unlock.cs b/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.Unlock.cs index e521e93a4e..b2be023a83 100644 --- a/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.Unlock.cs +++ b/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.Unlock.cs @@ -65,7 +65,7 @@ public abstract partial class SharedXenoArtifactSystem /// public void FinishUnlockingState(Entity ent) { - string unlockAttemptResultMsg; + string? unlockAttemptResultMsg; XenoArtifactComponent artifactComponent = ent; XenoArtifactUnlockingComponent unlockingComponent = ent; @@ -74,7 +74,7 @@ public abstract partial class SharedXenoArtifactSystem { SetNodeUnlocked((ent, artifactComponent), node.Value); ActivateNode((ent, ent), (node.Value, node.Value), null, null, Transform(ent).Coordinates, false); - unlockAttemptResultMsg = "artifact-unlock-state-end-success"; + unlockAttemptResultMsg = artifactComponent.UnlockSuccessMsg; // as an experiment - unlocking node doesn't activate it, activation is left for player to decide. // var activated = ActivateNode((ent, artifactComponent), node.Value, null, null, Transform(ent).Coordinates, false); @@ -83,13 +83,15 @@ public abstract partial class SharedXenoArtifactSystem } else { - unlockAttemptResultMsg = "artifact-unlock-state-end-failure"; + unlockAttemptResultMsg = artifactComponent.UnlockFailureMsg; soundEffect = unlockingComponent.UnlockActivationFailedSound; } if (_net.IsServer) { - _popup.PopupEntity(Loc.GetString(unlockAttemptResultMsg), ent); + if (unlockAttemptResultMsg != null) + _popup.PopupEntity(Loc.GetString(unlockAttemptResultMsg), ent); + _audio.PlayPvs(soundEffect, ent.Owner); } diff --git a/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.XAT.cs b/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.XAT.cs index 4d9e2e6df4..e8573d2a2a 100644 --- a/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.XAT.cs +++ b/Content.Shared/Xenoarchaeology/Artifact/SharedXenoArtifactSystem.XAT.cs @@ -70,8 +70,9 @@ public abstract partial class SharedXenoArtifactSystem unlockingComp.EndTime = _timing.CurTime + ent.Comp.UnlockStateDuration; Log.Debug($"{ToPrettyString(ent)} entered unlocking state"); - if (_net.IsServer) - _popup.PopupEntity(Loc.GetString("artifact-unlock-state-begin"), ent); + if (ent.Comp.UnlockBeginMsg != null) + _popup.PopupEntity(Loc.GetString(ent.Comp.UnlockBeginMsg), ent); + Dirty(ent); } else if (node != null) @@ -87,6 +88,9 @@ public abstract partial class SharedXenoArtifactSystem ) // we add time on each new trigger, if it is not going to fail us unlockingComp.EndTime += ent.Comp.UnlockStateIncrementPerNode; + + if (ent.Comp.UnlockContinueMsg != null) + _popup.PopupEntity(Loc.GetString(ent.Comp.UnlockContinueMsg), ent); } if (node != null && unlockingComp.TriggeredNodeIndexes.Add(GetIndex(ent, node.Value))) diff --git a/Resources/Locale/en-US/xenoarchaeology/artifact-component.ftl b/Resources/Locale/en-US/xenoarchaeology/artifact-component.ftl index 90029b282c..c131be8859 100644 --- a/Resources/Locale/en-US/xenoarchaeology/artifact-component.ftl +++ b/Resources/Locale/en-US/xenoarchaeology/artifact-component.ftl @@ -4,6 +4,7 @@ artifact-verb-activate = Activate artifact ### Unlocking artifact-unlock-state-begin = It begins to shift in strange ways... +artifact-unlock-state-continue = The shifting continues, intensifying... artifact-unlock-state-end-success = It slows down, visibly changed. artifact-unlock-state-end-failure = It slows down before uneventfully stopping. From 7a8fab78e3b8178f811c3dd3b244c141578493c6 Mon Sep 17 00:00:00 2001 From: Pok <113675512+Pok27@users.noreply.github.com> Date: Sun, 26 Jul 2026 01:29:39 +0300 Subject: [PATCH 04/35] Move Accents to Shared v2 (#44772) * move-accents-to-shared * Update AccentSystem.cs * Update ListeningSystem.cs * aaaaaa * Update AccentSystem.cs * oh god * aaooao * // * review * fix * Update VocalSystem.cs --- Content.Client/Entry/EntryPoint.cs | 1 - .../DamagedSiliconAccentSystem.cs | 5 + .../EntitySystems/RatvarianLanguageSystem.cs | 8 -- .../Speech/EntitySystems/SlurredSystem.cs | 12 -- .../Speech/EntitySystems/StutteringSystem.cs | 12 -- .../Administration/Commands/OwoifyCommand.cs | 3 +- .../Systems/AdminVerbSystem.Smites.cs | 2 - .../Chat/Systems/ChatSystem.Utility.cs | 2 +- Content.Server/Chat/Systems/ChatSystem.cs | 2 +- .../Cloning/CloningSystem.Subscriptions.cs | 2 +- Content.Server/Cluwne/CluwneSystem.cs | 4 +- .../Electrocution/ElectrocutionSystem.cs | 2 +- .../Effects/MakeSentientEntityEffectSystem.cs | 2 +- .../GameTicking/GameTicker.Spawning.cs | 2 - .../Components/BackwardsAccentComponent.cs | 6 - .../Speech/Components/BarkAccentComponent.cs | 6 - .../Components/BleatingAccentComponent.cs | 9 -- .../Components/BlockListeningComponent.cs | 11 -- .../Speech/Components/FrontalLispComponent.cs | 6 - .../Components/GermanAccentComponent.cs | 6 - .../Components/LizardAccentComponent.cs | 9 -- .../Components/MobsterAccentComponent.cs | 17 --- .../Components/MonkeyAccentComponent.cs | 6 - .../Speech/Components/MothAccentComponent.cs | 9 -- .../Speech/Components/OwOAccentComponent.cs | 6 - .../Components/ReplacementAccentComponent.cs | 16 --- .../Components/RussianAccentComponent.cs | 6 - .../Components/ScrambledAccentComponent.cs | 6 - .../Components/SkeletonAccentComponent.cs | 16 --- .../Speech/Components/SlowAccentComponent.cs | 9 -- .../Components/SouthernAccentComponent.cs | 8 -- .../Components/SpanishAccentComponent.cs | 6 - .../Components/UnblockableSpeechComponent.cs | 7 - .../Speech/EntitySystems/BarkAccentSystem.cs | 33 ----- .../EntitySystems/BlockListeningSystem.cs | 19 --- .../DamagedSiliconAccentSystem.cs | 108 +-------------- .../Speech/EntitySystems/FrontalLispSystem.cs | 26 ---- .../Speech/EntitySystems/MeleeSpeechSystem.cs | 82 ----------- .../Speech/EntitySystems/OwOAccentSystem.cs | 31 ----- .../EntitySystems/RatvarianLanguageSystem.cs | 14 -- .../EntitySystems/SpeakOnActionSystem.cs | 39 ------ .../Speech/EntitySystems/StutteringSystem.cs | 75 ----------- .../EntitySystems/UnblockableSpeechSystem.cs | 18 --- .../Speech/EntitySystems/VocalSystem.cs | 127 ------------------ .../EntitySystems/VoiceOverrideSystem.cs | 22 --- .../{Components => }/ListenWireAction.cs | 4 +- Content.Server/Speech/Muting/MutingSystem.cs | 2 +- Content.Server/Speech/SpeechNoiseSystem.cs | 74 ---------- .../{Components => }/SpeechWireAction.cs | 0 .../SurveillanceCameraSpeakerSystem.cs | 4 +- Content.Server/Telephone/TelephoneSystem.cs | 1 + Content.Server/VoiceMask/VoiceMaskSystem.cs | 2 +- .../Zombies/ZombieSystem.Transform.cs | 24 ++-- Content.Server/Zombies/ZombieSystem.cs | 2 +- Content.Shared/Chat/EmotesEvents.cs | 8 +- Content.Shared/Chat/SharedChatSystem.Emote.cs | 8 +- Content.Shared/Chat/SharedChatSystem.cs | 1 - Content.Shared/Speech/AccentEvent.cs | 8 +- .../Components/ActiveListenerComponent.cs | 4 +- .../Components/AllCapsAccentComponent.cs | 6 +- .../Components/BackwardsAccentComponent.cs | 11 ++ .../Speech/Components/BarkAccentComponent.cs | 11 ++ .../Components/BleatingAccentComponent.cs | 12 ++ .../Components/BlockListeningComponent.cs | 9 ++ .../DamagedSiliconAccentComponent.cs | 40 +++--- .../Components/FrenchAccentComponent.cs | 8 +- .../Speech/Components/FrontalLispComponent.cs | 11 ++ .../Components/GermanAccentComponent.cs | 11 ++ .../Components/LizardAccentComponent.cs | 11 ++ .../Speech/Components/MeleeSpeechComponent.cs | 33 ++--- .../Components/MobsterAccentComponent.cs | 18 +++ .../Components/MonkeyAccentComponent.cs | 11 ++ .../Speech/Components/MothAccentComponent.cs | 11 ++ .../Components/MumbleAccentComponent.cs | 11 +- .../Speech/Components/OwOAccentComponent.cs | 11 ++ .../Components/ParrotAccentComponent.cs | 14 +- .../Components/PirateAccentComponent.cs | 14 +- .../Components/RatvarianLanguageComponent.cs | 4 +- .../Components/ReplacementAccentComponent.cs | 17 +++ .../Components/RussianAccentComponent.cs | 11 ++ .../Components/ScrambledAccentComponent.cs | 11 ++ .../Components/SkeletonAccentComponent.cs | 18 +++ .../Speech/Components/SlowAccentComponent.cs | 11 ++ .../Components/SlurredAccentComponent.cs | 20 ++- .../Components/SouthernAccentComponent.cs | 11 ++ .../Components/SpanishAccentComponent.cs | 11 ++ .../Components/SpeakOnActionComponent.cs | 3 +- .../Components/StutteringAccentComponent.cs | 5 + .../Components/UnblockableSpeechComponent.cs | 11 ++ .../Speech/Components/VocalComponent.cs | 8 +- .../Components/VoiceOverrideComponent.cs | 10 +- .../Speech/EntitySystems}/AccentSystem.cs | 11 +- .../EntitySystems/BackwardsAccentSystem.cs | 5 +- .../Speech/EntitySystems/BarkAccentSystem.cs | 43 ++++++ .../EntitySystems/BleatingAccentSystem.cs | 5 +- .../EntitySystems/BlockListeningSystem.cs | 12 ++ .../EntitySystems/EmoteBlockerSystem.cs | 14 +- .../Speech/EntitySystems}/EmotesMenuSystem.cs | 5 +- .../EntitySystems/FrenchAccentSystem.cs | 24 ++-- .../Speech/EntitySystems/FrontalLispSystem.cs | 25 ++++ .../EntitySystems/GermanAccentSystem.cs | 19 ++- .../Speech/EntitySystems/ListeningSystem.cs | 18 +-- .../EntitySystems/LizardAccentSystem.cs | 5 +- .../Speech/EntitySystems/MeleeSpeechSystem.cs | 85 ++++++++++++ .../EntitySystems/MobsterAccentSystem.cs | 28 ++-- .../EntitySystems/MonkeyAccentSystem.cs | 18 ++- .../Speech/EntitySystems/MothAccentSystem.cs | 9 +- .../EntitySystems/MumbleAccentSystem.cs | 12 +- .../Speech/EntitySystems/OwOAccentSystem.cs | 42 ++++++ .../EntitySystems/ParrotAccentSystem.cs | 38 +++--- .../EntitySystems/PirateAccentSystem.cs | 25 ++-- ...geSystem.cs => RatvarianLanguageSystem.cs} | 28 ++-- .../EntitySystems/ReplacementAccentSystem.cs | 58 +++++--- .../EntitySystems/RussianAccentSystem.cs | 8 +- .../EntitySystems/ScrambledAccentSystem.cs | 16 ++- .../SharedDamagedSiliconAccentSystem.cs | 122 +++++++++++++++++ .../EntitySystems/SharedMeleeSpeechSystem.cs | 7 - .../EntitySystems/SharedSlurredSystem.cs | 12 -- .../SharedSpeakOnActionSystem.cs | 13 -- .../EntitySystems/SharedStutteringSystem.cs | 25 ---- .../EntitySystems/SkeletonAccentSystem.cs | 26 ++-- .../Speech/EntitySystems/SlowAccentSystem.cs | 5 +- .../Speech/EntitySystems/SlurredSystem.cs | 79 +++++------ .../EntitySystems/SouthernAccentSystem.cs | 7 +- .../EntitySystems/SpanishAccentSystem.cs | 6 +- .../EntitySystems/SpeakOnActionSystem.cs | 26 ++++ .../Speech/EntitySystems/SpeechNoiseSystem.cs | 70 ++++++++++ .../Speech/EntitySystems/StutteringSystem.cs | 73 ++++++++++ .../EntitySystems/UnblockableSpeechSystem.cs | 13 ++ .../Speech/EntitySystems/VocalSystem.cs | 124 +++++++++++++++++ .../EntitySystems/VoiceOverrideSystem.cs | 17 +++ ...istenWireAction.cs => ListenWireAction.cs} | 0 .../Prototypes/ReplacementAccentPrototype.cs | 8 +- ...peechWireAction.cs => SpeechWireAction.cs} | 0 134 files changed, 1289 insertions(+), 1261 deletions(-) create mode 100644 Content.Client/Speech/EntitySystems/DamagedSiliconAccentSystem.cs delete mode 100644 Content.Client/Speech/EntitySystems/RatvarianLanguageSystem.cs delete mode 100644 Content.Client/Speech/EntitySystems/SlurredSystem.cs delete mode 100644 Content.Client/Speech/EntitySystems/StutteringSystem.cs delete mode 100644 Content.Server/Speech/Components/BackwardsAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/BarkAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/BleatingAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/BlockListeningComponent.cs delete mode 100644 Content.Server/Speech/Components/FrontalLispComponent.cs delete mode 100644 Content.Server/Speech/Components/GermanAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/LizardAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/MobsterAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/MonkeyAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/MothAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/OwOAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/ReplacementAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/RussianAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/ScrambledAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/SkeletonAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/SlowAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/SouthernAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/SpanishAccentComponent.cs delete mode 100644 Content.Server/Speech/Components/UnblockableSpeechComponent.cs delete mode 100644 Content.Server/Speech/EntitySystems/BarkAccentSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/BlockListeningSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/FrontalLispSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/OwOAccentSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/RatvarianLanguageSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/StutteringSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/VocalSystem.cs delete mode 100644 Content.Server/Speech/EntitySystems/VoiceOverrideSystem.cs rename Content.Server/Speech/{Components => }/ListenWireAction.cs (98%) delete mode 100644 Content.Server/Speech/SpeechNoiseSystem.cs rename Content.Server/Speech/{Components => }/SpeechWireAction.cs (100%) create mode 100644 Content.Shared/Speech/Components/BackwardsAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/BarkAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/BleatingAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/BlockListeningComponent.cs rename {Content.Server => Content.Shared}/Speech/Components/FrenchAccentComponent.cs (60%) create mode 100644 Content.Shared/Speech/Components/FrontalLispComponent.cs create mode 100644 Content.Shared/Speech/Components/GermanAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/LizardAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/MobsterAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/MonkeyAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/MothAccentComponent.cs rename {Content.Server => Content.Shared}/Speech/Components/MumbleAccentComponent.cs (63%) create mode 100644 Content.Shared/Speech/Components/OwOAccentComponent.cs rename {Content.Server => Content.Shared}/Speech/Components/ParrotAccentComponent.cs (84%) rename {Content.Server => Content.Shared}/Speech/Components/PirateAccentComponent.cs (61%) create mode 100644 Content.Shared/Speech/Components/ReplacementAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/RussianAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/ScrambledAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/SkeletonAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/SlowAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/SouthernAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/SpanishAccentComponent.cs create mode 100644 Content.Shared/Speech/Components/UnblockableSpeechComponent.cs rename {Content.Server => Content.Shared}/Speech/Components/VoiceOverrideComponent.cs (82%) rename {Content.Server/Speech => Content.Shared/Speech/EntitySystems}/AccentSystem.cs (67%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/BackwardsAccentSystem.cs (70%) create mode 100644 Content.Shared/Speech/EntitySystems/BarkAccentSystem.cs rename {Content.Server => Content.Shared}/Speech/EntitySystems/BleatingAccentSystem.cs (79%) create mode 100644 Content.Shared/Speech/EntitySystems/BlockListeningSystem.cs rename {Content.Server/Speech => Content.Shared/Speech/EntitySystems}/EmotesMenuSystem.cs (83%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/FrenchAccentSystem.cs (71%) create mode 100644 Content.Shared/Speech/EntitySystems/FrontalLispSystem.cs rename {Content.Server => Content.Shared}/Speech/EntitySystems/GermanAccentSystem.cs (82%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/ListeningSystem.cs (80%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/LizardAccentSystem.cs (88%) create mode 100644 Content.Shared/Speech/EntitySystems/MeleeSpeechSystem.cs rename {Content.Server => Content.Shared}/Speech/EntitySystems/MobsterAccentSystem.cs (83%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/MonkeyAccentSystem.cs (72%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/MothAccentSystem.cs (59%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/MumbleAccentSystem.cs (79%) create mode 100644 Content.Shared/Speech/EntitySystems/OwOAccentSystem.cs rename {Content.Server => Content.Shared}/Speech/EntitySystems/ParrotAccentSystem.cs (62%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/PirateAccentSystem.cs (60%) rename Content.Shared/Speech/EntitySystems/{SharedRatvarianLanguageSystem.cs => RatvarianLanguageSystem.cs} (87%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/ReplacementAccentSystem.cs (77%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/RussianAccentSystem.cs (84%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/ScrambledAccentSystem.cs (67%) create mode 100644 Content.Shared/Speech/EntitySystems/SharedDamagedSiliconAccentSystem.cs delete mode 100644 Content.Shared/Speech/EntitySystems/SharedMeleeSpeechSystem.cs delete mode 100644 Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs delete mode 100644 Content.Shared/Speech/EntitySystems/SharedSpeakOnActionSystem.cs delete mode 100644 Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs rename {Content.Server => Content.Shared}/Speech/EntitySystems/SkeletonAccentSystem.cs (52%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/SlowAccentSystem.cs (87%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/SlurredSystem.cs (53%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/SouthernAccentSystem.cs (89%) rename {Content.Server => Content.Shared}/Speech/EntitySystems/SpanishAccentSystem.cs (94%) create mode 100644 Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs create mode 100644 Content.Shared/Speech/EntitySystems/SpeechNoiseSystem.cs create mode 100644 Content.Shared/Speech/EntitySystems/StutteringSystem.cs create mode 100644 Content.Shared/Speech/EntitySystems/UnblockableSpeechSystem.cs create mode 100644 Content.Shared/Speech/EntitySystems/VocalSystem.cs create mode 100644 Content.Shared/Speech/EntitySystems/VoiceOverrideSystem.cs rename Content.Shared/Speech/{EntitySystems/SharedListenWireAction.cs => ListenWireAction.cs} (100%) rename {Content.Server => Content.Shared}/Speech/Prototypes/ReplacementAccentPrototype.cs (61%) rename Content.Shared/Speech/{EntitySystems/SharedSpeechWireAction.cs => SpeechWireAction.cs} (100%) diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index 74f693c890..29ff0e85aa 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -107,7 +107,6 @@ namespace Content.Client.Entry _prototypeManager.RegisterIgnore("utilityQuery"); _prototypeManager.RegisterIgnore("utilityCurvePreset"); - _prototypeManager.RegisterIgnore("accent"); _prototypeManager.RegisterIgnore("gasReaction"); _prototypeManager.RegisterIgnore("seed"); // Seeds prototypes are server-only. _prototypeManager.RegisterIgnore("objective"); diff --git a/Content.Client/Speech/EntitySystems/DamagedSiliconAccentSystem.cs b/Content.Client/Speech/EntitySystems/DamagedSiliconAccentSystem.cs new file mode 100644 index 0000000000..36368b62bf --- /dev/null +++ b/Content.Client/Speech/EntitySystems/DamagedSiliconAccentSystem.cs @@ -0,0 +1,5 @@ +using Content.Shared.Speech.EntitySystems; + +namespace Content.Client.Speech.EntitySystems; + +public sealed class DamagedSiliconAccentSystem : SharedDamagedSiliconAccentSystem; diff --git a/Content.Client/Speech/EntitySystems/RatvarianLanguageSystem.cs b/Content.Client/Speech/EntitySystems/RatvarianLanguageSystem.cs deleted file mode 100644 index f24194a597..0000000000 --- a/Content.Client/Speech/EntitySystems/RatvarianLanguageSystem.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Content.Shared.Speech.EntitySystems; - -namespace Content.Client.Speech.EntitySystems; - -public sealed class RatvarianLanguageSystem : SharedRatvarianLanguageSystem -{ - -} diff --git a/Content.Client/Speech/EntitySystems/SlurredSystem.cs b/Content.Client/Speech/EntitySystems/SlurredSystem.cs deleted file mode 100644 index a4bb677edf..0000000000 --- a/Content.Client/Speech/EntitySystems/SlurredSystem.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Content.Shared.Speech.Components; -using Content.Shared.Speech.EntitySystems; - -namespace Content.Client.Speech.EntitySystems; - -public sealed class SlurredSystem : SharedSlurredSystem -{ - public override string Accentuate(string message, Entity? ent = null) - { - return message; - } -} diff --git a/Content.Client/Speech/EntitySystems/StutteringSystem.cs b/Content.Client/Speech/EntitySystems/StutteringSystem.cs deleted file mode 100644 index 9c98df4588..0000000000 --- a/Content.Client/Speech/EntitySystems/StutteringSystem.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Content.Shared.Speech.Components; -using Content.Shared.Speech.EntitySystems; - -namespace Content.Client.Speech.EntitySystems; - -public sealed class StutteringSystem : SharedStutteringSystem -{ - public override string Accentuate(string message, Entity? ent = null) - { - return message; - } -} diff --git a/Content.Server/Administration/Commands/OwoifyCommand.cs b/Content.Server/Administration/Commands/OwoifyCommand.cs index dcb9b4bcce..2acc7fadac 100644 --- a/Content.Server/Administration/Commands/OwoifyCommand.cs +++ b/Content.Server/Administration/Commands/OwoifyCommand.cs @@ -1,7 +1,6 @@ -using Content.Server.Speech.EntitySystems; using Content.Shared.Administration; +using Content.Shared.Speech.EntitySystems; using Robust.Shared.Console; -using Robust.Shared.Random; namespace Content.Server.Administration.Commands; diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs index 3dee9db3a9..a114c5f112 100644 --- a/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs +++ b/Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs @@ -13,14 +13,12 @@ using Content.Server.Pointing.Components; using Content.Server.Polymorph.Systems; using Content.Server.Popups; using Content.Server.Roles; -using Content.Server.Speech.Components; using Content.Shared.Speech.Components; using Content.Server.Storage.EntitySystems; using Content.Server.Tabletop; using Content.Shared.Actions; using Content.Shared.Administration; using Content.Shared.Administration.Components; -using Content.Shared.Administration.Systems; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; using Content.Shared.Body; diff --git a/Content.Server/Chat/Systems/ChatSystem.Utility.cs b/Content.Server/Chat/Systems/ChatSystem.Utility.cs index fc24e75cc7..b1eba9f856 100644 --- a/Content.Server/Chat/Systems/ChatSystem.Utility.cs +++ b/Content.Server/Chat/Systems/ChatSystem.Utility.cs @@ -1,9 +1,9 @@ using System.Linq; using System.Text; -using Content.Server.Speech.Prototypes; using Content.Shared.Chat; using Content.Shared.Ghost; using Content.Shared.Players; +using Content.Shared.Speech.Prototypes; using Robust.Shared.Console; using Robust.Shared.Network; using Robust.Shared.Player; diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 5432b552e5..fbbe41310b 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -3,7 +3,6 @@ using Content.Server.Administration.Logs; using Content.Server.Administration.Managers; using Content.Server.Chat.Managers; using Content.Server.GameTicking; -using Content.Server.Speech.EntitySystems; using Content.Server.Station.Systems; using Content.Shared.ActionBlocker; using Content.Shared.Administration; @@ -13,6 +12,7 @@ using Content.Shared.Examine; using Content.Shared.Ghost; using Content.Shared.Mobs.Systems; using Content.Shared.Players.RateLimiting; +using Content.Shared.Speech.EntitySystems; using Robust.Server.Player; using Robust.Shared.Audio.Systems; using Robust.Shared.Configuration; diff --git a/Content.Server/Cloning/CloningSystem.Subscriptions.cs b/Content.Server/Cloning/CloningSystem.Subscriptions.cs index cb1c8593f8..559618306e 100644 --- a/Content.Server/Cloning/CloningSystem.Subscriptions.cs +++ b/Content.Server/Cloning/CloningSystem.Subscriptions.cs @@ -1,5 +1,4 @@ using Content.Server.Forensics; -using Content.Server.Speech.EntitySystems; using Content.Shared.Body.Components; using Content.Shared.Body.Systems; using Content.Shared.Cloning.Events; @@ -15,6 +14,7 @@ using Content.Shared.Movement.Pulling.Systems; using Content.Shared.Movement.Systems; using Content.Shared.Paper; using Content.Shared.Speech.Components; +using Content.Shared.Speech.EntitySystems; using Content.Shared.Stacks; using Content.Shared.Storage; using Content.Shared.Store; diff --git a/Content.Server/Cluwne/CluwneSystem.cs b/Content.Server/Cluwne/CluwneSystem.cs index d36c58e301..bb96744aea 100644 --- a/Content.Server/Cluwne/CluwneSystem.cs +++ b/Content.Server/Cluwne/CluwneSystem.cs @@ -1,9 +1,8 @@ using Content.Server.Chat; using Content.Server.Chat.Systems; -using Content.Server.Emoting.Systems; using Content.Server.Clothing.Systems; +using Content.Server.Emoting.Systems; using Content.Server.Popups; -using Content.Server.Speech.EntitySystems; using Content.Shared.Chat; using Content.Shared.Chat.Prototypes; using Content.Shared.Clumsy; @@ -13,6 +12,7 @@ using Content.Shared.IdentityManagement; using Content.Shared.Mobs; using Content.Shared.NameModifier.EntitySystems; using Content.Shared.Popups; +using Content.Shared.Speech.EntitySystems; using Content.Shared.Stunnable; using Robust.Shared.Audio.Systems; using Robust.Shared.Random; diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index de2fbb6d69..b605ae58f8 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -50,7 +50,7 @@ public sealed partial class ElectrocutionSystem : SharedElectrocutionSystem [Dependency] private SharedJitteringSystem _jittering = default!; [Dependency] private SharedPopupSystem _popup = default!; [Dependency] private SharedStunSystem _stun = default!; - [Dependency] private SharedStutteringSystem _stuttering = default!; + [Dependency] private StutteringSystem _stuttering = default!; [Dependency] private TagSystem _tag = default!; [Dependency] private MetaDataSystem _metaData = default!; [Dependency] private TurfSystem _turf = default!; diff --git a/Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs b/Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs index c623b25857..b1e2703995 100644 --- a/Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs +++ b/Content.Server/EntityEffects/Effects/MakeSentientEntityEffectSystem.cs @@ -1,8 +1,8 @@ using Content.Server.Ghost.Roles.Components; -using Content.Server.Speech.Components; using Content.Shared.EntityEffects; using Content.Shared.EntityEffects.Effects; using Content.Shared.Mind.Components; +using Content.Shared.Speech.Components; namespace Content.Server.EntityEffects.Effects; diff --git a/Content.Server/GameTicking/GameTicker.Spawning.cs b/Content.Server/GameTicking/GameTicker.Spawning.cs index d18b37fc23..d5b6649104 100644 --- a/Content.Server/GameTicking/GameTicker.Spawning.cs +++ b/Content.Server/GameTicking/GameTicker.Spawning.cs @@ -5,12 +5,10 @@ using Content.Server.Administration.Managers; using Content.Server.Administration.Systems; using Content.Server.GameTicking.Events; using Content.Server.Spawners.Components; -using Content.Server.Speech.Components; using Content.Server.Station.Components; using Content.Shared.CCVar; using Content.Shared.Database; using Content.Shared.GameTicking; -using Content.Shared.Humanoid; using Content.Shared.Humanoid.Prototypes; using Content.Shared.Mind; using Content.Shared.Players; diff --git a/Content.Server/Speech/Components/BackwardsAccentComponent.cs b/Content.Server/Speech/Components/BackwardsAccentComponent.cs deleted file mode 100644 index 6ee8aa7690..0000000000 --- a/Content.Server/Speech/Components/BackwardsAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class BackwardsAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/BarkAccentComponent.cs b/Content.Server/Speech/Components/BarkAccentComponent.cs deleted file mode 100644 index f584a2aa23..0000000000 --- a/Content.Server/Speech/Components/BarkAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class BarkAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/BleatingAccentComponent.cs b/Content.Server/Speech/Components/BleatingAccentComponent.cs deleted file mode 100644 index 4f889b1e87..0000000000 --- a/Content.Server/Speech/Components/BleatingAccentComponent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -/// -/// Makes this entity speak like a sheep or a goat in all chat messages it sends. -/// -[RegisterComponent] -public sealed partial class BleatingAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/BlockListeningComponent.cs b/Content.Server/Speech/Components/BlockListeningComponent.cs deleted file mode 100644 index 3c747252ba..0000000000 --- a/Content.Server/Speech/Components/BlockListeningComponent.cs +++ /dev/null @@ -1,11 +0,0 @@ - -namespace Content.Server.Speech.Components; - -/// -/// Causes all ListenAttemptEvents to fail on the entity. -/// -[RegisterComponent] -public sealed partial class BlockListeningComponent : Component -{ - -} diff --git a/Content.Server/Speech/Components/FrontalLispComponent.cs b/Content.Server/Speech/Components/FrontalLispComponent.cs deleted file mode 100644 index 9f0ec761e3..0000000000 --- a/Content.Server/Speech/Components/FrontalLispComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class FrontalLispComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/GermanAccentComponent.cs b/Content.Server/Speech/Components/GermanAccentComponent.cs deleted file mode 100644 index 10b7ed0234..0000000000 --- a/Content.Server/Speech/Components/GermanAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class GermanAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/LizardAccentComponent.cs b/Content.Server/Speech/Components/LizardAccentComponent.cs deleted file mode 100644 index 6008c7248e..0000000000 --- a/Content.Server/Speech/Components/LizardAccentComponent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -/// -/// Hiss! -/// -[RegisterComponent] -public sealed partial class LizardAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/MobsterAccentComponent.cs b/Content.Server/Speech/Components/MobsterAccentComponent.cs deleted file mode 100644 index db92c5fd7a..0000000000 --- a/Content.Server/Speech/Components/MobsterAccentComponent.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -/// -/// Nyehh, my gabagool, see? -/// Etc etc. -/// -[RegisterComponent] -public sealed partial class MobsterAccentComponent : BaseAccentComponent -{ - /// - /// Do you make all the rules? - /// - [DataField("isBoss")] - public bool IsBoss = true; -} diff --git a/Content.Server/Speech/Components/MonkeyAccentComponent.cs b/Content.Server/Speech/Components/MonkeyAccentComponent.cs deleted file mode 100644 index b2ae0ed246..0000000000 --- a/Content.Server/Speech/Components/MonkeyAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class MonkeyAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/MothAccentComponent.cs b/Content.Server/Speech/Components/MothAccentComponent.cs deleted file mode 100644 index e3a61cc4cf..0000000000 --- a/Content.Server/Speech/Components/MothAccentComponent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -/// -/// Buzzz! -/// -[RegisterComponent] -public sealed partial class MothAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/OwOAccentComponent.cs b/Content.Server/Speech/Components/OwOAccentComponent.cs deleted file mode 100644 index a7c1d3c7b4..0000000000 --- a/Content.Server/Speech/Components/OwOAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class OwOAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/ReplacementAccentComponent.cs b/Content.Server/Speech/Components/ReplacementAccentComponent.cs deleted file mode 100644 index 4a6508b241..0000000000 --- a/Content.Server/Speech/Components/ReplacementAccentComponent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Content.Server.Speech.Prototypes; -using Content.Shared.Speech.Components; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Server.Speech.Components; - -/// -/// Replaces full sentences or words within sentences with new strings. -/// -[RegisterComponent] -public sealed partial class ReplacementAccentComponent : BaseAccentComponent -{ - [DataField(customTypeSerializer: typeof(PrototypeIdSerializer), required: true)] - public string Accent = default!; - -} diff --git a/Content.Server/Speech/Components/RussianAccentComponent.cs b/Content.Server/Speech/Components/RussianAccentComponent.cs deleted file mode 100644 index 2b06b3b668..0000000000 --- a/Content.Server/Speech/Components/RussianAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class RussianAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/ScrambledAccentComponent.cs b/Content.Server/Speech/Components/ScrambledAccentComponent.cs deleted file mode 100644 index f2f75a18fd..0000000000 --- a/Content.Server/Speech/Components/ScrambledAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class ScrambledAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/SkeletonAccentComponent.cs b/Content.Server/Speech/Components/SkeletonAccentComponent.cs deleted file mode 100644 index 50b52b57f7..0000000000 --- a/Content.Server/Speech/Components/SkeletonAccentComponent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -/// -/// Rattle me bones! -/// -[RegisterComponent] -public sealed partial class SkeletonAccentComponent : BaseAccentComponent -{ - /// - /// Chance that the message will be appended with "ACK ACK!" - /// - [DataField("ackChance")] - public float ackChance = 0.3f; // Funnier if it doesn't happen every single time -} diff --git a/Content.Server/Speech/Components/SlowAccentComponent.cs b/Content.Server/Speech/Components/SlowAccentComponent.cs deleted file mode 100644 index 225b727b9e..0000000000 --- a/Content.Server/Speech/Components/SlowAccentComponent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -/// -/// Makes... the... entity... talk... like... this... -/// -[RegisterComponent] -public sealed partial class SlowAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/SouthernAccentComponent.cs b/Content.Server/Speech/Components/SouthernAccentComponent.cs deleted file mode 100644 index ac44e051cb..0000000000 --- a/Content.Server/Speech/Components/SouthernAccentComponent.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Content.Server.Speech.EntitySystems; -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -[Access(typeof(SouthernAccentSystem))] -public sealed partial class SouthernAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/SpanishAccentComponent.cs b/Content.Server/Speech/Components/SpanishAccentComponent.cs deleted file mode 100644 index c7c769b074..0000000000 --- a/Content.Server/Speech/Components/SpanishAccentComponent.cs +++ /dev/null @@ -1,6 +0,0 @@ -using Content.Shared.Speech.Components; - -namespace Content.Server.Speech.Components; - -[RegisterComponent] -public sealed partial class SpanishAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/UnblockableSpeechComponent.cs b/Content.Server/Speech/Components/UnblockableSpeechComponent.cs deleted file mode 100644 index 48e2b9863a..0000000000 --- a/Content.Server/Speech/Components/UnblockableSpeechComponent.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Content.Server.Speech.Components -{ - [RegisterComponent] - public sealed partial class UnblockableSpeechComponent : Component - { - } -} diff --git a/Content.Server/Speech/EntitySystems/BarkAccentSystem.cs b/Content.Server/Speech/EntitySystems/BarkAccentSystem.cs deleted file mode 100644 index dcf8f8f08c..0000000000 --- a/Content.Server/Speech/EntitySystems/BarkAccentSystem.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; -using Robust.Shared.Random; - -namespace Content.Server.Speech.EntitySystems; - -public sealed partial class BarkAccentSystem : RelayAccentSystem -{ - [Dependency] private IRobustRandom _random = default!; - - private static readonly IReadOnlyList Barks = new List{ - " Woof!", " WOOF", " wof-wof" - }.AsReadOnly(); - - private static readonly IReadOnlyDictionary SpecialWords = new Dictionary() - { - { "ah", "arf" }, - { "Ah", "Arf" }, - { "oh", "oof" }, - { "Oh", "Oof" }, - }; - - public override string Accentuate(string message, Entity? ent = null) - { - foreach (var (word, repl) in SpecialWords) - { - message = message.Replace(word, repl); - } - - return message.Replace("!", _random.Pick(Barks)) - .Replace("l", "r").Replace("L", "R"); - } -} diff --git a/Content.Server/Speech/EntitySystems/BlockListeningSystem.cs b/Content.Server/Speech/EntitySystems/BlockListeningSystem.cs deleted file mode 100644 index 6b09877512..0000000000 --- a/Content.Server/Speech/EntitySystems/BlockListeningSystem.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Content.Server.Speech.Components; -using Content.Shared.Speech; - -namespace Content.Server.Speech.EntitySystems; - -public sealed class BlockListeningSystem : EntitySystem -{ - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnListenAttempt); - } - - private void OnListenAttempt(EntityUid uid, BlockListeningComponent component, ListenAttemptEvent args) - { - args.Cancel(); - } -} diff --git a/Content.Server/Speech/EntitySystems/DamagedSiliconAccentSystem.cs b/Content.Server/Speech/EntitySystems/DamagedSiliconAccentSystem.cs index 067dc34687..3ab654746a 100644 --- a/Content.Server/Speech/EntitySystems/DamagedSiliconAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/DamagedSiliconAccentSystem.cs @@ -1,119 +1,19 @@ using System.Text; using Content.Server.Destructible; -using Content.Shared.Speech.Components; -using Content.Shared.Damage.Components; -using Content.Shared.Damage.Systems; using Content.Shared.FixedPoint; -using Content.Shared.Power.EntitySystems; -using Content.Shared.PowerCell; +using Content.Shared.Speech.Components; using Content.Shared.Speech.EntitySystems; + using Robust.Shared.Random; namespace Content.Server.Speech.EntitySystems; -public sealed partial class DamagedSiliconAccentSystem : RelayAccentSystem +public sealed partial class DamagedSiliconAccentSystem : SharedDamagedSiliconAccentSystem { [Dependency] private IRobustRandom _random = default!; - [Dependency] private SharedBatterySystem _battery = default!; - [Dependency] private PowerCellSystem _powerCell = default!; [Dependency] private DestructibleSystem _destructibleSystem = default!; - [Dependency] private DamageableSystem _damageable = default!; - protected override Type[]? AccentAfter => [typeof(ReplacementAccentSystem)]; - protected override Type[]? RelayAccentAfter => [typeof(ReplacementAccentSystem)]; - - public override string Accentuate(string message, Entity? ent = null) - { - if (ent == null) - return message; - - var uid = ent.Value.Owner; - - if (ent.Value.Comp.EnableChargeCorruption) - { - var currentChargeLevel = 0.0f; - if (ent.Value.Comp.OverrideChargeLevel.HasValue) - { - currentChargeLevel = ent.Value.Comp.OverrideChargeLevel.Value; - } - else if (_powerCell.TryGetBatteryFromSlot(uid, out var battery)) - { - currentChargeLevel = _battery.GetChargeLevel(battery.Value.AsNullable()); - } - currentChargeLevel = Math.Clamp(currentChargeLevel, 0.0f, 1.0f); - // Corrupt due to low power (drops characters on longer messages) - message = CorruptPower(message, currentChargeLevel, ent.Value.Comp); - } - - if (ent.Value.Comp.EnableDamageCorruption) - { - var damage = FixedPoint2.Zero; - if (ent.Value.Comp.OverrideTotalDamage.HasValue) - { - damage = ent.Value.Comp.OverrideTotalDamage.Value; - } - else if (TryComp(uid, out var damageable)) - { - damage = _damageable.GetTotalDamage((uid, damageable)); - } - // Corrupt due to damage (drop, repeat, replace with symbols) - message = CorruptDamage(message, damage, ent.Value); - } - - return message; - } - - public string CorruptPower(string message, float chargeLevel, DamagedSiliconAccentComponent comp) - { - // The first idxMin characters are SAFE - var idxMin = comp.StartPowerCorruptionAtCharIdx; - // Probability will max at idxMax - var idxMax = comp.MaxPowerCorruptionAtCharIdx; - - // Fast bails, would not have an effect - if (chargeLevel > comp.ChargeThresholdForPowerCorruption || message.Length < idxMin) - { - return message; - } - - var outMsg = new StringBuilder(); - - var maxDropProb = comp.MaxDropProbFromPower * (1.0f - chargeLevel / comp.ChargeThresholdForPowerCorruption); - - var idx = -1; - foreach (var letter in message) - { - idx++; - if (idx < idxMin) // Fast character, no effect - { - outMsg.Append(letter); - continue; - } - - // use an x^2 interpolation to increase the drop probability until we hit idxMax - var probToDrop = idx >= idxMax - ? maxDropProb - : (float)Math.Pow(((double)idx - idxMin) / (idxMax - idxMin), 2.0) * maxDropProb; - // Ensure we're in the range for Prob() - probToDrop = Math.Clamp(probToDrop, 0.0f, 1.0f); - - if (_random.Prob(probToDrop)) // Lose a character - { - // Additional chance to change to dot for flavor instead of full drop - if (_random.Prob(comp.ProbToCorruptDotFromPower)) - { - outMsg.Append('.'); - } - } - else // Character is safe - { - outMsg.Append(letter); - } - } - return outMsg.ToString(); - } - - private string CorruptDamage(string message, FixedPoint2 totalDamage, Entity ent) + protected override string CorruptDamage(string message, FixedPoint2 totalDamage, Entity ent) { var outMsg = new StringBuilder(); diff --git a/Content.Server/Speech/EntitySystems/FrontalLispSystem.cs b/Content.Server/Speech/EntitySystems/FrontalLispSystem.cs deleted file mode 100644 index 8cf62d23e3..0000000000 --- a/Content.Server/Speech/EntitySystems/FrontalLispSystem.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; - -namespace Content.Server.Speech.EntitySystems; - -public sealed class FrontalLispSystem : RelayAccentSystem -{ - // @formatter:off - private static readonly Regex RegexUpperTh = new(@"[T]+[Ss]+|[S]+[Cc]+(?=[IiEeYy]+)|[C]+(?=[IiEeYy]+)|[P][Ss]+|([S]+[Tt]+|[T]+)(?=[Ii]+[Oo]+[Uu]*[Nn]*)|[C]+[Hh]+(?=[Ii]*[Ee]*)|[Z]+|[S]+|[X]+(?=[Ee]+)"); - private static readonly Regex RegexLowerTh = new(@"[t]+[s]+|[s]+[c]+(?=[iey]+)|[c]+(?=[iey]+)|[p][s]+|([s]+[t]+|[t]+)(?=[i]+[o]+[u]*[n]*)|[c]+[h]+(?=[i]*[e]*)|[z]+|[s]+|[x]+(?=[e]+)"); - private static readonly Regex RegexUpperEcks = new(@"[E]+[Xx]+[Cc]*|[X]+"); - private static readonly Regex RegexLowerEcks = new(@"[e]+[x]+[c]*|[x]+"); - // @formatter:on - - public override string Accentuate(string message, Entity? ent = null) - { - // handles ts, sc(i|e|y), c(i|e|y), ps, st(io(u|n)), ch(i|e), z, s - message = RegexUpperTh.Replace(message, "TH"); - message = RegexLowerTh.Replace(message, "th"); - // handles ex(c), x - message = RegexUpperEcks.Replace(message, "EKTH"); - message = RegexLowerEcks.Replace(message, "ekth"); - return message; - } -} diff --git a/Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs b/Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs deleted file mode 100644 index e9e224dddb..0000000000 --- a/Content.Server/Speech/EntitySystems/MeleeSpeechSystem.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Content.Server.Administration.Logs; -using Content.Shared.Actions; -using Content.Shared.Database; -using Content.Shared.Speech.Components; -using Content.Shared.Speech.EntitySystems; -using Robust.Server.GameObjects; -using Robust.Shared.Player; - -namespace Content.Server.Speech.EntitySystems; - -public sealed partial class MeleeSpeechSystem : SharedMeleeSpeechSystem -{ - [Dependency] private IAdminLogManager _adminLogger = default!; - [Dependency] private SharedActionsSystem _actionSystem = default!; - [Dependency] private UserInterfaceSystem _uiSystem = default!; - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnBattlecryChanged); - SubscribeLocalEvent(OnConfigureAction); - SubscribeLocalEvent(OnGetActions); - SubscribeLocalEvent(OnComponentMapInit); - } - private void OnComponentMapInit(EntityUid uid, MeleeSpeechComponent component, MapInitEvent args) - { - _actionSystem.AddAction(uid, ref component.ConfigureActionEntity, component.ConfigureAction, uid); - } - private void OnGetActions(EntityUid uid, MeleeSpeechComponent component, GetItemActionsEvent args) - { - args.AddAction(ref component.ConfigureActionEntity, component.ConfigureAction); - } - private void OnBattlecryChanged(EntityUid uid, MeleeSpeechComponent comp, MeleeSpeechBattlecryChangedMessage args) - { - if (!TryComp(uid, out var meleeSpeechUser)) - return; - var battlecry = args.Battlecry; - if (battlecry.Length > comp.MaxBattlecryLength) - battlecry = battlecry[..comp.MaxBattlecryLength]; - TryChangeBattlecry(uid, battlecry, meleeSpeechUser); - } - /// - /// Attempts to open the Battlecry UI. - /// - private void OnConfigureAction(EntityUid uid, MeleeSpeechComponent comp, MeleeSpeechConfigureActionEvent args) - { - TryOpenUi(args.Performer, uid, comp); - } - public void TryOpenUi(EntityUid user, EntityUid source, MeleeSpeechComponent? component = null) - { - if (!Resolve(source, ref component)) - return; - if (!TryComp(user, out var actor)) - return; - _uiSystem.TryToggleUi(source, MeleeSpeechUiKey.Key, actor.PlayerSession); - } - /// - /// Attempts to change the battlecry of an entity. - /// Returns true/false. - /// - /// - /// Logs changes to an entity's battlecry - /// - public bool TryChangeBattlecry(EntityUid uid, string? battlecry, MeleeSpeechComponent? meleeSpeechComp = null) - { - if (!Resolve(uid, ref meleeSpeechComp)) - return false; - if (!string.IsNullOrWhiteSpace(battlecry)) - { - battlecry = battlecry.Trim(); - } - else - { - battlecry = null; - } - if (meleeSpeechComp.Battlecry == battlecry) - return true; - meleeSpeechComp.Battlecry = battlecry; - Dirty(uid, meleeSpeechComp); - _adminLogger.Add(LogType.ItemConfigure, LogImpact.Medium, $" {ToPrettyString(uid):entity}'s battlecry has been changed to {battlecry}"); - return true; - } -} diff --git a/Content.Server/Speech/EntitySystems/OwOAccentSystem.cs b/Content.Server/Speech/EntitySystems/OwOAccentSystem.cs deleted file mode 100644 index 9f37fe6372..0000000000 --- a/Content.Server/Speech/EntitySystems/OwOAccentSystem.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; -using Robust.Shared.Random; - -namespace Content.Server.Speech.EntitySystems; - -public sealed partial class OwOAccentSystem : RelayAccentSystem -{ - [Dependency] private IRobustRandom _random = default!; - - private static readonly IReadOnlyList Faces = new List{ - " (•`ω´•)", " ;;w;;", " owo", " UwU", " >w<", " ^w^" - }.AsReadOnly(); - - private static readonly IReadOnlyDictionary SpecialWords = new Dictionary() - { - { "you", "wu" }, - }; - - public override string Accentuate(string message, Entity? ent = null) - { - foreach (var (word, repl) in SpecialWords) - { - message = message.Replace(word, repl); - } - - return message.Replace("!", _random.Pick(Faces)) - .Replace("r", "w").Replace("R", "W") - .Replace("l", "w").Replace("L", "W"); - } -} diff --git a/Content.Server/Speech/EntitySystems/RatvarianLanguageSystem.cs b/Content.Server/Speech/EntitySystems/RatvarianLanguageSystem.cs deleted file mode 100644 index 0978154b23..0000000000 --- a/Content.Server/Speech/EntitySystems/RatvarianLanguageSystem.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Content.Shared.Speech.EntitySystems; - -namespace Content.Server.Speech.EntitySystems; - -public sealed partial class RatvarianLanguageSystem : SharedRatvarianLanguageSystem -{ - public override void DoRatvarian(EntityUid uid, TimeSpan time, bool refresh) - { - if (refresh) - Status.TryUpdateStatusEffectDuration(uid, Ratvarian, time); - else - Status.TryAddStatusEffectDuration(uid, Ratvarian, time); - } -} diff --git a/Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs b/Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs deleted file mode 100644 index de4a814345..0000000000 --- a/Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Content.Server.Chat.Systems; -using Content.Shared.Actions.Events; -using Content.Shared.Chat; -using Content.Shared.Speech; -using Content.Shared.Speech.Components; -using Content.Shared.Speech.EntitySystems; -using Content.Shared.Speech.Muting; - -namespace Content.Server.Speech.EntitySystems; - -/// -/// As soon as the chat refactor moves to Shared -/// the logic here can move to the shared -/// -public sealed partial class SpeakOnActionSystem : SharedSpeakOnActionSystem -{ - [Dependency] private ChatSystem _chat = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnActionPerformed); - } - - private void OnActionPerformed(Entity ent, ref ActionPerformedEvent args) - { - var user = args.Performer; - - // If we can't speak, we can't speak - if (!HasComp(user) || HasComp(user)) - return; - - if (string.IsNullOrWhiteSpace(ent.Comp.Sentence)) - return; - - _chat.TrySendInGameICMessage(user, Loc.GetString(ent.Comp.Sentence), InGameICChatType.Speak, false); - } -} diff --git a/Content.Server/Speech/EntitySystems/StutteringSystem.cs b/Content.Server/Speech/EntitySystems/StutteringSystem.cs deleted file mode 100644 index 11fc1438d0..0000000000 --- a/Content.Server/Speech/EntitySystems/StutteringSystem.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Text; -using System.Text.RegularExpressions; -using Content.Shared.Speech.Components; -using Content.Shared.Speech.EntitySystems; -using Robust.Shared.Random; - -namespace Content.Server.Speech.EntitySystems; - -public sealed partial class StutteringSystem : SharedStutteringSystem -{ - [Dependency] private IRobustRandom _random = default!; - - // Regex of characters to stutter. - private static readonly Regex Stutter = new(@"[b-df-hj-np-tv-wxyz]", - RegexOptions.Compiled | RegexOptions.IgnoreCase); - - public override void DoStutter(EntityUid uid, TimeSpan time, bool refresh) - { - if (refresh) - Status.TryUpdateStatusEffectDuration(uid, Stuttering, time); - else - Status.TryAddStatusEffectDuration(uid, Stuttering, time); - } - - public override void DoRemoveStutterTime(EntityUid uid, TimeSpan timeRemoved) - { - Status.TryAddTime(uid, Stuttering, -timeRemoved); - } - - public override void DoRemoveStutter(EntityUid uid) - { - Status.TryRemoveStatusEffect(uid, Stuttering); - } - - public override string Accentuate(string message, Entity? ent = null) - { - if (ent == null) - return message; - - var length = message.Length; - - var finalMessage = new StringBuilder(); - - string newLetter; - - for (var i = 0; i < length; i++) - { - newLetter = message[i].ToString(); - if (Stutter.IsMatch(newLetter) && _random.Prob(ent.Value.Comp.MatchRandomProb)) - { - if (_random.Prob(ent.Value.Comp.FourRandomProb)) - { - newLetter = $"{newLetter}-{newLetter}-{newLetter}-{newLetter}"; - } - else if (_random.Prob(ent.Value.Comp.ThreeRandomProb)) - { - newLetter = $"{newLetter}-{newLetter}-{newLetter}"; - } - else if (_random.Prob(ent.Value.Comp.CutRandomProb)) - { - newLetter = ""; - } - else - { - newLetter = $"{newLetter}-{newLetter}"; - } - } - - finalMessage.Append(newLetter); - } - - return finalMessage.ToString(); - } -} - diff --git a/Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs b/Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs deleted file mode 100644 index 6d5f165d6c..0000000000 --- a/Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Content.Server.Speech.Components; -using Content.Shared.Chat; - -namespace Content.Server.Speech.EntitySystems -{ - public sealed class UnblockableSpeechSystem : EntitySystem - { - public override void Initialize() - { - SubscribeLocalEvent(OnCheck); - } - - private void OnCheck(EntityUid uid, UnblockableSpeechComponent component, CheckIgnoreSpeechBlockerEvent args) - { - args.IgnoreBlocker = true; - } - } -} diff --git a/Content.Server/Speech/EntitySystems/VocalSystem.cs b/Content.Server/Speech/EntitySystems/VocalSystem.cs deleted file mode 100644 index 7bd561b4f8..0000000000 --- a/Content.Server/Speech/EntitySystems/VocalSystem.cs +++ /dev/null @@ -1,127 +0,0 @@ -using Content.Server.Actions; -using Content.Server.Chat.Systems; -using Content.Shared.Chat; -using Content.Shared.Chat.Prototypes; -using Content.Shared.Humanoid; -using Content.Shared.Speech; -using Content.Shared.Speech.Components; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Random; -using Robust.Shared.Prototypes; - -namespace Content.Server.Speech.EntitySystems; - -public sealed partial class VocalSystem : EntitySystem -{ - [Dependency] private IRobustRandom _random = default!; - [Dependency] private SharedAudioSystem _audio = default!; - [Dependency] private ChatSystem _chat = default!; - [Dependency] private ActionsSystem _actions = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnShutdown); - SubscribeLocalEvent(OnVoiceChanged); - SubscribeLocalEvent(OnEmote); - SubscribeLocalEvent(OnEmoteAction); - } - - /// - /// Copy this component's datafields from one entity to another. - /// This can't use CopyComp because of the ScreamActionEntity DataField, which should not be copied. - /// - public void CopyComponent(Entity source, EntityUid target) - { - if (!Resolve(source, ref source.Comp)) - return; - - var targetComp = EnsureComp(target); - targetComp.ScreamId = source.Comp.ScreamId; - targetComp.Wilhelm = source.Comp.Wilhelm; - targetComp.WilhelmProbability = source.Comp.WilhelmProbability; - LoadSounds(target, targetComp); - - Dirty(target, targetComp); - } - - private void OnMapInit(EntityUid uid, VocalComponent component, MapInitEvent args) - { - // try to add scream action when vocal comp added - _actions.AddAction(uid, ref component.EmoteActionEntity, component.EmoteAction); - } - - private void OnShutdown(EntityUid uid, VocalComponent component, ComponentShutdown args) - { - // remove scream action when component removed - if (component.EmoteActionEntity != null) - { - _actions.RemoveAction(uid, component.EmoteActionEntity); - } - } - - private void OnVoiceChanged(EntityUid uid, VocalComponent component, VoiceChangedEvent args) - { - LoadSounds(uid, component, args.NewVoice); - } - - private void OnEmote(EntityUid uid, VocalComponent component, ref EmoteEvent args) - { - if (args.Handled || !args.Emote.Category.HasFlag(EmoteCategory.Vocal)) - return; - - // snowflake case for wilhelm scream easter egg - if (args.Emote == component.ScreamId) - { - args.Handled = TryPlayScreamSound(uid, component); - return; - } - - if (component.EmoteSounds is not { } sounds) - return; - - // just play regular sound based on emote proto - args.Handled = _chat.TryPlayEmoteSound(uid, ProtoMan.Index(sounds), args.Emote); - } - - private void OnEmoteAction(EntityUid uid, VocalComponent component, EmoteActionEvent args) - { - if (args.Handled) - return; - - _chat.TryEmoteWithChat(uid, args.Emote); - args.Handled = true; - } - - private bool TryPlayScreamSound(EntityUid uid, VocalComponent component) - { - if (_random.Prob(component.WilhelmProbability)) - { - _audio.PlayPvs(component.Wilhelm, uid, component.Wilhelm.Params); - return true; - } - - if (component.EmoteSounds is not { } sounds) - return false; - - return _chat.TryPlayEmoteSound(uid, ProtoMan.Index(sounds), component.ScreamId); - } - - /// - /// This only works on Humanoids. Mobs should have emoteSounds on set directly instead. - /// - private void LoadSounds(EntityUid uid, VocalComponent component, ProtoId? protoId = null) - { - if (!TryComp(uid, out var humanoid)) - return; - - protoId ??= humanoid.Voice; - - if (!ProtoMan.HasIndex(protoId)) - return; - - component.EmoteSounds = protoId; - } -} diff --git a/Content.Server/Speech/EntitySystems/VoiceOverrideSystem.cs b/Content.Server/Speech/EntitySystems/VoiceOverrideSystem.cs deleted file mode 100644 index daaad099d6..0000000000 --- a/Content.Server/Speech/EntitySystems/VoiceOverrideSystem.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Content.Shared.Chat; -using Content.Server.Speech.Components; - -namespace Content.Server.Speech.EntitySystems; - -public sealed partial class VoiceOverrideSystem : EntitySystem -{ - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnTransformSpeakerName); - } - - private void OnTransformSpeakerName(Entity entity, ref TransformSpeakerNameEvent args) - { - if (!entity.Comp.Enabled) - return; - - args.VoiceName = entity.Comp.NameOverride ?? args.VoiceName; - args.SpeechVerb = entity.Comp.SpeechVerbOverride ?? args.SpeechVerb; - } -} diff --git a/Content.Server/Speech/Components/ListenWireAction.cs b/Content.Server/Speech/ListenWireAction.cs similarity index 98% rename from Content.Server/Speech/Components/ListenWireAction.cs rename to Content.Server/Speech/ListenWireAction.cs index f9f1d9e92e..f8f6045523 100644 --- a/Content.Server/Speech/Components/ListenWireAction.cs +++ b/Content.Server/Speech/ListenWireAction.cs @@ -1,10 +1,10 @@ using Content.Server.Chat.Systems; -using Content.Shared.Radio.Components; using Content.Server.Radio.EntitySystems; -using Content.Server.Speech.Components; using Content.Server.Wires; using Content.Shared.Radio; +using Content.Shared.Radio.Components; using Content.Shared.Speech; +using Content.Shared.Speech.Components; using Content.Shared.Wires; using Robust.Shared.Prototypes; diff --git a/Content.Server/Speech/Muting/MutingSystem.cs b/Content.Server/Speech/Muting/MutingSystem.cs index 5ccd30bd76..2dd1e00906 100644 --- a/Content.Server/Speech/Muting/MutingSystem.cs +++ b/Content.Server/Speech/Muting/MutingSystem.cs @@ -1,5 +1,5 @@ using Content.Server.Popups; -using Content.Server.Speech.EntitySystems; +using Content.Shared.Speech.EntitySystems; using Content.Shared.Abilities.Mime; using Content.Shared.Chat; using Content.Shared.Chat.Prototypes; diff --git a/Content.Server/Speech/SpeechNoiseSystem.cs b/Content.Server/Speech/SpeechNoiseSystem.cs deleted file mode 100644 index 79d4cadc19..0000000000 --- a/Content.Server/Speech/SpeechNoiseSystem.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Content.Shared.Chat; -using Content.Shared.Speech; -using Robust.Shared.Audio; -using Robust.Shared.Audio.Systems; -using Robust.Shared.Random; -using Robust.Shared.Timing; - -namespace Content.Server.Speech -{ - public sealed partial class SpeechSoundSystem : EntitySystem - { - [Dependency] private IGameTiming _gameTiming = default!; - [Dependency] private IRobustRandom _random = default!; - [Dependency] private SharedAudioSystem _audio = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnEntitySpoke); - } - - public SoundSpecifier? GetSpeechSound(Entity ent, string message) - { - if (ent.Comp.SpeechSounds == null) - return null; - - // Play speech sound - SoundSpecifier? contextSound; - var prototype = ProtoMan.Index(ent.Comp.SpeechSounds); - - // Different sounds for ask/exclaim based on last character - contextSound = message[^1] switch - { - '?' => prototype.AskSound, - '!' => prototype.ExclaimSound, - _ => prototype.SaySound - }; - - // Use exclaim sound if most characters are uppercase. - int uppercaseCount = 0; - for (int i = 0; i < message.Length; i++) - { - if (char.IsUpper(message[i])) - uppercaseCount++; - } - if (uppercaseCount > (message.Length / 2)) - { - contextSound = prototype.ExclaimSound; - } - - var scale = (float) _random.NextGaussian(1, prototype.Variation); - contextSound.Params = ent.Comp.AudioParams.WithPitchScale(scale); - return contextSound; - } - - private void OnEntitySpoke(EntityUid uid, SpeechComponent component, EntitySpokeEvent args) - { - if (component.SpeechSounds == null) - return; - - var currentTime = _gameTiming.CurTime; - var cooldown = TimeSpan.FromSeconds(component.SoundCooldownTime); - - // Ensure more than the cooldown time has passed since last speaking - if (currentTime - component.LastTimeSoundPlayed < cooldown) - return; - - var sound = GetSpeechSound((uid, component), args.Message); - component.LastTimeSoundPlayed = currentTime; - _audio.PlayPvs(sound, uid); - } - } -} diff --git a/Content.Server/Speech/Components/SpeechWireAction.cs b/Content.Server/Speech/SpeechWireAction.cs similarity index 100% rename from Content.Server/Speech/Components/SpeechWireAction.cs rename to Content.Server/Speech/SpeechWireAction.cs diff --git a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSpeakerSystem.cs b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSpeakerSystem.cs index 4ad44ec9ac..97e454a45d 100644 --- a/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSpeakerSystem.cs +++ b/Content.Server/SurveillanceCamera/Systems/SurveillanceCameraSpeakerSystem.cs @@ -1,8 +1,8 @@ using Content.Server.Chat.Systems; -using Content.Server.Speech; using Content.Server.SurveillanceCamera.Systems; -using Content.Shared.Speech; using Content.Shared.Chat; +using Content.Shared.Speech; +using Content.Shared.Speech.EntitySystems; using Robust.Shared.Audio.Systems; using Robust.Shared.Timing; diff --git a/Content.Server/Telephone/TelephoneSystem.cs b/Content.Server/Telephone/TelephoneSystem.cs index 1c64d6c40d..97ca38212e 100644 --- a/Content.Server/Telephone/TelephoneSystem.cs +++ b/Content.Server/Telephone/TelephoneSystem.cs @@ -433,6 +433,7 @@ public sealed partial class TelephoneSystem : SharedTelephoneSystem { var activeListener = AddComp(entity); activeListener.Range = entity.Comp.ListeningRange; + Dirty(entity, activeListener); } if (!microphoneOn && HasComp(entity)) diff --git a/Content.Server/VoiceMask/VoiceMaskSystem.cs b/Content.Server/VoiceMask/VoiceMaskSystem.cs index 25da4b516d..48c2a88aa3 100644 --- a/Content.Server/VoiceMask/VoiceMaskSystem.cs +++ b/Content.Server/VoiceMask/VoiceMaskSystem.cs @@ -1,4 +1,3 @@ -using Content.Server.Speech; using Content.Shared.Actions; using Content.Shared.Administration.Logs; using Content.Shared.CCVar; @@ -12,6 +11,7 @@ using Content.Shared.Inventory; using Content.Shared.Lock; using Content.Shared.Popups; using Content.Shared.Speech; +using Content.Shared.Speech.EntitySystems; using Content.Shared.VoiceMask; using Robust.Shared.Configuration; using Robust.Shared.Containers; diff --git a/Content.Server/Zombies/ZombieSystem.Transform.cs b/Content.Server/Zombies/ZombieSystem.Transform.cs index 03cd0267c8..b668927f86 100644 --- a/Content.Server/Zombies/ZombieSystem.Transform.cs +++ b/Content.Server/Zombies/ZombieSystem.Transform.cs @@ -5,46 +5,43 @@ using Content.Server.Body.Components; using Content.Server.Chat; using Content.Server.Chat.Managers; using Content.Server.Ghost; -using Content.Server.Ghost.Roles.Components; -using Content.Server.Humanoid; using Content.Server.Inventory; using Content.Server.Mind; using Content.Server.NPC; using Content.Server.NPC.HTN; using Content.Server.NPC.Systems; using Content.Server.StationEvents.Components; -using Content.Server.Speech.Components; using Content.Shared.Body; using Content.Shared.Body.Components; using Content.Shared.CombatMode; using Content.Shared.CombatMode.Pacification; +using Content.Shared.Ghost.Roles.Components; using Content.Shared.Hands.Components; using Content.Shared.Hands.EntitySystems; using Content.Shared.Humanoid; +using Content.Shared.IdentityManagement; using Content.Shared.Interaction.Components; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Movement.Pulling.Components; using Content.Shared.Movement.Systems; using Content.Shared.NameModifier.EntitySystems; +using Content.Shared.NPC.Prototypes; using Content.Shared.NPC.Systems; using Content.Shared.Nutrition.AnimalHusbandry; using Content.Shared.Nutrition.Components; using Content.Shared.Popups; +using Content.Shared.Prying.Components; +using Content.Shared.Roles; +using Content.Shared.Speech.EntitySystems; +using Content.Shared.Tag; +using Content.Shared.Temperature.Components; +using Content.Shared.Traits.Assorted; using Content.Shared.Weapons.Melee; using Content.Shared.Zombies; -using Content.Shared.Prying.Components; -using Content.Shared.Traits.Assorted; using Robust.Shared.Audio.Systems; -using Content.Shared.Ghost.Roles.Components; -using Content.Shared.Humanoid.Markings; -using Content.Shared.IdentityManagement; -using Content.Shared.Tag; using Robust.Shared.Player; using Robust.Shared.Prototypes; -using Content.Shared.NPC.Prototypes; -using Content.Shared.Roles; -using Content.Shared.Temperature.Components; using Robust.Shared.Utility; namespace Content.Server.Zombies; @@ -70,6 +67,7 @@ public sealed partial class ZombieSystem [Dependency] private MindSystem _mind = default!; [Dependency] private MovementSpeedModifierSystem _movementSpeedModifier = default!; [Dependency] private NameModifierSystem _nameMod = default!; + [Dependency] private ReplacementAccentSystem _replacementAccent = default!; [Dependency] private NPCSystem _npc = default!; [Dependency] private TagSystem _tag = default!; [Dependency] private ISharedPlayerManager _player = default!; @@ -152,7 +150,7 @@ public sealed partial class ZombieSystem if (TryComp(target, out var accent)) accentType = accent.Accent; - EnsureComp(target).Accent = accentType; + _replacementAccent.ApplyAccent(target, accentType); //This is needed for stupid entities that fuck up combat mode component //in an attempt to make an entity not attack. This is the easiest way to do it. diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index 6c890536d0..1d1be3c0ba 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -4,7 +4,7 @@ using Content.Server.Body.Systems; using Content.Server.Chat; using Content.Server.Chat.Systems; using Content.Server.Emoting.Systems; -using Content.Server.Speech.EntitySystems; +using Content.Shared.Speech.EntitySystems; using Content.Shared.Anomaly.Components; using Content.Shared.Armor; using Content.Shared.Bed.Sleep; diff --git a/Content.Shared/Chat/EmotesEvents.cs b/Content.Shared/Chat/EmotesEvents.cs index 196bbb43bd..74eedca31a 100644 --- a/Content.Shared/Chat/EmotesEvents.cs +++ b/Content.Shared/Chat/EmotesEvents.cs @@ -1,5 +1,6 @@ using Content.Shared.Chat.Prototypes; using Content.Shared.Inventory; +using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; @@ -28,8 +29,13 @@ public sealed class BeforeEmoteEvent(EntityUid source, EmotePrototype emote) /// Use it to play sound, change sprite or something else. /// [ByRefEvent] -public record struct EmoteEvent(EmotePrototype Emote) +public record struct EmoteEvent(NetEntity Source, EmotePrototype Emote) { + /// + /// The entity that performed the emote. + /// + public NetEntity Source = Source; + /// /// The used emote. /// diff --git a/Content.Shared/Chat/SharedChatSystem.Emote.cs b/Content.Shared/Chat/SharedChatSystem.Emote.cs index 8b4b8a1d91..e9b74dd49f 100644 --- a/Content.Shared/Chat/SharedChatSystem.Emote.cs +++ b/Content.Shared/Chat/SharedChatSystem.Emote.cs @@ -156,7 +156,7 @@ public abstract partial class SharedChatSystem // optional override params > general params for all sounds in set > individual sound params var param = audioParams ?? proto.GeneralParams ?? sound.Params; - _audio.PlayPvs(sound, uid, param); + _audio.PlayPredicted(sound, uid, uid, param); return true; } /// @@ -222,10 +222,6 @@ public abstract partial class SharedChatSystem if (beforeEv.Cancelled) { - // Chat is not predicted anyways, so no need to predict this popup either. - if (_net.IsClient) - return false; - if (beforeEv.Blocker != null) { _popup.PopupEntity( @@ -251,7 +247,7 @@ public abstract partial class SharedChatSystem return false; } - var ev = new EmoteEvent(proto); + var ev = new EmoteEvent(GetNetEntity(uid), proto); RaiseLocalEvent(uid, ref ev); return true; diff --git a/Content.Shared/Chat/SharedChatSystem.cs b/Content.Shared/Chat/SharedChatSystem.cs index a4df6ff26d..37799f6bc0 100644 --- a/Content.Shared/Chat/SharedChatSystem.cs +++ b/Content.Shared/Chat/SharedChatSystem.cs @@ -49,7 +49,6 @@ public abstract partial class SharedChatSystem : EntitySystem [Dependency] private ActionBlockerSystem _actionBlocker = default!; [Dependency] private SharedAudioSystem _audio = default!; [Dependency] private IRobustRandom _random = default!; - [Dependency] private INetManager _net = default!; /// /// Cache of the keycodes for faster lookup. diff --git a/Content.Shared/Speech/AccentEvent.cs b/Content.Shared/Speech/AccentEvent.cs index 30d384cbb2..4404404246 100644 --- a/Content.Shared/Speech/AccentEvent.cs +++ b/Content.Shared/Speech/AccentEvent.cs @@ -1,11 +1,11 @@ -using Content.Shared.Inventory; +using Content.Shared.Inventory; namespace Content.Shared.Speech; /// -/// Raised on an entity to apply speech accents to its message. -/// Handlers should modify in place. -/// Relayed through inventory (e.g. voice masks) and status effects. +/// Raised on an entity to apply speech accents to its message. +/// Handlers should modify in place. +/// Relayed through inventory (e.g. voice masks) and status effects. /// [ByRefEvent] public record struct AccentGetEvent(EntityUid Entity, string Message) : IInventoryRelayEvent diff --git a/Content.Shared/Speech/Components/ActiveListenerComponent.cs b/Content.Shared/Speech/Components/ActiveListenerComponent.cs index fde108a817..921c6ce499 100644 --- a/Content.Shared/Speech/Components/ActiveListenerComponent.cs +++ b/Content.Shared/Speech/Components/ActiveListenerComponent.cs @@ -6,12 +6,12 @@ namespace Content.Shared.Speech.Components; /// /// This component is used to relay speech events to other systems. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class ActiveListenerComponent : Component { /// /// The range in which to listen to speech. /// - [DataField] + [DataField, AutoNetworkedField] public float Range = SharedChatSystem.VoiceRange; } diff --git a/Content.Shared/Speech/Components/AllCapsAccentComponent.cs b/Content.Shared/Speech/Components/AllCapsAccentComponent.cs index 7b0c37b538..88ad1e8286 100644 --- a/Content.Shared/Speech/Components/AllCapsAccentComponent.cs +++ b/Content.Shared/Speech/Components/AllCapsAccentComponent.cs @@ -1,7 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + namespace Content.Shared.Speech.Components; /// /// Marks a speech status effect that transforms spoken text to uppercase. /// -[RegisterComponent] +[RegisterComponent, NetworkedComponent] +[Access(typeof(AllCapsAccentSystem))] public sealed partial class AllCapsAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/BackwardsAccentComponent.cs b/Content.Shared/Speech/Components/BackwardsAccentComponent.cs new file mode 100644 index 0000000000..8d577ccd39 --- /dev/null +++ b/Content.Shared/Speech/Components/BackwardsAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// sdrawkcaB +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(BackwardsAccentSystem))] +public sealed partial class BackwardsAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/BarkAccentComponent.cs b/Content.Shared/Speech/Components/BarkAccentComponent.cs new file mode 100644 index 0000000000..8917f73464 --- /dev/null +++ b/Content.Shared/Speech/Components/BarkAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Arf! Arso makes "L" into "R"! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(BarkAccentSystem))] +public sealed partial class BarkAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/BleatingAccentComponent.cs b/Content.Shared/Speech/Components/BleatingAccentComponent.cs new file mode 100644 index 0000000000..7891dacfb7 --- /dev/null +++ b/Content.Shared/Speech/Components/BleatingAccentComponent.cs @@ -0,0 +1,12 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Makes this entity speak like a sheep or a goat in all chat messages it sends. +/// Repeats the vowel in certain consonant-vowel pairs so you taaaalk liiiike thiiiis. +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(BleatingAccentSystem))] +public sealed partial class BleatingAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/BlockListeningComponent.cs b/Content.Shared/Speech/Components/BlockListeningComponent.cs new file mode 100644 index 0000000000..472d03e16e --- /dev/null +++ b/Content.Shared/Speech/Components/BlockListeningComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Causes all ListenAttemptEvents to fail on the entity. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class BlockListeningComponent : Component; diff --git a/Content.Shared/Speech/Components/DamagedSiliconAccentComponent.cs b/Content.Shared/Speech/Components/DamagedSiliconAccentComponent.cs index 919347d080..d1965b1bd9 100644 --- a/Content.Shared/Speech/Components/DamagedSiliconAccentComponent.cs +++ b/Content.Shared/Speech/Components/DamagedSiliconAccentComponent.cs @@ -1,79 +1,83 @@ -using Content.Shared.FixedPoint; +using Content.Shared.FixedPoint; +using Content.Shared.Speech.EntitySystems; using Robust.Shared.GameStates; namespace Content.Shared.Speech.Components; +/// +/// Applies damage corruption effects to the speech. +/// [RegisterComponent, NetworkedComponent] public sealed partial class DamagedSiliconAccentComponent : BaseAccentComponent { /// - /// Enable damage corruption effects + /// Enable damage corruption effects /// [DataField] public bool EnableDamageCorruption = true; /// - /// Override total damage for damage corruption effects + /// Override total damage for damage corruption effects /// [DataField] public FixedPoint2? OverrideTotalDamage; /// - /// The probability that a character will be corrupted when total damage at or above . + /// The probability that a character will be corrupted when total damage at or above . /// [DataField] public float MaxDamageCorruption = 0.5f; /// - /// Probability of character corruption will increase linearly to once until - /// total damage is at or above this value. If null, it will use the value returned by - /// DestructibleSystem.DestroyedAt, which is the damage threshold for destruction or breakage. + /// Probability of character corruption will increase linearly to once until + /// total damage is at or above this value. If null, it will use the value returned by + /// DestructibleSystem.DestroyedAt, which is the damage threshold for destruction or breakage. /// [DataField] public FixedPoint2? DamageAtMaxCorruption; /// - /// Enable charge level corruption effects + /// Enable charge level corruption effects /// [DataField] public bool EnableChargeCorruption = true; /// - /// Override charge level for charge level corruption effects + /// Override charge level for charge level corruption effects /// [DataField] public float? OverrideChargeLevel; /// - /// If the power cell charge is below this value (as a fraction of maximum charge), - /// power corruption will begin to be applied. + /// If the power cell charge is below this value (as a fraction of maximum charge), + /// power corruption will begin to be applied. /// [DataField] public float ChargeThresholdForPowerCorruption = 0.15f; /// - /// Regardless of charge level, this is how many characters at the start of a message will be 100% safe - /// from being dropped. + /// Regardless of charge level, this is how many characters at the start of a message will be 100% safe + /// from being dropped. /// [DataField] public int StartPowerCorruptionAtCharIdx = 8; /// - /// The probability that a character will be dropped due to charge level will be maximum for characters past - /// this index. This has the effect of longer messages dropping more characters later in the message. + /// The probability that a character will be dropped due to charge level will be maximum for characters past + /// this index. This has the effect of longer messages dropping more characters later in the message. /// [DataField] public int MaxPowerCorruptionAtCharIdx = 40; /// - /// The maximum probability that a character will be dropped due to charge level. + /// The maximum probability that a character will be dropped due to charge level. /// [DataField] public float MaxDropProbFromPower = 0.5f; /// - /// If a character is "dropped", this is the probability that the character will be turned into a period instead - /// of completely deleting the character. + /// If a character is "dropped", this is the probability that the character will be turned into a period instead + /// of completely deleting the character. /// [DataField] public float ProbToCorruptDotFromPower = 0.6f; diff --git a/Content.Server/Speech/Components/FrenchAccentComponent.cs b/Content.Shared/Speech/Components/FrenchAccentComponent.cs similarity index 60% rename from Content.Server/Speech/Components/FrenchAccentComponent.cs rename to Content.Shared/Speech/Components/FrenchAccentComponent.cs index 29743f2787..2bbbde42b7 100644 --- a/Content.Server/Speech/Components/FrenchAccentComponent.cs +++ b/Content.Shared/Speech/Components/FrenchAccentComponent.cs @@ -1,11 +1,11 @@ -using Content.Server.Speech.EntitySystems; -using Content.Shared.Speech.Components; +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; -namespace Content.Server.Speech.Components; +namespace Content.Shared.Speech.Components; /// /// French accent replaces spoken letters. "th" becomes "z" and "H" at the start of a word becomes "'". /// -[RegisterComponent] +[RegisterComponent, NetworkedComponent] [Access(typeof(FrenchAccentSystem))] public sealed partial class FrenchAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/FrontalLispComponent.cs b/Content.Shared/Speech/Components/FrontalLispComponent.cs new file mode 100644 index 0000000000..a5082c0f5d --- /dev/null +++ b/Content.Shared/Speech/Components/FrontalLispComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Lithping! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(FrontalLispSystem))] +public sealed partial class FrontalLispComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/GermanAccentComponent.cs b/Content.Shared/Speech/Components/GermanAccentComponent.cs new file mode 100644 index 0000000000..e7c4bb6768 --- /dev/null +++ b/Content.Shared/Speech/Components/GermanAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Das accent, ja? +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(GermanAccentSystem))] +public sealed partial class GermanAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/LizardAccentComponent.cs b/Content.Shared/Speech/Components/LizardAccentComponent.cs new file mode 100644 index 0000000000..2d06c1875b --- /dev/null +++ b/Content.Shared/Speech/Components/LizardAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Hiss! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(LizardAccentSystem))] +public sealed partial class LizardAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/MeleeSpeechComponent.cs b/Content.Shared/Speech/Components/MeleeSpeechComponent.cs index e9bea22e2d..f93d928832 100644 --- a/Content.Shared/Speech/Components/MeleeSpeechComponent.cs +++ b/Content.Shared/Speech/Components/MeleeSpeechComponent.cs @@ -2,19 +2,15 @@ using Content.Shared.Actions; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Speech.Components; -[RegisterComponent, NetworkedComponent] -[AutoGenerateComponentState] - +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class MeleeSpeechComponent : Component { /// /// The battlecry to be said when an entity attacks with this component /// - [ViewVariables(VVAccess.ReadWrite)] [DataField("Battlecry")] [AutoNetworkedField] public string? Battlecry; @@ -22,21 +18,22 @@ public sealed partial class MeleeSpeechComponent : Component /// /// The maximum amount of characters allowed in a battlecry /// - [ViewVariables(VVAccess.ReadWrite)] [DataField("MaxBattlecryLength")] [AutoNetworkedField] public int MaxBattlecryLength = 12; - [DataField] public EntProtoId ConfigureAction = "ActionConfigureMeleeSpeech"; + [DataField] + public EntProtoId ConfigureAction = "ActionConfigureMeleeSpeech"; /// /// The action to open the battlecry UI /// - [DataField("configureActionEntity")] public EntityUid? ConfigureActionEntity; + [DataField] + public EntityUid? ConfigureActionEntity; } /// -/// Key representing which is currently open. +/// Key representing which is currently open. /// Useful when there are multiple UI for an object. Here it's future-proofing only. /// [Serializable, NetSerializable] @@ -49,23 +46,15 @@ public enum MeleeSpeechUiKey : byte /// Represents an state that can be sent to the client /// [Serializable, NetSerializable] -public sealed class MeleeSpeechBoundUserInterfaceState : BoundUserInterfaceState +public sealed class MeleeSpeechBoundUserInterfaceState(string currentBattlecry) : BoundUserInterfaceState { - public string CurrentBattlecry { get; } - public MeleeSpeechBoundUserInterfaceState(string currentBattlecry) - { - CurrentBattlecry = currentBattlecry; - } + public string CurrentBattlecry { get; } = currentBattlecry; } [Serializable, NetSerializable] -public sealed class MeleeSpeechBattlecryChangedMessage : BoundUserInterfaceMessage +public sealed class MeleeSpeechBattlecryChangedMessage(string battlecry) : BoundUserInterfaceMessage { - public string Battlecry { get; } - public MeleeSpeechBattlecryChangedMessage(string battlecry) - { - Battlecry = battlecry; - } + public string Battlecry { get; } = battlecry; } -public sealed partial class MeleeSpeechConfigureActionEvent : InstantActionEvent { } +public sealed partial class MeleeSpeechConfigureActionEvent : InstantActionEvent; diff --git a/Content.Shared/Speech/Components/MobsterAccentComponent.cs b/Content.Shared/Speech/Components/MobsterAccentComponent.cs new file mode 100644 index 0000000000..ca1b62b61c --- /dev/null +++ b/Content.Shared/Speech/Components/MobsterAccentComponent.cs @@ -0,0 +1,18 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Nyehh, my gabagool, see? +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(MobsterAccentSystem))] +public sealed partial class MobsterAccentComponent : BaseAccentComponent +{ + /// + /// Do you make all the rules? + /// + [DataField] + public bool IsBoss = true; +} diff --git a/Content.Shared/Speech/Components/MonkeyAccentComponent.cs b/Content.Shared/Speech/Components/MonkeyAccentComponent.cs new file mode 100644 index 0000000000..e8e73c4112 --- /dev/null +++ b/Content.Shared/Speech/Components/MonkeyAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// OOH AAH! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(MonkeyAccentSystem))] +public sealed partial class MonkeyAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/MothAccentComponent.cs b/Content.Shared/Speech/Components/MothAccentComponent.cs new file mode 100644 index 0000000000..fd3d3317b3 --- /dev/null +++ b/Content.Shared/Speech/Components/MothAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Buzzz! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(MothAccentSystem))] +public sealed partial class MothAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/MumbleAccentComponent.cs b/Content.Shared/Speech/Components/MumbleAccentComponent.cs similarity index 63% rename from Content.Server/Speech/Components/MumbleAccentComponent.cs rename to Content.Shared/Speech/Components/MumbleAccentComponent.cs index 0d809f64ac..a3f69f407b 100644 --- a/Content.Server/Speech/Components/MumbleAccentComponent.cs +++ b/Content.Shared/Speech/Components/MumbleAccentComponent.cs @@ -1,9 +1,14 @@ -using Content.Shared.Speech.Components; using Robust.Shared.Audio; +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; -namespace Content.Server.Speech.Components; +namespace Content.Shared.Speech.Components; -[RegisterComponent] +/// +/// Hmmfff! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(MumbleAccentSystem))] public sealed partial class MumbleAccentComponent : BaseAccentComponent { /// diff --git a/Content.Shared/Speech/Components/OwOAccentComponent.cs b/Content.Shared/Speech/Components/OwOAccentComponent.cs new file mode 100644 index 0000000000..f888113211 --- /dev/null +++ b/Content.Shared/Speech/Components/OwOAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// I am not typing out an example for this one. +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(OwOAccentSystem))] +public sealed partial class OwOAccentComponent : BaseAccentComponent; diff --git a/Content.Server/Speech/Components/ParrotAccentComponent.cs b/Content.Shared/Speech/Components/ParrotAccentComponent.cs similarity index 84% rename from Content.Server/Speech/Components/ParrotAccentComponent.cs rename to Content.Shared/Speech/Components/ParrotAccentComponent.cs index 2e10a505c6..980996c672 100644 --- a/Content.Server/Speech/Components/ParrotAccentComponent.cs +++ b/Content.Shared/Speech/Components/ParrotAccentComponent.cs @@ -1,11 +1,13 @@ -using Content.Shared.Speech.Components; +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; -namespace Content.Server.Speech.Components; +namespace Content.Shared.Speech.Components; /// -/// Makes this entity speak like a parrot in all chat messages it sends. +/// Makes this entity speak like a parrot in all chat messages it sends. SQUAWK! /// -[RegisterComponent] +[RegisterComponent, NetworkedComponent] +[Access(typeof(ParrotAccentSystem))] public sealed partial class ParrotAccentComponent : BaseAccentComponent { /// @@ -35,7 +37,8 @@ public sealed partial class ParrotAccentComponent : BaseAccentComponent /// /// Strings to use as squawking noises. /// - public readonly string[] Squawks = [ + public readonly string[] Squawks = + [ "accent-parrot-squawk-1", "accent-parrot-squawk-2", "accent-parrot-squawk-3", @@ -45,5 +48,4 @@ public sealed partial class ParrotAccentComponent : BaseAccentComponent "accent-parrot-squawk-7", "accent-parrot-squawk-8" ]; - } diff --git a/Content.Server/Speech/Components/PirateAccentComponent.cs b/Content.Shared/Speech/Components/PirateAccentComponent.cs similarity index 61% rename from Content.Server/Speech/Components/PirateAccentComponent.cs rename to Content.Shared/Speech/Components/PirateAccentComponent.cs index 34afabb8ee..eb34e681d1 100644 --- a/Content.Server/Speech/Components/PirateAccentComponent.cs +++ b/Content.Shared/Speech/Components/PirateAccentComponent.cs @@ -1,14 +1,16 @@ -using Content.Server.Speech.EntitySystems; -using Content.Shared.Speech.Components; +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; -namespace Content.Server.Speech.Components; +namespace Content.Shared.Speech.Components; -[RegisterComponent] +/// +/// Lets you speak Ratvarian! +/// +[RegisterComponent, NetworkedComponent] [Access(typeof(PirateAccentSystem))] public sealed partial class PirateAccentComponent : BaseAccentComponent { - [ViewVariables(VVAccess.ReadWrite)] - [DataField("yarrChance")] + [DataField] public float YarrChance = 0.5f; [ViewVariables] diff --git a/Content.Shared/Speech/Components/RatvarianLanguageComponent.cs b/Content.Shared/Speech/Components/RatvarianLanguageComponent.cs index ddb4ce5e90..c195c648ef 100644 --- a/Content.Shared/Speech/Components/RatvarianLanguageComponent.cs +++ b/Content.Shared/Speech/Components/RatvarianLanguageComponent.cs @@ -1,4 +1,5 @@ -using Robust.Shared.GameStates; +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; namespace Content.Shared.Speech.Components; @@ -6,4 +7,5 @@ namespace Content.Shared.Speech.Components; /// Marks a speech status effect that transforms spoken text into Ratvarian. /// [RegisterComponent, NetworkedComponent] +[Access(typeof(RatvarianLanguageSystem))] public sealed partial class RatvarianLanguageComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/ReplacementAccentComponent.cs b/Content.Shared/Speech/Components/ReplacementAccentComponent.cs new file mode 100644 index 0000000000..edb3d9bb3d --- /dev/null +++ b/Content.Shared/Speech/Components/ReplacementAccentComponent.cs @@ -0,0 +1,17 @@ +using Content.Shared.Speech.Prototypes; +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Speech.Components; + +/// +/// Replaces full sentences or words within sentences with new strings. +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(ReplacementAccentSystem))] +public sealed partial class ReplacementAccentComponent : BaseAccentComponent +{ + [DataField(required: true)] + public ProtoId Accent; +} diff --git a/Content.Shared/Speech/Components/RussianAccentComponent.cs b/Content.Shared/Speech/Components/RussianAccentComponent.cs new file mode 100644 index 0000000000..e210ccd434 --- /dev/null +++ b/Content.Shared/Speech/Components/RussianAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// ЯussiДи! Becomes incomprehensible to read for anyone who actually knows cyrillic. +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(RussianAccentSystem))] +public sealed partial class RussianAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/ScrambledAccentComponent.cs b/Content.Shared/Speech/Components/ScrambledAccentComponent.cs new file mode 100644 index 0000000000..dd82de4ccb --- /dev/null +++ b/Content.Shared/Speech/Components/ScrambledAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Structure is sentence weird accent this with! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(ScrambledAccentSystem))] +public sealed partial class ScrambledAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/SkeletonAccentComponent.cs b/Content.Shared/Speech/Components/SkeletonAccentComponent.cs new file mode 100644 index 0000000000..d8e301feb8 --- /dev/null +++ b/Content.Shared/Speech/Components/SkeletonAccentComponent.cs @@ -0,0 +1,18 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Rattle me bones! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(SkeletonAccentSystem))] +public sealed partial class SkeletonAccentComponent : BaseAccentComponent +{ + /// + /// Chance that the message will be appended with "ACK ACK!" + /// + [DataField] + public float AckChance = 0.3f; // Funnier if it doesn't happen every single time +} diff --git a/Content.Shared/Speech/Components/SlowAccentComponent.cs b/Content.Shared/Speech/Components/SlowAccentComponent.cs new file mode 100644 index 0000000000..51e4186bc9 --- /dev/null +++ b/Content.Shared/Speech/Components/SlowAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Makes... the... entity... talk... like... this... +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(SlowAccentSystem))] +public sealed partial class SlowAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/SlurredAccentComponent.cs b/Content.Shared/Speech/Components/SlurredAccentComponent.cs index 004a62a777..daf52870c8 100644 --- a/Content.Shared/Speech/Components/SlurredAccentComponent.cs +++ b/Content.Shared/Speech/Components/SlurredAccentComponent.cs @@ -1,6 +1,24 @@ +using Content.Shared.Speech.EntitySystems; using Robust.Shared.GameStates; namespace Content.Shared.Speech.Components; +/// +/// Go houhhm... yo'r drrunkk... +/// [RegisterComponent, NetworkedComponent] -public sealed partial class SlurredAccentComponent : BaseAccentComponent; +[Access(typeof(SlurredSystem))] +public sealed partial class SlurredAccentComponent : BaseAccentComponent +{ + /// + /// Divisor applied to total seconds used to get the odds of slurred speech occuring. + /// + [DataField] + public float SlurredModifier = 1100f; + + /// + /// Minimum amount of time on the slurred accent for it to start taking effect. + /// + [DataField] + public float SlurredThreshold = 80f; +} diff --git a/Content.Shared/Speech/Components/SouthernAccentComponent.cs b/Content.Shared/Speech/Components/SouthernAccentComponent.cs new file mode 100644 index 0000000000..89543aaa9e --- /dev/null +++ b/Content.Shared/Speech/Components/SouthernAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Dagnabit. +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(SouthernAccentSystem))] +public sealed partial class SouthernAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/SpanishAccentComponent.cs b/Content.Shared/Speech/Components/SpanishAccentComponent.cs new file mode 100644 index 0000000000..e8227cf942 --- /dev/null +++ b/Content.Shared/Speech/Components/SpanishAccentComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Mios dios! +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(SpanishAccentSystem))] +public sealed partial class SpanishAccentComponent : BaseAccentComponent; diff --git a/Content.Shared/Speech/Components/SpeakOnActionComponent.cs b/Content.Shared/Speech/Components/SpeakOnActionComponent.cs index 3de09932e2..8a33c858b5 100644 --- a/Content.Shared/Speech/Components/SpeakOnActionComponent.cs +++ b/Content.Shared/Speech/Components/SpeakOnActionComponent.cs @@ -6,7 +6,8 @@ namespace Content.Shared.Speech.Components; /// /// Action components which should write a message to ICChat on use /// -[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedSpeakOnActionSystem))] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SpeakOnActionSystem))] public sealed partial class SpeakOnActionComponent : Component { /// diff --git a/Content.Shared/Speech/Components/StutteringAccentComponent.cs b/Content.Shared/Speech/Components/StutteringAccentComponent.cs index ff64885238..1c1dc1b95d 100644 --- a/Content.Shared/Speech/Components/StutteringAccentComponent.cs +++ b/Content.Shared/Speech/Components/StutteringAccentComponent.cs @@ -1,8 +1,13 @@ +using Content.Shared.Speech.EntitySystems; using Robust.Shared.GameStates; namespace Content.Shared.Speech.Components; +/// +/// S-s-s-stuttering! +/// [RegisterComponent, NetworkedComponent] +[Access(typeof(StutteringSystem))] public sealed partial class StutteringAccentComponent : BaseAccentComponent { /// diff --git a/Content.Shared/Speech/Components/UnblockableSpeechComponent.cs b/Content.Shared/Speech/Components/UnblockableSpeechComponent.cs new file mode 100644 index 0000000000..842cb18e83 --- /dev/null +++ b/Content.Shared/Speech/Components/UnblockableSpeechComponent.cs @@ -0,0 +1,11 @@ +using Content.Shared.Speech.EntitySystems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Speech.Components; + +/// +/// Makes the entity's speech unblockable by speech-blocking effects or entities. +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(UnblockableSpeechSystem))] +public sealed partial class UnblockableSpeechComponent : Component; diff --git a/Content.Shared/Speech/Components/VocalComponent.cs b/Content.Shared/Speech/Components/VocalComponent.cs index f41c5e7e3d..1579887fac 100644 --- a/Content.Shared/Speech/Components/VocalComponent.cs +++ b/Content.Shared/Speech/Components/VocalComponent.cs @@ -1,5 +1,5 @@ using Content.Shared.Chat.Prototypes; -using Content.Shared.Humanoid; +using Content.Shared.Speech.EntitySystems; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; @@ -9,8 +9,8 @@ namespace Content.Shared.Speech.Components; /// /// Component required for entities to be able to do vocal emotions. /// -[RegisterComponent, NetworkedComponent] -[AutoGenerateComponentState] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(VocalSystem))] public sealed partial class VocalComponent : Component { //TODO: Wilhelm scream logic needs to be more generic @@ -53,5 +53,5 @@ public sealed partial class VocalComponent : Component /// [DataField] [AutoNetworkedField] - public ProtoId? EmoteSounds = null; + public ProtoId? EmoteSounds; } diff --git a/Content.Server/Speech/Components/VoiceOverrideComponent.cs b/Content.Shared/Speech/Components/VoiceOverrideComponent.cs similarity index 82% rename from Content.Server/Speech/Components/VoiceOverrideComponent.cs rename to Content.Shared/Speech/Components/VoiceOverrideComponent.cs index 349babc948..7369c12200 100644 --- a/Content.Server/Speech/Components/VoiceOverrideComponent.cs +++ b/Content.Shared/Speech/Components/VoiceOverrideComponent.cs @@ -1,7 +1,7 @@ -using Content.Shared.Speech; +using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -namespace Content.Server.Speech.Components; +namespace Content.Shared.Speech.Components; /// /// Will change the voice of the entity that has the component (e.g radio and speech). @@ -10,7 +10,7 @@ namespace Content.Server.Speech.Components; /// Before using this component, please take a look at the the TransformSpeakerNameEvent (and the inventory relay version). /// Depending on what you're doing, it could be a better choice! /// -[RegisterComponent] +[RegisterComponent, NetworkedComponent] public sealed partial class VoiceOverrideComponent : Component { /// @@ -18,14 +18,14 @@ public sealed partial class VoiceOverrideComponent : Component /// Uses the localized version of the string and if null wont do anything. /// [DataField] - public string? NameOverride = null; + public string? NameOverride; /// /// The verb that will be used insteand of an entities default one. /// If null, the defaut will be used. /// [DataField] - public ProtoId? SpeechVerbOverride = null; + public ProtoId? SpeechVerbOverride; /// /// If true, the override values (if they are not null) will be applied. diff --git a/Content.Server/Speech/AccentSystem.cs b/Content.Shared/Speech/EntitySystems/AccentSystem.cs similarity index 67% rename from Content.Server/Speech/AccentSystem.cs rename to Content.Shared/Speech/EntitySystems/AccentSystem.cs index 67353e8e9b..f05765b9f9 100644 --- a/Content.Server/Speech/AccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/AccentSystem.cs @@ -1,18 +1,13 @@ using System.Text.RegularExpressions; using Content.Shared.Chat; -using Content.Shared.Speech; -namespace Content.Server.Speech; +namespace Content.Shared.Speech.EntitySystems; -public sealed class AccentSystem : EntitySystem +public sealed partial class AccentSystem : EntitySystem { public static readonly Regex SentenceRegex = new(@"(?<=[\.!\?‽])(?![\.!\?‽])", RegexOptions.Compiled); - public override void Initialize() - { - SubscribeLocalEvent(AccentHandler); - } - + [SubscribeLocalEvent] private void AccentHandler(TransformSpeechEvent args) { if (args.Cancelled) diff --git a/Content.Server/Speech/EntitySystems/BackwardsAccentSystem.cs b/Content.Shared/Speech/EntitySystems/BackwardsAccentSystem.cs similarity index 70% rename from Content.Server/Speech/EntitySystems/BackwardsAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/BackwardsAccentSystem.cs index 838e0d53d5..2bb9941898 100644 --- a/Content.Server/Speech/EntitySystems/BackwardsAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/BackwardsAccentSystem.cs @@ -1,7 +1,6 @@ -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class BackwardsAccentSystem : RelayAccentSystem { diff --git a/Content.Shared/Speech/EntitySystems/BarkAccentSystem.cs b/Content.Shared/Speech/EntitySystems/BarkAccentSystem.cs new file mode 100644 index 0000000000..501a3a0d3a --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/BarkAccentSystem.cs @@ -0,0 +1,43 @@ +using System.Collections.Frozen; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class BarkAccentSystem : RelayAccentSystem +{ + [Dependency] private IGameTiming _timing = default!; + [Dependency] private IRobustRandom _random = default!; + + private static readonly IReadOnlyList Barks = + [ + " Woof!", " WOOF", " wof-wof", + ]; + + private static readonly FrozenDictionary SpecialWords = + new Dictionary + { + { "ah", "arf" }, + { "Ah", "Arf" }, + { "oh", "oof" }, + { "Oh", "Oof" }, + }.ToFrozenDictionary(); + + public override string Accentuate(string message, Entity? ent = null) + { + var random = ent.HasValue + ? SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)) + : _random; + + foreach (var (word, repl) in SpecialWords) + { + message = message.Replace(word, repl); + } + + return message.Replace("!", random.Pick(Barks)) + .Replace("l", "r") + .Replace("L", "R"); + } +} diff --git a/Content.Server/Speech/EntitySystems/BleatingAccentSystem.cs b/Content.Shared/Speech/EntitySystems/BleatingAccentSystem.cs similarity index 79% rename from Content.Server/Speech/EntitySystems/BleatingAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/BleatingAccentSystem.cs index 0871dd1c72..4c5605a1c0 100644 --- a/Content.Server/Speech/EntitySystems/BleatingAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/BleatingAccentSystem.cs @@ -1,8 +1,7 @@ using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class BleatingAccentSystem : RelayAccentSystem { diff --git a/Content.Shared/Speech/EntitySystems/BlockListeningSystem.cs b/Content.Shared/Speech/EntitySystems/BlockListeningSystem.cs new file mode 100644 index 0000000000..2ae03feafd --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/BlockListeningSystem.cs @@ -0,0 +1,12 @@ +using Content.Shared.Speech.Components; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class BlockListeningSystem : EntitySystem +{ + [SubscribeLocalEvent] + private void OnListenAttempt(Entity ent, ref ListenAttemptEvent args) + { + args.Cancel(); + } +} diff --git a/Content.Shared/Speech/EntitySystems/EmoteBlockerSystem.cs b/Content.Shared/Speech/EntitySystems/EmoteBlockerSystem.cs index e2c9728fbc..eaa7b8e957 100644 --- a/Content.Shared/Speech/EntitySystems/EmoteBlockerSystem.cs +++ b/Content.Shared/Speech/EntitySystems/EmoteBlockerSystem.cs @@ -14,26 +14,26 @@ public sealed class EmoteBlockerSystem : EntitySystem SubscribeLocalEvent>(OnRelayedEmoteEvent); } - private static void OnRelayedEmoteEvent(Entity entity, ref InventoryRelayedEvent args) + private static void OnRelayedEmoteEvent(Entity ent, ref InventoryRelayedEvent args) { - OnEmoteEvent(entity, ref args.Args); + OnEmoteEvent(ent, ref args.Args); } - private static void OnEmoteEvent(Entity entity, ref BeforeEmoteEvent args) + private static void OnEmoteEvent(Entity ent, ref BeforeEmoteEvent args) { - if (entity.Comp.BlocksEmotes.Contains(args.Emote)) + if (ent.Comp.BlocksEmotes.Contains(args.Emote)) { args.Cancel(); - args.Blocker = entity; + args.Blocker = ent; return; } - foreach (var blockedCat in entity.Comp.BlocksCategories) + foreach (var blockedCat in ent.Comp.BlocksCategories) { if (blockedCat == args.Emote.Category) { args.Cancel(); - args.Blocker = entity; + args.Blocker = ent; return; } } diff --git a/Content.Server/Speech/EmotesMenuSystem.cs b/Content.Shared/Speech/EntitySystems/EmotesMenuSystem.cs similarity index 83% rename from Content.Server/Speech/EmotesMenuSystem.cs rename to Content.Shared/Speech/EntitySystems/EmotesMenuSystem.cs index 8a4841d82a..978c75b2d9 100644 --- a/Content.Server/Speech/EmotesMenuSystem.cs +++ b/Content.Shared/Speech/EntitySystems/EmotesMenuSystem.cs @@ -1,11 +1,10 @@ using Content.Shared.Chat; -using Content.Server.Chat.Systems; -namespace Content.Server.Speech; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class EmotesMenuSystem : EntitySystem { - [Dependency] private ChatSystem _chat = default!; + [Dependency] private SharedChatSystem _chat = default!; public override void Initialize() { diff --git a/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs b/Content.Shared/Speech/EntitySystems/FrenchAccentSystem.cs similarity index 71% rename from Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/FrenchAccentSystem.cs index 50d5961d37..be173dff30 100644 --- a/Content.Server/Speech/EntitySystems/FrenchAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/FrenchAccentSystem.cs @@ -1,8 +1,7 @@ using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; /// /// System that gives the speaker a faux-French accent. @@ -11,7 +10,7 @@ public sealed partial class FrenchAccentSystem : RelayAccentSystem +{ + // @formatter:off + private static readonly Regex RegexUpperTh = new("[T]+[Ss]+|[S]+[Cc]+(?=[IiEeYy]+)|[C]+(?=[IiEeYy]+)|[P][Ss]+|([S]+[Tt]+|[T]+)(?=[Ii]+[Oo]+[Uu]*[Nn]*)|[C]+[Hh]+(?=[Ii]*[Ee]*)|[Z]+|[S]+|[X]+(?=[Ee]+)"); + private static readonly Regex RegexLowerTh = new("[t]+[s]+|[s]+[c]+(?=[iey]+)|[c]+(?=[iey]+)|[p][s]+|([s]+[t]+|[t]+)(?=[i]+[o]+[u]*[n]*)|[c]+[h]+(?=[i]*[e]*)|[z]+|[s]+|[x]+(?=[e]+)"); + private static readonly Regex RegexUpperEcks = new("[E]+[Xx]+[Cc]*|[X]+"); + private static readonly Regex RegexLowerEcks = new("[e]+[x]+[c]*|[x]+"); + // @formatter:on + + public override string Accentuate(string message, Entity? ent = null) + { + // handles ts, sc(i|e|y), c(i|e|y), ps, st(io(u|n)), ch(i|e), z, s + message = RegexUpperTh.Replace(message, "TH"); + message = RegexLowerTh.Replace(message, "th"); + // handles ex(c), x + message = RegexUpperEcks.Replace(message, "EKTH"); + message = RegexLowerEcks.Replace(message, "ekth"); + return message; + } +} diff --git a/Content.Server/Speech/EntitySystems/GermanAccentSystem.cs b/Content.Shared/Speech/EntitySystems/GermanAccentSystem.cs similarity index 82% rename from Content.Server/Speech/EntitySystems/GermanAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/GermanAccentSystem.cs index 47868dd9ff..83adebe110 100644 --- a/Content.Server/Speech/EntitySystems/GermanAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/GermanAccentSystem.cs @@ -1,14 +1,15 @@ using System.Text; using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; using Robust.Shared.Random; +using Robust.Shared.Timing; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class GermanAccentSystem : RelayAccentSystem { + [Dependency] private IGameTiming _timing = default!; [Dependency] private IRobustRandom _random = default!; [Dependency] private ReplacementAccentSystem _replacement = default!; @@ -19,11 +20,15 @@ public sealed partial class GermanAccentSystem : RelayAccentSystem ze is handled by replacements already) var msgBuilder = new StringBuilder(msg); @@ -51,7 +56,7 @@ public sealed partial class GermanAccentSystem : RelayAccentSystem -/// This system redirects local chat messages to listening entities (e.g., radio microphones). +/// This system redirects local chat messages to listening entities (e.g., radio microphones). /// public sealed partial class ListeningSystem : EntitySystem { [Dependency] private SharedTransformSystem _xforms = default!; - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(OnSpeak); - } - + [SubscribeLocalEvent] private void OnSpeak(EntitySpokeEvent ev) { PingListeners(ev.Source, ev.Message, ev.ObfuscatedMessage); } + /// + /// Sends a speech message to entities listening within range. + /// public void PingListeners(EntityUid source, string message, string? obfuscatedMessage) { // TODO whispering / audio volume? Microphone sensitivity? @@ -54,7 +50,7 @@ public sealed partial class ListeningSystem : EntitySystem continue; } - if (obfuscatedEv != null && distance > ChatSystem.WhisperClearRange) + if (obfuscatedEv != null && distance > SharedChatSystem.WhisperClearRange) RaiseLocalEvent(listenerUid, obfuscatedEv); else RaiseLocalEvent(listenerUid, ev); diff --git a/Content.Server/Speech/EntitySystems/LizardAccentSystem.cs b/Content.Shared/Speech/EntitySystems/LizardAccentSystem.cs similarity index 88% rename from Content.Server/Speech/EntitySystems/LizardAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/LizardAccentSystem.cs index b460d66e94..3467a7005a 100644 --- a/Content.Server/Speech/EntitySystems/LizardAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/LizardAccentSystem.cs @@ -1,8 +1,7 @@ using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed class LizardAccentSystem : RelayAccentSystem { diff --git a/Content.Shared/Speech/EntitySystems/MeleeSpeechSystem.cs b/Content.Shared/Speech/EntitySystems/MeleeSpeechSystem.cs new file mode 100644 index 0000000000..7e25d0c5cb --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/MeleeSpeechSystem.cs @@ -0,0 +1,85 @@ +using Content.Shared.Administration.Logs; +using Content.Shared.Actions; +using Content.Shared.Database; +using Content.Shared.Speech.Components; +using Robust.Shared.Player; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class MeleeSpeechSystem : EntitySystem +{ + [Dependency] private ISharedAdminLogManager _adminLogger = default!; + [Dependency] private SharedActionsSystem _action = default!; + [Dependency] private SharedUserInterfaceSystem _ui = default!; + + [SubscribeLocalEvent] + private void OnComponentMapInit(Entity ent, ref MapInitEvent args) + { + _action.AddAction(ent, ref ent.Comp.ConfigureActionEntity, ent.Comp.ConfigureAction, ent); + } + + [SubscribeLocalEvent] + private void OnGetActions(Entity ent, ref GetItemActionsEvent args) + { + args.AddAction(ref ent.Comp.ConfigureActionEntity, ent.Comp.ConfigureAction); + } + + [SubscribeLocalEvent] + private void OnBattlecryChanged(Entity ent, ref MeleeSpeechBattlecryChangedMessage args) + { + var battlecry = args.Battlecry; + if (battlecry.Length > ent.Comp.MaxBattlecryLength) + battlecry = battlecry[..ent.Comp.MaxBattlecryLength]; + + TryChangeBattlecry(ent.AsNullable(), battlecry); + } + + /// + /// Attempts to open the Battlecry UI. + /// + [SubscribeLocalEvent] + private void OnConfigureAction(Entity ent, ref MeleeSpeechConfigureActionEvent args) + { + TryOpenUi(args.Performer, ent.AsNullable()); + } + + /// + /// Attempts to open the Battlecry UI for a user. + /// + public void TryOpenUi(EntityUid user, Entity source) + { + if (!Resolve(source, ref source.Comp)) + return; + + if (!TryComp(user, out var actor)) + return; + + _ui.TryToggleUi(source.Owner, MeleeSpeechUiKey.Key, actor.PlayerSession); + } + + /// + /// Attempts to change the battlecry of an entity. + /// Returns true/false. + /// + /// + /// Logs changes to an entity's battlecry + /// + public bool TryChangeBattlecry(Entity ent, string? battlecry) + { + if (!Resolve(ent, ref ent.Comp)) + return false; + + battlecry = !string.IsNullOrWhiteSpace(battlecry) ? battlecry.Trim() : null; + + if (ent.Comp.Battlecry == battlecry) + return true; + + ent.Comp.Battlecry = battlecry; + Dirty(ent); + _adminLogger.Add(LogType.ItemConfigure, + LogImpact.Medium, + $" {ToPrettyString(ent):entity}'s battlecry has been changed to {battlecry}"); + + return true; + } +} diff --git a/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs b/Content.Shared/Speech/EntitySystems/MobsterAccentSystem.cs similarity index 83% rename from Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/MobsterAccentSystem.cs index 48d0ff88df..6b94012fe9 100644 --- a/Content.Server/Speech/EntitySystems/MobsterAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/MobsterAccentSystem.cs @@ -1,10 +1,11 @@ using System.Linq; using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; using Robust.Shared.Random; +using Robust.Shared.Timing; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class MobsterAccentSystem : RelayAccentSystem { @@ -16,6 +17,8 @@ public sealed partial class MobsterAccentSystem : RelayAccentSystem thinkin' // king -> king @@ -40,12 +47,12 @@ public sealed partial class MobsterAccentSystem : RelayAccentSystem { + [Dependency] private IGameTiming _timing = default!; [Dependency] private IRobustRandom _random = default!; public override string Accentuate(string message, Entity? ent = null) { + var random = ent.HasValue + ? SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)) + : _random; + var words = message.Split(); var accentedMessage = new StringBuilder(message.Length + 2); @@ -18,7 +24,7 @@ public sealed partial class MonkeyAccentSystem : RelayAccentSystem= 0.5) + if (random.NextDouble() >= 0.5) { if (word.Length > 1) { @@ -27,7 +33,7 @@ public sealed partial class MonkeyAccentSystem : RelayAccentSystem= 0.3) + if (random.NextDouble() >= 0.3) accentedMessage.Append('K'); } else @@ -37,7 +43,7 @@ public sealed partial class MonkeyAccentSystem : RelayAccentSystem= 0.8) + if (random.NextDouble() >= 0.8) accentedMessage.Append('H'); else accentedMessage.Append('A'); diff --git a/Content.Server/Speech/EntitySystems/MothAccentSystem.cs b/Content.Shared/Speech/EntitySystems/MothAccentSystem.cs similarity index 59% rename from Content.Server/Speech/EntitySystems/MothAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/MothAccentSystem.cs index 60f7812914..03b0dde54c 100644 --- a/Content.Server/Speech/EntitySystems/MothAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/MothAccentSystem.cs @@ -1,13 +1,12 @@ using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed class MothAccentSystem : RelayAccentSystem { - private static readonly Regex RegexLowerBuzz = new Regex("z{1,3}"); - private static readonly Regex RegexUpperBuzz = new Regex("Z{1,3}"); + private static readonly Regex RegexLowerBuzz = new("z{1,3}"); + private static readonly Regex RegexUpperBuzz = new("Z{1,3}"); public override string Accentuate(string message, Entity? ent = null) { diff --git a/Content.Server/Speech/EntitySystems/MumbleAccentSystem.cs b/Content.Shared/Speech/EntitySystems/MumbleAccentSystem.cs similarity index 79% rename from Content.Server/Speech/EntitySystems/MumbleAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/MumbleAccentSystem.cs index 7cf1ce3320..f5fd2dceb8 100644 --- a/Content.Server/Speech/EntitySystems/MumbleAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/MumbleAccentSystem.cs @@ -1,16 +1,12 @@ -using Content.Server.Chat.Systems; -using Content.Server.Speech.Components; +using Content.Shared.Speech.Components; using Content.Shared.Chat; using Content.Shared.Chat.Prototypes; -using Content.Shared.Speech.Components; -using Content.Shared.Speech.EntitySystems; -using Robust.Shared.Prototypes; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class MumbleAccentSystem : RelayAccentSystem { - [Dependency] private ChatSystem _chat = default!; + [Dependency] private SharedChatSystem _chat = default!; [Dependency] private ReplacementAccentSystem _replacement = default!; public override void Initialize() @@ -39,6 +35,6 @@ public sealed partial class MumbleAccentSystem : RelayAccentSystem? ent = null) { - return _replacement.ApplyReplacements(message, "mumble"); + return _replacement.ApplyReplacements(message, "mumble", ent?.Owner); } } diff --git a/Content.Shared/Speech/EntitySystems/OwOAccentSystem.cs b/Content.Shared/Speech/EntitySystems/OwOAccentSystem.cs new file mode 100644 index 0000000000..73dcd80cb0 --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/OwOAccentSystem.cs @@ -0,0 +1,42 @@ +using System.Collections.Frozen; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class OwOAccentSystem : RelayAccentSystem +{ + [Dependency] private IGameTiming _timing = default!; + [Dependency] private IRobustRandom _random = default!; + + private static readonly IReadOnlyList Faces = + [ + " (•`ω´•)", " ;;w;;", " owo", " UwU", " >w<", " ^w^", + ]; + + private static readonly FrozenDictionary SpecialWords = + new Dictionary + { + { "you", "wu" }, + }.ToFrozenDictionary(); + + public override string Accentuate(string message, Entity? ent = null) + { + var random = ent.HasValue + ? SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)) + : _random; + + foreach (var (word, repl) in SpecialWords) + { + message = message.Replace(word, repl); + } + + return message.Replace("!", random.Pick(Faces)) + .Replace("r", "w") + .Replace("R", "W") + .Replace("l", "w") + .Replace("L", "W"); + } +} diff --git a/Content.Server/Speech/EntitySystems/ParrotAccentSystem.cs b/Content.Shared/Speech/EntitySystems/ParrotAccentSystem.cs similarity index 62% rename from Content.Server/Speech/EntitySystems/ParrotAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/ParrotAccentSystem.cs index fffe1875cf..4d5eb3edbe 100644 --- a/Content.Server/Speech/EntitySystems/ParrotAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/ParrotAccentSystem.cs @@ -1,25 +1,27 @@ using System.Linq; using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; using Robust.Shared.Random; +using Robust.Shared.Timing; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class ParrotAccentSystem : RelayAccentSystem { - private static readonly Regex WordCleanupRegex = new Regex("[^A-Za-z0-9 -]"); + private static readonly Regex WordCleanupRegex = new("[^A-Za-z0-9 -]"); - [Dependency] private IRobustRandom _random = default!; + [Dependency] private IGameTiming _timing = default!; public override string Accentuate(string message, Entity? ent = null) { - // TODO: Make this accent possible to apply without an entity with the component. if (ent == null) return message; + var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)); + // Sometimes repeat the longest word at the end of the message, after a squawk! SQUAWK! Sometimes! - if (_random.Prob(ent.Value.Comp.LongestWordRepeatChance)) + if (random.Prob(ent.Value.Comp.LongestWordRepeatChance)) { // Don't count non-alphanumeric characters as parts of words var cleaned = WordCleanupRegex.Replace(message, string.Empty); @@ -27,6 +29,7 @@ public sealed partial class ParrotAccentSystem : RelayAccentSystem word.Length); + if (longest?.Length >= ent.Value.Comp.LongestWordMinLength) { message = EnsurePunctuation(message); @@ -34,21 +37,21 @@ public sealed partial class ParrotAccentSystem : RelayAccentSystem private string EnsurePunctuation(string message) { - if (!message.EndsWith('!') && !message.EndsWith('?') && !message.EndsWith('.')) - return message + '!'; - return message; + return message.EndsWith('!') || message.EndsWith('?') || message.EndsWith('.') + ? message + : message + '!'; } /// /// Returns a random, localized squawk sound. /// - private string GetRandomSquawk(Entity entity) + private string GetRandomSquawk(Entity ent) { - return Loc.GetString(_random.Pick(entity.Comp.Squawks)); + var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent)); + return Loc.GetString(random.Pick(ent.Comp.Squawks)); } } diff --git a/Content.Server/Speech/EntitySystems/PirateAccentSystem.cs b/Content.Shared/Speech/EntitySystems/PirateAccentSystem.cs similarity index 60% rename from Content.Server/Speech/EntitySystems/PirateAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/PirateAccentSystem.cs index aa7ed96529..88de28e174 100644 --- a/Content.Server/Speech/EntitySystems/PirateAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/PirateAccentSystem.cs @@ -1,32 +1,39 @@ using System.Linq; -using Content.Server.Speech.Components; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; using Robust.Shared.Random; +using Robust.Shared.Timing; using System.Text.RegularExpressions; -using Content.Shared.Speech.EntitySystems; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class PirateAccentSystem : RelayAccentSystem { private static readonly Regex FirstWordAllCapsRegex = new(@"^(\S+)"); + [Dependency] private IGameTiming _timing = default!; [Dependency] private IRobustRandom _random = default!; [Dependency] private ReplacementAccentSystem _replacement = default!; - // converts left word when typed into the right word. For example typing you becomes ye. + // Converts left word when typed into the right word. For example typing you becomes ye. public override string Accentuate(string message, Entity? ent = null) { - var msg = _replacement.ApplyReplacements(message, "pirate"); + var random = ent.HasValue + ? SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)) + : _random; - if (!_random.Prob(ent.HasValue ? ent.Value.Comp.YarrChance : 0.5f)) + var msg = _replacement.ApplyReplacements(message, "pirate", ent?.Owner); + + if (!random.Prob(ent.HasValue ? ent.Value.Comp.YarrChance : 0.5f)) return msg; - //Checks if the first word of the sentence is all caps - //So the prefix can be allcapped and to not resanitize the captial + + // Checks if the first word of the sentence is all caps + // So the prefix can be allcapped and to not resanitize the captial var firstWordAllCaps = !FirstWordAllCapsRegex.Match(msg).Value.Any(char.IsLower); if (ent.HasValue) { - var pick = _random.Pick(ent.Value.Comp.PirateWords); + var pick = random.Pick(ent.Value.Comp.PirateWords); var pirateWord = Loc.GetString(pick); // Reverse sanitize capital if (!firstWordAllCaps) diff --git a/Content.Shared/Speech/EntitySystems/SharedRatvarianLanguageSystem.cs b/Content.Shared/Speech/EntitySystems/RatvarianLanguageSystem.cs similarity index 87% rename from Content.Shared/Speech/EntitySystems/SharedRatvarianLanguageSystem.cs rename to Content.Shared/Speech/EntitySystems/RatvarianLanguageSystem.cs index 969af67990..73447ff5f1 100644 --- a/Content.Shared/Speech/EntitySystems/SharedRatvarianLanguageSystem.cs +++ b/Content.Shared/Speech/EntitySystems/RatvarianLanguageSystem.cs @@ -7,14 +7,14 @@ using Robust.Shared.Prototypes; namespace Content.Shared.Speech.EntitySystems; -public abstract partial class SharedRatvarianLanguageSystem : RelayAccentSystem +public sealed partial class RatvarianLanguageSystem : RelayAccentSystem { public static readonly EntProtoId Ratvarian = "StatusEffectRatvarianLanguage"; - [Dependency] protected StatusEffectsSystem Status = default!; + [Dependency] private StatusEffectsSystem _statusEffect = default!; - protected override Type[] AccentBefore => [typeof(SharedSlurredSystem), typeof(SharedStutteringSystem)]; - protected override Type[] RelayAccentBefore => [typeof(SharedSlurredSystem), typeof(SharedStutteringSystem)]; + protected override Type[] AccentBefore => [typeof(SlurredSystem), typeof(StutteringSystem)]; + protected override Type[] RelayAccentBefore => [typeof(SlurredSystem), typeof(StutteringSystem)]; // This is the word of Ratvar and those who speak it shall abide by His rules: /* @@ -40,14 +40,6 @@ public abstract partial class SharedRatvarianLanguageSystem : RelayAccentSystem< private static readonly Regex TomyPattern = new(@"(to|my)\s", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ProperNouns = new("(ratvar)|(nezbere)|(sevtuq)|(nzcrentr)|(inath-neq)", RegexOptions.Compiled | RegexOptions.IgnoreCase); - /// - /// Applies or refreshes the Ratvarian speech status effect on an entity. - /// - [PublicAPI] - public virtual void DoRatvarian(EntityUid uid, TimeSpan time, bool refresh) - { - } - public override string Accentuate(string message, Entity? ent = null) { var ruleTranslation = message; @@ -105,4 +97,16 @@ public abstract partial class SharedRatvarianLanguageSystem : RelayAccentSystem< return finalMessage.ToString().Trim(); } + + /// + /// Applies or refreshes the Ratvarian speech status effect on an entity. + /// + [PublicAPI] + public void DoRatvarian(EntityUid uid, TimeSpan time, bool refresh) + { + if (refresh) + _statusEffect.TryUpdateStatusEffectDuration(uid, Ratvarian, time); + else + _statusEffect.TryAddStatusEffectDuration(uid, Ratvarian, time); + } } diff --git a/Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs b/Content.Shared/Speech/EntitySystems/ReplacementAccentSystem.cs similarity index 77% rename from Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/ReplacementAccentSystem.cs index e40af39fa1..854e37b958 100644 --- a/Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/ReplacementAccentSystem.cs @@ -1,14 +1,14 @@ using System.Linq; using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Server.Speech.Prototypes; -using Content.Shared.Speech; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; +using Content.Shared.Speech.Prototypes; using JetBrains.Annotations; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Shared.Timing; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; // TODO: Code in-game languages and make this a language /// @@ -16,6 +16,7 @@ namespace Content.Server.Speech.EntitySystems; /// public sealed partial class ReplacementAccentSystem : RelayAccentSystem { + [Dependency] private IGameTiming _timing = default!; [Dependency] private IRobustRandom _random = default!; private readonly Dictionary, (Regex regex, string replacement)[]> @@ -40,26 +41,40 @@ public sealed partial class ReplacementAccentSystem : RelayAccentSystem - /// Attempts to apply a given replacement accent prototype to a message. + /// Applies a replacement accent to an entity. /// [PublicAPI] - public string ApplyReplacements(string message, string accent) + public void ApplyAccent(EntityUid uid, string accent) + { + var component = EnsureComp(uid); + component.Accent = accent; + Dirty(uid, component); + } + + /// + /// Attempts to apply a given replacement accent prototype to a message. + /// + [PublicAPI] + public string ApplyReplacements(string message, string accent, EntityUid? uid = null) { if (!ProtoMan.TryIndex(accent, out var prototype)) return message; - if (!_random.Prob(prototype.ReplacementChance)) + var random = uid != null + ? SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(uid.Value)) + : _random; + if (!random.Prob(prototype.ReplacementChance)) return message; // Prioritize fully replacing if that exists-- // ideally both aren't used at the same time (but we don't have a way to enforce that in serialization yet) if (prototype.FullReplacements != null) { - return prototype.FullReplacements.Length != 0 ? Loc.GetString(_random.Pick(prototype.FullReplacements)) : ""; + return prototype.FullReplacements.Length != 0 ? Loc.GetString(random.Pick(prototype.FullReplacements)) : ""; } // Prohibition of repeated word replacements. @@ -73,10 +88,10 @@ public sealed partial class ReplacementAccentSystem : RelayAccentSystem 0; i--) + for (var i = regex.Count(maskMessage); i > 0; i--) { // fetch the match again as the character indices may have changed - Match match = regex.Match(maskMessage); + var match = regex.Match(maskMessage); var replacement = replace; // Intelligently replace capitalization @@ -109,11 +124,11 @@ public sealed partial class ReplacementAccentSystem : RelayAccentSystem + return + [ + .. replacements.Select(kv => { var (first, replace) = kv; var firstLoc = Loc.GetString(first); @@ -132,8 +149,8 @@ public sealed partial class ReplacementAccentSystem : RelayAccentSystem { @@ -11,7 +9,7 @@ public sealed partial class RussianAccentSystem : RelayAccentSystem? ent = null) { - var accentedMessage = new StringBuilder(_replacement.ApplyReplacements(message, "russian")); + var accentedMessage = new StringBuilder(_replacement.ApplyReplacements(message, "russian", ent?.Owner)); for (var i = 0; i < accentedMessage.Length; i++) { diff --git a/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs b/Content.Shared/Speech/EntitySystems/ScrambledAccentSystem.cs similarity index 67% rename from Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/ScrambledAccentSystem.cs index 459f15bdbf..654024a29b 100644 --- a/Content.Server/Speech/EntitySystems/ScrambledAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/ScrambledAccentSystem.cs @@ -1,30 +1,36 @@ using System.Linq; using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; using Robust.Shared.Random; +using Robust.Shared.Timing; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class ScrambledAccentSystem : RelayAccentSystem { private static readonly Regex RegexLoneI = new(@"(?<=\ )i(?=[\ \.\?]|$)"); + [Dependency] private IGameTiming _timing = default!; [Dependency] private IRobustRandom _random = default!; public override string Accentuate(string message, Entity? ent = null) { + var random = ent.HasValue + ? SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)) + : _random; + var words = message.ToLower().Split(); if (words.Length < 2) { - var pick = _random.Next(1, 8); + var pick = random.Next(1, 8); // If they try to weasel out of it by saying one word at a time we give them this. return Loc.GetString($"accent-scrambled-words-{pick}"); } // Scramble the words - var scrambled = words.OrderBy(x => _random.Next()).ToArray(); + var scrambled = words.OrderBy(_ => random.Next()).ToArray(); var msg = string.Join(" ", scrambled); diff --git a/Content.Shared/Speech/EntitySystems/SharedDamagedSiliconAccentSystem.cs b/Content.Shared/Speech/EntitySystems/SharedDamagedSiliconAccentSystem.cs new file mode 100644 index 0000000000..8369ad1425 --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/SharedDamagedSiliconAccentSystem.cs @@ -0,0 +1,122 @@ +using System.Text; +using Content.Shared.Damage.Components; +using Content.Shared.Damage.Systems; +using Content.Shared.FixedPoint; +using Content.Shared.Power.EntitySystems; +using Content.Shared.PowerCell; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Shared.Speech.EntitySystems; + +public abstract partial class SharedDamagedSiliconAccentSystem : RelayAccentSystem +{ + [Dependency] private IGameTiming _timing = default!; + [Dependency] private SharedBatterySystem _battery = default!; + [Dependency] private PowerCellSystem _powerCell = default!; + [Dependency] private DamageableSystem _damageable = default!; + + protected override Type[] AccentAfter => [typeof(ReplacementAccentSystem)]; + protected override Type[] RelayAccentAfter => [typeof(ReplacementAccentSystem)]; + + public override string Accentuate(string message, Entity? ent = null) + { + if (ent == null) + return message; + + var uid = ent.Value.Owner; + if (ent.Value.Comp.EnableChargeCorruption) + { + var currentChargeLevel = 0.0f; + if (ent.Value.Comp.OverrideChargeLevel.HasValue) + { + currentChargeLevel = ent.Value.Comp.OverrideChargeLevel.Value; + } + else if (_powerCell.TryGetBatteryFromSlot(uid, out var battery)) + { + currentChargeLevel = _battery.GetChargeLevel(battery.Value.AsNullable()); + } + currentChargeLevel = Math.Clamp(currentChargeLevel, 0.0f, 1.0f); + // Corrupt due to low power (drops characters on longer messages) + message = CorruptPower(message, currentChargeLevel, ent.Value); + } + + if (ent.Value.Comp.EnableDamageCorruption) + { + var damage = FixedPoint2.Zero; + if (ent.Value.Comp.OverrideTotalDamage.HasValue) + { + damage = ent.Value.Comp.OverrideTotalDamage.Value; + } + else if (TryComp(uid, out var damageable)) + { + damage = _damageable.GetTotalDamage((uid, damageable)); + } + // Corrupt due to damage (drop, repeat, replace with symbols) + message = CorruptDamage(message, damage, ent.Value); + } + + return message; + } + + protected virtual string CorruptDamage(string message, FixedPoint2 totalDamage, Entity ent) + { + return message; + } + + /// + /// Corrupts a message based on the entity's charge level. + /// + public string CorruptPower(string message, float chargeLevel, Entity ent) + { + // The first idxMin characters are SAFE + var idxMin = ent.Comp.StartPowerCorruptionAtCharIdx; + // Probability will max at idxMax + var idxMax = ent.Comp.MaxPowerCorruptionAtCharIdx; + + // Fast bails, would not have an effect + if (chargeLevel > ent.Comp.ChargeThresholdForPowerCorruption || message.Length < idxMin) + { + return message; + } + + var outMsg = new StringBuilder(); + + var maxDropProb = ent.Comp.MaxDropProbFromPower * (1.0f - chargeLevel / ent.Comp.ChargeThresholdForPowerCorruption); + + var idx = -1; + foreach (var letter in message) + { + idx++; + if (idx < idxMin) // Fast character, no effect + { + outMsg.Append(letter); + continue; + } + + // use an x^2 interpolation to increase the drop probability until we hit idxMax + var probToDrop = idx >= idxMax + ? maxDropProb + : (float)Math.Pow(((double)idx - idxMin) / (idxMax - idxMin), 2.0) * maxDropProb; + // Ensure we're in the range for Prob() + probToDrop = Math.Clamp(probToDrop, 0.0f, 1.0f); + + var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent)); + if (random.Prob(probToDrop)) // Lose a character + { + // Additional chance to change to dot for flavor instead of full drop + if (random.Prob(ent.Comp.ProbToCorruptDotFromPower)) + { + outMsg.Append('.'); + } + } + else // Character is safe + { + outMsg.Append(letter); + } + } + return outMsg.ToString(); + } +} diff --git a/Content.Shared/Speech/EntitySystems/SharedMeleeSpeechSystem.cs b/Content.Shared/Speech/EntitySystems/SharedMeleeSpeechSystem.cs deleted file mode 100644 index 21841ef0ac..0000000000 --- a/Content.Shared/Speech/EntitySystems/SharedMeleeSpeechSystem.cs +++ /dev/null @@ -1,7 +0,0 @@ -using Robust.Shared.Serialization; - -namespace Content.Shared.Speech.EntitySystems; - -public abstract class SharedMeleeSpeechSystem : EntitySystem -{ -} diff --git a/Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs b/Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs deleted file mode 100644 index b53a7743ee..0000000000 --- a/Content.Shared/Speech/EntitySystems/SharedSlurredSystem.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Content.Shared.Speech.Components; -using Content.Shared.StatusEffect; -using Robust.Shared.Prototypes; - -namespace Content.Shared.Speech.EntitySystems; - -public abstract class SharedSlurredSystem : RelayAccentSystem -{ - public static readonly EntProtoId Stutter = "StatusEffectSlurred"; - - public virtual void DoSlur(EntityUid uid, TimeSpan time, StatusEffectsComponent? status = null) { } -} diff --git a/Content.Shared/Speech/EntitySystems/SharedSpeakOnActionSystem.cs b/Content.Shared/Speech/EntitySystems/SharedSpeakOnActionSystem.cs deleted file mode 100644 index 075d336cc4..0000000000 --- a/Content.Shared/Speech/EntitySystems/SharedSpeakOnActionSystem.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Content.Shared.Chasm; -using Content.Shared.Speech.Components; -using Content.Shared.Speech.Muting; -using System; - -namespace Content.Shared.Speech.EntitySystems; - -/// -/// Once the chat refactor has happened, move the code from -/// -/// to here and set this class to sealed. -/// -public abstract class SharedSpeakOnActionSystem : EntitySystem; diff --git a/Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs b/Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs deleted file mode 100644 index 06871aad09..0000000000 --- a/Content.Shared/Speech/EntitySystems/SharedStutteringSystem.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Content.Shared.Speech.Components; -using Content.Shared.StatusEffectNew; -using Robust.Shared.Prototypes; - -namespace Content.Shared.Speech.EntitySystems; - -public abstract partial class SharedStutteringSystem : RelayAccentSystem -{ - public static readonly EntProtoId Stuttering = "StatusEffectStutter"; - - [Dependency] protected StatusEffectsSystem Status = default!; - - // For code in shared... I imagine we ain't getting accent prediction anytime soon so let's not bother. - public virtual void DoStutter(EntityUid uid, TimeSpan time, bool refresh) - { - } - - public virtual void DoRemoveStutterTime(EntityUid uid, TimeSpan timeRemoved) - { - } - - public virtual void DoRemoveStutter(EntityUid uid) - { - } -} diff --git a/Content.Server/Speech/EntitySystems/SkeletonAccentSystem.cs b/Content.Shared/Speech/EntitySystems/SkeletonAccentSystem.cs similarity index 52% rename from Content.Server/Speech/EntitySystems/SkeletonAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/SkeletonAccentSystem.cs index 655ad4aec5..852f18ee79 100644 --- a/Content.Server/Speech/EntitySystems/SkeletonAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SkeletonAccentSystem.cs @@ -1,20 +1,25 @@ using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; using Robust.Shared.Random; +using Robust.Shared.Timing; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class SkeletonAccentSystem : RelayAccentSystem { + [Dependency] private IGameTiming _timing = default!; [Dependency] private IRobustRandom _random = default!; [Dependency] private ReplacementAccentSystem _replacement = default!; - [GeneratedRegex(@"(?? ent = null) { + var random = ent.HasValue + ? SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)) + : _random; + // Order: // Do character manipulations first // Then direct word/phrase replacements @@ -24,16 +29,15 @@ public sealed partial class SkeletonAccentSystem : RelayAccentSystem bone ; lonely -> bonely; clone -> clone (remains unchanged). - msg = BoneRegex().Replace(msg, "bone"); + msg = BoneRegex.Replace(msg, "bone"); // apply word replacements - msg = _replacement.ApplyReplacements(msg, "skeleton"); + msg = _replacement.ApplyReplacements(msg, "skeleton", ent?.Owner); // Suffix: - if (_random.Prob(ent.HasValue ? ent.Value.Comp.ackChance : 0.3f)) - { - msg += (" " + Loc.GetString("skeleton-suffix")); // e.g. "We only want to socialize. ACK ACK!" - } + if (random.Prob(ent.HasValue ? ent.Value.Comp.AckChance : 0.3f)) + msg += " " + Loc.GetString("skeleton-suffix"); // e.g. "We only want to socialize. ACK ACK!" + return msg; } } diff --git a/Content.Server/Speech/EntitySystems/SlowAccentSystem.cs b/Content.Shared/Speech/EntitySystems/SlowAccentSystem.cs similarity index 87% rename from Content.Server/Speech/EntitySystems/SlowAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/SlowAccentSystem.cs index a92839c213..7c8d86ba02 100644 --- a/Content.Server/Speech/EntitySystems/SlowAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SlowAccentSystem.cs @@ -1,8 +1,7 @@ using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class SlowAccentSystem : RelayAccentSystem { diff --git a/Content.Server/Speech/EntitySystems/SlurredSystem.cs b/Content.Shared/Speech/EntitySystems/SlurredSystem.cs similarity index 53% rename from Content.Server/Speech/EntitySystems/SlurredSystem.cs rename to Content.Shared/Speech/EntitySystems/SlurredSystem.cs index a15cc22c14..a3b7769d06 100644 --- a/Content.Server/Speech/EntitySystems/SlurredSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SlurredSystem.cs @@ -1,63 +1,34 @@ using System.Text; -using Content.Shared.Speech; +using Content.Shared.Random.Helpers; using Content.Shared.Speech.Components; -using Content.Shared.Speech.EntitySystems; using Content.Shared.StatusEffectNew; using Content.Shared.StatusEffectNew.Components; using Robust.Shared.Random; using Robust.Shared.Timing; +using Robust.Shared.Prototypes; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; -public sealed partial class SlurredSystem : SharedSlurredSystem +public sealed partial class SlurredSystem : RelayAccentSystem { + public static readonly EntProtoId Stutter = "StatusEffectSlurred"; + [Dependency] private StatusEffectsSystem _status = default!; - [Dependency] private IRobustRandom _random = default!; [Dependency] private IGameTiming _timing = default!; - /// - /// Divisor applied to total seconds used to get the odds of slurred speech occuring. - /// - private const float SlurredModifier = 1100f; - - /// - /// Minimum amount of time on the slurred accent for it to start taking effect. - /// - private const float SlurredThreshold = 80f; - - /// - /// Slur chance scales with the time remaining on any status effect with the SlurredAccentComponent. - /// Typically, this is equivalent to "drunkenness" on the DrunkStatusEffect - /// - private float GetProbabilityScale(EntityUid uid) + public override string Accentuate(string message, Entity? ent = null) { - if (!TryComp(uid, out var component) || component.AppliedTo == null) - return 0; + if (ent == null) + return message; - if (!_status.TryGetMaxTime(component.AppliedTo.Value, out var time)) - return 0; - - // This is a magic number. Why this value? No clue it was made 3 years before I refactored this. - var magic = time.Item2 == null ? SlurredModifier : (float) (time.Item2 - _timing.CurTime).Value.TotalSeconds - SlurredThreshold; - - return Math.Clamp(magic / SlurredModifier, 0f, 1f); - } - - // TODO: Make this accent possible to use without a status effect - protected override void OnAccent(Entity ent, ref AccentGetEvent args) - { - var scale = GetProbabilityScale(ent); - args.Message = Accentuate(args.Message, scale); - } - - private string Accentuate(string message, float scale) - { + var scale = GetProbabilityScale(ent.Value); + var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)); var sb = new StringBuilder(); // This is pretty much ported from TG. foreach (var character in message) { - if (_random.Prob(scale / 3f)) + if (random.Prob(scale / 3f)) { var lower = char.ToLowerInvariant(character); var newString = lower switch @@ -73,7 +44,7 @@ public sealed partial class SlurredSystem : SharedSlurredSystem sb.Append(newString); } - if (_random.Prob(scale / 20f)) + if (random.Prob(scale / 20f)) { if (character == ' ') { @@ -86,13 +57,13 @@ public sealed partial class SlurredSystem : SharedSlurredSystem } } - if (!_random.Prob(scale * 3/20)) + if (!random.Prob(scale * 3 / 20)) { sb.Append(character); continue; } - var next = _random.Next(1, 3) switch + var next = random.Next(1, 3) switch { 1 => "'", 2 => $"{character}{character}", @@ -104,4 +75,24 @@ public sealed partial class SlurredSystem : SharedSlurredSystem return sb.ToString(); } + + /// + /// Slur chance scales with the time remaining on any status effect with the SlurredAccentComponent. + /// Typically, this is equivalent to "drunkenness" on the DrunkStatusEffect + /// + private float GetProbabilityScale(Entity ent) + { + if (!TryComp(ent, out var component) || component.AppliedTo == null) + return 1f; + + if (!_status.TryGetMaxTime(component.AppliedTo.Value, out var time)) + return 1f; + + // This is a magic number. Why this value? No clue it was made 3 years before I refactored this. + var magic = time.Item2 == null + ? ent.Comp.SlurredModifier + : (float)(time.Item2 - _timing.CurTime).Value.TotalSeconds - ent.Comp.SlurredThreshold; + + return Math.Clamp(magic / ent.Comp.SlurredModifier, 0f, 1f); + } } diff --git a/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs b/Content.Shared/Speech/EntitySystems/SouthernAccentSystem.cs similarity index 89% rename from Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/SouthernAccentSystem.cs index ef56a0264a..b77e465628 100644 --- a/Content.Server/Speech/EntitySystems/SouthernAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SouthernAccentSystem.cs @@ -1,8 +1,7 @@ using System.Text.RegularExpressions; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed partial class SouthernAccentSystem : RelayAccentSystem { @@ -17,7 +16,7 @@ public sealed partial class SouthernAccentSystem : RelayAccentSystem? ent = null) { - message = _replacement.ApplyReplacements(message, "southern"); + message = _replacement.ApplyReplacements(message, "southern", ent?.Owner); //They shoulda started runnin' an' hidin' from me! message = RegexLowerIng.Replace(message, "in'"); diff --git a/Content.Server/Speech/EntitySystems/SpanishAccentSystem.cs b/Content.Shared/Speech/EntitySystems/SpanishAccentSystem.cs similarity index 94% rename from Content.Server/Speech/EntitySystems/SpanishAccentSystem.cs rename to Content.Shared/Speech/EntitySystems/SpanishAccentSystem.cs index e68d23a190..3d77840656 100644 --- a/Content.Server/Speech/EntitySystems/SpanishAccentSystem.cs +++ b/Content.Shared/Speech/EntitySystems/SpanishAccentSystem.cs @@ -1,9 +1,8 @@ using System.Text.RegularExpressions; using System.Text; -using Content.Server.Speech.Components; -using Content.Shared.Speech.EntitySystems; +using Content.Shared.Speech.Components; -namespace Content.Server.Speech.EntitySystems; +namespace Content.Shared.Speech.EntitySystems; public sealed class SpanishAccentSystem : RelayAccentSystem { @@ -50,6 +49,7 @@ public sealed class SpanishAccentSystem : RelayAccentSystem ' ' }); } + if (toInsert.Length == 0) msg.Append(s); else diff --git a/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs b/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs new file mode 100644 index 0000000000..6880ef9edf --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/SpeakOnActionSystem.cs @@ -0,0 +1,26 @@ +using Content.Shared.Speech.Components; +using Content.Shared.Actions.Events; +using Content.Shared.Chat; +using Content.Shared.Speech.Muting; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class SpeakOnActionSystem : EntitySystem +{ + [Dependency] private SharedChatSystem _chat = default!; + + [SubscribeLocalEvent] + private void OnActionPerformed(Entity ent, ref ActionPerformedEvent args) + { + var user = args.Performer; + + // If we can't speak, we can't speak. + if (!HasComp(user) || HasComp(user)) + return; + + if (string.IsNullOrWhiteSpace(ent.Comp.Sentence)) + return; + + _chat.TrySendInGameICMessage(user, Loc.GetString(ent.Comp.Sentence), InGameICChatType.Speak, false); + } +} diff --git a/Content.Shared/Speech/EntitySystems/SpeechNoiseSystem.cs b/Content.Shared/Speech/EntitySystems/SpeechNoiseSystem.cs new file mode 100644 index 0000000000..ea5f99e66f --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/SpeechNoiseSystem.cs @@ -0,0 +1,70 @@ +using Content.Shared.Chat; +using Content.Shared.Random.Helpers; +using Robust.Shared.Audio; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class SpeechSoundSystem : EntitySystem +{ + [Dependency] private IGameTiming _gameTiming = default!; + [Dependency] private SharedAudioSystem _audio = default!; + + [SubscribeLocalEvent] + private void OnEntitySpoke(Entity ent, ref EntitySpokeEvent args) + { + if (ent.Comp.SpeechSounds == null) + return; + + var currentTime = _gameTiming.CurTime; + var cooldown = TimeSpan.FromSeconds(ent.Comp.SoundCooldownTime); + + // Ensure more than the cooldown time has passed since last speaking + if (currentTime - ent.Comp.LastTimeSoundPlayed < cooldown) + return; + + var sound = GetSpeechSound(ent, args.Message); + ent.Comp.LastTimeSoundPlayed = currentTime; + _audio.PlayPredicted(sound, ent, ent); + } + + /// + /// Gets the speech sound for a message. + /// + public SoundSpecifier? GetSpeechSound(Entity ent, string message) + { + if (ent.Comp.SpeechSounds == null) + return null; + + // Play speech sound + var prototype = ProtoMan.Index(ent.Comp.SpeechSounds); + + // Different sounds for ask/exclaim based on last character + var contextSound = message[^1] switch + { + '?' => prototype.AskSound, + '!' => prototype.ExclaimSound, + _ => prototype.SaySound + }; + + // Use exclaim sound if most characters are uppercase. + var uppercaseCount = 0; + foreach (var t in message) + { + if (char.IsUpper(t)) + uppercaseCount++; + } + + if (uppercaseCount > message.Length / 2) + { + contextSound = prototype.ExclaimSound; + } + + var random = SharedRandomExtensions.PredictedRandom(_gameTiming, GetNetEntity(ent)); + var scale = (float)random.NextGaussian(1, prototype.Variation); + contextSound.Params = ent.Comp.AudioParams.WithPitchScale(scale); + return contextSound; + } +} diff --git a/Content.Shared/Speech/EntitySystems/StutteringSystem.cs b/Content.Shared/Speech/EntitySystems/StutteringSystem.cs new file mode 100644 index 0000000000..1a0624372b --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/StutteringSystem.cs @@ -0,0 +1,73 @@ +using System.Text; +using System.Text.RegularExpressions; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; +using Content.Shared.StatusEffectNew; +using JetBrains.Annotations; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class StutteringSystem : RelayAccentSystem +{ + public static readonly EntProtoId StutterEffect = "StatusEffectSlurred"; + + [Dependency] private IGameTiming _timing = default!; + [Dependency] private StatusEffectsSystem _statusEffects = default!; + + // Regex of characters to stutter. + private static readonly Regex Stutter = new("[b-df-hj-np-tv-wxyz]", + RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public override string Accentuate(string message, Entity? ent = null) + { + if (ent == null) + return message; + + var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Value)); + var length = message.Length; + var finalMessage = new StringBuilder(); + + for (var i = 0; i < length; i++) + { + var newLetter = message[i].ToString(); + if (Stutter.IsMatch(newLetter) && random.Prob(ent.Value.Comp.MatchRandomProb)) + { + if (random.Prob(ent.Value.Comp.FourRandomProb)) + { + newLetter = $"{newLetter}-{newLetter}-{newLetter}-{newLetter}"; + } + else if (random.Prob(ent.Value.Comp.ThreeRandomProb)) + { + newLetter = $"{newLetter}-{newLetter}-{newLetter}"; + } + else if (random.Prob(ent.Value.Comp.CutRandomProb)) + { + newLetter = ""; + } + else + { + newLetter = $"{newLetter}-{newLetter}"; + } + } + + finalMessage.Append(newLetter); + } + + return finalMessage.ToString(); + } + + /// + /// Applies or refreshes the stuttering speech status effect on an entity. + /// + [PublicAPI] + public void DoStutter(EntityUid uid, TimeSpan time, bool refresh) + { + if (refresh) + _statusEffects.TryUpdateStatusEffectDuration(uid, StutterEffect, time); + else + _statusEffects.TryAddStatusEffectDuration(uid, StutterEffect, time); + } +} diff --git a/Content.Shared/Speech/EntitySystems/UnblockableSpeechSystem.cs b/Content.Shared/Speech/EntitySystems/UnblockableSpeechSystem.cs new file mode 100644 index 0000000000..90580e593a --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/UnblockableSpeechSystem.cs @@ -0,0 +1,13 @@ +using Content.Shared.Speech.Components; +using Content.Shared.Chat; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class UnblockableSpeechSystem : EntitySystem +{ + [SubscribeLocalEvent] + private void OnCheck(Entity ent, ref CheckIgnoreSpeechBlockerEvent args) + { + args.IgnoreBlocker = true; + } +} diff --git a/Content.Shared/Speech/EntitySystems/VocalSystem.cs b/Content.Shared/Speech/EntitySystems/VocalSystem.cs new file mode 100644 index 0000000000..f241debe1e --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/VocalSystem.cs @@ -0,0 +1,124 @@ +using Content.Shared.Actions; +using Content.Shared.Chat; +using Content.Shared.Chat.Prototypes; +using Content.Shared.Humanoid; +using Content.Shared.Random.Helpers; +using Content.Shared.Speech.Components; +using JetBrains.Annotations; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Robust.Shared.Timing; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class VocalSystem : EntitySystem +{ + [Dependency] private IGameTiming _timing = default!; + [Dependency] private SharedAudioSystem _audio = default!; + [Dependency] private SharedChatSystem _chat = default!; + [Dependency] private SharedActionsSystem _actions = default!; + + [SubscribeLocalEvent] + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + // try to add scream action when vocal comp added + _actions.AddAction(ent.Owner, ref ent.Comp.EmoteActionEntity, ent.Comp.EmoteAction); + Dirty(ent); + } + + [SubscribeLocalEvent] + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + // remove scream action when component removed + _actions.RemoveAction(ent.Owner, ent.Comp.EmoteActionEntity); + Dirty(ent); + } + + [SubscribeLocalEvent] + private void OnVoiceChanged(Entity ent, ref VoiceChangedEvent args) + { + LoadSounds(ent, args.NewVoice); + } + + [SubscribeLocalEvent] + private void OnEmote(Entity ent, ref EmoteEvent args) + { + if (args.Handled || !args.Emote.Category.HasFlag(EmoteCategory.Vocal)) + return; + + // snowflake case for wilhelm scream easter egg + if (args.Emote == ent.Comp.ScreamId) + { + args.Handled = TryPlayScreamSound(ent, GetEntity(args.Source)); + return; + } + + if (ent.Comp.EmoteSounds is not { } sounds) + return; + + // just play regular sound based on emote proto + args.Handled = _chat.TryPlayEmoteSound(ent.Owner, ProtoMan.Index(sounds), args.Emote); + } + + [SubscribeLocalEvent] + private void OnEmoteAction(Entity ent, ref EmoteActionEvent args) + { + if (args.Handled) + return; + + _chat.TryEmoteWithChat(ent.Owner, args.Emote); + args.Handled = true; + } + + /// + /// Copy this component's datafields from one entity to another. + /// This can't use CopyComp because of the ScreamActionEntity DataField, which should not be copied. + /// + [PublicAPI] + public void CopyComponent(Entity source, EntityUid target) + { + if (!Resolve(source, ref source.Comp)) + return; + + var targetComp = EnsureComp(target); + targetComp.ScreamId = source.Comp.ScreamId; + targetComp.Wilhelm = source.Comp.Wilhelm; + targetComp.WilhelmProbability = source.Comp.WilhelmProbability; + LoadSounds((target, targetComp)); + + Dirty(target, targetComp); + } + + private bool TryPlayScreamSound(Entity ent, EntityUid user) + { + var random = SharedRandomExtensions.PredictedRandom(_timing, GetNetEntity(ent.Owner), GetNetEntity(user)); + if (random.Prob(ent.Comp.WilhelmProbability)) + { + _audio.PlayPredicted(ent.Comp.Wilhelm, ent.Owner, user, ent.Comp.Wilhelm.Params); + return true; + } + + if (ent.Comp.EmoteSounds is not { } sounds) + return false; + + return _chat.TryPlayEmoteSound(ent.Owner, ProtoMan.Index(sounds), ent.Comp.ScreamId); + } + + /// + /// This only works on Humanoids. Mobs should have emoteSounds on set directly instead. + /// + private void LoadSounds(Entity ent, ProtoId? protoId = null) + { + if (!TryComp(ent.Owner, out var humanoid)) + return; + + protoId ??= humanoid.Voice; + + if (!ProtoMan.HasIndex(protoId)) + return; + + ent.Comp.EmoteSounds = protoId; + Dirty(ent); + } +} diff --git a/Content.Shared/Speech/EntitySystems/VoiceOverrideSystem.cs b/Content.Shared/Speech/EntitySystems/VoiceOverrideSystem.cs new file mode 100644 index 0000000000..a1d6f291cf --- /dev/null +++ b/Content.Shared/Speech/EntitySystems/VoiceOverrideSystem.cs @@ -0,0 +1,17 @@ +using Content.Shared.Chat; +using Content.Shared.Speech.Components; + +namespace Content.Shared.Speech.EntitySystems; + +public sealed partial class VoiceOverrideSystem : EntitySystem +{ + [SubscribeLocalEvent] + private void OnTransformSpeakerName(Entity ent, ref TransformSpeakerNameEvent args) + { + if (!ent.Comp.Enabled) + return; + + args.VoiceName = ent.Comp.NameOverride ?? args.VoiceName; + args.SpeechVerb = ent.Comp.SpeechVerbOverride ?? args.SpeechVerb; + } +} diff --git a/Content.Shared/Speech/EntitySystems/SharedListenWireAction.cs b/Content.Shared/Speech/ListenWireAction.cs similarity index 100% rename from Content.Shared/Speech/EntitySystems/SharedListenWireAction.cs rename to Content.Shared/Speech/ListenWireAction.cs diff --git a/Content.Server/Speech/Prototypes/ReplacementAccentPrototype.cs b/Content.Shared/Speech/Prototypes/ReplacementAccentPrototype.cs similarity index 61% rename from Content.Server/Speech/Prototypes/ReplacementAccentPrototype.cs rename to Content.Shared/Speech/Prototypes/ReplacementAccentPrototype.cs index cde4baeb2f..dc541e0a1b 100644 --- a/Content.Server/Speech/Prototypes/ReplacementAccentPrototype.cs +++ b/Content.Shared/Speech/Prototypes/ReplacementAccentPrototype.cs @@ -1,6 +1,6 @@ using Robust.Shared.Prototypes; -namespace Content.Server.Speech.Prototypes; +namespace Content.Shared.Speech.Prototypes; [Prototype("accent")] public sealed partial class ReplacementAccentPrototype : IPrototype @@ -11,14 +11,14 @@ public sealed partial class ReplacementAccentPrototype : IPrototype public string ID { get; private set; } = default!; /// - /// If this array is non-null, the full text of anything said will be randomly replaced with one of these words. + /// If this array is non-null, the full text of anything said will be randomly replaced with one of these words. /// [DataField] public string[]? FullReplacements; /// - /// If this dictionary is non-null and is null, any keys surrounded by spaces - /// (words) will be replaced by the value, attempting to intelligently keep capitalization. + /// If this dictionary is non-null and is null, any keys surrounded by spaces + /// (words) will be replaced by the value, attempting to intelligently keep capitalization. /// [DataField] public Dictionary? WordReplacements; diff --git a/Content.Shared/Speech/EntitySystems/SharedSpeechWireAction.cs b/Content.Shared/Speech/SpeechWireAction.cs similarity index 100% rename from Content.Shared/Speech/EntitySystems/SharedSpeechWireAction.cs rename to Content.Shared/Speech/SpeechWireAction.cs From b92ce0002643095d940385ef5d95c87fc1aff960 Mon Sep 17 00:00:00 2001 From: Whatstone <166147148+whatston3@users.noreply.github.com> Date: Sat, 25 Jul 2026 18:45:49 -0400 Subject: [PATCH 05/35] Bugfix: Check UIDs in TryMergeStacks (#44914) Check entity UIDs in TryMergeStacks --- Content.Shared/Stacks/SharedStackSystem.API.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/Stacks/SharedStackSystem.API.cs b/Content.Shared/Stacks/SharedStackSystem.API.cs index 3459f4f0dc..96a13e3ac2 100644 --- a/Content.Shared/Stacks/SharedStackSystem.API.cs +++ b/Content.Shared/Stacks/SharedStackSystem.API.cs @@ -120,7 +120,7 @@ public abstract partial class SharedStackSystem { transferred = 0; - if (donor == recipient) + if (donor.Owner == recipient.Owner) return false; // Recipient is being torn down, don't give it anything. From 19dbe485f1cd112b49ee93528071ca1419f5f08c Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Sun, 26 Jul 2026 00:34:06 -0700 Subject: [PATCH 06/35] Disposals dynamic power consumption (#44113) * init * trolled by my own test --- .../Disposal/Unit/SharedDisposalUnitSystem.cs | 11 +++++++++-- .../Entities/Structures/Piping/Disposal/units.yml | 5 +++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Content.Shared/Disposal/Unit/SharedDisposalUnitSystem.cs b/Content.Shared/Disposal/Unit/SharedDisposalUnitSystem.cs index 1e8fe47fe3..cc43ea889e 100644 --- a/Content.Shared/Disposal/Unit/SharedDisposalUnitSystem.cs +++ b/Content.Shared/Disposal/Unit/SharedDisposalUnitSystem.cs @@ -55,6 +55,7 @@ public abstract partial class SharedDisposalUnitSystem : EntitySystem [Dependency] private SharedMapSystem _map = default!; [Dependency] private SharedTransformSystem _xform = default!; [Dependency] private INetManager _net = default!; + [Dependency] private SharedPowerStateSystem _powerState = default!; public override void Initialize() { @@ -259,9 +260,15 @@ public abstract partial class SharedDisposalUnitSystem : EntitySystem ent.Comp.State = state; - if (state == DisposalsPressureState.Ready) + switch (state) { - ent.Comp.NextPressurized = TimeSpan.Zero; + case DisposalsPressureState.Ready: + ent.Comp.NextPressurized = TimeSpan.Zero; + _powerState.SetWorkingState(ent.Owner, false); + break; + case DisposalsPressureState.Pressurizing: + _powerState.SetWorkingState(ent.Owner, true); + break; } RecalculateFlushTime(ent, true); diff --git a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml index f9525d9989..02fd03d95e 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Disposal/units.yml @@ -114,6 +114,11 @@ - type: StaticPrice price: 70 - type: PowerSwitch + - type: ApcPowerReceiver + powerLoad: 5 + - type: PowerState + idlePowerDraw: 5 + workingPowerDraw: 1000 - type: entity id: DisposalUnit From 2e9c4c01032d9341383458d30bbe13426f322cba Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Sun, 26 Jul 2026 00:56:44 -0700 Subject: [PATCH 07/35] IHeatContainers for TemperatureComponent (#42785) * Hope I'm not forgetting anything... * They call me the sender the way I'm sending it. * remove commented out YAML * last of the slop * fix test fails * first batch of test fails * no more test fails * make cryo pods work again. * Make cryo work better-er * I didn't like that a firesuit helmet was so effective on its own so I decided to be a dick about it. * review.com * oop * actually real quick do this * fix YAML issues * IHeatContainer my beloved <3 * borger * not networked :( * jackets * burgeewqjfrwjkhaskfjfsahjkfsahjkfsahjkfsajhkfsa * utter yaml nonsense * phishing --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> --- .../Medical/Cryogenics/CryoPodWindow.xaml.cs | 2 +- .../Interaction/EdgeClobbering.cs | 3 +- .../Atmos/Components/AtmosExposedComponent.cs | 29 +++- .../Atmos/EntitySystems/AtmosphereSystem.cs | 16 +-- .../Atmos/EntitySystems/FlammableSystem.cs | 3 +- Content.Server/Atmos/Rotting/RottingSystem.cs | 2 +- .../Body/Systems/ThermalRegulatorSystem.cs | 16 +-- .../ConstructionSystem.Interactions.cs | 13 +- .../Kitchen/EntitySystems/MicrowaveSystem.cs | 3 +- .../Medical/HealthAnalyzerSystem.cs | 2 +- .../NPC/Systems/NPCUtilitySystem.cs | 2 +- .../ContainerTemperatureComponent.cs | 14 +- .../InternalTemperatureComponent.cs | 43 +++--- .../TemperatureProtectionComponent.cs | 10 +- .../Temperature/Systems/EntityHeaterSystem.cs | 4 +- .../Systems/TemperatureSystem.Damage.cs | 16 +-- .../Temperature/Systems/TemperatureSystem.cs | 92 ++++-------- Content.Shared/Atmos/AtmosExposedEvents.cs | 9 +- .../TemperatureEntityConditionSystem.cs | 2 +- .../AdjustTemperatureEntityEffectsSystem.cs | 2 +- .../Inventory/InventorySystem.Relay.cs | 2 +- .../Cryogenics/InsideCryoPodComponent.cs | 6 + .../Cryogenics/SharedInsideCryoPodSystem.cs | 20 +-- .../Components/EntityHeaterComponent.cs | 2 +- .../Components/TemperatureComponent.cs | 36 +++-- .../Systems/SharedEntityHeaterSystem.cs | 4 +- .../Systems/SharedTemperatureSystem.cs | 134 ++++++++++++++++-- .../Temperature/TemperatureEvents.cs | 38 ++--- Resources/Prototypes/Atmospherics/gases.yml | 6 +- Resources/Prototypes/Body/Species/moth.yml | 3 - .../Prototypes/Body/Species/reptilian.yml | 3 - .../Prototypes/Body/Species/vulpkanin.yml | 5 - Resources/Prototypes/Body/species_base.yml | 4 +- .../Clothing/Head/base_clothinghead.yml | 19 ++- .../Entities/Clothing/Head/eva-helmets.yml | 3 - .../Clothing/Head/hardsuit-helmets.yml | 13 +- .../Entities/Clothing/Head/helmets.yml | 10 +- .../Entities/Clothing/Head/hoods.yml | 5 +- .../Clothing/Neck/base_clothingneck.yml | 5 +- .../Entities/Clothing/OuterClothing/armor.yml | 5 +- .../OuterClothing/base_clothingouter.yml | 100 ++++++------- .../Entities/Clothing/OuterClothing/coats.yml | 7 +- .../Clothing/OuterClothing/hardsuits.yml | 19 +-- .../Entities/Clothing/OuterClothing/misc.yml | 12 +- .../Clothing/OuterClothing/softsuits.yml | 19 +-- .../Clothing/OuterClothing/specific.yml | 5 +- .../Entities/Clothing/OuterClothing/suits.yml | 39 +---- .../Clothing/OuterClothing/wintercoats.yml | 7 +- .../Clothing/Shoes/base_clothingshoes.yml | 6 +- .../Entities/Clothing/base_clothing.yml | 28 ++++ .../Prototypes/Entities/Mobs/NPCs/animals.yml | 9 -- .../Prototypes/Entities/Mobs/NPCs/scurret.yml | 3 - .../Prototypes/Entities/Mobs/NPCs/xeno.yml | 4 - Resources/Prototypes/Entities/Mobs/base.yml | 5 - .../Entities/Objects/Consumable/Food/egg.yml | 12 +- .../Entities/Objects/Consumable/Food/meat.yml | 19 +-- .../Entities/Objects/Misc/ice_crust.yml | 3 + .../Entities/Objects/Misc/kudzu.yml | 45 +++--- .../Entities/Objects/Misc/spaceshroom.yml | 7 +- .../Structures/Machines/Medical/cryo_pod.yml | 2 +- .../Entities/Structures/spider_web.yml | 7 - Resources/Prototypes/Reagents/medicine.yml | 34 +++-- 62 files changed, 493 insertions(+), 505 deletions(-) diff --git a/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs b/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs index 76b1c876d3..3faa03512d 100644 --- a/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs +++ b/Content.Client/Medical/Cryogenics/CryoPodWindow.xaml.cs @@ -181,7 +181,7 @@ public sealed partial class CryoPodWindow : FancyWindow } // Status checklist - const float fallbackTemperatureRequirement = 213; + const float fallbackTemperatureRequirement = Atmospherics.T0C; var hasTemperatureCheck = (hasGas && hasCorrectTemperature && (lowestTempRequirement != null || msg.GasMix.Temperature < fallbackTemperatureRequirement)); var hasChemicals = (hasBeaker && !isBeakerEmpty); diff --git a/Content.IntegrationTests/Tests/Construction/Interaction/EdgeClobbering.cs b/Content.IntegrationTests/Tests/Construction/Interaction/EdgeClobbering.cs index 9f578148cf..0f8f48663c 100644 --- a/Content.IntegrationTests/Tests/Construction/Interaction/EdgeClobbering.cs +++ b/Content.IntegrationTests/Tests/Construction/Interaction/EdgeClobbering.cs @@ -41,7 +41,8 @@ public sealed class EdgeClobbering : InteractionTest var sTarget = SEntMan.GetEntity(Target!.Value); await InteractUsing(Screw, false); - SEntMan.EventBus.RaiseLocalEvent(sTarget, new OnTemperatureChangeEvent(0f, 0f, 0f)); + var ev = new TemperatureChangedEvent(0f, 0f); + SEntMan.EventBus.RaiseLocalEvent(sTarget, ref ev); await AwaitDoAfters(); Assert.That(SEntMan.GetComponent(sTarget).Node, Is.EqualTo("C")); diff --git a/Content.Server/Atmos/Components/AtmosExposedComponent.cs b/Content.Server/Atmos/Components/AtmosExposedComponent.cs index 721aae8f4f..0f40e998ea 100644 --- a/Content.Server/Atmos/Components/AtmosExposedComponent.cs +++ b/Content.Server/Atmos/Components/AtmosExposedComponent.cs @@ -1,11 +1,26 @@ -namespace Content.Server.Atmos.Components +using Content.Shared.Temperature.Components; + +namespace Content.Server.Atmos.Components; + +// not if i get there first - Flipp +/// +/// Represents that entity can be exposed to Atmos +/// +[RegisterComponent, AutoGenerateComponentPause] +public sealed partial class AtmosExposedComponent : Component { - // not if i get there first - Flipp /// - /// Represents that entity can be exposed to Atmos + /// Last real time we were exposed to the atmosphere! /// - [RegisterComponent] - public sealed partial class AtmosExposedComponent : Component - { - } + [DataField, AutoPausedField] + public TimeSpan LastExposure = TimeSpan.Zero; + + /// + /// The amount of surface area this entity has exposed to the atmosphere in m^2. + /// The human body has about 2m^2 of surface area so we use that as a default. + /// This is multiplied by the + /// Source: https://pmc.ncbi.nlm.nih.gov/articles/PMC8953946/ + /// + [DataField] + public float ExposedArea = 2f; } diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs index 400b778cac..dd09d95ed2 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs @@ -48,7 +48,6 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem [Dependency] private EntityQuery _firelockQuery = default!; private const float ExposedUpdateDelay = 1f; - private float _exposedTimer = 0f; private HashSet _entSet = new(); @@ -103,24 +102,23 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem UpdateProcessing(frameTime); UpdateHighPressure(frameTime); - _exposedTimer += frameTime; - - if (_exposedTimer < ExposedUpdateDelay) - return; + var delay = TimeSpan.FromSeconds(ExposedUpdateDelay); var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out _, out var transform)) + while (query.MoveNext(out var uid, out var exposed, out var transform)) { + if (exposed.LastExposure + delay > _gameTiming.CurTime) + continue; + var air = GetContainingMixture((uid, transform)); if (air == null) continue; - var updateEvent = new AtmosExposedUpdateEvent(transform.Coordinates, air, transform); + var updateEvent = new AtmosExposedUpdateEvent(transform.Coordinates, air, transform, ExposedUpdateDelay, exposed.ExposedArea); RaiseLocalEvent(uid, ref updateEvent); + exposed.LastExposure = _gameTiming.CurTime; } - - _exposedTimer -= ExposedUpdateDelay; } private void CacheDecals() diff --git a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs index 137da5f10d..490e7ae845 100644 --- a/Content.Server/Atmos/EntitySystems/FlammableSystem.cs +++ b/Content.Server/Atmos/EntitySystems/FlammableSystem.cs @@ -453,8 +453,7 @@ namespace Content.Server.Atmos.EntitySystems var source = EnsureComp(uid); _ignitionSourceSystem.SetIgnited((uid, source)); - if (TryComp(uid, out TemperatureComponent? temp)) - _temperatureSystem.ChangeHeat(uid, 12500 * flammable.FireStacks, false, temp); + _temperatureSystem.ChangeHeat(uid, 12500 * flammable.FireStacks, false); var ev = new GetFireProtectionEvent(); // let the thing on fire handle it diff --git a/Content.Server/Atmos/Rotting/RottingSystem.cs b/Content.Server/Atmos/Rotting/RottingSystem.cs index 46dd913bcf..cbad6f9a84 100644 --- a/Content.Server/Atmos/Rotting/RottingSystem.cs +++ b/Content.Server/Atmos/Rotting/RottingSystem.cs @@ -44,7 +44,7 @@ public sealed partial class RottingSystem : SharedRottingSystem { if (args.Handled) return; - args.Handled = component.CurrentTemperature < Atmospherics.T0C + 0.85f; + args.Handled = component.Temperature < Atmospherics.T0C + 0.85f; } /// diff --git a/Content.Server/Body/Systems/ThermalRegulatorSystem.cs b/Content.Server/Body/Systems/ThermalRegulatorSystem.cs index 581c308f56..e0b8899a17 100644 --- a/Content.Server/Body/Systems/ThermalRegulatorSystem.cs +++ b/Content.Server/Body/Systems/ThermalRegulatorSystem.cs @@ -55,10 +55,10 @@ public sealed partial class ThermalRegulatorSystem : EntitySystem var totalMetabolismTempChange = ent.Comp1.MetabolismHeat - ent.Comp1.RadiatedHeat; // implicit heat regulation - var tempDiff = Math.Abs(ent.Comp2.CurrentTemperature - ent.Comp1.NormalBodyTemperature); - var heatCapacity = _tempSys.GetHeatCapacity(ent, ent); + var tempDiff = Math.Abs(ent.Comp2.Temperature - ent.Comp1.NormalBodyTemperature); + var heatCapacity = ent.Comp2.HeatCapacity; var targetHeat = tempDiff * heatCapacity; - if (ent.Comp2.CurrentTemperature > ent.Comp1.NormalBodyTemperature) + if (ent.Comp2.Temperature > ent.Comp1.NormalBodyTemperature) { totalMetabolismTempChange -= Math.Min(targetHeat, ent.Comp1.ImplicitHeatRegulation); } @@ -67,10 +67,10 @@ public sealed partial class ThermalRegulatorSystem : EntitySystem totalMetabolismTempChange += Math.Min(targetHeat, ent.Comp1.ImplicitHeatRegulation); } - _tempSys.ChangeHeat(ent, totalMetabolismTempChange, ignoreHeatResistance: true, ent); + _tempSys.ChangeHeat((ent, ent.Comp2), totalMetabolismTempChange, ignoreHeatResistance: true); // recalc difference and target heat - tempDiff = Math.Abs(ent.Comp2.CurrentTemperature - ent.Comp1.NormalBodyTemperature); + tempDiff = Math.Abs(ent.Comp2.Temperature - ent.Comp1.NormalBodyTemperature); targetHeat = tempDiff * heatCapacity; // if body temperature is not within comfortable, thermal regulation @@ -78,19 +78,19 @@ public sealed partial class ThermalRegulatorSystem : EntitySystem if (tempDiff < ent.Comp1.ThermalRegulationTemperatureThreshold) return; - if (ent.Comp2.CurrentTemperature > ent.Comp1.NormalBodyTemperature) + if (ent.Comp2.Temperature > ent.Comp1.NormalBodyTemperature) { if (!_actionBlockerSys.CanSweat(ent)) return; - _tempSys.ChangeHeat(ent, -Math.Min(targetHeat, ent.Comp1.SweatHeatRegulation), ignoreHeatResistance: true, ent); + _tempSys.ChangeHeat((ent, ent.Comp2), -Math.Min(targetHeat, ent.Comp1.SweatHeatRegulation), ignoreHeatResistance: true); } else { if (!_actionBlockerSys.CanShiver(ent)) return; - _tempSys.ChangeHeat(ent, Math.Min(targetHeat, ent.Comp1.ShiveringHeatRegulation), ignoreHeatResistance: true, ent); + _tempSys.ChangeHeat((ent, ent.Comp2), Math.Min(targetHeat, ent.Comp1.ShiveringHeatRegulation), ignoreHeatResistance: true); } } } diff --git a/Content.Server/Construction/ConstructionSystem.Interactions.cs b/Content.Server/Construction/ConstructionSystem.Interactions.cs index ca4865639c..f467e2c220 100644 --- a/Content.Server/Construction/ConstructionSystem.Interactions.cs +++ b/Content.Server/Construction/ConstructionSystem.Interactions.cs @@ -42,7 +42,7 @@ namespace Content.Server.Construction SubscribeLocalEvent(EnqueueEvent, new []{typeof(AnchorableSystem), typeof(PryingSystem), typeof(WeldableSystem)}, new []{typeof(EncryptionKeySystem)}); - SubscribeLocalEvent(EnqueueEvent); + SubscribeLocalEvent(EnqueueRefEvent); SubscribeLocalEvent(EnqueueEvent); } @@ -382,7 +382,7 @@ namespace Content.Server.Construction case TemperatureConstructionGraphStep temperatureChangeStep: { - if (ev is not OnTemperatureChangeEvent) + if (ev is not TemperatureChangedEvent) break; // Some things, like microwaves, might need to block the temperature construction step from kicking in, or override it entirely. @@ -400,7 +400,7 @@ namespace Content.Server.Construction } else if (TryComp(uid, out var tempComp)) { - temp = tempComp.CurrentTemperature; + temp = tempComp.Temperature; } else { @@ -544,6 +544,13 @@ namespace Content.Server.Construction #region Event Handlers + // Why does this system have you subscribe to an event, + // and then pass it through 5 layers of bullshit into a switch statement which tries to guess what event got passed? + private void EnqueueRefEvent(Entity entity, ref T args) where T : struct + { + EnqueueEvent(entity, entity.Comp, args); + } + /// /// Queues a directed event to be handled by construction on the next update tick. /// Used as a handler for any events that construction can listen to. diff --git a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs index 774331080f..e2a16b2ebf 100644 --- a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs @@ -179,8 +179,7 @@ namespace Content.Server.Kitchen.EntitySystems var heatToAdd = time * component.BaseHeatMultiplier; foreach (var entity in component.Storage.ContainedEntities) { - if (TryComp(entity, out var tempComp)) - _temperature.ChangeHeat(entity, heatToAdd * component.ObjectHeatMultiplier, false, tempComp); + _temperature.ChangeHeat(entity, heatToAdd * component.ObjectHeatMultiplier, false); foreach (var (_, soln) in _solutionContainer.EnumerateSolutions(entity)) { diff --git a/Content.Server/Medical/HealthAnalyzerSystem.cs b/Content.Server/Medical/HealthAnalyzerSystem.cs index cce1d4ad13..869cfc69d5 100644 --- a/Content.Server/Medical/HealthAnalyzerSystem.cs +++ b/Content.Server/Medical/HealthAnalyzerSystem.cs @@ -231,7 +231,7 @@ public sealed partial class HealthAnalyzerSystem : EntitySystem var bodyTemperature = float.NaN; if (TryComp(entity, out var temp)) - bodyTemperature = temp.CurrentTemperature; + bodyTemperature = temp.Temperature; var bloodAmount = float.NaN; var bleeding = false; diff --git a/Content.Server/NPC/Systems/NPCUtilitySystem.cs b/Content.Server/NPC/Systems/NPCUtilitySystem.cs index c0e7db0120..859aac60a0 100644 --- a/Content.Server/NPC/Systems/NPCUtilitySystem.cs +++ b/Content.Server/NPC/Systems/NPCUtilitySystem.cs @@ -384,7 +384,7 @@ public sealed partial class NPCUtilitySystem : EntitySystem if (!TryComp(targetUid, out var temperature)) return 0f; - return temperature.CurrentTemperature <= con.MinTemp ? 1f : 0f; + return temperature.Temperature <= con.MinTemp ? 1f : 0f; } default: throw new NotImplementedException(); diff --git a/Content.Server/Temperature/Components/ContainerTemperatureComponent.cs b/Content.Server/Temperature/Components/ContainerTemperatureComponent.cs index 7c7b1e81e8..7cbd398b79 100644 --- a/Content.Server/Temperature/Components/ContainerTemperatureComponent.cs +++ b/Content.Server/Temperature/Components/ContainerTemperatureComponent.cs @@ -1,11 +1,23 @@ -namespace Content.Server.Temperature.Components; +using Content.Shared.Temperature.Components; +namespace Content.Server.Temperature.Components; + +/// +/// Overrides the thresholds for an entity inserted into this container. +/// Used for cryogenics typically. +/// [RegisterComponent] public sealed partial class ContainerTemperatureComponent : Component { + /// + /// Overrides the for an entity inserted into this container. + /// [DataField] public float? HeatDamageThreshold; + /// + /// Overrides the for an entity inserted into this container. + /// [DataField] public float? ColdDamageThreshold; } diff --git a/Content.Server/Temperature/Components/InternalTemperatureComponent.cs b/Content.Server/Temperature/Components/InternalTemperatureComponent.cs index 1e456d4410..ff134727f0 100644 --- a/Content.Server/Temperature/Components/InternalTemperatureComponent.cs +++ b/Content.Server/Temperature/Components/InternalTemperatureComponent.cs @@ -1,4 +1,7 @@ using Content.Server.Temperature.Systems; +using Content.Shared.Atmos; +using Content.Shared.Temperature.Components; +using Content.Shared.Temperature.HeatContainer; namespace Content.Server.Temperature.Components; @@ -12,37 +15,33 @@ namespace Content.Server.Temperature.Components; /// Too cold? Suffering hypothermia, start shivering to warm up and increase hunger. /// [RegisterComponent, Access(typeof(TemperatureSystem))] -public sealed partial class InternalTemperatureComponent : Component +public sealed partial class InternalTemperatureComponent : Component, IHeatContainer { + // TODO: These values probably shouldn't be duplicated from temperature component, but they're only used for the chef atm so low priority. /// /// Internal temperature which is modified by surface temperature. - /// This gets set to on mapinit. + /// This gets set to on mapinit. /// - [DataField, ViewVariables(VVAccess.ReadWrite)] - public float Temperature; + [DataField] + public float Temperature { get; set; } = Atmospherics.T20C; /// - /// Thermal conductivity of the material in W/m/K. - /// Higher conductivity means its insides will heat up faster. + /// Heat capacity of our internal temperature. + /// This gets set to on mapinit. /// - [DataField, ViewVariables(VVAccess.ReadWrite)] - public float Conductivity = 0.5f; + [DataField] + public float HeatCapacity { get; set; } /// - /// Average thickness between the surface and the inside. - /// For meats and such this is constant. - /// Thicker materials take longer for heat to dissipate. + /// Thermal Conductance in W/K to this entity's . + /// Roughly estimated by multiplying meat's thermal conductivity of about 0.4 W/(m*K) by the total surface area of the meat, + /// and dividing by the thickness of the meat. + /// Then we multiply by four because we should only care about half the thickness typically, and also we're sharing a heat capacity. + /// Yes this is stupid. I'll care when chef has content or this is used by BodySystem. + /// No I'm not doing a custom value for each piece of meat. /// - [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] - public float Thickness; + [DataField] + public float Conductance = 40f; + - /// - /// Surface area in m^2 for the purpose of conducting surface temperature to the inside. - /// Larger surface area means it takes longer to heat up/cool down - /// - /// - /// For meats etc this should just be the area of the cooked surface not the whole thing as it's only getting heat from one side usually. - /// - [DataField(required: true), ViewVariables(VVAccess.ReadWrite)] - public float Area; } diff --git a/Content.Server/Temperature/Components/TemperatureProtectionComponent.cs b/Content.Server/Temperature/Components/TemperatureProtectionComponent.cs index 01e46cfc8d..8c40e35fa0 100644 --- a/Content.Server/Temperature/Components/TemperatureProtectionComponent.cs +++ b/Content.Server/Temperature/Components/TemperatureProtectionComponent.cs @@ -7,16 +7,10 @@ namespace Content.Server.Temperature.Components; public sealed partial class TemperatureProtectionComponent : Component { /// - /// Multiplier for the transferred heat when heating up + /// Multiplier for the transferred heat when heating up or cooling down. /// [DataField] - public float HeatingCoefficient = 1.0f; - - /// - /// Multiplier for the transferred heat when cooling down - /// - [DataField] - public float CoolingCoefficient = 1.0f; + public float Coefficient = 1.0f; } /// diff --git a/Content.Server/Temperature/Systems/EntityHeaterSystem.cs b/Content.Server/Temperature/Systems/EntityHeaterSystem.cs index a9c6ede33f..1c46afa011 100644 --- a/Content.Server/Temperature/Systems/EntityHeaterSystem.cs +++ b/Content.Server/Temperature/Systems/EntityHeaterSystem.cs @@ -35,13 +35,13 @@ public sealed partial class EntityHeaterSystem : SharedEntityHeaterSystem if (!power.Powered) continue; - // don't divide by total entities since it's a big grill + // divide by total entities to encourage the use of multiple grills // excess would just be wasted in the air but that's not worth simulating // if you want a heater thermomachine just use that... var energy = power.PowerReceived * deltaTime; foreach (var ent in placer.PlacedEntities) { - _temperature.ChangeHeat(ent, energy); + _temperature.ChangeHeat(ent, energy / placer.PlacedEntities.Count); } } } diff --git a/Content.Server/Temperature/Systems/TemperatureSystem.Damage.cs b/Content.Server/Temperature/Systems/TemperatureSystem.Damage.cs index c7e31bad81..c16ef38325 100644 --- a/Content.Server/Temperature/Systems/TemperatureSystem.Damage.cs +++ b/Content.Server/Temperature/Systems/TemperatureSystem.Damage.cs @@ -52,9 +52,9 @@ public sealed partial class TemperatureSystem private void InitializeDamage() { - SubscribeLocalEvent(ServerAlert); + SubscribeLocalEvent(ServerAlert); - SubscribeLocalEvent(EnqueueDamage); + SubscribeLocalEvent(EnqueueDamage); SubscribeLocalEvent(OnUnpaused); // Allows overriding thresholds based on the parent's thresholds. @@ -98,7 +98,7 @@ public sealed partial class TemperatureSystem var heatDamageThreshold = entity.Comp.ParentHeatDamageThreshold ?? entity.Comp.HeatDamageThreshold; var coldDamageThreshold = entity.Comp.ParentColdDamageThreshold ?? entity.Comp.ColdDamageThreshold; - if (temperature.CurrentTemperature >= heatDamageThreshold) + if (temperature.Temperature >= heatDamageThreshold) { if (!entity.Comp.TakingDamage) { @@ -106,11 +106,11 @@ public sealed partial class TemperatureSystem entity.Comp.TakingDamage = true; } - var diff = Math.Abs(temperature.CurrentTemperature - heatDamageThreshold); + var diff = Math.Abs(temperature.Temperature - heatDamageThreshold); var tempDamage = c / (1 + a * Math.Pow(Math.E, -heatK * diff)) - y; _damageable.TryChangeDamage(entity.Owner, entity.Comp.HeatDamage * tempDamage * deltaTime.TotalSeconds, ignoreResistances: true, interruptsDoAfters: false); } - else if (temperature.CurrentTemperature <= coldDamageThreshold) + else if (temperature.Temperature <= coldDamageThreshold) { if (!entity.Comp.TakingDamage) { @@ -118,7 +118,7 @@ public sealed partial class TemperatureSystem entity.Comp.TakingDamage = true; } - var diff = Math.Abs(temperature.CurrentTemperature - coldDamageThreshold); + var diff = Math.Abs(temperature.Temperature - coldDamageThreshold); var tempDamage = Math.Sqrt(diff * (Math.Pow(entity.Comp.DamageCap.Double(), 2) / coldDamageThreshold)); _damageable.TryChangeDamage(entity.Owner, entity.Comp.ColdDamage * tempDamage * deltaTime.TotalSeconds, ignoreResistances: true, interruptsDoAfters: false); @@ -130,7 +130,7 @@ public sealed partial class TemperatureSystem } } - private void ServerAlert(Entity entity, ref OnTemperatureChangeEvent args) + private void ServerAlert(Entity entity, ref TemperatureChangedEvent args) { ProtoId type; float threshold; @@ -175,7 +175,7 @@ public sealed partial class TemperatureSystem _alerts.ClearAlertCategory(entity.AsNullable(), TemperatureAlertCategory); } - private void EnqueueDamage(Entity ent, ref OnTemperatureChangeEvent args) + private void EnqueueDamage(Entity ent, ref TemperatureChangedEvent args) { if (ShouldUpdateDamage.Add(ent) && !ent.Comp.TakingDamage) ent.Comp.LastUpdate = _gameTiming.CurTime; diff --git a/Content.Server/Temperature/Systems/TemperatureSystem.cs b/Content.Server/Temperature/Systems/TemperatureSystem.cs index 14539728f3..0698e090ab 100644 --- a/Content.Server/Temperature/Systems/TemperatureSystem.cs +++ b/Content.Server/Temperature/Systems/TemperatureSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Rejuvenate; using Content.Shared.Temperature; using Content.Shared.Projectiles; using Content.Shared.Temperature.Components; +using Content.Shared.Temperature.HeatContainer; using Content.Shared.Temperature.Systems; namespace Content.Server.Temperature.Systems; @@ -20,7 +21,7 @@ public sealed partial class TemperatureSystem : SharedTemperatureSystem SubscribeLocalEvent(OnAtmosExposedUpdate); SubscribeLocalEvent(OnRejuvenate); - Subs.SubscribeWithRelay(OnTemperatureChangeAttempt, held: false); + Subs.SubscribeWithRelay(OnBeforeHeatExchange, held: false); SubscribeLocalEvent(OnInit); @@ -29,6 +30,15 @@ public sealed partial class TemperatureSystem : SharedTemperatureSystem InitializeDamage(); } + protected override void OnMapInit(Entity entity, ref MapInitEvent args) + { + base.OnMapInit(entity, ref args); + + // Make sure entities don't spawn cold! + if (_thermalRegulatorQuery.TryComp(entity, out var comp)) + entity.Comp.Temperature = comp.NormalBodyTemperature; + } + public override void Update(float frameTime) { base.Update(frameTime); @@ -37,72 +47,28 @@ public sealed partial class TemperatureSystem : SharedTemperatureSystem var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp, out var temp)) { - // don't do anything if they equalised - var diff = Math.Abs(temp.CurrentTemperature - comp.Temperature); + // don't do anything if they equalized + var diff = Math.Abs(temp.Temperature - comp.Temperature); if (diff < 0.1f) continue; - // heat flow in W/m^2 as per fourier's law in 1D. - var q = comp.Conductivity * diff / comp.Thickness; - - // convert to J then K - var joules = q * comp.Area * frameTime; - var degrees = joules / GetHeatCapacity(uid, temp); - if (temp.CurrentTemperature < comp.Temperature) - degrees *= -1; - - // exchange heat between inside and surface - comp.Temperature += degrees; - ForceChangeTemperature(uid, temp.CurrentTemperature - degrees, temp); + ConductHeat((uid, temp), ref comp, frameTime, comp.Conductance, true); } UpdateDamage(); } - public void ForceChangeTemperature(EntityUid uid, float temp, TemperatureComponent? temperature = null) - { - if (!TemperatureQuery.Resolve(uid, ref temperature)) - return; - - var lastTemp = temperature.CurrentTemperature; - var delta = temperature.CurrentTemperature - temp; - temperature.CurrentTemperature = temp; - RaiseLocalEvent(uid, new OnTemperatureChangeEvent(temperature.CurrentTemperature, lastTemp, delta), broadcast: true); - } - - public override void ChangeHeat(EntityUid uid, float heatAmount, bool ignoreHeatResistance = false, TemperatureComponent? temperature = null) - { - if (!TemperatureQuery.Resolve(uid, ref temperature, false)) - return; - - if (!ignoreHeatResistance) - { - var ev = new ModifyChangedTemperatureEvent(heatAmount); - RaiseLocalEvent(uid, ev); - heatAmount = ev.TemperatureDelta; - } - - float lastTemp = temperature.CurrentTemperature; - temperature.CurrentTemperature += heatAmount / GetHeatCapacity(uid, temperature); - float delta = temperature.CurrentTemperature - lastTemp; - - RaiseLocalEvent(uid, new OnTemperatureChangeEvent(temperature.CurrentTemperature, lastTemp, delta), broadcast: true); - } - - private void OnAtmosExposedUpdate(EntityUid uid, TemperatureComponent temperature, ref AtmosExposedUpdateEvent args) + private void OnAtmosExposedUpdate(Entity entity, ref AtmosExposedUpdateEvent args) { var transform = args.Transform; if (transform.MapUid == null) return; - var temperatureDelta = args.GasMixture.Temperature - temperature.CurrentTemperature; - var airHeatCapacity = _atmosphere.GetHeatCapacity(args.GasMixture, false); - var heatCapacity = GetHeatCapacity(uid, temperature); - // TODO ATMOS: This heat transfer formula is really really wrong, it needs to be pulled out. Pending on HeatContainers. - var heat = temperatureDelta * (airHeatCapacity * heatCapacity / - (airHeatCapacity + heatCapacity)); - ChangeHeat(uid, heat * temperature.AtmosTemperatureTransferEfficiency, temperature: temperature); + // TODO ATMOS: Atmos heat containers!!! + var atmosContainer = new HeatContainer(_atmosphere.GetHeatCapacity(args.GasMixture, false), args.GasMixture.Temperature); + ConductHeat(entity.AsNullable(), ref atmosContainer, args.DeltaTime, args.ConductivityMod); + args.GasMixture.Temperature = atmosContainer.Temperature; } private void OnInit(Entity entity, ref MapInitEvent args) @@ -110,24 +76,20 @@ public sealed partial class TemperatureSystem : SharedTemperatureSystem if (!TemperatureQuery.TryComp(entity, out var temp)) return; - entity.Comp.Temperature = temp.CurrentTemperature; + // TODO: This shouldn't copy temperature component, but this component is so niche it's not worth the effort of fixing. + entity.Comp.Temperature = temp.Temperature; + entity.Comp.HeatCapacity = temp.HeatCapacity; } - private void OnRejuvenate(EntityUid uid, TemperatureComponent comp, RejuvenateEvent args) + private void OnRejuvenate(Entity entity, ref RejuvenateEvent args) { - ForceChangeTemperature(uid, Atmospherics.T20C, comp); + SetTemperature(entity.AsNullable(), _thermalRegulatorQuery.CompOrNull(entity)?.NormalBodyTemperature ?? Atmospherics.T20C); } - private void OnTemperatureChangeAttempt(EntityUid uid, TemperatureProtectionComponent component, ModifyChangedTemperatureEvent args) + private void OnBeforeHeatExchange(Entity entity, ref BeforeHeatExchangeEvent args) { - var coefficient = args.TemperatureDelta < 0 - ? component.CoolingCoefficient - : component.HeatingCoefficient; - - var ev = new GetTemperatureProtectionEvent(coefficient); - RaiseLocalEvent(uid, ref ev); - - args.TemperatureDelta *= ev.Coefficient; + // TODO: Proper coverage modifiers!!! This should be its own system which relays to inventory and then based on coverage spits out a modifier! + args.HeatTransferModifier *= entity.Comp.Coefficient; } private void ChangeTemperatureOnCollide(Entity ent, ref ProjectileHitEvent args) diff --git a/Content.Shared/Atmos/AtmosExposedEvents.cs b/Content.Shared/Atmos/AtmosExposedEvents.cs index 41b65fe24f..b64ebb49cd 100644 --- a/Content.Shared/Atmos/AtmosExposedEvents.cs +++ b/Content.Shared/Atmos/AtmosExposedEvents.cs @@ -9,15 +9,22 @@ namespace Content.Shared.Atmos; /// The coordinates of the entity that is being exposed. /// The gas mixture that the entity is exposed to. /// The xform of the entity that is being exposed. +/// Amount of time since the last AtmosExposedUpdateEvent, in seconds. +/// A modifier for thermal conductivity between the exposed entity and the atmosphere. +/// Typically equal to [ByRefEvent] public readonly struct AtmosExposedUpdateEvent( EntityCoordinates coordinates, GasMixture mixture, - TransformComponent transform) + TransformComponent transform, + float deltaTime, + float conductivityMod) { public readonly EntityCoordinates Coordinates = coordinates; public readonly GasMixture GasMixture = mixture; public readonly TransformComponent Transform = transform; + public readonly float DeltaTime = deltaTime; + public readonly float ConductivityMod = conductivityMod; } /// diff --git a/Content.Shared/EntityConditions/Conditions/TemperatureEntityConditionSystem.cs b/Content.Shared/EntityConditions/Conditions/TemperatureEntityConditionSystem.cs index f87bbecf8c..6a818a1d33 100644 --- a/Content.Shared/EntityConditions/Conditions/TemperatureEntityConditionSystem.cs +++ b/Content.Shared/EntityConditions/Conditions/TemperatureEntityConditionSystem.cs @@ -12,7 +12,7 @@ public sealed partial class TemperatureEntityConditionSystem : EntityConditionSy { protected override void Condition(Entity entity, ref EntityConditionEvent args) { - if (entity.Comp.CurrentTemperature >= args.Condition.Min && entity.Comp.CurrentTemperature <= args.Condition.Max) + if (entity.Comp.Temperature >= args.Condition.Min && entity.Comp.Temperature <= args.Condition.Max) args.Result = true; } } diff --git a/Content.Shared/EntityEffects/Effects/AdjustTemperatureEntityEffectsSystem.cs b/Content.Shared/EntityEffects/Effects/AdjustTemperatureEntityEffectsSystem.cs index 94b850fd98..418730e33a 100644 --- a/Content.Shared/EntityEffects/Effects/AdjustTemperatureEntityEffectsSystem.cs +++ b/Content.Shared/EntityEffects/Effects/AdjustTemperatureEntityEffectsSystem.cs @@ -16,7 +16,7 @@ public sealed partial class AdjustTemperatureEntityEffectSystem : EntityEffectSy { var amount = args.Effect.Amount * args.Scale; - _temperature.ChangeHeat(entity, amount, true, entity.Comp); + _temperature.ChangeHeat(entity.AsNullable(), amount, true); } } diff --git a/Content.Shared/Inventory/InventorySystem.Relay.cs b/Content.Shared/Inventory/InventorySystem.Relay.cs index 439123320e..7283fb6153 100644 --- a/Content.Shared/Inventory/InventorySystem.Relay.cs +++ b/Content.Shared/Inventory/InventorySystem.Relay.cs @@ -49,7 +49,6 @@ public partial class InventorySystem SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); - SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); SubscribeLocalEvent(RelayInventoryEvent); @@ -86,6 +85,7 @@ public partial class InventorySystem SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); + SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); SubscribeLocalEvent(RefRelayInventoryEvent); diff --git a/Content.Shared/Medical/Cryogenics/InsideCryoPodComponent.cs b/Content.Shared/Medical/Cryogenics/InsideCryoPodComponent.cs index 03cc3edf13..033a79e3ff 100644 --- a/Content.Shared/Medical/Cryogenics/InsideCryoPodComponent.cs +++ b/Content.Shared/Medical/Cryogenics/InsideCryoPodComponent.cs @@ -10,4 +10,10 @@ public sealed partial class InsideCryoPodComponent: Component [ViewVariables] [DataField("previousOffset")] public Vector2 PreviousOffset { get; set; } = new(0, 0); + + /// + /// A modifier for the conductance between the cryo pod and the entity inside. + /// + [DataField] + public float ConductanceMod = 20f; // Arbitrary number. Likely cryopods will have to be heat containers with special juice in the future, or use Frezon... } diff --git a/Content.Shared/Medical/Cryogenics/SharedInsideCryoPodSystem.cs b/Content.Shared/Medical/Cryogenics/SharedInsideCryoPodSystem.cs index da3604e6e5..76fd6034e8 100644 --- a/Content.Shared/Medical/Cryogenics/SharedInsideCryoPodSystem.cs +++ b/Content.Shared/Medical/Cryogenics/SharedInsideCryoPodSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.Standing; +using Content.Shared.Temperature; using Robust.Shared.Containers; namespace Content.Shared.Medical.Cryogenics; @@ -7,23 +8,24 @@ public abstract partial class SharedCryoPodSystem { public virtual void InitializeInsideCryoPod() { - SubscribeLocalEvent(HandleDown); SubscribeLocalEvent(OnEntGotRemovedFromContainer); + SubscribeLocalEvent(HandleDown); + SubscribeLocalEvent(OnBeforeHeatExchange); + } + + private void OnEntGotRemovedFromContainer(Entity entity, ref EntGotRemovedFromContainerMessage args) + { + RemCompDeferred(entity); } // Must stand in the cryo pod - private void HandleDown(EntityUid uid, InsideCryoPodComponent component, DownAttemptEvent args) + private void HandleDown(Entity entity, ref DownAttemptEvent args) { args.Cancel(); } - private void OnEntGotRemovedFromContainer(EntityUid uid, InsideCryoPodComponent component, EntGotRemovedFromContainerMessage args) + private void OnBeforeHeatExchange(Entity entity, ref BeforeHeatExchangeEvent args) { - if (Terminating(uid)) - { - return; - } - - RemComp(uid); + args.HeatTransferModifier *= entity.Comp.ConductanceMod; } } diff --git a/Content.Shared/Temperature/Components/EntityHeaterComponent.cs b/Content.Shared/Temperature/Components/EntityHeaterComponent.cs index 6cf97a0534..76bb4f4ba7 100644 --- a/Content.Shared/Temperature/Components/EntityHeaterComponent.cs +++ b/Content.Shared/Temperature/Components/EntityHeaterComponent.cs @@ -16,7 +16,7 @@ public sealed partial class EntityHeaterComponent : Component /// Low and medium are 33% and 66% respectively. /// [DataField] - public float Power = 2400f; + public float Power = 12000f; /// /// Current setting of the heater. If it is off or unpowered it won't heat anything. diff --git a/Content.Shared/Temperature/Components/TemperatureComponent.cs b/Content.Shared/Temperature/Components/TemperatureComponent.cs index fd79c4b4b2..00b0cf2934 100644 --- a/Content.Shared/Temperature/Components/TemperatureComponent.cs +++ b/Content.Shared/Temperature/Components/TemperatureComponent.cs @@ -1,4 +1,6 @@ using Content.Shared.Atmos; +using Content.Shared.Temperature.HeatContainer; +using Content.Shared.Temperature.Systems; namespace Content.Shared.Temperature.Components; @@ -7,23 +9,31 @@ namespace Content.Shared.Temperature.Components; /// informing others of the current temperature. /// [RegisterComponent] -public sealed partial class TemperatureComponent : Component +[Access(typeof(SharedTemperatureSystem))] +public sealed partial class TemperatureComponent : Component, IHeatContainer { /// - /// Surface temperature which is modified by the environment. + /// The specific heat capacity of this entity in J/(kg*K). Humans are about 3kJ/(kg*K) /// - [DataField, ViewVariables(VVAccess.ReadWrite)] - public float CurrentTemperature = Atmospherics.T20C; + [DataField] + public float SpecificHeat = 3000f; + + [DataField] + public float HeatCapacity { get; set; } + + [DataField] + public float Temperature { get; set; } = Atmospherics.T20C; /// - /// Heat capacity per kg of mass. + /// Thermal Conductivity in W/(K*m^2). + /// Human skin is about 0.3 W/(m*K) + /// Divide that by the thickness of skin of about 2mm giving us a final value of 150 + /// Source: https://pmc.ncbi.nlm.nih.gov/articles/PMC8953946/ /// - [DataField, ViewVariables(VVAccess.ReadWrite)] - public float SpecificHeat = 50f; - - /// - /// How well does the air surrounding you merge into your body temperature? - /// - [DataField, ViewVariables(VVAccess.ReadWrite)] - public float AtmosTemperatureTransferEfficiency = 0.1f; + /// + /// This value should be multiplied by a surface area value based on the amount of area in contact. + /// For Atmospherics, this is typically 2m^2, the surface area of the average body. + /// + [DataField] + public float ThermalConductivity = 150f; } diff --git a/Content.Shared/Temperature/Systems/SharedEntityHeaterSystem.cs b/Content.Shared/Temperature/Systems/SharedEntityHeaterSystem.cs index 9a8dc57d4b..848052ebf6 100644 --- a/Content.Shared/Temperature/Systems/SharedEntityHeaterSystem.cs +++ b/Content.Shared/Temperature/Systems/SharedEntityHeaterSystem.cs @@ -88,8 +88,8 @@ public abstract partial class SharedEntityHeaterSystem : EntitySystem // Just think of the load as a little LED, or bad wiring, or something. return setting switch { - EntityHeaterSetting.Low => max / 3f, - EntityHeaterSetting.Medium => max * 2f / 3f, + EntityHeaterSetting.Low => max / 4f, + EntityHeaterSetting.Medium => max / 2f, EntityHeaterSetting.High => max, _ => 0.01f, }; diff --git a/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs b/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs index 32c370d220..375579c6bc 100644 --- a/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs +++ b/Content.Shared/Temperature/Systems/SharedTemperatureSystem.cs @@ -1,9 +1,10 @@ using System.Linq; -using Content.Shared.Atmos; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Content.Shared.Temperature.Components; +using Content.Shared.Temperature.HeatContainer; using Robust.Shared.Physics.Components; +using Robust.Shared.Physics.Events; using Robust.Shared.Timing; namespace Content.Shared.Temperature.Systems; @@ -27,11 +28,33 @@ public abstract partial class SharedTemperatureSystem : EntitySystem { base.Initialize(); - SubscribeLocalEvent(OnTemperatureChanged); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnMassDataChanged); + SubscribeLocalEvent(OnTemperatureChanged); SubscribeLocalEvent(OnRefreshMovementSpeedModifiers); } - private void OnTemperatureChanged(Entity ent, ref OnTemperatureChangeEvent args) + /// + /// Calculates the HeatCapacity for this entity based on its SpecificHeat and mass. + /// This is a carryover from the old TemperatureSystem. + /// If this entity does not have a , then it assumes it's 1kg. + /// + protected virtual void OnMapInit(Entity entity, ref MapInitEvent args) + { + // We calculate the heat capacity for our entity by multiplying its mass by its specific heat. + // If the entity has no mass, we assume it's 1 kilogram. + var mass = CompOrNull(entity)?.FixturesMass ?? 1f; + + // TODO: This assumes this is temperature for the whole body, but ideally we want it split into surface and internal temperature! + entity.Comp.HeatCapacity = mass * entity.Comp.SpecificHeat; + } + + private void OnMassDataChanged(Entity entity, ref MassDataChangedEvent args) + { + entity.Comp.HeatCapacity = args.NewMass * entity.Comp.SpecificHeat; + } + + private void OnTemperatureChanged(Entity ent, ref TemperatureChangedEvent args) { foreach (var (threshold, modifier) in ent.Comp.Thresholds) { @@ -82,18 +105,107 @@ public abstract partial class SharedTemperatureSystem : EntitySystem } } - public virtual void ChangeHeat(EntityUid uid, float heatAmount, bool ignoreHeatResistance = false, TemperatureComponent? temperature = null) + /// + /// Conducts heat between an entity with TemperatureComponent and another + /// + /// Entity we're conducting heat with + /// Heat container which is conducting heat with our entity + /// The amount of time that the heat is allowed to conduct, in seconds. This value should be small. + /// An optional heat transfer modifier for this exchange + /// Whether we should avoid raising an event which checks for conduction modifiers on our entity. + /// Returns the amount of heat exchanged, in Joules. A positive value means the entity lost heat energy. + public float ConductHeat(Entity entity, ref T heatContainer, float deltaT, float heatTransferMod = 1f, bool ignoreHeatResistance = false) where T : IHeatContainer { + if (!TemperatureQuery.Resolve(entity, ref entity.Comp, false) + || MathHelper.CloseTo(entity.Comp.Temperature, heatContainer.Temperature)) + return 0f; - } - - public float GetHeatCapacity(EntityUid uid, TemperatureComponent? comp = null, PhysicsComponent? physics = null) - { - if (!TemperatureQuery.Resolve(uid, ref comp) || !Resolve(uid, ref physics, false) || physics.FixturesMass <= 0) + var conductance = entity.Comp.ThermalConductivity * heatTransferMod; + if (!ignoreHeatResistance) { - return Atmospherics.MinimumHeatCapacity; + var ev = new BeforeHeatExchangeEvent(); + RaiseLocalEvent(entity, ref ev); + conductance *= ev.HeatTransferModifier; } - return comp.SpecificHeat * physics.FixturesMass; + var lastTemp = entity.Comp.Temperature; + var heatEx = HeatContainerHelpers.ConductHeat(ref entity.Comp, ref heatContainer, deltaT, conductance); + + var changeEv = new TemperatureChangedEvent(entity.Comp.Temperature, lastTemp); + RaiseLocalEvent(entity, ref changeEv, broadcast: true); + return heatEx; + } + + /// + /// Conducts heat for an entity with a TemperatureComponent to a source at a fixed temperature. + /// + /// Entity we're conducting heat with + /// Temperature this entity is being exposed to + /// The amount of time that the heat is allowed to conduct, in seconds. This value should be small. + /// An optional heat transfer modifier for this exchange + /// Whether we should avoid raising an event which checks for conduction modifiers on our entity. + /// Returns the amount of heat exchanged, in Joules. A positive value means the entity lost heat energy. + public float ConductHeat(Entity entity, float temperature, float deltaT, float heatTransferMod = 1f, bool ignoreHeatResistance = false) + { + if (!TemperatureQuery.Resolve(entity, ref entity.Comp, false) + || MathHelper.CloseTo(entity.Comp.Temperature, temperature)) + return 0f; + + var conductance = entity.Comp.ThermalConductivity * heatTransferMod; + if (!ignoreHeatResistance) + { + var ev = new BeforeHeatExchangeEvent(); + RaiseLocalEvent(entity, ref ev); + conductance *= ev.HeatTransferModifier; + } + + var lastTemp = entity.Comp.Temperature; + var heatEx = HeatContainerHelpers.ConductHeat(ref entity.Comp, temperature, deltaT, conductance); + + var changeEv = new TemperatureChangedEvent(entity.Comp.Temperature, lastTemp); + RaiseLocalEvent(entity, ref changeEv, broadcast: true); + return heatEx; + } + + /// + /// Adds or removes the specified amount of heat from an entity. + /// + /// Entity whose temperature we're modifying. + /// The change in heat. + /// Whether we should avoid raising an event to modify the conductance of our entity. + /// Returns the amount of heat that was actually added, after applying heat resistances. + public float ChangeHeat(Entity entity, float heatAmount, bool ignoreHeatResistance = false) + { + if (!TemperatureQuery.Resolve(entity, ref entity.Comp, false) || heatAmount == 0f) + return 0f; + + if (!ignoreHeatResistance) + { + var ev = new BeforeHeatExchangeEvent(); + RaiseLocalEvent(entity, ref ev ); + heatAmount *= ev.HeatTransferModifier; + } + + var lastTemp = entity.Comp.Temperature; + HeatContainerHelpers.AddHeat(ref entity.Comp, heatAmount); + + var changeEv = new TemperatureChangedEvent(entity.Comp.Temperature, lastTemp); + RaiseLocalEvent(entity, ref changeEv, broadcast: true); + + return heatAmount; + } + + /// + /// Protected because you should not be calling this. Sets heat to a new value. + /// + protected void SetTemperature(Entity entity, float temp) + { + if (!TemperatureQuery.Resolve(entity, ref entity.Comp)) + return; + + var lastTemp = entity.Comp.Temperature; + entity.Comp.Temperature = temp; + var changeEv = new TemperatureChangedEvent(entity.Comp.Temperature, lastTemp); + RaiseLocalEvent(entity, ref changeEv, broadcast: true); } } diff --git a/Content.Shared/Temperature/TemperatureEvents.cs b/Content.Shared/Temperature/TemperatureEvents.cs index 7a26d07e30..5f596b1b7f 100644 --- a/Content.Shared/Temperature/TemperatureEvents.cs +++ b/Content.Shared/Temperature/TemperatureEvents.cs @@ -2,29 +2,29 @@ using Content.Shared.Inventory; namespace Content.Shared.Temperature; -public sealed class ModifyChangedTemperatureEvent : EntityEventArgs, IInventoryRelayEvent +/// +/// This event is raised before heat is exchanged so that the conductance of the exchange can be changed. +/// +[ByRefEvent] +public record struct BeforeHeatExchangeEvent() : IInventoryRelayEvent { public SlotFlags TargetSlots { get; } = ~SlotFlags.POCKET; - public float TemperatureDelta; - - public ModifyChangedTemperatureEvent(float temperature) - { - TemperatureDelta = temperature; - } + /// + /// A multiplicative modifier for heat transfers on the entity this event is being raised to. + /// + public float HeatTransferModifier = 1f; } -public sealed class OnTemperatureChangeEvent : EntityEventArgs +/// +/// This event is raised after heat is exchanged to inform other systems that temperature has changed. +/// +/// Current temperature of this entity. +/// Previous temperature of this entity. +[ByRefEvent] +public record struct TemperatureChangedEvent(float CurrentTemperature, float LastTemperature) { - public readonly float CurrentTemperature; - public readonly float LastTemperature; - public readonly float TemperatureDelta; - - public OnTemperatureChangeEvent(float current, float last, float delta) - { - CurrentTemperature = current; - LastTemperature = last; - TemperatureDelta = delta; - } + public readonly float CurrentTemperature = CurrentTemperature; + public readonly float LastTemperature = LastTemperature; + public readonly float TemperatureDelta = CurrentTemperature - LastTemperature; } - diff --git a/Resources/Prototypes/Atmospherics/gases.yml b/Resources/Prototypes/Atmospherics/gases.yml index b217074ca8..94244e55ce 100644 --- a/Resources/Prototypes/Atmospherics/gases.yml +++ b/Resources/Prototypes/Atmospherics/gases.yml @@ -2,7 +2,7 @@ id: Oxygen name: gas-oxygen abbreviation: gas-oxygen-abbreviation - molarHeatCapacity: 20 + molarHeatCapacity: 29 heatCapacityRatio: 1.4 molarMass: 32 color: '#2887E8' @@ -14,7 +14,7 @@ id: Nitrogen name: gas-nitrogen abbreviation: gas-nitrogen-abbreviation - molarHeatCapacity: 30 + molarHeatCapacity: 29 heatCapacityRatio: 1.4 molarMass: 28 color: '#DA1010' @@ -25,7 +25,7 @@ id: CarbonDioxide name: gas-carbon-dioxide abbreviation: gas-carbon-dioxide-abbreviation - molarHeatCapacity: 30 + molarHeatCapacity: 37 heatCapacityRatio: 1.3 molarMass: 44 color: '#4e4e4e' diff --git a/Resources/Prototypes/Body/Species/moth.yml b/Resources/Prototypes/Body/Species/moth.yml index 326fa64bdb..18dcec3ab9 100644 --- a/Resources/Prototypes/Body/Species/moth.yml +++ b/Resources/Prototypes/Body/Species/moth.yml @@ -178,9 +178,6 @@ damage: types: Heat: 2.5 # moths burn more easily - - type: Temperature - currentTemperature: 310.15 - specificHeat: 46 - type: TemperatureDamage # Moths hate the heat and thrive in the cold. heatDamageThreshold: 320 coldDamageThreshold: 230 diff --git a/Resources/Prototypes/Body/Species/reptilian.yml b/Resources/Prototypes/Body/Species/reptilian.yml index 222ea617bb..74eab20814 100644 --- a/Resources/Prototypes/Body/Species/reptilian.yml +++ b/Resources/Prototypes/Body/Species/reptilian.yml @@ -149,9 +149,6 @@ damage: types: Slash: 5 - - type: Temperature - currentTemperature: 310.15 - specificHeat: 42 - type: TemperatureDamage heatDamageThreshold: 400 coldDamageThreshold: 285 diff --git a/Resources/Prototypes/Body/Species/vulpkanin.yml b/Resources/Prototypes/Body/Species/vulpkanin.yml index a48649d7b4..38c551434c 100644 --- a/Resources/Prototypes/Body/Species/vulpkanin.yml +++ b/Resources/Prototypes/Body/Species/vulpkanin.yml @@ -173,8 +173,6 @@ types: Piercing: 2 Slash: 3 - - type: Temperature - specificHeat: 44 - type: TemperatureDamage heatDamageThreshold: 320 coldDamageThreshold: 230 @@ -186,9 +184,6 @@ Heat: 2.5 # Per second, scales with temperature & other constants - type: Wagging action: ActionToggleWaggingVulpkanin - - type: TemperatureProtection - heatingCoefficient: 1.2 - coolingCoefficient: 0.3 - type: JumpAbility action: ActionVulpkaninGravityJump canCollide: true diff --git a/Resources/Prototypes/Body/species_base.yml b/Resources/Prototypes/Body/species_base.yml index ae386d2be2..6428ddb87e 100644 --- a/Resources/Prototypes/Body/species_base.yml +++ b/Resources/Prototypes/Body/species_base.yml @@ -185,11 +185,9 @@ - type: Fingerprint - type: Blindable - type: Temperature - currentTemperature: 310.15 - specificHeat: 42 - type: TemperatureDamage heatDamageThreshold: 325 - coldDamageThreshold: 260 + coldDamageThreshold: 273.15 coldDamage: types: Cold: 0.1 #per second, scales with temperature & other constants diff --git a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml index bfe0e53600..ec3f13dde9 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/base_clothinghead.yml @@ -103,7 +103,7 @@ - type: entity abstract: true - parent: ClothingHeadBase + parent: [ ClothingHeadBase, TemperatureProtection ] id: ClothingHeadEVAHelmetBase name: base space helmet components: @@ -116,9 +116,6 @@ - type: PressureProtection highPressureMultiplier: 0.6 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.2 - coolingCoefficient: 0.2 - type: IngestionBlocker - type: Clothing #Copies ClothingHeadHardsuitBase behavior @@ -141,7 +138,7 @@ - type: entity abstract: true - # No parent since we aren't actually an item. + parent: TemperatureProtection id: ClothingHeadHardsuitBase name: base hardsuit helmet categories: [ HideSpawnMenu ] @@ -163,9 +160,6 @@ - type: PressureProtection highPressureMultiplier: 0.3 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.1 - coolingCoefficient: 0.1 - type: Armor modifiers: coefficients: @@ -188,6 +182,11 @@ - HeadSide - FacialHair +- type: entity + abstract: true + parent: [ TemperatureProtection, ClothingHeadHardsuitBase ] + id: ClothingHeadHardsuitInsulatedBase + - type: entity abstract: true # No parent since it isn't an item @@ -247,6 +246,7 @@ - type: entity abstract: true + parent: TemperatureProtectionMinimal id: ClothingHeadHatHoodWinterBase name: base winter coat hood description: A hood, made to keep your head warm. @@ -260,9 +260,6 @@ unequipSound: /Audio/Effects/rustle2.ogg quickEquip: false slots: [ HEAD ] - - type: TemperatureProtection - heatingCoefficient: 1.05 - coolingCoefficient: 0.7 - type: ZombificationResistance zombificationResistanceCoefficient: 0.90 - type: Armor # so zombification resistance shows up diff --git a/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml index 0d2814d537..4a70210939 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/eva-helmets.yml @@ -95,9 +95,6 @@ - state: equipped-head head-vox: - state: equipped-head-vox - - type: TemperatureProtection - heatingCoefficient: 0.1 - coolingCoefficient: 0.1 - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml index cc8761ca62..848227e3bb 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hardsuit-helmets.yml @@ -7,7 +7,7 @@ #CREW HARDSUITS #Atmospherics Hardsuit - type: entity - parent: [ ClothingHeadHardsuitBase, ClothingHeadSuitWithLightBase ] + parent: [ ClothingHeadHardsuitInsulatedBase, ClothingHeadSuitWithLightBase ] id: ClothingHeadHelmetHardsuitAtmos name: atmos hardsuit helmet description: A special hardsuit helmet designed for working in low-pressure, high thermal environments. @@ -62,9 +62,6 @@ - type: PressureProtection highPressureMultiplier: 0.08 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.005 - coolingCoefficient: 0.005 - type: FireProtection reduction: 0.2 - type: Tag @@ -584,7 +581,7 @@ #Syndicate Elite Hardsuit - type: entity - parent: [ ClothingHeadHardsuitBase, ClothingHeadSuitWithLightBase ] + parent: [ ClothingHeadHardsuitInsulatedBase, ClothingHeadSuitWithLightBase ] id: ClothingHeadHelmetHardsuitSyndieElite name: syndicate elite helmet description: An elite version of the blood-red hardsuit's helmet, with improved radiation resistance and fireproofing. Property of Gorlex Marauders. @@ -598,9 +595,6 @@ - type: PressureProtection highPressureMultiplier: 0.08 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.005 - coolingCoefficient: 0.005 - type: FireProtection reduction: 0.2 - type: Armor @@ -919,9 +913,6 @@ - type: PressureProtection highPressureMultiplier: 0.08 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.005 - coolingCoefficient: 0.005 - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml index ba6e5d7b53..5f68a1104a 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/helmets.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/helmets.yml @@ -276,7 +276,7 @@ #Fire Helmet - type: entity - parent: ClothingHeadLightBase + parent: [ClothingHeadLightBase, TemperatureProtection] id: ClothingHeadHelmetFire name: fire helmet description: An atmos tech's best friend. Provides some heat resistance and looks cool. @@ -287,9 +287,6 @@ sprite: Clothing/Head/Helmets/firehelmet.rsi quickEquip: true - type: IngestionBlocker - - type: TemperatureProtection - heatingCoefficient: 0.5 - coolingCoefficient: 0.8 - type: FireProtection reduction: 0.15 # not fully sealed so less protection - type: ItemSlots @@ -309,7 +306,7 @@ #Atmos Fire Helmet - type: entity - parent: [ClothingHeadLightBase, BaseEngineeringContraband] + parent: [ClothingHeadLightBase, TemperatureProtection, BaseEngineeringContraband] id: ClothingHeadHelmetAtmosFire name: atmos fire helmet description: An atmos fire helmet, able to keep the user cool in any situation. @@ -320,9 +317,6 @@ sprite: Clothing/Head/Helmets/atmos_firehelmet.rsi quickEquip: true - type: IngestionBlocker - - type: TemperatureProtection - heatingCoefficient: 0.3 - coolingCoefficient: 0.8 - type: FireProtection reduction: 0.2 - type: PressureProtection diff --git a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml index a9f119146b..44759965a9 100644 --- a/Resources/Prototypes/Entities/Clothing/Head/hoods.yml +++ b/Resources/Prototypes/Entities/Clothing/Head/hoods.yml @@ -226,16 +226,13 @@ - Hair - type: entity - parent: ClothingHeadHatHoodCarp + parent: [ ClothingHeadHatHoodCarp, TemperatureProtection ] id: ClothingHeadHelmetHardsuitCarp categories: [ HideSpawnMenu ] components: - type: PressureProtection highPressureMultiplier: 0.6 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.2 - coolingCoefficient: 0.2 - type: BreathMask # this is on the hood so you only fool the fish if you wear the whole set # wear carp suit and security helmet, they'll know you are fake diff --git a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml index 4e0bdbe2a2..32ce5bc2cd 100644 --- a/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml +++ b/Resources/Prototypes/Entities/Clothing/Neck/base_clothingneck.yml @@ -33,7 +33,7 @@ - type: entity abstract: true - parent: ClothingNeckBase + parent: [ TemperatureProtectionMinimal, ClothingNeckBase ] id: ClothingScarfBase components: - type: Tag @@ -42,6 +42,3 @@ - ClothMade - Recyclable - WhitelistChameleon - - type: TemperatureProtection - heatingCoefficient: 1.025 - coolingCoefficient: 0.5 diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 510f9895b0..4c986c4881 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -164,7 +164,7 @@ #Elite web vest - type: entity - parent: [ClothingOuterArmorBase, ClothingOuterStorageBase, BaseSyndicateContraband] + parent: [ClothingOuterArmorBase, TemperatureProtection, ClothingOuterStorageBase, BaseSyndicateContraband] id: ClothingOuterVestWebElite name: elite web vest description: A synthetic armor vest. This one has added webbing and heat resistant fibers. @@ -173,9 +173,6 @@ sprite: Clothing/OuterClothing/Vests/elitevest.rsi - type: Clothing sprite: Clothing/OuterClothing/Vests/elitevest.rsi - - type: TemperatureProtection - heatingCoefficient: 0.1 - coolingCoefficient: 0.1 - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml index 1ab627f078..de3f7208de 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/base_clothingouter.yml @@ -24,6 +24,19 @@ sprintModifier: 0.9 - type: HeldSpeedModifier +- type: entity + abstract: true + parent: [ ClothingOuterBaseLarge, TemperatureProtectionGood ] + id: ClothingOuterBaseLargeInsulated + +- type: entity + abstract: true + parent: [ ClothingOuterBaseLarge, TemperatureProtectionGreat ] + id: ClothingOuterBaseLargeFireproof + components: + - type: FireProtection + reduction: 0.65 + - type: entity abstract: true parent: ClothingOuterBase @@ -61,6 +74,11 @@ - ReagentId: Fiber Quantity: 60 +- type: entity + abstract: true + parent: [ ClothingOuterStorageEdible, TemperatureProtectionMinimal] + id: ClothingOuterJacketBase + - type: entity abstract: true parent: [ClothingOuterStorageBase, BaseFoldable] @@ -104,8 +122,8 @@ - type: entity abstract: true - parent: ClothingOuterStorageBase - id: ClothingOuterStorageToggleableBase + parent: ClothingOuterJacketBase + id: ClothingOuterJacketToggleableBase components: - type: ToggleableClothing clothingPrototype: ClothingHeadHatHoodWinterDefault @@ -118,23 +136,41 @@ - type: entity abstract: true - parent: [ClothingOuterBase, GeigerCounterClothing, AllowSuitStorageClothing] - id: ClothingOuterHardsuitBase - name: base hardsuit + parent: [ClothingOuterBaseLargeInsulated, AllowSuitStorageClothing] + id: ClothingOuterEVASuitBase + name: base EVA Suit components: # SlotBlocker blocked until UI change # - type: SlotBlock # slots: [innerclothing, feet] - type: PressureProtection - highPressureMultiplier: 0.3 + highPressureMultiplier: 0.6 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.01 - coolingCoefficient: 0.01 + - type: ClothingSpeedModifier + walkModifier: 0.8 + sprintModifier: 0.8 + - type: ProtectedFromStepTriggers + slots: WITHOUT_POCKET + - type: DamageOnInteractProtection + damageProtection: + flatReductions: + Heat: 10 # the average lightbulb only does around four damage! + slots: OUTERCLOTHING + - type: HideLayerClothing + slots: + - Tail + +- type: entity + abstract: true + parent: [ ClothingOuterEVASuitBase, GeigerCounterClothing ] + id: ClothingOuterHardsuitBase + name: base hardsuit + components: + - type: PressureProtection + highPressureMultiplier: 0.3 - type: ClothingSpeedModifier walkModifier: 0.6 sprintModifier: 0.6 - - type: HeldSpeedModifier - type: Item size: Ginormous shape: @@ -159,48 +195,6 @@ tags: - Hardsuit - WhitelistChameleon - - type: ProtectedFromStepTriggers - slots: WITHOUT_POCKET - - type: DamageOnInteractProtection - damageProtection: - flatReductions: - Heat: 10 # the average lightbulb only does around four damage! - slots: OUTERCLOTHING - - type: HideLayerClothing - slots: - - Tail - -- type: entity - abstract: true - parent: [ClothingOuterBase, AllowSuitStorageClothing] - id: ClothingOuterEVASuitBase - name: base EVA Suit - components: -# SlotBlocker blocked until UI change -# - type: SlotBlock -# slots: [innerclothing, feet] - - type: PressureProtection - highPressureMultiplier: 0.6 - lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.01 # Not complete protection from fire - coolingCoefficient: 0.01 - - type: ClothingSpeedModifier - walkModifier: 0.8 - sprintModifier: 0.8 - - type: HeldSpeedModifier - - type: Item - size: Huge - - type: ProtectedFromStepTriggers - slots: WITHOUT_POCKET - - type: DamageOnInteractProtection - damageProtection: - flatReductions: - Heat: 10 # the average lightbulb only does around four damage! - slots: OUTERCLOTHING - - type: HideLayerClothing - slots: - - Tail - type: entity parent: ClothingOuterEVASuitBase @@ -216,10 +210,10 @@ toggleable-clothing: !type:ContainerSlot {} - type: entity + abstract: true parent: ClothingOuterBase id: ClothingOuterBaseToggleable name: hoodie with hood - abstract: True components: - type: ToggleableClothing clothingPrototype: ClothingHeadHatHoodWinterDefault diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml index 235650d789..bc3d02385c 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/coats.yml @@ -100,7 +100,7 @@ sprite: Clothing/OuterClothing/Coats/hos_trenchcoat.rsi - type: entity - parent: ClothingOuterStorageToggleableBase + parent: ClothingOuterJacketToggleableBase id: ClothingOuterCoatJensen name: jensen coat description: A jensen coat. @@ -123,7 +123,7 @@ id: SyndieHandyFlag - type: entity - parent: ClothingOuterStorageEdible + parent: ClothingOuterJacketBase id: ClothingOuterCoatTrench name: trench coat description: A comfy trench coat. @@ -132,9 +132,6 @@ sprite: Clothing/OuterClothing/Coats/trenchcoat.rsi - type: Clothing sprite: Clothing/OuterClothing/Coats/trenchcoat.rsi - - type: TemperatureProtection - heatingCoefficient: 0.1 - coolingCoefficient: 0.1 - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index f15dfdf732..056b47da30 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -15,9 +15,6 @@ - type: PressureProtection highPressureMultiplier: 0.02 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.001 - coolingCoefficient: 0.001 - type: FireProtection reduction: 0.8 - type: ExplosionResistance @@ -213,9 +210,6 @@ Radiation: 0.1 - type: ExplosionResistance damageCoefficient: 0.2 - - type: TemperatureProtection - heatingCoefficient: 0.001 - coolingCoefficient: 0.001 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitMaxim @@ -350,7 +344,7 @@ #Chief Engineer's Hardsuit - type: entity - parent: [ClothingOuterHardsuitBase, BaseCommandContraband] + parent: [ TemperatureProtectionGreat, ClothingOuterHardsuitBase, BaseCommandContraband] id: ClothingOuterHardsuitEngineeringWhite name: chief engineer's hardsuit description: A special hardsuit that protects against hazardous, low pressure environments, made for the chief engineer of the station. @@ -594,7 +588,7 @@ #Syndicate Elite Hardsuit - type: entity - parent: [ClothingOuterHardsuitBase, BaseSyndicateContraband] + parent: [ TemperatureProtectionGreat, ClothingOuterHardsuitBase, BaseSyndicateContraband ] id: ClothingOuterHardsuitSyndieElite name: syndicate elite hardsuit description: An elite version of the blood-red hardsuit, with improved radiation resistance and fireproofing. Property of Gorlex Marauders. @@ -606,9 +600,6 @@ - type: PressureProtection highPressureMultiplier: 0.02 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.001 - coolingCoefficient: 0.001 - type: ExplosionResistance damageCoefficient: 0.3 - type: FireProtection @@ -986,8 +977,7 @@ highPressureMultiplier: 0.02 lowPressureMultiplier: 1000 - type: TemperatureProtection - heatingCoefficient: 0.001 - coolingCoefficient: 0.001 + coefficient: 0.001 - type: ExplosionResistance damageCoefficient: 0.2 - type: FireProtection @@ -1024,9 +1014,6 @@ - type: PressureProtection highPressureMultiplier: 0.02 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.001 - coolingCoefficient: 0.001 - type: ExplosionResistance damageCoefficient: 0.7 - type: Armor diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml index c1f8e250cf..2612bc8507 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/misc.yml @@ -304,7 +304,7 @@ sprite: Clothing/OuterClothing/Misc/hospitalgown.rsi - type: entity - parent: ClothingOuterBase + parent: ClothingOuterJacketBase id: ClothingOuterFlannelRed name: red flannel jacket description: An old fashioned red flannel jacket for space autumn. @@ -336,11 +336,9 @@ color: "#670a09" - state: equipped-OUTERCLOTHING-lines color: "#000000" - - type: TemperatureProtection - coolingCoefficient: 0.3 - type: entity - parent: ClothingOuterBase + parent: ClothingOuterJacketBase id: ClothingOuterFlannelBlue name: blue flannel jacket description: An old fashioned blue flannel jacket for space autumn. @@ -372,11 +370,9 @@ color: "#3232a6" - state: equipped-OUTERCLOTHING-lines color: "#000000" - - type: TemperatureProtection - coolingCoefficient: 0.3 - type: entity - parent: ClothingOuterBase + parent: ClothingOuterJacketBase id: ClothingOuterFlannelGreen name: green flannel jacket description: An old fashioned green flannel jacket for space autumn. @@ -408,8 +404,6 @@ color: "#164d0f" - state: equipped-OUTERCLOTHING-lines color: "#000000" - - type: TemperatureProtection - coolingCoefficient: 0.3 - type: entity parent: ClothingOuterBase diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/softsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/softsuits.yml index 7b81ad7ed2..1e9aae7b64 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/softsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/softsuits.yml @@ -36,7 +36,7 @@ #Emergency EVA - type: entity - parent: ClothingOuterEVASuitBaseToggleable + parent: [ TemperatureProtectionMinimal, ClothingOuterEVASuitBaseToggleable ] id: ClothingOuterSuitEmergency name: emergency pressure suit description: This bulky, uninsulated pressure suit was clearly not meant for extended use in outer space, despite NanoTrasen's claims that it passes corporate regulations. @@ -48,10 +48,6 @@ - type: ClothingSpeedModifier walkModifier: 0.7 sprintModifier: 0.7 - - type: HeldSpeedModifier - - type: TemperatureProtection - heatingCoefficient: 0.75 - coolingCoefficient: 0.5 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetEVALarge - type: Tag @@ -63,7 +59,7 @@ #Prisoner EVA - type: entity - parent: ClothingOuterEVASuitBase + parent: [ TemperatureProtectionMinimal, ClothingOuterEVASuitBase] id: ClothingOuterHardsuitEVAPrisoner name: prisoner pressure suit description: An emergency pressure suit meant for prisoners. It's not fully rated for extended use in outer space, but some wardens consider the lack of thermal insulation a feature. @@ -75,10 +71,6 @@ - type: ClothingSpeedModifier walkModifier: 0.7 sprintModifier: 0.7 - - type: HeldSpeedModifier - - type: TemperatureProtection - heatingCoefficient: 0.75 - coolingCoefficient: 0.5 - type: Tag tags: - SuitEVA @@ -115,17 +107,10 @@ - type: Appearance - type: Clothing sprite: Clothing/OuterClothing/Hardsuits/paramed.rsi - - type: PressureProtection - highPressureMultiplier: 0.5 - lowPressureMultiplier: 1000 - type: ClothingSpeedModifier walkModifier: 0.9 sprintModifier: 0.9 requireActivated: false - - type: HeldSpeedModifier - - type: TemperatureProtection - heatingCoefficient: 0.1 - coolingCoefficient: 0.1 - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/specific.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/specific.yml index 56508af486..169a322dd4 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/specific.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/specific.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ClothingOuterBase, AllowSuitStorageClothingGasTanks, BaseChameleon] + parent: [ClothingOuterBase, TemperatureProtectionMinimal, AllowSuitStorageClothingGasTanks, BaseChameleon] id: ClothingOuterChameleon name: vest description: A thick vest with a rubbery, water-resistant shell. @@ -14,9 +14,6 @@ - type: ChameleonClothing slot: [outerClothing] default: ClothingOuterVest - - type: TemperatureProtection # Same as a basic winter coat. - heatingCoefficient: 1.1 - coolingCoefficient: 0.1 - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml index 1b1bfdab15..15b615e230 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/suits.yml @@ -44,7 +44,7 @@ sprite: Clothing/OuterClothing/Suits/janitor_bombsuit.rsi - type: entity - parent: [ClothingOuterBaseLarge, AllowSuitStorageClothing] + parent: [ ClothingOuterBaseLargeFireproof, AllowSuitStorageClothing ] id: ClothingOuterSuitFire name: fire suit description: A suit that helps protect against hazardous temperatures. @@ -55,11 +55,6 @@ sprite: Clothing/OuterClothing/Suits/fire.rsi - type: PressureProtection highPressureMultiplier: 0.04 - - type: TemperatureProtection - heatingCoefficient: 0.005 - coolingCoefficient: 0.05 - - type: FireProtection - reduction: 0.65 # doesnt have a full seal so not as good - type: Armor modifiers: coefficients: @@ -78,7 +73,7 @@ - Tail - type: entity - parent: [ClothingOuterBaseLarge, AllowSuitStorageClothing] + parent: [ TemperatureProtectionGreat, ClothingOuterEVASuitBase, AllowSuitStorageClothing ] id: ClothingOuterSuitAtmosFire name: atmos fire suit description: An expensive firesuit that protects against even the most deadly of station fires. Designed to protect even if the wearer is set aflame. @@ -87,12 +82,6 @@ sprite: Clothing/OuterClothing/Suits/atmos_firesuit.rsi - type: Clothing sprite: Clothing/OuterClothing/Suits/atmos_firesuit.rsi - - type: PressureProtection - highPressureMultiplier: 0.02 - lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.001 - coolingCoefficient: 0.05 - type: FireProtection reduction: 0.8 # atmos firesuit offers best protection, hardsuits are a little vulnerable - type: Armor @@ -101,19 +90,10 @@ Slash: 0.9 Heat: 0.8 Cold: 0.8 - - type: ClothingSpeedModifier - walkModifier: 0.8 - sprintModifier: 0.8 - - type: HeldSpeedModifier - type: GroupExamine - - type: ProtectedFromStepTriggers - slots: WITHOUT_POCKET - type: Tag tags: - WhitelistChameleon - - type: HideLayerClothing - slots: - - Tail - type: entity parent: [ClothingOuterBaseLarge, GeigerCounterClothing, AllowSuitStorageClothing] @@ -146,7 +126,7 @@ - Tail - type: entity - parent: [ClothingOuterBaseLarge, AllowSuitStorageClothing, BaseToggleClothing, BaseHighlyIllegalContraband] + parent: [ ClothingOuterBaseLargeInsulated, AllowSuitStorageClothing, BaseToggleClothing, BaseHighlyIllegalContraband ] id: ClothingOuterSuitSpaceNinja name: space ninja suit description: This black technologically advanced, cybernetically-enhanced suit provides many abilities like invisibility or teleportation. @@ -159,9 +139,6 @@ - type: PressureProtection highPressureMultiplier: 0.6 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.01 - coolingCoefficient: 0.01 - type: Armor modifiers: coefficients: @@ -297,16 +274,13 @@ relayAccent: true - type: entity - parent: ClothingOuterBase + parent: [ ClothingOuterBaseToggleable, AllowSuitStorageClothing ] id: ClothingOuterSuitCarp name: carp suit description: A special suit that makes you look just like a space carp, if your eyesight is bad. components: - - type: AllowSuitStorage - type: Sprite sprite: Clothing/OuterClothing/Suits/carpsuit.rsi - - type: Item - size: Normal - type: Clothing sprite: Clothing/OuterClothing/Suits/carpsuit.rsi - type: ToggleableClothing @@ -321,7 +295,7 @@ - Tail - type: entity - parent: ClothingOuterSuitCarp + parent: [ ClothingOuterSuitCarp, TemperatureProtectionGood ] id: ClothingOuterHardsuitCarp suffix: Hardsuit, DO NOT MAP categories: [ DoNotMap ] @@ -329,9 +303,6 @@ - type: PressureProtection highPressureMultiplier: 0.6 lowPressureMultiplier: 1000 - - type: TemperatureProtection - heatingCoefficient: 0.01 - coolingCoefficient: 0.01 - type: ToggleableClothing clothingPrototype: ClothingHeadHelmetHardsuitCarp - type: StaticPrice diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml index 1d09b24a22..88699d7e26 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/wintercoats.yml @@ -1,5 +1,5 @@ - type: entity - parent: ClothingOuterStorageEdible + parent: [ TemperatureProtection, ClothingOuterJacketBase ] id: ClothingOuterWinterCoat name: winter coat description: A heavy jacket made from 'synthetic' animal furs. @@ -8,11 +8,6 @@ sprite: Clothing/OuterClothing/WinterCoats/coat.rsi - type: Clothing sprite: Clothing/OuterClothing/WinterCoats/coat.rsi - - type: TemperatureProtection - heatingCoefficient: 1.1 - coolingCoefficient: 0.1 - - type: Item - size: Normal - type: Armor modifiers: coefficients: diff --git a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml index e799e3ed30..5733cc7cfb 100644 --- a/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml +++ b/Resources/Prototypes/Entities/Clothing/Shoes/base_clothingshoes.yml @@ -67,10 +67,6 @@ - type: entity abstract: true - parent: ClothingShoesBaseButcherable + parent: [ ClothingShoesBaseButcherable, TemperatureProtectionMinimal ] id: ClothingShoesBaseWinterBoots description: Fluffy boots to help survive even the coldest of winters. - components: - - type: TemperatureProtection - heatingCoefficient: 1.025 - coolingCoefficient: 0.5 diff --git a/Resources/Prototypes/Entities/Clothing/base_clothing.yml b/Resources/Prototypes/Entities/Clothing/base_clothing.yml index f02feff158..2cfbeac59b 100644 --- a/Resources/Prototypes/Entities/Clothing/base_clothing.yml +++ b/Resources/Prototypes/Entities/Clothing/base_clothing.yml @@ -69,3 +69,31 @@ - type: ItemToggle onUse: false # can't really wear it like that - type: ToggleClothing + +- type: entity + abstract: true + id: TemperatureProtectionMinimal # Really light jackets and hoods. + components: + - type: TemperatureProtection + coefficient: 0.8 + +- type: entity + abstract: true + id: TemperatureProtection # Winter coats and environmentally sealed helmets + components: + - type: TemperatureProtection + coefficient: 0.6 + +- type: entity + abstract: true + id: TemperatureProtectionGood # EVA suits and basic hardsuits + components: + - type: TemperatureProtection + coefficient: 0.05 + +- type: entity + abstract: true + id: TemperatureProtectionGreat # Fire-retardant suits + components: + - type: TemperatureProtection + coefficient: 0.01 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 45f6612f1a..90fa37782e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -1801,9 +1801,6 @@ types: Slash: 5 Piercing: 4 - - type: Temperature - currentTemperature: 310.15 - specificHeat: 42 - type: TemperatureDamage heatDamageThreshold: 360 coldDamageThreshold: 285 @@ -2533,9 +2530,6 @@ - type: NpcFactionMember factions: - Passive - - type: Temperature - currentTemperature: 310.15 - specificHeat: 46 - type: TemperatureDamage heatDamageThreshold: 335 coldDamageThreshold: 230 @@ -3228,9 +3222,6 @@ damageModifierSet: Infernal - type: Injurable damageContainer: BiologicalMetaphysical - - type: Temperature - currentTemperature: 310.15 - specificHeat: 42 - type: TemperatureDamage heatDamageThreshold: 4000 #They come from hell, so.. coldDamageThreshold: 260 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml index f0795a1fd6..4ceddc730a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml @@ -35,9 +35,6 @@ 0: Alive 60: Critical 125: Dead - - type: Temperature - currentTemperature: 310.15 - specificHeat: 42 - type: TemperatureDamage heatDamageThreshold: 360 coldDamageThreshold: 285 diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index b2427856f7..547886f76a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -105,8 +105,6 @@ - type: GhostTakeoverAvailable - type: TypingIndicator proto: alien - - type: Temperature - currentTemperature: 310.15 - type: TemperatureDamage heatDamageThreshold: 360 coldDamageThreshold: -150 @@ -529,8 +527,6 @@ amount: 5 - type: TypingIndicator proto: alien - - type: Temperature - currentTemperature: 310.15 - type: TemperatureDamage heatDamageThreshold: 360 coldDamageThreshold: -150 diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index f3447bce3a..ee63ea6d9b 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -179,8 +179,6 @@ components: - type: AtmosExposed - type: Temperature - currentTemperature: 310.15 - specificHeat: 42 - type: TemperatureDamage heatDamageThreshold: 325 coldDamageThreshold: 0 @@ -214,9 +212,6 @@ shiveringHeatRegulation: 500 normalBodyTemperature: 310.15 thermalRegulationTemperatureThreshold: 2 - - type: Temperature - currentTemperature: 310.15 - specificHeat: 42 - type: TemperatureDamage heatDamageThreshold: 325 coldDamageThreshold: 260 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml index ca6c7ca508..20ead4214c 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/egg.yml @@ -60,13 +60,11 @@ # all below are for egg cooking/exploding - type: AtmosExposed - type: Temperature + thermalConductivity: 1 + temperature: 293.15 + heatCapacity: 15000 - type: TemperatureDamage - type: InternalTemperature - # ~1mm shell and ~1cm of albumen - thickness: 0.011 - area: 0.04 - # conductivity of egg shell based on a paper from Romanoff and Romanoff (1949) - conductivity: 0.456 # Splat - type: entity @@ -123,6 +121,6 @@ - ReagentId: EggCooked Quantity: 6 - type: Temperature - # preserve temperature from the boiling step - currentTemperature: 344 + temperature: 344.0 # preserve temperature from the boiling step, TODO: Construction system that doesn't suck. + heatCapacity: 15000 - type: TemperatureDamage diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml index 74e5c6ce53..9315826b78 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/meat.yml @@ -39,12 +39,11 @@ # let air cook and freeze meat for cooking and preservation - type: AtmosExposed - type: Temperature - currentTemperature: 290 + thermalConductivity: 1 + heatCapacity: 750 - type: TemperatureDamage # required for cooking to work - type: InternalTemperature - thickness: 0.02 - area: 0.02 # arbitrary number that sounds right for a slab of meat - type: Material - type: PhysicalComposition materialComposition: @@ -83,8 +82,6 @@ refineResult: - id: FoodMeatCutlet amount: 5 - - type: InternalTemperature - conductivity: 0.43 - type: Construction graph: MeatSteak node: start @@ -178,10 +175,6 @@ Quantity: 6 - ReagentId: Fat Quantity: 9 - - type: InternalTemperature - conductivity: 0.44 - thickness: 0.004 # bacon is thin so faster to cook than a steak - area: 0.0075 # ~5x15cm - type: Construction graph: Bacon node: start @@ -256,8 +249,6 @@ refineResult: - id: FoodMeatChickenCutlet amount: 5 - - type: InternalTemperature - conductivity: 0.41 - type: Construction graph: ChickenSteak node: start @@ -352,8 +343,6 @@ components: - type: Sprite state: goliath - - type: InternalTemperature - thickness: 0.1 # very big, do cook it in lava - type: Construction graph: GoliathSteak node: start @@ -781,8 +770,6 @@ - Meat - type: Sprite state: raw_patty - - type: InternalTemperature - conductivity: 0.43 - type: Construction graph: CookedPatty node: start @@ -851,8 +838,6 @@ refineResult: - id: FoodMeatCutlet amount: 16 - - type: InternalTemperature - conductivity: 0.43 - type: Construction graph: AnomalyMeatSteak node: start diff --git a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml index fd34bdf42b..82daefcb99 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/ice_crust.yml @@ -46,11 +46,14 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - type: Temperature + temperature: 250 + heatCapacity: 13440.002 - type: TemperatureDamage heatDamage: types: Heat: 5 coldDamage: {} + heatDamageThreshold: 273.15 coldDamageThreshold: 0 - type: FrictionContacts - type: TileFrictionModifier diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml index b49a5b5238..eb98dcd15b 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml @@ -17,6 +17,19 @@ id: Kudzu - type: SpeedModifierContacts affectAirborne: true + - type: Fixtures + fixtures: + fix1: + hard: false + density: 7 + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + layer: + - MidImpassable + - type: Temperature + temperature: 293.15 + heatCapacity: 21000 - type: entity parent: [ BaseKudzu, SolutionFood ] @@ -35,16 +48,6 @@ drawdepth: Overdoors - type: KudzuVisuals - type: Clickable - - type: Fixtures - fixtures: - fix1: - hard: false - density: 7 - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - layer: - - MidImpassable - type: Damageable damageModifierSet: Wood - type: Injurable @@ -56,7 +59,6 @@ behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Temperature - type: TemperatureDamage heatDamage: types: @@ -197,16 +199,6 @@ drawdepth: Overdoors - type: KudzuVisuals - type: Clickable - - type: Fixtures - fixtures: - fix1: - hard: false - density: 7 - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - layer: - - MidImpassable - type: Damageable - type: Injurable - type: Destructible @@ -235,6 +227,17 @@ Heat: -1.0 Cold: -1.0 Blunt: -0.5 # Needs to be balanced (approx 3x) with vacuum damage to stall but not kill Kudzu + - type: TemperatureDamage + heatDamage: + types: + Heat: 10 + coldDamage: + types: + Cold: 5 #per second, scales with temperature & other constants + - type: Barotrauma + damage: + types: + Blunt: 0.10 #per second, scales with pressure and other constants. - type: Flammable fireSpread: true damage: diff --git a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml index f6a63b0e5b..fdbeaa8dbb 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml @@ -87,12 +87,11 @@ defaultTarget: cooked spaceshroom - type: AtmosExposed - type: Temperature - currentTemperature: 290 + thermalConductivity: 1 + temperature: 293.15 + heatCapacity: 750 - type: TemperatureDamage - type: InternalTemperature - thickness: 0.02 - area: 0.02 - conductivity: 0.43 - type: Tag tags: - Mushroom diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml index ad6c09834d..9091f36401 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml @@ -108,7 +108,7 @@ - type: Climbable # so that ejected bodies don't get stuck vaultable: false - type: ContainerTemperature - coldDamageThreshold: 10 + coldDamageThreshold: 213 - type: GuideHelp guides: - Cryogenics diff --git a/Resources/Prototypes/Entities/Structures/spider_web.yml b/Resources/Prototypes/Entities/Structures/spider_web.yml index 6a223e9179..50dba8e2ee 100644 --- a/Resources/Prototypes/Entities/Structures/spider_web.yml +++ b/Resources/Prototypes/Entities/Structures/spider_web.yml @@ -24,13 +24,6 @@ - type: Damageable damageModifierSet: Wood - type: Injurable - - type: Temperature - - type: TemperatureDamage - heatDamage: - types: - Heat: 5 - coldDamage: {} - coldDamageThreshold: 0 - type: Flammable fireSpread: true damage: diff --git a/Resources/Prototypes/Reagents/medicine.yml b/Resources/Prototypes/Reagents/medicine.yml index a38be9e4cb..b0542174b3 100644 --- a/Resources/Prototypes/Reagents/medicine.yml +++ b/Resources/Prototypes/Reagents/medicine.yml @@ -188,17 +188,19 @@ metabolisms: Bloodstream: effects: - - !type:EvenHealthChange - conditions: - - !type:TemperatureCondition - # this is a little arbitrary but they gotta be pretty cold - max: 213.0 - damage: - # todo scale with temp like SS13 - Airloss: -3 - Brute: -2 - Burn: -2 - Toxin: -2 + - !type:AdjustTemperature + amount: 80000 # Heats you up as it metabolizes necessitating constant cooling. + - !type:EvenHealthChange + conditions: + - !type:TemperatureCondition + # taken from tg, must be below freezing. + max: 273.15 + damage: + # todo scale with temp like SS13 + Airloss: -3 + Brute: -2 + Burn: -2 + Toxin: -2 - type: reagent id: Doxarubixadone @@ -214,7 +216,7 @@ - !type:HealthChange conditions: - !type:TemperatureCondition - max: 213.0 + max: 273.15 damage: types: Cellular: -2 @@ -520,12 +522,12 @@ conditions: - !type:TemperatureCondition max: 293.15 - amount: 100000 # thermal energy, not temperature! + amount: 1000000 # thermal energy, not temperature! - !type:AdjustTemperature conditions: - !type:TemperatureCondition min: 293.15 - amount: -10000 + amount: -1000000 - !type:PopupMessage type: Local visualType: Medium @@ -1327,10 +1329,12 @@ metabolisms: Bloodstream: effects: + - !type:AdjustTemperature + amount: 80000 # Heats you up as it metabolizes necessitating constant cooling. - !type:EvenHealthChange conditions: - !type:TemperatureCondition - max: 213.0 + max: 273.15 damage: Brute: -3 Burn: -3 From c73fc00e8a6a758a08722151c90cd6425d21d6da Mon Sep 17 00:00:00 2001 From: Schuyler Duryee Date: Sun, 26 Jul 2026 01:13:45 -0700 Subject: [PATCH 08/35] Fix default metamorphic glasses (e.g. milk) solution not showing (#44917) * add check to set fill sprite to visible for default metamorphic glasses * edit comment for clarity --- .../Chemistry/Visualizers/SolutionContainerVisualsSystem.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Content.Client/Chemistry/Visualizers/SolutionContainerVisualsSystem.cs b/Content.Client/Chemistry/Visualizers/SolutionContainerVisualsSystem.cs index 7d2874bd11..7b39ad514b 100644 --- a/Content.Client/Chemistry/Visualizers/SolutionContainerVisualsSystem.cs +++ b/Content.Client/Chemistry/Visualizers/SolutionContainerVisualsSystem.cs @@ -80,6 +80,10 @@ public sealed partial class SolutionContainerVisualsSystem : VisualizerSystem Date: Sun, 26 Jul 2026 11:43:23 +0300 Subject: [PATCH 09/35] Prediction + small Cleanup: WaggingSystem (#44867) * Predict * Update Content.Shared/Wagging/WaggingSystem.cs Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com> * refactor: fix xml-doc * refactor: remove excessive dirty --------- Co-authored-by: Pok <113675512+Pok27@users.noreply.github.com> Co-authored-by: Fildrance --- Content.Shared/Wagging/WaggingComponent.cs | 32 ++++++--- .../Wagging/WaggingSystem.cs | 69 ++++++++++++------- 2 files changed, 68 insertions(+), 33 deletions(-) rename {Content.Server => Content.Shared}/Wagging/WaggingSystem.cs (66%) diff --git a/Content.Shared/Wagging/WaggingComponent.cs b/Content.Shared/Wagging/WaggingComponent.cs index 4173cb5173..c96884a265 100644 --- a/Content.Shared/Wagging/WaggingComponent.cs +++ b/Content.Shared/Wagging/WaggingComponent.cs @@ -1,38 +1,50 @@ using Content.Shared.Body; -using Content.Shared.Chat.Prototypes; using Content.Shared.Humanoid; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; namespace Content.Shared.Wagging; /// /// An emoting wag for markings. /// -[RegisterComponent, NetworkedComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(fieldDeltas: true)] +[Access(typeof(WaggingSystem))] public sealed partial class WaggingComponent : Component { - [DataField] + /// + /// The prototype id of the wagging action. + /// + [DataField, AutoNetworkedField] public EntProtoId Action = "ActionToggleWagging"; - [DataField] + /// + /// Reference to the action entity. + /// + [DataField, AutoNetworkedField] public EntityUid? ActionEntity; - [DataField] + /// + /// The visual layer of the tail marking. + /// + [DataField, AutoNetworkedField] public HumanoidVisualLayers Layer = HumanoidVisualLayers.Tail; - [DataField] + /// + /// The organ category to which the tail is attached. + /// + [DataField, AutoNetworkedField] public ProtoId Organ = "Torso"; /// - /// Suffix to add to get the animated marking. + /// The suffix to add to get the animated marking. /// + [DataField, AutoNetworkedField] public string Suffix = "Animated"; /// - /// Is the entity currently wagging. + /// Whether the entity is currently wagging. /// - [DataField] + [DataField, AutoNetworkedField] public bool Wagging = false; } diff --git a/Content.Server/Wagging/WaggingSystem.cs b/Content.Shared/Wagging/WaggingSystem.cs similarity index 66% rename from Content.Server/Wagging/WaggingSystem.cs rename to Content.Shared/Wagging/WaggingSystem.cs index 8aa401e571..7b227bedf7 100644 --- a/Content.Server/Wagging/WaggingSystem.cs +++ b/Content.Shared/Wagging/WaggingSystem.cs @@ -1,34 +1,26 @@ -using Content.Server.Actions; +using Content.Shared.Actions; using Content.Shared.Body; using Content.Shared.Cloning.Events; using Content.Shared.Humanoid.Markings; using Content.Shared.Mobs; using Content.Shared.Toggleable; -using Content.Shared.Wagging; -using Robust.Shared.Prototypes; +using JetBrains.Annotations; using Robust.Shared.Utility; -namespace Content.Server.Wagging; +namespace Content.Shared.Wagging; /// -/// Adds an action to toggle wagging animation for tails markings that supporting this +/// Adds an action to toggle the wagging animation for tails markings that support it. /// public sealed partial class WaggingSystem : EntitySystem { - [Dependency] private ActionsSystem _actions = default!; + [Dependency] private SharedActionsSystem _actions = default!; [Dependency] private SharedVisualBodySystem _visualBody = default!; - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnWaggingMapInit); - SubscribeLocalEvent(OnWaggingShutdown); - SubscribeLocalEvent(OnWaggingToggle); - SubscribeLocalEvent(OnMobStateChanged); - SubscribeLocalEvent(OnCloning); - } - + /// + /// Copies the component and its values to the clone. + /// + [SubscribeLocalEvent] private void OnCloning(Entity ent, ref CloningEvent args) { if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name)) @@ -43,35 +35,64 @@ public sealed partial class WaggingSystem : EntitySystem AddComp(args.CloneUid, cloneComp, true); } + /// + /// Adds the wagging action during initialization. + /// + [SubscribeLocalEvent] private void OnWaggingMapInit(Entity ent, ref MapInitEvent args) { _actions.AddAction(ent, ref ent.Comp.ActionEntity, ent.Comp.Action, ent); + DirtyField(ent.AsNullable(), nameof(WaggingComponent.ActionEntity)); } + /// + /// Removes the wagging action during shutdown. + /// + [SubscribeLocalEvent] private void OnWaggingShutdown(Entity ent, ref ComponentShutdown args) { _actions.RemoveAction(ent.Owner, ent.Comp.ActionEntity); } + /// + /// Attempts to toggle the wagging action. + /// + [SubscribeLocalEvent] private void OnWaggingToggle(Entity ent, ref ToggleActionEvent args) { if (args.Handled) return; - TryToggleWagging(ent.AsNullable()); + if (!TryToggleWagging(ent.AsNullable())) + return; + + args.Handled = true; } + /// + /// Tries to disable wagging when the mob state changes. + /// + [SubscribeLocalEvent] private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) { - if (ent.Comp.Wagging) - TryToggleWagging(ent.AsNullable()); + TryToggleWagging(ent.AsNullable(), false); } - private bool TryToggleWagging(Entity ent) + /// + /// If provided - attempts to set wagging to it, otherwise tries to toggle wagging. + /// + /// The entity to toggle. + /// The desired wagging state. + /// Whether wagging was toggled. + [PublicAPI] + public bool TryToggleWagging(Entity ent, bool? desired = null) { if (!Resolve(ent, ref ent.Comp)) return false; + if (desired == ent.Comp.Wagging) + return false; + if (!_visualBody.TryGatherMarkingsData(ent.Owner, [ent.Comp.Layer], out _, @@ -85,14 +106,15 @@ public sealed partial class WaggingSystem : EntitySystem return false; ent.Comp.Wagging = !ent.Comp.Wagging; + DirtyField(ent, nameof(WaggingComponent.Wagging)); markingsSet = markingsSet.ShallowClone(); - foreach (var (layers, markings) in markingsSet) + foreach (var (layers, _) in markingsSet) { markingsSet[layers] = markingsSet[layers].ShallowClone(); var layerMarkings = markingsSet[layers]; - for (int i = 0; i < layerMarkings.Count; i++) + for (var i = 0; i < layerMarkings.Count; i++) { var currentMarkingId = layerMarkings[i].MarkingId; string newMarkingId; @@ -128,6 +150,7 @@ public sealed partial class WaggingSystem : EntitySystem { [ent.Comp.Organ] = markingsSet }); + return true; } } From 63c90e4d4e331c53dee76de20c205b33269888dd Mon Sep 17 00:00:00 2001 From: pathetic meowmeow Date: Sun, 26 Jul 2026 05:20:50 -0400 Subject: [PATCH 10/35] Organ relations (#44812) * Organ relations * address reviews --- .../Tests/Body/DetachableOrganSystemTest.cs | 111 +++++++++++ .../Tests/Body/InitialBodySpawnTest.cs | 67 +++++++ .../Tests/Body/InitialBodyValidationTest.cs | 179 ++++++++++++++++++ .../Tests/Body/OrganRelationSystemTest.cs | 93 +++++++++ .../Tests/Sprite/ItemSpriteTest.cs | 3 +- Content.Server/Body/BodyCommand.cs | 42 ++++ Content.Server/Body/OrganCommand.cs | 112 +++++++++++ Content.Shared/Body/ChildOrganComponent.cs | 17 ++ .../Body/DetachableOrganComponent.cs | 18 ++ Content.Shared/Body/DetachableOrganSystem.cs | 52 +++++ Content.Shared/Body/InitialBodyComponent.cs | 6 + Content.Shared/Body/InitialBodySystem.cs | 25 ++- .../Body/InternalChildOrganComponent.cs | 9 + Content.Shared/Body/OrganRelationSystem.cs | 120 ++++++++++++ Content.Shared/Body/ParentOrganComponent.cs | 17 ++ Resources/Locale/en-US/body/commands.ftl | 23 +++ Resources/Prototypes/Body/base_organs.yml | 109 +++++++++-- Resources/Prototypes/Body/detached.yml | 15 ++ .../Prototypes/Body/species_appearance.yml | 8 + 19 files changed, 1004 insertions(+), 22 deletions(-) create mode 100644 Content.IntegrationTests/Tests/Body/DetachableOrganSystemTest.cs create mode 100644 Content.IntegrationTests/Tests/Body/InitialBodySpawnTest.cs create mode 100644 Content.IntegrationTests/Tests/Body/InitialBodyValidationTest.cs create mode 100644 Content.IntegrationTests/Tests/Body/OrganRelationSystemTest.cs create mode 100644 Content.Server/Body/BodyCommand.cs create mode 100644 Content.Server/Body/OrganCommand.cs create mode 100644 Content.Shared/Body/ChildOrganComponent.cs create mode 100644 Content.Shared/Body/DetachableOrganComponent.cs create mode 100644 Content.Shared/Body/DetachableOrganSystem.cs create mode 100644 Content.Shared/Body/InternalChildOrganComponent.cs create mode 100644 Content.Shared/Body/OrganRelationSystem.cs create mode 100644 Content.Shared/Body/ParentOrganComponent.cs create mode 100644 Resources/Locale/en-US/body/commands.ftl create mode 100644 Resources/Prototypes/Body/detached.yml diff --git a/Content.IntegrationTests/Tests/Body/DetachableOrganSystemTest.cs b/Content.IntegrationTests/Tests/Body/DetachableOrganSystemTest.cs new file mode 100644 index 0000000000..67d210ccf8 --- /dev/null +++ b/Content.IntegrationTests/Tests/Body/DetachableOrganSystemTest.cs @@ -0,0 +1,111 @@ +using System.Linq; +using Content.IntegrationTests.Fixtures; +using Content.IntegrationTests.Fixtures.Attributes; +using Content.Shared.Body; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; + +namespace Content.IntegrationTests.Tests.Body; + +[TestFixture] +[TestOf(typeof(DetachableOrganSystem))] +public sealed class DetachableOrganSystemTest : GameTest +{ + private const string DetachTestOldBody = "DetachTestOldBody"; + private const string DetachTestNewBody = "DetachTestNewBody"; + private const string DetachTestGrandParentOrgan = "DetachTestGrandParentOrgan"; + private const string DetachTestRootOrgan = "DetachTestRootOrgan"; + private const string DetachTestChildOrgan = "DetachTestChildOrgan"; + private const string DetachTestSiblingOrgan = "DetachTestSiblingOrgan"; + + [TestPrototypes] + private const string Prototypes = $@" +- type: entity + id: {DetachTestOldBody} + components: + - type: Body + +- type: entity + id: {DetachTestNewBody} + components: + - type: Body + +- type: entity + id: {DetachTestGrandParentOrgan} + components: + - type: Organ + - type: ParentOrgan + - type: ChildOrgan + +- type: entity + id: {DetachTestRootOrgan} + components: + - type: Organ + - type: ParentOrgan + - type: ChildOrgan + - type: DetachableOrgan + detachedBody: DetachTestNewBody + +- type: entity + id: {DetachTestChildOrgan} + components: + - type: Organ + - type: ChildOrgan + +- type: entity + id: {DetachTestSiblingOrgan} + components: + - type: Organ + - type: ChildOrgan +"; + + [SidedDependency(Side.Server)] private SharedContainerSystem _container = default!; + [SidedDependency(Side.Server)] private OrganRelationSystem _organRelation = default!; + [SidedDependency(Side.Server)] private DetachableOrganSystem _detachableOrgan = default!; + + [Test] + [RunOnSide(Side.Server)] + public void Detach() + { + var oldBody = SSpawn(DetachTestOldBody); + var oldBodyContainer = _container.GetContainer(oldBody, BodyComponent.ContainerID); + + var grandParent = SSpawn(DetachTestGrandParentOrgan); + var root = SSpawn(DetachTestRootOrgan); + var child = SSpawn(DetachTestChildOrgan); + var sibling = SSpawn(DetachTestSiblingOrgan); + + _container.Insert(grandParent, oldBodyContainer, force: true); + _container.Insert(root, oldBodyContainer, force: true); + _container.Insert(child, oldBodyContainer, force: true); + _container.Insert(sibling, oldBodyContainer, force: true); + + _organRelation.Relate(grandParent, root); + _organRelation.Relate(grandParent, sibling); + _organRelation.Relate(root, child); + + var newBody = _detachableOrgan.Detach(root); + + Assert.That(newBody, Is.Not.Null); + + var newBodyContained = _container.GetContainer(newBody!.Value, BodyComponent.ContainerID).ContainedEntities.ToList(); + Assert.That(newBodyContained, Is.EquivalentTo(new[] { root, child })); + + var oldBodyContained = oldBodyContainer.ContainedEntities.ToList(); + Assert.That(oldBodyContained, Is.EquivalentTo(new[] { grandParent, sibling })); + + var grandParentComp = SComp(grandParent); + Assert.That(grandParentComp.Children, Does.Not.Contain(root)); + Assert.That(grandParentComp.Children, Does.Contain(sibling)); + + Assert.That(SComp(root).Parent, Is.Null); + Assert.That(SComp(root).Children, Does.Contain(child)); + Assert.That(SComp(child).Parent, Is.EqualTo(root)); + + Assert.That(SComp(root).Body, Is.EqualTo(newBody)); + Assert.That(SComp(child).Body, Is.EqualTo(newBody)); + Assert.That(SComp(grandParent).Body, Is.EqualTo(oldBody)); + Assert.That(SComp(sibling).Body, Is.EqualTo(oldBody)); + } +} diff --git a/Content.IntegrationTests/Tests/Body/InitialBodySpawnTest.cs b/Content.IntegrationTests/Tests/Body/InitialBodySpawnTest.cs new file mode 100644 index 0000000000..8b1b855125 --- /dev/null +++ b/Content.IntegrationTests/Tests/Body/InitialBodySpawnTest.cs @@ -0,0 +1,67 @@ +using System.Linq; +using Content.IntegrationTests.Fixtures; +using Content.IntegrationTests.Fixtures.Attributes; +using Content.Shared.Body; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; + +namespace Content.IntegrationTests.Tests.Body; + +[TestFixture] +[TestOf(typeof(InitialBodySystem))] +public sealed class InitialBodySpawnTest : GameTest +{ + [TestPrototypes] + private const string Prototypes = @" +- type: organCategory + id: InitialBodySpawnTestParent + +- type: organCategory + id: InitialBodySpawnTestChild + +- type: entity + id: InitialBodySpawnTestBody + components: + - type: Body + - type: InitialBody + organs: + InitialBodySpawnTestParent: InitialBodySpawnTestParentOrgan + InitialBodySpawnTestChild: InitialBodySpawnTestChildOrgan + relationships: + InitialBodySpawnTestParent: [InitialBodySpawnTestChild] + +- type: entity + id: InitialBodySpawnTestParentOrgan + components: + - type: Organ + - type: ParentOrgan + +- type: entity + id: InitialBodySpawnTestChildOrgan + components: + - type: Organ + - type: ChildOrgan +"; + + [SidedDependency(Side.Server)] private SharedContainerSystem _container = default!; + + [Test] + [RunOnSide(Side.Server)] + public void SpawningWiresUpOrganRelations() + { + var body = SSpawn("InitialBodySpawnTestBody"); + + var bodyContainer = _container.GetContainer(body, BodyComponent.ContainerID); + var contained = bodyContainer.ContainedEntities.ToList(); + Assert.That(contained, Has.Count.EqualTo(2)); + + var parent = contained.Single(SEntMan.HasComponent); + var child = contained.Single(SEntMan.HasComponent); + + var parentComp = SComp(parent); + var childComp = SComp(child); + + Assert.That(parentComp.Children, Does.Contain(child)); + Assert.That(childComp.Parent, Is.EqualTo(parent)); + } +} diff --git a/Content.IntegrationTests/Tests/Body/InitialBodyValidationTest.cs b/Content.IntegrationTests/Tests/Body/InitialBodyValidationTest.cs new file mode 100644 index 0000000000..851964e422 --- /dev/null +++ b/Content.IntegrationTests/Tests/Body/InitialBodyValidationTest.cs @@ -0,0 +1,179 @@ +using System.Collections.Generic; +using System.Linq; +using Content.IntegrationTests.Fixtures; +using Content.IntegrationTests.Fixtures.Attributes; +using Content.Shared.Body; +using Robust.Shared.GameObjects; +using Robust.Shared.Prototypes; + +namespace Content.IntegrationTests.Tests.Body; + +[TestFixture] +[TestOf(typeof(InitialBodySystem))] +public sealed class InitialBodyValidationTest : GameTest +{ + [SidedDependency(Side.Server)] private IComponentFactory _componentFactory = default!; + [SidedDependency(Side.Server)] private IPrototypeManager _prototype = default!; + + [Test] + [RunOnSide(Side.Server)] + public void RelatedOrgansCanBeRelated() + { + using var scope = Assert.EnterMultipleScope(); + + foreach (var proto in _prototype.EnumeratePrototypes()) + { + if (proto.Abstract || Pair.IsTestEntityPrototype(proto.ID)) + continue; + + if (!proto.TryComp(out var initial, _componentFactory)) + continue; + + if (initial.Relationships is not { } relationships) + continue; + + var organs = initial.Organs; + foreach (var (parent, children) in relationships) + { + if (!organs.TryGetValue(parent, out var parentProtoId)) + continue; + + var parentProto = _prototype.Index(parentProtoId); + if (!parentProto.HasComp(_componentFactory)) + { + Assert.Fail($"{proto.ID}'s parent organ {parent} {parentProtoId} is missing {nameof(ParentOrganComponent)}"); + } + + foreach (var child in children) + { + if (!organs.TryGetValue(child, out var childProtoId)) + continue; + + var childProto = _prototype.Index(childProtoId); + if (!childProto.HasComp(_componentFactory)) + { + Assert.Fail($"{proto.ID}'s child organ {child} {childProtoId} (child of {parent} {parentProtoId}) is missing {nameof(ChildOrganComponent)}"); + } + } + } + } + } + + [Test] + [RunOnSide(Side.Server)] + public void NoMultipleParents() + { + using var scope = Assert.EnterMultipleScope(); + + foreach (var proto in _prototype.EnumeratePrototypes()) + { + if (proto.Abstract || Pair.IsTestEntityPrototype(proto.ID)) + continue; + + if (!proto.TryComp(out var initial, _componentFactory)) + continue; + + if (initial.Relationships is not { } relationships) + continue; + + var parentOf = new Dictionary, ProtoId>(); + foreach (var (parent, children) in relationships) + { + foreach (var child in children) + { + if (parentOf.TryGetValue(child, out var existingParent)) + { + Assert.Fail($"{proto.ID}'s organ category {child} is claimed as a child by both {existingParent} and {parent}"); + } + + parentOf[child] = parent; + } + } + } + } + + [Test] + [RunOnSide(Side.Server)] + public void InternalChildOrgansAreNotDetachable() + { + using var scope = Assert.EnterMultipleScope(); + + foreach (var proto in _prototype.EnumeratePrototypes()) + { + if (proto.Abstract || Pair.IsTestEntityPrototype(proto.ID)) + continue; + + if (!proto.HasComp(_componentFactory)) + continue; + + if (proto.HasComp(_componentFactory)) + { + Assert.Fail($"{proto.ID} has both {nameof(InternalChildOrganComponent)} and {nameof(DetachableOrganComponent)}. Pick a lane, make your organs internal or detachable, but not both."); + } + } + } + + [Test] + [RunOnSide(Side.Server)] + public void NoCyclicalRelationships() + { + using var scope = Assert.EnterMultipleScope(); + + foreach (var proto in _prototype.EnumeratePrototypes()) + { + if (proto.Abstract || Pair.IsTestEntityPrototype(proto.ID)) + continue; + + if (!proto.TryComp(out var initial, _componentFactory)) + continue; + + if (initial.Relationships is not { } relationships) + continue; + + var visited = new HashSet>(); + var stack = new List>(); + + foreach (var parent in relationships.Keys) + { + if (TryFindCycle(parent, relationships, visited, stack, out var cycle)) + { + Assert.Fail($"{proto.ID} has a cycle in its InitialBodyComponent relationships: {string.Join(" -> ", cycle)}"); + } + } + } + } + + private static bool TryFindCycle( + ProtoId node, + Dictionary, HashSet>> relationships, + HashSet> visited, + List> stack, + out List> cycle) + { + if (stack.Contains(node)) + { + var start = stack.IndexOf(node); + cycle = stack.Skip(start).Append(node).ToList(); + return true; + } + + cycle = new List>(); + + if (!visited.Add(node)) + return false; + + if (!relationships.TryGetValue(node, out var children)) + return false; + + stack.Add(node); + + foreach (var child in children) + { + if (TryFindCycle(child, relationships, visited, stack, out cycle)) + return true; + } + + stack.RemoveAt(stack.Count - 1); + return false; + } +} diff --git a/Content.IntegrationTests/Tests/Body/OrganRelationSystemTest.cs b/Content.IntegrationTests/Tests/Body/OrganRelationSystemTest.cs new file mode 100644 index 0000000000..ee012f9815 --- /dev/null +++ b/Content.IntegrationTests/Tests/Body/OrganRelationSystemTest.cs @@ -0,0 +1,93 @@ +using System.Linq; +using Content.IntegrationTests.Fixtures; +using Content.IntegrationTests.Fixtures.Attributes; +using Content.Shared.Body; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; + +namespace Content.IntegrationTests.Tests.Body; + +[TestFixture] +[TestOf(typeof(OrganRelationSystem))] +public sealed class OrganRelationSystemTest : GameTest +{ + [TestPrototypes] + private const string Prototypes = @" +- type: entity + id: OrganRelationTestOrgan + components: + - type: Organ + - type: ParentOrgan + - type: ChildOrgan +"; + + [SidedDependency(Side.Server)] private OrganRelationSystem _organRelation = default!; + + [Test] + [RunOnSide(Side.Server)] + public void RelateAndOrphan() + { + var parent = SSpawn("OrganRelationTestOrgan"); + var child = SSpawn("OrganRelationTestOrgan"); + + _organRelation.Relate(parent, child); + + var parentComp = SComp(parent); + var childComp = SComp(child); + + Assert.That(parentComp.Children, Does.Contain(child)); + Assert.That(childComp.Parent, Is.EqualTo(parent)); + + _organRelation.Orphan(child); + + Assert.That(parentComp.Children, Does.Not.Contain(child)); + Assert.That(childComp.Parent, Is.Null); + } + + [Test] + [RunOnSide(Side.Server)] + public void Traversal() + { + var grandParent = SSpawn("OrganRelationTestOrgan"); + var parent = SSpawn("OrganRelationTestOrgan"); + var child = SSpawn("OrganRelationTestOrgan"); + + _organRelation.Relate(grandParent, parent); + _organRelation.Relate(parent, child); + + var allChildren = _organRelation.AllChildren(grandParent).Select(e => e.Owner).ToList(); + Assert.That(allChildren, Is.EquivalentTo(new[] { parent, child })); + + var allParents = _organRelation.AllParents(child).Select(e => e.Owner).ToList(); + Assert.That(allParents, Is.EquivalentTo(new[] { parent, grandParent })); + } + + [Test] + [RunOnSide(Side.Server)] + public void ParentDeletion() + { + var parent = SSpawn("OrganRelationTestOrgan"); + var child = SSpawn("OrganRelationTestOrgan"); + + _organRelation.Relate(parent, child); + + SDeleteNow(parent); + + Assert.That(SEntMan.Deleted(child), Is.False); + Assert.That(SComp(child).Parent, Is.Null); + } + + [Test] + [RunOnSide(Side.Server)] + public void ChildDeletion() + { + var parent = SSpawn("OrganRelationTestOrgan"); + var child = SSpawn("OrganRelationTestOrgan"); + + _organRelation.Relate(parent, child); + + SDeleteNow(child); + + Assert.That(SComp(parent).Children, Does.Not.Contain(child)); + } +} diff --git a/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs b/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs index ca667f2e7a..4c2f0be60e 100644 --- a/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs +++ b/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs @@ -29,7 +29,8 @@ public sealed class PrototypeSaveTest : GameTest { // The only prototypes that should get ignored are those that REQUIRE setup to get a sprite. At that point it is // the responsibility of the spawner to ensure that a valid sprite is set. - "VirtualItem" + "VirtualItem", + "DetachedBody" }; [Test] diff --git a/Content.Server/Body/BodyCommand.cs b/Content.Server/Body/BodyCommand.cs new file mode 100644 index 0000000000..6e9fe5b838 --- /dev/null +++ b/Content.Server/Body/BodyCommand.cs @@ -0,0 +1,42 @@ +using System.Linq; +using Content.Server.Administration; +using Content.Shared.Administration; +using Content.Shared.Body; +using Robust.Shared.Containers; +using Robust.Shared.Toolshed; + +namespace Content.Server.Body; + +[ToolshedCommand, AdminCommand(AdminFlags.Debug)] +public sealed class BodyCommand : ToolshedCommand +{ + private SharedContainerSystem? _container; + + [CommandImplementation("insert")] + public void Insert([PipedArgument] EntityUid body, EntityUid organ) + { + _container ??= GetSys(); + + if (!_container.TryGetContainer(body, BodyComponent.ContainerID, out var container)) + return; + + _container.Insert(organ, container, force: true); + } + + [CommandImplementation("organs")] + public IEnumerable Organs([PipedArgument] EntityUid body) + { + _container ??= GetSys(); + + if (!_container.TryGetContainer(body, BodyComponent.ContainerID, out var container)) + return Enumerable.Empty(); + + return container.ContainedEntities.ToList(); + } + + [CommandImplementation("organs")] + public IEnumerable Organs([PipedArgument] IEnumerable body) + { + return body.SelectMany(Organs); + } +} diff --git a/Content.Server/Body/OrganCommand.cs b/Content.Server/Body/OrganCommand.cs new file mode 100644 index 0000000000..e791783cf6 --- /dev/null +++ b/Content.Server/Body/OrganCommand.cs @@ -0,0 +1,112 @@ +using System.Linq; +using Content.Server.Administration; +using Content.Shared.Administration; +using Content.Shared.Body; +using Robust.Shared.Containers; +using Robust.Shared.Prototypes; +using Robust.Shared.Toolshed; + +namespace Content.Server.Body; + +[ToolshedCommand, AdminCommand(AdminFlags.Debug)] +public sealed class OrganCommand : ToolshedCommand +{ + private DetachableOrganSystem? _detachableOrgan; + private SharedContainerSystem? _container; + private OrganRelationSystem? _organRelation; + + [CommandImplementation("parent")] + public EntityUid? Parent([PipedArgument] EntityUid child) + { + if (!TryComp(child, out var childOrgan)) + return null; + + return childOrgan.Parent; + } + + [CommandImplementation("parent")] + public IEnumerable Parent([PipedArgument] IEnumerable children) + { + return children.Select(Parent); + } + + [CommandImplementation("children")] + public IEnumerable Children([PipedArgument] EntityUid parent) + { + if (!TryComp(parent, out var parentOrgan)) + yield break; + + foreach (var child in parentOrgan.Children) + { + yield return child; + } + } + + [CommandImplementation("children")] + public IEnumerable Children([PipedArgument] IEnumerable parents) + { + return parents.SelectMany(Children); + } + + [CommandImplementation("detach")] + public EntityUid? Detach([PipedArgument] EntityUid organ) + { + _detachableOrgan ??= GetSys(); + return _detachableOrgan.Detach(organ); + } + + [CommandImplementation("detach")] + public IEnumerable Detach([PipedArgument] IEnumerable organs) + { + return organs.Select(Detach); + } + + [CommandImplementation("attach")] + public void Attach([PipedArgument] EntityUid parent, EntityUid child) + { + _container ??= GetSys(); + _organRelation ??= GetSys(); + + if (!TryComp(parent, out var parentOrgan) || + !TryComp(child, out var childOrgan) || + !TryComp(parent, out var parentOrganComponent) || + parentOrganComponent.Body is not { } body) + return; + + if (!_container.TryGetContainer(body, BodyComponent.ContainerID, out var container)) + return; + + _container.Insert(child, container, force: true); + _organRelation.Relate((parent, parentOrgan), (child, childOrgan)); + } + + [CommandImplementation("attach")] + public void Attach([PipedArgument] IEnumerable parents, EntityUid child) + { + foreach (var parent in parents) + { + Attach(parent, child); + } + } + + [CommandImplementation("is")] + public bool Is([PipedArgument] EntityUid organ, ProtoId category) + { + if (!TryComp(organ, out var organComp)) + return false; + + return organComp.Category == category; + } + + [CommandImplementation("is")] + public IEnumerable Is([PipedArgument] IEnumerable organs, ProtoId category) + { + return organs.Select(it => Is(it, category)); + } + + [CommandImplementation("of_type")] + public IEnumerable Typed([PipedArgument] IEnumerable organs, ProtoId category) + { + return organs.Where(it => Is(it, category)); + } +} diff --git a/Content.Shared/Body/ChildOrganComponent.cs b/Content.Shared/Body/ChildOrganComponent.cs new file mode 100644 index 0000000000..815f8d3423 --- /dev/null +++ b/Content.Shared/Body/ChildOrganComponent.cs @@ -0,0 +1,17 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Body; + +/// +/// An organ that can be a child to a parent organ within a body. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(OrganRelationSystem))] +public sealed partial class ChildOrganComponent : Component +{ + /// + /// The current organ that's a parent to this one, if any + /// + [DataField, AutoNetworkedField] + public EntityUid? Parent; +} diff --git a/Content.Shared/Body/DetachableOrganComponent.cs b/Content.Shared/Body/DetachableOrganComponent.cs new file mode 100644 index 0000000000..9cd0af4115 --- /dev/null +++ b/Content.Shared/Body/DetachableOrganComponent.cs @@ -0,0 +1,18 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Body; + +/// +/// An organ that can be detached with all of its children into a new body +/// +[RegisterComponent, NetworkedComponent] +[Access(typeof(DetachableOrganSystem))] +public sealed partial class DetachableOrganComponent : Component +{ + /// + /// The body to spawn upon detaching + /// + [DataField(required: true)] + public EntProtoId DetachedBody; +} diff --git a/Content.Shared/Body/DetachableOrganSystem.cs b/Content.Shared/Body/DetachableOrganSystem.cs new file mode 100644 index 0000000000..ce1d720acc --- /dev/null +++ b/Content.Shared/Body/DetachableOrganSystem.cs @@ -0,0 +1,52 @@ +using Content.Shared.Body; +using JetBrains.Annotations; +using Robust.Shared.Containers; +using Robust.Shared.Network; + +namespace Content.Shared.Body; + +public sealed partial class DetachableOrganSystem : EntitySystem +{ + [Dependency] private EntityQuery _detachableOrgan; + [Dependency] private EntityQuery _organ; + [Dependency] private OrganRelationSystem _organRelation = default!; + [Dependency] private SharedContainerSystem _container = default!; + + /// + /// Detaches an organ from its containing body. + /// + /// The organ to detach + /// The body that spawned when this organ was detached + [PublicAPI] + public EntityUid? Detach(Entity organ) + { + if (!_detachableOrgan.Resolve(organ, ref organ.Comp) || !_organ.TryComp(organ, out var organComp) || organComp.Body is not { } oldBody) + return null; + + _organRelation.Orphan(organ.Owner); + var body = PredictedSpawnNextToOrDrop(organ.Comp.DetachedBody, oldBody); + + if (!_container.TryGetContainer(body, BodyComponent.ContainerID, out var container)) + { + Log.Error($"Entity {ToPrettyString(body)} relied on by {nameof(DetachableOrganComponent)} on {ToPrettyString(organ)} is missing a container ({BodyComponent.ContainerID})."); + Del(body); + return null; + } + + if (!_container.Insert(organ.Owner, container, force: true)) + { + Log.Error($"{ToPrettyString(organ)} could not be transferred to new body {ToPrettyString(body)}."); + } + + foreach (var child in _organRelation.AllChildren(organ.Owner)) + { + if (!_container.Insert(child.Owner, container, force: true)) + { + Log.Error($"{ToPrettyString(child)} could not be transferred to new body {ToPrettyString(body)}."); + _organRelation.Orphan(child.AsNullable()); + } + } + + return body; + } +} diff --git a/Content.Shared/Body/InitialBodyComponent.cs b/Content.Shared/Body/InitialBodyComponent.cs index a27e5c092c..70326ea7d4 100644 --- a/Content.Shared/Body/InitialBodyComponent.cs +++ b/Content.Shared/Body/InitialBodyComponent.cs @@ -15,4 +15,10 @@ public sealed partial class InitialBodyComponent : Component /// [DataField(required: true)] public Dictionary, EntProtoId> Organs; + + /// + /// Organ relationships, based on their categories. Keys are parents to their values. + /// + [DataField] + public Dictionary, HashSet>>? Relationships; } diff --git a/Content.Shared/Body/InitialBodySystem.cs b/Content.Shared/Body/InitialBodySystem.cs index 6ac8066e54..5df762e495 100644 --- a/Content.Shared/Body/InitialBodySystem.cs +++ b/Content.Shared/Body/InitialBodySystem.cs @@ -1,12 +1,14 @@ using System.Numerics; using Robust.Shared.Containers; using Robust.Shared.Map; +using Robust.Shared.Prototypes; namespace Content.Shared.Body; public sealed partial class InitialBodySystem : EntitySystem { [Dependency] private SharedContainerSystem _container = default!; + [Dependency] private OrganRelationSystem _organRelation = default!; public override void Initialize() { @@ -31,8 +33,9 @@ public sealed partial class InitialBodySystem : EntitySystem var xform = Transform(ent); var coords = new EntityCoordinates(ent, Vector2.Zero); + var spawned = new Dictionary, EntityUid>(); - foreach (var proto in ent.Comp.Organs.Values) + foreach (var (part, proto) in ent.Comp.Organs) { // TODO: When e#6192 is merged replace this all with TrySpawnInContainer... var spawn = Spawn(proto, coords); @@ -41,6 +44,26 @@ public sealed partial class InitialBodySystem : EntitySystem { Log.Error($"Entity {ToPrettyString(ent)} with a {nameof(InitialBodyComponent)} failed to insert an entity: {ToPrettyString(spawn)}.\n"); Del(spawn); + continue; + } + + spawned[part] = spawn; + } + + if (ent.Comp.Relationships is null) + return; + + foreach (var (partId, parentUid) in spawned) + { + if (!ent.Comp.Relationships.TryGetValue(partId, out var children)) + continue; + + foreach (var childId in children) + { + if (!spawned.TryGetValue(childId, out var childUid)) + continue; + + _organRelation.Relate(parentUid, childUid); } } } diff --git a/Content.Shared/Body/InternalChildOrganComponent.cs b/Content.Shared/Body/InternalChildOrganComponent.cs new file mode 100644 index 0000000000..0f3c9348ef --- /dev/null +++ b/Content.Shared/Body/InternalChildOrganComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Body; + +/// +/// Marker components for child organs that are considered "internal" to their parent. e.g. kidneys are internal to a torso, but an arm isn't. +/// +[RegisterComponent, NetworkedComponent] +public sealed partial class InternalChildOrganComponent : Component; diff --git a/Content.Shared/Body/OrganRelationSystem.cs b/Content.Shared/Body/OrganRelationSystem.cs new file mode 100644 index 0000000000..d5236277e8 --- /dev/null +++ b/Content.Shared/Body/OrganRelationSystem.cs @@ -0,0 +1,120 @@ +using JetBrains.Annotations; +using Robust.Shared.Utility; + +namespace Content.Shared.Body; + +public sealed partial class OrganRelationSystem : EntitySystem +{ + [Dependency] private EntityQuery _child; + [Dependency] private EntityQuery _parent; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnParentShutdown); + SubscribeLocalEvent(OnChildShutdown); + } + + private void OnChildShutdown(Entity ent, ref ComponentShutdown args) + { + if (ent.Comp.Parent is not { } parentUid) + return; + + var parentComp = _parent.Comp(parentUid); + parentComp.Children.Remove(ent); + Dirty(parentUid, parentComp); + } + + private void OnParentShutdown(Entity ent, ref ComponentShutdown args) + { + if (ent.Comp.Children.Count == 0) + return; + + foreach (var childUid in ent.Comp.Children) + { + var childComp = _child.Comp(childUid); + childComp.Parent = null; + + Dirty(childUid, childComp); + } + } + + /// + /// Associates a parent organ and a child organ. + /// + [PublicAPI] + public void Relate(Entity parent, Entity child) + { + if (!_parent.Resolve(parent, ref parent.Comp) || !_child.Resolve(child, ref child.Comp)) + return; + + DebugTools.Assert(child.Comp.Parent == null); + + parent.Comp.Children.Add(child); + Dirty(parent, parent.Comp); + + child.Comp.Parent = parent; + Dirty(child, child.Comp); + } + + /// + /// Breaks the relationship between a child orphan and its parent. + /// + [PublicAPI] + public void Orphan(Entity child) + { + if (!_child.Resolve(child, ref child.Comp)) + return; + + if (child.Comp.Parent is not { } parentUid) + return; + + child.Comp.Parent = null; + Dirty(child, child.Comp); + + var parentComp = _parent.Comp(parentUid); + parentComp.Children.Remove(child); + Dirty(parentUid, parentComp); + } + + /// + /// Enumerates all parents of a child organ recursively. + /// + [PublicAPI] + public IEnumerable> AllParents(Entity child) + { + if (!_child.Resolve(child, ref child.Comp)) + yield break; + + while (child.Comp?.Parent is { } parent) + { + yield return (parent, _parent.Comp(parent)); + + if (!_child.TryGetComponent(parent, out var parentChild)) + yield break; + + child = (parent, parentChild); + } + } + + /// + /// Enumerates all children of a parent organ recursively. + /// + [PublicAPI] + public IEnumerable> AllChildren(Entity parent) + { + if (!_parent.Resolve(parent, ref parent.Comp, false)) + yield break; + + foreach (var child in parent.Comp.Children) + { + yield return (child, _child.Comp(child)); + + foreach (var childChild in AllChildren(child)) + { + yield return childChild; + } + } + } +} diff --git a/Content.Shared/Body/ParentOrganComponent.cs b/Content.Shared/Body/ParentOrganComponent.cs new file mode 100644 index 0000000000..e82fa70574 --- /dev/null +++ b/Content.Shared/Body/ParentOrganComponent.cs @@ -0,0 +1,17 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Body; + +/// +/// An organ that can be a parent to other organs. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(OrganRelationSystem))] +public sealed partial class ParentOrganComponent : Component +{ + /// + /// The current set of child organs parented to this one. + /// + [DataField, AutoNetworkedField] + public HashSet Children = new(); +} diff --git a/Resources/Locale/en-US/body/commands.ftl b/Resources/Locale/en-US/body/commands.ftl new file mode 100644 index 0000000000..e170e7e62a --- /dev/null +++ b/Resources/Locale/en-US/body/commands.ftl @@ -0,0 +1,23 @@ +command-description-body-insert = + Inserts the given organ into the body. + +command-description-body-organs = + Returns all organs contained within the body. + +command-description-organ-parent = + Returns the parent of the organ. + +command-description-organ-children = + Returns the children of the organ. + +command-description-organ-detach = + (DEBUG ONLY) Detaches an organ from its current body into a detached body. + +command-description-organ-attach = + Attaches an organ to another organ. + +command-description-organ-is = + Returns if an organ is the given type. + +command-description-organ-of_type = + Filters to organs of the given type. diff --git a/Resources/Prototypes/Body/base_organs.yml b/Resources/Prototypes/Body/base_organs.yml index f77e83e75a..0db5199615 100644 --- a/Resources/Prototypes/Body/base_organs.yml +++ b/Resources/Prototypes/Body/base_organs.yml @@ -43,7 +43,10 @@ - Meat - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseParent + - OrganBaseChildExternal id: OrganBaseTorso name: torso abstract: true @@ -68,7 +71,10 @@ - Special - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseParent + - OrganBaseChildExternal id: OrganBaseHead name: head abstract: true @@ -95,7 +101,10 @@ - HeadTop - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseParent + - OrganBaseChildExternal id: OrganBaseArmLeft name: left arm abstract: true @@ -114,7 +123,10 @@ - LArm - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseParent + - OrganBaseChildExternal id: OrganBaseArmRight name: right arm abstract: true @@ -133,7 +145,9 @@ - RArm - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildExternal id: OrganBaseHandLeft name: left hand abstract: true @@ -156,7 +170,9 @@ - LHand - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildExternal id: OrganBaseHandRight name: right hand abstract: true @@ -179,7 +195,10 @@ - RHand - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseParent + - OrganBaseChildExternal id: OrganBaseLegLeft name: left leg abstract: true @@ -198,7 +217,10 @@ - LLeg - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseParent + - OrganBaseChildExternal id: OrganBaseLegRight name: right leg abstract: true @@ -217,7 +239,9 @@ - RLeg - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildExternal id: OrganBaseFootLeft name: left foot abstract: true @@ -236,7 +260,9 @@ - LFoot - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildExternal id: OrganBaseFootRight name: right foot abstract: true @@ -255,7 +281,9 @@ - RFoot - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseBrain name: brain abstract: true @@ -288,7 +316,9 @@ Taco: Brain - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseEyes name: eyes abstract: true @@ -311,7 +341,9 @@ - Eyes - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseTongue name: tongue abstract: true @@ -324,7 +356,9 @@ - state: tongue - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseAppendix name: appendix abstract: true @@ -337,7 +371,9 @@ - state: appendix - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseEars name: ears abstract: true @@ -350,7 +386,9 @@ - state: ears - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseLungs name: lungs abstract: true @@ -383,7 +421,9 @@ canReact: false - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseHeart name: heart abstract: true @@ -399,7 +439,9 @@ stages: [ Bloodstream ] - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseStomach name: stomach abstract: true @@ -431,7 +473,9 @@ maxVol: 150 # 1.25 liters which is average for a human - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseLiver name: liver abstract: true @@ -449,7 +493,9 @@ stages: [ Metabolites ] - type: entity - parent: OrganBase + parent: + - OrganBase + - OrganBaseChildInternal id: OrganBaseKidneys name: kidneys abstract: true @@ -498,3 +544,26 @@ sexStateOverrides: Male: torso_m Female: torso_f + +- type: entity + abstract: true + id: OrganBaseParent + components: + - type: ParentOrgan + - type: DetachableOrgan + detachedBody: DetachedBody + +- type: entity + abstract: true + id: OrganBaseChildExternal + components: + - type: ChildOrgan + - type: DetachableOrgan + detachedBody: DetachedBody + +- type: entity + abstract: true + id: OrganBaseChildInternal + components: + - type: ChildOrgan + - type: InternalChildOrgan diff --git a/Resources/Prototypes/Body/detached.yml b/Resources/Prototypes/Body/detached.yml new file mode 100644 index 0000000000..65e370eb8c --- /dev/null +++ b/Resources/Prototypes/Body/detached.yml @@ -0,0 +1,15 @@ +- type: entity + parent: + - BaseSpeciesLayers + id: DetachedBody + save: false + components: + - type: Clickable + - type: Body + - type: VisualBody + - type: ContainerContainer + - type: Appearance + - type: HideableHumanoidLayers + - type: Item + - type: InteractionOutline + - type: InputMover diff --git a/Resources/Prototypes/Body/species_appearance.yml b/Resources/Prototypes/Body/species_appearance.yml index e70b6abb38..574fdbf820 100644 --- a/Resources/Prototypes/Body/species_appearance.yml +++ b/Resources/Prototypes/Body/species_appearance.yml @@ -87,3 +87,11 @@ type: HumanoidMarkingModifierBoundUserInterface enum.StrippingUiKey.Key: type: StrippableBoundUserInterface + - type: InitialBody + relationships: + Torso: [Head, ArmLeft, ArmRight, LegLeft, LegRight, Appendix, Lungs, Heart, Stomach, Liver, Kidneys] + Head: [Brain, Eyes, Tongue, Ears] + ArmLeft: [HandLeft] + ArmRight: [HandRight] + LegLeft: [FootLeft] + LegRight: [FootRight] From ac53efaa78acc88a9375b730ab204f08a87f5060 Mon Sep 17 00:00:00 2001 From: Errant <35878406+Errant-4@users.noreply.github.com> Date: Sun, 26 Jul 2026 15:14:46 +0200 Subject: [PATCH 11/35] [STAGING] Increase afk time limit (#44859) * increase afk time limit * Update Content.Shared/CCVar/CCVars.Misc.cs Co-authored-by: Connor Huffine --------- Co-authored-by: Connor Huffine --- Content.Shared/CCVar/CCVars.Misc.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Shared/CCVar/CCVars.Misc.cs b/Content.Shared/CCVar/CCVars.Misc.cs index a158505ffc..a7d322d8a8 100644 --- a/Content.Shared/CCVar/CCVars.Misc.cs +++ b/Content.Shared/CCVar/CCVars.Misc.cs @@ -35,7 +35,8 @@ public sealed partial class CCVars /// [CVarControl(AdminFlags.VarEdit, min: 0f, max: float.MaxValue)] public static readonly CVarDef AfkTime = - CVarDef.Create("afk.time", 300f, CVar.SERVER | CVar.REPLICATED); + CVarDef.Create("afk.time", 600f, CVar.SERVER | CVar.REPLICATED); + // If afk players become an issue again, implement using a more aggressive time limit when server pop is near full /// /// How long a player has to confirm they are not AFK before being disconnected. From 64ea572638bcdd9ccc86a4aed7dd828bbf77e45d Mon Sep 17 00:00:00 2001 From: 0-Anon Date: Sun, 26 Jul 2026 09:27:51 -0400 Subject: [PATCH 12/35] Update Powercell Reagents to have Lithium and Uranium (#43569) * Update powercells.yml * bugfix pushed a line * adding back parent to see if this unfucks it trying to see what this bug is about * fixed formatting my b * princess_cleanup removing the unnecessary zincs * refactor: added lithium to medium/high cap power cages, removed invalid whitespace --------- Co-authored-by: Fildrance --- .../Entities/Objects/Power/powercells.yml | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Power/powercells.yml b/Resources/Prototypes/Entities/Objects/Power/powercells.yml index f125d087ab..976956c712 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powercells.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powercells.yml @@ -24,8 +24,8 @@ - type: Extractable juiceSolution: reagents: - - ReagentId: Zinc - Quantity: 5 + - ReagentId: Zinc + Quantity: 5 - type: Tag tags: - PowerCell @@ -116,6 +116,11 @@ - type: BatterySelfRecharger autoRechargeRate: 36 # 10 seconds to recharge autoRechargePauseTime: 30 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Uranium + Quantity: 5 - type: entity name: medium-capacity power cell @@ -134,6 +139,11 @@ - type: Battery maxCharge: 720 startingCharge: 720 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Lithium + Quantity: 5 - type: entity id: PowerCellMediumPrinted @@ -169,6 +179,11 @@ - type: Battery maxCharge: 1080 startingCharge: 1080 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Lithium + Quantity: 5 - type: entity id: PowerCellHighPrinted @@ -204,6 +219,11 @@ - type: Battery maxCharge: 1800 startingCharge: 1800 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Lithium + Quantity: 5 - type: entity id: PowerCellHyperPrinted @@ -241,6 +261,11 @@ startingCharge: 720 - type: BatterySelfRecharger autoRechargeRate: 12 # takes 1 minute to charge itself back to full + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Uranium + Quantity: 5 - type: entity parent: PowerCellMicroreactor @@ -276,6 +301,11 @@ startingCharge: 1200 - type: BatterySelfRecharger autoRechargeRate: 40 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Uranium + Quantity: 5 # Power cage (big heavy power cell for big devices) @@ -299,8 +329,8 @@ - type: Extractable juiceSolution: reagents: - - ReagentId: Zinc - Quantity: 15 + - ReagentId: Zinc + Quantity: 15 - type: Tag tags: - PowerCage @@ -354,6 +384,11 @@ - type: Battery maxCharge: 2700 startingCharge: 2700 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Lithium + Quantity: 10 - type: entity id: PowerCageHigh @@ -372,6 +407,11 @@ - type: Battery maxCharge: 6200 startingCharge: 6200 + - type: Extractable + juiceSolution: + reagents: + - ReagentId: Lithium + Quantity: 15 - type: entity id: PowerCageSmallEmpty From 0c5b250f03af78eec743fdb51fd2bba9644f9e21 Mon Sep 17 00:00:00 2001 From: Ataman Date: Sun, 26 Jul 2026 18:50:28 +0200 Subject: [PATCH 13/35] Instrument UI overhaul (#41604) * Added base type for UI panels of MIDI input sources. * Renamed BandMenu into BandMidiSource. * Implemented the UI overhaul, skipping channels dialog functionality for now. * Refactored for conventions and reordered type members. Got rid of SetInstrument/ClearInstrument again. * Decreased background opacity for UnavailableOverlay to improve readability. * Localization * Added text to InputMidiSource so players know what it does. * Changed window MinSize to SetSize. Allows players to reduce window size if desired. * Improved button looks by adding style classes. * cleanup * leftover cleanup * Reverted fetching InstrumentSystem via IoCManager (crashes it, woops). * added filter bar to file list * refactored almost all system/manager interaction into instrument BUI * text changed for instruments-component-menu-input-notice-label * fixed InstrumentBoundUserInterface.Dispose not unsubscribing from everything * minor cleanup * finished configuration menu & cleanup * Comments and fixes for InstrumentMidiSourceBase * Fixed RA0051 * Removed unncecessary null check * Added methods for accessing the selected track. * Limited depth of search for instrument master to prevent deadlock. * Cached system access * Storing midis asynchronously * Actual MIDI data now only loaded before playback. * async removed from InstrumentBoundUserInterface.LoadStoredUserMidis * Replaced GetComponent calls with TryGetComponent * Localized MIDI playback track timer * Searching for next track using raw index now * Fixed CS0168 * XML comments, minor fixes and disabled MIDI library management while a track is playing. * removed timers with simple watchdog and switched to MidiFileCollectionManager * Missed one (timer) * Changed access for MidiFileCollectionManager.UserMidiDirectory field to public. * Added instrument config control for MIDI collection utilities. * redesigned instrument config menu * Removed rename function, updated adding implementation * more redesigns * fixed _isMidiFileDialogueWindowOpen not resetting correctly in certain cases. * file scoped namespaces * replaced EntityUid with Entity * if spaces * returning Tooltip instead of Control * replaced SetEntity with public field * readonly system fields * InstrumentMenu MinSize * xml comment for InstrumentMidiSourceBase * small refactor * more cleanup * TryGetComponent to GetComponent on Open() * more formatting issues * switched to [Dependency] for systems * playback improvements * disable playback button if no file selected and playing * activating shuffle now selects track if none is selected * rearranged playback buttons * channels overhauled * Play/Stop label to Play only * Removed all channel on/off * Program now default channel name display selection * improved RemoveButton.Disable behavior * channels now toggable by clicking anywhere * Shuffle no longer selects already selected track. * Loop & Shuffle no longer both selectable at once * minor improvements to channel item visuals * minor channel toggle fixes * xml docs & code cleanup * `RefreshBandRequest` now sent automatically when band source becomes visible * converted 5 items tuple to MidiChannelInfo record * added markup support to instrument menu configuration header * added note to midi channels config header explaining update behavior. --- .../Audio/Midi/MidiFileCollectionManager.cs | 2 +- Content.Client/Instruments/UI/BandMenu.xaml | 9 - .../Instruments/UI/BandMenu.xaml.cs | 48 -- .../Instruments/UI/BandMidiSource.xaml | 7 + .../Instruments/UI/BandMidiSource.xaml.cs | 59 +++ .../Instruments/UI/ChannelItem.xaml | 19 + .../Instruments/UI/ChannelItem.xaml.cs | 71 +++ .../Instruments/UI/ChannelsControl.xaml | 27 + .../Instruments/UI/ChannelsControl.xaml.cs | 116 +++++ .../Instruments/UI/ChannelsMenu.xaml | 14 - .../Instruments/UI/ChannelsMenu.xaml.cs | 152 ------ .../Instruments/UI/FileMidiSource.xaml | 38 ++ .../Instruments/UI/FileMidiSource.xaml.cs | 463 ++++++++++++++++++ .../Instruments/UI/InputMidiSource.xaml | 6 + .../Instruments/UI/InputMidiSource.xaml.cs | 38 ++ .../UI/InstrumentBoundUserInterface.cs | 387 +++++++++++---- .../Instruments/UI/InstrumentMenu.xaml | 61 +-- .../Instruments/UI/InstrumentMenu.xaml.cs | 379 +++++--------- .../UI/InstrumentMidiSourceBase.xaml | 1 + .../UI/InstrumentMidiSourceBase.xaml.cs | 51 ++ .../UI/MidiCollectionUtilsControl.xaml | 17 + .../UI/MidiCollectionUtilsControl.xaml.cs | 57 +++ .../instruments/instruments-component.ftl | 49 +- 23 files changed, 1456 insertions(+), 615 deletions(-) delete mode 100644 Content.Client/Instruments/UI/BandMenu.xaml delete mode 100644 Content.Client/Instruments/UI/BandMenu.xaml.cs create mode 100644 Content.Client/Instruments/UI/BandMidiSource.xaml create mode 100644 Content.Client/Instruments/UI/BandMidiSource.xaml.cs create mode 100644 Content.Client/Instruments/UI/ChannelItem.xaml create mode 100644 Content.Client/Instruments/UI/ChannelItem.xaml.cs create mode 100644 Content.Client/Instruments/UI/ChannelsControl.xaml create mode 100644 Content.Client/Instruments/UI/ChannelsControl.xaml.cs delete mode 100644 Content.Client/Instruments/UI/ChannelsMenu.xaml delete mode 100644 Content.Client/Instruments/UI/ChannelsMenu.xaml.cs create mode 100644 Content.Client/Instruments/UI/FileMidiSource.xaml create mode 100644 Content.Client/Instruments/UI/FileMidiSource.xaml.cs create mode 100644 Content.Client/Instruments/UI/InputMidiSource.xaml create mode 100644 Content.Client/Instruments/UI/InputMidiSource.xaml.cs create mode 100644 Content.Client/Instruments/UI/InstrumentMidiSourceBase.xaml create mode 100644 Content.Client/Instruments/UI/InstrumentMidiSourceBase.xaml.cs create mode 100644 Content.Client/Instruments/UI/MidiCollectionUtilsControl.xaml create mode 100644 Content.Client/Instruments/UI/MidiCollectionUtilsControl.xaml.cs diff --git a/Content.Client/Audio/Midi/MidiFileCollectionManager.cs b/Content.Client/Audio/Midi/MidiFileCollectionManager.cs index 9f84fad30b..0f8308ed8b 100644 --- a/Content.Client/Audio/Midi/MidiFileCollectionManager.cs +++ b/Content.Client/Audio/Midi/MidiFileCollectionManager.cs @@ -15,7 +15,7 @@ public sealed partial class MidiFileCollectionManager : IPostInjectInit /// /// Directory path to use inside UserData for storing MIDIs. /// - private static readonly ResPath UserMidiDirectory = new("/UserMidis/"); + public static readonly ResPath UserMidiDirectory = new("/UserMidis/"); private const string SawmillCategory = "midifilecollection"; diff --git a/Content.Client/Instruments/UI/BandMenu.xaml b/Content.Client/Instruments/UI/BandMenu.xaml deleted file mode 100644 index 620f38fa97..0000000000 --- a/Content.Client/Instruments/UI/BandMenu.xaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - -[RegisterComponent, Access(typeof(DestructibleSystem))] +[RegisterComponent] public sealed partial class DestructibleComponent : Component { /// @@ -14,7 +14,6 @@ public sealed partial class DestructibleComponent : Component /// includes their triggers and resultant behaviors. /// [DataField(customTypeSerializer: typeof(DamageThresholdsSerializer))] - [AlwaysPushInheritance] public List Thresholds = new(); /// diff --git a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs index c051adec2c..13027a31fc 100644 --- a/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs +++ b/Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs @@ -1,14 +1,12 @@ using System.Numerics; using Content.Server.Forensics; -using Content.Server.Spawners.Components; -using Content.Server.Spawners.EntitySystems; +using Content.Server.Stack; using Content.Shared.Destructible.Thresholds; using Content.Shared.Prototypes; using Content.Shared.Stacks; using Robust.Server.GameObjects; using Robust.Shared.Prototypes; using Robust.Shared.Random; -using Robust.Shared.Spawners; namespace Content.Server.Destructible.Thresholds.Behaviors { @@ -16,15 +14,13 @@ namespace Content.Server.Destructible.Thresholds.Behaviors [DataDefinition] public sealed partial class SpawnEntitiesBehavior : IThresholdBehavior { - private static readonly EntProtoId TempEntityProtoId = "TemporaryEntityForTimedDespawnSpawners"; - /// /// Entities spawned on reaching this threshold, from a min to a max. /// [DataField] - public Dictionary Spawn = []; + public Dictionary Spawn = new(); - [DataField] + [DataField("offset")] public float Offset { get; set; } = 0.5f; [DataField("transferForensics")] @@ -33,21 +29,12 @@ namespace Content.Server.Destructible.Thresholds.Behaviors [DataField] public bool SpawnInContainer; - /// - /// Time in seconds to wait before spawning entities. - /// - /// - /// If positive, and are ignored. - /// - [DataField] - public float SpawnAfter; - public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null) { var tSys = system.EntityManager.System(); var position = tSys.GetMapCoordinates(owner); - Vector2 GetRandomVector() => system.Random.NextVector2(Offset); + var getRandomVector = () => new Vector2(system.Random.NextFloat(-Offset, Offset), system.Random.NextFloat(-Offset, Offset)); var executions = 1; if (system.EntityManager.TryGetComponent(owner, out var stack)) @@ -66,23 +53,11 @@ namespace Content.Server.Destructible.Thresholds.Behaviors if (count == 0) continue; - if (SpawnAfter > 0) - { - // TODO: TransferForensics is not supported here because the actual entity UID is not known until the spawner spawns it. - for (var i = 0; i < count; i++) - { - var spawner = system.EntityManager.SpawnEntity(TempEntityProtoId, position.Offset(GetRandomVector())); - var timedDespawn = system.EntityManager.GetComponent(spawner); - timedDespawn.Lifetime = SpawnAfter; - var spawnOnDespawn = system.EntityManager.GetComponent(spawner); - system.EntityManager.System().SetPrototype((spawner, spawnOnDespawn), entityId); - } - } - else if (EntityPrototypeHelpers.HasComponent(entityId, system.PrototypeManager, system.EntityManager.ComponentFactory)) + if (EntityPrototypeHelpers.HasComponent(entityId, system.PrototypeManager, system.EntityManager.ComponentFactory)) { var spawned = SpawnInContainer ? system.EntityManager.SpawnNextToOrDrop(entityId, owner) - : system.EntityManager.SpawnEntity(entityId, position.Offset(GetRandomVector())); + : system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); system.StackSystem.SetCount((spawned, null), count); TransferForensics(spawned, system, owner); @@ -93,7 +68,7 @@ namespace Content.Server.Destructible.Thresholds.Behaviors { var spawned = SpawnInContainer ? system.EntityManager.SpawnNextToOrDrop(entityId, owner) - : system.EntityManager.SpawnEntity(entityId, position.Offset(GetRandomVector())); + : system.EntityManager.SpawnEntity(entityId, position.Offset(getRandomVector())); TransferForensics(spawned, system, owner); } diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs index 9d839264e4..ca3be8c37f 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs @@ -230,11 +230,7 @@ public sealed partial class ExplosionSystem totalDamageTarget = _destructibleSystem.DestroyedAt(uid, destructible); } - // We are assuming airtight entities don't need to relay since they shouldn't have inventories. - var modifiers = _damageableSystem.GetDamageModifierSet(uid); - var explosionComp = _explosionResistanceQuery.CompOrNull(uid); - - if (totalDamageTarget == FixedPoint2.MaxValue || !_injurableQuery.TryComp(uid, out var injurable)) + if (totalDamageTarget == FixedPoint2.MaxValue || !_injurableQuery.TryGetComponent(uid, out var injurable)) { for (var i = 0; i < explosionTolerance.Length; i++) { @@ -258,89 +254,30 @@ public sealed partial class ExplosionSystem // evaluate the damage that this damage type would do to this entity var damagePerIntensity = FixedPoint2.Zero; - - // Create a dictionary of intensity thresholds which dictates when damagePerIntensity increases! - var damageThresholds = new SortedDictionary(); foreach (var (type, value) in explosionType.DamagePerIntensity.DamageDict) { if (!_damageableSystem.CanBeDamagedBy((uid, injurable), type)) continue; - var modifier = mod; - if (explosionComp != null) - { - modifier *= explosionComp.DamageCoefficient; - if (explosionComp.Modifiers.TryGetValue(explosionType.ID, out var typeMod)) - modifier *= typeMod; - } + // TODO EXPLOSION SYSTEM + // add a variant of the event that gets raised once, instead of once per prototype. + // Or better yet, just calculate this manually w/o the event. + // The event mainly exists for indirect resistances via things like inventory & clothing + // But this shouldn't matter for airtight entities. + var ev = new GetExplosionResistanceEvent(explosionType.ID); + RaiseLocalEvent(uid, ref ev); - if (modifiers != null) - { - if (modifiers.Coefficients.TryGetValue(type, out var armorMod)) - modifier *= armorMod; - - if (modifiers.FlatReduction.TryGetValue(type, out var flat)) - { - if (flat > 0) - { - // If the flat modifier is reducing damage, we cache the extra damage per intensity for later! - var intensity = flat / value; - var damage = damageThresholds.GetValueOrDefault(intensity); - damageThresholds[intensity] = value * Math.Max(0, modifier) + damage; - continue; - } - } - } - - damagePerIntensity += value * Math.Max(0, modifier); + damagePerIntensity += value * mod * Math.Max(0, ev.DamageCoefficient); } - explosionTolerance[index] += GetExplosionTolerance(uid, totalDamageTarget, damagePerIntensity, damageThresholds); + var toleranceValue = damagePerIntensity > 0 + ? (float) ((totalDamageTarget - _damageableSystem.GetTotalDamage(uid)) / damagePerIntensity) + : ToleranceValues.Invulnerable; + + explosionTolerance[index] = toleranceValue; } } - private FixedPoint2 GetExplosionTolerance(EntityUid uid, - FixedPoint2 totalDamageTarget, - FixedPoint2 damagePerIntensity, - SortedDictionary damageThresholds) - { - return GetExplosionTolerance(totalDamageTarget - _damageableSystem.GetTotalDamage(uid), - damagePerIntensity, - damageThresholds); - } - - private FixedPoint2 GetExplosionTolerance(FixedPoint2 damageTarget, - FixedPoint2 damagePerIntensity, - SortedDictionary damageThresholds) - { - var tolerance = damagePerIntensity > 0 ? damageTarget / damagePerIntensity : ToleranceValues.Invulnerable; - var prevIntensity = FixedPoint2.Zero; - /* - * Calculated through a pretty simple equation which relies on this dictionary being sorted. - * We precalculate the intensity at which an explosion's damage type exceeds the flat reduction of an entity's armor - * That is done above and stored in our `damageThresholds` SortedDictionary. If you can find a more mem efficient way to do this be my guest, - * but these values *have* to be sorted. - */ - foreach (var (intensity, damage) in damageThresholds) - { - // Check if the object would break before hitting this threshold, if so, return the current tolerance value - if (intensity > tolerance) - return tolerance; - - /* - * If the object breaks after this threshold, reduce the HP left by the amount of HP lost between the last flat reduction and this one - * Then adjust our damagePerIntensity and new tolerance values accordingly. - * Lastly store this intensity value so we can calculate the delta next loop. - */ - damageTarget -= (intensity - prevIntensity) * damagePerIntensity; - damagePerIntensity += damage; - tolerance = intensity + damageTarget / damagePerIntensity; - prevIntensity = intensity; - } - - return tolerance; - } - private void OnAirtightGridRemoved(EntityUid entity) { if (!TryComp(entity, out ExplosionAirtightGridComponent? airtightGrid)) diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index df00da3647..c33e02efa8 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -452,7 +452,7 @@ public sealed partial class ExplosionSystem continue; // TODO EXPLOSIONS turn explosions into entities, and pass the the entity in as the damage origin. - _damageableSystem.ChangeDamage((entity, damageable), damage); + _damageableSystem.ChangeDamage((entity, damageable), damage, ignoreResistances: true); if (_actorQuery.HasComp(entity)) { diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index cdb90c781d..e043c89392 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -6,7 +6,6 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Destructible; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NPC.Pathfinding; -using Content.Shared.Armor; using Content.Shared.Atmos.Components; using Content.Shared.Camera; using Content.Shared.CCVar; @@ -61,7 +60,6 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem [Dependency] private EntityQuery _actorQuery = default!; [Dependency] private EntityQuery _destructibleQuery = default!; [Dependency] private EntityQuery _damageableQuery = default!; - [Dependency] private EntityQuery _explosionResistanceQuery = default!; [Dependency] private EntityQuery _injurableQuery = default!; [Dependency] private EntityQuery _airtightQuery = default!; [Dependency] private EntityQuery _tileHistoryQuery = default!; diff --git a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs index c89ed23987..d0e4f2fd91 100644 --- a/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs +++ b/Content.Shared/Silicons/Borgs/SharedBorgSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Access.Systems; using Content.Shared.Actions; using Content.Shared.Administration.Logs; +using Content.Shared.Body.Events; using Content.Shared.Containers.ItemSlots; using Content.Shared.Database; using Content.Shared.Gibbing; @@ -23,8 +24,8 @@ using Content.Shared.Roles; using Content.Shared.Silicons.Borgs.Components; using Content.Shared.Throwing; using Content.Shared.UserInterface; -using Content.Shared.Whitelist; using Content.Shared.Wires; +using Content.Shared.Whitelist; using Robust.Shared.Audio.Systems; using Robust.Shared.Configuration; using Robust.Shared.Containers; @@ -89,7 +90,7 @@ public abstract partial class SharedBorgSystem : EntitySystem SubscribeLocalEvent(OnRefreshMovementSpeedModifiers); SubscribeLocalEvent(OnUIOpenAttempt); SubscribeLocalEvent(OnMobStateChanged); - SubscribeLocalEvent(OnBeingGibbed); + SubscribeLocalEvent(OnBeingGibbed); SubscribeLocalEvent(OnGetDeadIC); SubscribeLocalEvent(OnGetUnrevivableIC); SubscribeLocalEvent(OnPowerCellSlotEmpty); @@ -286,17 +287,15 @@ public abstract partial class SharedBorgSystem : EntitySystem SetActive(chassis, false, user: args.Origin); } - private void OnBeingGibbed(Entity chassis, ref BeingGibbedEvent args) + private void OnBeingGibbed(Entity chassis, ref GibbedBeforeDeletionEvent args) { // Don't use the ItemSlotsSystem eject method since we don't want to play a sound and want we to eject the battery even if the slot is locked. if (TryComp(chassis, out var slotComp) && _container.TryGetContainer(chassis, slotComp.CellSlotId, out var slotContainer)) - { - args.Giblets.UnionWith(_container.EmptyContainer(slotContainer)); - } + _container.EmptyContainer(slotContainer); - args.Giblets.UnionWith(_container.EmptyContainer(chassis.Comp.BrainContainer)); - args.Giblets.UnionWith(_container.EmptyContainer(chassis.Comp.ModuleContainer)); + _container.EmptyContainer(chassis.Comp.BrainContainer); + _container.EmptyContainer(chassis.Comp.ModuleContainer); } private void OnGetDeadIC(Entity chassis, ref GetCharactedDeadIcEvent args) diff --git a/Resources/Locale/en-US/explosions/explosion-resistance.ftl b/Resources/Locale/en-US/explosions/explosion-resistance.ftl index 50268ef32c..6ebb406b9a 100644 --- a/Resources/Locale/en-US/explosions/explosion-resistance.ftl +++ b/Resources/Locale/en-US/explosions/explosion-resistance.ftl @@ -1,2 +1,2 @@ -explosion-resistance-coefficient-value = - [color=orange]Explosion[/color] damage reduced by an additional [color=lightblue]{$value}%[/color]. +explosion-resistance-coefficient-value = - [color=orange]Explosion[/color] damage reduced by [color=lightblue]{$value}%[/color]. explosion-resistance-contents-coefficient-value = - [color=orange]Explosion[/color] damage [color=white]to contents[/color] reduced by [color=lightblue]{$value}%[/color]. diff --git a/Resources/Locale/en-US/station-events/events/meteor-swarm.ftl b/Resources/Locale/en-US/station-events/events/meteor-swarm.ftl index 030bd61be7..0b82c7fb95 100644 --- a/Resources/Locale/en-US/station-events/events/meteor-swarm.ftl +++ b/Resources/Locale/en-US/station-events/events/meteor-swarm.ftl @@ -7,4 +7,3 @@ station-event-meteor-cow-start-announcement = The station is colliding with an u station-event-meteor-clown-start-announcement = The station is colliding with an unidentified swarm of debris. HONK! Evacuate laughing gas storage immediately. station-event-meteor-potato-start-announcement = The station is colliding with an unidentified swarm of debris. High starch content detected. station-event-fun-swarm-start-announcement = The station is colliding with an unidentified swarm of debris. Please panic appropriately. -station-event-bio-swarm-start-announcement = Meteors have been detected on collision course with the station. Biological activity detected. diff --git a/Resources/Prototypes/Body/Species/vox.yml b/Resources/Prototypes/Body/Species/vox.yml index 94a8a7d37a..e94375594e 100644 --- a/Resources/Prototypes/Body/Species/vox.yml +++ b/Resources/Prototypes/Body/Species/vox.yml @@ -183,6 +183,12 @@ amount: 5 - type: Destructible thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 400 + behaviors: + - !type:GibBehavior { } - trigger: !type:DamageTypeTrigger damageType: Heat @@ -194,6 +200,26 @@ FoodMeatChickenFriedVox: min: 3 max: 5 + - !type:BurnBodyBehavior + popupMessage: bodyburn-vox-text-others + - !type:PlaySoundBehavior + sound: + collection: MeatLaserImpact + - trigger: + !type:DamageTypeTrigger + damageType: Radiation + damage: 15 + behaviors: + - !type:PopupBehavior + popup: mouth-taste-metal + popupType: LargeCaution + targetOnly: true + - trigger: + !type:DamageTypeTrigger + damageType: Radiation + damage: 40 + behaviors: + - !type:VomitBehavior - type: PassiveDamage # Augment normal health regen to be able to tank some Poison damage # This allows Vox to take their mask off temporarily to eat something without needing a trip to medbay afterwards. diff --git a/Resources/Prototypes/Body/species_base.yml b/Resources/Prototypes/Body/species_base.yml index ae386d2be2..69ab8fcc71 100644 --- a/Resources/Prototypes/Body/species_base.yml +++ b/Resources/Prototypes/Body/species_base.yml @@ -162,7 +162,6 @@ - MobAtmosStandard - MobFlammable - BaseSpeciesMob - - BaseMobDestructible id: BaseSpeciesMobOrganic save: false components: diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index 510f9895b0..b7a1e3cd30 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -114,6 +114,8 @@ Piercing: 0.6 Heat: 0.5 Caustic: 0.9 + - type: ExplosionResistance + damageCoefficient: 0.65 - type: GroupExamine - type: entity @@ -185,6 +187,8 @@ Heat: 0.3 Radiation: 0.5 Caustic: 0.5 + - type: ExplosionResistance + damageCoefficient: 0.5 - type: FireProtection reduction: 0.85 - type: StaticPrice @@ -234,6 +238,8 @@ Piercing: 0.35 Heat: 0.35 Caustic: 0.5 + - type: ExplosionResistance + damageCoefficient: 0.35 - type: StaminaResistance # do not add these to other equipment or mobs, we don't want to microbalance these everywhere damageCoefficient: 0.45 - type: ClothingSpeedModifier @@ -419,7 +425,7 @@ sprintModifier: 0.65 - type: HeldSpeedModifier - type: ExplosionResistance - damageCoefficient: 0.75 + damageCoefficient: 0.5 - type: GroupExamine - type: ProtectedFromStepTriggers slots: WITHOUT_POCKET @@ -445,7 +451,7 @@ sprintModifier: 0.8 - type: HeldSpeedModifier - type: ExplosionResistance - damageCoefficient: 0.6 + damageCoefficient: 0.4 - type: GroupExamine - type: Construction graph: BoneArmor diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 3427215049..e0d956ee59 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -162,7 +162,7 @@ highPressureMultiplier: 0.5 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.5 + damageCoefficient: 0.3 - type: Armor modifiers: coefficients: @@ -234,7 +234,7 @@ highPressureMultiplier: 0.5 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.5 + damageCoefficient: 0.4 - type: Armor modifiers: coefficients: @@ -296,7 +296,7 @@ highPressureMultiplier: 0.5 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.5 + damageCoefficient: 0.4 - type: Armor modifiers: coefficients: @@ -327,7 +327,7 @@ highPressureMultiplier: 0.02 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.7 + damageCoefficient: 0.5 - type: Armor modifiers: coefficients: @@ -608,7 +608,7 @@ heatingCoefficient: 0.001 coolingCoefficient: 0.001 - type: ExplosionResistance - damageCoefficient: 0.3 + damageCoefficient: 0.2 - type: FireProtection reduction: 0.8 - type: StaminaResistance # do not add these to other equipment or mobs, we don't want to microbalance these everywhere @@ -688,6 +688,8 @@ - type: PressureProtection highPressureMultiplier: 0.2 lowPressureMultiplier: 1000 + - type: ExplosionResistance + damageCoefficient: 0.3 # - type: StaminaResistance # Should not have stamina resistance, this is purely so people know it was not forgotten. - type: Armor modifiers: diff --git a/Resources/Prototypes/Entities/Markers/Spawners/temp.yml b/Resources/Prototypes/Entities/Markers/Spawners/temp.yml index cf52b00a05..aa76bb5ea7 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/temp.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/temp.yml @@ -8,5 +8,4 @@ bodyType: Static canCollide: false - type: TimedDespawn - - type: SpawnOnDespawn - prototype: Ash # placeholder (required by component), overridden at runtime + # we can't declare the SpawnOnDespawnComponent because the entity is required on yml diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 568e932b82..764f6954e3 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -169,6 +169,32 @@ - type: Damageable - type: Injurable damageContainer: Silicon + - type: Destructible + generateOverkillThreshold: false + thresholds: + - trigger: + !type:DamageTrigger + damage: 75 + behaviors: + - !type:PlaySoundBehavior + sound: + path: /Audio/Machines/warning_buzzer.ogg + params: + volume: 5 + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:EmptyContainersBehaviour + containers: + - borg_brain + - borg_module + - cell_slot + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: HandheldLight toggleOnInteract: false wattage: 0.2 @@ -235,34 +261,6 @@ id: BaseBorgChassis components: - type: IonStormTarget - - type: Destructible - generateOverkillThreshold: false - thresholds: - - trigger: - !type:DamageTrigger - damage: 75 - behaviors: - - !type:PlaySoundBehavior - sound: - path: /Audio/Machines/warning_buzzer.ogg - params: - volume: 5 - - trigger: - !type:DamageTrigger - damage: 300 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:GibBehavior - - !type:SpawnEntitiesBehavior - spawn: - ScrapGlass: - min: 1 - max: 1 - SheetSteel: - min: 10 - max: 20 - type: entity abstract: true @@ -504,32 +502,6 @@ - type: NpcFactionMember factions: - Xenoborg - - type: PointLight - color: "#3010ff" - energy: 7 - - type: GuideHelp - guides: - - Cyborgs - - Robotics - - Xenoborgs - - type: Access - tags: - - Xenoborg - - type: AccessReader - access: [["Xenoborg"]] - - type: ShowJobIcons # not sure if it is needed - - type: ShowCrewIcons - - type: InteractionPopup - interactSuccessSound: - path: /Audio/Ambience/Objects/periodic_beep.ogg - - type: Xenoborg - - type: BypassLock - bypassDelay: 15 # We don't want people to easily be able to remove xenoborg brains. - -- type: entity - abstract: true - id: BaseXenoborgDestructible - components: - type: Destructible thresholds: - trigger: @@ -560,3 +532,24 @@ - cell_slot - !type:DoActsBehavior acts: [ "Destruction" ] + - type: PointLight + color: "#3010ff" + energy: 7 + - type: GuideHelp + guides: + - Cyborgs + - Robotics + - Xenoborgs + - type: Access + tags: + - Xenoborg + - type: AccessReader + access: [["Xenoborg"]] + - type: ShowJobIcons # not sure if it is needed + - type: ShowCrewIcons + - type: InteractionPopup + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg + - type: Xenoborg + - type: BypassLock + bypassDelay: 15 # We don't want people to easily be able to remove xenoborg brains. diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml index 4e14e24cf1..77c82f3fbd 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseXenoborgChassis, BaseXenoborgTransponder, BaseXenoborgDestructible ] + parent: [ BaseXenoborgChassis, BaseXenoborgTransponder ] id: XenoborgEngi name: engi xenoborg suffix: with brain @@ -148,7 +148,7 @@ startingItem: PowerCellHigh - type: entity - parent: [ BaseXenoborgChassis, BaseXenoborgTransponder, BaseXenoborgDestructible ] + parent: [ BaseXenoborgChassis, BaseXenoborgTransponder ] id: XenoborgScout name: scout xenoborg suffix: with brain @@ -203,7 +203,7 @@ startingItem: PowerCellHigh - type: entity - parent: [ BaseXenoborgChassis, BaseXenoborgTransponder, BaseXenoborgDestructible ] + parent: [ BaseXenoborgChassis, BaseXenoborgTransponder ] id: XenoborgStealth name: stealth xenoborg suffix: with brain diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 45f6612f1a..c447f1570e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -199,7 +199,7 @@ - type: entity name: chicken - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] id: MobChicken description: Comes before an egg, and IS a dinosaur! components: @@ -348,12 +348,17 @@ lifetime: 21 - type: entity - abstract: true + name: cockroach parent: [SolutionFood, SolutionTiny, SimpleMobBase, BaseSlicingRefinable, MobNightVision] - id: BaseCockroach + id: MobCockroach + description: This station is just crawling with bugs. components: - type: Sprite drawdepth: SmallMobs + sprite: Mobs/Animals/cockroach.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: cockroach - type: Item size: Tiny - type: HTN @@ -380,6 +385,14 @@ - type: MovementSpeedModifier baseWalkSpeed : 2.5 baseSprintSpeed : 5 + - type: DamageStateVisuals + states: + Alive: + Base: cockroach + Critical: + Base: cockroach_dead + Dead: + Base: cockroach_dead - type: Bloodstream bloodReferenceSolution: reagents: @@ -409,6 +422,15 @@ tags: - Trash - VimPilot + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 10 + behaviors: + - !type:GibBehavior + recursive: false - type: NonSpreaderZombie - type: StepTrigger requiredTriggeredSpeed: 1 @@ -426,38 +448,9 @@ types: Piercing: 0 -- type: entity - parent: BaseCockroach - id: MobCockroach - name: cockroach - description: This station is just crawling with bugs. - components: - - type: Sprite - sprite: Mobs/Animals/cockroach.rsi - layers: - - map: ["enum.DamageStateVisualLayers.Base"] - state: cockroach - - type: DamageStateVisuals - states: - Alive: - Base: cockroach - Critical: - Base: cockroach_dead - Dead: - Base: cockroach_dead - - type: Destructible - thresholds: - - trigger: - !type:DamageTypeTrigger - damageType: Blunt - damage: 10 - behaviors: - - !type:GibBehavior - recursive: false - - type: entity name: glockroach - parent: MobCockroach + parent: [MobCockroach, BaseSlicingRefinable] suffix: Admeme id: MobGlockroach description: This station is just crawling with bu- OH GOD THAT COCKROACH HAS A GUN!!! @@ -483,10 +476,13 @@ - type: NpcFactionMember factions: - SimpleHostile + - type: ToolRefinable + refineResult: + - id: FoodMeatSlime - type: entity name: mothroach - parent: [ BaseMobMothroach, BaseCockroach, BaseSlicingRefinable ] + parent: [ BaseMobMothroach, MobCockroach, BaseSlicingRefinable ] id: MobMothroach description: This is the adorable by-product of multiple attempts at genetically mixing mothpeople with cockroaches. components: @@ -660,7 +656,7 @@ - type: entity name: mallard duck #Quack - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] id: MobDuckMallard description: An adorable mallard duck, it's fluffy and soft! components: @@ -863,7 +859,7 @@ - type: entity name: cow - parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable ] id: MobCow description: Moo. components: @@ -954,7 +950,7 @@ - type: entity name: crab - parent: [ SimpleMobBase, BaseMobHemocyanin, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleMobBase, BaseMobHemocyanin, BaseSlicingRefinable ] id: MobCrab description: A folk legend goes around that his claw snaps spacemen out of existence over distasteful remarks. Be polite and tolerant for your own safety. components: @@ -1022,7 +1018,7 @@ - type: entity name: goat - parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable ] id: MobGoat description: Her spine consists of long sharp segments, no wonder she is so grumpy. components: @@ -1290,7 +1286,7 @@ Quantity: 25 - type: entity - parent: [ MobSheepBase, SimpleMobBase, BaseMobDestructible ] + parent: [ MobSheepBase, SimpleMobBase ] id: MobSheep name: sheep description: An adorable genetically engineered chemical factory producing milk and cotton. @@ -1327,7 +1323,7 @@ # Note that we gotta make this bitch vomit someday when you feed it anthrax or sumthin. Needs to be a small item thief too and aggressive if attacked. - type: entity name: goose - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] id: MobGoose description: Its stomach and mind are an enigma beyond human comprehension. components: @@ -1378,7 +1374,7 @@ - type: entity name: gorilla - parent: [ SimpleMobBase, MobCombat, BaseMobDestructible ] + parent: [ SimpleMobBase, MobCombat ] id: MobGorilla description: Smashes, roars, looks cool. Don't stand near one. components: @@ -1463,7 +1459,6 @@ - MobCombat - StripableInventoryBase - BaseSlicingRefinable - - BaseMobDestructible id: MobKangaroo description: A large marsupial herbivore. It has powerful hind legs, with nails that resemble long claws. components: @@ -1555,7 +1550,7 @@ - type: entity name: genetic ancestor id: MobBaseAncestor - parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase, BaseMobDestructible] + parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase] description: The genetic bipedal ancestor of... Uh... Something. Yeah, there's definitely something on the station that descended from whatever this is. abstract: true components: @@ -2221,7 +2216,7 @@ - type: entity name: lizard #Weh - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] id: MobLizard description: A harmless dragon. components: @@ -2278,7 +2273,7 @@ - type: entity name: slug - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] id: MobSlug description: And they called this a lizard? components: @@ -2399,7 +2394,7 @@ # Would be cool to have some functionality for the parrot to be able to sit on stuff - type: entity - parent: [ SimpleMobBase, FlyingMobBase, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleMobBase, FlyingMobBase, BaseSlicingRefinable ] id: MobParrotBase name: parrot abstract: true @@ -2486,7 +2481,7 @@ - type: entity name: penguin - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] id: MobPenguin description: Their lives are constant pain due to their inner-body knees. components: @@ -2625,7 +2620,7 @@ # I have included a snake_hiss.ogg sound file so if you want to use that be my guest - type: entity name: snake - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] id: MobSnake description: Hissss! Bites aren't poisonous. components: @@ -2675,7 +2670,7 @@ # Code unique spider prototypes or combine them all into one spider and get a # random sprite state when you spawn it. - type: entity - parent: [ SimpleMobBase, BaseMobHemocyanin, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] + parent: [ SimpleMobBase, BaseMobHemocyanin, MobCombat, BaseSlicingRefinable, MobNightVision ] id: MobSpiderBase abstract: true components: @@ -2883,7 +2878,6 @@ reagents: - ReagentId: Laughter Quantity: 150 - - type: entity name: wizard spider parent: MobGiantSpider @@ -2898,7 +2892,7 @@ - type: entity name: possum - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobPossum description: '"O Possum! My Possum!" -- Walt Whitman, 1865' components: @@ -2971,7 +2965,7 @@ - type: entity name: raccoon - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobRaccoon description: Trash panda! components: @@ -3024,7 +3018,7 @@ - type: entity name: fox - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobFox description: They're a fox. components: @@ -3106,7 +3100,7 @@ - type: entity abstract: true - parent: [SimpleMobBase, StripableInventoryBase, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase] id: MobCorgiBase name: corgi description: Finally, a space corgi! @@ -3270,7 +3264,7 @@ - type: entity name: cat - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobCat description: Feline pet, very funny. components: @@ -3506,7 +3500,7 @@ - type: entity name: sloth - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobSloth description: Very slow animal. For people with low energy. components: @@ -3563,7 +3557,7 @@ - type: entity name: ferret - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobFerret description: Just a silly little guy! components: @@ -3772,7 +3766,7 @@ - type: entity name: pig - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobPig description: Oink. components: @@ -3843,7 +3837,7 @@ - type: entity name: diona nymph - parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobDionaNymph description: It's like a cat, only.... branch-ier. components: @@ -3931,7 +3925,7 @@ - type: entity name: reindeer buck - parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable ] id: MobReindeerBuck description: You think it can pull a sleigh? components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml index 6768f4599e..6d4266d252 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml @@ -1,6 +1,6 @@ - type: entity save: false - parent: [ BaseSimpleMob, BaseMobAnimal, MobCombat, MobBloodstream, BaseMobDestructible ] + parent: [ BaseSimpleMob, BaseMobAnimal, MobCombat, MobBloodstream ] id: BaseMobArgocyte suffix: AI description: A dangerous alien found on the wrong side of planets, known for their propensity for munching on ruins. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml index 6ee68e56c2..89ef10385a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml @@ -27,7 +27,7 @@ - type: entity id: MobGoliath - parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable ] name: goliath description: A massive beast that uses long tentacles to ensnare its prey, threatening them is not advised under any conditions. components: @@ -189,7 +189,7 @@ - type: entity id: MobHivelord - parent: [ BaseMobAsteroid, FlyingMobBase, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ BaseMobAsteroid, FlyingMobBase, BaseSlicingRefinable ] name: hivelord description: A truly alien creature, it is a mass of unknown organic material, constantly fluctuating. When attacking, pieces of it split off and attack in tandem with the original. components: @@ -354,7 +354,7 @@ - type: entity id: MobBasilisk - parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable ] name: basilisk description: A territorial beast, covered in a thick shell that absorbs energy. Its stare causes victims to freeze from the inside. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml index a72c62a925..429d4db091 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml @@ -1,6 +1,6 @@ - type: entity name: behonker - parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable ] id: BaseMobBehonker abstract: true description: A floating demon aspect of the honkmother. @@ -115,7 +115,6 @@ reagents: - ReagentId: Laughter Quantity: 300 - - type: entity name: behonker parent: BaseMobBehonker diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index e6dd5c3cf4..23deb0eeab 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -1,7 +1,7 @@ - type: entity name: space carp id: BaseMobCarp - parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable, MobNightVision ] description: It's a space carp. abstract: true components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml b/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml index dbcebebdcc..c617eab499 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable ] id: BaseMobFlesh name: aberrant flesh description: A shambling mass of flesh, animated through anomalous energy. @@ -204,7 +204,7 @@ Blunt: 10 - type: entity - parent: [ SimpleSpaceMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, MobCombat, BaseSlicingRefinable ] id: BaseMobFleshSalvage #This one is immune to space! name: aberrant flesh suffix: "Salvage Ruleset" diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml index 621354bc27..9e8732bf1a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml @@ -6,7 +6,6 @@ - MobBloodstream - BaseMobAnimal - BaseSlicingRefinable - - BaseMobDestructible id: MobHellspawn description: An unstoppable force of carnage. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml b/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml index 448df6ae43..784b5dcc43 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml @@ -1,6 +1,6 @@ # Base hivebot - type: entity - parent: [ BaseSimpleMob, MobCombat, MobRobotic, BaseMobDestructible ] + parent: [ BaseSimpleMob, MobCombat, MobRobotic ] id: MobHivebot name: hivebot description: Agitating, mechanized pests. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml b/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml index 1b2902ab3c..65bc1c30fe 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml @@ -1,7 +1,7 @@ - type: entity name: watcher id: MobWatcherBase - parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable ] abstract: true description: It's like it's staring right through you. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml index 12955eae57..e8325e026c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml @@ -1,7 +1,7 @@ - type: entity name: mimic id: MobMimic - parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] + parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable ] description: Surprise. # When this gets a proper write this should use the object's actual description >:) components: - type: Tag diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml index 321c7078a5..108464284d 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml @@ -1,7 +1,7 @@ - type: entity name: laser raptor id: MobLaserRaptor - parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, BaseSlicingRefinable] description: From the Viking age. components: - type: NpcFactionMember diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 5b6b8d2a2c..00357e73e9 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -241,7 +241,7 @@ - type: entity name: Bingus - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobBingus description: Bingus my beloved... components: @@ -298,7 +298,7 @@ - type: entity name: McGriff - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobMcGriff description: This dog can tell something smells around here, and that something is CRIME! components: @@ -408,7 +408,7 @@ - type: entity name: Walter - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] id: MobWalter description: He likes chems and treats. Walter. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index cc08ff8f08..0b1f2d1657 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -1,7 +1,7 @@ - type: entity name: rat king id: MobRatKing - parent: [ BaseMobRat, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] + parent: [ BaseMobRat, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision ] description: He's da rat. He make da roolz. components: - type: CombatMode diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml index f0795a1fd6..0b0616e88e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml @@ -182,9 +182,10 @@ # feel free to hook them into random content. - type: entity - abstract: true - id: MobBaseEmotionalSupportScurret name: Emotional Support Scurret + id: MobBaseEmotionalSupportScurret + parent: MobBaseScurret + abstract: true components: - type: Loadout prototypes: [ EmotionalSupportScurretGear ] diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml index 074b1d0ecd..09af04aeea 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml @@ -1,7 +1,7 @@ - type: entity name: basic slime id: BaseMobAdultSlimes - parent: [ BaseMobSlimes, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] + parent: [ BaseMobSlimes, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision ] abstract: true description: It looks so much like jelly. I wonder what it tastes like? components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml index 705bbfe04e..65e861d3de 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml @@ -74,7 +74,7 @@ - type: entity name: space bear id: MobBearSpace - parent: [MobSpaceBasic, BaseSlicingRefinable, BaseMobDestructible] + parent: [MobSpaceBasic, BaseSlicingRefinable] description: It looks friendly. Why don't you give it a hug? components: - type: Sprite @@ -123,7 +123,7 @@ - type: entity name: space kangaroo id: MobKangarooSpace - parent: [MobSpaceBasic, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [MobSpaceBasic, StripableInventoryBase, BaseSlicingRefinable] description: It looks friendly. Why don't you give it a hug? components: - type: Sprite @@ -184,7 +184,7 @@ - type: entity name: space spider id: MobSpiderSpace - parent: [MobSpaceBasic, BaseSlicingRefinable, BaseMobDestructible] + parent: [MobSpaceBasic, BaseSlicingRefinable] description: It's so glowing, it looks dangerous. components: - type: Sprite @@ -289,7 +289,7 @@ - type: entity name: space cobra id: MobCobraSpace - parent: [MobSpaceBasic, BaseSlicingRefinable, BaseMobDestructible] + parent: [MobSpaceBasic, BaseSlicingRefinable] description: Long fangs and a glowing hood, and the alluring look begs to come closer. components: - type: Sprite @@ -394,7 +394,7 @@ - type: SalvageMobRestrictions - type: entity - parent: [ SimpleSpaceMobBase, FlyingMobBase, MobSheepBase, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, MobSheepBase ] id: MobSheepSpace name: space sheep description: A sheep... in space! diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index b2427856f7..2a4a6a219d 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -2,7 +2,7 @@ - type: entity name: burrower id: MobXeno - parent: [ SimpleSpaceMobBase, MobNightVision, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, MobNightVision ] description: They mostly come at night. Mostly. components: - type: Insulated @@ -360,7 +360,7 @@ - type: entity name: space adder - parent: [SimpleSpaceMobBase, BaseSlicingRefinable, BaseMobDestructible] + parent: [SimpleSpaceMobBase, BaseSlicingRefinable] id: MobPurpleSnake description: A menacing purple snake from Kepler-283c. components: @@ -469,7 +469,7 @@ - type: entity name: '"Dale"' description: A praetorian left over from the station's initial security sweep. Has a pair of bloodied dog tags engraved with the name "Pvt. Dale" stuck in its maw. - parent: [SimpleSpaceMobBase, BaseMobDestructible] + parent: SimpleSpaceMobBase id: MobXenoLonePraetorianNoGhost components: - type: Insulated diff --git a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml index 543a34e30c..52a5cecd49 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml @@ -18,7 +18,7 @@ ChangelingDNA: 60 - type: entity - parent: [ SimpleSpaceMobBase, MobNightVision, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, MobNightVision ] id: MobHeadSlug name: headslug description: A small, slug-like creature with a large, gaping maw. It's covered in a thick, slimy mucus. diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml index 9a2c187c4e..31b89c3c24 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable, MobNightVision ] id: BaseMobDragon suffix: "" name: space dragon diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index f3447bce3a..e81adfb589 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -71,6 +71,44 @@ - type: Damageable - type: Injurable damageContainer: Biological + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 400 + behaviors: + - !type:GibBehavior { } + - trigger: + !type:DamageTypeTrigger + damageType: Heat + damage: 1500 + behaviors: + - !type:SpawnEntitiesBehavior + spawnInContainer: true + spawn: + Ash: + min: 1 + max: 1 + - !type:BurnBodyBehavior + - !type:PlaySoundBehavior + sound: + collection: MeatLaserImpact + - trigger: + !type:DamageTypeTrigger + damageType: Radiation + damage: 15 + behaviors: + - !type:PopupBehavior + popup: mouth-taste-metal + popupType: LargeCaution + targetOnly: true + - trigger: + !type:DamageTypeTrigger + damageType: Radiation + damage: 40 + behaviors: + - !type:VomitBehavior - type: RadiationReceiver - type: Stamina - type: StunVisuals @@ -112,50 +150,6 @@ - type: GhostOnMove mustBeDead: true -# Used as a simple default for mob destruction -- type: entity - abstract: true - id: BaseMobDestructible - components: - - type: Destructible - thresholds: - - trigger: - !type:DamageTypeTrigger - damageType: Blunt - damage: 400 - behaviors: - - !type:GibBehavior { } - - trigger: - !type:DamageTypeTrigger - damageType: Heat - damage: 1500 - behaviors: - - !type:SpawnEntitiesBehavior - spawnInContainer: true - spawn: - Ash: - min: 1 - max: 1 - - !type:BurnBodyBehavior - - !type:PlaySoundBehavior - sound: - collection: MeatLaserImpact - - trigger: - !type:DamageTypeTrigger - damageType: Radiation - damage: 15 - behaviors: - - !type:PopupBehavior - popup: mouth-taste-metal - popupType: LargeCaution - targetOnly: true - - trigger: - !type:DamageTypeTrigger - damageType: Radiation - damage: 40 - behaviors: - - !type:VomitBehavior - # Used for mobs that can enter combat mode and can attack. - type: entity save: false diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml index 164d3f02ca..a81caef76a 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml @@ -21,6 +21,12 @@ sound: collection: GlassBreak - !type:SpillBehavior { } + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + transferForensics: true - !type:DoActsBehavior acts: [ "Destruction" ] - type: DamageOnLand @@ -42,12 +48,9 @@ # Porcelain (like glass but no shard) - type: entity abstract: true + parent: DrinkBaseMaterialGlass id: DrinkBaseMaterialPorcelain components: - - type: Damageable - damageModifierSet: FlimsyGlass - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -60,15 +63,9 @@ - !type:SpillBehavior { } - !type:DoActsBehavior acts: [ "Destruction" ] - - type: DamageOnLand - ignoreResistances: true - damage: - types: - Blunt: 5 # so fragile it smashes when thrown - - type: DamageOtherOnHit - damage: - types: - Blunt: 5 + - type: PhysicalComposition + materialComposition: + Glass: 10 # Trace amounts of glass I guess. Important for overriding inheritance # Fragile plastic - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml index 06c9932261..45fb858a66 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml @@ -23,18 +23,24 @@ tags: - DrinkBottle - Trash - - type: Destructible + - type: Destructible # Same as parent, but spawns BrokenBottle instead of ShardGlass thresholds: - trigger: !type:DamageTrigger damage: 5 behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + - !type:SpillBehavior { } - !type:SpawnEntitiesBehavior spawn: BrokenBottle: min: 1 max: 1 transferForensics: true + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml index a71cf24e76..e7f4c3b56f 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml @@ -67,18 +67,6 @@ sprite: Objects/Consumable/Drinks/glass_coupe_shape.rsi - type: SolutionContainerVisuals inHandsMaxFillLevels: 1 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 5 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - transferForensics: true - type: entity parent: [DrinkBaseMaterialCardboard, DrinkBaseCup, DrinkBaseEmptyTrash, DrinkVisualsFill] diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml index 8652dc348e..0e8e12265d 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml @@ -78,18 +78,6 @@ sprite: Objects/Consumable/Drinks/jar_what.rsi - type: FitsInDispenser solution: drink - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 5 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - transferForensics: true # Mopwata - type: weightedRandomFillSolution diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml index c0d1b3a51e..84f4d954a4 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml @@ -21,18 +21,6 @@ metamorphicDefaultSprite: sprite: Objects/Consumable/Drinks/glass_clear.rsi state: icon - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 5 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - transferForensics: true - type: entity parent: DrinkGlass diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml index 1c20831194..9d23f09eb8 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml @@ -16,18 +16,6 @@ inHandsMaxFillLevels: 1 - type: FitsInDispenser solution: drink - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 5 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 0 - max: 1 - transferForensics: true - type: entity parent: [DrinkBaseMaterialMetal, SolutionLarge, DrinkBase] @@ -218,18 +206,6 @@ solution: drink - type: FitsInDispenser solution: drink - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 5 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - transferForensics: true - type: entity parent: DrinkShakeBase diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml index 1ee516e425..62a09538dc 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml @@ -7,13 +7,23 @@ # Large Plate - type: entity - abstract: true + name: large plate parent: BaseItem - id: BaseFoodPlate + id: FoodPlate + description: A large plate, excellent for bread. components: + - type: Sprite + sprite: Objects/Consumable/Food/plates.rsi + state: plate - type: Item shape: - 0,0,1,0 + storedOffset: 0,-6 + inhandVisuals: + left: + - state: plate-inhand-left + right: + - state: plate-inhand-right - type: DamageOnLand damage: types: @@ -36,48 +46,25 @@ collection: GlassBreak params: volume: -8 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: Tag - tags: - - Trash - - type: SpaceGarbage - -- type: entity - parent: BaseFoodPlate - id: FoodPlate - name: large plate - description: A large plate, excellent for bread. - components: - - type: Sprite - sprite: Objects/Consumable/Food/plates.rsi - state: plate - - type: Item - storedOffset: 0,-6 - inhandVisuals: - left: - - state: plate-inhand-left - right: - - state: plate-inhand-right - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 5 - behaviors: - !type:SpawnEntitiesBehavior spawn: FoodPlateTrash: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Tag + tags: + - Trash - type: PhysicalComposition materialComposition: Glass: 50 + - type: SpaceGarbage - type: entity + name: broken plate parent: BaseItem id: FoodPlateTrash - name: broken plate description: A broken plate. Useless. components: - type: Sprite @@ -95,9 +82,9 @@ # Small Plate - type: entity - parent: BaseFoodPlate - id: FoodPlateSmall name: small plate + parent: FoodPlate + id: FoodPlateSmall description: A small plate. Delicate. components: - type: Sprite @@ -110,17 +97,25 @@ - state: plate-inhand-left right: - state: plate-inhand-right +# Needs the full thing because inherting is dumb sometimes. - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 5 behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + params: + volume: -8 - !type:SpawnEntitiesBehavior spawn: FoodPlateSmallTrash: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: PhysicalComposition materialComposition: Glass: 25 @@ -138,7 +133,7 @@ # Plastic Plate - type: entity - parent: BaseFoodPlate + parent: BaseItem id: FoodPlatePlastic name: large plastic plate description: A large blue plastic plate, excellent for a birthday cake. @@ -147,6 +142,8 @@ sprite: Objects/Consumable/Food/plates.rsi state: plate-plastic - type: Item + shape: + - 0,0,1,0 storedOffset: 0,-6 inhandVisuals: left: @@ -158,7 +155,7 @@ - Trash - type: entity - parent: BaseFoodPlate + parent: BaseItem id: FoodPlateSmallPlastic name: small plastic plate description: A blue plastic plate, excellent for slices of birthday cake. @@ -167,6 +164,8 @@ sprite: Objects/Consumable/Food/plates.rsi state: plate-small-plastic - type: Item + shape: + - 0,0,1,0 storedOffset: 0,-3 inhandVisuals: left: @@ -180,9 +179,9 @@ # Pie Tin - type: entity + name: pie tin parent: BaseItem id: FoodPlateTin - name: pie tin description: A cheap foil tin for pies. components: - type: Sprite diff --git a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml index 6d399cc644..266c9eca82 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml @@ -391,8 +391,21 @@ thresholds: - trigger: !type:DamageTrigger - damage: 50 + damage: 25 behaviors: + - !type:PlaySoundBehavior + sound: + path: /Audio/Effects/tree_fell.ogg + params: + volume: 5 + variation: 0.05 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:SpawnEntitiesBehavior + spawn: + Log: + min: 0 + max: 1 - !type:SpawnEntitiesBehavior spawn: MobLuminousObject: diff --git a/Resources/Prototypes/Entities/Objects/Decoration/mining.yml b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml index 01f1c13995..7a04fc6fcb 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/mining.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml @@ -50,36 +50,28 @@ state: sign_right - type: entity - abstract: true + id: WoodenSupport parent: BaseStructure - id: BaseWoodenSupport + name: wooden support + description: Increases your confidence that a rock won't fall on your head. placement: mode: SnapgridCenter components: - type: PlacementReplacement key: walls + - type: Tag + tags: + - Wooden - type: Sprite noRot: true sprite: Objects/Decoration/mines.rsi + state: support - type: Damageable damageModifierSet: Wood - type: Injurable damageContainer: StructuralInorganic - type: Physics bodyType: Static - - type: MeleeSound - soundGroups: - Brute: - path: /Audio/Effects/chop.ogg - params: - variation: 0.05 - -- type: entity - parent: BaseWoodenSupport - id: WoodenSupport - name: wooden support - description: Increases your confidence that a rock won't fall on your head. - components: - type: Fixtures fixtures: fix1: @@ -91,6 +83,12 @@ layer: - WallLayer density: 1000 + - type: MeleeSound + soundGroups: + Brute: + path: /Audio/Effects/chop.ogg + params: + variation: 0.05 - type: Destructible thresholds: - trigger: @@ -106,11 +104,12 @@ max: 3 - type: entity - parent: BaseWoodenSupport id: WoodenSupportBeam name: wooden support beam + parent: WoodenSupport components: - type: Sprite + sprite: Objects/Decoration/mines.rsi state: support_beams - type: Fixtures fixtures: @@ -126,16 +125,29 @@ density: 1000 - type: entity - parent: BaseWoodenSupport id: WoodenSupportWall + parent: BaseStructure name: wooden support wall description: An old, rotten wall. + placement: + mode: SnapgridCenter components: + - type: PlacementReplacement + key: walls - type: Tag tags: - Wall + - Wooden - type: Sprite + noRot: true + sprite: Objects/Decoration/mines.rsi state: support_wall + - type: Damageable + damageModifierSet: Wood + - type: Injurable + damageContainer: StructuralInorganic + - type: Physics + bodyType: Static - type: Fixtures fixtures: fix1: @@ -162,13 +174,11 @@ max: 5 - type: entity - parent: BaseWoodenSupport id: WoodenSupportWallBroken + parent: WoodenSupportWall components: - - type: Tag - tags: - - Wall - type: Sprite + sprite: Objects/Decoration/mines.rsi state: support_wall_broken - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml index 4a03e5e3fa..5c5dcd8979 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml @@ -1,6 +1,6 @@ - type: entity id: SingularityBeacon - parent: [BaseMachinePowered, BaseSyndicateContraband, BaseMachineDestructible] + parent: [BaseMachinePowered, BaseSyndicateContraband] name: singularity beacon description: A syndicate device that attracts the singularity. If it's loose and you're seeing this, run. components: @@ -29,15 +29,15 @@ baseRange: 80 - type: SinguloFood energy: 120 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: ApcPowerReceiver powerLoad: 5000 - type: StaticPrice price: 7500 - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Objects/Devices/payload.yml b/Resources/Prototypes/Entities/Objects/Devices/payload.yml index eef0b1668d..a18d533fd8 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/payload.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/payload.yml @@ -35,6 +35,14 @@ intensitySlope: 3 totalIntensity: 120 # about a ~4 tile radius - type: ExplodeOnTrigger + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity name: chemical payload diff --git a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml index 704e7ffc0f..acd8ad873e 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseItem, BaseItemDestructible ] + parent: BaseItem id: BaseHandheldStationMap name: station map description: Displays a readout of the current station. @@ -19,6 +19,14 @@ - type: Damageable - type: Injurable damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: UserInterface interfaces: enum.StationMapUiKey.Key: diff --git a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml index 173f83f561..621b086084 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml @@ -1,6 +1,6 @@ - type: entity id: Wristwatch - parent: [ BaseItem, BaseItemDestructible ] + parent: BaseItem name: wristwatch description: A cheap watch for telling time. How much did you waste playing Space Station 14? components: @@ -26,10 +26,16 @@ price: 50 - type: Destructible thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - trigger: !type:DamageGroupTrigger damageGroup: Brute - damage: 5 + damage: 25 behaviors: - !type:DoActsBehavior acts: [ "Breakage" ] diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 2e7e186826..1f87047b2d 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -11,6 +11,24 @@ sprite: Objects/Materials/Sheets/glass.rsi - type: Damageable damageModifierSet: Glass + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + params: + volume: -4 + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: SheetGlassBase @@ -45,22 +63,6 @@ reagents: - ReagentId: Silicon Quantity: 10 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - params: - volume: -4 - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - type: entity parent: SheetGlass @@ -130,6 +132,8 @@ ShardGlassReinforced: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Solution solution: maxVol: 15 @@ -196,6 +200,8 @@ ShardGlassPlasma: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Solution solution: maxVol: 20 @@ -312,6 +318,8 @@ ShardGlassUranium: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Solution solution: maxVol: 20 @@ -427,6 +435,8 @@ ShardGlassClockwork: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Solution solution: maxVol: 20 diff --git a/Resources/Prototypes/Entities/Objects/Materials/base.yml b/Resources/Prototypes/Entities/Objects/Materials/base.yml index 7fd3e93ed8..0d49a037b5 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/base.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/base.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [SolutionCryo, SolutionCompositeNormalStackable, BaseItem, BaseItemDestructible] + parent: [SolutionCryo, SolutionCompositeNormalStackable, BaseItem] id: MaterialBase description: A raw material. components: @@ -14,6 +14,17 @@ - type: Tag tags: - RawMaterial + - type: Damageable + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Extractable grindableSolutionName: composite diff --git a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml index d64f69686c..feb79ff44b 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml @@ -14,6 +14,16 @@ - ConstructionMaterial - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 500 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: IngotBase diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index 33f2c0ab16..bab92dbad4 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -56,6 +56,16 @@ - type: SpaceGarbage - type: Damageable damageModifierSet: Glass + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: StepTrigger intersectRatio: 0.2 - type: PreventableStepTrigger diff --git a/Resources/Prototypes/Entities/Objects/Misc/candles.yml b/Resources/Prototypes/Entities/Objects/Misc/candles.yml index 37cd942645..5710d7f11f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/candles.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/candles.yml @@ -1,6 +1,6 @@ - type: entity name: candle - parent: [ BaseItem, BaseItemDestructible ] + parent: BaseItem id: Candle description: A thin wick threaded through fat. components: @@ -52,6 +52,15 @@ shader: unshaded - type: Damageable damageModifierSet: Wood + - type: Injurable + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity name: red candle @@ -159,6 +168,15 @@ normalState: fire-small - type: Flammable firestacksOnIgnite: 2.0 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 60 + behaviors: + - !type:SpawnEntitiesBehavior + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity name: small red candle diff --git a/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml b/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml index 53c6a5aa64..6437b383e2 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml @@ -1,7 +1,8 @@ - type: entity - abstract: true - parent: [ BaseItem, BaseItemDestructible ] - id: BaseDeskBell + parent: BaseItem + id: EmptyDeskBell + name: unfinished desk bell + description: An empty bell missing its noise maker. components: - type: Sprite sprite: Objects/Misc/desk_bell.rsi @@ -9,15 +10,25 @@ - type: Construction graph: &BellGraph BellGraph node: start + - type: Damageable + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - - trigger: &DamageTrigger50 + - trigger: &DamageTrigger20 !type:DamageTrigger - damage: 50 + damage: 20 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 0 + max: 1 + - !type:DoActsBehavior + acts: ["Destruction"] - type: MeleeWeapon wideAnimationRotation: 180 soundHit: &BellSound @@ -38,23 +49,7 @@ sound: *BellSound - type: entity - parent: BaseDeskBell - id: EmptyDeskBell - name: unfinished desk bell - description: An empty bell missing its noise maker. - components: - - type: Destructible - thresholds: - - trigger: *DamageTrigger50 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 0 - max: 1 - -- type: entity - parent: BaseDeskBell + parent: EmptyDeskBell id: DeskBell name: desk bell description: The cornerstone of any customer service job. You feel an unending urge to ring it. @@ -69,8 +64,11 @@ node: deskBellNode - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: *DamageTrigger20 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: PartRodMetal1: @@ -78,6 +76,8 @@ max: 1 - !type:ChangeConstructionNodeBehavior node: start + - !type:DoActsBehavior + acts: ["Destruction"] - type: InteractionPopup successChance: 1 onActivate: true @@ -91,7 +91,7 @@ sound: *BellSound - type: entity - parent: BaseDeskBell + parent: EmptyDeskBell id: DeskBuzzer name: desk buzzer description: An advanced customer service tool. You feel an unending urge to buzz it. @@ -105,8 +105,11 @@ node: deskBuzzerNode - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: *DamageTrigger20 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: CableApcStack1: @@ -114,6 +117,8 @@ max: 2 - !type:ChangeConstructionNodeBehavior node: start + - !type:DoActsBehavior + acts: ["Destruction"] - type: StationAiWhitelist - type: InteractionPopup successChance: 1 @@ -139,7 +144,7 @@ sound: *BuzzerSound - type: entity - parent: BaseDeskBell + parent: EmptyDeskBell id: DeskHorn name: desk horn description: The cornerstone of any clown business. You feel an unending urge to honk it. @@ -153,8 +158,11 @@ node: deskHornNode - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: *DamageTrigger20 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: BikeHorn: @@ -162,6 +170,8 @@ max: 1 - !type:ChangeConstructionNodeBehavior node: start + - !type:DoActsBehavior + acts: ["Destruction"] - type: InteractionPopup successChance: 1 onActivate: true diff --git a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml index b49a5b5238..2407b539ec 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/kudzu.yml @@ -180,9 +180,8 @@ - id: MobLuminousPerson - type: entity - abstract: true parent: [ BaseKudzu, SolutionFood ] - id: BaseFleshKudzu + id: FleshKudzu name: tendons description: A rapidly growing cluster of meaty tendons. WHY ARE YOU STOPPING TO LOOK AT IT?! components: @@ -235,11 +234,23 @@ Heat: -1.0 Cold: -1.0 Blunt: -0.5 # Needs to be balanced (approx 3x) with vacuum damage to stall but not kill Kudzu + - type: Temperature + - type: TemperatureDamage + heatDamage: + types: + Heat: 10 + coldDamage: + types: + Cold: 5 #per second, scales with temperature & other constants + - type: Barotrauma + damage: + types: + Blunt: 0.10 #per second, scales with pressure and other constants. - type: Flammable fireSpread: true damage: - types: - Heat: 3 + types: + Heat: 3 - type: AtmosExposed - type: Edible # delightfully devilish ! delay: 0.5 @@ -264,29 +275,6 @@ - Meat - Ruminant -- type: entity - parent: BaseFleshKudzu - id: FleshKudzu - components: - - type: Temperature - - type: TemperatureDamage - heatDamage: - types: - Heat: 10 - coldDamage: - types: - Cold: 5 #per second, scales with temperature & other constants - coldDamageThreshold: 0 - - type: Barotrauma - damage: - types: - Blunt: 0.10 #per second, scales with pressure and other constants. - -- type: entity - parent: BaseFleshKudzu - id: FleshKudzuSpace - suffix: Space - - type: entity parent: [ BaseKudzu, BaseShadow ] id: ShadowKudzu diff --git a/Resources/Prototypes/Entities/Objects/Power/lights.yml b/Resources/Prototypes/Entities/Objects/Power/lights.yml index ebe53da8cf..85a7398473 100644 --- a/Resources/Prototypes/Entities/Objects/Power/lights.yml +++ b/Resources/Prototypes/Entities/Objects/Power/lights.yml @@ -1,7 +1,7 @@ - type: entity - abstract: true parent: BaseItem - id: BaseReplacementLight + id: BaseLightbulb + abstract: true components: - type: MeleeSound soundGroups: @@ -10,8 +10,8 @@ - type: Sprite sprite: Objects/Power/light_bulb.rsi layers: - - map: [ enum.LightBulbVisualLayers.Base ] - state: normal + - map: [ enum.LightBulbVisualLayers.Base ] + state: normal - type: LightBulb - type: Damageable - type: Injurable @@ -34,10 +34,10 @@ sound: collection: GlassBreak params: - volume: -4 + volume: -8 - !type:DoActsBehavior acts: [ "Breakage" ] - - trigger: &DamageTrigger10 + - trigger: !type:DamageTrigger damage: 10 behaviors: @@ -45,7 +45,12 @@ sound: collection: GlassBreak params: - volume: -4 + volume: -8 + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: Appearance @@ -61,24 +66,9 @@ - id: SheetGlass1 - type: entity - abstract: true - parent: BaseReplacementLight - id: BaseLightbulb - components: - - type: Destructible - thresholds: - - trigger: *DamageTrigger10 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - LightBulbBroken: - min: 1 - max: 1 - -- type: entity - abstract: true - parent: BaseReplacementLight + parent: BaseLightbulb id: BaseLightTube + abstract: true components: - type: Sprite sprite: Objects/Power/light_tube.rsi @@ -86,13 +76,29 @@ bulb: Tube - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 5 behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + - !type:DoActsBehavior + acts: [ "Breakage" ] + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - LightTubeBroken: + ShardGlass: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] # Lighting color values gathered from # https://andi-siess.de/rgb-to-color-temperature/ diff --git a/Resources/Prototypes/Entities/Objects/Power/powersink.yml b/Resources/Prototypes/Entities/Objects/Power/powersink.yml index f89af1986b..5b273ce150 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powersink.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powersink.yml @@ -1,6 +1,6 @@ - type: entity id: PowerSink - parent: [BaseMachine, BaseSyndicateContraband, BaseMachineDestructible] + parent: [BaseMachine, BaseSyndicateContraband] name: power sink description: Drains immense amounts of electricity from the grid. components: @@ -30,6 +30,14 @@ - MachineMask layer: - MachineLayer + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 25 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: PowerSink - type: Battery # Very important: @@ -50,11 +58,3 @@ location: location-powersink - type: StaticPrice price: 3000 - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 0496b67c61..c4f2182641 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -24,33 +24,28 @@ damageContainer: Shield - type: ExaminableDamage messages: ShieldMessages + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 125 #This is probably enough damage before it breaks + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel: + min: 2 + max: 2 + SheetGlass: + min: 2 + max: 2 - type: StaticPrice price: 100 -- type: entity - abstract: true - id: BaseShieldDestructible - components: - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 125 #This is probably enough damage before it breaks - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel: - min: 2 - max: 2 - SheetGlass: - min: 2 - max: 2 - - type: entity name: base repairable shield parent: BaseShield @@ -73,7 +68,7 @@ - type: entity name: riot shield - parent: [ BaseRepairableShield, BaseShieldDestructible, BaseSecurityContraband ] + parent: [ BaseRepairableShield, BaseSecurityContraband ] id: RiotShield description: A large tower shield. Good for controlling crowds. components: @@ -89,7 +84,7 @@ - type: entity name: laser shield - parent: [ BaseRepairableShield, BaseShieldDestructible, BaseSecurityContraband ] + parent: [ BaseRepairableShield, BaseSecurityContraband ] id: RiotLaserShield description: A shield built for withstanding lasers, but not much else. components: @@ -107,7 +102,7 @@ - type: entity name: ballistic shield - parent: [ BaseRepairableShield, BaseShieldDestructible, BaseSecurityContraband ] + parent: [ BaseRepairableShield, BaseSecurityContraband ] id: RiotBulletShield description: A shield built for protecting against ballistics, but not much else. components: @@ -273,7 +268,7 @@ - type: entity name: clockwork shield - parent: [ BaseRepairableShield, BaseShieldDestructible ] + parent: BaseRepairableShield id: ClockworkShield description: Ratvar oyrffrf lbh jvgu uvf cebgrpgvba. components: @@ -430,7 +425,7 @@ - type: entity name: telescopic shield - parent: [ BaseRepairableShield, BaseShieldDestructible ] + parent: BaseRepairableShield id: TelescopicShield description: An advanced riot shield made of lightweight materials that collapses for easy storage. components: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml index 329ff6b0ce..ed58e56aa3 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml @@ -19,11 +19,6 @@ tags: - Trash - CentrifugeCompatible # unique feature of vials - - type: DamageOnLand - ignoreResistances: true - damage: - types: - Blunt: 3 # can be thrown once without breaking ## Entities @@ -48,14 +43,20 @@ thresholds: - trigger: !type:DamageTrigger - damage: 5 + damage: 15 # stronger than base behaviors: + - &SoundGlassBreak !type:PlaySoundBehavior + sound: + collection: GlassBreak + - !type:SpillBehavior { } - !type:SpawnEntitiesBehavior spawn: - ShardGlass: + ShardGlass: # less glass than base min: 0 max: 1 transferForensics: true + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: [SolutionVeryTiny, BaseChemistryVial] @@ -77,6 +78,16 @@ - type: PhysicalComposition materialComposition: Glass: 10 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 5 # smaller so weaker + behaviors: # remove glass shard spawn + - *SoundGlassBreak + - !type:SpillBehavior { } + - !type:DoActsBehavior + acts: [ "Destruction" ] ## Reagent filled diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml index 6ad7c91870..15feb76cf5 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml @@ -1,7 +1,7 @@ - type: entity - abstract: true + id: BaseTarget parent: BaseStructureDynamic - id: BaseTargetIndestructible + abstract: true components: - type: Sprite sprite: Objects/Specific/Security/target.rsi @@ -27,12 +27,6 @@ - type: Damageable - type: Injurable damageContainer: Inorganic - -- type: entity - abstract: true - parent: BaseTargetIndestructible - id: BaseTarget - components: - type: Destructible thresholds: - trigger: @@ -50,11 +44,10 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - - type: entity - parent: BaseTarget - id: TargetHuman name: human target + id: TargetHuman + parent: BaseTarget description: A shooting target. This one is a human. components: - type: Sprite @@ -62,9 +55,9 @@ state: target_h - type: entity - parent: BaseTarget - id: TargetSyndicate name: syndicate target + id: TargetSyndicate + parent: BaseTarget description: A shooting target. This one is a syndicate agent. components: - type: Sprite @@ -72,9 +65,9 @@ state: target_s - type: entity - parent: BaseTarget - id: TargetClown name: clown target + id: TargetClown + parent: BaseTarget description: A shooting target. This one is a clown. components: - type: Sprite @@ -83,11 +76,27 @@ # put it on a salvage or something - type: entity - parent: BaseTargetIndestructible - id: TargetStrange name: strange target + id: TargetStrange + parent: BaseTarget description: A shooting target. You aren't quite sure what this one is, but it seems to be extra robust. components: - type: Sprite sprite: Objects/Specific/Security/target.rsi state: target_f + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 2000 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel: + min: 10 + max: 10 + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:DoActsBehavior + acts: [ "Destruction" ] diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml index 4884ae457c..4d54bfb236 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml @@ -1,7 +1,7 @@ - type: entity - abstract: true - parent: [ BaseItem, BaseItemDestructible ] + parent: BaseItem id: BaseVendingMachineRestock + abstract: true name: vending machine restock box description: A box for restocking vending machines with corporate goodies. components: @@ -24,16 +24,20 @@ size: Normal - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 50 + damage: 20 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - !type:DumpRestockInventory + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity parent: BaseVendingMachineRestock diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index 03bd2a5e03..76d48ed4e3 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -4,7 +4,7 @@ - type: entity abstract: true - parent: [SolutionCompositeSmallStackable, BaseItem, BaseItemDestructible] + parent: [SolutionCompositeSmallStackable, BaseItem] id: CableStack name: cable stack suffix: Full @@ -36,8 +36,18 @@ - Power - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Extractable grindableSolutionName: composite + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity id: CableHVStack diff --git a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml index 764a82183c..336ee6b8a9 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml @@ -50,10 +50,10 @@ map: ["foldedLayer"] - type: entity - parent: [ BaseItem, BaseItemDestructible ] id: Fulton - name: fulton + parent: BaseItem suffix: Full + name: fulton description: Used to extract containers, items, or forcibly recruit people into your base of operations. components: - type: Fulton @@ -71,6 +71,17 @@ drawdepth: SmallObjects sprite: Objects/Tools/fulton.rsi state: extraction_pack + - type: Damageable + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity id: Fulton1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml index 20dcde15a6..5dd20c9c34 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml @@ -92,7 +92,6 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior # todo this is not a good way to be doing this. Should probably use a construction graph - offset: 0 spawn: WeaponTurretSyndicateDisposable: min: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml index dae2f9da1a..27862d7a4f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml @@ -35,6 +35,7 @@ Quantity: 3 - ReagentId: Charcoal Quantity: 2 + - type: Damageable - type: Injurable damageContainer: StructuralInorganic - type: Destructible # should have the same general explosive behavior as in cables.yml & detonator.yml @@ -47,8 +48,12 @@ - !type:DoActsBehavior acts: ["Destruction"] - !type:ExplodeBehavior - # the 50 damage destruction node is inherited from the parent - # idea here is to prevent you from just beating it until it explodes. + - trigger: + !type:DamageTrigger # the idea here is to prevent you from just beating it until it explodes. + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Explosive explosionType: DemolitionCharge totalIntensity: 60 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml index 17ad36f4c4..b59459bd10 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseItem, BaseItemDestructible, BaseSecurityContraband ] + parent: [ BaseItem, BaseSecurityContraband ] id: EmptyDetonator name: detonator cap description: A detonator cap. Requires a trigger and wire. @@ -15,6 +15,7 @@ - type: Construction graph: DetonatorGraph node: emptyDetonator + - type: Damageable - type: Injurable damageContainer: StructuralInorganic - type: Destructible @@ -27,8 +28,12 @@ - !type:TriggerBehavior - !type:DoActsBehavior acts: [ "Destruction" ] - # the 50 damage destruction node is inherited from the parent - # idea here is to prevent you from just beating it until it explodes. + - trigger: + !type:DamageTrigger # the idea here is to prevent you from just beating it until it explodes. + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml index 9d9eb78072..ce9943c7f6 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml @@ -2,7 +2,7 @@ # ideally it would be dynamic and work by actually sparking the solution but that doesnt exist yet :( # with that you could make napalm ied instead of welding fuel with no additional complexity - type: entity - parent: [ BaseItem, BaseItemDestructible, BaseMinorContraband ] + parent: [ BaseItem, BaseMinorContraband ] id: FireBomb name: fire bomb description: A weak, improvised incendiary device. @@ -41,12 +41,17 @@ - type: AnimationPlayer - type: TimerTriggerVisuals unprimedSprite: base + - type: Damageable + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 50 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:ExplodeBehavior - type: Construction graph: FireBomb diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml index c2d13900bb..10fc8c3167 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml @@ -41,17 +41,22 @@ - type: entity abstract: true - parent: [ BaseItem, BaseItemDestructible, BasePlasticExplosiveTrigger ] + parent: [ BaseItem, BasePlasticExplosiveTrigger ] id: BasePlasticExplosive components: - type: Item size: Small + - type: Damageable + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 50 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:ExplodeBehavior - type: Explosive # Powerful explosion in a very small radius. Doesn't break underplating. explosionType: DemolitionCharge diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml index 35becc49b8..b5abc8abb9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ BaseItem, BaseItemDestructible ] + parent: BaseItem id: BaseCartridge components: - type: Sprite @@ -16,6 +16,18 @@ - ItemMask restitution: 0.3 # fite me friction: 0.2 + - type: Damageable + damageModifierSet: StrongMetallic # We only want explosions breaking them (for the most part) + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 75 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Tag tags: - Cartridge diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml index ce56aa8c8d..bf22e87158 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml @@ -323,7 +323,6 @@ id: MeteorPotato name: Space potato description: A starchy threat from the depths of the space. Contains 200% of your daily sodium intake! - suffix: Meteor components: - type: Sprite state: potato @@ -350,72 +349,3 @@ min: 1 max: 5 - !type:ExplodeBehavior - -# Flesh Meteor -- type: entity - parent: BaseMeteor - id: MeteorFlesh - name: flesh meteor - description: A meteor covered in tendons. - components: - - type: Sprite - state: tendons - - type: Explosive - totalIntensity: 100 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 1000 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:WeightedSpawnEntityBehavior - weightedEntityTable: "MeteorSpawnFleshMonstersTable" - minSpawn: 1 - maxSpawn: 3 - spawnOffset: 1 - spawnAfter: 0.5 - - !type:SpawnEntitiesBehavior - spawn: - FleshKudzuSpace: - min: 1 - max: 3 - spawnAfter: 0.5 - offset: 1 - - !type:SpawnEntitiesBehavior - spawn: - FleshBlocker: - min: 1 - max: 2 - spawnAfter: 0.5 - offset: 2 - - !type:ExplodeBehavior - -# Kudzu Meteor -- type: entity - parent: BaseMeteor - id: MeteorKudzu - name: kudzu meteor - description: A meteor overgrown with kudzu. - components: - - type: Sprite - state: kudzu - - type: Explosive - totalIntensity: 100 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 1000 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:SpawnEntitiesBehavior - spawn: - Kudzu: - min: 1 - max: 3 - spawnAfter: 0.5 - offset: 1 - - !type:ExplodeBehavior diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml index f176281890..916e40d65e 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml @@ -8,7 +8,7 @@ - Syndicate - type: entity - parent: BaseWeaponBallisticTurretIndestructible + parent: BaseWeaponBallisticTurret id: WeaponTurretSyndicateDisposable name: disposable ballistic turret suffix: Syndicate, Disposable @@ -16,9 +16,6 @@ - type: NpcFactionMember factions: - Syndicate - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -81,7 +78,7 @@ - AllHostile - type: entity - parent: BaseWeaponBallisticTurretIndestructible + parent: BaseWeaponBallisticTurret id: WeaponTurretXeno name: xeno turret suffix: Xeno diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml index 4379ed8c15..1c331c1421 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml @@ -1,9 +1,10 @@ - type: entity - abstract: true parent: BaseStructure - id: BaseWeaponTurretIndestructible + id: BaseWeaponTurret name: turret + abstract: true components: + - type: Clickable - type: InteractionOutline - type: Actions - type: Fixtures @@ -31,6 +32,26 @@ path: /Audio/Effects/double_beep.ogg - type: CombatMode toggleMouseRotator: false + - type: Damageable + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 + # TODO: Construction graph + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 3 + max: 5 - type: HTN rootTask: task: TurretCompound @@ -49,41 +70,11 @@ context: "human" - type: entity - abstract: true - id: BaseTurretDestructible - components: - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 300 - # TODO: Construction graph - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 3 - max: 5 - -- type: entity - abstract: true - parent: [ BaseWeaponTurretIndestructible, BaseTurretDestructible ] - id: BaseWeaponTurret - -- type: entity - abstract: true - parent: BaseWeaponTurretIndestructible - id: BaseWeaponBallisticTurretIndestructible - name: ballistic turret + parent: BaseWeaponTurret + id: BaseWeaponBallisticTurret description: A ballistic machine gun auto-turret. + name: ballistic turret + abstract: true components: - type: ContainerContainer containers: @@ -100,16 +91,11 @@ capacity: 500 - type: entity - abstract: true - parent: [ BaseWeaponBallisticTurretIndestructible, BaseTurretDestructible ] - id: BaseWeaponBallisticTurret - -- type: entity - abstract: true - parent: BaseWeaponTurretIndestructible - id: BaseWeaponEnergyTurretIndestructible + parent: BaseWeaponTurret + id: BaseWeaponEnergyTurret name: laser turret description: An auto-turret armed with a heavy laser. Its weapon will recharge while connected to an active power grid. + abstract: true components: - type: Sprite sprite: Objects/Weapons/Guns/Turrets/sentry_turret.rsi @@ -149,8 +135,3 @@ task: EnergyTurretCompound - type: StaticPrice price: 200 - -- type: entity - abstract: true - parent: [ BaseWeaponEnergyTurretIndestructible, BaseTurretDestructible ] - id: BaseWeaponEnergyTurret diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml index 0977796d86..da88cccc8c 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [BaseWeaponEnergyTurretIndestructible, ConstructibleMachine] + parent: [BaseWeaponEnergyTurret, ConstructibleMachine] id: WeaponEnergyTurretStationBase name: sentry turret description: A high-tech autonomous weapons system designed to keep unauthorized personnel out of sensitive areas. @@ -87,8 +87,6 @@ deployedDamageModifierSetId: FlimsyMetallic - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: Repairable doAfterDelay: 10 allowSelfRepair: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index 4a28221fd0..69375a2e0d 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -189,11 +189,18 @@ !type:DamageTrigger damage: 20 behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + params: + volume: -4 - !type:SpawnEntitiesBehavior spawn: MaterialBones1: min: 1 max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity name: sharkminnow tooth spear diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml index 6c84c46495..5ba248eb05 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml @@ -1,6 +1,6 @@ -- type: entity - abstract: true +- type: entity # Starts fuse after taking 10 damage. parent: BaseItem + abstract: true id: GrenadeBase components: - type: Sprite @@ -34,8 +34,8 @@ friction: 0.2 - type: entity # Starts fuse after taking 10 damage. - abstract: true parent: GrenadeBase + abstract: true id: TimerGrenadeBase components: - type: TriggerOnUse @@ -55,15 +55,25 @@ Primed: { state: primed } Unprimed: { state: icon } -- type: entity +- type: entity # Starts fuse after taking 10 damage. + parent: GrenadeBase abstract: true - parent: [ GrenadeBase, VolatileGrenadeBase ] id: ImpactGrenadeBase components: - type: TriggerOnLand - type: LandAtCursor + - type: Destructible + thresholds: + - trigger: # immediately explode + !type:DamageTrigger + damage: 45 + behaviors: + - !type:TriggerBehavior + keyOut: timer + - !type:DoActsBehavior + acts: [ "Destruction" ] -- type: entity # Instantly detonates/activates after taking 45 damage. +- type: entity # Starts fuse after taking 10 damage, instantly detonates/activates after taking 45 damage. abstract: true id: VolatileGrenadeBase components: @@ -77,8 +87,13 @@ keyOut: timer - !type:DoActsBehavior acts: ["Destruction"] + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:TimerStartBehavior -- type: entity # Is destroyed without activating/detonating after taking 45 damage. +- type: entity # Starts fuse after taking 10 damage, is destroyed without activating/detonating after taking 45 damage. abstract: true id: FragileGrenadeBase components: @@ -90,3 +105,8 @@ behaviors: - !type:DoActsBehavior acts: ["Destruction"] + - trigger: + !type:DamageTrigger + damage: 10 + behaviors: + - !type:TimerStartBehavior diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 72c7ed11f3..711cc27d21 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -284,9 +284,9 @@ price: 1000 - type: entity - parent: [ VolatileGrenadeBase, TimerGrenadeBase ] name: the nuclear option description: Please don't throw it, think of the children. + parent: TimerGrenadeBase id: NuclearGrenade components: - type: Sprite @@ -301,16 +301,26 @@ totalIntensity: 20000 # ~15 tile radius. intensitySlope: 5 maxIntensity: 50 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:TriggerBehavior + keyOut: timer # immediately explode + - !type:DoActsBehavior + acts: ["Destruction"] - type: Appearance - type: TimerTriggerVisuals primingSound: path: /Audio/Effects/countdown.ogg - type: entity - parent: [ BaseItem, BaseItemDestructible ] - id: ModularGrenade name: modular grenade description: A grenade casing. Requires a trigger and a payload. + parent: BaseItem + id: ModularGrenade components: - type: Sprite sprite: Objects/Weapons/Grenades/modular.rsi @@ -326,6 +336,9 @@ - type: Construction graph: ModularGrenadeGraph node: emptyCase + - type: Damageable + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -333,6 +346,8 @@ damage: 50 behaviors: - !type:TriggerBehavior + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml index 435186f2f9..e0d5a5f23f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml @@ -93,7 +93,7 @@ price: 2500 - type: entity - parent: [ScatteringGrenadeBase, ImpactGrenadeBase, BaseSyndicateContraband] + parent: [FragileGrenadeBase, ScatteringGrenadeBase, ImpactGrenadeBase, BaseSyndicateContraband] id: ClusterBananaPeel name: cluster banana peel description: Splits into 6 explosive banana peels after throwing, guaranteed fun! diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index c562dd427f..fe8f5655af 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -187,7 +187,7 @@ - type: entity name: portable flasher - parent: [BaseMachine, BaseSecurityContraband, BaseMachineDestructible] + parent: [BaseMachine, BaseSecurityContraband] id: PortableFlasher description: An ultrabright flashbulb with a proximity trigger, useful for making an area security-only. components: @@ -231,11 +231,3 @@ guides: - Security - Antagonists - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak diff --git a/Resources/Prototypes/Entities/Objects/base_item.yml b/Resources/Prototypes/Entities/Objects/base_item.yml index 31a5364c4b..a83d50842f 100644 --- a/Resources/Prototypes/Entities/Objects/base_item.yml +++ b/Resources/Prototypes/Entities/Objects/base_item.yml @@ -1,7 +1,7 @@ - type: entity - abstract: true - id: BaseItem name: "item" + id: BaseItem + abstract: true components: - type: Item size: Small @@ -47,22 +47,6 @@ - type: Rotatable increment: 30 -- type: entity - abstract: true - id: BaseItemDestructible # Should be replaced by a variety of destruction bases, possibly combined with drink_base_materials.yml - components: - - type: Damageable - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - type: entity name: "storage item" id: BaseStorageItem diff --git a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml index c178137d40..b9e2e4a238 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml @@ -1,13 +1,14 @@ - type: entity - abstract: true + id: CrystalGreen parent: BaseStructure - id: BaseCrystalStalagmite + suffix: green name: crystal description: A crystaline solid. components: - type: Sprite sprite: Structures/Decoration/crystal.rsi state: crystal_grey + color: "#52ff39" noRot: true - type: Reflect reflectProb: 0.5 @@ -35,156 +36,219 @@ - type: PointLight radius: 3 energy: 3 + color: "#52ff39" - type: Damageable damageModifierSet: Glass - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: &DamageTrigger20 + - trigger: !type:DamageTrigger damage: 20 behaviors: - !type:PlaySoundBehavior sound: collection: GlassBreak + - !type:SpawnEntitiesBehavior + spawn: + ShardCrystalGreen: + min: 1 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: entity - parent: BaseCrystalStalagmite - id: CrystalGreen - suffix: green - components: - - type: Sprite - color: "#52ff39" - - type: PointLight - color: "#52ff39" - - type: Destructible - thresholds: - - trigger: *DamageTrigger20 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardCrystalGreen: &Min1Max2 - min: 1 - max: 2 - -- type: entity - parent: BaseCrystalStalagmite id: CrystalPink + parent: CrystalGreen suffix: pink components: - type: Sprite color: "#ff66cc" - type: PointLight + radius: 3 + energy: 3 color: "#ff66cc" - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: + !type:DamageTrigger + damage: 20 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalPink: *Min1Max2 + ShardCrystalPink: + min: 1 + max: 1 - type: entity - parent: BaseCrystalStalagmite id: CrystalGrey + parent: CrystalGreen suffix: red components: - type: Sprite + state: crystal_grey color: "#fb4747" - type: PointLight color: "#fb4747" - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: + !type:DamageTrigger + damage: 20 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalRed: *Min1Max2 + ShardCrystalRed: + min: 1 + max: 2 - type: entity - parent: BaseCrystalStalagmite id: CrystalOrange + parent: CrystalGreen suffix: orange components: - type: Sprite color: "#ff8227" - type: PointLight + radius: 3 + energy: 3 color: "#ff8227" - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: + !type:DamageTrigger + damage: 20 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalOrange: *Min1Max2 + ShardCrystalOrange: + min: 1 + max: 2 - type: entity - parent: BaseCrystalStalagmite id: CrystalBlack + parent: CrystalGreen suffix: black components: - type: Sprite color: "#363636" - type: PointLight + radius: 3 + energy: 3 color: "#363636" - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: + !type:DamageTrigger + damage: 20 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalBlack: *Min1Max2 + ShardCrystalBlack: + min: 1 + max: 2 - type: entity - parent: BaseCrystalStalagmite id: CrystalBlue + parent: CrystalGreen suffix: blue components: - type: Sprite color: "#39a1ff" - type: PointLight + radius: 3 + energy: 3 color: "#39a1ff" - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: + !type:DamageTrigger + damage: 20 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalBlue: *Min1Max2 + ShardCrystalBlue: + min: 1 + max: 2 - type: entity - parent: BaseCrystalStalagmite id: CrystalYellow + parent: CrystalGreen suffix: yellow components: - type: Sprite color: "#ffde46" - type: PointLight + radius: 3 + energy: 3 color: "#ffde46" - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: + !type:DamageTrigger + damage: 20 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalYellow: *Min1Max2 + ShardCrystalYellow: + min: 1 + max: 2 - type: entity - parent: BaseCrystalStalagmite id: CrystalCyan + parent: CrystalGreen suffix: cyan components: - type: Sprite color: "#47f8ff" - type: PointLight + radius: 3 + energy: 3 color: "#47f8ff" - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: + !type:DamageTrigger + damage: 20 behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalCyan: *Min1Max2 + ShardCrystalCyan: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index 3bcf8bfd60..4f8e90646a 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -1,7 +1,7 @@ - type: entity abstract: true id: ReagentDispenserBase - parent: [ SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: SmallConstructibleMachine placement: mode: SnapgridCenter components: @@ -44,8 +44,10 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 200 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml index 7b9d55c01d..676b0481ba 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml @@ -16,6 +16,19 @@ - ChemDispensable - type: ApcPowerReceiver - type: ExtensionCableReceiver + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Machine board: ChemDispenserMachineCircuitboard - type: GuideHelp diff --git a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml index bf9388b05e..716d6980df 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml @@ -52,6 +52,14 @@ cost: 6 delay: 6 fx: EffectRCDDeconstruct6 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Occluder - type: BlockWeather diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml index d74866e329..2e820f8056 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml @@ -1,13 +1,14 @@ - type: entity - abstract: true - parent: BaseStructure - id: BaseWindoorAssembly + id: WindoorAssembly name: windoor assembly description: It opens, it closes, and you can see through it! - placement: - mode: SnapgridCenter + parent: BaseStructure components: - type: InteractionOutline + - type: Sprite + sprite: Structures/Doors/Windoors/windoor.rsi + layers: + - state: assembly - type: Physics - type: Fixtures fixtures: @@ -32,39 +33,28 @@ fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - - trigger: &DamageTrigger300 + - trigger: !type:DamageTrigger damage: 300 behaviors: - !type:DoActsBehavior acts: ["Destruction"] - -- type: entity - parent: BaseWindoorAssembly - id: WindoorAssembly - components: - - type: Sprite - sprite: Structures/Doors/Windoors/windoor.rsi - layers: - - state: assembly - - type: Destructible - thresholds: - - trigger: *DamageTrigger300 - behaviors: - !type:SpawnEntitiesBehavior spawn: - SheetSteel1: &BaseWindoorDrop + SheetSteel1: min: 1 max: 3 - type: Construction graph: Windoor node: assembly + placement: + mode: SnapgridCenter - type: entity - parent: BaseWindoorAssembly id: WindoorAssemblySecure name: secure windoor assembly description: It opens, it closes, and you can see through it! This one looks tough. + parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/windoor.rsi @@ -73,20 +63,26 @@ - state: assembly - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 600 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetPlasteel1: *BaseWindoorDrop + SheetPlasteel1: + min: 1 + max: 2 - type: Construction graph: Windoor node: assemblySecure - type: entity - parent: BaseWindoorAssembly id: WindoorAssemblyClockwork name: clockwork windoor assembly description: It opens, it closes, and you can see through it! This one looks tough. + parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/clockwork_windoor.rsi @@ -94,21 +90,27 @@ - state: open - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 450 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetBrass1: *BaseWindoorDrop + SheetBrass1: + min: 1 + max: 2 - type: Construction graph: Windoor node: assemblyClockwork #plasma windoor assemblies - type: entity - parent: BaseWindoorAssembly id: WindoorAssemblyPlasma name: plasma windoor assembly description: It opens, it closes, and you can see through it! This one looks purp-, no, pink. Wait... + parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi @@ -116,21 +118,29 @@ - state: assembly - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 360 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetSteel1: *BaseWindoorDrop - SheetPGlass1: *BaseWindoorDrop + SheetSteel1: + min: 1 + max: 2 + SheetPGlass1: + min: 1 + max: 3 - type: Construction graph: Windoor node: pglass - type: entity - parent: BaseWindoorAssembly id: WindoorAssemblySecurePlasma name: secure plasma windoor assembly description: It opens, it closes, and you can see through it! This one looks strong and pin-, no, purple. Hold on... + parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi @@ -139,24 +149,30 @@ - state: assembly - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 1200 behaviors: - !type:DoActsBehavior acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetPlasteel1: *BaseWindoorDrop - SheetRPGlass1: *BaseWindoorDrop + SheetPlasteel1: + min: 1 + max: 2 + SheetRPGlass1: + min: 1 + max: 3 - type: Construction graph: Windoor node: pglassSecure #uranium windoor assemblies - type: entity - parent: BaseWindoorAssembly id: WindoorAssemblyUranium name: uranium windoor assembly description: It opens, it closes, and you can see through it! This one looks sickly green... + parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi @@ -164,21 +180,29 @@ - state: assembly - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetSteel1: *BaseWindoorDrop - SheetUGlass1: *BaseWindoorDrop + SheetSteel1: + min: 1 + max: 2 + SheetUGlass1: + min: 1 + max: 3 - type: Construction graph: Windoor node: uglass - type: entity - parent: BaseWindoorAssembly id: WindoorAssemblySecureUranium name: secure uranium windoor assembly description: It opens, it closes, and you can see through it! This one looks strong and radioactive-lime-green! + parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi @@ -187,12 +211,20 @@ - state: assembly - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 1200 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetPlasteel1: *BaseWindoorDrop - SheetRUGlass1: *BaseWindoorDrop + SheetPlasteel1: + min: 1 + max: 2 + SheetRUGlass1: + min: 1 + max: 3 - type: Construction graph: Windoor node: uglassSecure diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml index 86d0d2bc8b..0f91871837 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml @@ -1,7 +1,8 @@ +#Normal windoors - type: entity + id: BaseWindoor + parent: [BaseDeltaPressureGlassQuarter, BaseStructure] abstract: true - parent: BaseStructure - id: BaseWindoorGeneric placement: mode: SnapgridCenter components: @@ -15,6 +16,7 @@ collection: GlassSmash - type: InteractionOutline - type: StationAiWhitelist + - type: Physics - type: Fixtures fixtures: fix1: @@ -27,6 +29,7 @@ layer: - GlassAirlockLayer - type: Sprite + sprite: Structures/Doors/Windoors/windoor.rsi layers: - state: closed map: ["enum.DoorVisualLayers.Base"] @@ -69,11 +72,11 @@ range: 200 - type: DeviceLinkSink ports: - - Open - - Close - - Toggle - - AutoClose - - DoorBolt + - Open + - Close + - Toggle + - AutoClose + - DoorBolt - type: DeviceLinkSource ports: - DoorStatus @@ -89,6 +92,22 @@ cost: 8 delay: 8 fx: EffectRCDDeconstruct8 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + SheetSteel1: + min: 2 + max: 4 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: ContainerFill containers: board: [ DoorElectronics ] @@ -144,23 +163,27 @@ - type: Airtight noAirWhenFullyAirBlocked: false airBlockedDirection: - - South + - South - type: Construction graph: Windoor + node: windoor containers: - board + - type: StaticPrice + price: 150 - type: PryUnpowered - type: Tag tags: - - DoorRemoteWhitelist - # This tag is used by door remotes to allow or not a door remote to normally be able to interact with a door + - DoorRemoteWhitelist + # This tag is used by door remotes to allow or not a door remote to normally be able to interact with a door - type: entity + id: BaseSecureWindoor + parent: [BaseDeltaPressureReinforcedGlassQuarter, BaseWindoor] abstract: true - parent: BaseWindoorGeneric - id: BaseSecureWindoorGeneric components: - type: Sprite + sprite: Structures/Doors/Windoors/windoor.rsi layers: - state: secure_underlay - state: closed @@ -196,43 +219,6 @@ visible: false - type: Damageable damageModifierSet: RGlass - - type: StaticPrice - price: 150 - -#Normal windoors -- type: entity - abstract: true - parent: [ BaseDeltaPressureGlassQuarter, BaseWindoorGeneric ] - id: BaseWindoor - components: - - type: Sprite - sprite: Structures/Doors/Windoors/windoor.rsi - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 200 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 2 - SheetSteel1: - min: 2 - max: 4 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: Construction - node: windoor - -- type: entity - abstract: true - parent: [ BaseDeltaPressureReinforcedGlassQuarter, BaseSecureWindoorGeneric ] - id: BaseSecureWindoor - components: - - type: Sprite - sprite: Structures/Doors/Windoors/windoor.rsi - type: Destructible thresholds: - trigger: @@ -264,12 +250,44 @@ #Plasma Windoors - type: entity - abstract: true - parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoorGeneric] id: BasePlasmaWindoor + parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoor] + abstract: true components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi + layers: + - state: closed + map: [ "enum.DoorVisualLayers.Base" ] + - state: closed_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseUnlit" ] + visible: false + - state: welded + map: [ "enum.WeldableLayers.BaseWelded" ] + - state: bolted_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseBolted" ] + - state: emergency_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] + - state: panel_open + map: [ "enum.WiresVisualLayers.MaintenancePanel" ] + visible: false + - state: electrified_ai + sprite: Interface/Misc/ai_hud.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.HUD" ] + - state: electrified + sprite: Effects/electricity.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.Sparks" ] + - state: sparks + map: ["enum.DoorVisualLayers.BaseEmagging"] + shader: unshaded + visible: false - type: Destructible thresholds: - trigger: @@ -295,12 +313,45 @@ resistance: 2 - type: entity - abstract: true - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoorGeneric] id: BaseSecurePlasmaWindoor + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoor] + abstract: true components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi + layers: + - state: secure_underlay + - state: closed + map: [ "enum.DoorVisualLayers.Base" ] + - state: closed_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseUnlit" ] + visible: false + - state: welded + map: [ "enum.WeldableLayers.BaseWelded" ] + - state: bolted_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseBolted" ] + - state: emergency_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] + - state: panel_open + map: [ "enum.WiresVisualLayers.MaintenancePanel" ] + visible: false + - state: electrified_ai + sprite: Interface/Misc/ai_hud.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.HUD" ] + - state: electrified + sprite: Effects/electricity.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.Sparks" ] + - state: sparks + map: ["enum.DoorVisualLayers.BaseEmagging"] + shader: unshaded + visible: false - type: Destructible thresholds: - trigger: @@ -334,12 +385,44 @@ #Uranium Windoors - type: entity - abstract: true - parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoorGeneric] id: BaseUraniumWindoor + parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoor] + abstract: true components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi + layers: + - state: closed + map: [ "enum.DoorVisualLayers.Base" ] + - state: closed_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseUnlit" ] + visible: false + - state: welded + map: [ "enum.WeldableLayers.BaseWelded" ] + - state: bolted_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseBolted" ] + - state: emergency_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] + - state: panel_open + map: [ "enum.WiresVisualLayers.MaintenancePanel" ] + visible: false + - state: electrified_ai + sprite: Interface/Misc/ai_hud.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.HUD" ] + - state: electrified + sprite: Effects/electricity.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.Sparks" ] + - state: sparks + map: ["enum.DoorVisualLayers.BaseEmagging"] + shader: unshaded + visible: false - type: Destructible thresholds: - trigger: @@ -365,12 +448,45 @@ resistance: 3 - type: entity - abstract: true - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoorGeneric] id: BaseSecureUraniumWindoor + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoor] + abstract: true components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi + layers: + - state: secure_underlay + - state: closed + map: [ "enum.DoorVisualLayers.Base" ] + - state: closed_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseUnlit" ] + visible: false + - state: welded + map: [ "enum.WeldableLayers.BaseWelded" ] + - state: bolted_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseBolted" ] + - state: emergency_unlit + shader: unshaded + map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] + - state: panel_open + map: [ "enum.WiresVisualLayers.MaintenancePanel" ] + visible: false + - state: electrified_ai + sprite: Interface/Misc/ai_hud.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.HUD" ] + - state: electrified + sprite: Effects/electricity.rsi + shader: unshaded + visible: false + map: [ "enum.ElectrifiedLayers.Sparks" ] + - state: sparks + map: ["enum.DoorVisualLayers.BaseEmagging"] + shader: unshaded + visible: false - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml index 24a42d6ed4..e0a726e9c4 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml @@ -1,8 +1,8 @@ - type: entity - abstract: true - parent: BaseWindoorGeneric id: BaseClockworkWindoor name: clockwork windoor + parent: BaseWindoor + abstract: true components: - type: Sprite sprite: Structures/Doors/Windoors/clockwork_windoor.rsi diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml index f51b0b6a98..aa914b544a 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml @@ -1,9 +1,9 @@ - type: entity - abstract: true - parent: BaseStructure id: TableBase + parent: BaseStructure name: table description: A square piece of metal standing on four metal legs. + abstract: true components: - type: Animateable - type: Damageable @@ -43,10 +43,10 @@ - ForceFixRotations - type: entity - abstract: true - parent: TableBase id: CounterBase + parent: TableBase name: counter + abstract: true components: - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml index 20678a0e5d..bacad30788 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml @@ -1,7 +1,7 @@ - type: entity - parent: BaseStructure id: TableFrame # BaseStructure and not BaseTable, since these shouldn't be climbable/placeable. + parent: BaseStructure name: table frame description: Pieces of metal that make the frame of a table. components: @@ -51,8 +51,8 @@ node: TableFrame - type: entity - parent: BaseStructure id: CounterWoodFrame + parent: BaseStructure name: wooden counter frame description: Pieces of wood that make the frame of a table. components: @@ -101,28 +101,16 @@ node: CounterWoodFrame - type: entity - parent: BaseStructure id: CounterMetalFrame + parent: CounterWoodFrame name: metal counter frame description: Pieces of metal that make the frame of a table. components: - - type: SpriteFade - type: Sprite sprite: Structures/Furniture/Tables/frame.rsi - type: Icon sprite: Structures/Furniture/Tables/frame.rsi state: full - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.45,-0.45,0.45,0.45" - density: 55 - mask: - - TableMask - layer: - - TableLayer - type: Damageable damageModifierSet: Metallic - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml index 8663834053..0855cef8d0 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml @@ -1,7 +1,8 @@ - type: entity - abstract: true + name: bed + id: Bed parent: BaseStructure - id: BaseBed + description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing. components: - type: HealOnBuckle damage: @@ -38,18 +39,6 @@ damageModifierSet: Metallic - type: Injurable damageContainer: Inorganic - - type: Transform - anchored: true - noRot: true - - type: Anchorable - - type: Pullable - -- type: entity - parent: BaseBed - id: Bed - name: bed - description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing. - components: - type: Destructible thresholds: - trigger: @@ -63,6 +52,12 @@ SheetSteel1: min: 1 max: 2 + - type: Transform + anchored: true + noRot: true + - type: Anchorable + - type: Pullable + - type: entity parent: Bed @@ -87,7 +82,7 @@ - type: AmbientMusicMarkerMedical - type: entity - parent: BaseBed + parent: Bed id: DogBed name: dog bed description: A comfy-looking dog bed. You can even strap your pet in, in case the gravity turns off. @@ -131,7 +126,7 @@ damageModifierSet: Inflatable - type: entity - parent: BaseBed + parent: Bed id: WebBed name: web bed description: You got webbed. @@ -162,7 +157,7 @@ node: bed - type: entity - parent: BaseBed + parent: Bed id: PsychBed name: psychologist bed description: An upholstered bed for the psychological care of patients. diff --git a/Resources/Prototypes/Entities/Structures/Furniture/bench.yml b/Resources/Prototypes/Entities/Structures/Furniture/bench.yml index d43e603e38..ce8f8b5686 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/bench.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/bench.yml @@ -17,17 +17,6 @@ bodyType: Static - type: StaticPrice price: 35 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity id: BenchColorfulComfy diff --git a/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml b/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml index a302e5c7f7..812cf68a31 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml @@ -1,7 +1,7 @@ # TODO move all of this to tiles once tile smoothing is supported - type: entity - parent: BaseStructure id: CarpetBase + parent: BaseStructure name: carpet description: "Fancy walking surface." abstract: true @@ -33,7 +33,7 @@ damageContainer: Inorganic - type: Destructible thresholds: - - trigger: &DamageTrigger10 + - trigger: !type:DamageTrigger damage: 10 behaviors: @@ -55,11 +55,15 @@ sprite: Structures/Furniture/Carpets/red_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemRed: &BaseCarpetSpawn + FloorCarpetItemRed: min: 1 max: 1 @@ -75,11 +79,17 @@ sprite: Structures/Furniture/Carpets/black_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemBlack: *BaseCarpetSpawn + FloorCarpetItemBlack: + min: 1 + max: 1 - type: entity id: CarpetPink @@ -93,11 +103,17 @@ sprite: Structures/Furniture/Carpets/pink_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemPink: *BaseCarpetSpawn + FloorCarpetItemPink: + min: 1 + max: 1 - type: entity id: CarpetBlue @@ -111,11 +127,17 @@ sprite: Structures/Furniture/Carpets/blue_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemBlue: *BaseCarpetSpawn + FloorCarpetItemBlue: + min: 1 + max: 1 - type: entity id: CarpetGreen @@ -129,11 +151,17 @@ sprite: Structures/Furniture/Carpets/green_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemGreen: *BaseCarpetSpawn + FloorCarpetItemGreen: + min: 1 + max: 1 - type: entity id: CarpetOrange @@ -147,11 +175,17 @@ sprite: Structures/Furniture/Carpets/orange_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemOrange: *BaseCarpetSpawn + FloorCarpetItemOrange: + min: 1 + max: 1 - type: entity id: CarpetSBlue @@ -165,11 +199,17 @@ sprite: Structures/Furniture/Carpets/skyblue_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemSkyBlue: *BaseCarpetSpawn + FloorCarpetItemSkyBlue: + min: 1 + max: 1 - type: entity id: CarpetPurple @@ -183,11 +223,17 @@ sprite: Structures/Furniture/Carpets/purple_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemPurple: *BaseCarpetSpawn + FloorCarpetItemPurple: + min: 1 + max: 1 - type: entity id: CarpetCyan @@ -201,11 +247,17 @@ sprite: Structures/Furniture/Carpets/cyan_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemCyan: *BaseCarpetSpawn + FloorCarpetItemCyan: + min: 1 + max: 1 - type: entity id: CarpetWhite @@ -219,16 +271,22 @@ sprite: Structures/Furniture/Carpets/white_carpet.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemWhite: *BaseCarpetSpawn + FloorCarpetItemWhite: + min: 1 + max: 1 # TODO nuke this once tiles support rotating sprites - type: entity - parent: BaseStructure id: CarpetChapel + parent: BaseStructure name: "chapel's carpet" components: - type: Sprite @@ -249,7 +307,9 @@ damageContainer: Inorganic - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] @@ -258,8 +318,8 @@ #cardpet - type: entity - parent: BaseStructure id: CarpetCard + parent: BaseStructure name: cardboard "carpet" description: "Even lino is better." components: @@ -288,13 +348,17 @@ damageContainer: Inorganic - type: Destructible thresholds: - - trigger: *DamageTrigger10 + - trigger: + !type:DamageTrigger + damage: 10 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - MaterialCardboard: *BaseCarpetSpawn + MaterialCardboard: + min: 1 + max: 1 - type: ToolRefinable refineResult: - id: MaterialCardboard1 diff --git a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml index 6a127b9958..9fe9e91d87 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml @@ -1,7 +1,7 @@ - type: entity - abstract: true - id: SeatBase name: chair + id: SeatBase + abstract: true description: You sit in this. Either by will or force. placement: mode: PlaceFree @@ -31,6 +31,17 @@ damageModifierSet: Metallic - type: Injurable damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: StaticPrice price: 50 @@ -67,17 +78,6 @@ components: - type: Rotatable rotateWhileAnchored: true - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak #Starts anchored, can be rotated while anchored - type: entity @@ -103,17 +103,6 @@ - type: Construction graph: Seat node: chair - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity name: chair @@ -135,17 +124,6 @@ - type: Construction graph: Seat node: stool - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity name: bar stool @@ -202,17 +180,6 @@ - type: Construction graph: Seat node: chairComfy - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity name: pilot seat @@ -225,17 +192,6 @@ - type: Construction graph: Seat node: chairPilotSeat - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity name: wooden chair @@ -310,11 +266,18 @@ thresholds: - trigger: !type:DamageTrigger - damage: 25 + damage: 50 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:PlaySoundBehavior sound: path: /Audio/Voice/Human/womanlaugh.ogg + - !type:SpawnEntitiesBehavior + spawn: + MaterialWoodPlank: + min: 1 + max: 1 - type: Construction graph: RitualSeat node: chairCursed @@ -382,17 +345,6 @@ graph: Seat node: chairFolding - type: DamageExaminable - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity parent: ChairFolding @@ -415,17 +367,6 @@ - type: Construction graph: Seat node: chairSteelBench - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity name: cardboard stool @@ -440,6 +381,8 @@ node: stoolCard - type: Damageable damageModifierSet: Card + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml index dcf5aa88bb..8eef044346 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml @@ -117,17 +117,6 @@ reagents: - ReagentId: Water Quantity: 1 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak # constructed toilets don't come with Rummageable or plungeruse component to avoid infinite item spawning. - type: entity @@ -207,8 +196,15 @@ thresholds: - trigger: !type:DamageTrigger - damage: 50 + damage: 100 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + params: + volume: -6 - !type:SpawnEntitiesBehavior spawn: IngotGold1: diff --git a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml index 2d2c0cd789..3c4238eff9 100644 --- a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml +++ b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml @@ -1,6 +1,7 @@ - type: entity - abstract: true - id: BaseHoloSign + id: HolosignWetFloor + name: wet floor sign + description: The words flicker as if they mean nothing. placement: mode: SnapgridCenter components: @@ -9,22 +10,15 @@ - type: Physics bodyType: Static canCollide: false + - type: Sprite + sprite: Structures/Holo/wetfloor.rsi + state: icon - type: TimedDespawn lifetime: 90 - type: Clickable - type: Damageable - type: Injurable damageContainer: Inorganic - -- type: entity - parent: BaseHoloSign - id: HolosignWetFloor - name: wet floor sign - description: The words flicker as if they mean nothing. - components: - - type: Sprite - sprite: Structures/Holo/wetfloor.rsi - state: icon - type: Destructible thresholds: - trigger: @@ -35,8 +29,8 @@ acts: [ "Destruction" ] - type: entity - parent: BaseHoloSign id: HoloFan + parent: HolosignWetFloor name: holofan description: A barrier of hard light that blocks air, but nothing else. components: @@ -53,18 +47,10 @@ lifetime: 180 - type: Airtight noAirWhenFullyAirBlocked: false - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 30 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity - parent: BaseHoloSign id: HoloPeel + parent: HolosignWetFloor name: holopeel description: A banana peel made of slippery hard light, watch your step! components: @@ -72,6 +58,7 @@ sprite: Structures/Holo/peel.rsi state: icon - type: Physics + bodyType: Static canCollide: true - type: Slippery - type: StepTrigger @@ -99,12 +86,13 @@ acts: [ "Destruction" ] - type: entity - parent: BaseHoloSign id: HolosignSecurity + parent: HolosignWetFloor name: holographic barrier description: A barrier of hard light that blocks movement, but pretty weak. components: - type: Physics + bodyType: Static canCollide: true - type: Sprite sprite: Structures/Holo/security.rsi @@ -126,22 +114,15 @@ radius: 3 color: red - type: Climbable - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 30 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity - parent: BaseHoloSign id: HolosignForcefield + parent: HolosignWetFloor name: holographic force field description: A powerful temporal containment field that doesn't let anything through, not even a tesla or singularity. components: - type: Physics + bodyType: Static canCollide: true - type: Sprite sprite: Structures/Holo/field.rsi diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index 0c0224ebfe..7b9a89052e 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -5,12 +5,10 @@ #Basic lights - type: entity - abstract: true - id: BaseWallLight - placement: - mode: SnapgridCenter - snap: - - Wallmount + id: AlwaysPoweredWallLight + name: light + description: "An always powered light." + suffix: Always powered components: - type: MeleeSound soundGroups: @@ -20,7 +18,11 @@ anchored: true - type: Clickable - type: InteractionOutline + - type: Construction + graph: LightFixture + node: tubeLight - type: Sprite + sprite: Structures/Wallmounts/Lighting/light_tube.rsi drawdepth: WallMountedItems layers: - map: ["enum.PoweredLightLayers.Base"] @@ -28,6 +30,7 @@ - map: ["enum.PoweredLightLayers.Glow"] state: glow shader: unshaded + state: base - type: PointLight color: "#FFE4CE" # 5000K color temp energy: 0.8 @@ -62,43 +65,22 @@ damage: 50 behaviors: - !type:EmptyAllContainersBehaviour - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - - type: PlacementReplacement - key: lights - -- type: entity - parent: BaseWallLight - id: AlwaysPoweredWallLight - name: light - suffix: Always powered - description: "An always powered light." - components: - - type: Construction - graph: LightFixture - node: tubeLight - - type: Sprite - sprite: Structures/Wallmounts/Lighting/light_tube.rsi - layers: - - map: ["enum.PoweredLightLayers.Base"] - state: base - - map: ["enum.PoweredLightLayers.Glow"] - state: glow - shader: unshaded - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - !type:SpawnEntitiesBehavior spawn: SheetSteel1: min: 2 max: 2 + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + - type: PlacementReplacement + key: lights + placement: + mode: SnapgridCenter + snap: + - Wallmount - type: entity name: light @@ -259,11 +241,11 @@ #Small lights - type: entity - parent: BaseWallLight - id: SmallLight name: small light - suffix: Always Powered description: "An always powered light." + id: SmallLight + suffix: Always Powered + parent: AlwaysPoweredWallLight components: - type: AmbientSound volume: -15 @@ -278,6 +260,8 @@ radius: 6 softness: 1.1 enabled: true + - type: Physics + bodyType: Static - type: Fixtures fixtures: fix1: @@ -289,17 +273,23 @@ - None layer: - TabletopMachineLayer + - type: Damageable + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 50 + damage: 25 behaviors: + - !type:EmptyAllContainersBehaviour - !type:SpawnEntitiesBehavior spawn: SheetSteel1: min: 1 max: 1 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Construction graph: LightFixture node: bulbLight @@ -432,10 +422,11 @@ #Emergency Lights - type: entity - parent: BaseWallLight id: EmergencyLight name: emergency light description: A small light with an internal battery that turns on as soon as it stops receiving any power. Nanotrasen technology allows it to adapt its color to alert crew to the conditions of the station. + parent: AlwaysPoweredWallLight + suffix: "" components: - type: PointLight enabled: false @@ -470,6 +461,7 @@ color: "#7CFC00" shader: "unshaded" visible: false + - type: Appearance - type: Construction graph: LightFixture node: emergencyLight @@ -477,7 +469,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 50 + damage: 25 behaviors: - !type:SpawnEntitiesBehavior spawn: @@ -487,6 +479,15 @@ ShardGlass: min: 1 max: 1 + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + placement: + mode: SnapgridCenter + snap: + - Wallmount #Coloured lights diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml index 8272b8cd3d..6d6b2e4f77 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml @@ -1,8 +1,10 @@ - type: entity - abstract: true + id: BaseStructureComputer parent: BaseStructure - id: BaseStructureComputerIndestructible + abstract: true components: + - type: Physics + bodyType: Static - type: Fixtures fixtures: fix1: @@ -19,17 +21,9 @@ - type: Anchorable - type: Construction graph: Computer + node: frameUnsecured - type: Sprite drawdepth: Objects - -- type: entity - abstract: true - parent: BaseStructureComputerIndestructible - id: BaseStructureComputer - components: - - type: Construction - graph: Computer - node: frameUnsecured - type: Damageable damageModifierSet: Electronic - type: Injurable @@ -71,7 +65,7 @@ monitorUnsecured: { state: 4 } - type: entity - parent: BaseStructureComputerIndestructible + parent: BaseStructureComputer id: ComputerBroken name: broken computer description: This computer has seen better days. diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml index e22f777754..b6e8e791e6 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml @@ -1,6 +1,6 @@ - type: entity id: BiomassReclaimer - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: biomass reclaimer description: Reclaims biomass from corpses. Gruesome. placement: @@ -24,11 +24,3 @@ - type: GuideHelp guides: - Cloning - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml index 149876d29d..718a0ec886 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml @@ -1,6 +1,6 @@ - type: entity id: BaseTabletopChemicalMachine - parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] abstract: true components: - type: Transform @@ -36,14 +36,6 @@ mixer: !type:ContainerSlot machine_board: !type:Container machine_parts: !type:Container - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak - type: entity id: MachineElectrolysisUnit diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml index ad6c09834d..530bc36864 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml @@ -1,5 +1,5 @@ - type: entity - parent: [BaseStructure, ConstructibleMachine, BaseConstructibleMachineDestructible] # Not a BaseMachinePowered since we don't want the anchorable component + parent: [BaseStructure, ConstructibleMachine] # Not a BaseMachinePowered since we don't want the anchorable component id: CryoPod name: cryo pod description: A special machine intended to create a safe environment for the use of chemicals that react in cold environments. @@ -55,16 +55,22 @@ layoutId: CryoPod - type: Damageable damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 100 behaviors: - !type:EmptyAllContainersBehaviour - !type:PlaySoundBehavior sound: collection: WindowShatter + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: ApcPowerReceiver powerLoad: 3000 - type: ExtensionCableReceiver diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml index dff44d54f9..ad98f47e36 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml @@ -1,6 +1,6 @@ - type: entity id: DiseaseDiagnoser - parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: Disease Diagnoser Delta Extreme description: A machine that analyzes disease samples. placement: @@ -17,14 +17,6 @@ - type: Appearance - type: Machine board: DiagnoserMachineCircuitboard - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: entity name: disease diagnoser report diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml index 5fa16d2abd..49a77d1d09 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml @@ -1,6 +1,6 @@ - type: entity id: Vaccinator - parent: [ BaseMachinePowered, BaseMachineDestructible ] + parent: BaseMachinePowered name: vaccinator description: A machine that creates vaccines. placement: @@ -22,11 +22,3 @@ machine_board: !type:Container machine_parts: !type:Container - type: RequireProjectileTarget - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml index 7bfaabe2cb..f5d8c40545 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml @@ -1,6 +1,6 @@ - type: entity id: MachineAnomalyVessel - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: anomaly vessel description: A container able to harness a scan of an anomaly and turn it into research data. components: @@ -73,8 +73,10 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 150 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak @@ -111,7 +113,7 @@ - type: entity id: MachineAPE - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: A.P.E. description: An Anomalous Particle Emitter, capable of shooting out unstable particles which can interface with anomalies. components: @@ -146,14 +148,6 @@ - MachineMask layer: - MachineLayer - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: Rotatable rotateWhileAnchored: true - type: Machine diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml index 62f91e1f5c..de4ea19350 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml @@ -1,6 +1,6 @@ - type: entity id: MachineAnomalySynchronizer - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: anomaly synchronizer description: A sophisticated device that reads changes in anomalous waves, and converts them into energy signals. components: @@ -43,14 +43,6 @@ mask: - ItemMask hard: True - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak - type: Transform anchored: true noRot: false diff --git a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml index fc21d9e296..87dc468018 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml @@ -1,6 +1,6 @@ - type: entity id: MachineArtifactAnalyzer - parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: artifact analyzer description: A platform capable of performing analysis on various types of artifacts. components: @@ -45,14 +45,6 @@ - LowImpassable - BulletImpassable hard: False - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak - type: Transform anchored: true - type: ApcPowerReceiver @@ -89,7 +81,7 @@ - type: entity id: MachineArtifactCrusher - parent: [ ConstructibleMachine, BaseMachinePowered, BaseConstructibleMachineDestructible ] + parent: [ ConstructibleMachine, BaseMachinePowered ] name: artifact crusher description: Best not to let your fingers get stuck... components: @@ -129,17 +121,6 @@ - HighImpassable layer: - HighImpassable - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:EmptyContainersBehaviour - containers: - - entity_storage - type: EntityStorage capacity: 1 whitelist: diff --git a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml index 09ad3e4af0..c0c4135702 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml @@ -22,27 +22,21 @@ - MachineMask layer: - MachineLayer - -- type: entity - abstract: true - id: BaseMachineDestructible - components: - type: Damageable + damageModifierSet: StructuralMetallic - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: + !type:DamageTrigger + damage: 100 behaviors: - !type:DoActsBehavior acts: ["Destruction"] - - !type:SpawnEntitiesBehavior - offset: 0 - spawn: - MachineFrameDestroyed: - min: 1 - max: 1 + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity abstract: true @@ -74,43 +68,9 @@ - type: LightningTarget priority: 1 -- type: entity - abstract: true - id: BaseConstructibleMachineDestructible - components: - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - type: entity abstract: true parent: ConstructibleMachine id: SmallConstructibleMachine components: - type: RequireProjectileTarget - -- type: entity - abstract: true - id: BaseSmallConstructibleMachineDestructible - components: - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 100 - behaviors: - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml index 649704c0a8..72df7c9249 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml @@ -1,6 +1,6 @@ - type: entity id: ChemMaster - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: ChemMaster 4000 description: An industrial grade chemical manipulator with pill and bottle production included. placement: @@ -41,12 +41,17 @@ - MachineLayer - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: + !type:DamageTrigger + damage: 50 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: ActivatableUI key: enum.ChemMasterUiKey.Key - type: ActivatableUIRequiresPower diff --git a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml index a3ef94c834..bfbd05033f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml @@ -1,6 +1,6 @@ - type: entity id: CloningPod - parent: [ BaseMachinePowered, BaseConstructibleMachineDestructible ] + parent: BaseMachinePowered name: cloning pod description: A Cloning Pod. 50% reliable. components: @@ -32,14 +32,21 @@ - clonepod-bodyContainer - type: Damageable damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: + !type:DamageTrigger + damage: 100 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Machine board: CloningPodMachineCircuitboard - type: MaterialStorage diff --git a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml index bf2e5a3f62..9da9c5932b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml @@ -1,6 +1,6 @@ - type: entity id: FatExtractor - parent: [ BaseMachinePowered, BaseMachineDestructible ] + parent: BaseMachinePowered name: lipid extractor description: Safely and efficiently extracts excess fat from a subject. components: @@ -77,14 +77,21 @@ - entity_storage - type: Damageable damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: + !type:DamageTrigger + damage: 100 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Machine board: FatExtractorMachineCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml index 22c65d0e2d..3d1465993d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml @@ -14,7 +14,7 @@ - state: printing map: [ "printing" ] visible: false - - state: + - state: map: [ "enum.FaxMachineVisuals.VisualState" ] - type: Icon sprite: Structures/Machines/fax_machine.rsi @@ -33,16 +33,6 @@ - TabletopMachineMask layer: - TabletopMachineLayer - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:DoActsBehavior - acts: ["Destruction"] - type: ActivatableUI key: enum.FaxUiKey.Key - type: ActivatableUIRequiresPower @@ -99,7 +89,7 @@ suffix: CentCom components: - type: Sprite - layers: + layers: - state: icon color: "#bfe3ff" - state: idle @@ -107,7 +97,7 @@ - state: printing map: [ "printing" ] visible: false - - state: + - state: map: [ "enum.FaxMachineVisuals.VisualState" ] - type: FaxMachine name: "Central Command" @@ -120,7 +110,7 @@ suffix: Syndicate components: - type: Sprite - layers: + layers: - state: icon color: "#a3a3a3" - state: idle @@ -128,7 +118,7 @@ - state: printing map: [ "printing" ] visible: false - - state: + - state: map: [ "enum.FaxMachineVisuals.VisualState" ] - type: FaxMachine name: "ERR*?*%!" diff --git a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml index cc29264fc0..f7f1bcba1b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml @@ -1,6 +1,6 @@ - type: entity id: MachineFlatpacker - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: Flatpacker 1001 description: An industrial machine used for expediting machine construction across the station. components: @@ -30,14 +30,6 @@ anim: True: { visible: true } False: { visible: false } - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: FlatpackCreator baseMachineCost: Steel: 750 diff --git a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml index d78fb6464f..84948f38fb 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml @@ -81,7 +81,7 @@ price: 5000 - type: entity - parent: [ GravityGenerator, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ GravityGenerator, ConstructibleMachine ] id: GravityGeneratorMini name: mini gravity generator suffix: Charged @@ -115,11 +115,18 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 500 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak + - !type:SpawnEntitiesBehavior + spawn: + MachineFrameDestroyed: + min: 1 + max: 1 - type: WiresPanel - type: Machine board: MiniGravityGeneratorCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/holopad.yml b/Resources/Prototypes/Entities/Structures/Machines/holopad.yml index 1348a53418..5d1d61030d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/holopad.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/holopad.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] id: Holopad name: holopad description: "A floor-mounted device for projecting holographic images." @@ -94,11 +94,15 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 100 behaviors: - !type:PlaySoundBehavior sound: - collection: MetalGlassBreak + collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity name: long-range holopad diff --git a/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml b/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml index d1ba017bf5..5ef0deb154 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml @@ -1,7 +1,7 @@ # heats an entity or solution placed on it - type: entity abstract: true - parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] id: BaseHeaterMachine components: - type: ItemPlacer @@ -22,14 +22,6 @@ - TabletopMachineMask layer: - TabletopMachineLayer - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: ApcPowerReceiver powerLoad: 300 diff --git a/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml b/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml index 0ab1af87a0..e69e8ad4dc 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml @@ -1,7 +1,7 @@ - type: entity id: Jukebox name: jukebox - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] description: A machine capable of playing a wide variety of tunes. Enjoyment not guaranteed. components: - type: StationAiWhitelist @@ -37,15 +37,21 @@ layoutId: Jukebox - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 75 behaviors: - - !type:PlaySoundBehavior - sound: - collection: WoodDestroy + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 2 - type: Physics bodyType: Static - type: Fixtures diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index d54236a4a9..4bf527a977 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -1,6 +1,6 @@ - type: entity id: BaseLathe - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] abstract: true name: lathe components: @@ -23,11 +23,15 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 100 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: WiresPanel - type: ActivatableUI key: enum.LatheUiKey.Key diff --git a/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml b/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml index 30b8e551bb..e1223ed614 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml @@ -1,6 +1,6 @@ - type: entity id: CargoMailTeleporter - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: mail teleporter description: Periodically teleports in mail to deliver across the station. components: @@ -29,6 +29,8 @@ map: [ "enum.PowerDeviceVisualLayers.Powered" ] - type: Damageable damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic - type: ApcPowerReceiver powerLoad: 1000 - type: Appearance diff --git a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml index f3dbe73461..79aa7c2747 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml @@ -1,6 +1,6 @@ - type: entity id: MedicalScanner - parent: [ BaseMachinePowered, BaseConstructibleMachineDestructible ] + parent: BaseMachinePowered name: medical scanner description: A bulky medical scanner. components: @@ -52,15 +52,21 @@ machine_parts: !type:Container - type: Damageable damageModifierSet: StrongMetallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 100 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Machine board: MedicalScannerMachineCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml index 24304b809f..edc367a934 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml @@ -1,6 +1,6 @@ - type: entity id: KitchenMicrowave - parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: microwave description: It's magic. components: @@ -79,12 +79,17 @@ - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities + !type:DamageTrigger + damage: 200 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - trigger: !type:DamageTrigger damage: 100 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak + - !type:DoActsBehavior + acts: ["Breakage"] - type: Explosive explosionType: Default maxIntensity: 10 diff --git a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml index bbfb2c2d80..213e6df5ea 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml @@ -1,6 +1,6 @@ - type: entity id: KitchenReagentGrinder - parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, SmallConstructibleMachine ] name: reagent grinder description: From BlenderTech. Will It Blend? Let's find out! components: @@ -39,14 +39,6 @@ - TabletopMachineMask layer: - TabletopMachineLayer - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: Sprite sprite: Structures/Machines/grinder.rsi drawdepth: LargeObjects diff --git a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml index c095e8fad0..dad4176617 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] id: SalvageMagnet name: salvage magnet description: Pulls in salvage. diff --git a/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml b/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml index 6572e86da6..ec07294bfb 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml @@ -1,7 +1,7 @@ - type: entity id: SeedExtractor name: seed extractor - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] description: Extracts seeds from produce. components: - type: Sprite @@ -25,14 +25,6 @@ - MachineMask layer: - MachineLayer - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml index 0832a62b67..a99c3fdaf1 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml @@ -1,5 +1,5 @@ - type: entity - parent: [BaseStructureDynamic, ConstructibleMachine, BaseMachinePowered, BaseConstructibleMachineDestructible] + parent: [BaseStructureDynamic, ConstructibleMachine, BaseMachinePowered] id: SmartFridge name: SmartFridge description: A refrigerated storage unit for keeping items cold and fresh. @@ -98,14 +98,21 @@ - type: InteractionOutline - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: - !type:PlaySoundBehavior sound: - collection: MetalGlassBreak + collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: DamageOnHighSpeedImpact damage: types: diff --git a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml index a47b5cacdc..626c42213f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml @@ -1,7 +1,7 @@ - type: entity id: StasisBed name: stasis bed - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] description: A bed that massively slows down the patient's metabolism and prevents bodily decay, allowing more time to administer a proper treatment for stabilization. components: - type: StasisBed @@ -31,14 +31,21 @@ - type: ExtensionCableReceiver - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: + !type:DamageTrigger + damage: 75 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 2 - type: Strap position: Down rotation: -90 diff --git a/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml b/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml index f345fa3988..e94436ef77 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] id: SurveillanceCameraRouterBase name: camera router description: A surveillance camera router. It routes. Perhaps. @@ -33,14 +33,6 @@ enum.PowerDeviceVisualLayers.Powered: True: { visible: true } False: { visible: false } - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: Appearance - type: AmbientOnPowered - type: AmbientSound @@ -142,7 +134,7 @@ - type: entity abstract: true - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] id: SurveillanceCameraWirelessRouterBase name: wireless camera router description: A wireless surveillance camera router. It routes. Perhaps. @@ -175,14 +167,6 @@ enum.PowerDeviceVisualLayers.Powered: True: { visible: true } False: { visible: false } - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: Appearance - type: AmbientOnPowered - type: AmbientSound diff --git a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml index 69e875d945..fcb97f60d9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] id: TelecomServer name: telecommunication server description: When powered and filled with encryption keys it allows radio headset communication. @@ -158,12 +158,17 @@ - MachineLayer - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: + !type:DamageTrigger + damage: 100 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Machine board: TelecomServerCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml index aac88c7fb0..de155db63d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml @@ -2,7 +2,7 @@ - type: entity id: VendingMachine - parent: [ BaseMachinePowered, BaseMachineDestructible ] + parent: BaseMachinePowered name: vending machine description: Just add capitalism! abstract: true @@ -38,17 +38,21 @@ density: 200 - type: Destructible thresholds: - - trigger: !type:DamageTrigger - damage: 175 + - trigger: # Excess damage, don't do anything + !type:DamageTrigger + damage: 200 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - trigger: !type:DamageTrigger - damage: 75 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - trigger: + !type:DamageTrigger + damage: 100 behaviors: - !type:DoActsBehavior - acts: [ "Breakage" ] + acts: ["Breakage"] - !type:EjectVendorItems - type: Repairable doAfterDelay: 8 diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml index 83a5ef8c03..5c52d6fb88 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml @@ -496,7 +496,7 @@ - AirVent - type: entity - parent: [ BaseMachine, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachine, ConstructibleMachine ] id: GasRecycler name: gas recycler description: Recycles carbon dioxide and nitrous oxide. Heater and compressor not included. @@ -553,11 +553,15 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 100 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Machine board: GasRecyclerMachineCircuitboard - type: AtmosMonitoringConsoleDevice diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml index 7716777560..260c998c5e 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml @@ -1,7 +1,7 @@ - type: entity abstract: true parent: BaseItem - id: GasPipeSansLayersIndestructible + id: GasPipeSansLayers name: gas pipe description: Holds gas. placement: @@ -13,41 +13,15 @@ size: Normal - type: Transform anchored: true + - type: Damageable + damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: SubFloorHide - type: CollideOnAnchor - type: Anchorable - type: Rotatable increment: 90 - - type: Sprite - sprite: Structures/Piping/Atmospherics/pipe.rsi - drawdepth: ThinPipe - visible: false - - type: Appearance - - type: PipeAppearance - - type: PipeColorVisuals - - type: NodeContainer - - type: PipeRestrictOverlap - - type: AtmosUnsafeUnanchor - - type: AtmosPipeColor - - type: AtmosMonitoringConsoleDevice - - type: Tag - tags: - - Pipe - - type: Physics - canCollide: false - bodyType: static - - type: StaticPrice - price: 30 - -- type: entity - abstract: true - parent: GasPipeSansLayersIndestructible - id: GasPipeSansLayers - components: - - type: Damageable - damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # for nukes @@ -73,10 +47,31 @@ offset: 0 - !type:DoActsBehavior acts: ["Breakage"] + - type: Sprite + sprite: Structures/Piping/Atmospherics/pipe.rsi + drawdepth: ThinPipe + visible: false + - type: Appearance + - type: PipeAppearance + - type: PipeColorVisuals + - type: NodeContainer + - type: PipeRestrictOverlap + - type: AtmosUnsafeUnanchor + - type: AtmosPipeColor + - type: AtmosMonitoringConsoleDevice + - type: Tag + tags: + - Pipe + - type: Physics + canCollide: false + bodyType: static + - type: StaticPrice + price: 30 - type: entity abstract: true - id: BaseGasPipeLayers + parent: GasPipeSansLayers + id: GasPipeBase components: - type: AtmosPipeLayers spriteLayersRsiPaths: @@ -85,11 +80,6 @@ Secondary: Structures/Piping/Atmospherics/pipe_alt1.rsi Tertiary: Structures/Piping/Atmospherics/pipe_alt2.rsi -- type: entity - abstract: true - parent: [ GasPipeSansLayers, BaseGasPipeLayers ] - id: GasPipeBase - #Note: The PipeDirection of the PipeNode should be the south-facing version, because the entity starts at an angle of 0 (south) - type: entity @@ -311,7 +301,7 @@ - type: entity id: GasPipeBroken - parent: [ GasPipeSansLayersIndestructible, BaseGasPipeLayers ] + parent: GasPipeBase name: broken pipe description: It used to hold gas. components: @@ -329,12 +319,8 @@ node: broken - type: Item size: Small - - type: Damageable - damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible - thresholds: + thresholds: # override parent to avoid recursive destruction - trigger: !type:DamageTrigger damage: 100 diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml index 665e663d61..8b9bf5e7cc 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml @@ -1,6 +1,6 @@ - type: entity id: PortableScrubber - parent: [BaseMachinePowered, SmallConstructibleMachine, StructureWheeled, BaseSmallConstructibleMachineDestructible] + parent: [BaseMachinePowered, SmallConstructibleMachine, StructureWheeled] name: portable scrubber description: It scrubs, portably! components: @@ -69,22 +69,34 @@ board: PortableScrubberMachineCircuitBoard - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 300 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 3 + SheetGlass1: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: GuideHelp guides: - PortableScrubber - type: entity id: SpaceHeater - parent: [BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible] + parent: [BaseMachinePowered, ConstructibleMachine] name: space heater description: A bluespace technology device that alters local temperature. Commonly referred to as a "Space Heater". suffix: Unanchored @@ -143,15 +155,24 @@ atmospheric: true - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 300 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 3 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: GuideHelp guides: - Thermomachines diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml index ea2c874236..72936097dc 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml @@ -213,7 +213,7 @@ - AirInjector - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] id: BaseGasThermoMachine name: thermomachine abstract: true @@ -388,7 +388,7 @@ board: HellfireHeaterMachineCircuitBoard - type: entity - parent: [ SolutionTank, SolutionHuge, BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] + parent: [ SolutionTank, SolutionHuge, BaseMachinePowered, SmallConstructibleMachine ] id: BaseGasCondenser name: condenser description: Condenses gases into liquids. Now we just need some plumbing. @@ -445,6 +445,8 @@ !type:DamageTrigger damage: 100 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpillBehavior solution: tank - !type:PlaySoundBehavior diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml index fb2f17b657..4c3c3749eb 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml @@ -6,6 +6,8 @@ id: BaseGenerator description: A high efficiency thermoelectric generator. name: generator + placement: + mode: SnapgridCenter components: - type: AmbientSound range: 5 @@ -224,67 +226,28 @@ # RTG - no fuel requirement - type: entity - abstract: true - parent: BaseMachine - id: BaseRTG - components: - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.4,-0.5,0.4,0.3" - density: 190 - mask: - - MachineMask - layer: - - MachineLayer - - type: PowerSupplier - supplyRate: 10000 # supposed to be low power at no fuel cost to power derelicts - supplyRampRate: 500 - supplyRampTolerance: 500 - - type: AmbientSound - range: 5 - sound: - path: /Audio/Ambience/Objects/buzzing.ogg - - type: Sprite - sprite: Structures/Power/Generation/rtg.rsi - snapCardinals: true - - type: PowerMonitoringDevice - group: Generator - loadNode: output - sprite: Structures/Power/Generation/rtg.rsi - - type: NodeContainer - examinable: true - nodes: - output: - !type:CableDeviceNode - nodeGroupID: HVPower - - type: PacifismDangerousAttack - - type: StaticPrice - price: 500 - - type: Electrified - onHandInteract: false - onInteractUsing: false - onBump: false - requirePower: true - highVoltageNode: output - - type: GuideHelp - guides: - - RTG - - Power - -- type: entity - parent: BaseRTG + parent: BaseGenerator id: GeneratorRTG name: RTG description: A Radioisotope Thermoelectric Generator for long term power. suffix: 10kW components: + - type: PowerSupplier + supplyRate: 10000 # supposed to be low power at no fuel cost to power derelicts - type: Sprite + sprite: Structures/Power/Generation/rtg.rsi state: rtg - type: PowerMonitoringDevice + sprite: Structures/Power/Generation/rtg.rsi state: rtg + - type: AmbientSound + range: 5 + sound: + path: /Audio/Ambience/Objects/buzzing.ogg + - type: GuideHelp + guides: + - RTG + - Power - type: Destructible thresholds: - trigger: @@ -295,7 +258,6 @@ sound: collection: MetalBreak - !type:SpawnEntitiesBehavior - offset: 0 spawn: GeneratorRTGDamaged: min: 1 @@ -306,17 +268,21 @@ # TODO: need radioactive fallout when destroyed - type: entity - parent: BaseRTG + parent: GeneratorRTG id: GeneratorRTGDamaged name: damaged RTG description: A Radioisotope Thermoelectric Generator for long term power. This one has damaged shielding. suffix: 10kW components: + - type: PowerSupplier + supplyRate: 10000 - type: Sprite + sprite: Structures/Power/Generation/rtg.rsi layers: - state: rtg_damaged - state: rtg_glow - type: PowerMonitoringDevice + sprite: Structures/Power/Generation/rtg.rsi state: rtg_damaged - type: RadiationSource # ideally only when opened. intensity: 2 diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml index 8a1f90677f..a685a5e779 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml @@ -6,7 +6,7 @@ - type: entity abstract: true id: PortableGeneratorBase - parent: [ BaseMachine, SmallConstructibleMachine, StructureWheeled, BaseSmallConstructibleMachineDestructible] + parent: [ BaseMachine, SmallConstructibleMachine, StructureWheeled] components: # Basic properties - type: Transform @@ -64,6 +64,10 @@ - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: GuideHelp guides: - PortableGenerator @@ -328,6 +332,13 @@ behaviors: - !type:SpillBehavior solution: tank + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - trigger: !type:DamageTypeTrigger damageType: Piercing diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml index 1a2218788c..dc537c35c2 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml @@ -2,7 +2,7 @@ id: TegCenter name: thermo-electric generator description: A high efficiency generator that uses energy transfer between hot and cold gases to produce electricity. - parent: [ BaseMachinePowered, BaseMachineDestructible ] + parent: BaseMachinePowered placement: mode: SnapgridCenter components: @@ -109,7 +109,7 @@ id: TegCirculator name: circulator description: Passes gas through the thermo-electric generator to exchange heat. Has an inlet and outlet port. - parent: [ BaseMachine, BaseMachineDestructible ] + parent: BaseMachine placement: mode: SnapgridCenter components: diff --git a/Resources/Prototypes/Entities/Structures/Power/cables.yml b/Resources/Prototypes/Entities/Structures/Power/cables.yml index 6812163c09..94a51cc0dc 100644 --- a/Resources/Prototypes/Entities/Structures/Power/cables.yml +++ b/Resources/Prototypes/Entities/Structures/Power/cables.yml @@ -91,6 +91,8 @@ CableHVStack1: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: CableVisualizer statePrefix: hvcable_ # TODO make this change on power @@ -143,6 +145,8 @@ CableMVStack1: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: CableVisualizer statePrefix: mvcable_ extraLayerPrefix: mvstripes_ @@ -190,6 +194,8 @@ CableApcStack1: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: CableVisualizer statePrefix: lvcable_ diff --git a/Resources/Prototypes/Entities/Structures/Power/chargers.yml b/Resources/Prototypes/Entities/Structures/Power/chargers.yml index 43b9d1975e..77e4d69ee8 100644 --- a/Resources/Prototypes/Entities/Structures/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Structures/Power/chargers.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible] + parent: [BaseMachinePowered, ConstructibleMachine] id: BaseRecharger placement: mode: SnapgridCenter @@ -21,9 +21,11 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 40 behaviors: - !type:EmptyAllContainersBehaviour + - !type:DoActsBehavior + acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Power/smes.yml b/Resources/Prototypes/Entities/Structures/Power/smes.yml index d8e6f5a305..612947af07 100644 --- a/Resources/Prototypes/Entities/Structures/Power/smes.yml +++ b/Resources/Prototypes/Entities/Structures/Power/smes.yml @@ -2,7 +2,7 @@ - type: entity abstract: true id: BaseSMES - parent: [ BaseMachine, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachine, ConstructibleMachine ] name: SMES description: A high-capacity superconducting magnetic energy storage (SMES) unit. placement: @@ -87,14 +87,8 @@ mediumVoltageNode: output - type: Damageable damageModifierSet: StructuralMetallicStrong - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak + - type: Injurable + damageContainer: StructuralInorganic - type: BatterySensor - type: DeviceNetwork deviceNetId: AtmosDevices diff --git a/Resources/Prototypes/Entities/Structures/Power/substation.yml b/Resources/Prototypes/Entities/Structures/Power/substation.yml index d868e1bc9d..786621ee5d 100644 --- a/Resources/Prototypes/Entities/Structures/Power/substation.yml +++ b/Resources/Prototypes/Entities/Structures/Power/substation.yml @@ -74,7 +74,7 @@ - type: entity abstract: true id: BaseSubstation - parent: [ CoreSubstation, BaseMachine, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ CoreSubstation, BaseMachine, ConstructibleMachine ] name: substation description: Reduces the voltage of electricity put into it. placement: @@ -104,12 +104,19 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 100 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - !type:ExplodeBehavior + - !type:SpawnEntitiesBehavior + spawn: + MachineFrameDestroyed: + min: 1 + max: 1 - !type:SpawnGasBehavior gasMixture: volume: 1000 diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml b/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml index 0a613da695..df0c803ea1 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml @@ -41,7 +41,7 @@ - type: entity id: ShuttleGunSvalinnMachineGun - parent: [ ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] + parent: [ ShuttleGunBase, ConstructibleMachine] name: LSE-400c "Svalinn machine gun" description: Basic stationary laser unit. Effective against live targets and electronics. Uses regular power cells to fire, and has an extremely high rate of fire. categories: [ DoNotMap ] @@ -58,6 +58,16 @@ machine_board: !type:Container machine_parts: !type:Container cell_slot: !type:ContainerSlot + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Gun fireRate: 5 useKey: false @@ -89,7 +99,7 @@ - type: entity id: ShuttleGunPerforator - parent: [ ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] + parent: [ ShuttleGunBase, ConstructibleMachine] name: LSE-1200c "Perforator" description: Advanced stationary laser unit. Annihilates electronics and is extremely dangerous to health! Uses the power cage to fire. categories: [ DoNotMap ] @@ -106,6 +116,16 @@ machine_board: !type:Container machine_parts: !type:Container cell_slot: !type:ContainerSlot + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Gun fireRate: 1 soundGunshot: @@ -139,7 +159,7 @@ - type: entity id: ShuttleGunFriendship - parent: [ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] + parent: [ShuttleGunBase, ConstructibleMachine] name: EXP-320g "Friendship" description: A small stationary grenade launcher that holds 2 grenades. categories: [ DoNotMap ] @@ -155,6 +175,16 @@ machine_board: !type:Container machine_parts: !type:Container ballistic-ammo: !type:Container + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Gun projectileSpeed: 80 fireRate: 1 @@ -183,7 +213,7 @@ - type: entity id: ShuttleGunDuster - parent: [ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] + parent: [ShuttleGunBase, ConstructibleMachine] name: EXP-2100g "Duster" description: A powerful stationary grenade launcher. A cartridge is required for use. categories: [ DoNotMap ] @@ -199,6 +229,16 @@ machine_board: !type:Container machine_parts: !type:Container gun_magazine: !type:ContainerSlot + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 350 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Gun projectileSpeed: 40 fireRate: 0.3 @@ -272,7 +312,7 @@ - type: entity id: ShuttleGunKinetic - parent: [ ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] + parent: [ ShuttleGunBase, ConstructibleMachine] name: PTK-800 "Matter Dematerializer" description: Salvage stationary mining turret. Gradually accumulates charges on its own, extremely effective for asteroid excavation. categories: [ DoNotMap ] @@ -286,6 +326,16 @@ containers: machine_board: !type:Container machine_parts: !type:Container + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] - type: Gun projectileSpeed: 20 fireRate: 2 diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml index d42f2f2887..2b2418816a 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml @@ -40,6 +40,21 @@ - type: ApcPowerReceiver powerLoad: 1500 - type: ExtensionCableReceiver + - type: Damageable + damageModifierSet: Electronic + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 # Changed 100->300 because impact damage is real + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: StaticPrice price: 300 - type: GuideHelp @@ -53,15 +68,11 @@ components: - type: Machine board: ThrusterMachineCircuitboard - - type: Damageable - damageModifierSet: Electronic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 300 # Changed 100->300 because impact damage is real + damage: 300 behaviors: - !type:DoActsBehavior acts: ["Destruction"] @@ -103,7 +114,7 @@ - type: entity id: ThrusterLarge name: large thruster - parent: BaseThruster + parent: [ BaseThruster] placement: mode: AlignTileAny components: @@ -195,7 +206,7 @@ - type: entity id: Gyroscope - parent: [ BaseThruster, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseThruster, ConstructibleMachine ] name: gyroscope description: Increases the shuttle's potential angular rotation. components: @@ -236,11 +247,15 @@ thresholds: - trigger: !type:DamageTrigger - damage: 175 + damage: 100 behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:ChangeConstructionNodeBehavior + node: machineFrame - type: Damageable damageModifierSet: Electronic - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml index d31e94ede5..f1439caedf 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml @@ -69,13 +69,18 @@ type: GasCanisterBoundUserInterface - type: Destructible thresholds: - - trigger: &DamageTrigger300 + - trigger: !type:DamageTrigger damage: 300 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + GasCanisterBrokenBase: + min: 1 + max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - !type:DumpCanisterBehavior @@ -216,13 +221,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: AirCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: entity parent: GasCanister @@ -253,13 +266,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: OxygenCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: entity id: LiquidOxygenCanister @@ -305,13 +326,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: NitrogenCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: entity id: LiquidNitrogenCanister @@ -357,13 +386,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: CarbonDioxideCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: Lock locked: true @@ -411,13 +448,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: PlasmaCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: Lock locked: true @@ -450,13 +495,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: TritiumCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: Lock locked: true @@ -489,13 +542,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: WaterVaporCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: entity parent: GasCanister @@ -526,13 +587,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: AmmoniaCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: Lock locked: true @@ -565,13 +634,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: NitrousOxideCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: Lock locked: true @@ -604,13 +681,21 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: *DamageTrigger300 + - trigger: + !type:DamageTrigger + damage: 300 behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: FrezonCanisterBroken: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:DumpCanisterBehavior - type: Lock locked: true diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml index 9f6de3bc2a..51a7f6058e 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml @@ -25,6 +25,24 @@ sprite: Structures/Storage/closet_labels.rsi offset: "-0.065,0" map: ["enum.PaperLabelVisuals.Layer"] + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + params: + volume: -6 + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 2 - type: Construction graph: ClosetSteelSecure node: done @@ -32,6 +50,12 @@ - entity_storage - type: Paintable group: Locker + +- type: entity + id: LockerBaseSecure + parent: LockerBase + abstract: true + components: - type: Damageable damageModifierSet: StructuralMetallic - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml index 755928f6b9..93244037cd 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml @@ -23,7 +23,7 @@ # Basic - type: entity id: LockerSteel - parent: LockerBase + parent: LockerBaseSecure name: secure closet components: - type: Appearance @@ -35,7 +35,7 @@ # Cargo - type: entity id: LockerQuarterMaster - parent: LockerBase + parent: LockerBaseSecure name: quartermaster's locker components: - type: Appearance @@ -63,7 +63,7 @@ # Command - type: entity id: LockerCaptain - parent: LockerBase + parent: LockerBaseSecure name: captain's locker components: - type: Appearance @@ -76,7 +76,7 @@ - type: entity id: LockerHeadOfPersonnel - parent: LockerBase + parent: LockerBaseSecure name: head of personnel's locker components: - type: Appearance @@ -90,7 +90,7 @@ # CE - type: entity id: LockerChiefEngineer - parent: LockerBase + parent: LockerBaseSecure name: chief engineer's locker components: - type: Appearance @@ -279,7 +279,7 @@ # CMO - type: entity id: LockerChiefMedicalOfficer - parent: LockerBase + parent: LockerBaseSecure name: chief medical officer's locker components: - type: Appearance @@ -320,7 +320,7 @@ # HoS - type: entity id: LockerHeadOfSecurity - parent: LockerBase + parent: LockerBaseSecure name: head of security's locker components: - type: Appearance @@ -334,7 +334,7 @@ # Warden - type: entity id: LockerWarden - parent: LockerBase + parent: LockerBaseSecure name: warden's locker components: - type: Appearance @@ -348,7 +348,7 @@ # Brigmedic - type: entity id: LockerBrigmedic - parent: LockerBase + parent: LockerBaseSecure name: brigmedic locker components: - type: Appearance @@ -362,7 +362,7 @@ # Security Officer - type: entity id: LockerSecurity - parent: LockerBase + parent: LockerBaseSecure name: security officer's locker components: - type: Appearance @@ -375,7 +375,7 @@ - type: entity id: GunSafe - parent: LockerBase + parent: LockerBaseSecure name: gun safe components: - type: Appearance @@ -427,7 +427,7 @@ isPlaceable: True - type: entity - parent: [ GenpopBase , LockerBase ] + parent: [ GenpopBase , LockerBaseSecure ] id: LockerPrisoner name: prisoner closet description: It's a secure locker for an inmate's personal belongings during their time in prison. @@ -535,7 +535,7 @@ - type: entity id: LockerSyndicatePersonal name: blood-red locker - parent: LockerBase + parent: LockerBaseSecure description: It's a personal storage unit with a blood-red design. suffix: "Locked" components: @@ -549,7 +549,7 @@ # Bluespace - type: entity - parent: LockerBase + parent: LockerBaseSecure id: LockerBluespaceStation name: bluespace locker description: Advanced locker technology. @@ -583,7 +583,7 @@ - type: entity id: LockerClown name: clown locker - parent: LockerBase + parent: LockerBaseSecure components: - type: Appearance - type: AccessReader @@ -597,7 +597,7 @@ - type: entity id: LockerMime name: mime locker - parent: LockerBase + parent: LockerBaseSecure components: - type: Appearance - type: AccessReader @@ -611,7 +611,7 @@ - type: entity id: LockerRepresentative name: representative locker - parent: LockerBase + parent: LockerBaseSecure components: - type: Appearance - type: AccessReader diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml index 42e45502ca..4a84b69a09 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml @@ -53,6 +53,28 @@ - type: PlaceableSurface placeCentered: true isPlaceable: false + - type: Damageable + damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + params: + volume: -6 + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 1 - type: GenericVisualizer visuals: enum.PaperLabelVisuals.HasLabel: @@ -88,28 +110,6 @@ - entity_storage - type: Paintable group: Closet - - type: Damageable - damageModifierSet: StructuralMetallic - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - params: - volume: -6 - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 1 #Wall Closet - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml index e9a9220d3b..b571b7b287 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml @@ -1,15 +1,30 @@ - type: entity - abstract: true parent: [ BaseStructureDynamic, BasePaperLabelableVisualized ] - id: BaseCrate + id: CrateGeneric + categories: [ HideSpawnMenu ] name: crate description: A large container for items. components: - type: Animateable - type: Transform noRot: true + - type: Icon + sprite: Structures/Storage/Crates/generic.rsi + state: icon - type: Sprite noRot: true + sprite: Structures/Storage/Crates/generic.rsi + layers: + - state: base + map: ["enum.StorageVisualLayers.Base"] + - state: closed + map: ["enum.StorageVisualLayers.Door"] + - state: welded + visible: false + map: ["enum.WeldableLayers.BaseWelded"] + - state: paper + sprite: Structures/Storage/Crates/labels.rsi + map: ["enum.PaperLabelVisuals.Layer"] - type: InteractionOutline - type: Physics - type: Fixtures @@ -26,38 +41,6 @@ - type: EntityStorage - type: PlaceableSurface isPlaceable: false # defaults to closed. - - type: EntityStorageVisuals - stateDoorOpen: open - stateDoorClosed: closed - - type: ContainerContainer - containers: - entity_storage: !type:Container - paper_label: !type:ContainerSlot - - type: StaticPrice - price: 75 - - type: RequireProjectileTarget - -- type: entity - parent: BaseCrate - id: CrateGeneric - categories: [ HideSpawnMenu ] - components: - - type: Icon - sprite: Structures/Storage/Crates/generic.rsi - state: icon - - type: Sprite - sprite: Structures/Storage/Crates/generic.rsi - layers: - - state: base - map: ["enum.StorageVisualLayers.Base"] - - state: closed - map: ["enum.StorageVisualLayers.Door"] - - state: welded - visible: false - map: ["enum.WeldableLayers.BaseWelded"] - - state: paper - sprite: Structures/Storage/Crates/labels.rsi - map: ["enum.PaperLabelVisuals.Layer"] - type: Damageable damageModifierSet: Metallic - type: Injurable @@ -73,11 +56,21 @@ - !type:PlaySoundBehavior sound: collection: MetalBreak + - type: EntityStorageVisuals + stateDoorOpen: open + stateDoorClosed: closed + - type: ContainerContainer + containers: + entity_storage: !type:Container + paper_label: !type:ContainerSlot + - type: StaticPrice + price: 75 - type: Construction graph: CrateGenericSteel node: crategenericsteel containers: - - entity_storage + - entity_storage + - type: RequireProjectileTarget - type: entity parent: CrateGeneric @@ -116,6 +109,19 @@ map: ["enum.PaperLabelVisuals.Layer"] - type: Damageable damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 75 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: Construction graph: CrateSecure node: cratesecure diff --git a/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml b/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml index 728dedec89..d7eb050100 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml @@ -138,13 +138,12 @@ sprite: Structures/Storage/Crates/surgery.rsi - type: entity - parent: BaseCrate + parent: CrateGeneric id: CrateWeb name: web crate components: - type: Icon sprite: Structures/Storage/Crates/web.rsi - state: icon - type: Sprite sprite: Structures/Storage/Crates/web.rsi layers: @@ -158,12 +157,8 @@ - type: Construction graph: WebStructures node: crate - containers: - - entity_storage - type: Damageable damageModifierSet: Web - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -195,7 +190,6 @@ components: - type: Icon sprite: Structures/Storage/Crates/sec_gear.rsi - state: icon - type: Sprite sprite: Structures/Storage/Crates/sec_gear.rsi - type: AccessReader @@ -343,7 +337,7 @@ access: [["SyndicateAgent", "NuclearOperative"]] - type: entity - parent: BaseCrate + parent: CrateGeneric id: CrateLivestock name: livestock crate components: @@ -362,9 +356,6 @@ - type: Icon sprite: Structures/Storage/Crates/livestock.rsi state: base - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -403,7 +394,7 @@ price: 125 - type: entity - parent: BaseCrate + parent: CrateGeneric id: CrateRodentCage name: hamster cage components: @@ -421,10 +412,6 @@ map: ["enum.PaperLabelVisuals.Layer"] - type: Icon sprite: Structures/Storage/Crates/cage.rsi - state: icon - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -702,7 +689,7 @@ state: crate_icon - type: entity - parent: BaseCrate + parent: CrateGeneric id: CrateCoffin name: coffin description: A comfy coffin, excellent place for the vampires and corpses. @@ -718,9 +705,6 @@ - type: Icon sprite: Structures/Storage/Crates/coffin.rsi state: base - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -744,7 +728,7 @@ - entity_storage - type: entity - parent: BaseCrate + parent: CrateGeneric id: CrateWoodenGrave name: grave suffix: wooden @@ -763,9 +747,6 @@ - type: Icon sprite: Structures/Storage/Crates/wooden_grave.rsi state: base - - type: Damageable - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml index 9e781e3948..d9d025a86f 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml @@ -1,9 +1,9 @@ - type: entity - abstract: true + id: StorageTank parent: [SolutionTank, SolutionGinormous, BaseStructureDynamic] - id: StorageTankIndestructible name: storage tank description: A liquids storage tank. + abstract: true components: - type: Animateable - type: Sprite @@ -22,19 +22,6 @@ layer: - MachineLayer - InteractImpassable - - type: DrainableSolution - solution: tank - - type: ReagentTank - - type: Transform - noRot: true - -- type: entity - abstract: true - parent: StorageTankIndestructible - id: StorageTank - name: storage tank - description: A liquids storage tank. - components: - type: Damageable damageModifierSet: Metallic - type: Injurable @@ -66,6 +53,11 @@ collection: MetalBreak - !type:DoActsBehavior acts: ["Destruction"] + - type: DrainableSolution + solution: tank + - type: ReagentTank + - type: Transform + noRot: true # For highcap tanks - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Storage/barrels.yml b/Resources/Prototypes/Entities/Structures/Storage/barrels.yml index 84c350a4ee..195e502ae3 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/barrels.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/barrels.yml @@ -1,5 +1,5 @@ - type: entity - parent: StorageTankIndestructible + parent: StorageTank id: BaseBarrelChem abstract: true name: chemical barrel diff --git a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml index 6e1582c26d..ca7de0e1bb 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml @@ -201,8 +201,16 @@ !type:DamageTrigger damage: 100 behaviors: + - !type:PlaySoundBehavior + sound: + collection: WoodDestroy - !type:SpawnEntitiesBehavior spawn: ShardGlassReinforced: min: 1 max: 1 + MaterialWoodPlank1: + min: 2 + max: 5 + - !type:DoActsBehavior + acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml index 36aa4dd643..2a55a4ee04 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml @@ -7,15 +7,19 @@ sprite: Structures/Wallmounts/posters.rsi - type: Damageable damageModifierSet: Card + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 5 + damage: 15 behaviors: - !type:PlaySoundBehavior sound: path: /Audio/Effects/poster_broken.ogg + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: PosterBroken: @@ -47,6 +51,8 @@ - !type:PlaySoundBehavior sound: path: /Audio/Effects/poster_broken.ogg + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: PosterGraph node: tornPoster diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml index 3ffa500b92..a0ec0e8218 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml @@ -1,8 +1,8 @@ # Parents - type: entity - abstract: true parent: BaseWallmount id: ShelfBase + abstract: true name: shelf description: A strange place to place, well, anything really. You feel like you shouldn't be seeing this. components: @@ -11,14 +11,18 @@ sprite: Structures/Storage/Shelfs/wood.rsi state: base - type: Damageable + damageModifierSet: Wood - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: &DamageTrigger50 + - trigger: !type:DamageTrigger - damage: 50 + damage: 60 behaviors: + - !type:PlaySoundBehavior + sound: + collection: WoodDestroyHeavy - !type:DoActsBehavior acts: ["Destruction"] - type: Storage @@ -36,8 +40,8 @@ - type: entity abstract: true - parent: ShelfBase id: ShelfBaseReinforced + parent: ShelfBase name: reinforced shelf description: It looks as strong as reality itself. components: @@ -66,14 +70,16 @@ # Normal - type: entity - parent: ShelfBase id: ShelfWood + parent: ShelfBase name: wooden shelf description: A convenient place to place, well, anything really. components: - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 60 behaviors: - !type:PlaySoundBehavior sound: @@ -83,6 +89,8 @@ MaterialWoodPlank1: min: 1 max: 3 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Tag tags: - Structure @@ -92,8 +100,8 @@ node: ShelfWood - type: entity - parent: ShelfBase id: ShelfMetal + parent: ShelfBase name: metal shelf description: A sturdy place to place, well, anything really. components: @@ -102,9 +110,13 @@ state: base - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 120 behaviors: - !type:PlaySoundBehavior sound: @@ -114,13 +126,15 @@ SheetSteel1: min: 2 max: 4 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfMetal - type: entity - parent: ShelfBase id: ShelfGlass + parent: ShelfBase name: glass shelf description: A fragile place to place, well, anything really. components: @@ -129,9 +143,13 @@ state: base - type: Damageable damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 50 behaviors: - !type:PlaySoundBehavior sound: @@ -141,14 +159,16 @@ ShardGlass: min: 0 max: 2 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfGlass # Reinforced - type: entity - parent: ShelfBaseReinforced id: ShelfRWood + parent: ShelfBaseReinforced name: sturdy wood shelf description: A safe place to put your favorite bottle of whiskey. components: @@ -165,7 +185,9 @@ shader: unshaded - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 215 behaviors: - !type:PlaySoundBehavior sound: @@ -175,13 +197,15 @@ MaterialWoodPlank: min: 2 max: 5 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfRWood - type: entity - parent: ShelfBaseReinforced id: ShelfRMetal + parent: ShelfBaseReinforced name: sturdy metal shelf description: A strong & shiny place to keep all your vials safe. components: @@ -189,7 +213,9 @@ sprite: Structures/Storage/Shelfs/metal.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 450 behaviors: - !type:PlaySoundBehavior sound: @@ -205,13 +231,15 @@ PartRodMetal1: min: 1 max: 2 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfRMetal - type: entity - parent: ShelfBaseReinforced id: ShelfRGlass + parent: ShelfBaseReinforced name: sturdy glass shelf description: Crystal clear reinforced glass doors to show off all your fancy bottles you definitely didn't sell a co-worker's favorite mothroach for. components: @@ -219,7 +247,9 @@ sprite: Structures/Storage/Shelfs/glass.rsi - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 250 behaviors: - !type:PlaySoundBehavior sound: @@ -235,14 +265,16 @@ PartRodMetal1: min: 0 max: 1 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfRGlass # Departmental - type: entity - parent: ShelfBase id: ShelfBar + parent: ShelfBase name: bar shelf description: Made out of the finest synthetic wood for all alcohol holding needs. components: @@ -259,7 +291,9 @@ fillBaseName: bar - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 100 behaviors: - !type:PlaySoundBehavior sound: @@ -269,6 +303,8 @@ MaterialWoodPlank1: min: 1 max: 4 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Storage grid: - 0,0,5,1 @@ -278,8 +314,8 @@ node: ShelfBar - type: entity - parent: ShelfBase id: ShelfKitchen + parent: ShelfBase name: kitchen shelf description: Holds knifes, spice, and everything nice! components: @@ -296,7 +332,9 @@ fillBaseName: kitchen - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 150 behaviors: - !type:PlaySoundBehavior sound: @@ -312,6 +350,8 @@ PartRodMetal1: min: 0 max: 2 + - !type:DoActsBehavior + acts: ["Destruction"] - type: Storage grid: - 0,0,5,1 @@ -321,8 +361,8 @@ node: ShelfKitchen - type: entity - parent: ShelfBaseReinforced id: ShelfChemistry + parent: ShelfBaseReinforced name: chemical shelf description: Keeps all your chemicals safe and out of the clow- er, public hands! components: @@ -345,7 +385,9 @@ fillBaseName: chem - type: Destructible thresholds: - - trigger: *DamageTrigger50 + - trigger: + !type:DamageTrigger + damage: 330 behaviors: - !type:PlaySoundBehavior sound: diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml index f6df92a552..1b16c3361c 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml @@ -77,7 +77,6 @@ sound: collection: GlassBreak - !type:SpawnEntitiesBehavior - offset: 0 spawn: StationMapBroken: min: 1 diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index 7865aae4e3..f2c7570589 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -3,9 +3,12 @@ # Anyway # See WallRock variants for the remappings. +#Asteroid rock - type: entity + id: AsteroidRock parent: BaseWall - id: BaseAsteroidRock + name: asteroid rock + description: A rocky asteroid. components: - type: Transform noRot: true @@ -33,25 +36,6 @@ damageModifierSet: Rock - type: Injurable damageContainer: StructuralInorganic - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - mask: - - FullTileMask - layer: - - WallLayer - density: 2000 - -#Asteroid rock -- type: entity - parent: BaseAsteroidRock - id: AsteroidRock - name: asteroid rock - description: A rocky asteroid. - components: - type: Destructible thresholds: - trigger: @@ -65,6 +49,17 @@ path: /Audio/Effects/break_stone.ogg params: volume: -6 + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 2000 - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml index c418a97c9f..2eb003555c 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml @@ -33,8 +33,8 @@ - !type:SpawnEntitiesBehavior spawn: PartRodMetal1: - min: 1 - max: 2 + min: 3 + max: 5 - !type:DoActsBehavior acts: [ "Destruction" ] - type: Climbable @@ -108,6 +108,22 @@ messagePerceivedByOthers: fence-rattle-success interactSuccessSound: collection: FenceRattle + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + PartRodMetal1: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: FenceMetal node: broken @@ -149,10 +165,20 @@ thresholds: - trigger: !type:DamageTrigger - damage: 150 + damage: 100 behaviors: + - !type:PlaySoundBehavior + sound: + path: /Audio/Items/wirecutter.ogg + - !type:SpawnEntitiesBehavior + spawn: + PartRodMetal1: + min: 2 + max: 4 - !type:ChangeConstructionNodeBehavior node: broken + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Construction graph: FenceMetal node: straight diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml index 30848256eb..e5dbfe5b24 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml @@ -1,9 +1,9 @@ - type: entity - abstract: true parent: BaseStructure id: BaseFenceWood name: wooden fence description: Wooden piece of fencing. I hope there is babushka's garden behind it. + abstract: true components: - type: MeleeSound soundGroups: @@ -28,15 +28,6 @@ cost: 2 delay: 2 fx: EffectRCDDeconstruct2 - - type: Climbable - delay: 5.0 - - type: Appearance - -- type: entity - abstract: true - parent: BaseFenceWood - id: BaseFenceWoodHigh - components: - type: Destructible thresholds: - trigger: @@ -53,13 +44,16 @@ max: 2 - !type:DoActsBehavior acts: [ "Destruction" ] + - type: Climbable + delay: 5.0 + - type: Appearance - type: entity - abstract: true parent: BaseFenceWood id: BaseFenceWoodSmall name: small wooden fence description: Wooden piece of small fence. The best protection for the fencing of a private territory! + abstract: true components: - type: Destructible thresholds: @@ -81,9 +75,9 @@ delay: 2.5 - type: RequireProjectileTarget -#region High +#High - type: entity - parent: BaseFenceWoodHigh + parent: BaseFenceWood id: FenceWoodHighStraight suffix: Straight components: @@ -112,7 +106,7 @@ node: straight - type: entity - parent: BaseFenceWoodHigh + parent: BaseFenceWood id: FenceWoodHighEnd suffix: End components: @@ -141,7 +135,7 @@ node: end - type: entity - parent: BaseFenceWoodHigh + parent: BaseFenceWood id: FenceWoodHighCorner suffix: Corner components: @@ -179,7 +173,7 @@ node: corner - type: entity - parent: BaseFenceWoodHigh + parent: BaseFenceWood id: FenceWoodHighTJunction suffix: T-Junction components: @@ -217,7 +211,7 @@ node: tjunction - type: entity - parent: BaseFenceWoodHigh + parent: BaseFenceWood id: FenceWoodHighGate name: wooden fence gate description: Do you have any idea what awaits you behind these gates? It can be either a toilet or a luxurious mansion. But you continue to love your emo boys. @@ -264,9 +258,7 @@ graph: FenceWood node: gate -#endregion -#region Small - +#Small - type: entity parent: BaseFenceWoodSmall id: FenceWoodSmallStraight @@ -443,5 +435,3 @@ - type: Construction graph: FenceWood node: gate_small - -#endregion diff --git a/Resources/Prototypes/Entities/Structures/Walls/girders.yml b/Resources/Prototypes/Entities/Structures/Walls/girders.yml index 2fb1f97fda..7acadb48be 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/girders.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/girders.yml @@ -51,8 +51,8 @@ price: 30 - type: entity - parent: Girder id: ReinforcedGirder + parent: Girder name: reinforced girder description: A large structural assembly made out of metal and plasteel; It requires a layer of plasteel before it can be considered a reinforced wall. components: @@ -70,15 +70,23 @@ behaviors: - !type:SpawnEntitiesBehavior spawn: + SheetSteel1: + min: 1 + max: 1 SheetPlasteel1: min: 1 max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: StaticPrice price: 130 - type: entity - parent: Girder id: ClockworkGirder + parent: ReinforcedGirder name: wall gear description: A large gear with mounting brackets for additional plating; This could be made into a wall with more brass plating. components: @@ -101,3 +109,11 @@ SheetBrass1: min: 1 max: 2 + PartRodMetal1: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml b/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml index a8abdf8131..a771291bda 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml @@ -43,18 +43,16 @@ mode: SnapgridCenter - type: entity - parent: [ BaseStructure, BaseDeltaPressureGlass ] id: InflatableDoor name: inflatable door + parent: [BaseMaterialDoor, BaseDeltaPressureGlass] description: An inflated membrane. Activate to deflate. Now with a door. Do not puncture. components: - type: Clickable - type: InteractionOutline - type: Sprite sprite: Objects/Misc/inflatable_door.rsi - layers: - - state: closed - map: ["enum.DoorVisualLayers.Base"] + state: closed - type: Physics bodyType: Static - type: Fixtures @@ -67,22 +65,11 @@ layer: - WallLayer - type: Door - bumpOpen: false - clickOpen: true - canCrush: false - closeTimeOne: 0.2 - closeTimeTwo: 0.6 - openTimeOne: 0.6 - openTimeTwo: 0.2 - openingAnimationTime: 1.2 - closingAnimationTime: 1.2 occludes: false openSound: path: /Audio/Misc/zip.ogg closeSound: path: /Audio/Misc/zip.ogg - - type: Appearance - - type: Airtight - type: Damageable damageModifierSet: Inflatable - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Walls/meteor.yml b/Resources/Prototypes/Entities/Structures/Walls/meteor.yml index 5da5e42230..6f310e3b74 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/meteor.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/meteor.yml @@ -1,7 +1,7 @@ # These define Meteor Walls separate from Asteroid walls so they have different properties - type: entity - parent: BaseAsteroidRock id: MeteorRock + parent: AsteroidRock name: meteorite rock description: What remains of a meteorite. components: diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index 12cc546cba..709796c49c 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -88,10 +88,10 @@ fix1: shape: !type:PolygonShape - vertices: - - "-0.5,-0.5" - - "0.5,0.5" - - "0.5,-0.5" + vertices: + - "-0.5,-0.5" + - "0.5,0.5" + - "0.5,-0.5" mask: - FullTileMask layer: @@ -208,8 +208,8 @@ components: - type: Tag tags: - - Wall - - Structure + - Wall + - Structure - type: Sprite sprite: Structures/Walls/meat.rsi - type: Icon @@ -268,7 +268,7 @@ components: - type: Tag tags: - - Wall + - Wall - type: Sprite sprite: Structures/Walls/debug.rsi - type: Icon @@ -464,30 +464,30 @@ name: plastitanium wall suffix: indestructible components: - - type: Sprite - sprite: Structures/Walls/plastitanium.rsi - - type: Icon - sprite: Structures/Walls/plastitanium.rsi - - type: IconSmooth - key: walls - base: plastitanium - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - mask: - - FullTileMask - layer: - - WallLayer - density: 4000 - - type: Damageable - damageModifierSet: StructuralMetallicStrong - - type: Injurable - damageContainer: StructuralInorganic - - type: RadiationBlocker - resistance: 5 + - type: Sprite + sprite: Structures/Walls/plastitanium.rsi + - type: Icon + sprite: Structures/Walls/plastitanium.rsi + - type: IconSmooth + key: walls + base: plastitanium + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 4000 + - type: Damageable + damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic + - type: RadiationBlocker + resistance: 5 - type: entity parent: WallPlastitaniumIndestructible @@ -548,16 +548,16 @@ !type:DamageTrigger damage: 1000 behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalSlam + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalSlam - type: entity parent: BaseWall @@ -637,8 +637,19 @@ - type: IconSmooth key: walls base: reinf_over - - type: Damageable - damageModifierSet: StructuralMetallic # weaker because rust + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 350 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalSlam + - !type:ChangeConstructionNodeBehavior + node: girder + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity parent: WallDiagonalBase @@ -794,10 +805,10 @@ fix1: shape: !type:PolygonShape - vertices: - - "-0.5,-0.5" - - "0.5,0.5" - - "0.5,-0.5" + vertices: + - "-0.5,-0.5" + - "0.5,0.5" + - "0.5,-0.5" mask: - FullTileMask layer: @@ -967,8 +978,19 @@ - type: IconSmooth key: walls base: solid - - type: Damageable - damageModifierSet: Metallic # weaker because rust + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalSlam + - !type:ChangeConstructionNodeBehavior + node: girder + - !type:DoActsBehavior + acts: ["Destruction"] - type: entity parent: BaseWall @@ -977,7 +999,7 @@ components: - type: Tag tags: - - Wall + - Wall - type: Destructible thresholds: - trigger: @@ -1336,7 +1358,7 @@ lifetime: 15 - type: Tag tags: - - Wall + - Wall - type: Physics bodyType: Static - type: Fixtures @@ -1344,7 +1366,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" + bounds: "-0.5,-0.5,0.5,0.5" mask: - FullTileMask layer: @@ -1506,6 +1528,8 @@ !type:DamageTrigger damage: 100 behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - !type:PlaySoundBehavior sound: path: /Audio/Effects/break_stone.ogg diff --git a/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml b/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml index 87e599cdce..0922122ff7 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml @@ -1,14 +1,14 @@ - type: entity - parent: BaseWindowStructure id: ClockworkWindow name: clockwork window description: Don't smudge up the brass down there. + parent: Window components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/clockwork_window.rsi - type: Icon sprite: Structures/Windows/clockwork_window.rsi - state: full - type: Repairable fuelCost: 10 doAfterDelay: 2 @@ -37,14 +37,23 @@ - type: Construction graph: Window node: clockworkWindow + - type: Appearance - type: DamageVisuals + thresholds: [5, 10, 20] damageDivisor: 3 + trackAllDamage: true + damageOverlay: + sprite: Structures/Windows/cracks.rsi - type: entity - parent: BaseWindowStructureDirectional id: WindowClockworkDirectional + parent: WindowDirectional name: directional clockwork window description: Don't smudge up the brass down there. + placement: + mode: SnapgridCenter + snap: + - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -55,10 +64,13 @@ - type: Construction graph: WindowDirectional node: windowClockworkDirectional + - type: Appearance - type: DamageVisuals + thresholds: [5, 10, 20] damageDivisor: 1.5 - - type: Injurable - damageContainer: StructuralInorganic + trackAllDamage: true + damageOverlay: + sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass - type: Destructible diff --git a/Resources/Prototypes/Entities/Structures/Windows/mining.yml b/Resources/Prototypes/Entities/Structures/Windows/mining.yml index 90379bb277..fa20edb6e0 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/mining.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/mining.yml @@ -1,13 +1,13 @@ - type: entity - parent: [BaseWindowStructure, BaseRCDResistant] id: MiningWindow name: mining window + parent: WindowRCDResistant components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/mining.rsi - type: Icon sprite: Structures/Windows/mining.rsi - state: full - type: Repairable fuelCost: 15 doAfterDelay: 3 @@ -36,8 +36,13 @@ acts: [ "Destruction" ] - type: IconSmooth base: mwindow + - type: Appearance - type: DamageVisuals + thresholds: [5, 10, 20] damageDivisor: 4 + trackAllDamage: true + damageOverlay: + sprite: Structures/Windows/cracks.rsi - type: StaticPrice price: 100 diff --git a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml index dc0d754f9a..b71f93db2a 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml @@ -1,13 +1,13 @@ - type: entity id: PlasmaWindow name: plasma window - parent: [BaseDeltaPressurePlasma, BaseWindowStructure, BaseRCDResistant] + parent: [BaseDeltaPressurePlasma, WindowRCDResistant] components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/plasma_window.rsi - type: Icon sprite: Structures/Windows/plasma_window.rsi - state: full - type: Damageable damageModifierSet: Glass - type: Injurable @@ -47,9 +47,13 @@ - type: entity id: PlasmaWindowDirectional - parent: [BaseDeltaPressurePlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] + parent: [BaseDeltaPressurePlasmaQuarter, WindowDirectionalRCDResistant] name: directional plasma window description: Don't smudge up the glass down there. + placement: + mode: SnapgridCenter + snap: + - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -67,10 +71,6 @@ trackAllDamage: true damageOverlay: sprite: Structures/Windows/cracks_directional.rsi - - type: Damageable - damageModifierSet: Glass - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml index 5adf28b80d..fbd098a146 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml @@ -1,13 +1,13 @@ - type: entity - parent: [BaseDeltaPressureReinforcedGlass, BaseWindowStructure] id: ReinforcedWindow name: reinforced window + parent: [BaseDeltaPressureReinforcedGlass, Window] components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/reinforced_window.rsi - type: Icon sprite: Structures/Windows/reinforced_window.rsi - state: full - type: Repairable fuelCost: 10 doAfterDelay: 2 @@ -49,9 +49,14 @@ sprite: Structures/Windows/cracks.rsi - type: entity - parent: [BaseDeltaPressureReinforcedGlassQuarter, BaseWindowStructureDirectional] id: WindowReinforcedDirectional + parent: [BaseDeltaPressureReinforcedGlassQuarter, WindowDirectional] name: directional reinforced window + description: Don't smudge up the glass down there. + placement: + mode: SnapgridCenter + snap: + - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -71,8 +76,6 @@ sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass - - type: Injurable - damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 4 delay: 4 diff --git a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml index 7399b71430..a8f9d8e385 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml @@ -1,13 +1,13 @@ - type: entity - parent: [BaseDeltaPressureReinforcedPlasma, BaseWindowStructure, BaseRCDResistant] id: ReinforcedPlasmaWindow name: reinforced plasma window + parent: [BaseDeltaPressureReinforcedPlasma, WindowRCDResistant] components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/reinforced_plasma_window.rsi - type: Icon sprite: Structures/Windows/reinforced_plasma_window.rsi - state: full - type: Damageable damageModifierSet: RGlass - type: Injurable @@ -49,9 +49,14 @@ price: 132 - type: entity - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] id: PlasmaReinforcedWindowDirectional + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, WindowDirectionalRCDResistant] name: directional reinforced plasma window + description: Don't smudge up the glass down there. + placement: + mode: SnapgridCenter + snap: + - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -71,8 +76,6 @@ sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass - - type: Injurable - damageContainer: StructuralInorganic - type: RadiationBlocker resistance: 2 - type: Destructible diff --git a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml index db233d30e5..96381de72e 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml @@ -1,13 +1,13 @@ - type: entity - parent: [BaseDeltaPressureReinforcedPlasma, BaseWindowStructure, BaseRCDResistant] id: ReinforcedUraniumWindow name: reinforced uranium window + parent: [BaseDeltaPressureReinforcedPlasma, WindowRCDResistant] components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/reinforced_uranium_window.rsi - type: Icon sprite: Structures/Windows/reinforced_uranium_window.rsi - state: full - type: Damageable damageModifierSet: RGlass - type: Injurable @@ -49,9 +49,14 @@ resistance: 5 - type: entity - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] id: UraniumReinforcedWindowDirectional + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, WindowDirectionalRCDResistant] name: directional reinforced uranium window + description: Don't smudge up the glass down there. + placement: + mode: SnapgridCenter + snap: + - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -71,8 +76,6 @@ sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml index a76ffc5f19..b3ead67f1b 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml @@ -1,13 +1,13 @@ - type: entity - parent: [BaseDeltaPressureReinforcedGlass, BaseWindowStructure, BaseRCDResistant] id: ShuttleWindow name: shuttle window + parent: [BaseDeltaPressureReinforcedGlass, WindowRCDResistant] components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/shuttle_window.rsi - type: Icon sprite: Structures/Windows/shuttle_window.rsi - state: full - type: Repairable fuelCost: 15 doAfterDelay: 3 diff --git a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml index 76527c619b..73adc37fae 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml @@ -1,9 +1,10 @@ - type: entity - parent: [BaseDeltaPressurePlasma, BaseWindowStructure, BaseRCDResistant] id: UraniumWindow name: uranium window + parent: [BaseDeltaPressurePlasma, WindowRCDResistant] components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/uranium_window.rsi - type: Icon sprite: Structures/Windows/uranium_window.rsi @@ -46,9 +47,14 @@ resistance: 3 - type: entity - parent: [BaseDeltaPressurePlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] id: UraniumWindowDirectional + parent: [BaseDeltaPressurePlasmaQuarter, WindowDirectionalRCDResistant] name: directional uranium window + description: Don't smudge up the glass down there. + placement: + mode: SnapgridCenter + snap: + - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -66,10 +72,6 @@ trackAllDamage: true damageOverlay: sprite: Structures/Windows/cracks_directional.rsi - - type: Damageable - damageModifierSet: Glass - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/window.yml b/Resources/Prototypes/Entities/Structures/Windows/window.yml index 7dad29c496..5ecd83aece 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/window.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/window.yml @@ -1,7 +1,6 @@ - type: entity - abstract: true + id: Window parent: [BaseDeltaPressureGlass, BaseStructure] - id: BaseWindowStructure name: window description: Don't smudge up the glass down there. placement: @@ -21,10 +20,14 @@ arc: 360 # interact despite grilles - type: Tag tags: - - ForceFixRotations - - Window + - ForceFixRotations + - Window - type: Sprite drawdepth: WallTops + sprite: Structures/Windows/window.rsi + - type: Icon + sprite: Structures/Windows/window.rsi + state: full - type: Physics bodyType: Static - type: Fixtures @@ -36,6 +39,10 @@ - FullTileMask layer: - GlassLayer + - type: Damageable + damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages - type: Repairable @@ -43,6 +50,22 @@ cost: 6 delay: 4 fx: EffectRCDDeconstruct4 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WindowShatter + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: Airtight - type: IconSmooth key: windows @@ -66,36 +89,6 @@ price: 100 - type: BlockWeather -- type: entity - parent: BaseWindowStructure - id: Window - components: - - type: Sprite - sprite: Structures/Windows/window.rsi - - type: Icon - sprite: Structures/Windows/window.rsi - state: full - - type: Damageable - damageModifierSet: Glass - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: WindowShatter - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - type: entity parent: Window id: TintedWindow @@ -116,21 +109,16 @@ price: 70 - type: entity + id: WindowRCDResistant + parent: Window abstract: true - id: BaseRCDResistant components: - type: RCDDeconstructable deconstructable: false - type: entity - abstract: true - parent: [Window, BaseRCDResistant] - id: WindowRCDResistant - -- type: entity - abstract: true + id: WindowDirectional parent: [BaseDeltaPressureGlassQuarter, BaseStructure] - id: BaseWindowStructureDirectional name: directional window description: Don't smudge up the glass down there. placement: @@ -142,13 +130,18 @@ arc: 360 # interact despite grilles - type: Tag tags: - - Window + - Window - type: MeleeSound soundGroups: Brute: collection: GlassSmack - type: Sprite drawdepth: Mobs + sprite: Structures/Windows/directional.rsi + state: window + - type: Icon + sprite: Structures/Windows/directional.rsi + state: window - type: InteractionPopup interactSuccessString: comp-window-knock messagePerceivedByOthers: comp-window-knock @@ -167,42 +160,16 @@ layer: - GlassLayer - type: Repairable + - type: Damageable + damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages - type: RCDDeconstructable cost: 4 delay: 2 fx: EffectRCDDeconstruct2 - - type: Airtight - noAirWhenFullyAirBlocked: false - airBlockedDirection: - - South - - type: Appearance - - type: DamageVisuals - thresholds: [5, 10, 20] - trackAllDamage: true - damageOverlay: - sprite: Structures/Windows/cracks_directional.rsi - - type: StaticPrice - price: 15 - - type: Construction - graph: WindowDirectional - node: windowDirectional - -- type: entity - parent: BaseWindowStructureDirectional - id: WindowDirectional - components: - - type: Sprite - sprite: Structures/Windows/directional.rsi - state: window - - type: Icon - sprite: Structures/Windows/directional.rsi - state: window - - type: Damageable - damageModifierSet: Glass - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -219,11 +186,29 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] + - type: Airtight + noAirWhenFullyAirBlocked: false + airBlockedDirection: + - South + - type: Construction + graph: WindowDirectional + node: windowDirectional + - type: Appearance + - type: DamageVisuals + thresholds: [5, 10, 20] + trackAllDamage: true + damageOverlay: + sprite: Structures/Windows/cracks_directional.rsi + - type: StaticPrice + price: 15 - type: entity - abstract: true - parent: [WindowDirectional, BaseRCDResistant] id: WindowDirectionalRCDResistant + parent: WindowDirectional + abstract: true + components: + - type: RCDDeconstructable + deconstructable: false - type: entity id: WindowFrostedDirectional diff --git a/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml b/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml index 71eafe0569..989ffcca9b 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml @@ -2,11 +2,34 @@ parent: ReinforcedWindow id: XenoResinWindow name: resin window - description: Transparent and hardened, yet slightly sticky to the touch. + description: Transparent and hardened, yet slightly sticky to the touch. Slightly stronger than a normal reinforced window. components: - type: Sprite + drawdepth: WallTops sprite: Structures/Windows/xeno_resin.rsi - type: Icon sprite: Structures/Windows/xeno_resin.rsi + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WindowShatter + - !type:SpawnEntitiesBehavior + spawn: + ShardGlassReinforced: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: IconSmooth base: xwindow + - type: DamageVisuals + thresholds: [5, 10, 20] + damageDivisor: 4 + trackAllDamage: true + damageOverlay: + sprite: Structures/Windows/cracks.rsi diff --git a/Resources/Prototypes/Entities/Structures/cargo_telepad.yml b/Resources/Prototypes/Entities/Structures/cargo_telepad.yml index f2935a6117..eb96ebf609 100644 --- a/Resources/Prototypes/Entities/Structures/cargo_telepad.yml +++ b/Resources/Prototypes/Entities/Structures/cargo_telepad.yml @@ -1,6 +1,6 @@ - type: entity id: CargoTelepad - parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] + parent: [ BaseMachinePowered, ConstructibleMachine ] name: cargo telepad description: Beam in the pizzas and dig in. components: @@ -31,14 +31,8 @@ shader: unshaded - type: Damageable damageModifierSet: StructuralMetallicStrong - - type: Destructible - thresholds: - - trigger: !type:DamageTrigger - damage: 175 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak + - type: Injurable + damageContainer: StructuralInorganic - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice diff --git a/Resources/Prototypes/Entities/Structures/hydro_tray.yml b/Resources/Prototypes/Entities/Structures/hydro_tray.yml index dff2d7481c..b1cbcc8b86 100644 --- a/Resources/Prototypes/Entities/Structures/hydro_tray.yml +++ b/Resources/Prototypes/Entities/Structures/hydro_tray.yml @@ -1,6 +1,6 @@ - type: entity name: hydroponics tray - parent: [ BaseHydroponicsSoil, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible] + parent: [ hydroponicsSoil, SmallConstructibleMachine] id: hydroponicsTray description: An interstellar-grade space farmplot allowing for rapid growth and selective breeding of crops. Just... keep in mind the space weeds. components: @@ -78,9 +78,13 @@ !type:DamageTrigger damage: 100 behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame - !type:PlaySoundBehavior sound: collection: MetalGlassBreak + - !type:DoActsBehavior + acts: ["Destruction"] - type: Machine board: HydroponicsTrayMachineCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml index e6fe0fab44..fa9079b632 100644 --- a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml +++ b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml @@ -85,6 +85,14 @@ suffix: Airtight, Clear description: Heavy duty, slightly stronger, airtight plastic flaps. Definitely can't get past those. No way. components: + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Airtight - type: StaticPrice price: 100 @@ -96,6 +104,14 @@ suffix: Airtight, Opaque description: Heavy duty, slightly stronger, airtight plastic flaps. Definitely can't get past those. No way. components: + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 150 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Airtight - type: StaticPrice price: 100 diff --git a/Resources/Prototypes/Entities/Structures/soil.yml b/Resources/Prototypes/Entities/Structures/soil.yml index 4c7297ca63..a999781300 100644 --- a/Resources/Prototypes/Entities/Structures/soil.yml +++ b/Resources/Prototypes/Entities/Structures/soil.yml @@ -1,7 +1,8 @@ - type: entity parent: SolutionLarge - abstract: true - id: BaseHydroponicsSoil + id: hydroponicsSoil + name: soil + description: A mix of organic matter and minerals creating a soil to grow your plant in space. Seems to be dry. placement: mode: SnapgridCenter components: @@ -21,7 +22,21 @@ - FullTileMask layer: - FullTileMask + - type: Damageable + damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] - type: Sprite + sprite: Structures/Hydroponics/misc.rsi + state: soil noRot: true - type: PlantHolder drawWarnings: false @@ -43,28 +58,6 @@ - type: Appearance - type: PlantHolderVisuals -- type: entity - parent: BaseHydroponicsSoil - id: hydroponicsSoil - name: soil - description: A mix of organic matter and minerals creating a soil to grow your plant in space. Seems to be dry. - components: - - type: Damageable - damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - type: Sprite - sprite: Structures/Hydroponics/misc.rsi - state: soil - - type: entity parent: hydroponicsSoil id: FungalSoil diff --git a/Resources/Prototypes/GameRules/meteorswarms.yml b/Resources/Prototypes/GameRules/meteorswarms.yml index a9a21e6dab..134995b801 100644 --- a/Resources/Prototypes/GameRules/meteorswarms.yml +++ b/Resources/Prototypes/GameRules/meteorswarms.yml @@ -37,8 +37,6 @@ - id: CowSwarm - id: PotatoSwarm - id: FunSwarm - - id: MeteorSwarmFlesh - - id: MeteorSwarmKudzu - id: ImmovableRodSpawn - type: weightedRandomEntity @@ -55,14 +53,6 @@ MeteorRockUranium: 0.5 MeteorRockBananium: 0.5 -- type: weightedRandomEntity - id: MeteorSpawnFleshMonstersTable - weights: - MobFleshGolemSalvage: 1 - MobFleshClampSalvage: 1 - MobFleshLoverSalvage: 1 - MobFleshJaredSalvage: 1 - # Event Schedulers - type: entity @@ -326,39 +316,3 @@ meteorsPerWave: min: 8 max: 12 - -- type: entity - parent: MeteorSwarm - id: MeteorSwarmFlesh - components: - - type: StationEvent - weight: 4 - - type: MeteorSwarm - announcement: station-event-bio-swarm-start-announcement - announcementSound: /Audio/Announcements/attention.ogg - meteors: - MeteorFlesh: 1 - waves: - min: 2 - max: 3 - meteorsPerWave: - min: 5 - max: 6 - -- type: entity - parent: MeteorSwarm - id: MeteorSwarmKudzu - components: - - type: StationEvent - weight: 5 - - type: MeteorSwarm - announcement: station-event-bio-swarm-start-announcement - announcementSound: /Audio/Announcements/attention.ogg - meteors: - MeteorKudzu: 1 - waves: - min: 2 - max: 3 - meteorsPerWave: - min: 3 - max: 5 diff --git a/Resources/Textures/Objects/Misc/meteor.rsi/kudzu.png b/Resources/Textures/Objects/Misc/meteor.rsi/kudzu.png deleted file mode 100644 index 53149e9dea6ed29c43cc83b23feceb8058137988..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5905 zcmcIo3p`YL`#<9@(U6QpCM^*&bLMJHZn=~$E|u1;G`BNMm>Dy}jMhDpE?ZkI5>e^4 z6;Yy9W0Is&kuH>?6ww8hNZ~yb+4kLSci;c}f9La=Grx1rbNxQw=lT6UlkVfSP+0$=pUr1N=;aGt(3W^RJE|1`Sl(pO=>&l| zQV8kM>9yCbttJU2%QtS^vYhU8Q(hyl1Ju&5TvGiJfpA1e2ge7`RaP5}-kPNAw&t$t z?n}-_ZHuv%a}l=^5}Pc|OR2k)k{W>88(5qbu!(pBQR2R%^5sO1qy%er2Tpr}`6Ac~hPw|0I{pmw5s4WL6IyDSX@0|Vz$ z4?Uf8aIT75yc0F;Dat&f;1F=frA1vW8JU`oYy{Sxu4m^HfJ@3L{dP!W z*%oF9lBuzMRiLjLL?BF`+A+H>YxV_sTjj2#q-RrH>IyQG7)d(H%A>w1S=qCc*C#qE zUzFJa@*3~q=`_kJ7&uLVM}PgT!bi6vE{>nDtatnxVOD2QxpiC+I0~g+jR=>x9sXbzZ)#bzv+!wwaS7 z+FnY74Mad<23i^s&J)q34rZV2(%`k?G0qJASwtM>U^Z4ie@`E@D_;nqDOeE00zm@W z)((rOkVsUj4VnNFKpbd`!-E(Cfd*1&WFmU}V+MN@vN^QnZVSeJ!FLX3p<=OshQmoD z60C%X@ODFAQ4N*6^OZf9$I0M!Q@AY9n9cJ z$5Mz8Oqk_~#$kd1!$}ze93BfQQu-{&W=+TmqJ-g}owHduC>)A_cw!MOi=U7cg!09F zQ7Hc#rYBzi&H)Uqr{{!^KaC|KV#0+;>>drLF%HO|N{f7B1Q2dHB;rR2S&(})9OmpV z*@(o;q2KWQ2kNl+XJrA+RR}S}e4#I&AO5AvK40=h69`xkZRyA5vH22_mBQP&0_4UJ zLk?ze$;lXy4Ail57IzzOw^Ol=5k{GC`zFbKpLL#J5iW#Y=)Tex58`| zjl&m4FkrN}5sVNBC*Xycp(koUbLEHgg|K5dI^x&Q7r{eF$mejw;TQitj6O%}=}B9} z6Nwo-7PQFC!3<6n%jL3ZBr=u7qLN4$5*6fN7;KU)hJj~MFl30$U=tyTY|G|+(Rbss zq7?K|=#O<0o6mx6{1zRR$Oai8nT26e$RLIcl2{l9i%Gx`*>-jygGGQiZ2T8%-a; z3oaUONf$=Q_$r+1_@9`!$0_;`Rzi=h#th;9+9T`$#@U0bh#+R%?+Pe#A_Da1MxZfR ziUxNuV=2f9vCYOGbN{41{|Je3eMu+;8~qE?j(HdHIbsPz2+a?HYx#vOKHq8z+&6>g z^P(Z)SK$j7LIylnA)&~@j3eYnpeG277W2^zfgqgAVki>FMf2F>vugrQvv2wlF{1w( zA}WPt3sFHl#ufw_7&ePUz%a=m6+_?NrpT`u- ziGv_~GjWuJcyOl*;e%rP`&HfmpryOWZN9Jc{;OP1p0O=5HEP?-WMdZ};G&Mc{3K#V z-(szZ(@Qe0%t~fYXYcXEZnyRtD*doBICCB6*FDCIUJ2&cZF@E=peVlfiS_$Cj|Ju3 zuRa8#T-5WG>x1A6_@J=z9AgIs zgRgq>7Cu%6PH2@UXL&%wVLXbm6fGcR8$mqotNEvu|laWzYIvox<_4e9@~Yw z)F`o)v@WuWKT+h6>xh1EH1`pEYpCD+p_@1pqIg1zZgy6 zd5CX0bGUNk?X|~Qy~lvIg@SpvKBc9lWqntb@V3KKqmm4CKbW&g-v8l+sVqIR&!MMm zOS?Yco|Q+g^tW$s2z%X=HDirR;%vLMLAunc&Qrl;2Ev)n!^GNbyAnV2j=RO7I?re0 z1*85==7F*Im7J?-Wz;xt({8`GUsZppG_QhnjdBkp4aTbNwClYvq78GOgIgN;3pT3atm&*6?g-PMaiwB1kZC3B;W*Ep*H zh0mGTBO1=b-TfUMobaLJ__Hq3rGfKi0?xhJrq1(#Y~m(4Qw2DgEgIgdOn+IeUR6!z zo?m-Qe6_&AkP`50^3FSKft?P}?$g-1Pu~ay9N(&{1RQidGOLLh0JLoaJPriS#dqZx zd+AiK-y3gux(f+7#(y$Q_6yTaPSK5*7;X#OThrTp=a|19YpWiReKvaKhC5ShyLS33 z1CDC;$;zaF-P(D!2z4yiexrAQi{RK#YgRI%LqN@6OYgqWXIR+5{lTSX`+571H z4+E_(EM!SMYQSJIClNohMtVaPd)N6>Tj--j%CP~PRNGw30+SBY3RaRxV2^9d@Y&un zC7@Rcy(*|dJnR@B-198C*qNQe)GO~F?$~MwEM3}oy1~!bNN_xx$KL~>QCZ3kff`7e z=7V1md$g+RtWv@N>B-D~O$`Gq!~BeX;Uf2?6jP1h_4Nax8%87?pGgsKYD~b&L@#R8eX-$=3sa5~&rDWjs=1A30vnt6>_qS!d+QHGi!ruJD zBkvaHl{>cP<~>l!Rcb48O2~ORV&3$)qPXZdTgUlEdTx+*p-^+My`kvmhkMn~jOxIc z=f27(`YsetH+v9jjXs?&LwW>*HqEIs!}Mfx(90~ZUt<{q&!Dnxdy0*hq{7G!P<~ zM0izH!yy7fgWZFAp@ zxXw5cwxH?k9skyxUT%y{aq~RD}Rx`a`hHTx0Ks z8^8os6KtNeyIy)^-H9gkC0efgjep5m5UGE(hdNm(^9chwQcn13wsh^;*;xE$ zU?osr9F}cyYz017`|#U)>pQOoEp538*%@{k5^VB~Jzes`BX%d=?8*!>ZX>GcUu@Rv zv|;>|pq1hGcoXN0!0`wd;X=Eu>Dm5ix}zoBf93l#GM=Xmmz&lCyT5DOLY-HBUnjBg zZPrO=jbK^iv)oOOqgIs4Y){R~F95b!5(<%+)yPS5`_&d+IvjidXL`)n0RTIC>W1RT zo?P=SD>s@P>N&U-d33F3>si}u($1(2My#{GaoH$yf`xS1?CD{Kn|DfoQh(Dh8l;`L z0?f%!H@%f${42G3b<2+EgrQcS^Cwfn0~~} zL0Cn5hVYk6t)nq#z04iJx`&y0q4rawGfqEB!|@E$ZkM6*>RXJ^ljr?ZZUij7YRyWH z3%8HM-Ix27DJ9A~N%|=J#ci7i0l6z{W})H_$vcgd$`%~%zWq|!BG#kM^wks;`=E=9 zU-3@_teZ-Kdv57Er4{6( zh&6HLZ85mH<-}9Pj+*PQKl$Fg*4;{`&S-x1lwKyM@4&s3L>}CTT17Q~Z~~1wTH0h) zF{&;;U7sXjNc)Gr2b#pX?DIhVF=CfrPr&h&UFxw)JuU5mI0Z=7j2YL`@YnH1-rvI!_=sY}YvQnOULTPNs z#alHwwQ(OdG-k>QSR0jx%1SRJXnK#xH`JB3TDu&X)Mvs91B9jfiz?ISF-F`6rva-R z0+%(DH4fxot33AMQOK)vC{M>7;prRqSkG?GkI@XXCfFo3TwAU?X~_kA?}O?xC9q8S zy{BPZ%+;iaqxZ{C`F@<)H{Z$yy@0MOQ@dMPsswn}IZg-myB!@4kUxDI@%rUH|CW#! ztC|zy&fH3Aw|bF*il!r~_aC_Pyyljy`pUhh;33`m>!+vAI(~jP8#Bjg@h;A-wk24P zA+ssZ-d>8!EI++X{`|uG+mEjWJ2z?nfL@>7-iSy3pe4ul;TL>qO-Y!~miOk(%y)`i8{bDvaoeiv%5U2>|v z23UFn@yYAV+09j*uLqmW0is{jrJr9HZaupe`f-2oY?UJTY!hiuFC!2J}K?2YoK`R}QSz z-OKq2S8_}>akhuXa*^$sj}H%#%iha001fe~TbJDnBK<-e91X7x1-;g}F0r`ROC*}K zq)v9KEgfxuT7OUlPF#GrW!s$Tj+=LO4Uk>$9`u=y9-OwbR3$(~Yjh#o((+Aw$ecXl zR$(UKR&O0^dfKGhq*atg%0VY=S3^rElBZu4^Qut0CM+7Ct9{o z70#;eNb{hlj(oQ@^YsR=49>bZL$+mtblcm$10crX=CL!(9g)V?sV*Of^&%@Hh7VTk zI{?(i#t3tr=Be6lNBFR+KINhohnwWbH|CjaP!cS3dgr!Qk3`wUnUXZ95A0Ox^6y@@ zIcO%+mHvM1j=DQVs)?~vZx;83M9qrr+&m;L@Tk~~=-QN3AFk3JwahV~GmUeD<9X|5 zK<%I;f&QSj5r@5u)31EG+Q3`W`MXOwlb1BO6nf-@mHJ*fyJxYz)6>)>d$(75wukL! z0MWT0tM#x^?sZm3k9s@nAmAix;8=Kch3-7H#JA7dUw;a@T~gOPaO;TAkEk0{9xBOK zV!fm{G@oh}ynpZ3gL^`s=X8_qJ#aaSGjUjjPpoaD%_FLspQ0~j^>)-N{(@cP?&VhK HLQnn|mbyN> diff --git a/Resources/Textures/Objects/Misc/meteor.rsi/meta.json b/Resources/Textures/Objects/Misc/meteor.rsi/meta.json index eac06f7000..986fed4345 100644 --- a/Resources/Textures/Objects/Misc/meteor.rsi/meta.json +++ b/Resources/Textures/Objects/Misc/meteor.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from vgstation13 at https://github.com/vgstation-coders/vgstation13/blob/31dd6749bfe32810c46e7913efc99a187479cd51/icons/obj/meteor.dmi. cow_pixel - taken from https://github.com/tgstation/tgstation/commit/53d1f1477d22a11a99c6c6924977cd431075761b, modified by B_Kirill. potato by Chaoticaa (GitHub), modified by B_Kirill. clown_pixel - assembly of [Human sprite - taken from https://github.com/tgstation/tgstation/blob/8024397cc81c5f47f74cf4279e35728487d0a1a7/icons/mob/human_parts_greyscale.dmi and modified by DrSmugleaf ; Clown wig and mask - taken from https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e ; Clown suit - taken from https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 ; Clown shoes - taken from https://github.com/tgstation/tgstation/commit/7e4e9d432d88981fb9bb463970c5b98ce85c0abe ; Giggles von honkerton - taken from https://github.com/tgstation/tgstation/commit/547852588166c8e091b441e4e67169e156bb09c1] by B_Kirill. kudzu - medium meteor + texture of kudzu from https://github.com/tgstation/tgstation/commit/15bf91049e33979a855995579b48592e34bcdd8c by B_Kirill. tendons - medium meteor + texture of tendons [tendons by EmoGarbage404 & tom-leys (github)] by B_Kirill", + "copyright": "Taken from vgstation13 at https://github.com/vgstation-coders/vgstation13/blob/31dd6749bfe32810c46e7913efc99a187479cd51/icons/obj/meteor.dmi. cow_pixel - taken from https://github.com/tgstation/tgstation/commit/53d1f1477d22a11a99c6c6924977cd431075761b and modified by B_Kirill. potato by Chaoticaa (GitHub), modified by B_Kirill. clown_pixel - assembly of [Human sprite - taken from https://github.com/tgstation/tgstation/blob/8024397cc81c5f47f74cf4279e35728487d0a1a7/icons/mob/human_parts_greyscale.dmi and modified by DrSmugleaf ; Clown wig and mask - taken from https://github.com/tgstation/tgstation/commit/4f6190e2895e09116663ef282d3ce1d8b35c032e ; Clown suit - taken from https://github.com/tgstation/tgstation/commit/c838ba21dae97db345e0113f99596decd1d66039 ; Clown shoes - taken from https://github.com/tgstation/tgstation/commit/7e4e9d432d88981fb9bb463970c5b98ce85c0abe ; Giggles von honkerton - taken from https://github.com/tgstation/tgstation/commit/547852588166c8e091b441e4e67169e156bb09c1] by B_Kirill.", "size": { "x": 32, "y": 32 @@ -303,36 +303,6 @@ 0.1 ] ] - }, - { - "name": "kudzu", - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] - }, - { - "name": "tendons", - "delays": [ - [ - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1, - 0.1 - ] - ] } ] } diff --git a/Resources/Textures/Objects/Misc/meteor.rsi/tendons.png b/Resources/Textures/Objects/Misc/meteor.rsi/tendons.png deleted file mode 100644 index caf8e39f7da47b37dbb3c4b93b232befc79d5379..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5466 zcmcIo2Ut_tw%(yh86ac9h7zM9Wzq{FN(UtfsK}^vPLh)lfg~iMh$3Y`Q4vv5#0Cmt zeIf`-l_H7-X``YD*ijTg6af|GozTXaJI>5~_uYKS&N=(6y~@A-wf0W7EO%a_sXjv; z0HDdTw{=0jedQlj6=Zy}FO&fQN?%}Ov)qa+V#64hCDs@NlBp@f5CDTZj;}9SEDMsr z6McQJ-7+>*mxQ{+$0xY>TGW+aEw2G8TdrSGPDG*1F(KX?y^R!A212$+|7h!TS2^{H z<%~xTcmpF;V`S7lgZcT4)ad92aIF?kFa%pEwWwUXUAYyVnwXFk_DPha2&HT7OE;g( zj=IM}_f0|6Rt>SAo!M`pa3>Z${0@skavxx2d?F|wX5 zIA)}@S|=s5UB@`Aeg2E7Q=Uzozc(`r+_7$%pb~?QOGp0-*5=i7)5+k9V(bS~wC<$@ zHXqGaP4aYiRe{Om>66;$*6f>GQU0hbIXe2ewslQrN;DL$rKmXM8oO`*9K~Ov%oQ(R zG6m&VmwlPeqz)##%E0P?rf@*T~j5IWjq-Ks+Re6CV~RMx+5) zWDzEYIR3B;G$D|PI5L?@q%&z0%;*b?Sd(yhOc&e5qqdMcGpwIXCT0={p`oGp zPzqio;S&&Um=cI&0-20MByiGoLKzf>6H4cfX|RQ*9Em_I6NrQuxkiXB3YM8+5l=@# z2o#U26-q~8LI5L#L1F?4Pn3r=EXd`I%ZY;}0mH_*90D8w2f{*`6pjz~lD?MgCXk{QU`m_%d}i6f#;BCde9?q5Y2Od^>{A^lDi;Tso{L4PaE;vMDNc^1-yBqE+50D17oW;E=rlM|CAl*%9> z2WHutVUbYr0s)r^nJ_q9swoY}V3SEWDn#Ys7!aF|Gi5*&m`*k2ame(s^|m5Tu$(^f z^&^$U6>$(9zj?>ykr)gH!fXW|(pRKlc8XasRAoj-daqjQg)8X}DvJv>U=7JJHC!?Ff>K<<&X7 zsWShp=loL+BD*XT*#XA)gny^K$_rAyUi6>t0`k5w9QZd!r?DyIJSM*!KL{c><3~wY zh*YWsIVcY7nRXI6le)8Ptz5&J-yA9xdYYi)E-u}Jce=62(m`<(S{3g(jsB!^j|Oe+ zdsV}Cs_POLS+ z^W?+NpTBJO(TW@ze9-aY-@SOmRaOS4t;!|u9J4>#gf+(%6l$v)?R{o z+uPRBzeCT$8DqQqZNEx6uG&Mfob}SDY@=B|dP7Nn=9>lJi5V)$7}Q2MZAE8iYnHF` zUYXV)M3pzRCYDXDEYkt6jL$67yi4D1l|A&S!z-@~R1KY9)>r&tp^2uWa6z7#VntKT zVGx_O;sG~0*E*5a-SJ@x*k>8?h=P7rbO0n>U3WaqJc3C}<@g=aD4PN7b5*}F3L>&qsqq_+n^J*K7GKSo!=3Omk6)$b<&Ru+#HNWZH zZ9U~vemfp6oN&o5J{Sz7M11ZGe6?J$p&O6(v$}Z2H#gX{r z3Dua;0$z~!!2;$Eovf_d-sXsO>ZYuFYt=f9m1az8dPdWqs?e`L1^=@0#$;YfjFu7V zxs9nS>XFZd+m(YEHbvV85@$F2G@6@)syU=Re6{iDm4_|^T0cz*s#R|Ast%*~9=<5Ng_o>pO;E3R^~f)%=`bFil;NFl1h zN)selQ`OWTeKUc`EhCUHARfI)2(v>h3w?#&%|2wA3t#%?g^c0L}VxStc;LMdWARrDl$~P_iXBi=TuX5pDshH6{vD^ z)C7y32BqKe8BE@!bNBG8h|O9LTJG4bj7)v-bn*5%;;A6lOFyo=S+6o%x%{$~w#vQZ zpPpB4Se3jAXnBewDhRXc>>q6;-ru0}3||ppVN*975F3-)_r!KVem9+4P;WK&dc@AM za6EqO@XQVc%l4G{)An<;LG8AenRYj5=h7T09wt#rmQNQEGDp^X`@#{j4%b^tm;a|4`(q3GfMyVafV!iop3AWrYyNpSWxOvGi-} zUZtX!-KRj<+Q!|4)Q=Yw&ZX!|-sl#~7Ol}HRB6np)T=s!D)&>2`rRPX1>~A1%N_YE zUMS{nd!JHzTi0stZYoL2xHb+~@aL~ExTyMhb4YhlCkM8!By1jM0(mF$_(P!V_ zmJC7S$pw@H)%DX`ukN;VjRk&&3v$Bd9oTtvkzTmQfhP=z><{`S5FOW=R>iW_+LKrxDV-fwpJ zPQzRM9+zFSoiOmhY&U}^cMW2M#^BPm-8xU96HTXRs7DFZqVxolZt4de(7qL4FwH;r zh*E`P2yk!N*`&bVLzFsp(8&9YT?+0gUej#o?TwtB+S`2MW7f^W{?3(qD5#iyH_@Ic z^%o~^T3qIxkQ1WWqGXvD&|`>;r`<7>(iFNP4OM>(E}VTwAwBNl$-TliU7J|Wi8-`G z$~^}!N9-RM5K3AWik1&-wISeK$?~ zqh?uG@blHoKN5T{ISQjztofhMIZtEx>l0lHJ15R8QU`+l#Y+1jza@tFuHa=#8Q7vU zbO~EX(8usBZCOe#A&Dnq}Q7Vno>A0JA z=hV767YVhuz)RcYB^4#}V;>9!fYLmRPra3bwPlt`bccai@f97)n2ogPZjB2Ct@$%| zcC<}cf2ggl{FVy=EHdhOW8S*s{C@w>W|7qmgcFUgGgUd~8)^J_1Kk}8Yr9^ho(IdS zxC?(xSk-n@xvymMsfB>Cx$JF)ndl0eyQ}``j``k02bSF^HuQeKHunsJTbHj^jEk)g zx1FO6LYD6&gK6LgUd!mVHN1Br!)c{-SrdvQIu!q^gr8X1>c7NclO%5l2be0D=%r1U zYrJF)MjOg5wBw@AO$RMna)Ii}ZzLSQkqm=S9CJR|qkFsbYTR*~RD6DK$7vO)=fbY52Hre&u9j{( z=rg~ty|#v?)S58iS*NOz_1@yv3=M~=rPF7Bz3qT;HFtawGf?%l<8$kbLnh4>lZZ*6 zAbzXJ#(lQly(F*qXPGgpb_v_nmv&OUpqf{##oS`W^6U)H+}K^gdFFg$k62dXlbF-R z`$M%YLxM{zX2sm@OvrIuos;D$#et=9GufxML{7800GH zTGW}l8&7}mfW`Vmid&hFw0~WL`y3q)y(8~VNh`I=XBa)E0W_z%N!M1q*}Lw1i6L13 r`GtS2|Ew3jc0ah^_@>RS9YU>GcIWUX^`3h9e|aoBXWO&ZzA^s`qkDGL From b122b95377074ce40d8eabdad762b2d0f54dffe2 Mon Sep 17 00:00:00 2001 From: KeTuFaisPiKiNut <85769816+ketufaispikinut@users.noreply.github.com> Date: Mon, 27 Jul 2026 15:38:28 -0400 Subject: [PATCH 28/35] Fix a dumb bug with the changeling's screech (#44960) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit take 1 Co-authored-by: nomdéraisonnablementlong --- Content.Client/Overlays/ScreechShockWaveOverlay.cs | 1 + Resources/Textures/Shaders/screech_shock_wave.swsl | 6 ++++-- Resources/Textures/Shaders/singularity.swsl | 14 +++++++------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Content.Client/Overlays/ScreechShockWaveOverlay.cs b/Content.Client/Overlays/ScreechShockWaveOverlay.cs index affb7ce8bc..21b80c6e4b 100644 --- a/Content.Client/Overlays/ScreechShockWaveOverlay.cs +++ b/Content.Client/Overlays/ScreechShockWaveOverlay.cs @@ -119,6 +119,7 @@ public sealed partial class ScreechShockWaveOverlay : Overlay _shader.SetParameter("times", _times); _shader.SetParameter("count", _currentCount); _shader.SetParameter("SCREEN_TEXTURE", ScreenTexture); + _shader?.SetParameter("renderScale", args.Viewport.RenderScale * args.Viewport.Eye.Scale); // finally do the rendering var worldHandle = args.WorldHandle; diff --git a/Resources/Textures/Shaders/screech_shock_wave.swsl b/Resources/Textures/Shaders/screech_shock_wave.swsl index 086f78d3e7..2447fb779a 100644 --- a/Resources/Textures/Shaders/screech_shock_wave.swsl +++ b/Resources/Textures/Shaders/screech_shock_wave.swsl @@ -5,9 +5,11 @@ uniform highp float[10] waveSpeeds; uniform highp float[10] downScales; uniform highp float[10] fades; uniform highp float[10] times; + // variables that are the same for everyone uniform lowp int count; uniform sampler2D SCREEN_TEXTURE; +uniform highp vec2 renderScale; void fragment() { @@ -24,8 +26,8 @@ void fragment() WaveCentre.y *= ratio; // calculate the distortion itself - highp float dist = distance(vec2(st.x, st.y * ratio), WaveCentre) * downScales[i]; - highp vec2 delta = vec2(st.x, st.y * ratio) - WaveCentre; + highp float dist = distance(vec2(st.x, st.y * ratio) / renderScale, WaveCentre / renderScale) * downScales[i]; + highp vec2 delta = (vec2(st.x, st.y * ratio) - WaveCentre) / renderScale; highp float angle = atan(delta.y/delta.x); highp float sinf = sin(angle*60.0)/80.0; diff --git a/Resources/Textures/Shaders/singularity.swsl b/Resources/Textures/Shaders/singularity.swsl index 609a4b3b10..7ea9501859 100644 --- a/Resources/Textures/Shaders/singularity.swsl +++ b/Resources/Textures/Shaders/singularity.swsl @@ -8,7 +8,7 @@ uniform lowp int count; uniform highp float[5] falloffPower; uniform highp float[5] intensity; uniform highp vec2[5] position; -// the `5`s in the array lengths correspond to the upper limit on the simultaneous distortion sources that can be present on screen at a time. +// the `5`s in the array lengths correspond to the upper limit on the simultaneous distortion sources that can be present on screen at a time. // If you want to change this, make sure to change all of them here, in the for loop, and, in whatever overlay assigns the uniforms // (apparently #define is an unknown preprocessor directive) @@ -18,28 +18,28 @@ void fragment() { highp vec2 delta; highp float distance; highp float deformation; - + for (int i = 0; i < 5 && i < count; i++) { - + delta = FRAGCOORD.xy - position[i]; distance = length(delta / renderScale); deformation = intensity[i] / pow(distance, falloffPower[i]); - + // ensure deformation goes to zero at max distance // avoids long-range single-pixel shifts that are noticeable when leaving PVS. - + if (distance >= maxDistance) { deformation = 0.0; } else { deformation *= (1.0 - pow(distance/maxDistance, 4.0)); } - + if(deformation > 0.8) deformation = pow(deformation, 0.3); finalCoords -= deformation * delta; } - + COLOR = zTextureSpec(SCREEN_TEXTURE, finalCoords*SCREEN_PIXEL_SIZE ); } From 4009f2d8338c2340be178fe288b4e8a7e33174b5 Mon Sep 17 00:00:00 2001 From: Andrei Hava Date: Mon, 27 Jul 2026 23:07:07 +0300 Subject: [PATCH 29/35] Move SuicideSystem into its own directory (#44965) --- Content.Client/Suicide/SuicideSystem.cs | 5 ++++ .../Chat/Commands/SuicideCommand.cs | 3 +-- .../Kitchen/EntitySystems/MicrowaveSystem.cs | 27 +++++++++---------- .../{Chat => Suicide}/SuicideSystem.cs | 12 ++++----- .../Execution/SharedExecutionSystem.cs | 4 +-- .../{Chat => Suicide}/SharedSuicideSystem.cs | 4 +-- 6 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 Content.Client/Suicide/SuicideSystem.cs rename Content.Server/{Chat => Suicide}/SuicideSystem.cs (95%) rename Content.Shared/{Chat => Suicide}/SharedSuicideSystem.cs (97%) diff --git a/Content.Client/Suicide/SuicideSystem.cs b/Content.Client/Suicide/SuicideSystem.cs new file mode 100644 index 0000000000..517180b651 --- /dev/null +++ b/Content.Client/Suicide/SuicideSystem.cs @@ -0,0 +1,5 @@ +using Content.Shared.Suicide; + +namespace Content.Client.Suicide; + +public sealed class SuicideSystem : SharedSuicideSystem; diff --git a/Content.Server/Chat/Commands/SuicideCommand.cs b/Content.Server/Chat/Commands/SuicideCommand.cs index 87557cb754..813fbf5b2e 100644 --- a/Content.Server/Chat/Commands/SuicideCommand.cs +++ b/Content.Server/Chat/Commands/SuicideCommand.cs @@ -1,7 +1,6 @@ -using Content.Server.GameTicking; using Content.Server.Popups; +using Content.Server.Suicide; using Content.Shared.Administration; -using Content.Shared.Chat; using Content.Shared.Mind; using Robust.Shared.Console; using Robust.Shared.Enums; diff --git a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs index e2a16b2ebf..dd39f63716 100644 --- a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs @@ -1,45 +1,42 @@ +using System.Linq; using Content.Server.Administration.Logs; using Content.Server.Construction; -using Content.Server.Explosion.EntitySystems; +using Content.Server.Construction.Components; using Content.Server.DeviceLinking.Systems; +using Content.Server.Explosion.EntitySystems; using Content.Server.Hands.Systems; using Content.Server.Kitchen.Components; +using Content.Server.Lightning; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Server.Temperature.Systems; -using Content.Shared.Chemistry.Components.SolutionManager; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Chemistry.Reaction; using Content.Shared.Construction.EntitySystems; +using Content.Shared.Damage.Components; using Content.Shared.Database; -using Content.Shared.DeviceLinking.Events; using Content.Shared.Destructible; +using Content.Shared.DeviceLinking.Events; using Content.Shared.FixedPoint; +using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Interaction.Events; -using Robust.Shared.Random; -using Robust.Shared.Audio; -using Content.Server.Lightning; using Content.Shared.Item; using Content.Shared.Kitchen; using Content.Shared.Kitchen.Components; using Content.Shared.Popups; using Content.Shared.Power; +using Content.Shared.Power.EntitySystems; +using Content.Shared.Stacks; +using Content.Shared.Suicide; using Content.Shared.Tag; using Robust.Server.GameObjects; +using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; -using Robust.Shared.Player; -using System.Linq; using Robust.Shared.Prototypes; +using Robust.Shared.Random; using Robust.Shared.Timing; -using Content.Shared.Stacks; -using Content.Server.Construction.Components; -using Content.Shared.Chat; -using Content.Shared.Damage.Components; -using Content.Shared.Power.EntitySystems; -using Content.Shared.Temperature.Components; -using Content.Shared.IdentityManagement; namespace Content.Server.Kitchen.EntitySystems { diff --git a/Content.Server/Chat/SuicideSystem.cs b/Content.Server/Suicide/SuicideSystem.cs similarity index 95% rename from Content.Server/Chat/SuicideSystem.cs rename to Content.Server/Suicide/SuicideSystem.cs index b4f27b945f..936fa6ae89 100644 --- a/Content.Server/Chat/SuicideSystem.cs +++ b/Content.Server/Suicide/SuicideSystem.cs @@ -1,7 +1,6 @@ using Content.Server.Ghost; using Content.Server.Hands.Systems; using Content.Shared.Administration.Logs; -using Content.Shared.Chat; using Content.Shared.Damage.Components; using Content.Shared.Database; using Content.Shared.IdentityManagement; @@ -12,13 +11,14 @@ using Content.Shared.Mind.Components; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; +using Content.Shared.Suicide; using Content.Shared.Tag; using Robust.Shared.Player; using Robust.Shared.Prototypes; -namespace Content.Server.Chat; +namespace Content.Server.Suicide; -public sealed partial class SuicideSystem : EntitySystem +public sealed partial class SuicideSystem : SharedSuicideSystem { [Dependency] private EntityLookupSystem _entityLookupSystem = default!; [Dependency] private ISharedAdminLogManager _adminLogger = default!; @@ -27,7 +27,6 @@ public sealed partial class SuicideSystem : EntitySystem [Dependency] private MobStateSystem _mobState = default!; [Dependency] private SharedPopupSystem _popup = default!; [Dependency] private GhostSystem _ghostSystem = default!; - [Dependency] private SharedSuicideSystem _suicide = default!; [Dependency] private EntityQuery _itemQuery = default!; private static readonly ProtoId CannotSuicideTag = "CannotSuicide"; @@ -83,6 +82,7 @@ public sealed partial class SuicideSystem : EntitySystem { _adminLogger.Add(LogType.Mind, $"{ToPrettyString(victim):player} suicided."); } + return true; } @@ -162,13 +162,13 @@ public sealed partial class SuicideSystem : EntitySystem if (args.DamageSpecifier != null) { - _suicide.ApplyLethalDamage(victim, args.DamageSpecifier); + ApplyLethalDamage(victim, args.DamageSpecifier); args.Handled = true; return; } args.DamageType ??= "Bloodloss"; - _suicide.ApplyLethalDamage(victim, args.DamageType); + ApplyLethalDamage(victim, args.DamageType); args.Handled = true; } } diff --git a/Content.Shared/Execution/SharedExecutionSystem.cs b/Content.Shared/Execution/SharedExecutionSystem.cs index 17c44cf430..e1ca1a0268 100644 --- a/Content.Shared/Execution/SharedExecutionSystem.cs +++ b/Content.Shared/Execution/SharedExecutionSystem.cs @@ -1,17 +1,17 @@ using Content.Shared.ActionBlocker; -using Content.Shared.Chat; using Content.Shared.CombatMode; using Content.Shared.Damage.Components; using Content.Shared.Database; using Content.Shared.DoAfter; using Content.Shared.IdentityManagement; +using Content.Shared.Interaction.Events; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; +using Content.Shared.Suicide; using Content.Shared.Verbs; using Content.Shared.Weapons.Melee; using Content.Shared.Weapons.Melee.Events; -using Content.Shared.Interaction.Events; using Robust.Shared.Audio.Systems; namespace Content.Shared.Execution; diff --git a/Content.Shared/Chat/SharedSuicideSystem.cs b/Content.Shared/Suicide/SharedSuicideSystem.cs similarity index 97% rename from Content.Shared/Chat/SharedSuicideSystem.cs rename to Content.Shared/Suicide/SharedSuicideSystem.cs index 01f88d9276..c7e7206f0d 100644 --- a/Content.Shared/Chat/SharedSuicideSystem.cs +++ b/Content.Shared/Suicide/SharedSuicideSystem.cs @@ -6,9 +6,9 @@ using Content.Shared.Damage.Systems; using Content.Shared.Mobs.Components; using Robust.Shared.Prototypes; -namespace Content.Shared.Chat; +namespace Content.Shared.Suicide; -public sealed partial class SharedSuicideSystem : EntitySystem +public abstract partial class SharedSuicideSystem : EntitySystem { private static readonly ProtoId FallbackDamageType = "Blunt"; From da04a52e80246454ae577bfc9b56989064a96b60 Mon Sep 17 00:00:00 2001 From: Kowlin <10947836+Kowlin@users.noreply.github.com> Date: Mon, 27 Jul 2026 22:07:57 +0200 Subject: [PATCH 30/35] Update configs (#44974) --- .../ConfigPresets/WizardsDen/lizard.toml | 2 +- .../ConfigPresets/WizardsDen/raptor.toml | 23 +++++++++++++++++++ .../ConfigPresets/WizardsDen/salamander.toml | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 Resources/ConfigPresets/WizardsDen/raptor.toml diff --git a/Resources/ConfigPresets/WizardsDen/lizard.toml b/Resources/ConfigPresets/WizardsDen/lizard.toml index cc849e435d..229732362a 100644 --- a/Resources/ConfigPresets/WizardsDen/lizard.toml +++ b/Resources/ConfigPresets/WizardsDen/lizard.toml @@ -3,7 +3,7 @@ # Nothing specific yet [game] -hostname = "[EN] Wizard's Den Lizard [US West]" +hostname = "[EN] Wizard's Den Lizard [NA West]" panic_bunker.enabled = false panic_bunker.disable_with_admins = false panic_bunker.enable_without_admins = false diff --git a/Resources/ConfigPresets/WizardsDen/raptor.toml b/Resources/ConfigPresets/WizardsDen/raptor.toml new file mode 100644 index 0000000000..2c2e7cdfd3 --- /dev/null +++ b/Resources/ConfigPresets/WizardsDen/raptor.toml @@ -0,0 +1,23 @@ +# Configuration preset used on Wizard's Den Raptor + +[game] +hostname = "[EN] Wizard's Den Raptor [NA East]" +desc = "Official English server for Space Station 14.\nVanilla, roleplay ruleset.\n\nPlease report bugs on our GitHub, forum, or community Discord." +panic_bunker.enabled = false +panic_bunker.disable_with_admins = false +panic_bunker.enable_without_admins = false +panic_bunker.custom_reason = "" + +[hub] +tags = "lang:en,region:am_n_e,rp:low" + +[server] +# This needs to be specified even though it's identical to the hostname, because fallback lobby name is "Lobby " which would be too long and go out of bounds +lobby_name = "[EN] Wizard's Den Raptor [NA East]" +force_client_hud_version_watermark = true + +[chat] +motd = "" + +[feedback] +valid_origins = "wizden wizden_master" diff --git a/Resources/ConfigPresets/WizardsDen/salamander.toml b/Resources/ConfigPresets/WizardsDen/salamander.toml index 7112fc8d8b..69e9f342d5 100644 --- a/Resources/ConfigPresets/WizardsDen/salamander.toml +++ b/Resources/ConfigPresets/WizardsDen/salamander.toml @@ -2,7 +2,7 @@ [game] desc = "Official English Space Station 14 servers. Medium roleplay ruleset. Open to anyone with at least 20 hours of playtime on any Wizard's Den server. Freely joinable when the player count is less than 15 players." -hostname = "[EN][MRP] Wizard's Den Salamander [US West]" +hostname = "[EN][MRP] Wizard's Den Salamander [NA West]" round_restart_time = 300 [server] From 5dfd4e57f314228260df2f7cfaee0d53e1124133 Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Mon, 1 Jun 2026 19:50:53 -0700 Subject: [PATCH 31/35] reapply --- .../EntitySystems/ExplosionSystem.Airtight.cs | 91 ++++++++++++++++--- .../ExplosionSystem.Processing.cs | 2 +- .../EntitySystems/ExplosionSystem.cs | 2 + .../en-US/explosions/explosion-resistance.ftl | 2 +- .../Entities/Clothing/OuterClothing/armor.yml | 10 +- .../Clothing/OuterClothing/hardsuits.yml | 12 +-- 6 files changed, 88 insertions(+), 31 deletions(-) diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs index ca3be8c37f..9d839264e4 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Airtight.cs @@ -230,7 +230,11 @@ public sealed partial class ExplosionSystem totalDamageTarget = _destructibleSystem.DestroyedAt(uid, destructible); } - if (totalDamageTarget == FixedPoint2.MaxValue || !_injurableQuery.TryGetComponent(uid, out var injurable)) + // We are assuming airtight entities don't need to relay since they shouldn't have inventories. + var modifiers = _damageableSystem.GetDamageModifierSet(uid); + var explosionComp = _explosionResistanceQuery.CompOrNull(uid); + + if (totalDamageTarget == FixedPoint2.MaxValue || !_injurableQuery.TryComp(uid, out var injurable)) { for (var i = 0; i < explosionTolerance.Length; i++) { @@ -254,30 +258,89 @@ public sealed partial class ExplosionSystem // evaluate the damage that this damage type would do to this entity var damagePerIntensity = FixedPoint2.Zero; + + // Create a dictionary of intensity thresholds which dictates when damagePerIntensity increases! + var damageThresholds = new SortedDictionary(); foreach (var (type, value) in explosionType.DamagePerIntensity.DamageDict) { if (!_damageableSystem.CanBeDamagedBy((uid, injurable), type)) continue; - // TODO EXPLOSION SYSTEM - // add a variant of the event that gets raised once, instead of once per prototype. - // Or better yet, just calculate this manually w/o the event. - // The event mainly exists for indirect resistances via things like inventory & clothing - // But this shouldn't matter for airtight entities. - var ev = new GetExplosionResistanceEvent(explosionType.ID); - RaiseLocalEvent(uid, ref ev); + var modifier = mod; + if (explosionComp != null) + { + modifier *= explosionComp.DamageCoefficient; + if (explosionComp.Modifiers.TryGetValue(explosionType.ID, out var typeMod)) + modifier *= typeMod; + } - damagePerIntensity += value * mod * Math.Max(0, ev.DamageCoefficient); + if (modifiers != null) + { + if (modifiers.Coefficients.TryGetValue(type, out var armorMod)) + modifier *= armorMod; + + if (modifiers.FlatReduction.TryGetValue(type, out var flat)) + { + if (flat > 0) + { + // If the flat modifier is reducing damage, we cache the extra damage per intensity for later! + var intensity = flat / value; + var damage = damageThresholds.GetValueOrDefault(intensity); + damageThresholds[intensity] = value * Math.Max(0, modifier) + damage; + continue; + } + } + } + + damagePerIntensity += value * Math.Max(0, modifier); } - var toleranceValue = damagePerIntensity > 0 - ? (float) ((totalDamageTarget - _damageableSystem.GetTotalDamage(uid)) / damagePerIntensity) - : ToleranceValues.Invulnerable; - - explosionTolerance[index] = toleranceValue; + explosionTolerance[index] += GetExplosionTolerance(uid, totalDamageTarget, damagePerIntensity, damageThresholds); } } + private FixedPoint2 GetExplosionTolerance(EntityUid uid, + FixedPoint2 totalDamageTarget, + FixedPoint2 damagePerIntensity, + SortedDictionary damageThresholds) + { + return GetExplosionTolerance(totalDamageTarget - _damageableSystem.GetTotalDamage(uid), + damagePerIntensity, + damageThresholds); + } + + private FixedPoint2 GetExplosionTolerance(FixedPoint2 damageTarget, + FixedPoint2 damagePerIntensity, + SortedDictionary damageThresholds) + { + var tolerance = damagePerIntensity > 0 ? damageTarget / damagePerIntensity : ToleranceValues.Invulnerable; + var prevIntensity = FixedPoint2.Zero; + /* + * Calculated through a pretty simple equation which relies on this dictionary being sorted. + * We precalculate the intensity at which an explosion's damage type exceeds the flat reduction of an entity's armor + * That is done above and stored in our `damageThresholds` SortedDictionary. If you can find a more mem efficient way to do this be my guest, + * but these values *have* to be sorted. + */ + foreach (var (intensity, damage) in damageThresholds) + { + // Check if the object would break before hitting this threshold, if so, return the current tolerance value + if (intensity > tolerance) + return tolerance; + + /* + * If the object breaks after this threshold, reduce the HP left by the amount of HP lost between the last flat reduction and this one + * Then adjust our damagePerIntensity and new tolerance values accordingly. + * Lastly store this intensity value so we can calculate the delta next loop. + */ + damageTarget -= (intensity - prevIntensity) * damagePerIntensity; + damagePerIntensity += damage; + tolerance = intensity + damageTarget / damagePerIntensity; + prevIntensity = intensity; + } + + return tolerance; + } + private void OnAirtightGridRemoved(EntityUid entity) { if (!TryComp(entity, out ExplosionAirtightGridComponent? airtightGrid)) diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs index c33e02efa8..df00da3647 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs @@ -452,7 +452,7 @@ public sealed partial class ExplosionSystem continue; // TODO EXPLOSIONS turn explosions into entities, and pass the the entity in as the damage origin. - _damageableSystem.ChangeDamage((entity, damageable), damage, ignoreResistances: true); + _damageableSystem.ChangeDamage((entity, damageable), damage); if (_actorQuery.HasComp(entity)) { diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs index e043c89392..cdb90c781d 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.cs @@ -6,6 +6,7 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Destructible; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NPC.Pathfinding; +using Content.Shared.Armor; using Content.Shared.Atmos.Components; using Content.Shared.Camera; using Content.Shared.CCVar; @@ -60,6 +61,7 @@ public sealed partial class ExplosionSystem : SharedExplosionSystem [Dependency] private EntityQuery _actorQuery = default!; [Dependency] private EntityQuery _destructibleQuery = default!; [Dependency] private EntityQuery _damageableQuery = default!; + [Dependency] private EntityQuery _explosionResistanceQuery = default!; [Dependency] private EntityQuery _injurableQuery = default!; [Dependency] private EntityQuery _airtightQuery = default!; [Dependency] private EntityQuery _tileHistoryQuery = default!; diff --git a/Resources/Locale/en-US/explosions/explosion-resistance.ftl b/Resources/Locale/en-US/explosions/explosion-resistance.ftl index 6ebb406b9a..50268ef32c 100644 --- a/Resources/Locale/en-US/explosions/explosion-resistance.ftl +++ b/Resources/Locale/en-US/explosions/explosion-resistance.ftl @@ -1,2 +1,2 @@ -explosion-resistance-coefficient-value = - [color=orange]Explosion[/color] damage reduced by [color=lightblue]{$value}%[/color]. +explosion-resistance-coefficient-value = - [color=orange]Explosion[/color] damage reduced by an additional [color=lightblue]{$value}%[/color]. explosion-resistance-contents-coefficient-value = - [color=orange]Explosion[/color] damage [color=white]to contents[/color] reduced by [color=lightblue]{$value}%[/color]. diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml index edbe0f95e4..4c986c4881 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/armor.yml @@ -114,8 +114,6 @@ Piercing: 0.6 Heat: 0.5 Caustic: 0.9 - - type: ExplosionResistance - damageCoefficient: 0.65 - type: GroupExamine - type: entity @@ -184,8 +182,6 @@ Heat: 0.3 Radiation: 0.5 Caustic: 0.5 - - type: ExplosionResistance - damageCoefficient: 0.5 - type: FireProtection reduction: 0.85 - type: StaticPrice @@ -235,8 +231,6 @@ Piercing: 0.35 Heat: 0.35 Caustic: 0.5 - - type: ExplosionResistance - damageCoefficient: 0.35 - type: StaminaResistance # do not add these to other equipment or mobs, we don't want to microbalance these everywhere damageCoefficient: 0.45 - type: ClothingSpeedModifier @@ -422,7 +416,7 @@ sprintModifier: 0.65 - type: HeldSpeedModifier - type: ExplosionResistance - damageCoefficient: 0.5 + damageCoefficient: 0.75 - type: GroupExamine - type: ProtectedFromStepTriggers slots: WITHOUT_POCKET @@ -448,7 +442,7 @@ sprintModifier: 0.8 - type: HeldSpeedModifier - type: ExplosionResistance - damageCoefficient: 0.4 + damageCoefficient: 0.6 - type: GroupExamine - type: Construction graph: BoneArmor diff --git a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml index 26ab26bd5e..056b47da30 100644 --- a/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml +++ b/Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml @@ -159,7 +159,7 @@ highPressureMultiplier: 0.5 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.3 + damageCoefficient: 0.5 - type: Armor modifiers: coefficients: @@ -228,7 +228,7 @@ highPressureMultiplier: 0.5 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.4 + damageCoefficient: 0.5 - type: Armor modifiers: coefficients: @@ -290,7 +290,7 @@ highPressureMultiplier: 0.5 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.4 + damageCoefficient: 0.5 - type: Armor modifiers: coefficients: @@ -321,7 +321,7 @@ highPressureMultiplier: 0.02 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.5 + damageCoefficient: 0.7 - type: Armor modifiers: coefficients: @@ -601,7 +601,7 @@ highPressureMultiplier: 0.02 lowPressureMultiplier: 1000 - type: ExplosionResistance - damageCoefficient: 0.2 + damageCoefficient: 0.3 - type: FireProtection reduction: 0.8 - type: StaminaResistance # do not add these to other equipment or mobs, we don't want to microbalance these everywhere @@ -683,8 +683,6 @@ - type: PressureProtection highPressureMultiplier: 0.2 lowPressureMultiplier: 1000 - - type: ExplosionResistance - damageCoefficient: 0.3 # - type: StaminaResistance # Should not have stamina resistance, this is purely so people know it was not forgotten. - type: Armor modifiers: From cf0b70c5e1c9d19d762db34dd0b56d8c88ca649b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=81da?= Date: Wed, 22 Jul 2026 05:31:08 -0500 Subject: [PATCH 32/35] cherry 2 --- .../Destructible/DestructibleComponent.cs | 3 +- Resources/Prototypes/Body/Species/vox.yml | 26 -- Resources/Prototypes/Body/species_base.yml | 1 + .../Mobs/Cyborgs/base_borg_chassis.yml | 99 ++++---- .../Entities/Mobs/Cyborgs/xenoborgs.yml | 6 +- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 114 +++++---- .../Entities/Mobs/NPCs/argocyte.yml | 2 +- .../Entities/Mobs/NPCs/asteroid.yml | 6 +- .../Entities/Mobs/NPCs/behonker.yml | 3 +- .../Prototypes/Entities/Mobs/NPCs/carp.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/flesh.yml | 4 +- .../Entities/Mobs/NPCs/hellspawn.yml | 1 + .../Prototypes/Entities/Mobs/NPCs/hivebot.yml | 2 +- .../Entities/Mobs/NPCs/lavaland.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/mimic.yml | 2 +- .../Entities/Mobs/NPCs/miscellaneous.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/pets.yml | 6 +- .../Entities/Mobs/NPCs/regalrat.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/scurret.yml | 5 +- .../Prototypes/Entities/Mobs/NPCs/slimes.yml | 2 +- .../Prototypes/Entities/Mobs/NPCs/space.yml | 10 +- .../Prototypes/Entities/Mobs/NPCs/xeno.yml | 6 +- .../Entities/Mobs/Player/changeling.yml | 2 +- .../Entities/Mobs/Player/dragon.yml | 2 +- Resources/Prototypes/Entities/Mobs/base.yml | 82 ++++--- .../Drinks/drinks_base_materials.yml | 23 +- .../Drinks/drinks_bottles_glass.yml | 8 +- .../Objects/Consumable/Drinks/drinks_cups.yml | 12 + .../Objects/Consumable/Drinks/drinks_fun.yml | 12 + .../Consumable/Drinks/drinks_metamorphic.yml | 12 + .../Consumable/Drinks/drinks_special.yml | 24 ++ .../Consumable/Food/Containers/plate.yml | 77 +++--- .../Entities/Objects/Decoration/flora.yml | 15 +- .../Entities/Objects/Decoration/mining.yml | 52 ++-- .../Syndicate_Gadgets/singularity_beacon.yml | 18 +- .../Entities/Objects/Devices/payload.yml | 8 - .../Entities/Objects/Devices/station_map.yml | 10 +- .../Entities/Objects/Devices/wristwatch.yml | 10 +- .../Objects/Materials/Sheets/glass.yml | 42 ++-- .../Entities/Objects/Materials/base.yml | 13 +- .../Entities/Objects/Materials/ingots.yml | 10 - .../Entities/Objects/Materials/shards.yml | 10 - .../Entities/Objects/Misc/candles.yml | 20 +- .../Entities/Objects/Misc/desk_bell.yml | 64 ++--- .../Entities/Objects/Power/lights.yml | 15 +- .../Entities/Objects/Power/powersink.yml | 18 +- .../Entities/Objects/Shields/shields.yml | 53 ++-- .../Specific/Chemistry/chemistry-vials.yml | 25 +- .../Objects/Specific/Security/target.yml | 43 ++-- .../Service/vending_machine_restock.yml | 10 +- .../Entities/Objects/Tools/cable_coils.yml | 12 +- .../Entities/Objects/Tools/fulton.yml | 15 +- .../Entities/Objects/Tools/toolbox.yml | 1 + .../Entities/Objects/Weapons/Bombs/cord.yml | 9 +- .../Objects/Weapons/Bombs/detonator.yml | 11 +- .../Objects/Weapons/Bombs/firebomb.yml | 7 +- .../Objects/Weapons/Bombs/plastic.yml | 7 +- .../Ammunition/Cartridges/base_cartridge.yml | 14 +- .../Guns/Turrets/turrets_ballistic.yml | 7 +- .../Weapons/Guns/Turrets/turrets_base.yml | 81 +++--- .../Weapons/Guns/Turrets/turrets_energy.yml | 4 +- .../Entities/Objects/Weapons/Melee/spear.yml | 7 - .../Weapons/Throwable/base_grenades.yml | 34 +-- .../Objects/Weapons/Throwable/grenades.yml | 21 +- .../Weapons/Throwable/scattering_grenades.yml | 2 +- .../Entities/Objects/Weapons/security.yml | 10 +- .../Prototypes/Entities/Objects/base_item.yml | 20 +- .../Structures/Decoration/crystals.yml | 150 ++++-------- .../Dispensers/base_structuredispensers.yml | 6 +- .../Entities/Structures/Dispensers/chem.yml | 13 - .../Doors/MaterialDoors/material_doors.yml | 8 - .../Structures/Doors/Windoors/assembly.yml | 116 ++++----- .../Doors/Windoors/base_structurewindoors.yml | 230 +++++------------- .../Structures/Doors/Windoors/clockwork.yml | 4 +- .../Furniture/Tables/base_structuretables.yml | 10 +- .../Structures/Furniture/Tables/tables.yml | 18 +- .../Entities/Structures/Furniture/beds.yml | 29 ++- .../Entities/Structures/Furniture/bench.yml | 11 + .../Entities/Structures/Furniture/carpets.yml | 118 ++------- .../Entities/Structures/Furniture/chairs.yml | 103 ++++++-- .../Entities/Structures/Furniture/toilet.yml | 20 +- .../Structures/Holographic/projections.yml | 45 +++- .../Structures/Lighting/base_lighting.yml | 87 ++++--- .../Structures/Machines/Computers/frame.yml | 18 +- .../Machines/Medical/biomass_reclaimer.yml | 10 +- .../Machines/Medical/chemistry_machines.yml | 10 +- .../Structures/Machines/Medical/cryo_pod.yml | 10 +- .../Machines/Medical/disease_diagnoser.yml | 10 +- .../Machines/Medical/vaccinator.yml | 10 +- .../Structures/Machines/anomaly_equipment.yml | 16 +- .../Structures/Machines/anomaly_sync.yml | 10 +- .../Structures/Machines/artifact_analyzer.yml | 23 +- .../Machines/base_structuremachines.yml | 54 +++- .../Structures/Machines/chem_master.yml | 11 +- .../Structures/Machines/cloning_machine.yml | 13 +- .../Structures/Machines/fatextractor.yml | 13 +- .../Structures/Machines/fax_machine.yml | 20 +- .../Structures/Machines/flatpacker.yml | 10 +- .../Structures/Machines/gravity_generator.yml | 11 +- .../Entities/Structures/Machines/holopad.yml | 10 +- .../Entities/Structures/Machines/hotplate.yml | 10 +- .../Entities/Structures/Machines/jukebox.yml | 16 +- .../Entities/Structures/Machines/lathe.yml | 8 +- .../Structures/Machines/mail_teleporter.yml | 4 +- .../Structures/Machines/medical_scanner.yml | 10 +- .../Structures/Machines/microwave.yml | 13 +- .../Structures/Machines/reagent_grinder.yml | 10 +- .../Entities/Structures/Machines/salvage.yml | 2 +- .../Structures/Machines/seed_extractor.yml | 10 +- .../Structures/Machines/smartfridge.yml | 15 +- .../Structures/Machines/stasisbed.yml | 19 +- .../Machines/surveillance_camera_routers.yml | 20 +- .../Structures/Machines/telecomms.yml | 11 +- .../Structures/Machines/vending_machines.yml | 16 +- .../Structures/Piping/Atmospherics/binary.yml | 8 +- .../Structures/Piping/Atmospherics/pipes.yml | 72 +++--- .../Piping/Atmospherics/portable.yml | 29 +-- .../Structures/Piping/Atmospherics/unary.yml | 6 +- .../Power/Generation/generators.yml | 74 ++++-- .../Power/Generation/portable_generator.yml | 13 +- .../Structures/Power/Generation/teg.yml | 4 +- .../Entities/Structures/Power/cables.yml | 6 - .../Entities/Structures/Power/chargers.yml | 6 +- .../Entities/Structures/Power/smes.yml | 12 +- .../Entities/Structures/Power/substation.yml | 11 +- .../Entities/Structures/Shuttles/cannons.yml | 60 +---- .../Structures/Shuttles/thrusters.yml | 31 +-- .../Storage/Canisters/gas_canisters.yml | 107 +------- .../Closets/Lockers/base_structurelockers.yml | 24 -- .../Storage/Closets/Lockers/lockers.yml | 34 +-- .../Storage/Closets/base_structureclosets.yml | 44 ++-- .../Storage/Crates/base_structurecrates.yml | 76 +++--- .../Structures/Storage/Crates/crates.yml | 29 ++- .../Storage/Tanks/base_structuretanks.yml | 22 +- .../Entities/Structures/Storage/barrels.yml | 2 +- .../Entities/Structures/Storage/glass_box.yml | 8 - .../Structures/Wallmounts/Signs/posters.yml | 8 +- .../Structures/Wallmounts/Storage/shelfs.yml | 86 ++----- .../WallmountMachines/station_map.yml | 1 + .../Entities/Structures/Walls/asteroid.yml | 35 +-- .../Entities/Structures/Walls/fence_metal.yml | 32 +-- .../Entities/Structures/Walls/fence_wood.yml | 34 ++- .../Entities/Structures/Walls/girders.yml | 20 +- .../Structures/Walls/inflatable_wall.yml | 17 +- .../Entities/Structures/Walls/meteor.yml | 2 +- .../Entities/Structures/Walls/walls.yml | 128 ++++------ .../Entities/Structures/Windows/clockwork.yml | 22 +- .../Entities/Structures/Windows/mining.yml | 9 +- .../Entities/Structures/Windows/plasma.yml | 14 +- .../Structures/Windows/reinforced.yml | 13 +- .../Entities/Structures/Windows/rplasma.yml | 13 +- .../Entities/Structures/Windows/ruranium.yml | 13 +- .../Entities/Structures/Windows/shuttle.yml | 4 +- .../Entities/Structures/Windows/uranium.yml | 14 +- .../Entities/Structures/Windows/window.yml | 135 +++++----- .../Entities/Structures/Windows/xenoresin.yml | 25 +- .../Entities/Structures/cargo_telepad.yml | 12 +- .../Entities/Structures/hydro_tray.yml | 6 +- .../Entities/Structures/plastic_flaps.yml | 16 -- .../Prototypes/Entities/Structures/soil.yml | 41 ++-- 160 files changed, 1754 insertions(+), 2273 deletions(-) diff --git a/Content.Server/Destructible/DestructibleComponent.cs b/Content.Server/Destructible/DestructibleComponent.cs index d991d8b2f9..41f4c9c5c1 100644 --- a/Content.Server/Destructible/DestructibleComponent.cs +++ b/Content.Server/Destructible/DestructibleComponent.cs @@ -6,7 +6,7 @@ namespace Content.Server.Destructible; /// When attached to an , allows it to take damage /// and triggers thresholds when reached. /// -[RegisterComponent] +[RegisterComponent, Access(typeof(DestructibleSystem))] public sealed partial class DestructibleComponent : Component { /// @@ -14,6 +14,7 @@ public sealed partial class DestructibleComponent : Component /// includes their triggers and resultant behaviors. /// [DataField(customTypeSerializer: typeof(DamageThresholdsSerializer))] + [AlwaysPushInheritance] public List Thresholds = new(); /// diff --git a/Resources/Prototypes/Body/Species/vox.yml b/Resources/Prototypes/Body/Species/vox.yml index e94375594e..94a8a7d37a 100644 --- a/Resources/Prototypes/Body/Species/vox.yml +++ b/Resources/Prototypes/Body/Species/vox.yml @@ -183,12 +183,6 @@ amount: 5 - type: Destructible thresholds: - - trigger: - !type:DamageTypeTrigger - damageType: Blunt - damage: 400 - behaviors: - - !type:GibBehavior { } - trigger: !type:DamageTypeTrigger damageType: Heat @@ -200,26 +194,6 @@ FoodMeatChickenFriedVox: min: 3 max: 5 - - !type:BurnBodyBehavior - popupMessage: bodyburn-vox-text-others - - !type:PlaySoundBehavior - sound: - collection: MeatLaserImpact - - trigger: - !type:DamageTypeTrigger - damageType: Radiation - damage: 15 - behaviors: - - !type:PopupBehavior - popup: mouth-taste-metal - popupType: LargeCaution - targetOnly: true - - trigger: - !type:DamageTypeTrigger - damageType: Radiation - damage: 40 - behaviors: - - !type:VomitBehavior - type: PassiveDamage # Augment normal health regen to be able to tank some Poison damage # This allows Vox to take their mask off temporarily to eat something without needing a trip to medbay afterwards. diff --git a/Resources/Prototypes/Body/species_base.yml b/Resources/Prototypes/Body/species_base.yml index 5b72f503ab..6428ddb87e 100644 --- a/Resources/Prototypes/Body/species_base.yml +++ b/Resources/Prototypes/Body/species_base.yml @@ -162,6 +162,7 @@ - MobAtmosStandard - MobFlammable - BaseSpeciesMob + - BaseMobDestructible id: BaseSpeciesMobOrganic save: false components: diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index 764f6954e3..22f72eae78 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -169,32 +169,6 @@ - type: Damageable - type: Injurable damageContainer: Silicon - - type: Destructible - generateOverkillThreshold: false - thresholds: - - trigger: - !type:DamageTrigger - damage: 75 - behaviors: - - !type:PlaySoundBehavior - sound: - path: /Audio/Machines/warning_buzzer.ogg - params: - volume: 5 - - trigger: - !type:DamageTrigger - damage: 300 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:EmptyContainersBehaviour - containers: - - borg_brain - - borg_module - - cell_slot - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: HandheldLight toggleOnInteract: false wattage: 0.2 @@ -261,6 +235,32 @@ id: BaseBorgChassis components: - type: IonStormTarget + - type: Destructible + generateOverkillThreshold: false + thresholds: + - trigger: + !type:DamageTrigger + damage: 75 + behaviors: + - !type:PlaySoundBehavior + sound: + path: /Audio/Machines/warning_buzzer.ogg + params: + volume: 5 + - trigger: + !type:DamageTrigger + damage: 300 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:EmptyContainersBehaviour + containers: + - borg_brain + - borg_module + - cell_slot + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity abstract: true @@ -502,6 +502,32 @@ - type: NpcFactionMember factions: - Xenoborg + - type: PointLight + color: "#3010ff" + energy: 7 + - type: GuideHelp + guides: + - Cyborgs + - Robotics + - Xenoborgs + - type: Access + tags: + - Xenoborg + - type: AccessReader + access: [["Xenoborg"]] + - type: ShowJobIcons # not sure if it is needed + - type: ShowCrewIcons + - type: InteractionPopup + interactSuccessSound: + path: /Audio/Ambience/Objects/periodic_beep.ogg + - type: Xenoborg + - type: BypassLock + bypassDelay: 15 # We don't want people to easily be able to remove xenoborg brains. + +- type: entity + abstract: true + id: BaseXenoborgDestructible + components: - type: Destructible thresholds: - trigger: @@ -532,24 +558,3 @@ - cell_slot - !type:DoActsBehavior acts: [ "Destruction" ] - - type: PointLight - color: "#3010ff" - energy: 7 - - type: GuideHelp - guides: - - Cyborgs - - Robotics - - Xenoborgs - - type: Access - tags: - - Xenoborg - - type: AccessReader - access: [["Xenoborg"]] - - type: ShowJobIcons # not sure if it is needed - - type: ShowCrewIcons - - type: InteractionPopup - interactSuccessSound: - path: /Audio/Ambience/Objects/periodic_beep.ogg - - type: Xenoborg - - type: BypassLock - bypassDelay: 15 # We don't want people to easily be able to remove xenoborg brains. diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml index 77c82f3fbd..4e14e24cf1 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/xenoborgs.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseXenoborgChassis, BaseXenoborgTransponder ] + parent: [ BaseXenoborgChassis, BaseXenoborgTransponder, BaseXenoborgDestructible ] id: XenoborgEngi name: engi xenoborg suffix: with brain @@ -148,7 +148,7 @@ startingItem: PowerCellHigh - type: entity - parent: [ BaseXenoborgChassis, BaseXenoborgTransponder ] + parent: [ BaseXenoborgChassis, BaseXenoborgTransponder, BaseXenoborgDestructible ] id: XenoborgScout name: scout xenoborg suffix: with brain @@ -203,7 +203,7 @@ startingItem: PowerCellHigh - type: entity - parent: [ BaseXenoborgChassis, BaseXenoborgTransponder ] + parent: [ BaseXenoborgChassis, BaseXenoborgTransponder, BaseXenoborgDestructible ] id: XenoborgStealth name: stealth xenoborg suffix: with brain diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index f603fcf136..90fa37782e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -199,7 +199,7 @@ - type: entity name: chicken - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobChicken description: Comes before an egg, and IS a dinosaur! components: @@ -348,17 +348,12 @@ lifetime: 21 - type: entity - name: cockroach + abstract: true parent: [SolutionFood, SolutionTiny, SimpleMobBase, BaseSlicingRefinable, MobNightVision] - id: MobCockroach - description: This station is just crawling with bugs. + id: BaseCockroach components: - type: Sprite drawdepth: SmallMobs - sprite: Mobs/Animals/cockroach.rsi - layers: - - map: ["enum.DamageStateVisualLayers.Base"] - state: cockroach - type: Item size: Tiny - type: HTN @@ -385,14 +380,6 @@ - type: MovementSpeedModifier baseWalkSpeed : 2.5 baseSprintSpeed : 5 - - type: DamageStateVisuals - states: - Alive: - Base: cockroach - Critical: - Base: cockroach_dead - Dead: - Base: cockroach_dead - type: Bloodstream bloodReferenceSolution: reagents: @@ -422,15 +409,6 @@ tags: - Trash - VimPilot - - type: Destructible - thresholds: - - trigger: - !type:DamageTypeTrigger - damageType: Blunt - damage: 10 - behaviors: - - !type:GibBehavior - recursive: false - type: NonSpreaderZombie - type: StepTrigger requiredTriggeredSpeed: 1 @@ -448,9 +426,38 @@ types: Piercing: 0 +- type: entity + parent: BaseCockroach + id: MobCockroach + name: cockroach + description: This station is just crawling with bugs. + components: + - type: Sprite + sprite: Mobs/Animals/cockroach.rsi + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: cockroach + - type: DamageStateVisuals + states: + Alive: + Base: cockroach + Critical: + Base: cockroach_dead + Dead: + Base: cockroach_dead + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 10 + behaviors: + - !type:GibBehavior + recursive: false + - type: entity name: glockroach - parent: [MobCockroach, BaseSlicingRefinable] + parent: MobCockroach suffix: Admeme id: MobGlockroach description: This station is just crawling with bu- OH GOD THAT COCKROACH HAS A GUN!!! @@ -476,13 +483,10 @@ - type: NpcFactionMember factions: - SimpleHostile - - type: ToolRefinable - refineResult: - - id: FoodMeatSlime - type: entity name: mothroach - parent: [ BaseMobMothroach, MobCockroach, BaseSlicingRefinable ] + parent: [ BaseMobMothroach, BaseCockroach, BaseSlicingRefinable ] id: MobMothroach description: This is the adorable by-product of multiple attempts at genetically mixing mothpeople with cockroaches. components: @@ -656,7 +660,7 @@ - type: entity name: mallard duck #Quack - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobDuckMallard description: An adorable mallard duck, it's fluffy and soft! components: @@ -859,7 +863,7 @@ - type: entity name: cow - parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable ] + parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible ] id: MobCow description: Moo. components: @@ -950,7 +954,7 @@ - type: entity name: crab - parent: [ SimpleMobBase, BaseMobHemocyanin, BaseSlicingRefinable ] + parent: [ SimpleMobBase, BaseMobHemocyanin, BaseSlicingRefinable, BaseMobDestructible ] id: MobCrab description: A folk legend goes around that his claw snaps spacemen out of existence over distasteful remarks. Be polite and tolerant for your own safety. components: @@ -1018,7 +1022,7 @@ - type: entity name: goat - parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable ] + parent: [ BaseMobRuminant, SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible ] id: MobGoat description: Her spine consists of long sharp segments, no wonder she is so grumpy. components: @@ -1286,7 +1290,7 @@ Quantity: 25 - type: entity - parent: [ MobSheepBase, SimpleMobBase ] + parent: [ MobSheepBase, SimpleMobBase, BaseMobDestructible ] id: MobSheep name: sheep description: An adorable genetically engineered chemical factory producing milk and cotton. @@ -1323,7 +1327,7 @@ # Note that we gotta make this bitch vomit someday when you feed it anthrax or sumthin. Needs to be a small item thief too and aggressive if attacked. - type: entity name: goose - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobGoose description: Its stomach and mind are an enigma beyond human comprehension. components: @@ -1374,7 +1378,7 @@ - type: entity name: gorilla - parent: [ SimpleMobBase, MobCombat ] + parent: [ SimpleMobBase, MobCombat, BaseMobDestructible ] id: MobGorilla description: Smashes, roars, looks cool. Don't stand near one. components: @@ -1459,6 +1463,7 @@ - MobCombat - StripableInventoryBase - BaseSlicingRefinable + - BaseMobDestructible id: MobKangaroo description: A large marsupial herbivore. It has powerful hind legs, with nails that resemble long claws. components: @@ -1550,7 +1555,7 @@ - type: entity name: genetic ancestor id: MobBaseAncestor - parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase] + parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase, BaseMobDestructible] description: The genetic bipedal ancestor of... Uh... Something. Yeah, there's definitely something on the station that descended from whatever this is. abstract: true components: @@ -2213,7 +2218,7 @@ - type: entity name: lizard #Weh - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobLizard description: A harmless dragon. components: @@ -2270,7 +2275,7 @@ - type: entity name: slug - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobSlug description: And they called this a lizard? components: @@ -2391,7 +2396,7 @@ # Would be cool to have some functionality for the parrot to be able to sit on stuff - type: entity - parent: [ SimpleMobBase, FlyingMobBase, BaseSlicingRefinable ] + parent: [ SimpleMobBase, FlyingMobBase, BaseSlicingRefinable, BaseMobDestructible ] id: MobParrotBase name: parrot abstract: true @@ -2478,7 +2483,7 @@ - type: entity name: penguin - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobPenguin description: Their lives are constant pain due to their inner-body knees. components: @@ -2614,7 +2619,7 @@ # I have included a snake_hiss.ogg sound file so if you want to use that be my guest - type: entity name: snake - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobSnake description: Hissss! Bites aren't poisonous. components: @@ -2664,7 +2669,7 @@ # Code unique spider prototypes or combine them all into one spider and get a # random sprite state when you spawn it. - type: entity - parent: [ SimpleMobBase, BaseMobHemocyanin, MobCombat, BaseSlicingRefinable, MobNightVision ] + parent: [ SimpleMobBase, BaseMobHemocyanin, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] id: MobSpiderBase abstract: true components: @@ -2872,6 +2877,7 @@ reagents: - ReagentId: Laughter Quantity: 150 + - type: entity name: wizard spider parent: MobGiantSpider @@ -2886,7 +2892,7 @@ - type: entity name: possum - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobPossum description: '"O Possum! My Possum!" -- Walt Whitman, 1865' components: @@ -2959,7 +2965,7 @@ - type: entity name: raccoon - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobRaccoon description: Trash panda! components: @@ -3012,7 +3018,7 @@ - type: entity name: fox - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobFox description: They're a fox. components: @@ -3094,7 +3100,7 @@ - type: entity abstract: true - parent: [SimpleMobBase, StripableInventoryBase] + parent: [SimpleMobBase, StripableInventoryBase, BaseMobDestructible] id: MobCorgiBase name: corgi description: Finally, a space corgi! @@ -3255,7 +3261,7 @@ - type: entity name: cat - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobCat description: Feline pet, very funny. components: @@ -3491,7 +3497,7 @@ - type: entity name: sloth - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobSloth description: Very slow animal. For people with low energy. components: @@ -3548,7 +3554,7 @@ - type: entity name: ferret - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobFerret description: Just a silly little guy! components: @@ -3757,7 +3763,7 @@ - type: entity name: pig - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobPig description: Oink. components: @@ -3828,7 +3834,7 @@ - type: entity name: diona nymph - parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [BaseMobAnimal, SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobDionaNymph description: It's like a cat, only.... branch-ier. components: @@ -3916,7 +3922,7 @@ - type: entity name: reindeer buck - parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable ] + parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] id: MobReindeerBuck description: You think it can pull a sleigh? components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml index 6d4266d252..6768f4599e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/argocyte.yml @@ -1,6 +1,6 @@ - type: entity save: false - parent: [ BaseSimpleMob, BaseMobAnimal, MobCombat, MobBloodstream ] + parent: [ BaseSimpleMob, BaseMobAnimal, MobCombat, MobBloodstream, BaseMobDestructible ] id: BaseMobArgocyte suffix: AI description: A dangerous alien found on the wrong side of planets, known for their propensity for munching on ruins. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml index 9258986eae..c4e2649550 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/asteroid.yml @@ -27,7 +27,7 @@ - type: entity id: MobGoliath - parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable ] + parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable, BaseMobDestructible ] name: goliath description: A massive beast that uses long tentacles to ensnare its prey, threatening them is not advised under any conditions. components: @@ -191,7 +191,7 @@ - type: entity id: MobHivelord - parent: [ BaseMobAsteroid, FlyingMobBase, BaseSlicingRefinable ] + parent: [ BaseMobAsteroid, FlyingMobBase, BaseSlicingRefinable, BaseMobDestructible ] name: hivelord description: A truly alien creature, it is a mass of unknown organic material, constantly fluctuating. When attacking, pieces of it split off and attack in tandem with the original. components: @@ -356,7 +356,7 @@ - type: entity id: MobBasilisk - parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable ] + parent: [ BaseMobAsteroid, MobBloodstream, BaseSlicingRefinable, BaseMobDestructible ] name: basilisk description: A territorial beast, covered in a thick shell that absorbs energy. Its stare causes victims to freeze from the inside. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml index 429d4db091..a72c62a925 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/behonker.yml @@ -1,6 +1,6 @@ - type: entity name: behonker - parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] id: BaseMobBehonker abstract: true description: A floating demon aspect of the honkmother. @@ -115,6 +115,7 @@ reagents: - ReagentId: Laughter Quantity: 300 + - type: entity name: behonker parent: BaseMobBehonker diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml index 23deb0eeab..e6dd5c3cf4 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/carp.yml @@ -1,7 +1,7 @@ - type: entity name: space carp id: BaseMobCarp - parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable, MobNightVision ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] description: It's a space carp. abstract: true components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml b/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml index c617eab499..dbcebebdcc 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/flesh.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable ] + parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] id: BaseMobFlesh name: aberrant flesh description: A shambling mass of flesh, animated through anomalous energy. @@ -204,7 +204,7 @@ Blunt: 10 - type: entity - parent: [ SimpleSpaceMobBase, MobCombat, BaseSlicingRefinable ] + parent: [ SimpleSpaceMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] id: BaseMobFleshSalvage #This one is immune to space! name: aberrant flesh suffix: "Salvage Ruleset" diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml index 9e8732bf1a..621354bc27 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/hellspawn.yml @@ -6,6 +6,7 @@ - MobBloodstream - BaseMobAnimal - BaseSlicingRefinable + - BaseMobDestructible id: MobHellspawn description: An unstoppable force of carnage. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml b/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml index 784b5dcc43..448df6ae43 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/hivebot.yml @@ -1,6 +1,6 @@ # Base hivebot - type: entity - parent: [ BaseSimpleMob, MobCombat, MobRobotic ] + parent: [ BaseSimpleMob, MobCombat, MobRobotic, BaseMobDestructible ] id: MobHivebot name: hivebot description: Agitating, mechanized pests. diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml b/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml index 65bc1c30fe..1b2902ab3c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/lavaland.yml @@ -1,7 +1,7 @@ - type: entity name: watcher id: MobWatcherBase - parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable, BaseMobDestructible ] abstract: true description: It's like it's staring right through you. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml index e8325e026c..12955eae57 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/mimic.yml @@ -1,7 +1,7 @@ - type: entity name: mimic id: MobMimic - parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable ] + parent: [ SimpleMobBase, MobCombat, BaseSlicingRefinable, BaseMobDestructible ] description: Surprise. # When this gets a proper write this should use the object's actual description >:) components: - type: Tag diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml index 108464284d..321c7078a5 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/miscellaneous.yml @@ -1,7 +1,7 @@ - type: entity name: laser raptor id: MobLaserRaptor - parent: [SimpleMobBase, BaseSlicingRefinable] + parent: [SimpleMobBase, BaseSlicingRefinable, BaseMobDestructible] description: From the Viking age. components: - type: NpcFactionMember diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 00357e73e9..5b6b8d2a2c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -241,7 +241,7 @@ - type: entity name: Bingus - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobBingus description: Bingus my beloved... components: @@ -298,7 +298,7 @@ - type: entity name: McGriff - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobMcGriff description: This dog can tell something smells around here, and that something is CRIME! components: @@ -408,7 +408,7 @@ - type: entity name: Walter - parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable] + parent: [SimpleMobBase, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] id: MobWalter description: He likes chems and treats. Walter. components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index e047f2500f..e9e761735c 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -1,7 +1,7 @@ - type: entity name: rat king id: MobRatKing - parent: [ BaseMobRat, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision ] + parent: [ BaseMobRat, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] description: He's da rat. He make da roolz. components: - type: CombatMode diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml index c4dfbf94c0..4ceddc730a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/scurret.yml @@ -179,10 +179,9 @@ # feel free to hook them into random content. - type: entity - name: Emotional Support Scurret - id: MobBaseEmotionalSupportScurret - parent: MobBaseScurret abstract: true + id: MobBaseEmotionalSupportScurret + name: Emotional Support Scurret components: - type: Loadout prototypes: [ EmotionalSupportScurretGear ] diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml index 09af04aeea..074b1d0ecd 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/slimes.yml @@ -1,7 +1,7 @@ - type: entity name: basic slime id: BaseMobAdultSlimes - parent: [ BaseMobSlimes, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision ] + parent: [ BaseMobSlimes, SimpleMobBase, MobCombat, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] abstract: true description: It looks so much like jelly. I wonder what it tastes like? components: diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml index 65e861d3de..705bbfe04e 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml @@ -74,7 +74,7 @@ - type: entity name: space bear id: MobBearSpace - parent: [MobSpaceBasic, BaseSlicingRefinable] + parent: [MobSpaceBasic, BaseSlicingRefinable, BaseMobDestructible] description: It looks friendly. Why don't you give it a hug? components: - type: Sprite @@ -123,7 +123,7 @@ - type: entity name: space kangaroo id: MobKangarooSpace - parent: [MobSpaceBasic, StripableInventoryBase, BaseSlicingRefinable] + parent: [MobSpaceBasic, StripableInventoryBase, BaseSlicingRefinable, BaseMobDestructible] description: It looks friendly. Why don't you give it a hug? components: - type: Sprite @@ -184,7 +184,7 @@ - type: entity name: space spider id: MobSpiderSpace - parent: [MobSpaceBasic, BaseSlicingRefinable] + parent: [MobSpaceBasic, BaseSlicingRefinable, BaseMobDestructible] description: It's so glowing, it looks dangerous. components: - type: Sprite @@ -289,7 +289,7 @@ - type: entity name: space cobra id: MobCobraSpace - parent: [MobSpaceBasic, BaseSlicingRefinable] + parent: [MobSpaceBasic, BaseSlicingRefinable, BaseMobDestructible] description: Long fangs and a glowing hood, and the alluring look begs to come closer. components: - type: Sprite @@ -394,7 +394,7 @@ - type: SalvageMobRestrictions - type: entity - parent: [ SimpleSpaceMobBase, FlyingMobBase, MobSheepBase ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, MobSheepBase, BaseMobDestructible ] id: MobSheepSpace name: space sheep description: A sheep... in space! diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 6ffefa49da..547886f76a 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -2,7 +2,7 @@ - type: entity name: burrower id: MobXeno - parent: [ SimpleSpaceMobBase, MobNightVision ] + parent: [ SimpleSpaceMobBase, MobNightVision, BaseMobDestructible ] description: They mostly come at night. Mostly. components: - type: Insulated @@ -358,7 +358,7 @@ - type: entity name: space adder - parent: [SimpleSpaceMobBase, BaseSlicingRefinable] + parent: [SimpleSpaceMobBase, BaseSlicingRefinable, BaseMobDestructible] id: MobPurpleSnake description: A menacing purple snake from Kepler-283c. components: @@ -467,7 +467,7 @@ - type: entity name: '"Dale"' description: A praetorian left over from the station's initial security sweep. Has a pair of bloodied dog tags engraved with the name "Pvt. Dale" stuck in its maw. - parent: SimpleSpaceMobBase + parent: [SimpleSpaceMobBase, BaseMobDestructible] id: MobXenoLonePraetorianNoGhost components: - type: Insulated diff --git a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml index 52a5cecd49..543a34e30c 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/changeling.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/changeling.yml @@ -18,7 +18,7 @@ ChangelingDNA: 60 - type: entity - parent: [ SimpleSpaceMobBase, MobNightVision ] + parent: [ SimpleSpaceMobBase, MobNightVision, BaseMobDestructible ] id: MobHeadSlug name: headslug description: A small, slug-like creature with a large, gaping maw. It's covered in a thick, slimy mucus. diff --git a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml index 2a97a9a891..df74c3a6d8 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/dragon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/dragon.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable, MobNightVision ] + parent: [ SimpleSpaceMobBase, FlyingMobBase, BaseSlicingRefinable, MobNightVision, BaseMobDestructible ] id: BaseMobDragon suffix: "" name: space dragon diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index f01f1a85de..ee63ea6d9b 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -71,44 +71,6 @@ - type: Damageable - type: Injurable damageContainer: Biological - - type: Destructible - thresholds: - - trigger: - !type:DamageTypeTrigger - damageType: Blunt - damage: 400 - behaviors: - - !type:GibBehavior { } - - trigger: - !type:DamageTypeTrigger - damageType: Heat - damage: 1500 - behaviors: - - !type:SpawnEntitiesBehavior - spawnInContainer: true - spawn: - Ash: - min: 1 - max: 1 - - !type:BurnBodyBehavior - - !type:PlaySoundBehavior - sound: - collection: MeatLaserImpact - - trigger: - !type:DamageTypeTrigger - damageType: Radiation - damage: 15 - behaviors: - - !type:PopupBehavior - popup: mouth-taste-metal - popupType: LargeCaution - targetOnly: true - - trigger: - !type:DamageTypeTrigger - damageType: Radiation - damage: 40 - behaviors: - - !type:VomitBehavior - type: RadiationReceiver - type: Stamina - type: StunVisuals @@ -150,6 +112,50 @@ - type: GhostOnMove mustBeDead: true +# Used as a simple default for mob destruction +- type: entity + abstract: true + id: BaseMobDestructible + components: + - type: Destructible + thresholds: + - trigger: + !type:DamageTypeTrigger + damageType: Blunt + damage: 400 + behaviors: + - !type:GibBehavior { } + - trigger: + !type:DamageTypeTrigger + damageType: Heat + damage: 1500 + behaviors: + - !type:SpawnEntitiesBehavior + spawnInContainer: true + spawn: + Ash: + min: 1 + max: 1 + - !type:BurnBodyBehavior + - !type:PlaySoundBehavior + sound: + collection: MeatLaserImpact + - trigger: + !type:DamageTypeTrigger + damageType: Radiation + damage: 15 + behaviors: + - !type:PopupBehavior + popup: mouth-taste-metal + popupType: LargeCaution + targetOnly: true + - trigger: + !type:DamageTypeTrigger + damageType: Radiation + damage: 40 + behaviors: + - !type:VomitBehavior + # Used for mobs that can enter combat mode and can attack. - type: entity save: false diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml index a81caef76a..164d3f02ca 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_base_materials.yml @@ -21,12 +21,6 @@ sound: collection: GlassBreak - !type:SpillBehavior { } - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - transferForensics: true - !type:DoActsBehavior acts: [ "Destruction" ] - type: DamageOnLand @@ -48,9 +42,12 @@ # Porcelain (like glass but no shard) - type: entity abstract: true - parent: DrinkBaseMaterialGlass id: DrinkBaseMaterialPorcelain components: + - type: Damageable + damageModifierSet: FlimsyGlass + - type: Injurable + damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -63,9 +60,15 @@ - !type:SpillBehavior { } - !type:DoActsBehavior acts: [ "Destruction" ] - - type: PhysicalComposition - materialComposition: - Glass: 10 # Trace amounts of glass I guess. Important for overriding inheritance + - type: DamageOnLand + ignoreResistances: true + damage: + types: + Blunt: 5 # so fragile it smashes when thrown + - type: DamageOtherOnHit + damage: + types: + Blunt: 5 # Fragile plastic - type: entity diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml index 45fb858a66..06c9932261 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_bottles_glass.yml @@ -23,24 +23,18 @@ tags: - DrinkBottle - Trash - - type: Destructible # Same as parent, but spawns BrokenBottle instead of ShardGlass + - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 5 behaviors: - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - - !type:SpillBehavior { } - !type:SpawnEntitiesBehavior spawn: BrokenBottle: min: 1 max: 1 transferForensics: true - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml index e7f4c3b56f..a71cf24e76 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_cups.yml @@ -67,6 +67,18 @@ sprite: Objects/Consumable/Drinks/glass_coupe_shape.rsi - type: SolutionContainerVisuals inHandsMaxFillLevels: 1 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 5 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + transferForensics: true - type: entity parent: [DrinkBaseMaterialCardboard, DrinkBaseCup, DrinkBaseEmptyTrash, DrinkVisualsFill] diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml index 0e8e12265d..8652dc348e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_fun.yml @@ -78,6 +78,18 @@ sprite: Objects/Consumable/Drinks/jar_what.rsi - type: FitsInDispenser solution: drink + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 5 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + transferForensics: true # Mopwata - type: weightedRandomFillSolution diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml index 84f4d954a4..c0d1b3a51e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_metamorphic.yml @@ -21,6 +21,18 @@ metamorphicDefaultSprite: sprite: Objects/Consumable/Drinks/glass_clear.rsi state: icon + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 5 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + transferForensics: true - type: entity parent: DrinkGlass diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml index 9d23f09eb8..1c20831194 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Drinks/drinks_special.yml @@ -16,6 +16,18 @@ inHandsMaxFillLevels: 1 - type: FitsInDispenser solution: drink + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 5 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 0 + max: 1 + transferForensics: true - type: entity parent: [DrinkBaseMaterialMetal, SolutionLarge, DrinkBase] @@ -206,6 +218,18 @@ solution: drink - type: FitsInDispenser solution: drink + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 5 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 + transferForensics: true - type: entity parent: DrinkShakeBase diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml index 62a09538dc..1ee516e425 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/Containers/plate.yml @@ -7,23 +7,13 @@ # Large Plate - type: entity - name: large plate + abstract: true parent: BaseItem - id: FoodPlate - description: A large plate, excellent for bread. + id: BaseFoodPlate components: - - type: Sprite - sprite: Objects/Consumable/Food/plates.rsi - state: plate - type: Item shape: - 0,0,1,0 - storedOffset: 0,-6 - inhandVisuals: - left: - - state: plate-inhand-left - right: - - state: plate-inhand-right - type: DamageOnLand damage: types: @@ -46,25 +36,48 @@ collection: GlassBreak params: volume: -8 - - !type:SpawnEntitiesBehavior - spawn: - FoodPlateTrash: - min: 1 - max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: Tag tags: - Trash - - type: PhysicalComposition - materialComposition: - Glass: 50 - type: SpaceGarbage - type: entity - name: broken plate + parent: BaseFoodPlate + id: FoodPlate + name: large plate + description: A large plate, excellent for bread. + components: + - type: Sprite + sprite: Objects/Consumable/Food/plates.rsi + state: plate + - type: Item + storedOffset: 0,-6 + inhandVisuals: + left: + - state: plate-inhand-left + right: + - state: plate-inhand-right + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 5 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + FoodPlateTrash: + min: 1 + max: 1 + - type: PhysicalComposition + materialComposition: + Glass: 50 + +- type: entity parent: BaseItem id: FoodPlateTrash + name: broken plate description: A broken plate. Useless. components: - type: Sprite @@ -82,9 +95,9 @@ # Small Plate - type: entity - name: small plate - parent: FoodPlate + parent: BaseFoodPlate id: FoodPlateSmall + name: small plate description: A small plate. Delicate. components: - type: Sprite @@ -97,25 +110,17 @@ - state: plate-inhand-left right: - state: plate-inhand-right -# Needs the full thing because inherting is dumb sometimes. - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 5 behaviors: - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - params: - volume: -8 - !type:SpawnEntitiesBehavior spawn: FoodPlateSmallTrash: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: PhysicalComposition materialComposition: Glass: 25 @@ -133,7 +138,7 @@ # Plastic Plate - type: entity - parent: BaseItem + parent: BaseFoodPlate id: FoodPlatePlastic name: large plastic plate description: A large blue plastic plate, excellent for a birthday cake. @@ -142,8 +147,6 @@ sprite: Objects/Consumable/Food/plates.rsi state: plate-plastic - type: Item - shape: - - 0,0,1,0 storedOffset: 0,-6 inhandVisuals: left: @@ -155,7 +158,7 @@ - Trash - type: entity - parent: BaseItem + parent: BaseFoodPlate id: FoodPlateSmallPlastic name: small plastic plate description: A blue plastic plate, excellent for slices of birthday cake. @@ -164,8 +167,6 @@ sprite: Objects/Consumable/Food/plates.rsi state: plate-small-plastic - type: Item - shape: - - 0,0,1,0 storedOffset: 0,-3 inhandVisuals: left: @@ -179,9 +180,9 @@ # Pie Tin - type: entity - name: pie tin parent: BaseItem id: FoodPlateTin + name: pie tin description: A cheap foil tin for pies. components: - type: Sprite diff --git a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml index 266c9eca82..6d399cc644 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/flora.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/flora.yml @@ -391,21 +391,8 @@ thresholds: - trigger: !type:DamageTrigger - damage: 25 + damage: 50 behaviors: - - !type:PlaySoundBehavior - sound: - path: /Audio/Effects/tree_fell.ogg - params: - volume: 5 - variation: 0.05 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:SpawnEntitiesBehavior - spawn: - Log: - min: 0 - max: 1 - !type:SpawnEntitiesBehavior spawn: MobLuminousObject: diff --git a/Resources/Prototypes/Entities/Objects/Decoration/mining.yml b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml index 7a04fc6fcb..01f1c13995 100644 --- a/Resources/Prototypes/Entities/Objects/Decoration/mining.yml +++ b/Resources/Prototypes/Entities/Objects/Decoration/mining.yml @@ -50,28 +50,36 @@ state: sign_right - type: entity - id: WoodenSupport + abstract: true parent: BaseStructure - name: wooden support - description: Increases your confidence that a rock won't fall on your head. + id: BaseWoodenSupport placement: mode: SnapgridCenter components: - type: PlacementReplacement key: walls - - type: Tag - tags: - - Wooden - type: Sprite noRot: true sprite: Objects/Decoration/mines.rsi - state: support - type: Damageable damageModifierSet: Wood - type: Injurable damageContainer: StructuralInorganic - type: Physics bodyType: Static + - type: MeleeSound + soundGroups: + Brute: + path: /Audio/Effects/chop.ogg + params: + variation: 0.05 + +- type: entity + parent: BaseWoodenSupport + id: WoodenSupport + name: wooden support + description: Increases your confidence that a rock won't fall on your head. + components: - type: Fixtures fixtures: fix1: @@ -83,12 +91,6 @@ layer: - WallLayer density: 1000 - - type: MeleeSound - soundGroups: - Brute: - path: /Audio/Effects/chop.ogg - params: - variation: 0.05 - type: Destructible thresholds: - trigger: @@ -104,12 +106,11 @@ max: 3 - type: entity + parent: BaseWoodenSupport id: WoodenSupportBeam name: wooden support beam - parent: WoodenSupport components: - type: Sprite - sprite: Objects/Decoration/mines.rsi state: support_beams - type: Fixtures fixtures: @@ -125,29 +126,16 @@ density: 1000 - type: entity + parent: BaseWoodenSupport id: WoodenSupportWall - parent: BaseStructure name: wooden support wall description: An old, rotten wall. - placement: - mode: SnapgridCenter components: - - type: PlacementReplacement - key: walls - type: Tag tags: - Wall - - Wooden - type: Sprite - noRot: true - sprite: Objects/Decoration/mines.rsi state: support_wall - - type: Damageable - damageModifierSet: Wood - - type: Injurable - damageContainer: StructuralInorganic - - type: Physics - bodyType: Static - type: Fixtures fixtures: fix1: @@ -174,11 +162,13 @@ max: 5 - type: entity + parent: BaseWoodenSupport id: WoodenSupportWallBroken - parent: WoodenSupportWall components: + - type: Tag + tags: + - Wall - type: Sprite - sprite: Objects/Decoration/mines.rsi state: support_wall_broken - type: Destructible thresholds: diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml index 5c5dcd8979..4a03e5e3fa 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/singularity_beacon.yml @@ -1,6 +1,6 @@ - type: entity id: SingularityBeacon - parent: [BaseMachinePowered, BaseSyndicateContraband] + parent: [BaseMachinePowered, BaseSyndicateContraband, BaseMachineDestructible] name: singularity beacon description: A syndicate device that attracts the singularity. If it's loose and you're seeing this, run. components: @@ -29,15 +29,15 @@ baseRange: 80 - type: SinguloFood energy: 120 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: ApcPowerReceiver powerLoad: 5000 - type: StaticPrice price: 7500 + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Objects/Devices/payload.yml b/Resources/Prototypes/Entities/Objects/Devices/payload.yml index a18d533fd8..eef0b1668d 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/payload.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/payload.yml @@ -35,14 +35,6 @@ intensitySlope: 3 totalIntensity: 120 # about a ~4 tile radius - type: ExplodeOnTrigger - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity name: chemical payload diff --git a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml index acd8ad873e..704e7ffc0f 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml @@ -1,5 +1,5 @@ - type: entity - parent: BaseItem + parent: [ BaseItem, BaseItemDestructible ] id: BaseHandheldStationMap name: station map description: Displays a readout of the current station. @@ -19,14 +19,6 @@ - type: Damageable - type: Injurable damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: UserInterface interfaces: enum.StationMapUiKey.Key: diff --git a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml index 621b086084..173f83f561 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/wristwatch.yml @@ -1,6 +1,6 @@ - type: entity id: Wristwatch - parent: BaseItem + parent: [ BaseItem, BaseItemDestructible ] name: wristwatch description: A cheap watch for telling time. How much did you waste playing Space Station 14? components: @@ -26,16 +26,10 @@ price: 50 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - trigger: !type:DamageGroupTrigger damageGroup: Brute - damage: 25 + damage: 5 behaviors: - !type:DoActsBehavior acts: [ "Breakage" ] diff --git a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml index 1f87047b2d..2e7e186826 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/Sheets/glass.yml @@ -11,24 +11,6 @@ sprite: Objects/Materials/Sheets/glass.rsi - type: Damageable damageModifierSet: Glass - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - params: - volume: -4 - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity parent: SheetGlassBase @@ -63,6 +45,22 @@ reagents: - ReagentId: Silicon Quantity: 10 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: GlassBreak + params: + volume: -4 + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 1 - type: entity parent: SheetGlass @@ -132,8 +130,6 @@ ShardGlassReinforced: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Solution solution: maxVol: 15 @@ -200,8 +196,6 @@ ShardGlassPlasma: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Solution solution: maxVol: 20 @@ -318,8 +312,6 @@ ShardGlassUranium: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Solution solution: maxVol: 20 @@ -435,8 +427,6 @@ ShardGlassClockwork: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Solution solution: maxVol: 20 diff --git a/Resources/Prototypes/Entities/Objects/Materials/base.yml b/Resources/Prototypes/Entities/Objects/Materials/base.yml index 0d49a037b5..7fd3e93ed8 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/base.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/base.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [SolutionCryo, SolutionCompositeNormalStackable, BaseItem] + parent: [SolutionCryo, SolutionCompositeNormalStackable, BaseItem, BaseItemDestructible] id: MaterialBase description: A raw material. components: @@ -14,17 +14,6 @@ - type: Tag tags: - RawMaterial - - type: Damageable - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Extractable grindableSolutionName: composite diff --git a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml index feb79ff44b..d64f69686c 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/ingots.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/ingots.yml @@ -14,16 +14,6 @@ - ConstructionMaterial - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 500 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity parent: IngotBase diff --git a/Resources/Prototypes/Entities/Objects/Materials/shards.yml b/Resources/Prototypes/Entities/Objects/Materials/shards.yml index bab92dbad4..33f2c0ab16 100644 --- a/Resources/Prototypes/Entities/Objects/Materials/shards.yml +++ b/Resources/Prototypes/Entities/Objects/Materials/shards.yml @@ -56,16 +56,6 @@ - type: SpaceGarbage - type: Damageable damageModifierSet: Glass - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: StepTrigger intersectRatio: 0.2 - type: PreventableStepTrigger diff --git a/Resources/Prototypes/Entities/Objects/Misc/candles.yml b/Resources/Prototypes/Entities/Objects/Misc/candles.yml index 5710d7f11f..37cd942645 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/candles.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/candles.yml @@ -1,6 +1,6 @@ - type: entity name: candle - parent: BaseItem + parent: [ BaseItem, BaseItemDestructible ] id: Candle description: A thin wick threaded through fat. components: @@ -52,15 +52,6 @@ shader: unshaded - type: Damageable damageModifierSet: Wood - - type: Injurable - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity name: red candle @@ -168,15 +159,6 @@ normalState: fire-small - type: Flammable firestacksOnIgnite: 2.0 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 60 - behaviors: - - !type:SpawnEntitiesBehavior - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity name: small red candle diff --git a/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml b/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml index 6437b383e2..53c6a5aa64 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/desk_bell.yml @@ -1,8 +1,7 @@ - type: entity - parent: BaseItem - id: EmptyDeskBell - name: unfinished desk bell - description: An empty bell missing its noise maker. + abstract: true + parent: [ BaseItem, BaseItemDestructible ] + id: BaseDeskBell components: - type: Sprite sprite: Objects/Misc/desk_bell.rsi @@ -10,25 +9,15 @@ - type: Construction graph: &BellGraph BellGraph node: start - - type: Damageable - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - - trigger: &DamageTrigger20 + - trigger: &DamageTrigger50 !type:DamageTrigger - damage: 20 + damage: 50 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 0 - max: 1 - - !type:DoActsBehavior - acts: ["Destruction"] - type: MeleeWeapon wideAnimationRotation: 180 soundHit: &BellSound @@ -49,7 +38,23 @@ sound: *BellSound - type: entity - parent: EmptyDeskBell + parent: BaseDeskBell + id: EmptyDeskBell + name: unfinished desk bell + description: An empty bell missing its noise maker. + components: + - type: Destructible + thresholds: + - trigger: *DamageTrigger50 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 0 + max: 1 + +- type: entity + parent: BaseDeskBell id: DeskBell name: desk bell description: The cornerstone of any customer service job. You feel an unending urge to ring it. @@ -64,11 +69,8 @@ node: deskBellNode - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: *DamageTrigger50 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: PartRodMetal1: @@ -76,8 +78,6 @@ max: 1 - !type:ChangeConstructionNodeBehavior node: start - - !type:DoActsBehavior - acts: ["Destruction"] - type: InteractionPopup successChance: 1 onActivate: true @@ -91,7 +91,7 @@ sound: *BellSound - type: entity - parent: EmptyDeskBell + parent: BaseDeskBell id: DeskBuzzer name: desk buzzer description: An advanced customer service tool. You feel an unending urge to buzz it. @@ -105,11 +105,8 @@ node: deskBuzzerNode - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: *DamageTrigger50 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: CableApcStack1: @@ -117,8 +114,6 @@ max: 2 - !type:ChangeConstructionNodeBehavior node: start - - !type:DoActsBehavior - acts: ["Destruction"] - type: StationAiWhitelist - type: InteractionPopup successChance: 1 @@ -144,7 +139,7 @@ sound: *BuzzerSound - type: entity - parent: EmptyDeskBell + parent: BaseDeskBell id: DeskHorn name: desk horn description: The cornerstone of any clown business. You feel an unending urge to honk it. @@ -158,11 +153,8 @@ node: deskHornNode - type: Destructible thresholds: - - trigger: *DamageTrigger20 + - trigger: *DamageTrigger50 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: BikeHorn: @@ -170,8 +162,6 @@ max: 1 - !type:ChangeConstructionNodeBehavior node: start - - !type:DoActsBehavior - acts: ["Destruction"] - type: InteractionPopup successChance: 1 onActivate: true diff --git a/Resources/Prototypes/Entities/Objects/Power/lights.yml b/Resources/Prototypes/Entities/Objects/Power/lights.yml index d296a9564b..ef376f0673 100644 --- a/Resources/Prototypes/Entities/Objects/Power/lights.yml +++ b/Resources/Prototypes/Entities/Objects/Power/lights.yml @@ -68,10 +68,10 @@ - type: Destructible thresholds: - trigger: *DamageTrigger10 - behaviors: &BehaviorsSpawnShardGlass + behaviors: - !type:SpawnEntitiesBehavior spawn: - ShardGlass: + LightBulbBroken: min: 1 max: 1 @@ -80,14 +80,15 @@ parent: BaseReplacementLight id: BaseLightTube components: - - type: Sprite - sprite: Objects/Power/light_tube.rsi - - type: LightBulb - bulb: Tube - type: Destructible thresholds: - trigger: *DamageTrigger10 - behaviors: *BehaviorsSpawnShardGlass + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + LightTubeBroken: + min: 1 + max: 1 # Lighting color values gathered from # https://andi-siess.de/rgb-to-color-temperature/ diff --git a/Resources/Prototypes/Entities/Objects/Power/powersink.yml b/Resources/Prototypes/Entities/Objects/Power/powersink.yml index 5b273ce150..f89af1986b 100644 --- a/Resources/Prototypes/Entities/Objects/Power/powersink.yml +++ b/Resources/Prototypes/Entities/Objects/Power/powersink.yml @@ -1,6 +1,6 @@ - type: entity id: PowerSink - parent: [BaseMachine, BaseSyndicateContraband] + parent: [BaseMachine, BaseSyndicateContraband, BaseMachineDestructible] name: power sink description: Drains immense amounts of electricity from the grid. components: @@ -30,14 +30,6 @@ - MachineMask layer: - MachineLayer - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 25 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: PowerSink - type: Battery # Very important: @@ -58,3 +50,11 @@ location: location-powersink - type: StaticPrice price: 3000 + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Objects/Shields/shields.yml b/Resources/Prototypes/Entities/Objects/Shields/shields.yml index 466782ff32..8511bd3c24 100644 --- a/Resources/Prototypes/Entities/Objects/Shields/shields.yml +++ b/Resources/Prototypes/Entities/Objects/Shields/shields.yml @@ -26,28 +26,33 @@ damageContainer: Shield - type: ExaminableDamage messages: ShieldMessages - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 125 #This is probably enough damage before it breaks - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel: - min: 2 - max: 2 - SheetGlass: - min: 2 - max: 2 - type: StaticPrice price: 100 +- type: entity + abstract: true + id: BaseShieldDestructible + components: + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 125 #This is probably enough damage before it breaks + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel: + min: 2 + max: 2 + SheetGlass: + min: 2 + max: 2 + - type: entity name: base repairable shield parent: BaseShield @@ -70,7 +75,7 @@ - type: entity name: riot shield - parent: [ BaseRepairableShield, BaseSecurityContraband ] + parent: [ BaseRepairableShield, BaseShieldDestructible, BaseSecurityContraband ] id: RiotShield description: A large tower shield. Good for controlling crowds. components: @@ -86,7 +91,7 @@ - type: entity name: laser shield - parent: [ BaseRepairableShield, BaseSecurityContraband ] + parent: [ BaseRepairableShield, BaseShieldDestructible, BaseSecurityContraband ] id: RiotLaserShield description: A shield built for withstanding lasers, but not much else. components: @@ -104,7 +109,7 @@ - type: entity name: ballistic shield - parent: [ BaseRepairableShield, BaseSecurityContraband ] + parent: [ BaseRepairableShield, BaseShieldDestructible, BaseSecurityContraband ] id: RiotBulletShield description: A shield built for protecting against ballistics, but not much else. components: @@ -270,7 +275,7 @@ - type: entity name: clockwork shield - parent: BaseRepairableShield + parent: [ BaseRepairableShield, BaseShieldDestructible ] id: ClockworkShield description: Ratvar oyrffrf lbh jvgu uvf cebgrpgvba. components: @@ -429,7 +434,7 @@ - type: entity name: telescopic shield - parent: BaseRepairableShield + parent: [ BaseRepairableShield, BaseShieldDestructible ] id: TelescopicShield description: An advanced riot shield made of lightweight materials that collapses for easy storage. components: diff --git a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml index ed58e56aa3..329ff6b0ce 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Chemistry/chemistry-vials.yml @@ -19,6 +19,11 @@ tags: - Trash - CentrifugeCompatible # unique feature of vials + - type: DamageOnLand + ignoreResistances: true + damage: + types: + Blunt: 3 # can be thrown once without breaking ## Entities @@ -43,20 +48,14 @@ thresholds: - trigger: !type:DamageTrigger - damage: 15 # stronger than base + damage: 5 behaviors: - - &SoundGlassBreak !type:PlaySoundBehavior - sound: - collection: GlassBreak - - !type:SpillBehavior { } - !type:SpawnEntitiesBehavior spawn: - ShardGlass: # less glass than base + ShardGlass: min: 0 max: 1 transferForensics: true - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity parent: [SolutionVeryTiny, BaseChemistryVial] @@ -78,16 +77,6 @@ - type: PhysicalComposition materialComposition: Glass: 10 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 5 # smaller so weaker - behaviors: # remove glass shard spawn - - *SoundGlassBreak - - !type:SpillBehavior { } - - !type:DoActsBehavior - acts: [ "Destruction" ] ## Reagent filled diff --git a/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml b/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml index 15feb76cf5..6ad7c91870 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Security/target.yml @@ -1,7 +1,7 @@ - type: entity - id: BaseTarget - parent: BaseStructureDynamic abstract: true + parent: BaseStructureDynamic + id: BaseTargetIndestructible components: - type: Sprite sprite: Objects/Specific/Security/target.rsi @@ -27,6 +27,12 @@ - type: Damageable - type: Injurable damageContainer: Inorganic + +- type: entity + abstract: true + parent: BaseTargetIndestructible + id: BaseTarget + components: - type: Destructible thresholds: - trigger: @@ -44,10 +50,11 @@ - !type:DoActsBehavior acts: [ "Destruction" ] + - type: entity - name: human target - id: TargetHuman parent: BaseTarget + id: TargetHuman + name: human target description: A shooting target. This one is a human. components: - type: Sprite @@ -55,9 +62,9 @@ state: target_h - type: entity - name: syndicate target - id: TargetSyndicate parent: BaseTarget + id: TargetSyndicate + name: syndicate target description: A shooting target. This one is a syndicate agent. components: - type: Sprite @@ -65,9 +72,9 @@ state: target_s - type: entity - name: clown target - id: TargetClown parent: BaseTarget + id: TargetClown + name: clown target description: A shooting target. This one is a clown. components: - type: Sprite @@ -76,27 +83,11 @@ # put it on a salvage or something - type: entity - name: strange target + parent: BaseTargetIndestructible id: TargetStrange - parent: BaseTarget + name: strange target description: A shooting target. You aren't quite sure what this one is, but it seems to be extra robust. components: - type: Sprite sprite: Objects/Specific/Security/target.rsi state: target_f - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 2000 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel: - min: 10 - max: 10 - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:DoActsBehavior - acts: [ "Destruction" ] diff --git a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml index 4d54bfb236..4884ae457c 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Service/vending_machine_restock.yml @@ -1,7 +1,7 @@ - type: entity - parent: BaseItem - id: BaseVendingMachineRestock abstract: true + parent: [ BaseItem, BaseItemDestructible ] + id: BaseVendingMachineRestock name: vending machine restock box description: A box for restocking vending machines with corporate goodies. components: @@ -24,20 +24,16 @@ size: Normal - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 20 + damage: 50 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - !type:DumpRestockInventory - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity parent: BaseVendingMachineRestock diff --git a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml index 76d48ed4e3..03bd2a5e03 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml @@ -4,7 +4,7 @@ - type: entity abstract: true - parent: [SolutionCompositeSmallStackable, BaseItem] + parent: [SolutionCompositeSmallStackable, BaseItem, BaseItemDestructible] id: CableStack name: cable stack suffix: Full @@ -36,18 +36,8 @@ - Power - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - type: Extractable grindableSolutionName: composite - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - type: entity id: CableHVStack diff --git a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml index 336ee6b8a9..764a82183c 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/fulton.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/fulton.yml @@ -50,10 +50,10 @@ map: ["foldedLayer"] - type: entity + parent: [ BaseItem, BaseItemDestructible ] id: Fulton - parent: BaseItem - suffix: Full name: fulton + suffix: Full description: Used to extract containers, items, or forcibly recruit people into your base of operations. components: - type: Fulton @@ -71,17 +71,6 @@ drawdepth: SmallObjects sprite: Objects/Tools/fulton.rsi state: extraction_pack - - type: Damageable - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity id: Fulton1 diff --git a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml index 8c85d57b52..194dcd8827 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/toolbox.yml @@ -94,6 +94,7 @@ - !type:DoActsBehavior acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior # todo this is not a good way to be doing this. Should probably use a construction graph + offset: 0 spawn: WeaponTurretSyndicateDisposable: min: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml index 27862d7a4f..dae2f9da1a 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/cord.yml @@ -35,7 +35,6 @@ Quantity: 3 - ReagentId: Charcoal Quantity: 2 - - type: Damageable - type: Injurable damageContainer: StructuralInorganic - type: Destructible # should have the same general explosive behavior as in cables.yml & detonator.yml @@ -48,12 +47,8 @@ - !type:DoActsBehavior acts: ["Destruction"] - !type:ExplodeBehavior - - trigger: - !type:DamageTrigger # the idea here is to prevent you from just beating it until it explodes. - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + # the 50 damage destruction node is inherited from the parent + # idea here is to prevent you from just beating it until it explodes. - type: Explosive explosionType: DemolitionCharge totalIntensity: 60 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml index b59459bd10..17ad36f4c4 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/detonator.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseItem, BaseSecurityContraband ] + parent: [ BaseItem, BaseItemDestructible, BaseSecurityContraband ] id: EmptyDetonator name: detonator cap description: A detonator cap. Requires a trigger and wire. @@ -15,7 +15,6 @@ - type: Construction graph: DetonatorGraph node: emptyDetonator - - type: Damageable - type: Injurable damageContainer: StructuralInorganic - type: Destructible @@ -28,12 +27,8 @@ - !type:TriggerBehavior - !type:DoActsBehavior acts: [ "Destruction" ] - - trigger: - !type:DamageTrigger # the idea here is to prevent you from just beating it until it explodes. - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] + # the 50 damage destruction node is inherited from the parent + # idea here is to prevent you from just beating it until it explodes. - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml index ce9943c7f6..9d9eb78072 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/firebomb.yml @@ -2,7 +2,7 @@ # ideally it would be dynamic and work by actually sparking the solution but that doesnt exist yet :( # with that you could make napalm ied instead of welding fuel with no additional complexity - type: entity - parent: [ BaseItem, BaseMinorContraband ] + parent: [ BaseItem, BaseItemDestructible, BaseMinorContraband ] id: FireBomb name: fire bomb description: A weak, improvised incendiary device. @@ -41,17 +41,12 @@ - type: AnimationPlayer - type: TimerTriggerVisuals unprimedSprite: base - - type: Damageable - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 50 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:ExplodeBehavior - type: Construction graph: FireBomb diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml index 10fc8c3167..c2d13900bb 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Bombs/plastic.yml @@ -41,22 +41,17 @@ - type: entity abstract: true - parent: [ BaseItem, BasePlasticExplosiveTrigger ] + parent: [ BaseItem, BaseItemDestructible, BasePlasticExplosiveTrigger ] id: BasePlasticExplosive components: - type: Item size: Small - - type: Damageable - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger damage: 50 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:ExplodeBehavior - type: Explosive # Powerful explosion in a very small radius. Doesn't break underplating. explosionType: DemolitionCharge diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml index b5abc8abb9..35becc49b8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Ammunition/Cartridges/base_cartridge.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: BaseItem + parent: [ BaseItem, BaseItemDestructible ] id: BaseCartridge components: - type: Sprite @@ -16,18 +16,6 @@ - ItemMask restitution: 0.3 # fite me friction: 0.2 - - type: Damageable - damageModifierSet: StrongMetallic # We only want explosions breaking them (for the most part) - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 75 - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Tag tags: - Cartridge diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml index 916e40d65e..f176281890 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_ballistic.yml @@ -8,7 +8,7 @@ - Syndicate - type: entity - parent: BaseWeaponBallisticTurret + parent: BaseWeaponBallisticTurretIndestructible id: WeaponTurretSyndicateDisposable name: disposable ballistic turret suffix: Syndicate, Disposable @@ -16,6 +16,9 @@ - type: NpcFactionMember factions: - Syndicate + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -78,7 +81,7 @@ - AllHostile - type: entity - parent: BaseWeaponBallisticTurret + parent: BaseWeaponBallisticTurretIndestructible id: WeaponTurretXeno name: xeno turret suffix: Xeno diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml index 1c331c1421..4379ed8c15 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_base.yml @@ -1,10 +1,9 @@ - type: entity - parent: BaseStructure - id: BaseWeaponTurret - name: turret abstract: true + parent: BaseStructure + id: BaseWeaponTurretIndestructible + name: turret components: - - type: Clickable - type: InteractionOutline - type: Actions - type: Fixtures @@ -32,26 +31,6 @@ path: /Audio/Effects/double_beep.ogg - type: CombatMode toggleMouseRotator: false - - type: Damageable - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 300 - # TODO: Construction graph - behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 3 - max: 5 - type: HTN rootTask: task: TurretCompound @@ -70,11 +49,41 @@ context: "human" - type: entity - parent: BaseWeaponTurret - id: BaseWeaponBallisticTurret - description: A ballistic machine gun auto-turret. - name: ballistic turret abstract: true + id: BaseTurretDestructible + components: + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 300 + # TODO: Construction graph + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 3 + max: 5 + +- type: entity + abstract: true + parent: [ BaseWeaponTurretIndestructible, BaseTurretDestructible ] + id: BaseWeaponTurret + +- type: entity + abstract: true + parent: BaseWeaponTurretIndestructible + id: BaseWeaponBallisticTurretIndestructible + name: ballistic turret + description: A ballistic machine gun auto-turret. components: - type: ContainerContainer containers: @@ -91,11 +100,16 @@ capacity: 500 - type: entity - parent: BaseWeaponTurret - id: BaseWeaponEnergyTurret + abstract: true + parent: [ BaseWeaponBallisticTurretIndestructible, BaseTurretDestructible ] + id: BaseWeaponBallisticTurret + +- type: entity + abstract: true + parent: BaseWeaponTurretIndestructible + id: BaseWeaponEnergyTurretIndestructible name: laser turret description: An auto-turret armed with a heavy laser. Its weapon will recharge while connected to an active power grid. - abstract: true components: - type: Sprite sprite: Objects/Weapons/Guns/Turrets/sentry_turret.rsi @@ -135,3 +149,8 @@ task: EnergyTurretCompound - type: StaticPrice price: 200 + +- type: entity + abstract: true + parent: [ BaseWeaponEnergyTurretIndestructible, BaseTurretDestructible ] + id: BaseWeaponEnergyTurret diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml index da88cccc8c..0977796d86 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Turrets/turrets_energy.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [BaseWeaponEnergyTurret, ConstructibleMachine] + parent: [BaseWeaponEnergyTurretIndestructible, ConstructibleMachine] id: WeaponEnergyTurretStationBase name: sentry turret description: A high-tech autonomous weapons system designed to keep unauthorized personnel out of sensitive areas. @@ -87,6 +87,8 @@ deployedDamageModifierSetId: FlimsyMetallic - type: Damageable damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Repairable doAfterDelay: 10 allowSelfRepair: false diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index c724d27a7d..3204beb958 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -192,18 +192,11 @@ !type:DamageTrigger damage: 20 behaviors: - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - params: - volume: -4 - !type:SpawnEntitiesBehavior spawn: MaterialBones1: min: 1 max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: entity name: sharkminnow tooth spear diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml index 5ba248eb05..6c84c46495 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/base_grenades.yml @@ -1,6 +1,6 @@ -- type: entity # Starts fuse after taking 10 damage. - parent: BaseItem +- type: entity abstract: true + parent: BaseItem id: GrenadeBase components: - type: Sprite @@ -34,8 +34,8 @@ friction: 0.2 - type: entity # Starts fuse after taking 10 damage. - parent: GrenadeBase abstract: true + parent: GrenadeBase id: TimerGrenadeBase components: - type: TriggerOnUse @@ -55,25 +55,15 @@ Primed: { state: primed } Unprimed: { state: icon } -- type: entity # Starts fuse after taking 10 damage. - parent: GrenadeBase +- type: entity abstract: true + parent: [ GrenadeBase, VolatileGrenadeBase ] id: ImpactGrenadeBase components: - type: TriggerOnLand - type: LandAtCursor - - type: Destructible - thresholds: - - trigger: # immediately explode - !type:DamageTrigger - damage: 45 - behaviors: - - !type:TriggerBehavior - keyOut: timer - - !type:DoActsBehavior - acts: [ "Destruction" ] -- type: entity # Starts fuse after taking 10 damage, instantly detonates/activates after taking 45 damage. +- type: entity # Instantly detonates/activates after taking 45 damage. abstract: true id: VolatileGrenadeBase components: @@ -87,13 +77,8 @@ keyOut: timer - !type:DoActsBehavior acts: ["Destruction"] - - trigger: - !type:DamageTrigger - damage: 10 - behaviors: - - !type:TimerStartBehavior -- type: entity # Starts fuse after taking 10 damage, is destroyed without activating/detonating after taking 45 damage. +- type: entity # Is destroyed without activating/detonating after taking 45 damage. abstract: true id: FragileGrenadeBase components: @@ -105,8 +90,3 @@ behaviors: - !type:DoActsBehavior acts: ["Destruction"] - - trigger: - !type:DamageTrigger - damage: 10 - behaviors: - - !type:TimerStartBehavior diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml index 711cc27d21..72c7ed11f3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/grenades.yml @@ -284,9 +284,9 @@ price: 1000 - type: entity + parent: [ VolatileGrenadeBase, TimerGrenadeBase ] name: the nuclear option description: Please don't throw it, think of the children. - parent: TimerGrenadeBase id: NuclearGrenade components: - type: Sprite @@ -301,26 +301,16 @@ totalIntensity: 20000 # ~15 tile radius. intensitySlope: 5 maxIntensity: 50 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:TriggerBehavior - keyOut: timer # immediately explode - - !type:DoActsBehavior - acts: ["Destruction"] - type: Appearance - type: TimerTriggerVisuals primingSound: path: /Audio/Effects/countdown.ogg - type: entity + parent: [ BaseItem, BaseItemDestructible ] + id: ModularGrenade name: modular grenade description: A grenade casing. Requires a trigger and a payload. - parent: BaseItem - id: ModularGrenade components: - type: Sprite sprite: Objects/Weapons/Grenades/modular.rsi @@ -336,9 +326,6 @@ - type: Construction graph: ModularGrenadeGraph node: emptyCase - - type: Damageable - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - trigger: @@ -346,8 +333,6 @@ damage: 50 behaviors: - !type:TriggerBehavior - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml index e0d5a5f23f..435186f2f9 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml @@ -93,7 +93,7 @@ price: 2500 - type: entity - parent: [FragileGrenadeBase, ScatteringGrenadeBase, ImpactGrenadeBase, BaseSyndicateContraband] + parent: [ScatteringGrenadeBase, ImpactGrenadeBase, BaseSyndicateContraband] id: ClusterBananaPeel name: cluster banana peel description: Splits into 6 explosive banana peels after throwing, guaranteed fun! diff --git a/Resources/Prototypes/Entities/Objects/Weapons/security.yml b/Resources/Prototypes/Entities/Objects/Weapons/security.yml index fe8f5655af..c562dd427f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/security.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/security.yml @@ -187,7 +187,7 @@ - type: entity name: portable flasher - parent: [BaseMachine, BaseSecurityContraband] + parent: [BaseMachine, BaseSecurityContraband, BaseMachineDestructible] id: PortableFlasher description: An ultrabright flashbulb with a proximity trigger, useful for making an area security-only. components: @@ -231,3 +231,11 @@ guides: - Security - Antagonists + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak diff --git a/Resources/Prototypes/Entities/Objects/base_item.yml b/Resources/Prototypes/Entities/Objects/base_item.yml index a83d50842f..31a5364c4b 100644 --- a/Resources/Prototypes/Entities/Objects/base_item.yml +++ b/Resources/Prototypes/Entities/Objects/base_item.yml @@ -1,7 +1,7 @@ - type: entity - name: "item" - id: BaseItem abstract: true + id: BaseItem + name: "item" components: - type: Item size: Small @@ -47,6 +47,22 @@ - type: Rotatable increment: 30 +- type: entity + abstract: true + id: BaseItemDestructible # Should be replaced by a variety of destruction bases, possibly combined with drink_base_materials.yml + components: + - type: Damageable + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - type: entity name: "storage item" id: BaseStorageItem diff --git a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml index b9e2e4a238..c178137d40 100644 --- a/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml +++ b/Resources/Prototypes/Entities/Structures/Decoration/crystals.yml @@ -1,14 +1,13 @@ - type: entity - id: CrystalGreen + abstract: true parent: BaseStructure - suffix: green + id: BaseCrystalStalagmite name: crystal description: A crystaline solid. components: - type: Sprite sprite: Structures/Decoration/crystal.rsi state: crystal_grey - color: "#52ff39" noRot: true - type: Reflect reflectProb: 0.5 @@ -36,219 +35,156 @@ - type: PointLight radius: 3 energy: 3 - color: "#52ff39" - type: Damageable damageModifierSet: Glass - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: + - trigger: &DamageTrigger20 !type:DamageTrigger damage: 20 behaviors: - !type:PlaySoundBehavior sound: collection: GlassBreak - - !type:SpawnEntitiesBehavior - spawn: - ShardCrystalGreen: - min: 1 - max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - type: entity + parent: BaseCrystalStalagmite + id: CrystalGreen + suffix: green + components: + - type: Sprite + color: "#52ff39" + - type: PointLight + color: "#52ff39" + - type: Destructible + thresholds: + - trigger: *DamageTrigger20 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardCrystalGreen: &Min1Max2 + min: 1 + max: 2 + +- type: entity + parent: BaseCrystalStalagmite id: CrystalPink - parent: CrystalGreen suffix: pink components: - type: Sprite color: "#ff66cc" - type: PointLight - radius: 3 - energy: 3 color: "#ff66cc" - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 20 + - trigger: *DamageTrigger20 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalPink: - min: 1 - max: 1 + ShardCrystalPink: *Min1Max2 - type: entity + parent: BaseCrystalStalagmite id: CrystalGrey - parent: CrystalGreen suffix: red components: - type: Sprite - state: crystal_grey color: "#fb4747" - type: PointLight color: "#fb4747" - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 20 + - trigger: *DamageTrigger20 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalRed: - min: 1 - max: 2 + ShardCrystalRed: *Min1Max2 - type: entity + parent: BaseCrystalStalagmite id: CrystalOrange - parent: CrystalGreen suffix: orange components: - type: Sprite color: "#ff8227" - type: PointLight - radius: 3 - energy: 3 color: "#ff8227" - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 20 + - trigger: *DamageTrigger20 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalOrange: - min: 1 - max: 2 + ShardCrystalOrange: *Min1Max2 - type: entity + parent: BaseCrystalStalagmite id: CrystalBlack - parent: CrystalGreen suffix: black components: - type: Sprite color: "#363636" - type: PointLight - radius: 3 - energy: 3 color: "#363636" - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 20 + - trigger: *DamageTrigger20 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalBlack: - min: 1 - max: 2 + ShardCrystalBlack: *Min1Max2 - type: entity + parent: BaseCrystalStalagmite id: CrystalBlue - parent: CrystalGreen suffix: blue components: - type: Sprite color: "#39a1ff" - type: PointLight - radius: 3 - energy: 3 color: "#39a1ff" - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 20 + - trigger: *DamageTrigger20 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalBlue: - min: 1 - max: 2 + ShardCrystalBlue: *Min1Max2 - type: entity + parent: BaseCrystalStalagmite id: CrystalYellow - parent: CrystalGreen suffix: yellow components: - type: Sprite color: "#ffde46" - type: PointLight - radius: 3 - energy: 3 color: "#ffde46" - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 20 + - trigger: *DamageTrigger20 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalYellow: - min: 1 - max: 2 + ShardCrystalYellow: *Min1Max2 - type: entity + parent: BaseCrystalStalagmite id: CrystalCyan - parent: CrystalGreen suffix: cyan components: - type: Sprite color: "#47f8ff" - type: PointLight - radius: 3 - energy: 3 color: "#47f8ff" - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 20 + - trigger: *DamageTrigger20 behaviors: - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - !type:SpawnEntitiesBehavior spawn: - ShardCrystalCyan: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] + ShardCrystalCyan: *Min1Max2 diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml index 4f8e90646a..3bcf8bfd60 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/base_structuredispensers.yml @@ -1,7 +1,7 @@ - type: entity abstract: true id: ReagentDispenserBase - parent: SmallConstructibleMachine + parent: [ SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] placement: mode: SnapgridCenter components: @@ -44,10 +44,8 @@ thresholds: - trigger: !type:DamageTrigger - damage: 200 + damage: 100 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak diff --git a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml index 676b0481ba..7b9d55c01d 100644 --- a/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml +++ b/Resources/Prototypes/Entities/Structures/Dispensers/chem.yml @@ -16,19 +16,6 @@ - ChemDispensable - type: ApcPowerReceiver - type: ExtensionCableReceiver - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalGlassBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Machine board: ChemDispenserMachineCircuitboard - type: GuideHelp diff --git a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml index 716d6980df..bf9388b05e 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/MaterialDoors/material_doors.yml @@ -52,14 +52,6 @@ cost: 6 delay: 6 fx: EffectRCDDeconstruct6 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 300 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - type: Occluder - type: BlockWeather diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml index 2e820f8056..d74866e329 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/assembly.yml @@ -1,14 +1,13 @@ - type: entity - id: WindoorAssembly + abstract: true + parent: BaseStructure + id: BaseWindoorAssembly name: windoor assembly description: It opens, it closes, and you can see through it! - parent: BaseStructure + placement: + mode: SnapgridCenter components: - type: InteractionOutline - - type: Sprite - sprite: Structures/Doors/Windoors/windoor.rsi - layers: - - state: assembly - type: Physics - type: Fixtures fixtures: @@ -33,28 +32,39 @@ fx: EffectRCDDeconstruct8 - type: Destructible thresholds: - - trigger: + - trigger: &DamageTrigger300 !type:DamageTrigger damage: 300 behaviors: - !type:DoActsBehavior acts: ["Destruction"] + +- type: entity + parent: BaseWindoorAssembly + id: WindoorAssembly + components: + - type: Sprite + sprite: Structures/Doors/Windoors/windoor.rsi + layers: + - state: assembly + - type: Destructible + thresholds: + - trigger: *DamageTrigger300 + behaviors: - !type:SpawnEntitiesBehavior spawn: - SheetSteel1: + SheetSteel1: &BaseWindoorDrop min: 1 max: 3 - type: Construction graph: Windoor node: assembly - placement: - mode: SnapgridCenter - type: entity + parent: BaseWindoorAssembly id: WindoorAssemblySecure name: secure windoor assembly description: It opens, it closes, and you can see through it! This one looks tough. - parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/windoor.rsi @@ -63,26 +73,20 @@ - state: assembly - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 600 + - trigger: *DamageTrigger300 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetPlasteel1: - min: 1 - max: 2 + SheetPlasteel1: *BaseWindoorDrop - type: Construction graph: Windoor node: assemblySecure - type: entity + parent: BaseWindoorAssembly id: WindoorAssemblyClockwork name: clockwork windoor assembly description: It opens, it closes, and you can see through it! This one looks tough. - parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/clockwork_windoor.rsi @@ -90,27 +94,21 @@ - state: open - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 450 + - trigger: *DamageTrigger300 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetBrass1: - min: 1 - max: 2 + SheetBrass1: *BaseWindoorDrop - type: Construction graph: Windoor node: assemblyClockwork #plasma windoor assemblies - type: entity + parent: BaseWindoorAssembly id: WindoorAssemblyPlasma name: plasma windoor assembly description: It opens, it closes, and you can see through it! This one looks purp-, no, pink. Wait... - parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi @@ -118,29 +116,21 @@ - state: assembly - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 360 + - trigger: *DamageTrigger300 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetSteel1: - min: 1 - max: 2 - SheetPGlass1: - min: 1 - max: 3 + SheetSteel1: *BaseWindoorDrop + SheetPGlass1: *BaseWindoorDrop - type: Construction graph: Windoor node: pglass - type: entity + parent: BaseWindoorAssembly id: WindoorAssemblySecurePlasma name: secure plasma windoor assembly description: It opens, it closes, and you can see through it! This one looks strong and pin-, no, purple. Hold on... - parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi @@ -149,30 +139,24 @@ - state: assembly - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 1200 + - trigger: *DamageTrigger300 behaviors: - !type:DoActsBehavior acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetPlasteel1: - min: 1 - max: 2 - SheetRPGlass1: - min: 1 - max: 3 + SheetPlasteel1: *BaseWindoorDrop + SheetRPGlass1: *BaseWindoorDrop - type: Construction graph: Windoor node: pglassSecure #uranium windoor assemblies - type: entity + parent: BaseWindoorAssembly id: WindoorAssemblyUranium name: uranium windoor assembly description: It opens, it closes, and you can see through it! This one looks sickly green... - parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi @@ -180,29 +164,21 @@ - state: assembly - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetSteel1: - min: 1 - max: 2 - SheetUGlass1: - min: 1 - max: 3 + SheetSteel1: *BaseWindoorDrop + SheetUGlass1: *BaseWindoorDrop - type: Construction graph: Windoor node: uglass - type: entity + parent: BaseWindoorAssembly id: WindoorAssemblySecureUranium name: secure uranium windoor assembly description: It opens, it closes, and you can see through it! This one looks strong and radioactive-lime-green! - parent: WindoorAssembly components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi @@ -211,20 +187,12 @@ - state: assembly - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 1200 + - trigger: *DamageTrigger300 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:SpawnEntitiesBehavior spawn: - SheetPlasteel1: - min: 1 - max: 2 - SheetRUGlass1: - min: 1 - max: 3 + SheetPlasteel1: *BaseWindoorDrop + SheetRUGlass1: *BaseWindoorDrop - type: Construction graph: Windoor node: uglassSecure diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml index 0f91871837..86d0d2bc8b 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/base_structurewindoors.yml @@ -1,8 +1,7 @@ -#Normal windoors - type: entity - id: BaseWindoor - parent: [BaseDeltaPressureGlassQuarter, BaseStructure] abstract: true + parent: BaseStructure + id: BaseWindoorGeneric placement: mode: SnapgridCenter components: @@ -16,7 +15,6 @@ collection: GlassSmash - type: InteractionOutline - type: StationAiWhitelist - - type: Physics - type: Fixtures fixtures: fix1: @@ -29,7 +27,6 @@ layer: - GlassAirlockLayer - type: Sprite - sprite: Structures/Doors/Windoors/windoor.rsi layers: - state: closed map: ["enum.DoorVisualLayers.Base"] @@ -72,11 +69,11 @@ range: 200 - type: DeviceLinkSink ports: - - Open - - Close - - Toggle - - AutoClose - - DoorBolt + - Open + - Close + - Toggle + - AutoClose + - DoorBolt - type: DeviceLinkSource ports: - DoorStatus @@ -92,22 +89,6 @@ cost: 8 delay: 8 fx: EffectRCDDeconstruct8 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 200 - behaviors: - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 2 - SheetSteel1: - min: 2 - max: 4 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: ContainerFill containers: board: [ DoorElectronics ] @@ -163,27 +144,23 @@ - type: Airtight noAirWhenFullyAirBlocked: false airBlockedDirection: - - South + - South - type: Construction graph: Windoor - node: windoor containers: - board - - type: StaticPrice - price: 150 - type: PryUnpowered - type: Tag tags: - - DoorRemoteWhitelist - # This tag is used by door remotes to allow or not a door remote to normally be able to interact with a door + - DoorRemoteWhitelist + # This tag is used by door remotes to allow or not a door remote to normally be able to interact with a door - type: entity - id: BaseSecureWindoor - parent: [BaseDeltaPressureReinforcedGlassQuarter, BaseWindoor] abstract: true + parent: BaseWindoorGeneric + id: BaseSecureWindoorGeneric components: - type: Sprite - sprite: Structures/Doors/Windoors/windoor.rsi layers: - state: secure_underlay - state: closed @@ -219,6 +196,43 @@ visible: false - type: Damageable damageModifierSet: RGlass + - type: StaticPrice + price: 150 + +#Normal windoors +- type: entity + abstract: true + parent: [ BaseDeltaPressureGlassQuarter, BaseWindoorGeneric ] + id: BaseWindoor + components: + - type: Sprite + sprite: Structures/Doors/Windoors/windoor.rsi + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 200 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + SheetSteel1: + min: 2 + max: 4 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: Construction + node: windoor + +- type: entity + abstract: true + parent: [ BaseDeltaPressureReinforcedGlassQuarter, BaseSecureWindoorGeneric ] + id: BaseSecureWindoor + components: + - type: Sprite + sprite: Structures/Doors/Windoors/windoor.rsi - type: Destructible thresholds: - trigger: @@ -250,44 +264,12 @@ #Plasma Windoors - type: entity - id: BasePlasmaWindoor - parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoor] abstract: true + parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoorGeneric] + id: BasePlasmaWindoor components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi - layers: - - state: closed - map: [ "enum.DoorVisualLayers.Base" ] - - state: closed_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseUnlit" ] - visible: false - - state: welded - map: [ "enum.WeldableLayers.BaseWelded" ] - - state: bolted_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseBolted" ] - - state: emergency_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] - - state: panel_open - map: [ "enum.WiresVisualLayers.MaintenancePanel" ] - visible: false - - state: electrified_ai - sprite: Interface/Misc/ai_hud.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.HUD" ] - - state: electrified - sprite: Effects/electricity.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.Sparks" ] - - state: sparks - map: ["enum.DoorVisualLayers.BaseEmagging"] - shader: unshaded - visible: false - type: Destructible thresholds: - trigger: @@ -313,45 +295,12 @@ resistance: 2 - type: entity - id: BaseSecurePlasmaWindoor - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoor] abstract: true + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoorGeneric] + id: BaseSecurePlasmaWindoor components: - type: Sprite sprite: Structures/Doors/Windoors/plasma.rsi - layers: - - state: secure_underlay - - state: closed - map: [ "enum.DoorVisualLayers.Base" ] - - state: closed_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseUnlit" ] - visible: false - - state: welded - map: [ "enum.WeldableLayers.BaseWelded" ] - - state: bolted_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseBolted" ] - - state: emergency_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] - - state: panel_open - map: [ "enum.WiresVisualLayers.MaintenancePanel" ] - visible: false - - state: electrified_ai - sprite: Interface/Misc/ai_hud.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.HUD" ] - - state: electrified - sprite: Effects/electricity.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.Sparks" ] - - state: sparks - map: ["enum.DoorVisualLayers.BaseEmagging"] - shader: unshaded - visible: false - type: Destructible thresholds: - trigger: @@ -385,44 +334,12 @@ #Uranium Windoors - type: entity - id: BaseUraniumWindoor - parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoor] abstract: true + parent: [BaseDeltaPressurePlasmaQuarter, BaseWindoorGeneric] + id: BaseUraniumWindoor components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi - layers: - - state: closed - map: [ "enum.DoorVisualLayers.Base" ] - - state: closed_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseUnlit" ] - visible: false - - state: welded - map: [ "enum.WeldableLayers.BaseWelded" ] - - state: bolted_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseBolted" ] - - state: emergency_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] - - state: panel_open - map: [ "enum.WiresVisualLayers.MaintenancePanel" ] - visible: false - - state: electrified_ai - sprite: Interface/Misc/ai_hud.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.HUD" ] - - state: electrified - sprite: Effects/electricity.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.Sparks" ] - - state: sparks - map: ["enum.DoorVisualLayers.BaseEmagging"] - shader: unshaded - visible: false - type: Destructible thresholds: - trigger: @@ -448,45 +365,12 @@ resistance: 3 - type: entity - id: BaseSecureUraniumWindoor - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoor] abstract: true + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseSecureWindoorGeneric] + id: BaseSecureUraniumWindoor components: - type: Sprite sprite: Structures/Doors/Windoors/uranium.rsi - layers: - - state: secure_underlay - - state: closed - map: [ "enum.DoorVisualLayers.Base" ] - - state: closed_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseUnlit" ] - visible: false - - state: welded - map: [ "enum.WeldableLayers.BaseWelded" ] - - state: bolted_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseBolted" ] - - state: emergency_unlit - shader: unshaded - map: [ "enum.DoorVisualLayers.BaseEmergencyAccess" ] - - state: panel_open - map: [ "enum.WiresVisualLayers.MaintenancePanel" ] - visible: false - - state: electrified_ai - sprite: Interface/Misc/ai_hud.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.HUD" ] - - state: electrified - sprite: Effects/electricity.rsi - shader: unshaded - visible: false - map: [ "enum.ElectrifiedLayers.Sparks" ] - - state: sparks - map: ["enum.DoorVisualLayers.BaseEmagging"] - shader: unshaded - visible: false - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml b/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml index e0a726e9c4..24a42d6ed4 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Windoors/clockwork.yml @@ -1,8 +1,8 @@ - type: entity + abstract: true + parent: BaseWindoorGeneric id: BaseClockworkWindoor name: clockwork windoor - parent: BaseWindoor - abstract: true components: - type: Sprite sprite: Structures/Doors/Windoors/clockwork_windoor.rsi diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml index aa914b544a..f51b0b6a98 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/base_structuretables.yml @@ -1,9 +1,9 @@ - type: entity - id: TableBase + abstract: true parent: BaseStructure + id: TableBase name: table description: A square piece of metal standing on four metal legs. - abstract: true components: - type: Animateable - type: Damageable @@ -43,10 +43,10 @@ - ForceFixRotations - type: entity - id: CounterBase - parent: TableBase - name: counter abstract: true + parent: TableBase + id: CounterBase + name: counter components: - type: Fixtures fixtures: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml index bacad30788..20678a0e5d 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/Tables/tables.yml @@ -1,7 +1,7 @@ - type: entity + parent: BaseStructure id: TableFrame # BaseStructure and not BaseTable, since these shouldn't be climbable/placeable. - parent: BaseStructure name: table frame description: Pieces of metal that make the frame of a table. components: @@ -51,8 +51,8 @@ node: TableFrame - type: entity - id: CounterWoodFrame parent: BaseStructure + id: CounterWoodFrame name: wooden counter frame description: Pieces of wood that make the frame of a table. components: @@ -101,16 +101,28 @@ node: CounterWoodFrame - type: entity + parent: BaseStructure id: CounterMetalFrame - parent: CounterWoodFrame name: metal counter frame description: Pieces of metal that make the frame of a table. components: + - type: SpriteFade - type: Sprite sprite: Structures/Furniture/Tables/frame.rsi - type: Icon sprite: Structures/Furniture/Tables/frame.rsi state: full + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.45,-0.45,0.45,0.45" + density: 55 + mask: + - TableMask + layer: + - TableLayer - type: Damageable damageModifierSet: Metallic - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml index 0855cef8d0..8663834053 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/beds.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/beds.yml @@ -1,8 +1,7 @@ - type: entity - name: bed - id: Bed + abstract: true parent: BaseStructure - description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing. + id: BaseBed components: - type: HealOnBuckle damage: @@ -39,6 +38,18 @@ damageModifierSet: Metallic - type: Injurable damageContainer: Inorganic + - type: Transform + anchored: true + noRot: true + - type: Anchorable + - type: Pullable + +- type: entity + parent: BaseBed + id: Bed + name: bed + description: This is used to lie in, sleep in or strap on. Resting here provides extremely slow healing. + components: - type: Destructible thresholds: - trigger: @@ -52,12 +63,6 @@ SheetSteel1: min: 1 max: 2 - - type: Transform - anchored: true - noRot: true - - type: Anchorable - - type: Pullable - - type: entity parent: Bed @@ -82,7 +87,7 @@ - type: AmbientMusicMarkerMedical - type: entity - parent: Bed + parent: BaseBed id: DogBed name: dog bed description: A comfy-looking dog bed. You can even strap your pet in, in case the gravity turns off. @@ -126,7 +131,7 @@ damageModifierSet: Inflatable - type: entity - parent: Bed + parent: BaseBed id: WebBed name: web bed description: You got webbed. @@ -157,7 +162,7 @@ node: bed - type: entity - parent: Bed + parent: BaseBed id: PsychBed name: psychologist bed description: An upholstered bed for the psychological care of patients. diff --git a/Resources/Prototypes/Entities/Structures/Furniture/bench.yml b/Resources/Prototypes/Entities/Structures/Furniture/bench.yml index ce8f8b5686..d43e603e38 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/bench.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/bench.yml @@ -17,6 +17,17 @@ bodyType: Static - type: StaticPrice price: 35 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity id: BenchColorfulComfy diff --git a/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml b/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml index 812cf68a31..a302e5c7f7 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/carpets.yml @@ -1,7 +1,7 @@ # TODO move all of this to tiles once tile smoothing is supported - type: entity - id: CarpetBase parent: BaseStructure + id: CarpetBase name: carpet description: "Fancy walking surface." abstract: true @@ -33,7 +33,7 @@ damageContainer: Inorganic - type: Destructible thresholds: - - trigger: + - trigger: &DamageTrigger10 !type:DamageTrigger damage: 10 behaviors: @@ -55,15 +55,11 @@ sprite: Structures/Furniture/Carpets/red_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemRed: + FloorCarpetItemRed: &BaseCarpetSpawn min: 1 max: 1 @@ -79,17 +75,11 @@ sprite: Structures/Furniture/Carpets/black_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemBlack: - min: 1 - max: 1 + FloorCarpetItemBlack: *BaseCarpetSpawn - type: entity id: CarpetPink @@ -103,17 +93,11 @@ sprite: Structures/Furniture/Carpets/pink_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemPink: - min: 1 - max: 1 + FloorCarpetItemPink: *BaseCarpetSpawn - type: entity id: CarpetBlue @@ -127,17 +111,11 @@ sprite: Structures/Furniture/Carpets/blue_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemBlue: - min: 1 - max: 1 + FloorCarpetItemBlue: *BaseCarpetSpawn - type: entity id: CarpetGreen @@ -151,17 +129,11 @@ sprite: Structures/Furniture/Carpets/green_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemGreen: - min: 1 - max: 1 + FloorCarpetItemGreen: *BaseCarpetSpawn - type: entity id: CarpetOrange @@ -175,17 +147,11 @@ sprite: Structures/Furniture/Carpets/orange_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemOrange: - min: 1 - max: 1 + FloorCarpetItemOrange: *BaseCarpetSpawn - type: entity id: CarpetSBlue @@ -199,17 +165,11 @@ sprite: Structures/Furniture/Carpets/skyblue_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemSkyBlue: - min: 1 - max: 1 + FloorCarpetItemSkyBlue: *BaseCarpetSpawn - type: entity id: CarpetPurple @@ -223,17 +183,11 @@ sprite: Structures/Furniture/Carpets/purple_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemPurple: - min: 1 - max: 1 + FloorCarpetItemPurple: *BaseCarpetSpawn - type: entity id: CarpetCyan @@ -247,17 +201,11 @@ sprite: Structures/Furniture/Carpets/cyan_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemCyan: - min: 1 - max: 1 + FloorCarpetItemCyan: *BaseCarpetSpawn - type: entity id: CarpetWhite @@ -271,22 +219,16 @@ sprite: Structures/Furniture/Carpets/white_carpet.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - FloorCarpetItemWhite: - min: 1 - max: 1 + FloorCarpetItemWhite: *BaseCarpetSpawn # TODO nuke this once tiles support rotating sprites - type: entity - id: CarpetChapel parent: BaseStructure + id: CarpetChapel name: "chapel's carpet" components: - type: Sprite @@ -307,9 +249,7 @@ damageContainer: Inorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] @@ -318,8 +258,8 @@ #cardpet - type: entity - id: CarpetCard parent: BaseStructure + id: CarpetCard name: cardboard "carpet" description: "Even lino is better." components: @@ -348,17 +288,13 @@ damageContainer: Inorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 10 + - trigger: *DamageTrigger10 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: - MaterialCardboard: - min: 1 - max: 1 + MaterialCardboard: *BaseCarpetSpawn - type: ToolRefinable refineResult: - id: MaterialCardboard1 diff --git a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml index 9fe9e91d87..6a127b9958 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/chairs.yml @@ -1,7 +1,7 @@ - type: entity - name: chair - id: SeatBase abstract: true + id: SeatBase + name: chair description: You sit in this. Either by will or force. placement: mode: PlaceFree @@ -31,17 +31,6 @@ damageModifierSet: Metallic - type: Injurable damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: StaticPrice price: 50 @@ -78,6 +67,17 @@ components: - type: Rotatable rotateWhileAnchored: true + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak #Starts anchored, can be rotated while anchored - type: entity @@ -103,6 +103,17 @@ - type: Construction graph: Seat node: chair + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity name: chair @@ -124,6 +135,17 @@ - type: Construction graph: Seat node: stool + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity name: bar stool @@ -180,6 +202,17 @@ - type: Construction graph: Seat node: chairComfy + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity name: pilot seat @@ -192,6 +225,17 @@ - type: Construction graph: Seat node: chairPilotSeat + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity name: wooden chair @@ -266,18 +310,11 @@ thresholds: - trigger: !type:DamageTrigger - damage: 50 + damage: 25 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:PlaySoundBehavior sound: path: /Audio/Voice/Human/womanlaugh.ogg - - !type:SpawnEntitiesBehavior - spawn: - MaterialWoodPlank: - min: 1 - max: 1 - type: Construction graph: RitualSeat node: chairCursed @@ -345,6 +382,17 @@ graph: Seat node: chairFolding - type: DamageExaminable + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity parent: ChairFolding @@ -367,6 +415,17 @@ - type: Construction graph: Seat node: chairSteelBench + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity name: cardboard stool @@ -381,8 +440,6 @@ node: stoolCard - type: Damageable damageModifierSet: Card - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml index 8eef044346..dcf5aa88bb 100644 --- a/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml +++ b/Resources/Prototypes/Entities/Structures/Furniture/toilet.yml @@ -117,6 +117,17 @@ reagents: - ReagentId: Water Quantity: 1 + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak # constructed toilets don't come with Rummageable or plungeruse component to avoid infinite item spawning. - type: entity @@ -196,15 +207,8 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 50 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - params: - volume: -6 - !type:SpawnEntitiesBehavior spawn: IngotGold1: diff --git a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml index 3c4238eff9..2d2c0cd789 100644 --- a/Resources/Prototypes/Entities/Structures/Holographic/projections.yml +++ b/Resources/Prototypes/Entities/Structures/Holographic/projections.yml @@ -1,7 +1,6 @@ - type: entity - id: HolosignWetFloor - name: wet floor sign - description: The words flicker as if they mean nothing. + abstract: true + id: BaseHoloSign placement: mode: SnapgridCenter components: @@ -10,15 +9,22 @@ - type: Physics bodyType: Static canCollide: false - - type: Sprite - sprite: Structures/Holo/wetfloor.rsi - state: icon - type: TimedDespawn lifetime: 90 - type: Clickable - type: Damageable - type: Injurable damageContainer: Inorganic + +- type: entity + parent: BaseHoloSign + id: HolosignWetFloor + name: wet floor sign + description: The words flicker as if they mean nothing. + components: + - type: Sprite + sprite: Structures/Holo/wetfloor.rsi + state: icon - type: Destructible thresholds: - trigger: @@ -29,8 +35,8 @@ acts: [ "Destruction" ] - type: entity + parent: BaseHoloSign id: HoloFan - parent: HolosignWetFloor name: holofan description: A barrier of hard light that blocks air, but nothing else. components: @@ -47,10 +53,18 @@ lifetime: 180 - type: Airtight noAirWhenFullyAirBlocked: false + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 30 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity + parent: BaseHoloSign id: HoloPeel - parent: HolosignWetFloor name: holopeel description: A banana peel made of slippery hard light, watch your step! components: @@ -58,7 +72,6 @@ sprite: Structures/Holo/peel.rsi state: icon - type: Physics - bodyType: Static canCollide: true - type: Slippery - type: StepTrigger @@ -86,13 +99,12 @@ acts: [ "Destruction" ] - type: entity + parent: BaseHoloSign id: HolosignSecurity - parent: HolosignWetFloor name: holographic barrier description: A barrier of hard light that blocks movement, but pretty weak. components: - type: Physics - bodyType: Static canCollide: true - type: Sprite sprite: Structures/Holo/security.rsi @@ -114,15 +126,22 @@ radius: 3 color: red - type: Climbable + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 30 + behaviors: + - !type:DoActsBehavior + acts: [ "Destruction" ] - type: entity + parent: BaseHoloSign id: HolosignForcefield - parent: HolosignWetFloor name: holographic force field description: A powerful temporal containment field that doesn't let anything through, not even a tesla or singularity. components: - type: Physics - bodyType: Static canCollide: true - type: Sprite sprite: Structures/Holo/field.rsi diff --git a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml index 7b9a89052e..0c0224ebfe 100644 --- a/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml +++ b/Resources/Prototypes/Entities/Structures/Lighting/base_lighting.yml @@ -5,10 +5,12 @@ #Basic lights - type: entity - id: AlwaysPoweredWallLight - name: light - description: "An always powered light." - suffix: Always powered + abstract: true + id: BaseWallLight + placement: + mode: SnapgridCenter + snap: + - Wallmount components: - type: MeleeSound soundGroups: @@ -18,11 +20,7 @@ anchored: true - type: Clickable - type: InteractionOutline - - type: Construction - graph: LightFixture - node: tubeLight - type: Sprite - sprite: Structures/Wallmounts/Lighting/light_tube.rsi drawdepth: WallMountedItems layers: - map: ["enum.PoweredLightLayers.Base"] @@ -30,7 +28,6 @@ - map: ["enum.PoweredLightLayers.Glow"] state: glow shader: unshaded - state: base - type: PointLight color: "#FFE4CE" # 5000K color temp energy: 0.8 @@ -65,22 +62,43 @@ damage: 50 behaviors: - !type:EmptyAllContainersBehaviour - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 2 - max: 2 - !type:DoActsBehavior - acts: ["Destruction"] + acts: [ "Destruction" ] - !type:PlaySoundBehavior sound: collection: GlassBreak - type: PlacementReplacement key: lights - placement: - mode: SnapgridCenter - snap: - - Wallmount + +- type: entity + parent: BaseWallLight + id: AlwaysPoweredWallLight + name: light + suffix: Always powered + description: "An always powered light." + components: + - type: Construction + graph: LightFixture + node: tubeLight + - type: Sprite + sprite: Structures/Wallmounts/Lighting/light_tube.rsi + layers: + - map: ["enum.PoweredLightLayers.Base"] + state: base + - map: ["enum.PoweredLightLayers.Glow"] + state: glow + shader: unshaded + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 2 + max: 2 - type: entity name: light @@ -241,11 +259,11 @@ #Small lights - type: entity - name: small light - description: "An always powered light." + parent: BaseWallLight id: SmallLight + name: small light suffix: Always Powered - parent: AlwaysPoweredWallLight + description: "An always powered light." components: - type: AmbientSound volume: -15 @@ -260,8 +278,6 @@ radius: 6 softness: 1.1 enabled: true - - type: Physics - bodyType: Static - type: Fixtures fixtures: fix1: @@ -273,23 +289,17 @@ - None layer: - TabletopMachineLayer - - type: Damageable - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 25 + damage: 50 behaviors: - - !type:EmptyAllContainersBehaviour - !type:SpawnEntitiesBehavior spawn: SheetSteel1: min: 1 max: 1 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Construction graph: LightFixture node: bulbLight @@ -422,11 +432,10 @@ #Emergency Lights - type: entity + parent: BaseWallLight id: EmergencyLight name: emergency light description: A small light with an internal battery that turns on as soon as it stops receiving any power. Nanotrasen technology allows it to adapt its color to alert crew to the conditions of the station. - parent: AlwaysPoweredWallLight - suffix: "" components: - type: PointLight enabled: false @@ -461,7 +470,6 @@ color: "#7CFC00" shader: "unshaded" visible: false - - type: Appearance - type: Construction graph: LightFixture node: emergencyLight @@ -469,7 +477,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 25 + damage: 50 behaviors: - !type:SpawnEntitiesBehavior spawn: @@ -479,15 +487,6 @@ ShardGlass: min: 1 max: 1 - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: GlassBreak - placement: - mode: SnapgridCenter - snap: - - Wallmount #Coloured lights diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml index 6d6b2e4f77..8272b8cd3d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/frame.yml @@ -1,10 +1,8 @@ - type: entity - id: BaseStructureComputer - parent: BaseStructure abstract: true + parent: BaseStructure + id: BaseStructureComputerIndestructible components: - - type: Physics - bodyType: Static - type: Fixtures fixtures: fix1: @@ -21,9 +19,17 @@ - type: Anchorable - type: Construction graph: Computer - node: frameUnsecured - type: Sprite drawdepth: Objects + +- type: entity + abstract: true + parent: BaseStructureComputerIndestructible + id: BaseStructureComputer + components: + - type: Construction + graph: Computer + node: frameUnsecured - type: Damageable damageModifierSet: Electronic - type: Injurable @@ -65,7 +71,7 @@ monitorUnsecured: { state: 4 } - type: entity - parent: BaseStructureComputer + parent: BaseStructureComputerIndestructible id: ComputerBroken name: broken computer description: This computer has seen better days. diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml index b6e8e791e6..e22f777754 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/biomass_reclaimer.yml @@ -1,6 +1,6 @@ - type: entity id: BiomassReclaimer - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: biomass reclaimer description: Reclaims biomass from corpses. Gruesome. placement: @@ -24,3 +24,11 @@ - type: GuideHelp guides: - Cloning + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml index 718a0ec886..149876d29d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/chemistry_machines.yml @@ -1,6 +1,6 @@ - type: entity id: BaseTabletopChemicalMachine - parent: [ BaseMachinePowered, SmallConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] abstract: true components: - type: Transform @@ -36,6 +36,14 @@ mixer: !type:ContainerSlot machine_board: !type:Container machine_parts: !type:Container + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak - type: entity id: MachineElectrolysisUnit diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml index cdef37524b..9091f36401 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/cryo_pod.yml @@ -1,5 +1,5 @@ - type: entity - parent: [BaseStructure, ConstructibleMachine] # Not a BaseMachinePowered since we don't want the anchorable component + parent: [BaseStructure, ConstructibleMachine, BaseConstructibleMachineDestructible] # Not a BaseMachinePowered since we don't want the anchorable component id: CryoPod name: cryo pod description: A special machine intended to create a safe environment for the use of chemicals that react in cold environments. @@ -55,22 +55,16 @@ layoutId: CryoPod - type: Damageable damageModifierSet: StructuralMetallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 175 behaviors: - !type:EmptyAllContainersBehaviour - !type:PlaySoundBehavior sound: collection: WindowShatter - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: ApcPowerReceiver powerLoad: 3000 - type: ExtensionCableReceiver diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml index ad98f47e36..dff44d54f9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/disease_diagnoser.yml @@ -1,6 +1,6 @@ - type: entity id: DiseaseDiagnoser - parent: [ BaseMachinePowered, SmallConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] name: Disease Diagnoser Delta Extreme description: A machine that analyzes disease samples. placement: @@ -17,6 +17,14 @@ - type: Appearance - type: Machine board: DiagnoserMachineCircuitboard + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: entity name: disease diagnoser report diff --git a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml index 49a77d1d09..5fa16d2abd 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Medical/vaccinator.yml @@ -1,6 +1,6 @@ - type: entity id: Vaccinator - parent: BaseMachinePowered + parent: [ BaseMachinePowered, BaseMachineDestructible ] name: vaccinator description: A machine that creates vaccines. placement: @@ -22,3 +22,11 @@ machine_board: !type:Container machine_parts: !type:Container - type: RequireProjectileTarget + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml index f5d8c40545..7bfaabe2cb 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_equipment.yml @@ -1,6 +1,6 @@ - type: entity id: MachineAnomalyVessel - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: anomaly vessel description: A container able to harness a scan of an anomaly and turn it into research data. components: @@ -73,10 +73,8 @@ thresholds: - trigger: !type:DamageTrigger - damage: 150 + damage: 175 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak @@ -113,7 +111,7 @@ - type: entity id: MachineAPE - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: A.P.E. description: An Anomalous Particle Emitter, capable of shooting out unstable particles which can interface with anomalies. components: @@ -148,6 +146,14 @@ - MachineMask layer: - MachineLayer + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: Rotatable rotateWhileAnchored: true - type: Machine diff --git a/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml b/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml index de4ea19350..62f91e1f5c 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/anomaly_sync.yml @@ -1,6 +1,6 @@ - type: entity id: MachineAnomalySynchronizer - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: anomaly synchronizer description: A sophisticated device that reads changes in anomalous waves, and converts them into energy signals. components: @@ -43,6 +43,14 @@ mask: - ItemMask hard: True + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak - type: Transform anchored: true noRot: false diff --git a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml index 87dc468018..fc21d9e296 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/artifact_analyzer.yml @@ -1,6 +1,6 @@ - type: entity id: MachineArtifactAnalyzer - parent: [ BaseMachinePowered, SmallConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] name: artifact analyzer description: A platform capable of performing analysis on various types of artifacts. components: @@ -45,6 +45,14 @@ - LowImpassable - BulletImpassable hard: False + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak - type: Transform anchored: true - type: ApcPowerReceiver @@ -81,7 +89,7 @@ - type: entity id: MachineArtifactCrusher - parent: [ ConstructibleMachine, BaseMachinePowered ] + parent: [ ConstructibleMachine, BaseMachinePowered, BaseConstructibleMachineDestructible ] name: artifact crusher description: Best not to let your fingers get stuck... components: @@ -121,6 +129,17 @@ - HighImpassable layer: - HighImpassable + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:EmptyContainersBehaviour + containers: + - entity_storage - type: EntityStorage capacity: 1 whitelist: diff --git a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml index c0c4135702..09ad3e4af0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/base_structuremachines.yml @@ -22,21 +22,27 @@ - MachineMask layer: - MachineLayer + +- type: entity + abstract: true + id: BaseMachineDestructible + components: - type: Damageable - damageModifierSet: StructuralMetallic - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 100 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - !type:DoActsBehavior acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak + - !type:SpawnEntitiesBehavior + offset: 0 + spawn: + MachineFrameDestroyed: + min: 1 + max: 1 - type: entity abstract: true @@ -68,9 +74,43 @@ - type: LightningTarget priority: 1 +- type: entity + abstract: true + id: BaseConstructibleMachineDestructible + components: + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - type: entity abstract: true parent: ConstructibleMachine id: SmallConstructibleMachine components: - type: RequireProjectileTarget + +- type: entity + abstract: true + id: BaseSmallConstructibleMachineDestructible + components: + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 100 + behaviors: + - !type:ChangeConstructionNodeBehavior + node: machineFrame + - !type:DoActsBehavior + acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml index 72df7c9249..649704c0a8 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/chem_master.yml @@ -1,6 +1,6 @@ - type: entity id: ChemMaster - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: ChemMaster 4000 description: An industrial grade chemical manipulator with pill and bottle production included. placement: @@ -41,17 +41,12 @@ - MachineLayer - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 50 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: ActivatableUI key: enum.ChemMasterUiKey.Key - type: ActivatableUIRequiresPower diff --git a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml index bfbd05033f..a3ef94c834 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/cloning_machine.yml @@ -1,6 +1,6 @@ - type: entity id: CloningPod - parent: BaseMachinePowered + parent: [ BaseMachinePowered, BaseConstructibleMachineDestructible ] name: cloning pod description: A Cloning Pod. 50% reliable. components: @@ -32,21 +32,14 @@ - clonepod-bodyContainer - type: Damageable damageModifierSet: StrongMetallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 100 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Machine board: CloningPodMachineCircuitboard - type: MaterialStorage diff --git a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml index 9da9c5932b..bf2e5a3f62 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/fatextractor.yml @@ -1,6 +1,6 @@ - type: entity id: FatExtractor - parent: BaseMachinePowered + parent: [ BaseMachinePowered, BaseMachineDestructible ] name: lipid extractor description: Safely and efficiently extracts excess fat from a subject. components: @@ -77,21 +77,14 @@ - entity_storage - type: Damageable damageModifierSet: StructuralMetallicStrong - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 100 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Machine board: FatExtractorMachineCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml index 3d1465993d..22c65d0e2d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/fax_machine.yml @@ -14,7 +14,7 @@ - state: printing map: [ "printing" ] visible: false - - state: + - state: map: [ "enum.FaxMachineVisuals.VisualState" ] - type: Icon sprite: Structures/Machines/fax_machine.rsi @@ -33,6 +33,16 @@ - TabletopMachineMask layer: - TabletopMachineLayer + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + - !type:DoActsBehavior + acts: ["Destruction"] - type: ActivatableUI key: enum.FaxUiKey.Key - type: ActivatableUIRequiresPower @@ -89,7 +99,7 @@ suffix: CentCom components: - type: Sprite - layers: + layers: - state: icon color: "#bfe3ff" - state: idle @@ -97,7 +107,7 @@ - state: printing map: [ "printing" ] visible: false - - state: + - state: map: [ "enum.FaxMachineVisuals.VisualState" ] - type: FaxMachine name: "Central Command" @@ -110,7 +120,7 @@ suffix: Syndicate components: - type: Sprite - layers: + layers: - state: icon color: "#a3a3a3" - state: idle @@ -118,7 +128,7 @@ - state: printing map: [ "printing" ] visible: false - - state: + - state: map: [ "enum.FaxMachineVisuals.VisualState" ] - type: FaxMachine name: "ERR*?*%!" diff --git a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml index f7f1bcba1b..cc29264fc0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/flatpacker.yml @@ -1,6 +1,6 @@ - type: entity id: MachineFlatpacker - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: Flatpacker 1001 description: An industrial machine used for expediting machine construction across the station. components: @@ -30,6 +30,14 @@ anim: True: { visible: true } False: { visible: false } + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: FlatpackCreator baseMachineCost: Steel: 750 diff --git a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml index 84948f38fb..d78fb6464f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml @@ -81,7 +81,7 @@ price: 5000 - type: entity - parent: [ GravityGenerator, ConstructibleMachine ] + parent: [ GravityGenerator, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: GravityGeneratorMini name: mini gravity generator suffix: Charged @@ -115,18 +115,11 @@ thresholds: - trigger: !type:DamageTrigger - damage: 500 + damage: 175 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:SpawnEntitiesBehavior - spawn: - MachineFrameDestroyed: - min: 1 - max: 1 - type: WiresPanel - type: Machine board: MiniGravityGeneratorCircuitboard diff --git a/Resources/Prototypes/Entities/Structures/Machines/holopad.yml b/Resources/Prototypes/Entities/Structures/Machines/holopad.yml index 5d1d61030d..1348a53418 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/holopad.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/holopad.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: Holopad name: holopad description: "A floor-mounted device for projecting holographic images." @@ -94,15 +94,11 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 175 behaviors: - !type:PlaySoundBehavior sound: - collection: MetalBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] + collection: MetalGlassBreak - type: entity name: long-range holopad diff --git a/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml b/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml index 5ef0deb154..d1ba017bf5 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/hotplate.yml @@ -1,7 +1,7 @@ # heats an entity or solution placed on it - type: entity abstract: true - parent: [ BaseMachinePowered, SmallConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] id: BaseHeaterMachine components: - type: ItemPlacer @@ -22,6 +22,14 @@ - TabletopMachineMask layer: - TabletopMachineLayer + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: ApcPowerReceiver powerLoad: 300 diff --git a/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml b/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml index e69e8ad4dc..0ab1af87a0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/jukebox.yml @@ -1,7 +1,7 @@ - type: entity id: Jukebox name: jukebox - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] description: A machine capable of playing a wide variety of tunes. Enjoyment not guaranteed. components: - type: StationAiWhitelist @@ -37,21 +37,15 @@ layoutId: Jukebox - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 75 + damage: 175 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 2 + - !type:PlaySoundBehavior + sound: + collection: WoodDestroy - type: Physics bodyType: Static - type: Fixtures diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index 4bf527a977..d54236a4a9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -1,6 +1,6 @@ - type: entity id: BaseLathe - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] abstract: true name: lathe components: @@ -23,15 +23,11 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: WiresPanel - type: ActivatableUI key: enum.LatheUiKey.Key diff --git a/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml b/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml index e1223ed614..30b8e551bb 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/mail_teleporter.yml @@ -1,6 +1,6 @@ - type: entity id: CargoMailTeleporter - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: mail teleporter description: Periodically teleports in mail to deliver across the station. components: @@ -29,8 +29,6 @@ map: [ "enum.PowerDeviceVisualLayers.Powered" ] - type: Damageable damageModifierSet: StructuralMetallicStrong - - type: Injurable - damageContainer: StructuralInorganic - type: ApcPowerReceiver powerLoad: 1000 - type: Appearance diff --git a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml index 79aa7c2747..f3dbe73461 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/medical_scanner.yml @@ -1,6 +1,6 @@ - type: entity id: MedicalScanner - parent: BaseMachinePowered + parent: [ BaseMachinePowered, BaseConstructibleMachineDestructible ] name: medical scanner description: A bulky medical scanner. components: @@ -52,21 +52,15 @@ machine_parts: !type:Container - type: Damageable damageModifierSet: StrongMetallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Machine board: MedicalScannerMachineCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml index df8a924dd2..18d05f6d2b 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/microwave.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/microwave.yml @@ -1,6 +1,6 @@ - type: entity id: KitchenMicrowave - parent: [ BaseMachinePowered, SmallConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] name: microwave description: It's magic. components: @@ -79,17 +79,12 @@ - type: Destructible thresholds: - trigger: # Excess damage, don't spawn entities - !type:DamageTrigger - damage: 200 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - trigger: !type:DamageTrigger damage: 100 behaviors: - - !type:DoActsBehavior - acts: ["Breakage"] + - !type:PlaySoundBehavior + sound: + collection: MetalGlassBreak - type: Explosive explosionType: Default maxIntensity: 10 diff --git a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml index 213e6df5ea..bbfb2c2d80 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/reagent_grinder.yml @@ -1,6 +1,6 @@ - type: entity id: KitchenReagentGrinder - parent: [ BaseMachinePowered, SmallConstructibleMachine ] + parent: [ BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] name: reagent grinder description: From BlenderTech. Will It Blend? Let's find out! components: @@ -39,6 +39,14 @@ - TabletopMachineMask layer: - TabletopMachineLayer + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 100 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: Sprite sprite: Structures/Machines/grinder.rsi drawdepth: LargeObjects diff --git a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml index dad4176617..c095e8fad0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/salvage.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/salvage.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: SalvageMagnet name: salvage magnet description: Pulls in salvage. diff --git a/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml b/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml index ec07294bfb..6572e86da6 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/seed_extractor.yml @@ -1,7 +1,7 @@ - type: entity id: SeedExtractor name: seed extractor - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] description: Extracts seeds from produce. components: - type: Sprite @@ -25,6 +25,14 @@ - MachineMask layer: - MachineLayer + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml index a99c3fdaf1..0832a62b67 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/smartfridge.yml @@ -1,5 +1,5 @@ - type: entity - parent: [BaseStructureDynamic, ConstructibleMachine, BaseMachinePowered] + parent: [BaseStructureDynamic, ConstructibleMachine, BaseMachinePowered, BaseConstructibleMachineDestructible] id: SmartFridge name: SmartFridge description: A refrigerated storage unit for keeping items cold and fresh. @@ -98,21 +98,14 @@ - type: InteractionOutline - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - !type:PlaySoundBehavior sound: - collection: MetalBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] + collection: MetalGlassBreak - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: DamageOnHighSpeedImpact damage: types: diff --git a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml index 626c42213f..a47b5cacdc 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/stasisbed.yml @@ -1,7 +1,7 @@ - type: entity id: StasisBed name: stasis bed - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] description: A bed that massively slows down the patient's metabolism and prevents bodily decay, allowing more time to administer a proper treatment for stabilization. components: - type: StasisBed @@ -31,21 +31,14 @@ - type: ExtensionCableReceiver - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 75 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 2 + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: Strap position: Down rotation: -90 diff --git a/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml b/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml index e94436ef77..f345fa3988 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/surveillance_camera_routers.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: SurveillanceCameraRouterBase name: camera router description: A surveillance camera router. It routes. Perhaps. @@ -33,6 +33,14 @@ enum.PowerDeviceVisualLayers.Powered: True: { visible: true } False: { visible: false } + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: Appearance - type: AmbientOnPowered - type: AmbientSound @@ -134,7 +142,7 @@ - type: entity abstract: true - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: SurveillanceCameraWirelessRouterBase name: wireless camera router description: A wireless surveillance camera router. It routes. Perhaps. @@ -167,6 +175,14 @@ enum.PowerDeviceVisualLayers.Powered: True: { visible: true } False: { visible: false } + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: Appearance - type: AmbientOnPowered - type: AmbientSound diff --git a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml index fcb97f60d9..69e875d945 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/telecomms.yml @@ -1,5 +1,5 @@ - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: TelecomServer name: telecommunication server description: When powered and filled with encryption keys it allows radio headset communication. @@ -158,17 +158,12 @@ - MachineLayer - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 100 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Machine board: TelecomServerCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml index de155db63d..aac88c7fb0 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml @@ -2,7 +2,7 @@ - type: entity id: VendingMachine - parent: BaseMachinePowered + parent: [ BaseMachinePowered, BaseMachineDestructible ] name: vending machine description: Just add capitalism! abstract: true @@ -38,21 +38,17 @@ density: 200 - type: Destructible thresholds: - - trigger: # Excess damage, don't do anything - !type:DamageTrigger - damage: 200 + - trigger: !type:DamageTrigger + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:DoActsBehavior - acts: [ "Destruction" ] - - trigger: - !type:DamageTrigger - damage: 100 + - trigger: !type:DamageTrigger + damage: 75 behaviors: - !type:DoActsBehavior - acts: ["Breakage"] + acts: [ "Breakage" ] - !type:EjectVendorItems - type: Repairable doAfterDelay: 8 diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml index 5c52d6fb88..83a5ef8c03 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml @@ -496,7 +496,7 @@ - AirVent - type: entity - parent: [ BaseMachine, ConstructibleMachine ] + parent: [ BaseMachine, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: GasRecycler name: gas recycler description: Recycles carbon dioxide and nitrous oxide. Heater and compressor not included. @@ -553,15 +553,11 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Machine board: GasRecyclerMachineCircuitboard - type: AtmosMonitoringConsoleDevice diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml index 260c998c5e..7716777560 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml @@ -1,7 +1,7 @@ - type: entity abstract: true parent: BaseItem - id: GasPipeSansLayers + id: GasPipeSansLayersIndestructible name: gas pipe description: Holds gas. placement: @@ -13,15 +13,41 @@ size: Normal - type: Transform anchored: true - - type: Damageable - damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: SubFloorHide - type: CollideOnAnchor - type: Anchorable - type: Rotatable increment: 90 + - type: Sprite + sprite: Structures/Piping/Atmospherics/pipe.rsi + drawdepth: ThinPipe + visible: false + - type: Appearance + - type: PipeAppearance + - type: PipeColorVisuals + - type: NodeContainer + - type: PipeRestrictOverlap + - type: AtmosUnsafeUnanchor + - type: AtmosPipeColor + - type: AtmosMonitoringConsoleDevice + - type: Tag + tags: + - Pipe + - type: Physics + canCollide: false + bodyType: static + - type: StaticPrice + price: 30 + +- type: entity + abstract: true + parent: GasPipeSansLayersIndestructible + id: GasPipeSansLayers + components: + - type: Damageable + damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: # for nukes @@ -47,31 +73,10 @@ offset: 0 - !type:DoActsBehavior acts: ["Breakage"] - - type: Sprite - sprite: Structures/Piping/Atmospherics/pipe.rsi - drawdepth: ThinPipe - visible: false - - type: Appearance - - type: PipeAppearance - - type: PipeColorVisuals - - type: NodeContainer - - type: PipeRestrictOverlap - - type: AtmosUnsafeUnanchor - - type: AtmosPipeColor - - type: AtmosMonitoringConsoleDevice - - type: Tag - tags: - - Pipe - - type: Physics - canCollide: false - bodyType: static - - type: StaticPrice - price: 30 - type: entity abstract: true - parent: GasPipeSansLayers - id: GasPipeBase + id: BaseGasPipeLayers components: - type: AtmosPipeLayers spriteLayersRsiPaths: @@ -80,6 +85,11 @@ Secondary: Structures/Piping/Atmospherics/pipe_alt1.rsi Tertiary: Structures/Piping/Atmospherics/pipe_alt2.rsi +- type: entity + abstract: true + parent: [ GasPipeSansLayers, BaseGasPipeLayers ] + id: GasPipeBase + #Note: The PipeDirection of the PipeNode should be the south-facing version, because the entity starts at an angle of 0 (south) - type: entity @@ -301,7 +311,7 @@ - type: entity id: GasPipeBroken - parent: GasPipeBase + parent: [ GasPipeSansLayersIndestructible, BaseGasPipeLayers ] name: broken pipe description: It used to hold gas. components: @@ -319,8 +329,12 @@ node: broken - type: Item size: Small + - type: Damageable + damageModifierSet: Metallic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible - thresholds: # override parent to avoid recursive destruction + thresholds: - trigger: !type:DamageTrigger damage: 100 diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml index 8b9bf5e7cc..665e663d61 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/portable.yml @@ -1,6 +1,6 @@ - type: entity id: PortableScrubber - parent: [BaseMachinePowered, SmallConstructibleMachine, StructureWheeled] + parent: [BaseMachinePowered, SmallConstructibleMachine, StructureWheeled, BaseSmallConstructibleMachineDestructible] name: portable scrubber description: It scrubs, portably! components: @@ -69,34 +69,22 @@ board: PortableScrubberMachineCircuitBoard - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 300 + damage: 100 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 3 - SheetGlass1: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: GuideHelp guides: - PortableScrubber - type: entity id: SpaceHeater - parent: [BaseMachinePowered, ConstructibleMachine] + parent: [BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible] name: space heater description: A bluespace technology device that alters local temperature. Commonly referred to as a "Space Heater". suffix: Unanchored @@ -155,24 +143,15 @@ atmospheric: true - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 300 + damage: 175 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 3 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: GuideHelp guides: - Thermomachines diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml index 72936097dc..ea2c874236 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml @@ -213,7 +213,7 @@ - AirInjector - type: entity - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] id: BaseGasThermoMachine name: thermomachine abstract: true @@ -388,7 +388,7 @@ board: HellfireHeaterMachineCircuitBoard - type: entity - parent: [ SolutionTank, SolutionHuge, BaseMachinePowered, SmallConstructibleMachine ] + parent: [ SolutionTank, SolutionHuge, BaseMachinePowered, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible ] id: BaseGasCondenser name: condenser description: Condenses gases into liquids. Now we just need some plumbing. @@ -445,8 +445,6 @@ !type:DamageTrigger damage: 100 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpillBehavior solution: tank - !type:PlaySoundBehavior diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml index 4c3c3749eb..fb2f17b657 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/generators.yml @@ -6,8 +6,6 @@ id: BaseGenerator description: A high efficiency thermoelectric generator. name: generator - placement: - mode: SnapgridCenter components: - type: AmbientSound range: 5 @@ -226,28 +224,67 @@ # RTG - no fuel requirement - type: entity - parent: BaseGenerator + abstract: true + parent: BaseMachine + id: BaseRTG + components: + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.4,-0.5,0.4,0.3" + density: 190 + mask: + - MachineMask + layer: + - MachineLayer + - type: PowerSupplier + supplyRate: 10000 # supposed to be low power at no fuel cost to power derelicts + supplyRampRate: 500 + supplyRampTolerance: 500 + - type: AmbientSound + range: 5 + sound: + path: /Audio/Ambience/Objects/buzzing.ogg + - type: Sprite + sprite: Structures/Power/Generation/rtg.rsi + snapCardinals: true + - type: PowerMonitoringDevice + group: Generator + loadNode: output + sprite: Structures/Power/Generation/rtg.rsi + - type: NodeContainer + examinable: true + nodes: + output: + !type:CableDeviceNode + nodeGroupID: HVPower + - type: PacifismDangerousAttack + - type: StaticPrice + price: 500 + - type: Electrified + onHandInteract: false + onInteractUsing: false + onBump: false + requirePower: true + highVoltageNode: output + - type: GuideHelp + guides: + - RTG + - Power + +- type: entity + parent: BaseRTG id: GeneratorRTG name: RTG description: A Radioisotope Thermoelectric Generator for long term power. suffix: 10kW components: - - type: PowerSupplier - supplyRate: 10000 # supposed to be low power at no fuel cost to power derelicts - type: Sprite - sprite: Structures/Power/Generation/rtg.rsi state: rtg - type: PowerMonitoringDevice - sprite: Structures/Power/Generation/rtg.rsi state: rtg - - type: AmbientSound - range: 5 - sound: - path: /Audio/Ambience/Objects/buzzing.ogg - - type: GuideHelp - guides: - - RTG - - Power - type: Destructible thresholds: - trigger: @@ -258,6 +295,7 @@ sound: collection: MetalBreak - !type:SpawnEntitiesBehavior + offset: 0 spawn: GeneratorRTGDamaged: min: 1 @@ -268,21 +306,17 @@ # TODO: need radioactive fallout when destroyed - type: entity - parent: GeneratorRTG + parent: BaseRTG id: GeneratorRTGDamaged name: damaged RTG description: A Radioisotope Thermoelectric Generator for long term power. This one has damaged shielding. suffix: 10kW components: - - type: PowerSupplier - supplyRate: 10000 - type: Sprite - sprite: Structures/Power/Generation/rtg.rsi layers: - state: rtg_damaged - state: rtg_glow - type: PowerMonitoringDevice - sprite: Structures/Power/Generation/rtg.rsi state: rtg_damaged - type: RadiationSource # ideally only when opened. intensity: 2 diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml index a685a5e779..8a1f90677f 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/portable_generator.yml @@ -6,7 +6,7 @@ - type: entity abstract: true id: PortableGeneratorBase - parent: [ BaseMachine, SmallConstructibleMachine, StructureWheeled] + parent: [ BaseMachine, SmallConstructibleMachine, StructureWheeled, BaseSmallConstructibleMachineDestructible] components: # Basic properties - type: Transform @@ -64,10 +64,6 @@ - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: GuideHelp guides: - PortableGenerator @@ -332,13 +328,6 @@ behaviors: - !type:SpillBehavior solution: tank - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - trigger: !type:DamageTypeTrigger damageType: Piercing diff --git a/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml b/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml index dc537c35c2..1a2218788c 100644 --- a/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml +++ b/Resources/Prototypes/Entities/Structures/Power/Generation/teg.yml @@ -2,7 +2,7 @@ id: TegCenter name: thermo-electric generator description: A high efficiency generator that uses energy transfer between hot and cold gases to produce electricity. - parent: BaseMachinePowered + parent: [ BaseMachinePowered, BaseMachineDestructible ] placement: mode: SnapgridCenter components: @@ -109,7 +109,7 @@ id: TegCirculator name: circulator description: Passes gas through the thermo-electric generator to exchange heat. Has an inlet and outlet port. - parent: BaseMachine + parent: [ BaseMachine, BaseMachineDestructible ] placement: mode: SnapgridCenter components: diff --git a/Resources/Prototypes/Entities/Structures/Power/cables.yml b/Resources/Prototypes/Entities/Structures/Power/cables.yml index 94a51cc0dc..6812163c09 100644 --- a/Resources/Prototypes/Entities/Structures/Power/cables.yml +++ b/Resources/Prototypes/Entities/Structures/Power/cables.yml @@ -91,8 +91,6 @@ CableHVStack1: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: CableVisualizer statePrefix: hvcable_ # TODO make this change on power @@ -145,8 +143,6 @@ CableMVStack1: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: CableVisualizer statePrefix: mvcable_ extraLayerPrefix: mvstripes_ @@ -194,8 +190,6 @@ CableApcStack1: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: CableVisualizer statePrefix: lvcable_ diff --git a/Resources/Prototypes/Entities/Structures/Power/chargers.yml b/Resources/Prototypes/Entities/Structures/Power/chargers.yml index 77e4d69ee8..43b9d1975e 100644 --- a/Resources/Prototypes/Entities/Structures/Power/chargers.yml +++ b/Resources/Prototypes/Entities/Structures/Power/chargers.yml @@ -1,6 +1,6 @@ - type: entity abstract: true - parent: [BaseMachinePowered, ConstructibleMachine] + parent: [BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible] id: BaseRecharger placement: mode: SnapgridCenter @@ -21,11 +21,9 @@ thresholds: - trigger: !type:DamageTrigger - damage: 40 + damage: 175 behaviors: - !type:EmptyAllContainersBehaviour - - !type:DoActsBehavior - acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Power/smes.yml b/Resources/Prototypes/Entities/Structures/Power/smes.yml index 612947af07..d8e6f5a305 100644 --- a/Resources/Prototypes/Entities/Structures/Power/smes.yml +++ b/Resources/Prototypes/Entities/Structures/Power/smes.yml @@ -2,7 +2,7 @@ - type: entity abstract: true id: BaseSMES - parent: [ BaseMachine, ConstructibleMachine ] + parent: [ BaseMachine, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: SMES description: A high-capacity superconducting magnetic energy storage (SMES) unit. placement: @@ -87,8 +87,14 @@ mediumVoltageNode: output - type: Damageable damageModifierSet: StructuralMetallicStrong - - type: Injurable - damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: BatterySensor - type: DeviceNetwork deviceNetId: AtmosDevices diff --git a/Resources/Prototypes/Entities/Structures/Power/substation.yml b/Resources/Prototypes/Entities/Structures/Power/substation.yml index 786621ee5d..d868e1bc9d 100644 --- a/Resources/Prototypes/Entities/Structures/Power/substation.yml +++ b/Resources/Prototypes/Entities/Structures/Power/substation.yml @@ -74,7 +74,7 @@ - type: entity abstract: true id: BaseSubstation - parent: [ CoreSubstation, BaseMachine, ConstructibleMachine ] + parent: [ CoreSubstation, BaseMachine, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: substation description: Reduces the voltage of electricity put into it. placement: @@ -104,19 +104,12 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 175 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - !type:ExplodeBehavior - - !type:SpawnEntitiesBehavior - spawn: - MachineFrameDestroyed: - min: 1 - max: 1 - !type:SpawnGasBehavior gasMixture: volume: 1000 diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml b/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml index df0c803ea1..0a613da695 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/cannons.yml @@ -41,7 +41,7 @@ - type: entity id: ShuttleGunSvalinnMachineGun - parent: [ ShuttleGunBase, ConstructibleMachine] + parent: [ ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] name: LSE-400c "Svalinn machine gun" description: Basic stationary laser unit. Effective against live targets and electronics. Uses regular power cells to fire, and has an extremely high rate of fire. categories: [ DoNotMap ] @@ -58,16 +58,6 @@ machine_board: !type:Container machine_parts: !type:Container cell_slot: !type:ContainerSlot - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 150 - behaviors: - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Gun fireRate: 5 useKey: false @@ -99,7 +89,7 @@ - type: entity id: ShuttleGunPerforator - parent: [ ShuttleGunBase, ConstructibleMachine] + parent: [ ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] name: LSE-1200c "Perforator" description: Advanced stationary laser unit. Annihilates electronics and is extremely dangerous to health! Uses the power cage to fire. categories: [ DoNotMap ] @@ -116,16 +106,6 @@ machine_board: !type:Container machine_parts: !type:Container cell_slot: !type:ContainerSlot - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 300 - behaviors: - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Gun fireRate: 1 soundGunshot: @@ -159,7 +139,7 @@ - type: entity id: ShuttleGunFriendship - parent: [ShuttleGunBase, ConstructibleMachine] + parent: [ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] name: EXP-320g "Friendship" description: A small stationary grenade launcher that holds 2 grenades. categories: [ DoNotMap ] @@ -175,16 +155,6 @@ machine_board: !type:Container machine_parts: !type:Container ballistic-ammo: !type:Container - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 200 - behaviors: - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Gun projectileSpeed: 80 fireRate: 1 @@ -213,7 +183,7 @@ - type: entity id: ShuttleGunDuster - parent: [ShuttleGunBase, ConstructibleMachine] + parent: [ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] name: EXP-2100g "Duster" description: A powerful stationary grenade launcher. A cartridge is required for use. categories: [ DoNotMap ] @@ -229,16 +199,6 @@ machine_board: !type:Container machine_parts: !type:Container gun_magazine: !type:ContainerSlot - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 350 - behaviors: - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Gun projectileSpeed: 40 fireRate: 0.3 @@ -312,7 +272,7 @@ - type: entity id: ShuttleGunKinetic - parent: [ ShuttleGunBase, ConstructibleMachine] + parent: [ ShuttleGunBase, ConstructibleMachine, BaseConstructibleMachineDestructible] name: PTK-800 "Matter Dematerializer" description: Salvage stationary mining turret. Gradually accumulates charges on its own, extremely effective for asteroid excavation. categories: [ DoNotMap ] @@ -326,16 +286,6 @@ containers: machine_board: !type:Container machine_parts: !type:Container - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:ChangeConstructionNodeBehavior - node: machineFrame - - !type:DoActsBehavior - acts: ["Destruction"] - type: Gun projectileSpeed: 20 fireRate: 2 diff --git a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml index 2b2418816a..d42f2f2887 100644 --- a/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml +++ b/Resources/Prototypes/Entities/Structures/Shuttles/thrusters.yml @@ -40,21 +40,6 @@ - type: ApcPowerReceiver powerLoad: 1500 - type: ExtensionCableReceiver - - type: Damageable - damageModifierSet: Electronic - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 300 # Changed 100->300 because impact damage is real - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: StaticPrice price: 300 - type: GuideHelp @@ -68,11 +53,15 @@ components: - type: Machine board: ThrusterMachineCircuitboard + - type: Damageable + damageModifierSet: Electronic + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 300 + damage: 300 # Changed 100->300 because impact damage is real behaviors: - !type:DoActsBehavior acts: ["Destruction"] @@ -114,7 +103,7 @@ - type: entity id: ThrusterLarge name: large thruster - parent: [ BaseThruster] + parent: BaseThruster placement: mode: AlignTileAny components: @@ -206,7 +195,7 @@ - type: entity id: Gyroscope - parent: [ BaseThruster, ConstructibleMachine ] + parent: [ BaseThruster, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: gyroscope description: Increases the shuttle's potential angular rotation. components: @@ -247,15 +236,11 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 175 behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:ChangeConstructionNodeBehavior - node: machineFrame - type: Damageable damageModifierSet: Electronic - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml index f1439caedf..d31e94ede5 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Canisters/gas_canisters.yml @@ -69,18 +69,13 @@ type: GasCanisterBoundUserInterface - type: Destructible thresholds: - - trigger: + - trigger: &DamageTrigger300 !type:DamageTrigger damage: 300 behaviors: - !type:PlaySoundBehavior sound: collection: MetalBreak - - !type:SpawnEntitiesBehavior - spawn: - GasCanisterBrokenBase: - min: 1 - max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - !type:DumpCanisterBehavior @@ -221,21 +216,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: AirCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: entity parent: GasCanister @@ -266,21 +253,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: OxygenCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: entity id: LiquidOxygenCanister @@ -326,21 +305,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: NitrogenCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: entity id: LiquidNitrogenCanister @@ -386,21 +357,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: CarbonDioxideCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: Lock locked: true @@ -448,21 +411,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: PlasmaCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: Lock locked: true @@ -495,21 +450,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: TritiumCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: Lock locked: true @@ -542,21 +489,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: WaterVaporCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: entity parent: GasCanister @@ -587,21 +526,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: AmmoniaCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: Lock locked: true @@ -634,21 +565,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: NitrousOxideCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: Lock locked: true @@ -681,21 +604,13 @@ temperature: 293.15 - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 300 + - trigger: *DamageTrigger300 behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - !type:SpawnEntitiesBehavior spawn: FrezonCanisterBroken: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:DumpCanisterBehavior - type: Lock locked: true diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml index 51a7f6058e..9f6de3bc2a 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/base_structurelockers.yml @@ -25,24 +25,6 @@ sprite: Structures/Storage/closet_labels.rsi offset: "-0.065,0" map: ["enum.PaperLabelVisuals.Layer"] - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - params: - volume: -6 - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 2 - type: Construction graph: ClosetSteelSecure node: done @@ -50,12 +32,6 @@ - entity_storage - type: Paintable group: Locker - -- type: entity - id: LockerBaseSecure - parent: LockerBase - abstract: true - components: - type: Damageable damageModifierSet: StructuralMetallic - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml index 93244037cd..755928f6b9 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/Lockers/lockers.yml @@ -23,7 +23,7 @@ # Basic - type: entity id: LockerSteel - parent: LockerBaseSecure + parent: LockerBase name: secure closet components: - type: Appearance @@ -35,7 +35,7 @@ # Cargo - type: entity id: LockerQuarterMaster - parent: LockerBaseSecure + parent: LockerBase name: quartermaster's locker components: - type: Appearance @@ -63,7 +63,7 @@ # Command - type: entity id: LockerCaptain - parent: LockerBaseSecure + parent: LockerBase name: captain's locker components: - type: Appearance @@ -76,7 +76,7 @@ - type: entity id: LockerHeadOfPersonnel - parent: LockerBaseSecure + parent: LockerBase name: head of personnel's locker components: - type: Appearance @@ -90,7 +90,7 @@ # CE - type: entity id: LockerChiefEngineer - parent: LockerBaseSecure + parent: LockerBase name: chief engineer's locker components: - type: Appearance @@ -279,7 +279,7 @@ # CMO - type: entity id: LockerChiefMedicalOfficer - parent: LockerBaseSecure + parent: LockerBase name: chief medical officer's locker components: - type: Appearance @@ -320,7 +320,7 @@ # HoS - type: entity id: LockerHeadOfSecurity - parent: LockerBaseSecure + parent: LockerBase name: head of security's locker components: - type: Appearance @@ -334,7 +334,7 @@ # Warden - type: entity id: LockerWarden - parent: LockerBaseSecure + parent: LockerBase name: warden's locker components: - type: Appearance @@ -348,7 +348,7 @@ # Brigmedic - type: entity id: LockerBrigmedic - parent: LockerBaseSecure + parent: LockerBase name: brigmedic locker components: - type: Appearance @@ -362,7 +362,7 @@ # Security Officer - type: entity id: LockerSecurity - parent: LockerBaseSecure + parent: LockerBase name: security officer's locker components: - type: Appearance @@ -375,7 +375,7 @@ - type: entity id: GunSafe - parent: LockerBaseSecure + parent: LockerBase name: gun safe components: - type: Appearance @@ -427,7 +427,7 @@ isPlaceable: True - type: entity - parent: [ GenpopBase , LockerBaseSecure ] + parent: [ GenpopBase , LockerBase ] id: LockerPrisoner name: prisoner closet description: It's a secure locker for an inmate's personal belongings during their time in prison. @@ -535,7 +535,7 @@ - type: entity id: LockerSyndicatePersonal name: blood-red locker - parent: LockerBaseSecure + parent: LockerBase description: It's a personal storage unit with a blood-red design. suffix: "Locked" components: @@ -549,7 +549,7 @@ # Bluespace - type: entity - parent: LockerBaseSecure + parent: LockerBase id: LockerBluespaceStation name: bluespace locker description: Advanced locker technology. @@ -583,7 +583,7 @@ - type: entity id: LockerClown name: clown locker - parent: LockerBaseSecure + parent: LockerBase components: - type: Appearance - type: AccessReader @@ -597,7 +597,7 @@ - type: entity id: LockerMime name: mime locker - parent: LockerBaseSecure + parent: LockerBase components: - type: Appearance - type: AccessReader @@ -611,7 +611,7 @@ - type: entity id: LockerRepresentative name: representative locker - parent: LockerBaseSecure + parent: LockerBase components: - type: Appearance - type: AccessReader diff --git a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml index 4a84b69a09..42e45502ca 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Closets/base_structureclosets.yml @@ -53,28 +53,6 @@ - type: PlaceableSurface placeCentered: true isPlaceable: false - - type: Damageable - damageModifierSet: StructuralMetallic - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - params: - volume: -6 - - !type:SpawnEntitiesBehavior - spawn: - SheetSteel1: - min: 1 - max: 1 - type: GenericVisualizer visuals: enum.PaperLabelVisuals.HasLabel: @@ -110,6 +88,28 @@ - entity_storage - type: Paintable group: Closet + - type: Damageable + damageModifierSet: StructuralMetallic + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - !type:PlaySoundBehavior + sound: + collection: MetalBreak + params: + volume: -6 + - !type:SpawnEntitiesBehavior + spawn: + SheetSteel1: + min: 1 + max: 1 #Wall Closet - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml index b571b7b287..e9a9220d3b 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Crates/base_structurecrates.yml @@ -1,30 +1,15 @@ - type: entity + abstract: true parent: [ BaseStructureDynamic, BasePaperLabelableVisualized ] - id: CrateGeneric - categories: [ HideSpawnMenu ] + id: BaseCrate name: crate description: A large container for items. components: - type: Animateable - type: Transform noRot: true - - type: Icon - sprite: Structures/Storage/Crates/generic.rsi - state: icon - type: Sprite noRot: true - sprite: Structures/Storage/Crates/generic.rsi - layers: - - state: base - map: ["enum.StorageVisualLayers.Base"] - - state: closed - map: ["enum.StorageVisualLayers.Door"] - - state: welded - visible: false - map: ["enum.WeldableLayers.BaseWelded"] - - state: paper - sprite: Structures/Storage/Crates/labels.rsi - map: ["enum.PaperLabelVisuals.Layer"] - type: InteractionOutline - type: Physics - type: Fixtures @@ -41,6 +26,38 @@ - type: EntityStorage - type: PlaceableSurface isPlaceable: false # defaults to closed. + - type: EntityStorageVisuals + stateDoorOpen: open + stateDoorClosed: closed + - type: ContainerContainer + containers: + entity_storage: !type:Container + paper_label: !type:ContainerSlot + - type: StaticPrice + price: 75 + - type: RequireProjectileTarget + +- type: entity + parent: BaseCrate + id: CrateGeneric + categories: [ HideSpawnMenu ] + components: + - type: Icon + sprite: Structures/Storage/Crates/generic.rsi + state: icon + - type: Sprite + sprite: Structures/Storage/Crates/generic.rsi + layers: + - state: base + map: ["enum.StorageVisualLayers.Base"] + - state: closed + map: ["enum.StorageVisualLayers.Door"] + - state: welded + visible: false + map: ["enum.WeldableLayers.BaseWelded"] + - state: paper + sprite: Structures/Storage/Crates/labels.rsi + map: ["enum.PaperLabelVisuals.Layer"] - type: Damageable damageModifierSet: Metallic - type: Injurable @@ -56,21 +73,11 @@ - !type:PlaySoundBehavior sound: collection: MetalBreak - - type: EntityStorageVisuals - stateDoorOpen: open - stateDoorClosed: closed - - type: ContainerContainer - containers: - entity_storage: !type:Container - paper_label: !type:ContainerSlot - - type: StaticPrice - price: 75 - type: Construction graph: CrateGenericSteel node: crategenericsteel containers: - - entity_storage - - type: RequireProjectileTarget + - entity_storage - type: entity parent: CrateGeneric @@ -109,19 +116,6 @@ map: ["enum.PaperLabelVisuals.Layer"] - type: Damageable damageModifierSet: StructuralMetallic - - type: Injurable - damageContainer: StructuralInorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 75 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: Construction graph: CrateSecure node: cratesecure diff --git a/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml b/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml index d7eb050100..728dedec89 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Crates/crates.yml @@ -138,12 +138,13 @@ sprite: Structures/Storage/Crates/surgery.rsi - type: entity - parent: CrateGeneric + parent: BaseCrate id: CrateWeb name: web crate components: - type: Icon sprite: Structures/Storage/Crates/web.rsi + state: icon - type: Sprite sprite: Structures/Storage/Crates/web.rsi layers: @@ -157,8 +158,12 @@ - type: Construction graph: WebStructures node: crate + containers: + - entity_storage - type: Damageable damageModifierSet: Web + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -190,6 +195,7 @@ components: - type: Icon sprite: Structures/Storage/Crates/sec_gear.rsi + state: icon - type: Sprite sprite: Structures/Storage/Crates/sec_gear.rsi - type: AccessReader @@ -337,7 +343,7 @@ access: [["SyndicateAgent", "NuclearOperative"]] - type: entity - parent: CrateGeneric + parent: BaseCrate id: CrateLivestock name: livestock crate components: @@ -356,6 +362,9 @@ - type: Icon sprite: Structures/Storage/Crates/livestock.rsi state: base + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -394,7 +403,7 @@ price: 125 - type: entity - parent: CrateGeneric + parent: BaseCrate id: CrateRodentCage name: hamster cage components: @@ -412,6 +421,10 @@ map: ["enum.PaperLabelVisuals.Layer"] - type: Icon sprite: Structures/Storage/Crates/cage.rsi + state: icon + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -689,7 +702,7 @@ state: crate_icon - type: entity - parent: CrateGeneric + parent: BaseCrate id: CrateCoffin name: coffin description: A comfy coffin, excellent place for the vampires and corpses. @@ -705,6 +718,9 @@ - type: Icon sprite: Structures/Storage/Crates/coffin.rsi state: base + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -728,7 +744,7 @@ - entity_storage - type: entity - parent: CrateGeneric + parent: BaseCrate id: CrateWoodenGrave name: grave suffix: wooden @@ -747,6 +763,9 @@ - type: Icon sprite: Structures/Storage/Crates/wooden_grave.rsi state: base + - type: Damageable + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml index d9d025a86f..9e781e3948 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/Tanks/base_structuretanks.yml @@ -1,9 +1,9 @@ - type: entity - id: StorageTank + abstract: true parent: [SolutionTank, SolutionGinormous, BaseStructureDynamic] + id: StorageTankIndestructible name: storage tank description: A liquids storage tank. - abstract: true components: - type: Animateable - type: Sprite @@ -22,6 +22,19 @@ layer: - MachineLayer - InteractImpassable + - type: DrainableSolution + solution: tank + - type: ReagentTank + - type: Transform + noRot: true + +- type: entity + abstract: true + parent: StorageTankIndestructible + id: StorageTank + name: storage tank + description: A liquids storage tank. + components: - type: Damageable damageModifierSet: Metallic - type: Injurable @@ -53,11 +66,6 @@ collection: MetalBreak - !type:DoActsBehavior acts: ["Destruction"] - - type: DrainableSolution - solution: tank - - type: ReagentTank - - type: Transform - noRot: true # For highcap tanks - type: entity diff --git a/Resources/Prototypes/Entities/Structures/Storage/barrels.yml b/Resources/Prototypes/Entities/Structures/Storage/barrels.yml index 195e502ae3..84c350a4ee 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/barrels.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/barrels.yml @@ -1,5 +1,5 @@ - type: entity - parent: StorageTank + parent: StorageTankIndestructible id: BaseBarrelChem abstract: true name: chemical barrel diff --git a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml index ca7de0e1bb..6e1582c26d 100644 --- a/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml +++ b/Resources/Prototypes/Entities/Structures/Storage/glass_box.yml @@ -201,16 +201,8 @@ !type:DamageTrigger damage: 100 behaviors: - - !type:PlaySoundBehavior - sound: - collection: WoodDestroy - !type:SpawnEntitiesBehavior spawn: ShardGlassReinforced: min: 1 max: 1 - MaterialWoodPlank1: - min: 2 - max: 5 - - !type:DoActsBehavior - acts: ["Destruction"] diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml index 2a55a4ee04..36aa4dd643 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Signs/posters.yml @@ -7,19 +7,15 @@ sprite: Structures/Wallmounts/posters.rsi - type: Damageable damageModifierSet: Card - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: !type:DamageTrigger - damage: 15 + damage: 5 behaviors: - !type:PlaySoundBehavior sound: path: /Audio/Effects/poster_broken.ogg - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:SpawnEntitiesBehavior spawn: PosterBroken: @@ -51,8 +47,6 @@ - !type:PlaySoundBehavior sound: path: /Audio/Effects/poster_broken.ogg - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Construction graph: PosterGraph node: tornPoster diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml index a0ec0e8218..3ffa500b92 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/Storage/shelfs.yml @@ -1,8 +1,8 @@ # Parents - type: entity + abstract: true parent: BaseWallmount id: ShelfBase - abstract: true name: shelf description: A strange place to place, well, anything really. You feel like you shouldn't be seeing this. components: @@ -11,18 +11,14 @@ sprite: Structures/Storage/Shelfs/wood.rsi state: base - type: Damageable - damageModifierSet: Wood - type: Injurable damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: + - trigger: &DamageTrigger50 !type:DamageTrigger - damage: 60 + damage: 50 behaviors: - - !type:PlaySoundBehavior - sound: - collection: WoodDestroyHeavy - !type:DoActsBehavior acts: ["Destruction"] - type: Storage @@ -40,8 +36,8 @@ - type: entity abstract: true - id: ShelfBaseReinforced parent: ShelfBase + id: ShelfBaseReinforced name: reinforced shelf description: It looks as strong as reality itself. components: @@ -70,16 +66,14 @@ # Normal - type: entity - id: ShelfWood parent: ShelfBase + id: ShelfWood name: wooden shelf description: A convenient place to place, well, anything really. components: - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 60 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -89,8 +83,6 @@ MaterialWoodPlank1: min: 1 max: 3 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Tag tags: - Structure @@ -100,8 +92,8 @@ node: ShelfWood - type: entity - id: ShelfMetal parent: ShelfBase + id: ShelfMetal name: metal shelf description: A sturdy place to place, well, anything really. components: @@ -110,13 +102,9 @@ state: base - type: Damageable damageModifierSet: Metallic - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 120 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -126,15 +114,13 @@ SheetSteel1: min: 2 max: 4 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfMetal - type: entity - id: ShelfGlass parent: ShelfBase + id: ShelfGlass name: glass shelf description: A fragile place to place, well, anything really. components: @@ -143,13 +129,9 @@ state: base - type: Damageable damageModifierSet: Glass - - type: Injurable - damageContainer: StructuralInorganic - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 50 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -159,16 +141,14 @@ ShardGlass: min: 0 max: 2 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfGlass # Reinforced - type: entity - id: ShelfRWood parent: ShelfBaseReinforced + id: ShelfRWood name: sturdy wood shelf description: A safe place to put your favorite bottle of whiskey. components: @@ -185,9 +165,7 @@ shader: unshaded - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 215 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -197,15 +175,13 @@ MaterialWoodPlank: min: 2 max: 5 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfRWood - type: entity - id: ShelfRMetal parent: ShelfBaseReinforced + id: ShelfRMetal name: sturdy metal shelf description: A strong & shiny place to keep all your vials safe. components: @@ -213,9 +189,7 @@ sprite: Structures/Storage/Shelfs/metal.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 450 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -231,15 +205,13 @@ PartRodMetal1: min: 1 max: 2 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfRMetal - type: entity - id: ShelfRGlass parent: ShelfBaseReinforced + id: ShelfRGlass name: sturdy glass shelf description: Crystal clear reinforced glass doors to show off all your fancy bottles you definitely didn't sell a co-worker's favorite mothroach for. components: @@ -247,9 +219,7 @@ sprite: Structures/Storage/Shelfs/glass.rsi - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 250 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -265,16 +235,14 @@ PartRodMetal1: min: 0 max: 1 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Construction graph: Shelf node: ShelfRGlass # Departmental - type: entity - id: ShelfBar parent: ShelfBase + id: ShelfBar name: bar shelf description: Made out of the finest synthetic wood for all alcohol holding needs. components: @@ -291,9 +259,7 @@ fillBaseName: bar - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 100 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -303,8 +269,6 @@ MaterialWoodPlank1: min: 1 max: 4 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Storage grid: - 0,0,5,1 @@ -314,8 +278,8 @@ node: ShelfBar - type: entity - id: ShelfKitchen parent: ShelfBase + id: ShelfKitchen name: kitchen shelf description: Holds knifes, spice, and everything nice! components: @@ -332,9 +296,7 @@ fillBaseName: kitchen - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 150 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: @@ -350,8 +312,6 @@ PartRodMetal1: min: 0 max: 2 - - !type:DoActsBehavior - acts: ["Destruction"] - type: Storage grid: - 0,0,5,1 @@ -361,8 +321,8 @@ node: ShelfKitchen - type: entity - id: ShelfChemistry parent: ShelfBaseReinforced + id: ShelfChemistry name: chemical shelf description: Keeps all your chemicals safe and out of the clow- er, public hands! components: @@ -385,9 +345,7 @@ fillBaseName: chem - type: Destructible thresholds: - - trigger: - !type:DamageTrigger - damage: 330 + - trigger: *DamageTrigger50 behaviors: - !type:PlaySoundBehavior sound: diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml index 1b16c3361c..f6df92a552 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/WallmountMachines/station_map.yml @@ -77,6 +77,7 @@ sound: collection: GlassBreak - !type:SpawnEntitiesBehavior + offset: 0 spawn: StationMapBroken: min: 1 diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index f2c7570589..7865aae4e3 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -3,12 +3,9 @@ # Anyway # See WallRock variants for the remappings. -#Asteroid rock - type: entity - id: AsteroidRock parent: BaseWall - name: asteroid rock - description: A rocky asteroid. + id: BaseAsteroidRock components: - type: Transform noRot: true @@ -36,6 +33,25 @@ damageModifierSet: Rock - type: Injurable damageContainer: StructuralInorganic + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 2000 + +#Asteroid rock +- type: entity + parent: BaseAsteroidRock + id: AsteroidRock + name: asteroid rock + description: A rocky asteroid. + components: - type: Destructible thresholds: - trigger: @@ -49,17 +65,6 @@ path: /Audio/Effects/break_stone.ogg params: volume: -6 - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - mask: - - FullTileMask - layer: - - WallLayer - density: 2000 - type: entity abstract: true diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml index 2eb003555c..c418a97c9f 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_metal.yml @@ -33,8 +33,8 @@ - !type:SpawnEntitiesBehavior spawn: PartRodMetal1: - min: 3 - max: 5 + min: 1 + max: 2 - !type:DoActsBehavior acts: [ "Destruction" ] - type: Climbable @@ -108,22 +108,6 @@ messagePerceivedByOthers: fence-rattle-success interactSuccessSound: collection: FenceRattle - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - - !type:SpawnEntitiesBehavior - spawn: - PartRodMetal1: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Construction graph: FenceMetal node: broken @@ -165,20 +149,10 @@ thresholds: - trigger: !type:DamageTrigger - damage: 100 + damage: 150 behaviors: - - !type:PlaySoundBehavior - sound: - path: /Audio/Items/wirecutter.ogg - - !type:SpawnEntitiesBehavior - spawn: - PartRodMetal1: - min: 2 - max: 4 - !type:ChangeConstructionNodeBehavior node: broken - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Construction graph: FenceMetal node: straight diff --git a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml index e5dbfe5b24..30848256eb 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/fence_wood.yml @@ -1,9 +1,9 @@ - type: entity + abstract: true parent: BaseStructure id: BaseFenceWood name: wooden fence description: Wooden piece of fencing. I hope there is babushka's garden behind it. - abstract: true components: - type: MeleeSound soundGroups: @@ -28,6 +28,15 @@ cost: 2 delay: 2 fx: EffectRCDDeconstruct2 + - type: Climbable + delay: 5.0 + - type: Appearance + +- type: entity + abstract: true + parent: BaseFenceWood + id: BaseFenceWoodHigh + components: - type: Destructible thresholds: - trigger: @@ -44,16 +53,13 @@ max: 2 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Climbable - delay: 5.0 - - type: Appearance - type: entity + abstract: true parent: BaseFenceWood id: BaseFenceWoodSmall name: small wooden fence description: Wooden piece of small fence. The best protection for the fencing of a private territory! - abstract: true components: - type: Destructible thresholds: @@ -75,9 +81,9 @@ delay: 2.5 - type: RequireProjectileTarget -#High +#region High - type: entity - parent: BaseFenceWood + parent: BaseFenceWoodHigh id: FenceWoodHighStraight suffix: Straight components: @@ -106,7 +112,7 @@ node: straight - type: entity - parent: BaseFenceWood + parent: BaseFenceWoodHigh id: FenceWoodHighEnd suffix: End components: @@ -135,7 +141,7 @@ node: end - type: entity - parent: BaseFenceWood + parent: BaseFenceWoodHigh id: FenceWoodHighCorner suffix: Corner components: @@ -173,7 +179,7 @@ node: corner - type: entity - parent: BaseFenceWood + parent: BaseFenceWoodHigh id: FenceWoodHighTJunction suffix: T-Junction components: @@ -211,7 +217,7 @@ node: tjunction - type: entity - parent: BaseFenceWood + parent: BaseFenceWoodHigh id: FenceWoodHighGate name: wooden fence gate description: Do you have any idea what awaits you behind these gates? It can be either a toilet or a luxurious mansion. But you continue to love your emo boys. @@ -258,7 +264,9 @@ graph: FenceWood node: gate -#Small +#endregion +#region Small + - type: entity parent: BaseFenceWoodSmall id: FenceWoodSmallStraight @@ -435,3 +443,5 @@ - type: Construction graph: FenceWood node: gate_small + +#endregion diff --git a/Resources/Prototypes/Entities/Structures/Walls/girders.yml b/Resources/Prototypes/Entities/Structures/Walls/girders.yml index 7acadb48be..2fb1f97fda 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/girders.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/girders.yml @@ -51,8 +51,8 @@ price: 30 - type: entity - id: ReinforcedGirder parent: Girder + id: ReinforcedGirder name: reinforced girder description: A large structural assembly made out of metal and plasteel; It requires a layer of plasteel before it can be considered a reinforced wall. components: @@ -70,23 +70,15 @@ behaviors: - !type:SpawnEntitiesBehavior spawn: - SheetSteel1: - min: 1 - max: 1 SheetPlasteel1: min: 1 max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak - type: StaticPrice price: 130 - type: entity + parent: Girder id: ClockworkGirder - parent: ReinforcedGirder name: wall gear description: A large gear with mounting brackets for additional plating; This could be made into a wall with more brass plating. components: @@ -109,11 +101,3 @@ SheetBrass1: min: 1 max: 2 - PartRodMetal1: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalBreak diff --git a/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml b/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml index a771291bda..a8abdf8131 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/inflatable_wall.yml @@ -43,16 +43,18 @@ mode: SnapgridCenter - type: entity + parent: [ BaseStructure, BaseDeltaPressureGlass ] id: InflatableDoor name: inflatable door - parent: [BaseMaterialDoor, BaseDeltaPressureGlass] description: An inflated membrane. Activate to deflate. Now with a door. Do not puncture. components: - type: Clickable - type: InteractionOutline - type: Sprite sprite: Objects/Misc/inflatable_door.rsi - state: closed + layers: + - state: closed + map: ["enum.DoorVisualLayers.Base"] - type: Physics bodyType: Static - type: Fixtures @@ -65,11 +67,22 @@ layer: - WallLayer - type: Door + bumpOpen: false + clickOpen: true + canCrush: false + closeTimeOne: 0.2 + closeTimeTwo: 0.6 + openTimeOne: 0.6 + openTimeTwo: 0.2 + openingAnimationTime: 1.2 + closingAnimationTime: 1.2 occludes: false openSound: path: /Audio/Misc/zip.ogg closeSound: path: /Audio/Misc/zip.ogg + - type: Appearance + - type: Airtight - type: Damageable damageModifierSet: Inflatable - type: Injurable diff --git a/Resources/Prototypes/Entities/Structures/Walls/meteor.yml b/Resources/Prototypes/Entities/Structures/Walls/meteor.yml index 6f310e3b74..5da5e42230 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/meteor.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/meteor.yml @@ -1,7 +1,7 @@ # These define Meteor Walls separate from Asteroid walls so they have different properties - type: entity + parent: BaseAsteroidRock id: MeteorRock - parent: AsteroidRock name: meteorite rock description: What remains of a meteorite. components: diff --git a/Resources/Prototypes/Entities/Structures/Walls/walls.yml b/Resources/Prototypes/Entities/Structures/Walls/walls.yml index 709796c49c..12cc546cba 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/walls.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/walls.yml @@ -88,10 +88,10 @@ fix1: shape: !type:PolygonShape - vertices: - - "-0.5,-0.5" - - "0.5,0.5" - - "0.5,-0.5" + vertices: + - "-0.5,-0.5" + - "0.5,0.5" + - "0.5,-0.5" mask: - FullTileMask layer: @@ -208,8 +208,8 @@ components: - type: Tag tags: - - Wall - - Structure + - Wall + - Structure - type: Sprite sprite: Structures/Walls/meat.rsi - type: Icon @@ -268,7 +268,7 @@ components: - type: Tag tags: - - Wall + - Wall - type: Sprite sprite: Structures/Walls/debug.rsi - type: Icon @@ -464,30 +464,30 @@ name: plastitanium wall suffix: indestructible components: - - type: Sprite - sprite: Structures/Walls/plastitanium.rsi - - type: Icon - sprite: Structures/Walls/plastitanium.rsi - - type: IconSmooth - key: walls - base: plastitanium - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" - mask: - - FullTileMask - layer: - - WallLayer - density: 4000 - - type: Damageable - damageModifierSet: StructuralMetallicStrong - - type: Injurable - damageContainer: StructuralInorganic - - type: RadiationBlocker - resistance: 5 + - type: Sprite + sprite: Structures/Walls/plastitanium.rsi + - type: Icon + sprite: Structures/Walls/plastitanium.rsi + - type: IconSmooth + key: walls + base: plastitanium + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 4000 + - type: Damageable + damageModifierSet: StructuralMetallicStrong + - type: Injurable + damageContainer: StructuralInorganic + - type: RadiationBlocker + resistance: 5 - type: entity parent: WallPlastitaniumIndestructible @@ -548,16 +548,16 @@ !type:DamageTrigger damage: 1000 behaviors: - - !type:SpawnEntitiesBehavior - spawn: - Girder: - min: 1 - max: 1 - - !type:DoActsBehavior - acts: [ "Destruction" ] - - !type:PlaySoundBehavior - sound: - collection: MetalSlam + - !type:SpawnEntitiesBehavior + spawn: + Girder: + min: 1 + max: 1 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - !type:PlaySoundBehavior + sound: + collection: MetalSlam - type: entity parent: BaseWall @@ -637,19 +637,8 @@ - type: IconSmooth key: walls base: reinf_over - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 350 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalSlam - - !type:ChangeConstructionNodeBehavior - node: girder - - !type:DoActsBehavior - acts: ["Destruction"] + - type: Damageable + damageModifierSet: StructuralMetallic # weaker because rust - type: entity parent: WallDiagonalBase @@ -805,10 +794,10 @@ fix1: shape: !type:PolygonShape - vertices: - - "-0.5,-0.5" - - "0.5,0.5" - - "0.5,-0.5" + vertices: + - "-0.5,-0.5" + - "0.5,0.5" + - "0.5,-0.5" mask: - FullTileMask layer: @@ -978,19 +967,8 @@ - type: IconSmooth key: walls base: solid - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 150 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: MetalSlam - - !type:ChangeConstructionNodeBehavior - node: girder - - !type:DoActsBehavior - acts: ["Destruction"] + - type: Damageable + damageModifierSet: Metallic # weaker because rust - type: entity parent: BaseWall @@ -999,7 +977,7 @@ components: - type: Tag tags: - - Wall + - Wall - type: Destructible thresholds: - trigger: @@ -1358,7 +1336,7 @@ lifetime: 15 - type: Tag tags: - - Wall + - Wall - type: Physics bodyType: Static - type: Fixtures @@ -1366,7 +1344,7 @@ fix1: shape: !type:PhysShapeAabb - bounds: "-0.5,-0.5,0.5,0.5" + bounds: "-0.5,-0.5,0.5,0.5" mask: - FullTileMask layer: @@ -1528,8 +1506,6 @@ !type:DamageTrigger damage: 100 behaviors: - - !type:DoActsBehavior - acts: [ "Destruction" ] - !type:PlaySoundBehavior sound: path: /Audio/Effects/break_stone.ogg diff --git a/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml b/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml index 0922122ff7..87e599cdce 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/clockwork.yml @@ -1,14 +1,14 @@ - type: entity + parent: BaseWindowStructure id: ClockworkWindow name: clockwork window description: Don't smudge up the brass down there. - parent: Window components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/clockwork_window.rsi - type: Icon sprite: Structures/Windows/clockwork_window.rsi + state: full - type: Repairable fuelCost: 10 doAfterDelay: 2 @@ -37,23 +37,14 @@ - type: Construction graph: Window node: clockworkWindow - - type: Appearance - type: DamageVisuals - thresholds: [5, 10, 20] damageDivisor: 3 - trackAllDamage: true - damageOverlay: - sprite: Structures/Windows/cracks.rsi - type: entity + parent: BaseWindowStructureDirectional id: WindowClockworkDirectional - parent: WindowDirectional name: directional clockwork window description: Don't smudge up the brass down there. - placement: - mode: SnapgridCenter - snap: - - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -64,13 +55,10 @@ - type: Construction graph: WindowDirectional node: windowClockworkDirectional - - type: Appearance - type: DamageVisuals - thresholds: [5, 10, 20] damageDivisor: 1.5 - trackAllDamage: true - damageOverlay: - sprite: Structures/Windows/cracks_directional.rsi + - type: Injurable + damageContainer: StructuralInorganic - type: Damageable damageModifierSet: RGlass - type: Destructible diff --git a/Resources/Prototypes/Entities/Structures/Windows/mining.yml b/Resources/Prototypes/Entities/Structures/Windows/mining.yml index fa20edb6e0..90379bb277 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/mining.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/mining.yml @@ -1,13 +1,13 @@ - type: entity + parent: [BaseWindowStructure, BaseRCDResistant] id: MiningWindow name: mining window - parent: WindowRCDResistant components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/mining.rsi - type: Icon sprite: Structures/Windows/mining.rsi + state: full - type: Repairable fuelCost: 15 doAfterDelay: 3 @@ -36,13 +36,8 @@ acts: [ "Destruction" ] - type: IconSmooth base: mwindow - - type: Appearance - type: DamageVisuals - thresholds: [5, 10, 20] damageDivisor: 4 - trackAllDamage: true - damageOverlay: - sprite: Structures/Windows/cracks.rsi - type: StaticPrice price: 100 diff --git a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml index b71f93db2a..dc0d754f9a 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/plasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/plasma.yml @@ -1,13 +1,13 @@ - type: entity id: PlasmaWindow name: plasma window - parent: [BaseDeltaPressurePlasma, WindowRCDResistant] + parent: [BaseDeltaPressurePlasma, BaseWindowStructure, BaseRCDResistant] components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/plasma_window.rsi - type: Icon sprite: Structures/Windows/plasma_window.rsi + state: full - type: Damageable damageModifierSet: Glass - type: Injurable @@ -47,13 +47,9 @@ - type: entity id: PlasmaWindowDirectional - parent: [BaseDeltaPressurePlasmaQuarter, WindowDirectionalRCDResistant] + parent: [BaseDeltaPressurePlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] name: directional plasma window description: Don't smudge up the glass down there. - placement: - mode: SnapgridCenter - snap: - - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -71,6 +67,10 @@ trackAllDamage: true damageOverlay: sprite: Structures/Windows/cracks_directional.rsi + - type: Damageable + damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml index fbd098a146..5adf28b80d 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/reinforced.yml @@ -1,13 +1,13 @@ - type: entity + parent: [BaseDeltaPressureReinforcedGlass, BaseWindowStructure] id: ReinforcedWindow name: reinforced window - parent: [BaseDeltaPressureReinforcedGlass, Window] components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/reinforced_window.rsi - type: Icon sprite: Structures/Windows/reinforced_window.rsi + state: full - type: Repairable fuelCost: 10 doAfterDelay: 2 @@ -49,14 +49,9 @@ sprite: Structures/Windows/cracks.rsi - type: entity + parent: [BaseDeltaPressureReinforcedGlassQuarter, BaseWindowStructureDirectional] id: WindowReinforcedDirectional - parent: [BaseDeltaPressureReinforcedGlassQuarter, WindowDirectional] name: directional reinforced window - description: Don't smudge up the glass down there. - placement: - mode: SnapgridCenter - snap: - - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -76,6 +71,8 @@ sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: RCDDeconstructable cost: 4 delay: 4 diff --git a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml index a8f9d8e385..7399b71430 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/rplasma.yml @@ -1,13 +1,13 @@ - type: entity + parent: [BaseDeltaPressureReinforcedPlasma, BaseWindowStructure, BaseRCDResistant] id: ReinforcedPlasmaWindow name: reinforced plasma window - parent: [BaseDeltaPressureReinforcedPlasma, WindowRCDResistant] components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/reinforced_plasma_window.rsi - type: Icon sprite: Structures/Windows/reinforced_plasma_window.rsi + state: full - type: Damageable damageModifierSet: RGlass - type: Injurable @@ -49,14 +49,9 @@ price: 132 - type: entity + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] id: PlasmaReinforcedWindowDirectional - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, WindowDirectionalRCDResistant] name: directional reinforced plasma window - description: Don't smudge up the glass down there. - placement: - mode: SnapgridCenter - snap: - - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -76,6 +71,8 @@ sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: RadiationBlocker resistance: 2 - type: Destructible diff --git a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml index 96381de72e..db233d30e5 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/ruranium.yml @@ -1,13 +1,13 @@ - type: entity + parent: [BaseDeltaPressureReinforcedPlasma, BaseWindowStructure, BaseRCDResistant] id: ReinforcedUraniumWindow name: reinforced uranium window - parent: [BaseDeltaPressureReinforcedPlasma, WindowRCDResistant] components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/reinforced_uranium_window.rsi - type: Icon sprite: Structures/Windows/reinforced_uranium_window.rsi + state: full - type: Damageable damageModifierSet: RGlass - type: Injurable @@ -49,14 +49,9 @@ resistance: 5 - type: entity + parent: [BaseDeltaPressureReinforcedPlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] id: UraniumReinforcedWindowDirectional - parent: [BaseDeltaPressureReinforcedPlasmaQuarter, WindowDirectionalRCDResistant] name: directional reinforced uranium window - description: Don't smudge up the glass down there. - placement: - mode: SnapgridCenter - snap: - - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -76,6 +71,8 @@ sprite: Structures/Windows/cracks_directional.rsi - type: Damageable damageModifierSet: RGlass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml index b3ead67f1b..a76ffc5f19 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/shuttle.yml @@ -1,13 +1,13 @@ - type: entity + parent: [BaseDeltaPressureReinforcedGlass, BaseWindowStructure, BaseRCDResistant] id: ShuttleWindow name: shuttle window - parent: [BaseDeltaPressureReinforcedGlass, WindowRCDResistant] components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/shuttle_window.rsi - type: Icon sprite: Structures/Windows/shuttle_window.rsi + state: full - type: Repairable fuelCost: 15 doAfterDelay: 3 diff --git a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml index 73adc37fae..76527c619b 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/uranium.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/uranium.yml @@ -1,10 +1,9 @@ - type: entity + parent: [BaseDeltaPressurePlasma, BaseWindowStructure, BaseRCDResistant] id: UraniumWindow name: uranium window - parent: [BaseDeltaPressurePlasma, WindowRCDResistant] components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/uranium_window.rsi - type: Icon sprite: Structures/Windows/uranium_window.rsi @@ -47,14 +46,9 @@ resistance: 3 - type: entity + parent: [BaseDeltaPressurePlasmaQuarter, BaseWindowStructureDirectional, BaseRCDResistant] id: UraniumWindowDirectional - parent: [BaseDeltaPressurePlasmaQuarter, WindowDirectionalRCDResistant] name: directional uranium window - description: Don't smudge up the glass down there. - placement: - mode: SnapgridCenter - snap: - - Window components: - type: Sprite sprite: Structures/Windows/directional.rsi @@ -72,6 +66,10 @@ trackAllDamage: true damageOverlay: sprite: Structures/Windows/cracks_directional.rsi + - type: Damageable + damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: diff --git a/Resources/Prototypes/Entities/Structures/Windows/window.yml b/Resources/Prototypes/Entities/Structures/Windows/window.yml index 5ecd83aece..7dad29c496 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/window.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/window.yml @@ -1,6 +1,7 @@ - type: entity - id: Window + abstract: true parent: [BaseDeltaPressureGlass, BaseStructure] + id: BaseWindowStructure name: window description: Don't smudge up the glass down there. placement: @@ -20,14 +21,10 @@ arc: 360 # interact despite grilles - type: Tag tags: - - ForceFixRotations - - Window + - ForceFixRotations + - Window - type: Sprite drawdepth: WallTops - sprite: Structures/Windows/window.rsi - - type: Icon - sprite: Structures/Windows/window.rsi - state: full - type: Physics bodyType: Static - type: Fixtures @@ -39,10 +36,6 @@ - FullTileMask layer: - GlassLayer - - type: Damageable - damageModifierSet: Glass - - type: Injurable - damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages - type: Repairable @@ -50,22 +43,6 @@ cost: 6 delay: 4 fx: EffectRCDDeconstruct4 - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: WindowShatter - - !type:SpawnEntitiesBehavior - spawn: - ShardGlass: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: Airtight - type: IconSmooth key: windows @@ -89,6 +66,36 @@ price: 100 - type: BlockWeather +- type: entity + parent: BaseWindowStructure + id: Window + components: + - type: Sprite + sprite: Structures/Windows/window.rsi + - type: Icon + sprite: Structures/Windows/window.rsi + state: full + - type: Damageable + damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: WindowShatter + - !type:SpawnEntitiesBehavior + spawn: + ShardGlass: + min: 1 + max: 2 + - !type:DoActsBehavior + acts: [ "Destruction" ] + - type: entity parent: Window id: TintedWindow @@ -109,16 +116,21 @@ price: 70 - type: entity - id: WindowRCDResistant - parent: Window abstract: true + id: BaseRCDResistant components: - type: RCDDeconstructable deconstructable: false - type: entity - id: WindowDirectional + abstract: true + parent: [Window, BaseRCDResistant] + id: WindowRCDResistant + +- type: entity + abstract: true parent: [BaseDeltaPressureGlassQuarter, BaseStructure] + id: BaseWindowStructureDirectional name: directional window description: Don't smudge up the glass down there. placement: @@ -130,18 +142,13 @@ arc: 360 # interact despite grilles - type: Tag tags: - - Window + - Window - type: MeleeSound soundGroups: Brute: collection: GlassSmack - type: Sprite drawdepth: Mobs - sprite: Structures/Windows/directional.rsi - state: window - - type: Icon - sprite: Structures/Windows/directional.rsi - state: window - type: InteractionPopup interactSuccessString: comp-window-knock messagePerceivedByOthers: comp-window-knock @@ -160,16 +167,42 @@ layer: - GlassLayer - type: Repairable - - type: Damageable - damageModifierSet: Glass - - type: Injurable - damageContainer: StructuralInorganic - type: ExaminableDamage messages: WindowMessages - type: RCDDeconstructable cost: 4 delay: 2 fx: EffectRCDDeconstruct2 + - type: Airtight + noAirWhenFullyAirBlocked: false + airBlockedDirection: + - South + - type: Appearance + - type: DamageVisuals + thresholds: [5, 10, 20] + trackAllDamage: true + damageOverlay: + sprite: Structures/Windows/cracks_directional.rsi + - type: StaticPrice + price: 15 + - type: Construction + graph: WindowDirectional + node: windowDirectional + +- type: entity + parent: BaseWindowStructureDirectional + id: WindowDirectional + components: + - type: Sprite + sprite: Structures/Windows/directional.rsi + state: window + - type: Icon + sprite: Structures/Windows/directional.rsi + state: window + - type: Damageable + damageModifierSet: Glass + - type: Injurable + damageContainer: StructuralInorganic - type: Destructible thresholds: - trigger: @@ -186,29 +219,11 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Airtight - noAirWhenFullyAirBlocked: false - airBlockedDirection: - - South - - type: Construction - graph: WindowDirectional - node: windowDirectional - - type: Appearance - - type: DamageVisuals - thresholds: [5, 10, 20] - trackAllDamage: true - damageOverlay: - sprite: Structures/Windows/cracks_directional.rsi - - type: StaticPrice - price: 15 - type: entity - id: WindowDirectionalRCDResistant - parent: WindowDirectional abstract: true - components: - - type: RCDDeconstructable - deconstructable: false + parent: [WindowDirectional, BaseRCDResistant] + id: WindowDirectionalRCDResistant - type: entity id: WindowFrostedDirectional diff --git a/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml b/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml index 989ffcca9b..71eafe0569 100644 --- a/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml +++ b/Resources/Prototypes/Entities/Structures/Windows/xenoresin.yml @@ -2,34 +2,11 @@ parent: ReinforcedWindow id: XenoResinWindow name: resin window - description: Transparent and hardened, yet slightly sticky to the touch. Slightly stronger than a normal reinforced window. + description: Transparent and hardened, yet slightly sticky to the touch. components: - type: Sprite - drawdepth: WallTops sprite: Structures/Windows/xeno_resin.rsi - type: Icon sprite: Structures/Windows/xeno_resin.rsi - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 100 - behaviors: - - !type:PlaySoundBehavior - sound: - collection: WindowShatter - - !type:SpawnEntitiesBehavior - spawn: - ShardGlassReinforced: - min: 1 - max: 2 - - !type:DoActsBehavior - acts: [ "Destruction" ] - type: IconSmooth base: xwindow - - type: DamageVisuals - thresholds: [5, 10, 20] - damageDivisor: 4 - trackAllDamage: true - damageOverlay: - sprite: Structures/Windows/cracks.rsi diff --git a/Resources/Prototypes/Entities/Structures/cargo_telepad.yml b/Resources/Prototypes/Entities/Structures/cargo_telepad.yml index eb96ebf609..f2935a6117 100644 --- a/Resources/Prototypes/Entities/Structures/cargo_telepad.yml +++ b/Resources/Prototypes/Entities/Structures/cargo_telepad.yml @@ -1,6 +1,6 @@ - type: entity id: CargoTelepad - parent: [ BaseMachinePowered, ConstructibleMachine ] + parent: [ BaseMachinePowered, ConstructibleMachine, BaseConstructibleMachineDestructible ] name: cargo telepad description: Beam in the pizzas and dig in. components: @@ -31,8 +31,14 @@ shader: unshaded - type: Damageable damageModifierSet: StructuralMetallicStrong - - type: Injurable - damageContainer: StructuralInorganic + - type: Destructible + thresholds: + - trigger: !type:DamageTrigger + damage: 175 + behaviors: + - !type:PlaySoundBehavior + sound: + collection: MetalBreak - type: DeviceNetwork deviceNetId: Wireless receiveFrequencyId: BasicDevice diff --git a/Resources/Prototypes/Entities/Structures/hydro_tray.yml b/Resources/Prototypes/Entities/Structures/hydro_tray.yml index b1cbcc8b86..dff2d7481c 100644 --- a/Resources/Prototypes/Entities/Structures/hydro_tray.yml +++ b/Resources/Prototypes/Entities/Structures/hydro_tray.yml @@ -1,6 +1,6 @@ - type: entity name: hydroponics tray - parent: [ hydroponicsSoil, SmallConstructibleMachine] + parent: [ BaseHydroponicsSoil, SmallConstructibleMachine, BaseSmallConstructibleMachineDestructible] id: hydroponicsTray description: An interstellar-grade space farmplot allowing for rapid growth and selective breeding of crops. Just... keep in mind the space weeds. components: @@ -78,13 +78,9 @@ !type:DamageTrigger damage: 100 behaviors: - - !type:ChangeConstructionNodeBehavior - node: machineFrame - !type:PlaySoundBehavior sound: collection: MetalGlassBreak - - !type:DoActsBehavior - acts: ["Destruction"] - type: Machine board: HydroponicsTrayMachineCircuitboard - type: WiresPanel diff --git a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml index fa9079b632..e6fe0fab44 100644 --- a/Resources/Prototypes/Entities/Structures/plastic_flaps.yml +++ b/Resources/Prototypes/Entities/Structures/plastic_flaps.yml @@ -85,14 +85,6 @@ suffix: Airtight, Clear description: Heavy duty, slightly stronger, airtight plastic flaps. Definitely can't get past those. No way. components: - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 150 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - type: Airtight - type: StaticPrice price: 100 @@ -104,14 +96,6 @@ suffix: Airtight, Opaque description: Heavy duty, slightly stronger, airtight plastic flaps. Definitely can't get past those. No way. components: - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 150 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - type: Airtight - type: StaticPrice price: 100 diff --git a/Resources/Prototypes/Entities/Structures/soil.yml b/Resources/Prototypes/Entities/Structures/soil.yml index a999781300..4c7297ca63 100644 --- a/Resources/Prototypes/Entities/Structures/soil.yml +++ b/Resources/Prototypes/Entities/Structures/soil.yml @@ -1,8 +1,7 @@ - type: entity parent: SolutionLarge - id: hydroponicsSoil - name: soil - description: A mix of organic matter and minerals creating a soil to grow your plant in space. Seems to be dry. + abstract: true + id: BaseHydroponicsSoil placement: mode: SnapgridCenter components: @@ -22,21 +21,7 @@ - FullTileMask layer: - FullTileMask - - type: Damageable - damageModifierSet: Metallic - - type: Injurable - damageContainer: Inorganic - - type: Destructible - thresholds: - - trigger: - !type:DamageTrigger - damage: 50 - behaviors: - - !type:DoActsBehavior - acts: ["Destruction"] - type: Sprite - sprite: Structures/Hydroponics/misc.rsi - state: soil noRot: true - type: PlantHolder drawWarnings: false @@ -58,6 +43,28 @@ - type: Appearance - type: PlantHolderVisuals +- type: entity + parent: BaseHydroponicsSoil + id: hydroponicsSoil + name: soil + description: A mix of organic matter and minerals creating a soil to grow your plant in space. Seems to be dry. + components: + - type: Damageable + damageModifierSet: Metallic + - type: Injurable + damageContainer: Inorganic + - type: Destructible + thresholds: + - trigger: + !type:DamageTrigger + damage: 50 + behaviors: + - !type:DoActsBehavior + acts: ["Destruction"] + - type: Sprite + sprite: Structures/Hydroponics/misc.rsi + state: soil + - type: entity parent: hydroponicsSoil id: FungalSoil From cf7c92e74e4d1154c34fe28f88da88096a4431db Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Mon, 27 Jul 2026 18:00:46 -0700 Subject: [PATCH 33/35] v283.1.3 --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 3eda0469cf..edad26f42a 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 3eda0469cf2a9240c04ee4961c1a86042fadb730 +Subproject commit edad26f42aca013df2262e8462ba4adf94d8beee From 7e7bf76a26007d79133bc8a6076fad0c85e54b1b Mon Sep 17 00:00:00 2001 From: Princess Cheeseballs <66055347+Princess-Cheeseballs@users.noreply.github.com> Date: Mon, 27 Jul 2026 18:03:21 -0700 Subject: [PATCH 34/35] v284.0.2 --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index 5960554571..81e82b01d6 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 5960554571b266f49ac6bce8677a4869032da9de +Subproject commit 81e82b01d6cc5957015a8c9f3baf5e573b0a5217 From d9943c97531daffbeded121fcd0a91195a5b715f Mon Sep 17 00:00:00 2001 From: Whatstone <166147148+whatston3@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:15:35 -0400 Subject: [PATCH 35/35] RecyclerLoopTest: check all materials, simplify test. (#44967) * ReclaimerLoopTest: check every material * Remove unused stuff * constant Recycler, no GameScrounger dependency * talked myself out of it * o kurwa * Tweak comments, convert asserts to assumes, remove return Signed-off-by: Connor Huffine --------- Signed-off-by: Connor Huffine Co-authored-by: Connor Huffine --- .../Tests/Materials/ReclaimerLoopTest.cs | 74 +++++-------------- .../Reagents/Materials/materials.yml | 1 + 2 files changed, 19 insertions(+), 56 deletions(-) diff --git a/Content.IntegrationTests/Tests/Materials/ReclaimerLoopTest.cs b/Content.IntegrationTests/Tests/Materials/ReclaimerLoopTest.cs index 6e2a4ea229..310401ed59 100644 --- a/Content.IntegrationTests/Tests/Materials/ReclaimerLoopTest.cs +++ b/Content.IntegrationTests/Tests/Materials/ReclaimerLoopTest.cs @@ -2,13 +2,9 @@ using Content.IntegrationTests.Fixtures.Attributes; using Content.IntegrationTests.Tests.Interaction; using Content.IntegrationTests.Utility; using Content.Server.Materials; -using Content.Server.Spawners.Components; using Content.Shared.Materials; -using Content.Shared.Sprite; -using Content.Shared.Whitelist; using Robust.Shared.GameObjects; using Robust.Shared.Prototypes; -using System.Collections.Generic; namespace Content.IntegrationTests.Tests.Materials; @@ -19,15 +15,13 @@ namespace Content.IntegrationTests.Tests.Materials; [TestOf(typeof(MaterialReclaimerComponent))] public sealed class ReclaimerLoopTest : InteractionTest { - //ProtoIDs we need + // ProtoIDs we need private static readonly EntProtoId ApcId = "APCBasic"; - private static readonly EntProtoId FloorTileId = "FloorTileItemSteelCheckerDark"; + private static readonly EntProtoId FloorTileId = "FloorTileItemSteel"; private static readonly string[] Reclaimers = GameDataScrounger.EntitiesWithComponent("MaterialReclaimer"); [SidedDependency(Side.Server)] private readonly SharedMaterialReclaimerSystem _materialReclaimerSystem = null!; - [SidedDependency(Side.Server)] private readonly EntityWhitelistSystem _entityWhitelistSystem = null!; - [SidedDependency(Side.Server)] private readonly IComponentFactory _compFactory = null!; [Test] [TestCaseSource(nameof(Reclaimers))] @@ -37,78 +31,46 @@ public sealed class ReclaimerLoopTest : InteractionTest [TrackingIssue("https://github.com/space-wizards/space-station-14/issues/39691")] public async Task MaterialSpawnLoopTest(string reclaimerId) { - //Spawn the reclaimer + // Spawn the reclaimer await SpawnTarget(reclaimerId, PlayerCoords); - Assert.That(STarget, Is.Not.Null, "STarget was null, did the reclaimer spawn correctly?"); + Assume.That(STarget, Is.Not.Null, "STarget was null, did the reclaimer spawn correctly?"); var reclaimComp = Comp(Target); - //If the reclaimer can produce materials - var reclaimsMaterials = reclaimComp.ReclaimMaterials; - - //if the reclaimer has reclaimsMaterials and is able to produce materials - //go through all recyclable items, compile a HashSet of producible materials - HashSet> producibleMaterials = []; //If reclaimMaterials is false, this will stay empty - if (reclaimsMaterials) - { - foreach (var proto in ProtoMan.EnumeratePrototypes()) - { - //we don't care about items that don't recycle into anything physical - if (!proto.HasComp(_compFactory)) - continue; - - //spawners and random items mess things up quickly, avoid them too - if (proto.HasComp(_compFactory) || proto.HasComp(_compFactory)) - continue; - - var currentScrap = await Spawn(proto.ID); - var currentScrapUid = ToServer(currentScrap); - var currentScrapCompositionComp = Comp(currentScrap); - - //If it's on the whitelist for the reclaimer, and not on its blacklist. - if (_entityWhitelistSystem.CheckBoth(currentScrapUid, reclaimComp.Blacklist, reclaimComp.Whitelist)) - { - //for each material it produces, add it to the HashSet - foreach (var (mat, _) in currentScrapCompositionComp.MaterialComposition) - { - ProtoId matAsProto = ProtoMan.Index(mat); - producibleMaterials.Add(matAsProto); - } - } - - await Delete(currentScrapUid); - } - } // Power the reclaimer await SpawnEntity(ApcId, SEntMan.GetCoordinates(TargetCoords)); await RunTicks(1); - //Set reclaimer to enabled + // Set reclaimer to enabled await Server.WaitPost(() => { _materialReclaimerSystem.SetReclaimerEnabled((EntityUid)STarget, true); }); - //Assert that reclaimer enabled - Assert.That(reclaimComp.Enabled, "The reclaimer did not get or stay enabled"); + // Check that reclaimer enabled + Assume.That(reclaimComp.Enabled, "The reclaimer did not get or stay enabled"); - //put a floor tile down + // Put a floor tile down await InteractUsing(FloorTileId); + // Reclaimer can't reclaim materials? Job's done. + if (!reclaimComp.ReclaimMaterials) + Assert.Ignore("Cannot reclaim materials"); + using (Assert.EnterMultipleScope()) { - //For each producible Material, assert that it is not recyclable (and would thus cause a recycling loop) - foreach (ProtoId material in producibleMaterials) + // For each material, assert that it is not recyclable (and would thus cause a recycling loop) + foreach (var material in ProtoMan.EnumeratePrototypes()) { - var matStack = ProtoMan.Index(material).StackEntity; + var matStack = material.StackEntity; Assert.That( matStack, Is.Not.Null, - $"The material, {material}, did not have a stackentity associated with it. You may need to add a stackEntity to its Reagents/Materials yml file."); + $"The material, {material.ID}, did not have a stackentity associated with it. You may need to add a stackEntity to its Reagents/Materials yml file."); var matInHands = await PlaceInHands(matStack); var matInHandsUid = ToServer(matInHands); - //Assert we're holding material + // Assert we're holding material Assert.That( HandSys.GetActiveItem((SPlayer, Hands)), Is.EqualTo(matInHandsUid), @@ -116,7 +78,7 @@ public sealed class ReclaimerLoopTest : InteractionTest await Interact(); - //Assert Hands not empty + // Assert Hands not empty Assert.That( HandSys.GetActiveItem((SPlayer, Hands)), Is.Not.Null, diff --git a/Resources/Prototypes/Reagents/Materials/materials.yml b/Resources/Prototypes/Reagents/Materials/materials.yml index 3455026913..e139c8152b 100644 --- a/Resources/Prototypes/Reagents/Materials/materials.yml +++ b/Resources/Prototypes/Reagents/Materials/materials.yml @@ -113,6 +113,7 @@ - type: material id: Bones + stackEntity: MaterialBones1 name: materials-bones unit: materials-unit-piece icon: { sprite: Objects/Materials/materials.rsi, state: bones }