From b08f79fb38cb89c1cfbb14be1a8f2d9fde1ac52b Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Fri, 17 May 2024 18:33:22 +0200 Subject: [PATCH 01/19] Move replacement chance from ReplacementAccentComponent to ReplacementAccentPrototype (#28049) Move replacement chance to ReplacementAccentPrototype --- .../Speech/Components/ReplacementAccentComponent.cs | 11 ++++++----- .../Speech/EntitySystems/ReplacementAccentSystem.cs | 6 +++--- Resources/Prototypes/Accents/word_replacements.yml | 3 ++- Resources/Prototypes/Traits/neutral.yml | 3 +-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Content.Server/Speech/Components/ReplacementAccentComponent.cs b/Content.Server/Speech/Components/ReplacementAccentComponent.cs index e7f57b80d0..037da72029 100644 --- a/Content.Server/Speech/Components/ReplacementAccentComponent.cs +++ b/Content.Server/Speech/Components/ReplacementAccentComponent.cs @@ -22,6 +22,12 @@ namespace Content.Server.Speech.Components /// [DataField("wordReplacements")] public Dictionary? WordReplacements; + + /// + /// Allows you to substitute words, not always, but with some chance + /// + [DataField] + public float ReplacementChance = 1f; } /// @@ -33,10 +39,5 @@ namespace Content.Server.Speech.Components [DataField("accent", customTypeSerializer: typeof(PrototypeIdSerializer), required: true)] public string Accent = default!; - /// - /// Allows you to substitute words, not always, but with some chance - /// - [DataField] - public float ReplacementChance = 1f; } } diff --git a/Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs b/Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs index da198bcc12..d81d913a36 100644 --- a/Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/ReplacementAccentSystem.cs @@ -24,9 +24,6 @@ namespace Content.Server.Speech.EntitySystems private void OnAccent(EntityUid uid, ReplacementAccentComponent component, AccentGetEvent args) { - if (!_random.Prob(component.ReplacementChance)) - return; - args.Message = ApplyReplacements(args.Message, component.Accent); } @@ -39,6 +36,9 @@ namespace Content.Server.Speech.EntitySystems if (!_proto.TryIndex(accent, out var prototype)) return message; + 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) diff --git a/Resources/Prototypes/Accents/word_replacements.yml b/Resources/Prototypes/Accents/word_replacements.yml index 30c739b845..9a801d786d 100644 --- a/Resources/Prototypes/Accents/word_replacements.yml +++ b/Resources/Prototypes/Accents/word_replacements.yml @@ -428,6 +428,7 @@ - type: accent id: liar + replacementChance: 0.15 wordReplacements: liar-word-1: liar-word-replacement-1 liar-word-2: liar-word-replacement-2 @@ -471,4 +472,4 @@ liar-word-39: liar-word-replacement-39 liar-word-40: liar-word-replacement-40 liar-word-41: liar-word-replacement-41 - liar-word-42: liar-word-replacement-42 \ No newline at end of file + liar-word-42: liar-word-replacement-42 diff --git a/Resources/Prototypes/Traits/neutral.yml b/Resources/Prototypes/Traits/neutral.yml index d1e0afc83c..78d2bba049 100644 --- a/Resources/Prototypes/Traits/neutral.yml +++ b/Resources/Prototypes/Traits/neutral.yml @@ -1,4 +1,4 @@ -- type: trait +- type: trait id: PirateAccent name: trait-pirate-accent-name description: trait-pirate-accent-desc @@ -30,5 +30,4 @@ description: trait-liar-desc components: - type: ReplacementAccent - replacementChance: 0.15 accent: liar From 6082df7eac5d6ca443f4a0740227c4d281552f9a Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 17 May 2024 16:34:28 +0000 Subject: [PATCH 02/19] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 7e598ba4b5..3b48adab7c 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: Just_Art - changes: - - message: Added bob 5 hair! - type: Add - - message: Added long hair with bundles! - type: Add - id: 6100 - time: '2024-03-06T01:42:05.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/25772 - author: Errant changes: - message: Debug coordinates are now automatically enabled on the F3 overlay upon @@ -3868,3 +3859,10 @@ id: 6599 time: '2024-05-17T07:51:28.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/27960 +- author: lzk228 + changes: + - message: Fixed bug with pathological liar and zombie accents. + type: Fix + id: 6600 + time: '2024-05-17T16:33:22.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28049 From 99072341eb366a6fb15eacc21850fccb64b8d5a1 Mon Sep 17 00:00:00 2001 From: YuNii Date: Fri, 17 May 2024 21:46:45 +0200 Subject: [PATCH 03/19] Add keybind option for the Emote Menu (#28083) * Add keybind option for the Emote Menu * Update .editorconfig oopsies --- Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs | 1 + Resources/Locale/en-US/escape-menu/ui/options-menu.ftl | 1 + 2 files changed, 2 insertions(+) diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index a575f1ba51..6fa416ed59 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -215,6 +215,7 @@ namespace Content.Client.Options.UI.Tabs AddButton(ContentKeyFunctions.OpenInventoryMenu); AddButton(ContentKeyFunctions.OpenAHelp); AddButton(ContentKeyFunctions.OpenActionsMenu); + AddButton(ContentKeyFunctions.OpenEmotesMenu); AddButton(ContentKeyFunctions.ToggleRoundEndSummaryWindow); AddButton(ContentKeyFunctions.OpenEntitySpawnWindow); AddButton(ContentKeyFunctions.OpenSandboxWindow); diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index 1c0c0005b4..d07f9127a4 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -173,6 +173,7 @@ ui-options-function-open-crafting-menu = Open crafting menu ui-options-function-open-inventory-menu = Open inventory ui-options-function-open-a-help = Open admin help ui-options-function-open-abilities-menu = Open action menu +ui-options-function-open-emotes-menu = Open emotes menu ui-options-function-toggle-round-end-summary-window = Toggle round end summary window ui-options-function-open-entity-spawn-window = Open entity spawn menu ui-options-function-open-sandbox-window = Open sandbox menu From ca96a27c31b0e630a8c730461b6b34c5e253b649 Mon Sep 17 00:00:00 2001 From: PJBot Date: Fri, 17 May 2024 19:47:51 +0000 Subject: [PATCH 04/19] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 3b48adab7c..6ad80313b3 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Errant - changes: - - message: Debug coordinates are now automatically enabled on the F3 overlay upon - readmin. - type: Fix - id: 6101 - time: '2024-03-06T01:43:51.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/25063 - author: metalgearsloth changes: - message: Pod launches will now be offset slightly. @@ -3866,3 +3858,10 @@ id: 6600 time: '2024-05-17T16:33:22.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28049 +- author: YuNii + changes: + - message: Added the ability to re-bind the emote menu. + type: Add + id: 6601 + time: '2024-05-17T19:46:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28083 From 37382b3186868bb7dc6cd5320281b796cbedd44b Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sat, 18 May 2024 11:51:02 +0200 Subject: [PATCH 05/19] Move pens out of paper.yml mess (#28044) * Move pens out of paper.yml mess * forgor * fix tests * fux * fix 2 --- .../Catalog/Cargo/cargo_service.yml | 2 +- .../Prototypes/Catalog/uplink_catalog.yml | 6 +- .../Entities/Objects/Misc/paper.yml | 113 ------------------ .../Prototypes/Entities/Objects/Misc/pen.yml | 106 ++++++++++++++++ .../Objects/Misc/bureaucracy.rsi/meta.json | 34 +----- .../luxury_pen.png | Bin .../Textures/Objects/Misc/pens.rsi/meta.json | 59 +++++++++ .../pens.rsi/overpriced_pen-inhand-left.png | Bin 0 -> 236 bytes .../pens.rsi/overpriced_pen-inhand-right.png | Bin 0 -> 236 bytes .../overpriced_pen.png | Bin .../pen-inhand-left.png | Bin .../pen-inhand-right.png | Bin .../{bureaucracy.rsi => pens.rsi}/pen.png | Bin .../pen_blue.png | Bin .../{bureaucracy.rsi => pens.rsi}/pen_cap.png | Bin .../Misc/pens.rsi/pen_centcom-inhand-left.png | Bin 0 -> 227 bytes .../pens.rsi/pen_centcom-inhand-right.png | Bin 0 -> 217 bytes .../pen_centcom.png | Bin .../{bureaucracy.rsi => pens.rsi}/pen_hop.png | Bin .../{bureaucracy.rsi => pens.rsi}/pen_red.png | Bin 20 files changed, 170 insertions(+), 150 deletions(-) create mode 100644 Resources/Prototypes/Entities/Objects/Misc/pen.yml rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/luxury_pen.png (100%) create mode 100644 Resources/Textures/Objects/Misc/pens.rsi/meta.json create mode 100644 Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen-inhand-left.png create mode 100644 Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen-inhand-right.png rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/overpriced_pen.png (100%) rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen-inhand-left.png (100%) rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen-inhand-right.png (100%) rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen.png (100%) rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen_blue.png (100%) rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen_cap.png (100%) create mode 100644 Resources/Textures/Objects/Misc/pens.rsi/pen_centcom-inhand-left.png create mode 100644 Resources/Textures/Objects/Misc/pens.rsi/pen_centcom-inhand-right.png rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen_centcom.png (100%) rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen_hop.png (100%) rename Resources/Textures/Objects/Misc/{bureaucracy.rsi => pens.rsi}/pen_red.png (100%) diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_service.yml b/Resources/Prototypes/Catalog/Cargo/cargo_service.yml index 267f706f3b..ebcd9dfc5e 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_service.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_service.yml @@ -61,7 +61,7 @@ - type: cargoProduct id: ServiceBureaucracy icon: - sprite: Objects/Misc/bureaucracy.rsi + sprite: Objects/Misc/pens.rsi state: pen product: CrateServiceBureaucracy cost: 1000 diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 747328f305..c8d6eb4f61 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -298,7 +298,7 @@ id: UplinkExplodingPen name: uplink-exploding-pen-name description: uplink-exploding-pen-desc - icon: { sprite: /Textures/Objects/Misc/bureaucracy.rsi, state: pen } + icon: { sprite: /Textures/Objects/Misc/pens.rsi, state: pen } productEntity: PenExplodingBox cost: Telecrystal: 4 @@ -472,7 +472,7 @@ id: UplinkHypopen name: uplink-hypopen-name description: uplink-hypopen-desc - icon: { sprite: /Textures/Objects/Misc/bureaucracy.rsi, state: pen } + icon: { sprite: /Textures/Objects/Misc/pens.rsi, state: pen } productEntity: HypopenBox cost: Telecrystal: 6 @@ -1715,4 +1715,4 @@ - !type:BuyerWhitelistCondition blacklist: components: - - SurplusBundle \ No newline at end of file + - SurplusBundle diff --git a/Resources/Prototypes/Entities/Objects/Misc/paper.yml b/Resources/Prototypes/Entities/Objects/Misc/paper.yml index 5fa341c976..05a0b9d345 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/paper.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/paper.yml @@ -283,119 +283,6 @@ components: - type: NukeCodePaper -- type: entity - name: pen - parent: BaseItem - id: Pen - description: 'A dark ink pen.' - components: - - type: Tag - tags: - - Write - - Pen - - type: Sprite - sprite: Objects/Misc/bureaucracy.rsi - state: pen - - type: Item - sprite: Objects/Misc/bureaucracy.rsi - heldPrefix: pen - size: Tiny - - type: PhysicalComposition - materialComposition: - Steel: 25 - -- type: entity - parent: Pen - id: PenEmbeddable - abstract: true - components: - - type: EmbeddableProjectile - offset: 0.3,0.0 - removalTime: 0.0 - - type: ThrowingAngle - angle: 315 - - type: DamageOtherOnHit - damage: - types: - Piercing: 3 - -#TODO: I want the luxury pen to write a cool font like Merriweather in the future. - -- type: entity - name: luxury pen - parent: Pen - id: LuxuryPen - description: A fancy and expensive pen that you only deserve to own if you're qualified to handle vast amounts of paperwork. - components: - - type: Sprite - state: luxury_pen - - type: Item - heldPrefix: luxury_pen - -- type: entity - name: Cybersun pen - parent: PenEmbeddable - id: CyberPen - description: A high-tech pen straight from Cybersun's legal department, capable of refracting hard-light at impossible angles through its diamond tip in order to write. So powerful, it's even able to rewrite officially stamped documents should the need arise. - components: - - type: Tag - tags: - - Write - - WriteIgnoreStamps - - Pickaxe - - type: Sprite - sprite: Objects/Misc/bureaucracy.rsi - state: overpriced_pen - - type: MeleeWeapon - wideAnimationRotation: -45 - damage: - types: - Piercing: 15 - soundHit: - path: /Audio/Weapons/bladeslice.ogg - - type: Tool - qualities: - - Screwing - useSound: - collection: Screwdriver - - type: Item - sprite: Objects/Misc/bureaucracy.rsi - heldPrefix: overpriced_pen - size: Tiny - -- type: entity - name: captain's fountain pen - parent: PenEmbeddable - id: PenCap - description: 'A luxurious fountain pen for the captain of the station.' - components: - - type: Sprite - sprite: Objects/Misc/bureaucracy.rsi - state: pen_cap - -- type: entity - name: CentCom pen - parent: CyberPen - id: PenCentcom - description: In an attempt to keep up with the "power" of the cybersun bureaucracy, NT made a replica of cyber pen, in their corporate style. - components: - - type: Sprite - sprite: Objects/Misc/bureaucracy.rsi - state: pen_centcom - - type: Item - sprite: Objects/Misc/bureaucracy.rsi - heldPrefix: pen_centcom - -- type: entity - name: hop's fountain pen - parent: PenEmbeddable - id: PenHop - description: 'A luxurious fountain pen for the hop of the station.' - components: - - type: Sprite - sprite: Objects/Misc/bureaucracy.rsi - state: pen_hop - - type: entity id: BoxFolderBase parent: BoxBase diff --git a/Resources/Prototypes/Entities/Objects/Misc/pen.yml b/Resources/Prototypes/Entities/Objects/Misc/pen.yml new file mode 100644 index 0000000000..635df230a4 --- /dev/null +++ b/Resources/Prototypes/Entities/Objects/Misc/pen.yml @@ -0,0 +1,106 @@ +- type: entity + name: pen + parent: BaseItem + id: Pen + description: A dark ink pen. + components: + - type: Sprite + sprite: Objects/Misc/pens.rsi + state: pen + - type: Item + sprite: Objects/Misc/pens.rsi + heldPrefix: pen + size: Tiny + - type: Tag + tags: + - Write + - Pen + - type: PhysicalComposition + materialComposition: + Steel: 25 + +- type: entity + parent: Pen + id: PenEmbeddable + abstract: true + components: + - type: EmbeddableProjectile + offset: 0.3,0.0 + removalTime: 0.0 + - type: ThrowingAngle + angle: 315 + - type: DamageOtherOnHit + damage: + types: + Piercing: 3 + +#TODO: I want the luxury pen to write a cool font like Merriweather in the future. + +- type: entity + name: luxury pen + parent: Pen + id: LuxuryPen + description: A fancy and expensive pen that you only deserve to own if you're qualified to handle vast amounts of paperwork. + components: + - type: Sprite + state: luxury_pen + - type: Item + heldPrefix: luxury_pen + +- type: entity + name: Cybersun pen + parent: PenEmbeddable + id: CyberPen + description: A high-tech pen straight from Cybersun's legal department, capable of refracting hard-light at impossible angles through its diamond tip in order to write. So powerful, it's even able to rewrite officially stamped documents should the need arise. + components: + - type: Tag + tags: + - Write + - WriteIgnoreStamps + - Pickaxe + - Pen + - type: Sprite + state: overpriced_pen + - type: Item + heldPrefix: overpriced_pen + - type: MeleeWeapon + wideAnimationRotation: -45 + damage: + types: + Piercing: 15 + soundHit: + path: /Audio/Weapons/bladeslice.ogg + - type: Tool + qualities: + - Screwing + useSound: + collection: Screwdriver + +- type: entity + name: captain's fountain pen + parent: PenEmbeddable + id: PenCap + description: A luxurious fountain pen for the captain of the station. + components: + - type: Sprite + state: pen_cap + +- type: entity + name: CentCom pen + parent: CyberPen + id: PenCentcom + description: In an attempt to keep up with the "power" of the cybersun bureaucracy, NT made a replica of cyber pen, in their corporate style. + components: + - type: Sprite + state: pen_centcom + - type: Item + heldPrefix: pen_centcom + +- type: entity + name: hop's fountain pen + parent: PenEmbeddable + id: PenHop + description: A luxurious fountain pen for the hop of the station. + components: + - type: Sprite + state: pen_hop diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json b/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json index 91602db51e..d62baa885d 100644 --- a/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json +++ b/Resources/Textures/Objects/Misc/bureaucracy.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/e1142f20f5e4661cb6845cfcf2dd69f864d67432. paper_stamp-syndicate by Veritius. paper_receipt, paper_receipt_horizontal by eoineoineoin. pen_centcom is a resprited version of pen_cap by PuroSlavKing (Github). Luxury pen is drawn by Ubaser.", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/e1142f20f5e4661cb6845cfcf2dd69f864d67432. paper_stamp-syndicate by Veritius. paper_receipt, paper_receipt_horizontal by eoineoineoin.", "size": { "x": 32, "y": 32 @@ -159,38 +159,6 @@ { "name": "paper_dotmatrix_words" }, - { - "name": "pen" - }, - { - "name": "pen_cap" - }, - { - "name": "pen_centcom" - }, - { - "name": "pen_hop" - }, - { - "name": "overpriced_pen" - }, - { - "name": "luxury_pen" - }, - { - "name": "pen_blue" - }, - { - "name": "pen_red" - }, - { - "name": "pen-inhand-left", - "directions": 4 - }, - { - "name": "pen-inhand-right", - "directions": 4 - }, { "name": "scrap" }, diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/luxury_pen.png b/Resources/Textures/Objects/Misc/pens.rsi/luxury_pen.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/luxury_pen.png rename to Resources/Textures/Objects/Misc/pens.rsi/luxury_pen.png diff --git a/Resources/Textures/Objects/Misc/pens.rsi/meta.json b/Resources/Textures/Objects/Misc/pens.rsi/meta.json new file mode 100644 index 0000000000..738bc09ee3 --- /dev/null +++ b/Resources/Textures/Objects/Misc/pens.rsi/meta.json @@ -0,0 +1,59 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from tgstation at https://github.com/tgstation/tgstation/commit/e1142f20f5e4661cb6845cfcf2dd69f864d67432. pen_centcom is a resprited version of pen_cap by PuroSlavKing (Github). Luxury pen is drawn by Ubaser.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "pen" + }, + { + "name": "pen_cap" + }, + { + "name": "pen_centcom" + }, + { + "name": "pen_hop" + }, + { + "name": "overpriced_pen" + }, + { + "name": "luxury_pen" + }, + { + "name": "pen_blue" + }, + { + "name": "pen_red" + }, + { + "name": "pen-inhand-left", + "directions": 4 + }, + { + "name": "pen-inhand-right", + "directions": 4 + }, + { + "name": "overpriced_pen-inhand-left", + "directions": 4 + }, + { + "name": "overpriced_pen-inhand-right", + "directions": 4 + }, + { + "name": "pen_centcom-inhand-left", + "directions": 4 + }, + { + "name": "pen_centcom-inhand-right", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen-inhand-left.png b/Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..55b4fe1bd217b7459f37f795581b367b4add32c8 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAP;j27 zi(^Pd+}m3lc^eFPSPr~7Dv@(kBc#XSB+DA+DIp?dN|7%v{Xe~PNl7*zBNGdUfPzB< z0}>;$vC?{d&T;GeyVpO@*|m>lS*q{fmYjV@UdvQ-E4mb`>g94^(S>AAkI)8Z1FvmW o@Ab<#7M%d%q9Uklqx%E4JNe=nE93qx0lJjI)78&qol`;+0DhuI6aWAK literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen-inhand-right.png b/Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen-inhand-right.png new file mode 100644 index 0000000000000000000000000000000000000000..22fd23b6ed80f780242d0db48aecaaaaf8df52dd GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAP;j27 zi(^Pd+}oQQc^eFPSPr~7Dv@(kBc#XSB+D9RQD3el8ojx(uRMO*Yfp_X<`7VDXkcJu zVnJfOV7>OZ&S+)IY3b`_H@}5Uey_UxQ+&F2?7zb+E-Ak=pV)(@9@zwkM8@CW4;_|W uWwy0mzDn~$>hJFd4h!}|b$n3&!1Q~$c!uT1PnUr%W$<+Mb6Mw<&;$TcPD@|_ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/overpriced_pen.png b/Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/overpriced_pen.png rename to Resources/Textures/Objects/Misc/pens.rsi/overpriced_pen.png diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen-inhand-left.png b/Resources/Textures/Objects/Misc/pens.rsi/pen-inhand-left.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen-inhand-left.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen-inhand-left.png diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen-inhand-right.png b/Resources/Textures/Objects/Misc/pens.rsi/pen-inhand-right.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen-inhand-right.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen-inhand-right.png diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen.png b/Resources/Textures/Objects/Misc/pens.rsi/pen.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen.png diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_blue.png b/Resources/Textures/Objects/Misc/pens.rsi/pen_blue.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_blue.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen_blue.png diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_cap.png b/Resources/Textures/Objects/Misc/pens.rsi/pen_cap.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_cap.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen_cap.png diff --git a/Resources/Textures/Objects/Misc/pens.rsi/pen_centcom-inhand-left.png b/Resources/Textures/Objects/Misc/pens.rsi/pen_centcom-inhand-left.png new file mode 100644 index 0000000000000000000000000000000000000000..2fee5064648181a69cbd042d11157908da7e46c8 GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=oCO|{#S9F5M?jcysy3fAP;jcJ zi(^Pd+}m3l1sfE2STE>2-O%^Mt?X7%q(IT}qwe$TpRj6mY~T=3aA;s)WMV;LcyP}- zKKYykbJ%m;yK^@1H@8mx*^LqPFZjjWJUaHLeB-n+uppc2Re(v)78&qol`;+04!NW3jhEB literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_centcom.png b/Resources/Textures/Objects/Misc/pens.rsi/pen_centcom.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_centcom.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen_centcom.png diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_hop.png b/Resources/Textures/Objects/Misc/pens.rsi/pen_hop.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_hop.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen_hop.png diff --git a/Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_red.png b/Resources/Textures/Objects/Misc/pens.rsi/pen_red.png similarity index 100% rename from Resources/Textures/Objects/Misc/bureaucracy.rsi/pen_red.png rename to Resources/Textures/Objects/Misc/pens.rsi/pen_red.png From 0525c63332d31a3ae4836a9fc8cc77c19f9f688e Mon Sep 17 00:00:00 2001 From: double_b <40827162+benjamin-burges@users.noreply.github.com> Date: Sat, 18 May 2024 14:23:16 +0000 Subject: [PATCH 06/19] Resolves Bible summon message being sent to all users (#28104) * Changed PopupEntity overload used to ensure message is only sent to user * Updated uid for PopupEntity call * Updating _popupSystem.PopupEntity call in AttemptSummon --- Content.Server/Bible/BibleSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Bible/BibleSystem.cs b/Content.Server/Bible/BibleSystem.cs index c845b17230..0c60e40dac 100644 --- a/Content.Server/Bible/BibleSystem.cs +++ b/Content.Server/Bible/BibleSystem.cs @@ -241,7 +241,7 @@ namespace Content.Server.Bible // If this is going to use a ghost role mob spawner, attach it to the bible. if (HasComp(familiar)) { - _popupSystem.PopupEntity(Loc.GetString("bible-summon-requested"), user, PopupType.Medium); + _popupSystem.PopupEntity(Loc.GetString("bible-summon-requested"), user, user, PopupType.Medium); _transform.SetParent(familiar, uid); } component.AlreadySummoned = true; From 8bbd2394efa4ad53b641e785c3d4ca0837d1e67e Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 18 May 2024 14:24:24 +0000 Subject: [PATCH 07/19] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 6ad80313b3..9ba439bc51 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Pod launches will now be offset slightly. - type: Add - id: 6102 - time: '2024-03-06T01:44:26.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/25855 - author: Brandon-Huu changes: - message: The Syndicate is now supplying barber scissors in the Hristov bundle @@ -3865,3 +3858,11 @@ id: 6601 time: '2024-05-17T19:46:45.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28083 +- author: benjamin-burges + changes: + - message: Bible summon messages are now only visible to the chaplain using the + Bible. + type: Tweak + id: 6602 + time: '2024-05-18T14:23:17.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28104 From 225a05ecdb2823efeb448188ce369c577976fe4c Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 18 May 2024 19:17:46 +0300 Subject: [PATCH 08/19] Nuke spaceshroom ore (#28110) nuke spaceshroom ore --- .../Components/GatherableComponent.cs | 18 +++++++++---- .../Gatherable/GatherableSystem.Projectile.cs | 14 +++++----- Content.Server/Gatherable/GatherableSystem.cs | 27 ++++++++----------- .../Entities/Objects/Misc/spaceshroom.yml | 15 +++++++---- .../Entities/Structures/Walls/asteroid.yml | 2 +- Resources/Prototypes/ore.yml | 4 --- 6 files changed, 41 insertions(+), 39 deletions(-) diff --git a/Content.Server/Gatherable/Components/GatherableComponent.cs b/Content.Server/Gatherable/Components/GatherableComponent.cs index f1d0c6ef74..5480f4404f 100644 --- a/Content.Server/Gatherable/Components/GatherableComponent.cs +++ b/Content.Server/Gatherable/Components/GatherableComponent.cs @@ -1,4 +1,6 @@ +using Content.Shared.EntityList; using Content.Shared.Whitelist; +using Robust.Shared.Prototypes; namespace Content.Server.Gatherable.Components; @@ -10,7 +12,7 @@ public sealed partial class GatherableComponent : Component /// Whitelist for specifying the kind of tools can be used on a resource /// Supports multiple tags. /// - [DataField("whitelist", required: true)] + [DataField(required: true)] public EntityWhitelist? ToolWhitelist; /// @@ -18,14 +20,20 @@ public sealed partial class GatherableComponent : Component /// (Tag1, Tag2, LootTableID1, LootTableID2 are placeholders for example) /// -------------------- /// useMappedLoot: true - /// whitelist: + /// toolWhitelist: /// tags: /// - Tag1 /// - Tag2 - /// mappedLoot: + /// loot: /// Tag1: LootTableID1 /// Tag2: LootTableID2 /// - [DataField("loot")] - public Dictionary? MappedLoot = new(); + [DataField] + public Dictionary>? Loot = new(); + + /// + /// Random shift of the appearing entity during gathering + /// + [DataField] + public float GatherOffset = 0.3f; } diff --git a/Content.Server/Gatherable/GatherableSystem.Projectile.cs b/Content.Server/Gatherable/GatherableSystem.Projectile.cs index f773ca2dbb..3ab8872fd7 100644 --- a/Content.Server/Gatherable/GatherableSystem.Projectile.cs +++ b/Content.Server/Gatherable/GatherableSystem.Projectile.cs @@ -1,7 +1,5 @@ using Content.Server.Gatherable.Components; -using Content.Server.Projectiles; using Content.Shared.Projectiles; -using Content.Shared.Weapons.Ranged.Systems; using Robust.Shared.Physics.Events; namespace Content.Server.Gatherable; @@ -13,20 +11,20 @@ public sealed partial class GatherableSystem SubscribeLocalEvent(OnProjectileCollide); } - private void OnProjectileCollide(EntityUid uid, GatheringProjectileComponent component, ref StartCollideEvent args) + private void OnProjectileCollide(Entity gathering, ref StartCollideEvent args) { if (!args.OtherFixture.Hard || args.OurFixtureId != SharedProjectileSystem.ProjectileFixture || - component.Amount <= 0 || + gathering.Comp.Amount <= 0 || !TryComp(args.OtherEntity, out var gatherable)) { return; } - Gather(args.OtherEntity, uid, gatherable); - component.Amount--; + Gather(args.OtherEntity, gathering, gatherable); + gathering.Comp.Amount--; - if (component.Amount <= 0) - QueueDel(uid); + if (gathering.Comp.Amount <= 0) + QueueDel(gathering); } } diff --git a/Content.Server/Gatherable/GatherableSystem.cs b/Content.Server/Gatherable/GatherableSystem.cs index 11295bb3a3..44e60cb102 100644 --- a/Content.Server/Gatherable/GatherableSystem.cs +++ b/Content.Server/Gatherable/GatherableSystem.cs @@ -1,11 +1,9 @@ using Content.Server.Destructible; using Content.Server.Gatherable.Components; -using Content.Shared.EntityList; using Content.Shared.Interaction; using Content.Shared.Tag; using Content.Shared.Weapons.Melee.Events; using Robust.Server.GameObjects; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -14,7 +12,7 @@ namespace Content.Server.Gatherable; public sealed partial class GatherableSystem : EntitySystem { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly DestructibleSystem _destructible = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; @@ -30,20 +28,20 @@ public sealed partial class GatherableSystem : EntitySystem InitializeProjectile(); } - private void OnAttacked(EntityUid uid, GatherableComponent component, AttackedEvent args) + private void OnAttacked(Entity gatherable, ref AttackedEvent args) { - if (component.ToolWhitelist?.IsValid(args.Used, EntityManager) != true) + if (gatherable.Comp.ToolWhitelist?.IsValid(args.Used, EntityManager) != true) return; - Gather(uid, args.User, component); + Gather(gatherable, args.User); } - private void OnActivate(EntityUid uid, GatherableComponent component, ActivateInWorldEvent args) + private void OnActivate(Entity gatherable, ref ActivateInWorldEvent args) { - if (component.ToolWhitelist?.IsValid(args.User, EntityManager) != true) + if (gatherable.Comp.ToolWhitelist?.IsValid(args.User, EntityManager) != true) return; - Gather(uid, args.User, component); + Gather(gatherable, args.User); } public void Gather(EntityUid gatheredUid, EntityUid? gatherer = null, GatherableComponent? component = null) @@ -60,25 +58,22 @@ public sealed partial class GatherableSystem : EntitySystem _destructible.DestroyEntity(gatheredUid); // Spawn the loot! - if (component.MappedLoot == null) + if (component.Loot == null) return; var pos = _transform.GetMapCoordinates(gatheredUid); - foreach (var (tag, table) in component.MappedLoot) + foreach (var (tag, table) in component.Loot) { if (tag != "All") { if (gatherer != null && !_tagSystem.HasTag(gatherer.Value, tag)) continue; } - var getLoot = _prototypeManager.Index(table); + var getLoot = _proto.Index(table); var spawnLoot = getLoot.GetSpawns(_random); - var spawnPos = pos.Offset(_random.NextVector2(0.3f)); + var spawnPos = pos.Offset(_random.NextVector2(component.GatherOffset)); Spawn(spawnLoot[0], spawnPos); } } } - - - diff --git a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml index 9ec6ce0ed1..1571787715 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/spaceshroom.yml @@ -19,14 +19,12 @@ !type:PhysShapeCircle radius: 0.2 - type: InteractionOutline - # TODO: Nuke this shit - - type: OreVein - oreChance: 1.0 - currentOre: SpaceShrooms - type: Gatherable - whitelist: + toolWhitelist: components: - Hands + loot: + All: SpaceshroomGather - type: Damageable damageContainer: Inorganic damageModifierSet: Wood @@ -39,6 +37,13 @@ - !type:DoActsBehavior acts: [ "Destruction" ] +- type: entityLootTable + id: SpaceshroomGather + entries: + - id: FoodSpaceshroom + amount: 1 + maxAmount: 1 + - type: entity name: spaceshroom parent: FoodProduceBase diff --git a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml index a8cb0b1cb8..c6c3692e59 100644 --- a/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml +++ b/Resources/Prototypes/Entities/Structures/Walls/asteroid.yml @@ -375,7 +375,7 @@ noRot: true - type: SoundOnGather - type: Gatherable - whitelist: + toolWhitelist: tags: - Pickaxe - type: Damageable diff --git a/Resources/Prototypes/ore.yml b/Resources/Prototypes/ore.yml index dde1516c85..84d1c66736 100644 --- a/Resources/Prototypes/ore.yml +++ b/Resources/Prototypes/ore.yml @@ -1,9 +1,5 @@ # TODO: Kill ore veins # Split it into 2 components, 1 for "spawn XYZ on destruction" and 1 for "randomly select one of these for spawn on destruction" -# You could even just use an entityspawncollection instead. -- type: ore - id: SpaceShrooms - oreEntity: FoodSpaceshroom # High yields - type: ore From bad3bb4a89736b7b8b343dc14e0d0259ab7e45a1 Mon Sep 17 00:00:00 2001 From: Tayrtahn Date: Sat, 18 May 2024 12:20:00 -0400 Subject: [PATCH 09/19] Random book story generator refactor (#28082) * Randomized book overhaul * Fix prototype names * Improved setting paper content * Praise Ratvar --- .../Paper/PaperRandomStoryComponent.cs | 13 +- .../Paper/PaperRandomStorySystem.cs | 12 +- .../EntitySystems/StoryGeneratorSystem.cs | 54 +++++ .../Prototypes/StoryTemplatePrototype.cs | 33 +++ .../Locale/en-US/paper/story-generation.ftl | 72 +++---- .../Locale/en-US/storygen/story-template.ftl | 4 + .../Prototypes/Datasets/story_generation.yml | 204 +++++++++--------- .../Entities/Objects/Misc/books.yml | 32 +-- .../Prototypes/StoryGen/story-templates.yml | 16 ++ 9 files changed, 261 insertions(+), 179 deletions(-) create mode 100644 Content.Shared/StoryGen/EntitySystems/StoryGeneratorSystem.cs create mode 100644 Content.Shared/StoryGen/Prototypes/StoryTemplatePrototype.cs create mode 100644 Resources/Locale/en-US/storygen/story-template.ftl create mode 100644 Resources/Prototypes/StoryGen/story-templates.yml diff --git a/Content.Server/Paper/PaperRandomStoryComponent.cs b/Content.Server/Paper/PaperRandomStoryComponent.cs index 7c5744f087..b8e07f0ee8 100644 --- a/Content.Server/Paper/PaperRandomStoryComponent.cs +++ b/Content.Server/Paper/PaperRandomStoryComponent.cs @@ -1,14 +1,17 @@ +using Content.Shared.StoryGen; +using Robust.Shared.Prototypes; + namespace Content.Server.Paper; /// -/// Adds randomly generated stories to Paper component +/// Adds a randomly generated story to the content of a /// [RegisterComponent, Access(typeof(PaperRandomStorySystem))] public sealed partial class PaperRandomStoryComponent : Component { + /// + /// The ID to use for story generation. + /// [DataField] - public List? StorySegments; - - [DataField] - public string StorySeparator = " "; + public ProtoId Template; } diff --git a/Content.Server/Paper/PaperRandomStorySystem.cs b/Content.Server/Paper/PaperRandomStorySystem.cs index e7712009c2..156718f545 100644 --- a/Content.Server/Paper/PaperRandomStorySystem.cs +++ b/Content.Server/Paper/PaperRandomStorySystem.cs @@ -1,11 +1,11 @@ -using Content.Server.RandomMetadata; +using Content.Shared.StoryGen; namespace Content.Server.Paper; public sealed class PaperRandomStorySystem : EntitySystem { - - [Dependency] private readonly RandomMetadataSystem _randomMeta = default!; + [Dependency] private readonly StoryGeneratorSystem _storyGen = default!; + [Dependency] private readonly PaperSystem _paper = default!; public override void Initialize() { @@ -19,11 +19,9 @@ public sealed class PaperRandomStorySystem : EntitySystem if (!TryComp(paperStory, out var paper)) return; - if (paperStory.Comp.StorySegments == null) + if (!_storyGen.TryGenerateStoryFromTemplate(paperStory.Comp.Template, out var story)) return; - var story = _randomMeta.GetRandomFromSegments(paperStory.Comp.StorySegments, paperStory.Comp.StorySeparator); - - paper.Content += $"\n{story}"; + _paper.SetContent(paperStory.Owner, story, paper); } } diff --git a/Content.Shared/StoryGen/EntitySystems/StoryGeneratorSystem.cs b/Content.Shared/StoryGen/EntitySystems/StoryGeneratorSystem.cs new file mode 100644 index 0000000000..51ad85730c --- /dev/null +++ b/Content.Shared/StoryGen/EntitySystems/StoryGeneratorSystem.cs @@ -0,0 +1,54 @@ +using System.Diagnostics.CodeAnalysis; +using Robust.Shared.Collections; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Shared.StoryGen; + +/// +/// Provides functionality to generate a story from a . +/// +public sealed partial class StoryGeneratorSystem : EntitySystem +{ + [Dependency] private readonly IPrototypeManager _protoMan = default!; + [Dependency] private readonly IRobustRandom _random = default!; + + /// + /// Tries to generate a random story using the given template, picking a random word from the referenced + /// datasets for each variable and passing them into the localization system with template. + /// If is specified, the randomizer will be seeded with it for consistent story generation; + /// otherwise the variables will be randomized. + /// Fails if the template prototype cannot be loaded. + /// + /// true if the template was loaded, otherwise false. + public bool TryGenerateStoryFromTemplate(ProtoId template, [NotNullWhen(true)] out string? story, int? seed = null) + { + // Get the story template prototype from the ID + if (!_protoMan.TryIndex(template, out var templateProto)) + { + story = null; + return false; + } + + // If given a seed, use it + if (seed != null) + _random.SetSeed(seed.Value); + + // Pick values for all of the variables in the template + var variables = new ValueList<(string, object)>(templateProto.Variables.Count); + foreach (var (name, list) in templateProto.Variables) + { + // Get the prototype for the world list dataset + if (!_protoMan.TryIndex(list, out var listProto)) + continue; // Missed one, but keep going with the rest of the story + + // Pick a random word from the dataset and localize it + var chosenWord = Loc.GetString(_random.Pick(listProto.Values)); + variables.Add((name, chosenWord)); + } + + // Pass the variables to the localization system and build the story + story = Loc.GetString(templateProto.LocId, variables.ToArray()); + return true; + } +} diff --git a/Content.Shared/StoryGen/Prototypes/StoryTemplatePrototype.cs b/Content.Shared/StoryGen/Prototypes/StoryTemplatePrototype.cs new file mode 100644 index 0000000000..7f6afacccc --- /dev/null +++ b/Content.Shared/StoryGen/Prototypes/StoryTemplatePrototype.cs @@ -0,0 +1,33 @@ +using Content.Shared.Dataset; +using Robust.Shared.Prototypes; + +namespace Content.Shared.StoryGen; + +/// +/// Prototype for a story template that can be filled in with words chosen from s. +/// +[Serializable, Prototype("storyTemplate")] +public sealed partial class StoryTemplatePrototype : IPrototype +{ + /// + /// Identifier for this prototype instance. + /// + [ViewVariables] + [IdDataField] + public string ID { get; private set; } = default!; + + /// + /// Localization ID of the Fluent string that forms the structure of this story. + /// + [DataField(required: true)] + public LocId LocId { get; } = default!; + + /// + /// Dictionary containing the name of each variable to pass to the template and the ID of the + /// from which a random entry will be selected as its value. + /// For example, name: book_character will pick a random entry from the book_character + /// dataset which can then be used in the template by {$name}. + /// + [DataField] + public Dictionary> Variables { get; } = default!; +} diff --git a/Resources/Locale/en-US/paper/story-generation.ftl b/Resources/Locale/en-US/paper/story-generation.ftl index bcd1c8901e..94ecbc3caa 100644 --- a/Resources/Locale/en-US/paper/story-generation.ftl +++ b/Resources/Locale/en-US/paper/story-generation.ftl @@ -86,7 +86,7 @@ story-gen-book-character29 = space dragon story-gen-book-character30 = revolutionary story-gen-book-character31 = nuclear operative story-gen-book-character32 = narsie cultist -story-gen-book-character33 = ratwar cultist +story-gen-book-character33 = ratvar cultist story-gen-book-character34 = greytider story-gen-book-character35 = arachnid story-gen-book-character36 = vox @@ -98,7 +98,7 @@ story-gen-book-character40 = slime story-gen-book-character-trait1 = stupid story-gen-book-character-trait2 = smart story-gen-book-character-trait3 = funny -story-gen-book-character-trait4 = attractive +story-gen-book-character-trait4 = attractive story-gen-book-character-trait5 = charming story-gen-book-character-trait6 = nasty story-gen-book-character-trait7 = dying @@ -113,7 +113,7 @@ story-gen-book-character-trait15 = сharismatic story-gen-book-character-trait16 = stoic story-gen-book-character-trait17 = cute story-gen-book-character-trait18 = dwarven -story-gen-book-character-trait19 = beer-smelling +story-gen-book-character-trait19 = beer-smelling story-gen-book-character-trait20 = joyful story-gen-book-character-trait21 = painfully beautiful story-gen-book-character-trait22 = robotic @@ -121,20 +121,20 @@ story-gen-book-character-trait23 = holographic story-gen-book-character-trait24 = hysterically laughing story-gen-book-event1 = a zombie outbreak -story-gen-book-event2 = a nuclear explosion +story-gen-book-event2 = a nuclear explosion story-gen-book-event3 = a mass murder story-gen-book-event4 = a sudden depressurization story-gen-book-event5 = a blackout -story-gen-book-event6 = the starvation of the protagonists +story-gen-book-event6 = the protagonists nearly starving story-gen-book-event7 = a wasting illness story-gen-book-event8 = love at first sight story-gen-book-event9 = a rush of inspiration -story-gen-book-event10 = the occurrence of some mystical phenomena +story-gen-book-event10 = some mystical phenomena story-gen-book-event11 = divine intervention story-gen-book-event12 = the characters' own selfish motives story-gen-book-event13 = an unforeseen deception -story-gen-book-event14 = the resurrection of one of these characters from the dead -story-gen-book-event15 = the terrible torture of the protagonist +story-gen-book-event14 = the resurrection of one of the characters from the dead +story-gen-book-event15 = the brutal torture of the protagonists story-gen-book-event16 = the inadvertent loosing of a gravitational singularity story-gen-book-event17 = a psychic prediction of future events story-gen-book-event18 = an antimatter explosion @@ -145,31 +145,31 @@ story-gen-book-event22 = having a quarrel with a close friend story-gen-book-event23 = the sudden loss of their home in a fiery blaze story-gen-book-event24 = the loss of a PDA -story-gen-book-action1 = share in a kiss with a -story-gen-book-action2 = strangle to death a -story-gen-book-action3 = manage to blow apart a -story-gen-book-action4 = manage to win a game of chess against a -story-gen-book-action5 = narrowly lose a game of chess against a -story-gen-book-action6 = reveal the hidden secrets of a -story-gen-book-action7 = manipulate a -story-gen-book-action8 = sacrifice upon an altar a -story-gen-book-action9 = attend the wedding of a -story-gen-book-action10 = join forces to defeat their common enemy, a -story-gen-book-action11 = are forced to work together to escape a +story-gen-book-action1 = share in a kiss with +story-gen-book-action2 = strangle +story-gen-book-action3 = blow apart +story-gen-book-action4 = win a game of chess against +story-gen-book-action5 = lose a game of chess against +story-gen-book-action6 = reveal the hidden secrets of +story-gen-book-action7 = manipulate +story-gen-book-action8 = sacrifice a hamster to +story-gen-book-action9 = infiltrate the wedding of +story-gen-book-action10 = join forces to defeat their common enemy, +story-gen-book-action11 = are forced to work together to escape story-gen-book-action12 = give a valuable gift to -story-gen-book-action-trait1 = terribly -story-gen-book-action-trait2 = disgustingly +story-gen-book-action-trait1 = clumsily +story-gen-book-action-trait2 = disgustingly story-gen-book-action-trait3 = marvelously story-gen-book-action-trait4 = nicely story-gen-book-action-trait5 = weirdly story-gen-book-action-trait6 = amusingly story-gen-book-action-trait7 = fancifully story-gen-book-action-trait8 = impressively -story-gen-book-action-trait9 = irresponsibly -story-gen-book-action-trait10 = severely -story-gen-book-action-trait11 = ruthlessly -story-gen-book-action-trait12 = playfully +story-gen-book-action-trait9 = irresponsibly +story-gen-book-action-trait10 = severely +story-gen-book-action-trait11 = ruthlessly +story-gen-book-action-trait12 = playfully story-gen-book-action-trait13 = thoughtfully story-gen-book-location1 = in an underground complex @@ -178,7 +178,7 @@ story-gen-book-location3 = while trapped in outer space story-gen-book-location4 = while in a news office story-gen-book-location5 = in a hidden garden story-gen-book-location6 = in the kitchen of a local restaurant -story-gen-book-location7 = under the counter of the local sports bar +story-gen-book-location7 = under the counter of the local sports bar story-gen-book-location8 = in an ancient library story-gen-book-location9 = while deep in bowels of the space station's maintenance corridors story-gen-book-location10 = on the bridge of a starship @@ -192,7 +192,7 @@ story-gen-book-location17 = standing too close to an anomaly story-gen-book-location18 = while huddling on the evacuation shuttle story-gen-book-location19 = standing in freshly fallen snow story-gen-book-location20 = lost in the woods -story-gen-book-location21 = iin the harsh desert +story-gen-book-location21 = in the harsh desert story-gen-book-location22 = worrying about their social media networks story-gen-book-location23 = atop of a mountain story-gen-book-location24 = while driving a car @@ -207,15 +207,15 @@ story-gen-book-location32 = while trapped in a shadow dimension story-gen-book-location33 = while trying to escape a destroyed space station story-gen-book-location34 = while sandwiched between a Tesla ball and a gravitational singularity -story-gen-book-element1 = The plot -story-gen-book-element2 = The twist -story-gen-book-element3 = The climax -story-gen-book-element4 = The final act -story-gen-book-element5 = The ending -story-gen-book-element6 = The moral of the story -story-gen-book-element7 = The theme of this work -story-gen-book-element8 = The literary style -story-gen-book-element9 = The illustrations +story-gen-book-element1 = plot +story-gen-book-element2 = twist +story-gen-book-element3 = climax +story-gen-book-element4 = final act +story-gen-book-element5 = ending +story-gen-book-element6 = moral of the story +story-gen-book-element7 = theme of this work +story-gen-book-element8 = literary style +story-gen-book-element9 = artwork story-gen-book-element-trait1 = terrifying story-gen-book-element-trait2 = disgusting diff --git a/Resources/Locale/en-US/storygen/story-template.ftl b/Resources/Locale/en-US/storygen/story-template.ftl new file mode 100644 index 0000000000..b535e2fd95 --- /dev/null +++ b/Resources/Locale/en-US/storygen/story-template.ftl @@ -0,0 +1,4 @@ +story-template-generic = + This is { INDEFINITE($bookGenre) } {$bookGenre} about { INDEFINITE($char1Adj) } {$char1Adj} {$char1Type} and { INDEFINITE($char2Adj) } {$char2Adj} {$char2Type}. Due to {$event}, they {$actionTrait} {$action} { INDEFINITE($char3Type) } {$char3Type} {$location}. + + The {$element} is {$elementTrait}. diff --git a/Resources/Prototypes/Datasets/story_generation.yml b/Resources/Prototypes/Datasets/story_generation.yml index 1083a6acdb..1a461c7596 100644 --- a/Resources/Prototypes/Datasets/story_generation.yml +++ b/Resources/Prototypes/Datasets/story_generation.yml @@ -1,31 +1,31 @@ - type: dataset - id: book_type + id: BookTypes values: - - story-gen-book-type1 - - story-gen-book-type2 - - story-gen-book-type3 - - story-gen-book-type4 - - story-gen-book-type5 - - story-gen-book-type6 - - story-gen-book-type7 - - story-gen-book-type8 - - story-gen-book-type9 + - story-gen-book-type1 + - story-gen-book-type2 + - story-gen-book-type3 + - story-gen-book-type4 + - story-gen-book-type5 + - story-gen-book-type6 + - story-gen-book-type7 + - story-gen-book-type8 + - story-gen-book-type9 - story-gen-book-type10 - story-gen-book-type11 - story-gen-book-type12 - type: dataset - id: book_genre + id: BookGenres values: - - story-gen-book-genre1 - - story-gen-book-genre2 - - story-gen-book-genre3 - - story-gen-book-genre4 - - story-gen-book-genre5 - - story-gen-book-genre6 - - story-gen-book-genre7 - - story-gen-book-genre8 - - story-gen-book-genre9 + - story-gen-book-genre1 + - story-gen-book-genre2 + - story-gen-book-genre3 + - story-gen-book-genre4 + - story-gen-book-genre5 + - story-gen-book-genre6 + - story-gen-book-genre7 + - story-gen-book-genre8 + - story-gen-book-genre9 - story-gen-book-genre10 - story-gen-book-genre11 - story-gen-book-genre12 @@ -33,17 +33,17 @@ - story-gen-book-genre14 - type: dataset - id: book_hint_appearance + id: BookHintAppearances values: - - story-gen-book-appearance1 - - story-gen-book-appearance2 - - story-gen-book-appearance3 - - story-gen-book-appearance4 - - story-gen-book-appearance5 - - story-gen-book-appearance6 - - story-gen-book-appearance7 - - story-gen-book-appearance8 - - story-gen-book-appearance9 + - story-gen-book-appearance1 + - story-gen-book-appearance2 + - story-gen-book-appearance3 + - story-gen-book-appearance4 + - story-gen-book-appearance5 + - story-gen-book-appearance6 + - story-gen-book-appearance7 + - story-gen-book-appearance8 + - story-gen-book-appearance9 - story-gen-book-appearance10 - story-gen-book-appearance11 - story-gen-book-appearance12 @@ -64,17 +64,17 @@ - story-gen-book-appearance27 - type: dataset - id: book_character + id: BookCharacters values: - - story-gen-book-character1 - - story-gen-book-character2 - - story-gen-book-character3 - - story-gen-book-character4 - - story-gen-book-character5 - - story-gen-book-character6 - - story-gen-book-character7 - - story-gen-book-character8 - - story-gen-book-character9 + - story-gen-book-character1 + - story-gen-book-character2 + - story-gen-book-character3 + - story-gen-book-character4 + - story-gen-book-character5 + - story-gen-book-character6 + - story-gen-book-character7 + - story-gen-book-character8 + - story-gen-book-character9 - story-gen-book-character10 - story-gen-book-character11 - story-gen-book-character12 @@ -108,17 +108,17 @@ - story-gen-book-character40 - type: dataset - id: book_character_trait + id: BookCharacterTraits values: - - story-gen-book-character-trait1 - - story-gen-book-character-trait2 - - story-gen-book-character-trait3 - - story-gen-book-character-trait4 - - story-gen-book-character-trait5 - - story-gen-book-character-trait6 - - story-gen-book-character-trait7 - - story-gen-book-character-trait8 - - story-gen-book-character-trait9 + - story-gen-book-character-trait1 + - story-gen-book-character-trait2 + - story-gen-book-character-trait3 + - story-gen-book-character-trait4 + - story-gen-book-character-trait5 + - story-gen-book-character-trait6 + - story-gen-book-character-trait7 + - story-gen-book-character-trait8 + - story-gen-book-character-trait9 - story-gen-book-character-trait10 - story-gen-book-character-trait11 - story-gen-book-character-trait12 @@ -137,17 +137,17 @@ - type: dataset - id: book_event + id: BookEvents values: - - story-gen-book-event1 - - story-gen-book-event2 - - story-gen-book-event3 - - story-gen-book-event4 - - story-gen-book-event5 - - story-gen-book-event6 - - story-gen-book-event7 - - story-gen-book-event8 - - story-gen-book-event9 + - story-gen-book-event1 + - story-gen-book-event2 + - story-gen-book-event3 + - story-gen-book-event4 + - story-gen-book-event5 + - story-gen-book-event6 + - story-gen-book-event7 + - story-gen-book-event8 + - story-gen-book-event9 - story-gen-book-event10 - story-gen-book-event11 - story-gen-book-event12 @@ -165,50 +165,50 @@ - story-gen-book-event24 - type: dataset - id: book_action + id: BookActions values: - - story-gen-book-action1 - - story-gen-book-action2 - - story-gen-book-action3 - - story-gen-book-action4 - - story-gen-book-action5 - - story-gen-book-action6 - - story-gen-book-action7 - - story-gen-book-action8 - - story-gen-book-action9 + - story-gen-book-action1 + - story-gen-book-action2 + - story-gen-book-action3 + - story-gen-book-action4 + - story-gen-book-action5 + - story-gen-book-action6 + - story-gen-book-action7 + - story-gen-book-action8 + - story-gen-book-action9 - story-gen-book-action10 - story-gen-book-action11 - story-gen-book-action12 - type: dataset - id: book_action_trait + id: BookActionTraits values: - - story-gen-book-action-trait1 - - story-gen-book-action-trait2 - - story-gen-book-action-trait3 - - story-gen-book-action-trait4 - - story-gen-book-action-trait5 - - story-gen-book-action-trait6 - - story-gen-book-action-trait7 - - story-gen-book-action-trait8 - - story-gen-book-action-trait9 + - story-gen-book-action-trait1 + - story-gen-book-action-trait2 + - story-gen-book-action-trait3 + - story-gen-book-action-trait4 + - story-gen-book-action-trait5 + - story-gen-book-action-trait6 + - story-gen-book-action-trait7 + - story-gen-book-action-trait8 + - story-gen-book-action-trait9 - story-gen-book-action-trait10 - story-gen-book-action-trait11 - story-gen-book-action-trait12 - story-gen-book-action-trait13 - type: dataset - id: book_location + id: BookLocations values: - - story-gen-book-location1 - - story-gen-book-location2 - - story-gen-book-location3 - - story-gen-book-location4 - - story-gen-book-location5 - - story-gen-book-location6 - - story-gen-book-location7 - - story-gen-book-location8 - - story-gen-book-location9 + - story-gen-book-location1 + - story-gen-book-location2 + - story-gen-book-location3 + - story-gen-book-location4 + - story-gen-book-location5 + - story-gen-book-location6 + - story-gen-book-location7 + - story-gen-book-location8 + - story-gen-book-location9 - story-gen-book-location10 - story-gen-book-location11 - story-gen-book-location12 @@ -236,7 +236,7 @@ - story-gen-book-location34 - type: dataset - id: book_story_element + id: BookStoryElements values: - story-gen-book-element1 - story-gen-book-element2 @@ -249,18 +249,18 @@ - story-gen-book-element9 - type: dataset - id: book_story_element_trait + id: BookStoryElementTraits values: - - story-gen-book-element-trait1 - - story-gen-book-element-trait2 - - story-gen-book-element-trait3 - - story-gen-book-element-trait4 - - story-gen-book-element-trait5 - - story-gen-book-element-trait6 - - story-gen-book-element-trait7 - - story-gen-book-element-trait8 - - story-gen-book-element-trait9 + - story-gen-book-element-trait1 + - story-gen-book-element-trait2 + - story-gen-book-element-trait3 + - story-gen-book-element-trait4 + - story-gen-book-element-trait5 + - story-gen-book-element-trait6 + - story-gen-book-element-trait7 + - story-gen-book-element-trait8 + - story-gen-book-element-trait9 - story-gen-book-element-trait10 - story-gen-book-element-trait11 - story-gen-book-element-trait12 - - story-gen-book-element-trait13 \ No newline at end of file + - story-gen-book-element-trait13 diff --git a/Resources/Prototypes/Entities/Objects/Misc/books.yml b/Resources/Prototypes/Entities/Objects/Misc/books.yml index 25e6bb9f94..3fc90048dd 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/books.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/books.yml @@ -361,8 +361,8 @@ components: - type: RandomMetadata nameSegments: - - book_hint_appearance - - book_type + - BookHintAppearances + - BookTypes - type: RandomSprite available: - cover: @@ -423,33 +423,7 @@ suffix: random visual, random story components: - type: PaperRandomStory - storySegments: - - "This is a " - - book_genre - - " about a " - - book_character_trait - - " " - - book_character - - " and " - - book_character_trait - - " " - - book_character - - ". Due to " - - book_event - - ", they " - - book_action_trait - - " " - - book_action - - " " - - book_character - - " " - - book_location - - ". \n\n" - - book_story_element - - " is " - - book_story_element_trait - - "." - storySeparator: "" + template: GenericStory - type: entity parent: BookBase diff --git a/Resources/Prototypes/StoryGen/story-templates.yml b/Resources/Prototypes/StoryGen/story-templates.yml new file mode 100644 index 0000000000..f05fd5afa6 --- /dev/null +++ b/Resources/Prototypes/StoryGen/story-templates.yml @@ -0,0 +1,16 @@ +- type: storyTemplate + id: GenericStory + locId: story-template-generic + variables: + bookGenre: BookGenres + char1Type: BookCharacters + char1Adj: BookCharacterTraits + char2Type: BookCharacters + char2Adj: BookCharacterTraits + event: BookEvents + action: BookActions + actionTrait: BookActionTraits + char3Type: BookCharacters + location: BookLocations + element: BookStoryElements + elementTrait: BookStoryElementTraits From bf0529df566c323820d5b7497bc55e75992f105c Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 18 May 2024 22:06:36 +0300 Subject: [PATCH 10/19] Tile variantize after deconstruct (#28118) Update TileSystem.cs --- Content.Shared/Maps/TileSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/Maps/TileSystem.cs b/Content.Shared/Maps/TileSystem.cs index d87b3ca50d..719ff8e68c 100644 --- a/Content.Shared/Maps/TileSystem.cs +++ b/Content.Shared/Maps/TileSystem.cs @@ -164,7 +164,7 @@ public sealed class TileSystem : EntitySystem } var plating = _tileDefinitionManager[tileDef.BaseTurf]; - _maps.SetTile(gridUid, mapGrid, tileRef.GridIndices, new Tile(plating.TileId)); + _maps.SetTile(gridUid, mapGrid, tileRef.GridIndices, new Tile(plating.TileId, variant: PickVariant(tileDef))); return true; } From fc11cc90acb3dd39ab67fb1b7ca6111ce4eb0bd2 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 18 May 2024 23:23:40 +0300 Subject: [PATCH 11/19] Revert "Tile variantize after deconstruct" (#28119) Revert "Tile variantize after deconstruct (#28118)" This reverts commit bf0529df566c323820d5b7497bc55e75992f105c. --- Content.Shared/Maps/TileSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/Maps/TileSystem.cs b/Content.Shared/Maps/TileSystem.cs index 719ff8e68c..d87b3ca50d 100644 --- a/Content.Shared/Maps/TileSystem.cs +++ b/Content.Shared/Maps/TileSystem.cs @@ -164,7 +164,7 @@ public sealed class TileSystem : EntitySystem } var plating = _tileDefinitionManager[tileDef.BaseTurf]; - _maps.SetTile(gridUid, mapGrid, tileRef.GridIndices, new Tile(plating.TileId, variant: PickVariant(tileDef))); + _maps.SetTile(gridUid, mapGrid, tileRef.GridIndices, new Tile(plating.TileId)); return true; } From 22aa8596dedd752883db5533ad67f777f482f80b Mon Sep 17 00:00:00 2001 From: Tayrtahn Date: Sat, 18 May 2024 20:12:47 -0400 Subject: [PATCH 12/19] Fix activatable UI popup message spam (#28123) Fixed activatable UI popup message spam --- Content.Shared/UserInterface/ActivatableUISystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/UserInterface/ActivatableUISystem.cs b/Content.Shared/UserInterface/ActivatableUISystem.cs index 3ac8835dd0..a6d27ac545 100644 --- a/Content.Shared/UserInterface/ActivatableUISystem.cs +++ b/Content.Shared/UserInterface/ActivatableUISystem.cs @@ -215,7 +215,7 @@ public sealed partial class ActivatableUISystem : EntitySystem if (aui.SingleUser && aui.CurrentSingleUser != null && user != aui.CurrentSingleUser) { var message = Loc.GetString("machine-already-in-use", ("machine", uiEntity)); - _popupSystem.PopupEntity(message, uiEntity, user); + _popupSystem.PopupClient(message, uiEntity, user); if (_uiSystem.IsUiOpen(uiEntity, aui.Key)) return true; From 9f1d95e3353493f28d579b562de348a322312885 Mon Sep 17 00:00:00 2001 From: dffdff2423 Date: Sat, 18 May 2024 19:23:44 -0500 Subject: [PATCH 13/19] Fix Flavor Text editor not saving correctly (#28122) * Check for flavor text equality in profile. * Fix some characters being deleted from flavor text Sometimes the last few characters of the flavor text would get deleted. This fixes this issue. --- Content.Client/FlavorText/FlavorText.xaml.cs | 2 +- Content.Shared/Preferences/HumanoidCharacterProfile.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Client/FlavorText/FlavorText.xaml.cs b/Content.Client/FlavorText/FlavorText.xaml.cs index ffcf653f11..91b59046a4 100644 --- a/Content.Client/FlavorText/FlavorText.xaml.cs +++ b/Content.Client/FlavorText/FlavorText.xaml.cs @@ -17,7 +17,7 @@ namespace Content.Client.FlavorText var loc = IoCManager.Resolve(); CFlavorTextInput.Placeholder = new Rope.Leaf(loc.GetString("flavor-text-placeholder")); - CFlavorTextInput.OnKeyBindDown += _ => FlavorTextChanged(); + CFlavorTextInput.OnTextChanged += _ => FlavorTextChanged(); } public void FlavorTextChanged() diff --git a/Content.Shared/Preferences/HumanoidCharacterProfile.cs b/Content.Shared/Preferences/HumanoidCharacterProfile.cs index fd679c7796..f47a3ac3db 100644 --- a/Content.Shared/Preferences/HumanoidCharacterProfile.cs +++ b/Content.Shared/Preferences/HumanoidCharacterProfile.cs @@ -387,6 +387,7 @@ namespace Content.Shared.Preferences if (!_antagPreferences.SequenceEqual(other._antagPreferences)) return false; if (!_traitPreferences.SequenceEqual(other._traitPreferences)) return false; if (!Loadouts.SequenceEqual(other.Loadouts)) return false; + if (FlavorText != other.FlavorText) return false; return Appearance.MemberwiseEquals(other.Appearance); } From 74e853ee7dc07ed222ed33c43e8bacccdd43c234 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 19 May 2024 00:24:50 +0000 Subject: [PATCH 14/19] Automatic changelog update --- Resources/Changelog/Changelog.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 9ba439bc51..e4b72cd303 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Brandon-Huu - changes: - - message: The Syndicate is now supplying barber scissors in the Hristov bundle - to make your disguises even balde- better. - type: Tweak - id: 6103 - time: '2024-03-06T02:03:08.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/25695 - author: Tayrtahn changes: - message: Flasks can once again be put into dispensers. @@ -3866,3 +3858,12 @@ id: 6602 time: '2024-05-18T14:23:17.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28104 +- author: Aquif + changes: + - message: Changing your character's description now properly updates the save button. + type: Fix + - message: The character description editor does not discard your last edit anymore. + type: Fix + id: 6603 + time: '2024-05-19T00:23:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28122 From 676fc22eb478aabaf8a1e27bafd38e306e8ac91b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 03:33:41 +0200 Subject: [PATCH 15/19] Update Credits (#28124) Co-authored-by: PJBot --- Resources/Credits/GitHub.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Credits/GitHub.txt b/Resources/Credits/GitHub.txt index 5344b6a2db..172dd2ad37 100644 --- a/Resources/Credits/GitHub.txt +++ b/Resources/Credits/GitHub.txt @@ -1 +1 @@ -0x6273, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 4dplanner, 612git, 778b, Ablankmann, Acruid, actioninja, adamsong, Admiral-Obvious-001, Adrian16199, Aerocrux, Aexxie, Afrokada, Agoichi, Ahion, AJCM-git, AjexRose, Alekshhh, AlexMorgan3817, AlexUm418, AlmondFlour, AlphaQwerty, Altoids1, amylizzle, ancientpower, ArchPigeon, Arendian, arimah, Arteben, AruMoon, as334, AsikKEsel, asperger-sind, avghdev, AzzyIsNotHere, BananaFlambe, Baptr0b0t, BasedUser, beck-thompson, BellwetherLogic, BGare, BingoJohnson-zz, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, Boaz1111, BobdaBiscuit, brainfood1183, Brandon-Huu, Bright0, brndd, BubblegumBlue, BYONDFuckery, c4llv07e, CakeQ, Callmore, CaptainSqrBeard, Carbonhell, casperr04, CatTheSystem, Centronias, chairbender, Charlese2, Cheackraze, cheesePizza2, Chief-Engineer, chromiumboy, Chronophylos, Ciac32, clement-or, Clyybber, Cojoke-dot, ColdAutumnRain, collinlunn, ComicIronic, coolmankid12345, corentt, crazybrain23, creadth, CrigCrag, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, Daemon, daerSeebaer, dahnte, dakamakat, dakimasu, DamianX, DangerRevolution, daniel-cr, Darkenson, DawBla, dch-GH, Deahaka, DEATHB4DEFEAT, DeathCamel58, deathride58, DebugOk, Decappi, deepdarkdepths, deepy, Delete69, deltanedas, DerbyX, Doctor-Cpu, DoctorBeard, DogZeroX, dontbetank, Doru991, DoubleRiceEddiedd, DoutorWhite, DrMelon, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, DuskyJay, Dutch-VanDerLinde, Easypoller, eclips_e, EdenTheLiznerd, EEASAS, Efruit, ElectroSR, elthundercloud, Emisse, EmoGarbage404, Endecc, enumerate0, eoineoineoin, ERORR404V1, Errant-4, estacaoespacialpirata, exincore, exp111, Fahasor, FairlySadPanda, ficcialfaint, Fildrance, FillerVK, Fishfish458, Flareguy, FluffiestFloof, FluidRock, FoLoKe, fooberticus, Fortune117, freeman2651, Froffy025, Fromoriss, FungiFellow, GalacticChimp, gbasood, Geekyhobo, Genkail, Ghagliiarghii, Git-Nivrak, github-actions[bot], gituhabu, GNF54, Golinth, GoodWheatley, Gotimanga, graevy, GreyMario, gusxyz, Gyrandola, h3half, Hanzdegloker, Hardly3D, harikattar, Hebiman, Henry12116, HerCoyote23, hitomishirichan, Hmeister-real, HoofedEar, hord-brayden, hubismal, Hugal31, Huxellberger, Hyenh, iacore, IamVelcroboy, icekot8, igorsaux, ike709, Illiux, Ilya246, IlyaElDunaev, Injazz, Insineer, IntegerTempest, Interrobang01, IProduceWidgets, ItsMeThom, j-giebel, Jackal298, Jackrost, jamessimo, janekvap, Jark255, JerryImMouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JoeHammad1844, joelhed, JohnGinnane, johnku1, joshepvodka, jproads, Jrpl, juliangiebel, JustArt1m, JustCone14, JustinTether, JustinTrotter, K-Dynamic, Kadeo64, KaiShibaa, kalane15, kalanosh, Keer-Sar, KEEYNy, Keikiru, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, KingFroozy, kira-er, Kit0vras, KittenColony, Kmc2000, Ko4ergaPunk, komunre, koteq, Krunklehorn, Kukutis96513, kxvvv, Lamrr, LankLTE, lapatison, Leander-0, LetterN, Level10Cybermancer, lever1209, liltenhead, LittleBuilderJane, Lomcastar, LordCarve, LordEclipse, luckyshotpictures, Lukasz825700516, lunarcomets, luringens, lvvova1, lzimann, lzk228, MACMAN2003, Macoron, MagnusCrowe, ManelNavola, Mangohydra, Matz05, MehimoNemo, MeltedPixel, MemeProof, Menshin, Mervill, metalgearsloth, mhamsterr, MilenVolf, Minty642, Mirino97, mirrorcult, MishaUnity, MisterMecky, Mith-randalf, Moneyl, Moomoobeef, moony, Morb0, Mr0maks, musicmanvr, Myakot, Myctai, N3X15, Nairodian, Naive817, namespace-Memory, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, nmajask, nok-ko, Nopey, notafet, notquitehadouken, noudoit, noverd, nuke-haus, NULL882, OctoRocket, OldDanceJacket, onoira, osjarw, Owai-Seek, pali6, Pangogie, patrikturi, PaulRitter, Peptide90, peptron1, Phantom-Lily, pigeonpeas, pissdemon, PixelTheKermit, PJB3005, Plykiya, pofitlo, pointer-to-null, PolterTzi, PoorMansDreams, potato1234x, ProfanedBane, PrPleGoo, ps3moira, Psychpsyo, psykzz, PuroSlavKing, PursuitInAshes, quatre, QuietlyWhisper, qwerltaz, Radosvik, Radrark, Rainbeon, Rainfey, Rane, ravage123321, rbertoche, Redict, RedlineTriad, RednoWCirabrab, RemberBM, RemieRichards, RemTim, rene-descartes2021, RiceMar1244, RieBi, Rinkashikachi, Rockdtben, rolfero, rosieposieeee, RumiTiger, Saakra, Samsterious, SaphireLattice, ScalyChimp, scrato, Scribbles0, Serkket, SethLafuente, ShadowCommander, Shadowtheprotogen546, shampunj, SignalWalker, Simyon264, Sirionaut, siyengar04, Skarletto, Skrauz, Skyedra, SlamBamActionman, slarticodefast, Slava0135, snebl, Snowni, snowsignal, SonicHDC, SoulFN, SoulSloth, SpaceManiac, SpeltIncorrectyl, SphiraI, spoogemonster, ssdaniel24, Stealthbomber16, StrawberryMoses, Subversionary, superjj18, SweptWasTaken, Szunti, takemysoult, TaralGit, Tayrtahn, tday93, TekuNut, TemporalOroboros, tentekal, Terraspark4941, tgrkzus, thatrandomcanadianguy, TheArturZh, theashtronaut, thedraccx, themias, Theomund, theOperand, TheShuEd, TimrodDX, Titian3, tkdrg, tmtmtl30, TokenStyle, tom-leys, tomasalves8, Tomeno, tosatur, TsjipTsjip, Tunguso4ka, TurboTrackerss14, Tyler-IN, Tyzemol, UbaserB, UBlueberry, UKNOWH, Uriende, UristMcDorf, Vaaankas, Varen, VasilisThePikachu, veliebm, Veritius, Vermidia, Verslebas, VigersRay, Visne, volundr-, Voomra, Vordenburg, vulppine, wafehling, waylon531, weaversam8, whateverusername0, Willhelm53, wixoaGit, WlarusFromDaSpace, wrexbe, xRiriq, yathxyz, Ygg01, YotaXP, YuriyKiss, zach-hill, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zerorulez, zionnBE, zlodo, ZNixian, ZoldorfTheWizard, Zumorica, Zymem +0x6273, 2013HORSEMEATSCANDAL, 20kdc, 21Melkuu, 4dplanner, 612git, 778b, Ablankmann, Acruid, actioninja, adamsong, Admiral-Obvious-001, Adrian16199, Aerocrux, Aexxie, Afrokada, Agoichi, Ahion, AJCM-git, AjexRose, Alekshhh, AlexMorgan3817, AlexUm418, AlmondFlour, AlphaQwerty, Altoids1, amylizzle, ancientpower, ArchPigeon, Arendian, arimah, Arteben, AruMoon, as334, AsikKEsel, asperger-sind, aspiringLich, avghdev, AzzyIsNotHere, BananaFlambe, Baptr0b0t, BasedUser, beck-thompson, BellwetherLogic, BGare, bhenrich, BingoJohnson-zz, BismarckShuffle, Bixkitts, Blackern5000, Blazeror, Boaz1111, BobdaBiscuit, brainfood1183, Brandon-Huu, Bright0, brndd, BubblegumBlue, BYONDFuckery, c4llv07e, CakeQ, Callmore, CaptainSqrBeard, Carbonhell, casperr04, CatTheSystem, Centronias, chairbender, Charlese2, Cheackraze, cheesePizza2, Chief-Engineer, chromiumboy, Chronophylos, Ciac32, clement-or, Clyybber, Cojoke-dot, ColdAutumnRain, collinlunn, ComicIronic, coolmankid12345, corentt, crazybrain23, creadth, CrigCrag, Crotalus, CrudeWax, CrzyPotato, Cyberboss, d34d10cc, Daemon, daerSeebaer, dahnte, dakamakat, dakimasu, DamianX, DangerRevolution, daniel-cr, Darkenson, DawBla, dch-GH, Deahaka, DEATHB4DEFEAT, DeathCamel58, deathride58, DebugOk, Decappi, deepdarkdepths, deepy, Delete69, deltanedas, DerbyX, DexlerXD, Doctor-Cpu, DoctorBeard, DogZeroX, dontbetank, Doru991, DoubleRiceEddiedd, DoutorWhite, DrMelon, DrSmugleaf, drteaspoon420, DTanxxx, DubiousDoggo, Duddino, DuskyJay, Dutch-VanDerLinde, Easypoller, eclips_e, EdenTheLiznerd, EEASAS, Efruit, ElectroSR, elthundercloud, Emisse, EmoGarbage404, Endecc, enumerate0, eoineoineoin, ERORR404V1, Errant-4, estacaoespacialpirata, exincore, exp111, Fahasor, FairlySadPanda, ficcialfaint, Fildrance, FillerVK, Fishfish458, Flareguy, FluffiestFloof, FluidRock, FoLoKe, fooberticus, Fortune117, freeman2651, Froffy025, Fromoriss, FungiFellow, GalacticChimp, gbasood, Geekyhobo, Genkail, Ghagliiarghii, Git-Nivrak, github-actions[bot], gituhabu, GNF54, Golinth, GoodWheatley, Gotimanga, graevy, GreyMario, gusxyz, Gyrandola, h3half, Hanzdegloker, Hardly3D, harikattar, Hebiman, Henry12116, HerCoyote23, hitomishirichan, Hmeister-real, HoofedEar, hord-brayden, hubismal, Hugal31, Huxellberger, Hyenh, iacore, IamVelcroboy, icekot8, igorsaux, ike709, Illiux, Ilya246, IlyaElDunaev, Injazz, Insineer, IntegerTempest, Interrobang01, IProduceWidgets, ItsMeThom, j-giebel, Jackal298, Jackrost, jamessimo, janekvap, Jark255, JerryImMouse, Jessetriesagain, jessicamaybe, Jezithyr, jicksaw, JiimBob, JoeHammad1844, joelhed, JohnGinnane, johnku1, joshepvodka, jproads, Jrpl, juliangiebel, JustArt1m, JustCone14, JustinTether, JustinTrotter, K-Dynamic, KaiShibaa, kalane15, kalanosh, KEEYNy, Kelrak, kerisargit, keronshb, KIBORG04, Killerqu00, KingFroozy, kira-er, Kit0vras, KittenColony, Ko4ergaPunk, komunre, koteq, Krunklehorn, Kukutis96513, kxvvv, Lamrr, LankLTE, lapatison, Leander-0, LetterN, Level10Cybermancer, lever1209, liltenhead, LittleBuilderJane, Lomcastar, LordCarve, LordEclipse, luckyshotpictures, Lukasz825700516, lunarcomets, luringens, lvvova1, lzimann, lzk228, MACMAN2003, Macoron, MagnusCrowe, ManelNavola, Mangohydra, Matz05, MehimoNemo, MeltedPixel, MemeProof, Menshin, Mervill, metalgearsloth, mhamsterr, MilenVolf, Minty642, Mirino97, mirrorcult, MishaUnity, MisterMecky, Mith-randalf, Moneyl, Moomoobeef, moony, Morb0, Mr0maks, musicmanvr, Myakot, Myctai, N3X15, Nairodian, Naive817, namespace-Memory, NickPowers43, nikthechampiongr, Nimfar11, Nirnael, nmajask, nok-ko, Nopey, notafet, notquitehadouken, noudoit, noverd, nuke-haus, NULL882, OctoRocket, OldDanceJacket, onoira, osjarw, Owai-Seek, pali6, Pangogie, patrikturi, PaulRitter, Peptide90, peptron1, Phantom-Lily, pigeonpeas, pissdemon, PixelTheKermit, PJB3005, Plykiya, pofitlo, pointer-to-null, PolterTzi, PoorMansDreams, potato1234x, ProfanedBane, PrPleGoo, ps3moira, Psychpsyo, psykzz, PuroSlavKing, PursuitInAshes, quatre, QuietlyWhisper, qwerltaz, Radosvik, Radrark, Rainbeon, Rainfey, Rane, ravage123321, rbertoche, Redict, RedlineTriad, RednoWCirabrab, RemberBM, RemieRichards, RemTim, rene-descartes2021, RiceMar1244, RieBi, Rinkashikachi, Rockdtben, rolfero, rosieposieeee, RumiTiger, Saakra, Samsterious, SaphireLattice, ScalyChimp, scrato, Scribbles0, Serkket, SethLafuente, ShadowCommander, Shadowtheprotogen546, shampunj, SignalWalker, Simyon264, Sirionaut, siyengar04, Skarletto, Skrauz, Skyedra, SlamBamActionman, slarticodefast, Slava0135, snebl, Snowni, snowsignal, SonicHDC, SoulFN, SoulSloth, SpaceManiac, SpeltIncorrectyl, SphiraI, spoogemonster, ssdaniel24, Stealthbomber16, StrawberryMoses, Subversionary, superjj18, SweptWasTaken, Szunti, takemysoult, TaralGit, Tayrtahn, tday93, TekuNut, TemporalOroboros, tentekal, Terraspark4941, tgrkzus, thatrandomcanadianguy, TheArturZh, theashtronaut, thedraccx, themias, Theomund, theOperand, TheShuEd, TimrodDX, Titian3, tkdrg, tmtmtl30, TokenStyle, tom-leys, tomasalves8, Tomeno, tosatur, TsjipTsjip, Tunguso4ka, TurboTrackerss14, Tyler-IN, Tyzemol, UbaserB, UBlueberry, UKNOWH, Uriende, UristMcDorf, Vaaankas, Varen, VasilisThePikachu, veliebm, Veritius, Vermidia, Verslebas, VigersRay, Visne, volundr-, Voomra, Vordenburg, vulppine, wafehling, waylon531, weaversam8, whateverusername0, Willhelm53, wixoaGit, WlarusFromDaSpace, wrexbe, xRiriq, yathxyz, Ygg01, YotaXP, YuriyKiss, zach-hill, Zandario, Zap527, Zealith-Gamer, ZelteHonor, zerorulez, zionnBE, zlodo, ZNixian, ZoldorfTheWizard, Zumorica, Zymem From 3d41d5f2bcb501b1746e58ad0ca6a6cbc83e69ac Mon Sep 17 00:00:00 2001 From: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Date: Sat, 18 May 2024 18:35:46 -0700 Subject: [PATCH 16/19] Make wielding automatically drop the item on your other hand (#27975) * Make wielding automatically drop the item on your other hand * Fix docs * Remove redundant parameter * Fix not deleting virtuals on fail * Make count freeable hands method * Add popup when dropping item --- .../Hands/Components/HandHelpers.cs | 10 ++++ .../Hands/EntitySystems/SharedHandsSystem.cs | 13 ++++- .../VirtualItem/SharedVirtualItemSystem.cs | 48 ++++++++++++++++--- Content.Shared/Wieldable/WieldableSystem.cs | 16 ++++++- .../Locale/en-US/virtual/virtual-item.ftl | 1 + 5 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 Resources/Locale/en-US/virtual/virtual-item.ftl diff --git a/Content.Shared/Hands/Components/HandHelpers.cs b/Content.Shared/Hands/Components/HandHelpers.cs index 11fff6d9c8..aecf3a6936 100644 --- a/Content.Shared/Hands/Components/HandHelpers.cs +++ b/Content.Shared/Hands/Components/HandHelpers.cs @@ -1,4 +1,5 @@ using System.Linq; +using Content.Shared.Hands.EntitySystems; namespace Content.Shared.Hands.Components; @@ -20,6 +21,15 @@ public static class HandHelpers /// public static int CountFreeHands(this HandsComponent component) => component.Hands.Values.Count(hand => hand.IsEmpty); + /// + /// Get the number of hands that are not currently holding anything. This is a LinQ method, not a property, so + /// cache it instead of accessing this multiple times. + /// + public static int CountFreeableHands(this Entity component, SharedHandsSystem system) + { + return system.CountFreeableHands(component); + } + /// /// Get a list of hands that are currently holding nothing. This is a LinQ method, not a property, so cache /// it instead of accessing this multiple times. diff --git a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs index fd732009e9..e48aafeab5 100644 --- a/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs +++ b/Content.Shared/Hands/EntitySystems/SharedHandsSystem.cs @@ -5,7 +5,6 @@ using Content.Shared.Administration.Logs; using Content.Shared.Hands.Components; using Content.Shared.Interaction; using Content.Shared.Inventory.VirtualItem; -using Content.Shared.Item; using Content.Shared.Storage.EntitySystems; using Robust.Shared.Containers; using Robust.Shared.Input.Binding; @@ -299,4 +298,16 @@ public abstract partial class SharedHandsSystem return hands.Hands.TryGetValue(handId, out hand); } + + public int CountFreeableHands(Entity hands) + { + var freeable = 0; + foreach (var hand in hands.Comp.Hands.Values) + { + if (hand.IsEmpty || CanDropHeld(hands, hand)) + freeable++; + } + + return freeable; + } } diff --git a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs index e45530e458..b31cc75576 100644 --- a/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs +++ b/Content.Shared/Inventory/VirtualItem/SharedVirtualItemSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.Hands.EntitySystems; using Content.Shared.Interaction; using Content.Shared.Inventory.Events; using Content.Shared.Item; +using Content.Shared.Popups; using Robust.Shared.Containers; using Robust.Shared.Network; using Robust.Shared.Prototypes; @@ -29,6 +30,7 @@ public abstract class SharedVirtualItemSystem : EntitySystem [Dependency] private readonly SharedItemSystem _itemSystem = default!; [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; [ValidatePrototypeId] private const string VirtualItem = "VirtualItem"; @@ -71,23 +73,53 @@ public abstract class SharedVirtualItemSystem : EntitySystem } #region Hands + /// /// Spawns a virtual item in a empty hand /// /// The entity we will make a virtual entity copy of /// The entity that we want to insert the virtual entity - public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user) + /// Whether or not to try and drop other items to make space + public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user, bool dropOthers = false) { - return TrySpawnVirtualItemInHand(blockingEnt, user, out _); + return TrySpawnVirtualItemInHand(blockingEnt, user, out _, dropOthers); } - /// - public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user, [NotNullWhen(true)] out EntityUid? virtualItem) + /// + public bool TrySpawnVirtualItemInHand(EntityUid blockingEnt, EntityUid user, [NotNullWhen(true)] out EntityUid? virtualItem, bool dropOthers = false) { - if (!TrySpawnVirtualItem(blockingEnt, user, out virtualItem) || !_handsSystem.TryGetEmptyHand(user, out var hand)) + virtualItem = null; + if (!_handsSystem.TryGetEmptyHand(user, out var empty)) + { + if (!dropOthers) + return false; + + foreach (var hand in _handsSystem.EnumerateHands(user)) + { + if (hand.HeldEntity is not { } held) + continue; + + if (held == blockingEnt || HasComp(held)) + continue; + + if (!_handsSystem.TryDrop(user, hand)) + continue; + + if (!TerminatingOrDeleted(held)) + _popup.PopupClient(Loc.GetString("virtual-item-dropped-other", ("dropped", held)), user, user); + + empty = hand; + break; + } + } + + if (empty == null) return false; - _handsSystem.DoPickup(user, hand, virtualItem.Value); + if (!TrySpawnVirtualItem(blockingEnt, user, out virtualItem)) + return false; + + _handsSystem.DoPickup(user, empty, virtualItem.Value); return true; } @@ -120,6 +152,7 @@ public abstract class SharedVirtualItemSystem : EntitySystem /// The entity we will make a virtual entity copy of /// The entity that we want to insert the virtual entity /// The slot to which we will insert the virtual entity (could be the "shoes" slot, for example) + /// Whether or not to force an equip public bool TrySpawnVirtualItemInInventory(EntityUid blockingEnt, EntityUid user, string slot, bool force = false) { return TrySpawnVirtualItemInInventory(blockingEnt, user, slot, force, out _); @@ -140,6 +173,8 @@ public abstract class SharedVirtualItemSystem : EntitySystem /// that's done check if the found virtual entity is a copy of our matching entity, /// if it is, delete it /// + /// The entity that we want to delete the virtual entity from + /// The entity that made the virtual entity /// Set this param if you have the name of the slot, it avoids unnecessary queries public void DeleteInSlotMatching(EntityUid user, EntityUid matching, string? slotName = null) { @@ -178,6 +213,7 @@ public abstract class SharedVirtualItemSystem : EntitySystem /// /// The entity we will make a virtual entity copy of /// The entity that we want to insert the virtual entity + /// The virtual item, if spawned public bool TrySpawnVirtualItem(EntityUid blockingEnt, EntityUid user, [NotNullWhen(true)] out EntityUid? virtualItem) { if (_netManager.IsClient) diff --git a/Content.Shared/Wieldable/WieldableSystem.cs b/Content.Shared/Wieldable/WieldableSystem.cs index b765566f44..cee6c65fa1 100644 --- a/Content.Shared/Wieldable/WieldableSystem.cs +++ b/Content.Shared/Wieldable/WieldableSystem.cs @@ -161,7 +161,7 @@ public sealed class WieldableSystem : EntitySystem return false; } - if (hands.CountFreeHands() < component.FreeHandsRequired) + if (_handsSystem.CountFreeableHands((user, hands)) < component.FreeHandsRequired) { if (!quiet) { @@ -202,9 +202,21 @@ public sealed class WieldableSystem : EntitySystem if (component.WieldSound != null) _audioSystem.PlayPredicted(component.WieldSound, used, user); + var virtuals = new List(); for (var i = 0; i < component.FreeHandsRequired; i++) { - _virtualItemSystem.TrySpawnVirtualItemInHand(used, user); + if (_virtualItemSystem.TrySpawnVirtualItemInHand(used, user, out var virtualItem, true)) + { + virtuals.Add(virtualItem.Value); + continue; + } + + foreach (var existingVirtual in virtuals) + { + QueueDel(existingVirtual); + } + + return false; } if (TryComp(used, out UseDelayComponent? useDelay) diff --git a/Resources/Locale/en-US/virtual/virtual-item.ftl b/Resources/Locale/en-US/virtual/virtual-item.ftl new file mode 100644 index 0000000000..cb91f24cf7 --- /dev/null +++ b/Resources/Locale/en-US/virtual/virtual-item.ftl @@ -0,0 +1 @@ +virtual-item-dropped-other = You dropped {THE($dropped)}! From e5f30b12d266b39816c77f26acc74d316d8d0b7d Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 19 May 2024 01:36:52 +0000 Subject: [PATCH 17/19] Automatic changelog update --- Resources/Changelog/Changelog.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e4b72cd303..9dffda8901 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Tayrtahn - changes: - - message: Flasks can once again be put into dispensers. - type: Fix - id: 6104 - time: '2024-03-06T17:19:01.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/25883 - author: Doctor-Cpu changes: - message: Cargo palllets can no longer be ordered from cargo request terminal @@ -3867,3 +3860,11 @@ id: 6603 time: '2024-05-19T00:23:45.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28122 +- author: DrSmugleaf + changes: + - message: Attempting to dual wield something will now automatically drop the item + in your other hand. + type: Tweak + id: 6604 + time: '2024-05-19T01:35:46.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/27975 From b4a5399ad40aacb6db153640368869d12ab87aa5 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sun, 19 May 2024 13:54:52 +1200 Subject: [PATCH 18/19] Modify battery assert to avoid floating point errors (#28007) --- Content.Server/Power/Pow3r/BatteryRampPegSolver.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs index 5d52bde377..0afd86679b 100644 --- a/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs +++ b/Content.Server/Power/Pow3r/BatteryRampPegSolver.cs @@ -240,7 +240,8 @@ namespace Content.Server.Power.Pow3r } } - if (unmet <= 0 || totalBatterySupply <= 0) + // Return if normal supplies met all demand or there are no supplying batteries + if (unmet <= 0 || totalMaxBatterySupply <= 0) return; // Target output capacity for batteries @@ -275,8 +276,8 @@ namespace Content.Server.Power.Pow3r battery.SupplyRampTarget = battery.MaxEffectiveSupply * relativeTargetBatteryOutput - battery.CurrentReceiving * battery.Efficiency; - DebugTools.Assert(battery.SupplyRampTarget + battery.CurrentReceiving * battery.Efficiency <= battery.LoadingNetworkDemand - || MathHelper.CloseToPercent(battery.SupplyRampTarget + battery.CurrentReceiving * battery.Efficiency, battery.LoadingNetworkDemand, 0.001)); + DebugTools.Assert(battery.MaxEffectiveSupply * relativeTargetBatteryOutput <= battery.LoadingNetworkDemand + || MathHelper.CloseToPercent(battery.MaxEffectiveSupply * relativeTargetBatteryOutput, battery.LoadingNetworkDemand, 0.001)); } } From 6e83c4d570eff90dc461e1f252b9d2199fcf4182 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Sun, 19 May 2024 13:55:10 +1200 Subject: [PATCH 19/19] Update component query benchmarks (#27967) * Add more component query benchmarks. * Rename benchmark --- Content.Benchmarks/ComponentQueryBenchmark.cs | 273 ++++++++++++++++++ Content.Benchmarks/EntityQueryBenchmark.cs | 137 --------- Content.Benchmarks/MapLoadBenchmark.cs | 2 +- Content.Benchmarks/PvsBenchmark.cs | 2 +- .../SpawnEquipDeleteBenchmark.cs | 2 +- .../PoolManager.Prototypes.cs | 5 +- Content.IntegrationTests/PoolManager.cs | 30 +- .../PoolManagerTestEventHandler.cs | 2 +- Content.MapRenderer/Program.cs | 2 +- Content.YAMLLinter/Program.cs | 2 +- 10 files changed, 300 insertions(+), 157 deletions(-) create mode 100644 Content.Benchmarks/ComponentQueryBenchmark.cs delete mode 100644 Content.Benchmarks/EntityQueryBenchmark.cs diff --git a/Content.Benchmarks/ComponentQueryBenchmark.cs b/Content.Benchmarks/ComponentQueryBenchmark.cs new file mode 100644 index 0000000000..11c7ab9d5f --- /dev/null +++ b/Content.Benchmarks/ComponentQueryBenchmark.cs @@ -0,0 +1,273 @@ +#nullable enable +using System; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using Content.IntegrationTests; +using Content.IntegrationTests.Pair; +using Content.Shared.Clothing.Components; +using Content.Shared.Doors.Components; +using Content.Shared.Item; +using Robust.Server.GameObjects; +using Robust.Shared; +using Robust.Shared.Analyzers; +using Robust.Shared.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Random; + +namespace Content.Benchmarks; + +/// +/// Benchmarks for comparing the speed of various component fetching/lookup related methods, including directed event +/// subscriptions +/// +[Virtual] +[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)] +[CategoriesColumn] +public class ComponentQueryBenchmark +{ + public const string Map = "Maps/atlas.yml"; + + private TestPair _pair = default!; + private IEntityManager _entMan = default!; + private MapId _mapId = new(10); + private EntityQuery _itemQuery; + private EntityQuery _clothingQuery; + private EntityQuery _mapQuery; + private EntityUid[] _items = default!; + + [GlobalSetup] + public void Setup() + { + ProgramShared.PathOffset = "../../../../"; + PoolManager.Startup(typeof(QueryBenchSystem).Assembly); + + _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); + _entMan = _pair.Server.ResolveDependency(); + + _itemQuery = _entMan.GetEntityQuery(); + _clothingQuery = _entMan.GetEntityQuery(); + _mapQuery = _entMan.GetEntityQuery(); + + _pair.Server.ResolveDependency().SetSeed(42); + _pair.Server.WaitPost(() => + { + var success = _entMan.System().TryLoad(_mapId, Map, out _); + if (!success) + throw new Exception("Map load failed"); + _pair.Server.MapMan.DoMapInitialize(_mapId); + }).GetAwaiter().GetResult(); + + _items = new EntityUid[_entMan.Count()]; + var i = 0; + var enumerator = _entMan.AllEntityQueryEnumerator(); + while (enumerator.MoveNext(out var uid, out _)) + { + _items[i++] = uid; + } + } + + [GlobalCleanup] + public async Task Cleanup() + { + await _pair.DisposeAsync(); + PoolManager.Shutdown(); + } + + #region TryComp + + /// + /// Baseline TryComp benchmark. When the benchmark was created, around 40% of the items were clothing. + /// + [Benchmark(Baseline = true)] + [BenchmarkCategory("TryComp")] + public int TryComp() + { + var hashCode = 0; + foreach (var uid in _items) + { + if (_clothingQuery.TryGetComponent(uid, out var clothing)) + hashCode = HashCode.Combine(hashCode, clothing.GetHashCode()); + } + return hashCode; + } + + /// + /// Variant of that is meant to always fail to get a component. + /// + [Benchmark] + [BenchmarkCategory("TryComp")] + public int TryCompFail() + { + var hashCode = 0; + foreach (var uid in _items) + { + if (_mapQuery.TryGetComponent(uid, out var map)) + hashCode = HashCode.Combine(hashCode, map.GetHashCode()); + } + return hashCode; + } + + /// + /// Variant of that is meant to always succeed getting a component. + /// + [Benchmark] + [BenchmarkCategory("TryComp")] + public int TryCompSucceed() + { + var hashCode = 0; + foreach (var uid in _items) + { + if (_itemQuery.TryGetComponent(uid, out var item)) + hashCode = HashCode.Combine(hashCode, item.GetHashCode()); + } + return hashCode; + } + + /// + /// Variant of that uses `Resolve()` to try get the component. + /// + [Benchmark] + [BenchmarkCategory("TryComp")] + public int Resolve() + { + var hashCode = 0; + foreach (var uid in _items) + { + DoResolve(uid, ref hashCode); + } + return hashCode; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void DoResolve(EntityUid uid, ref int hash, ClothingComponent? clothing = null) + { + if (_clothingQuery.Resolve(uid, ref clothing, false)) + hash = HashCode.Combine(hash, clothing.GetHashCode()); + } + + #endregion + + #region Enumeration + + [Benchmark] + [BenchmarkCategory("Item Enumerator")] + public int SingleItemEnumerator() + { + var hashCode = 0; + var enumerator = _entMan.AllEntityQueryEnumerator(); + while (enumerator.MoveNext(out var item)) + { + hashCode = HashCode.Combine(hashCode, item.GetHashCode()); + } + + return hashCode; + } + + [Benchmark] + [BenchmarkCategory("Item Enumerator")] + public int DoubleItemEnumerator() + { + var hashCode = 0; + var enumerator = _entMan.AllEntityQueryEnumerator(); + while (enumerator.MoveNext(out _, out var item)) + { + hashCode = HashCode.Combine(hashCode, item.GetHashCode()); + } + + return hashCode; + } + + [Benchmark] + [BenchmarkCategory("Item Enumerator")] + public int TripleItemEnumerator() + { + var hashCode = 0; + var enumerator = _entMan.AllEntityQueryEnumerator(); + while (enumerator.MoveNext(out _, out _, out var xform)) + { + hashCode = HashCode.Combine(hashCode, xform.GetHashCode()); + } + + return hashCode; + } + + [Benchmark] + [BenchmarkCategory("Airlock Enumerator")] + public int SingleAirlockEnumerator() + { + var hashCode = 0; + var enumerator = _entMan.AllEntityQueryEnumerator(); + while (enumerator.MoveNext(out var airlock)) + { + hashCode = HashCode.Combine(hashCode, airlock.GetHashCode()); + } + + return hashCode; + } + + [Benchmark] + [BenchmarkCategory("Airlock Enumerator")] + public int DoubleAirlockEnumerator() + { + var hashCode = 0; + var enumerator = _entMan.AllEntityQueryEnumerator(); + while (enumerator.MoveNext(out _, out var door)) + { + hashCode = HashCode.Combine(hashCode, door.GetHashCode()); + } + + return hashCode; + } + + [Benchmark] + [BenchmarkCategory("Airlock Enumerator")] + public int TripleAirlockEnumerator() + { + var hashCode = 0; + var enumerator = _entMan.AllEntityQueryEnumerator(); + while (enumerator.MoveNext(out _, out _, out var xform)) + { + hashCode = HashCode.Combine(hashCode, xform.GetHashCode()); + } + + return hashCode; + } + + #endregion + + [Benchmark(Baseline = true)] + [BenchmarkCategory("Events")] + public int StructEvents() + { + var ev = new QueryBenchEvent(); + foreach (var uid in _items) + { + _entMan.EventBus.RaiseLocalEvent(uid, ref ev); + } + + return ev.HashCode; + } +} + +[ByRefEvent] +public struct QueryBenchEvent +{ + public int HashCode; +} + +public sealed class QueryBenchSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnEvent); + } + + private void OnEvent(EntityUid uid, ClothingComponent component, ref QueryBenchEvent args) + { + args.HashCode = HashCode.Combine(args.HashCode, component.GetHashCode()); + } +} diff --git a/Content.Benchmarks/EntityQueryBenchmark.cs b/Content.Benchmarks/EntityQueryBenchmark.cs deleted file mode 100644 index cef6a5e35c..0000000000 --- a/Content.Benchmarks/EntityQueryBenchmark.cs +++ /dev/null @@ -1,137 +0,0 @@ -#nullable enable -using System; -using System.Threading.Tasks; -using BenchmarkDotNet.Attributes; -using Content.IntegrationTests; -using Content.IntegrationTests.Pair; -using Content.Shared.Clothing.Components; -using Content.Shared.Item; -using Robust.Server.GameObjects; -using Robust.Shared; -using Robust.Shared.Analyzers; -using Robust.Shared.GameObjects; -using Robust.Shared.Map; -using Robust.Shared.Random; - -namespace Content.Benchmarks; - -[Virtual] -public class EntityQueryBenchmark -{ - public const string Map = "Maps/atlas.yml"; - - private TestPair _pair = default!; - private IEntityManager _entMan = default!; - private MapId _mapId = new MapId(10); - private EntityQuery _clothingQuery; - - [GlobalSetup] - public void Setup() - { - ProgramShared.PathOffset = "../../../../"; - PoolManager.Startup(null); - - _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); - _entMan = _pair.Server.ResolveDependency(); - - _pair.Server.ResolveDependency().SetSeed(42); - _pair.Server.WaitPost(() => - { - var success = _entMan.System().TryLoad(_mapId, Map, out _); - if (!success) - throw new Exception("Map load failed"); - _pair.Server.MapMan.DoMapInitialize(_mapId); - }).GetAwaiter().GetResult(); - - _clothingQuery = _entMan.GetEntityQuery(); - - // Apparently ~40% of entities are items, and 1 in 6 of those are clothing. - /* - var entCount = _entMan.EntityCount; - var itemCount = _entMan.Count(); - var clothingCount = _entMan.Count(); - var itemRatio = (float) itemCount / entCount; - var clothingRatio = (float) clothingCount / entCount; - Console.WriteLine($"Entities: {entCount}. Items: {itemRatio:P2}. Clothing: {clothingRatio:P2}."); - */ - } - - [GlobalCleanup] - public async Task Cleanup() - { - await _pair.DisposeAsync(); - PoolManager.Shutdown(); - } - - [Benchmark] - public int HasComponent() - { - var hashCode = 0; - var enumerator = _entMan.AllEntityQueryEnumerator(); - while (enumerator.MoveNext(out var uid, out var _)) - { - if (_entMan.HasComponent(uid)) - hashCode = HashCode.Combine(hashCode, uid.Id); - } - - return hashCode; - } - - [Benchmark] - public int HasComponentQuery() - { - var hashCode = 0; - var enumerator = _entMan.AllEntityQueryEnumerator(); - while (enumerator.MoveNext(out var uid, out var _)) - { - if (_clothingQuery.HasComponent(uid)) - hashCode = HashCode.Combine(hashCode, uid.Id); - } - - return hashCode; - } - - [Benchmark] - public int TryGetComponent() - { - var hashCode = 0; - var enumerator = _entMan.AllEntityQueryEnumerator(); - while (enumerator.MoveNext(out var uid, out var _)) - { - if (_entMan.TryGetComponent(uid, out ClothingComponent? clothing)) - hashCode = HashCode.Combine(hashCode, clothing.GetHashCode()); - } - - return hashCode; - } - - [Benchmark] - public int TryGetComponentQuery() - { - var hashCode = 0; - var enumerator = _entMan.AllEntityQueryEnumerator(); - while (enumerator.MoveNext(out var uid, out var _)) - { - if (_clothingQuery.TryGetComponent(uid, out var clothing)) - hashCode = HashCode.Combine(hashCode, clothing.GetHashCode()); - } - - return hashCode; - } - - /// - /// Enumerate all entities with both an item and clothing component. - /// - [Benchmark] - public int Enumerator() - { - var hashCode = 0; - var enumerator = _entMan.AllEntityQueryEnumerator(); - while (enumerator.MoveNext(out var _, out var clothing)) - { - hashCode = HashCode.Combine(hashCode, clothing.GetHashCode()); - } - - return hashCode; - } -} diff --git a/Content.Benchmarks/MapLoadBenchmark.cs b/Content.Benchmarks/MapLoadBenchmark.cs index 261e164f17..a3319e3067 100644 --- a/Content.Benchmarks/MapLoadBenchmark.cs +++ b/Content.Benchmarks/MapLoadBenchmark.cs @@ -26,7 +26,7 @@ public class MapLoadBenchmark public void Setup() { ProgramShared.PathOffset = "../../../../"; - PoolManager.Startup(null); + PoolManager.Startup(); _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); var server = _pair.Server; diff --git a/Content.Benchmarks/PvsBenchmark.cs b/Content.Benchmarks/PvsBenchmark.cs index c7f22bdb0c..0b4dd90762 100644 --- a/Content.Benchmarks/PvsBenchmark.cs +++ b/Content.Benchmarks/PvsBenchmark.cs @@ -49,7 +49,7 @@ public class PvsBenchmark #if !DEBUG ProgramShared.PathOffset = "../../../../"; #endif - PoolManager.Startup(null); + PoolManager.Startup(); _pair = PoolManager.GetServerClient().GetAwaiter().GetResult(); _entMan = _pair.Server.ResolveDependency(); diff --git a/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs b/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs index 8512107b69..0638d945aa 100644 --- a/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs +++ b/Content.Benchmarks/SpawnEquipDeleteBenchmark.cs @@ -32,7 +32,7 @@ public class SpawnEquipDeleteBenchmark public async Task SetupAsync() { ProgramShared.PathOffset = "../../../../"; - PoolManager.Startup(null); + PoolManager.Startup(); _pair = await PoolManager.GetServerClient(); var server = _pair.Server; diff --git a/Content.IntegrationTests/PoolManager.Prototypes.cs b/Content.IntegrationTests/PoolManager.Prototypes.cs index 760e8b1d37..eb7518ea15 100644 --- a/Content.IntegrationTests/PoolManager.Prototypes.cs +++ b/Content.IntegrationTests/PoolManager.Prototypes.cs @@ -15,11 +15,8 @@ public static partial class PoolManager | BindingFlags.Public | BindingFlags.DeclaredOnly; - private static void DiscoverTestPrototypes(Assembly? assembly = null) + private static void DiscoverTestPrototypes(Assembly assembly) { - assembly ??= typeof(PoolManager).Assembly; - _testPrototypes.Clear(); - foreach (var type in assembly.GetTypes()) { foreach (var field in type.GetFields(Flags)) diff --git a/Content.IntegrationTests/PoolManager.cs b/Content.IntegrationTests/PoolManager.cs index b544fe2854..25e6c7ef26 100644 --- a/Content.IntegrationTests/PoolManager.cs +++ b/Content.IntegrationTests/PoolManager.cs @@ -42,6 +42,8 @@ public static partial class PoolManager private static bool _dead; private static Exception? _poolFailureReason; + private static HashSet _contentAssemblies = default!; + public static async Task<(RobustIntegrationTest.ServerIntegrationInstance, PoolTestLogHandler)> GenerateServer( PoolSettings poolSettings, TextWriter testOut) @@ -54,12 +56,7 @@ public static partial class PoolManager LoadConfigAndUserData = false, LoadContentResources = !poolSettings.NoLoadContent, }, - ContentAssemblies = new[] - { - typeof(Shared.Entry.EntryPoint).Assembly, - typeof(Server.Entry.EntryPoint).Assembly, - typeof(PoolManager).Assembly - } + ContentAssemblies = _contentAssemblies.ToArray() }; var logHandler = new PoolTestLogHandler("SERVER"); @@ -140,7 +137,7 @@ public static partial class PoolManager { typeof(Shared.Entry.EntryPoint).Assembly, typeof(Client.Entry.EntryPoint).Assembly, - typeof(PoolManager).Assembly + typeof(PoolManager).Assembly, } }; @@ -422,13 +419,26 @@ we are just going to end this here to save a lot of time. This is the exception /// /// Initialize the pool manager. /// - /// Assembly to search for to discover extra test prototypes. - public static void Startup(Assembly? assembly) + /// Assemblies to search for to discover extra prototypes and systems. + public static void Startup(params Assembly[] extraAssemblies) { if (_initialized) throw new InvalidOperationException("Already initialized"); _initialized = true; - DiscoverTestPrototypes(assembly); + _contentAssemblies = + [ + typeof(Shared.Entry.EntryPoint).Assembly, + typeof(Server.Entry.EntryPoint).Assembly, + typeof(PoolManager).Assembly + ]; + _contentAssemblies.UnionWith(extraAssemblies); + + _testPrototypes.Clear(); + DiscoverTestPrototypes(typeof(PoolManager).Assembly); + foreach (var assembly in extraAssemblies) + { + DiscoverTestPrototypes(assembly); + } } } diff --git a/Content.IntegrationTests/PoolManagerTestEventHandler.cs b/Content.IntegrationTests/PoolManagerTestEventHandler.cs index d37dffff50..3b26d6637f 100644 --- a/Content.IntegrationTests/PoolManagerTestEventHandler.cs +++ b/Content.IntegrationTests/PoolManagerTestEventHandler.cs @@ -13,7 +13,7 @@ public sealed class PoolManagerTestEventHandler [OneTimeSetUp] public void Setup() { - PoolManager.Startup(typeof(PoolManagerTestEventHandler).Assembly); + PoolManager.Startup(); // If the tests seem to be stuck, we try to end it semi-nicely _ = Task.Delay(MaximumTotalTestingTimeLimit).ContinueWith(_ => { diff --git a/Content.MapRenderer/Program.cs b/Content.MapRenderer/Program.cs index 43dcff2c02..7314119108 100644 --- a/Content.MapRenderer/Program.cs +++ b/Content.MapRenderer/Program.cs @@ -29,7 +29,7 @@ namespace Content.MapRenderer if (!CommandLineArguments.TryParse(args, out var arguments)) return; - PoolManager.Startup(null); + PoolManager.Startup(); if (arguments.Maps.Count == 0) { Console.WriteLine("Didn't specify any maps to paint! Loading the map list..."); diff --git a/Content.YAMLLinter/Program.cs b/Content.YAMLLinter/Program.cs index 7f0b740fe8..32078faeef 100644 --- a/Content.YAMLLinter/Program.cs +++ b/Content.YAMLLinter/Program.cs @@ -17,7 +17,7 @@ namespace Content.YAMLLinter { private static async Task Main(string[] _) { - PoolManager.Startup(null); + PoolManager.Startup(); var stopwatch = new Stopwatch(); stopwatch.Start();