diff --git a/Content.Server/Access/Systems/IdCardConsoleSystem.cs b/Content.Server/Access/Systems/IdCardConsoleSystem.cs index 172577db1f..5875a4bb48 100644 --- a/Content.Server/Access/Systems/IdCardConsoleSystem.cs +++ b/Content.Server/Access/Systems/IdCardConsoleSystem.cs @@ -1,18 +1,24 @@ +using System.Linq; +using Content.Server.Chat.Systems; +using Content.Server.Containers; using Content.Server.StationRecords.Systems; using Content.Shared.Access.Components; +using static Content.Shared.Access.Components.IdCardConsoleComponent; using Content.Shared.Access.Systems; +using Content.Shared.Access; using Content.Shared.Administration.Logs; +using Content.Shared.Construction; +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.Roles; using Content.Shared.StationRecords; -using Content.Shared.StatusIcon; +using Content.Shared.Throwing; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Containers; using Robust.Shared.Prototypes; -using System.Linq; -using static Content.Shared.Access.Components.IdCardConsoleComponent; -using Content.Shared.Access; +using Robust.Shared.Random; namespace Content.Server.Access.Systems; @@ -26,6 +32,10 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem [Dependency] private readonly AccessSystem _access = default!; [Dependency] private readonly IdCardSystem _idCard = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly SharedContainerSystem _container = default!; + [Dependency] private readonly ThrowingSystem _throwing = default!; + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ChatSystem _chat = default!; public override void Initialize() { @@ -37,6 +47,11 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem SubscribeLocalEvent(UpdateUserInterface); SubscribeLocalEvent(UpdateUserInterface); SubscribeLocalEvent(UpdateUserInterface); + SubscribeLocalEvent(OnDamageChanged); + + // Intercept the event before anyone can do anything with it! + SubscribeLocalEvent(OnMachineDeconstructed, + before: [typeof(EmptyOnMachineDeconstructSystem), typeof(ItemSlotsSystem)]); } private void OnWriteToTargetIdMessage(EntityUid uid, IdCardConsoleComponent component, WriteToTargetIdMessage args) @@ -213,4 +228,46 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem _record.Synchronize(key); } + + private void OnMachineDeconstructed(Entity entity, ref MachineDeconstructedEvent args) + { + TryDropAndThrowIds(entity.AsNullable()); + } + + private void OnDamageChanged(Entity entity, ref DamageChangedEvent args) + { + if (TryDropAndThrowIds(entity.AsNullable())) + _chat.TrySendInGameICMessage(entity, Loc.GetString("id-card-console-damaged"), InGameICChatType.Speak, true); + } + + #region PublicAPI + + /// + /// Tries to drop any IDs stored in the console, and then tries to throw them away. + /// Returns true if anything was ejected and false otherwise. + /// + public bool TryDropAndThrowIds(Entity ent) + { + if (!Resolve(ent, ref ent.Comp1, ref ent.Comp2)) + return false; + + var didEject = false; + + foreach (var slot in ent.Comp2.Slots.Values) + { + if (slot.Item == null || slot.ContainerSlot == null) + continue; + + var item = slot.Item.Value; + if (_container.Remove(item, slot.ContainerSlot)) + { + _throwing.TryThrow(item, _random.NextVector2(), baseThrowSpeed: 5f); + didEject = true; + } + } + + return didEject; + } + + #endregion } diff --git a/Content.Server/Salvage/SpawnSalvageMissionJob.cs b/Content.Server/Salvage/SpawnSalvageMissionJob.cs index 21da7e89a0..6746c2f8bd 100644 --- a/Content.Server/Salvage/SpawnSalvageMissionJob.cs +++ b/Content.Server/Salvage/SpawnSalvageMissionJob.cs @@ -214,7 +214,14 @@ public sealed class SpawnSalvageMissionJob : Job if (!lootProto.Guaranteed) continue; - await SpawnDungeonLoot(lootProto, mapUid); + try + { + await SpawnDungeonLoot(lootProto, mapUid); + } + catch (Exception e) + { + _sawmill.Error($"Failed to spawn guaranteed loot {lootProto.ID}: {e}"); + } } // Handle boss loot (when relevant). @@ -244,7 +251,14 @@ public sealed class SpawnSalvageMissionJob : Job if (entry == null) break; - await SpawnRandomEntry(grid, entry, dungeon, random); + try + { + await SpawnRandomEntry(grid, entry, dungeon, random); + } + catch (Exception e) + { + _sawmill.Error($"Failed to spawn mobs for {entry.Proto}: {e}"); + } } var allLoot = _prototypeManager.Index(SharedSalvageSystem.ExpeditionsLootProto); diff --git a/Content.Shared/GPS/Systems/HandheldGpsSystem.cs b/Content.Shared/GPS/Systems/HandheldGpsSystem.cs new file mode 100644 index 0000000000..6a8e4c08db --- /dev/null +++ b/Content.Shared/GPS/Systems/HandheldGpsSystem.cs @@ -0,0 +1,37 @@ +using Content.Shared.GPS.Components; +using Content.Shared.Examine; +using Robust.Shared.Map; + +namespace Content.Shared.GPS.Systems; + +public sealed class HandheldGpsSystem : EntitySystem +{ + [Dependency] private readonly SharedTransformSystem _transform = default!; + + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamine); + } + + /// + /// Handles showing the coordinates when a GPS is examined. + /// + private void OnExamine(Entity ent, ref ExaminedEvent args) + { + var posText = "Error"; + + var pos = _transform.GetMapCoordinates(ent); + + if (pos.MapId != MapId.Nullspace) + { + var x = (int) pos.Position.X; + var y = (int) pos.Position.Y; + posText = $"({x}, {y})"; + } + + args.PushMarkup(Loc.GetString("handheld-gps-coordinates-title", ("coordinates", posText))); + } +} diff --git a/Content.Shared/Interaction/SharedInteractionSystem.cs b/Content.Shared/Interaction/SharedInteractionSystem.cs index 5f8d8364af..f492bce09e 100644 --- a/Content.Shared/Interaction/SharedInteractionSystem.cs +++ b/Content.Shared/Interaction/SharedInteractionSystem.cs @@ -106,7 +106,9 @@ namespace Content.Shared.Interaction _uiQuery = GetEntityQuery(); SubscribeLocalEvent(HandleUserInterfaceRangeCheck); - SubscribeLocalEvent(OnBoundInterfaceInteractAttempt); + + // TODO make this a broadcast event subscription again when engine has updated. + SubscribeLocalEvent(OnBoundInterfaceInteractAttempt); SubscribeAllEvent(HandleInteractInventorySlotEvent); @@ -151,12 +153,15 @@ namespace Content.Shared.Interaction /// /// Check that the user that is interacting with the BUI is capable of interacting and can access the entity. /// - private void OnBoundInterfaceInteractAttempt(Entity ent, ref BoundUserInterfaceMessageAttempt ev) + private void OnBoundInterfaceInteractAttempt(Entity ent, ref BoundUserInterfaceMessageAttempt ev) { + _uiQuery.TryComp(ev.Target, out var aUiComp); if (!_actionBlockerSystem.CanInteract(ev.Actor, ev.Target)) { // We permit ghosts to open uis unless explicitly blocked - if (ev.Message is not OpenBoundInterfaceMessage || !HasComp(ev.Actor) || ent.Comp.BlockSpectators) + if (ev.Message is not OpenBoundInterfaceMessage + || !HasComp(ev.Actor) + || aUiComp?.BlockSpectators == true) { ev.Cancel(); return; @@ -174,14 +179,16 @@ namespace Content.Shared.Interaction return; } + if (aUiComp == null) + return; - if (ent.Comp.SingleUser && ent.Comp.CurrentSingleUser != null && ent.Comp.CurrentSingleUser != ev.Actor) + if (aUiComp.SingleUser && aUiComp.CurrentSingleUser != null && aUiComp.CurrentSingleUser != ev.Actor) { ev.Cancel(); return; } - if (ent.Comp.RequiresComplex && !_actionBlockerSystem.CanComplexInteract(ev.Actor)) + if (aUiComp.RequiresComplex && !_actionBlockerSystem.CanComplexInteract(ev.Actor)) ev.Cancel(); } diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 8f2d122d81..006c06a22f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,44 +1,4 @@ Entries: -- author: VlaDOS1408 - changes: - - message: Locale to shuttle-ftl-status-Invalid - type: Add - id: 7663 - time: '2024-11-30T02:54:37.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33651 -- author: jbox144 - changes: - - message: Fixed the link on Marathon's TEG exterior airlock - type: Fix - - message: Fixed Cog's exterior atmospherics airlock - type: Fix - id: 7664 - time: '2024-11-30T06:23:50.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33621 -- author: Plykiya - changes: - - message: You can no longer cuff someone multiple times if multiple cuff do-afters - are completed at the exact same time. - type: Fix - id: 7665 - time: '2024-11-30T15:58:56.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33646 -- author: Plykiya - changes: - - message: You can now inspect the entity in your hand instead of the entity that - happened to be underneath your hand. - type: Fix - id: 7666 - time: '2024-11-30T16:14:39.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33642 -- author: Plykiya - changes: - - message: You can now inspect entities in the stripping window instead of the entity - that happened to be underneath the window. - type: Fix - id: 7667 - time: '2024-11-30T16:23:27.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/33644 - author: Winkarst-cpu changes: - message: Now borgs get names on roundstart. @@ -3898,3 +3858,44 @@ id: 8162 time: '2025-04-13T14:24:11.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/36503 +- author: ScarKy0 + changes: + - message: Oxygen, Carbon Dioxide, Nitrous Oxide and Frezon can now metabolize when + digested/injected. + type: Tweak + id: 8163 + time: '2025-04-13T15:21:55.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31648 +- author: ArchRBX + changes: + - message: Handheld GPS's can now be examined to read their displays + type: Add + - message: Handheld GPS's now update their displays much more frequently + type: Tweak + id: 8164 + time: '2025-04-13T15:29:13.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31814 +- author: Beck Thompson, Kaz Wooblie + changes: + - message: Computers now wont delete items inside of them when deconstructing. + type: Fix + - message: The ID card computer now throws the IDs out when deconstructed or damaged! + type: Add + id: 8165 + time: '2025-04-13T15:51:35.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32308 +- author: ElectroJr + changes: + - message: Fixed a bug that allowed dead or incapacitated people to potentially + interact with some UIs. + type: Fix + id: 8166 + time: '2025-04-13T16:09:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/36480 +- author: K-Dynamic + changes: + - message: Stinger grenades no longer flash on detonation. + type: Tweak + id: 8167 + time: '2025-04-13T17:23:35.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/36394 diff --git a/Resources/ConfigPresets/WizardsDen/wizardsDen.toml b/Resources/ConfigPresets/WizardsDen/wizardsDen.toml index 6c7becbbb6..eb8ff28958 100644 --- a/Resources/ConfigPresets/WizardsDen/wizardsDen.toml +++ b/Resources/ConfigPresets/WizardsDen/wizardsDen.toml @@ -33,7 +33,7 @@ appeal = "https://appeal.ss14.io" rules_file = "StandardRuleset" [movement] -mob_pushing = true +mob_pushing = false [net] max_connections = 1024 diff --git a/Resources/Locale/en-US/_strings/access/components/id-card-console-component.ftl b/Resources/Locale/en-US/_strings/access/components/id-card-console-component.ftl index be5d3f0bc3..7793b34846 100644 --- a/Resources/Locale/en-US/_strings/access/components/id-card-console-component.ftl +++ b/Resources/Locale/en-US/_strings/access/components/id-card-console-component.ftl @@ -10,3 +10,4 @@ id-card-console-window-job-selection-label = Job presets (sets department and jo access-id-card-console-component-no-hands-error = You have no hands. id-card-console-privileged-id = Privileged ID id-card-console-target-id = Target ID +id-card-console-damaged = Structural integrity compromised, ejecting contents. diff --git a/Resources/Locale/en-US/_strings/character-info/components/character-info-component.ftl b/Resources/Locale/en-US/_strings/character-info/components/character-info-component.ftl index b515c36c5a..dd2f848f77 100644 --- a/Resources/Locale/en-US/_strings/character-info/components/character-info-component.ftl +++ b/Resources/Locale/en-US/_strings/character-info/components/character-info-component.ftl @@ -1,4 +1,4 @@ character-info-title = Character -character-info-roles-antagonist-text = Antagonist Roles +character-info-roles-antagonist-text = You have no special Roles character-info-objectives-label = Objectives character-info-no-profession = No Profession diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml index 9f71158357..6a111ef1c8 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/projectile_grenades.yml @@ -40,8 +40,6 @@ - type: ProjectileGrenade fillPrototype: PelletClusterRubber capacity: 30 - - type: FlashOnTrigger - range: 7 - type: EmitSoundOnTrigger sound: path: "/Audio/Effects/flash_bang.ogg" diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml index 90c0d53528..eed2ead0eb 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/computers.yml @@ -599,6 +599,9 @@ type: WiresBoundUserInterface - type: CrewManifestViewer ownerKey: enum.IdCardConsoleUiKey.Key + - type: Speech + speechVerb: Robotic + speechSounds: Pai - type: Sprite layers: - map: ["computerLayerBody"] diff --git a/Resources/Prototypes/Reagents/gases.yml b/Resources/Prototypes/Reagents/gases.yml index 9ef508feea..ac39f2d725 100644 --- a/Resources/Prototypes/Reagents/gases.yml +++ b/Resources/Prototypes/Reagents/gases.yml @@ -8,6 +8,52 @@ boilingPoint: -183.0 meltingPoint: -218.4 metabolisms: + Poison: + effects: + - !type:Oxygenate + conditions: + - !type:OrganType + type: Human + - !type:Oxygenate + conditions: + - !type:OrganType + type: Animal + - !type:Oxygenate + conditions: + - !type:OrganType + type: Rat + - !type:Oxygenate + conditions: + - !type:OrganType + type: Plant + # Convert Oxygen into CO2. + - !type:ModifyLungGas + conditions: + - !type:OrganType + type: Vox + shouldHave: false + ratios: + CarbonDioxide: 1.0 + Oxygen: -1.0 + - !type:HealthChange + conditions: + - !type:OrganType + type: Vox + scaleByQuantity: true + ignoreResistances: true + damage: + types: + Poison: + 3 + - !type:AdjustAlert + alertType: Toxins + conditions: + - !type:ReagentThreshold + min: 0.5 + - !type:OrganType + type: Vox + clear: true + time: 5 Gas: effects: - !type:Oxygenate @@ -150,6 +196,32 @@ flavor: bitter color: "#66ff33" metabolisms: + Poison: + effects: + - !type:Oxygenate + conditions: + - !type:OrganType + type: Plant + - !type:HealthChange + conditions: + - !type:OrganType + type: Plant + shouldHave: false + - !type:OrganType + type: Vox + shouldHave: false + scaleByQuantity: true + ignoreResistances: true + damage: + types: + Poison: + 0.8 + - !type:Oxygenate + conditions: + - !type:OrganType + type: Plant + shouldHave: false + factor: -4 Gas: effects: - !type:Oxygenate @@ -236,6 +308,12 @@ boilingPoint: -88 meltingPoint: -90 metabolisms: + Poison: + effects: + - !type:HealthChange + damage: + types: + Poison: 2 Gas: effects: - !type:Emote @@ -317,6 +395,39 @@ boilingPoint: -195.8 meltingPoint: -210.0 metabolisms: + Narcotic: + effects: + - !type:HealthChange + scaleByQuantity: true + ignoreResistances: true + damage: + types: + Cellular: 1 + - !type:GenericStatusEffect + key: SeeingRainbows + component: SeeingRainbows + type: Add + time: 100 + refresh: false + - !type:Drunk + boozePower: 100 + - !type:PopupMessage + type: Local + messages: [ "frezon-lungs-cold" ] + probability: 0.1 + conditions: + - !type:ReagentThreshold + reagent: Frezon + min: 0.5 + - !type:PopupMessage + type: Local + visualType: Medium + messages: [ "frezon-euphoric" ] + probability: 0.1 + conditions: + - !type:ReagentThreshold + reagent: Frezon + min: 1 Gas: effects: - !type:HealthChange diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml b/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml index a33c0293ce..86d27affc4 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/machines/computer.yml @@ -123,6 +123,9 @@ entity: !type:BoardNodeEntity { container: board } edges: - to: monitorUnsecured + completed: + - !type:RaiseEvent + event: !type:MachineDeconstructedEvent steps: - tool: Prying doAfter: 1