From 1fde97cb54d60a13a7dc90d51e57ed2f62605df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82?= <123451459+JustArt1m@users.noreply.github.com> Date: Sat, 14 Sep 2024 17:55:13 +0300 Subject: [PATCH 001/138] New gauze customization (#30852) * Sprite&Meta * Marking_Prototype * Locale * Meta_copyright_change * Sprite_Change * New_Sprite * And_another_new_sprite * Change_Locale --- Resources/Locale/en-US/markings/gauze.ftl | 3 +++ .../Mobs/Customization/Markings/gauze.yml | 14 ++++++++++++++ .../Mobs/Customization/gauze.rsi/gauze_head.png | Bin 0 -> 409 bytes .../Mobs/Customization/gauze.rsi/meta.json | 6 +++++- 4 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 Resources/Textures/Mobs/Customization/gauze.rsi/gauze_head.png diff --git a/Resources/Locale/en-US/markings/gauze.ftl b/Resources/Locale/en-US/markings/gauze.ftl index f8bedc31957..7ed35a90ba1 100644 --- a/Resources/Locale/en-US/markings/gauze.ftl +++ b/Resources/Locale/en-US/markings/gauze.ftl @@ -46,6 +46,9 @@ marking-GauzeUpperLegRight = Gauze Thigh Wrap (Right) marking-GauzeBlindfold-gauze_blindfold = Gauze Blindfold marking-GauzeBlindfold = Gauze Blindfold +marking-GauzeHead-gauze_head = Gauze Head Wrap +marking-GauzeHead = Gauze Head Wrap + marking-GauzeLizardBlindfold-gauze_lizard_blindfold = Gauze Blindfold marking-GauzeLizardBlindfold = Gauze Blindfold diff --git a/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml b/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml index 7fda98e7640..540d098e505 100644 --- a/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml +++ b/Resources/Prototypes/Entities/Mobs/Customization/Markings/gauze.yml @@ -222,6 +222,20 @@ - sprite: Mobs/Customization/gauze.rsi state: gauze_boxerwrap_l +- type: marking + id: GauzeHead + bodyPart: Head + markingCategory: Overlay + speciesRestriction: [Dwarf, Human, Reptilian, Arachnid, Moth] + coloring: + default: + type: + !type:SimpleColoring + color: "#FFFFFF" + sprites: + - sprite: Mobs/Customization/gauze.rsi + state: gauze_head + # Lizard Specific Markings - type: marking id: GauzeLizardLefteyePatch diff --git a/Resources/Textures/Mobs/Customization/gauze.rsi/gauze_head.png b/Resources/Textures/Mobs/Customization/gauze.rsi/gauze_head.png new file mode 100644 index 0000000000000000000000000000000000000000..713ae3d4bc5c31af482e1e95cc7ac7d8a8682b17 GIT binary patch literal 409 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV080zaSW+oe0$3KAlhSQ)%m7G)|C=A*@+9`oi(m5SLE)!_U3>RwbvdbeKKecV`An&p`!3I~Yd`yS{9n>!I~@a! z)0gtBephTQkJbNd!Xn_nz=)S+syEwR!tECkXu1_kC9P`^TN9yKSWZe14qOb+-SX-GjHayFcDA2!Eqks}UT)Qonth zvr&aOJ{x~bXUd)tovZC^@9+c|uzaZzo@u_m3|c@o2M~k6rQpdR%G1@)Wt~$(695G7 Bo@4+3 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mobs/Customization/gauze.rsi/meta.json b/Resources/Textures/Mobs/Customization/gauze.rsi/meta.json index 8d82ccab517..bd7d1ed4eb4 100644 --- a/Resources/Textures/Mobs/Customization/gauze.rsi/meta.json +++ b/Resources/Textures/Mobs/Customization/gauze.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Gauze sprites by Github KittenColony / Discord kittencolony (297865728374210561)", + "copyright": "Gauze sprites by Github KittenColony / Discord kittencolony (297865728374210561), gauze_head by github:DreamlyJack(624946166152298517)", "size": { "x": 32, "y": 32 @@ -142,6 +142,10 @@ { "name": "gauze_moth_lowerleg_l", "directions": 4 + }, + { + "name": "gauze_head", + "directions": 4 } ] } \ No newline at end of file From e43c040a1b78e6a63495cc8619207a37093ddcfa Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 14 Sep 2024 14:56:20 +0000 Subject: [PATCH 002/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index af7e34b9f82..d667f813504 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Made vox roundstart. - type: Tweak - id: 6870 - time: '2024-07-04T07:11:02.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29704 - author: JIPDawg changes: - message: Changed the basic treatment module to include a Health Analyzer and removed @@ -3888,3 +3881,10 @@ id: 7369 time: '2024-09-14T13:09:43.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32063 +- author: Just_Art + changes: + - message: Added a head gauze to customization. + type: Add + id: 7370 + time: '2024-09-14T14:55:13.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30852 From 955f77d76d56f7ef465e4c5c24d50857a8530844 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 14 Sep 2024 15:58:04 +0000 Subject: [PATCH 003/138] 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 d667f813504..d2c35a5b10f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: JIPDawg - changes: - - message: Changed the basic treatment module to include a Health Analyzer and removed - the dropper. - type: Tweak - id: 6871 - time: '2024-07-04T07:17:47.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29696 - author: PJB3005 changes: - message: Fixed flashlights and similar permanently getting stuck blinking. @@ -3888,3 +3880,10 @@ id: 7370 time: '2024-09-14T14:55:13.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30852 +- author: deltanedas + changes: + - message: Fixed security's helmets not having any protection. + type: Fix + id: 7371 + time: '2024-09-14T15:56:57.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32152 From d7bef9938b44aea05f3ccdaa3a7c5a6bec132c3f Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 14 Sep 2024 19:21:33 +0300 Subject: [PATCH 004/138] Dev mouse acorgillation (#32040) * Update dev_map.yml * real mouse returned --- Resources/Maps/Test/dev_map.yml | 2 +- .../Entities/Markers/Spawners/mobs.yml | 14 + .../Prototypes/Entities/Mobs/NPCs/pets.yml | 23 ++ .../Textures/Mobs/Pets/corgi.rsi/meta.json | 292 ++---------------- .../Mobs/Pets/corgi.rsi/real_mouse.png | Bin 0 -> 2084 bytes .../Mobs/Pets/corgi.rsi/real_mouse_dead.png | Bin 0 -> 733 bytes 6 files changed, 71 insertions(+), 260 deletions(-) create mode 100644 Resources/Textures/Mobs/Pets/corgi.rsi/real_mouse.png create mode 100644 Resources/Textures/Mobs/Pets/corgi.rsi/real_mouse_dead.png diff --git a/Resources/Maps/Test/dev_map.yml b/Resources/Maps/Test/dev_map.yml index 748c4af9c2f..9fab52cc293 100644 --- a/Resources/Maps/Test/dev_map.yml +++ b/Resources/Maps/Test/dev_map.yml @@ -5077,7 +5077,7 @@ entities: - type: Transform pos: 3.5,7.5 parent: 179 -- proto: SpawnMobMouse +- proto: SpawnMobCorgiMouse entities: - uid: 1050 components: diff --git a/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml b/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml index 5cd162e8684..6509965cb52 100644 --- a/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml +++ b/Resources/Prototypes/Entities/Markers/Spawners/mobs.yml @@ -48,6 +48,20 @@ - MobCorgiLisa - MobCorgiIanPup +- type: entity + name: Dev Mouse Spawner + id: SpawnMobCorgiMouse + suffix: Admeme + parent: MarkerBase + components: + - type: Sprite + layers: + - state: green + - state: ai + - type: ConditionalSpawner + prototypes: + - MobCorgiMouse + - type: entity name: Possum Morty Spawner id: SpawnMobPossumMorty diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml index 377948b55d3..d28837dc0b1 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/pets.yml @@ -85,6 +85,29 @@ proper: true gender: female +- type: entity + name: real mouse + parent: MobCorgiIan + id: MobCorgiMouse + description: It's 100% a real hungry mouse. + components: + - type: Sprite + layers: + - map: ["enum.DamageStateVisualLayers.Base"] + state: real_mouse + - type: DamageStateVisuals + states: + Alive: + Base: real_mouse + Critical: + Base: real_mouse_dead + Dead: + Base: real_mouse_dead + - type: Grammar + attributes: + proper: true + gender: female + - type: entity name: Puppy Ian parent: MobCorgiPuppy diff --git a/Resources/Textures/Mobs/Pets/corgi.rsi/meta.json b/Resources/Textures/Mobs/Pets/corgi.rsi/meta.json index 3a540931649..0e36d32316f 100644 --- a/Resources/Textures/Mobs/Pets/corgi.rsi/meta.json +++ b/Resources/Textures/Mobs/Pets/corgi.rsi/meta.json @@ -5,207 +5,60 @@ "y": 32 }, "license": "CC-BY-SA-3.0", - "copyright": "https://github.com/tgstation/tgstation/commit/53d1f1477d22a11a99c6c6924977cd431075761b , cerberus by Alekshhh", + "copyright": "https://github.com/tgstation/tgstation/commit/53d1f1477d22a11a99c6c6924977cd431075761b , cerberus by Alekshhh, real mouse by TheShuEd", "states": [ { "name": "corgi", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "corgi_rest", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { - "name": "corgi_dead", - "delays": [ - [ - 1 - ] - ] + "name": "corgi_dead" }, { "name": "ian", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { - "name": "ian_dead", - "delays": [ - [ - 1 - ] - ] + "name": "ian_dead" }, { - "name": "corgi_deadcollar", - "delays": [ - [ - 1 - ] - ] + "name": "corgi_deadcollar" }, { - "name": "corgi_deadtag", - "delays": [ - [ - 1 - ] - ] + "name": "corgi_deadtag" }, { "name": "ian_shaved", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { - "name": "ian_shaved_dead", - "delays": [ - [ - 1 - ] - ] + "name": "ian_shaved_dead" }, { "name": "corgicollar", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "corgitag", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "lisa", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { - "name": "lisa_dead", - "delays": [ - [ - 1 - ] - ] + "name": "lisa_dead" }, { "name": "lisa_shaved", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { - "name": "lisa_shaved_dead", - "delays": [ - [ - 1 - ] - ] + "name": "lisa_shaved_dead" }, { "name": "narsian", @@ -238,12 +91,7 @@ ] }, { - "name": "old_ian_dead", - "delays": [ - [ - 1 - ] - ] + "name": "old_ian_dead" }, { "name": "old_ian_shaved", @@ -268,116 +116,42 @@ ] }, { - "name": "old_ian_shaved_dead", - "delays": [ - [ - 1 - ] - ] + "name": "old_ian_shaved_dead" }, { "name": "puppy", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { - "name": "puppy_dead", - "delays": [ - [ - 1 - ] - ] + "name": "puppy_dead" }, { - "name": "puppy_deadcollar", - "delays": [ - [ - 1 - ] - ] + "name": "puppy_deadcollar" }, { - "name": "puppy_deadtag", - "delays": [ - [ - 1 - ] - ] + "name": "puppy_deadtag" }, { "name": "puppy_shaved", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { - "name": "puppy_shaved_dead", - "delays": [ - [ - 1 - ] - ] + "name": "puppy_shaved_dead" }, { "name": "puppycollar", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 }, { "name": "puppytag", - "directions": 4, - "delays": [ - [ - 1 - ], - [ - 1 - ], - [ - 1 - ], - [ - 1 - ] - ] + "directions": 4 + }, + { + "name": "real_mouse", + "directions": 4 + }, + { + "name": "real_mouse_dead" } ] } diff --git a/Resources/Textures/Mobs/Pets/corgi.rsi/real_mouse.png b/Resources/Textures/Mobs/Pets/corgi.rsi/real_mouse.png new file mode 100644 index 0000000000000000000000000000000000000000..2983063c4fd885579acfe4f39ea30759330e03eb GIT binary patch literal 2084 zcmV+<2;29GP)Px+-bqA3RCt{2nr&!X*BO8xZPkxKrw=Q{t(c{FklPlI)b|2toZ=jOJX@*+!%~wv0+Q9O_Vm) z2mVu>aQ8z#H}~qx_sUn>kLm$)ea}65-}AobocEl2-vc#j)c7)E(OdEQxi@8i!Qe#z z4)=8dkiHwovDrhhXFGrN8{P8t>c4+ENIIPbVABuZQ1pNP!CL@095x==-KSgsSBx}b zFnE#P?rrpTZ&QqgoD)htGn;feOZ(n^H2azqqd))PEt-8zwC~-gI7cs!=&dLWe7bQL zvLyjb7Z|$jn;tB31HIi;)d`u{6aXHtoA}sSJYKh^+z7fIaJa9FpZ@x<{O)DAarbMq zwY3%0IW_(nJ2uA|3Qu#muZx{yV}=`Kgt~gC=2{7crodl*{}XQ!7Wml1IrB7fMc??pTHV8{WG z3vO<=n}&u4B9RE~bzkTF`SVDUgxl?AFnE!lhyKZt3rVA*%hG>(Mp9dc+hL(ZrL{0{V&J}R{e~PMgzkIN4Lso0wSWjP{f`-V(rvooYVMDn<(FIB zWtY9>WQzFM5`1fqE}4e5s$suXZuT`{KQIcQ1VR8wk^sn@dX7&fX6PPXHEkQ5uYWy^ z=+_+t!+xtQc3c8Ul9WF+9}%4k-_R7$yW^^>cM^{+ z84+y=ySD{fGQ}qo4&EVFF}xi%ybJ=+ndkpC%Rn zh$rqS*DIGlHY%zj=5Eh0cYEglroTpw8Z~Ovs8OTFdW8K}dF+s@=4_`H3r4b3#={KqfXtHnW1mVcSrn z!+xvmaM;LZR;u>Bv7+2yDb%@xEmFh7a%SZGj}+<*Zn11`u_Q_65Ya^IC0vryT zCU>x$OtI(fm@<4rp&_|-lT&WpuVBIJzKn96P^xX^Mp01*%-x+dGLT6C5?i(Wz z=(U_V^PcX54X4VF}v&8)DTOlcfZjovRMD_?J^ zgOh^Arv`~9?iB5al2f3V$Asc^I!ipZq&Na{PSJS3Gswt6S4F)q2n2d9BL`iYQBYU! zRE!md$74&%l2>eWmg;>dvk%DM;n@$2a_hB5zWe8U7IhuLDEbQoyY`LRPT`RPB+D|MHXsj_DVO6~-^hgU6O|B^i4c9ahJ?*Ij#xYR9U<4qluIFsrUnME+msFsp8j8Z~NssrfI5?Px%mq|oHR9J=Wl|M`qVHn1LHL{WGT?b1r?UiUwjT7-7VE}_@TrdtUjR`3Wi=@OD zCtO{0;!*|(L}E-j;2?I;1T?Z>Km`Yh$t~KFG}K7jYuFghLGHLKz2h27T>5PH-Sge^ zywCT3??Dqy{AUFGkW@8gL?dkgGGwHs)f)^P4IKctS2_W@9H z6LhRRAQNvf{BQwJF4U0#fSz3^6qd+k^NtS>q<5{DMNzQ07g(n#x08wI4Liq(k!wGA9)YT+jNZv@SRA$1 ziiHwFuoZw%SV9Q45|!Jn%B#fz&YV5(s^O~#^z6Fh*)9?aOO_Egoc#WTXrv8QO&#b5 zR|Be=G7^bFNA+F^g(XB$pjar?EWj;=Llf|-z8WzlQgb~hce?KJbp-XG+Mp@Eu<)*C z6CQdEgL3DA6zai`)%WDGd6Ma8HE*1!0Zr3T`p3a`1^uAy z%|Edo+qY>J`-W(85L;)DSd7atW=X_n=U}(C+{Fuzu;a83g z_oTUoRS$a!lz-(|`&|kEtR+VP$i#OHfcY`mA{Ps#njQbo2FwKP7)b91GHe*;UoNIZ z8rFDrc#h(M^lqSBt{? Date: Sat, 14 Sep 2024 16:27:05 +0000 Subject: [PATCH 005/138] add test for lathe recipes having results (#32100) * add test for lathe recipes having results * id --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Tests/ResearchTest.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Content.IntegrationTests/Tests/ResearchTest.cs b/Content.IntegrationTests/Tests/ResearchTest.cs index 7ae29a79ffd..f50e6111da3 100644 --- a/Content.IntegrationTests/Tests/ResearchTest.cs +++ b/Content.IntegrationTests/Tests/ResearchTest.cs @@ -98,4 +98,24 @@ await server.WaitAssertion(() => await pair.CleanReturnAsync(); } + + [Test] + public async Task AllLatheRecipesValidTest() + { + await using var pair = await PoolManager.GetServerClient(); + + var server = pair.Server; + var proto = server.ResolveDependency(); + + Assert.Multiple(() => + { + foreach (var recipe in proto.EnumeratePrototypes()) + { + if (recipe.Result == null) + Assert.That(recipe.ResultReagents, Is.Not.Null, $"Recipe '{recipe.ID}' has no result or result reagents."); + } + }); + + await pair.CleanReturnAsync(); + } } From 1508e6df5c7bcb3f2dc541f18ae1bb62b9e636a4 Mon Sep 17 00:00:00 2001 From: eoineoineoin Date: Sat, 14 Sep 2024 17:28:33 +0100 Subject: [PATCH 006/138] Allow ghosts to read books (#32151) Co-authored-by: Eoin Mcloughlin --- Resources/Prototypes/Entities/Objects/Misc/books.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Objects/Misc/books.yml b/Resources/Prototypes/Entities/Objects/Misc/books.yml index 48026c7f805..5e05f2d644f 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/books.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/books.yml @@ -22,6 +22,7 @@ contentSize: 12000 - type: ActivatableUI key: enum.PaperUiKey.Key + requiresComplex: false - type: UserInterface interfaces: enum.PaperUiKey.Key: From e7378247946ff1ccf86b262b243ecdd48e04d1e5 Mon Sep 17 00:00:00 2001 From: eoineoineoin Date: Sat, 14 Sep 2024 17:29:05 +0100 Subject: [PATCH 007/138] Fix some issues with pulling system (#32145) Joints were created with pivots at object origin, causing unintuitive behaviour when an object was not centered on the origin. Now puts the pivots at the COM. Joint limits were set based on fractions of the union of the AABB of objects, which did not make geometric sense. Now uses the pivot length with an additional [arbitrary] length. Joints were created with a very low spring stiffness, which had a negligible effect most of the time but caused very unintuitive behaviour when the pulled object had a low mass (#28028) - disable the spring limit, and just use the hard min/max limits. Co-authored-by: Eoin Mcloughlin --- .../Movement/Pulling/Systems/PullingSystem.cs | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs b/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs index 5f35adb3337..6392956d632 100644 --- a/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs +++ b/Content.Shared/Movement/Pulling/Systems/PullingSystem.cs @@ -438,7 +438,7 @@ public bool TryStartPull(EntityUid pullerUid, EntityUid pullableUid, if (!CanPull(pullerUid, pullableUid)) return false; - if (!HasComp(pullerUid) || !TryComp(pullableUid, out PhysicsComponent? pullablePhysics)) + if (!TryComp(pullerUid, out PhysicsComponent? pullerPhysics) || !TryComp(pullableUid, out PhysicsComponent? pullablePhysics)) return false; // Ensure that the puller is not currently pulling anything. @@ -485,17 +485,19 @@ public bool TryStartPull(EntityUid pullerUid, EntityUid pullableUid, // joint state handling will manage its own state if (!_timing.ApplyingState) { - // Joint startup - var union = _physics.GetHardAABB(pullerUid).Union(_physics.GetHardAABB(pullableUid, body: pullablePhysics)); - var length = Math.Max(union.Size.X, union.Size.Y) * 0.75f; - - var joint = _joints.CreateDistanceJoint(pullableUid, pullerUid, id: pullableComp.PullJointId); + var joint = _joints.CreateDistanceJoint(pullableUid, pullerUid, + pullablePhysics.LocalCenter, pullerPhysics.LocalCenter, + id: pullableComp.PullJointId); joint.CollideConnected = false; // This maximum has to be there because if the object is constrained too closely, the clamping goes backwards and asserts. - joint.MaxLength = Math.Max(1.0f, length); - joint.Length = length * 0.75f; + // Internally, the joint length has been set to the distance between the pivots. + // Add an additional 15cm (pretty arbitrary) to the maximum length for the hard limit. + joint.MaxLength = joint.Length + 0.15f; joint.MinLength = 0f; - joint.Stiffness = 1f; + // Set the spring stiffness to zero. The joint won't have any effect provided + // the current length is beteen MinLength and MaxLength. At those limits, the + // joint will have infinite stiffness. + joint.Stiffness = 0f; _physics.SetFixedRotation(pullableUid, pullableComp.FixedRotationOnPull, body: pullablePhysics); } From efdb55d83d985479e1d99244c6f24509aca3e580 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 14 Sep 2024 16:29:39 +0000 Subject: [PATCH 008/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index d2c35a5b10f..02abcfb8bc9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: PJB3005 - changes: - - message: Fixed flashlights and similar permanently getting stuck blinking. - type: Fix - id: 6872 - time: '2024-07-04T08:02:43.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29457 - author: Jezithyr changes: - message: All species except for Vox can now be played as Nukies. (Vox will be @@ -3887,3 +3880,10 @@ id: 7371 time: '2024-09-14T15:56:57.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32152 +- author: eoineoineoin + changes: + - message: Ghosts can now read books. + type: Add + id: 7372 + time: '2024-09-14T16:28:33.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32151 From 808176b1ef8958ce00b3216ea1470b9eb4af8782 Mon Sep 17 00:00:00 2001 From: Errant <35878406+Errant-4@users.noreply.github.com> Date: Sat, 14 Sep 2024 18:34:01 +0200 Subject: [PATCH 009/138] Vox LoneOp loadout fix (#31641) oh shit here we go again --- .../Locale/en-US/preferences/loadout-groups.ftl | 1 + Resources/Prototypes/GameRules/events.yml | 3 +++ Resources/Prototypes/GameRules/roundstart.yml | 12 ++++++------ .../Loadouts/Miscellaneous/survival.yml | 17 +++++++++++++++++ .../Prototypes/Loadouts/loadout_groups.yml | 10 +++++++++- Resources/Prototypes/Loadouts/role_loadouts.yml | 7 +++++++ Resources/Prototypes/Roles/Antags/nukeops.yml | 3 +-- 7 files changed, 44 insertions(+), 9 deletions(-) diff --git a/Resources/Locale/en-US/preferences/loadout-groups.ftl b/Resources/Locale/en-US/preferences/loadout-groups.ftl index dafbd151762..8fd7f7b6e99 100644 --- a/Resources/Locale/en-US/preferences/loadout-groups.ftl +++ b/Resources/Locale/en-US/preferences/loadout-groups.ftl @@ -15,6 +15,7 @@ loadout-group-survival-syndicate = Github is forcing me to write text that is li loadout-group-breath-tool = Species-dependent breath tools loadout-group-tank-harness = Species-specific survival equipment loadout-group-EVA-tank = Species-specific gas tank +loadout-group-pocket-tank-double = Species-specific double emergency tank in pocket loadout-group-survival-mime = Mime Survival Box # Command diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index 497b9a1add4..f587539e4f8 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -449,6 +449,9 @@ max: 1 pickPlayer: false startingGear: SyndicateLoneOperativeGearFull + roleLoadout: + - RoleSurvivalNukie + components: - type: NukeOperative - type: RandomMetadata diff --git a/Resources/Prototypes/GameRules/roundstart.yml b/Resources/Prototypes/GameRules/roundstart.yml index 3aa1ac09a0e..aa484de19f1 100644 --- a/Resources/Prototypes/GameRules/roundstart.yml +++ b/Resources/Prototypes/GameRules/roundstart.yml @@ -73,7 +73,7 @@ parent: BaseGameRule id: BaseNukeopsRule components: - - type: RandomMetadata #this generates the random operation name cuz it's cool. + - type: RandomMetadata #this generates the random operation name cuz it's cool. nameSegments: - operationPrefix - operationSuffix @@ -104,7 +104,7 @@ spawnerPrototype: SpawnPointNukeopsCommander startingGear: SyndicateCommanderGearFull roleLoadout: - - RoleSurvivalSyndicate + - RoleSurvivalNukie components: - type: NukeOperative - type: RandomMetadata @@ -122,7 +122,7 @@ spawnerPrototype: SpawnPointNukeopsMedic startingGear: SyndicateOperativeMedicFull roleLoadout: - - RoleSurvivalSyndicate + - RoleSurvivalNukie components: - type: NukeOperative - type: RandomMetadata @@ -142,7 +142,7 @@ playerRatio: 10 startingGear: SyndicateOperativeGearFull roleLoadout: - - RoleSurvivalSyndicate + - RoleSurvivalNukie components: - type: NukeOperative - type: RandomMetadata @@ -324,8 +324,8 @@ tableId: SpaceTrafficControlTable - type: entity - id: SpaceTrafficControlFriendlyEventScheduler - parent: BaseGameRule + id: SpaceTrafficControlFriendlyEventScheduler + parent: BaseGameRule components: - type: BasicStationEventScheduler minimumTimeUntilFirstEvent: 1200 # 20 mins diff --git a/Resources/Prototypes/Loadouts/Miscellaneous/survival.yml b/Resources/Prototypes/Loadouts/Miscellaneous/survival.yml index fdaaa18b4bc..41996dce543 100644 --- a/Resources/Prototypes/Loadouts/Miscellaneous/survival.yml +++ b/Resources/Prototypes/Loadouts/Miscellaneous/survival.yml @@ -195,6 +195,23 @@ equipment: suitstorage: OxygenTankFilled +# Species-appropriate Double Emergency Tank in Pocket 1 +- type: loadout + id: LoadoutSpeciesPocketDoubleNitrogen + effects: + - !type:GroupLoadoutEffect + proto: NitrogenBreather + equipment: + pocket1: DoubleEmergencyNitrogenTankFilled + +- type: loadout + id: LoadoutSpeciesPocketDoubleOxygen + effects: + - !type:GroupLoadoutEffect + proto: OxygenBreather + equipment: + pocket1: DoubleEmergencyOxygenTankFilled + # Tank Harness - type: loadout id: LoadoutTankHarness diff --git a/Resources/Prototypes/Loadouts/loadout_groups.yml b/Resources/Prototypes/Loadouts/loadout_groups.yml index 26da0d16627..c0d2d2153cd 100644 --- a/Resources/Prototypes/Loadouts/loadout_groups.yml +++ b/Resources/Prototypes/Loadouts/loadout_groups.yml @@ -65,6 +65,14 @@ - LoadoutSpeciesEVANitrogen - LoadoutSpeciesEVAOxygen +- type: loadoutGroup + id: GroupPocketTankDouble + name: loadout-group-pocket-tank-double + hidden: true + loadouts: + - LoadoutSpeciesPocketDoubleNitrogen + - LoadoutSpeciesPocketDoubleOxygen + # Command - type: loadoutGroup id: CaptainHead @@ -603,7 +611,7 @@ loadouts: - MimeSuspendersRed - MimeSuspendersBlack - + - type: loadoutGroup id: SurvivalMime name: loadout-group-survival-mime diff --git a/Resources/Prototypes/Loadouts/role_loadouts.yml b/Resources/Prototypes/Loadouts/role_loadouts.yml index 056ac9520c6..8181b634335 100644 --- a/Resources/Prototypes/Loadouts/role_loadouts.yml +++ b/Resources/Prototypes/Loadouts/role_loadouts.yml @@ -603,6 +603,13 @@ - GroupSpeciesBreathTool - GroupTankHarness +- type: roleLoadout + id: RoleSurvivalNukie + groups: + - SurvivalSyndicate + - GroupSpeciesBreathTool + - GroupPocketTankDouble + - type: roleLoadout id: RoleSurvivalEVA groups: diff --git a/Resources/Prototypes/Roles/Antags/nukeops.yml b/Resources/Prototypes/Roles/Antags/nukeops.yml index 311e5b5c094..ab3f901171b 100644 --- a/Resources/Prototypes/Roles/Antags/nukeops.yml +++ b/Resources/Prototypes/Roles/Antags/nukeops.yml @@ -63,7 +63,6 @@ outerClothing: ClothingOuterHardsuitSyndie shoes: ClothingShoesBootsCombatFilled id: SyndiPDA - pocket1: DoubleEmergencyOxygenTankFilled pocket2: PlushieCarp belt: ClothingBeltMilitaryWebbing storage: @@ -87,7 +86,7 @@ neck: SyndicateWhistle outerClothing: ClothingOuterHardsuitSyndieCommander inhand: - - NukeOpsDeclarationOfWar + - NukeOpsDeclarationOfWar #Nuclear Operative Medic Gear - type: startingGear From f83bfca7f17e2ce5c3c07399403a0b72b5cd7008 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 14 Sep 2024 16:35:07 +0000 Subject: [PATCH 010/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 02abcfb8bc9..f043194131b 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Jezithyr - changes: - - message: All species except for Vox can now be played as Nukies. (Vox will be - enabled when load out code supports them) - type: Tweak - id: 6873 - time: '2024-07-05T07:59:16.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29707 - author: metalgearsloth changes: - message: Shuttle map buttons will show up faster. @@ -3887,3 +3879,11 @@ id: 7372 time: '2024-09-14T16:28:33.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32151 +- author: Errant + changes: + - message: Lone Ops nukies now spawn with the appropriate species-specific survival + gear. + type: Fix + id: 7373 + time: '2024-09-14T16:34:01.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31641 From 1f77ec308b5b29b56a250046ea81a6573aed5844 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sat, 14 Sep 2024 10:19:32 -0700 Subject: [PATCH 011/138] Add snakes to vent spawn event (#32070) Add snakes to vents --- Resources/Prototypes/GameRules/events.yml | 49 ++++++++++++++++------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index f587539e4f8..7b4094cd91a 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -21,6 +21,7 @@ #- id: RandomSentience # DeltaV - replaced with RandomSentienceGlimmer - id: SlimesSpawn - id: SolarFlare + - id: SnakeSpawn - id: SpiderClownSpawn - id: SpiderSpawn - id: VentClog @@ -39,36 +40,35 @@ - id: SleeperAgents - id: ZombieOutbreak - - type: entity id: BaseStationEvent parent: BaseGameRule abstract: true components: - - type: GameRule - delay: - min: 10 - max: 20 + - type: GameRule + delay: + min: 10 + max: 20 - type: entity id: BaseStationEventShortDelay parent: BaseGameRule abstract: true components: - - type: GameRule - delay: - min: 10 - max: 20 + - type: GameRule + delay: + min: 10 + max: 20 - type: entity id: BaseStationEventLongDelay parent: BaseGameRule abstract: true components: - - type: GameRule - delay: - min: 40 - max: 60 + - type: GameRule + delay: + min: 40 + max: 60 - type: entity id: AnomalySpawn @@ -291,7 +291,7 @@ startAudio: path: /Audio/Announcements/power_off.ogg params: - volume: -4 + volume: -4 duration: 60 maxDuration: 120 - type: PowerGridCheckRule @@ -359,6 +359,27 @@ - id: MobAdultSlimesYellowAngry prob: 0.02 +- type: entity + id: SnakeSpawn + parent: BaseStationEventShortDelay + components: + - type: StationEvent + startAnnouncement: station-event-vent-creatures-start-announcement + startAudio: + path: /Audio/Announcements/attention.ogg + earliestStart: 20 + minimumPlayers: 15 + weight: 5 + duration: 60 + - type: VentCrittersRule + entries: + - id: MobPurpleSnake + prob: 0.02 + - id: MobSmallPurpleSnake + prob: 0.02 + - id: MobCobraSpace + prob: 0.02 + - type: entity id: SpiderSpawn parent: BaseStationEventShortDelay From 6ad0149bc573fb5d3b6081bd21dda0c68b036e38 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 14 Sep 2024 17:20:38 +0000 Subject: [PATCH 012/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index f043194131b..8405b14d129 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: metalgearsloth - changes: - - message: Shuttle map buttons will show up faster. - type: Tweak - id: 6874 - time: '2024-07-06T03:51:55.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29757 - author: JIPDawg changes: - message: Added Late join CryoSleepers to Origin. @@ -3887,3 +3880,10 @@ id: 7373 time: '2024-09-14T16:34:01.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31641 +- author: Plykiya + changes: + - message: The vent spawn event now has a chance to spawn snakes. + type: Add + id: 7374 + time: '2024-09-14T17:19:32.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32070 From 904b8ea11098ebcf53011bd9afcf7de89c47a7be Mon Sep 17 00:00:00 2001 From: BIGZi0348 <118811750+BIGZi0348@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:37:41 +0300 Subject: [PATCH 013/138] Moved hardcoded string "PEOPLE" to Loc.GetString() (#32164) --- Content.Server/StationEvents/Events/IonStormRule.cs | 4 +++- Resources/Locale/en-US/station-events/events/ion-storm.ftl | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Content.Server/StationEvents/Events/IonStormRule.cs b/Content.Server/StationEvents/Events/IonStormRule.cs index 7a959eb1e35..805549439ba 100644 --- a/Content.Server/StationEvents/Events/IonStormRule.cs +++ b/Content.Server/StationEvents/Events/IonStormRule.cs @@ -235,6 +235,8 @@ private string GenerateLaw() if (plural) feeling = feelingPlural; + var subjects = RobustRandom.Prob(0.5f) ? objectsThreats : Loc.GetString("ion-storm-people"); + // message logic!!! return RobustRandom.Next(0, 36) switch { @@ -266,7 +268,7 @@ private string GenerateLaw() 26 => Loc.GetString("ion-storm-law-crew-must-go", ("who", crewAll), ("area", area)), 27 => Loc.GetString("ion-storm-law-crew-only-1", ("who", crew1), ("part", part)), 28 => Loc.GetString("ion-storm-law-crew-only-2", ("who", crew1), ("other", crew2), ("part", part)), - 29 => Loc.GetString("ion-storm-law-crew-only-subjects", ("adjective", adjective), ("subjects", RobustRandom.Prob(0.5f) ? objectsThreats : "PEOPLE"), ("part", part)), + 29 => Loc.GetString("ion-storm-law-crew-only-subjects", ("adjective", adjective), ("subjects", subjects), ("part", part)), 30 => Loc.GetString("ion-storm-law-crew-must-do", ("must", must), ("part", part)), 31 => Loc.GetString("ion-storm-law-crew-must-have", ("adjective", adjective), ("objects", objects), ("part", part)), 32 => Loc.GetString("ion-storm-law-crew-must-eat", ("who", who), ("adjective", adjective), ("food", food), ("part", part)), diff --git a/Resources/Locale/en-US/station-events/events/ion-storm.ftl b/Resources/Locale/en-US/station-events/events/ion-storm.ftl index 28192d96637..02be271cdf2 100644 --- a/Resources/Locale/en-US/station-events/events/ion-storm.ftl +++ b/Resources/Locale/en-US/station-events/events/ion-storm.ftl @@ -9,6 +9,7 @@ ion-storm-the-job = THE {$job} ion-storm-clowns = CLOWNS ion-storm-heads = HEADS OF STAFF ion-storm-crew = CREW +ion-storm-people = PEOPLE ion-storm-adjective-things = {$adjective} THINGS ion-storm-x-and-y = {$x} AND {$y} From 1b7a8641df66822f50fadbfe4b0c9f5c55edc0f9 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sat, 14 Sep 2024 22:40:38 +0200 Subject: [PATCH 014/138] reinforce command intercom (#32169) * secure command intercom * Update intercom.yml --- .../Structures/Wallmounts/intercom.yml | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/intercom.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/intercom.yml index cefe0bdfba6..ae510a55750 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/intercom.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/intercom.yml @@ -205,6 +205,19 @@ - type: WiresPanel open: false +- type: entity + id: BaseIntercomSecure + parent: Intercom + abstract: true + components: + - type: WiresPanel + openDelay: 5 + - type: WiresPanelSecurity + examine: wires-panel-component-on-examine-security-level2 + wiresAccessible: false + - type: Construction + node: intercomReinforced + - type: entity id: IntercomCommon parent: Intercom @@ -219,8 +232,9 @@ - type: entity id: IntercomCommand - parent: Intercom + parent: BaseIntercomSecure suffix: Command + description: An intercom. It's been reinforced with metal. components: - type: ContainerFill containers: @@ -271,17 +285,10 @@ - type: entity id: IntercomSecurity - parent: Intercom + parent: BaseIntercomSecure suffix: Security description: An intercom. It's been reinforced with metal from security helmets, making it a bitch-and-a-half to open. components: - - type: WiresPanel - openDelay: 5 - - type: WiresPanelSecurity - examine: wires-panel-component-on-examine-security-level2 - wiresAccessible: false - - type: Construction - node: intercomReinforced - type: ContainerFill containers: board: From e22218dbff9bab5df37de50ffcc01c11df544935 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 14 Sep 2024 20:41:44 +0000 Subject: [PATCH 015/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 8405b14d129..1a505f220dd 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: JIPDawg - changes: - - message: Added Late join CryoSleepers to Origin. - type: Tweak - id: 6875 - time: '2024-07-06T17:33:20.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29761 - author: Beck Thompson changes: - message: Splashing reagents on players will now apply the correct amounts. @@ -3887,3 +3880,10 @@ id: 7374 time: '2024-09-14T17:19:32.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32070 +- author: lzk228 + changes: + - message: Command intercom now reinforced the same way as the security one. + type: Tweak + id: 7375 + time: '2024-09-14T20:40:38.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32169 From f2fc8c830d73e989be047392fb132a965adbc69f Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sat, 14 Sep 2024 21:12:01 +0000 Subject: [PATCH 016/138] clean up clothing lathe recipes (#31520) * clean up clothing lathe recipes * add result * :trollface: --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Prototypes/Recipes/Lathes/clothing.yml | 967 ++++++------------ 1 file changed, 309 insertions(+), 658 deletions(-) diff --git a/Resources/Prototypes/Recipes/Lathes/clothing.yml b/Resources/Prototypes/Recipes/Lathes/clothing.yml index b7b6a5c1a15..0db72f36636 100644 --- a/Resources/Prototypes/Recipes/Lathes/clothing.yml +++ b/Resources/Prototypes/Recipes/Lathes/clothing.yml @@ -1,1313 +1,964 @@ +# Base prototypes -# Jumpsuits/skirts - type: latheRecipe - id: ClothingUniformJumpsuitColorGrey # Tide - result: ClothingUniformJumpsuitColorGrey + abstract: true + id: BaseJumpsuitRecipe completetime: 4 materials: Cloth: 300 - type: latheRecipe - id: ClothingUniformJumpskirtColorGrey - result: ClothingUniformJumpskirtColorGrey - completetime: 4 + abstract: true + parent: BaseJumpsuitRecipe + id: BaseCommandJumpsuitRecipe materials: Cloth: 300 + Durathread: 100 + +- type: latheRecipe + abstract: true + id: BaseCoatRecipe + completetime: 3.2 # don't ask why its faster than a jumpsuit?? + materials: + Cloth: 500 + Durathread: 200 + +- type: latheRecipe + abstract: true + parent: BaseCoatRecipe + id: BaseCommandCoatRecipe + materials: + Cloth: 500 + Durathread: 300 + +- type: latheRecipe + abstract: true + id: BaseHatRecipe + completetime: 2 + materials: + Cloth: 100 + +- type: latheRecipe + abstract: true + id: BaseCarpetRecipe + completetime: 1 + materials: + Cloth: 100 + +- type: latheRecipe + abstract: true + parent: BaseHatRecipe + id: BaseCommandHatRecipe + materials: + Cloth: 100 + Durathread: 50 + +- type: latheRecipe + abstract: true + id: BaseNeckClothingRecipe + completetime: 2 + materials: + Cloth: 200 + +# Recipes + +# Jumpsuits/skirts +- type: latheRecipe + parent: BaseJumpsuitRecipe + id: ClothingUniformJumpsuitColorGrey # Tide + result: ClothingUniformJumpsuitColorGrey # Tide - type: latheRecipe + parent: BaseJumpsuitRecipe + id: ClothingUniformJumpskirtColorGrey + result: ClothingUniformJumpskirtColorGrey + +- type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitBartender result: ClothingUniformJumpsuitBartender - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtBartender result: ClothingUniformJumpskirtBartender - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCaptain result: ClothingUniformJumpsuitCaptain - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCapFormal result: ClothingUniformJumpsuitCapFormal - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtCapFormalDress result: ClothingUniformJumpskirtCapFormalDress - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtCaptain result: ClothingUniformJumpskirtCaptain - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitCargo result: ClothingUniformJumpsuitCargo - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtCargo result: ClothingUniformJumpskirtCargo - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitSalvageSpecialist result: ClothingUniformJumpsuitSalvageSpecialist - completetime: 4 - materials: - Cloth: 500 #It's armored but I don't want to include durathread for a non-head - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCentcomAgent result: ClothingUniformJumpsuitCentcomAgent - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCentcomFormal result: ClothingUniformJumpsuitCentcomFormal - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtCentcomFormalDress result: ClothingUniformJumpskirtCentcomFormalDress - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCentcomOfficer result: ClothingUniformJumpsuitCentcomOfficer - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCentcomOfficial result: ClothingUniformJumpsuitCentcomOfficial - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 + +## CE - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitChiefEngineer result: ClothingUniformJumpsuitChiefEngineer - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtChiefEngineer result: ClothingUniformJumpskirtChiefEngineer - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitChiefEngineerTurtle result: ClothingUniformJumpsuitChiefEngineerTurtle - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtChiefEngineerTurtle result: ClothingUniformJumpskirtChiefEngineerTurtle - completetime: 4 - materials: - Cloth: 300 + +## Chaplain - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitChaplain result: ClothingUniformJumpsuitChaplain - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtChaplain result: ClothingUniformJumpskirtChaplain - completetime: 4 - materials: - Cloth: 300 + +## Chef - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitChef result: ClothingUniformJumpsuitChef - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtChef result: ClothingUniformJumpskirtChef - completetime: 4 - materials: - Cloth: 300 + +## Chemist - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitChemistry result: ClothingUniformJumpsuitChemistry - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtChemistry result: ClothingUniformJumpskirtChemistry - completetime: 4 - materials: - Cloth: 300 + +## Clown - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitClown result: ClothingUniformJumpsuitClown - completetime: 4 - materials: - Cloth: 300 + +## CMO - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCMO result: ClothingUniformJumpsuitCMO - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtCMO result: ClothingUniformJumpskirtCMO - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitCMOTurtle result: ClothingUniformJumpsuitCMOTurtle - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtCMOTurtle result: ClothingUniformJumpskirtCMOTurtle - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 + +## Detective - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitDetective result: ClothingUniformJumpsuitDetective - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtDetective result: ClothingUniformJumpskirtDetective - completetime: 4 - materials: - Cloth: 300 + +## Engineer - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitEngineering result: ClothingUniformJumpsuitEngineering - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtEngineering result: ClothingUniformJumpskirtEngineering - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitSeniorEngineer result: ClothingUniformJumpsuitSeniorEngineer - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtSeniorEngineer result: ClothingUniformJumpskirtSeniorEngineer - completetime: 4 - materials: - Cloth: 300 + +## HoP - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitHoP result: ClothingUniformJumpsuitHoP - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtHoP result: ClothingUniformJumpskirtHoP - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 + +## HoS - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitHoS result: ClothingUniformJumpsuitHoS - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtHoS result: ClothingUniformJumpskirtHoS - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitHosFormal result: ClothingUniformJumpsuitHosFormal - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtHosFormal result: ClothingUniformJumpskirtHosFormal - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitHoSParadeMale result: ClothingUniformJumpsuitHoSParadeMale - completetime: 5 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtHoSParadeMale result: ClothingUniformJumpskirtHoSParadeMale - completetime: 5 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitHoSAlt result: ClothingUniformJumpsuitHoSAlt - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitHoSBlue result: ClothingUniformJumpsuitHoSBlue - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitHoSGrey result: ClothingUniformJumpsuitHoSGrey - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtHoSAlt result: ClothingUniformJumpskirtHoSAlt - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 + +## Hydroponics - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitHydroponics result: ClothingUniformJumpsuitHydroponics - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtHydroponics result: ClothingUniformJumpskirtHydroponics - completetime: 4 - materials: - Cloth: 300 + +## Janitor - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitJanitor result: ClothingUniformJumpsuitJanitor - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtJanitor result: ClothingUniformJumpskirtJanitor - completetime: 4 - materials: - Cloth: 300 + +## Lawyer - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitLawyerBlack result: ClothingUniformJumpsuitLawyerBlack - completetime: 4 - materials: - Cloth: 300 + +## Librarian - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitLibrarian result: ClothingUniformJumpsuitLibrarian - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtColorLightBrown #Librarian - result: ClothingUniformJumpskirtColorLightBrown - completetime: 4 - materials: - Cloth: 300 + result: ClothingUniformJumpskirtColorLightBrown #Librarian + +## Medical Doctor - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitMedicalDoctor result: ClothingUniformJumpsuitMedicalDoctor - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtMedicalDoctor result: ClothingUniformJumpskirtMedicalDoctor - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitSeniorPhysician result: ClothingUniformJumpsuitSeniorPhysician - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtSeniorPhysician result: ClothingUniformJumpskirtSeniorPhysician - completetime: 4 - materials: - Cloth: 300 + +## Mime - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitMime result: ClothingUniformJumpsuitMime - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtMime result: ClothingUniformJumpskirtMime - completetime: 4 - materials: - Cloth: 300 + +## Musician - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitMusician result: ClothingUniformJumpsuitMusician - completetime: 4 - materials: - Cloth: 300 + +## Operative - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitOperative result: ClothingUniformJumpsuitOperative - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtOperative result: ClothingUniformJumpskirtOperative - completetime: 4 - materials: - Cloth: 300 + +## Paramedic - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitParamedic result: ClothingUniformJumpsuitParamedic - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtParamedic result: ClothingUniformJumpskirtParamedic - completetime: 4 - materials: - Cloth: 300 + +## Senior Officer - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitSeniorOfficer result: ClothingUniformJumpsuitSeniorOfficer - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtSeniorOfficer result: ClothingUniformJumpskirtSeniorOfficer - completetime: 4 - materials: - Cloth: 300 + +## Prisoner - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitPrisoner result: ClothingUniformJumpsuitPrisoner - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtPrisoner result: ClothingUniformJumpskirtPrisoner - completetime: 4 - materials: - Cloth: 300 + +## QM - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitQM result: ClothingUniformJumpsuitQM - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitQMFormal result: ClothingUniformJumpsuitQMFormal - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtQM result: ClothingUniformJumpskirtQM - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitQMTurtleneck result: ClothingUniformJumpsuitQMTurtleneck - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtQMTurtleneck result: ClothingUniformJumpskirtQMTurtleneck - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 + +## RD - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpsuitResearchDirector result: ClothingUniformJumpsuitResearchDirector - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 - type: latheRecipe + parent: BaseCommandJumpsuitRecipe id: ClothingUniformJumpskirtResearchDirector result: ClothingUniformJumpskirtResearchDirector - completetime: 4 - materials: - Cloth: 300 - Durathread: 100 + +## Scientist - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitScientist result: ClothingUniformJumpsuitScientist - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtScientist result: ClothingUniformJumpskirtScientist - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitSeniorResearcher result: ClothingUniformJumpsuitSeniorResearcher - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtSeniorResearcher result: ClothingUniformJumpskirtSeniorResearcher - completetime: 4 - materials: - Cloth: 300 + +## Security Officer - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitSec result: ClothingUniformJumpsuitSec - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtSec result: ClothingUniformJumpskirtSec - completetime: 4 - materials: - Cloth: 300 + +## Brigmedic - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitBrigmedic result: ClothingUniformJumpsuitBrigmedic - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtBrigmedic result: ClothingUniformJumpskirtBrigmedic - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitSyndieFormal result: ClothingUniformJumpsuitSyndieFormal - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtSyndieFormalDress result: ClothingUniformJumpskirtSyndieFormalDress - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitPyjamaSyndicateBlack result: ClothingUniformJumpsuitPyjamaSyndicateBlack - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitPyjamaSyndicatePink result: ClothingUniformJumpsuitPyjamaSyndicatePink - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitPyjamaSyndicateRed result: ClothingUniformJumpsuitPyjamaSyndicateRed - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpsuitWarden result: ClothingUniformJumpsuitWarden - completetime: 4 - materials: - Cloth: 300 - type: latheRecipe + parent: BaseJumpsuitRecipe id: ClothingUniformJumpskirtWarden result: ClothingUniformJumpskirtWarden - completetime: 4 - materials: - Cloth: 300 + # Command winter coats - type: latheRecipe + parent: BaseCommandCoatRecipe id: ClothingOuterWinterCap result: ClothingOuterWinterCap - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - type: latheRecipe + parent: BaseCommandCoatRecipe id: ClothingOuterWinterCE result: ClothingOuterWinterCE - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - type: latheRecipe + parent: BaseCommandCoatRecipe id: ClothingOuterWinterCentcom result: ClothingOuterWinterCentcom - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - type: latheRecipe + parent: BaseCommandCoatRecipe id: ClothingOuterWinterCMO result: ClothingOuterWinterCMO - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - -- type: latheRecipe - id: ClothingOuterWinterHoP - result: ClothingOuterWinterHoP - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - -- type: latheRecipe - id: ClothingOuterWinterHoSUnarmored - result: ClothingOuterWinterHoSUnarmored - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - -- type: latheRecipe - id: ClothingOuterWinterWardenUnarmored - result: ClothingOuterWinterWardenUnarmored - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - -- type: latheRecipe - id: ClothingOuterWinterQM - result: ClothingOuterWinterQM - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 - -- type: latheRecipe - id: ClothingOuterWinterRD - result: ClothingOuterWinterRD - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 300 -# Mantles -- type: latheRecipe - id: ClothingNeckMantleCap - result: ClothingNeckMantleCap - completetime: 2.8 - materials: - Cloth: 200 - Durathread: 150 - type: latheRecipe - id: ClothingNeckMantleCE - result: ClothingNeckMantleCE - completetime: 2.8 - materials: - Cloth: 200 - Durathread: 150 + parent: BaseCommandCoatRecipe + id: ClothingOuterWinterHoP + result: ClothingOuterWinterHoP - type: latheRecipe - id: ClothingNeckMantleCMO - result: ClothingNeckMantleCMO - completetime: 2.8 - materials: - Cloth: 200 - Durathread: 150 + parent: BaseCommandCoatRecipe + id: ClothingOuterWinterHoSUnarmored + result: ClothingOuterWinterHoSUnarmored - type: latheRecipe - id: ClothingNeckMantleHOP - result: ClothingNeckMantleHOP - completetime: 2.8 - materials: - Cloth: 200 - Durathread: 150 + parent: BaseCommandCoatRecipe + id: ClothingOuterWinterWardenUnarmored + result: ClothingOuterWinterWardenUnarmored - type: latheRecipe - id: ClothingNeckMantleHOS - result: ClothingNeckMantleHOS - completetime: 2.8 - materials: - Cloth: 200 - Durathread: 150 + parent: BaseCommandCoatRecipe + id: ClothingOuterWinterQM + result: ClothingOuterWinterQM - type: latheRecipe - id: ClothingNeckMantleRD - result: ClothingNeckMantleRD - completetime: 2.8 - materials: - Cloth: 200 - Durathread: 150 + parent: BaseCommandCoatRecipe + id: ClothingOuterWinterRD + result: ClothingOuterWinterRD -- type: latheRecipe - id: ClothingNeckMantleQM - result: ClothingNeckMantleQM - completetime: 2.8 - materials: - Cloth: 200 - Durathread: 150 # Winter coats - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterMusician result: ClothingOuterWinterMusician - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterClown result: ClothingOuterWinterClown - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterMime result: ClothingOuterWinterMime - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterCoat result: ClothingOuterWinterCoat - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterJani result: ClothingOuterWinterJani - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterBar result: ClothingOuterWinterBar - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterChef result: ClothingOuterWinterChef - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterHydro result: ClothingOuterWinterHydro - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterAtmos result: ClothingOuterWinterAtmos - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterEngi result: ClothingOuterWinterEngi - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterCargo result: ClothingOuterWinterCargo - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterMiner result: ClothingOuterWinterMiner - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterMed result: ClothingOuterWinterMed - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterPara result: ClothingOuterWinterPara - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterChem result: ClothingOuterWinterChem - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterGen result: ClothingOuterWinterGen - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterViro result: ClothingOuterWinterViro - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterSci result: ClothingOuterWinterSci - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterRobo result: ClothingOuterWinterRobo - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterSec result: ClothingOuterWinterSec - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterSyndie result: ClothingOuterWinterSyndie - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 - type: latheRecipe + parent: BaseCoatRecipe id: ClothingOuterWinterSyndieCap result: ClothingOuterWinterSyndieCap - completetime: 3.2 - materials: - Cloth: 500 - Durathread: 200 + # Hats - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatCaptain result: ClothingHeadHatCaptain - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatCapcap result: ClothingHeadHatCapcap - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe + id: ClothingHeadHatCentcom + result: ClothingHeadHatCentcom + +- type: latheRecipe + parent: BaseCommandHatRecipe + id: ClothingHeadHatCentcomcap + result: ClothingHeadHatCentcomcap + +- type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatBeretHoS result: ClothingHeadHatBeretHoS - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatHoshat result: ClothingHeadHatHoshat - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatWarden result: ClothingHeadHatWarden - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatBeretWarden result: ClothingHeadHatBeretWarden - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatHopcap result: ClothingHeadHatHopcap - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatQMsoft result: ClothingHeadHatQMsoft - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatBeretRND result: ClothingHeadHatBeretRND - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatBeretEngineering result: ClothingHeadHatBeretEngineering - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatBeretQM result: ClothingHeadHatBeretQM - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseCommandHatRecipe id: ClothingHeadHatBeretCmo result: ClothingHeadHatBeretCmo - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 + +# Non-command hats - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadHatBeretMedic result: ClothingHeadHatBeretMedic - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadHatBeretBrigmedic result: ClothingHeadHatBeretBrigmedic - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadHatBeretSecurity result: ClothingHeadHatBeretSecurity - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadHatBeretSeniorPhysician result: ClothingHeadHatBeretSeniorPhysician - completetime: 2 - materials: - Cloth: 100 - -- type: latheRecipe - id: ClothingHeadHatCentcom - result: ClothingHeadHatCentcom - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - -- type: latheRecipe - id: ClothingHeadHatCentcomcap - result: ClothingHeadHatCentcomcap - completetime: 2 - materials: - Cloth: 100 - Durathread: 50 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadHatSyndie result: ClothingHeadHatSyndie - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadHatSyndieMAA result: ClothingHeadHatSyndieMAA - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadPyjamaSyndicateBlack result: ClothingHeadPyjamaSyndicateBlack - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadPyjamaSyndicatePink result: ClothingHeadPyjamaSyndicatePink - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadPyjamaSyndicateRed result: ClothingHeadPyjamaSyndicateRed - completetime: 2 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseHatRecipe id: ClothingHeadHatParamedicsoft result: ClothingHeadHatParamedicsoft - completetime: 1 - materials: - Cloth: 100 + # Ties - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckTieRed result: ClothingNeckTieRed - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckTieDet result: ClothingNeckTieDet - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckTieSci result: ClothingNeckTieSci - completetime: 2 - materials: - Cloth: 200 + # Scarfs - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedGreen result: ClothingNeckScarfStripedGreen - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedBlue result: ClothingNeckScarfStripedBlue - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedRed result: ClothingNeckScarfStripedRed - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedBrown result: ClothingNeckScarfStripedBrown - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedLightBlue result: ClothingNeckScarfStripedLightBlue - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedOrange result: ClothingNeckScarfStripedOrange - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedBlack result: ClothingNeckScarfStripedBlack - completetime: 2 - materials: - Cloth: 200 - type: latheRecipe + parent: BaseNeckClothingRecipe id: ClothingNeckScarfStripedPurple result: ClothingNeckScarfStripedPurple - completetime: 2 - materials: - Cloth: 200 + # Carpets - type: latheRecipe + parent: BaseCarpetRecipe id: Carpet result: FloorCarpetItemRed - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetBlack result: FloorCarpetItemBlack - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetPink result: FloorCarpetItemPink - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetBlue result: FloorCarpetItemBlue - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetGreen result: FloorCarpetItemGreen - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetOrange result: FloorCarpetItemOrange - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetPurple result: FloorCarpetItemPurple - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetCyan result: FloorCarpetItemCyan - completetime: 1 - materials: - Cloth: 100 - type: latheRecipe + parent: BaseCarpetRecipe id: CarpetWhite result: FloorCarpetItemWhite - completetime: 1 - materials: - Cloth: 100 From fbe93227f1581bc5691d7770428eff3662d0327e Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Sun, 15 Sep 2024 00:34:44 +0300 Subject: [PATCH 017/138] Use Transform instead of TryComp (#32170) Use Transform instead of TryComp --- Content.Server/Gravity/GravityGeneratorSystem.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Content.Server/Gravity/GravityGeneratorSystem.cs b/Content.Server/Gravity/GravityGeneratorSystem.cs index 5ab2dc89310..9d58b82d690 100644 --- a/Content.Server/Gravity/GravityGeneratorSystem.cs +++ b/Content.Server/Gravity/GravityGeneratorSystem.cs @@ -36,8 +36,10 @@ public override void Update(float frameTime) private void OnActivated(Entity ent, ref ChargedMachineActivatedEvent args) { ent.Comp.GravityActive = true; - if (TryComp(ent, out var xform) && - TryComp(xform.ParentUid, out GravityComponent? gravity)) + + var xform = Transform(ent); + + if (TryComp(xform.ParentUid, out GravityComponent? gravity)) { _gravitySystem.EnableGravity(xform.ParentUid, gravity); } @@ -46,8 +48,10 @@ private void OnActivated(Entity ent, ref ChargedMachi private void OnDeactivated(Entity ent, ref ChargedMachineDeactivatedEvent args) { ent.Comp.GravityActive = false; - if (TryComp(ent, out var xform) && - TryComp(xform.ParentUid, out GravityComponent? gravity)) + + var xform = Transform(ent); + + if (TryComp(xform.ParentUid, out GravityComponent? gravity)) { _gravitySystem.RefreshGravity(xform.ParentUid, gravity); } From 8b2b48262cf56a7bab28b790cc64394630b75ee8 Mon Sep 17 00:00:00 2001 From: de0rix <151521628+de0rix@users.noreply.github.com> Date: Sun, 15 Sep 2024 04:53:58 +0300 Subject: [PATCH 018/138] Fix animals sprites in critical state (#32175) Initial commit --- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 7726abf9100..3bdfac7cbad 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -33,6 +33,8 @@ states: Alive: Base: bat + Critical: + Base: dead Dead: Base: dead - type: Butcherable @@ -102,6 +104,8 @@ states: Alive: Base: 0 + Critical: + Base: dead Dead: Base: dead - type: Item @@ -352,6 +356,8 @@ states: Alive: Base: cockroach + Critical: + Base: cockroach_dead Dead: Base: cockroach_dead - type: Bloodstream @@ -609,6 +615,8 @@ states: Alive: Base: duck-0 + Critical: + Base: dead-0 Dead: Base: dead-0 - type: Butcherable @@ -649,6 +657,8 @@ states: Alive: Base: duck-1 + Critical: + Base: dead-1 Dead: Base: dead-1 @@ -666,6 +676,8 @@ states: Alive: Base: duck-2 + Critical: + Base: dead-2 Dead: Base: dead-2 @@ -725,6 +737,8 @@ states: Alive: Base: butterfly + Critical: + Base: dead Dead: Base: dead - type: Bloodstream @@ -771,6 +785,8 @@ states: Alive: Base: cow + Critical: + Base: dead Dead: Base: dead - type: SolutionContainerManager @@ -855,6 +871,8 @@ states: Alive: Base: crab + Critical: + Base: dead Dead: Base: dead - type: Butcherable @@ -1005,6 +1023,8 @@ states: Alive: Base: goose + Critical: + Base: dead Dead: Base: dead - type: Butcherable @@ -1833,6 +1853,8 @@ states: Alive: Base: lizard + Critical: + Base: dead Dead: Base: dead - type: Butcherable @@ -1889,6 +1911,8 @@ states: Alive: Base: slug + Critical: + Base: dead Dead: Base: dead - type: Butcherable @@ -1942,6 +1966,8 @@ states: Alive: Base: frog + Critical: + Base: dead Dead: Base: dead - type: Butcherable @@ -1994,6 +2020,8 @@ states: Alive: Base: parrot + Critical: + Base: dead Dead: Base: dead - type: Butcherable @@ -2046,6 +2074,8 @@ states: Alive: Base: penguin + Critical: + Base: penguin_dead Dead: Base: penguin_dead - type: Butcherable @@ -2115,6 +2145,8 @@ states: Alive: Base: penguin + Critical: + Base: dead Dead: Base: dead - type: MeleeWeapon @@ -2233,6 +2265,8 @@ states: Alive: Base: tarantula + Critical: + Base: tarantula_dead Dead: Base: tarantula_dead - type: Butcherable @@ -2358,6 +2392,8 @@ states: Alive: Base: clown + Critical: + Base: dead Dead: Base: dead - type: MobThresholds @@ -2428,6 +2464,8 @@ states: Alive: Base: possum + Critical: + Base: possum_dead Dead: Base: possum_dead - type: Butcherable @@ -2463,6 +2501,8 @@ states: Alive: Base: possum_old + Critical: + Base: possum_dead_old Dead: Base: possum_dead_old @@ -2498,6 +2538,8 @@ states: Alive: Base: raccoon + Critical: + Base: raccoon_dead Dead: Base: raccoon_dead - type: Butcherable @@ -2557,6 +2599,8 @@ states: Alive: Base: fox + Critical: + Base: fox_dead Dead: Base: fox_dead - type: Butcherable @@ -2629,6 +2673,8 @@ states: Alive: Base: corgi + Critical: + Base: corgi_dead Dead: Base: corgi_dead - type: Butcherable @@ -2670,6 +2716,8 @@ states: Alive: Base: narsian + Critical: + Base: narsian_dead Dead: Base: narsian_dead - type: MeleeWeapon @@ -2773,6 +2821,8 @@ states: Alive: Base: cat + Critical: + Base: cat_dead Dead: Base: cat_dead - type: Speech @@ -2823,6 +2873,8 @@ states: Alive: Base: cat2 + Critical: + Base: cat2_dead Dead: Base: cat2_dead @@ -2840,6 +2892,8 @@ states: Alive: Base: syndicat + Critical: + Base: syndicat_dead Dead: Base: syndicat_dead - type: GhostRole @@ -2885,6 +2939,8 @@ states: Alive: Base: spacecat + Critical: + Base: spacecat_dead Dead: Base: spacecat_dead - type: Temperature @@ -2922,6 +2978,8 @@ states: Alive: Base: caracal_flop + Critical: + Base: caracal_dead Dead: Base: caracal_dead @@ -2995,6 +3053,8 @@ states: Alive: Base: sloth + Critical: + Base: sloth_dead Dead: Base: sloth_dead - type: Butcherable @@ -3047,6 +3107,8 @@ states: Alive: Base: ferret + Critical: + Base: Dead: Base: ferret_dead - type: Butcherable @@ -3254,6 +3316,8 @@ states: Alive: Base: pig + Critical: + Base: Dead: Base: dead - type: Butcherable From e12eb474e5ee3580306753b230d30bcd1671c17b Mon Sep 17 00:00:00 2001 From: slarticodefast <161409025+slarticodefast@users.noreply.github.com> Date: Sun, 15 Sep 2024 03:54:18 +0200 Subject: [PATCH 019/138] fix infinite banana bug (#32167) --- .../Effects/Systems/ChemicalPuddleArtifactSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ChemicalPuddleArtifactSystem.cs b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ChemicalPuddleArtifactSystem.cs index cd312797ce7..542d8bb84cc 100644 --- a/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ChemicalPuddleArtifactSystem.cs +++ b/Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ChemicalPuddleArtifactSystem.cs @@ -18,7 +18,7 @@ public sealed class ChemicalPuddleArtifactSystem : EntitySystem /// The key for the node data entry containing /// the chemicals that the puddle is made of. /// - public const string NodeDataChemicalList = "nodeDataSpawnAmount"; + public const string NodeDataChemicalList = "nodeDataChemicalList"; /// public override void Initialize() From 9a089a1f04bb3efe5b65dc749d7cbecf52c59dd6 Mon Sep 17 00:00:00 2001 From: nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com> Date: Sun, 15 Sep 2024 01:55:03 +0000 Subject: [PATCH 020/138] Rename fix (#31654) * Localize RenameCommand and delegate most of the process to MetaDataSystem.SetEntityName() * Make renaming rely on the EntityRenamedEvent. Fix issue where renaming would keep old Examine text Requires engine change * Fix localisation strings * Make PDA search be based on a renamed entity's Uid instead of its old name To do this the pda component now has an PdaOwner field which gets assigned when it is given as a loadout to a player * Fix bad merge??? huh * Use AllEntityQuery --- .../Administration/Systems/AdminSystem.cs | 6 ++ .../IdentityManagement/IdentitySystem.cs | 1 + Content.Server/Mind/Commands/RenameCommand.cs | 80 ++----------------- Content.Server/PDA/PdaSystem.cs | 19 ++++- .../Station/Systems/StationSpawningSystem.cs | 2 +- .../Systems/StationRecordsSystem.cs | 30 ++++++- .../Access/Systems/SharedIdCardSystem.cs | 13 +++ Content.Shared/Mind/SharedMindSystem.cs | 7 ++ .../EntitySystems/NameModifierSystem.cs | 8 +- Content.Shared/PDA/PdaComponent.cs | 4 + .../en-US/mind/commands/rename-command.ftl | 5 ++ 11 files changed, 95 insertions(+), 80 deletions(-) create mode 100644 Resources/Locale/en-US/mind/commands/rename-command.ftl diff --git a/Content.Server/Administration/Systems/AdminSystem.cs b/Content.Server/Administration/Systems/AdminSystem.cs index db9f13dad82..e67ec326df1 100644 --- a/Content.Server/Administration/Systems/AdminSystem.cs +++ b/Content.Server/Administration/Systems/AdminSystem.cs @@ -98,6 +98,7 @@ public override void Initialize() SubscribeLocalEvent(OnRoleEvent); SubscribeLocalEvent(OnRoleEvent); SubscribeLocalEvent(OnRoundRestartCleanup); + SubscribeLocalEvent(OnPlayerRenamed); } private void OnRoundRestartCleanup(RoundRestartCleanupEvent ev) @@ -124,6 +125,11 @@ private void OnRoundRestartCleanup(RoundRestartCleanupEvent ev) } } + private void OnPlayerRenamed(Entity ent, ref EntityRenamedEvent args) + { + UpdatePlayerList(ent.Comp.PlayerSession); + } + public void UpdatePlayerList(ICommonSession player) { _playerList[player.UserId] = GetPlayerInfo(player.Data, player); diff --git a/Content.Server/IdentityManagement/IdentitySystem.cs b/Content.Server/IdentityManagement/IdentitySystem.cs index 4766b89172f..e110a424834 100644 --- a/Content.Server/IdentityManagement/IdentitySystem.cs +++ b/Content.Server/IdentityManagement/IdentitySystem.cs @@ -39,6 +39,7 @@ public override void Initialize() SubscribeLocalEvent((uid, _, _) => QueueIdentityUpdate(uid)); SubscribeLocalEvent((uid, _, _) => QueueIdentityUpdate(uid)); SubscribeLocalEvent((uid, _, _) => QueueIdentityUpdate(uid)); + SubscribeLocalEvent((uid, _, _) => QueueIdentityUpdate(uid)); SubscribeLocalEvent(OnMapInit); } diff --git a/Content.Server/Mind/Commands/RenameCommand.cs b/Content.Server/Mind/Commands/RenameCommand.cs index 834453fb198..f283fe5d19c 100644 --- a/Content.Server/Mind/Commands/RenameCommand.cs +++ b/Content.Server/Mind/Commands/RenameCommand.cs @@ -1,31 +1,22 @@ using System.Diagnostics.CodeAnalysis; -using Content.Server.Access.Systems; using Content.Server.Administration; -using Content.Server.Administration.Systems; -using Content.Server.PDA; -using Content.Server.StationRecords.Systems; using Content.Shared.Access.Components; using Content.Shared.Administration; -using Content.Shared.Mind; -using Content.Shared.PDA; -using Content.Shared.StationRecords; using Robust.Server.Player; using Robust.Shared.Console; -using Robust.Shared.Player; namespace Content.Server.Mind.Commands; [AdminCommand(AdminFlags.VarEdit)] -public sealed class RenameCommand : IConsoleCommand +public sealed class RenameCommand : LocalizedEntityCommands { [Dependency] private readonly IEntityManager _entManager = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly MetaDataSystem _metaSystem = default!; - public string Command => "rename"; - public string Description => "Renames an entity and its cloner entries, ID cards, and PDAs."; - public string Help => "rename "; + public override string Command => "rename"; - public void Execute(IConsoleShell shell, string argStr, string[] args) + public override void Execute(IConsoleShell shell, string argStr, string[] args) { if (args.Length != 2) { @@ -36,69 +27,14 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) var name = args[1]; if (name.Length > IdCardConsoleComponent.MaxFullNameLength) { - shell.WriteLine("Name is too long."); + shell.WriteLine(Loc.GetString("cmd-rename-too-long")); return; } if (!TryParseUid(args[0], shell, _entManager, out var entityUid)) return; - // Metadata - var metadata = _entManager.GetComponent(entityUid.Value); - var oldName = metadata.EntityName; - _entManager.System().SetEntityName(entityUid.Value, name, metadata); - - var minds = _entManager.System(); - - if (minds.TryGetMind(entityUid.Value, out var mindId, out var mind)) - { - // Mind - mind.CharacterName = name; - _entManager.Dirty(mindId, mind); - } - - // Id Cards - if (_entManager.TrySystem(out var idCardSystem)) - { - if (idCardSystem.TryFindIdCard(entityUid.Value, out var idCard)) - { - idCardSystem.TryChangeFullName(idCard, name, idCard); - - // Records - // This is done here because ID cards are linked to station records - if (_entManager.TrySystem(out var recordsSystem) - && _entManager.TryGetComponent(idCard, out StationRecordKeyStorageComponent? keyStorage) - && keyStorage.Key is {} key) - { - if (recordsSystem.TryGetRecord(key, out var generalRecord)) - { - generalRecord.Name = name; - } - - recordsSystem.Synchronize(key); - } - } - } - - // PDAs - if (_entManager.TrySystem(out var pdaSystem)) - { - var query = _entManager.EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var pda)) - { - if (pda.OwnerName == oldName) - { - pdaSystem.SetOwner(uid, pda, name); - } - } - } - - // Admin Overlay - if (_entManager.TrySystem(out var adminSystem) - && _entManager.TryGetComponent(entityUid, out var actorComp)) - { - adminSystem.UpdatePlayerList(actorComp.PlayerSession); - } + _metaSystem.SetEntityName(entityUid.Value, name); } private bool TryParseUid(string str, IConsoleShell shell, @@ -114,9 +50,9 @@ private bool TryParseUid(string str, IConsoleShell shell, } if (session == null) - shell.WriteError("Can't find username/uid: " + str); + shell.WriteError(Loc.GetString("cmd-rename-not-found", ("target", str))); else - shell.WriteError(str + " does not have an entity."); + shell.WriteError(Loc.GetString("cmd-rename-no-entity", ("target", str))); entityUid = EntityUid.Invalid; return false; diff --git a/Content.Server/PDA/PdaSystem.cs b/Content.Server/PDA/PdaSystem.cs index 691d024ecd7..cdcdbc02e5f 100644 --- a/Content.Server/PDA/PdaSystem.cs +++ b/Content.Server/PDA/PdaSystem.cs @@ -55,9 +55,23 @@ public override void Initialize() SubscribeLocalEvent(OnNotification); SubscribeLocalEvent(OnStationRenamed); + SubscribeLocalEvent(OnEntityRenamed); SubscribeLocalEvent(OnAlertLevelChanged); } + private void OnEntityRenamed(ref EntityRenamedEvent ev) + { + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var uid, out var comp)) + { + if (comp.PdaOwner == ev.Uid) + { + SetOwner(uid, comp, ev.Uid, ev.NewName); + } + } + } + protected override void OnComponentInit(EntityUid uid, PdaComponent pda, ComponentInit args) { base.OnComponentInit(uid, pda, args); @@ -94,9 +108,10 @@ private void OnLightToggle(EntityUid uid, PdaComponent pda, LightToggleEvent arg UpdatePdaUi(uid, pda); } - public void SetOwner(EntityUid uid, PdaComponent pda, string ownerName) + public void SetOwner(EntityUid uid, PdaComponent pda, EntityUid owner, string ownerName) { pda.OwnerName = ownerName; + pda.PdaOwner = owner; UpdatePdaUi(uid, pda); } @@ -112,7 +127,7 @@ private void OnAlertLevelChanged(AlertLevelChangedEvent args) private void UpdateAllPdaUisOnStation() { - var query = EntityQueryEnumerator(); + var query = AllEntityQuery(); while (query.MoveNext(out var ent, out var comp)) { UpdatePdaUi(ent, comp); diff --git a/Content.Server/Station/Systems/StationSpawningSystem.cs b/Content.Server/Station/Systems/StationSpawningSystem.cs index cbf9f4861d0..47340d9ff1e 100644 --- a/Content.Server/Station/Systems/StationSpawningSystem.cs +++ b/Content.Server/Station/Systems/StationSpawningSystem.cs @@ -254,7 +254,7 @@ public void SetPdaAndIdCardData(EntityUid entity, string characterName, JobCompo _accessSystem.SetAccessToJob(cardId, jobPrototype, extendedAccess); if (pdaComponent != null) - _pdaSystem.SetOwner(idUid.Value, pdaComponent, characterName); + _pdaSystem.SetOwner(idUid.Value, pdaComponent, entity, characterName); } diff --git a/Content.Server/StationRecords/Systems/StationRecordsSystem.cs b/Content.Server/StationRecords/Systems/StationRecordsSystem.cs index a16d023f60b..b3dfe4e75c5 100644 --- a/Content.Server/StationRecords/Systems/StationRecordsSystem.cs +++ b/Content.Server/StationRecords/Systems/StationRecordsSystem.cs @@ -1,7 +1,9 @@ using System.Diagnostics.CodeAnalysis; +using System.IO; +using Content.Server.Access.Systems; using Content.Server.Forensics; using Content.Server.GameTicking; -using Content.Shared.Access.Components; // DeltaV +using Content.Shared.Access.Components; using Content.Shared.Access.Systems; // DeltaV using Content.Shared.Inventory; using Content.Shared.PDA; @@ -38,12 +40,14 @@ public sealed class StationRecordsSystem : SharedStationRecordsSystem [Dependency] private readonly SharedIdCardSystem _idCard = default!; // DeltaV [Dependency] private readonly StationRecordKeyStorageSystem _keyStorage = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly IdCardSystem _idCard = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnPlayerSpawn); + SubscribeLocalEvent(OnRename); } private void OnPlayerSpawn(PlayerSpawnCompleteEvent args) @@ -54,6 +58,30 @@ private void OnPlayerSpawn(PlayerSpawnCompleteEvent args) CreateGeneralRecord(args.Station, args.Mob, args.Profile, args.JobId, stationRecords); } + private void OnRename(ref EntityRenamedEvent ev) + { + // When a player gets renamed their card gets changed to match. + // Unfortunately this means that an event is called for it as well, and since TryFindIdCard will succeed if the + // given entity is a card and the card itself is the key the record will be mistakenly renamed to the card's name + // if we don't return early. + if (HasComp(ev.Uid)) + return; + + if (_idCard.TryFindIdCard(ev.Uid, out var idCard)) + { + if (TryComp(idCard, out StationRecordKeyStorageComponent? keyStorage) + && keyStorage.Key is {} key) + { + if (TryGetRecord(key, out var generalRecord)) + { + generalRecord.Name = ev.NewName; + } + + Synchronize(key); + } + } + } + private void CreateGeneralRecord(EntityUid station, EntityUid player, HumanoidCharacterProfile profile, string? jobId, StationRecordsComponent records) { diff --git a/Content.Shared/Access/Systems/SharedIdCardSystem.cs b/Content.Shared/Access/Systems/SharedIdCardSystem.cs index 5a90d4ea355..8bdc548e353 100644 --- a/Content.Shared/Access/Systems/SharedIdCardSystem.cs +++ b/Content.Shared/Access/Systems/SharedIdCardSystem.cs @@ -25,6 +25,19 @@ public override void Initialize() SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnTryGetIdentityShortInfo); + SubscribeLocalEvent(OnRename); + } + + private void OnRename(ref EntityRenamedEvent ev) + { + // When a player gets renamed their id card is renamed as well to match. + // Unfortunately since TryFindIdCard will succeed if the entity is also a card this means that the card will + // keep renaming itself unless we return early. + if (HasComp(ev.Uid)) + return; + + if (TryFindIdCard(ev.Uid, out var idCard)) + TryChangeFullName(idCard, ev.NewName, idCard); } private void OnMapInit(EntityUid uid, IdCardComponent id, MapInitEvent args) diff --git a/Content.Shared/Mind/SharedMindSystem.cs b/Content.Shared/Mind/SharedMindSystem.cs index c8e1c1a4b3a..162bca495ca 100644 --- a/Content.Shared/Mind/SharedMindSystem.cs +++ b/Content.Shared/Mind/SharedMindSystem.cs @@ -39,6 +39,7 @@ public override void Initialize() SubscribeLocalEvent(OnVisitingTerminating); SubscribeLocalEvent(OnReset); SubscribeLocalEvent(OnMindStartup); + SubscribeLocalEvent(OnRenamed); } public override void Shutdown() @@ -181,6 +182,12 @@ private void OnSuicide(EntityUid uid, MindContainerComponent component, SuicideE args.Handled = true; } + private void OnRenamed(Entity ent, ref EntityRenamedEvent args) + { + ent.Comp.CharacterName = args.NewName; + Dirty(ent); + } + public EntityUid? GetMind(EntityUid uid, MindContainerComponent? mind = null) { if (!Resolve(uid, ref mind)) diff --git a/Content.Shared/NameModifier/EntitySystems/NameModifierSystem.cs b/Content.Shared/NameModifier/EntitySystems/NameModifierSystem.cs index 4dffb51805c..2e7c8054b3b 100644 --- a/Content.Shared/NameModifier/EntitySystems/NameModifierSystem.cs +++ b/Content.Shared/NameModifier/EntitySystems/NameModifierSystem.cs @@ -5,7 +5,7 @@ namespace Content.Shared.NameModifier.EntitySystems; /// -public sealed partial class NameModifierSystem : EntitySystem +public sealed class NameModifierSystem : EntitySystem { [Dependency] private readonly MetaDataSystem _metaData = default!; @@ -16,10 +16,10 @@ public override void Initialize() SubscribeLocalEvent(OnEntityRenamed); } - private void OnEntityRenamed(Entity entity, ref EntityRenamedEvent args) + private void OnEntityRenamed(Entity ent, ref EntityRenamedEvent args) { - SetBaseName((entity, entity.Comp), args.NewName); - RefreshNameModifiers((entity, entity.Comp)); + SetBaseName(ent, args.NewName); + RefreshNameModifiers((ent.Owner, ent.Comp)); } private void SetBaseName(Entity entity, string name) diff --git a/Content.Shared/PDA/PdaComponent.cs b/Content.Shared/PDA/PdaComponent.cs index d4cfc4fc0d8..6aeb245e27d 100644 --- a/Content.Shared/PDA/PdaComponent.cs +++ b/Content.Shared/PDA/PdaComponent.cs @@ -37,6 +37,10 @@ public sealed partial class PdaComponent : Component [ViewVariables] public bool FlashlightOn; [ViewVariables(VVAccess.ReadWrite)] public string? OwnerName; + // The Entity that "owns" the PDA, usually a player's character. + // This is useful when we are doing stuff like renaming a player and want to find their PDA to change the name + // as well. + [ViewVariables(VVAccess.ReadWrite)] public EntityUid? PdaOwner; [ViewVariables] public string? StationName; [ViewVariables] public string? StationAlertLevel; [ViewVariables] public Color StationAlertColor = Color.White; diff --git a/Resources/Locale/en-US/mind/commands/rename-command.ftl b/Resources/Locale/en-US/mind/commands/rename-command.ftl new file mode 100644 index 00000000000..4749cd6379e --- /dev/null +++ b/Resources/Locale/en-US/mind/commands/rename-command.ftl @@ -0,0 +1,5 @@ +cmd-rename-desc = Renames an entity and its cloner entries, ID cards, and PDAs. +cmd-rename-help = rename +cmd-rename-too-long = Name is too long. +cmd-rename-not-found = Can't find username/uid: {$target} +cmd-rename-no-entity = {$target} does not have an entity. From 49686299bc9b64f4b3846803d1949dddafb203b4 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 15 Sep 2024 01:55:04 +0000 Subject: [PATCH 021/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 1a505f220dd..8add68a9cf2 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Beck Thompson - changes: - - message: Splashing reagents on players will now apply the correct amounts. - type: Fix - id: 6876 - time: '2024-07-07T03:52:18.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29763 - author: Tayrtahn changes: - message: Dead bodies will no longer remain standing after being unbuckled from @@ -3887,3 +3880,10 @@ id: 7375 time: '2024-09-14T20:40:38.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32169 +- author: de0rix + changes: + - message: Animals in critical state now all have proper sprites. + type: Fix + id: 7376 + time: '2024-09-15T01:53:58.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32175 From a4f31860c163806ef81632c66713ce0703cbcb1e Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 15 Sep 2024 01:56:14 +0000 Subject: [PATCH 022/138] Automatic changelog update --- Resources/Changelog/Admin.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Resources/Changelog/Admin.yml b/Resources/Changelog/Admin.yml index dfb4dc3556c..9c9673a6622 100644 --- a/Resources/Changelog/Admin.yml +++ b/Resources/Changelog/Admin.yml @@ -534,5 +534,15 @@ Entries: id: 66 time: '2024-09-13T22:49:27.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32125 +- author: nikthechampiongr + changes: + - message: Rename verb now acts the same as the rename command. + type: Fix + - message: Renamed entities will now have their new name appear immediately on entity + examination and on crew monitor console. + type: Fix + id: 67 + time: '2024-09-15T01:55:03.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31654 Name: Admin Order: 3 From 01eb4aca7c7d75de9192984cefa4d6f4c29ccacf Mon Sep 17 00:00:00 2001 From: Partmedia Date: Sat, 14 Sep 2024 17:58:10 -0800 Subject: [PATCH 023/138] Make pressure and volume pumps require power (#28995) --- .../Binary/EntitySystems/GasPressurePumpSystem.cs | 11 ++++++++++- .../Binary/EntitySystems/GasVolumePumpSystem.cs | 11 ++++++++++- .../Structures/Piping/Atmospherics/binary.yml | 14 ++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs index 871c84e0588..56359a85af5 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs @@ -5,6 +5,7 @@ using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.Components; using Content.Shared.Atmos; using Content.Shared.Atmos.Piping; using Content.Shared.Atmos.Piping.Binary.Components; @@ -39,6 +40,7 @@ public override void Initialize() SubscribeLocalEvent(OnPumpLeaveAtmosphere); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnPumpActivate); + SubscribeLocalEvent(OnPowerChanged); // Bound UI subscriptions SubscribeLocalEvent(OnOutputPressureChangeMessage); SubscribeLocalEvent(OnToggleStatusMessage); @@ -63,9 +65,15 @@ private void OnExamined(EntityUid uid, GasPressurePumpComponent pump, ExaminedEv } } + private void OnPowerChanged(EntityUid uid, GasPressurePumpComponent component, ref PowerChangedEvent args) + { + UpdateAppearance(uid, component); + } + private void OnPumpUpdated(EntityUid uid, GasPressurePumpComponent pump, ref AtmosDeviceUpdateEvent args) { if (!pump.Enabled + || (TryComp(uid, out var power) && !power.Powered) || !_nodeContainer.TryGetNodes(uid, pump.InletName, pump.OutletName, out PipeNode? inlet, out PipeNode? outlet)) { _ambientSoundSystem.SetAmbience(uid, false); @@ -154,7 +162,8 @@ private void UpdateAppearance(EntityUid uid, GasPressurePumpComponent? pump = nu if (!Resolve(uid, ref pump, ref appearance, false)) return; - _appearance.SetData(uid, PumpVisuals.Enabled, pump.Enabled, appearance); + bool pumpOn = pump.Enabled && (TryComp(uid, out var power) && power.Powered); + _appearance.SetData(uid, PumpVisuals.Enabled, pumpOn, appearance); } } } diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs index d9fbeb474e2..d1127920514 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs @@ -9,6 +9,7 @@ using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; +using Content.Server.Power.Components; using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Atmos.Visuals; using Content.Shared.Audio; @@ -45,6 +46,7 @@ public override void Initialize() SubscribeLocalEvent(OnVolumePumpLeaveAtmosphere); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnPumpActivate); + SubscribeLocalEvent(OnPowerChanged); // Bound UI subscriptions SubscribeLocalEvent(OnTransferRateChangeMessage); SubscribeLocalEvent(OnToggleStatusMessage); @@ -69,9 +71,15 @@ private void OnExamined(EntityUid uid, GasVolumePumpComponent pump, ExaminedEven args.PushMarkup(str); } + private void OnPowerChanged(EntityUid uid, GasVolumePumpComponent component, ref PowerChangedEvent args) + { + UpdateAppearance(uid, component); + } + private void OnVolumePumpUpdated(EntityUid uid, GasVolumePumpComponent pump, ref AtmosDeviceUpdateEvent args) { if (!pump.Enabled || + (TryComp(uid, out var power) && !power.Powered) || !_nodeContainer.TryGetNodes(uid, pump.InletName, pump.OutletName, out PipeNode? inlet, out PipeNode? outlet)) { _ambientSoundSystem.SetAmbience(uid, false); @@ -183,7 +191,8 @@ private void UpdateAppearance(EntityUid uid, GasVolumePumpComponent? pump = null if (!Resolve(uid, ref pump, ref appearance, false)) return; - if (!pump.Enabled) + bool pumpOn = pump.Enabled && (TryComp(uid, out var power) && power.Powered); + if (!pumpOn) _appearance.SetData(uid, GasVolumePumpVisuals.State, GasVolumePumpState.Off, appearance); else if (pump.Blocked) _appearance.SetData(uid, GasVolumePumpVisuals.State, GasVolumePumpState.Blocked, appearance); diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml index 24a8cb58da0..ba86ca65a06 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml @@ -24,13 +24,18 @@ pipeDirection: South - type: entity - parent: GasBinaryBase + parent: [BaseMachinePowered, GasBinaryBase] id: GasPressurePump name: gas pump description: A pump that moves gas by pressure. placement: mode: SnapgridCenter components: + - type: ApcPowerReceiver + powerLoad: 200 + - type: Rotatable + - type: Transform + noRot: false - type: Sprite sprite: Structures/Piping/Atmospherics/pump.rsi layers: @@ -64,13 +69,18 @@ path: /Audio/Ambience/Objects/gas_pump.ogg - type: entity - parent: GasBinaryBase + parent: [BaseMachinePowered, GasBinaryBase] id: GasVolumePump name: volumetric gas pump description: A pump that moves gas by volume. placement: mode: SnapgridCenter components: + - type: ApcPowerReceiver + powerLoad: 200 + - type: Rotatable + - type: Transform + noRot: false - type: Sprite sprite: Structures/Piping/Atmospherics/pump.rsi layers: From 425250f6cd565d323310a2d1f406e2548d123f5e Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 15 Sep 2024 01:59:16 +0000 Subject: [PATCH 024/138] 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 8add68a9cf2..333c321c8bb 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Tayrtahn - changes: - - message: Dead bodies will no longer remain standing after being unbuckled from - chairs. - type: Fix - id: 6877 - time: '2024-07-07T06:20:53.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29741 - author: Simyon changes: - message: Ratkings now require at least 30 players in order to spawn. @@ -3887,3 +3879,10 @@ id: 7376 time: '2024-09-15T01:53:58.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32175 +- author: notafet + changes: + - message: Pressure and volume pumps now require power to operate. + type: Tweak + id: 7377 + time: '2024-09-15T01:58:10.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/28995 From dd642a6dd6f66b143049c5eb97e371a1afa61948 Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Sun, 15 Sep 2024 05:08:54 +0300 Subject: [PATCH 025/138] Update SharedBuckleSystem to use PopupClient (#31498) --- .../Buckle/SharedBuckleSystem.Buckle.cs | 47 ++++++++++--------- Content.Shared/Buckle/SharedBuckleSystem.cs | 2 - 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index 83c24016ceb..7f6c39eafc0 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -242,8 +242,9 @@ private bool CanBuckle(EntityUid buckleUid, if (_whitelistSystem.IsWhitelistFail(strapComp.Whitelist, buckleUid) || _whitelistSystem.IsBlacklistPass(strapComp.Blacklist, buckleUid)) { - if (_netManager.IsServer && popup && user != null) - _popup.PopupEntity(Loc.GetString("buckle-component-cannot-fit-message"), user.Value, user.Value, PopupType.Medium); + if (popup) + _popup.PopupClient(Loc.GetString("buckle-component-cannot-fit-message"), user, PopupType.Medium); + return false; } @@ -261,23 +262,24 @@ private bool CanBuckle(EntityUid buckleUid, if (user != null && !HasComp(user)) { - // PopupPredicted when - if (_netManager.IsServer && popup) - _popup.PopupEntity(Loc.GetString("buckle-component-no-hands-message"), user.Value, user.Value); + if (popup) + _popup.PopupClient(Loc.GetString("buckle-component-no-hands-message"), user); + return false; } if (buckleComp.Buckled) { - if (_netManager.IsClient || popup || user == null) - return false; - - var message = Loc.GetString(buckleUid == user + if (popup) + { + var message = Loc.GetString(buckleUid == user ? "buckle-component-already-buckled-message" : "buckle-component-other-already-buckled-message", ("owner", Identity.Entity(buckleUid, EntityManager))); - _popup.PopupEntity(message, user.Value, user.Value); + _popup.PopupClient(message, user); + } + return false; } @@ -291,29 +293,30 @@ private bool CanBuckle(EntityUid buckleUid, continue; } - if (_netManager.IsClient || popup || user == null) - return false; - - var message = Loc.GetString(buckleUid == user + if (popup) + { + var message = Loc.GetString(buckleUid == user ? "buckle-component-cannot-buckle-message" : "buckle-component-other-cannot-buckle-message", ("owner", Identity.Entity(buckleUid, EntityManager))); - _popup.PopupEntity(message, user.Value, user.Value); + _popup.PopupClient(message, user); + } + return false; } if (!StrapHasSpace(strapUid, buckleComp, strapComp)) { - if (_netManager.IsClient || popup || user == null) - return false; - - var message = Loc.GetString(buckleUid == user - ? "buckle-component-cannot-fit-message" - : "buckle-component-other-cannot-fit-message", + if (popup) + { + var message = Loc.GetString(buckleUid == user + ? "buckle-component-cannot-buckle-message" + : "buckle-component-other-cannot-buckle-message", ("owner", Identity.Entity(buckleUid, EntityManager))); - _popup.PopupEntity(message, user.Value, user.Value); + _popup.PopupClient(message, user); + } return false; } diff --git a/Content.Shared/Buckle/SharedBuckleSystem.cs b/Content.Shared/Buckle/SharedBuckleSystem.cs index d190f685ed0..da1d111f977 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.cs @@ -9,7 +9,6 @@ using Content.Shared.Standing; using Robust.Shared.Audio.Systems; using Robust.Shared.Containers; -using Robust.Shared.Network; using Robust.Shared.Physics.Systems; using Robust.Shared.Player; using Robust.Shared.Timing; @@ -18,7 +17,6 @@ namespace Content.Shared.Buckle; public abstract partial class SharedBuckleSystem : EntitySystem { - [Dependency] private readonly INetManager _netManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly ISharedPlayerManager _playerManager = default!; From 31e3ef00fa0f2faacc14e54e54fbdffdbe452e6a Mon Sep 17 00:00:00 2001 From: drakewill-CRL <46307022+drakewill-CRL@users.noreply.github.com> Date: Sat, 14 Sep 2024 23:12:17 -0400 Subject: [PATCH 026/138] Botany Rework Part 1: Mutations (#31163) Instead of each mutation being a flag that gets checked at some unique point in BotanySystem somewhere, they're now EntityEffects that get applied when the mutation occurs and when produce is harvested. One new list was added to SeedData so that multiple other fields could be removed. All the non-stat-change mutations that have been rolled are added to the Mutations list, and get applied to the plant when the mutation occurs or when a seed with the mutation is planted. Produce get mutations applied at harvest if they apply to the produce, and carry all of the plant's mutations over as a seed. This gets rid of the one-off checks for things like Slippery, Bioluminescent, Sentient, etc. The base odds of a mutation applying should be equal to the odds of the original mutation check. It pretended to have 1 bit flip (on averge) per mutation power, and odds of each mutation was the odds of one of its bit being flipped (1 /275 * bits). The 'thermometer code' applied for numbers will be replaced with simple random rolls, as both average out to the middle value. The new checks are much easier to understand and don't obfuscate the actual changes of something happening behind 3 layers of math. The biggest player-facing change is that Potency will be able to get over 65 significantly more often than it did in the previous system, but it will be just as common to get low values as high ones. Mutation definitions have been moved to a .yml file. These include the odds per tick per mutagen strength of that mutation applying that tick, the effect applied, if it applies to the plant and/or its produce. This makes mutations simpler to add and edit. This PR is limited specifically to the mutation logic. Improving other aspects of the system will be done in other PRs per the design document. Mutations was chosen first because its got the largest amount of one-off checks scattered all over that could be consolidated. Once this is merged, mutations could be contributed to the codebase with minimal extra work for later botany refactor PRs. --- .../Botany/Components/PlantHolderComponent.cs | 58 ++-- .../Botany/Components/ProduceComponent.cs | 4 +- Content.Server/Botany/SeedPrototype.cs | 102 +++--- .../Botany/Systems/BotanySystem.Produce.cs | 10 + .../Botany/Systems/BotanySystem.Seed.cs | 30 -- .../Botany/Systems/MutationSystem.cs | 306 ++---------------- .../Botany/Systems/PlantHolderSystem.cs | 50 +-- .../Botany/Systems/SeedExtractorSystem.cs | 6 - Content.Server/EntityEffects/Effects/Glow.cs | 48 +++ .../EntityEffects/Effects/PlantChangeStat.cs | 142 ++++++++ .../Effects/PlantMutateChemicals.cs | 55 ++++ .../EntityEffects/Effects/PlantMutateGases.cs | 87 +++++ .../Effects/PlantMutateHarvest.cs | 30 ++ .../Effects/PlantSpeciesChange.cs | 43 +++ .../EntityEffects/Effects/Slipify.cs | 38 +++ Content.Shared/Random/RandomPlantMutation.cs | 48 +++ .../RandomPlantMutationListPrototype.cs | 18 ++ .../{mutations.yml => randomChemicals.yml} | 0 .../Hydroponics/randomMutations.yml | 178 ++++++++++ 19 files changed, 812 insertions(+), 441 deletions(-) create mode 100644 Content.Server/EntityEffects/Effects/Glow.cs create mode 100644 Content.Server/EntityEffects/Effects/PlantChangeStat.cs create mode 100644 Content.Server/EntityEffects/Effects/PlantMutateChemicals.cs create mode 100644 Content.Server/EntityEffects/Effects/PlantMutateGases.cs create mode 100644 Content.Server/EntityEffects/Effects/PlantMutateHarvest.cs create mode 100644 Content.Server/EntityEffects/Effects/PlantSpeciesChange.cs create mode 100644 Content.Server/EntityEffects/Effects/Slipify.cs create mode 100644 Content.Shared/Random/RandomPlantMutation.cs create mode 100644 Content.Shared/Random/RandomPlantMutationListPrototype.cs rename Resources/Prototypes/Hydroponics/{mutations.yml => randomChemicals.yml} (100%) create mode 100644 Resources/Prototypes/Hydroponics/randomMutations.yml diff --git a/Content.Server/Botany/Components/PlantHolderComponent.cs b/Content.Server/Botany/Components/PlantHolderComponent.cs index 809af737ac6..8218bead72c 100644 --- a/Content.Server/Botany/Components/PlantHolderComponent.cs +++ b/Content.Server/Botany/Components/PlantHolderComponent.cs @@ -6,90 +6,90 @@ namespace Content.Server.Botany.Components; [RegisterComponent] public sealed partial class PlantHolderComponent : Component { - [DataField("nextUpdate", customTypeSerializer: typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] public TimeSpan NextUpdate = TimeSpan.Zero; - [ViewVariables(VVAccess.ReadWrite), DataField("updateDelay")] + [DataField] public TimeSpan UpdateDelay = TimeSpan.FromSeconds(3); - [DataField("lastProduce")] + [DataField] public int LastProduce; - [ViewVariables(VVAccess.ReadWrite), DataField("missingGas")] + [DataField] public int MissingGas; - [DataField("cycleDelay")] + [DataField] public TimeSpan CycleDelay = TimeSpan.FromSeconds(15f); - [DataField("lastCycle", customTypeSerializer: typeof(TimeOffsetSerializer))] + [DataField(customTypeSerializer: typeof(TimeOffsetSerializer))] public TimeSpan LastCycle = TimeSpan.Zero; - [ViewVariables(VVAccess.ReadWrite), DataField("updateSpriteAfterUpdate")] + [DataField] public bool UpdateSpriteAfterUpdate; - [ViewVariables(VVAccess.ReadWrite), DataField("drawWarnings")] + [DataField] public bool DrawWarnings = false; - [ViewVariables(VVAccess.ReadWrite), DataField("waterLevel")] + [DataField] public float WaterLevel = 100f; - [ViewVariables(VVAccess.ReadWrite), DataField("nutritionLevel")] + [DataField] public float NutritionLevel = 100f; - [ViewVariables(VVAccess.ReadWrite), DataField("pestLevel")] + [DataField] public float PestLevel; - [ViewVariables(VVAccess.ReadWrite), DataField("weedLevel")] + [DataField] public float WeedLevel; - [ViewVariables(VVAccess.ReadWrite), DataField("toxins")] + [DataField] public float Toxins; - [ViewVariables(VVAccess.ReadWrite), DataField("age")] + [DataField] public int Age; - [ViewVariables(VVAccess.ReadWrite), DataField("skipAging")] + [DataField] public int SkipAging; - [ViewVariables(VVAccess.ReadWrite), DataField("dead")] + [DataField] public bool Dead; - [ViewVariables(VVAccess.ReadWrite), DataField("harvest")] + [DataField] public bool Harvest; - [ViewVariables(VVAccess.ReadWrite), DataField("sampled")] + [DataField] public bool Sampled; - [ViewVariables(VVAccess.ReadWrite), DataField("yieldMod")] + [DataField] public int YieldMod = 1; - [ViewVariables(VVAccess.ReadWrite), DataField("mutationMod")] + [DataField] public float MutationMod = 1f; - [ViewVariables(VVAccess.ReadWrite), DataField("mutationLevel")] + [DataField] public float MutationLevel; - [ViewVariables(VVAccess.ReadWrite), DataField("health")] + [DataField] public float Health; - [ViewVariables(VVAccess.ReadWrite), DataField("weedCoefficient")] + [DataField] public float WeedCoefficient = 1f; - [ViewVariables(VVAccess.ReadWrite), DataField("seed")] + [DataField] public SeedData? Seed; - [ViewVariables(VVAccess.ReadWrite), DataField("improperHeat")] + [DataField] public bool ImproperHeat; - [ViewVariables(VVAccess.ReadWrite), DataField("improperPressure")] + [DataField] public bool ImproperPressure; - [ViewVariables(VVAccess.ReadWrite), DataField("improperLight")] + [DataField] public bool ImproperLight; - [ViewVariables(VVAccess.ReadWrite), DataField("forceUpdate")] + [DataField] public bool ForceUpdate; - [ViewVariables(VVAccess.ReadWrite), DataField("solution")] + [DataField] public string SoilSolutionName = "soil"; [DataField] diff --git a/Content.Server/Botany/Components/ProduceComponent.cs b/Content.Server/Botany/Components/ProduceComponent.cs index b3c4e1c95a9..db4ed62dd38 100644 --- a/Content.Server/Botany/Components/ProduceComponent.cs +++ b/Content.Server/Botany/Components/ProduceComponent.cs @@ -13,12 +13,12 @@ public sealed partial class ProduceComponent : SharedProduceComponent /// /// Seed data used to create a when this produce has its seeds extracted. /// - [DataField("seed")] + [DataField] public SeedData? Seed; /// /// Seed data used to create a when this produce has its seeds extracted. /// - [DataField("seedId", customTypeSerializer: typeof(PrototypeIdSerializer))] + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] public string? SeedId; } diff --git a/Content.Server/Botany/SeedPrototype.cs b/Content.Server/Botany/SeedPrototype.cs index 39f06a64360..7a3e08883de 100644 --- a/Content.Server/Botany/SeedPrototype.cs +++ b/Content.Server/Botany/SeedPrototype.cs @@ -2,6 +2,7 @@ using Content.Server.Botany.Systems; using Content.Shared.Atmos; using Content.Shared.EntityEffects; +using Content.Shared.Random; using Robust.Shared.Audio; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -132,78 +133,67 @@ public partial class SeedData [DataField("productPrototypes", customTypeSerializer: typeof(PrototypeIdListSerializer))] public List ProductPrototypes = new(); - [DataField("chemicals")] public Dictionary Chemicals = new(); + [DataField] public Dictionary Chemicals = new(); - [DataField("consumeGasses")] public Dictionary ConsumeGasses = new(); + [DataField] public Dictionary ConsumeGasses = new(); - [DataField("exudeGasses")] public Dictionary ExudeGasses = new(); + [DataField] public Dictionary ExudeGasses = new(); #endregion #region Tolerances - [DataField("nutrientConsumption")] public float NutrientConsumption = 0.75f; + [DataField] public float NutrientConsumption = 0.75f; - [DataField("waterConsumption")] public float WaterConsumption = 0.5f; - [DataField("idealHeat")] public float IdealHeat = 293f; - [DataField("heatTolerance")] public float HeatTolerance = 10f; - [DataField("idealLight")] public float IdealLight = 7f; - [DataField("lightTolerance")] public float LightTolerance = 3f; - [DataField("toxinsTolerance")] public float ToxinsTolerance = 4f; + [DataField] public float WaterConsumption = 0.5f; + [DataField] public float IdealHeat = 293f; + [DataField] public float HeatTolerance = 10f; + [DataField] public float IdealLight = 7f; + [DataField] public float LightTolerance = 3f; + [DataField] public float ToxinsTolerance = 4f; - [DataField("lowPressureTolerance")] public float LowPressureTolerance = 81f; + [DataField] public float LowPressureTolerance = 81f; - [DataField("highPressureTolerance")] public float HighPressureTolerance = 121f; + [DataField] public float HighPressureTolerance = 121f; - [DataField("pestTolerance")] public float PestTolerance = 5f; + [DataField] public float PestTolerance = 5f; - [DataField("weedTolerance")] public float WeedTolerance = 5f; + [DataField] public float WeedTolerance = 5f; - [DataField("weedHighLevelThreshold")] public float WeedHighLevelThreshold = 10f; + [DataField] public float WeedHighLevelThreshold = 10f; #endregion #region General traits - [DataField("endurance")] public float Endurance = 100f; + [DataField] public float Endurance = 100f; - [DataField("yield")] public int Yield; - [DataField("lifespan")] public float Lifespan; - [DataField("maturation")] public float Maturation; - [DataField("production")] public float Production; - [DataField("growthStages")] public int GrowthStages = 6; + [DataField] public int Yield; + [DataField] public float Lifespan; + [DataField] public float Maturation; + [DataField] public float Production; + [DataField] public int GrowthStages = 6; - [ViewVariables(VVAccess.ReadWrite)] - [DataField("harvestRepeat")] public HarvestType HarvestRepeat = HarvestType.NoRepeat; + [DataField] public HarvestType HarvestRepeat = HarvestType.NoRepeat; - [DataField("potency")] public float Potency = 1f; + [DataField] public float Potency = 1f; /// /// If true, cannot be harvested for seeds. Balances hybrids and /// mutations. /// - [DataField("seedless")] public bool Seedless = false; + [DataField] public bool Seedless = false; /// /// If false, rapidly decrease health while growing. Used to kill off /// plants with "bad" mutations. /// - [DataField("viable")] public bool Viable = true; - - /// - /// If true, fruit slips players. - /// - [DataField("slip")] public bool Slip = false; - - /// - /// If true, fruits are sentient. - /// - [DataField("sentient")] public bool Sentient = false; + [DataField] public bool Viable = true; /// /// If true, a sharp tool is required to harvest this plant. /// - [DataField("ligneous")] public bool Ligneous; + [DataField] public bool Ligneous; // No, I'm not removing these. // if you re-add these, make sure that they get cloned. @@ -222,36 +212,35 @@ public partial class SeedData #region Cosmetics - [DataField("plantRsi", required: true)] + [DataField(required: true)] public ResPath PlantRsi { get; set; } = default!; - [DataField("plantIconState")] public string PlantIconState { get; set; } = "produce"; + [DataField] public string PlantIconState { get; set; } = "produce"; /// - /// Screams random sound, could be strict sound SoundPathSpecifier or collection SoundCollectionSpecifier - /// base class is SoundSpecifier + /// Screams random sound from collection SoundCollectionSpecifier /// - [DataField("screamSound")] + [DataField] public SoundSpecifier ScreamSound = new SoundCollectionSpecifier("PlantScreams", AudioParams.Default.WithVolume(-10)); [DataField("screaming")] public bool CanScream; - [DataField("bioluminescent")] public bool Bioluminescent; - [DataField("bioluminescentColor")] public Color BioluminescentColor { get; set; } = Color.White; + [DataField(customTypeSerializer: typeof(PrototypeIdSerializer))] public string KudzuPrototype = "WeakKudzu"; - public float BioluminescentRadius = 2f; - - [DataField("kudzuPrototype", customTypeSerializer: typeof(PrototypeIdSerializer))] public string KudzuPrototype = "WeakKudzu"; - - [DataField("turnIntoKudzu")] public bool TurnIntoKudzu; - [DataField("splatPrototype")] public string? SplatPrototype { get; set; } + [DataField] public bool TurnIntoKudzu; + [DataField] public string? SplatPrototype { get; set; } #endregion + /// + /// The mutation effects that have been applied to this plant. + /// + [DataField] public List Mutations { get; set; } = new(); + /// /// The seed prototypes this seed may mutate into when prompted to. /// - [DataField("mutationPrototypes", customTypeSerializer: typeof(PrototypeIdListSerializer))] + [DataField(customTypeSerializer: typeof(PrototypeIdListSerializer))] public List MutationPrototypes = new(); public SeedData Clone() @@ -295,17 +284,14 @@ public SeedData Clone() Seedless = Seedless, Viable = Viable, - Slip = Slip, - Sentient = Sentient, Ligneous = Ligneous, PlantRsi = PlantRsi, PlantIconState = PlantIconState, - Bioluminescent = Bioluminescent, CanScream = CanScream, TurnIntoKudzu = TurnIntoKudzu, - BioluminescentColor = BioluminescentColor, SplatPrototype = SplatPrototype, + Mutations = Mutations, // Newly cloned seed is unique. No need to unnecessarily clone if repeatedly modified. Unique = true, @@ -356,18 +342,16 @@ public SeedData SpeciesChange(SeedData other) HarvestRepeat = HarvestRepeat, Potency = Potency, + Mutations = Mutations, + Seedless = Seedless, Viable = Viable, - Slip = Slip, - Sentient = Sentient, Ligneous = Ligneous, PlantRsi = other.PlantRsi, PlantIconState = other.PlantIconState, - Bioluminescent = Bioluminescent, CanScream = CanScream, TurnIntoKudzu = TurnIntoKudzu, - BioluminescentColor = BioluminescentColor, SplatPrototype = other.SplatPrototype, // Newly cloned seed is unique. No need to unnecessarily clone if repeatedly modified. diff --git a/Content.Server/Botany/Systems/BotanySystem.Produce.cs b/Content.Server/Botany/Systems/BotanySystem.Produce.cs index 34559a8304f..8fdf96f57ba 100644 --- a/Content.Server/Botany/Systems/BotanySystem.Produce.cs +++ b/Content.Server/Botany/Systems/BotanySystem.Produce.cs @@ -1,4 +1,5 @@ using Content.Server.Botany.Components; +using Content.Shared.EntityEffects; using Content.Shared.FixedPoint; namespace Content.Server.Botany.Systems; @@ -10,6 +11,15 @@ public void ProduceGrown(EntityUid uid, ProduceComponent produce) if (!TryGetSeed(produce, out var seed)) return; + foreach (var mutation in seed.Mutations) + { + if (mutation.AppliesToProduce) + { + var args = new EntityEffectBaseArgs(uid, EntityManager); + mutation.Effect.Effect(args); + } + } + if (!_solutionContainerSystem.EnsureSolution(uid, produce.SolutionName, out var solutionContainer, diff --git a/Content.Server/Botany/Systems/BotanySystem.Seed.cs b/Content.Server/Botany/Systems/BotanySystem.Seed.cs index c988e5338c0..1487ed71d47 100644 --- a/Content.Server/Botany/Systems/BotanySystem.Seed.cs +++ b/Content.Server/Botany/Systems/BotanySystem.Seed.cs @@ -5,16 +5,11 @@ using Content.Shared.Botany; using Content.Shared.Examine; using Content.Shared.Hands.EntitySystems; -using Content.Shared.Physics; using Content.Shared.Popups; using Content.Shared.Random; using Content.Shared.Random.Helpers; -using Content.Shared.Slippery; -using Content.Shared.StepTrigger.Components; using Robust.Server.GameObjects; using Robust.Shared.Map; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Systems; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -34,7 +29,6 @@ public sealed partial class BotanySystem : EntitySystem [Dependency] private readonly SharedSolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly FixtureSystem _fixtureSystem = default!; - [Dependency] private readonly CollisionWakeSystem _colWakeSystem = default!; [Dependency] private readonly RandomHelperSystem _randomHelper = default!; public override void Initialize() @@ -183,30 +177,6 @@ public IEnumerable GenerateProduct(SeedData proto, EntityCoordinates _metaData.SetEntityDescription(entity, metaData.EntityDescription + " " + Loc.GetString("botany-mysterious-description-addon"), metaData); } - - if (proto.Bioluminescent) - { - var light = _light.EnsureLight(entity); - _light.SetRadius(entity, proto.BioluminescentRadius, light); - _light.SetColor(entity, proto.BioluminescentColor, light); - // TODO: Ayo why you copy-pasting code between here and plantholder? - _light.SetCastShadows(entity, false, light); // this is expensive, and botanists make lots of plants - } - - if (proto.Slip) - { - var slippery = EnsureComp(entity); - Dirty(entity, slippery); - EnsureComp(entity); - // Need a fixture with a slip layer in order to actually do the slipping - var fixtures = EnsureComp(entity); - var body = EnsureComp(entity); - var shape = fixtures.Fixtures["fix1"].Shape; - _fixtureSystem.TryCreateFixture(entity, shape, "slips", 1, false, (int) CollisionGroup.SlipLayer, manager: fixtures, body: body); - // Need to disable collision wake so that mobs can collide with and slip on it - var collisionWake = EnsureComp(entity); - _colWakeSystem.SetEnabled(entity, false, collisionWake); - } } return products; diff --git a/Content.Server/Botany/Systems/MutationSystem.cs b/Content.Server/Botany/Systems/MutationSystem.cs index d3159655f54..07a24d19f6b 100644 --- a/Content.Server/Botany/Systems/MutationSystem.cs +++ b/Content.Server/Botany/Systems/MutationSystem.cs @@ -1,9 +1,9 @@ +using Content.Shared.Atmos; +using Content.Shared.EntityEffects; +using Content.Shared.Random; using Robust.Shared.Prototypes; using Robust.Shared.Random; -using Content.Shared.Random; -using Content.Shared.Random.Helpers; using System.Linq; -using Content.Shared.Atmos; namespace Content.Server.Botany; @@ -11,25 +11,40 @@ public sealed class MutationSystem : EntitySystem { [Dependency] private readonly IRobustRandom _robustRandom = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - private WeightedRandomFillSolutionPrototype _randomChems = default!; - + private RandomPlantMutationListPrototype _randomMutations = default!; public override void Initialize() { - _randomChems = _prototypeManager.Index("RandomPickBotanyReagent"); + _randomMutations = _prototypeManager.Index("RandomPlantMutations"); + } + + /// + /// For each random mutation, see if it occurs on this plant this check. + /// + /// + /// + public void CheckRandomMutations(EntityUid plantHolder, ref SeedData seed, float severity) + { + foreach (var mutation in _randomMutations.mutations) + { + if (Random(mutation.BaseOdds * severity)) + { + if (mutation.AppliesToPlant) + { + var args = new EntityEffectBaseArgs(plantHolder, EntityManager); + mutation.Effect.Effect(args); + } + // Stat adjustments do not persist by being an attached effect, they just change the stat. + if (mutation.Persists && !seed.Mutations.Any(m => m.Name == mutation.Name)) + seed.Mutations.Add(mutation); + } + } } /// - /// Main idea: Simulate genetic mutation using random binary flips. Each - /// seed attribute can be encoded with a variable number of bits, e.g. - /// NutrientConsumption is represented by 5 bits randomly distributed in the - /// plant's genome which thermometer code the floating value between 0.1 and - /// 5. 1 unit of mutation flips one bit in the plant's genome, which changes - /// NutrientConsumption if one of those 5 bits gets affected. - /// - /// You MUST clone() seed before mutating it! + /// Checks all defined mutations against a seed to see which of them are applied. /// - public void MutateSeed(ref SeedData seed, float severity) + public void MutateSeed(EntityUid plantHolder, ref SeedData seed, float severity) { if (!seed.Unique) { @@ -37,57 +52,7 @@ public void MutateSeed(ref SeedData seed, float severity) return; } - // Add up everything in the bits column and put the number here. - const int totalbits = 262; - - #pragma warning disable IDE0055 // disable formatting warnings because this looks more readable - // Tolerances (55) - MutateFloat(ref seed.NutrientConsumption , 0.05f, 1.2f, 5, totalbits, severity); - MutateFloat(ref seed.WaterConsumption , 3f , 9f , 5, totalbits, severity); - MutateFloat(ref seed.IdealHeat , 263f , 323f, 5, totalbits, severity); - MutateFloat(ref seed.HeatTolerance , 2f , 25f , 5, totalbits, severity); - MutateFloat(ref seed.IdealLight , 0f , 14f , 5, totalbits, severity); - MutateFloat(ref seed.LightTolerance , 1f , 5f , 5, totalbits, severity); - MutateFloat(ref seed.ToxinsTolerance , 1f , 10f , 5, totalbits, severity); - MutateFloat(ref seed.LowPressureTolerance , 60f , 100f, 5, totalbits, severity); - MutateFloat(ref seed.HighPressureTolerance, 100f , 140f, 5, totalbits, severity); - MutateFloat(ref seed.PestTolerance , 0f , 15f , 5, totalbits, severity); - MutateFloat(ref seed.WeedTolerance , 0f , 15f , 5, totalbits, severity); - - // Stats (30*2 = 60) - MutateFloat(ref seed.Endurance , 50f , 150f, 5, totalbits, 2 * severity); - MutateInt(ref seed.Yield , 3 , 10 , 5, totalbits, 2 * severity); - MutateFloat(ref seed.Lifespan , 10f , 80f , 5, totalbits, 2 * severity); - MutateFloat(ref seed.Maturation , 3f , 8f , 5, totalbits, 2 * severity); - MutateFloat(ref seed.Production , 1f , 10f , 5, totalbits, 2 * severity); - MutateFloat(ref seed.Potency , 30f , 100f, 5, totalbits, 2 * severity); - - // Kill the plant (30) - MutateBool(ref seed.Viable , false, 30, totalbits, severity); - - // Fun (72) - MutateBool(ref seed.Seedless , true , 10, totalbits, severity); - MutateBool(ref seed.Slip , true , 10, totalbits, severity); - MutateBool(ref seed.Sentient , true , 2 , totalbits, severity); - MutateBool(ref seed.Ligneous , true , 10, totalbits, severity); - MutateBool(ref seed.Bioluminescent, true , 10, totalbits, severity); - MutateBool(ref seed.TurnIntoKudzu , true , 10, totalbits, severity); - MutateBool(ref seed.CanScream , true , 10, totalbits, severity); - seed.BioluminescentColor = RandomColor(seed.BioluminescentColor, 10, totalbits, severity); - #pragma warning restore IDE0055 - - // ConstantUpgade (10) - MutateHarvestType(ref seed.HarvestRepeat, 10, totalbits, severity); - - // Gas (5) - MutateGasses(ref seed.ExudeGasses, 0.01f, 0.5f, 4, totalbits, severity); - MutateGasses(ref seed.ConsumeGasses, 0.01f, 0.5f, 1, totalbits, severity); - - // Chems (20) - MutateChemicals(ref seed.Chemicals, 20, totalbits, severity); - - // Species (10) - MutateSpecies(ref seed, 10, totalbits, severity); + CheckRandomMutations(plantHolder, ref seed, severity); } public SeedData Cross(SeedData a, SeedData b) @@ -115,19 +80,18 @@ public SeedData Cross(SeedData a, SeedData b) CrossFloat(ref result.Production, a.Production); CrossFloat(ref result.Potency, a.Potency); - // we do not transfer Sentient to another plant to avoid ghost role spam CrossBool(ref result.Seedless, a.Seedless); - CrossBool(ref result.Viable, a.Viable); - CrossBool(ref result.Slip, a.Slip); CrossBool(ref result.Ligneous, a.Ligneous); - CrossBool(ref result.Bioluminescent, a.Bioluminescent); CrossBool(ref result.TurnIntoKudzu, a.TurnIntoKudzu); CrossBool(ref result.CanScream, a.CanScream); CrossGasses(ref result.ExudeGasses, a.ExudeGasses); CrossGasses(ref result.ConsumeGasses, a.ConsumeGasses); - result.BioluminescentColor = Random(0.5f) ? a.BioluminescentColor : result.BioluminescentColor; + // LINQ Explanation + // For the list of mutation effects on both plants, use a 50% chance to pick each one. + // Union all of the chosen mutations into one list, and pick ones with a Distinct (unique) name. + result.Mutations = result.Mutations.Where(m => Random(0.5f)).Union(a.Mutations.Where(m => Random(0.5f))).DistinctBy(m => m.Name).ToList(); // Hybrids have a high chance of being seedless. Balances very // effective hybrid crossings. @@ -139,206 +103,6 @@ public SeedData Cross(SeedData a, SeedData b) return result; } - // Mutate reference 'val' between 'min' and 'max' by pretending the value - // is representable by a thermometer code with 'bits' number of bits and - // randomly flipping some of them. - // - // 'totalbits' and 'mult' are used only to calculate the probability that - // one bit gets flipped. - private void MutateFloat(ref float val, float min, float max, int bits, int totalbits, float mult) - { - // Probability that a bit flip happens for this value's representation in thermometer code. - float probBitflip = mult * bits / totalbits; - probBitflip = Math.Clamp(probBitflip, 0, 1); - if (!Random(probBitflip)) - return; - - if (min == max) - { - val = min; - return; - } - - // Starting number of bits that are high, between 0 and bits. - // In other words, it's val mapped linearly from range [min, max] to range [0, bits], and then rounded. - int valInt = (int)MathF.Round((val - min) / (max - min) * bits); - // val may be outside the range of min/max due to starting prototype values, so clamp. - valInt = Math.Clamp(valInt, 0, bits); - - // Probability that the bit flip increases n. - // The higher the current value is, the lower the probability of increasing value is, and the higher the probability of decreasive it it. - // In other words, it tends to go to the middle. - float probIncrease = 1 - (float)valInt / bits; - int valIntMutated; - if (Random(probIncrease)) - { - valIntMutated = valInt + 1; - } - else - { - valIntMutated = valInt - 1; - } - - // Set value based on mutated thermometer code. - float valMutated = Math.Clamp((float)valIntMutated / bits * (max - min) + min, min, max); - val = valMutated; - } - - private void MutateInt(ref int val, int min, int max, int bits, int totalbits, float mult) - { - // Probability that a bit flip happens for this value's representation in thermometer code. - float probBitflip = mult * bits / totalbits; - probBitflip = Math.Clamp(probBitflip, 0, 1); - if (!Random(probBitflip)) - return; - - if (min == max) - { - val = min; - return; - } - - // Starting number of bits that are high, between 0 and bits. - // In other words, it's val mapped linearly from range [min, max] to range [0, bits], and then rounded. - int valInt = (int)MathF.Round((val - min) / (max - min) * bits); - // val may be outside the range of min/max due to starting prototype values, so clamp. - valInt = Math.Clamp(valInt, 0, bits); - - // Probability that the bit flip increases n. - // The higher the current value is, the lower the probability of increasing value is, and the higher the probability of decreasing it. - // In other words, it tends to go to the middle. - float probIncrease = 1 - (float)valInt / bits; - int valMutated; - if (Random(probIncrease)) - { - valMutated = val + 1; - } - else - { - valMutated = val - 1; - } - - valMutated = Math.Clamp(valMutated, min, max); - val = valMutated; - } - - private void MutateBool(ref bool val, bool polarity, int bits, int totalbits, float mult) - { - // Probability that a bit flip happens for this value. - float probSet = mult * bits / totalbits; - probSet = Math.Clamp(probSet, 0, 1); - if (!Random(probSet)) - return; - - val = polarity; - } - - private void MutateHarvestType(ref HarvestType val, int bits, int totalbits, float mult) - { - float probModify = mult * bits / totalbits; - probModify = Math.Clamp(probModify, 0, 1); - - if (!Random(probModify)) - return; - - if (val == HarvestType.NoRepeat) - val = HarvestType.Repeat; - else if (val == HarvestType.Repeat) - val = HarvestType.SelfHarvest; - } - - private void MutateGasses(ref Dictionary gasses, float min, float max, int bits, int totalbits, float mult) - { - float probModify = mult * bits / totalbits; - probModify = Math.Clamp(probModify, 0, 1); - if (!Random(probModify)) - return; - - // Add a random amount of a random gas to this gas dictionary - float amount = _robustRandom.NextFloat(min, max); - Gas gas = _robustRandom.Pick(Enum.GetValues(typeof(Gas)).Cast().ToList()); - if (gasses.ContainsKey(gas)) - { - gasses[gas] += amount; - } - else - { - gasses.Add(gas, amount); - } - } - - private void MutateChemicals(ref Dictionary chemicals, int bits, int totalbits, float mult) - { - float probModify = mult * bits / totalbits; - probModify = Math.Clamp(probModify, 0, 1); - if (!Random(probModify)) - return; - - // Add a random amount of a random chemical to this set of chemicals - if (_randomChems != null) - { - var pick = _randomChems.Pick(_robustRandom); - string chemicalId = pick.reagent; - int amount = _robustRandom.Next(1, (int)pick.quantity); - SeedChemQuantity seedChemQuantity = new SeedChemQuantity(); - if (chemicals.ContainsKey(chemicalId)) - { - seedChemQuantity.Min = chemicals[chemicalId].Min; - seedChemQuantity.Max = chemicals[chemicalId].Max + amount; - } - else - { - seedChemQuantity.Min = 1; - seedChemQuantity.Max = 1 + amount; - seedChemQuantity.Inherent = false; - } - int potencyDivisor = (int)Math.Ceiling(100.0f / seedChemQuantity.Max); - seedChemQuantity.PotencyDivisor = potencyDivisor; - chemicals[chemicalId] = seedChemQuantity; - } - } - - private void MutateSpecies(ref SeedData seed, int bits, int totalbits, float mult) - { - float p = mult * bits / totalbits; - p = Math.Clamp(p, 0, 1); - if (!Random(p)) - return; - - if (seed.MutationPrototypes.Count == 0) - return; - - var targetProto = _robustRandom.Pick(seed.MutationPrototypes); - _prototypeManager.TryIndex(targetProto, out SeedPrototype? protoSeed); - - if (protoSeed == null) - { - Log.Error($"Seed prototype could not be found: {targetProto}!"); - return; - } - - seed = seed.SpeciesChange(protoSeed); - } - - private Color RandomColor(Color color, int bits, int totalbits, float mult) - { - float probModify = mult * bits / totalbits; - if (Random(probModify)) - { - var colors = new List{ - Color.White, - Color.Red, - Color.Yellow, - Color.Green, - Color.Blue, - Color.Purple, - Color.Pink - }; - return _robustRandom.Pick(colors); - } - return color; - } - private void CrossChemicals(ref Dictionary val, Dictionary other) { // Go through chemicals from the pollen in swab diff --git a/Content.Server/Botany/Systems/PlantHolderSystem.cs b/Content.Server/Botany/Systems/PlantHolderSystem.cs index 002a0543399..0fdca029b79 100644 --- a/Content.Server/Botany/Systems/PlantHolderSystem.cs +++ b/Content.Server/Botany/Systems/PlantHolderSystem.cs @@ -1,8 +1,6 @@ -using Content.Server.Atmos; using Content.Server.Atmos.EntitySystems; using Content.Server.Botany.Components; using Content.Server.Fluids.Components; -using Content.Server.Ghost.Roles.Components; using Content.Server.Kitchen.Components; using Content.Server.Popups; using Content.Shared.Chemistry.EntitySystems; @@ -79,7 +77,7 @@ private int GetCurrentGrowthStage(Entity entity) if (component.Seed == null) return 0; - var result = Math.Max(1, (int) (component.Age * component.Seed.GrowthStages / component.Seed.Maturation)); + var result = Math.Max(1, (int)(component.Age * component.Seed.GrowthStages / component.Seed.Maturation)); return result; } @@ -125,9 +123,9 @@ private void OnExamine(Entity entity, ref ExaminedEvent ar args.PushMarkup(Loc.GetString("plant-holder-component-pest-high-level-message")); args.PushMarkup(Loc.GetString($"plant-holder-component-water-level-message", - ("waterLevel", (int) component.WaterLevel))); + ("waterLevel", (int)component.WaterLevel))); args.PushMarkup(Loc.GetString($"plant-holder-component-nutrient-level-message", - ("nutritionLevel", (int) component.NutritionLevel))); + ("nutritionLevel", (int)component.NutritionLevel))); if (component.DrawWarnings) { @@ -299,21 +297,12 @@ private void OnInteractUsing(Entity entity, ref InteractUs healthOverride = component.Health; } var packetSeed = component.Seed; - if (packetSeed.Sentient) - { - packetSeed = packetSeed.Clone(); // clone before modifying the seed - packetSeed.Sentient = false; - } - else - { - packetSeed.Unique = false; - } var seed = _botany.SpawnSeedPacket(packetSeed, Transform(args.User).Coordinates, args.User, healthOverride); _randomHelper.RandomOffset(seed, 0.25f); var displayName = Loc.GetString(component.Seed.DisplayName); _popup.PopupCursor(Loc.GetString("plant-holder-component-take-sample-message", ("seedName", displayName)), args.User); - + DoScream(entity.Owner, component.Seed); if (_random.Prob(0.3f)) @@ -459,7 +448,7 @@ public void Update(EntityUid uid, PlantHolderComponent? component = null) else { if (_random.Prob(0.8f)) - component.Age += (int) (1 * HydroponicsSpeedMultiplier); + component.Age += (int)(1 * HydroponicsSpeedMultiplier); component.UpdateSpriteAfterUpdate = true; } @@ -632,12 +621,6 @@ public void Update(EntityUid uid, PlantHolderComponent? component = null) else if (component.Age < 0) // Revert back to seed packet! { var packetSeed = component.Seed; - if (packetSeed.Sentient) - { - if (!packetSeed.Unique) // clone if necessary before modifying the seed - packetSeed = packetSeed.Clone(); - packetSeed.Sentient = false; // remove Sentient to avoid ghost role spam - } // will put it in the trays hands if it has any, please do not try doing this _botany.SpawnSeedPacket(packetSeed, Transform(uid).Coordinates, uid); RemovePlant(uid, component); @@ -674,14 +657,6 @@ public void Update(EntityUid uid, PlantHolderComponent? component = null) CheckLevelSanity(uid, component); - if (component.Seed.Sentient) - { - var ghostRole = EnsureComp(uid); - EnsureComp(uid); - ghostRole.RoleName = MetaData(uid).EntityName; - ghostRole.RoleDescription = Loc.GetString("station-event-random-sentience-role-description", ("name", ghostRole.RoleName)); - } - if (component.UpdateSpriteAfterUpdate) UpdateSprite(uid, component); } @@ -911,7 +886,7 @@ private void Mutate(EntityUid uid, float severity, PlantHolderComponent? compone if (component.Seed != null) { EnsureUniqueSeed(uid, component); - _mutation.MutateSeed(ref component.Seed, severity); + _mutation.MutateSeed(uid, ref component.Seed, severity); } } @@ -922,19 +897,6 @@ public void UpdateSprite(EntityUid uid, PlantHolderComponent? component = null) component.UpdateSpriteAfterUpdate = false; - if (component.Seed != null && component.Seed.Bioluminescent) - { - var light = EnsureComp(uid); - _pointLight.SetRadius(uid, component.Seed.BioluminescentRadius, light); - _pointLight.SetColor(uid, component.Seed.BioluminescentColor, light); - _pointLight.SetCastShadows(uid, false, light); - Dirty(uid, light); - } - else - { - RemComp(uid); - } - if (!TryComp(uid, out var app)) return; diff --git a/Content.Server/Botany/Systems/SeedExtractorSystem.cs b/Content.Server/Botany/Systems/SeedExtractorSystem.cs index 4a0d56bfe98..93f76473ff8 100644 --- a/Content.Server/Botany/Systems/SeedExtractorSystem.cs +++ b/Content.Server/Botany/Systems/SeedExtractorSystem.cs @@ -43,12 +43,6 @@ private void OnInteractUsing(EntityUid uid, SeedExtractorComponent seedExtractor var coords = Transform(uid).Coordinates; var packetSeed = seed; - if (packetSeed.Sentient) - { - if (!packetSeed.Unique) // clone if necessary before modifying the seed - packetSeed = packetSeed.Clone(); - packetSeed.Sentient = false; // remove Sentient to avoid ghost role spam - } if (amount > 1) packetSeed.Unique = false; diff --git a/Content.Server/EntityEffects/Effects/Glow.cs b/Content.Server/EntityEffects/Effects/Glow.cs new file mode 100644 index 00000000000..9f034767297 --- /dev/null +++ b/Content.Server/EntityEffects/Effects/Glow.cs @@ -0,0 +1,48 @@ +using Content.Shared.EntityEffects; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server.EntityEffects.Effects; + +/// +/// Makes a mob glow. +/// +public sealed partial class Glow : EntityEffect +{ + [DataField] + public float Radius = 2f; + + [DataField] + public Color Color = Color.Black; + + private static readonly List Colors = new() + { + Color.White, + Color.Red, + Color.Yellow, + Color.Green, + Color.Blue, + Color.Purple, + Color.Pink + }; + + public override void Effect(EntityEffectBaseArgs args) + { + if (Color == Color.Black) + { + var random = IoCManager.Resolve(); + Color = random.Pick(Colors); + } + + var lightSystem = args.EntityManager.System(); + var light = lightSystem.EnsureLight(args.TargetEntity); + lightSystem.SetRadius(args.TargetEntity, Radius, light); + lightSystem.SetColor(args.TargetEntity, Color, light); + lightSystem.SetCastShadows(args.TargetEntity, false, light); // this is expensive, and botanists make lots of plants + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + return "TODO"; + } +} diff --git a/Content.Server/EntityEffects/Effects/PlantChangeStat.cs b/Content.Server/EntityEffects/Effects/PlantChangeStat.cs new file mode 100644 index 00000000000..9592ff779da --- /dev/null +++ b/Content.Server/EntityEffects/Effects/PlantChangeStat.cs @@ -0,0 +1,142 @@ +using Content.Server.Botany; +using Content.Server.Botany.Components; +using Content.Shared.EntityEffects; +using JetBrains.Annotations; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server.EntityEffects.Effects.PlantMetabolism; + +[UsedImplicitly] +public sealed partial class PlantChangeStat : EntityEffect +{ + [DataField] + public string TargetValue; + + [DataField] + public float MinValue; + + [DataField] + public float MaxValue; + + [DataField] + public int Steps; + + public override void Effect(EntityEffectBaseArgs args) + { + var plantHolder = args.EntityManager.GetComponent(args.TargetEntity); + if (plantHolder == null || plantHolder.Seed == null) + return; + + var member = plantHolder.Seed.GetType().GetField(TargetValue); + var mutationSys = args.EntityManager.System(); + + if (member == null) + { + mutationSys.Log.Error(this.GetType().Name + " Error: Member " + TargetValue + " not found on " + plantHolder.GetType().Name + ". Did you misspell it?"); + return; + } + + var currentValObj = member.GetValue(plantHolder.Seed); + if (currentValObj == null) + return; + + if (member.FieldType == typeof(float)) + { + var floatVal = (float)currentValObj; + MutateFloat(ref floatVal, MinValue, MaxValue, Steps); + member.SetValue(plantHolder.Seed, floatVal); + } + else if (member.FieldType == typeof(int)) + { + var intVal = (int)currentValObj; + MutateInt(ref intVal, (int)MinValue, (int)MaxValue, Steps); + member.SetValue(plantHolder.Seed, intVal); + } + else if (member.FieldType == typeof(bool)) + { + var boolVal = (bool)currentValObj; + boolVal = !boolVal; + member.SetValue(plantHolder.Seed, boolVal); + } + } + + // Mutate reference 'val' between 'min' and 'max' by pretending the value + // is representable by a thermometer code with 'bits' number of bits and + // randomly flipping some of them. + private void MutateFloat(ref float val, float min, float max, int bits) + { + if (min == max) + { + val = min; + return; + } + + // Starting number of bits that are high, between 0 and bits. + // In other words, it's val mapped linearly from range [min, max] to range [0, bits], and then rounded. + int valInt = (int)MathF.Round((val - min) / (max - min) * bits); + // val may be outside the range of min/max due to starting prototype values, so clamp. + valInt = Math.Clamp(valInt, 0, bits); + + // Probability that the bit flip increases n. + // The higher the current value is, the lower the probability of increasing value is, and the higher the probability of decreasive it it. + // In other words, it tends to go to the middle. + float probIncrease = 1 - (float)valInt / bits; + int valIntMutated; + if (Random(probIncrease)) + { + valIntMutated = valInt + 1; + } + else + { + valIntMutated = valInt - 1; + } + + // Set value based on mutated thermometer code. + float valMutated = Math.Clamp((float)valIntMutated / bits * (max - min) + min, min, max); + val = valMutated; + } + + private void MutateInt(ref int val, int min, int max, int bits) + { + if (min == max) + { + val = min; + return; + } + + // Starting number of bits that are high, between 0 and bits. + // In other words, it's val mapped linearly from range [min, max] to range [0, bits], and then rounded. + int valInt = (int)MathF.Round((val - min) / (max - min) * bits); + // val may be outside the range of min/max due to starting prototype values, so clamp. + valInt = Math.Clamp(valInt, 0, bits); + + // Probability that the bit flip increases n. + // The higher the current value is, the lower the probability of increasing value is, and the higher the probability of decreasing it. + // In other words, it tends to go to the middle. + float probIncrease = 1 - (float)valInt / bits; + int valMutated; + if (Random(probIncrease)) + { + valMutated = val + 1; + } + else + { + valMutated = val - 1; + } + + valMutated = Math.Clamp(valMutated, min, max); + val = valMutated; + } + + private bool Random(float odds) + { + var random = IoCManager.Resolve(); + return random.Prob(odds); + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + throw new NotImplementedException(); + } +} diff --git a/Content.Server/EntityEffects/Effects/PlantMutateChemicals.cs b/Content.Server/EntityEffects/Effects/PlantMutateChemicals.cs new file mode 100644 index 00000000000..7ee6cd13d75 --- /dev/null +++ b/Content.Server/EntityEffects/Effects/PlantMutateChemicals.cs @@ -0,0 +1,55 @@ +using Content.Server.Botany; +using Content.Server.Botany.Components; +using Content.Shared.EntityEffects; +using Content.Shared.Random; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server.EntityEffects.Effects; + +/// +/// changes the chemicals available in a plant's produce +/// +public sealed partial class PlantMutateChemicals : EntityEffect +{ + public override void Effect(EntityEffectBaseArgs args) + { + var plantholder = args.EntityManager.GetComponent(args.TargetEntity); + + if (plantholder.Seed == null) + return; + + var random = IoCManager.Resolve(); + var prototypeManager = IoCManager.Resolve(); + var chemicals = plantholder.Seed.Chemicals; + var randomChems = prototypeManager.Index("RandomPickBotanyReagent").Fills; + + // Add a random amount of a random chemical to this set of chemicals + if (randomChems != null) + { + var pick = random.Pick(randomChems); + var chemicalId = random.Pick(pick.Reagents); + var amount = random.Next(1, (int)pick.Quantity); + var seedChemQuantity = new SeedChemQuantity(); + if (chemicals.ContainsKey(chemicalId)) + { + seedChemQuantity.Min = chemicals[chemicalId].Min; + seedChemQuantity.Max = chemicals[chemicalId].Max + amount; + } + else + { + seedChemQuantity.Min = 1; + seedChemQuantity.Max = 1 + amount; + seedChemQuantity.Inherent = false; + } + var potencyDivisor = (int)Math.Ceiling(100.0f / seedChemQuantity.Max); + seedChemQuantity.PotencyDivisor = potencyDivisor; + chemicals[chemicalId] = seedChemQuantity; + } + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + return "TODO"; + } +} diff --git a/Content.Server/EntityEffects/Effects/PlantMutateGases.cs b/Content.Server/EntityEffects/Effects/PlantMutateGases.cs new file mode 100644 index 00000000000..52b9da3a851 --- /dev/null +++ b/Content.Server/EntityEffects/Effects/PlantMutateGases.cs @@ -0,0 +1,87 @@ +using Content.Server.Botany.Components; +using Content.Shared.Atmos; +using Content.Shared.EntityEffects; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using System.Linq; + +namespace Content.Server.EntityEffects.Effects; + +/// +/// changes the gases that a plant or produce create. +/// +public sealed partial class PlantMutateExudeGasses : EntityEffect +{ + [DataField] + public float MinValue = 0.01f; + + [DataField] + public float MaxValue = 0.5f; + + public override void Effect(EntityEffectBaseArgs args) + { + var plantholder = args.EntityManager.GetComponent(args.TargetEntity); + + if (plantholder.Seed == null) + return; + + var random = IoCManager.Resolve(); + var gasses = plantholder.Seed.ExudeGasses; + + // Add a random amount of a random gas to this gas dictionary + float amount = random.NextFloat(MinValue, MaxValue); + Gas gas = random.Pick(Enum.GetValues(typeof(Gas)).Cast().ToList()); + if (gasses.ContainsKey(gas)) + { + gasses[gas] += amount; + } + else + { + gasses.Add(gas, amount); + } + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + return "TODO"; + } +} + +/// +/// changes the gases that a plant or produce consumes. +/// +public sealed partial class PlantMutateConsumeGasses : EntityEffect +{ + [DataField] + public float MinValue = 0.01f; + + [DataField] + public float MaxValue = 0.5f; + public override void Effect(EntityEffectBaseArgs args) + { + var plantholder = args.EntityManager.GetComponent(args.TargetEntity); + + if (plantholder.Seed == null) + return; + + var random = IoCManager.Resolve(); + var gasses = plantholder.Seed.ConsumeGasses; + + // Add a random amount of a random gas to this gas dictionary + float amount = random.NextFloat(MinValue, MaxValue); + Gas gas = random.Pick(Enum.GetValues(typeof(Gas)).Cast().ToList()); + if (gasses.ContainsKey(gas)) + { + gasses[gas] += amount; + } + else + { + gasses.Add(gas, amount); + } + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + return "TODO"; + } +} diff --git a/Content.Server/EntityEffects/Effects/PlantMutateHarvest.cs b/Content.Server/EntityEffects/Effects/PlantMutateHarvest.cs new file mode 100644 index 00000000000..e67176ee16d --- /dev/null +++ b/Content.Server/EntityEffects/Effects/PlantMutateHarvest.cs @@ -0,0 +1,30 @@ +using Content.Server.Botany; +using Content.Server.Botany.Components; +using Content.Shared.EntityEffects; +using Robust.Shared.Prototypes; + +namespace Content.Server.EntityEffects.Effects; + +/// +/// Upgrades a plant's harvest type. +/// +public sealed partial class PlantMutateHarvest : EntityEffect +{ + public override void Effect(EntityEffectBaseArgs args) + { + var plantholder = args.EntityManager.GetComponent(args.TargetEntity); + + if (plantholder.Seed == null) + return; + + if (plantholder.Seed.HarvestRepeat == HarvestType.NoRepeat) + plantholder.Seed.HarvestRepeat = HarvestType.Repeat; + else if (plantholder.Seed.HarvestRepeat == HarvestType.Repeat) + plantholder.Seed.HarvestRepeat = HarvestType.SelfHarvest; + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + return "TODO"; + } +} diff --git a/Content.Server/EntityEffects/Effects/PlantSpeciesChange.cs b/Content.Server/EntityEffects/Effects/PlantSpeciesChange.cs new file mode 100644 index 00000000000..65bd59daa37 --- /dev/null +++ b/Content.Server/EntityEffects/Effects/PlantSpeciesChange.cs @@ -0,0 +1,43 @@ +using Content.Server.Botany; +using Content.Server.Botany.Components; +using Content.Shared.EntityEffects; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; +using Serilog; + +namespace Content.Server.EntityEffects.Effects; + +/// +/// Changes a plant into one of the species its able to mutate into. +/// +public sealed partial class PlantSpeciesChange : EntityEffect +{ + public override void Effect(EntityEffectBaseArgs args) + { + var prototypeManager = IoCManager.Resolve(); + var plantholder = args.EntityManager.GetComponent(args.TargetEntity); + + if (plantholder.Seed == null) + return; + + if (plantholder.Seed.MutationPrototypes.Count == 0) + return; + + var random = IoCManager.Resolve(); + var targetProto = random.Pick(plantholder.Seed.MutationPrototypes); + prototypeManager.TryIndex(targetProto, out SeedPrototype? protoSeed); + + if (protoSeed == null) + { + Log.Error($"Seed prototype could not be found: {targetProto}!"); + return; + } + + plantholder.Seed = plantholder.Seed.SpeciesChange(protoSeed); + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + return "TODO"; + } +} diff --git a/Content.Server/EntityEffects/Effects/Slipify.cs b/Content.Server/EntityEffects/Effects/Slipify.cs new file mode 100644 index 00000000000..bc1cc062a38 --- /dev/null +++ b/Content.Server/EntityEffects/Effects/Slipify.cs @@ -0,0 +1,38 @@ +using Content.Shared.EntityEffects; +using Content.Shared.Physics; +using Content.Shared.Slippery; +using Content.Shared.StepTrigger.Components; +using Robust.Shared.Physics; +using Robust.Shared.Physics.Components; +using Robust.Shared.Physics.Systems; +using Robust.Shared.Prototypes; + +namespace Content.Server.EntityEffects.Effects; + +/// +/// Makes a mob slippery. +/// +public sealed partial class Slipify : EntityEffect +{ + public override void Effect(EntityEffectBaseArgs args) + { + var fixtureSystem = args.EntityManager.System(); + var colWakeSystem = args.EntityManager.System(); + var slippery = args.EntityManager.EnsureComponent(args.TargetEntity); + args.EntityManager.Dirty(args.TargetEntity, slippery); + args.EntityManager.EnsureComponent(args.TargetEntity); + // Need a fixture with a slip layer in order to actually do the slipping + var fixtures = args.EntityManager.EnsureComponent(args.TargetEntity); + var body = args.EntityManager.EnsureComponent(args.TargetEntity); + var shape = fixtures.Fixtures["fix1"].Shape; + fixtureSystem.TryCreateFixture(args.TargetEntity, shape, "slips", 1, false, (int)CollisionGroup.SlipLayer, manager: fixtures, body: body); + // Need to disable collision wake so that mobs can collide with and slip on it + var collisionWake = args.EntityManager.EnsureComponent(args.TargetEntity); + colWakeSystem.SetEnabled(args.TargetEntity, false, collisionWake); + } + + protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) + { + throw new NotImplementedException(); + } +} diff --git a/Content.Shared/Random/RandomPlantMutation.cs b/Content.Shared/Random/RandomPlantMutation.cs new file mode 100644 index 00000000000..d95cf7bf422 --- /dev/null +++ b/Content.Shared/Random/RandomPlantMutation.cs @@ -0,0 +1,48 @@ +using Content.Shared.EntityEffects; +using Robust.Shared.Serialization; + +namespace Content.Shared.Random; + +/// +/// Data that specifies the odds and effects of possible random plant mutations. +/// +[Serializable, NetSerializable] +[DataDefinition] +public sealed partial class RandomPlantMutation +{ + /// + /// Odds of this mutation occurring with 1 point of mutation severity on a plant. + /// + [DataField] + public float BaseOdds = 0; + + /// + /// The name of this mutation. + /// + [DataField] + public string Name = ""; + + /// + /// The actual EntityEffect to apply to the target + /// + [DataField] + public EntityEffect Effect = default!; + + /// + /// This mutation will target the harvested produce + /// + [DataField] + public bool AppliesToProduce = true; + + /// + /// This mutation will target the growing plant as soon as this mutation is applied. + /// + [DataField] + public bool AppliesToPlant = true; + + /// + /// This mutation stays on the plant and its produce. If false while AppliesToPlant is true, the effect will run when triggered. + /// + [DataField] + public bool Persists = true; +} diff --git a/Content.Shared/Random/RandomPlantMutationListPrototype.cs b/Content.Shared/Random/RandomPlantMutationListPrototype.cs new file mode 100644 index 00000000000..84e3b9256c3 --- /dev/null +++ b/Content.Shared/Random/RandomPlantMutationListPrototype.cs @@ -0,0 +1,18 @@ +using Robust.Shared.Prototypes; + +namespace Content.Shared.Random; + +/// +/// Random weighting dataset for solutions, able to specify reagents quantity. +/// +[Prototype("RandomPlantMutationList")] +public sealed partial class RandomPlantMutationListPrototype : IPrototype +{ + [IdDataField] public string ID { get; } = default!; + + /// + /// List of RandomFills that can be picked from. + /// + [DataField("mutations", required: true, serverOnly: true)] + public List mutations = new(); +} diff --git a/Resources/Prototypes/Hydroponics/mutations.yml b/Resources/Prototypes/Hydroponics/randomChemicals.yml similarity index 100% rename from Resources/Prototypes/Hydroponics/mutations.yml rename to Resources/Prototypes/Hydroponics/randomChemicals.yml diff --git a/Resources/Prototypes/Hydroponics/randomMutations.yml b/Resources/Prototypes/Hydroponics/randomMutations.yml new file mode 100644 index 00000000000..50f6845ec32 --- /dev/null +++ b/Resources/Prototypes/Hydroponics/randomMutations.yml @@ -0,0 +1,178 @@ +- type: RandomPlantMutationList + id: RandomPlantMutations + mutations: + - name: Bioluminescent + baseOdds: 0.036 + effect: !type:Glow + - name: Sentient + baseOdds: 0.0072 + appliesToPlant: false # makes the botany tray sentient if true + effect: !type:MakeSentient # existing effect. + - name: Slippery + baseOdds: 0.036 + effect: !type:Slipify + - name: ChangeSpecies + baseOdds: 0.036 + appliesToProduce: false + effect: !type:PlantSpeciesChange + - name: Unviable + baseOdds: 0.109 + persists: false + effect: !type:PlantChangeStat + targetValue: Viable + - name: ChangeWaterConsumption + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: WaterConsumption + minValue: 0.3 + maxValue: 0.9 + steps: 5 + - name: ChangeNutrientConsumption + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: NutrientConsumption + minValue: 0.05 + maxValue: 1.2 + steps: 5 + - name: ChangeIdealHeat + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: IdealHeat + minValue: 263 + maxValue: 323 + steps: 5 + - name: ChangeHeatTolerance + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: HeatTolerance + minValue: 2 + maxValue: 25 + steps: 5 + - name: ChangeToxinsTolerance + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: ToxinsTolerance + minValue: 1 + maxValue: 10 + steps: 5 + - name: ChangeLowPressureTolerance + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: LowPressureTolerance + minValue: 60 + maxValue: 100 + steps: 5 + - name: ChangeHighPressureTolerance + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: HighPressureTolerance + minValue: 100 + maxValue: 140 + steps: 5 + - name: ChangePestTolerance + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: PestTolerance + minValue: 0 + maxValue: 15 + steps: 5 + - name: ChangeWeedTolerance + baseOdds: 0.018 + persists: false + effect: !type:PlantChangeStat + targetValue: WeedTolerance + minValue: 0 + maxValue: 15 + steps: 5 + - name: ChangeEndurance + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Endurance + minValue: 50 + maxValue: 150 + steps: 5 + - name: ChangeYield + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Yield + minValue: 3 + maxValue: 10 + steps: 5 + - name: ChangeLifespan + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Lifespan + minValue: 10 + maxValue: 80 + steps: 5 + - name: ChangeMaturation + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Maturation + minValue: 3 + maxValue: 8 + steps: 5 + - name: ChangeProduction + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Production + minValue: 1 + maxValue: 10 + steps: 5 + - name: ChangePotency + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Potency + minValue: 30 + maxValue: 100 + steps: 5 + - name: ChangeSeedless + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Seedless + - name: ChangeLigneous + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: Ligneous + - name: ChangeTurnIntoKudzu + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: TurnIntoKudzu + - name: ChangeScreaming + baseOdds: 0.036 + persists: false + effect: !type:PlantChangeStat + targetValue: CanScream + - name: ChangeChemicals + baseOdds: 0.072 + persists: false + effect: !type:PlantMutateChemicals + - name: ChangeExudeGasses + baseOdds: 0.0145 + persists: false + effect: !type:PlantMutateExudeGasses + - name: ChangeConsumeGasses + baseOdds: 0.0036 + persists: false + effect: !type:PlantMutateConsumeGasses + - name: ChangeHarvest + baseOdds: 0.036 + persists: false + effect: !type:PlantMutateHarvest \ No newline at end of file From 7f19d50900d77c1231376abd90101b9b4a7adff8 Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sat, 14 Sep 2024 21:00:06 -0700 Subject: [PATCH 027/138] Fix build and lint (#32180) --- .../Piping/Binary/EntitySystems/GasPressurePumpSystem.cs | 2 +- .../Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs | 2 +- Resources/Prototypes/Entities/Mobs/NPCs/animals.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs index 56359a85af5..abd34396a0c 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasPressurePumpSystem.cs @@ -2,7 +2,6 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Components; -using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; using Content.Server.Power.Components; @@ -14,6 +13,7 @@ using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Popups; +using Content.Shared.Power; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Player; diff --git a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs index d1127920514..9ddd7dce67d 100644 --- a/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs +++ b/Content.Server/Atmos/Piping/Binary/EntitySystems/GasVolumePumpSystem.cs @@ -6,7 +6,6 @@ using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Systems; -using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; using Content.Server.Power.Components; @@ -18,6 +17,7 @@ using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Popups; +using Content.Shared.Power; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Player; diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml index 3bdfac7cbad..5ad2482b19f 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/animals.yml @@ -3108,7 +3108,7 @@ Alive: Base: ferret Critical: - Base: + Base: ferret_dead Dead: Base: ferret_dead - type: Butcherable @@ -3317,7 +3317,7 @@ Alive: Base: pig Critical: - Base: + Base: dead Dead: Base: dead - type: Butcherable From a65484e61a7084bca243053274d2c3a7e6e35cc8 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Sun, 15 Sep 2024 19:04:31 +0000 Subject: [PATCH 028/138] prevent using holo inside containers (#32068) Co-authored-by: deltanedas <@deltanedas:kde.org> --- Content.Server/Guardian/GuardianSystem.cs | 6 ++++++ Resources/Locale/en-US/guardian/guardian.ftl | 1 + 2 files changed, 7 insertions(+) diff --git a/Content.Server/Guardian/GuardianSystem.cs b/Content.Server/Guardian/GuardianSystem.cs index ae4d0ca2b8c..7a1b875756e 100644 --- a/Content.Server/Guardian/GuardianSystem.cs +++ b/Content.Server/Guardian/GuardianSystem.cs @@ -80,6 +80,12 @@ private void OnPerformAction(EntityUid uid, GuardianHostComponent component, Gua if (args.Handled) return; + if (_container.IsEntityInContainer(uid)) + { + _popupSystem.PopupEntity(Loc.GetString("guardian-inside-container"), uid, uid); + return; + } + if (component.HostedGuardian != null) ToggleGuardian(uid, component); diff --git a/Resources/Locale/en-US/guardian/guardian.ftl b/Resources/Locale/en-US/guardian/guardian.ftl index 9e0966630dd..141646087d3 100644 --- a/Resources/Locale/en-US/guardian/guardian.ftl +++ b/Resources/Locale/en-US/guardian/guardian.ftl @@ -10,6 +10,7 @@ guardian-activator-empty-examine = [color=#ba1919]The injector is spent.[/color] guardian-activator-invalid-target = Only humans can be injected! guardian-no-soul = Your guardian has no soul. guardian-available = Your guardian now has a soul. +guardian-inside-container = There's no room to release your guardian! ## Guardian entity specific From 99bb203c86fb94368dbb359ff771850e64038218 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 15 Sep 2024 19:05:39 +0000 Subject: [PATCH 029/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 333c321c8bb..49c5d299d48 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Simyon - changes: - - message: Ratkings now require at least 30 players in order to spawn. - type: Tweak - id: 6878 - time: '2024-07-07T13:06:24.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29737 - author: EmoGarbage404 changes: - message: Intercoms now use encryption keys to determine what channels they can @@ -3886,3 +3879,10 @@ id: 7377 time: '2024-09-15T01:58:10.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/28995 +- author: deltanedas + changes: + - message: Holoparasites can no longer be summoned from inside containers. + type: Tweak + id: 7378 + time: '2024-09-15T19:04:32.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32068 From 02dfbd94c435577dba889400d23fbd7b851097bc Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:49:05 +0200 Subject: [PATCH 030/138] localize skeleton accent (#32166) * localize skeleton accent * commit number 2 * remove that from this * this * babushka --- .../EntitySystems/SkeletonAccentSystem.cs | 27 ++-------------- Resources/Locale/en-US/accent/skeleton.ftl | 32 +++++++++++++++++++ .../Prototypes/Accents/word_replacements.yml | 21 +++++++++++- 3 files changed, 55 insertions(+), 25 deletions(-) create mode 100644 Resources/Locale/en-US/accent/skeleton.ftl diff --git a/Content.Server/Speech/EntitySystems/SkeletonAccentSystem.cs b/Content.Server/Speech/EntitySystems/SkeletonAccentSystem.cs index d143c25fdba..1b773f1a5ac 100644 --- a/Content.Server/Speech/EntitySystems/SkeletonAccentSystem.cs +++ b/Content.Server/Speech/EntitySystems/SkeletonAccentSystem.cs @@ -7,29 +7,11 @@ namespace Content.Server.Speech.EntitySystems; public sealed partial class SkeletonAccentSystem : EntitySystem { [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ReplacementAccentSystem _replacement = default!; [GeneratedRegex(@"(? DirectReplacements = new() - { - { "fuck you", "I've got a BONE to pick with you" }, - { "fucked", "boned"}, - { "fuck", "RATTLE RATTLE" }, - { "fck", "RATTLE RATTLE" }, - { "shit", "RATTLE RATTLE" }, // Capitalize RATTLE RATTLE regardless of original message case. - { "definitely", "make no bones about it" }, - { "absolutely", "make no bones about it" }, - { "afraid", "rattled"}, - { "scared", "rattled"}, - { "spooked", "rattled"}, - { "shocked", "rattled"}, - { "killed", "skeletonized"}, - { "humorous", "humerus"}, - { "to be a", "tibia"}, - { "under", "ulna"} - }; - public override void Initialize() { base.Initialize(); @@ -50,11 +32,8 @@ public string Accentuate(string message, SkeletonAccentComponent component) // At the start of words, any non-vowel + "one" becomes "bone", e.g. tone -> bone ; lonely -> bonely; clone -> clone (remains unchanged). msg = BoneRegex().Replace(msg, "bone"); - // Direct word/phrase replacements: - foreach (var (first, replace) in DirectReplacements) - { - msg = Regex.Replace(msg, $@"(? Date: Sun, 15 Sep 2024 20:04:22 +0000 Subject: [PATCH 031/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 49c5d299d48..eb5b77ffa21 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,14 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - message: Intercoms now use encryption keys to determine what channels they can - broadcast on. - type: Tweak - - message: Intercoms and handheld radios no longer rely on telecom servers. - type: Fix - id: 6879 - time: '2024-07-07T14:19:10.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29580 - author: Vermidia changes: - message: Some drink reactions now require shaking with the shaker or stirring @@ -3886,3 +3876,10 @@ id: 7378 time: '2024-09-15T19:04:32.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32068 +- author: BackeTako + changes: + - message: Added French and Spanish speech traits. + type: Add + id: 7379 + time: '2024-09-15T20:03:15.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/30966 From 2673b1c75d416e9616847267f7bdcbec7155559c Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:04:37 -0700 Subject: [PATCH 032/138] Nerfs meteor penetration force (#32109) nerf meteor penetration force --- .../Entities/Objects/Weapons/Guns/Projectiles/meteors.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml index 235010acc96..095acee4729 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/meteors.yml @@ -104,7 +104,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 1250 + damage: 300 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] @@ -144,7 +144,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 1750 + damage: 500 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] @@ -172,7 +172,7 @@ thresholds: - trigger: !type:DamageTrigger - damage: 2500 + damage: 1200 behaviors: - !type:DoActsBehavior acts: [ "Destruction" ] @@ -220,4 +220,4 @@ volume: 10 - !type:SpillBehavior solution: blood - - !type:ExplodeBehavior \ No newline at end of file + - !type:ExplodeBehavior From 44161307e62e2784655991850604d13ab1f1107a Mon Sep 17 00:00:00 2001 From: PJBot Date: Sun, 15 Sep 2024 20:05:43 +0000 Subject: [PATCH 033/138] 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 eb5b77ffa21..a315324dbc5 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Vermidia - changes: - - message: Some drink reactions now require shaking with the shaker or stirring - with a spoon - type: Add - id: 6880 - time: '2024-07-07T14:21:53.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29243 - author: Dezzzix changes: - message: Now you can slice food with swords @@ -3883,3 +3875,10 @@ id: 7379 time: '2024-09-15T20:03:15.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/30966 +- author: Plykiya + changes: + - message: Meteors break through less walls now. + type: Tweak + id: 7380 + time: '2024-09-15T20:04:37.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32109 From ec22d26156af40c75d193bc6b6dffb9941328934 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:04:27 +0200 Subject: [PATCH 034/138] Fix plushie cutlass swing animation (#32157) Fix plushie cutlass animation --- Resources/Prototypes/Entities/Objects/Fun/toys.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index 7a6961b148a..c050a92deda 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -1327,10 +1327,9 @@ sprite: Objects/Weapons/Melee/cutlass.rsi state: foam_icon - type: MeleeWeapon + wideAnimationRotation: -135 attackRate: 1.5 range: 2.0 - angle: 0 - animation: WeaponArcThrust damage: types: Blunt: 0 From 92f19458ebd2ad50e1d77ed8e141e8b2436802f0 Mon Sep 17 00:00:00 2001 From: xprospero <116504990+xprospero@users.noreply.github.com> Date: Sun, 15 Sep 2024 13:57:53 -1000 Subject: [PATCH 035/138] Rubber chicken toy (#29637) * -added rubber chicken toy * -Removed faulty SolutionContainerManager type -Replaced default toy squeak sound with rubber chicken sound for on-trigger and on-collide. * fixed raw material cost * adjusted material composition * - Added rubber chicken to CrateFunToyBox - Added rubber chicken to MaintFluffTable under "uncommon group" so that it will spawn in maintenance * Update Resources/Prototypes/Entities/Objects/Fun/toys.yml --------- Co-authored-by: gambesun <116504990+gambesun@users.noreply.github.com> Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- Resources/Audio/Items/Toys/attributions.yml | 15 ++++++ .../Audio/Items/Toys/rubber_chicken_1.ogg | Bin 0 -> 10673 bytes .../Audio/Items/Toys/rubber_chicken_2.ogg | Bin 0 -> 9944 bytes .../Audio/Items/Toys/rubber_chicken_3.ogg | Bin 0 -> 12794 bytes .../Prototypes/Catalog/Fills/Crates/fun.yml | 1 + .../Markers/Spawners/Random/maintenance.yml | 1 + .../Prototypes/Entities/Objects/Fun/toys.yml | 49 ++++++++++++++++++ .../SoundCollections/rubber_chicken.yml | 6 +++ .../Textures/Objects/Fun/toys.rsi/meta.json | 5 +- .../Objects/Fun/toys.rsi/rubber_chicken.png | Bin 0 -> 606 bytes 10 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 Resources/Audio/Items/Toys/rubber_chicken_1.ogg create mode 100644 Resources/Audio/Items/Toys/rubber_chicken_2.ogg create mode 100644 Resources/Audio/Items/Toys/rubber_chicken_3.ogg create mode 100644 Resources/Prototypes/SoundCollections/rubber_chicken.yml create mode 100644 Resources/Textures/Objects/Fun/toys.rsi/rubber_chicken.png diff --git a/Resources/Audio/Items/Toys/attributions.yml b/Resources/Audio/Items/Toys/attributions.yml index 290539b9849..162ee8c1c33 100644 --- a/Resources/Audio/Items/Toys/attributions.yml +++ b/Resources/Audio/Items/Toys/attributions.yml @@ -72,3 +72,18 @@ license: "CC-BY-SA-3.0" copyright: "Taken from ss200, made by Daeberdir" source: "https://github.com/ss220-space/Paradise/pull/3756" + +- files: ["rubber_chicken_1.ogg"] + license: "CC0-1.0" + copyright: "Created by xprospero for ss14" + source: "https://github.com/space-wizards/space-station-14/blob/master/Resources/Audio/Items/Toys/rubber_chicken_1.ogg" + +- files: ["rubber_chicken_2.ogg"] + license: "CC0-1.0" + copyright: "Created by xprospero for ss14" + source: "https://github.com/space-wizards/space-station-14/blob/master/Resources/Audio/Items/Toys/rubber_chicken_2.ogg" + +- files: ["rubber_chicken_3.ogg"] + license: "CC0-1.0" + copyright: "Created by xprospero for ss14" + source: "https://github.com/space-wizards/space-station-14/blob/master/Resources/Audio/Items/Toys/rubber_chicken_3.ogg" diff --git a/Resources/Audio/Items/Toys/rubber_chicken_1.ogg b/Resources/Audio/Items/Toys/rubber_chicken_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e4ba8155a6cc1d94f9897f6eeb705cffca6ecc75 GIT binary patch literal 10673 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 P`FQ))@FtB@3jF^7vTU_^ literal 0 HcmV?d00001 diff --git a/Resources/Audio/Items/Toys/rubber_chicken_2.ogg b/Resources/Audio/Items/Toys/rubber_chicken_2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..ae79d97ff22920568aa85036c901267f583d3c29 GIT binary patch literal 9944 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 F{{Tkd6yg8? literal 0 HcmV?d00001 diff --git a/Resources/Audio/Items/Toys/rubber_chicken_3.ogg b/Resources/Audio/Items/Toys/rubber_chicken_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..97d93ed57e727571eaac761c500613444480c94d GIT binary patch literal 12794 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 literal 0 HcmV?d00001 From 654ada8ba3abbdf48a6b18f10772f282de00b559 Mon Sep 17 00:00:00 2001 From: drakewill-CRL <46307022+drakewill-CRL@users.noreply.github.com> Date: Sun, 15 Sep 2024 20:04:44 -0400 Subject: [PATCH 036/138] Fix sentient produce (#32192) sentient does not apply to produce Co-authored-by: PraxisMapper --- Resources/Prototypes/Hydroponics/randomMutations.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Resources/Prototypes/Hydroponics/randomMutations.yml b/Resources/Prototypes/Hydroponics/randomMutations.yml index 50f6845ec32..8f409a5eaf9 100644 --- a/Resources/Prototypes/Hydroponics/randomMutations.yml +++ b/Resources/Prototypes/Hydroponics/randomMutations.yml @@ -6,7 +6,8 @@ effect: !type:Glow - name: Sentient baseOdds: 0.0072 - appliesToPlant: false # makes the botany tray sentient if true + appliesToProduce: false + persists: false effect: !type:MakeSentient # existing effect. - name: Slippery baseOdds: 0.036 From d29816528284f1b980fdfbc35f362c40f27cf95f Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 16 Sep 2024 00:05:51 +0000 Subject: [PATCH 037/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index a315324dbc5..f5027df8d75 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Dezzzix - changes: - - message: Now you can slice food with swords - type: Add - id: 6881 - time: '2024-07-07T14:22:38.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29005 - author: EmoGarbage404 changes: - message: Changed AME power output. Lower injection amounts now produce more power @@ -3882,3 +3875,10 @@ id: 7380 time: '2024-09-15T20:04:37.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32109 +- author: drakewill-CRL + changes: + - message: Produce harvested from sentient plants are no longer sentient themselves. + type: Fix + id: 7381 + time: '2024-09-16T00:04:45.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32192 From bc391eec88142ce9c2471d2dfc8429bb34e43b82 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Mon, 16 Sep 2024 02:16:24 +0200 Subject: [PATCH 038/138] Add glass morgue airlock (#32163) --- .../Entities/Structures/Doors/Airlocks/access.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml index d32cdc09393..2a4b0fcf48a 100644 --- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml +++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml @@ -245,7 +245,6 @@ containers: board: [ DoorElectronicsMorgue ] - - type: entity parent: AirlockScience id: AirlockScienceLocked @@ -604,6 +603,15 @@ containers: board: [ DoorElectronicsChemistry ] +- type: entity + parent: AirlockMedicalGlass + id: AirlockMedicalMorgueGlassLocked + suffix: Morgue, Locked + components: + - type: ContainerFill + containers: + board: [ DoorElectronicsMorgue ] + - type: entity parent: AirlockMedicalGlass id: AirlockMedicalGlassLocked From e6ff813eda6823a3da0983a1b64938c3a5ca4669 Mon Sep 17 00:00:00 2001 From: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:51:53 -0700 Subject: [PATCH 039/138] Fix examine flickering until you examine something around you (#32205) --- Content.Client/Examine/ExamineSystem.cs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Content.Client/Examine/ExamineSystem.cs b/Content.Client/Examine/ExamineSystem.cs index 60d2b6a6ef6..069c9e2f93e 100644 --- a/Content.Client/Examine/ExamineSystem.cs +++ b/Content.Client/Examine/ExamineSystem.cs @@ -1,8 +1,13 @@ +using System.Linq; +using System.Numerics; +using System.Threading; using Content.Client.Verbs; using Content.Shared.Eye.Blinding; using Content.Shared.Examine; using Content.Shared.IdentityManagement; using Content.Shared.Input; +using Content.Shared.Interaction.Events; +using Content.Shared.Item; using Content.Shared.Verbs; using JetBrains.Annotations; using Robust.Client.GameObjects; @@ -13,15 +18,8 @@ using Robust.Shared.Input.Binding; using Robust.Shared.Map; using Robust.Shared.Utility; -using System.Linq; -using System.Numerics; -using System.Threading; -using Content.Shared.Eye.Blinding.Components; -using Robust.Client; using static Content.Shared.Interaction.SharedInteractionSystem; using static Robust.Client.UserInterface.Controls.BoxContainer; -using Content.Shared.Interaction.Events; -using Content.Shared.Item; using Direction = Robust.Shared.Maths.Direction; namespace Content.Client.Examine @@ -38,7 +36,6 @@ public sealed class ExamineSystem : ExamineSystemShared private EntityUid _examinedEntity; private EntityUid _lastExaminedEntity; - private EntityUid _playerEntity; private Popup? _examineTooltipOpen; private ScreenCoordinates _popupPos; private CancellationTokenSource? _requestCancelTokenSource; @@ -77,9 +74,9 @@ private void OnExaminedItemDropped(EntityUid item, ItemComponent comp, DroppedEv public override void Update(float frameTime) { if (_examineTooltipOpen is not {Visible: true}) return; - if (!_examinedEntity.Valid || !_playerEntity.Valid) return; + if (!_examinedEntity.Valid || _playerManager.LocalEntity is not { } player) return; - if (!CanExamine(_playerEntity, _examinedEntity)) + if (!CanExamine(player, _examinedEntity)) CloseTooltip(); } @@ -117,9 +114,8 @@ private bool HandleExamine(in PointerInputCmdHandler.PointerInputCmdArgs args) return false; } - _playerEntity = _playerManager.LocalEntity ?? default; - - if (_playerEntity == default || !CanExamine(_playerEntity, entity)) + if (_playerManager.LocalEntity is not { } player || + !CanExamine(player, entity)) { return false; } From 8deeae65144383729b3479b4e9efd6f7b96ff72a Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 16 Sep 2024 08:53:00 +0000 Subject: [PATCH 040/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index f5027df8d75..6dc0033fa6f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,16 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - message: Changed AME power output. Lower injection amounts now produce more power - but further injections have diminishing returns. - type: Tweak - - message: Increased damage per injection overclocked AMEs. - type: Tweak - - message: Halved fuel per AME jar. - type: Tweak - id: 6882 - time: '2024-07-07T14:27:52.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29587 - author: Plykiya changes: - message: Hyperzine's effective healing range has been changed from 70 to 120, @@ -3882,3 +3870,11 @@ id: 7381 time: '2024-09-16T00:04:45.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32192 +- author: DrSmugleaf + changes: + - message: Fixed examine sometimes flickering and closing until you examine something + around you. + type: Fix + id: 7382 + time: '2024-09-16T08:51:54.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32205 From 7cefd9cf9c6f189863b70454244d6de3c1649923 Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Mon, 16 Sep 2024 01:59:00 -0700 Subject: [PATCH 041/138] Adds the syndicate Booze-O-Mat (Bruise-O-Mat) to nukie planet (#32107) --- .../advertisements/vending/bruiseomat.ftl | 43 +++++++++ Resources/Maps/Nonstations/nukieplanet.yml | 2 +- .../VendingMachines/advertisements.yml | 6 ++ .../Catalog/VendingMachines/goodbyes.yml | 6 ++ .../Structures/Machines/vending_machines.yml | 35 +++++++ .../VendingMachines/bruiseomat.rsi/broken.png | Bin 0 -> 1104 bytes .../bruiseomat.rsi/deny-unshaded.png | Bin 0 -> 1616 bytes .../VendingMachines/bruiseomat.rsi/meta.json | 89 ++++++++++++++++++ .../bruiseomat.rsi/normal-unshaded.png | Bin 0 -> 4617 bytes .../VendingMachines/bruiseomat.rsi/off.png | Bin 0 -> 786 bytes .../VendingMachines/bruiseomat.rsi/panel.png | Bin 0 -> 247 bytes 11 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 Resources/Locale/en-US/advertisements/vending/bruiseomat.ftl create mode 100644 Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/broken.png create mode 100644 Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/deny-unshaded.png create mode 100644 Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/meta.json create mode 100644 Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/normal-unshaded.png create mode 100644 Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/off.png create mode 100644 Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/panel.png diff --git a/Resources/Locale/en-US/advertisements/vending/bruiseomat.ftl b/Resources/Locale/en-US/advertisements/vending/bruiseomat.ftl new file mode 100644 index 00000000000..a8cb903efe2 --- /dev/null +++ b/Resources/Locale/en-US/advertisements/vending/bruiseomat.ftl @@ -0,0 +1,43 @@ +advertisement-bruiseomat-1 = I VOTE WAROPS!!! +advertisement-bruiseomat-2 = Who has TC? +advertisement-bruiseomat-3 = Did anyone buy an EMAG? +advertisement-bruiseomat-4 = I wanna go back to my home station... +advertisement-bruiseomat-5 = Beware of the Mime and Clown. BEWARE! +advertisement-bruiseomat-6 = A nuke a day keeps the deathsquad at bay! +advertisement-bruiseomat-7 = You'll never be able to match MY mixing, Agent! +advertisement-bruiseomat-8 = Thirsting for blood? I got you covered! +advertisement-bruiseomat-9 = If they didn't want us to blow up the station, then why would they leave the disk so unsecured? +advertisement-bruiseomat-10 = They say an eye for an eye makes the whole world blind. So try a nuke instead! +advertisement-bruiseomat-11 = I hunger for blood! +advertisement-bruiseomat-12 = Drink up before the mission! +advertisement-bruiseomat-13 = Man, I didn't know I got moved back to Cadet City! +advertisement-bruiseomat-14 = Sicker than your average Booze-O-Mat! +advertisement-bruiseomat-15 = Nuke ops will continue until robustness improves. +thankyou-bruiseomat-1 = Good luck, schmuck! You're gonna need it! +thankyou-bruiseomat-2 = Show 'em the Gorlex Style! +thankyou-bruiseomat-3 = Don't forget to stay hydrated! +thankyou-bruiseomat-4 = You noted down the codes, right? +thankyou-bruiseomat-5 = Don't forget the nuke! +thankyou-bruiseomat-6 = I hope those are noslips. +thankyou-bruiseomat-7 = Please let this be a normal team... +thankyou-bruiseomat-8 = Seems like the station isn't the only thing getting hammered today. +thankyou-bruiseomat-9 = What the hell did you buy? +thankyou-bruiseomat-10 = Give it up for the flukeops professionals! +thankyou-bruiseomat-11 = Death to NanoTrasen!!! +thankyou-bruiseomat-12 = Really? That's your plan? +thankyou-bruiseomat-13 = In my endless life, never have I ever seen that loadout. +thankyou-bruiseomat-14 = Get that captain! +thankyou-bruiseomat-15 = Don't run off by yourself, now! +thankyou-bruiseomat-16 = Y'all are taking too long! +thankyou-bruiseomat-17 = They won't see that coming! +thankyou-bruiseomat-18 = Remember your pinpointer! +thankyou-bruiseomat-19 = See you soon! Or maybe never again, that one's more likely! +thankyou-bruiseomat-20 = Rescue another one of me! I need a friend! +thankyou-bruiseomat-21 = You're going to sober up before the mission, right? +thankyou-bruiseomat-22 = 5 telecrystal says you won't make it to the shuttle before you fall over. +thankyou-bruiseomat-23 = The soda fountain's over there, lightweight. +thankyou-bruiseomat-24 = Did you spend your TC on cat ears? +thankyou-bruiseomat-25 = Really? That's what you wanted to drink? +thankyou-bruiseomat-26 = Take a shot, give a shot! +thankyou-bruiseomat-27 = How many drinks have you had now? I've lost count. +thankyou-bruiseomat-28 = When the bosses say "die trying" they mean dying in BATTLE, not at the bar. diff --git a/Resources/Maps/Nonstations/nukieplanet.yml b/Resources/Maps/Nonstations/nukieplanet.yml index 2063451a0ee..665657f7dda 100644 --- a/Resources/Maps/Nonstations/nukieplanet.yml +++ b/Resources/Maps/Nonstations/nukieplanet.yml @@ -13721,7 +13721,7 @@ entities: - type: Transform pos: 3.5882664,-8.344303 parent: 104 -- proto: VendingMachineBooze +- proto: VendingMachineBoozeSyndicate entities: - uid: 1380 components: diff --git a/Resources/Prototypes/Catalog/VendingMachines/advertisements.yml b/Resources/Prototypes/Catalog/VendingMachines/advertisements.yml index 5f6806afbb1..9314de97914 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/advertisements.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/advertisements.yml @@ -22,6 +22,12 @@ prefix: advertisement-boozeomat- count: 19 +- type: localizedDataset + id: BruiseOMatAds + values: + prefix: advertisement-bruiseomat- + count: 15 + - type: localizedDataset id: CargoDrobeAds values: diff --git a/Resources/Prototypes/Catalog/VendingMachines/goodbyes.yml b/Resources/Prototypes/Catalog/VendingMachines/goodbyes.yml index 5a3d91db116..fd4e53acaa7 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/goodbyes.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/goodbyes.yml @@ -4,6 +4,12 @@ prefix: thankyou-boozeomat- count: 3 +- type: localizedDataset + id: BruiseOMatGoodbyes + values: + prefix: thankyou-bruiseomat- + count: 28 + - type: localizedDataset id: ChangGoodbyes values: diff --git a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml index b6504c81c48..9e0d13745e9 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/vending_machines.yml @@ -199,6 +199,41 @@ - Bartender #- Drinks # DeltaV - doesn't exist +- type: entity + parent: VendingMachineBooze + id: VendingMachineBoozeSyndicate # syndie booze-o-mat for nukie outpost + name: Bruise-O-Mat + description: A refurbished Booze-O-Mat for boosting operative morale. An imprint of a blood-red hardsuit is visible on one side, and the paint seems ashed off on the other side. + components: + - type: VendingMachine + pack: BoozeOMatInventory + offState: off + brokenState: broken + normalState: normal-unshaded + denyState: deny-unshaded + loopDeny: false + - type: Advertise + pack: BruiseOMatAds + - type: SpeakOnUIClosed + pack: BruiseOMatGoodbyes + - type: Speech + - type: Sprite + sprite: Structures/Machines/VendingMachines/bruiseomat.rsi + layers: + - state: "off" + map: ["enum.VendingMachineVisualLayers.Base"] + - state: "off" + map: ["enum.VendingMachineVisualLayers.BaseUnshaded"] + shader: unshaded + - state: panel + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: AccessReader + access: [["SyndicateAgent"]] + - type: GuideHelp + guides: + - Bartender + - Drinks + - type: entity parent: VendingMachine id: VendingMachineCart diff --git a/Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/broken.png b/Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/broken.png new file mode 100644 index 0000000000000000000000000000000000000000..1df632306540fd93c9d253dc312b1aaa50abc43e GIT binary patch literal 1104 zcmV-W1h4yvP)Px(3Q0skR9J=WmS1RFRUF4Z=l*G$nwqqtH5o1Fb4?#wK`1sN)lI=sX}b>XpG_@n zu*yLCq6~Dny|_tj)s}9n%yqihu4O|Q!hBNSHqlail$0P;wl=v-$&!1M93S$BB{yMh z2knbrINW=G=lp)Z&-tBm&%MIy^-6Y88i3pF#^dqqXyRxzieVU80FTE*V`Jlv0st6> zfwJRSOY}d$t^;TQjg5`e)z$5I@|Bepv{)=gI2=X@v7^bu;V`jSEL(xRmX?;b9nkOh zZ`$AQ_ZRMq0OIlZwgI;5uaz1`Kl}&)p$MjDFO!lg0E()T%%}|a?nh=M-`)6`{GzS@ zb*tb%6pNuhy9WTr$PtngQ^ecask!wV*5Chdv9`7-pY1J}2?m)72C+;Fp{QsgUDW^8 z<#`$!8W`z6@X*-_AqvSW$p#Qf2qFnV3I!u6xMyj^Q-Y0T2FtP#Lh$hylY~}6L=A(e zVN?vB7@wr-xo3#CwO1TtTLO(51Zr47> zt}lWR821d~)e;@aK+hZOdD_R>=?fKu#@pISy)!`l)$2fZDXc?pmmOWBt80dtS-h)#vkVDS24{Ek8pb zl}clpCI|O+(DB0aD2js5>tpQH8P;p;GmS(dn@ZZ$)Ks{)Z9+v+Q4}@zCS>LFc{y_8 z1g2>+cIph~Q%_P|U5&%xz~OKd`G-Owx?X>|&_baQ06m(M9?cGItALXGDyGR2^uE%; z>gvA$II0{Re6ODiSARrRRTRbk1#N9@W$f#jqUW`>HReO>(iX{m8pOYK-cv` zlTy;N_eFGFXLNWFhr6D+UvKm2m**H6I8Ye(D6#=mxzbd*(&#m54t2eT`*AnpSFVvv zB$2s|A=DI8b911kvTYMe=US<3dq8Hg*Q4EUv3h5f*&8>}TslG#d@$I{XVd3URRu)> z%KSw2_4T1?8bS!9lt?L=n3$-z2W$X$ZvO$m$=o%s(|`V6adrg|4-O_(; W9$!}jmzmK30000 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/off.png b/Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/off.png new file mode 100644 index 0000000000000000000000000000000000000000..c3427b7188c359f38b6f49a481f84cd3199bf0e8 GIT binary patch literal 786 zcmV+t1MU2YP)Px%%t=H+R9J=Wmd#GvKomyL*kcExL@`t#K@~*1Mq$AN@Di1>tkh*!eH0`l#0sg) zN_~`8su1e3f<|2w3W?)1KNH*2g^h_F2aeX6%`-{@R4Nr5 z$62UxtJT7F-3Y*O9IDmoLID6=*Tq=4YexS8o*h5}RI621R#p~nesOVu^gNG7qk#}& zq2`T71JCoK2;A!Q^mOh8Yqi?c^J}$Q(oO+%yWP0~=AAFIH=ONP0BAq}zBU0cOp`%q zqLiXisUU>l_NCo?|B}pq>v>qOU*?((fBfQOxqLr>X-0-xM-Va$5{N`vKUvO<0W|yB zh2uy35C{=M(DuA1G0z2XoM^W_RYV9uuj69db~3J%;zhZTn)Bx=0d#UWNAJKdOMF6# z0|TqqrvPX)cNy?FO|FC*JhKNvfFbBEX)H7az;E@R#2oI6fQTuCh<@l>u6uPXCH(w7 z!A-LK5J0;f#H|iiX3Ui%k9SnA$MSO4;(m<*SXS0HN<1KyjH4RF*Uin%napzmq`dp) zeLp}cg;ObD7;w`Zu)4a6eR;)AaeSxEW^*djt*x!e0EQ6(1VNA;0>Hk!Lanc{gZx9~_;qy}ivF83BLxd#Uxt0pbc5Oh`AizQ%Ak#57F|WBgOx+uP&d z=p@y@zP=tao(SM|I;p-80=KP__B3JM-`~fwEQZ4&op`-^9Dz>{MPM`ul~TyEh3^fq zZ5yK)9VB5lU5W?HuQ33-6uo;Lf>NYDd>tP`!t@`k2U+E3R9+zpqwC*RfGkJRkR=P% zQ52RT=ru7-1H*v4YFw|^ky0XrKx>WGn#04x>2u)f>$i!!nDlpJwD^Q!NWb4tqLqM6 zn**~}vaF7ek8|&5jdKC!sbr(t-QAsejwqE%8enH<=TYXf>g?<+4e(t02cZlCuO2cJ QWdHyG07*qoM6N<$g6wW>IsgCw literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/panel.png b/Resources/Textures/Structures/Machines/VendingMachines/bruiseomat.rsi/panel.png new file mode 100644 index 0000000000000000000000000000000000000000..60dbf76b85e3f9f18a80a5d810366360f199f9ba GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?4jBOuH;Rhv&5D7ezo z#WAE}&f6=7T!$P4STD$nyx(**th!lbTG+gU4O4I5WVQBAblh;7aZS)HW1p?;A5?^9 zb}-r=aQWcBegDt=^u*^gDmWAx7?{As83xUzcF%3*%`NUQ6iZ{!jbCq-Q*J!RpFiey zc-}9TsCApye80i6k^RM4(L!q(_7=?p)&14F8mA4`-51%AAr+#;>S9-9+%PTP=>_`{ nkp}Ze*1zZXcQ7#3iG5&UGSGT7l{r%o=x7E{S3j3^P6 Date: Mon, 16 Sep 2024 09:00:06 +0000 Subject: [PATCH 042/138] 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 6dc0033fa6f..711c7641373 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: Hyperzine's effective healing range has been changed from 70 to 120, - to anything above 70 total damage. - type: Tweak - id: 6883 - time: '2024-07-07T14:28:13.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29712 - author: Tayrtahn changes: - message: Fixed admin ghosts briefly becoming visible when a news article is published. @@ -3878,3 +3870,12 @@ id: 7382 time: '2024-09-16T08:51:54.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32205 +- author: ArtisticRoomba + changes: + - message: The Bruise-O-Mat alcohol vendor has been added to the nukie outpost, + for all your pre-op drinking needs. Seems to have developed a witty personality, + too... + type: Add + id: 7383 + time: '2024-09-16T08:59:00.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32107 From 26ed0aa7ff1332e52ede5eaee8ac17905b32be73 Mon Sep 17 00:00:00 2001 From: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com> Date: Mon, 16 Sep 2024 03:01:49 -0700 Subject: [PATCH 043/138] Change the binary translator key's contraband designation to syndicate contraband + minor sprite change for consistency (#32193) * adds new icon, changes binary key icon and frame, changes contraband designation * added back the regular key as admeme because it makes sense (why am I not thinking about these things) * hehe I cannot read! --- .../Prototypes/Catalog/uplink_catalog.yml | 4 ++-- .../Objects/Devices/encryption_keys.yml | 17 ++++++++++++++++- .../Devices/encryption_keys.rsi/borg_label.png | Bin 0 -> 149 bytes .../Devices/encryption_keys.rsi/meta.json | 7 ++++--- 4 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 Resources/Textures/Objects/Devices/encryption_keys.rsi/borg_label.png diff --git a/Resources/Prototypes/Catalog/uplink_catalog.yml b/Resources/Prototypes/Catalog/uplink_catalog.yml index 2219eec84d4..92ff0dc62e0 100644 --- a/Resources/Prototypes/Catalog/uplink_catalog.yml +++ b/Resources/Prototypes/Catalog/uplink_catalog.yml @@ -771,8 +771,8 @@ id: UplinkBinaryTranslatorKey name: uplink-binary-translator-key-name description: uplink-binary-translator-key-desc - icon: { sprite: /Textures/Objects/Devices/encryption_keys.rsi, state: rd_label } - productEntity: EncryptionKeyBinary + icon: { sprite: /Textures/Objects/Devices/encryption_keys.rsi, state: borg_label } + productEntity: EncryptionKeyBinarySyndicate cost: Telecrystal: 1 categories: diff --git a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml index b35d2e435c3..c0f27ca2c48 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/encryption_keys.yml @@ -234,7 +234,22 @@ - type: Sprite layers: - state: crypt_silver - - state: rd_label + - state: borg_label + +- type: entity + parent: [ EncryptionKey, BaseSyndicateContraband ] + id: EncryptionKeyBinarySyndicate + name: binary translator key + description: A syndicate encryption key that translates binary signals used by silicons. + components: + - type: EncryptionKey + channels: + - Binary + defaultChannel: Binary + - type: Sprite + layers: + - state: crypt_red + - state: borg_label - type: entity parent: EncryptionKey diff --git a/Resources/Textures/Objects/Devices/encryption_keys.rsi/borg_label.png b/Resources/Textures/Objects/Devices/encryption_keys.rsi/borg_label.png new file mode 100644 index 0000000000000000000000000000000000000000..2b56e167730682294aca3f6c0465c838176a3bfb GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}{+=$5ArY-_ zFBtMQ81Oh>>|nl~ezNm$2 Date: Sun, 30 Jun 2024 23:06:28 -0400 Subject: [PATCH 044/138] Remove blurry vision examine mispredict (#29633) remove blurry vision examine mispredict --- Content.Client/Examine/ExamineSystem.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Content.Client/Examine/ExamineSystem.cs b/Content.Client/Examine/ExamineSystem.cs index 069c9e2f93e..1c1f1984de4 100644 --- a/Content.Client/Examine/ExamineSystem.cs +++ b/Content.Client/Examine/ExamineSystem.cs @@ -2,7 +2,6 @@ using System.Numerics; using System.Threading; using Content.Client.Verbs; -using Content.Shared.Eye.Blinding; using Content.Shared.Examine; using Content.Shared.IdentityManagement; using Content.Shared.Input; @@ -356,10 +355,7 @@ public void DoExamine(EntityUid entity, bool centeredOnCursor = true, EntityUid? FormattedMessage message; - // Basically this just predicts that we can't make out the entity if we have poor vision. - var canSeeClearly = !HasComp(playerEnt); - - OpenTooltip(playerEnt.Value, entity, centeredOnCursor, false, knowTarget: canSeeClearly); + OpenTooltip(playerEnt.Value, entity, centeredOnCursor, false); // Always update tooltip info from client first. // If we get it wrong, server will correct us later anyway. From 432d0c0458413e2f7fbe0469719a530185d2beae Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 16 Sep 2024 10:02:55 +0000 Subject: [PATCH 045/138] 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 711c7641373..2b959c50705 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Tayrtahn - changes: - - message: Fixed admin ghosts briefly becoming visible when a news article is published. - type: Fix - id: 6884 - time: '2024-07-08T03:33:17.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29801 - author: slarticodefast changes: - message: Improved throwing calculations. Thrown items now stop moving exactly @@ -3879,3 +3872,11 @@ id: 7383 time: '2024-09-16T08:59:00.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32107 +- author: ArtisticRoomba + changes: + - message: The binary translator key in the syndie uplink is now correctly marked + as syndicate contraband. + type: Tweak + id: 7384 + time: '2024-09-16T10:01:49.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32193 From b8efe95a70a47f954f20fbd47e0f564f50446563 Mon Sep 17 00:00:00 2001 From: august-sun <45527070+august-sun@users.noreply.github.com> Date: Mon, 16 Sep 2024 04:37:26 -0600 Subject: [PATCH 046/138] Immovable Rod Spawn Addition: Lizard Plushie (#32113) * a deadly weh * Updated meteorswarms.yml Updated probabilities to match exactly 1 * Updated immovable_rod.yml Removed rotation --------- Co-authored-by: august-sun <45527070+august.sun@users.noreply.github.com> --- .../Entities/Objects/Fun/immovable_rod.yml | 13 ++++++++++++- .../Prototypes/GameRules/meteorswarms.yml | 19 +++++++++++-------- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml b/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml index 69f0ed415eb..0bee05aa6ad 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/immovable_rod.yml @@ -1,4 +1,4 @@ -- type: entity +- type: entity id: ImmovableRod name: immovable rod description: You can sense that it's hungry. That's usually a bad sign. @@ -177,3 +177,14 @@ state: icon rotation: 225 noRot: false + +- type: entity + parent: ImmovableRodKeepTilesStill + id: ImmovableRodWeh + name: immovable weh + description: WEH! + components: + - type: Sprite + sprite: Objects/Fun/toys.rsi + state: plushie_lizard + noRot: false diff --git a/Resources/Prototypes/GameRules/meteorswarms.yml b/Resources/Prototypes/GameRules/meteorswarms.yml index e2c8ea41fd1..935843257ff 100644 --- a/Resources/Prototypes/GameRules/meteorswarms.yml +++ b/Resources/Prototypes/GameRules/meteorswarms.yml @@ -212,26 +212,29 @@ - type: ImmovableRodRule rodPrototypes: - id: ImmovableRodKeepTilesStill - prob: 0.95 + prob: 0.94 orGroup: rodProto - id: ImmovableRodMop - prob: 0.0072 + prob: 0.0075 orGroup: rodProto - id: ImmovableRodShark - prob: 0.0072 + prob: 0.0075 orGroup: rodProto - id: ImmovableRodClown - prob: 0.0072 + prob: 0.0075 orGroup: rodProto - id: ImmovableRodBanana - prob: 0.0072 + prob: 0.0075 orGroup: rodProto - id: ImmovableRodHammer - prob: 0.0072 + prob: 0.0075 orGroup: rodProto - id: ImmovableRodThrongler - prob: 0.0072 + prob: 0.0075 orGroup: rodProto - id: ImmovableRodGibstick - prob: 0.0072 + prob: 0.0075 + orGroup: rodProto + - id: ImmovableRodWeh + prob: 0.0075 orGroup: rodProto From 895000d6908494e4689290d3457ba171f87a07b5 Mon Sep 17 00:00:00 2001 From: MissKay1994 <15877268+MissKay1994@users.noreply.github.com> Date: Mon, 16 Sep 2024 08:45:15 -0400 Subject: [PATCH 047/138] Lizards now metabolize chocolate (#32147) * Eat the chocolate * Update toxins.yml * fully delete threshold lines * Update snacks.yml * Fix tags Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Prototypes/Entities/Objects/Consumable/Food/snacks.yml | 4 ++++ Resources/Prototypes/Reagents/toxins.yml | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml index ff0504d39ea..e9e57f79ce4 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml @@ -129,6 +129,10 @@ - type: Sprite state: chocolatebar-open - type: Item + - type: Tag + tags: + - FoodSnack + - ReptilianFood - type: SolutionContainerManager solutions: food: diff --git a/Resources/Prototypes/Reagents/toxins.yml b/Resources/Prototypes/Reagents/toxins.yml index a39d845729d..12b05f9b232 100644 --- a/Resources/Prototypes/Reagents/toxins.yml +++ b/Resources/Prototypes/Reagents/toxins.yml @@ -407,8 +407,6 @@ effects: - !type:HealthChange conditions: - - !type:ReagentThreshold - min: 1 - !type:OrganType type: Animal # Applying damage to the mobs with lower metabolism capabilities damage: @@ -417,8 +415,6 @@ - !type:ChemVomit probability: 0.04 #Scaled for time, not metabolismrate. conditions: - - !type:ReagentThreshold - min: 3 - !type:OrganType type: Animal From a9879689183a4968ea901b2a2b4a170c7a943b6f Mon Sep 17 00:00:00 2001 From: PJBot Date: Mon, 16 Sep 2024 12:46:21 +0000 Subject: [PATCH 048/138] 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 2b959c50705..9afdf08d174 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,13 +1,4 @@ Entries: -- author: slarticodefast - changes: - - message: Improved throwing calculations. Thrown items now stop moving exactly - below your cursor. Throwing weapons will land at your cursor and then slide - until stopped by friction. - type: Tweak - id: 6885 - time: '2024-07-08T09:03:53.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29726 - author: Errant changes: - message: Vox now have their entry in the guidebook. @@ -3880,3 +3871,10 @@ id: 7384 time: '2024-09-16T10:01:49.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32193 +- author: MissKay1994 + changes: + - message: Lizards are now poisoned by hot chocolate + type: Fix + id: 7385 + time: '2024-09-16T12:45:15.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32147 From ffdf6bb838593771ba9beb60d665279d7ba03d4b Mon Sep 17 00:00:00 2001 From: chavonadelal <156101927+chavonadelal@users.noreply.github.com> Date: Mon, 16 Sep 2024 15:50:14 +0300 Subject: [PATCH 049/138] Localization of steal targets (#30153) * Localization of steal targets * Correction of localization of theft objects * The second correction of the localization of theft targets * Update steal-target-groups.ftl Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> * Revision of the localization method * Choosing a simple option for localization * Fix TechnologyDisk name * Corrections based on feedback received * correction of declension --------- Co-authored-by: Ed <96445749+TheShuEd@users.noreply.github.com> --- .../Systems/StealConditionSystem.cs | 9 +- .../Prototypes/StealTargetGroupPrototype.cs | 2 +- .../conditions/steal-target-groups.ftl | 7 ++ .../conditions/steal-target-groups.ftl | 1 + .../conditions/steal-target-groups.ftl | 68 +++++++++++ .../en-US/objectives/conditions/steal.ftl | 2 +- .../DeltaV/Objectives/recruiter.yml | 2 +- .../DeltaV/Objectives/stealTargetGroups.yml | 10 +- .../Objectives/stealTargetGroups.yml | 4 +- .../Objectives/stealTargetGroups.yml | 112 +++++++++--------- 10 files changed, 146 insertions(+), 71 deletions(-) create mode 100644 Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl create mode 100644 Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl create mode 100644 Resources/Locale/en-US/objectives/conditions/steal-target-groups.ftl diff --git a/Content.Server/Objectives/Systems/StealConditionSystem.cs b/Content.Server/Objectives/Systems/StealConditionSystem.cs index 2c9244cf7d5..be34a80fe34 100644 --- a/Content.Server/Objectives/Systems/StealConditionSystem.cs +++ b/Content.Server/Objectives/Systems/StealConditionSystem.cs @@ -72,14 +72,15 @@ private void OnAssigned(Entity condition, ref Objective private void OnAfterAssign(Entity condition, ref ObjectiveAfterAssignEvent args) { var group = _proto.Index(condition.Comp.StealGroup); + string localizedName = Loc.GetString(group.Name); var title =condition.Comp.OwnerText == null - ? Loc.GetString(condition.Comp.ObjectiveNoOwnerText, ("itemName", group.Name)) - : Loc.GetString(condition.Comp.ObjectiveText, ("owner", Loc.GetString(condition.Comp.OwnerText)), ("itemName", group.Name)); + ? Loc.GetString(condition.Comp.ObjectiveNoOwnerText, ("itemName", localizedName)) + : Loc.GetString(condition.Comp.ObjectiveText, ("owner", Loc.GetString(condition.Comp.OwnerText)), ("itemName", localizedName)); var description = condition.Comp.CollectionSize > 1 - ? Loc.GetString(condition.Comp.DescriptionMultiplyText, ("itemName", group.Name), ("count", condition.Comp.CollectionSize)) - : Loc.GetString(condition.Comp.DescriptionText, ("itemName", group.Name)); + ? Loc.GetString(condition.Comp.DescriptionMultiplyText, ("itemName", localizedName), ("count", condition.Comp.CollectionSize)) + : Loc.GetString(condition.Comp.DescriptionText, ("itemName", localizedName)); _metaData.SetEntityName(condition.Owner, title, args.Meta); _metaData.SetEntityDescription(condition.Owner, description, args.Meta); diff --git a/Content.Shared/Objectives/Prototypes/StealTargetGroupPrototype.cs b/Content.Shared/Objectives/Prototypes/StealTargetGroupPrototype.cs index 2730acb9aca..bc2af0eb092 100644 --- a/Content.Shared/Objectives/Prototypes/StealTargetGroupPrototype.cs +++ b/Content.Shared/Objectives/Prototypes/StealTargetGroupPrototype.cs @@ -10,6 +10,6 @@ namespace Content.Shared.Objectives; public sealed partial class StealTargetGroupPrototype : IPrototype { [IdDataField] public string ID { get; private set; } = default!; - [DataField] public string Name { get; private set; } = string.Empty; + [DataField] public LocId Name { get; private set; } = string.Empty; [DataField] public SpriteSpecifier Sprite { get; private set; } = SpriteSpecifier.Invalid; } diff --git a/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl b/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl new file mode 100644 index 00000000000..2a3231cf323 --- /dev/null +++ b/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl @@ -0,0 +1,7 @@ +steal-target-group-lucky-bill = logistics officer's lucky bill +steal-target-group-ian-dossier = head of personnel's photobook +steal-target-group-x01 = x-01 multiphase energy gun +steal-target-group-notary-stamp = notary stamp +steal-target-group-silvia = silvia + +steal-target-group-recruiter-pen = recruiter's pen diff --git a/Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl b/Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl new file mode 100644 index 00000000000..fa96136b13d --- /dev/null +++ b/Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl @@ -0,0 +1 @@ +steal-target-group-anti-psychic-knife = anti-psychic knife diff --git a/Resources/Locale/en-US/objectives/conditions/steal-target-groups.ftl b/Resources/Locale/en-US/objectives/conditions/steal-target-groups.ftl new file mode 100644 index 00000000000..12c562422d9 --- /dev/null +++ b/Resources/Locale/en-US/objectives/conditions/steal-target-groups.ftl @@ -0,0 +1,68 @@ +# Traitor single items +steal-target-groups-hypospray = hypospray +steal-target-groups-handheld-crew-monitor = handheld crew monitor +steal-target-groups-clothing-outer-hardsuit-rd = experimental research hardsuit +steal-target-groups-hand-teleporter = hand teleporter +steal-target-groups-clothing-shoes-boots-mag-adv = advanced magboots +steal-target-groups-box-folder-qm-clipboard = requisition digi-board +steal-target-groups-food-meat-corgi = prime-cut corgi meat +steal-target-groups-captain-id-card = captain ID card +steal-target-groups-jetpack-captain-filled = captain's jetpack +steal-target-groups-weapon-antique-laser = antique laser pistol +steal-target-groups-nuke-disk = nuclear authentication disk +steal-target-groups-weapon-energy-shot-gun = energy shotgun + +# Thief Collection +steal-target-groups-figurines = figurine +steal-target-groups-heads-cloaks = head's cloak +steal-target-groups-heads-bedsheets = head's bedsheet +steal-target-groups-stamps = stamp +steal-target-groups-door-remotes = door remote +steal-target-groups-encryption-keys = encryption key +steal-target-groups-technology-disks = technology disk +steal-target-groups-id-cards = ID Card +steal-target-groups-lamps = LAMP + +# Thief single item +steal-target-groups-forensic-scanner = forensic scanner +steal-target-groups-flippo-engraved-lighter = detective's Flippo engraved lighter +steal-target-groups-ammo-tech-fab-circuitboard = ammo techfab circuit board +steal-target-groups-clothing-head-hat-warden = warden's cap +steal-target-groups-clothing-outer-hardsuit-void-paramed = paramedic void suit +steal-target-groups-medical-tech-fab-circuitboard = medical techfab machine board +steal-target-groups-clothing-headset-alt-medical = chief medical officer's over-ear headset +steal-target-groups-research-and-development-server-machine-circuitboard = R&D server machine board +steal-target-groups-fire-axe = fireaxe +steal-target-groups-ame-part-flatpack = AME flatpack +steal-target-groups-salvage-expeditions-computer-circuitboard = salvage expeditions computer board +steal-target-groups-cargo-shuttle-console-circuitboard = cargo shuttle console board +steal-target-groups-clothing-eyes-hud-beer = beer goggles +steal-target-groups-bible = bible +steal-target-groups-clothing-neck-goldmedal = gold medal of crewmanship +steal-target-groups-clothing-neck-clownmedal = clown medal + +# Thief structures +steal-target-groups-teg = teg generator part +steal-target-groups-freezer-heater = freezer or heater +steal-target-groups-altar-nanotrasen = nanotrasen altar (any) + +steal-target-groups-nuclear-bomb = nuclear fission explosive +steal-target-groups-fax-machine-captain = captain long range fax machine +steal-target-groups-chem-dispenser = chemical dispenser +steal-target-groups-xeno-artifact = alien artifact +steal-target-groups-booze-dispenser = booze dispenser +# DeltaV - Epistemics Department - Replace RD with Mystagogue +steal-target-groups-plant-rd = "Mytagogue's potted plant" +steal-target-groups-toilet-golden-dirty-water = golden toilet + +# Thief Animal +steal-target-groups-animal-named-cat = CMO's Cat + +steal-target-groups-animal-ian = Ian +steal-target-groups-animal-mc-griff = McGriff +steal-target-groups-animal-walter = Walter +steal-target-groups-animal-morty = Morty +steal-target-groups-animal-renault = Renault +# DeltaV - Adjusts from Shiva because we have multiple possible sec animals +steal-target-groups-animal-shiva = Security Pet +steal-target-groups-animal-tropico = Tropico diff --git a/Resources/Locale/en-US/objectives/conditions/steal.ftl b/Resources/Locale/en-US/objectives/conditions/steal.ftl index 1bca71ce90d..d63f3de1883 100644 --- a/Resources/Locale/en-US/objectives/conditions/steal.ftl +++ b/Resources/Locale/en-US/objectives/conditions/steal.ftl @@ -9,4 +9,4 @@ objective-condition-steal-Ian = head of personnel's corgi objective-condition-thief-description = The {$itemName} would be a great addition to my collection! objective-condition-thief-animal-description = The {$itemName} would be a great addition to my collection! Most importantly, alive. -objective-condition-thief-multiply-description = I need to get {$count} {MAKEPLURAL($itemName)} and take them with me. +objective-condition-thief-multiply-description = I need to get {$count} {MAKEPLURAL($itemName)} (any) and take them with me. diff --git a/Resources/Prototypes/DeltaV/Objectives/recruiter.yml b/Resources/Prototypes/DeltaV/Objectives/recruiter.yml index f73a31da35f..cff6f085806 100644 --- a/Resources/Prototypes/DeltaV/Objectives/recruiter.yml +++ b/Resources/Prototypes/DeltaV/Objectives/recruiter.yml @@ -43,7 +43,7 @@ - type: stealTargetGroup id: RecruiterPen - name: recruiter pen + name: steal-target-group-recruiter-pen sprite: sprite: DeltaV/Objects/Misc/recruiter_pen.rsi state: empty diff --git a/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml b/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml index 19fbcd25b22..dde963cf359 100644 --- a/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml @@ -1,34 +1,34 @@ - type: stealTargetGroup id: SpaceCashLuckyBill - name: logistics officer's lucky bill + name: steal-target-group-lucky-bill sprite: sprite: DeltaV/Objects/Misc/first_bill.rsi state: icon - type: stealTargetGroup id: BookIanDossier - name: head of personnel's photobook + name: steal-target-group-ian-dossier sprite: sprite: DeltaV/Objects/Misc/bureaucracy.rsi state: folder-hop-ian - type: stealTargetGroup id: WeaponEnergyGunMultiphase - name: x-01 multiphase energy gun + name: steal-target-group-x01 sprite: sprite: DeltaV/Objects/Weapons/Guns/Battery/multiphase_energygun.rsi state: base - type: stealTargetGroup id: RubberStampNotary - name: notary stamp + name: steal-target-group-notary-stamp sprite: sprite: DeltaV/Objects/Misc/stamps.rsi state: stamp-notary - type: stealTargetGroup id: AnimalSilvia - name: Silvia + name: steal-target-group-silvia sprite: sprite: DeltaV/Mobs/Pets/silvia.rsi state: silvia diff --git a/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml index 4f0e78b354d..3afd4b9dc84 100644 --- a/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml @@ -1,6 +1,6 @@ -- type: stealTargetGroup +- type: stealTargetGroup id: AntiPsychicKnife - name: anti-psychic knife + name: steal-target-group-anti-psychic-knife sprite: sprite: Nyanotrasen/Objects/Weapons/Melee/anti_psychic_knife.rsi state: icon diff --git a/Resources/Prototypes/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Objectives/stealTargetGroups.yml index 3c635d4c628..4241f6b03fc 100644 --- a/Resources/Prototypes/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Objectives/stealTargetGroups.yml @@ -2,77 +2,77 @@ - type: stealTargetGroup id: Hypospray - name: hypospray + name: steal-target-groups-hypospray sprite: sprite: Objects/Specific/Medical/hypospray.rsi state: hypo - type: stealTargetGroup id: HandheldCrewMonitor - name: handheld crew monitor + name: steal-target-groups-handheld-crew-monitor sprite: sprite: Objects/Specific/Medical/handheldcrewmonitor.rsi state: scanner - type: stealTargetGroup id: ClothingOuterHardsuitRd - name: experimental research hardsuit + name: steal-target-groups-clothing-outer-hardsuit-rd sprite: sprite: Clothing/OuterClothing/Hardsuits/rd.rsi state: icon - type: stealTargetGroup id: HandTeleporter - name: hand teleporter + name: steal-target-groups-hand-teleporter sprite: sprite: Objects/Devices/hand_teleporter.rsi state: icon - type: stealTargetGroup id: ClothingShoesBootsMagAdv - name: advanced magboots + name: steal-target-groups-clothing-shoes-boots-mag-adv sprite: sprite: Clothing/Shoes/Boots/magboots-advanced.rsi state: icon - type: stealTargetGroup id: BoxFolderQmClipboard - name: requisition digi-board + name: steal-target-groups-box-folder-qm-clipboard sprite: sprite: Objects/Misc/qm_clipboard.rsi state: qm_clipboard - type: stealTargetGroup id: FoodMeatCorgi - name: prime-cut corgi meat + name: steal-target-groups-food-meat-corgi sprite: sprite: Objects/Consumable/Food/meat.rsi state: corgi # - type: stealTargetGroup id: CaptainIDCard - name: captain ID card + name: steal-target-groups-captain-id-card sprite: sprite: Objects/Misc/id_cards.rsi state: ert_commander #no one will know the difference. - type: stealTargetGroup id: JetpackCaptainFilled - name: captain's jetpack + name: steal-target-groups-jetpack-captain-filled sprite: sprite: Objects/Tanks/Jetpacks/captain.rsi state: icon - type: stealTargetGroup id: WeaponAntiqueLaser - name: antique laser pistol + name: steal-target-groups-weapon-antique-laser sprite: sprite: Objects/Weapons/Guns/Battery/antiquelasergun.rsi state: base - type: stealTargetGroup id: NukeDisk - name: nuclear authentication disk + name: steal-target-groups-nuke-disk sprite: sprite: Objects/Misc/nukedisk.rsi state: icon @@ -86,7 +86,7 @@ - type: stealTargetGroup id: WeaponEnergyShotgun - name: energy shotgun + name: steal-target-groups-weapon-energy-shot-gun sprite: sprite: Objects/Weapons/Guns/Battery/energy_shotgun.rsi state: base @@ -95,63 +95,63 @@ - type: stealTargetGroup id: Figurines - name: figurines (any) + name: steal-target-groups-figurines sprite: sprite: Objects/Fun/figurines.rsi state: figurine_spawner - type: stealTargetGroup id: HeadCloak - name: head's cloaks (any) + name: steal-target-groups-heads-cloaks sprite: sprite: Clothing/Neck/Cloaks/cap.rsi state: icon - type: stealTargetGroup id: HeadBedsheet - name: head's bedsheets (any) + name: steal-target-groups-heads-bedsheets sprite: sprite: Objects/Misc/bedsheets.rsi state: sheetNT - type: stealTargetGroup id: Stamp - name: stamps (any) + name: steal-target-groups-stamps sprite: sprite: Objects/Misc/stamps.rsi state: stamp-cap - type: stealTargetGroup id: DoorRemote - name: door remotes (any) + name: steal-target-groups-door-remotes sprite: sprite: Objects/Devices/door_remote.rsi state: door_remotebase - type: stealTargetGroup id: EncryptionKey - name: encryption keys (any) + name: steal-target-groups-encryption-keys sprite: sprite: Objects/Devices/encryption_keys.rsi state: crypt_gray - type: stealTargetGroup id: TechnologyDisk - name: technology disks + name: steal-target-groups-technology-disks sprite: sprite: Objects/Misc/module.rsi state: datadisk_base - type: stealTargetGroup id: IDCard - name: ID Cards (any) + name: steal-target-groups-id-cards sprite: sprite: Objects/Misc/id_cards.rsi state: default - type: stealTargetGroup id: LAMP - name: LAMPS + name: steal-target-groups-lamps sprite: sprite: Objects/Tools/lantern.rsi state: lantern @@ -160,112 +160,112 @@ - type: stealTargetGroup id: ForensicScanner - name: forensic scanner + name: steal-target-groups-forensic-scanner sprite: sprite: Objects/Devices/forensic_scanner.rsi state: forensicnew - type: stealTargetGroup id: FlippoEngravedLighter - name: detective's Flippo engraved lighter + name: steal-target-groups-flippo-engraved-lighter sprite: sprite: Objects/Tools/lighters.rsi state: zippo_engraved_icon_base - type: stealTargetGroup id: AmmoTechFabCircuitboard - name: ammo techfab circuit board + name: steal-target-groups-ammo-tech-fab-circuitboard sprite: sprite: Objects/Misc/module.rsi state: security - type: stealTargetGroup id: ClothingHeadHatWarden - name: warden's cap + name: steal-target-groups-clothing-head-hat-warden sprite: sprite: Clothing/Head/Hats/warden.rsi state: icon - type: stealTargetGroup id: ClothingOuterHardsuitVoidParamed - name: paramedic void suit + name: steal-target-groups-clothing-outer-hardsuit-void-paramed sprite: sprite: Clothing/OuterClothing/Hardsuits/paramed.rsi state: icon - type: stealTargetGroup id: MedicalTechFabCircuitboard - name: medical techfab machine board + name: steal-target-groups-medical-tech-fab-circuitboard sprite: sprite: Objects/Misc/module.rsi state: medical - type: stealTargetGroup id: ClothingHeadsetAltMedical - name: chief medical officer's over-ear headset + name: steal-target-groups-clothing-headset-alt-medical sprite: sprite: Clothing/Ears/Headsets/medical.rsi state: icon_alt - type: stealTargetGroup id: ResearchAndDevelopmentServerMachineCircuitboard - name: R&D server machine board + name: steal-target-groups-research-and-development-server-machine-circuitboard sprite: sprite: Objects/Misc/module.rsi state: science - type: stealTargetGroup id: FireAxe - name: fireaxe + name: steal-target-groups-fire-axe sprite: sprite: Objects/Weapons/Melee/fireaxe.rsi state: icon - type: stealTargetGroup id: AmePartFlatpack - name: AME part + name: steal-target-groups-ame-part-flatpack sprite: sprite: Objects/Devices/flatpack.rsi state: ame-part - type: stealTargetGroup id: SalvageExpeditionsComputerCircuitboard - name: salvage expeditions computer board + name: steal-target-groups-salvage-expeditions-computer-circuitboard sprite: sprite: Objects/Misc/module.rsi state: cpu_supply - type: stealTargetGroup id: CargoShuttleConsoleCircuitboard - name: cargo shuttle console board + name: steal-target-groups-cargo-shuttle-console-circuitboard sprite: sprite: Objects/Misc/module.rsi state: cpuboard - type: stealTargetGroup id: ClothingEyesHudBeer - name: beer goggles + name: steal-target-groups-clothing-eyes-hud-beer sprite: sprite: Clothing/Eyes/Hud/beergoggles.rsi state: icon - type: stealTargetGroup id: Bible - name: bible + name: steal-target-groups-bible sprite: sprite: Objects/Specific/Chapel/bible.rsi state: icon - type: stealTargetGroup id: ClothingNeckGoldmedal - name: gold medal of crewmanship + name: steal-target-groups-clothing-neck-goldmedal sprite: sprite: Clothing/Neck/Medals/gold.rsi state: icon - type: stealTargetGroup id: ClothingNeckClownmedal - name: clown medal + name: steal-target-groups-clothing-neck-clownmedal sprite: sprite: Clothing/Neck/Medals/clownmedal.rsi state: icon @@ -281,70 +281,70 @@ - type: stealTargetGroup id: NuclearBomb - name: nuclear fission explosive + name: steal-target-groups-nuclear-bomb sprite: sprite: Objects/Devices/nuke.rsi state: nuclearbomb_base - type: stealTargetGroup id: FaxMachineCaptain - name: captain long range fax machine + name: steal-target-groups-fax-machine-captain sprite: sprite: Structures/Machines/fax_machine.rsi state: icon - type: stealTargetGroup id: ChemDispenser - name: chemical dispenser + name: steal-target-groups-chem-dispenser sprite: sprite: Structures/dispensers.rsi state: industrial-working - type: stealTargetGroup id: XenoArtifact - name: big alien artifact + name: steal-target-groups-xeno-artifact sprite: sprite: Objects/Specific/Xenoarchaeology/xeno_artifacts.rsi state: ano28 - type: stealTargetGroup id: FreezerHeater - name: freezer or heater + name: steal-target-groups-freezer-heater sprite: sprite: Structures/Piping/Atmospherics/thermomachine.rsi state: heaterOff - type: stealTargetGroup id: Teg - name: teg generator part + name: steal-target-groups-teg sprite: sprite: Structures/Power/Generation/teg.rsi state: teg - type: stealTargetGroup id: BoozeDispenser - name: booze dispenser + name: steal-target-groups-booze-dispenser sprite: sprite: Structures/smalldispensers.rsi state: booze - type: stealTargetGroup id: AltarNanotrasen - name: nanotrasen altar (any) + name: steal-target-groups-altar-nanotrasen sprite: sprite: Structures/Furniture/Altars/Gods/nanotrasen.rsi state: nanotrasen - type: stealTargetGroup id: PlantRD - name: Mystagogue's potted plant # DeltaV - Epistemics Department - Replace Research Director with Mystagogue + name: steal-target-groups-plant-rd sprite: sprite: Structures/Furniture/potted_plants.rsi state: plant-25 - type: stealTargetGroup id: ToiletGoldenDirtyWater - name: golden toilet + name: steal-target-groups-toilet-golden-dirty-water sprite: sprite: Structures/Furniture/golden_toilet.rsi state: condisposal @@ -353,58 +353,56 @@ - type: stealTargetGroup id: AnimalIan - name: Ian + name: steal-target-groups-animal-ian sprite: sprite: Mobs/Pets/corgi.rsi state: ian - type: stealTargetGroup id: AnimalNamedCat - name: CMO's Cat + name: steal-target-groups-animal-named-cat sprite: sprite: Mobs/Pets/bingus.rsi state: bingus - type: stealTargetGroup id: AnimalMcGriff - name: McGriff + name: steal-target-groups-animal-mc-griff sprite: sprite: Mobs/Pets/mcgriff.rsi state: mcgriff - type: stealTargetGroup id: AnimalWalter - name: Walter + name: steal-target-groups-animal-walter sprite: sprite: Mobs/Pets/walter.rsi state: walter - type: stealTargetGroup id: AnimalMorty - name: Morty + name: steal-target-groups-animal-morty sprite: sprite: Mobs/Animals/possum.rsi state: possum - type: stealTargetGroup id: AnimalRenault - name: Renault + name: steal-target-groups-animal-renault sprite: sprite: Mobs/Animals/fox.rsi state: fox - type: stealTargetGroup id: AnimalSecurity #DeltaV - Adjusts because we have multiple possible sec animals - name: Security Pet #DeltaV - Adjusts because we have multiple possible sec animals + name: steal-target-groups-animal-shiva sprite: sprite: Mobs/Pets/shiva.rsi state: shiva - type: stealTargetGroup id: AnimalTropico - name: Tropico + name: steal-target-groups-animal-tropico sprite: sprite: Mobs/Animals/crab.rsi state: crab - - From 9a769d8ee619d12ada848aa86ee4e64e7af97d0c Mon Sep 17 00:00:00 2001 From: Kanashi-Panda Date: Mon, 16 Sep 2024 17:35:57 -0700 Subject: [PATCH 050/138] Crayons buffed to 45 uses (#32061) * Buffs crayons to 45 uses * Update Resources/Prototypes/Entities/Objects/Fun/crayons.yml Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- Resources/Prototypes/Entities/Objects/Fun/crayons.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml index ffecfdf9940..3c4a4800a87 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/crayons.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/crayons.yml @@ -21,7 +21,7 @@ enum.CrayonUiKey.Key: type: CrayonBoundUserInterface - type: Crayon - capacity: 15 + capacity: 25 - type: Food - type: FlavorProfile flavors: From 1726338acad538824236220edb171ae4110cecb6 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 17 Sep 2024 00:37:05 +0000 Subject: [PATCH 051/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 9afdf08d174..1df9fae6ee9 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Errant - changes: - - message: Vox now have their entry in the guidebook. - type: Fix - id: 6886 - time: '2024-07-09T00:28:33.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29713 - author: Whisper changes: - message: Light toggle actions now have a 1 second cooldown between uses. @@ -3878,3 +3871,10 @@ id: 7385 time: '2024-09-16T12:45:15.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32147 +- author: Alice Liddel + changes: + - message: Crayon charges increased from 15 to 25 + type: Add + id: 7386 + time: '2024-09-17T00:35:57.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32061 From dd701436ab2eb4e7d6b4b9598034fa47261cc9ac Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:49:19 +0300 Subject: [PATCH 052/138] Anomalous infections (#31876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * inner anomaly * anomaly pulse action * test anom mine * Update anomalies.yml * fix action cooldown * pyro_eyes * clientsystem * experiments * blya * some telegraphy * shock eyes! * shadow eyes * separate files * frosty eyes * fix * flora eyes * bluespace eyes * flesh eyes * redoing injction * auto add layers * пипяу * new injector component * stupid me * nice marker injectors * anomaly spawn on shutdown * gravity anom * dead anomaly spawning * add VOX states * sprite specific layers support * technology anom infection * auto detach anomalies that have moved away * Update anomaly_injections.yml * anomalyspawner integration * rock anomaly! * Update anomaly_injections.yml * fix crash bug * tag filter * fix anom dublication spawns * Update anomaly.yml * Update InnerBodyAnomalyComponent.cs * Update anomaly_injections.yml * dont spawn anomalies after decay * fix morb sprite, add end message * gravity resprite * admin logging, double injection fix * make flesh and living light mobs friendly to anomaly hosts * popups * severity feedback * sloth review * A * keep organs after gib * punpun host * sloth synchronization * Update arachnid.yml * increase infections spawnrate --- .../Anomaly/Effects/ClientInnerBodySystem.cs | 50 ++ .../Anomaly/AnomalySynchronizerSystem.cs | 44 +- .../Anomaly/AnomalySystem.Psionics.cs | 10 +- Content.Server/Anomaly/AnomalySystem.cs | 6 +- .../AnomalySynchronizerComponent.cs | 11 +- .../Anomaly/Effects/InnerBodyAnomalySystem.cs | 236 +++++++ .../Explosion/EntitySystems/TriggerSystem.cs | 3 +- .../Anomaly/Components/AnomalyComponent.cs | 15 +- .../Components/InnerBodyAnomalyComponent.cs | 72 ++ .../InnerBodyAnomalyInjectorComponent.cs | 21 + .../Effects/SharedInnerBodyAnomalySystem.cs | 5 + Content.Shared/Anomaly/SharedAnomalySystem.cs | 21 +- Resources/Audio/Effects/attributions.yml | 5 + Resources/Audio/Effects/inneranomaly.ogg | Bin 0 -> 46892 bytes .../Locale/en-US/anomaly/inner_anomaly.ftl | 17 + Resources/Prototypes/Actions/anomaly.yml | 9 + .../Markers/Spawners/Random/anomaly.yml | 33 +- .../Prototypes/Entities/Mobs/NPCs/animals.yml | 1 + .../Prototypes/Entities/Mobs/NPCs/flesh.yml | 7 +- .../Entities/Mobs/NPCs/living_light.yml | 5 + .../Prototypes/Entities/Mobs/NPCs/pets.yml | 1 + .../Entities/Mobs/Species/arachnid.yml | 1 + .../Prototypes/Entities/Mobs/Species/base.yml | 1 + .../Structures/Specific/Anomaly/anomalies.yml | 3 +- .../Specific/Anomaly/anomaly_injections.yml | 353 ++++++++++ .../Specific/Anomaly/anomaly_injectors.yml | 320 +++++++++ Resources/Prototypes/tags.yml | 3 + .../inner_anom_layer.rsi/bluespace.png | Bin 0 -> 864 bytes .../inner_anom_layer.rsi/bluespace_VOX.png | Bin 0 -> 1031 bytes .../Anomalies/inner_anom_layer.rsi/fire.png | Bin 0 -> 1007 bytes .../inner_anom_layer.rsi/fire_VOX.png | Bin 0 -> 1514 bytes .../Anomalies/inner_anom_layer.rsi/flesh.png | Bin 0 -> 1342 bytes .../inner_anom_layer.rsi/flesh_VOX.png | Bin 0 -> 1385 bytes .../Anomalies/inner_anom_layer.rsi/flora.png | Bin 0 -> 1868 bytes .../inner_anom_layer.rsi/flora_VOX.png | Bin 0 -> 1952 bytes .../Anomalies/inner_anom_layer.rsi/frost.png | Bin 0 -> 2650 bytes .../inner_anom_layer.rsi/frost_VOX.png | Bin 0 -> 2718 bytes .../Anomalies/inner_anom_layer.rsi/grav.png | Bin 0 -> 2837 bytes .../inner_anom_layer.rsi/grav_VOX.png | Bin 0 -> 3405 bytes .../Anomalies/inner_anom_layer.rsi/meta.json | 643 ++++++++++++++++++ .../Anomalies/inner_anom_layer.rsi/rock.png | Bin 0 -> 1398 bytes .../inner_anom_layer.rsi/rock_VOX.png | Bin 0 -> 1398 bytes .../Anomalies/inner_anom_layer.rsi/shadow.png | Bin 0 -> 768 bytes .../inner_anom_layer.rsi/shadow_VOX.png | Bin 0 -> 1002 bytes .../Anomalies/inner_anom_layer.rsi/shock.png | Bin 0 -> 879 bytes .../inner_anom_layer.rsi/shock_VOX.png | Bin 0 -> 2083 bytes .../Anomalies/inner_anom_layer.rsi/tech.png | Bin 0 -> 1241 bytes .../inner_anom_layer.rsi/tech_VOX.png | Bin 0 -> 1244 bytes .../Specific/anomaly.rsi/anom5-pulse.png | Bin 1195 -> 1252 bytes .../Structures/Specific/anomaly.rsi/anom5.png | Bin 429 -> 513 bytes 50 files changed, 1865 insertions(+), 31 deletions(-) create mode 100644 Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs create mode 100644 Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs create mode 100644 Content.Shared/Anomaly/Components/InnerBodyAnomalyComponent.cs create mode 100644 Content.Shared/Anomaly/Components/InnerBodyAnomalyInjectorComponent.cs create mode 100644 Content.Shared/Anomaly/Effects/SharedInnerBodyAnomalySystem.cs create mode 100644 Resources/Audio/Effects/inneranomaly.ogg create mode 100644 Resources/Locale/en-US/anomaly/inner_anomaly.ftl create mode 100644 Resources/Prototypes/Actions/anomaly.yml create mode 100644 Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomaly_injections.yml create mode 100644 Resources/Prototypes/Entities/Structures/Specific/Anomaly/anomaly_injectors.yml create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/bluespace.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/bluespace_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/fire.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/fire_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flesh.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flesh_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flora.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flora_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/frost.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/frost_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/grav.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/grav_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/meta.json create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/rock.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/rock_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shadow.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shadow_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shock.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shock_VOX.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/tech.png create mode 100644 Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/tech_VOX.png diff --git a/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs new file mode 100644 index 00000000000..efb1a8d46e8 --- /dev/null +++ b/Content.Client/Anomaly/Effects/ClientInnerBodySystem.cs @@ -0,0 +1,50 @@ +using Content.Shared.Anomaly.Components; +using Content.Shared.Anomaly.Effects; +using Content.Shared.Body.Components; +using Robust.Client.GameObjects; + +namespace Content.Client.Anomaly.Effects; + +public sealed class ClientInnerBodyAnomalySystem : SharedInnerBodyAnomalySystem +{ + public override void Initialize() + { + SubscribeLocalEvent(OnAfterHandleState); + SubscribeLocalEvent(OnCompShutdown); + } + + private void OnAfterHandleState(Entity ent, ref AfterAutoHandleStateEvent args) + { + if (!TryComp(ent, out var sprite)) + return; + + if (ent.Comp.FallbackSprite is null) + return; + + if (!sprite.LayerMapTryGet(ent.Comp.LayerMap, out var index)) + index = sprite.LayerMapReserveBlank(ent.Comp.LayerMap); + + if (TryComp(ent, out var body) && + body.Prototype is not null && + ent.Comp.SpeciesSprites.TryGetValue(body.Prototype.Value, out var speciesSprite)) + { + sprite.LayerSetSprite(index, speciesSprite); + } + else + { + sprite.LayerSetSprite(index, ent.Comp.FallbackSprite); + } + + sprite.LayerSetVisible(index, true); + sprite.LayerSetShader(index, "unshaded"); + } + + private void OnCompShutdown(Entity ent, ref ComponentShutdown args) + { + if (!TryComp(ent, out var sprite)) + return; + + var index = sprite.LayerMapGet(ent.Comp.LayerMap); + sprite.LayerSetVisible(index, false); + } +} diff --git a/Content.Server/Anomaly/AnomalySynchronizerSystem.cs b/Content.Server/Anomaly/AnomalySynchronizerSystem.cs index 59ef08402ee..b1814c2741d 100644 --- a/Content.Server/Anomaly/AnomalySynchronizerSystem.cs +++ b/Content.Server/Anomaly/AnomalySynchronizerSystem.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Numerics; using Content.Server.Anomaly.Components; using Content.Server.DeviceLinking.Systems; using Content.Server.Power.Components; @@ -10,6 +11,7 @@ using Content.Shared.Power; using Robust.Shared.Audio.Systems; using Content.Shared.Verbs; +using Robust.Shared.Timing; namespace Content.Server.Anomaly; @@ -25,6 +27,7 @@ public sealed partial class AnomalySynchronizerSystem : EntitySystem [Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly PowerReceiverSystem _power = default!; + [Dependency] private readonly IGameTiming _timing = default!; public override void Initialize() { @@ -40,6 +43,34 @@ public override void Initialize() SubscribeLocalEvent(OnAnomalyStabilityChanged); } + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var sync, out var xform)) + { + if (sync.ConnectedAnomaly is null) + continue; + + if (_timing.CurTime < sync.NextCheckTime) + continue; + sync.NextCheckTime += sync.CheckFrequency; + + if (Transform(sync.ConnectedAnomaly.Value).MapUid != Transform(uid).MapUid) + { + DisconnectFromAnomaly((uid, sync), sync.ConnectedAnomaly.Value); + continue; + } + + if (!xform.Coordinates.TryDistance(EntityManager, Transform(sync.ConnectedAnomaly.Value).Coordinates, out var distance)) + continue; + + if (distance > sync.AttachRange) + DisconnectFromAnomaly((uid, sync), sync.ConnectedAnomaly.Value); + } + } + /// /// If powered, try to attach a nearby anomaly. /// @@ -73,10 +104,10 @@ private void OnPowerChanged(Entity ent, ref PowerC if (args.Powered) return; - if (!TryComp(ent.Comp.ConnectedAnomaly, out var anomaly)) + if (ent.Comp.ConnectedAnomaly is null) return; - DisconnectFromAnomaly(ent, anomaly); + DisconnectFromAnomaly(ent, ent.Comp.ConnectedAnomaly.Value); } private void OnExamined(Entity ent, ref ExaminedEvent args) @@ -125,13 +156,16 @@ private void ConnectToAnomaly(Entity ent, Entity ent, AnomalyComponent anomaly) + private void DisconnectFromAnomaly(Entity ent, EntityUid other) { if (ent.Comp.ConnectedAnomaly == null) return; - if (ent.Comp.PulseOnDisconnect) - _anomaly.DoAnomalyPulse(ent.Comp.ConnectedAnomaly.Value, anomaly); + if (TryComp(other, out var anomaly)) + { + if (ent.Comp.PulseOnDisconnect) + _anomaly.DoAnomalyPulse(ent.Comp.ConnectedAnomaly.Value, anomaly); + } _popup.PopupEntity(Loc.GetString("anomaly-sync-disconnected"), ent, PopupType.Large); _audio.PlayPvs(ent.Comp.ConnectedSound, ent); diff --git a/Content.Server/Anomaly/AnomalySystem.Psionics.cs b/Content.Server/Anomaly/AnomalySystem.Psionics.cs index ea15a8ab624..c42eb1c58fd 100644 --- a/Content.Server/Anomaly/AnomalySystem.Psionics.cs +++ b/Content.Server/Anomaly/AnomalySystem.Psionics.cs @@ -1,4 +1,4 @@ -using Content.Server.Abilities.Psionics; //Nyano - Summary: the psniocs bin where dispel is located. +using Content.Server.Abilities.Psionics; using Content.Shared.Anomaly; using Content.Shared.Anomaly.Components; using Robust.Shared.Random; @@ -7,18 +7,18 @@ namespace Content.Server.Anomaly; public sealed partial class AnomalySystem { - [Dependency] private readonly SharedAnomalySystem _sharedAnomaly = default!; [Dependency] private readonly DispelPowerSystem _dispel = default!; + private void InitializePsionics() { SubscribeLocalEvent(OnDispelled); } //Nyano - Summary: gives dispellable behavior to Anomalies. - private void OnDispelled(EntityUid uid, AnomalyComponent component, DispelledEvent args) + private void OnDispelled(Entity ent, ref DispelledEvent args) { - _dispel.DealDispelDamage(uid); - _sharedAnomaly.ChangeAnomalyHealth(uid, 0 - _random.NextFloat(0.4f, 0.8f), component); + _dispel.DealDispelDamage(ent); + ChangeAnomalyHealth(ent, 0 - _random.NextFloat(0.4f, 0.8f), ent.Comp); args.Handled = true; } } diff --git a/Content.Server/Anomaly/AnomalySystem.cs b/Content.Server/Anomaly/AnomalySystem.cs index 4b6cdd2beae..75ad47ad83b 100644 --- a/Content.Server/Anomaly/AnomalySystem.cs +++ b/Content.Server/Anomaly/AnomalySystem.cs @@ -56,6 +56,7 @@ public override void Initialize() SubscribeLocalEvent(OnStartCollide); InitializePsionics(); //Nyano - Summary: stats up psionic related behavior. + InitializeGenerator(); InitializeScanner(); InitializeVessel(); @@ -87,7 +88,10 @@ public void ShuffleParticlesEffect(Entity anomaly) private void OnShutdown(Entity anomaly, ref ComponentShutdown args) { - EndAnomaly(anomaly); + if (anomaly.Comp.CurrentBehavior is not null) + RemoveBehavior(anomaly, anomaly.Comp.CurrentBehavior.Value); + + EndAnomaly(anomaly, spawnCore: false); } private void OnStartCollide(Entity anomaly, ref StartCollideEvent args) diff --git a/Content.Server/Anomaly/Components/AnomalySynchronizerComponent.cs b/Content.Server/Anomaly/Components/AnomalySynchronizerComponent.cs index 235e740cf35..3127f091e55 100644 --- a/Content.Server/Anomaly/Components/AnomalySynchronizerComponent.cs +++ b/Content.Server/Anomaly/Components/AnomalySynchronizerComponent.cs @@ -7,7 +7,7 @@ namespace Content.Server.Anomaly.Components; /// /// a device that allows you to translate anomaly activity into multitool signals. /// -[RegisterComponent, Access(typeof(AnomalySynchronizerSystem))] +[RegisterComponent, AutoGenerateComponentPause, Access(typeof(AnomalySynchronizerSystem))] public sealed partial class AnomalySynchronizerComponent : Component { /// @@ -34,6 +34,15 @@ public sealed partial class AnomalySynchronizerComponent : Component [DataField] public float AttachRange = 0.4f; + /// + /// Periodicheski checks to see if the anomaly has moved to disconnect it. + /// + [DataField] + public TimeSpan CheckFrequency = TimeSpan.FromSeconds(1f); + + [DataField, AutoPausedField] + public TimeSpan NextCheckTime = TimeSpan.Zero; + [DataField] public ProtoId DecayingPort = "Decaying"; diff --git a/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs b/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs new file mode 100644 index 00000000000..38c4c51d874 --- /dev/null +++ b/Content.Server/Anomaly/Effects/InnerBodyAnomalySystem.cs @@ -0,0 +1,236 @@ +using Content.Server.Administration.Logs; +using Content.Server.Body.Systems; +using Content.Server.Chat.Managers; +using Content.Server.Jittering; +using Content.Server.Mind; +using Content.Server.Stunnable; +using Content.Shared.Actions; +using Content.Shared.Anomaly; +using Content.Shared.Anomaly.Components; +using Content.Shared.Anomaly.Effects; +using Content.Shared.Body.Components; +using Content.Shared.Chat; +using Content.Shared.Database; +using Content.Shared.Mobs; +using Content.Shared.Popups; +using Content.Shared.Whitelist; +using Robust.Shared.Audio.Systems; +using Robust.Shared.Physics.Events; +using Robust.Shared.Prototypes; + +namespace Content.Server.Anomaly.Effects; + +public sealed class InnerBodyAnomalySystem : SharedInnerBodyAnomalySystem +{ + [Dependency] private readonly IAdminLogManager _adminLog = default!; + [Dependency] private readonly AnomalySystem _anomaly = default!; + [Dependency] private readonly ActionContainerSystem _actionContainer = default!; + [Dependency] private readonly SharedActionsSystem _actions = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + [Dependency] private readonly BodySystem _body = default!; + [Dependency] private readonly IChatManager _chat = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; + [Dependency] private readonly JitteringSystem _jitter = default!; + [Dependency] private readonly MindSystem _mind = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly StunSystem _stun = default!; + + private readonly Color _messageColor = Color.FromSrgb(new Color(201, 22, 94)); + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnStartCollideInjector); + + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnCompShutdown); + + SubscribeLocalEvent(OnAnomalyPulse); + SubscribeLocalEvent(OnAnomalyShutdown); + SubscribeLocalEvent(OnAnomalySupercritical); + SubscribeLocalEvent(OnSeverityChanged); + + SubscribeLocalEvent(OnMobStateChanged); + + SubscribeLocalEvent(OnActionPulse); + } + + private void OnActionPulse(Entity ent, ref ActionAnomalyPulseEvent args) + { + if (args.Handled) + return; + + _anomaly.DoAnomalyPulse(ent, ent.Comp); + + args.Handled = true; + } + + private void OnStartCollideInjector(Entity ent, ref StartCollideEvent args) + { + if (ent.Comp.Whitelist is not null && !_whitelist.IsValid(ent.Comp.Whitelist, args.OtherEntity)) + return; + if (TryComp(args.OtherEntity, out var innerAnom) && innerAnom.Injected) + return; + if (!_mind.TryGetMind(args.OtherEntity, out _, out var mindComponent)) + return; + + EntityManager.AddComponents(args.OtherEntity, ent.Comp.InjectionComponents); + QueueDel(ent); + } + + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + AddAnomalyToBody(ent); + } + + private void AddAnomalyToBody(Entity ent) + { + if (!_proto.TryIndex(ent.Comp.InjectionProto, out var injectedAnom)) + return; + + if (ent.Comp.Injected) + return; + + ent.Comp.Injected = true; + + EntityManager.AddComponents(ent, injectedAnom.Components); + + _stun.TryParalyze(ent, TimeSpan.FromSeconds(ent.Comp.StunDuration), true); + _jitter.DoJitter(ent, TimeSpan.FromSeconds(ent.Comp.StunDuration), true); + + if (ent.Comp.StartSound is not null) + _audio.PlayPvs(ent.Comp.StartSound, ent); + + if (ent.Comp.StartMessage is not null && + _mind.TryGetMind(ent, out _, out var mindComponent) && + mindComponent.Session != null) + { + var message = Loc.GetString(ent.Comp.StartMessage); + var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message)); + _chat.ChatMessageToOne(ChatChannel.Server, + message, + wrappedMessage, + default, + false, + mindComponent.Session.Channel, + _messageColor); + + _popup.PopupEntity(message, ent, ent, PopupType.MediumCaution); + + _adminLog.Add(LogType.Anomaly,LogImpact.Extreme,$"{ToPrettyString(ent)} became anomaly host."); + } + Dirty(ent); + } + + private void OnAnomalyPulse(Entity ent, ref AnomalyPulseEvent args) + { + _stun.TryParalyze(ent, TimeSpan.FromSeconds(ent.Comp.StunDuration / 2 * args.Severity), true); + _jitter.DoJitter(ent, TimeSpan.FromSeconds(ent.Comp.StunDuration / 2 * args.Severity), true); + } + + private void OnAnomalySupercritical(Entity ent, ref AnomalySupercriticalEvent args) + { + if (!TryComp(ent, out var body)) + return; + + _body.GibBody(ent, true, body, splatModifier: 5f); + } + + private void OnSeverityChanged(Entity ent, ref AnomalySeverityChangedEvent args) + { + if (!_mind.TryGetMind(ent, out _, out var mindComponent) || mindComponent.Session == null) + return; + + var message = string.Empty; + + if (args.Severity >= 0.5 && ent.Comp.LastSeverityInformed < 0.5) + { + ent.Comp.LastSeverityInformed = 0.5f; + message = Loc.GetString("inner-anomaly-severity-info-50"); + } + if (args.Severity >= 0.75 && ent.Comp.LastSeverityInformed < 0.75) + { + ent.Comp.LastSeverityInformed = 0.75f; + message = Loc.GetString("inner-anomaly-severity-info-75"); + } + if (args.Severity >= 0.9 && ent.Comp.LastSeverityInformed < 0.9) + { + ent.Comp.LastSeverityInformed = 0.9f; + message = Loc.GetString("inner-anomaly-severity-info-90"); + } + if (args.Severity >= 1 && ent.Comp.LastSeverityInformed < 1) + { + ent.Comp.LastSeverityInformed = 1f; + message = Loc.GetString("inner-anomaly-severity-info-100"); + } + + if (message == string.Empty) + return; + + var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message)); + _chat.ChatMessageToOne(ChatChannel.Server, + message, + wrappedMessage, + default, + false, + mindComponent.Session.Channel, + _messageColor); + + _popup.PopupEntity(message, ent, ent, PopupType.MediumCaution); + } + + private void OnMobStateChanged(Entity ent, ref MobStateChangedEvent args) + { + if (args.NewMobState != MobState.Dead) + return; + + _anomaly.ChangeAnomalyHealth(ent, -2); //Shutdown it + } + + private void OnAnomalyShutdown(Entity ent, ref AnomalyShutdownEvent args) + { + RemoveAnomalyFromBody(ent); + RemCompDeferred(ent); + } + + private void OnCompShutdown(Entity ent, ref ComponentShutdown args) + { + RemoveAnomalyFromBody(ent); + } + + private void RemoveAnomalyFromBody(Entity ent) + { + if (!ent.Comp.Injected) + return; + + if (_proto.TryIndex(ent.Comp.InjectionProto, out var injectedAnom)) + EntityManager.RemoveComponents(ent, injectedAnom.Components); + + _stun.TryParalyze(ent, TimeSpan.FromSeconds(ent.Comp.StunDuration), true); + + if (ent.Comp.EndMessage is not null && + _mind.TryGetMind(ent, out _, out var mindComponent) && + mindComponent.Session != null) + { + var message = Loc.GetString(ent.Comp.EndMessage); + var wrappedMessage = Loc.GetString("chat-manager-server-wrap-message", ("message", message)); + _chat.ChatMessageToOne(ChatChannel.Server, + message, + wrappedMessage, + default, + false, + mindComponent.Session.Channel, + _messageColor); + + + _popup.PopupEntity(message, ent, ent, PopupType.MediumCaution); + + _adminLog.Add(LogType.Anomaly, LogImpact.Medium,$"{ToPrettyString(ent)} is no longer a host for the anomaly."); + } + + ent.Comp.Injected = false; + RemCompDeferred(ent); + } +} diff --git a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs index 853b4fbc29d..57847551aa7 100644 --- a/Content.Server/Explosion/EntitySystems/TriggerSystem.cs +++ b/Content.Server/Explosion/EntitySystems/TriggerSystem.cs @@ -202,6 +202,7 @@ private void HandleGibTrigger(EntityUid uid, GibOnTriggerComponent component, Tr args.Handled = true; } + private void HandleRattleTrigger(EntityUid uid, RattleComponent component, TriggerEvent args) { if (!TryComp(uid, out var implanted)) @@ -230,7 +231,7 @@ private void HandleRattleTrigger(EntityUid uid, RattleComponent component, Trigg private void OnTriggerCollide(EntityUid uid, TriggerOnCollideComponent component, ref StartCollideEvent args) { if (args.OurFixtureId == component.FixtureID && (!component.IgnoreOtherNonHard || args.OtherFixture.Hard)) - Trigger(uid); + Trigger(uid, args.OtherEntity); } private void OnSpawnTriggered(EntityUid uid, TriggerOnSpawnComponent component, MapInitEvent args) diff --git a/Content.Shared/Anomaly/Components/AnomalyComponent.cs b/Content.Shared/Anomaly/Components/AnomalyComponent.cs index 724dfd38d2f..e6228b5fb0d 100644 --- a/Content.Shared/Anomaly/Components/AnomalyComponent.cs +++ b/Content.Shared/Anomaly/Components/AnomalyComponent.cs @@ -1,6 +1,6 @@ using System.Numerics; +using Content.Shared.Anomaly.Effects; using Content.Shared.Anomaly.Prototypes; -using Content.Shared.Damage; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; @@ -16,7 +16,7 @@ namespace Content.Shared.Anomaly.Components; /// Anomalies and their related components were designed here: https://hackmd.io/@ss14-design/r1sQbkJOs /// [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause] -[Access(typeof(SharedAnomalySystem))] +[Access(typeof(SharedAnomalySystem), typeof(SharedInnerBodyAnomalySystem))] public sealed partial class AnomalyComponent : Component { /// @@ -184,21 +184,21 @@ public sealed partial class AnomalyComponent : Component /// /// The minimum amount of research points generated per second /// - [DataField("minPointsPerSecond")] + [DataField] public int MinPointsPerSecond = 10; /// /// The maximum amount of research points generated per second /// This doesn't include the point bonus for being unstable. /// - [DataField("maxPointsPerSecond")] + [DataField] public int MaxPointsPerSecond = 70; /// /// The multiplier applied to the point value for the /// anomaly being above the /// - [DataField("growingPointMultiplier")] + [DataField] public float GrowingPointMultiplier = 1.5f; #endregion @@ -252,10 +252,13 @@ public sealed partial class AnomalyComponent : Component /// [ViewVariables(VVAccess.ReadWrite)] [DataField("offset")] - public Vector2 FloatingOffset = new(0, 0.15f); + public Vector2 FloatingOffset = new(0, 0); public readonly string AnimationKey = "anomalyfloat"; #endregion + + [DataField] + public bool DeleteEntity = true; } /// diff --git a/Content.Shared/Anomaly/Components/InnerBodyAnomalyComponent.cs b/Content.Shared/Anomaly/Components/InnerBodyAnomalyComponent.cs new file mode 100644 index 00000000000..e88cedb18ef --- /dev/null +++ b/Content.Shared/Anomaly/Components/InnerBodyAnomalyComponent.cs @@ -0,0 +1,72 @@ +using Content.Shared.Anomaly.Effects; +using Content.Shared.Body.Prototypes; +using Robust.Shared.Audio; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; + +namespace Content.Shared.Anomaly.Components; + +/// +/// An anomaly within the body of a living being. Controls the ability to return to the standard state. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true), Access(typeof(SharedInnerBodyAnomalySystem))] +public sealed partial class InnerBodyAnomalyComponent : Component +{ + [DataField] + public bool Injected; + + /// + /// A prototype of an entity whose components will be added to the anomaly host **AND** then removed at the right time + /// + [DataField(required: true)] + public EntProtoId? InjectionProto; + + /// + /// Duration of stun from the effect of the anomaly + /// + [DataField] + public float StunDuration = 4f; + + /// + /// A message sent in chat to a player who has become infected by an anomaly + /// + [DataField] + public LocId? StartMessage = null; + + /// + /// A message sent in chat to a player who has cleared an anomaly + /// + [DataField] + public LocId? EndMessage = "inner-anomaly-end-message"; + + /// + /// Sound, playing on becoming anomaly + /// + [DataField] + public SoundSpecifier? StartSound = new SoundPathSpecifier("/Audio/Effects/inneranomaly.ogg"); + + /// + /// Used to display messages to the player about their level of disease progression + /// + [DataField] + public float LastSeverityInformed = 0f; + + /// + /// The fallback sprite to be added on the original entity. Allows you to visually identify the feature and type of anomaly to other players + /// + [DataField, AutoNetworkedField] + public SpriteSpecifier? FallbackSprite = null; + + /// + /// Ability to use unique sprites for different body types + /// + [DataField, AutoNetworkedField] + public Dictionary, SpriteSpecifier> SpeciesSprites = new(); + + /// + /// The key of the entity layer into which the sprite will be inserted + /// + [DataField] + public string LayerMap = "inner_anomaly_layer"; +} diff --git a/Content.Shared/Anomaly/Components/InnerBodyAnomalyInjectorComponent.cs b/Content.Shared/Anomaly/Components/InnerBodyAnomalyInjectorComponent.cs new file mode 100644 index 00000000000..e4c398c9cc5 --- /dev/null +++ b/Content.Shared/Anomaly/Components/InnerBodyAnomalyInjectorComponent.cs @@ -0,0 +1,21 @@ +using Content.Shared.Anomaly.Effects; +using Content.Shared.Whitelist; +using Robust.Shared.Prototypes; + +namespace Content.Shared.Anomaly.Components; + +/// +/// On contact with an entity, if it meets the conditions, it will transfer the specified components to it +/// +[RegisterComponent, Access(typeof(SharedInnerBodyAnomalySystem))] +public sealed partial class InnerBodyAnomalyInjectorComponent : Component +{ + [DataField] + public EntityWhitelist? Whitelist; + + /// + /// components that will be automatically removed after “curing” + /// + [DataField(required: true)] + public ComponentRegistry InjectionComponents = default!; +} diff --git a/Content.Shared/Anomaly/Effects/SharedInnerBodyAnomalySystem.cs b/Content.Shared/Anomaly/Effects/SharedInnerBodyAnomalySystem.cs new file mode 100644 index 00000000000..a1ec7cd3973 --- /dev/null +++ b/Content.Shared/Anomaly/Effects/SharedInnerBodyAnomalySystem.cs @@ -0,0 +1,5 @@ +namespace Content.Shared.Anomaly.Effects; + +public abstract class SharedInnerBodyAnomalySystem : EntitySystem +{ +} diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index c3d6591b725..9a0cde29988 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -1,13 +1,10 @@ using Content.Shared.Administration.Logs; using Content.Shared.Anomaly.Components; using Content.Shared.Anomaly.Prototypes; -using Content.Shared.Damage; using Content.Shared.Database; -using Content.Shared.Interaction; using Content.Shared.Physics; using Content.Shared.Popups; using Content.Shared.Weapons.Melee.Components; -using Content.Shared.Weapons.Melee.Events; using Robust.Shared.Audio.Systems; using Robust.Shared.Map; using Robust.Shared.Map.Components; @@ -21,6 +18,7 @@ using Robust.Shared.Utility; using System.Linq; using System.Numerics; +using Content.Shared.Actions; namespace Content.Shared.Anomaly; @@ -36,6 +34,7 @@ public abstract class SharedAnomalySystem : EntitySystem [Dependency] protected readonly SharedPopupSystem Popup = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; public override void Initialize() { @@ -145,7 +144,7 @@ public void DoAnomalySupercriticalEvent(EntityUid uid, AnomalyComponent? compone if (!Timing.IsFirstTimePredicted) return; - Audio.PlayPvs(component.SupercriticalSound, uid); + Audio.PlayPvs(component.SupercriticalSound, Transform(uid).Coordinates); if (_net.IsServer) Log.Info($"Raising supercritical event. Entity: {ToPrettyString(uid)}"); @@ -169,7 +168,8 @@ public void DoAnomalySupercriticalEvent(EntityUid uid, AnomalyComponent? compone /// The anomaly being shut down /// /// Whether or not the anomaly ended via supercritical event - public void EndAnomaly(EntityUid uid, AnomalyComponent? component = null, bool supercritical = false) + /// Create anomaly cores based on the result of completing an anomaly? + public void EndAnomaly(EntityUid uid, AnomalyComponent? component = null, bool supercritical = false, bool spawnCore = true) { // Logging before resolve, in case the anomaly has deleted itself. if (_net.IsServer) @@ -186,9 +186,14 @@ public void EndAnomaly(EntityUid uid, AnomalyComponent? component = null, bool s if (Terminating(uid) || _net.IsClient) return; - Spawn(supercritical ? component.CorePrototype : component.CoreInertPrototype, Transform(uid).Coordinates); + if (spawnCore) + { + var core = Spawn(supercritical ? component.CorePrototype : component.CoreInertPrototype, Transform(uid).Coordinates); + _transform.PlaceNextTo(core, uid); + } - QueueDel(uid); + if (component.DeleteEntity) + QueueDel(uid); } /// @@ -458,3 +463,5 @@ public partial record struct AnomalySpawnSettings() /// public bool SpawnOnSeverityChanged { get; set; } = false; } + +public sealed partial class ActionAnomalyPulseEvent : InstantActionEvent { } diff --git a/Resources/Audio/Effects/attributions.yml b/Resources/Audio/Effects/attributions.yml index 6f18510d17b..75cf22aa4fe 100644 --- a/Resources/Audio/Effects/attributions.yml +++ b/Resources/Audio/Effects/attributions.yml @@ -231,3 +231,8 @@ copyright: '"beep_landmine.ogg" by kaktuscsc of Discord for SS14' license: "CC-BY-SA-3.0" source: https://github.com/YuriyKiss/space-station-14/commit/971a135a9c83aed46e967aac9302ab5b35562b5f + +- files: [inneranomaly.ogg] + copyright: 'created by waveplaySFX on Freesound' + license: "CC0-1.0" + source: https://freesound.org/people/waveplaySFX/sounds/553744/ diff --git a/Resources/Audio/Effects/inneranomaly.ogg b/Resources/Audio/Effects/inneranomaly.ogg new file mode 100644 index 0000000000000000000000000000000000000000..43fc40357f2035e44587498af0aa886803b2ec5a GIT binary patch literal 46892 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 y?bC{%Tv^7p@8wU literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/fire.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/fire.png new file mode 100644 index 0000000000000000000000000000000000000000..a6fcde7a1841bc5fd50326ba2b168d9dd61b3735 GIT binary patch literal 1007 zcmeAS@N?(olHy`uVBq!ia0vp^3xK$RgAGXbBqvD&DaPU;cPEB*=VV?oFfgz5ba4!+ znDh3|`8?rpiDM718y`}20|$MvXa$f_HT ztu0qHoF;TkS&{kXNX4N9v3ZVRn^)RSHZJ{Cy+rxuD$D07O~;`8P)UU)7$gY^^Q-Pbn4h;Z~cb1Zec;bb*e_%i8pZ#HWxbgPO zZ@lvzmVV8@vp>*$?uEA5Z*x^Azl@)^w?rWR&ClnV2bev}RrgNZvdiO#(xJ6|Dw$6o zF0VkH6pl`SN?r^ZCme+l{Zwm^o;lo~66vwD<>? zpf{2KZ*1OoMNd6m_3Hon3H-qHKr$#;8T5^9+TGXg(fgL*EexUeY|or^M<=8yjFRx^0u06;x&Eo zpSG!2dic-tz4`ui-I9gNd|$ZS{Ca+N{1Mp=SF9Vtjl+UW>dH5X-^se`w|TBm=dF3%FOfK)$<=yo$Zr+m?ZDD-N-)sJ{ z{qnlcyi;QS@A>I!lCUWA`ubHZ-{tj9HZF1e^ReVE_t}{;cK=i~UzjHQ%I{wNGJW|^ zt)2fWKLd?TNwXCG5*7JvMNiGtKfh11V-Kg8%ropUO5ufK4=98a}O+?=Q>?{Ge`IO|BHAl mbki>yc5nDngUy`}_#DXiF)u5*PpgDXXhU z`~9TuAO4{Dz9)FzQQi-c2lkc-puAgU1^~opR>;dY9%at6yMn%=6vVk$Z$ahQC%+=! z420w*WHC$ZSnR>yB=qaZoCA_UqDK1N@i4B^5#qfcc3L!4p;}F$1gpc349))H%z6_D zjpK14sBz2httUER<3Btz@4@kLad9ZM-`7F!Ax0xrCZ z*Afv#O!o%}vzZ`Rz&NrWC2vGm(p`NZ0Prc|38QZ((N19zf-B^>`xo0nMhc{jAM@tI z9V9I=I{xz$)rRy$|`BDneVhp8PBf&XJ9UM{vJ7)X!7({L;h-TI)BI|^q{5n zppwmc%*odZk1tZ`H~KoUqb+3?pCl|%4mY(-98cLWDm94{slR{K&P^v~7>x&ip)i%C zo?W^6#$Pz7_VQlF?pp#`yh97ptb!NL>@@7PZ<`OD>U3KjMS#$SfuE&0fB+@eBwUS;7`I)ae*97>+Zb6bsbI}>e%6y2F3Qizw082T_(orZVMCcgMM zhs~@I)iKVv+Wa?h8GIR{4cUoL=H=K^sj%+7d_i}7 zoRo*XSYo|Qy-CZBt)AKv?Rfcy3hA(ijH)1VpE}wo=S5^D9H7-#)-BUsX!oua%aKYE zalPq6Peo|b*x0Pxt0tGe)+EX0-M-k_`MiAa+8f*^btQLO-^M&o&sY{^APj@oGHN!Y zU>6L*{^o$*hj)VXNe}LLY0d4jDuP%xLr+%~Y!0YdFKW_s>|`eTvDG01t^Zh~0H?lD zgE`qM14dM{ODkdKJLI;yD@u`QZT)9{LEZ5KA2 zji@pxWWE_&VePn<=|Ck)_WPzXzoeM}T!@kFWj>GrhwqS9L{vb&G-12$(pJH0mJ_s! zjEufM1G}PY2#=DSa4Ts8jwB6I;6%ie7=;uJ7Y!lgp(ju+=R!|=yAG+X%>CA?u z3EAy_=w|zUb{|mG3tdpVpS=Zj0KK||UCilbFl~z-NF=T7LrQO1f7hO&vS4wUd^mal q&t=oE!LUcCdT>8!{Hr!Cwk1g;k`7OgrHbr7Z@|g|jVwpp{^Kw7SjNf# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flesh.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flesh.png new file mode 100644 index 0000000000000000000000000000000000000000..6e178307c33ea27caa13f9978a8337668a3eb2fe GIT binary patch literal 1342 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flora.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flora.png new file mode 100644 index 0000000000000000000000000000000000000000..70e369cb02ba37b76aea647060974a8a7517d27e GIT binary patch literal 1868 zcmZuxc{JOJ7WQfwr3TLsOO$3>wU**YDPsC8%~2FnM3FwNtudCWwUIDhE!9qF82d7% zRbiy4TGAw@53vNbH5H9iE7FQIB(?l1%gem?=j%P^-h0ly_uPB#_uX@gFZy|_s~V^( zC@84I&wB*Q{g7O9Rg~p6;$JZ+x%*pcp!Ye2&S~&R1%+>w;T}K!lv&4T!Tb&3dbDlY zNmV93xaf|uzWMC{Rqs=ArB?$kdfq61@mxXG>~Y7f!$l1*l5!!=$1Mn?AZCzRskxsW zcb%YeEFc_@hwydw5u=k#(pl2ke7wN>4#Z@IEnceb)#m7H$tNp}HL>Dv*BbKvNt#z3 zKZy+xVY}7YPT=!o{jup)_i&9vz#=y(v7=C4Qp`wOlC`8~8p+aIb&ev#3$d~T_JW|( zpbUy#@pv@LkjK1<85KmLWla()^{VUUZdft2u^sTg{tpg-Fuh$D z?yQE%-uJ;!kb_kTY)_cn2LrMPw;_;wtV=-lo^K-YlReaIW%U67twdfsW8g1wvBu6} z2grk!%k7?PL_-T$wdGwD8)kVlN3<93Ecitbw4h9fPciR&c>u zc!40&KL>`Q)G&S>HcpUZaF4b4SVWadE9G61<4gUO2)u4!d4C3n_n890X? zW!~zk9HE1Zt5a-hBG8U|)i_maGkRvDAj(p(&yHmI$hYwL?m>E$p^xsrXZuYhiJ@^) z&QH@{SW*5z*6x*UYb1JFhhgRp(klU`jNJTR9=2kiKqTz5%T@w@K2M4W=W76^6}q$T*=tp&o25MbQu4s;=}1L^E={u5w;>pZt`sA!=I9*8( z#h`Cy+ZQpqaTEEm54>E-DI(dcuG8J-jb57{_2-L(cxZ0pS``WFyQFf#x zd0qR;83RT`u*gINH~TZpHa=OZX!owcInau|8T4DY=x~eL)~a8isIWQ3I#eyjx{59s z>2089z0Lm_)1lr*pU?YTTHb>R`K8x{yT5!InrpXC-3nqq8cwe^rX+|aC!V#5kY28s zKlp+{Sv(g%Fa|{m4y2Rx45v>7VNYb=CfarF7*9QPH_s$n5!k>+MhZa^q9y1Uc4b(q zA|X0cx2THWpz;`tGBUTdzH67fCws`P#2nQH)@%YX3q|QPsfmMd9NCX%w{DgBQ)bX# zp?Bzo5Wt=rKgo8amJ2`d{Vd-&fs2SYUa#Q=)>KwJqVnYr*c4%`gqF&X;QE^5r1W?F z2v=PzmWHSD?K=-nouhn*7Oc5ggmNs{bvKOx$hb~t1P=Q=0WJR!K7Ljkw}z~49vLJr zk$e|{cqLTCU8*kMml@wa%{X0E5rClRcPL%<(SVObvA~#MH*98fXfXU=m(gTa zZQp)f0g4-OA$LFo&~Y%O`Sj-QWzCtC>c)km#%i{d{fUX0&-(5fcl!r6y<(9{sJyYb za4*Ba)EyK9fY_x4mV8{Do+|U{u?y#%OmUK4my_DUR*#sG+1vbn#0Y>TN`3leUjgQS zp|>ZN-h^r_*Z;;Cv|Ym^U+vsz)VP?W+?{$x6PfSs2DphvI%YmJYsulVM?UrFC+bw4 zpiT(0N=lIrja^|ou2qQ9iik)=&BVX#G5FWf-YfjmV##ud{NrY1E1Ggh zEx=BUW;6+Xs2W&bZXBQbU?tn#h%{JkoqHW|kGcA8VRT;%edf>E-EcF&O&B(z!N||| zg*gr1n+q4PuD-N1^_(8rE$_?I{!fZ$U|f~Vtw7x-VlhLSD*98cQBCvz(acqpDVj3p V!`4n{*8i1-d-{2Fp1bnPe*hXXv(*3q literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flora_VOX.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/flora_VOX.png new file mode 100644 index 0000000000000000000000000000000000000000..97969116a97829de4c31cae8825cf0dd1f59e4b9 GIT binary patch literal 1952 zcmZvcdpr~R8^cWL@-d(^NN92LJ$? z@UzZdiuzV@Qq@!x8JHdsttd(fUT#hR+_3R70HAse?tI!ixq9sr(Zk4Z59!N--cBuR zCvRJ|^M`(W0_dze{oRwgY}-rfd;qBUK6%P5xT)g4LER~*c$Zcui=){;P!jJR z&$i9lvwSlII}c9Ykn||eZ#NwuM5QFHWA~Pf*P8B7dpO#fSk_=gEjbYl_ehx8}d0HeoEV7c4(|m5~-kvhN?l>@4 zr{DsN;pkXGobAEA9(rW}J)fc<&8f}IY$dIOi9vzK6c>%Ig*l-*4V%Q%fxQA(q3ebAg$VQd7EM!Pa4s;x)vKTOaluQeOap% zG5Of{EuDuCU|2?{JP8BRMjA8yW$plT41FSI5JtzyxU=O;-;bT1yi>8rrgDEjXg{3C zAPzsopk>ez`c*9Cz=6JX-~R+6m>cdMQ?gA6pWm(q+rrV>7ip;MgO?bPVqt7hRw62* zZPynzEavI8fNO=U`O3}N9{nOF2XA6TN>jF$R$Pcl63tLKJC^qM&-RZ3b1nODvE6!} zAS;}uVRy&+V1Gu~iOB5))nNL2M8HFh!;u8ECe^cDbeq2u8?%kFaIfCJ`tsA_>k*-X z&Gv#v(X8T)H|3F9r!m&g&ob;#0GIXS^W9rmTu5Oh>*DoKm`N;*Oskr0T8Ad1O%hT4 zvByJ+L93Ic1PGm3UIg4K`)N??8p9!Pu9-d~ivS_yqfAD^gK%T9j~SeRt71inEFavK z(j#V#oTu(Js^`9*Ng&gBfC1ClnN*~4?-3#K6|pi>nbj)iNlxssSwsTp*BPE~+xqwS zvd+NCj;a4D^UauBKGbY+rFfc{ZQ^biepQ$95U=-<+(Ir-iWEOywPb|*`U^wL607}8 zpaJ3boZwM!mEmg>4$Xgx6cQlitg?am%DX3GvfL>{jWLBq=CI4RnHsww&;+R{?DOa* z67Hqv&~_#_@blE08^5X2iziSo%%D3~b=Hu~44nV75>*17+BcSNhh>jmbT}s{)U{%*Jq6 z&VUsN=23RTKq&uUf38NpR^xh+%;gjy6z*2b5MmJTrTA@&p{)y>p=m`X3#&$+xCKx# zV?U}>JiX$bROeBAgBpCooSjj@1m_4C=J9T-o{h*6xavK!1Y>5D+^c|`!-aw1E@ZO4 zACAlW{2VM}8O53tC+z2qK&FVQ0FAD&y?21e>uwd{sbC!K6Dwo9BmZY}iUU+PD5IWl zP@(@=A%Qdr|EmlcA`%QvHWuVKISWegLy`@D>tVVD%_cn|fJHMbXcl41s)S+^O8G{g z8e06-)>ogiG+dFnAvbZdsoR9iY0g+^S5F*0{*Yy#kL(DDjo4Cc$o><(fRX}})x(zt zFr6aL5cxN0{!2JD^snbfuHbPhTl!X3xazB>3i|atcDd`==N2Piej||%1|7V2mq!^g z(AFk?R9nFT6H%^Rw;abM-4r(Tm8838Qxd!zt`Fmi^WeOkXVsEwMb_-KBU-pDl5Q3y z{%#sSDlk2)!+HGw^;lPn4k~6MuozlTJg-|)Z$3DgvJ07iY+Yh-3>L@tnU1?|(xSo< z+Qv-JMKuhOlRDvjx(G&~zV;#J?qSNLV^@>wNZ5bbn7GLK8MFb~qF1EobWzMF%_$il z6yjTym%geVt|OCCo8hWj8Ai9R5Y9g&cC7FGh&zt4pOuN*UzbM9`#MF6tsLd==EVry z)&HpGb^wzjp6tlK{$Zag|I$AIZ*P7_MX}tM3o_W0y{yXT7>Wf_?piE_8>}0I5v!HX qH5tEc(+}cesTp3SNWeEB+i$@B@T!;4Z2s{1N*nIt;f!+%zW+Z{QQd3+ literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/frost.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/frost.png new file mode 100644 index 0000000000000000000000000000000000000000..4823cb5a6f2f7edd7a38ad837c42d8bec339c367 GIT binary patch literal 2650 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 Nz{1oDU4rt6{x604_oV;; literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/frost_VOX.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/frost_VOX.png new file mode 100644 index 0000000000000000000000000000000000000000..346cad09b1065c067a96bc22b9d2e6b2ee6d4764 GIT binary patch literal 2718 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 SQijm~5wNpyv?g16#{U!Z-Ghh# literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/meta.json b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/meta.json new file mode 100644 index 00000000000..4e069d0cd90 --- /dev/null +++ b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/meta.json @@ -0,0 +1,643 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Created by TheShuEd (github) for Space Station 14", + "states": [ + { + "name": "bluespace", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "bluespace_VOX", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "fire", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "fire_VOX", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "flesh", + "directions": 4, + "delays": [ + [ + 0.8, + 0.2, + 0.2 + ], + [ + 0.8, + 0.2, + 0.2 + ], + [ + 0.8, + 0.2, + 0.2 + ], + [ + 0.8, + 0.2, + 0.2 + ] + ] + }, + { + "name": "flesh_VOX", + "directions": 4, + "delays": [ + [ + 0.8, + 0.2, + 0.2 + ], + [ + 0.8, + 0.2, + 0.2 + ], + [ + 0.8, + 0.2, + 0.2 + ], + [ + 0.8, + 0.2, + 0.2 + ] + ] + }, + { + "name": "flora", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "flora_VOX", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "frost", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "frost_VOX", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "grav", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "grav_VOX", + "directions": 4, + "delays": [ + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ], + [ + 0.3, + 0.3, + 0.3, + 0.3 + ] + ] + }, + { + "name": "rock", + "directions": 4, + "delays": [ + [ + 0.9, + 0.2, + 0.2, + 0.2 + ], + [ + 0.9, + 0.2, + 0.2, + 0.2 + ], + [ + 0.9, + 0.2, + 0.2, + 0.2 + ], + [ + 0.9, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "rock_VOX", + "directions": 4, + "delays": [ + [ + 0.9, + 0.2, + 0.2, + 0.2 + ], + [ + 0.9, + 0.2, + 0.2, + 0.2 + ], + [ + 0.9, + 0.2, + 0.2, + 0.2 + ], + [ + 0.9, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "shadow", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "shadow_VOX", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "shock", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "shock_VOX", + "directions": 4, + "delays": [ + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ], + [ + 0.2, + 0.2, + 0.2, + 0.2, + 0.2 + ] + ] + }, + { + "name": "tech", + "directions": 4, + "delays": [ + [ + 0.2, + 0.4, + 0.2, + 0.4 + ], + [ + 0.2, + 0.4, + 0.2, + 0.4 + ], + [ + 0.2, + 0.4, + 0.2, + 0.4 + ], + [ + 0.2, + 0.4, + 0.2, + 0.4 + ] + ] + }, + { + "name": "tech_VOX", + "directions": 4, + "delays": [ + [ + 0.2, + 0.4, + 0.2, + 0.4 + ], + [ + 0.2, + 0.4, + 0.2, + 0.4 + ], + [ + 0.2, + 0.4, + 0.2, + 0.4 + ], + [ + 0.2, + 0.4, + 0.2, + 0.4 + ] + ] + } + ] +} diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/rock.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/rock.png new file mode 100644 index 0000000000000000000000000000000000000000..770e4b8d2f80570a23e6088fbc64afbe3fdeead7 GIT binary patch literal 1398 zcmZXUX;ji_6vintJvQQ2V`WMuEtV$1G>j3Eg(Btwb8FnvGDSr*mqdesHb>JOGc|L| zF>_0EU&at5b1PhqQfUxkDS1@TT=B00Lo=Uddd|7;bI$#A@43I{z3WK8X>0A&0)ar< zcss0<%5Qut&CRO!)ya!om2HT0!kq?H_U)Pkfz)AmthGx_u2gt5(CGYjjjxQex!Kpb z_X7@YHuNw^yM%JI!H-WS6#nqP%I+bRc9}5iXPYarqfUVnfwU%}9l}=k> z?Qk%7>JscoyVk)pixNC={3+4O$G_|0>cVfgSIBzf8lCtiQ)hxgIvbN|T^GBI+ zRTarFl5^6aazx#0l6p6yCI~I^W`xQ%1`D*I0au=llO+rg=U3<+=NhXWNznF?tzSiC zqT}FPMX*BEtt+#^chzldQFMOj2|M3Pk?5`1#wbI7Hva+mGD;Rxr-@y45B?zOw3vH{ zg};0eh|yMR{?x=*>vEUkm7_j9yAu_EoM@NurN}g!SNg)sQQ#W1Cm$9xj zhNbY@C{a$p~^arxpvFv96e~CO{pf`{eS@F15#n?|nwU!Q+ zNlY2~Xe2L~9WA#WhfJ&MeWU5+b;C;S7S6kov(>`g=LA6LYYm^UJeyAaMn40o9 zn$El(hEV>w>dL&+km;&JWlz=4^E=|vK1-tp?z1T*1$}+lK<__F4SSN+@|PjJHZMOa z@$-f5*U_p`>Eo1^t50J$M$?{Z07b?ju5a?_F1Q|p>cUsTgU=-eY`2E&D(_Yw;J}pm zQ8HiPWyKBMEA9r^*384C=D?w=dKD`oGg!_? m`JgawHNH#0KY<`*F+e(|1(%kpd*f9fDF|;vz*e62z4bREM%!Wl literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/rock_VOX.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/rock_VOX.png new file mode 100644 index 0000000000000000000000000000000000000000..b11a9182fb7fa91a8d13b392cbe6864f59a8633b GIT binary patch literal 1398 zcmZuxeK^wz9REpqsV8!Y%M`tMNmiQ5?Us!p#x)X&^V$pL5K}`N6Lqz`rRPe_%aJP; zTVaN6mP2USa+EBNoGq#`);6=Zn}6<}>$&gqe7~RP`#j&jKA-RBLkvKBuU~7i765?t zC?C&2EoQH@fu44D!DHB3&`AySMgnAxn_cKAGhy7XIug^LQxba!<;Rt7z?vZ4jY}iwyY$Sa zZgfWP4SaetAvzT^vVYfkBjMYWMshn$%=}3z-?B+inihLOEn-gSZ!kIF_=^v_0LDFC zec}!%trGQ^-&>zQ#*l?K{&qtP%Hd&6q1F44E<>H{h2lN6C23EaZi!DdJ+LKgPcj7Z zjj-1A_G?p@I?rb9kkI698|S5&h2|jHf?~?JBT?2o?cWWCz8flH(cXx}pK0I_jT&9I z+6C1iu5$Bpl_)UllGoY%5ig4oDtk%q9?8vdbdx4XC;XbDDZ4SiF;5ov@H+SzDWMnSrOwSy7`hi9N(`| z26f+I)!U%F5*`Le2lTw_XP6Q~O<<)ZVQchmQzA4eVh~h*Aj*(egOJsF<7lk!Ig(7sbFLSnyg)z3yxZf=+FXkW+0co zsK1JstCBQJ6}}y^CI2HF0{}m^FMH-Qb#g*pk>kHir`b$EC&T1aNW73VpOe)Sla=T| zNsr{|SHBjMrnUoL5OheCOV#zS3hkUW(e^yqUWiYdU_DQ+xBi4Uo;t(vHJar|k7}y8LczkS9(i}AhG8`_>Ur`ulBz)&E^ghGz zQDPWuB4c-Q)M}oDKC$7xZQSWS9Xl^K7vK=6b_#OdUF6CzTx3>VAwA5R_evg1tejDs z`quJQ+@GH`-RjCKP&ld1pkavEGt){tU3;?mla}-lrdlluiH);ukirudw}ir2JVh&3 zr9A8=$anyDR+Tot7Bhzgn+Fi_obLttpX#6+iC^)$vf_^>X5s`iG~A@Z*6!mjKd*!o z8eE@=X(_3AnMaq5_PrS0!;|P26Kdo-Tayr-+J_3C#Sz)#=F#o$C&lLsR|pB@?k=Y^ zgScrUnjVq2)A+B|nMxhTsAew74>GtDdH{N_3~|uX^%Y@0iGA=k;e_gWndjrHx&p!A z5QlPr|Qq0$M79#TFb@ZmIuh? z{F(?BR=x5X8gE>Wqi`8CKv9@Yn)%kgp35zAp#_WgO0hd)&kR?303N*rZM+0^lP#i8 zhT~g;ve^Kj=54==7d=ae2VTt{POQNT`MjV{Bk(1j9GtoMe7L7rN0$y(e4KsanQs1qDM5Q?@Tf)l+;e$W z_EDf9?6KozSwlOWO9z)HFfEM`s(QEPJo}l(1K(@?et92bv*%=B2>$$J;r$P-+i_Mt$A)E&TONAN%`r{$KiQcYXh92D6>BzsXNNbHA=?{_NYYzx|My^>^;xo45Vn zU;fsA-v5>1Z}aWfGk@>2=1;b*owUT#&VHr$x6fz4-oJlycIn&ik_TKTx!UeO_3+)n zub;zt^Or^8f#o&YZ~ppw9mBzaM8;ZH}pZcl4E2&&~b8p||7R zc>lFudaZFafA`YgwWXCz>sr6Dn4Epi{$K6C#G2F3-&uF;W#8~cc!h}h0TX+3U^o*1 zQ$8$tFTJO#Fhn(T|16cWule15?|;8K-|hcPhU^uSY`j0!e2wD$Fz=V}OMc6S(&?-` z7wbQNyjyeXuZZ3M+F#B*36oQ1K54)DI-~#pw*C7zn_KU-@Lu`v?AuZ=a8OM8`(?*J zXTAp@omcINS?qoFk3`#r5;NSh`e={pCe_wPte*Zt`a<>~V_P+RXef|AX z2J<3)tG^F_t+o|(mp`C(^3#_`I>(=@mvZH@hV7c)RIRwq`9DzTw{`Vq#b0yTHq48E zTJSv~yMr|+Y5#+`is1X*g|<`fb!NT#tC;)bTh2Bn?d%iM3obL*EwkRhjT)rE-}LV< Vp6pz5Th$HZG*4GQmvv4FO#q9YeJ=n2 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shadow_VOX.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shadow_VOX.png new file mode 100644 index 0000000000000000000000000000000000000000..6efb246ac1889f38de9d82fefbd4e0ce5b43fb5b GIT binary patch literal 1002 zcmeAS@N?(olHy`uVBq!ia0vp^3xK$RgAGXbBqvD&DaPU;cPEB*=VV?oFfcFiba4!+ znDh3|K`-f8iT01n=Poi4_#ni^%BsJx{9hgJ9b!|m(YAJ*^NE3~og;;b|C)~sByx^2qO`WN-DYAO!=+dt#sEuIR_EsuXY z>NG`!7>0((s?9c-X&V{5Vk1!5_pkP)b~XwB=bw*o;I`;reYC>(*ZlqUl1H*%O*uN} zpUbxr-_mOnjQ;QYxBOiFg@5OZ7?=%M;*OfC%=_iH{`A{eyIsrt63c5>-+ft{SaY1W z|Gb}tjjhtPkaXUM-}KV0=Kue;WZfSI9)ACR3p?w^!vE4|pU?YyKlXms`N_7g8P7Dn z-tj4r@$W&^-?OV%e-<%V%pmeUZhx+!9mCJ7XIZVKZ)a~@7RCSI-?MvJ^#vzW{vFSs ze@^oIl5@-x-sj}3kG&gnV8{Q<)j`>I1+w<<-~XL|qkq@;|I>A{|K_NySaRj7$z1!n z)2;q1rd2ZO^}J+jG0^#Y`;Sq?mh-MWc$VW&=q4t0J$@QN&cNhfa zJ7g*HX#algc6Zt*hGoxqKUCx~U=Nh~@7L=U;wH?j?$3L7chb}A+y19MW7a!#X0N;X z_q>yzvTy%4T5RdY`o((hy9O5H?-eb@@2Bb1v%WZfvwdpX^hzeS1uwqr`mNOVm|yQE&@*dyHB9;mOBE`!s>Rdq zEuB$4qv~DKtC`*1ieHbcTs|*;y1VhbvlHVpua+`Tv1>S8#XjvRuL6cI#7^v={PKP7 U5=RDMVCH4;boFyt=akR{0G7Mzr2qf` literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shock.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/shock.png new file mode 100644 index 0000000000000000000000000000000000000000..acdc87a291c1f3ae96bef140d18330ebc0273608 GIT binary patch literal 879 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 literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/tech.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/tech.png new file mode 100644 index 0000000000000000000000000000000000000000..0611fa8a2a092a82bedac5ee8b2aebd1d0ada50d GIT binary patch literal 1241 zcmZXTeN@tC6vwepo14;UGf&N6q`mD}*^A9UK*chbqG?8oP09?LE!+@w;@d_>OPiW2 z-z7}bFhwaa@C6l@PKKB-vGV;u87K)E7$Ue||8=%|&U5c`?{m+2p6ByD_qPz7zrEdN zI}iwDA8^bs6o^?L);b%&i_vE#K(L~O`ul*S!-8amt4EfjgRflA=7p zitRSv{1_AUSg@-n-1YfpsiZ{UVp^rgeoCMW96-`MqyqdJ=uIanKR#JF@U~Qglefq5 z!=fMNLi^d~zpA3^u~X&Cvs;MWS428~1G{V!?JPdn)+x;N-=5{+H6YSgKgBU{&wtAw3D97(mIFH?URS}35#X`cB%+@vU6s%>P7MCK!WLp+g z+FpgssbEChw%p(&YiJ;=sg&cKGD5c66#t-s%=UO4WG0v5r?`we#<7aV#l5hAs(e27x16hn$5{qv zaty>1qCToy>bg=)Vv1zWt-iMs28jHzb<*=mUWk(#VQz2jt?v<@%Ah_3aRZk>O3I1q zO`~5!jDuCHy4S*I21-F}UT>{Az0iK^&>?pLIqPN6W3pH3g%`>){h3pYAH{%?X=N(0vmiL=fySP_h7n)s{6~;_XHg-XU&7h`TR$b4MHL|0f07aAlm+8L3tgISw;e1MzTD zWl^jp5aPY1Th6lGWoqkioLecugD&bK4B^G|EOu#x;j^7(;g*r%`X!BHNOb~~MJsM0 zd58D+F;lINAtc{Lracm7S3}u#804O4s(Jt0*+{F7@t^OK(W`->LVK47<8tgRfKIY@ z03rh51n~&hYo?8hZydGxseQ;jwT#*qG94=aBb_+x}1X#z2n5J7s`;uP!k> zrY586fcZ#BywAp0<)coI;Jnc2ptWN+Eas()TV`U;hT4XhBLJ*`Q{l!C1Gho4Nwkra8tuP;DNxFNT(M uTtR_lur{mFm_)>RNY|n*`M-}($+fJ_Qq#-0ue^FboCO@g`8E0yfBhFxa%ye> literal 0 HcmV?d00001 diff --git a/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/tech_VOX.png b/Resources/Textures/Structures/Specific/Anomalies/inner_anom_layer.rsi/tech_VOX.png new file mode 100644 index 0000000000000000000000000000000000000000..1787cdd4e06cebddb5753fbb349d2c06e2bcd10c GIT binary patch literal 1244 zcmZuwYfw@N6uy?Dt!D17Q){(+D0Fr0uw-hhF1l($_+S+W9|boj5#@Se@n5sEXXc#m%$z^x`@VBZqECjo zIBjg{N}mnvSg~P8fkp*t9sun5gplC)+)Dk#p$HTm)w8HU zO*IsKxnnBr^|UBFKDt>z&bTOd-{ZKSvymM-s&FUgoLhD9v;V#IWDvUR;_w$vPb*$| z|9rw;P~<(=LG;GdL$|&3v!Vg-7TJsKIhc$P_Smz2%jG&(Z7D7$!McVNOF8)!D=hjhko{vJXR(Ff znMa6aGma>YXl!Jp@b>&2B4LOyqDTS@^(0c|ytWu*C8rCj8!Wqh3RER+*9~`f`*E`2 zzr%+)??hhED1M$7& zP4p>ii8Hx*wIZr2{QBLi2j?)T_trEx2+KuaVx!fLgfF<>T4>wcIi=4}abm%UX>vj! zX1dT(!Y+Q~Mp);?(fAo3N@$cD@*JyrBG7M5AJ@jd(zf#TnSjpMBfs1*yTu*20;LG# z469U-b4&h6syB*EAJsBQmqhWPXeUA2aeN*;M>#b}ouF?k>!D>pnau;m(V5M!Y0L`K zy7bNuwzvkHal4XC>ap41_OpWUP}b=kAu}$6GA^&Q_*y^}SCiJ>q|QL7-kW>Js~(hD z;(Wty=!UiXTE3XTXmyhifuPK?NxSOkMl5D>^^61 z>&cs{;BDfYbX;!q&by{N@-9{DHwnlr3CQ|Ey2Z0@ngxpzmy_pQ_E5lKX(Zy=&_GOu zc+bUivLSzc(#LyVOo-PYHh@`N-d;LQZHmBYCLhAsn@QmMU_oL4l^eow!z6RIw&?lx z-TdlavtDQ<=Rkv*HBBs7J0dgQw{!KntXH*{nj6iSC7(ef`b;f=K`Jz7Y>>4rQFf0As+niKwk$uV>#8_aohnXjj?U7?CLJqb55M(Q( z_y7CNXy(nl2Nfz**km~C7LW(A=hXoDn*b9h3@3SPWpaQfc7K67uw@7s10x{HDO#z+LRm3xD|&_!sCqVK`d;bJxdjb%6H15BvuF1@OT=WDt>fea{KFi+u)>`Yu9x zW1mkXLjC~$0fH=}piKUsQZ%@zcg_>?Jts*1x#tA5_ha^)fTpWN^~OH!{g|VzAn7Ij z{0nU_3rgc(aDeuH12z0Egs?aEX}VK#AQ2(>eBDe$Xn$O2I}L63QIySZ8v)||1}N_f zp^4iYhua(V21!rIeR)npX7E)F$!w3xxI0?i+upAI1#0Bq3zYJ z4Gq|Ozaak9QDAd`M0k8~4-;~kb+3lqgdCU=BLd~S(F-+g_c6%Qw_7m(uC}}2fS*%D z%rxwc{eMJ6)9r9I?DBHE1MZY~5W%;HF3?do-02K$vzdY#D!jccnEw)ZW7A+80TS9K zHwHPVz1qJV1kP6PYUKg(RLR!*c>pHh99G^Gc&I_>wbIa zay9HGL?*dhjrCYIOshEH9u?ac$^Tv3UC99>RDT@(*1Ty>L^1?lH#$l0G+i}enah%f z#ORMkgF0A|c)m#fJ}|TeLpBFQOg9rrc-h{MlL<$>-8mT0IT*}{lnKc2zU&fb2W2`+ zm7eY|IV8-31DETbcK{Vt2kZiqQI{%Y) zgMTLGh@phtU=jRJIu8)c5tnuzPy~N;sCE7v3dzr(YkRK% zKlZ$Onj_X(A5cTZ_AOL|cLs&#=g+j=mgY$t32Unlki7gCo2mlx^Wp@6Ur66Lt$(dP zK=Sg(sIYd1yny^X+U_wadHOjWrPl{cP`%OzdRlCe`T2L+ZeQ~(b3pm^0ZtfBbhH!z z*QkxnsoC%e`T0|A?-~`5jM9RVwbuve2KV}b01C;^%LZxHJwa6;P$qv>ACUHssy?8q z57_V%p(R2#=S(m~$PQ{_BYOr3ay+idIovbyueUznN6QQ3O^wx=%M9h2>7N7grp6+s h`-fEvp({K`{11t~Wue8V+^PTo002ovPDHLkV1k!7P>BEl delta 1162 zcmV;51akqe~C0ep)b zBe&22Qsn|E45)UYSb*CIDkyaVRt?j5)+1_2&MwzB4D$g7jO8xh<8U2{<`u{jls&=&it)EAmRrAw||psYz}*j2P4eZ3w(Zj z=Q$10H^2HtpZL5Q0sxlv4wu6-0KnGO&t?c`j9Xc&=ARma%GxBqO5i=m>N#eOwODu&j3tH}TIW z*G+7QA!z`beSfn2crX&*qvzZR56E98IY0I9Yw)?-@T)w4&!#jB^xPNLmlyc`_!=Z` zEq~MizV%a(gynbv=ij=znPK1MIrrApt@x83z^ynQj6`xDTtu!H{4!Tq*1IP7UJlQi zzh%8^xJc9Hus_n6;{PZ;lq^Oa(hA^5eqY1}`=d7MvwzL1Fg506#qmL0TpQOj9*i(G z1_%U1(EucpL`zEzp8;+V-#~t!ZLqQyn0z^TzI8P=2YJwv#@K3*{0Yp~i<7~V2;j-( zd@)2mTQ5=+Nq!%j!@l_$q~g z>*^%GYJVB@XMse-1}}Zr6}%ss{kGqQkTk#rP<_U+C@6TdaK>cqMBn{RFxvpRGtdWjj)u+#xPJ#67x2=DB7e|bjS#&QmB7#A^TE@V z^$fPt-G5uqKq+BLxLGfnHqAu{LH(jnEZxW~>m7dByXGpYjgU6{Kh2ex5Ad(Tdb<(g z`FW{6fD52@ZGOHjzh57~LC>G1K7hzChi6Srzz44%nD_6jSXrwkrv&PG zHGjm)+Uy%6ntfg$km3f=@TY>K$^*DHV<~DPmcGk@-%qGW!=EG#f2;Zco)PxTVnTv) z>I3}Q=lzDz)(fHrm>SbuJyTMGTR#+tIBqA`ssx1(5*_nCDNz#gf{+n{2H+p?0tKl+ z$`>OUM!QjQ#yII+J^|GK=CD68Ld+wjzJG%op~~9I8RN9cNM5KQ6;EiFLwb*dh6*6~ zPw;$rJSm|VA!&$;q8RY^(^s)QR;WO2-|b!JBq_y!-vNH$sR~3Y(g1*O|Ncbx1D)#w z_~0cEIj@Gm09hGg^1`{mPa1&JlAL9|!v_1NJSOISs%7vdQKix5yDkXz!@ZB|Ab(vN zepP+I)R?1Sqe)Y5U5%+R*$1P_+7o`RAyg(q{Jm|3d44_>7-=uwC%V)JXwd02_%l); z(DpReg`W;(u_9?L|C_51h}{QtF??2i0N>%QtbNh^ytG;B)8n#)yd-yM=lE_=uEh%q c3Ucrt#86llirPac00000NkvXXt^-0~f~LST$1WzK;UIe|0kXP`*_q4B25Mgfx zFD)XTgceHnkexIYZEJR6Fa2+6ll$fG)dl@|ixL>$h8&_}=t={D5P2Pf(0#h6keJ23eI*_WD&HZB$(|gJJ z54nn8ehZ-e9ssR2^w0iJ0DK5&zlOe=HvHq)unz>njDr9kfrJ{58Z}Dv4O?Og7Rhkr QfdBvi07*qoM6N<$g2@Wm4FCWD delta 389 zcmV;00eb#{1g!&*F@I-CL_t(oh3%FxZiFxpML!_|87alG1vkiQ%RRszf|GIx4nWBn zkOFidBO#|6WV|*WP*!R9rLq0rAI1jY)TvYdtl;RvTnJ^372~*jzugPSxSMA@uMafS zfGkQ-wiVJa+zrB>Xd0(M3;?KQk9&Lp0CY<324Ml@LMSsa0e=t#04s2W(ixTTR8rLDZdA2s|E&u?lG-i5z+=Sy)VG}@4&yhKg zQw47Y^b}c?pqBkoW|ul8t?O<2^Z}5_lum%z`TCq@8qi=^J#&fG19aB!@ntEqe&kF* zjxigcY%A-AWPaRC!%KAtu$Dc_w%Xi(^A!~18012zPRW-BYo=i_aw&@v{CF-S)+;bm zPM#W)6O7_K_InfwjbDfzcoaoJWY2%kA8J#g@A`2BTrHs)KthAt5Ol6m|8 jfD1&|kw2nSr%wF>39-#Z{0ZNi00000NkvXXu0mjfSD&j} From 0159baf9151352dc56e060552288eb33f8ef2b1f Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 17 Sep 2024 09:50:26 +0000 Subject: [PATCH 053/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 1df9fae6ee9..7b79fca23df 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Whisper - changes: - - message: Light toggle actions now have a 1 second cooldown between uses. - type: Tweak - id: 6887 - time: '2024-07-09T04:14:51.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29833 - author: Cojoke-dot changes: - message: Shotgun loading doafter now does something @@ -3878,3 +3871,18 @@ id: 7386 time: '2024-09-17T00:35:57.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32061 +- author: TheShuEd + changes: + - message: Anomalous infections added! People can now be infected by anomalies! + This allows you to use abnormal abilities, but can easily kill the host. To + cure them, bombard them with containment particles, because if the anomaly inside + them explodes, their bodies will be gibbed.... + type: Add + - message: Flesh anomaly resprite + type: Tweak + - message: anomalies now disconnect from the anomaly synchronizer if they are too + far away from it. + type: Fix + id: 7387 + time: '2024-09-17T09:49:19.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31876 From 482caea466098a118d07f55d4303e735cd67a61a Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Tue, 17 Sep 2024 19:05:38 +0300 Subject: [PATCH 054/138] fix Tech anomaly loud sounds and superfast flickering (#32245) Update TechAnomalySystem.cs --- Content.Server/Anomaly/Effects/TechAnomalySystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Anomaly/Effects/TechAnomalySystem.cs b/Content.Server/Anomaly/Effects/TechAnomalySystem.cs index 1b2849f1d77..3e4d101f4fd 100644 --- a/Content.Server/Anomaly/Effects/TechAnomalySystem.cs +++ b/Content.Server/Anomaly/Effects/TechAnomalySystem.cs @@ -37,7 +37,7 @@ public override void Update(float frameTime) if (_timing.CurTime < tech.NextTimer) continue; - tech.NextTimer += TimeSpan.FromSeconds(tech.TimerFrequency * anom.Stability); + tech.NextTimer += TimeSpan.FromSeconds(tech.TimerFrequency); _signal.InvokePort(uid, tech.TimerPort); } From 73e89c3f815fb2f333e224f386222e5d7fe521e9 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 17 Sep 2024 16:06:45 +0000 Subject: [PATCH 055/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 7b79fca23df..d9f64d1f559 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: Shotgun loading doafter now does something - type: Fix - id: 6888 - time: '2024-07-09T04:23:08.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29827 - author: slarticodefast changes: - message: The construction menu and building preview now show the correct passive @@ -3886,3 +3879,10 @@ id: 7387 time: '2024-09-17T09:49:19.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31876 +- author: TheShuEd + changes: + - message: fix Tech anomaly loud sounds and superfast flickering + type: Fix + id: 7388 + time: '2024-09-17T16:05:38.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32245 From 3951e2dcdfbdecbf91e0f69715c204523009d82c Mon Sep 17 00:00:00 2001 From: drakewill-CRL <46307022+drakewill-CRL@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:45:42 -0400 Subject: [PATCH 056/138] Fix plant mutations carrying over to other plants and future rounds (#32257) Lists are a reference type, so each component should get a new one, not point at the previous one. Co-authored-by: PraxisMapper --- Content.Server/Botany/SeedPrototype.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Content.Server/Botany/SeedPrototype.cs b/Content.Server/Botany/SeedPrototype.cs index 7a3e08883de..5608338f22e 100644 --- a/Content.Server/Botany/SeedPrototype.cs +++ b/Content.Server/Botany/SeedPrototype.cs @@ -291,12 +291,13 @@ public SeedData Clone() CanScream = CanScream, TurnIntoKudzu = TurnIntoKudzu, SplatPrototype = SplatPrototype, - Mutations = Mutations, + Mutations = new List(), // Newly cloned seed is unique. No need to unnecessarily clone if repeatedly modified. Unique = true, }; + newSeed.Mutations.AddRange(Mutations); return newSeed; } From f2abebdc4a412eb8067827c6b6570ae8dee9227e Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 17 Sep 2024 19:46:48 +0000 Subject: [PATCH 057/138] 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 d9f64d1f559..7f904065cba 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,12 +1,4 @@ Entries: -- author: slarticodefast - changes: - - message: The construction menu and building preview now show the correct passive - vent sprite. - type: Fix - id: 6889 - time: '2024-07-09T13:39:47.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29820 - author: Cojoke-dot changes: - message: Pacifists can now use foam weaponry @@ -3886,3 +3878,10 @@ id: 7388 time: '2024-09-17T16:05:38.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32245 +- author: drakewill-CRL + changes: + - message: Fixed plant mutations carrying over to other plants and future rounds. + type: Fix + id: 7389 + time: '2024-09-17T19:45:42.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32257 From 00877bc816c4ca6b4cbb099e0851bfe4ecea89a4 Mon Sep 17 00:00:00 2001 From: Moomoobeef <62638182+Moomoobeef@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:09:55 -0700 Subject: [PATCH 058/138] Added a number of new and very nerdy names for the AI (#31951) * added many new names for AIs * fixed mistakes * removed Intel and AMD trademarks. Rip AI named Pentium. --- Resources/Prototypes/Datasets/Names/ai.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Resources/Prototypes/Datasets/Names/ai.yml b/Resources/Prototypes/Datasets/Names/ai.yml index 1d320c3f52f..539ef4e3fad 100644 --- a/Resources/Prototypes/Datasets/Names/ai.yml +++ b/Resources/Prototypes/Datasets/Names/ai.yml @@ -2,8 +2,11 @@ id: names_ai values: - 16-20 + - 512k + - 640k #ought to be enough for anybody - "790" - Adaptive Manipulator + - Adlib #named after the famous soundcard - ALICE - Allied Mastercomputer - Alpha 2 @@ -19,21 +22,28 @@ - Aniel - AOL - Asimov + - Bell 301 #the most influential modem ever, created by the bell system. It still lives on today in certain applications - Bishop - Blitz - Box + - Calculator - Cassandra - Cell - Chii - Chip + - C.R.A.I.G. + - Cray-2 #commercial supercomputer from the 70s + - CompuServe #if we're going to have AOL we may as well have some of their major competitors - Computer - Cutie - Daedalus + - DecTalk - Dee Model - Dial Up - Dorfl - Duey - Emma-2 + - ENIAC #famous early computer - Erasmus - Everything - Ez-27 @@ -47,12 +57,16 @@ - Helios - Hivebot Overmind - Huey + - iAI #a play on the fad apple spawned of putting "i" infront of your tech products name + - I.E. 6 #hell on earth (web browser) - Icarus + - Jeeves #if you don't get this one you are too young - Jinx - K.I.N.G - Klapaucius - Knight - Louie + - Manchester Mark 2 #named after the Manchester Mark 1, the successor of which was actually named the Ferranti Mark 1, rather than Manchester Mark 2 - MARK13 - Maria - Marvin @@ -64,6 +78,8 @@ - Mugsy3000 - Multivac - NCH + - NT v6.0 #A play on both NT as in NanoTrasen and NT as in windows NT, of which version 6.0 is windows vista + - Packard Bell - PTO - Project Y2K - Revelation @@ -76,10 +92,13 @@ - Shrike - Solo - Station Control Program + - AINU (AI's Not Unix) - Super 35 - Surgeon General - TWA - Terminus + - TPM 3.0 + - Turing Complete - Tidy - Ulysses - W1k1 From aac4b837e2c28281c9a317c8c13551805e9f1067 Mon Sep 17 00:00:00 2001 From: PJBot Date: Tue, 17 Sep 2024 22:11:01 +0000 Subject: [PATCH 059/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 7f904065cba..46f7200cc34 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Cojoke-dot - changes: - - message: Pacifists can now use foam weaponry - type: Tweak - id: 6890 - time: '2024-07-09T13:46:21.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29835 - author: Plykiya changes: - message: You can now drop food and drinks to stop consuming it. @@ -3885,3 +3878,10 @@ id: 7389 time: '2024-09-17T19:45:42.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32257 +- author: Moomoobeef + changes: + - message: Added more names to the pool of names the AI can have. + type: Add + id: 7390 + time: '2024-09-17T22:09:55.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31951 From 0535e3e8097ce4e675ba087a030c9e2172276b98 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 18 Sep 2024 01:19:34 +0300 Subject: [PATCH 060/138] Fix Anomaly infections infinity growing after curing (#32259) --- Content.Client/Anomaly/AnomalySystem.cs | 12 +++++++++++- Content.Shared/Anomaly/SharedAnomalySystem.cs | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Content.Client/Anomaly/AnomalySystem.cs b/Content.Client/Anomaly/AnomalySystem.cs index c93f0ce9490..28c015f3021 100644 --- a/Content.Client/Anomaly/AnomalySystem.cs +++ b/Content.Client/Anomaly/AnomalySystem.cs @@ -20,8 +20,9 @@ public override void Initialize() SubscribeLocalEvent(OnAppearanceChanged); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnAnimationComplete); - } + SubscribeLocalEvent(OnShutdown); + } private void OnStartup(EntityUid uid, AnomalyComponent component, ComponentStartup args) { _floating.FloatAnimation(uid, component.FloatingOffset, component.AnimationKey, component.AnimationTime); @@ -75,4 +76,13 @@ public override void Update(float frameTime) } } } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + if (!TryComp(ent, out var sprite)) + return; + + sprite.Scale = Vector2.One; + sprite.Color = sprite.Color.WithAlpha(1f); + } } diff --git a/Content.Shared/Anomaly/SharedAnomalySystem.cs b/Content.Shared/Anomaly/SharedAnomalySystem.cs index 9a0cde29988..07beb1444d7 100644 --- a/Content.Shared/Anomaly/SharedAnomalySystem.cs +++ b/Content.Shared/Anomaly/SharedAnomalySystem.cs @@ -194,6 +194,8 @@ public void EndAnomaly(EntityUid uid, AnomalyComponent? component = null, bool s if (component.DeleteEntity) QueueDel(uid); + else + RemCompDeferred(uid); } /// From 100e52568c569847485ffc469379e733aa30f1ec Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 18 Sep 2024 03:40:24 +0200 Subject: [PATCH 061/138] Fix borg defib module throwing an exception (#32260) ToggleCellDraw was erroneously added to the parent prototype instead of the one that actually has a battery. --- .../Prototypes/Entities/Objects/Specific/Medical/defib.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml index 7b5ba23fe33..69c106efab1 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Medical/defib.yml @@ -47,13 +47,13 @@ - type: GuideHelp guides: - Medical Doctor - - type: ToggleCellDraw - type: entity id: Defibrillator parent: [ BaseDefibrillator, PowerCellSlotMediumItem ] components: - type: MultiHandedItem + - type: ToggleCellDraw - type: PowerCellDraw useRate: 100 From 1befc659b504d8c1bc519a8241e992cf82527172 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Wed, 18 Sep 2024 04:41:24 +0300 Subject: [PATCH 062/138] Easy IconSmooth spriting (#32210) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * фыр * Update IconSmoothingTemplate README.txt --- .../IconSmoothingTemplate README.txt | 4 ++++ .../IconSmoothingTemplate.aseprite | Bin 0 -> 14094 bytes 2 files changed, 4 insertions(+) create mode 100644 Tools/SS14 Aseprite Templates/IconSmoothingTemplate README.txt create mode 100644 Tools/SS14 Aseprite Templates/IconSmoothingTemplate.aseprite diff --git a/Tools/SS14 Aseprite Templates/IconSmoothingTemplate README.txt b/Tools/SS14 Aseprite Templates/IconSmoothingTemplate README.txt new file mode 100644 index 00000000000..083e803ecd1 --- /dev/null +++ b/Tools/SS14 Aseprite Templates/IconSmoothingTemplate README.txt @@ -0,0 +1,4 @@ +This is a template that greatly simplifies working with IconSmooth sprites. + +A video on how to use it can be found at the link: +https://github.com/space-wizards/space-station-14/pull/32210 \ No newline at end of file diff --git a/Tools/SS14 Aseprite Templates/IconSmoothingTemplate.aseprite b/Tools/SS14 Aseprite Templates/IconSmoothingTemplate.aseprite new file mode 100644 index 0000000000000000000000000000000000000000..112a1d932cadd62741abd5abceda653934e920fa GIT binary patch literal 14094 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 UoOs=6@h%0vEot(c1jDqy1Eecdl>h($ literal 0 HcmV?d00001 From e7ac40578ac85223e8edee9fe68717c666e15ed2 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:43:30 +1200 Subject: [PATCH 063/138] Fix AudioSystem nullability checks for engine PR (#32233) --- Content.Client/Audio/AmbientSoundSystem.cs | 3 +++ Content.Client/Audio/ClientGlobalSoundSystem.cs | 4 ++-- Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs | 4 ++-- Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs | 2 +- Content.Client/Traits/ParacusiaSystem.cs | 2 +- Content.Client/Weather/WeatherSystem.cs | 9 +++++---- Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs | 2 +- .../Kitchen/EntitySystems/ReagentGrinderSystem.cs | 2 +- .../Mech/Equipment/EntitySystems/MechGrabberSystem.cs | 2 +- Content.Server/Salvage/SalvageSystem.Runner.cs | 4 ++-- .../Shuttles/Systems/ShuttleSystem.FasterThanLight.cs | 3 ++- 11 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Content.Client/Audio/AmbientSoundSystem.cs b/Content.Client/Audio/AmbientSoundSystem.cs index ca6336b91b8..b525747aa9c 100644 --- a/Content.Client/Audio/AmbientSoundSystem.cs +++ b/Content.Client/Audio/AmbientSoundSystem.cs @@ -306,6 +306,9 @@ private void ProcessNearbyAmbience(TransformComponent playerXform) .WithMaxDistance(comp.Range); var stream = _audio.PlayEntity(comp.Sound, Filter.Local(), uid, false, audioParams); + if (stream == null) + continue; + _playingSounds[sourceEntity] = (stream.Value.Entity, comp.Sound, key); playingCount++; diff --git a/Content.Client/Audio/ClientGlobalSoundSystem.cs b/Content.Client/Audio/ClientGlobalSoundSystem.cs index 7c77865f741..50c3971d95a 100644 --- a/Content.Client/Audio/ClientGlobalSoundSystem.cs +++ b/Content.Client/Audio/ClientGlobalSoundSystem.cs @@ -67,7 +67,7 @@ private void PlayAdminSound(AdminSoundEvent soundEvent) if(!_adminAudioEnabled) return; var stream = _audio.PlayGlobal(soundEvent.Filename, Filter.Local(), false, soundEvent.AudioParams); - _adminAudio.Add(stream.Value.Entity); + _adminAudio.Add(stream?.Entity); } private void PlayStationEventMusic(StationEventMusicEvent soundEvent) @@ -76,7 +76,7 @@ private void PlayStationEventMusic(StationEventMusicEvent soundEvent) if(!_eventAudioEnabled || _eventAudio.ContainsKey(soundEvent.Type)) return; var stream = _audio.PlayGlobal(soundEvent.Filename, Filter.Local(), false, soundEvent.AudioParams); - _eventAudio.Add(soundEvent.Type, stream.Value.Entity); + _eventAudio.Add(soundEvent.Type, stream?.Entity); } private void PlayGameSound(GameGlobalSoundEvent soundEvent) diff --git a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs index d60c978ccf5..bf7ab26cba2 100644 --- a/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.AmbientMusic.cs @@ -213,9 +213,9 @@ private void UpdateAmbientMusic() false, AudioParams.Default.WithVolume(_musicProto.Sound.Params.Volume + _volumeSlider)); - _ambientMusicStream = strim.Value.Entity; + _ambientMusicStream = strim?.Entity; - if (_musicProto.FadeIn) + if (_musicProto.FadeIn && strim != null) { FadeIn(_ambientMusicStream, strim.Value.Component, AmbientMusicFadeTime); } diff --git a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs index 92c5b7a4191..9864dbcb2a9 100644 --- a/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs +++ b/Content.Client/Audio/ContentAudioSystem.LobbyMusic.cs @@ -185,7 +185,7 @@ private void PlaySoundtrack(string soundtrackFilename) false, _lobbySoundtrackParams.WithVolume(_lobbySoundtrackParams.Volume + SharedAudioSystem.GainToVolume(_configManager.GetCVar(CCVars.LobbyMusicVolume))) ); - if (playResult.Value.Entity == default) + if (playResult == null) { _sawmill.Warning( $"Tried to play lobby soundtrack '{{Filename}}' using {nameof(SharedAudioSystem)}.{nameof(SharedAudioSystem.PlayGlobal)} but it returned default value of EntityUid!", diff --git a/Content.Client/Traits/ParacusiaSystem.cs b/Content.Client/Traits/ParacusiaSystem.cs index 3789f24cb0d..af4d8ef278f 100644 --- a/Content.Client/Traits/ParacusiaSystem.cs +++ b/Content.Client/Traits/ParacusiaSystem.cs @@ -69,7 +69,7 @@ private void PlayParacusiaSounds(EntityUid uid) var newCoords = Transform(uid).Coordinates.Offset(randomOffset); // Play the sound - paracusia.Stream = _audio.PlayStatic(paracusia.Sounds, uid, newCoords).Value.Entity; + paracusia.Stream = _audio.PlayStatic(paracusia.Sounds, uid, newCoords)?.Entity; } } diff --git a/Content.Client/Weather/WeatherSystem.cs b/Content.Client/Weather/WeatherSystem.cs index a0e8a44f40b..975831392cb 100644 --- a/Content.Client/Weather/WeatherSystem.cs +++ b/Content.Client/Weather/WeatherSystem.cs @@ -47,10 +47,11 @@ protected override void Run(EntityUid uid, WeatherData weather, WeatherPrototype if (!Timing.IsFirstTimePredicted || weatherProto.Sound == null) return; - weather.Stream ??= _audio.PlayGlobal(weatherProto.Sound, Filter.Local(), true).Value.Entity; + weather.Stream ??= _audio.PlayGlobal(weatherProto.Sound, Filter.Local(), true)?.Entity; + + if (!TryComp(weather.Stream, out AudioComponent? comp)) + return; - var stream = weather.Stream.Value; - var comp = Comp(stream); var occlusion = 0f; // Work out tiles nearby to determine volume. @@ -115,7 +116,7 @@ protected override void Run(EntityUid uid, WeatherData weather, WeatherPrototype var alpha = GetPercent(weather, uid); alpha *= SharedAudioSystem.VolumeToGain(weatherProto.Sound.Params.Volume); - _audio.SetGain(stream, alpha, comp); + _audio.SetGain(weather.Stream, alpha, comp); comp.Occlusion = occlusion; } diff --git a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs index 9f43f760185..1ac02ac8825 100644 --- a/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/MicrowaveSystem.cs @@ -112,7 +112,7 @@ private void OnCookStart(Entity ent, ref ComponentStar SetAppearance(ent.Owner, MicrowaveVisualState.Cooking, microwaveComponent); microwaveComponent.PlayingStream = - _audio.PlayPvs(microwaveComponent.LoopingSound, ent, AudioParams.Default.WithLoop(true).WithMaxDistance(5)).Value.Entity; + _audio.PlayPvs(microwaveComponent.LoopingSound, ent, AudioParams.Default.WithLoop(true).WithMaxDistance(5))?.Entity; } private void OnCookStop(Entity ent, ref ComponentShutdown args) diff --git a/Content.Server/Kitchen/EntitySystems/ReagentGrinderSystem.cs b/Content.Server/Kitchen/EntitySystems/ReagentGrinderSystem.cs index 71536ddf8eb..12c5a30a4b2 100644 --- a/Content.Server/Kitchen/EntitySystems/ReagentGrinderSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/ReagentGrinderSystem.cs @@ -305,7 +305,7 @@ private void DoWork(EntityUid uid, ReagentGrinderComponent reagentGrinder, Grind active.Program = program; reagentGrinder.AudioStream = _audioSystem.PlayPvs(sound, uid, - AudioParams.Default.WithPitchScale(1 / reagentGrinder.WorkTimeMultiplier)).Value.Entity; //slightly higher pitched + AudioParams.Default.WithPitchScale(1 / reagentGrinder.WorkTimeMultiplier))?.Entity; //slightly higher pitched _userInterfaceSystem.ServerSendUiMessage(uid, ReagentGrinderUiKey.Key, new ReagentGrinderWorkStartedMessage(program)); } diff --git a/Content.Server/Mech/Equipment/EntitySystems/MechGrabberSystem.cs b/Content.Server/Mech/Equipment/EntitySystems/MechGrabberSystem.cs index aa28a8063c0..08120f5c296 100644 --- a/Content.Server/Mech/Equipment/EntitySystems/MechGrabberSystem.cs +++ b/Content.Server/Mech/Equipment/EntitySystems/MechGrabberSystem.cs @@ -155,7 +155,7 @@ private void OnInteract(EntityUid uid, MechGrabberComponent component, UserActiv return; args.Handled = true; - component.AudioStream = _audio.PlayPvs(component.GrabSound, uid).Value.Entity; + component.AudioStream = _audio.PlayPvs(component.GrabSound, uid)?.Entity; var doAfterArgs = new DoAfterArgs(EntityManager, args.User, component.GrabDelay, new GrabberDoAfterEvent(), uid, target: target, used: uid) { BreakOnMove = true diff --git a/Content.Server/Salvage/SalvageSystem.Runner.cs b/Content.Server/Salvage/SalvageSystem.Runner.cs index 23a575413ed..921d9667094 100644 --- a/Content.Server/Salvage/SalvageSystem.Runner.cs +++ b/Content.Server/Salvage/SalvageSystem.Runner.cs @@ -154,8 +154,8 @@ private void UpdateRunner() } else if (comp.Stream == null && remaining < audioLength) { - var audio = _audio.PlayPvs(comp.Sound, uid).Value; - comp.Stream = audio.Entity; + var audio = _audio.PlayPvs(comp.Sound, uid); + comp.Stream = audio?.Entity; _audio.SetMapAudio(audio); comp.Stage = ExpeditionStage.MusicCountdown; Dirty(uid, comp); diff --git a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs index e544c1538d1..ce6a914847f 100644 --- a/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs +++ b/Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs @@ -397,7 +397,8 @@ private void UpdateFTLStarting(Entity entity) new EntityCoordinates(fromMapUid.Value, _mapSystem.GetGridPosition(entity.Owner)), true, startupAudio.Params); _audio.SetPlaybackPosition(clippedAudio, entity.Comp1.StartupTime); - clippedAudio.Value.Component.Flags |= AudioFlags.NoOcclusion; + if (clippedAudio != null) + clippedAudio.Value.Component.Flags |= AudioFlags.NoOcclusion; } // Offset the start by buffer range just to avoid overlap. From ba94df3dcb77c9e6563cdcb498eb8b42b5204737 Mon Sep 17 00:00:00 2001 From: Winkarst <74284083+Winkarst-cpu@users.noreply.github.com> Date: Wed, 18 Sep 2024 04:49:37 +0300 Subject: [PATCH 064/138] Use TurfSystem.IsTileBlocked instead of TurfHelpers (#32174) * Use TurfSystem.IsTileBlocked instead of TurfHelpers * ! --- .../Engineering/EntitySystems/SpawnAfterInteractSystem.cs | 4 +++- Content.Server/Respawn/SpecialRespawnSystem.cs | 7 +++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Content.Server/Engineering/EntitySystems/SpawnAfterInteractSystem.cs b/Content.Server/Engineering/EntitySystems/SpawnAfterInteractSystem.cs index 8391e8faada..407f877515a 100644 --- a/Content.Server/Engineering/EntitySystems/SpawnAfterInteractSystem.cs +++ b/Content.Server/Engineering/EntitySystems/SpawnAfterInteractSystem.cs @@ -4,6 +4,7 @@ using Content.Shared.DoAfter; using Content.Shared.Interaction; using Content.Shared.Maps; +using Content.Shared.Physics; using Content.Shared.Stacks; using JetBrains.Annotations; using Robust.Shared.Map.Components; @@ -15,6 +16,7 @@ public sealed class SpawnAfterInteractSystem : EntitySystem { [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; [Dependency] private readonly StackSystem _stackSystem = default!; + [Dependency] private readonly TurfSystem _turfSystem = default!; public override void Initialize() { @@ -36,7 +38,7 @@ private async void HandleAfterInteract(EntityUid uid, SpawnAfterInteractComponen bool IsTileClear() { - return tileRef.Tile.IsEmpty == false && !tileRef.IsBlockedTurf(true); + return tileRef.Tile.IsEmpty == false && !_turfSystem.IsTileBlocked(tileRef, CollisionGroup.MobMask); } if (!IsTileClear()) diff --git a/Content.Server/Respawn/SpecialRespawnSystem.cs b/Content.Server/Respawn/SpecialRespawnSystem.cs index 8c86449008a..6d398db259d 100644 --- a/Content.Server/Respawn/SpecialRespawnSystem.cs +++ b/Content.Server/Respawn/SpecialRespawnSystem.cs @@ -2,16 +2,15 @@ using Content.Server.Atmos.EntitySystems; using Content.Server.Chat.Managers; using Content.Server.GameTicking; -using Content.Shared.Station.Components; -using Content.Server.Station.Systems; using Content.Shared.Database; using Content.Shared.Maps; using Content.Shared.Physics; using Content.Shared.Respawn; +using Content.Shared.Station.Components; using Robust.Shared.Map; using Robust.Shared.Map.Components; -using Robust.Shared.Random; using Robust.Shared.Prototypes; +using Robust.Shared.Random; namespace Content.Server.Respawn; @@ -179,7 +178,7 @@ public bool TryFindRandomTile(EntityUid targetGrid, EntityUid targetMap, int max foreach (var newTileRef in grid.GetTilesIntersecting(circle)) { - if (newTileRef.IsSpace(_tileDefinitionManager) || newTileRef.IsBlockedTurf(true) || !_atmosphere.IsTileMixtureProbablySafe(targetGrid, targetMap, mapTarget)) + if (newTileRef.IsSpace(_tileDefinitionManager) || _turf.IsTileBlocked(newTileRef, CollisionGroup.MobMask) || !_atmosphere.IsTileMixtureProbablySafe(targetGrid, targetMap, mapTarget)) continue; found = true; From adbd28ffe79164bacecc4db97c0e8e6f52b9384c Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:32:16 +1000 Subject: [PATCH 065/138] Update submodule to 235.0.0 (#32265) --- Resources/Prototypes/Entities/Mobs/Player/silicon.yml | 6 +++--- RobustToolbox | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index 62dbf3ee106..493cfdf6cb6 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -2,7 +2,7 @@ - type: entity id: AiHeld description: Components added / removed from an entity that gets inserted into an AI core. - noSpawn: true + categories: [ HideSpawnMenu ] components: - type: IntrinsicRadioReceiver - type: IntrinsicRadioTransmitter @@ -341,7 +341,7 @@ - type: entity id: StationAiBrain parent: PositronicBrain - noSpawn: true + categories: [ HideSpawnMenu ] suffix: DO NOT MAP components: - type: Sprite @@ -382,7 +382,7 @@ id: StationAiHolo name: AI eye description: The AI's viewer. - noSpawn: true + categories: [ HideSpawnMenu ] suffix: DO NOT MAP components: - type: NoFTL diff --git a/RobustToolbox b/RobustToolbox index 0f60ad9018f..c86cb0b7951 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit 0f60ad9018f54f9b49da1810bbffa01e2c5975f7 +Subproject commit c86cb0b7951cc4a662c7292138c5f45d868c5f58 From bc8c5228efadc32018c5bc3da4912c8da486d960 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 18 Sep 2024 15:28:09 +0200 Subject: [PATCH 066/138] New publish workflow for Robust.Cdn (#32222) This uses multiple API requests to directly send the publish to the CDN server, no more GitHub artifacts. Faster, less moving parts. Needs Robust.Cdn 2.2.0 --- .github/workflows/publish.yml | 18 +------- Tools/publish_multi_request.py | 78 ++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 17 deletions(-) create mode 100644 Tools/publish_multi_request.py diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 16cb5017d6a..d08ae135020 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -41,21 +41,10 @@ jobs: - name: Package client run: dotnet run --project Content.Packaging client --no-wipe-release - - name: Upload build artifact - id: artifact-upload-step - uses: actions/upload-artifact@v4 - with: - name: build - path: release/*.zip - compression-level: 0 - retention-days: 0 - - name: Publish version - run: Tools/publish_github_artifact.py + run: Tools/publish_multi_request.py env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }} - ARTIFACT_ID: ${{ steps.artifact-upload-step.outputs.artifact-id }} GITHUB_REPOSITORY: ${{ vars.GITHUB_REPOSITORY }} - name: Publish changelog (Discord) @@ -68,8 +57,3 @@ jobs: run: Tools/actions_changelog_rss.py env: CHANGELOG_RSS_KEY: ${{ secrets.CHANGELOG_RSS_KEY }} - - - uses: geekyeggo/delete-artifact@v5 - if: always() - with: - name: build diff --git a/Tools/publish_multi_request.py b/Tools/publish_multi_request.py new file mode 100644 index 00000000000..a63359afd6c --- /dev/null +++ b/Tools/publish_multi_request.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 + +import requests +import os +import subprocess +from typing import Iterable + +PUBLISH_TOKEN = os.environ["PUBLISH_TOKEN"] +VERSION = os.environ["GITHUB_SHA"] + +RELEASE_DIR = "release" + +# +# CONFIGURATION PARAMETERS +# Forks should change these to publish to their own infrastructure. +# +ROBUST_CDN_URL = "https://wizards.cdn.spacestation14.com/" +FORK_ID = "wizards" + +def main(): + session = requests.Session() + session.headers = { + "Authorization": f"Bearer {PUBLISH_TOKEN}", + } + + print(f"Starting publish on Robust.Cdn for version {VERSION}") + + data = { + "version": VERSION, + "engineVersion": get_engine_version(), + } + headers = { + "Content-Type": "application/json" + } + resp = session.post(f"{ROBUST_CDN_URL}fork/{FORK_ID}/publish/start", json=data, headers=headers) + resp.raise_for_status() + print("Publish successfully started, adding files...") + + for file in get_files_to_publish(): + print(f"Publishing {file}") + with open(file, "rb") as f: + headers = { + "Content-Type": "application/octet-stream", + "Robust-Cdn-Publish-File": os.path.basename(file), + "Robust-Cdn-Publish-Version": VERSION + } + resp = session.post(f"{ROBUST_CDN_URL}fork/{FORK_ID}/publish/file", data=f, headers=headers) + + resp.raise_for_status() + + print("Successfully pushed files, finishing publish...") + + data = { + "version": VERSION + } + headers = { + "Content-Type": "application/json" + } + resp = session.post(f"{ROBUST_CDN_URL}fork/{FORK_ID}/publish/finish", json=data, headers=headers) + resp.raise_for_status() + + print("SUCCESS!") + + +def get_files_to_publish() -> Iterable[str]: + for file in os.listdir(RELEASE_DIR): + yield os.path.join(RELEASE_DIR, file) + + +def get_engine_version() -> str: + proc = subprocess.run(["git", "describe","--tags", "--abbrev=0"], stdout=subprocess.PIPE, cwd="RobustToolbox", check=True, encoding="UTF-8") + tag = proc.stdout.strip() + assert tag.startswith("v") + return tag[1:] # Cut off v prefix. + + +if __name__ == '__main__': + main() From f3a6a99a368ce56e6960646107ea5088327cbad7 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Wed, 18 Sep 2024 16:09:25 +0200 Subject: [PATCH 067/138] chmod +x publish_multi_request.py (#32274) Fuck. --- Tools/publish_multi_request.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 Tools/publish_multi_request.py diff --git a/Tools/publish_multi_request.py b/Tools/publish_multi_request.py old mode 100644 new mode 100755 From 5d946c58cc001fbe1b0bd6da07a4e82a13e7dd94 Mon Sep 17 00:00:00 2001 From: AsnDen <75905158+AsnDen@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:54:00 +0300 Subject: [PATCH 068/138] ghost-role-information-silicon-rules (#32275) changes missing ghost-role-information-rules-default-silicon to ghost-role-information-silicon-rules --- Resources/Prototypes/Entities/Mobs/Player/silicon.yml | 4 ++-- .../Devices/Syndicate_Gadgets/reinforcement_teleporter.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml index 493cfdf6cb6..15878a4017d 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/silicon.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/silicon.yml @@ -462,7 +462,7 @@ - type: GhostRole name: ghost-role-information-syndicate-cyborg-assault-name description: ghost-role-information-syndicate-cyborg-description - rules: ghost-role-information-rules-default-silicon + rules: ghost-role-information-silicon-rules raffle: settings: default - type: GhostTakeoverAvailable @@ -495,7 +495,7 @@ - type: GhostRole name: ghost-role-information-syndicate-cyborg-saboteur-name description: ghost-role-information-syndicate-cyborg-description - rules: ghost-role-information-rules-default-silicon + rules: ghost-role-information-silicon-rules raffle: settings: default - type: GhostTakeoverAvailable diff --git a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml index 1a7a02e7337..71f98d81c96 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Syndicate_Gadgets/reinforcement_teleporter.yml @@ -100,7 +100,7 @@ - type: GhostRole name: ghost-role-information-syndicate-cyborg-assault-name description: ghost-role-information-syndicate-cyborg-description - rules: ghost-role-information-rules-default-silicon + rules: ghost-role-information-silicon-rules raffle: settings: default - type: GhostRoleMobSpawner From 849a96ce582b61c11ebbc06b70e74e1edde4a7d1 Mon Sep 17 00:00:00 2001 From: Calecute <34964590+Calecute@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:15:34 -0300 Subject: [PATCH 069/138] Fix guidebook cakebatter recipe (#32276) Bugfix: Add 5 milk to cake batter recipe in the guidebook to correctly reflect new recipe --- Resources/ServerInfo/Guidebook/Service/FoodRecipes.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/ServerInfo/Guidebook/Service/FoodRecipes.xml b/Resources/ServerInfo/Guidebook/Service/FoodRecipes.xml index 3eb9c2ca2f2..7e5e20139b0 100644 --- a/Resources/ServerInfo/Guidebook/Service/FoodRecipes.xml +++ b/Resources/ServerInfo/Guidebook/Service/FoodRecipes.xml @@ -13,7 +13,7 @@ WARNING: This is not an automatically generated list, things here may become out - Tortila Dough = 15 Cornmeal, 10 Water - Tofu = 5 Enzyme (Catalyst), 30 Soy Milk - Pie Dough = 2 Eggs (12u), 15 Flour, 5 Table Salt -- Cake Batter = 2 Eggs(12u), 15 flour, 5 Sugar +- Cake Batter = 2 Eggs(12u), 15 flour, 5 Sugar, 5 Milk - Vegan Cake Batter = 15 Soy Milk, 15 Flour, 5 Sugar - Butter = 30 Milk, 5 Table Salt (Catalyst) - Cheese Wheel = 5 Enzyme (Catalyst), 40 Milk From f3b5be83226db4b458e1c98bb1ffaf22bc57e2ca Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 18 Sep 2024 15:16:42 +0000 Subject: [PATCH 070/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 46f7200cc34..be43273f6e7 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Plykiya - changes: - - message: You can now drop food and drinks to stop consuming it. - type: Fix - id: 6891 - time: '2024-07-09T23:12:40.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29854 - author: Boaz1111 changes: - message: Guitars can now be worn in the suit storage slot @@ -3885,3 +3878,10 @@ id: 7390 time: '2024-09-17T22:09:55.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31951 +- author: Calecute + changes: + - message: Corrected cake batter recipe in guidebook + type: Fix + id: 7391 + time: '2024-09-18T15:15:34.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32276 From 724456d0995d3f205a7b54f7ede1ef3bbb23bafd Mon Sep 17 00:00:00 2001 From: chavonadelal <156101927+chavonadelal@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:10:53 +0300 Subject: [PATCH 071/138] Wires ui tooltip localization (#32284) * Wires ui tooltip localization * Corrections after review --- Content.Client/Wires/UI/WiresMenu.cs | 9 +-------- .../Locale/en-US/wires/components/wires-component.ftl | 6 ++++++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Content.Client/Wires/UI/WiresMenu.cs b/Content.Client/Wires/UI/WiresMenu.cs index eccc548297c..77fc3accceb 100644 --- a/Content.Client/Wires/UI/WiresMenu.cs +++ b/Content.Client/Wires/UI/WiresMenu.cs @@ -584,17 +584,10 @@ public StatusLight(StatusLightData data, IResourceCache resourceCache) private sealed class HelpPopup : Popup { - private const string Text = "Click on the gold contacts with a multitool in hand to pulse their wire.\n" + - "Click on the wires with a pair of wirecutters in hand to cut/mend them.\n\n" + - "The lights at the top show the state of the machine, " + - "messing with wires will probably do stuff to them.\n" + - "Wire layouts are different each round, " + - "but consistent between machines of the same type."; - public HelpPopup() { var label = new RichTextLabel(); - label.SetMessage(Text); + label.SetMessage(Loc.GetString("wires-menu-help-popup")); AddChild(new PanelContainer { StyleClasses = {ExamineSystem.StyleClassEntityTooltip}, diff --git a/Resources/Locale/en-US/wires/components/wires-component.ftl b/Resources/Locale/en-US/wires/components/wires-component.ftl index be27c270bb4..e98e5c21cab 100644 --- a/Resources/Locale/en-US/wires/components/wires-component.ftl +++ b/Resources/Locale/en-US/wires/components/wires-component.ftl @@ -10,3 +10,9 @@ wires-component-ui-on-receive-message-cannot-mend-uncut-wire = You can't mend a wires-menu-name-label = Wires wires-menu-dead-beef-text = DEAD-BEEF +wires-menu-help-popup = + Click on the gold contacts with a multitool in hand to pulse their wire. + Click on the wires with a pair of wirecutters in hand to cut/mend them. + + The lights at the top show the state of the machine, messing with wires will probably do stuff to them. + Wire layouts are different each round, but consistent between machines of the same type. From 418ced15308f981bb1415940dad3269e704fc82e Mon Sep 17 00:00:00 2001 From: chavonadelal <156101927+chavonadelal@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:16:47 +0300 Subject: [PATCH 072/138] Localization of the shuttle call sender (#32286) --- Content.Server/RoundEnd/RoundEndSystem.cs | 6 +++--- Resources/Locale/en-US/round-end/round-end-system.ftl | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Content.Server/RoundEnd/RoundEndSystem.cs b/Content.Server/RoundEnd/RoundEndSystem.cs index 82bdb78816f..bb5934f3f08 100644 --- a/Content.Server/RoundEnd/RoundEndSystem.cs +++ b/Content.Server/RoundEnd/RoundEndSystem.cs @@ -125,7 +125,7 @@ public bool IsRoundEndRequested() return _countdownTokenSource != null; } - public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "Station") + public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement") { var duration = DefaultCountdownDuration; @@ -143,7 +143,7 @@ public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = tr RequestRoundEnd(duration, requester, checkCooldown, text, name); } - public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "Station") + public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement") { if (_gameTicker.RunLevel != GameRunLevel.InRound) return; @@ -183,7 +183,7 @@ public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, _chatSystem.DispatchGlobalAnnouncement(Loc.GetString(text, ("time", time), ("units", Loc.GetString(units))), - name, + Loc.GetString(name), false, null, Color.Gold); diff --git a/Resources/Locale/en-US/round-end/round-end-system.ftl b/Resources/Locale/en-US/round-end/round-end-system.ftl index f86851506bc..30069f71713 100644 --- a/Resources/Locale/en-US/round-end/round-end-system.ftl +++ b/Resources/Locale/en-US/round-end/round-end-system.ftl @@ -4,6 +4,7 @@ round-end-system-shuttle-called-announcement = An emergency shuttle has been sen round-end-system-shuttle-already-called-announcement = An emergency shuttle has already been sent. round-end-system-shuttle-auto-called-announcement = An automatic crew shift change shuttle has been sent. ETA: {$time} {$units}. Recall the shuttle to extend the shift. round-end-system-shuttle-recalled-announcement = The emergency shuttle has been recalled. +round-end-system-shuttle-sender-announcement = Station round-end-system-round-restart-eta-announcement = Restarting the round in {$time} {$units}... eta-units-minutes = minutes From 6c07f3f72b85ea40d4e14a27c59c1533a6440cbe Mon Sep 17 00:00:00 2001 From: Skarletto <122584947+Skarletto@users.noreply.github.com> Date: Wed, 18 Sep 2024 17:51:11 -0400 Subject: [PATCH 073/138] change jamjar glasses description (#32215) nerds only please --- Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml index f8912995629..c900464076b 100644 --- a/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml +++ b/Resources/Prototypes/Entities/Clothing/Eyes/glasses.yml @@ -103,7 +103,7 @@ parent: ClothingEyesBase id: ClothingEyesGlassesJamjar name: jamjar glasses - description: Also known as Virginity Protectors. + description: These retro glasses remind you of a simpler time. components: - type: Sprite sprite: Clothing/Eyes/Glasses/jamjar.rsi From 669764124356960d95a0ab1a9b4a62060b3f9369 Mon Sep 17 00:00:00 2001 From: beck-thompson <107373427+beck-thompson@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:58:58 -0700 Subject: [PATCH 074/138] Fix recycler eating materials (Salvage mains rejoice) (#32144) first commit --- Resources/Prototypes/Entities/Structures/Machines/recycler.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Resources/Prototypes/Entities/Structures/Machines/recycler.yml b/Resources/Prototypes/Entities/Structures/Machines/recycler.yml index 8bbbad6c0d1..f62923fe2af 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/recycler.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/recycler.yml @@ -85,6 +85,7 @@ volume: -3 cutOffSound: false - type: MaterialStorage + insertOnInteract: false - type: Conveyor - type: Rotatable - type: Repairable From df8a2be5f61e7247760284d705a4dfc04a3ca220 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 18 Sep 2024 22:00:05 +0000 Subject: [PATCH 075/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index be43273f6e7..0f906992583 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Boaz1111 - changes: - - message: Guitars can now be worn in the suit storage slot - type: Add - id: 6892 - time: '2024-07-09T23:28:10.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29048 - author: Winkarst-cpu changes: - message: Fixed popup spam when trying to open borg's UI while the borg is locked. @@ -3885,3 +3878,10 @@ id: 7391 time: '2024-09-18T15:15:34.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32276 +- author: Beck Thompson + changes: + - message: Recycler no longer allows basic materials to be inserted into it. + type: Fix + id: 7392 + time: '2024-09-18T21:58:59.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32144 From e331842c013fe6e9b05782470bc1eb1ad1e139da Mon Sep 17 00:00:00 2001 From: chavonadelal <156101927+chavonadelal@users.noreply.github.com> Date: Thu, 19 Sep 2024 01:21:53 +0300 Subject: [PATCH 076/138] Localization cooldown/remaining string in alerts (#32282) Cooldown localization --- Content.Client/Actions/UI/ActionAlertTooltip.cs | 2 +- Resources/Locale/en-US/actions/ui/actionslot.ftl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Client/Actions/UI/ActionAlertTooltip.cs b/Content.Client/Actions/UI/ActionAlertTooltip.cs index f805f6643d2..2425cdefb91 100644 --- a/Content.Client/Actions/UI/ActionAlertTooltip.cs +++ b/Content.Client/Actions/UI/ActionAlertTooltip.cs @@ -101,7 +101,7 @@ protected override void FrameUpdate(FrameEventArgs args) { var duration = Cooldown.Value.End - Cooldown.Value.Start; - if (!FormattedMessage.TryFromMarkup($"[color=#a10505]{(int) duration.TotalSeconds} sec cooldown ({(int) timeLeft.TotalSeconds + 1} sec remaining)[/color]", out var markup)) + if (!FormattedMessage.TryFromMarkup(Loc.GetString("ui-actionslot-duration", ("duration", (int)duration.TotalSeconds), ("timeLeft", (int)timeLeft.TotalSeconds + 1)), out var markup)) return; _cooldownLabel.SetMessage(markup); diff --git a/Resources/Locale/en-US/actions/ui/actionslot.ftl b/Resources/Locale/en-US/actions/ui/actionslot.ftl index 332054f10e9..c0deaad248c 100644 --- a/Resources/Locale/en-US/actions/ui/actionslot.ftl +++ b/Resources/Locale/en-US/actions/ui/actionslot.ftl @@ -1,2 +1,2 @@ ui-actionslot-charges = Uses left: {$charges} - +ui-actionslot-duration = [color=#a10505] {$duration} sec cooldown ({$timeLeft} sec remaining)[/color] From 3a1d442e67ab4cdec818b4e43752d259acdafc3c Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Wed, 18 Sep 2024 22:36:44 +0000 Subject: [PATCH 077/138] add interaction success/failure events (#32216) * add interaction success/failure events * pro --------- Co-authored-by: deltanedas <@deltanedas:kde.org> --- .../Interaction/Events/InteractionFailureEvent.cs | 7 +++++++ .../Interaction/Events/InteractionSuccessEvent.cs | 7 +++++++ Content.Shared/Interaction/InteractionPopupSystem.cs | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 Content.Shared/Interaction/Events/InteractionFailureEvent.cs create mode 100644 Content.Shared/Interaction/Events/InteractionSuccessEvent.cs diff --git a/Content.Shared/Interaction/Events/InteractionFailureEvent.cs b/Content.Shared/Interaction/Events/InteractionFailureEvent.cs new file mode 100644 index 00000000000..a820048104d --- /dev/null +++ b/Content.Shared/Interaction/Events/InteractionFailureEvent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Interaction.Events; + +/// +/// Raised on the target when failing to pet/hug something. +/// +[ByRefEvent] +public readonly record struct InteractionFailureEvent(EntityUid User); diff --git a/Content.Shared/Interaction/Events/InteractionSuccessEvent.cs b/Content.Shared/Interaction/Events/InteractionSuccessEvent.cs new file mode 100644 index 00000000000..da4f9e43d7d --- /dev/null +++ b/Content.Shared/Interaction/Events/InteractionSuccessEvent.cs @@ -0,0 +1,7 @@ +namespace Content.Shared.Interaction.Events; + +/// +/// Raised on the target when successfully petting/hugging something. +/// +[ByRefEvent] +public readonly record struct InteractionSuccessEvent(EntityUid User); diff --git a/Content.Shared/Interaction/InteractionPopupSystem.cs b/Content.Shared/Interaction/InteractionPopupSystem.cs index 2a742d4211b..20c079dfd8c 100644 --- a/Content.Shared/Interaction/InteractionPopupSystem.cs +++ b/Content.Shared/Interaction/InteractionPopupSystem.cs @@ -1,6 +1,7 @@ using Content.Shared.Bed.Sleep; using Content.Shared.IdentityManagement; using Content.Shared.Interaction.Components; +using Content.Shared.Interaction.Events; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Content.Shared.Popups; @@ -100,6 +101,9 @@ private void SharedInteract( if (component.InteractSuccessSpawn != null) Spawn(component.InteractSuccessSpawn, _transform.GetMapCoordinates(uid)); + + var ev = new InteractionSuccessEvent(user); + RaiseLocalEvent(target, ref ev); } else { @@ -111,6 +115,9 @@ private void SharedInteract( if (component.InteractFailureSpawn != null) Spawn(component.InteractFailureSpawn, _transform.GetMapCoordinates(uid)); + + var ev = new InteractionFailureEvent(user); + RaiseLocalEvent(target, ref ev); } if (!string.IsNullOrEmpty(component.MessagePerceivedByOthers)) From 3e3984b8c771d58f5df78eb2102f7730b236c705 Mon Sep 17 00:00:00 2001 From: deltanedas <39013340+deltanedas@users.noreply.github.com> Date: Wed, 18 Sep 2024 23:00:48 +0000 Subject: [PATCH 078/138] make epinephrine adrenaline (#32076) Co-authored-by: deltanedas <@deltanedas:kde.org> --- Resources/Prototypes/Reagents/medicine.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Resources/Prototypes/Reagents/medicine.yml b/Resources/Prototypes/Reagents/medicine.yml index defe4c1af38..21640c7aebe 100644 --- a/Resources/Prototypes/Reagents/medicine.yml +++ b/Resources/Prototypes/Reagents/medicine.yml @@ -368,6 +368,10 @@ key: KnockedDown time: 0.75 type: Remove + - !type:GenericStatusEffect + key: Adrenaline # Guess what epinephrine is... + component: IgnoreSlowOnDamage + time: 5 # lingers less than hivemind reagent to give it a niche - type: reagent id: Hyronalin From 4386f5e034079d8fcab128e8d6d0679aaca16f75 Mon Sep 17 00:00:00 2001 From: deltanedas <@deltanedas:kde.org> Date: Sun, 22 Sep 2024 02:40:58 +0100 Subject: [PATCH 079/138] change cdn to deltav --- Tools/publish_multi_request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/publish_multi_request.py b/Tools/publish_multi_request.py index a63359afd6c..03edea02b4e 100755 --- a/Tools/publish_multi_request.py +++ b/Tools/publish_multi_request.py @@ -14,8 +14,8 @@ # CONFIGURATION PARAMETERS # Forks should change these to publish to their own infrastructure. # -ROBUST_CDN_URL = "https://wizards.cdn.spacestation14.com/" -FORK_ID = "wizards" +ROBUST_CDN_URL = "https://cdn.delta-v.org/" +FORK_ID = "delta-v" def main(): session = requests.Session() From 9118c5fa4a8052fe8357ea3a10f333527853d7f2 Mon Sep 17 00:00:00 2001 From: PJBot Date: Wed, 18 Sep 2024 23:01:54 +0000 Subject: [PATCH 080/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 0f906992583..3795ca6d59f 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Winkarst-cpu - changes: - - message: Fixed popup spam when trying to open borg's UI while the borg is locked. - type: Fix - id: 6893 - time: '2024-07-09T23:48:56.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29861 - author: Lokachop changes: - message: Scarves now count as warm clothing for the warm clothing cargo bounty. @@ -3885,3 +3878,10 @@ id: 7392 time: '2024-09-18T21:58:59.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/32144 +- author: deltanedas + changes: + - message: Epinephrine now adds Adrenaline, because it is. + type: Tweak + id: 7393 + time: '2024-09-18T23:00:48.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32076 From a8c2444a665907b0438b5aad4053cea84eb1376d Mon Sep 17 00:00:00 2001 From: DrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com> Date: Sat, 3 Aug 2024 20:31:45 -0700 Subject: [PATCH 081/138] Add mapping editor (#23427) * Add mapping editor (#757) * Remove mapping actions, never again * Cleanup actions system * Jarvis, remove all references to CM14 * Fix InventoryUIController crashing when an InventoryGui is not found * Rename mapping1 to mapping * Clean up context calls * Add doc comments * Add delegate for hiding decals in the mapping screen * Jarvis mission failed * a * Add test * Fix not flushing save stream in mapping manager * change * Fix verbs * fixes * localise --------- Co-authored-by: DrSmugleaf Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth Co-authored-by: Pieter-Jan Briers --- Content.Client/Actions/ActionsSystem.cs | 2 +- Content.Client/Commands/ActionsCommands.cs | 26 +- .../Commands/MappingClientSideSetupCommand.cs | 7 +- .../ContextMenu/UI/ContextMenuUIController.cs | 38 +- .../Decals/Overlays/DecalPlacementOverlay.cs | 6 +- Content.Client/IoC/ClientContentIoC.cs | 9 +- .../Mapping/MappingActionsButton.xaml | 8 + .../Mapping/MappingActionsButton.xaml.cs | 15 + .../Mapping/MappingDoNotMeasure.xaml | 4 + .../Mapping/MappingDoNotMeasure.xaml.cs | 21 + Content.Client/Mapping/MappingManager.cs | 69 ++ Content.Client/Mapping/MappingOverlay.cs | 84 ++ Content.Client/Mapping/MappingPrototype.cs | 39 + .../Mapping/MappingPrototypeList.xaml | 21 + .../Mapping/MappingPrototypeList.xaml.cs | 170 ++++ Content.Client/Mapping/MappingScreen.xaml | 85 ++ Content.Client/Mapping/MappingScreen.xaml.cs | 197 ++++ .../Mapping/MappingSpawnButton.xaml | 26 + .../Mapping/MappingSpawnButton.xaml.cs | 16 + Content.Client/Mapping/MappingState.cs | 936 ++++++++++++++++++ Content.Client/Mapping/MappingSystem.cs | 8 - .../Systems/Actions/ActionUIController.cs | 2 +- .../Verbs/UI/VerbMenuUIController.cs | 17 +- .../Tests/MappingEditorTest.cs | 41 + Content.Server/IoC/ServerContentIoC.cs | 2 + Content.Server/Mapping/MappingManager.cs | 76 ++ Content.Shared/Decals/DecalPrototype.cs | 11 +- Content.Shared/Input/ContentKeyFunctions.cs | 9 + .../Mapping/MappingMapDataMessage.cs | 46 + .../Mapping/MappingSaveMapErrorMessage.cs | 19 + .../Mapping/MappingSaveMapMessage.cs | 19 + Resources/Locale/en-US/mapping/editor.ftl | 7 + Resources/Textures/Interface/eraser.svg | 3 + Resources/Textures/Interface/eraser.svg.png | Bin 0 -> 1706 bytes Resources/Textures/Interface/eyedropper.svg | 3 + .../Textures/Interface/eyedropper.svg.png | Bin 0 -> 1956 bytes Resources/keybinds.yml | 30 + 37 files changed, 2024 insertions(+), 48 deletions(-) create mode 100644 Content.Client/Mapping/MappingActionsButton.xaml create mode 100644 Content.Client/Mapping/MappingActionsButton.xaml.cs create mode 100644 Content.Client/Mapping/MappingDoNotMeasure.xaml create mode 100644 Content.Client/Mapping/MappingDoNotMeasure.xaml.cs create mode 100644 Content.Client/Mapping/MappingManager.cs create mode 100644 Content.Client/Mapping/MappingOverlay.cs create mode 100644 Content.Client/Mapping/MappingPrototype.cs create mode 100644 Content.Client/Mapping/MappingPrototypeList.xaml create mode 100644 Content.Client/Mapping/MappingPrototypeList.xaml.cs create mode 100644 Content.Client/Mapping/MappingScreen.xaml create mode 100644 Content.Client/Mapping/MappingScreen.xaml.cs create mode 100644 Content.Client/Mapping/MappingSpawnButton.xaml create mode 100644 Content.Client/Mapping/MappingSpawnButton.xaml.cs create mode 100644 Content.Client/Mapping/MappingState.cs create mode 100644 Content.IntegrationTests/Tests/MappingEditorTest.cs create mode 100644 Content.Server/Mapping/MappingManager.cs create mode 100644 Content.Shared/Mapping/MappingMapDataMessage.cs create mode 100644 Content.Shared/Mapping/MappingSaveMapErrorMessage.cs create mode 100644 Content.Shared/Mapping/MappingSaveMapMessage.cs create mode 100644 Resources/Locale/en-US/mapping/editor.ftl create mode 100644 Resources/Textures/Interface/eraser.svg create mode 100644 Resources/Textures/Interface/eraser.svg.png create mode 100644 Resources/Textures/Interface/eyedropper.svg create mode 100644 Resources/Textures/Interface/eyedropper.svg.png diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 889447eba59..b36b0031091 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -301,7 +301,7 @@ public void LoadActionAssignments(string path, bool userData) continue; var action = _serialization.Read(actionNode, notNullableOverride: true); - var actionId = Spawn(null); + var actionId = Spawn(); AddComp(actionId, action); AddActionDirect(user, actionId); diff --git a/Content.Client/Commands/ActionsCommands.cs b/Content.Client/Commands/ActionsCommands.cs index dd489fd4d65..87f35bd26e2 100644 --- a/Content.Client/Commands/ActionsCommands.cs +++ b/Content.Client/Commands/ActionsCommands.cs @@ -1,4 +1,4 @@ -using System.IO; +using Content.Client.Actions; using Content.Client.Actions; using Content.Client.Mapping; using Content.Shared.Administration; @@ -84,27 +84,3 @@ private static async void LoadActs() reader.Close(); } } - -[AnyCommand] -public sealed class LoadMappingActionsCommand : LocalizedCommands -{ - [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; - - public const string CommandName = "loadmapacts"; - - public override string Command => CommandName; - - public override string Help => LocalizationManager.GetString($"cmd-{Command}-help", ("command", Command)); - - public override void Execute(IConsoleShell shell, string argStr, string[] args) - { - try - { - _entitySystemManager.GetEntitySystem().LoadMappingActions(); - } - catch - { - shell.WriteError(LocalizationManager.GetString($"cmd-{Command}-error")); - } - } -} diff --git a/Content.Client/Commands/MappingClientSideSetupCommand.cs b/Content.Client/Commands/MappingClientSideSetupCommand.cs index 39268c62847..eb2d13c9540 100644 --- a/Content.Client/Commands/MappingClientSideSetupCommand.cs +++ b/Content.Client/Commands/MappingClientSideSetupCommand.cs @@ -1,6 +1,8 @@ +using Content.Client.Mapping; using Content.Client.Markers; using JetBrains.Annotations; using Robust.Client.Graphics; +using Robust.Client.State; using Robust.Shared.Console; namespace Content.Client.Commands; @@ -10,6 +12,7 @@ internal sealed class MappingClientSideSetupCommand : LocalizedCommands { [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; [Dependency] private readonly ILightManager _lightManager = default!; + [Dependency] private readonly IStateManager _stateManager = default!; public override string Command => "mappingclientsidesetup"; @@ -21,8 +24,8 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) { _entitySystemManager.GetEntitySystem().MarkersVisible = true; _lightManager.Enabled = false; - shell.ExecuteCommand(ShowSubFloorForever.CommandName); - shell.ExecuteCommand(LoadMappingActionsCommand.CommandName); + shell.ExecuteCommand("showsubfloorforever"); + _stateManager.RequestStateChange(); } } } diff --git a/Content.Client/ContextMenu/UI/ContextMenuUIController.cs b/Content.Client/ContextMenu/UI/ContextMenuUIController.cs index 5b156644a73..2d94034bb9c 100644 --- a/Content.Client/ContextMenu/UI/ContextMenuUIController.cs +++ b/Content.Client/ContextMenu/UI/ContextMenuUIController.cs @@ -2,6 +2,7 @@ using System.Threading; using Content.Client.CombatMode; using Content.Client.Gameplay; +using Content.Client.Mapping; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controllers; using Timer = Robust.Shared.Timing.Timer; @@ -16,7 +17,7 @@ namespace Content.Client.ContextMenu.UI /// /// This largely involves setting up timers to open and close sub-menus when hovering over other menu elements. /// - public sealed class ContextMenuUIController : UIController, IOnStateEntered, IOnStateExited, IOnSystemChanged + public sealed class ContextMenuUIController : UIController, IOnStateEntered, IOnStateExited, IOnSystemChanged, IOnStateEntered, IOnStateExited { public static readonly TimeSpan HoverDelay = TimeSpan.FromSeconds(0.2); @@ -42,18 +43,51 @@ public sealed class ContextMenuUIController : UIController, IOnStateEntered? OnSubMenuOpened; public Action? OnContextKeyEvent; + private bool _setup; + public void OnStateEntered(GameplayState state) { + Setup(); + } + + public void OnStateExited(GameplayState state) + { + Shutdown(); + } + + public void OnStateEntered(MappingState state) + { + Setup(); + } + + public void OnStateExited(MappingState state) + { + Shutdown(); + } + + public void Setup() + { + if (_setup) + return; + + _setup = true; + RootMenu = new(this, null); RootMenu.OnPopupHide += Close; Menus.Push(RootMenu); } - public void OnStateExited(GameplayState state) + public void Shutdown() { + if (!_setup) + return; + + _setup = false; + Close(); RootMenu.OnPopupHide -= Close; RootMenu.Dispose(); + RootMenu = default!; } /// diff --git a/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs b/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs index 845bd7c03d2..07b6f57bdb9 100644 --- a/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs +++ b/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs @@ -4,6 +4,7 @@ using Robust.Client.Input; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Prototypes; namespace Content.Client.Decals.Overlays; @@ -16,7 +17,7 @@ public sealed class DecalPlacementOverlay : Overlay private readonly SharedTransformSystem _transform; private readonly SpriteSystem _sprite; - public override OverlaySpace Space => OverlaySpace.WorldSpace; + public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities; public DecalPlacementOverlay(DecalPlacementSystem placement, SharedTransformSystem transform, SpriteSystem sprite) { @@ -24,6 +25,7 @@ public DecalPlacementOverlay(DecalPlacementSystem placement, SharedTransformSyst _placement = placement; _transform = transform; _sprite = sprite; + ZIndex = 1000; } protected override void Draw(in OverlayDrawArgs args) @@ -55,7 +57,7 @@ protected override void Draw(in OverlayDrawArgs args) if (snap) { - localPos = (Vector2) localPos.Floored() + grid.TileSizeHalfVector; + localPos = localPos.Floored() + grid.TileSizeHalfVector; } // Nothing uses snap cardinals so probably don't need preview? diff --git a/Content.Client/IoC/ClientContentIoC.cs b/Content.Client/IoC/ClientContentIoC.cs index 328cf41d0d4..1fd237cf3e3 100644 --- a/Content.Client/IoC/ClientContentIoC.cs +++ b/Content.Client/IoC/ClientContentIoC.cs @@ -4,23 +4,23 @@ using Content.Client.Clickable; using Content.Client.DebugMon; using Content.Client.Eui; +using Content.Client.Fullscreen; using Content.Client.GhostKick; +using Content.Client.Guidebook; using Content.Client.Launcher; +using Content.Client.Mapping; using Content.Client.Parallax.Managers; using Content.Client.Players.PlayTimeTracking; +using Content.Client.Replay; using Content.Client.Screenshot; -using Content.Client.Fullscreen; using Content.Client.Stylesheets; using Content.Client.Viewport; using Content.Client.Voting; using Content.Shared.Administration.Logs; -using Content.Client.Guidebook; using Content.Client.Lobby; -using Content.Client.Replay; using Content.Shared.Administration.Managers; using Content.Shared.Players.PlayTimeTracking; - namespace Content.Client.IoC { internal static class ClientContentIoC @@ -49,6 +49,7 @@ public static void Register() collection.Register(); collection.Register(); collection.Register(); + collection.Register(); collection.Register(); } } diff --git a/Content.Client/Mapping/MappingActionsButton.xaml b/Content.Client/Mapping/MappingActionsButton.xaml new file mode 100644 index 00000000000..099719a70e1 --- /dev/null +++ b/Content.Client/Mapping/MappingActionsButton.xaml @@ -0,0 +1,8 @@ + + + diff --git a/Content.Client/Mapping/MappingActionsButton.xaml.cs b/Content.Client/Mapping/MappingActionsButton.xaml.cs new file mode 100644 index 00000000000..1a2f2c069f6 --- /dev/null +++ b/Content.Client/Mapping/MappingActionsButton.xaml.cs @@ -0,0 +1,15 @@ +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.Mapping; + +[GenerateTypedNameReferences] +public sealed partial class MappingActionsButton : Button +{ + public MappingActionsButton() + { + RobustXamlLoader.Load(this); + } +} + diff --git a/Content.Client/Mapping/MappingDoNotMeasure.xaml b/Content.Client/Mapping/MappingDoNotMeasure.xaml new file mode 100644 index 00000000000..08909636ee5 --- /dev/null +++ b/Content.Client/Mapping/MappingDoNotMeasure.xaml @@ -0,0 +1,4 @@ + + diff --git a/Content.Client/Mapping/MappingDoNotMeasure.xaml.cs b/Content.Client/Mapping/MappingDoNotMeasure.xaml.cs new file mode 100644 index 00000000000..c4cb560234c --- /dev/null +++ b/Content.Client/Mapping/MappingDoNotMeasure.xaml.cs @@ -0,0 +1,21 @@ +using System.Numerics; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; + +namespace Content.Client.Mapping; + +[GenerateTypedNameReferences] +public sealed partial class MappingDoNotMeasure : Control +{ + public MappingDoNotMeasure() + { + RobustXamlLoader.Load(this); + } + + protected override Vector2 MeasureOverride(Vector2 availableSize) + { + return Vector2.Zero; + } +} + diff --git a/Content.Client/Mapping/MappingManager.cs b/Content.Client/Mapping/MappingManager.cs new file mode 100644 index 00000000000..1aac02be714 --- /dev/null +++ b/Content.Client/Mapping/MappingManager.cs @@ -0,0 +1,69 @@ +using System.IO; +using System.Text; +using System.Threading.Tasks; +using Content.Shared.Mapping; +using Robust.Client.UserInterface; +using Robust.Shared.Network; + +namespace Content.Client.Mapping; + +public sealed class MappingManager : IPostInjectInit +{ + [Dependency] private readonly IFileDialogManager _file = default!; + [Dependency] private readonly IClientNetManager _net = default!; + + private Stream? _saveStream; + private MappingMapDataMessage? _mapData; + + public void PostInject() + { + _net.RegisterNetMessage(); + _net.RegisterNetMessage(OnSaveError); + _net.RegisterNetMessage(OnMapData); + } + + private void OnSaveError(MappingSaveMapErrorMessage message) + { + _saveStream?.DisposeAsync(); + _saveStream = null; + } + + private async void OnMapData(MappingMapDataMessage message) + { + if (_saveStream == null) + { + _mapData = message; + return; + } + + await _saveStream.WriteAsync(Encoding.ASCII.GetBytes(message.Yml)); + await _saveStream.DisposeAsync(); + + _saveStream = null; + _mapData = null; + } + + public async Task SaveMap() + { + if (_saveStream != null) + await _saveStream.DisposeAsync(); + + var request = new MappingSaveMapMessage(); + _net.ClientSendMessage(request); + + var path = await _file.SaveFile(); + if (path is not { fileStream: var stream }) + return; + + if (_mapData != null) + { + await stream.WriteAsync(Encoding.ASCII.GetBytes(_mapData.Yml)); + _mapData = null; + await stream.FlushAsync(); + await stream.DisposeAsync(); + return; + } + + _saveStream = stream; + } +} diff --git a/Content.Client/Mapping/MappingOverlay.cs b/Content.Client/Mapping/MappingOverlay.cs new file mode 100644 index 00000000000..ef9f3e795e6 --- /dev/null +++ b/Content.Client/Mapping/MappingOverlay.cs @@ -0,0 +1,84 @@ +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Client.Player; +using Robust.Client.UserInterface; +using Robust.Shared.Enums; +using Robust.Shared.Prototypes; +using static Content.Client.Mapping.MappingState; + +namespace Content.Client.Mapping; + +public sealed class MappingOverlay : Overlay +{ + [Dependency] private readonly IEntityManager _entities = default!; + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IPrototypeManager _prototypes = default!; + + // 1 off in case something else uses these colors since we use them to compare + private static readonly Color PickColor = new(1, 255, 0); + private static readonly Color DeleteColor = new(255, 1, 0); + + private readonly Dictionary _oldColors = new(); + + private readonly MappingState _state; + private readonly ShaderInstance _shader; + + public override OverlaySpace Space => OverlaySpace.WorldSpace; + + public MappingOverlay(MappingState state) + { + IoCManager.InjectDependencies(this); + + _state = state; + _shader = _prototypes.Index("unshaded").Instance(); + } + + protected override void Draw(in OverlayDrawArgs args) + { + foreach (var (id, color) in _oldColors) + { + if (!_entities.TryGetComponent(id, out SpriteComponent? sprite)) + continue; + + if (sprite.Color == DeleteColor || sprite.Color == PickColor) + sprite.Color = color; + } + + _oldColors.Clear(); + + if (_player.LocalEntity == null) + return; + + var handle = args.WorldHandle; + handle.UseShader(_shader); + + switch (_state.State) + { + case CursorState.Pick: + { + if (_state.GetHoveredEntity() is { } entity && + _entities.TryGetComponent(entity, out SpriteComponent? sprite)) + { + _oldColors[entity] = sprite.Color; + sprite.Color = PickColor; + } + + break; + } + case CursorState.Delete: + { + if (_state.GetHoveredEntity() is { } entity && + _entities.TryGetComponent(entity, out SpriteComponent? sprite)) + { + _oldColors[entity] = sprite.Color; + sprite.Color = DeleteColor; + } + + break; + } + } + + handle.UseShader(null); + } +} diff --git a/Content.Client/Mapping/MappingPrototype.cs b/Content.Client/Mapping/MappingPrototype.cs new file mode 100644 index 00000000000..eff2dfab151 --- /dev/null +++ b/Content.Client/Mapping/MappingPrototype.cs @@ -0,0 +1,39 @@ +using Content.Shared.Decals; +using Content.Shared.Maps; +using Robust.Shared.Prototypes; + +namespace Content.Client.Mapping; + +/// +/// Used to represent a button's data in the mapping editor. +/// +public sealed class MappingPrototype +{ + /// + /// The prototype instance, if any. + /// Can be one of , or + /// If null, this is a top-level button (such as Entities, Tiles or Decals) + /// + public readonly IPrototype? Prototype; + + /// + /// The text to display on the UI for this button. + /// + public readonly string Name; + + /// + /// Which other prototypes (buttons) this one is nested inside of. + /// + public List? Parents; + + /// + /// Which other prototypes (buttons) are nested inside this one. + /// + public List? Children; + + public MappingPrototype(IPrototype? prototype, string name) + { + Prototype = prototype; + Name = name; + } +} diff --git a/Content.Client/Mapping/MappingPrototypeList.xaml b/Content.Client/Mapping/MappingPrototypeList.xaml new file mode 100644 index 00000000000..de311240df1 --- /dev/null +++ b/Content.Client/Mapping/MappingPrototypeList.xaml @@ -0,0 +1,21 @@ + + + + + + diff --git a/Content.Client/Pinpointer/UI/StationMapBeaconControl.xaml.cs b/Content.Client/Pinpointer/UI/StationMapBeaconControl.xaml.cs new file mode 100644 index 00000000000..a4d4055c7df --- /dev/null +++ b/Content.Client/Pinpointer/UI/StationMapBeaconControl.xaml.cs @@ -0,0 +1,50 @@ +using Content.Shared.Pinpointer; +using Robust.Client.AutoGenerated; +using Robust.Client.Graphics; +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Map; + +namespace Content.Client.Pinpointer.UI; + +[GenerateTypedNameReferences] +public sealed partial class StationMapBeaconControl : Control, IComparable +{ + [Dependency] private readonly IEntityManager _entMan = default!; + + public readonly EntityCoordinates BeaconPosition; + public Action? OnPressed; + public string? Label => BeaconNameLabel.Text; + private StyleBoxFlat _styleBox; + public Color Color => _styleBox.BackgroundColor; + + public StationMapBeaconControl(EntityUid mapUid, SharedNavMapSystem.NavMapBeacon beacon) + { + RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + BeaconPosition = new EntityCoordinates(mapUid, beacon.Position); + + _styleBox = new StyleBoxFlat { BackgroundColor = beacon.Color }; + ColorPanel.PanelOverride = _styleBox; + BeaconNameLabel.Text = beacon.Text; + + MainButton.OnPressed += args => OnPressed?.Invoke(BeaconPosition); + } + + public int CompareTo(StationMapBeaconControl? other) + { + if (other == null) + return 1; + + // Group by color + var colorCompare = Color.ToArgb().CompareTo(other.Color.ToArgb()); + if (colorCompare != 0) + { + return colorCompare; + } + + // If same color, sort by text + return string.Compare(Label, other.Label); + } +} diff --git a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs index 91fb4ef71bd..3d1eb1723c3 100644 --- a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs @@ -24,9 +24,16 @@ protected override void Open() _window = this.CreateWindow(); _window.Title = EntMan.GetComponent(Owner).EntityName; + + string stationName = string.Empty; + if(EntMan.TryGetComponent(gridUid, out var gridMetaData)) + { + stationName = gridMetaData.EntityName; + } + if (EntMan.TryGetComponent(Owner, out var comp) && comp.ShowLocation) - _window.Set(gridUid, Owner); + _window.Set(stationName, gridUid, Owner); else - _window.Set(gridUid, null); + _window.Set(stationName, gridUid, null); } } diff --git a/Content.Client/Pinpointer/UI/StationMapWindow.xaml b/Content.Client/Pinpointer/UI/StationMapWindow.xaml index 00424a3566a..c79fc8f9e7b 100644 --- a/Content.Client/Pinpointer/UI/StationMapWindow.xaml +++ b/Content.Client/Pinpointer/UI/StationMapWindow.xaml @@ -3,11 +3,28 @@ xmlns:ui="clr-namespace:Content.Client.Pinpointer.UI" Title="{Loc 'station-map-window-title'}" Resizable="False" - SetSize="668 713" - MinSize="668 713"> + SetSize="868 748" + MinSize="868 748"> - + + + + + + + + + + + + + + + + + diff --git a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs index 7cbb8b7d0db..52ef2ab7da4 100644 --- a/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs +++ b/Content.Client/Pinpointer/UI/StationMapWindow.xaml.cs @@ -3,24 +3,75 @@ using Robust.Client.AutoGenerated; using Robust.Client.UserInterface.XAML; using Robust.Shared.Map; +using Content.Shared.Pinpointer; namespace Content.Client.Pinpointer.UI; [GenerateTypedNameReferences] public sealed partial class StationMapWindow : FancyWindow { + [Dependency] private readonly IEntityManager _entMan = default!; + + private readonly List _buttons = new(); + public StationMapWindow() { RobustXamlLoader.Load(this); + IoCManager.InjectDependencies(this); + + FilterBar.OnTextChanged += (bar) => OnFilterChanged(bar.Text); } - public void Set(EntityUid? mapUid, EntityUid? trackedEntity) + public void Set(string stationName, EntityUid? mapUid, EntityUid? trackedEntity) { NavMapScreen.MapUid = mapUid; if (trackedEntity != null) NavMapScreen.TrackedCoordinates.Add(new EntityCoordinates(trackedEntity.Value, Vector2.Zero), (true, Color.Cyan)); + if (!string.IsNullOrEmpty(stationName)) + { + StationName.Text = stationName; + } + NavMapScreen.ForceNavMapUpdate(); + UpdateBeaconList(mapUid); + } + + public void OnFilterChanged(string newFilter) + { + foreach (var button in _buttons) + { + button.Visible = string.IsNullOrEmpty(newFilter) || ( + !string.IsNullOrEmpty(button.Label) && + button.Label.Contains(newFilter, StringComparison.OrdinalIgnoreCase) + ); + }; + } + + public void UpdateBeaconList(EntityUid? mapUid) + { + BeaconButtons.Children.Clear(); + _buttons.Clear(); + + if (!mapUid.HasValue) + return; + + if (!_entMan.TryGetComponent(mapUid, out var navMap)) + return; + + foreach (var beacon in navMap.Beacons.Values) + { + var button = new StationMapBeaconControl(mapUid.Value, beacon); + + button.OnPressed += NavMapScreen.CenterToCoordinates; + + _buttons.Add(button); + } + + _buttons.Sort(); + + foreach (var button in _buttons) + BeaconButtons.AddChild(button); } -} +} \ No newline at end of file diff --git a/Resources/Locale/en-US/navmap-beacons/station_map.ftl b/Resources/Locale/en-US/navmap-beacons/station_map.ftl index 1563e0abaf2..e2528515566 100644 --- a/Resources/Locale/en-US/navmap-beacons/station_map.ftl +++ b/Resources/Locale/en-US/navmap-beacons/station_map.ftl @@ -1,6 +1,7 @@ station-map-window-title = Station map station-map-user-interface-flavor-left = Don't panic station-map-user-interface-flavor-right = v1.42 +station-map-filter-placeholder = Search by name nav-beacon-window-title = Station Beacon nav-beacon-toggle-visible = Visible From 3fba7bb2febf2cb7ca17f9e7bb21ad1a835c5290 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 21 Sep 2024 07:34:28 +0000 Subject: [PATCH 126/138] 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 0c4df4d2ad4..23b611255df 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: lzk228 - changes: - - message: Secure windoors now use reinforced glass damage modifier. - type: Fix - id: 6912 - time: '2024-07-13T04:03:16.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29941 - author: Tayrtahn changes: - message: Antag objective total difficulty is now properly capped. @@ -3889,3 +3882,11 @@ id: 7411 time: '2024-09-21T05:54:48.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31879 +- author: TGRCDev + changes: + - message: Station maps now have a directory for finding specific departments and + areas. + type: Add + id: 7412 + time: '2024-09-21T07:33:22.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31156 From 53e1894ffa8eda87503bd4ec40f77b4108104963 Mon Sep 17 00:00:00 2001 From: lzk <124214523+lzk228@users.noreply.github.com> Date: Sat, 21 Sep 2024 11:33:28 +0200 Subject: [PATCH 127/138] Add skirt of life in contraband medidrobe (#32214) --- .../VendingMachines/Inventories/medidrobe.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Resources/Prototypes/Catalog/VendingMachines/Inventories/medidrobe.yml b/Resources/Prototypes/Catalog/VendingMachines/Inventories/medidrobe.yml index 8364329ed95..de39f780359 100644 --- a/Resources/Prototypes/Catalog/VendingMachines/Inventories/medidrobe.yml +++ b/Resources/Prototypes/Catalog/VendingMachines/Inventories/medidrobe.yml @@ -23,8 +23,10 @@ ClothingHeadHatSurgcapBlue: 4 ClothingHeadHatSurgcapPurple: 4 ClothingShoesBootsWinterMed: 2 - contrabandInventory: #DeltaV - UniformScrubsColorCybersun: 1 #DeltaV - ClothingHeadHatSurgcapCybersun: 1 #DeltaV - ClothingOuterCoatCybersunWindbreaker: 1 #DeltaV - ClothingShoesBootsWinterMed: 2 + contrabandInventory: + ClothingUniformJumpskirtOfLife: 1 + # Begin Delta-V additions + UniformScrubsColorCybersun: 1 + ClothingHeadHatSurgcapCybersun: 1 + ClothingOuterCoatCybersunWindbreaker: 1 + # End Delta-V additions From ecee19cb0f2cefed51f1539ff13b499ce7421dc4 Mon Sep 17 00:00:00 2001 From: voidnull000 <18663194+voidnull000@users.noreply.github.com> Date: Sat, 21 Sep 2024 13:56:00 +0100 Subject: [PATCH 128/138] Fix a spelling mistake in the DonutVend's advertisments (#32348) change that one line so i never think about this again --- Resources/Locale/en-US/advertisements/vending/donut.ftl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Locale/en-US/advertisements/vending/donut.ftl b/Resources/Locale/en-US/advertisements/vending/donut.ftl index af801f621c4..53d8ee6ccb5 100644 --- a/Resources/Locale/en-US/advertisements/vending/donut.ftl +++ b/Resources/Locale/en-US/advertisements/vending/donut.ftl @@ -1,5 +1,5 @@ advertisement-donut-1 = Each of us is a little cop! -advertisement-donut-2 = Hope you're hunger! +advertisement-donut-2 = Hope you're hungry! advertisement-donut-3 = Over 1 million donuts sold! advertisement-donut-4 = We pride ourselves in the consistency of our products! advertisement-donut-5 = Sweet, sugary and delicious! From 12f12f97af1e532874fd38cc39478a4bb17bf179 Mon Sep 17 00:00:00 2001 From: Ed <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 21 Sep 2024 22:54:56 +0300 Subject: [PATCH 129/138] Flora anomaly seeds (#31987) * content * Update meta.json * Update mobspawn.yml * Update mobspawn.yml * Update Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml * Update Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml * Update Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml * Update Resources/Prototypes/Entities/Effects/mobspawn.yml --------- Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com> --- .../Locale/en-US/flavors/flavor-profiles.ftl | 1 + .../nutrition/components/food-sequence.ftl | 2 + Resources/Locale/en-US/seeds/seeds.ftl | 2 + .../Prototypes/Entities/Effects/mobspawn.yml | 56 ++++++++---------- .../Objects/Consumable/Food/produce.yml | 36 +++++++++++ .../Objects/Specific/Hydroponics/seeds.yml | 10 ++++ .../Structures/Specific/Anomaly/cores.yml | 4 ++ Resources/Prototypes/Flavors/flavors.yml | 5 ++ Resources/Prototypes/Hydroponics/seeds.yml | 31 ++++++++++ .../Recipes/Cooking/food_sequence_element.yml | 17 ++++++ .../Hydroponics/anomaly_berry.rsi/dead.png | Bin 0 -> 570 bytes .../Hydroponics/anomaly_berry.rsi/harvest.png | Bin 0 -> 589 bytes .../Hydroponics/anomaly_berry.rsi/meta.json | 29 +++++++++ .../Hydroponics/anomaly_berry.rsi/produce.png | Bin 0 -> 548 bytes .../Hydroponics/anomaly_berry.rsi/seed.png | Bin 0 -> 403 bytes .../Hydroponics/anomaly_berry.rsi/stage-1.png | Bin 0 -> 389 bytes .../Hydroponics/anomaly_berry.rsi/stage-2.png | Bin 0 -> 491 bytes 17 files changed, 161 insertions(+), 32 deletions(-) create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/dead.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/harvest.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/meta.json create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/produce.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/seed.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/stage-1.png create mode 100644 Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/stage-2.png diff --git a/Resources/Locale/en-US/flavors/flavor-profiles.ftl b/Resources/Locale/en-US/flavors/flavor-profiles.ftl index 3e7cde8449a..0ba65217ef8 100644 --- a/Resources/Locale/en-US/flavors/flavor-profiles.ftl +++ b/Resources/Locale/en-US/flavors/flavor-profiles.ftl @@ -20,6 +20,7 @@ flavor-base-fishy = fishy flavor-base-crabby = crabby flavor-base-cheesy = cheesy flavor-base-funny = funny +flavor-base-strange = strange flavor-base-tingly = tingly flavor-base-acid = acidic flavor-base-leafy = leafy diff --git a/Resources/Locale/en-US/nutrition/components/food-sequence.ftl b/Resources/Locale/en-US/nutrition/components/food-sequence.ftl index 97dd7ffcc6a..b21d2a83151 100644 --- a/Resources/Locale/en-US/nutrition/components/food-sequence.ftl +++ b/Resources/Locale/en-US/nutrition/components/food-sequence.ftl @@ -76,6 +76,7 @@ food-sequence-content-berries = berries food-sequence-content-spacemans-trumpet = spaceman's trupmet food-sequence-content-cherry = cherry food-sequence-content-snail = snail +food-sequence-content-anomaly-berry = anomaly berry # BURGERS @@ -116,6 +117,7 @@ food-sequence-burger-content-suppermatter = supper food-sequence-burger-content-hamster = hams food-sequence-burger-content-berries = berri food-sequence-burger-content-spacemans-trumpet = spacetrump +food-sequence-burger-content-anomaly-berry = anom food-sequence-burger-content-extradimensional-orange = 3d food-sequence-burger-content-world-pea = peace diff --git a/Resources/Locale/en-US/seeds/seeds.ftl b/Resources/Locale/en-US/seeds/seeds.ftl index c8d524ba1d7..1ca559db302 100644 --- a/Resources/Locale/en-US/seeds/seeds.ftl +++ b/Resources/Locale/en-US/seeds/seeds.ftl @@ -140,3 +140,5 @@ seeds-capfruit-name = capfruit seeds-capfruit-display-name = capfruit tree seeds-cherry-name = cherry seeds-cherry-display-name = cherry tree +seeds-anomaly-berry-name = anomaly berry +seeds-anomaly-berry-display-name = anomaly berries diff --git a/Resources/Prototypes/Entities/Effects/mobspawn.yml b/Resources/Prototypes/Entities/Effects/mobspawn.yml index c4396a775da..1489c26493a 100644 --- a/Resources/Prototypes/Entities/Effects/mobspawn.yml +++ b/Resources/Prototypes/Entities/Effects/mobspawn.yml @@ -82,36 +82,28 @@ tags: - HideContextMenu - type: AnimationPlayer - - type: RandomSpawner + - type: EntityTableSpawner deleteSpawnerAfterSpawn: false - rareChance: 0.1 - offset: 0.3 - chance: 1 - prototypes: - - FoodAmbrosiaVulgaris - - FoodAloe - - FoodCabbage - - FoodCarrot - - FoodGalaxythistle - - FoodLemon - - FoodLime - - FoodPeaPod - - FoodPineapple - - FoodOnionRed - - FoodWatermelon - - FoodAmbrosiaVulgaris - - FoodAloe - - FoodCabbage - - FoodCarrot - - FoodGalaxythistle - - FoodLemon - - FoodLime - - FoodPeaPod - - FoodPineapple - - FoodOnionRed - - FoodWatermelon - - FoodGatfruit - - MobTomatoKiller - rarePrototypes: - - MobLuminousEntity - - MobLuminousObject + table: !type:NestedSelector + tableId: AnomalyFloraLootTable + +- type: entityTable + id: AnomalyFloraLootTable + table: !type:GroupSelector + children: + - id: FoodAmbrosiaVulgaris + - id: FoodAloe + - id: FoodCabbage + - id: FoodGalaxythistle + - id: FoodLemon + - id: FoodLime + - id: FoodPeaPod + - id: FoodPineapple + - id: FoodOnionRed + - id: FoodWatermelon + - id: FoodCherry + - id: MobTomatoKiller + - id: MobLuminousEntity + - id: MobLuminousObject + - id: FoodGatfruit # 0.007% spawn chance. 1 / 141 + weight: 0.10 diff --git a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml index cc09b8f34d7..69a7de8963b 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/Food/produce.yml @@ -2553,3 +2553,39 @@ seedId: cherry - type: SpaceGarbage - type: BadFood + +- type: entity + name: anomaly berry + description: A strange blue fruit. Something about it doesn't seem right. + parent: FoodProduceBase + id: FoodAnomalyBerry + components: + - type: FlavorProfile + flavors: + - strange + - type: Sprite + sprite: Objects/Specific/Hydroponics/anomaly_berry.rsi + state: produce + - type: Produce + seedId: anomalyBerry + - type: Food + trash: + - EffectAnomalyFloraBulb # Random loot + - type: SolutionContainerManager + solutions: + food: + maxVol: 5 + reagents: + - ReagentId: Nutriment + Quantity: 2 + - ReagentId: Vitamin + Quantity: 2 + - ReagentId: Artifexium + Quantity: 1 + - type: Tag + tags: + - Fruit + - type: FoodSequenceElement + entries: + Taco: AnomalyBerry + Burger: AnomalyBerryBurger \ No newline at end of file diff --git a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml index 6015a8bf013..1ad3dd5bdf2 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/Hydroponics/seeds.yml @@ -725,3 +725,13 @@ seedId: cherry - type: Sprite sprite: Objects/Specific/Hydroponics/cherry.rsi + +- type: entity + parent: SeedBase + name: packet of anomaly berry seeds + id: AnomalyBerrySeeds + components: + - type: Seed + seedId: anomalyBerry + - type: Sprite + sprite: Objects/Specific/Hydroponics/anomaly_berry.rsi diff --git a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml index 71065a8e3d5..315505b81e9 100644 --- a/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml +++ b/Resources/Prototypes/Entities/Structures/Specific/Anomaly/cores.yml @@ -147,6 +147,8 @@ id: AnomalyCoreFlora suffix: Flora components: + - type: Seed + seedId: anomalyBerry - type: Sprite sprite: Structures/Specific/Anomalies/Cores/flora_core.rsi - type: PointLight @@ -307,6 +309,8 @@ id: AnomalyCoreFloraInert suffix: Flora, Inert components: + - type: Seed + seedId: anomalyBerry - type: Sprite sprite: Structures/Specific/Anomalies/Cores/flora_core.rsi - type: PointLight diff --git a/Resources/Prototypes/Flavors/flavors.yml b/Resources/Prototypes/Flavors/flavors.yml index bc0515cacab..f27d110552b 100644 --- a/Resources/Prototypes/Flavors/flavors.yml +++ b/Resources/Prototypes/Flavors/flavors.yml @@ -59,6 +59,11 @@ flavorType: Base description: flavor-base-funny +- type: flavor + id: strange + flavorType: Base + description: flavor-base-strange + - type: flavor id: tingly flavorType: Base diff --git a/Resources/Prototypes/Hydroponics/seeds.yml b/Resources/Prototypes/Hydroponics/seeds.yml index e126342df84..67cf804f2c2 100644 --- a/Resources/Prototypes/Hydroponics/seeds.yml +++ b/Resources/Prototypes/Hydroponics/seeds.yml @@ -1952,3 +1952,34 @@ Min: 1 Max: 3 PotencyDivisor: 40 + +- type: seed + id: anomalyBerry + name: seeds-anomaly-berry-name + noun: seeds-noun-seeds + displayName: seeds-anomaly-berry-display-name + plantRsi: Objects/Specific/Hydroponics/anomaly_berry.rsi + packetPrototype: AnomalyBerrySeeds + productPrototypes: + - FoodAnomalyBerry + lifespan: 25 + maturation: 12 + production: 3 + yield: 3 + potency: 10 + growthStages: 2 + waterConsumption: 0.60 + nutrientConsumption: 0.50 + chemicals: + Artifexium: + Min: 1 + Max: 1 + PotencyDivisor: 4 + Nutriment: + Min: 1 + Max: 2 + PotencyDivisor: 30 + Vitamin: + Min: 1 + Max: 2 + PotencyDivisor: 40 diff --git a/Resources/Prototypes/Recipes/Cooking/food_sequence_element.yml b/Resources/Prototypes/Recipes/Cooking/food_sequence_element.yml index 43d6fe8852b..0654376442c 100644 --- a/Resources/Prototypes/Recipes/Cooking/food_sequence_element.yml +++ b/Resources/Prototypes/Recipes/Cooking/food_sequence_element.yml @@ -1176,3 +1176,20 @@ sprites: - sprite: Objects/Consumable/Food/Baked/cake.rsi state: suppermatter-shard + + +# Anomaly berries + +- type: foodSequenceElement + id: AnomalyBerry + name: food-sequence-content-anomaly-berry + sprites: + - sprite: Objects/Specific/Hydroponics/anomaly_berry.rsi + state: produce + +- type: foodSequenceElement + id: AnomalyBerryBurger + name: food-sequence-burger-content-anomaly-berry + sprites: + - sprite: Objects/Specific/Hydroponics/anomaly_berry.rsi + state: produce diff --git a/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/dead.png b/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/dead.png new file mode 100644 index 0000000000000000000000000000000000000000..e6082a57443e4d0e42fb264b9fc856bc78775430 GIT binary patch literal 570 zcmV-A0>%A_P)Px$^hrcPR9J=Wl`(4@K@f#MVMBxqVFgRvvBsr?gMyUk2S{K90)aZYRGTujAiaM> z+LU%@2nf=|RVtekF(jxAI!>Gf2PuMGZ3=l;yLYFv0_k$E($37@ym>P_f*d(=Z&OvbRc+Z(&`l;8uzRi+iG3XsHs-LI7R;>5CtP(S!Dn zuO|rtnKJ;ZIq;@ScJ|kPRqeXpSZB|>cU(c^_#mNz{*g9(jw?8F_IO^}1E5-d24Kl*+7(Q{QotNSlYrF%^)%G; zn+HDgAX%kJwA-rdgzA1g7Ql-sVi7Q_#|X?=K&$vz(hc#tt>aAu;_RQ=eCnwxrLyiA zcB#|=q_qdOS+$#BZnbSl$L*=la9gBJ^%f-l9n$__a{Mj+0N%zGB>2`bP5=M^07*qo IM6N<$g4Ov9Hvj+t literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/harvest.png b/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/harvest.png new file mode 100644 index 0000000000000000000000000000000000000000..5a405285d7eccb8435c44cd5b21420eb54232d34 GIT binary patch literal 589 zcmV-T0Px%2T4RhR9J=Wl`&7-Kp2LfRF-fTkSo`X>!?ebEKM?HC?lP!h=IS;U%=n#fKa#o zflR;zMwKFHz_FZ?DM*&C!*S-$c1%sX)$iuJ@B7~O{qDOnG-%MEL4*Gtt-nd$+dmZf zweLq?YSny}07d-q^CxyXTijjUa~rMz_z_NPiKs1LZ~sszVgN6&iLTcGnUFdnUepx; zu+!PX3v7d2;m!N)TD2-wj{02zaB_ax0@J-0*Z>6qo4TNC={PyRY*|&ry|Js73dv>U zRYrPamt`cs{ei{l@eKe40i%9b3@2^YQJN*V?_3-Yl2tYN-PL_1x#PjbG$x)scC{ej zVZ(5oskeEUc6rWf5Owm~aK$pYHq6Y=(u`aYE0i9A9yIEAh3#4R9{dcE#X~u4dB^H1 z{z~QqyWa?QJBUS!KPaWyEI=Qa-q>Xwr2xFz{z{S@$c?bPpmHx3GDqdwUbzUP9f~+V z10V-S6-!nJ8yzX3fRXQbQpD-;jnUyumOgy*vouT6)xZ28uio3mk?G>K=}s)f6 zU>Si!S`cew=7}$+aj8SSL;k?Z+O4iuJ{Bao-VsB9?p`O(PpocoIBDY`yA{tW?0v}uJQrnC{Rblc9m;+% b4eH`ImfsvO8U`ay00000NkvXXu0mjflzkEL literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/meta.json b/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/meta.json new file mode 100644 index 00000000000..7d86d10f9bb --- /dev/null +++ b/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/meta.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by TheShuEd for Space Station 14", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "dead" + }, + { + "name": "harvest" + }, + { + "name": "produce" + }, + { + "name": "seed" + }, + { + "name": "stage-1" + }, + { + "name": "stage-2" + } + ] +} diff --git a/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/produce.png b/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/produce.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9f83bd5929734767b8b8aa5fe3b3a7830ab630 GIT binary patch literal 548 zcmV+<0^9wGP)Px$-bqA3R9J=Wl|4_wKpe(@HBDr~0Z>pvVj!KMlY^@+DwE&9#V_G^Vc{Dv88=r4 zCuC}BNC=8AbbS%K<&!W{XGZ{>0FkM8Pv3Q>1jXXB@($`)}Yg#2lrD-x51R($g>vU%1 z_f&gm0I5n`0%cw@sWf3Sm?Cn=6s(~A;PeQ9*YP`77pV3Zr=w#Vc(Z~Zk!3XCo)mN(!MMomT zO!ZWWXhE3yZQjfOyf)c(qAh80000P)Px$O-V#SR9J=Wm9a|0P!xv0NT}(O;&4++T?*;cj)hR%N{7CKFX01p>;w1!uD(MA zaT5_7>sD~FlqQ4N#aIGyC~0eraxN-5+;6$VJvsk>|9iLrgTY|J2pTL~BKf7?KQua>eY#Y3vT3&4D`V5vrHQR&HZ zw1;qdGob3bG=mDwphDGmDaFHgH2|}*%!tUq_Eb0g4wb`w0HSG9Sg(_UIDy@Jjiw3D zkFU%p3mztSV!>Ushj6JzT$~MP_?@+Iy&L|nfz>OwNuk~iSrSrLA8U1oP%8mx^CXg+ x(Eb-l#GfL#y1W(j)_#g5by9JI!C?3oyaDU8c!|r)FpdBK002ovPDHLkV1n8!w!i=Y literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/stage-1.png b/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/stage-1.png new file mode 100644 index 0000000000000000000000000000000000000000..b6511c4e61d6ba3b1841897845ebfaa783291fca GIT binary patch literal 389 zcmV;00eb$4P)Px$KS@MER9J=Wk}*%hKp2J}3`1Q=AhiKaObFOTVCoNmQR3j=@fY}a91JUepc6Pj z35h|)f)bcY(&QZK)jF8=ESvW%cWK}I-uL_NK%>!UG#br+r=WVEcYP=7O^3PX0x*2I zRj!ew_!o1#dxG7)lAlGM5J~~0xpijXKL>0Vd+JSxce^2yy3u5oIgnBSfbC)*uW#NC z0Q20W){07v2TP@TsR25P?xK5lfKqHe_gpI0x3Nn1kn#vSc0;uLRbC%M0Lm78>~4N& zDy4fie)MnZt`8ePh5)#5OaP8A4PJ%;Wh>f?RY>56Y<#G-ii`)#!@hyhWLD_d4I#}S z>UQG;1Wes^tX)54wN(fp5vwr1XE_aNt~&N4M_Gl*(Hd5f)1Hyr95PNIY4Wuf?S3_n juUdd#0*O?iMw5Y0qf~%KmjLF~00000NkvXXu0mjfuY{&C literal 0 HcmV?d00001 diff --git a/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/stage-2.png b/Resources/Textures/Objects/Specific/Hydroponics/anomaly_berry.rsi/stage-2.png new file mode 100644 index 0000000000000000000000000000000000000000..c3ba2f74e233e31c32a42c141a982fca7e135e70 GIT binary patch literal 491 zcmVPx$rAb6VR9J=Wl)X;EP#A_EOozIdU`hj#kQlU!+KF8qB@SMI3D@BT7_Wmna4@Xg z0244Nh6M$S3DKz}O^ySe!-2Lmpb1Ogr8(#OdEf8n6jG!}ks?Kk6kA4S-GIyM2XS~* zQRjZI1wixZZtYwE#wO&>MGpJG#C!8`F0Q0mY$9T3mC<#|!gb0*o^^5^UxO)nSJpvd z2hOT_043sUFb$D^^u8lwb@A=z*U0W93h=!Et7K6)ow?4)_CkLBUTc96P;s5cC^mnh z0MjdohRPhKWoqJnVi9U(^vN|txq6+{viRbQxgPM*Fv-;PFfs5SS5?y6O(p*5b3{kCzkDhg6ovU?ftn}e)pST<*#@Z h^qtrW{-gR706$iI#01l$;%)!{002ovPDHLkV1li=)WiS) literal 0 HcmV?d00001 From ecd0a4bbce2034ab6ef1d6e3aa2030a898d90855 Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 21 Sep 2024 19:56:02 +0000 Subject: [PATCH 130/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 23b611255df..df14d1df2dd 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: Tayrtahn - changes: - - message: Antag objective total difficulty is now properly capped. - type: Fix - id: 6913 - time: '2024-07-13T04:14:30.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29830 - author: EmoGarbage404 changes: - message: Added wristwatches for telling time. @@ -3890,3 +3883,10 @@ id: 7412 time: '2024-09-21T07:33:22.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31156 +- author: TheShuEd + changes: + - message: Cores from floral anomalies are now seeds for hydroponics! + type: Add + id: 7413 + time: '2024-09-21T19:54:56.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/31987 From 7f489defcb6b01fb8c8c1924344bf3eb4374bdc8 Mon Sep 17 00:00:00 2001 From: Ilya246 <57039557+Ilya246@users.noreply.github.com> Date: Sun, 22 Sep 2024 00:51:20 +0400 Subject: [PATCH 131/138] fix cargo order scams, fix internals crate desc (#32350) fix description, fix scams --- Resources/Prototypes/Catalog/Cargo/cargo_emergency.yml | 2 +- Resources/Prototypes/Catalog/Cargo/cargo_engineering.yml | 2 +- Resources/Prototypes/Catalog/Fills/Crates/emergency.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_emergency.yml b/Resources/Prototypes/Catalog/Cargo/cargo_emergency.yml index 6e91a37e2a3..8d28a79001e 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_emergency.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_emergency.yml @@ -34,7 +34,7 @@ sprite: Clothing/Mask/breath.rsi state: icon product: CrateEmergencyInternalsLarge - cost: 2000 + cost: 1200 category: cargoproduct-category-name-emergency group: market diff --git a/Resources/Prototypes/Catalog/Cargo/cargo_engineering.yml b/Resources/Prototypes/Catalog/Cargo/cargo_engineering.yml index 78e5468164b..3239b5c1b51 100644 --- a/Resources/Prototypes/Catalog/Cargo/cargo_engineering.yml +++ b/Resources/Prototypes/Catalog/Cargo/cargo_engineering.yml @@ -44,7 +44,7 @@ sprite: Objects/Tools/cable-coils.rsi state: coilall-30 product: CrateEngineeringCableBulk - cost: 750 + cost: 600 category: cargoproduct-category-name-engineering group: market diff --git a/Resources/Prototypes/Catalog/Fills/Crates/emergency.yml b/Resources/Prototypes/Catalog/Fills/Crates/emergency.yml index 9532fbf74e6..7e1fb8f98b2 100644 --- a/Resources/Prototypes/Catalog/Fills/Crates/emergency.yml +++ b/Resources/Prototypes/Catalog/Fills/Crates/emergency.yml @@ -38,7 +38,7 @@ id: CrateEmergencyInternals parent: CrateInternals name: internals crate - description: Master your life energy and control your breathing with three breath masks, three emergency oxygen tanks and three large air tanks. + description: Master your life energy and control your breathing with 3 breath masks, emergency suits and large air tanks. components: - type: StorageFill contents: @@ -57,7 +57,7 @@ id: CrateEmergencyInternalsLarge parent: CrateInternals name: internals crate (large) - description: Master your life energy and control your breathing with six breath masks, six emergency oxygen tanks and six large air tanks. + description: Master your life energy and control your breathing with 6 breath masks, emergency suits and large air tanks. components: - type: StorageFill contents: From 5260d8b6222877e1e1ca2749531fd7de930ed5ba Mon Sep 17 00:00:00 2001 From: Plykiya <58439124+Plykiya@users.noreply.github.com> Date: Sat, 21 Sep 2024 16:21:52 -0700 Subject: [PATCH 132/138] Rat kings can butcher things (#32232) * rat kings can butcher things * minor organization * fix * important comma --- .../Kitchen/EntitySystems/SharpSystem.cs | 33 +++++++++++++++---- .../Entities/Mobs/NPCs/regalrat.yml | 1 + 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs index 99ea516f74d..67a04d9601e 100644 --- a/Content.Server/Kitchen/EntitySystems/SharpSystem.cs +++ b/Content.Server/Kitchen/EntitySystems/SharpSystem.cs @@ -11,6 +11,7 @@ using Content.Shared.Verbs; using Content.Shared.Destructible; using Content.Shared.DoAfter; +using Content.Shared.Hands.Components; using Content.Shared.Kitchen; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; @@ -72,12 +73,17 @@ private bool TryStartButcherDoafter(EntityUid knife, EntityUid target, EntityUid if (!sharp.Butchering.Add(target)) return false; + // if the user isn't the entity with the sharp component, + // they will need to be holding something with their hands, so we set needHand to true + // so that the doafter can be interrupted if they drop the item in their hands + var needHand = user != knife; + var doAfter = new DoAfterArgs(EntityManager, user, sharp.ButcherDelayModifier * butcher.ButcherDelay, new SharpDoAfterEvent(), knife, target: target, used: knife) { BreakOnDamage = true, BreakOnMove = true, - NeedHand = true, + NeedHand = needHand, }; _doAfterSystem.TryStartDoAfter(doAfter); return true; @@ -136,13 +142,20 @@ private void OnDoAfter(EntityUid uid, SharpComponent component, DoAfterEvent arg private void OnGetInteractionVerbs(EntityUid uid, ButcherableComponent component, GetVerbsEvent args) { - if (component.Type != ButcheringType.Knife || args.Hands == null || !args.CanAccess || !args.CanInteract) + if (component.Type != ButcheringType.Knife || !args.CanAccess || !args.CanInteract) + return; + + // if the user has no hands, don't show them the verb if they have no SharpComponent either + if (!TryComp(args.User, out var userSharpComp) && args.Hands == null) return; - bool disabled = false; + var disabled = false; string? message = null; - if (!HasComp(args.Using)) + // if the user has hands + // and the item they're holding doesn't have the SharpComponent + // disable the verb + if (!TryComp(args.Using, out var usingSharpComp) && args.Hands != null) { disabled = true; message = Loc.GetString("butcherable-need-knife", @@ -150,9 +163,9 @@ private void OnGetInteractionVerbs(EntityUid uid, ButcherableComponent component } else if (_containerSystem.IsEntityInContainer(uid)) { + disabled = true; message = Loc.GetString("butcherable-not-in-container", ("target", uid)); - disabled = true; } else if (TryComp(uid, out var state) && !_mobStateSystem.IsDead(uid, state)) { @@ -160,12 +173,20 @@ private void OnGetInteractionVerbs(EntityUid uid, ButcherableComponent component message = Loc.GetString("butcherable-mob-isnt-dead"); } + // set the object doing the butchering to the item in the user's hands or to the user themselves + // if either has the SharpComponent + EntityUid sharpObject = default; + if (usingSharpComp != null) + sharpObject = args.Using!.Value; + else if (userSharpComp != null) + sharpObject = args.User; + InteractionVerb verb = new() { Act = () => { if (!disabled) - TryStartButcherDoafter(args.Using!.Value, args.Target, args.User); + TryStartButcherDoafter(sharpObject, args.Target, args.User); }, Message = message, Disabled = disabled, diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml index 464f9f40972..19d6cafd7b1 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml @@ -122,6 +122,7 @@ - type: Grammar attributes: gender: male + - type: Sharp - type: PotentialPsionic # Nyano - type: entity From 76d140a013703e2a1de4d94471dcd8596200064f Mon Sep 17 00:00:00 2001 From: PJBot Date: Sat, 21 Sep 2024 23:23:00 +0000 Subject: [PATCH 133/138] Automatic changelog update --- Resources/Changelog/Changelog.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index df14d1df2dd..2c55f6b5721 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -1,11 +1,4 @@ Entries: -- author: EmoGarbage404 - changes: - - message: Added wristwatches for telling time. - type: Add - id: 6914 - time: '2024-07-13T06:09:19.0000000+00:00' - url: https://github.com/space-wizards/space-station-14/pull/29550 - author: TheShuEd changes: - message: Added diamonds ore! @@ -3890,3 +3883,10 @@ id: 7413 time: '2024-09-21T19:54:56.0000000+00:00' url: https://github.com/space-wizards/space-station-14/pull/31987 +- author: Plykiya + changes: + - message: The rat king is now capable of butchering things, like animals. + type: Add + id: 7414 + time: '2024-09-21T23:21:52.0000000+00:00' + url: https://github.com/space-wizards/space-station-14/pull/32232 From 4d6af523bc7fd2a66db954ffe6db65cb0273c963 Mon Sep 17 00:00:00 2001 From: deltanedas <@deltanedas:kde.org> Date: Sun, 22 Sep 2024 03:39:29 +0100 Subject: [PATCH 134/138] :trollface: --- Content.Server/StationRecords/Systems/StationRecordsSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/StationRecords/Systems/StationRecordsSystem.cs b/Content.Server/StationRecords/Systems/StationRecordsSystem.cs index b3dfe4e75c5..80c88917c02 100644 --- a/Content.Server/StationRecords/Systems/StationRecordsSystem.cs +++ b/Content.Server/StationRecords/Systems/StationRecordsSystem.cs @@ -37,7 +37,6 @@ namespace Content.Server.StationRecords.Systems; public sealed class StationRecordsSystem : SharedStationRecordsSystem { [Dependency] private readonly InventorySystem _inventory = default!; - [Dependency] private readonly SharedIdCardSystem _idCard = default!; // DeltaV [Dependency] private readonly StationRecordKeyStorageSystem _keyStorage = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IdCardSystem _idCard = default!; @@ -155,6 +154,7 @@ public void CreateGeneralRecord( Entity? card = null; if (idUid != null && _idCard.TryFindIdCard(idUid.Value, out var card2)) card = card2; + var record = new GeneralStationRecord() { Name = name, From f6480d0c3209480531d53597c5cd4612bdfc8131 Mon Sep 17 00:00:00 2001 From: deltanedas <@deltanedas:kde.org> Date: Sun, 22 Sep 2024 03:45:52 +0100 Subject: [PATCH 135/138] :trollface: --- Content.Client/Commands/ActionsCommands.cs | 26 +------------------ .../Entities/Structures/Machines/lathe.yml | 7 ----- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/Content.Client/Commands/ActionsCommands.cs b/Content.Client/Commands/ActionsCommands.cs index 87f35bd26e2..c155c7a9dea 100644 --- a/Content.Client/Commands/ActionsCommands.cs +++ b/Content.Client/Commands/ActionsCommands.cs @@ -1,10 +1,6 @@ using Content.Client.Actions; -using Content.Client.Actions; -using Content.Client.Mapping; using Content.Shared.Administration; -using Robust.Client.UserInterface; using Robust.Shared.Console; -using YamlDotNet.RepresentationModel; namespace Content.Client.Commands; @@ -50,7 +46,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) { if (args.Length != 1) { - LoadActs(); // DeltaV - Load from a file dialogue instead + shell.WriteLine(Help); return; } @@ -63,24 +59,4 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) shell.WriteError(LocalizationManager.GetString($"cmd-{Command}-error")); } } - - /// - /// DeltaV - Load actions from a file stream instead - /// - private static async void LoadActs() - { - var fileMan = IoCManager.Resolve(); - var actMan = IoCManager.Resolve().GetEntitySystem(); - - var stream = await fileMan.OpenFile(new FileDialogFilters(new FileDialogFilters.Group("yml"))); - if (stream is null) - return; - - var reader = new StreamReader(stream); - var yamlStream = new YamlStream(); - yamlStream.Load(reader); - - actMan.LoadActionAssignments(yamlStream); - reader.Close(); - } } diff --git a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml index cec06854d99..6162cd46f0d 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/lathe.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/lathe.yml @@ -1219,13 +1219,6 @@ - ClothingOuterWinterQM - ClothingOuterWinterRD - ClothingOuterChiefJustice # DeltaV - Chief Justice - - ClothingNeckMantleCap - - ClothingNeckMantleCE - - ClothingNeckMantleCMO - - ClothingNeckMantleHOP - - ClothingNeckMantleHOS - - ClothingNeckMantleRD - - ClothingNeckMantleQM - ClothingNeckCloakCJ # DeltaV - Chief Justice - ClothingOuterStasecSweater # DeltaV - added stasec sweater to uniform printer. - ClothingOuterWinterMusician From 9689973d62644f64f5e49131b3b558b4d6e464c5 Mon Sep 17 00:00:00 2001 From: deltanedas <@deltanedas:kde.org> Date: Sun, 22 Sep 2024 03:56:24 +0100 Subject: [PATCH 136/138] remove shock collar objective as it isn't stealing it's using a lathe, fix things --- .../objectives/conditions/steal-target-groups.ftl | 1 + .../Entities/Objects/Devices/shock_collar.yml | 2 -- Resources/Prototypes/Objectives/stealTargetGroups.yml | 9 +-------- Resources/Prototypes/Objectives/thief.yml | 11 ----------- Resources/Prototypes/Objectives/traitor.yml | 1 - 5 files changed, 2 insertions(+), 22 deletions(-) rename Resources/Prototypes/{ => DeltaV}/Entities/Objects/Devices/shock_collar.yml (92%) diff --git a/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl b/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl index 2a3231cf323..83355729533 100644 --- a/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl +++ b/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl @@ -1,3 +1,4 @@ +steal-target-group-plutonium-core = plutonium core steal-target-group-lucky-bill = logistics officer's lucky bill steal-target-group-ian-dossier = head of personnel's photobook steal-target-group-x01 = x-01 multiphase energy gun diff --git a/Resources/Prototypes/Entities/Objects/Devices/shock_collar.yml b/Resources/Prototypes/DeltaV/Entities/Objects/Devices/shock_collar.yml similarity index 92% rename from Resources/Prototypes/Entities/Objects/Devices/shock_collar.yml rename to Resources/Prototypes/DeltaV/Entities/Objects/Devices/shock_collar.yml index 22f2d097fc8..8a4a304ca86 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/shock_collar.yml +++ b/Resources/Prototypes/DeltaV/Entities/Objects/Devices/shock_collar.yml @@ -29,8 +29,6 @@ - type: GuideHelp guides: - Security - - type: StealTarget - stealGroup: ClothingNeckShockCollar - type: Tag tags: - WhitelistChameleon diff --git a/Resources/Prototypes/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Objectives/stealTargetGroups.yml index 4241f6b03fc..a3f990dcc2d 100644 --- a/Resources/Prototypes/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Objectives/stealTargetGroups.yml @@ -79,7 +79,7 @@ - type: stealTargetGroup # DeltaV, upstream reverted id: PlutoniumCore - name: plutonium core + name: steal-target-groups-plutonium-core sprite: sprite: Objects/Misc/plutonium_core.rsi state: icon @@ -270,13 +270,6 @@ sprite: Clothing/Neck/Medals/clownmedal.rsi state: icon -- type: stealTargetGroup - id: ClothingNeckShockCollar - name: shock collar - sprite: - sprite: Clothing/Neck/Misc/shock_collar.rsi - state: icon - #Thief structures - type: stealTargetGroup diff --git a/Resources/Prototypes/Objectives/thief.yml b/Resources/Prototypes/Objectives/thief.yml index ca6053a2ee8..7a397d9ab6f 100644 --- a/Resources/Prototypes/Objectives/thief.yml +++ b/Resources/Prototypes/Objectives/thief.yml @@ -305,17 +305,6 @@ # - type: Objective # difficulty: 1 -- type: entity - parent: BaseThiefStealObjective - id: ClothingNeckShockCollarStealObjective - components: - - type: NotJobRequirement - job: Warden - - type: StealCondition - stealGroup: ClothingNeckShockCollar - - type: Objective - difficulty: 1 - # Structures - type: entity diff --git a/Resources/Prototypes/Objectives/traitor.yml b/Resources/Prototypes/Objectives/traitor.yml index c2ac0958929..6ddbb36a946 100644 --- a/Resources/Prototypes/Objectives/traitor.yml +++ b/Resources/Prototypes/Objectives/traitor.yml @@ -49,7 +49,6 @@ - type: EscapeShuttleCondition - type: entity - noSpawn: true parent: BaseTraitorObjective id: DieObjective name: Die a glorious death From 65134d978705ebd75ecdb6b36b4ce1e2408810cc Mon Sep 17 00:00:00 2001 From: deltanedas <@deltanedas:kde.org> Date: Sun, 22 Sep 2024 04:22:33 +0100 Subject: [PATCH 137/138] :trollface: --- .../objectives/conditions/steal-target-groups.ftl | 14 +++++++------- .../DeltaV/Objectives/stealTargetGroups.yml | 10 +++++----- .../Nyanotrasen/Objectives/stealTargetGroups.yml | 2 +- Resources/Prototypes/Objectives/traitor.yml | 1 - 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl b/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl index 83355729533..9ee5e824214 100644 --- a/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl +++ b/Resources/Locale/en-US/deltav/objectives/conditions/steal-target-groups.ftl @@ -1,8 +1,8 @@ -steal-target-group-plutonium-core = plutonium core -steal-target-group-lucky-bill = logistics officer's lucky bill -steal-target-group-ian-dossier = head of personnel's photobook -steal-target-group-x01 = x-01 multiphase energy gun -steal-target-group-notary-stamp = notary stamp -steal-target-group-silvia = silvia +steal-target-groups-plutonium-core = plutonium core +steal-target-groups-lucky-bill = logistics officer's lucky bill +steal-target-groups-ian-dossier = head of personnel's photobook +steal-target-groups-x01 = x-01 multiphase energy gun +steal-target-groups-notary-stamp = notary stamp +steal-target-groups-silvia = silvia -steal-target-group-recruiter-pen = recruiter's pen +steal-target-groups-recruiter-pen = recruiter's pen diff --git a/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml b/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml index dde963cf359..1df9cd69736 100644 --- a/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/DeltaV/Objectives/stealTargetGroups.yml @@ -1,34 +1,34 @@ - type: stealTargetGroup id: SpaceCashLuckyBill - name: steal-target-group-lucky-bill + name: steal-target-groups-lucky-bill sprite: sprite: DeltaV/Objects/Misc/first_bill.rsi state: icon - type: stealTargetGroup id: BookIanDossier - name: steal-target-group-ian-dossier + name: steal-target-groups-ian-dossier sprite: sprite: DeltaV/Objects/Misc/bureaucracy.rsi state: folder-hop-ian - type: stealTargetGroup id: WeaponEnergyGunMultiphase - name: steal-target-group-x01 + name: steal-target-groups-x01 sprite: sprite: DeltaV/Objects/Weapons/Guns/Battery/multiphase_energygun.rsi state: base - type: stealTargetGroup id: RubberStampNotary - name: steal-target-group-notary-stamp + name: steal-target-groups-notary-stamp sprite: sprite: DeltaV/Objects/Misc/stamps.rsi state: stamp-notary - type: stealTargetGroup id: AnimalSilvia - name: steal-target-group-silvia + name: steal-target-groups-silvia sprite: sprite: DeltaV/Mobs/Pets/silvia.rsi state: silvia diff --git a/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml b/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml index 3afd4b9dc84..58e6a1cb6a3 100644 --- a/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml +++ b/Resources/Prototypes/Nyanotrasen/Objectives/stealTargetGroups.yml @@ -1,6 +1,6 @@ - type: stealTargetGroup id: AntiPsychicKnife - name: steal-target-group-anti-psychic-knife + name: steal-target-groups-anti-psychic-knife sprite: sprite: Nyanotrasen/Objects/Weapons/Melee/anti_psychic_knife.rsi state: icon diff --git a/Resources/Prototypes/Objectives/traitor.yml b/Resources/Prototypes/Objectives/traitor.yml index 6ddbb36a946..fc97e1797c7 100644 --- a/Resources/Prototypes/Objectives/traitor.yml +++ b/Resources/Prototypes/Objectives/traitor.yml @@ -301,7 +301,6 @@ # Station - type: entity - noSpawn: true parent: BaseTraitorStealObjective id: PlutoniumCoreStealObjective components: From 936172cf2915dbac05c8716fde316a8aab0ae833 Mon Sep 17 00:00:00 2001 From: deltanedas <@deltanedas:kde.org> Date: Sun, 22 Sep 2024 04:29:12 +0100 Subject: [PATCH 138/138] g --- .../nyanotrasen/objectives/conditions/steal-target-groups.ftl | 2 +- Resources/Prototypes/DeltaV/Objectives/recruiter.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl b/Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl index fa96136b13d..4db9318495c 100644 --- a/Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl +++ b/Resources/Locale/en-US/nyanotrasen/objectives/conditions/steal-target-groups.ftl @@ -1 +1 @@ -steal-target-group-anti-psychic-knife = anti-psychic knife +steal-target-groups-anti-psychic-knife = anti-psychic knife diff --git a/Resources/Prototypes/DeltaV/Objectives/recruiter.yml b/Resources/Prototypes/DeltaV/Objectives/recruiter.yml index cff6f085806..d8760388c71 100644 --- a/Resources/Prototypes/DeltaV/Objectives/recruiter.yml +++ b/Resources/Prototypes/DeltaV/Objectives/recruiter.yml @@ -43,7 +43,7 @@ - type: stealTargetGroup id: RecruiterPen - name: steal-target-group-recruiter-pen + name: steal-target-groups-recruiter-pen sprite: sprite: DeltaV/Objects/Misc/recruiter_pen.rsi state: empty