From 2958172ad64acc4e924f782799dc8de86f12480b Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:28:45 +0000 Subject: [PATCH 01/99] Fixes the Queen Eye being stuck as immature (#5299) # About the pull request Makes the 'Queen Eye' mob update its name when the Queen passes the 'Immature' stage, by adding a `COMSIG_MOB_REAL_NAME_CHANGED` signal. This would be better if it was more similar to TG's `COMSIG_ATOM_UPDATE_NAME`, but from looking into that it would take a *big* refactor to implement `update_name()`/`update_appearance()`, so this'll probably do for the time being. # Explain why it's good for the game Fixes the queen eye being stuck as immature unless the queen toggles it on and off. # Testing Photographs and Procedure
Screenshots & Videos **Before:** https://github.com/cmss13-devs/cmss13/assets/57483089/329b8e92-29b3-4629-bd94-c0096bea6508 **After:** https://github.com/cmss13-devs/cmss13/assets/57483089/49746267-03f5-4e62-aa5b-6f36927cc3e9
# Changelog :cl: fix: Fixed the Queen Eye still showing as "Immature" after the Queen ages. /:cl: --- code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm | 3 +++ code/__HELPERS/mobs.dm | 2 ++ code/modules/mob/living/carbon/xenomorph/castes/Queen.dm | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm index bfb62c2bcf6e..f288f5d94584 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm @@ -77,6 +77,9 @@ ///from base of /mob/Logout(): () #define COMSIG_MOB_LOGOUT "mob_logout" +/// From /mob/proc/change_real_name(): (old_name, new_name) +#define COMSIG_MOB_REAL_NAME_CHANGED "mob_real_name_changed" + //from /mob/proc/on_deafness_gain() #define COMSIG_MOB_DEAFENED "mob_deafened" //from /mob/proc/on_deafness_loss() diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 55b234b1e419..663d72fd5079 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -73,6 +73,7 @@ /mob/proc/change_real_name(mob/M, new_name) if(!new_name) return FALSE + var/old_name = M.real_name M.real_name = new_name M.name = new_name @@ -83,6 +84,7 @@ // If we are humans, we need to update our voice as well M.change_mob_voice(new_name) + SEND_SIGNAL(src, COMSIG_MOB_REAL_NAME_CHANGED, old_name, new_name) return TRUE /mob/proc/change_mind_name(new_mind_name) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm index 7e43db5b3f89..7416b85a13c4 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm @@ -102,6 +102,7 @@ COMSIG_XENO_STOP_OVERWATCH, COMSIG_XENO_STOP_OVERWATCH_XENO ), PROC_REF(stop_watching)) + RegisterSignal(Q, COMSIG_MOB_REAL_NAME_CHANGED, PROC_REF(on_name_changed)) RegisterSignal(src, COMSIG_MOVABLE_TURF_ENTER, PROC_REF(turf_weed_only)) // Default color @@ -157,6 +158,10 @@ X.reset_view() return +/mob/hologram/queen/proc/on_name_changed(mob/parent, old_name, new_name) + SIGNAL_HANDLER + name = "[initial(src.name)] ([new_name])" + /mob/hologram/queen/proc/turf_weed_only(mob/self, turf/crossing_turf) SIGNAL_HANDLER From 8bb657115c1ff2767987671ddfe34dd8806ba4da Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:42:31 +0000 Subject: [PATCH 02/99] Automatic changelog for PR #5299 [ci skip] --- html/changelogs/AutoChangeLog-pr-5299.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5299.yml diff --git a/html/changelogs/AutoChangeLog-pr-5299.yml b/html/changelogs/AutoChangeLog-pr-5299.yml new file mode 100644 index 000000000000..a3a90165dec9 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5299.yml @@ -0,0 +1,4 @@ +author: "SabreML" +delete-after: True +changes: + - bugfix: "Fixed the Queen Eye still showing as \"Immature\" after the Queen ages." \ No newline at end of file From b6245a65d8e05b1b8ae08f3a3e700574899f34ff Mon Sep 17 00:00:00 2001 From: Changelogs Date: Wed, 27 Dec 2023 01:08:58 +0000 Subject: [PATCH 03/99] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-5185.yml | 6 ------ html/changelogs/AutoChangeLog-pr-5205.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5224.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5225.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5276.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5286.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5287.yml | 6 ------ html/changelogs/AutoChangeLog-pr-5289.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5296.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5299.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5305.yml | 4 ---- html/changelogs/archive/2023-12.yml | 25 +++++++++++++++++++++++ 12 files changed, 25 insertions(+), 48 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-5185.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5205.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5224.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5225.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5276.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5286.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5287.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5289.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5296.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5299.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5305.yml diff --git a/html/changelogs/AutoChangeLog-pr-5185.yml b/html/changelogs/AutoChangeLog-pr-5185.yml deleted file mode 100644 index 53d873313e5a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5185.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "realforest2001" -delete-after: True -changes: - - code_imp: "Added a new span class that combines bold and big." - - code_imp: "Tweaked the way prayer sends notifications to be more efficient." - - admin: "Moved the prayer notification sound to a toggle preference, combined with ARES Interface notifications." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5205.yml b/html/changelogs/AutoChangeLog-pr-5205.yml deleted file mode 100644 index 8f5427790747..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5205.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed the death message from GAU-21 and Laser Cannon strikes saying that the player was killed by the ammo crate." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5224.yml b/html/changelogs/AutoChangeLog-pr-5224.yml deleted file mode 100644 index 009b76a4824a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5224.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "cuberound" -delete-after: True -changes: - - balance: "launchbay price 400 -> 200" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5225.yml b/html/changelogs/AutoChangeLog-pr-5225.yml deleted file mode 100644 index ea1426f071c1..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5225.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "cuberound" -delete-after: True -changes: - - balance: "DS installed sentrygun price lowered to 200" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5276.yml b/html/changelogs/AutoChangeLog-pr-5276.yml deleted file mode 100644 index 82e8f2ccb48c..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5276.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "InsaneRed" -delete-after: True -changes: - - spellcheck: "More WE/YOU fixes for xenomorph side." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5286.yml b/html/changelogs/AutoChangeLog-pr-5286.yml deleted file mode 100644 index b8234642d6d6..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5286.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed carriers being unable to reduce their 'reserved facehuggers' number." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5287.yml b/html/changelogs/AutoChangeLog-pr-5287.yml deleted file mode 100644 index feed5bb64b23..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5287.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: "Birdtalon" -delete-after: True -changes: - - rscdel: "Removed old crystal code from xenos" - - code_imp: "Renames still used vars from crystal to plasma" - - code_imp: "Removes crystal define in place of plasma string" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5289.yml b/html/changelogs/AutoChangeLog-pr-5289.yml deleted file mode 100644 index df6ec245ea14..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5289.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Drathek" -delete-after: True -changes: - - bugfix: "Fix xeno wounds layering over weeds when merged with the weeds" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5296.yml b/html/changelogs/AutoChangeLog-pr-5296.yml deleted file mode 100644 index 51629d2c02ab..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5296.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "InsaneRed" -delete-after: True -changes: - - bugfix: "Spitter's charge spit abiltiy now properly adds and removes the 5 armor like its supposed to initially." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5299.yml b/html/changelogs/AutoChangeLog-pr-5299.yml deleted file mode 100644 index a3a90165dec9..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5299.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed the Queen Eye still showing as \"Immature\" after the Queen ages." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5305.yml b/html/changelogs/AutoChangeLog-pr-5305.yml deleted file mode 100644 index de49a7cf386a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5305.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed being able to vend infinite alcohol." \ No newline at end of file diff --git a/html/changelogs/archive/2023-12.yml b/html/changelogs/archive/2023-12.yml index eb93ac1733a5..43d61e9d7aec 100644 --- a/html/changelogs/archive/2023-12.yml +++ b/html/changelogs/archive/2023-12.yml @@ -496,3 +496,28 @@ - refactor: CAS can offset in different direction to attack vector realforest2001: - bugfix: Yautja bracer lock can now properly unlock thrall bracers. +2023-12-27: + Birdtalon: + - rscdel: Removed old crystal code from xenos + - code_imp: Renames still used vars from crystal to plasma + - code_imp: Removes crystal define in place of plasma string + Drathek: + - bugfix: Fix xeno wounds layering over weeds when merged with the weeds + InsaneRed: + - spellcheck: More WE/YOU fixes for xenomorph side. + - bugfix: Spitter's charge spit abiltiy now properly adds and removes the 5 armor + like its supposed to initially. + SabreML: + - bugfix: Fixed the Queen Eye still showing as "Immature" after the Queen ages. + - bugfix: Fixed carriers being unable to reduce their 'reserved facehuggers' number. + - bugfix: Fixed being able to vend infinite alcohol. + - bugfix: Fixed the death message from GAU-21 and Laser Cannon strikes saying that + the player was killed by the ammo crate. + cuberound: + - balance: launchbay price 400 -> 200 + - balance: DS installed sentrygun price lowered to 200 + realforest2001: + - code_imp: Added a new span class that combines bold and big. + - code_imp: Tweaked the way prayer sends notifications to be more efficient. + - admin: Moved the prayer notification sound to a toggle preference, combined with + ARES Interface notifications. From fa754d7a7f71e0a10b8b424037cf344d82d653b0 Mon Sep 17 00:00:00 2001 From: InsaneRed <47158596+InsaneRed@users.noreply.github.com> Date: Wed, 27 Dec 2023 21:04:45 +0300 Subject: [PATCH 04/99] Fixes synths being unlungeable while in "critical state" (#5303) # About the pull request Synths were given immunity to dragging from old code back when they could go into 'crit' so they dont get dragged to hell, however they no longer have a crit state but still keep the immunity lunges also do not work because of this. this is not intended. # Explain why it's good for the game bugfix # Testing Photographs and Procedure
Screenshots & Videos yeah i tested it also no you cant get dragged while dead
# Changelog :cl: fix: Synths are no longer immune to lunges / dragging while in 'critical state' since they dont go into crit. /:cl: Co-authored-by: InsaneRed --- code/modules/mob/living/carbon/xenomorph/Xenomorph.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index 3f6e5e85f565..d8f92554c8b3 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -731,8 +731,6 @@ if(!isliving(AM)) return FALSE var/mob/living/L = AM - if(issynth(L) && L.health < 0) // no pulling critted or dead synths - return FALSE if(L.buckled) return FALSE //to stop xeno from pulling marines on roller beds. if(!L.is_xeno_grabbable()) From 5bc9eabe47d0ac9b3f6899c011eb512547acd880 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 27 Dec 2023 18:12:52 +0000 Subject: [PATCH 05/99] Automatic changelog for PR #5303 [ci skip] --- html/changelogs/AutoChangeLog-pr-5303.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5303.yml diff --git a/html/changelogs/AutoChangeLog-pr-5303.yml b/html/changelogs/AutoChangeLog-pr-5303.yml new file mode 100644 index 000000000000..68f9dbb14544 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5303.yml @@ -0,0 +1,4 @@ +author: "InsaneRed" +delete-after: True +changes: + - bugfix: "Synths are no longer immune to lunges / dragging while in 'critical state' since they dont go into crit." \ No newline at end of file From eecedaaedb8b7554f1c37de98cb97342e29ef08c Mon Sep 17 00:00:00 2001 From: fira Date: Wed, 27 Dec 2023 23:44:07 +0100 Subject: [PATCH 06/99] Fixes a simple race condition in XRF Setup (#5312) # About the pull request As seen on ~~TV~~ Live game Someone can remove the vial during the do_after, bricking the machine as it runtimes and is stuck with processing = TRUE # Changelog :cl: fix: Fixed XRF Scanner bricking if people were adding and removing vials at same time. /:cl: --- code/modules/reagents/chemistry_machinery/reagent_analyzer.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/reagents/chemistry_machinery/reagent_analyzer.dm b/code/modules/reagents/chemistry_machinery/reagent_analyzer.dm index e0d0a80cadc2..51db188826b8 100644 --- a/code/modules/reagents/chemistry_machinery/reagent_analyzer.dm +++ b/code/modules/reagents/chemistry_machinery/reagent_analyzer.dm @@ -29,6 +29,9 @@ updateUsrDialog() if(!do_after(user, 1 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC)) return + if(!sample) + to_chat(user, SPAN_WARNING("Someone else removed the sample. Make up your mind!")) + return processing = TRUE if(sample.reagents.total_volume < 30 || sample.reagents.reagent_list.len > 1) icon_state = "reagent_analyzer_error" From 8963d0a479ff689dc2825b9bb9dcf6869fe9a3c4 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 27 Dec 2023 22:52:27 +0000 Subject: [PATCH 07/99] Automatic changelog for PR #5312 [ci skip] --- html/changelogs/AutoChangeLog-pr-5312.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5312.yml diff --git a/html/changelogs/AutoChangeLog-pr-5312.yml b/html/changelogs/AutoChangeLog-pr-5312.yml new file mode 100644 index 000000000000..e7be9dce1385 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5312.yml @@ -0,0 +1,4 @@ +author: "fira" +delete-after: True +changes: + - bugfix: "Fixed XRF Scanner bricking if people were adding and removing vials at same time." \ No newline at end of file From 92a96a8a4b1d236113ea9ce28efa6bc1971cfea7 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Wed, 27 Dec 2023 23:30:21 +0000 Subject: [PATCH 08/99] Shoe item storage refactor (#5263) # About the pull request Refactors shoe item storage to fix #5245, adds a bit of documentation, and generally just makes it a bit neater. (The overall 'Files changed' view looks a bit messy, so I've tried to keep each commit atomic to help with reviews.) # Explain why it's good for the game Code works gooder. # Testing Photographs and Procedure
Screenshots & Videos **Inserting a knife manually:** https://github.com/cmss13-devs/cmss13/assets/57483089/adf6267c-7a30-4c00-ae32-37524048ddc6 **Inserting a knife with the (un)holster hotkey:** https://github.com/cmss13-devs/cmss13/assets/57483089/b66824cb-5ad8-433e-a732-4854c0f68ff4 **Inserting a knife while holding the shoes:** https://github.com/cmss13-devs/cmss13/assets/57483089/0db1ac5c-7375-478a-9464-449657c7b659 **Picking up/dropping the shoes, and inserting a knife while they're on the ground:** https://github.com/cmss13-devs/cmss13/assets/57483089/404a8199-dee0-4cd0-92a9-d2a46cadfac6 **Trying a few different things with two pairs of shoes:** https://github.com/cmss13-devs/cmss13/assets/57483089/c5aab994-1002-4ffe-80e9-ddbaff4f95af
# Changelog :cl: fix: Fixed inserting/removing an item from shoes sometimes acting weirdly. refactor: Refactored shoe item storage. /:cl: --- code/datums/supply_packs/black_market.dm | 2 +- code/game/objects/items.dm | 2 +- code/modules/clothing/clothing.dm | 90 ++++++++++------- code/modules/clothing/shoes/colour.dm | 11 ++- code/modules/clothing/shoes/marine_shoes.dm | 92 ++++++++---------- code/modules/cm_preds/thrall_items.dm | 2 +- code/modules/cm_preds/yaut_items.dm | 9 +- code/modules/gear_presets/clf.dm | 2 +- code/modules/gear_presets/corpses.dm | 6 +- code/modules/gear_presets/fun.dm | 2 +- code/modules/gear_presets/other.dm | 8 +- code/modules/gear_presets/survivors/misc.dm | 2 +- .../sorokyne_strata/preset_sorokyne_strata.dm | 5 +- .../crashlanding_upp_bar_insert_trijent.dm | 4 +- code/modules/gear_presets/synths.dm | 2 +- code/modules/gear_presets/upp.dm | 96 +++++++++---------- code/modules/mob/inventory.dm | 9 +- .../mob/living/carbon/human/inventory.dm | 5 +- code/modules/projectiles/gun_attachables.dm | 4 + .../FOP_v3_Sciannex/Fiorina_SciAnnex.dmm | 2 +- 20 files changed, 184 insertions(+), 171 deletions(-) diff --git a/code/datums/supply_packs/black_market.dm b/code/datums/supply_packs/black_market.dm index 36d890e2b3d5..43e0358a96f9 100644 --- a/code/datums/supply_packs/black_market.dm +++ b/code/datums/supply_packs/black_market.dm @@ -101,7 +101,7 @@ Non-USCM items, from CLF, UPP, colonies, etc. Mostly combat-related. new /obj/item/clothing/head/helmet/marine/veteran/UPP(src) new /obj/item/clothing/under/marine/veteran/UPP(src) new /obj/item/clothing/suit/storage/marine/faction/UPP(src) - new /obj/item/clothing/shoes/marine/upp(src) + new /obj/item/clothing/shoes/marine/upp/knife(src) new /obj/item/clothing/gloves/marine/veteran(src) new /obj/item/storage/backpack/lightpack/five_slot(src) if(5) //freelancer diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 11da4cce6d98..ef9fcacf5647 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -708,7 +708,7 @@ cases. Override_icon_state should be a list.*/ if(WEAR_IN_SHOES) if(human.shoes && istype(human.shoes, /obj/item/clothing/shoes)) var/obj/item/clothing/shoes/shoes = human.shoes - if(shoes.attempt_insert_item(human, src)) + if(shoes.can_be_inserted(src)) return TRUE return FALSE if(WEAR_IN_SCABBARD) diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index d6596474885c..91f42fbafe79 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -336,41 +336,64 @@ permeability_coefficient = 0.50 slowdown = SHOES_SLOWDOWN blood_overlay_type = "feet" + /// The currently inserted item. var/obj/item/stored_item - var/list/items_allowed + /// List of item types that can be inserted. + var/list/allowed_items_typecache + /// An item which should be inserted when the shoes are spawned. + var/obj/item/spawn_item_type var/shoes_blood_amt = 0 -///Checks if you can put the item inside of the shoes -/obj/item/clothing/shoes/proc/attempt_insert_item(mob/user, obj/item/attacking_item, insert_after = FALSE) - if(!items_allowed) - return +/obj/item/clothing/shoes/Initialize(mapload, ...) + . = ..() + if(allowed_items_typecache) + allowed_items_typecache = typecacheof(allowed_items_typecache) + if(spawn_item_type) + _insert_item(new spawn_item_type(src)) + +/// Returns a boolean indicating if `item_to_insert` can be inserted into the shoes. +/obj/item/clothing/shoes/proc/can_be_inserted(obj/item/item_to_insert) + // If the shoes can't actually hold an item. + if(allowed_items_typecache == null) + return FALSE + // If there's already an item inside. if(stored_item) - return - var/allowed = FALSE - for(var/allowed_item in items_allowed) - if(istype(attacking_item, allowed_item)) - allowed = TRUE - break - if(!allowed) - return - if(!insert_after) - return TRUE - insert_item(user, attacking_item) - -///Puts the item inside of the shoe -/obj/item/clothing/shoes/proc/insert_item(mob/user, obj/item/attacking_item) - stored_item = attacking_item - user.drop_inv_item_to_loc(attacking_item, src) - to_chat(user, SPAN_NOTICE("You slide [attacking_item] into [src].")) - playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, 1) + return FALSE + // If `item_to_insert` isn't in the whitelist. + if(!is_type_in_typecache(item_to_insert, allowed_items_typecache)) + return FALSE + // If all of those passed, `item_to_insert` can be inserted. + return TRUE + +/** + * Try to insert `item_to_insert` into the shoes. + * + * Returns `TRUE` if it succeeded, or `FALSE` if [/obj/item/clothing/shoes/proc/can_be_inserted] failed, or `user` couldn't drop the item. + */ +/obj/item/clothing/shoes/proc/attempt_insert_item(mob/user, obj/item/item_to_insert) + if(!can_be_inserted(item_to_insert)) + return FALSE + // Try to drop the item and place it inside `src`. + if(!user.drop_inv_item_to_loc(item_to_insert, src)) + return FALSE + _insert_item(item_to_insert) + to_chat(user, SPAN_NOTICE("You slide [item_to_insert] into [src].")) + playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, TRUE) + return TRUE + +/// Insert `item_to_insert` directly into the shoes without bothering with any checks. +/// (In the majority of cases [/obj/item/clothing/shoes/proc/attempt_insert_item()] should be used instead of this.) +/obj/item/clothing/shoes/proc/_insert_item(obj/item/item_to_insert) + PROTECTED_PROC(TRUE) + stored_item = item_to_insert update_icon() -///Removes the item from the shoes +/// Remove `stored_item` from the shoes, and place it into the `user`'s active hand. /obj/item/clothing/shoes/proc/remove_item(mob/user) - if(!user.put_in_active_hand(stored_item)) + if(!stored_item || !user.put_in_active_hand(stored_item)) return to_chat(user, SPAN_NOTICE("You slide [stored_item] out of [src].")) - playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, 1) + playsound(user, 'sound/weapons/gun_shotgun_shell_insert.ogg', 15, TRUE) stored_item = null update_icon() @@ -380,10 +403,8 @@ user.update_inv_shoes() /obj/item/clothing/shoes/Destroy() - if(stored_item) - qdel(stored_item) - stored_item = null - . = ..() + QDEL_NULL(stored_item) + return ..() /obj/item/clothing/shoes/get_examine_text(mob/user) . = ..() @@ -391,17 +412,14 @@ . += "\nIt is storing \a [stored_item]." /obj/item/clothing/shoes/attack_hand(mob/living/user) - if(!stored_item) //Only allow someone to take out the stored_item if it's being worn or held. So you can pick them up off the floor - return ..() - if(user.is_mob_incapacitated()) - return ..() - if(loc != user) + // Only allow someone to take out the `stored_item` if it's being worn or held, so that you can pick them up off the floor. + if(!stored_item || loc != user || user.is_mob_incapacitated()) return ..() remove_item(user) /obj/item/clothing/shoes/attackby(obj/item/attacking_item, mob/living/user) . = ..() - user.equip_to_slot_if_possible(attacking_item, WEAR_IN_SHOES) + attempt_insert_item(user, attacking_item) /obj/item/clothing/equipped(mob/user, slot, silent) if(is_valid_slot(slot, TRUE)) //is it going to a matching clothing slot? diff --git a/code/modules/clothing/shoes/colour.dm b/code/modules/clothing/shoes/colour.dm index b5ec4f3ab924..4318e1a3b184 100644 --- a/code/modules/clothing/shoes/colour.dm +++ b/code/modules/clothing/shoes/colour.dm @@ -41,7 +41,14 @@ /obj/item/clothing/shoes/red/knife name = "dirty red shoes" desc = "Stylish red shoes with a small space to hold a knife." - items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/tool/screwdriver, /obj/item/weapon/straight_razor) + allowed_items_typecache = list( + /obj/item/attachable/bayonet, + /obj/item/weapon/throwing_knife, + /obj/item/weapon/gun/pistol/holdout, + /obj/item/weapon/gun/pistol/clfpistol, + /obj/item/tool/screwdriver, + /obj/item/weapon/straight_razor, + ) /obj/item/clothing/shoes/white name = "white shoes" @@ -90,5 +97,3 @@ ..() if (istype(H, /obj/item/handcuffs)) attach_cuffs(H, user) - - diff --git a/code/modules/clothing/shoes/marine_shoes.dm b/code/modules/clothing/shoes/marine_shoes.dm index c7eb4ba53982..7855075c2fb4 100644 --- a/code/modules/clothing/shoes/marine_shoes.dm +++ b/code/modules/clothing/shoes/marine_shoes.dm @@ -18,47 +18,46 @@ min_cold_protection_temperature = SHOE_MIN_COLD_PROT max_heat_protection_temperature = SHOE_MAX_HEAT_PROT siemens_coefficient = 0.7 - var/armor_stage = 0 - items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/tool/screwdriver, /obj/item/tool/surgery/scalpel, /obj/item/weapon/straight_razor) - var/knife_type + allowed_items_typecache = list( + /obj/item/attachable/bayonet, + /obj/item/weapon/throwing_knife, + /obj/item/weapon/gun/pistol/holdout, + /obj/item/weapon/gun/pistol/clfpistol, + /obj/item/tool/screwdriver, + /obj/item/tool/surgery/scalpel, + /obj/item/weapon/straight_razor, + ) drop_sound = "armorequip" -/obj/item/clothing/shoes/marine/Initialize(mapload, ...) - . = ..() - if(knife_type) - stored_item = new knife_type(src) - update_icon() - /obj/item/clothing/shoes/marine/update_icon() - if(stored_item && !armor_stage) + if(stored_item) icon_state = "[initial(icon_state)]-1" else - if(!armor_stage) - icon_state = initial(icon_state) + icon_state = initial(icon_state) /obj/item/clothing/shoes/marine/knife - knife_type = /obj/item/attachable/bayonet + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/marine/jungle icon_state = "marine_jungle" desc = "Don't go walkin' slow, the devil's on the loose." /obj/item/clothing/shoes/marine/jungle/knife - knife_type = /obj/item/attachable/bayonet + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/marine/brown icon_state = "marine_brown" desc = "Standard issue combat boots for combat scenarios or combat situations. All combat, all the time. These are brown." /obj/item/clothing/shoes/marine/brown/knife - knife_type = /obj/item/attachable/bayonet + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/marine/monkey name = "monkey combat boots" desc = "A sturdy pair of combat boots, the reflection of the polished leather reflects your true self." icon_state = "monkey_shoes" item_state = "monkey_shoes" - knife_type = /obj/item/attachable/bayonet + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/marine/upp name = "military combat boots" @@ -67,10 +66,9 @@ armor_bullet = CLOTHING_ARMOR_HIGHPLUS armor_bomb = CLOTHING_ARMOR_MEDIUM armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH - knife_type = /obj/item/attachable/bayonet/upp -/obj/item/clothing/shoes/marine/upp_knife - knife_type = /obj/item/attachable/bayonet/upp +/obj/item/clothing/shoes/marine/upp/knife + spawn_item_type = /obj/item/attachable/bayonet/upp /obj/item/clothing/shoes/marine/joe name = "biohazard boots" @@ -80,7 +78,7 @@ armor_bio = CLOTHING_ARMOR_MEDIUMHIGH armor_rad = CLOTHING_ARMOR_MEDIUMHIGH armor_internaldamage = CLOTHING_ARMOR_MEDIUMLOW - knife_type = /obj/item/attachable/bayonet + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/dress name = "dress shoes" @@ -120,7 +118,13 @@ flags_heat_protection = BODY_FLAG_FEET flags_inventory = FPRINT|NOSLIPPING siemens_coefficient = 0.6 - items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/weapon/straight_razor) + allowed_items_typecache = list( + /obj/item/attachable/bayonet, + /obj/item/weapon/throwing_knife, + /obj/item/weapon/gun/pistol/holdout, + /obj/item/weapon/gun/pistol/clfpistol, + /obj/item/weapon/straight_razor, + ) /obj/item/clothing/shoes/veteran/pmc/update_icon() if(stored_item) @@ -128,10 +132,8 @@ else icon_state = initial(icon_state) -/obj/item/clothing/shoes/veteran/pmc/knife/Initialize(mapload, ...) - . = ..() - stored_item = new /obj/item/attachable/bayonet(src) - update_icon() +/obj/item/clothing/shoes/veteran/pmc/knife + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/veteran/pmc/commando name = "\improper PMC commando boots" @@ -141,22 +143,13 @@ siemens_coefficient = 0.2 unacidable = TRUE -/obj/item/clothing/shoes/veteran/pmc/commando/knife/Initialize(mapload, ...) - . = ..() - stored_item = new /obj/item/attachable/bayonet(src) - update_icon() +/obj/item/clothing/shoes/veteran/pmc/commando/knife + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/veteran/pmc/van_bandolier name = "hiking boots" desc = "Over stone, over ice, through sun and sand, mud and snow, into raging water and hungry bog, these will never let you down." - -/obj/item/clothing/shoes/veteran/pmc/van_bandolier/New() - ..() - var/obj/item/attachable/bayonet/upp/knife = new(src) - knife.name = "\improper Fairbairn-Sykes fighting knife" - knife.desc = "This isn't for dressing game or performing camp chores. It's almost certainly not an original. Almost." - stored_item = knife - update_icon() + spawn_item_type = /obj/item/attachable/bayonet/van_bandolier /obj/item/clothing/shoes/veteran/pmc/commando/cbrn name = "\improper M3 MOPP boots" @@ -165,22 +158,18 @@ item_state = "cbrn" armor_rad = CLOTHING_ARMOR_GIGAHIGHPLUS armor_bio = CLOTHING_ARMOR_GIGAHIGHPLUS - -/obj/item/clothing/shoes/veteran/pmc/commando/cbrn/Initialize(mapload, ...) - . = ..() - stored_item = new /obj/item/attachable/bayonet(src) - update_icon() + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/marine/corporate name = "rugged boots" desc = "These synth-leather boots seem high quality when first worn, but quickly detoriate, especially in the environments the corporate security members these are issued to operate in. Still, better than nothing." - knife_type = /obj/item/attachable/bayonet + spawn_item_type = /obj/item/attachable/bayonet /obj/item/clothing/shoes/marine/ress name = "armored sandals" icon_state = "sandals" item_state = "sandals" - items_allowed = null + allowed_items_typecache = null /obj/item/clothing/shoes/hiking name = "hiking shoes" @@ -201,7 +190,13 @@ flags_heat_protection = BODY_FLAG_FEET flags_inventory = FPRINT|NOSLIPPING siemens_coefficient = 0.6 - items_allowed = list(/obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, /obj/item/weapon/gun/pistol/clfpistol, /obj/item/weapon/straight_razor) + allowed_items_typecache = list( + /obj/item/attachable/bayonet, + /obj/item/weapon/throwing_knife, + /obj/item/weapon/gun/pistol/holdout, + /obj/item/weapon/gun/pistol/clfpistol, + /obj/item/weapon/straight_razor, + ) var/weed_slowdown_mult = 0.5 /obj/item/clothing/shoes/hiking/equipped(mob/user, slot, silent) @@ -239,7 +234,7 @@ flags_heat_protection = BODY_FLAG_FEET flags_inventory = FPRINT|NOSLIPPING siemens_coefficient = 0.6 - items_allowed = list( + allowed_items_typecache = list( /obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, @@ -248,7 +243,4 @@ flags_atom = NO_NAME_OVERRIDE /obj/item/clothing/shoes/royal_marine/knife -/obj/item/clothing/shoes/royal_marine/knife/Initialize(mapload, ...) - . = ..() - stored_item = new /obj/item/attachable/bayonet/rmc(src) - update_icon() + spawn_item_type = /obj/item/attachable/bayonet/rmc diff --git a/code/modules/cm_preds/thrall_items.dm b/code/modules/cm_preds/thrall_items.dm index 80b4d42c16e2..708b230d5c11 100644 --- a/code/modules/cm_preds/thrall_items.dm +++ b/code/modules/cm_preds/thrall_items.dm @@ -35,7 +35,7 @@ ) thrall = TRUE - items_allowed = list( + allowed_items_typecache = list( /obj/item/attachable/bayonet, /obj/item/weapon/throwing_knife, /obj/item/weapon/gun/pistol/holdout, diff --git a/code/modules/cm_preds/yaut_items.dm b/code/modules/cm_preds/yaut_items.dm index a648f2392d47..c646d929d9f7 100644 --- a/code/modules/cm_preds/yaut_items.dm +++ b/code/modules/cm_preds/yaut_items.dm @@ -217,7 +217,7 @@ siemens_coefficient = 0.2 min_cold_protection_temperature = SHOE_MIN_COLD_PROT max_heat_protection_temperature = SHOE_MAX_HEAT_PROT - items_allowed = list( + allowed_items_typecache = list( /obj/item/weapon/yautja/knife, /obj/item/weapon/gun/energy/yautja/plasmapistol, ) @@ -259,10 +259,9 @@ armor_rad = CLOTHING_ARMOR_MEDIUMHIGH armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH -/obj/item/clothing/shoes/yautja/hunter/knife/New() - ..() - stored_item = new /obj/item/weapon/yautja/knife(src) - update_icon() +/obj/item/clothing/shoes/yautja/hunter/knife + spawn_item_type = /obj/item/weapon/yautja/knife + /obj/item/clothing/under/chainshirt name = "ancient alien mesh suit" desc = "A strange alloy weave in the form of a vest. It feels cold with an alien weight." diff --git a/code/modules/gear_presets/clf.dm b/code/modules/gear_presets/clf.dm index d89e349a62c1..7748f4e0c558 100644 --- a/code/modules/gear_presets/clf.dm +++ b/code/modules/gear_presets/clf.dm @@ -918,7 +918,7 @@ new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/smartgun/clf(new_human), WEAR_J_STORE) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/black(new_human), WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/smartgunner/clf/full(new_human), WEAR_WAIST) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/survival/full(new_human), WEAR_L_STORE) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/firstaid/full(new_human), WEAR_R_STORE) diff --git a/code/modules/gear_presets/corpses.dm b/code/modules/gear_presets/corpses.dm index ca2b2e2ab52d..72513a95f880 100644 --- a/code/modules/gear_presets/corpses.dm +++ b/code/modules/gear_presets/corpses.dm @@ -111,7 +111,7 @@ new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/sec(new_human), WEAR_BACK) new_human.equip_to_slot_or_del(new /obj/item/storage/belt/marine(new_human), WEAR_WAIST) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel(new_human), WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/rebreather/scarf(new_human), WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine(new_human), WEAR_HANDS) if(prob(25)) @@ -738,7 +738,7 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP, WEAR_JACKET) new_human.equip_to_slot_or_del(new /obj/item/device/binoculars, WEAR_IN_JACKET) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) add_random_survivor_equipment(new_human) @@ -854,7 +854,7 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/freelancer, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/freelancer, WEAR_JACKET) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/pmc, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/dutch, WEAR_L_EAR) new_human.equip_to_slot_or_del(new /obj/item/storage/belt/marine, WEAR_WAIST) diff --git a/code/modules/gear_presets/fun.dm b/code/modules/gear_presets/fun.dm index 68253afbf90a..44b2a1a1157a 100644 --- a/code/modules/gear_presets/fun.dm +++ b/code/modules/gear_presets/fun.dm @@ -327,7 +327,7 @@ //head new_human.equip_to_slot_or_del(new /obj/item/clothing/head/ivanberet, WEAR_HEAD) //limb - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/pmc, WEAR_HANDS) //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/ivan, WEAR_WAIST) diff --git a/code/modules/gear_presets/other.dm b/code/modules/gear_presets/other.dm index 6a9fa4d6f55a..3f773f90520e 100644 --- a/code/modules/gear_presets/other.dm +++ b/code/modules/gear_presets/other.dm @@ -69,7 +69,7 @@ //generic clothing new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/freelancer, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/freelancer, WEAR_JACKET) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/pmc, WEAR_HANDS) spawn_merc_helmet(new_human) //storage and specific stuff, they all get an ERT medpouch. @@ -149,7 +149,7 @@ new_human.equip_to_slot_or_del(FREELANCER, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/freelancer, WEAR_JACKET) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/pmc, WEAR_HANDS) spawn_merc_helmet(new_human) @@ -216,7 +216,7 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/freelancer, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/freelancer, WEAR_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/head/freelancer/beret, WEAR_HEAD) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) if(new_human.disabilities & NEARSIGHTED) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/hud/health/prescription(new_human), WEAR_EYES) @@ -774,7 +774,7 @@ /datum/equipment_preset/other/xeno_cultist/load_gear(mob/living/carbon/human/new_human) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/rank/chaplain/cultist(new_human), WEAR_BODY) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/lightpack(new_human), WEAR_BACK) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/tools/full(new_human), WEAR_R_STORE) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/survival/full(new_human), WEAR_L_STORE) diff --git a/code/modules/gear_presets/survivors/misc.dm b/code/modules/gear_presets/survivors/misc.dm index 396c38054965..692833bfa82b 100644 --- a/code/modules/gear_presets/survivors/misc.dm +++ b/code/modules/gear_presets/survivors/misc.dm @@ -242,7 +242,7 @@ Everything below isn't used or out of place. new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/freelancer, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/freelancer, WEAR_JACKET) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/pmc, WEAR_HANDS) spawn_merc_helmet(new_human) new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/dutch, WEAR_L_EAR) diff --git a/code/modules/gear_presets/survivors/sorokyne_strata/preset_sorokyne_strata.dm b/code/modules/gear_presets/survivors/sorokyne_strata/preset_sorokyne_strata.dm index f53f25326b69..220034399293 100644 --- a/code/modules/gear_presets/survivors/sorokyne_strata/preset_sorokyne_strata.dm +++ b/code/modules/gear_presets/survivors/sorokyne_strata/preset_sorokyne_strata.dm @@ -5,7 +5,7 @@ /datum/equipment_preset/survivor/engineer/soro/load_gear(mob/living/carbon/human/new_human) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel(new_human), WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/snow_suit/soviet(new_human), WEAR_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/head/ushanka(new_human), WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/rebreather/scarf(new_human), WEAR_FACE) @@ -19,7 +19,7 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/under/rank/veteran/soviet_uniform_01(new_human), WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/snow_suit/soviet(new_human), WEAR_JACKET) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/sec(new_human), WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/rebreather/scarf(new_human), WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/head/ushanka(new_human), WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine(new_human), WEAR_HANDS) @@ -71,4 +71,3 @@ new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/satchel/lockable/liaison, WEAR_BACK) new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/knife(new_human), WEAR_FEET) ..() - diff --git a/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm b/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm index 324cfbe3bf7a..99589582cbf6 100644 --- a/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm +++ b/code/modules/gear_presets/survivors/trijent/crashlanding_upp_bar_insert_trijent.dm @@ -26,7 +26,7 @@ uniform.roll_suit_sleeves(new_human) new_human.equip_to_slot_or_del(uniform, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/patch/upp (new_human), WEAR_ACCESSORY) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp_knife(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/flare(new_human), WEAR_R_STORE) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/firstaid/full/alternate(new_human), WEAR_L_STORE) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/lightpack/five_slot(new_human), WEAR_BACK) @@ -207,4 +207,4 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/accessory/patch/upp, WEAR_ACCESSORY) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/tools/uppsynth, WEAR_R_STORE) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) diff --git a/code/modules/gear_presets/synths.dm b/code/modules/gear_presets/synths.dm index 3b2efd8c22be..9a181c817020 100644 --- a/code/modules/gear_presets/synths.dm +++ b/code/modules/gear_presets/synths.dm @@ -317,7 +317,7 @@ WEAR_WAIST = /obj/item/storage/belt/marine, WEAR_HANDS = /obj/item/clothing/gloves/marine/veteran, WEAR_R_HAND = /obj/item/storage/pouch/flare/full, - WEAR_FEET = /obj/item/clothing/shoes/marine/upp, + WEAR_FEET = /obj/item/clothing/shoes/marine/upp/knife, WEAR_L_HAND = /obj/item/storage/large_holster/katana/full ) diff --git a/code/modules/gear_presets/upp.dm b/code/modules/gear_presets/upp.dm index dc79f87c5135..0b3b4d4ecfb5 100644 --- a/code/modules/gear_presets/upp.dm +++ b/code/modules/gear_presets/upp.dm @@ -78,7 +78,7 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP, WEAR_JACKET) new_human.equip_to_slot_or_del(new /obj/item/device/binoculars, WEAR_IN_JACKET) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) if(SSmapping.configs[GROUND_MAP].environment_traits[MAP_COLD]) @@ -151,7 +151,7 @@ /datum/equipment_preset/upp/soldier/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UM5 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), @@ -261,7 +261,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/medical/lifesaver/upp/full, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pĆ³ckets var/obj/item/storage/pouch/magazine/large/ppouch = new() @@ -280,7 +280,7 @@ /datum/equipment_preset/upp/medic/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Medic Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/medic, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), @@ -435,7 +435,7 @@ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/marine/upp/sapper(new_human), WEAR_WAIST) //limb new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/insulated(new_human), WEAR_HANDS) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/firstaid/ert(new_human), WEAR_L_STORE) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/construction/full(new_human), WEAR_R_STORE) @@ -443,7 +443,7 @@ /datum/equipment_preset/upp/sapper/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UM5 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), @@ -556,7 +556,7 @@ new_human.equip_to_slot_or_del(UPP, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/heavy, WEAR_JACKET) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/explosive/C4, WEAR_R_STORE) @@ -582,7 +582,7 @@ /datum/equipment_preset/upp/specialist/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UH7 Heavy Plated Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/heavy, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), @@ -683,7 +683,7 @@ new_human.equip_to_slot_or_del(UPP, WEAR_BODY) new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/storage/marine/faction/UPP/heavy, WEAR_JACKET) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/explosive/C4, WEAR_R_STORE) @@ -707,7 +707,7 @@ /datum/equipment_preset/upp/machinegunner/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UH7 Heavy Plated Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/heavy, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), @@ -829,7 +829,7 @@ if(4) //25% new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/revolver, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/flamertank, WEAR_R_STORE) @@ -843,7 +843,7 @@ /datum/equipment_preset/upp/leader/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UH7 Heavy Plated Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/heavy, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), @@ -979,7 +979,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/security/MP/UPP/full, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/autoinjector/full, WEAR_L_STORE) @@ -990,7 +990,7 @@ /datum/equipment_preset/upp/military_police/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/mp, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UL4 camouflaged jacket", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/mp, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), @@ -1140,7 +1140,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -1155,7 +1155,7 @@ /datum/equipment_preset/upp/officer/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -1300,7 +1300,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -1315,7 +1315,7 @@ /datum/equipment_preset/upp/officer/senior/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -1461,7 +1461,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -1476,7 +1476,7 @@ /datum/equipment_preset/upp/officer/kapitan/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -1622,7 +1622,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -1637,7 +1637,7 @@ /datum/equipment_preset/upp/officer/major/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -1783,7 +1783,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -1798,7 +1798,7 @@ /datum/equipment_preset/upp/officer/lt_kolonel/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -1944,7 +1944,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -1959,7 +1959,7 @@ /datum/equipment_preset/upp/officer/kolonel/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -2105,7 +2105,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -2120,7 +2120,7 @@ /datum/equipment_preset/upp/officer/may_gen/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -2266,7 +2266,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -2281,7 +2281,7 @@ /datum/equipment_preset/upp/officer/ley_gen/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -2427,7 +2427,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/t73/leader, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_L_STORE) @@ -2442,7 +2442,7 @@ /datum/equipment_preset/upp/officer/gen/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/officer, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -2583,7 +2583,7 @@ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/shotgun/upp/heavybuck(new_human), WEAR_WAIST) //limb new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/insulated(new_human), WEAR_HANDS) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) //pockets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/firstaid/ert(new_human), WEAR_L_STORE) new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/explosive/C4, WEAR_R_STORE) @@ -2667,7 +2667,7 @@ //waist new_human.equip_to_slot_or_del(new /obj/item/storage/belt/medical/lifesaver/upp/full, WEAR_WAIST) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pĆ³ckets var/obj/item/storage/pouch/magazine/large/ppouch = new() @@ -2836,7 +2836,7 @@ new_human.equip_to_slot_or_del(new /obj/item/explosive/grenade/high_explosive/upp, WEAR_IN_JACKET) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) var/maybegloves = prob(80) ? pick(/obj/item/clothing/gloves/black, /obj/item/clothing/gloves/marine/veteran/upp, /obj/item/clothing/gloves/combat) : null if(maybegloves) new_human.equip_to_slot_or_del(new maybegloves, WEAR_HANDS) @@ -2865,7 +2865,7 @@ /datum/equipment_preset/upp/conscript/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), list("Ration", 0, /obj/item/reagent_container/food/snacks/upp, MARINE_CAN_BUY_MRE, VENDOR_ITEM_MANDATORY), @@ -2933,7 +2933,7 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap, WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92/suppressed, WEAR_WAIST) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp, WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/m42_night_goggles/upp, WEAR_EYES) @@ -2954,7 +2954,7 @@ /datum/equipment_preset/upp/commando/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/commando, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/kdo, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -3055,7 +3055,7 @@ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap, WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp, WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/m42_night_goggles/upp, WEAR_EYES) @@ -3085,7 +3085,7 @@ /datum/equipment_preset/upp/commando/medic/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues Medic", 0, /obj/item/clothing/under/marine/veteran/UPP/medic, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/kdo/medic, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -3225,7 +3225,7 @@ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap/beret, WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp, WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/m42_night_goggles/upp, WEAR_EYES) @@ -3249,7 +3249,7 @@ /datum/equipment_preset/upp/commando/leader/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Fatigues", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/commando, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), list("Headset", 0, /obj/item/device/radio/headset/distress/UPP/kdo/command, MARINE_CAN_BUY_EAR, VENDOR_ITEM_MANDATORY), @@ -3369,7 +3369,7 @@ new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap, WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/storage/belt/gun/type47/np92/suppressed, WEAR_WAIST) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp/weak, WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/m42_night_goggles/upp, WEAR_EYES) @@ -3399,7 +3399,7 @@ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap, WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp/weak, WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/m42_night_goggles/upp, WEAR_EYES) @@ -3438,7 +3438,7 @@ new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rifle/type71/ap, WEAR_IN_JACKET) new_human.equip_to_slot_or_del(new /obj/item/clothing/head/uppcap/beret, WEAR_HEAD) new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/marine/satchel/scout_cloak/upp/weak, WEAR_BACK) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran, WEAR_HANDS) new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/pmc/upp, WEAR_FACE) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/m42_night_goggles/upp, WEAR_EYES) @@ -3472,7 +3472,7 @@ /datum/equipment_preset/upp/tank/load_gear(mob/living/carbon/human/new_human) new_human.equip_to_slot_or_del(new /obj/item/clothing/under/marine/veteran/UPP(new_human), WEAR_BODY) - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp(new_human), WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife(new_human), WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/UPP/cct(new_human), WEAR_L_EAR) new_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/welding(new_human), WEAR_EYES) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/yellow(new_human), WEAR_HANDS) @@ -3611,7 +3611,7 @@ new_human.equip_to_slot_or_del(new /obj/item/storage/belt/medical/lifesaver/upp/full, WEAR_WAIST) new_human.equip_to_slot_or_del(new /obj/item/reagent_container/hypospray/autoinjector/oxycodone, WEAR_IN_BELT) //limbs - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp, WEAR_FEET) + new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/marine/upp/knife, WEAR_FEET) new_human.equip_to_slot_or_del(new /obj/item/clothing/gloves/marine/veteran/upp, WEAR_HANDS) //pĆ³ckets new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/general/large, WEAR_R_STORE) @@ -3630,7 +3630,7 @@ /datum/equipment_preset/upp/doctor/get_antag_clothing_equipment() return list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), - list("Boots", 0, /obj/item/clothing/shoes/marine/upp, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), + list("Boots", 0, /obj/item/clothing/shoes/marine/upp/knife, MARINE_CAN_BUY_SHOES, VENDOR_ITEM_MANDATORY), list("Medic Fatigues", 0, /obj/item/clothing/under/marine/veteran/UPP/medic, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), list("UL6 Personal Armor", 0, /obj/item/clothing/suit/storage/marine/faction/UPP/support, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_MANDATORY), list("Gloves", 0, /obj/item/clothing/gloves/marine/veteran/upp, MARINE_CAN_BUY_GLOVES, VENDOR_ITEM_MANDATORY), diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index d71a908d627a..8a0f0f8aa1e9 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -347,13 +347,12 @@ W.forceMove(B) equipped = 1 if(WEAR_IN_SHOES) - if(!shoes) - return + // If the player isn't wearing shoes, or the shoes somehow aren't shoes. if(!istype(shoes, /obj/item/clothing/shoes)) return - if(shoes.stored_item) - return - shoes.attempt_insert_item(src, shoes, TRUE) + // If the item was successfully inserted. + if(shoes.attempt_insert_item(src, W)) + equipped = 1 // what is this proc if(WEAR_IN_SCABBARD) if(src.back && istype(src.back, /obj/item/storage/large_holster)) var/obj/item/storage/large_holster/B = src.back diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index b54f03e2ce7d..34b80d1ce6f9 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -354,8 +354,7 @@ current_storage.attempt_item_insertion(equipping_item, disable_warning, src) back.update_icon() if(WEAR_IN_SHOES) - shoes.attempt_insert_item(src, equipping_item, TRUE) - shoes.update_icon() + shoes.attempt_insert_item(src, equipping_item) if(WEAR_IN_SCABBARD) var/obj/item/storage/current_storage = back current_storage.attempt_item_insertion(equipping_item, disable_warning, src) @@ -571,5 +570,3 @@ /mob/living/carbon/human/drop_inv_item_on_ground(obj/item/I, nomoveupdate, force) remember_dropped_object(I) return ..() - - diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm index 33d28527c8a1..e0dda3203d96 100644 --- a/code/modules/projectiles/gun_attachables.dm +++ b/code/modules/projectiles/gun_attachables.dm @@ -342,6 +342,10 @@ Defined in conflicts.dm of the #defines folder. throw_range = 7 pry_delay = 1 SECONDS +/obj/item/attachable/bayonet/van_bandolier + name = "\improper Fairbairn-Sykes fighting knife" + desc = "This isn't for dressing game or performing camp chores. It's almost certainly not an original. Almost." + /obj/item/attachable/bayonet/co2/update_icon() icon_state = "co2_knife[filled ? "-f" : ""]" attach_icon = "co2_bayonet[filled ? "-f" : ""]_a" diff --git a/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm b/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm index b37d42f1a55f..ab98e02cb6e4 100644 --- a/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm +++ b/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm @@ -31053,7 +31053,7 @@ }, /area/fiorina/station/park) "sRv" = ( -/obj/item/clothing/shoes/marine/upp_knife, +/obj/item/clothing/shoes/marine/upp/knife, /turf/open/floor/prison, /area/fiorina/station/lowsec) "sRE" = ( From f24799c6b25055b857da1c413b57e920809e216a Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Wed, 27 Dec 2023 23:41:44 +0000 Subject: [PATCH 09/99] Automatic changelog for PR #5263 [ci skip] --- html/changelogs/AutoChangeLog-pr-5263.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5263.yml diff --git a/html/changelogs/AutoChangeLog-pr-5263.yml b/html/changelogs/AutoChangeLog-pr-5263.yml new file mode 100644 index 000000000000..3b2b0690a4ed --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5263.yml @@ -0,0 +1,5 @@ +author: "SabreML" +delete-after: True +changes: + - bugfix: "Fixed inserting/removing an item from shoes sometimes acting weirdly." + - refactor: "Refactored shoe item storage." \ No newline at end of file From c3ae2dbf71e010d70579657506f5ad77403b381c Mon Sep 17 00:00:00 2001 From: Changelogs Date: Thu, 28 Dec 2023 01:09:10 +0000 Subject: [PATCH 10/99] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-5263.yml | 5 ----- html/changelogs/AutoChangeLog-pr-5303.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5312.yml | 4 ---- html/changelogs/archive/2023-12.yml | 10 ++++++++++ 4 files changed, 10 insertions(+), 13 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-5263.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5303.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5312.yml diff --git a/html/changelogs/AutoChangeLog-pr-5263.yml b/html/changelogs/AutoChangeLog-pr-5263.yml deleted file mode 100644 index 3b2b0690a4ed..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5263.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed inserting/removing an item from shoes sometimes acting weirdly." - - refactor: "Refactored shoe item storage." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5303.yml b/html/changelogs/AutoChangeLog-pr-5303.yml deleted file mode 100644 index 68f9dbb14544..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5303.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "InsaneRed" -delete-after: True -changes: - - bugfix: "Synths are no longer immune to lunges / dragging while in 'critical state' since they dont go into crit." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5312.yml b/html/changelogs/AutoChangeLog-pr-5312.yml deleted file mode 100644 index e7be9dce1385..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5312.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "fira" -delete-after: True -changes: - - bugfix: "Fixed XRF Scanner bricking if people were adding and removing vials at same time." \ No newline at end of file diff --git a/html/changelogs/archive/2023-12.yml b/html/changelogs/archive/2023-12.yml index 43d61e9d7aec..0333e4beea0c 100644 --- a/html/changelogs/archive/2023-12.yml +++ b/html/changelogs/archive/2023-12.yml @@ -521,3 +521,13 @@ - code_imp: Tweaked the way prayer sends notifications to be more efficient. - admin: Moved the prayer notification sound to a toggle preference, combined with ARES Interface notifications. +2023-12-28: + InsaneRed: + - bugfix: Synths are no longer immune to lunges / dragging while in 'critical state' + since they dont go into crit. + SabreML: + - bugfix: Fixed inserting/removing an item from shoes sometimes acting weirdly. + - refactor: Refactored shoe item storage. + fira: + - bugfix: Fixed XRF Scanner bricking if people were adding and removing vials at + same time. From 0747cc806cff131925f4f1c0eff4f624f4262bc5 Mon Sep 17 00:00:00 2001 From: sleepynecrons <106241650+sleepynecrons@users.noreply.github.com> Date: Thu, 28 Dec 2023 03:46:15 -0600 Subject: [PATCH 11/99] new sprites for predalien (abomination) and co. (#5269) # About the pull request this PR replaces the predalien sprites with some that i think match the look of the rest of our xenos a bit better also replaces the sprites for the predalien larva, adds wounded overlays, and updates the corpse weed sprites ![paulblart](https://github.com/cmss13-devs/cmss13/assets/106241650/68ed6d5c-5536-41e2-9239-04917b6caea4) # Explain why it's good for the game visual consistency good # Testing Photographs and Procedure
Screenshots & Videos ![46QUJQC](https://github.com/cmss13-devs/cmss13/assets/106241650/6813bc51-f009-4525-8fe8-f513642f5edf)
# Changelog :cl: imageadd: new sprites for predalien, predlarva and weeded corpse imageadd: added predalien wound overlays /:cl: --- icons/mob/xenos/predalien.dmi | Bin 3963 -> 12846 bytes icons/mob/xenos/predalien_larva.dmi | Bin 1207 -> 3616 bytes icons/mob/xenos/weeds_64x64.dmi | Bin 32998 -> 32984 bytes icons/mob/xenos/wounds.dmi | Bin 64220 -> 68814 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/xenos/predalien.dmi b/icons/mob/xenos/predalien.dmi index 1e3ec5caf8065951ece16bcacdfc3106e00aa40d..c6162729b5169dac5913c9d53919411299d69ce3 100644 GIT binary patch literal 12846 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 diff --git a/icons/mob/xenos/predalien_larva.dmi b/icons/mob/xenos/predalien_larva.dmi index 82786f273980688eaddf5bc0d25d0e48ab36a1a8..41eb31a2c809ebb57895a6423e5e1be204071cc1 100644 GIT binary patch delta 3497 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 delta 1068 zcmV+{1k?MV9JdLO7fWCS0{{R3Csb#80000aP)t-sz`(#26Az=4Xu+;~$iSmTKrv%n zNA2XoI5a4;!YbMI0Bmn0+p1V300001bW%=J06^y0W&i*HpOGboe~nm;C8c?JsVOAu zb4g9asYzME)z1YSuXu8KY^Ee_$ zoSDrg`}d5{hS4W}Vfs%FPf57EY zw7^hca3Mw&Mc{By6iS3UlFf3xh*C&Z5gY>J%c2-^Bo0L>5VKs1k$?&W(tQGXB%tDy z+(!pnFhITGPzgr}K?Z~_xZFennNgw~cmskDI}jsrA-IREe_WN>VRUOufT;&w+f{9j zJ$@?KVWqQSgQmQgUp^lyfiN9rKpM^T#XLRt{ImS>wXSvJw`5SCT)aMIeF~|tE`z-1 zZD!G9_yqK>%BnwwROXx2;Ue_`gv*j)1_Lixg&uah zKC{h9e*}04f2U1Vg1;BsP`xwabLxvRl`=N~s_qj~LIVW%o&sp2crU;eUhGSnb^=(} z661#qk;g&^?ww&7NF{yBDF!IDNJ#DloFeZ_4SB>e__s2IfdfMa0MQGiI|12OqT?~8 zFarR$gI~cy-W6_|czP$$R~{Cgic8&-i;QWgX`VcO>v)m zwvTV|+0EuG60omUYJJq6vI}+-LOt8ZcLJv$__94kycQfc_=`<9++yoh554 mzt^5@udlCv{CfQV%671dP0i~1}8YE{3 znStTV$MfU;|E=}DKh9d`+gNBHR==#G4+RuoHh!Iy; zBo)QgigNf5-m3@hP-C+IZAX85KUbdsS8p#OqTu|LELry+nVY)KyQc9D(hoUX10Qnz zxpv(%CsniP@$2PBKG_9u+or^1(aejxL#n}azVCBhwE^l}o|mCAqz?yV=Y-o@EOU2; z)fLt@eeJ)!!T$Wz{`dXkJ5sFkgOWq89Wq(YfBT{CMg@K0hBgH9LqoJCWmtM}-#R(@ z3HdbXEB)A8z^%aWTY+IuooRS}Ldy?e25QT3ly0TLe0Ex=k<`|%sZe~~++|&4F7oL>`nKKSeZ)FD*#i62Gz@YkI4s&Y$TjY&_EMj; zChEjGrh`I}A^5u2CokZTngcQVcXM=QD-EU=aX|Q!^9ra008J zPwA-5>B*$cWPg)CC6~1J+%0T;W$AgQ&V%8SEmiz5de2_BH<^XL^lTD_`88W(3umH< z(<(;a#fJs)Y7`rYFwq1RG1>ihW0UYK^2%foEcl3+<;rO#ON89)${uH0^1pUi^*&IK zG{l<{#()bt!Wuw8T?U-_E|8-M0O63ZHNOQM9YZdU8vQY^z^ll?s{JIfh?twbTL1=0 z*nljAtC~i)-@;rrujgJ8h971_@g=gbVxeu6Z0QjW_v#x=$<~!jWSZ8DPEQfQJG&-iT;)w_L-H zZj|SDIx5X&>THdE*of2F+mCPYu*jxkX{IHb!QB}wEFCq+BP}*5;FCZy#jZ+)$3TJe zXvU~R<7k0s183TAWTtw(ypiH*BTl#q2D5MmA0_~`WrV$os(Tl_g+#NjH7UNyB_-+m zx&-UM{@tCe(c3Gd4Rrj{boq4hEz3| zRuhKtv~h|8?*U^QWl#WmbLR8QPg{o~hse+7MLTpt|N8xlh*D3eVF^|EzhWohm^v@` z4+f?8@Kw?O_93!9SonM!B@(;yJi1D@UC_BGZe)Z{V~&~SsXf(zIdOk(pHU`XDywQk zwQnpW!hZE;r@Jc=Ix|=VC+>t*DeQ+EU;~0}^rS0w1mhE=`jytAe|L%=r+p{!{z{ts z@`c$ObE3iH^%OEa;=*^6r-yGYS}pMkx^Iw$Ca-%|4t1G+ac&U4PF!meUg*&)#R3!r z5#v&n{C%Aaj$$(No$P`n6C1=eFT==*6D4|!xm3p!>R%gu9>w&kqT+YfkZVDp71qznf{BO$e*-Ut+Qn&S_5md$_qr& zqttF1l)PW?z+I;IO!)$}oo&BX%=veaVVIEP5RP+Pt>gXzbxOoymxO;%4 z>b#7qt7BsK+jZ%sL0B*iAU!=i%sv<=msA^mdbE7(@@&*bFxX7|&Wy|U6E2cu)-1~5 z+aG?D4xD$qnOjiQpPPR4eSmkufzDRh z7x8IihyFCwG+k}NubgAnSZALJ2SVM$o0*4s5pDfF-#v6di}%y-cg5P^X>0IQ*VK6z zywTm41p<}oeJd;EuwaK_C146sPlAsc_;P;L?SC>4dPHYnGP&id!qal zgWeu($sYOFd%Zdqw`!@?{8wfccawidYgJ*od6`inT5UopC=+u=0mcqAnXc937IyS9 z1%{k^SL0u+u7N?gSK5~K_w6I|TQJKF8|HKYIr}NDi_dRNt|B**eOJ!5o!EUHU-HQq zF`&9~2tlktOLJZ;vejkse^?0g?;z<}daBGeLcL%DwvzGFG}(%wL5QaKToxbtFW&Oe zO|t~T1E{mjfJf!IwyAJK?ux%Q3*L)WguJu$u4txS7Vp26nY2RVJVZqvfgM0tA{?ta zGC!i8aL^um{tbg0Vb&JC_gskN5o#6qP<$!Dmiu=|lCl$8er>ro0~SBIcDSa!7}YC$ zg#0c>n55*8@z!MKbSKm+iY%#3P1A<&cS+H{>xQx1SPM|z^lBJDWfDVji1P$SdC;BD9@8v(q)36}Bvf^iiP!{e=VBoCUeM>r4BW~Vui`C9_DnR4sSSExZH@�LV< zEl8qATN_S~(FYkbq5WXE?g>OYw-6*+EUg_PNsdor5qiefO1>;lyqM#}`0X81fBiRz z9z7by{_=ays_Q`PcyXu@^J<|FLMqv42u9S^^aB*RmayoOt%FGkTgrj_yYJ1o=>by@ zY-M(|uy!(wMNM*{1`;c7ava_KHu_8`$1xCfuF~`14iWw#eLcljwlj-2Z4w$bY|QwM zq!MIJ5(9rd#Uu9~Hu*$~bM6_sB1IwfTjEaL=Biqc zd9Z##JT1=n(#s3L*XP}?7+&oGuOK2B?X8K^8}?>?JQx@C<@oqwyN)aO`IACu@X^C0 z$N)v~wp!(I`Xl`jl6-g}@_Dt&3cj>gV{9k6or{O?5A$O<9O)n!8tPQ{bGl>}Thy;8 zFTHHDH%!7U8o?FUIGA7+seHer#!RIQwL$R=G!71xPcG!`C|3jPV*@DKNdN@n^VDXD z9Eg8XDMS`EYCTX}dXVp7=g!TC8~-=ZL1XxXvdBwc(slCZ4GCdh=At~bCRkx}mJIKH z9GVHSO?-}PJ9{i2px42a$4Nh=k>wqHHZinxyJ$?xfP1bk=H2}HE1uiWH~Nv2jX?`U zToZpL=8fh`CE%4eCeBiV0-2A2DZvMo2uR|VDAdzWlT9(#?f znFdK)7yO}4wjV*xnk==A@DUOG4;|9?W9D%Z30?Z0F`Fzm;7vS*!9pVVkZanv7ZgDH z{fa(bbaO7t`=v47Z49Larqd(4U5-Fyvo@WSpdIrnK&B1-F(hElJYIq~B`maBBVcqC z-`^39%wtNwJRHVf)=6=$p#D($QUYS4-e*c}u)*ioT+-ohI;KMZ4G4L5ZAwgdn2ba( ziY#+$(w1}xAgI0{Ol!SkjV0`w_+-vyP!s4u!-eD+?X)$vSK%T+_eF&ARXt#`cIeZ@ z8h1IkX2)MFoA*Rxd?^6$ru`zR+=KMBZ-=F?BzbV{jd!25^K{ykfk66il=g4n2gthe zT>20Nz~VSeLi*q>42PADQ)fxZ<`YKLzX_3Q>hCMFE|UDbDNoPU>=dXwAC>9s@9MMQ zepy1;7z@;Cy93*pJbkEGb$mEBdO}S}CN1Qg@JCJaY`-}MLa#RVLL4{<(gD@#GYffO z5wBQz2T~4^12+e5s2?)x>UDLHh!wH5ZJhQyr*isX{+UG%-|W~r!MKPY%|7H^3mUi0 z@$Z;v_64n8F#}6EJAam1Ydk7_7WCl11iqg_xFO+}=YgT61PTPd85~u}81J zB4!EQ&MfguW3Yi$F9W+wf}$XHqv>sj6Fv|njuAFCI163gxs?4mrnUHD;jSBdpl~LH zb_#bV=qb(7#eK#+In{IsBJAT;fqOTynISXKB2VW1R+sFz41&u?6P+k=^&mo1Wk1W^ z77c1aGKck&ap_#~x3JRDXJXN9P8Z7eC!_Z9@{b?jc3&B~!EdlE?Ny*nt%i7)!9$Z! z8fgEZGV#4THlMcc(eIoY|1_n&;8zp>hJ|6aUf{DhUS1&r#oxgDmbpX)bEJ-rOU% z>ChMFpV@p;6=^1|)E4~xcR$~vEjR?8RRD4iX7#1^swCZMJdIE@JkVQ!JE+#1M_iD|B zO$vOb+{x>n_iANdM{w=t*zDQB6&fu^uSGPFBD1z0v;_pWsw19JydD=)UN1e(fOXp* zZqb7@`y?5dGua>tpkPqe=3XnIe7xlpGMcsA{8Q-9-j6`0FA|7tgeysy5QDeX^iNY(g8CxyB}bd?3a2ydMoAD_i>R_AB!z#kt^9hk6(hCDI!dczDT^fUH;e<}y`O|q ztKK#fWRES13>dNb*c@gl4-rC}vU?DV3Z)U5on$yF|0RyU!K zkaQ$(M!^)^G#i+mIWU0mqF@PU76+d_mKCoXfK?-& zP%n+4UyR~{Ku={$E+UkcP3)Ry%Y4aru$I@eT(@Sh%I_{M4tT<(0O$<}8+pz7H7 zwH)xpm$%P$1#hZGnVNm%pOZd2E;qhbD`z(%V58gij*HqfB6ybV?jf^&CY~(}ACjt@ zy5R-VhvLI7%o2e0T=aWI5>%kyUcn2q`RxnC8y5Cq6nB}sFUGz-zu2ksoc0hE-Gi=a z=U=Z9Bf4~QG~DLI8kvcXuM(KbWzfc8;p0qs*S#L{+s@Nf-7gmDW*|Qv1T&@k%zUDj zS_|*$rHVca>4go^cN~A`AZ#nif%S9$j*#Hl1GG(Ft-%dDcFDlko4&e7Ne?rm?%$!_ z9JWANcW5M(kI_&5T7o~0y;-?OF|x{uC_A1#iW_W@AAwwWJ_p(B5#dR+85agkKlI5$ zt3I*0x9qk%;-_`q9CmnJ;l2`9_tuX98MlBlX5ixY(91s)U61F3+e_C_oNVZG>)ew@ zOJb+tL)UJ1+7ji)RRRxqgZZUpp&^T4xKfE(Qgzr?9mWE$Cqz~%Wt%2lJr0}D&KY&% z!NF8;?)=x(6!M7G<#8!Y+k>z4R&UbYY_7N&NNz=6Y0d1_)sX^FusRu&KnQwOlO@OIWTHVl|&Mgnx7iD=`JmWMTx);n@*Su^$0 zN{a=*zu)+!g&`QSyUFh*!-0RE%`joKE&YG4oD)fBC##V=(V-=1aqw7BioS3dV9xw6 zVqCX)?QT@_e}tomD)WENSFGft|1lZTeE*M{tkD)l{O8cl@PFrkA6uj}2&Tl|Gz#ay zel)wwR2tSBubD|ZG_UEha`B@sZAHJm021{vC;u|PzOe_F*cir2J8mZ#ydLbrt7AH$b!K-XX`ks;xFXQhwO)HLtrhHYyghdBZ`+f|b3k36wH zYb1QBNCPUhx@=(@VPfIshhCA%kmjq@cNe+_kX?N!m-?jG2jUQT7Vt(GQ#MOkq{6yp zy4Wh9`nsTOFj5U4f~ug5Qi>)B(!5K2Of1J2x$*rCdRSj;oj_UWN9uqt9{i8l>xPq$ zZ>IJejXzBzm=F_0@x;6;0%i%2c7<_b8ZMK{{>IQ*4nHzK(jTi2=Xzix-_zu=w%KHB zQYsceZ?nS2PUVDO9gI1Hoy{Lo)O0$;Su&{$v32 zjjI|#b{IGTOjc`%g3x5a+_K=ke_a{yrby3P=~jZt>RdMu$f0tZP`Zv1rJ3;FG~vtS zu+Gv*%KX?RUeX8oK?X^I5Lf@MlzK)|>Z613thFtKF*^g%3)M-%m*)9iJrjxr<*G+y(%_RN`HmSso81|k$zH|l+-Cu-fxvpFS6+SZyz8s!XqpO@7{?iO z5460UDrVo=5J4!LgFfKiqC_-O^T}ax0$Bgu1Nqz7!`o(bafhyxZ5xhlUqvbvGoxGowUfkiBCLW;g z5uW?o#B;m0=`xm%W4o)eOMX1FKkCk1fi;-9X1YunIn(8v@FN>`QNb1t0lYP}vIU-a z15Ok0zWVG=j(@jqTvSjyf;>?JdHwKWyHH(@<<;%f^_q(l!o6t1i#Rlsu`vnHhnc_* zKC8tNCHmVN!o6qo`xjCo0724k{$1&Sk}l4FUXtC0bh{QG` z$=7Wmb)d@eg@yRTh~EuXjwO`IM_aASs>3i?N8vdY_|`m9nRFv+@<-R$lMM~V*(yG6 zHtZgXyXsH6%FQv2q3dvr&gaG)f)T>pVkD82t*vx1pYtxTRjabqh9FZ>8zoT3#x!L~NgOwU7d15 z6fUo^UJiKTqghtj9@N@fJ+8A`GzO%wgYk90cKKaB+CK`#F~eQZOqdMaH=eE+bSK@S zCArBgUEUjn+Y=<85FDcZhO-or`=!Z>lAmv}LB|{KaZdI=!TBHc5T~FNYTwQ)0TDrQ zMR-TC#^@*r`6?@^)p6?lmqpGsdAzAXw7k5` z#)g7z)h?xYWViG&Cd>{mc4pge>s+pSV~bA14&-O!CKpe->!JREL1%DNmyxlxuhibj$Opw*qZ0c8?0nhJS%k0atd<0oOSxC*41BjQgL0hh z#DPFhU3A!0GHFhPR41j*3;5IX$4w@|Z1;D@vGSW=cfWNHTNL6txP*Srh5H$cPKX9Z z282Ijzxj>n2U}!oO#L~G{Ux-^1f+o})bv6)%9p?OwNzU6oMoRLUQBmYA20_ByUSb0 z2~Xz7B}3xw8nqFRXUc=EuQTD^hg++u54-8{0?Fv0{4q#gv(E0mVX8dMrJEqz5I;-B z#hihnw>vDNIv-NwI>qEDej|yPA=Jlkv5*$DS)lEXBpp(DTggUy%vNNd4Tpw{X80iwdK*JKhScMZQ(1w;?Bv<)Y=m zaW1Lp-2K52_+|OGcLx!+V4_GS?W3v!yKau2AVaGa?wFom96kHek-SDaOD)kZyu+qs zxXBX$e+32c#g)()ALyZ4_L=#BvDls?9ssY;vt08Cnvrj^RdW`~f)W6pNB=o`#Qaf8 z09Z8bg$=9_!kEo6krxQqvugX(u$jXed#LDoG(9BBDiiA!XNI(Jb-{MS@W?8at;38VHLF*BM1eD9 z=YII_`odmkLE-=*>X?C)$Ii3}~3q8NusFWy~+R*u5A-mjcGzKj{@ z=32<1b1;>|TO)h2v@~$vW#-lxB(AfqAX%WL_>d0MWuynx^H8r`hN}fc46YyOgZT^F z4g5hV-ozcBcn{OqFHP5_gbtovL9*3T0qh0Xa`_vtD6S!G^Qqg&^8kMA@V9T~H(3#} zA#ecGA_v3^16cUM!uI!=AP2l<-FzF4@z2NiBdV9?yTJip=AJDW(|C!#7v`-V`tTln zC8R1FS1s{$Dbek|JgA)Hs7ep}s#K~?x5O%r-g17rVTrD>Hu!2LDE7DCv*n4K%Szt&+R zGwy%gN|3BwKMn7zHWj{BozHua6A6)|^(w_^ZV*(0mizGB#k=5$G^AMp7uJiiE;AfW z;|f8c`cS(IOvAI*{+2M4;*OV?YRrr9*5L=w#^~dNT?!h9rFd)`t?AlL%f(MFAAlbv zG?<;v2fX^-XL5wwnL-Nh z_qPIG>4|^c;=gr*dr_#sxv1#eC3&a4;v-V>UR6TD26CNUEp5H#piEp?BX4||@v9mB{iD8SynsD{UQO+eg=y!5?D`!}xV@*edGO;0D{43@ju;6a{yYA*R+Ofb= z$Y7I)VMyXBKmY6Ss22)c%oif;x6!`P&I7ZE%;U8OL4%f z;sE&^N1A-RTIW>druEh`;9$fwsVwKue&0zj(qglKnt6d95F>tyK1yzmCp2+{{#cA3CPMZm3M2kFI!7Kd7OHZyRO{@!#+3@}r7H(hP(>dL7 z>h*3#iCd#4PfZ24htmdz%sQ8l9v`|Mj$7k_^Yhc)DT?YSg@`p)b-AYK_p`?zGCGT9MG4vpi< zxbZI;0`P7i!yeMEGOl%aX}bw&5iuw_?g;gk-O`9i;>D;>7`W`(XUX4bfLf6c;W)4wXmuEjT@km ztVSVG3e;7o#8N9ybi31r8=uGAzYLrZevdAH>yjBkr75&V@q@Xvm@8IjN)B_!QG>P( zr;;{5A1PbI&rXJ8M7oYsA76Dj}U=>218IGfGYXw?UcnwP}3)uIUl4No0Oh=vFA7d?53v&055d zWWEFBVp;BE^f1XpHiN(w4r%qbz+?{oY5NFJ1R09eJEiSvXOPiASfiJomIp0WYZxyr zdvSGJM@Vo8mKz_2%yT@=o~M=zs;~~ zpZ!?YEcc>R5KnDNGWm-P4N;Lif z*3EMfWA0FnR_tx7jzQ+~!F5~Yurh6W@#<%q$yNb;U`r6y z2$q+dhV82QZ4G>kc4i&grOdsdPd;=_se^u-z+-a-K*Dw=QrJ*)ng#q6Tz``g`wW7%>;Wp;LN@H3khClK)*xIbgI? z0F@8)9_j05GOmI2(omAgaNVle>e!<+w{u;`TR8V_`;!2w_O>(H$Whgu2)0*I|17Li z4k&xk&sb?F6KJkSCL%KQ57@3%y+w~Nz1yK#4jRu^%XMM~>F->cX9Sh_y)ks~MNJnH zt#YenLTWzFNbh7o=g5VW6=B_w#M7?|4}!|=pM!1>z%0BRK6`sO}hkQ+(Fb+zV8YR;DAf=RQgaGna+7uDe5TbBJUqGFsr#>amK6SuI?5dU;x z+XpLhU-kmkT>8HZ#KrIBrdNd@9X~NGu2}iZcXf!1PpBg}fWCMJt0=ht#b&3xyCYM2 zL(|a*3JW}U;oo_q$Vp{9)cc*^Oan|TcGf&ssLCKCES#!ojR^T~mzvj2Z2>b{ac$f- zZTA5fe0Imz*4t4VV+qZiK%L@sE>`c^hAkV;pCVocah?!s+~kn3i2qfl9wyeQxg#f ziH$I}Z|3mvP||g}P26lIk8fc6VCT8KgLm%IrNCDr(e|4)km=PS#Od?mK?-V641}jd z38S|HNdgv(M0QJSoc<*Q6*4A=-=&P_Aq{XAZ)O41_g}n$i`A;&ppffYv|$1{OHVrT zgtL8K)%yJ$I0HXFWZW|Zd6p@g;aNCdYPB5LON?@;BVQjO1Yg?fU^h~mwoVbOyS@lT zU~hxJXeMHQ-bpHDQRrZN-`8uxLq-qu(c|?R!;?Gihe5|MlSu883B9o$mGx~F-QD6G?`7b2``F_AxGe?{x~d$!z00y6 ziwk9|Juy+!%5(YgCu9ig?jf_*gS^_DO3dK)W+$rZRr$7 zZAJ3qo<-7;G7&A>!KBDe6DHi~JJaD}T}^0drtyAzCO$Gg7|-jo+J%IsW+G8MJK?9& z94Goph}+E^97{6gK()Ltk5UxT^qE>`-M|Zh^kR(l21*oVtlbs6iMiqDDn^TXjg(5* zVlu*k?dASav_TpH1zw_nFv1!PJlXFU2q&w6y=4K4f^OJhDlU*&s4IcV(qcCxI{W?= z(lIdOF0+hOMwrikmbYYOU>6~S1od0-#qB^V=jSe_QHcMi_uEH-OjCDFa#=V zo(1F~UB6(&I%CtoHNpumw)Mj7Km%j@mLMo)U>eNUD@7I>t-(kVFWjspN`|Y}GPviA zzqNOXZw~X=IG$LA)>lJt$MQ?CUX<(z#6Lzo0ZyZQiHBd-5RSzqW}A-Em=@je(uR?S zs-)3GS{n9Yl7i*(%Vp+Kl7d7l3j7Fu)89tp_md#D8oTHA+^v_*ON>~(Sx;#~S;&2n zZT^*}Xl9?gOT)IzRt}gdJ93+BGE%|qY6um{4L6Z4!&yFby|E8$Lr<#m0nty3f2jJq zH_R?olhJ7!pc${Ues*Cm{4-gY3&yl^6c(w`8*JJYkGvU8=z;h1y@N%A96XVf0_P1WI$tV z&ky0FGefPbgN-gsVq(LE`3Eh`=1={-r))&c^My#Z zSs|PF*5?=#auWxPFGVD(etYpFF@#&$aQU9$Myfwzh_o|Ikx5^y8T=(g;=RTDA`>1) z5(!;K9T83H1h1@Er6xl{u9*I6_DXZx165b%bHC@Yz2=Y5cUVR0)U2sjb(&an{Qo5} zPA2+mC!$?zH7tmY_wvY!vt>e7R3e<)X}3~mGFq8o(E_+#u<%N7%M817>o!7mgywY& z1DVSuC`|Yb@CYR@1X@`V3qEM7UP2<`XZert+$lXYE5(r|F_&M+{!<|EZMIt3HvM9+ zxpCq$;jX%_A6(l=v#~8o@okxaJ@%&I-5T^}BHDVp^#qpDM5BwVw0zQ*9f{I;BuZPAHFiM_0`i(ttk@4hTQp;@}SMH6rOXy7qL~*1b>dWrW2lc zFXy5)IsHh*i|qAVgEGfTD_ORwKd1gx(D-KB<*&o)9B6YoXg_ggSQ2FBY-nZ?A5OuE zNposOuz-{5CgibpnFvPnK=bVNjC72!)spO+&EdnZTaMX~mBKE0nJOZ+-*E@9Lfj(< zEuulIawu6=2w93P?!K2oCv!_YyYSJdh1i7AU;x6t>*+W1g5Tlv3N5K#|5yNW!kRvK zka~y-;_3n%U8FSVjH98;XDJnlztoQ(gwdq3=hqv5FU*$5)*YUN^};UJL+m!!ryos78uBRO zcEhV=)uXMN(6a<9?k5L)Il^tHjdt0POoDK}faJabsMf-}xVxlvOyx0568A1aB7df< zfx#p+$_6PESh)$l=s8qN+b{l@aUjE7SkWBakt3Rw*VGjAvKzD3X*iNbe(6OnZh^n| zuz8m~y$USwx_*RJ6H<~(usS_QMw4_1&)pKi;W8w;B=Hb(gV=R7`4?+gr4fxkRuuH2 z1xtv0LD`>F!8#+8_OC4)&scmdr0b$ja~w;5a+k{*e9<&|v8>ocM14@#2ix_v+}qmm zXnBGQQH`ON_=YbrD=r;?SOS433&Bj8txNH{X^;F){i0Y{vmpkZD`6+A=Y|8BS8ZfN zIBFn0*?TBxhi$7fi%=XGnI5-Uw;};f<}qU8*lD4Us!BAZPj2*-4njfJ!^~2p!@l42D5`&-@J#WQMTAHMoxH8%C74EK>o+QXo7~m7)wVx09%?<% z5bfndi-~c$L>8d+S+3+r;Nddr{zz8onfg+x#6&WIk)FA8cl|?rEQe&Fuy_{>&~U;W z05hsSx=c7jeEW~_quVCs>dkBXmYBj}{V)ZeHqK^}i_s-NU|-O(H_h+}6H~H=!Eq@i zk2Z&+G>H#p-waeIDnD~Mj}0n#U_jqJoWzu8p%FAg;)IvS^38_Xl6M6){jGt|_bEE$ z79obC=@ZASO+)o9hW8oWNaexyf9a|l%0$A{@o8>~xzkmMnO;Y7@Z-x!re~@$!1pQ! zU%|5u`BB@PGpm>#7EJKq;sl$CyBbxfUw>-=;a_8^O2#3mVb*DXFSD<(_oF1AaC?S8 z+T$$FxK@@Bae{=?&WKgi&QTlgIBa(V{~XgotMJU}cQ|sx^w|5>BV8Z;Kl`8FmYD+r z_=bhgS%PW%!6;Qn{+nv#5jx;6mZE{z_|4}d)nyBzCd*AnZ>8a}kKQexRqVop_XLL6 zek+%llj=6RyPRUBzDpz=bri1qNF47f=_s$*$YvjYe zI-oksLTl1Y0t2yeZPhrWC!S$sp-|FvEB>Wbm!Q(O-b;|^$3u|L@lJv}msvWnnQa?K z$fT|RjL4*-DnFbF<4o0vBVrcGx<$Ko7|QfsQHAGk63yOMR1Cw^o56NNAN6W|q9JUC z3a*anCE0S3`6nw-a`%`(@N@*(`E}-^onjfz@2$~Qz9-UNd3z?=tz^VgbuOi@yY00C zEi&;IdThA3UM&-fih7Pa=HYe?@M9&sApbDkq+=kcK++o3PW=4BU!&Fly37jyS0Mh4Ssd!OSNB|*bv zfoEPfI?hVp{2t9DH8G5)zY~GVpe_76fUGRoy_{X_Th7P2Oty*>Z$8yF0KG2L?3lrJ zy;7kY6==eLV^{aZpAC-oDn?ee6UV!eo;G=?Aj^Mc1ZJz;soPQIyb}uAl8upVtd}&T zI6eAlUG60pe)}i;R#6{sd~BO7L=6h!9|RIyp@yi!gGu2d(x7O1AzTYXy;q=PC77BGyN&;FGFjf{U>!+TEM z;oAqXN67cGOZ~j@LT}W-B{Qw2dr5?1nhARzd75{FWE!uIrX)kZ92wDm=x!@p=994` z8OkDIh7Zsvh>~6Si9d+j`_1zGIA~-lD@RD9<>&FbNC9>m2!3|WM;I`TR5x49C>~j$ znL_bbyi-ad(9_5y1?gndk>?7xH8V`0OqoFq3?T)ges+MmwsSP|P|!z+a6c@{sq12L zpPzQzsN+(H-2atO`D{yy2kEU;PLjl1e#JVqH~Z`BCE4P*Y`$H?w-nFS0W6X$blS4&hzqM~3A|-6C%_}m zYt)A0yLe4k}GyT8XRYx3t%rAE{H5<9RUX1)qFc|;j4rFqa}|Ki+IdLnEf zWDu*O%JU5=9{?tYg|_eh#S3U3j7uy9DG=0HifG+#hX)67F-L$7L``49f3~-xr9n6* zNRS0{hB947Rgr!w;z%Lre0XYfc-@a?rh)tUSXm?Lvhy&6FeAv zoJ#br=wm|lqU(vFPV6zEbG!z*3M*Dr&xH54!4PnA)@K26Q5mzRf46wYyK+!WgdHtZ z*P3Jh);yLpSI!^&wtSV98i<<2G{$3<44kVFduC2E5QcM?g!a7{sv%7-4l>(N%i`Wl_UvXML8~4BM&e zPyWMiZL$dVjjbW#Nus`lc&i7=S(puYh04C0gDBdPr)N#wE1$OD_ErC=!Kf6;v2Z?D zT0LV`!%bs_f@`c%}O-F$dj*2Vn1BFWL=Mo~aJ@FwVSIBKw`UHS{%34}>y- zH%ucEp&K=_YW(l_#g7jyA`8E%%P*_Ve1_xJGD?&+s<%cyyo9{wQ$gHL-Y)Ktm(_@v z;S>@NLH~a5)XHF-X9e_f%pJ8OSb!9qV>J{Z$=3}FO;@9EjfD$+46aqEnv%4M;UUmF z;MHzCuo@z`&>F1drWT6PRa(s7O=N*Vx1dsno50kJmk!utUR3ogmg;w;;D=ker_?Eb z%4+W;vaAm=wpi$M5c~k+$y6D?Wy4M>F{@97_f}&)F!7>3UApfS7LR58cGJS^?jgE| z6-GJeC7ql$c69b-3ST|zTAws&0!ljI8|>dS#waI3(t_v+JSPd8SK3ghIPlWLoka=d zd~_x}h+4$N+0FR5Yc-1zik;@dvTVs}*xgS}PNZ)2Q2Ozm3~k`mTRqo*x|!S8e>zDR zG|Z3h3~cIbU(B;ikRMWM#bzRkpdqi3ELMH6hF6nhdk4arss)61v`mKDZnVY4q9_&n{UP zFNq5MA-I%rm0)=X2qNSU;zmx+axYJK>`PArV~?6gIzojA9;n!(S@(#Imbo5y8ClIL zq>>0zt;XFEJR5^nE3Up8s*+0*^?bNKN9*0!V9JiP(ALN%-&Ld}w>A!I(ZQ0Mi_3X> zzj0iuFrLr*3x?uPIoiU46hL#^sVY46M$JeVzBJRHe-+RcuNNUMQ{+rrRjlifIebMR zHpNi>cw+aQ#1u+VI1Y$VJm`Dd^`NUHuA>?e+T9nIp~y&4LYCIXbJiX0sA2DAd6q-{ zcP7NW@BIn38N!SR;6*wlJ6#aGLhz?5YbAvqr5GWUZ9i;C=JkMF;Z_Gep%hmktliRR zQRJ9%D}d{i$#xfOG4MSOpv~jEO;V|%Uwh!fa9?PuIZcI^EQ}lg(_)6dJm>entEyS4 zKx|am4K%agE&98Y>r}{Ym!70or={R&DH*BKYNt)j?RMSkp@ffn>t|yeAtFX+OCLC% z`)fk0yhax+r+1?E$GPSnNpWqJmG)v25 za?F_Ap1k8Msu79dd-_1>kJ`N>d{>(fIUx(94Sr z7~A*u{rP_X`Th6fPaf>B$GOja&ULQq^?F_d#0Qk+wc^R>ubO^)#q|q4W~_xNYrMlJ zW`AIhNy%y)GWHqRBc=jFXix^N&a@Vp#U*TX&u*z5K`p9elLcO!HYG6-ZUo$v0ROeA zSYGRHTfr=>gUwbiUJ#7Mj0a#>!Ap#?jPF$&SvXVG7?x|4ENQEn$A2fbqA?=h^t@f{ zC<&b`cC@Jx+n-$|Ql_4(&{~Q-3|taRjP_ud`kmjq3~r=3rJ6upZFm@2NPDTqv=7ul zQ%0t5Zql{6wPacQ$B+r0?2u>((pqjwFr`#=F2pIKJ^dpr;)xYBC@G`F`Q^R@fef4r zZh(b-6YkGt(Xao7A|%YIZs-L;0EjD0X;1+k->!8ZH{?b@bX-5CQMaB2&2BiM`>>IA-tv1R3w8)ZlXE^R4?O&q*qa?fx>fOC> zXnk^>JIG+0>i1$6?DJ#l7Y0Du;t*;_ZE zrH^tqqxT658`)xd$M?gRB?P-i&Yws;2Xe&yXs`CDL;ZL6$jU@DcmyK?X!;9fewIb9 zUp{<9|K;92oS z#b|&8*lYMP%Lo&W9Cm$ zQGDvu2q;Qx2Vh2`)^rA$n31Ua)ppcpp+xzFA!bBH`bK4+SaVpije0C6DMjFf4wd(!T(wJUWFNAjvD>i zkzPq@=v;ShP$lED_@oQR*A5i9NbB1O7p>{Fy0nPY(E;%hte(pgKTB8`ztSzsOM*J> zzaq!I*MCB8?>8!P9Gp4*YKm$=aM1bbbi9&Fil#*4^PgM^#=oRQ4+?S;2+V{KB%Vd$ z7(v#pr=Gk>wKBo$qoKwF7!qjQg~5Hpfo@ip9^<$UYhbBXU<3P1M|Pg{1|nyNgD9Fx z6Xys!e7viWfaZ5zGmzbw0O52{ajkLq7LZ=^dW@pRx2{!SE?ywRgT}hUSbHy@VMElu z#t!IKQU>>`_Xx4A*j$mNNp>@)mYMoS3pcn$LizI3g85|JgtQmy{LNK3ywIkdKUh&o zsT@Z5f#r=62~?WueYUn_zAA=a{{G_=^9b3Kh#wPgW3oV}L-#hn6;4k((ilncNr8J4 z(IukDibqEAh0C|>XiI1{Qy9SE@9pLZSv0M&Dd9YGsqF0x1#n5C;;KhxQA(O&eUuYJ zGtr7W_2@@H@?QJZiPhqgOh$+6xI&rn&#ZhgHg~FKu8r(dIC}T86xEF58^u9ehl;_6 zf1WEa2(KL)Nu&gR*MQL)){~v}OGURTssY>wQL#XO>{09)3HWBlLM?>=1ZtIO<&{JB z^Eur#)5b3U;A6x5H=PNLevj#<;Zwkr&A}5pC~P#U`?=$=5^{v@Jae3ix=m2+?jI0s z{%GCyay!|JyG_d2IC(C``|Q=2&&_&+SCOq!V_g{x9j!cAMoOyh^snT}644E!H`*F* z(ih1gy}uvDV_SvEUR>SkGH3drHtuQmve}gaM7?m#SWKmEGfF>qy--#P=f_1nE=P?!od9Q!m4E8BJo?6bNQUU#kzUM;_ZHiJLb(V|29@8`OV`j8l-|(V!-ZY^n0S{T=dvD<|H%-GyH)1>yqU z$oGRyUFZx~^3@0$d!uxQYalWYwh@s~Z7GC0!KD8vWto_daY#hg*k-HrXt z)6iT4RlMw(f9&^~@mh%X5jCk)xuA%qn20xMqI!7T#g&0yp6xSga8fv29VW1dTKaNRX(ztpEY=$m(V@BxN7pP00 zd$xujfotS4c!rJ9mNqwQ+3R? z)mt@^DCx(l8kKQyYTV>>z(Ex4`&(fK9*-($CrAMCm?m|agRbP|1L?}F*Ah2cNu1N| z%otaTihd?(6eh7a4I2-qji~kVdu<->>3R3Wfne|}8E~K|uayYv$22PwEs!h8uDn)J z$cK0mFy9>}q3k;hXy-qCy+*yyJGKCKaZZLrzwgbK-kTO71pyQ=UOan?=*BnZ zA`p71SZdm9rhdiUQ=c(~Sp=#T-du#TPY&GCk5LS7dI2x1y_i1qQ>g7n97ZM)_xUVS ziL774<2_cDWP5`~(}8@DhQ>D@{RDfo&j4?)k3U5HdM$ng`eu@W&^v|?!PvtqkCk|) z4Ab{Z5X;+W>XXcDG$5C!1?=Y6xPSdTx4QcF6U8ZMywzDd+npUW5xZ~bZxjhXMOoa& zyJVJGYHf7WfV-^Qb?_KF9YQH;gU=eAoT!_L-p!{{zmkj)qr=u>G$EiBXeQNC-}Ovb=9AA3x%VmZ7vkeXzM1pT zYC771?#{%h94*1PERf}}{53Hu|Am~W`zm>EyP#$E-(@NJrw^%WhNf}}L=!@=FWK(V z>S3=a_#nD157u8($ncftQS^mzDf#Bt%A4tcI!!M?5gD%!7}oY``oWHboV7hPl^ffA2z%IMWrFfZNVP;1UI&Fbp^?x7$V^uGSui2{an=vi;HxDc8NQR$$Ai!$DYAQ4ay|A_2R@ z7rfa9olKgq;LVgqC$G;wE|Z_QC0e2cz?Ze$)+3NnZqBW>=9FAP?R6wIKI~~r1}v7! z1h;&Bb1~QJ%|fd|5v(BVHVlut+2{KQ&h@j_s`1=8jkd|OtAkC-_BMUHamx820}{)> zS{0QCs|p$CJ$`p;!8H2)!?vn=4w&|U;66(!e(;Cx>z3Og?4FU@OuTx>s|DpA~_;S2>vk0&ACamN+GTGi7cCWE8eq4qq)V3djmPIY2pgdxv(#!-jhm2(4s9 zvtLoD`fPvFgrRCkvRO6gD0ly!;ty87H0G`hID?b&4;%EW>F0_0{@u&q76w2|p2pIAi5hR4jo2=Dx+jq1K<;$!%+=AiNBcPDo_lTRR(_5!b{Osyg zLJ#(KuLH&sM!|HV&8AG{2d8AN$s1F`)z$0cwe?w#Q7d*o;?$U;UsG;V))by~oN7c= zv;0bk0~QGzGhc`I&w}!~)ql{Rk9IdnA&RbE`^!=h@Zwx8H2$m<}0&T33Wdo~9>!`y)Vp!u|xh;1BshO_OfkKrNa z82nYfIfaFsaCVa!Un8^If6NrL&1$B|4&F35b3xPS^ZMbW2Z|@#5=9t-qSXa2X|0oG%uA{WZ10>a`XOJfctj5SANh&)}=zfvJOWuTi)Dg?5!r1#JO=jxw%6YAQXwb z6eSoxQUdlbGn`g>{>IL}JXh17k6XJ_vPit?whMK{+*bw$a1j6tV6O#bedbU9-$E@7PDW)pcsDtli6g@$mV{M7KA z6Q|GKU$;zJuLtt(G%}1+>FF(fyOR-0*{ab#!YzI*4G$xR6e8ka=a&Wc4mPKjWXqAM zZC9q(51S)7h@Hj53c*rMH5P_(OK1DBVP~0O+M=wrz zE^lb#XHVyYl_v`DVLtK=lbMzVFk9U&L96>hd6vbbGsoDH(#RG&VfH zoU%2mCt{t+DW?UQmWOG~_yCQgWw+rULv!SVC&Kf^QPaV4f1SK%(T6&TAlRNtW(Zky z2ifxAX3bAC6~&q>zofR60{Owolr2kGKPz1hxO~lb-TG$AtuJOS_|nuKuY*MqFJryX z7Aw!DMut-rlg(kc1?hf(IkFDM65#r>>uyvS4Y;?a&zLaq0}Fp1v6OPi)l>!Wv6`@Z z+2$OP@D;W+jSC3_GNssZ8FLrPKhqcBEAn_)a*QpcqF$YoGs`b9n(n<}!bxL`!nX#7 zm=+PqmPInI*|wZP4Tp!a%5E!uMIwFC#QeS;{X*(%#v=55KHRP%RL!9#cC}v8fLCmP zpzKH_&@)B<3X8gndCn@lA16^VS|{wU6nMk03v!nWM%$Q{WlX3QHD9YU^kQV@5xZh8=y~6!j~8_@3_4gbe52c=z_)>WJX6)%RYQ1bTCa^Y?dV_Q z{0-mZ%{p+)E|cFaAux2)>u~s*O%)9>4$S-m2xd7>dS)-ISNm@@@C1dM=UrmFD2Q|G zb7t?)B81cnV2T>Nrr{EHS!7GE3U!}E*`(HHpR9RN(%(8>*29wq2r(1=aS*KM5lLt5F;HTYt-^C*^&zq2d@DV z=n};%4cKkh+PWG*=r>6eJ5uhKrlc~W)_nuIjty2MAAaU^Eu|FOd4Uw$5_lTrxduv1 zrC$9Zg<$6QasANL;|*!oH;BemSX*Rs}5G>uD%051I6$o~ez0gL9QrG&(;F zmuuqPUBr&bWWg?YP(;u+(r_KYIYcY0zdOBL?e|=xtDXWqLPG*y$wl+D zsfPRHu10%D{6$UGK5R;OoBE4->!un#04-}X?lbNaKWxN;9+9p&R6?-_>+PHpN5gzY zGDtVS#Z-~kdrx3A&VxDl*VH{3pc+748~6#kL!)^5M}R%52&F2xpN~8+ zX-qsHL`_*QILrzTPx5lif8LJnP$If70xs_Nc#bPx(~Dj|2exHtyiE7D^hLK!aX-ut z`;EYmca&dsik21DH*wCPT1=$*u%n-QEio|oN5COJzoo8=!*o#v7~u22l@CXcrEWc_ z;RqWBROBTt`}-5eCHBwZk(pIZ!txy8_u`rb*SzG)mmO1#qQ)gOK3JM!q1UZZA}CMC zFLG~oeyxjlTT-7)!H&&oZyYiZXL5Sz-cqHCpdi-f3C09zpnwrm+5c1r)L7FmRW7xz zm4W0~C|*#1T|B8zraSk{5MmjX@4nuc`DA|;)reH)+0q(1Y=G)?rzETE6yJ}Ho2(`J3 zy=U*sME|_c9O8$v+*S_3U6406)_;EFnMwRk^Wisdbc_hZ3B|z{EHph!Qfm|y$Y8j7 zSli(K_HG&#iS_ae@!U-a)rGs2USidkcZf~uU*EtKh7$Y2CAouCHNLZ*S$e~Vq4qlEYe4q}?5k8<+J6$AGAvN_?eZhf84I`ztAkzqU@3%Ad|kK4P4I-XgF3Nd*v%If+8 zV6E2P+)cV_R$BLDW1`2;>klN}7d4cYAn%Q(BU7nmYXki)V$J%miD+$j}9%6M2gzy_C&zC+^=;HP;RHgXF(PBm%^|kTnYH4<>VD8UqR`n< zLaxfFE|u`bqRVou2&tx>l8e=I+{UBVoKJ65GIFiLn#csZWPp7~EQx$RDf$;Jbf>}Y zBSiQdH8gy;Ccc-2n)#srJHqmfmN@n1;lI>5#nrRVnX_+v$m52rO}4T$+m)Pf$7&7y zwNZ#~Cnh?3Z&J}ov(*Hp*P~tCC8d}vckVF;E zyFX-D7=fW5E4iBqmzzsj`Gzft%tn&sTS0TLEu->`=tT zhTE{voAk=;E>cdaViZm)ulHj*$U^#^>A+!J6M#Ey=?rE568D7qE%xFqbB7;oVIORk zG#0aAyg~)tUgavc`T#w}+udx=q_Q*(5qY3SIL}+5<;46ji*GXU-xs}V`qm2T2AgIj zT1oY~+%0IP`QD)vCQgQa*P-;j487)CXKLg`SqNa?+H`Q-1JShP+bGQ86JW zs?zDf-<3)_aBr(Bs$>0m0j|eM1u1in^YNkPVe&pqo-pSB4#Z#)X^u9(9m|^FY1|WB zy-T1_y(MThw7KwuIVD!apJA8mbN>(TB3TcfPTnmB{H)FI{?{}{@`#hquuhUb6>9BC zGw8b{nDD8W+VT_*#Qj_6UH`)v3MVJY^39Im(!J{|zV9m^Z&yFBroU6qD)jb_K+1|VZ(4Pfh7hRw$9nQPn*-i)xy5eCc% z&LZEMl#AU>@2FdpeE)MVN-nP2QDeR2#{T;~ZiVy0q4X$PNvo83nF!Ot(8oLZm6c*;;E&Y7aoiTO zpPI=7TUpYVQtTi-ReF? zFa2B6;%+tLp>e0y%Hx#TghEfBMo)P~o7$+B3W5ar==X{e zf$~@N9v^;`QsXB&Qa*_7Qz75FylO{|C|*y0Q@;K^>`-J8>?dzMiGW0BPMT3B?bUAe zd73rfP#uRX+TS#cR3GP0!IDe4g?~~dG1?p^?x01?{(w5cmr!Fup``B>Fidgza@ohf zGSsLTzAk7^2D^|O3Whi~bBj0bu#6pGO0gl1y(8#?N)ma+C&DMCXLoiL=Pk7V$gSN~ z<@kl*1@{b5ZYxE>_-VIWnJ04a{`?>P5x+lHQ}k z-x%;}XDhksNw2a1G8}!oKz8v6+hwcqU(0l=`;Nb!(U=dy__+pQF`d{>1)l3IYM;fI z5F^Mp1!bO05wN+Gb}O&5Y-V{NMKq(F3S=fqF!#+kk0}Tme$Xit{A&!6h5a?d&>sDu zvb=VIrzJ7$irk>Vq1El0YDA#Z9Kzjm3OKcCdKUSZMeOe;#;Rz4nD2T6-MDH<4 zm(KSI?<6jSWP{tEWf`h~!*bfD04^y)h}RXOdqFw<3V3{a9Xvc@mX7C!3N{S$rKM4z1mkAo25l@Xe(Ng4B&1^m?RKYHgzlo{@vUTTBs&D)t0%LT2J;QdDBPDsAm1y%LCaA9x-@N7b62v z6gL<|8r;Y)~p}CybbneYTuk+J51xt z)H}iM$=3aI7V#R5^D!lvlQayAh!!F>PnPmaGlK<>%ijeRmd0;dux~=(;#pqq9e6mN>HYdTX8y32(50nzm=4uzS4RmVj2Hf?-;TsyJ*BT zixSZ{v>QL!bnd#)A#Dh5C}o)KDHuf*$CK+F&F9@=;x~TFMpU6OIPRqRa7`eZukyai zBjn%B!{MFiGfBe0%CXlK@ZbVIQa&B3{z)N0L02JB^|n#O3bWd8#c58MIJPv`K4W0R8^o|gpNE)36-r(9>%047Xl1lk;*T3_#vLVty0|!7){Qys*EB?~y zI7z!Ujr*!bz_N>3nWe1y2j(0vcj`S0u0GJ1tC`~mwSA^v0P<2wr zij;=cs3f=BYjgT0+~e9#)Vl*R$1CO5$y0QYosny(Qk>oj&0oq#1R8jyS~T&%%;n^n zZ;^AqZQi91&gF^qpJPW<9{GL>^Goy4(lNT{$)FbJC06!$p`f|UxAu^Ti-<*Jqq=l_ z&MT!GKK4;p!;e2v^Bn4Sz<>=YD5(wZEp54w%*C{!K?vntty?@COvRISK}Vs#@=ntF z(!xxz^2f}uwD%C-AxX^LJ&dK+GA4(8lUEF+ri&W(ROXROoMz(nFObI?N@&#W{g^0! z@Zk7U(p%Z-Cc<{?7P!1+OY%5DL`w+_hGQYG(qU8ikUvn$mB!N``Q7@n2F=pTN zSa>e=f&^qCS^!IK@~2BZbSd#*9+N@sdxZI3EH4)c*??bU3dtX0hwbOd9-IUV=?(#$r$RbB(rS{W5M}lR^a$ zLBcFNY6Jm7uS>%Vlft!mi~*qZw@a_l`CKIU{G=u-?~U}E!|2CpT3pIso4VE}-moz= zxGQXNqUZmfp%72y>M8XvrwEUiO}eXlM=Y%@aI%}hfYadqGXSyHElB}_%3gq?!0A-$ zix;@~sd;Yv>}8p3ooK4a({NSkQI-ic>5duvLV%pPrG78-83elH)?cJ8qC zhVX6jYw3huM3lOUQNLmKjT;4{VR;K-@tvezb7jr9Ye?S;>f&09@-ZmLSpaKSw{d30 zqj?Y35sb&7`_3JjX4N+Lcd+4@WU{R%cn6@B3GvhXq&ED>^_6rlT`B>V#g>ypu9AuNTS$+z{LyF-{%>C=9_%L2zLZu3+}<%Inaa^ zN(jfX#S=g*cIhCc<8Po0C=Y>^Vbio$H}^pGLe0Dcxv%>uCH^cySGN1x{n1 zgD<`vB@%t%d^DWX4;uvU_4vK*ih&&*x^F@+zZ_h@9;>%^gpsgr)hjaX)D|`00zjo4 zV72#^?);dZvzI?T;3%>t*Li+ze96V#^*Z8Bsd-0pV3F0{lk*<0hVm>$`4}NDWVJEB zjJMH{srQz!z~sV29xxHqp@BI9zEQZwi&J=Xe3SP^rzwEBADU@0!{2^ZqIMl8d4h$n zy~dle?_B2=y9!&Gskce3>0~R69D_3u9~iHy+Wh2|vNHe&$?ujOa{F6rXfPEPlEoX0cV$_fO;bn>*cNrb*Q-`yHZS{zkWB!# zLnV0cU=_qnZUVc#Zh(SU^5()YXPe8KsM_e_&lIX(yi6H&hQM^HJP)deKn+USC)$e8 z5K{I$Q$;>x#gBpNW^V;K!i(Emc+w>i4zM8&5^O{rY!OGO9j}deA+W`3VHbkaLqObd zbI~31!IRwBn^Uwr22VcEAL+{;)ZwlXhyuewPGUxhuuk3#*c^@1QS~4~UcGcZcjlhd zHRs4(-uAq*jBfIesXLVy9Fa8Ox^w6J*MZJA>CwEA$L6Xru+Ej|h*)?IZNB_~XBuVw z8?kGrL$($;hAAkYC+Z|*P|Hn+&tW5ff!04Dn=6`_JRUD$3jc0N z-I4Ec+n=Z3h!n;TEDW&JDs0g;HSmP&eV7*o`v)~Fj+o+S|NcC$OOl8wmgrL(o}`Gb zS#14aA+k#b;k@r~;Y)ZY^1R}-EJ617)+`=f7()__MjI3Gkhyw#=OgDf(se1{x{BU8 z!J-$4XR$JY(yeV?%|`03@HRFzLhu9!G1J|IUxM38WzwE#Nbb3E+jWSh)J#<_NV}LuZ(|CQu%^cH0u1T(D0%k@@RR!PJ-nVzFqb$5 zN#r5bPeZEw%C81nOmSZ50SJWRapfb3b>%_0Y1nGaxz)cTMay2bl&$VFNlE%#x!XIQ z$LT)dEo6cw3_N|Heo^qGu-Y^Ba*`6%&h?d?3;QeP;vhbz9*a_PbJi}H73)*Dkilk9 z^U>9_BMbuQKw^7ug_`E2hhFTa`mOKOs#3*OOD)b$eTS=b+Y~A6H7o%R-rv>mii+R< z401PWW;|C3)jrNnk@lftI&O_*(#min<7_i7tOV?yhEJ8UQgE2YaQB#(}*%S+Mr_3bxpt z%Z0$7r_FA&&+4;a(!99aw)3al_CL|8`H z&uPh%GV)^(?+B<8a@+&$0r?zrD&1DFj0DHBf(?0m0a;32s!b$lSdw>dU7?P%BTh@D z@%i5l&sD^lO#fu#W5`GUyh19(7=hFp3mG7AnP0&=15Lk-rE;B0NplxA2df&VbBI8c zPm=TDErB8iCQcz$fmD9OLY8X{FtkaAzXL#WICif8Fm>Z=4sk>-=`d;>1Z)A0fRMPs zF)*NRG&L>q2~gDm{E(fsem{7UTLI1yJXX*$=Ub|qgF>HSpo*OIyn$FC1Pf`aRkH~- zB>)8?rm7|wN!3b|-uhp> zfQxsy8@wH@b8U$hCJk>>mQeShOdR{{9S zleKt?mv>)2FTR{*5G5RL@S>f{wV`i#216UmHma-fT!w4lxPNry;nf`)yW8sV;Gd_I zaf}-!2(yRyg@jq0p>rfqPdY|Z_k-!wV~DKdj?L9@wdVz3i~rlY?QW}<#D9wA(f`-H zZS4-_NTG+}VT?IYo{E7FRInl+U5fw1EgKo-eACl3CYKdx6LLtM4o~CiX zh0C#Q#5}q(qd--lgF?z|T(Z`|1H<_Wh&dz(dftQpl#p2qgQJx8G{jOg&uLT?dKzz@U)}#6AT}3p&t>_n~ z%+656{+JO6aQ-BiLqh)f?o;LBIpiWmq&nZ}^`+UP)v!}DLW<%)$i;v(Eq#Li)nbXd z2RX(MwIYqtIAyHbq8S2FNdY}^NmoNsB&3PHz$l{U55p0Fh&n9$X~g-Ginu6uQcbVw zyxZ*6-EYk8wGvw5)2-r~2At{ziZNhj&u}KIUw!#z!+vK_j_$Un^SA`k;=S_)aB%qibKkWDaKoouXJd+?5fyUW#7*Q`j| zR|uQAKP~!tJ53`-PqExm+a$^p$y;n)9Mdn${xpJFX<^^0QPrQD_1nd{MG~Ar?N(cv zHX@s!u#@Qt=LS^1A%QAHt(Ovats?vejZ-zL4{G4Y4Oa_x8gz~3PvHsz1j$~SwaZP` znVZ&;V+iyWfbg-vo4#W`&hT)FgIlGh@r(TOQ8=;_2w zZ0mnS5S}|Mc8?=>Je42EFmlCM1>e|zoWa-2sUbOkAbYNYq7cf?h)gPC5wK)1u@1J; z#W@$eFMOx=Pe^^wMZ8yvBOqs7H>)+Br|8j>489jlglwrwd8CN&!2XU)DMxXYL}*NBJ(Qw1oVmv6kE=hXO=IZy~A; zq?%w7w}z|&98tB>Ry1AaCPy0(w=W*!s2qh*>92qTr&bF~VEwPRpuS_|SthBm56uUQ zSbD~!!wLmG^U4mB=5#HoUbCnPZuxbyqp15aE1C8-^;}VS8|=D#&D?gj0O29D56$b5VY$Grm-9_gEH4>e3^#=tBOtuFaQ@ z2`QNAl1`|SOe5ZU6nFl7XftpaU4?`Y$j6XxgrETBgGA5Zh3Gy9+)-btAy5hZ%50kn zd;FOMBZcR#0!03W5dd;StYVEkTSkjA9?=N&6bW&ntet@NI>U%I3(cH^tzT(~TB~BeOs=d_ z^Kg9?pb^=_0#NxU^muU&D69purS;vdy2O7fO1*v2jae@xa*lECGi5PM$4+j9roV2G zcmCNSU3KDK%KD$iTcgl<_4T^z4Hc^Y_+CNJ9(FL|zh&`4lNiN%JJq;j`qN}L$!7ca z%oz3SrfoE{Ap8yVJ96JIb%!-19@h*?Of!a;ZfQwrQ(+4i)8iPQ)apV&EE#hn3}esg z!qO$R*%UK)SvCQH4Yh40HnQU+Ns!xefW>E#?;jE`LVLb<$>9?3|>l#7%~LF z;e5d=o-xYu`bZp~jfxCF4XR)#oFsyit;YM?JDCAvGV*lb-ZZDCvK zKZRlurnKGi5ulWuL)UmF0%~LAe8!n{ZQ0(%du_4!!oYh z2;eBaRLPaqpyC|5xO1TRbXP;Wz>0lq{KM(RMtBfccW_7JsyuPxNk#t(CA+plVb#3x8acN0Ma3{>*j=7BDXDF9| zKp8K;RyR_}6ezSkmF$Xhxtv5n0?m#d7klwMrTr>m1XCy`xH&C8_&%)fyZfS36x6am zdTcJ>>QX&td#4jVCEv0h^fS1(Fe8ZVXL8j-vKoQLpyf_q%;J&F;d_>ZwZ>{EyG+=t zci>{9U+*i}i-skX9#kxKiP|tsMz9!r*gnQp%w|y&tE%}eZ>9Qtw@1Clt@-Z#64?9m zMyG80Y4S)%@#cMPJWHX`YzGue46uyY4Nt~~F#ekPw{fcLpOPgrXIn+Aj5>azT4Av< z+c0?SsZCwYC{Ze5qyiSTd_>P)!P{je_LMr6HwIMG$ODe(2PGcrF0Q`lTqHA50>6qS zmb*17t^$!om_AE?NS8p!Ss`nq-lDEy=yqhSY{0!5F4|GXJ6-o5j4SMOl$d0z@)~n* zvH;g5)f>GrL{Ttvm_)Y5`j)PURTt#o4`j=jXA*j0nE@_FQUBM)bUA|^^8M-@N8PvrOIkNz&+isg#cb6c0VmUCW?P?fuVe|pUoe?1zb zvwJJp{#5DI8X5t*@jfnLq8(mEpP|-TXm2YrJPPIR)e*S_f zpAI5rBYS}{5H|L{dq`cAL0+=;D0m4jqH6eu*CXvOd_8i&6?jsHnm@=K4t4r7_!@to z+zTrltQeJDC{5unmq_-KIDTDEcX&;n^WvEV*`hY9LU^Yo_I1_0?=)P^)U>~xMhNb>2Nf?$Hw%x~pRNfKgT+3gRv>r$P<8JP)|Jz7<_eaPLM(@b%D z^}2_@Hy?;ls^3cz)~Es;XzJ9Hg6tk)f2d^yGM8M?b(SgOqBgkZS5B%!z}8~vUP>)3 z)wcIxq+0i|G>FwCvY9d0~&_ts=M6xnD!AnPS zniuzNb44^CxnBr_w>i&x{Br%I)`?Iv`uu6m_7C;+`k=FANDp`B>-%1}oh?#fuhKyg z7Zx}-HlbvXR@bX6=D>lZ&hUh?Tp>K-M(>RDiNzHc!`G*lB{tMyaaFW8{WnPqI}BDq z$Ka*1PE&4kH7YY8*nc|z8XX{`sk z+q*JGY_AQ=>w0ZfU?c+b&~X>a%78&!?Fi6LSKE(v_4Ot$V!Rsm0QXYk;!NJVbFRaZ zIaEhd#wW&6{wIBW5ZJXwwSW|bu2>o0SLG|X4)E|folfGj%qD9CN>g=iNy z@C?Nkx))04b-lkjMf2`8%1_MYRLqHyIS-Lo(PT$?p4IDG^OA}C)VRh9F1~QQIJ!Kt z2=i;78oJeZsTW1 zwop&CgAtVodgFfDxmEBFZe>Q^d!1}9Zp54@caQsQGH|^Or$42!fd(Ol?;wTrBwVR? z`p(rR-8aKqkIeUMDAnb)Apl0EgT)WMcNuaAT=2lPf0E|kyK^7o{eam|ndF`u{3B`C z%6LrgoJgCVM`M?|w_}p9w03i*6s?a{69R#NY-vn|6(h&t3gartV zm=*W61o1ix!cw9A5%qehQ5)y-)iob_StH`|E8HnYTJK4`^T!BQCAetYi;sz|v%Al_ zc?%^=$4@)!))yVOHu65;$36F4lb0FDrt2`(8qn24>RVP=&x$_xmvxC@XXjN%oSX3T zf$}@0Mxyw*)vIf31?1u(=l8!fIZ5`uFe~c}EL3XbW*Ad5&nlS@IH3|MH%k|BoH)Qp z60l2*K%RGt!c&N_65#h18q;qjn@%~_amT4#HfV6M;H8%?xk;9e84oDrzQg+t)6(Dl zWqc}c!uFG`G&MHJcpg4oyB`Ema$>DKe61SJ3SLq)_L*Y9Bv`)OsH;aWgz1d89yxzZ zM3Cp2p8u?WDw-c(OM8c`M&0w{->~Z}0@Bl&lx+>0Wi`{f%k|Pm1yB*jW}chcdmH;V zZs|wdG7l~L+LH(CQAzPh)oZS?p3CdHm$CtU5*}Dn$jC3sTs!oE_UGy-bp*{--azAT zE&+?}Q9u1nm8zACa^hqbQxVH)7P5XDX6kZ1ie!_|O=GH(YXO?zv}+d++FVg+KIdL0 zPdaS)*9hp*xhv3k((V&Ico6uO)lq=o74?g6dY4R|2E1|Y>u$tbM-uI^?$0NBGmNO5 zM4YIL(`TA6C$WQ7Xc%TR=6L=v;3$9=?Lug@cb)xjgeTI|`Y6J*6mcAqxi}K-&3&+D zG5UAMu2V^hi4>bd^EBhUkoi)-&Bl}#XY&h;tI<3W1)K7?Ht%>wfHCp&?#s&y_-0Ab zwVbe_b3)!>^j;E=ZL!g|eHvL3GE4$pyL`}`odtQGPJ8K zUd?E&IZ~n169Y_q3eGD8!D;aE)49ddZj&T$2GK3^@|O7Wz1@%zG^;&#;spa)C`v z!_EMj7#6P%vZW{imF%UM)Qwn|%M7Vyj*~|~t07M)MTJk-x6O8zMjNntGH`}cNLG-5 yI9?dlCLs6aVp(Lq5uZ)z4dJAKSIrbnB-Opsds9Utu#W`zd8lKcU8`jm^?v}{X~?Dk literal 32998 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 diff --git a/icons/mob/xenos/wounds.dmi b/icons/mob/xenos/wounds.dmi index bf7d573b73a9b66a09ec94508614e537a4a7539e..730e367f43aecdbf019705b7a6ae312db3aa49d1 100644 GIT binary patch delta 23430 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 From 4a4c961236cee9601550563820c0d42af8e17d33 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Thu, 28 Dec 2023 09:54:02 +0000 Subject: [PATCH 12/99] Automatic changelog for PR #5269 [ci skip] --- html/changelogs/AutoChangeLog-pr-5269.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5269.yml diff --git a/html/changelogs/AutoChangeLog-pr-5269.yml b/html/changelogs/AutoChangeLog-pr-5269.yml new file mode 100644 index 000000000000..b07fa02631ab --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5269.yml @@ -0,0 +1,5 @@ +author: "sleepynecrons" +delete-after: True +changes: + - imageadd: "new sprites for predalien, predlarva and weeded corpse" + - imageadd: "added predalien wound overlays" \ No newline at end of file From 33af189ea109dd0f8202715e502fc98a3de2b04b Mon Sep 17 00:00:00 2001 From: Changelogs Date: Fri, 29 Dec 2023 01:00:20 +0000 Subject: [PATCH 13/99] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-5269.yml | 5 ----- html/changelogs/archive/2023-12.yml | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-5269.yml diff --git a/html/changelogs/AutoChangeLog-pr-5269.yml b/html/changelogs/AutoChangeLog-pr-5269.yml deleted file mode 100644 index b07fa02631ab..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5269.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "sleepynecrons" -delete-after: True -changes: - - imageadd: "new sprites for predalien, predlarva and weeded corpse" - - imageadd: "added predalien wound overlays" \ No newline at end of file diff --git a/html/changelogs/archive/2023-12.yml b/html/changelogs/archive/2023-12.yml index 0333e4beea0c..73cd5f8771a1 100644 --- a/html/changelogs/archive/2023-12.yml +++ b/html/changelogs/archive/2023-12.yml @@ -531,3 +531,7 @@ fira: - bugfix: Fixed XRF Scanner bricking if people were adding and removing vials at same time. +2023-12-29: + sleepynecrons: + - imageadd: new sprites for predalien, predlarva and weeded corpse + - imageadd: added predalien wound overlays From f18d284cb9c83459585ce00fbb58b8321e83d779 Mon Sep 17 00:00:00 2001 From: cuberound <122645057+cuberound@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:50:03 +0100 Subject: [PATCH 14/99] north facing m56d shooting angle fix (#5308) # About the pull request prevents m56d from shooting anywhere to the right when facing north # Explain why it's good for the game fix good # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: m56d can not longer shoot backwards when facing north /:cl: Co-authored-by: vincibrv --- code/modules/cm_marines/smartgun_mount.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/cm_marines/smartgun_mount.dm b/code/modules/cm_marines/smartgun_mount.dm index 765f7a673812..21c8a58e279b 100644 --- a/code/modules/cm_marines/smartgun_mount.dm +++ b/code/modules/cm_marines/smartgun_mount.dm @@ -703,6 +703,9 @@ if((dir == NORTH) && (angle > 180) && (abs(360 - angle) > shoot_degree)) // If north and shooting to the left, we do some extra math return + if((dir == NORTH) && (angle < 180) && (angle > shoot_degree)) + return + else if((dir != NORTH) && (abs(angle - dir2angle(dir)) > shoot_degree)) return From 7479788b7cd3198b514492fe889375fa0c84df6d Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 10:58:26 +0000 Subject: [PATCH 15/99] Automatic changelog for PR #5308 [ci skip] --- html/changelogs/AutoChangeLog-pr-5308.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5308.yml diff --git a/html/changelogs/AutoChangeLog-pr-5308.yml b/html/changelogs/AutoChangeLog-pr-5308.yml new file mode 100644 index 000000000000..3adc1465faaf --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5308.yml @@ -0,0 +1,4 @@ +author: "cuberound" +delete-after: True +changes: + - bugfix: "m56d can not longer shoot backwards when facing north" \ No newline at end of file From 95b52c8f3149a2800e41a55b5c06357dd855a2ce Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Fri, 29 Dec 2023 10:50:46 +0000 Subject: [PATCH 16/99] Makes the designation of a tunnel display in chat when entered (#5315) # About the pull request Makes the designation of a tunnel display in chat when a player enters it. # Explain why it's good for the game I've quite often gone through a tunnel to drop a capture off at the hive, and then had no idea which tunnel to select in order to get back. It is possible to examine a tunnel before you go through it to see its name, but this just streamlines the whole process. # Testing Photographs and Procedure
Screenshots & Videos **Before:** ![before](https://github.com/cmss13-devs/cmss13/assets/57483089/de1a4a73-0d39-456a-a7fd-b0ddf401dc4f) **After:** ![after](https://github.com/cmss13-devs/cmss13/assets/57483089/75d139eb-5ea2-41b1-a003-e42b52d08ecd)
# Changelog :cl: qol: Made the designation of a tunnel display in chat when a player enters it. /:cl: --- code/modules/cm_aliens/structures/tunnel.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/modules/cm_aliens/structures/tunnel.dm b/code/modules/cm_aliens/structures/tunnel.dm index 1f0f98c14361..8e2993704f31 100644 --- a/code/modules/cm_aliens/structures/tunnel.dm +++ b/code/modules/cm_aliens/structures/tunnel.dm @@ -221,7 +221,7 @@ return XENO_NO_DELAY_ACTION if(!hive.tunnels.len) - to_chat(M, SPAN_WARNING("\The [src] doesn't seem to lead anywhere.")) + to_chat(M, SPAN_WARNING("[src] doesn't seem to lead anywhere.")) return XENO_NO_DELAY_ACTION if(contents.len > 2) @@ -236,11 +236,11 @@ tunnel_time = TUNNEL_ENTER_LARVA_DELAY if(M.mob_size >= MOB_SIZE_BIG) - M.visible_message(SPAN_XENONOTICE("[M] begins heaving their huge bulk down into \the [src]."), \ - SPAN_XENONOTICE("We begin heaving our monstrous bulk into \the [src]
.")) + M.visible_message(SPAN_XENONOTICE("[M] begins heaving their huge bulk down into [src]."), + SPAN_XENONOTICE("We begin heaving our monstrous bulk into [src] ([tunnel_desc]).")) else - M.visible_message(SPAN_XENONOTICE("\The [M] begins crawling down into \the [src]."), \ - SPAN_XENONOTICE("We begin crawling down into \the [src].")) + M.visible_message(SPAN_XENONOTICE("[M] begins crawling down into [src]."), + SPAN_XENONOTICE("We begin crawling down into [src] ([tunnel_desc]).")) xeno_attack_delay(M) if(!do_after(M, tunnel_time, INTERRUPT_NO_NEEDHAND, BUSY_ICON_GENERIC)) @@ -252,7 +252,7 @@ to_chat(M, SPAN_HIGHDANGER("Alt + Click the tunnel to exit, Ctrl + Click to choose a destination.")) pick_tunnel(M) else - to_chat(M, SPAN_WARNING("\The [src] ended unexpectedly, so we return back up.")) + to_chat(M, SPAN_WARNING("[src] ended unexpectedly, so we return back up.")) return XENO_NO_DELAY_ACTION /obj/structure/tunnel/maint_tunnel From 4f378ec6a81ec9f34b1d36b2ed34f47435a061ac Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:11:14 +0000 Subject: [PATCH 17/99] Automatic changelog for PR #5315 [ci skip] --- html/changelogs/AutoChangeLog-pr-5315.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5315.yml diff --git a/html/changelogs/AutoChangeLog-pr-5315.yml b/html/changelogs/AutoChangeLog-pr-5315.yml new file mode 100644 index 000000000000..c5dc61beb308 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5315.yml @@ -0,0 +1,4 @@ +author: "SabreML" +delete-after: True +changes: + - qol: "Made the designation of a tunnel display in chat when a player enters it." \ No newline at end of file From 86914ec2f1f0f8bdf0b681349cd960469a968c09 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Fri, 29 Dec 2023 17:28:30 +0000 Subject: [PATCH 18/99] Fixes a laser cannon bug which I added (#5319) # About the pull request Fixes CAS lasers only setting fire to a single tile, rather than in a 7x7 range around the target. This was caused by me somehow incorrectly setting the target turf in #5205. # Explain why it's good for the game uh, whoops # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: Fixed the CAS laser cannon only setting fire to a single tile, rather a 7x7 range. /:cl: --- code/modules/cm_marines/dropship_ammo.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/cm_marines/dropship_ammo.dm b/code/modules/cm_marines/dropship_ammo.dm index 9f28518915ea..19086b36c957 100644 --- a/code/modules/cm_marines/dropship_ammo.dm +++ b/code/modules/cm_marines/dropship_ammo.dm @@ -251,7 +251,7 @@ for(var/i=1 to 16) //This is how many tiles within that area of effect will be randomly ignited var/turf/U = pick(turf_list) turf_list -= U - fire_spread_recur(impact, create_cause_data(fired_from.name, source_mob), 1, null, 5, 75, "#EE6515")//Very, very intense, but goes out very quick + fire_spread_recur(U, create_cause_data(fired_from.name, source_mob), 1, null, 5, 75, "#EE6515")//Very, very intense, but goes out very quick if(!ammo_count && !QDELETED(src)) qdel(src) //deleted after last laser beam is fired and impact the ground. From 5053f217d4236dd4acc6142ce94afedae5af8abd Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 17:36:37 +0000 Subject: [PATCH 19/99] Automatic changelog for PR #5319 [ci skip] --- html/changelogs/AutoChangeLog-pr-5319.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5319.yml diff --git a/html/changelogs/AutoChangeLog-pr-5319.yml b/html/changelogs/AutoChangeLog-pr-5319.yml new file mode 100644 index 000000000000..d9582b58f9bc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5319.yml @@ -0,0 +1,4 @@ +author: "SabreML" +delete-after: True +changes: + - bugfix: "Fixed the CAS laser cannon only setting fire to a single tile, rather a 7x7 range." \ No newline at end of file From 932138ede8be1d06d2119777c11f7f181f793415 Mon Sep 17 00:00:00 2001 From: InsaneRed <47158596+InsaneRed@users.noreply.github.com> Date: Fri, 29 Dec 2023 20:29:02 +0300 Subject: [PATCH 20/99] Moves around "Remove Splints" and "View playtime" (#5323) # About the pull request This pr moves "View Playtimes" under the "Records" tab of OOC and "remove splints" into "IC" tab . # Explain why it's good for the game viewplaytimes s a record, and "remove splints" should be under IC for new players, not even i remember where to look for it sometimes because under objects doesnt make sense # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: qol: "View Playtime" is now under the "Records" section under OOC qol: "Remove Your Splints" is now under the "IC" section. /:cl: Co-authored-by: InsaneRed --- code/modules/mob/living/carbon/human/human.dm | 2 +- code/modules/mob/mob_verbs.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index b523cef08eec..26be5e97f9dd 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1445,7 +1445,7 @@ /mob/living/carbon/human/verb/remove_your_splints() set name = "Remove Your Splints" - set category = "Object" + set category = "IC" remove_splints() diff --git a/code/modules/mob/mob_verbs.dm b/code/modules/mob/mob_verbs.dm index a941dfc51090..1ba8985d56bd 100644 --- a/code/modules/mob/mob_verbs.dm +++ b/code/modules/mob/mob_verbs.dm @@ -32,7 +32,7 @@ return /mob/verb/view_stats() - set category = "OOC" + set category = "OOC.Records" set name = "View Playtimes" set desc = "View your playtimes." if(!SSentity_manager.ready) From 2bc3c4794cd6b473782a2ab6b8f46f466d3a3dd6 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 17:49:34 +0000 Subject: [PATCH 21/99] Automatic changelog for PR #5323 [ci skip] --- html/changelogs/AutoChangeLog-pr-5323.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5323.yml diff --git a/html/changelogs/AutoChangeLog-pr-5323.yml b/html/changelogs/AutoChangeLog-pr-5323.yml new file mode 100644 index 000000000000..1a521533c287 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5323.yml @@ -0,0 +1,5 @@ +author: "InsaneRed" +delete-after: True +changes: + - qol: "\"View Playtime\" is now under the \"Records\" section under OOC" + - qol: "\"Remove Your Splints\" is now under the \"IC\" section." \ No newline at end of file From f377f35b62161666d93e455b612e919631042785 Mon Sep 17 00:00:00 2001 From: Zonespace <41448081+Zonespace27@users.noreply.github.com> Date: Fri, 29 Dec 2023 09:56:13 -0800 Subject: [PATCH 22/99] Tutorial System: Retutorializing (#5030) # About the pull request Reopening of #4442 Adds a tutorial system to the game, accessible from the lobby screen. The tutorial system is entirely isolated from the main game, allowing players to get a curated experience to be taught the mechanics of SS13 or specific roles within CM. The tutorial system is fully capable of supporting a theoretically infinite amount of players at once, each getting their own instance. See below video for an example of the in-dev "Marine - Basic" tutorial. https://www.youtube.com/watch?v=aWEtd6EAZWk # Explain why it's good for the game Teaching new players how to play the game has always been a tough bit for us, so why not add a full-on tutorial system to get people into the know? # To-Do: This list is alive and will change over time. If you are interested in coding a tutorial, know that it's very easy and that most of the heavy lifting's done for you! You can find a [tutorial creation guide here](https://hackmd.io/@mRAdleXgRfmKqh97O8ixSA/BJQsmO8kT), and you can additionally contact me on discord at any time with questions. Also, you can find an example tutorial [here](https://github.com/cmss13-devs/cmss13/pull/4442/files#diff-843b2f84360b9b932dfc960027992f2b5117667962bfa8da14f9a35f0179a926). Backend: - [x] TGUI - [x] Add finished tutorials to save files - [x] Communicate to players with little playtime - [x] Suppress combat logs and similar done in tutorials SS13: - [x] Basics - [x] Intents Marine: - [x] Basics - [x] Medical - [ ] Weaponry - [ ] Comtech - Basics - [ ] Medic - Basics - [ ] FTL - Basics - [ ] Smartgunner - Basics - [ ] Specialist - Demolitionist - [ ] Specialist - Scout - [ ] Specialist - Pyrotechnician - [ ] Specialist - Grenadier - [ ] Specialist - Sniper - [ ] Squad Leader - Basics Xenomorph: - [ ] Basics - [ ] Builder Caste - Basics # Changelog :cl: add: Added a tutorial system for various roles (and just general information), find it in the lobby screen. /:cl: --------- Co-authored-by: fira --- code/__DEFINES/access.dm | 2 + .../signals/atom/mob/living/signals_human.dm | 3 + .../signals/atom/mob/living/signals_living.dm | 12 + .../dcs/signals/atom/mob/signals_mob.dm | 37 +++ .../__DEFINES/dcs/signals/atom/signals_obj.dm | 10 + code/__DEFINES/dcs/signals/signals_client.dm | 3 - code/__DEFINES/mob.dm | 1 + code/__DEFINES/traits.dm | 5 + code/__DEFINES/tutorial.dm | 6 + code/__HELPERS/level_traits.dm | 1 - code/__HELPERS/unsorted.dm | 12 + code/_onclick/item_attack.dm | 2 + code/_onclick/observer.dm | 2 +- code/_onclick/xeno.dm | 2 +- code/controllers/subsystem/ticker.dm | 1 + code/datums/ammo/ammo.dm | 2 +- code/datums/ammo/misc.dm | 2 +- code/datums/components/tutorial_status.dm | 25 ++ code/datums/datacore.dm | 4 +- code/datums/effects/bleeding.dm | 13 +- code/datums/helper_datums/teleport.dm | 2 +- code/datums/mind.dm | 2 - .../status_effects/_status_effect_helpers.dm | 1 + code/datums/tutorial/_tutorial.dm | 259 ++++++++++++++++++ code/datums/tutorial/_tutorial_menu.dm | 83 ++++++ code/datums/tutorial/creating_a_tutorial.md | 96 +++++++ code/datums/tutorial/marine/_marine.dm | 21 ++ code/datums/tutorial/marine/basic_marine.dm | 208 ++++++++++++++ code/datums/tutorial/marine/medical_basic.dm | 174 ++++++++++++ code/datums/tutorial/ss13/_ss13.dm | 41 +++ code/datums/tutorial/ss13/basic_ss13.dm | 84 ++++++ code/datums/tutorial/ss13/intents.dm | 113 ++++++++ code/datums/tutorial/tutorial_example.dm | 74 +++++ code/game/area/admin_level.dm | 19 ++ code/game/area/areas.dm | 4 + code/game/gamemodes/cm_initialize.dm | 2 +- .../colonialmarines/colonialmarines.dm | 2 +- .../whiskey_outpost/whiskey_output_waves.dm | 2 +- code/game/jobs/job/job.dm | 24 +- code/game/machinery/camera/tracking.dm | 2 +- .../game/machinery/computer/camera_console.dm | 2 +- code/game/machinery/cryopod.dm | 40 ++- .../telecomms/machine_interactions.dm | 4 +- code/game/machinery/teleporter.dm | 4 +- code/game/machinery/vending/cm_vending.dm | 2 + .../machinery/vending/vendor_types/food.dm | 21 ++ .../vendor_types/squad_prep/squad_prep.dm | 28 ++ .../vendor_types/squad_prep/tutorial.dm | 30 ++ .../objects/effects/landmarks/landmarks.dm | 4 + code/game/objects/items.dm | 1 + .../objects/items/devices/teleportation.dm | 4 +- .../items/reagent_containers/autoinjectors.dm | 18 ++ .../items/reagent_containers/food/snacks.dm | 1 + .../items/reagent_containers/hypospray.dm | 1 + code/game/objects/items/shards.dm | 16 +- code/game/objects/items/stacks/medical.dm | 3 + code/game/objects/items/weapons/blades.dm | 2 + code/game/supplyshuttle.dm | 2 +- .../admin/player_panel/actions/general.dm | 10 +- code/modules/asset_cache/asset_list_items.dm | 16 ++ code/modules/client/preferences.dm | 21 +- code/modules/client/preferences_savefile.dm | 6 + code/modules/cm_marines/marines_consoles.dm | 2 +- code/modules/cm_preds/yaut_items.dm | 4 +- code/modules/gear_presets/other.dm | 18 ++ code/modules/gear_presets/uscm.dm | 2 +- code/modules/maptext_alerts/screen_alerts.dm | 20 ++ code/modules/mob/dead/observer/observer.dm | 5 +- code/modules/mob/living/carbon/human/human.dm | 25 ++ .../living/carbon/human/human_attackhand.dm | 4 +- .../mob/living/carbon/human/human_dummy.dm | 9 + .../mob/living/carbon/xenomorph/Embryo.dm | 2 +- .../mob/living/carbon/xenomorph/Evolution.dm | 2 +- .../living/carbon/xenomorph/XenoOverwatch.dm | 6 +- .../mob/living/carbon/xenomorph/Xenomorph.dm | 4 +- .../living/carbon/xenomorph/castes/Drone.dm | 6 +- .../living/carbon/xenomorph/castes/Queen.dm | 6 +- .../mob/living/carbon/xenomorph/death.dm | 2 +- .../living/carbon/xenomorph/hive_status.dm | 16 +- .../living/carbon/xenomorph/hive_status_ui.dm | 6 +- .../mob/living/carbon/xenomorph/mark_menu.dm | 4 +- .../silicon/ai/freelook/update_triggers.dm | 17 +- code/modules/mob/mob.dm | 13 + code/modules/mob/mob_defines.dm | 2 +- code/modules/mob/mob_grab.dm | 4 + code/modules/mob/mob_helpers.dm | 2 + code/modules/mob/new_player/new_player.dm | 53 ++-- code/modules/organs/limbs.dm | 1 + code/modules/projectiles/gun.dm | 2 + colonialmarines.dme | 13 + icons/misc/tutorial.dmi | Bin 0 -> 938 bytes icons/turf/areas.dmi | Bin 35248 -> 35304 bytes maps/tutorial/tutorial_12x12.dmm | 180 ++++++++++++ maps/tutorial/tutorial_7x7.dmm | 75 +++++ maps/tutorial/tutorial_8x9.dmm | 100 +++++++ maps/tutorial/tutorial_8x9_nb.dmm | 100 +++++++ .../packages/tgui/interfaces/TutorialMenu.tsx | 149 ++++++++++ 97 files changed, 2308 insertions(+), 140 deletions(-) create mode 100644 code/__DEFINES/mob.dm create mode 100644 code/__DEFINES/tutorial.dm create mode 100644 code/datums/components/tutorial_status.dm create mode 100644 code/datums/tutorial/_tutorial.dm create mode 100644 code/datums/tutorial/_tutorial_menu.dm create mode 100644 code/datums/tutorial/creating_a_tutorial.md create mode 100644 code/datums/tutorial/marine/_marine.dm create mode 100644 code/datums/tutorial/marine/basic_marine.dm create mode 100644 code/datums/tutorial/marine/medical_basic.dm create mode 100644 code/datums/tutorial/ss13/_ss13.dm create mode 100644 code/datums/tutorial/ss13/basic_ss13.dm create mode 100644 code/datums/tutorial/ss13/intents.dm create mode 100644 code/datums/tutorial/tutorial_example.dm create mode 100644 code/game/machinery/vending/vendor_types/squad_prep/tutorial.dm create mode 100644 icons/misc/tutorial.dmi create mode 100644 maps/tutorial/tutorial_12x12.dmm create mode 100644 maps/tutorial/tutorial_7x7.dmm create mode 100644 maps/tutorial/tutorial_8x9.dmm create mode 100644 maps/tutorial/tutorial_8x9_nb.dmm create mode 100644 tgui/packages/tgui/interfaces/TutorialMenu.tsx diff --git a/code/__DEFINES/access.dm b/code/__DEFINES/access.dm index 97e4b0dbd1e8..be96a2e32b85 100644 --- a/code/__DEFINES/access.dm +++ b/code/__DEFINES/access.dm @@ -152,6 +152,8 @@ most of them are tied into map-placed objects. This should be reworked in the fu /// Ancients only #define ACCESS_YAUTJA_ANCIENT 392 +/// Anything in a tutorial sequence that shouldn't be accessed +#define ACCESS_TUTORIAL_LOCKED 998 ///Temporary, just so I can flag places I need to change #define ACCESS_COME_BACK_TO_ME 999 diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm index 6614272d33e5..2e247cdccc73 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_human.dm @@ -67,3 +67,6 @@ #define COMSIG_HUMAN_SURGERY_APPLY_MODIFIERS "human_surgery_apply_modifiers" /// From /mob/living/carbon/human/proc/get_flags_cold_protection() #define COMSIG_HUMAN_COLD_PROTECTION_APPLY_MODIFIERS "human_cold_protection_apply_modifiers" + +/// From /obj/item/proc/dig_out_shrapnel() : () +#define COMSIG_HUMAN_SHRAPNEL_REMOVED "human_shrapnel_removed" diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm index 89f3951e7c99..cea905dd1011 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_living.dm @@ -29,7 +29,19 @@ #define COMSIG_LIVING_PRE_COLLIDE "living_pre_collide" #define COMPONENT_LIVING_COLLIDE_HANDLED (1<<0) +/// From /mob/living/proc/do_ghost() : (mob/dead/observer/ghost) +#define COMSIG_LIVING_GHOSTED "living_ghosted" + +/// From /mob/living/carbon/human/attack_hand() : (mob/living/carbon/human/attacked_mob) +#define COMSIG_LIVING_ATTACKHAND_HUMAN "living_attackhand_human" + +/// From /obj/item/reagent_container/hypospray/attack() : (obj/item/reagent_container/hypospray/injector) +#define COMSIG_LIVING_HYPOSPRAY_INJECTED "living_hypospray_injected" + ///from base of mob/living/set_buckled(): (new_buckled) #define COMSIG_LIVING_SET_BUCKLED "living_set_buckled" ///from base of mob/living/set_body_position() #define COMSIG_LIVING_SET_BODY_POSITION "living_set_body_position" + +/// from base of /mob/living/apply_status_effect(): (datum/status_effect/new_effect) +#define COMSIG_LIVING_APPLY_EFFECT "living_apply_effect" diff --git a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm index f288f5d94584..58021ba564a2 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/signals_mob.dm @@ -131,5 +131,42 @@ /// From /obj/item/proc/pickup() : (obj/item/picked_up) #define COMSIG_MOB_PICKUP_ITEM "mob_pickup_item" +/// From /obj/item/proc/attack_self() : (obj/item/used) +#define COMSIG_MOB_ITEM_ATTACK_SELF "mob_item_attack_self" + +/// From /obj/item/proc/dropped() : (obj/item/dropped) +#define COMSIG_MOB_ITEM_DROPPED "mob_item_dropped" + + +/// From /obj/item/reagent_container/food/snacks/proc/on_Consume() : (obj/item/reagent_container/food/snacks/eaten_food) +#define COMSIG_MOB_EATEN_SNACK "mob_eaten_snack" + +/// From /atom/proc/attackby() : (atom/attacked, obj/item/attacked_with) +#define COMSIG_MOB_PARENT_ATTACKBY "mob_parent_attackby" + +/// From /obj/item/weapon/gun/proc/reload_into_chamber() : (obj/item/weapon/gun/empty_gun) +#define COMSIG_MOB_GUN_EMPTY "mob_gun_empty" + +/// From /obj/item/weapon/gun/proc/reload() : (obj/item/weapon/gun/reloaded) +#define COMSIG_MOB_RELOADED_GUN "mob_reloaded_gun" + +/// From /mob/proc/get_status_tab_items() : (list/status_list) +#define COMSIG_MOB_GET_STATUS_TAB_ITEMS "mob_get_status_tab_items" + +/// From /datum/tutorial/proc/update_objective() : (new_objective) +#define COMSIG_MOB_TUTORIAL_UPDATE_OBJECTIVE "mob_tutorial_update_objective" + +/// From /mob/proc/swap_hand() : () +#define COMSIG_MOB_SWAPPED_HAND "mob_swapped_hand" + +/// From /mob/proc/a_intent_change() : (new_intent) +#define COMSIG_MOB_INTENT_CHANGE "mob_intent_change" + +/// From /obj/item/grab/proc/progress_passive() : (mob/living/carbon/human/grabber) +#define COMSIG_MOB_AGGRESSIVELY_GRABBED "mob_aggressively_grabbed" + #define COMSIG_MOB_AGGRESIVE_GRAB_CANCEL (1<<0) + /// Cancels all running cloaking effects on target #define COMSIG_MOB_EFFECT_CLOAK_CANCEL "mob_effect_cloak_cancel" + +#define COMSIG_MOB_END_TUTORIAL "mob_end_tutorial" diff --git a/code/__DEFINES/dcs/signals/atom/signals_obj.dm b/code/__DEFINES/dcs/signals/atom/signals_obj.dm index b5f2bb3ff6a9..c870a55ed746 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_obj.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_obj.dm @@ -30,6 +30,16 @@ /// from /obj/proc/afterbuckle() #define COSMIG_OBJ_AFTER_BUCKLE "signal_obj_after_buckle" +/// from /obj/structure/machinery/cryopod/go_out() +#define COMSIG_CRYOPOD_GO_OUT "cryopod_go_out" + +/// from /proc/vendor_successful_vend() : (obj/structure/machinery/cm_vending/vendor, list/itemspec, mob/living/carbon/human/user) +#define COMSIG_VENDOR_SUCCESSFUL_VEND "vendor_successful_vend" + +/// from /obj/limb/proc/remove_all_bleeding() : (external, internal) +#define COMSIG_LIMB_STOP_BLEEDING "limb_stop_bleeding" + #define COMSIG_DROPSHIP_ADD_EQUIPMENT "dropship_add_equipment" #define COMSIG_DROPSHIP_REMOVE_EQUIPMENT "dropship_remove_equipment" + #define COMSIG_STRUCTURE_CRATE_SQUAD_LAUNCHED "structure_crate_squad_launched" diff --git a/code/__DEFINES/dcs/signals/signals_client.dm b/code/__DEFINES/dcs/signals/signals_client.dm index 6733e0703514..3968f654c486 100644 --- a/code/__DEFINES/dcs/signals/signals_client.dm +++ b/code/__DEFINES/dcs/signals/signals_client.dm @@ -27,6 +27,3 @@ /// Called when something is removed from a client's screen : /client/proc/remove_from_screen(screen_remove) #define COMSIG_CLIENT_SCREEN_REMOVE "client_screen_remove" - -/// When a mind is transfered to another mob at /datum/mind/proc/transfer_to() -#define COMSIG_CLIENT_MIND_TRANSFER "mind_transfer" diff --git a/code/__DEFINES/mob.dm b/code/__DEFINES/mob.dm new file mode 100644 index 000000000000..7f9f33ea483c --- /dev/null +++ b/code/__DEFINES/mob.dm @@ -0,0 +1 @@ +#define DEFAULT_MOB_STATUS_FLAGS CANKNOCKDOWN|CANPUSH|STATUS_FLAGS_DEBILITATE diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index d37c9185fa6d..8c93957c3ca0 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -221,6 +221,8 @@ #define TRAIT_HARDCORE "t_hardcore" /// If the mob is able to use the vulture rifle or spotting scope #define TRAIT_VULTURE_USER "t_vulture_user" +/// If the mob is currently loading a tutorial +#define TRAIT_IN_TUTORIAL "t_IN_TUTORIAL" /// If the mob is cloaked in any form #define TRAIT_CLOAKED "t_cloaked" @@ -297,6 +299,7 @@ GLOBAL_LIST_INIT(mob_traits, list( TRAIT_REAGENT_SCANNER, TRAIT_ABILITY_BURROWED, TRAIT_VULTURE_USER, + TRAIT_IN_TUTORIAL, )) /* @@ -403,6 +406,8 @@ GLOBAL_LIST(trait_name_map) #define TRAIT_SOURCE_JOB "t_s_job" ///Status trait forced by staff #define TRAIT_SOURCE_ADMIN "t_s_admin" +/// Status trait coming from a tutorial +#define TRAIT_SOURCE_TUTORIAL "t_s_tutorials" ///Status trait coming from equipment #define TRAIT_SOURCE_EQUIPMENT(slot) "t_s_equipment_[slot]" ///Status trait coming from skill diff --git a/code/__DEFINES/tutorial.dm b/code/__DEFINES/tutorial.dm new file mode 100644 index 000000000000..75dc7f6da21f --- /dev/null +++ b/code/__DEFINES/tutorial.dm @@ -0,0 +1,6 @@ +#define TUTORIAL_ATOM_FROM_TRACKING(path, varname) var##path/##varname = tracking_atoms[##path] + +#define TUTORIAL_CATEGORY_BASE "Base" // Shouldn't be used outside of base types +#define TUTORIAL_CATEGORY_SS13 "Space Station 13" +#define TUTORIAL_CATEGORY_MARINE "Marine" +#define TUTORIAL_CATEGORY_XENO "Xenomorph" diff --git a/code/__HELPERS/level_traits.dm b/code/__HELPERS/level_traits.dm index 01a972485fa2..8b3d1b0a3809 100644 --- a/code/__HELPERS/level_traits.dm +++ b/code/__HELPERS/level_traits.dm @@ -1,4 +1,3 @@ - #define is_admin_level(z) SSmapping.level_trait(z, ZTRAIT_ADMIN) #define is_ground_level(z) SSmapping.level_trait(z, ZTRAIT_GROUND) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 7425046da7c7..9faa74354494 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -2088,3 +2088,15 @@ GLOBAL_LIST_INIT(duplicate_forbidden_vars,list( if(NORTHWEST) return list(NORTHWEST, NORTH, WEST) + +/// Returns TRUE if the target is somewhere that the game should not interact with if possible +/// In this case, admin Zs and tutorial areas +/proc/should_block_game_interaction(atom/target) + if(is_admin_level(target.z)) + return TRUE + + var/area/target_area = get_area(target) + if(target_area?.block_game_interaction) + return TRUE + + return FALSE diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index c6052da33199..8d77920a59cc 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -3,6 +3,7 @@ /obj/item/proc/attack_self(mob/user) SHOULD_CALL_PARENT(TRUE) SEND_SIGNAL(src, COMSIG_ITEM_ATTACK_SELF, user) + SEND_SIGNAL(user, COMSIG_MOB_ITEM_ATTACK_SELF, src) if(flags_item & CAN_DIG_SHRAPNEL && ishuman(user)) dig_out_shrapnel(user) @@ -11,6 +12,7 @@ /atom/proc/attackby(obj/item/W, mob/living/user,list/mods) if(SEND_SIGNAL(src, COMSIG_PARENT_ATTACKBY, W, user, mods) & COMPONENT_NO_AFTERATTACK) return TRUE + SEND_SIGNAL(user, COMSIG_MOB_PARENT_ATTACKBY, src, W) return FALSE /atom/movable/attackby(obj/item/W, mob/living/user) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index f87778355755..21dd804f09c4 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -29,7 +29,7 @@ if(ismob(target) || isVehicle(target)) if(isxeno(target) && SSticker.mode.check_xeno_late_join(src)) //if it's a xeno and all checks are alright, we are gonna try to take their body var/mob/living/carbon/xenomorph/xeno = target - if(xeno.stat == DEAD || is_admin_level(xeno.z) || xeno.aghosted) + if(xeno.stat == DEAD || should_block_game_interaction(xeno) || xeno.aghosted) to_chat(src, SPAN_WARNING("You cannot join as [xeno].")) do_observe(xeno) return FALSE diff --git a/code/_onclick/xeno.dm b/code/_onclick/xeno.dm index cc785f32f426..ad4ba9d72546 100644 --- a/code/_onclick/xeno.dm +++ b/code/_onclick/xeno.dm @@ -111,7 +111,7 @@ so that it doesn't double up on the delays) so that it applies the delay immedia if(alt_pressed && shift_pressed) if(istype(target, /mob/living/carbon/xenomorph)) var/mob/living/carbon/xenomorph/xeno = target - if(!QDELETED(xeno) && xeno.stat != DEAD && !is_admin_level(xeno.z) && xeno.check_state(TRUE) && xeno.hivenumber == hivenumber) + if(!QDELETED(xeno) && xeno.stat != DEAD && !should_block_game_interaction(xeno) && xeno.check_state(TRUE) && xeno.hivenumber == hivenumber) overwatch(xeno) next_move = world.time + 3 // Some minimal delay so this isn't crazy spammy return TRUE diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index c6d6f008acd6..2e11ba8a96cb 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -46,6 +46,7 @@ SUBSYSTEM_DEF(ticker) var/totalPlayers = 0 //used for pregame stats on statpanel var/totalPlayersReady = 0 //used for pregame stats on statpanel + var/tutorial_disabled = FALSE //zonenote /datum/controller/subsystem/ticker/Initialize(timeofday) load_mode() diff --git a/code/datums/ammo/ammo.dm b/code/datums/ammo/ammo.dm index 48a387e54d20..7a4006deee73 100644 --- a/code/datums/ammo/ammo.dm +++ b/code/datums/ammo/ammo.dm @@ -106,7 +106,7 @@ SHOULD_NOT_SLEEP(TRUE) return -/datum/ammo/proc/on_embed(mob/embedded_mob, obj/limb/target_organ) +/datum/ammo/proc/on_embed(mob/embedded_mob, obj/limb/target_organ, silent = FALSE) return /datum/ammo/proc/do_at_max_range(obj/projectile/P) diff --git a/code/datums/ammo/misc.dm b/code/datums/ammo/misc.dm index 607a6e517a7c..3aaba8443efb 100644 --- a/code/datums/ammo/misc.dm +++ b/code/datums/ammo/misc.dm @@ -178,7 +178,7 @@ accurate_range = 12 shell_speed = AMMO_SPEED_TIER_1 -/datum/ammo/souto/on_embed(mob/embedded_mob, obj/limb/target_organ) +/datum/ammo/souto/on_embed(mob/embedded_mob, obj/limb/target_organ, silent = FALSE) if(ishuman(embedded_mob) && !isyautja(embedded_mob)) if(istype(target_organ)) target_organ.embed(new can_type) diff --git a/code/datums/components/tutorial_status.dm b/code/datums/components/tutorial_status.dm new file mode 100644 index 000000000000..97b8d408bcb5 --- /dev/null +++ b/code/datums/components/tutorial_status.dm @@ -0,0 +1,25 @@ +/datum/component/tutorial_status + dupe_mode = COMPONENT_DUPE_UNIQUE + /// What the mob's current tutorial status is, displayed in the status panel + var/tutorial_status = "" + +/datum/component/tutorial_status/Initialize() + . = ..() + if(!ismob(parent)) + return COMPONENT_INCOMPATIBLE + +/datum/component/tutorial_status/RegisterWithParent() + ..() + RegisterSignal(parent, COMSIG_MOB_TUTORIAL_UPDATE_OBJECTIVE, PROC_REF(update_objective)) + RegisterSignal(parent, COMSIG_MOB_GET_STATUS_TAB_ITEMS, PROC_REF(get_status_tab_item)) + +/datum/component/tutorial_status/proc/update_objective(datum/source, objective_text) + SIGNAL_HANDLER + + tutorial_status = objective_text + +/datum/component/tutorial_status/proc/get_status_tab_item(datum/source, list/status_tab_items) + SIGNAL_HANDLER + + if(tutorial_status) + status_tab_items += "Tutorial Objective: " + tutorial_status diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 933b547aa1f2..ae19a3044678 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -206,8 +206,8 @@ GLOBAL_DATUM_INIT(data_core, /datum/datacore, new) sleep(40) var/list/jobs_to_check = GLOB.ROLES_CIC + GLOB.ROLES_AUXIL_SUPPORT + GLOB.ROLES_MISC + GLOB.ROLES_POLICE + GLOB.ROLES_ENGINEERING + GLOB.ROLES_REQUISITION + GLOB.ROLES_MEDICAL + GLOB.ROLES_MARINES - for(var/mob/living/carbon/human/H in GLOB.human_mob_list) - if(is_admin_level(H.z)) + for(var/mob/living/carbon/human/H as anything in GLOB.human_mob_list) + if(should_block_game_interaction(H)) continue if(H.job in jobs_to_check) manifest_inject(H) diff --git a/code/datums/effects/bleeding.dm b/code/datums/effects/bleeding.dm index e6cb184850d4..2171580a94db 100644 --- a/code/datums/effects/bleeding.dm +++ b/code/datums/effects/bleeding.dm @@ -19,6 +19,13 @@ if(L && istype(L)) limb = L +/datum/effects/bleeding/Destroy() + if(limb) + SEND_SIGNAL(limb, COMSIG_LIMB_STOP_BLEEDING, TRUE, FALSE) + limb.bleeding_effects_list -= src + limb = null + return ..() + /datum/effects/bleeding/validate_atom(atom/A) if(isobj(A)) return FALSE @@ -48,12 +55,6 @@ duration += damage * (blood_duration_multiplier / BLOOD_ADD_PENALTY) blood_loss += damage / (blood_loss_divider * BLOOD_ADD_PENALTY) //Make the first hit count, adding on bleeding has a penalty -/datum/effects/bleeding/Destroy() - if(limb) - limb.bleeding_effects_list -= src - return ..() - - /datum/effects/bleeding/external var/buffer_blood_loss = 0 diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm index 207310ac34c5..6a4276208d13 100644 --- a/code/datums/helper_datums/teleport.dm +++ b/code/datums/helper_datums/teleport.dm @@ -177,7 +177,7 @@ teleatom.visible_message(SPAN_DANGER("[teleatom] bounces off of the portal!")) return 0 - if(is_admin_level(destination.z)) + if(should_block_game_interaction(destination)) if(length(teleatom.search_contents_for(/obj/item/storage/backpack/holding))) teleatom.visible_message(SPAN_DANGER("The Bag of Holding bounces off of the portal!")) return 0 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 205032f46a97..74f445f21597 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -44,8 +44,6 @@ msg_admin_niche("[key]/[ckey] has tried to transfer to deleted [new_character].") return - SEND_SIGNAL(current.client, COMSIG_CLIENT_MIND_TRANSFER, new_character) - if(current) current.mind = null //remove ourself from our old body's mind variable SSnano.nanomanager.user_transferred(current, new_character) // transfer active NanoUI instances to new user diff --git a/code/datums/status_effects/_status_effect_helpers.dm b/code/datums/status_effects/_status_effect_helpers.dm index 0ee952200610..02a4f9a5ccea 100644 --- a/code/datums/status_effects/_status_effect_helpers.dm +++ b/code/datums/status_effects/_status_effect_helpers.dm @@ -40,6 +40,7 @@ // Create the status effect with our mob + our arguments var/datum/status_effect/new_instance = new new_effect(arguments) + SEND_SIGNAL(src, COMSIG_LIVING_APPLY_EFFECT, new_instance) if(!QDELETED(new_instance)) return new_instance diff --git a/code/datums/tutorial/_tutorial.dm b/code/datums/tutorial/_tutorial.dm new file mode 100644 index 000000000000..5423453bbdb9 --- /dev/null +++ b/code/datums/tutorial/_tutorial.dm @@ -0,0 +1,259 @@ +GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial) + +/// A tutorial datum contains a set of instructions for a player tutorial, such as what to spawn, what's scripted to occur, and so on. +/datum/tutorial + /// What the tutorial is called, is player facing + var/name = "Base" + /// Internal ID of the tutorial, kept for save files + var/tutorial_id = "base" + /// A short 1-2 sentence description of the tutorial itself + var/desc = "" + /// What the tutorial's icon in the UI should look like + var/icon_state = "" + /// What category the tutorial should be under + var/category = TUTORIAL_CATEGORY_BASE + /// Ref to the bottom-left corner tile of the tutorial room + var/turf/bottom_left_corner + /// Ref to the turf reservation for this tutorial + var/datum/turf_reservation/reservation + /// Ref to the player who is doing the tutorial + var/mob/tutorial_mob + /// If the tutorial will be ending soon + var/tutorial_ending = FALSE + /// A dict of type:atom ref for some important junk that should be trackable + var/list/tracking_atoms = list() + /// What map template should be used for the tutorial + var/datum/map_template/tutorial/tutorial_template = /datum/map_template/tutorial/s12x12 + /// What is the parent path of this, to exclude from the tutorial menu + var/parent_path = /datum/tutorial + /// A dictionary of "bind_name" : "keybind_button". The inverse of `key_bindings` on a client's prefs + var/list/player_bind_dict = list() + +/datum/tutorial/Destroy(force, ...) + GLOB.ongoing_tutorials -= src + QDEL_NULL(reservation) // Its Destroy() handles releasing reserved turfs + + tutorial_mob = null // We don't delete it because the turf reservation will typically clean it up + + QDEL_LIST_ASSOC_VAL(tracking_atoms) + + return ..() + +/// The proc to begin doing everything related to the tutorial +/datum/tutorial/proc/start_tutorial(mob/starting_mob) + SHOULD_CALL_PARENT(TRUE) + + if(!starting_mob?.client) + return FALSE + + ADD_TRAIT(starting_mob, TRAIT_IN_TUTORIAL, TRAIT_SOURCE_TUTORIAL) + + tutorial_mob = starting_mob + + reservation = SSmapping.RequestBlockReservation(initial(tutorial_template.width), initial(tutorial_template.height)) + if(!reservation) + return FALSE + + var/turf/bottom_left_corner_reservation = locate(reservation.bottom_left_coords[1], reservation.bottom_left_coords[2], reservation.bottom_left_coords[3]) + var/datum/map_template/tutorial/template = new tutorial_template + template.load(bottom_left_corner_reservation, FALSE, TRUE) + var/obj/landmark = locate(/obj/effect/landmark/tutorial_bottom_left) in GLOB.landmarks_list + bottom_left_corner = get_turf(landmark) + qdel(landmark) + + if(!verify_template_loaded()) + abort_tutorial() + return FALSE + + generate_binds() + + GLOB.ongoing_tutorials |= src + var/area/tutorial_area = get_area(bottom_left_corner) + tutorial_area.update_base_lighting() // this will be entirely dark otherwise + init_map() + if(!tutorial_mob) + end_tutorial() + + return TRUE + +/// The proc used to end and clean up the tutorial +/datum/tutorial/proc/end_tutorial(completed = FALSE) + SHOULD_CALL_PARENT(TRUE) + + if(tutorial_mob) + remove_action(tutorial_mob, /datum/action/tutorial_end) // Just in case to make sure the client can't try and leave the tutorial while it's mid-cleanup + if(tutorial_mob.client?.prefs && completed) + tutorial_mob.client.prefs.completed_tutorials |= tutorial_id + tutorial_mob.client.prefs.save_character() + var/mob/new_player/new_player = new + if(!tutorial_mob.mind) + tutorial_mob.mind_initialize() + + tutorial_mob.mind.transfer_to(new_player) + + if(!QDELETED(src)) + qdel(src) + +/// Verify the template loaded fully and without error. +/datum/tutorial/proc/verify_template_loaded() + // We subtract 1 from x and y because the bottom left corner doesn't start at the walls. + var/turf/true_bottom_left_corner = locate( + reservation.bottom_left_coords[1], + reservation.bottom_left_coords[2], + reservation.bottom_left_coords[3], + ) + // We subtract 1 from x and y here because the bottom left corner counts as the first tile + var/turf/top_right_corner = locate( + true_bottom_left_corner.x + initial(tutorial_template.width) - 1, + true_bottom_left_corner.y + initial(tutorial_template.height) - 1, + true_bottom_left_corner.z + ) + for(var/turf/tile as anything in block(true_bottom_left_corner, top_right_corner)) + // For some reason I'm unsure of, the template will not always fully load, leaving some tiles to be space tiles. So, we check all tiles in the (small) tutorial area + // and tell start_tutorial to abort if there's any space tiles. + if(istype(tile, /turf/open/space)) + return FALSE + + return TRUE + +/// Something went very, very wrong during load so let's abort +/datum/tutorial/proc/abort_tutorial() + to_chat(tutorial_mob, SPAN_BOLDWARNING("Something went wrong during tutorial load, please try again!")) + end_tutorial(FALSE) + +/datum/tutorial/proc/add_highlight(atom/target, color = "#d19a02") + target.add_filter("tutorial_highlight", 2, list("type" = "outline", "color" = color, "size" = 1)) + +/datum/tutorial/proc/remove_highlight(atom/target) + target.remove_filter("tutorial_highlight") + +/datum/tutorial/proc/add_to_tracking_atoms(atom/reference) + tracking_atoms[reference.type] = reference + +/datum/tutorial/proc/remove_from_tracking_atoms(atom/reference) + tracking_atoms -= reference.type + +/// Broadcast a message to the player's screen +/datum/tutorial/proc/message_to_player(message) + playsound_client(tutorial_mob.client, 'sound/effects/radiostatic.ogg', tutorial_mob.loc, 25, FALSE) + tutorial_mob.play_screen_text(message, /atom/movable/screen/text/screen_text/command_order/tutorial, rgb(103, 214, 146)) + to_chat(tutorial_mob, SPAN_NOTICE(message)) + +/// Updates a player's objective in their status tab +/datum/tutorial/proc/update_objective(message) + SEND_SIGNAL(tutorial_mob, COMSIG_MOB_TUTORIAL_UPDATE_OBJECTIVE, message) + +/// Initialize the tutorial mob. +/datum/tutorial/proc/init_mob() + tutorial_mob.AddComponent(/datum/component/tutorial_status) + give_action(tutorial_mob, /datum/action/tutorial_end, null, null, src) + ADD_TRAIT(tutorial_mob, TRAIT_IN_TUTORIAL, TRAIT_SOURCE_TUTORIAL) + +/// Ends the tutorial after a certain amount of time. +/datum/tutorial/proc/tutorial_end_in(time = 5 SECONDS, completed = TRUE) + tutorial_ending = TRUE + addtimer(CALLBACK(src, PROC_REF(end_tutorial), completed), time) + +/// Initialize any objects that need to be in the tutorial area from the beginning. +/datum/tutorial/proc/init_map() + return + +/// Returns a turf offset by offset_x (left-to-right) and offset_y (up-to-down) +/datum/tutorial/proc/loc_from_corner(offset_x = 0, offset_y = 0) + RETURN_TYPE(/turf) + return locate(bottom_left_corner.x + offset_x, bottom_left_corner.y + offset_y, bottom_left_corner.z) + +/// Handle the player ghosting out +/datum/tutorial/proc/on_ghost(datum/source, mob/dead/observer/ghost) + SIGNAL_HANDLER + + var/mob/new_player/new_player = new + if(!ghost.mind) + ghost.mind_initialize() + + ghost.mind.transfer_to(new_player) + + end_tutorial(FALSE) + +/// A wrapper for signals to call end_tutorial() +/datum/tutorial/proc/signal_end_tutorial(datum/source) + SIGNAL_HANDLER + + end_tutorial(FALSE) + +/// Called whenever the tutorial_mob logs out +/datum/tutorial/proc/on_logout(datum/source) + SIGNAL_HANDLER + + if(tutorial_mob.aghosted) + return + + end_tutorial(FALSE) + +/// Generate a dictionary of button : action for use of referencing what keys to press +/datum/tutorial/proc/generate_binds() + if(!tutorial_mob.client?.prefs) + return + + for(var/bind in tutorial_mob.client.prefs.key_bindings) + var/action = tutorial_mob.client.prefs.key_bindings[bind] + // We presume the first action under a certain binding is the one we want. + if(action[1] in player_bind_dict) + player_bind_dict[action[1]] += bind + else + player_bind_dict[action[1]] = list(bind) + +/// Getter for player_bind_dict. Provide an action name like "North" or "quick_equip" +/datum/tutorial/proc/retrieve_bind(action_name) + if(!action_name) + return + + if(!(action_name in player_bind_dict)) + return "Undefined" + + return player_bind_dict[action_name][1] + +/datum/action/tutorial_end + name = "Stop Tutorial" + action_icon_state = "hologram_exit" + /// Weakref to the tutorial this is related to + var/datum/weakref/tutorial + +/datum/action/tutorial_end/New(Target, override_icon_state, datum/tutorial/selected_tutorial) + . = ..() + tutorial = WEAKREF(selected_tutorial) + +/datum/action/tutorial_end/action_activate() + if(!tutorial) + return + + var/datum/tutorial/selected_tutorial = tutorial.resolve() + if(selected_tutorial.tutorial_ending) + return + + selected_tutorial.end_tutorial() + + +/datum/map_template/tutorial + name = "Tutorial Zone (12x12)" + mappath = "maps/tutorial/tutorial_12x12.dmm" + width = 12 + height = 12 + +/datum/map_template/tutorial/s12x12 + +/datum/map_template/tutorial/s8x9 + name = "Tutorial Zone (8x9)" + mappath = "maps/tutorial/tutorial_8x9.dmm" + width = 8 + height = 9 + +/datum/map_template/tutorial/s8x9/no_baselight + name = "Tutorial Zone (8x9) (No Baselight)" + mappath = "maps/tutorial/tutorial_8x9_nb.dmm" + +/datum/map_template/tutorial/s7x7 + name = "Tutorial Zone (7x7)" + mappath = "maps/tutorial/tutorial_7x7.dmm" + width = 7 + height = 7 diff --git a/code/datums/tutorial/_tutorial_menu.dm b/code/datums/tutorial/_tutorial_menu.dm new file mode 100644 index 000000000000..42eb3f6aabfa --- /dev/null +++ b/code/datums/tutorial/_tutorial_menu.dm @@ -0,0 +1,83 @@ +/datum/tutorial_menu + /// List of ["name" = name, "tutorials" = ["name" = name, "path" = "path", "id" = tutorial_id]] + var/static/list/categories = list() + + +/datum/tutorial_menu/New() + if(!length(categories)) + var/list/categories_2 = list() + for(var/datum/tutorial/tutorial as anything in subtypesof(/datum/tutorial)) + if(initial(tutorial.parent_path) == tutorial) + continue + + if(!(initial(tutorial.category) in categories_2)) + categories_2[initial(tutorial.category)] = list() + + categories_2[initial(tutorial.category)] += list(list( + "name" = initial(tutorial.name), + "path" = "[tutorial]", + "id" = initial(tutorial.tutorial_id), + "description" = initial(tutorial.desc), + "image" = initial(tutorial.icon_state), + )) + + for(var/category in categories_2) + categories += list(list( + "name" = category, + "tutorials" = categories_2[category], + )) + + +/datum/tutorial_menu/proc/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "TutorialMenu") + ui.open() + +/datum/tutorial_menu/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/spritesheet/tutorial), + ) + +/datum/tutorial_menu/ui_state(mob/user) + if(istype(get_area(user), /area/misc/tutorial)) + return GLOB.never_state + + return GLOB.new_player_state + + +/datum/tutorial_menu/ui_static_data(mob/user) + var/list/data = list() + + data["tutorial_categories"] = categories + if(user.client?.prefs) + data["completed_tutorials"] = user.client.prefs.completed_tutorials + else + data["completed_tutorials"] = list() + + return data + + +/datum/tutorial_menu/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) + . = ..() + if(.) + return + + switch(action) + if("select_tutorial") + var/datum/tutorial/path + if(!params["tutorial_path"]) + return + + path = text2path(params["tutorial_path"]) + + if(!path || !isnewplayer(usr)) + return + + if(HAS_TRAIT(usr, TRAIT_IN_TUTORIAL) || istype(get_area(usr), /area/misc/tutorial)) + to_chat(usr, SPAN_NOTICE("You are currently in a tutorial, or one is loading. Please be patient.")) + return + + path = new path + path.start_tutorial(usr) + return TRUE diff --git a/code/datums/tutorial/creating_a_tutorial.md b/code/datums/tutorial/creating_a_tutorial.md new file mode 100644 index 000000000000..96a7cb886820 --- /dev/null +++ b/code/datums/tutorial/creating_a_tutorial.md @@ -0,0 +1,96 @@ +# Tutorial Creation + +[ToC] + +## Step 1: Identifying the Goal + +Your first objective when making a tutorial should be to have a clear and concise vision of what you want the tutorial to convey to the user. People absorb information better in smaller chunks, so you should ideally keep a tutorial to one section of information at a time. + +For example, if you are making a tutorial for new CM players, it should be split into multiple parts like: + +- Basics +- Medical +- Weaponry +- Requisitions/Communication + +## Step 2: Coding + +For an example of the current code standards for tutorials, see [this](https://github.com/cmss13-devs/cmss13/pull/4442/files#diff-843b2f84360b9b932dfc960027992f2b5117667962bfa8da14f9a35f0179a926) file. + +The API for tutorials is designed to be very simple, so I'll go over all the base `/datum/tutorial` procs and some vars here: + +### Variables +- `name` + - This is the player-facing name of the tutorial. +- `tutorial_id` + - This is the back-end ID of the tutorial, used for save files. Try not to change a tutorial's ID after it's on the live server. +- `category` + - This is what category the tutorial should be under. Use the `TUTORIAL_CATEGORY_XXXX` macros. +- `tutorial_template` + - This is what type the map template of the tutorial should be. The default space is 12x12; ideally make it so it fits the given scale of the tutorial with some wiggle room for the player to move around. +- `parent_path` + - This is the top-most parent `/datum/tutorial` path, used to exclude abstract parents from the tutorial menu. For example, `/datum/tutorial/marine/basic` would have a `parent_path` of `/datum/tutorial/marine`, since that path is the top-most abstract path. + +### Procs +- `start_tutorial(mob/starting_mob)` + - This proc starts the tutorial, setting up the map template and player. This should be overridden with a parent call before any overridden code. +- `end_tutorial(completed = FALSE)` + - This proc ends the tutorial, sending the player back to the lobby and deleting the tutorial itself. A parent call on any subtypes should be at the end of the overridden segment. If `completed` is `TRUE`, then the tutorial will save as a completed one for the user. +- `add_highlight(atom/target, color = "#d19a02")` + - This proc adds a highlight filter around an atom, by default this color. Successive calls of highlight on the same atom will override the last. +- `remove_highlight(atom/target)` + - This proc removes the tutorial highlight from a target. +- `add_to_tracking_atoms(atom/reference)` + - This proc will add a reference to the tutorial's tracked atom dictionary. For what a tracked atom is, see Step 2.1. +- `remove_from_tracking_atoms(atom/reference)` + - This proc will remove a reference from the tutorial's tracked atom dictionary. For what a tracked atom is, see Step 2.1. +- `message_to_player(message)` + - This proc is the ideal way to communicate to a player. It is visually similar to overwatch messages or weather alerts, but appears and disappears much faster. The messages sent should be consise, but can have a degree of dialogue to them. +- `update_objective(message)` + - This proc is used to update the player's objective in their status panel. This should be only what is required and how to do it without any dialogue or extra text. +- `init_mob()` + - This proc is used to initialize the mob and set them up correctly. +- `init_map()` + - This proc does nothing by default, but can be overriden to spawn any atoms necessary for the tutorial from the very start. +- `tutorial_end_in(time = 5 SECONDS, completed = TRUE)` + - This proc will end the tutorial in the given time, defaulting to 5 seconds. Once the proc is called, the player will be booted back to the menu screen after the time is up. Will mark the tutorial as completed if `completed` is `TRUE` +- `loc_from_corner(offset_x = 0, offset_y = 0)` + - This proc will return a turf offset from the bottom left corner of the tutorial zone. Keep in mind, the bottom left corner is NOT on a wall, it is on the first floor on the bottom left corner. `offset_x` and `offset_y` are used to offset what turf you want to get, and should never be negative. + +## Step 2.1: Tracking Atoms +Naturally, you will need to keep track of certain objects or mobs for signal purposes, so the tracking system exists to fill that purpose. When you add a reference to the tracking atom list with `add_to_tracking_atoms()`, it gets put into a dictionary of `{path : reference}`. Because of this limitation, you should not track more than 1 object of the same type. To get a tracked atom, use of the `TUTORIAL_ATOM_FROM_TRACKING(path, varname)` macro is recommended. `path` should be replaced with the precise typepath of the tracked atom, and `varname` should be replaced with the variable name you wish to use. If an object is going to be deleted, remove it with `remove_from_tracking_atoms()` first. + +## Step 2.2: Scripting Format +Any proc whose main purpose is to advance the tutorial will be hereon referred to as a "script proc", as part of the entire "script". In the vast majority of cases, a script proc should hand off to the next using signals. Here is an example from `basic_marine.dm`: + +```javascript +/datum/tutorial/marine/basic/proc/on_cryopod_exit() + SIGNAL_HANDLER + + UnregisterSignal(tracking_atoms[/obj/structure/machinery/cryopod/tutorial], COMSIG_CRYOPOD_GO_OUT) + message_to_player("Good. You may notice the yellow \"food\" icon on the right side of your screen. Proceed to the outlined Food Vendor and vend the USCM Protein Bar.") + update_objective("Vend a USCM Protein Bar from the outlined ColMarTech Food Vendor.") + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial, food_vendor) + add_highlight(food_vendor) + food_vendor.req_access = list() + RegisterSignal(food_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND, PROC_REF(on_food_vend)) + +``` + +Line-by-line: + - `SIGNAL_HANDLER` is necessary as this proc was called via signal. + - Here we are unregistering the signal we registered in the previous proc to call this one, which in this case was waiting for the player to leave the tracked cryopod. + - Now, we tell the user the next step in the script, which is sent to their screen. + - Here we update the player's status panel with similar info to the above line, but far more condensed. + - Since we need to access the food vendor, we use the `TUTORIAL_ATOM_FROM_TRACKING()` macro to get a ref to it. + - We add a yellow outline to the food vendor to make it more clear what is wanted of the player + - The tutorial food vendors are locked to `ACCESS_TUTORIAL_LOCKED` by default, so here we remove that access requirement + - And finally, we register a signal for the next script proc, waiting for the user to vend something from the food vendor. + + +## Step 2.3: Quirks & Tips +- Generally speaking, you will want to create `/tutorial` subtypes of anything you add in the tutorial, should it need any special functions or similar. +- Restrict access from players as much as possible. As seen in the example above, restricting access to vendors and similar machines is recommended to prevent sequence breaking. Additionally, avoid adding anything that detracts from the tutorial itself. +- Attempt to avoid softlocks when possible. If someone could reasonably do something (e.g. firing every bullet they have at a ranged target and missing, now unable to kill them and progress) that could softlock them, then there should be a fallback of some sort. However, accomodations don't need to be made for people who purposefully cause a softlock; there's a "stop tutorial" button for a reason. +- When calling `message_to_player()` or `update_objective()`, **bold** the names of objects, items, and keybinds. +- Attempt to bind as many scripting signals to the `tutorial_mob` as possible. The nature of SS13 means something as sequence-heavy as this will always be fragile, so keeping the fragility we can affect to a minimum is imperative. diff --git a/code/datums/tutorial/marine/_marine.dm b/code/datums/tutorial/marine/_marine.dm new file mode 100644 index 000000000000..ceb0ba8ab550 --- /dev/null +++ b/code/datums/tutorial/marine/_marine.dm @@ -0,0 +1,21 @@ +/datum/tutorial/marine + category = TUTORIAL_CATEGORY_MARINE + parent_path = /datum/tutorial/marine + icon_state = "marine" + +/datum/tutorial/marine/init_mob() + var/mob/living/carbon/human/new_character = new(bottom_left_corner) + new_character.lastarea = get_area(bottom_left_corner) + + setup_human(new_character, tutorial_mob) + + //SSround_recording.recorder.track_player(new_character) //zonenote: check if necessary + + new_character.marine_snowflake_points = MARINE_TOTAL_SNOWFLAKE_POINTS + new_character.marine_buyable_categories = MARINE_CAN_BUY_ALL + + tutorial_mob = new_character + RegisterSignal(tutorial_mob, COMSIG_LIVING_GHOSTED, PROC_REF(on_ghost)) + RegisterSignal(tutorial_mob, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_DEATH, COMSIG_MOB_END_TUTORIAL), PROC_REF(signal_end_tutorial)) + RegisterSignal(tutorial_mob, COMSIG_MOB_LOGOUT, PROC_REF(on_logout)) + return ..() diff --git a/code/datums/tutorial/marine/basic_marine.dm b/code/datums/tutorial/marine/basic_marine.dm new file mode 100644 index 000000000000..be49977f7a48 --- /dev/null +++ b/code/datums/tutorial/marine/basic_marine.dm @@ -0,0 +1,208 @@ +/datum/tutorial/marine/basic + name = "Marine - Basic" + desc = "A tutorial to get you acquainted with the very basics of how to play a groundside marine role." + tutorial_id = "marine_basic_1" + tutorial_template = /datum/map_template/tutorial/s8x9/no_baselight + /// How many items need to be vended from the clothing vendor for the script to continue, if something vends 2 items (for example), increase this number by 2. + var/clothing_items_to_vend = 8 + /// How many items need to be vended from the gun vendor to continue + var/gun_items_to_vend = 2 + +// START OF SCRIPTING + +/datum/tutorial/marine/basic/start_tutorial(mob/starting_mob) + . = ..() + if(!.) + return + + var/obj/item/device/flashlight/flashlight = new(loc_from_corner(2, 3)) + flashlight.anchored = TRUE + flashlight.set_light_power(4) + flashlight.set_light_range(12) + flashlight.icon = null + flashlight.set_light_on(TRUE) + add_to_tracking_atoms(flashlight) + + init_mob() + message_to_player("This is the tutorial for marine rifleman. Leave the cryopod by pressing [retrieve_bind("North")] or [retrieve_bind("East")] to continue.") + update_objective("Exit the cryopod by pressing [retrieve_bind("North")] or [retrieve_bind("East")].") + RegisterSignal(tracking_atoms[/obj/structure/machinery/cryopod/tutorial], COMSIG_CRYOPOD_GO_OUT, PROC_REF(on_cryopod_exit)) + +/datum/tutorial/marine/basic/proc/on_cryopod_exit() + SIGNAL_HANDLER + + UnregisterSignal(tracking_atoms[/obj/structure/machinery/cryopod/tutorial], COMSIG_CRYOPOD_GO_OUT) + message_to_player("Good. You may notice the yellow \"food\" icon on the right side of your screen. Proceed to the outlined Food Vendor and vend the USCM Protein Bar.") + update_objective("Vend a USCM Protein Bar from the outlined ColMarTech Food Vendor.") + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial, food_vendor) + add_highlight(food_vendor) + food_vendor.req_access = list() + RegisterSignal(food_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND, PROC_REF(on_food_vend)) + +/datum/tutorial/marine/basic/proc/on_food_vend(datum/source, obj/structure/machinery/cm_vending/vendor, list/itemspec, mob/living/carbon/human/user) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial, food_vendor) + UnregisterSignal(food_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND) + remove_highlight(food_vendor) + food_vendor.req_access = list(ACCESS_TUTORIAL_LOCKED) + message_to_player("Now click on your character with the USCM Protein Bar in-hand until it is fully eaten. If you accidentally switched hands, switch back with [retrieve_bind("swap_hands")].") + update_objective("Eat the USCM Protein Bar by clicking on yourself while holding it, until it is gone.") + RegisterSignal(tutorial_mob, COMSIG_MOB_EATEN_SNACK, PROC_REF(on_foodbar_eaten)) + +/datum/tutorial/marine/basic/proc/on_foodbar_eaten(datum/source, obj/item/reagent_container/food/snacks/eaten_food) + SIGNAL_HANDLER + + if(!istype(eaten_food, /obj/item/reagent_container/food/snacks/protein_pack) || eaten_food.reagents.total_volume) + return + + UnregisterSignal(source, COMSIG_MOB_EATEN_SNACK) + message_to_player("Good. Now move to the outlined vendor and vend everything inside.") + update_objective("Vend everything inside the ColMarTech Automated Closet.") + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/clothing/tutorial, clothing_vendor) + add_highlight(clothing_vendor) + clothing_vendor.req_access = list() + RegisterSignal(clothing_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND, PROC_REF(on_clothing_vend)) + +/datum/tutorial/marine/basic/proc/on_clothing_vend(datum/source) + SIGNAL_HANDLER + + clothing_items_to_vend-- + if(clothing_items_to_vend <= 0) + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/clothing/tutorial, clothing_vendor) + UnregisterSignal(clothing_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND) + clothing_vendor.req_access = list(ACCESS_TUTORIAL_LOCKED) + remove_highlight(clothing_vendor) + message_to_player("Now, the room will darken. Take a flare out of your flare pouch by clicking on it with an empty hand, and then light it by using it in-hand with [retrieve_bind("activate_inhand")].") + update_objective("Click on your flare pouch to remove a flare before using it in-hand.") + var/obj/item/storage/pouch/flare/flare_pouch = locate(/obj/item/storage/pouch/flare) in tutorial_mob.contents + if(flare_pouch) + add_highlight(flare_pouch) + RegisterSignal(tutorial_mob, COMSIG_MOB_ITEM_ATTACK_SELF, PROC_REF(on_flare_light)) + addtimer(CALLBACK(src, PROC_REF(dim_room)), 2.5 SECONDS) + +/datum/tutorial/marine/basic/proc/on_flare_light(datum/source, obj/item/used) + SIGNAL_HANDLER + + if(!istype(used, /obj/item/device/flashlight/flare)) + return + + UnregisterSignal(tutorial_mob, COMSIG_MOB_ITEM_ATTACK_SELF) + var/obj/item/storage/pouch/flare/flare_pouch = locate(/obj/item/storage/pouch/flare) in tutorial_mob.contents + if(flare_pouch) + remove_highlight(flare_pouch) + + message_to_player("Now throw the flare by clicking on a nearby tile, or dropping it with [retrieve_bind("drop_item")].") + update_objective("Throw the flare by clicking on a nearby tile, or dropping it with [retrieve_bind("drop_item")].") + RegisterSignal(tutorial_mob, COMSIG_MOB_ITEM_DROPPED, PROC_REF(on_flare_throw)) + +/datum/tutorial/marine/basic/proc/on_flare_throw(datum/source, obj/item/thrown) + SIGNAL_HANDLER + + if(!istype(thrown, /obj/item/device/flashlight/flare)) + return + + UnregisterSignal(tutorial_mob, COMSIG_MOB_ITEM_DROPPED) + message_to_player("Good. Now, the room will brighten again. Proceed to the highlighted vendor and vend a M41A Pulse Rifle MK2, along with a magazine.") + update_objective("Vend everything from the ColMarTech Automated Weapons Rack.") + addtimer(CALLBACK(src, PROC_REF(brighten_room)), 1.5 SECONDS) + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad_prep/tutorial, gun_vendor) + gun_vendor.req_access = list() + add_highlight(gun_vendor) + RegisterSignal(gun_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND, PROC_REF(on_gun_vend)) + +/datum/tutorial/marine/basic/proc/on_gun_vend(datum/source) + SIGNAL_HANDLER + + gun_items_to_vend-- + if(gun_items_to_vend <= 0) + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad_prep/tutorial, gun_vendor) + gun_vendor.req_access = list(ACCESS_TUTORIAL_LOCKED) + remove_highlight(gun_vendor) + UnregisterSignal(gun_vendor, COMSIG_VENDOR_SUCCESSFUL_VEND) + message_to_player("Now insert the magazine into the M41A Pulse Rifle by having the magazine in your active hand and hitting the Pulse Rifle with it. If it is in the off-hand, switch with [retrieve_bind("swap_hands")].") + update_objective("Insert the M41A magazine by hitting the M41A Pulse Rifle with it.") + RegisterSignal(tutorial_mob, COMSIG_MOB_RELOADED_GUN, PROC_REF(on_magazine_insert)) + +/datum/tutorial/marine/basic/proc/on_magazine_insert(datum/source, atom/attacked, obj/item/attacked_with) + SIGNAL_HANDLER + + UnregisterSignal(tutorial_mob, COMSIG_MOB_RELOADED_GUN) + message_to_player("Good. Now wield your gun by using it in-hand with [retrieve_bind("activate_inhand")].") + update_objective("Wield your gun with two hands by pressing [retrieve_bind("activate_inhand")] with the gun in your main hand.") + RegisterSignal(tutorial_mob, COMSIG_MOB_ITEM_ATTACK_SELF, PROC_REF(on_gun_wield)) + +/datum/tutorial/marine/basic/proc/on_gun_wield(datum/source, obj/item/used) + SIGNAL_HANDLER + + if(!istype(used, /obj/item/weapon/gun/rifle/m41a)) + return + + UnregisterSignal(tutorial_mob, COMSIG_MOB_ITEM_ATTACK_SELF) + message_to_player("Now, shoot at the highlighted Xenomorph until it dies.") + update_objective("Shoot at the Xenomorph until it dies.") + var/mob/living/carbon/xenomorph/drone/tutorial/xeno_dummy = new(loc_from_corner(4, 5)) + add_to_tracking_atoms(xeno_dummy) + add_highlight(xeno_dummy, COLOUR_VIVID_RED) + RegisterSignal(xeno_dummy, COMSIG_MOB_DEATH, PROC_REF(on_xeno_death)) + RegisterSignal(tutorial_mob, COMSIG_MOB_GUN_EMPTY, PROC_REF(on_magazine_empty)) // I'd like to prevent unwilling softlocks as much as I can + +/// Non-contiguous part of the script, called if the user manages to run out of ammo in the gun without the xeno dying +/datum/tutorial/marine/basic/proc/on_magazine_empty(obj/item/weapon/gun/empty_gun) + SIGNAL_HANDLER + + UnregisterSignal(tutorial_mob, COMSIG_MOB_GUN_EMPTY) + message_to_player("Your gun's out of ammo. Go grab some more from the Weaponry Vendor and kill the Xenomorph.") + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad_prep/tutorial, gun_vendor) + gun_vendor.req_access = list() + gun_vendor.load_ammo() // 99 magazines, to make sure that the xeno dies + +/datum/tutorial/marine/basic/proc/on_xeno_death(datum/source) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/xenomorph/drone/tutorial, xeno_dummy) + UnregisterSignal(xeno_dummy, COMSIG_MOB_DEATH) + UnregisterSignal(tutorial_mob, COMSIG_MOB_GUN_EMPTY) + remove_highlight(xeno_dummy) + addtimer(CALLBACK(src, PROC_REF(disappear_xeno)), 2.5 SECONDS) + message_to_player("Very good. This is the end of the tutorial, proceed to the next one to learn the basics of Medical. You will be sent back to the lobby screen momentarily.") + update_objective("") + tutorial_end_in(7.5 SECONDS, TRUE) + + +// END OF SCRIPTING +// START OF SCRIPT HELPERS + +/datum/tutorial/marine/basic/proc/dim_room() + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/device/flashlight, flashlight) + flashlight.set_light_on(FALSE) + +/datum/tutorial/marine/basic/proc/brighten_room() + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/device/flashlight, flashlight) + flashlight.set_light_on(TRUE) + +/datum/tutorial/marine/basic/proc/disappear_xeno() + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/xenomorph/drone/tutorial, xeno_dummy) + animate(xeno_dummy, time = 5 SECONDS, alpha = 0) + remove_from_tracking_atoms(xeno_dummy) + QDEL_IN(xeno_dummy, 5.5 SECONDS) + +// END OF SCRIPT HELPERS + +/datum/tutorial/marine/basic/init_mob() + . = ..() + arm_equipment(tutorial_mob, /datum/equipment_preset/tutorial) + + TUTORIAL_ATOM_FROM_TRACKING(/obj/structure/machinery/cryopod/tutorial, tutorial_pod) + tutorial_pod.go_in_cryopod(tutorial_mob, TRUE, FALSE) + + +/datum/tutorial/marine/basic/init_map() + var/obj/structure/machinery/cryopod/tutorial/tutorial_pod = new(bottom_left_corner) + add_to_tracking_atoms(tutorial_pod) + var/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial/food_vendor = new(loc_from_corner(0, 2)) + add_to_tracking_atoms(food_vendor) + var/obj/structure/machinery/cm_vending/clothing/tutorial/clothing_vendor = new(loc_from_corner(0, 4)) + add_to_tracking_atoms(clothing_vendor) + var/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad_prep/tutorial/gun_vendor = new(loc_from_corner(0, 5)) + add_to_tracking_atoms(gun_vendor) diff --git a/code/datums/tutorial/marine/medical_basic.dm b/code/datums/tutorial/marine/medical_basic.dm new file mode 100644 index 000000000000..3a42a6d2ecc2 --- /dev/null +++ b/code/datums/tutorial/marine/medical_basic.dm @@ -0,0 +1,174 @@ +/datum/tutorial/marine/medical_basic + name = "Marine - Medical (Basic)" + desc = "Learn how to treat common injuries you may face as a marine." + tutorial_id = "marine_medical_1" + tutorial_template = /datum/map_template/tutorial/s7x7 + +// START OF SCRIPTING + +/datum/tutorial/marine/medical_basic/start_tutorial(mob/starting_mob) + . = ..() + if(!.) + return + + init_mob() + message_to_player("This is the tutorial for the basics of medical that you will need to know for playing a marine role.") + addtimer(CALLBACK(src, PROC_REF(brute_tutorial)), 4 SECONDS) + +/datum/tutorial/marine/medical_basic/proc/brute_tutorial() + message_to_player("The first kind of damage is Brute, the most common kind. It represents physical trauma from things like punches, weapons, or guns.") + var/mob/living/living_mob = tutorial_mob + living_mob.adjustBruteLoss(10) + addtimer(CALLBACK(src, PROC_REF(brute_tutorial_2)), 4 SECONDS) + +/datum/tutorial/marine/medical_basic/proc/brute_tutorial_2() + message_to_player("You can observe if you have Brute or Burn damage by clicking on yourself with an empty hand on help intent.") + update_objective("Click on yourself with an empty hand.") + RegisterSignal(tutorial_mob, COMSIG_LIVING_ATTACKHAND_HUMAN, PROC_REF(on_health_examine)) + +/datum/tutorial/marine/medical_basic/proc/on_health_examine(datum/source, mob/living/carbon/human/attacked_mob) + SIGNAL_HANDLER + + if(attacked_mob != tutorial_mob) + return + + UnregisterSignal(tutorial_mob, COMSIG_LIVING_ATTACKHAND_HUMAN) + message_to_player("Good. Now, you have taken some brute damage. Bicaridine is used to fix brute over time. Pick up the bicaridine EZ autoinjector and use it in-hand.") + update_objective("Inject yourself with the bicaridine injector.") + var/obj/item/reagent_container/hypospray/autoinjector/bicaridine/skillless/one_use/brute_injector = new(loc_from_corner(0, 4)) + add_to_tracking_atoms(brute_injector) + add_highlight(brute_injector) + RegisterSignal(tutorial_mob, COMSIG_LIVING_HYPOSPRAY_INJECTED, PROC_REF(on_brute_inject)) + +/datum/tutorial/marine/medical_basic/proc/on_brute_inject(datum/source, obj/item/reagent_container/hypospray/injector) + SIGNAL_HANDLER + + if(!istype(injector, /obj/item/reagent_container/hypospray/autoinjector/bicaridine/skillless/one_use)) + return + + UnregisterSignal(tutorial_mob, COMSIG_LIVING_HYPOSPRAY_INJECTED) + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/reagent_container/hypospray/autoinjector/bicaridine/skillless/one_use, brute_injector) + remove_highlight(brute_injector) + message_to_player("All medicines take time to work after injection. Next is Burn damage. It is obtained from things like acid or being set on fire.") + update_objective("") + var/mob/living/living_mob = tutorial_mob + living_mob.adjustFireLoss(10) + addtimer(CALLBACK(src, PROC_REF(burn_tutorial)), 4 SECONDS) + +/datum/tutorial/marine/medical_basic/proc/burn_tutorial() + message_to_player("Kelotane is used to fix burn over time. Inject yourself with the kelotane EZ autoinjector.") + update_objective("Inject yourself with the kelotane injector.") + var/obj/item/reagent_container/hypospray/autoinjector/kelotane/skillless/one_use/burn_injector = new(loc_from_corner(0, 4)) + add_to_tracking_atoms(burn_injector) + add_highlight(burn_injector) + RegisterSignal(tutorial_mob, COMSIG_LIVING_HYPOSPRAY_INJECTED, PROC_REF(on_burn_inject)) + + +/datum/tutorial/marine/medical_basic/proc/on_burn_inject(datum/source, obj/item/reagent_container/hypospray/injector) + SIGNAL_HANDLER + + if(!istype(injector, /obj/item/reagent_container/hypospray/autoinjector/kelotane/skillless/one_use)) + return + + UnregisterSignal(tutorial_mob, COMSIG_LIVING_HYPOSPRAY_INJECTED) + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/reagent_container/hypospray/autoinjector/kelotane/skillless/one_use, burn_injector) + remove_highlight(burn_injector) + message_to_player("Good. Now, when you normally take damage, you will also feel pain. Pain slows you down and can knock you out if left unchecked.") + update_objective("") + var/mob/living/living_mob = tutorial_mob + living_mob.pain.apply_pain(PAIN_CHESTBURST_STRONG) + addtimer(CALLBACK(src, PROC_REF(pain_tutorial)), 4 SECONDS) + +/datum/tutorial/marine/medical_basic/proc/pain_tutorial() + message_to_player("Tramadol is used to reduce your pain. Inject yourself with the tramadol EZ autoinjector.") + update_objective("Inject yourself with the tramadol injector.") + var/obj/item/reagent_container/hypospray/autoinjector/tramadol/skillless/one_use/pain_injector = new(loc_from_corner(0, 4)) + add_to_tracking_atoms(pain_injector) + add_highlight(pain_injector) + RegisterSignal(tutorial_mob, COMSIG_LIVING_HYPOSPRAY_INJECTED, PROC_REF(on_pain_inject)) + +/datum/tutorial/marine/medical_basic/proc/on_pain_inject(datum/source, obj/item/reagent_container/hypospray/injector) + SIGNAL_HANDLER + + if(!istype(injector, /obj/item/reagent_container/hypospray/autoinjector/tramadol/skillless/one_use)) + return + + UnregisterSignal(tutorial_mob, COMSIG_LIVING_HYPOSPRAY_INJECTED) + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/reagent_container/hypospray/autoinjector/tramadol/skillless/one_use, pain_injector) + remove_highlight(pain_injector) + message_to_player("Good. Keep in mind that you can overdose on chemicals, so don't inject yourself with the same chemical too much too often. In the field, injectors have 3 uses.") + update_objective("Don't overdose! Generally, 3 injections of a chemical will overdose you.") + var/mob/living/living_mob = tutorial_mob + living_mob.pain.apply_pain(-PAIN_CHESTBURST_STRONG) // just to make sure + addtimer(CALLBACK(src, PROC_REF(bleed_tutorial)), 4 SECONDS) + +/datum/tutorial/marine/medical_basic/proc/bleed_tutorial() + message_to_player("You can sometimes start bleeding from things like bullets or slashes. Losing blood will accumulate oxygen damage, eventually causing death.") + update_objective("") + var/mob/living/carbon/human/human_mob = tutorial_mob + var/obj/limb/chest/mob_chest = locate(/obj/limb/chest) in human_mob.limbs + mob_chest.add_bleeding(damage_amount = 15) + addtimer(CALLBACK(src, PROC_REF(bleed_tutorial_2)), 4 SECONDS) + +/datum/tutorial/marine/medical_basic/proc/bleed_tutorial_2() + message_to_player("Bleeding wounds can clot themselves over time, or you can fix it quickly with gauze. Pick up the gauze and click on yourself while targeting your chest.") + update_objective("Gauze your chest, or let it clot on its own.") + var/obj/item/stack/medical/bruise_pack/two/bandage = new(loc_from_corner(0, 4)) + add_to_tracking_atoms(bandage) + add_highlight(bandage) + var/mob/living/carbon/human/human_mob = tutorial_mob + var/obj/limb/chest/mob_chest = locate(/obj/limb/chest) in human_mob.limbs + RegisterSignal(mob_chest, COMSIG_LIMB_STOP_BLEEDING, PROC_REF(on_chest_bleed_stop)) + +/datum/tutorial/marine/medical_basic/proc/on_chest_bleed_stop(datum/source, external, internal) + SIGNAL_HANDLER + + // If you exit on this step, your limbs get deleted, which stops the bleeding, which progresses the tutorial despite it ending + if(!tutorial_mob || QDELETED(src)) + return + + var/mob/living/carbon/human/human_mob = tutorial_mob + var/obj/limb/chest/mob_chest = locate(/obj/limb/chest) in human_mob.limbs + UnregisterSignal(mob_chest, COMSIG_LIMB_STOP_BLEEDING) + + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/stack/medical/bruise_pack/two, bandage) + remove_from_tracking_atoms(bandage) + remove_highlight(bandage) + qdel(bandage) + + message_to_player("Good. Sometimes, a bullet or bone shard can result in you getting shrapnel, dealing damage over time. Pick up the knife and use it in-hand to remove the shrapnel.") + update_objective("Remove your shrapnel by using the knife in-hand.") + var/mob/living/living_mob = tutorial_mob + living_mob.pain.feels_pain = FALSE + + var/obj/item/attachable/bayonet/knife = new(loc_from_corner(0, 4)) + add_to_tracking_atoms(knife) + add_highlight(knife) + + var/obj/item/shard/shrapnel/tutorial/shrapnel = new + shrapnel.on_embed(tutorial_mob, mob_chest, TRUE) + + RegisterSignal(tutorial_mob, COMSIG_HUMAN_SHRAPNEL_REMOVED, PROC_REF(on_shrapnel_removed)) + +/datum/tutorial/marine/medical_basic/proc/on_shrapnel_removed() + SIGNAL_HANDLER + + UnregisterSignal(tutorial_mob, COMSIG_HUMAN_SHRAPNEL_REMOVED) + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/attachable/bayonet, knife) + remove_highlight(knife) + message_to_player("Good. This is the end of the basic marine medical tutorial. The tutorial will end shortly.") + update_objective("Tutorial completed.") + tutorial_end_in(5 SECONDS) + +// END OF SCRIPTING +// START OF SCRIPT HELPERS + +// END OF SCRIPT HELPERS + +/datum/tutorial/marine/medical_basic/init_mob() + . = ..() + arm_equipment(tutorial_mob, /datum/equipment_preset/tutorial/fed) + + +/datum/tutorial/marine/medical_basic/init_map() + new /obj/structure/surface/table/almayer(loc_from_corner(0, 4)) diff --git a/code/datums/tutorial/ss13/_ss13.dm b/code/datums/tutorial/ss13/_ss13.dm new file mode 100644 index 000000000000..53cf5c918ee9 --- /dev/null +++ b/code/datums/tutorial/ss13/_ss13.dm @@ -0,0 +1,41 @@ +/datum/tutorial/ss13 + category = TUTORIAL_CATEGORY_SS13 + parent_path = /datum/tutorial/ss13 + icon_state = "ss13" + +/datum/tutorial/ss13/init_mob() + tutorial_mob.close_spawn_windows() + + var/mob/living/carbon/human/new_character = new(bottom_left_corner) + new_character.lastarea = get_area(bottom_left_corner) + + tutorial_mob.client.prefs.copy_all_to(new_character) + + if(tutorial_mob.client.prefs.be_random_body) + var/datum/preferences/rand_prefs = new() + rand_prefs.randomize_appearance(new_character) + + new_character.job = tutorial_mob.job + new_character.name = tutorial_mob.real_name + new_character.voice = tutorial_mob.real_name + + new_character.sec_hud_set_ID() + new_character.hud_set_squad() + + SSround_recording.recorder.track_player(new_character) + + if(tutorial_mob.mind) + tutorial_mob.mind_initialize() + tutorial_mob.mind.transfer_to(new_character, TRUE) + tutorial_mob.mind.setup_human_stats() + + INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, regenerate_icons)) + INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, update_body), 1, 0) + INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, update_hair)) + + tutorial_mob = new_character + RegisterSignal(tutorial_mob, COMSIG_LIVING_GHOSTED, PROC_REF(on_ghost)) + RegisterSignal(tutorial_mob, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_DEATH, COMSIG_MOB_END_TUTORIAL), PROC_REF(signal_end_tutorial)) + RegisterSignal(tutorial_mob, COMSIG_MOB_LOGOUT, PROC_REF(on_logout)) + arm_equipment(tutorial_mob, /datum/equipment_preset/tutorial/fed) + return ..() diff --git a/code/datums/tutorial/ss13/basic_ss13.dm b/code/datums/tutorial/ss13/basic_ss13.dm new file mode 100644 index 000000000000..65bb0cac94f4 --- /dev/null +++ b/code/datums/tutorial/ss13/basic_ss13.dm @@ -0,0 +1,84 @@ +/datum/tutorial/ss13/basic + name = "Space Station 13 - Basic" + desc = "Learn the very basics of Space Station 13. Recommended if you haven't played before." + tutorial_id = "ss13_basic_1" + tutorial_template = /datum/map_template/tutorial/s7x7 + +// START OF SCRIPTING + +/datum/tutorial/ss13/basic/start_tutorial(mob/starting_mob) + . = ..() + if(!.) + return + + init_mob() + message_to_player("This is the tutorial for the basics of Space Station 13. Any current instructions can be found in the top-right corner, in the status panel.") + update_objective("Here's where it'll be!") + + addtimer(CALLBACK(src, PROC_REF(require_move)), 4 SECONDS) // check if this is a good amount of time + +/datum/tutorial/ss13/basic/proc/require_move() + message_to_player("Now, move in any direction using [retrieve_bind("North")], [retrieve_bind("West")], [retrieve_bind("South")], or [retrieve_bind("East")].") + update_objective("Move in any direction using the [retrieve_bind("North")][retrieve_bind("West")][retrieve_bind("South")][retrieve_bind("East")] keys.") + + RegisterSignal(tutorial_mob, COMSIG_MOB_MOVE_OR_LOOK, PROC_REF(on_move)) + +/datum/tutorial/ss13/basic/proc/on_move(datum/source, actually_moving, direction, specific_direction) + SIGNAL_HANDLER + + if(!actually_moving) // The mob just looked in a different dir instead of moving + return + + UnregisterSignal(tutorial_mob, COMSIG_MOB_MOVE_OR_LOOK) + + message_to_player("Good. Now, switch hands with [retrieve_bind("swap_hands")].") + update_objective("Switch hands with [retrieve_bind("swap_hands")].") + + RegisterSignal(tutorial_mob, COMSIG_MOB_SWAPPED_HAND, PROC_REF(on_hand_swap)) + +/datum/tutorial/ss13/basic/proc/on_hand_swap(datum/source) + SIGNAL_HANDLER + + UnregisterSignal(tutorial_mob, COMSIG_MOB_SWAPPED_HAND) + + message_to_player("Good. Now, pick up the satchel that just spawned and equip it with [retrieve_bind("quick_equip")].") + update_objective("Pick up the satchel and equip it with [retrieve_bind("quick_equip")].") + + var/obj/item/storage/backpack/marine/satchel/satchel = new(loc_from_corner(2, 2)) + add_to_tracking_atoms(satchel) + add_highlight(satchel) + + RegisterSignal(tutorial_mob, COMSIG_HUMAN_EQUIPPED_ITEM, PROC_REF(on_satchel_equip)) + +/datum/tutorial/ss13/basic/proc/on_satchel_equip(datum/source, obj/item/equipped, slot) + SIGNAL_HANDLER + + if(!istype(equipped, /obj/item/storage/backpack/marine/satchel) || (slot != WEAR_BACK)) + return + + UnregisterSignal(tutorial_mob, COMSIG_HUMAN_EQUIPPED_ITEM) + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/storage/backpack/marine/satchel, satchel) + remove_highlight(satchel) + message_to_player("Now, say anything by pressing [retrieve_bind("Say")].") + update_objective("Speak using [retrieve_bind("Say")].") + + RegisterSignal(tutorial_mob, COMSIG_LIVING_SPEAK, PROC_REF(on_speak)) + +/datum/tutorial/ss13/basic/proc/on_speak(datum/source) + SIGNAL_HANDLER + + UnregisterSignal(tutorial_mob, COMSIG_LIVING_SPEAK) + message_to_player("Excellent. The next tutorial will cover intents. The tutorial will end shortly.") + update_objective("") + tutorial_end_in(5 SECONDS, TRUE) + +// END OF SCRIPTING +// START OF SCRIPT HELPERS + + + +// END OF SCRIPT HELPERS + +/datum/tutorial/ss13/basic/init_mob() + . = ..() + tutorial_mob.forceMove(loc_from_corner(2, 1)) diff --git a/code/datums/tutorial/ss13/intents.dm b/code/datums/tutorial/ss13/intents.dm new file mode 100644 index 000000000000..d67b2ac1b4a1 --- /dev/null +++ b/code/datums/tutorial/ss13/intents.dm @@ -0,0 +1,113 @@ +/datum/tutorial/ss13/intents + name = "Space Station 13 - Intents" + desc = "Learn how the intent interaction system works." + icon_state = "intents" + tutorial_id = "ss13_intents_1" + tutorial_template = /datum/map_template/tutorial/s7x7 + +// START OF SCRIPTING + +/datum/tutorial/ss13/intents/start_tutorial(mob/starting_mob) + . = ..() + if(!.) + return + + init_mob() + message_to_player("This is the tutorial for the intents system of Space Station 13. The highlighted UI element in the bottom-right corner is your current intent.") + var/datum/hud/human/human_hud = tutorial_mob.hud_used + add_highlight(human_hud.action_intent) + + addtimer(CALLBACK(src, PROC_REF(require_help)), 4.5 SECONDS) + +/datum/tutorial/ss13/intents/proc/require_help() + tutorial_mob.a_intent_change(INTENT_DISARM) + message_to_player("Your intent has been changed off of help. Change back to it by pressing [retrieve_bind("select_help_intent")].") + update_objective("Change to help intent by pressing [retrieve_bind("select_help_intent")].") + + RegisterSignal(tutorial_mob, COMSIG_MOB_INTENT_CHANGE, PROC_REF(on_help_intent)) + +/datum/tutorial/ss13/intents/proc/on_help_intent(datum/source, new_intent) + SIGNAL_HANDLER + + if(new_intent != INTENT_HELP) + return + + UnregisterSignal(tutorial_mob, COMSIG_MOB_INTENT_CHANGE) + + var/mob/living/carbon/human/dummy/tutorial/tutorial_dummy = new(loc_from_corner(2, 3)) + add_to_tracking_atoms(tutorial_dummy) + + message_to_player("The first of the intents is help intent. It is used to harmlessly touch others, put out fire, give CPR, and similar. Click on the Test Dummy to give them a pat on the back.") + update_objective("Click on the dummy on help intent.") + + RegisterSignal(tutorial_mob, COMSIG_LIVING_ATTACKHAND_HUMAN, PROC_REF(on_help_attack)) + +/datum/tutorial/ss13/intents/proc/on_help_attack(datum/source, mob/living/carbon/human/attacked_mob) + SIGNAL_HANDLER + + if((attacked_mob == src) || (tutorial_mob.a_intent != INTENT_HELP)) + return + + UnregisterSignal(tutorial_mob, COMSIG_LIVING_ATTACKHAND_HUMAN) + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human/dummy/tutorial, tutorial_dummy) + tutorial_dummy.status_flags = DEFAULT_MOB_STATUS_FLAGS + REMOVE_TRAIT(tutorial_dummy, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + tutorial_dummy.anchored = FALSE + + message_to_player("The second intent is disarm, selectable with [retrieve_bind("select_disarm_intent")]. Disarm is used to shove people, which can make them drop items or fall to the ground. Shove the Test Dummy until it falls over.") + update_objective("Switch to disarm intent by pressing [retrieve_bind("select_disarm_intent")] and shove the dummy to the ground.") + + RegisterSignal(tutorial_dummy, COMSIG_LIVING_APPLY_EFFECT, PROC_REF(on_shove_down)) + +/datum/tutorial/ss13/intents/proc/on_shove_down(datum/source, datum/status_effect/new_effect) + SIGNAL_HANDLER + + if(!istype(new_effect, /datum/status_effect/incapacitating/knockdown)) + return + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human/dummy/tutorial, tutorial_dummy) + UnregisterSignal(tutorial_dummy, COMSIG_LIVING_APPLY_EFFECT) + tutorial_dummy.rejuvenate() + + message_to_player("The third intent is grab. Grab is used to grab people in either a passive, aggressive, or chokehold grab. Grab successively to \"upgrade\" your grab. Aggressively grab the Test Dummy.") + update_objective("Aggressively grab the dummy by grabbing them twice.") + + + RegisterSignal(tutorial_dummy, COMSIG_MOB_AGGRESSIVELY_GRABBED, PROC_REF(on_aggrograb)) + +/datum/tutorial/ss13/intents/proc/on_aggrograb(datum/source, mob/living/carbon/human/choker) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human/dummy/tutorial, tutorial_dummy) + UnregisterSignal(tutorial_dummy, COMSIG_MOB_AGGRESSIVELY_GRABBED) + + message_to_player("The final intent is harm. Harm is used to injure people with your fists or a melee weapon. Punch the Test Dummy with an empty hand.") + update_objective("Attack the dummy with an empty hand.") + + RegisterSignal(tutorial_mob, COMSIG_LIVING_ATTACKHAND_HUMAN, PROC_REF(on_harm_attack)) + +/datum/tutorial/ss13/intents/proc/on_harm_attack(datum/source, mob/living/carbon/human/attacked_mob) + SIGNAL_HANDLER + + if((attacked_mob == src) || (tutorial_mob.a_intent != INTENT_HARM)) + return + + UnregisterSignal(tutorial_mob, COMSIG_LIVING_ATTACKHAND_HUMAN) + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human/dummy/tutorial, tutorial_dummy) + tutorial_dummy.status_flags = GODMODE + + message_to_player("Excellent. Those are the basics of the intent system. The tutorial will end shortly.") + update_objective("") + + tutorial_end_in(5 SECONDS, TRUE) + +// END OF SCRIPTING +// START OF SCRIPT HELPERS + + + +// END OF SCRIPT HELPERS + +/datum/tutorial/ss13/intents/init_mob() + . = ..() + tutorial_mob.forceMove(loc_from_corner(2, 0)) diff --git a/code/datums/tutorial/tutorial_example.dm b/code/datums/tutorial/tutorial_example.dm new file mode 100644 index 000000000000..9042346f8d39 --- /dev/null +++ b/code/datums/tutorial/tutorial_example.dm @@ -0,0 +1,74 @@ +/datum/tutorial/marine/example + name = "Example Tutorial" + tutorial_id = "example" // This won't show up in the list, so this'll be irrelevant anyway. + category = TUTORIAL_CATEGORY_BASE + parent_path = /datum/tutorial/marine/example + +// START OF SCRIPTING + +/datum/tutorial/marine/example/start_tutorial(mob/starting_mob) + // Here, we're calling parent and checking its return value. If it has a falsey one (as done by !.), then something went wrong and we should abort + // There isn't really a reason that you _shouldn't_ have this + . = ..() + if(!.) + return + + // Init_mob() isn't called by default, so we call it here + init_mob() + // As is standard, we give a message to the player and update their status panel with what we want done. + message_to_player("This is an example tutorial. Perform any emote to continue.") + update_objective("Do any emote.") + // This makes the player (tutorial_mob) listen for the COMSIG_MOB_EMOTE event, which will then call on_emote() when it hears it. + RegisterSignal(tutorial_mob, COMSIG_MOB_EMOTE, PROC_REF(on_emote)) + +/datum/tutorial/marine/example/proc/on_emote(datum/source) + // With any proc called via signal (see the RegisterSignal line above for details), we add SIGNAL_HANDLER to it. + SIGNAL_HANDLER + + // Now that we've gotten the signal and started the script, we want to immediately stop listening for it. + UnregisterSignal(tutorial_mob, COMSIG_MOB_EMOTE) + message_to_player("Good. Now, pick up that can of Weyland-Yutani Aspen Beer.") + update_objective("Pick up that can.") + // This macro takes a specific type path (the same used in init_map()) and a variable name to retrieve an object from the tracked object list + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/reagent_container/food/drinks/cans/aspen, beer_can) + // Now we're adding a yellow highlight around the can to make sure people know what we're talking about + add_highlight(beer_can) + // Now, we always prefer to register signals on the tutorial_mob (as opposed to the beer_can) whenever possible + RegisterSignal(tutorial_mob, COMSIG_MOB_PICKUP_ITEM, PROC_REF(on_can_pickup)) + +/// We get these arguments from the signal's definition. If you have VSC, ctrl+click on COMSIG_MOB_PICKUP_ITEM above. When dealing with a signal proc, `datum/source` is always the first argument, then any added ones +/datum/tutorial/marine/example/proc/on_can_pickup(datum/source, obj/item/picked_up) + SIGNAL_HANDLER + + // Since we're just listening for the mob picking anything up, we want to confirm that the picked up item is the can before continuing. If it's not, then we return and keep listening. + if(!istype(picked_up, /obj/item/reagent_container/food/drinks/cans/aspen)) + // If we hit this return here, then the picked up item wasn't the can, so we abort and keep listening. + return + + // Since we passed the above if statement, stop listening for item pickups. + UnregisterSignal(tutorial_mob, COMSIG_MOB_PICKUP_ITEM) + // Let's get the tracked beer can again. + TUTORIAL_ATOM_FROM_TRACKING(/obj/item/reagent_container/food/drinks/cans/aspen, beer_can) + // And remove the highlight now that it's picked up + remove_highlight(beer_can) + message_to_player("Very good. This is the end of the example tutorial. You will be sent back to the lobby screen momentarily.") + // 7.5 seconds after the above message is sent, kick the player out and end the tutorial. + tutorial_end_in(7.5 SECONDS, TRUE) + + +// END OF SCRIPTING +// START OF SCRIPT HELPERS + +// END OF SCRIPT HELPERS + +/datum/tutorial/marine/example/init_mob() + . = ..() + // We give the tutorial mob a basic ID so they can use general vendors and etc. This is here because not all marine tutorials may want to use a naked equipment preset. + arm_equipment(tutorial_mob, /datum/equipment_preset/tutorial) + + +/datum/tutorial/marine/example/init_map() + // Here we're initializing a new can that we want to track, so we spawn it 2 tiles to the left and up from the bottom left corner of the tutorial zone + var/obj/item/reagent_container/food/drinks/cans/aspen/the_can = new(loc_from_corner(2, 2)) + // Now we start tracking it + add_to_tracking_atoms(the_can) diff --git a/code/game/area/admin_level.dm b/code/game/area/admin_level.dm index 00b408c04adf..bfca1481155e 100644 --- a/code/game/area/admin_level.dm +++ b/code/game/area/admin_level.dm @@ -144,3 +144,22 @@ /area/misc/testroom requires_power = FALSE name = "Test Room" + +/area/misc/tutorial + name = "Tutorial Zone" + icon_state = "tutorial" + requires_power = FALSE + flags_area = AREA_NOTUNNEL|AREA_AVOID_BIOSCAN + statistic_exempt = TRUE + ceiling = CEILING_METAL + block_game_interaction = TRUE + unique = TRUE + + base_lighting_alpha = 255 + +/area/misc/tutorial/Initialize(mapload, ...) + . = ..() + update_base_lighting() + +/area/misc/tutorial/no_baselight + base_lighting_alpha = 0 diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 536e29599597..9699db527102 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -79,6 +79,10 @@ var/used_environ = 0 var/used_oneoff = 0 //one-off power usage + /// If this area is outside the game's normal interactivity and should be excluded from things like EOR reports and crew monitors. + /// Doesn't need to be set for areas/Z levels that are marked as admin-only + var/block_game_interaction = FALSE + /area/New() // This interacts with the map loader, so it needs to be set immediately diff --git a/code/game/gamemodes/cm_initialize.dm b/code/game/gamemodes/cm_initialize.dm index 981966082919..c017733de7fd 100644 --- a/code/game/gamemodes/cm_initialize.dm +++ b/code/game/gamemodes/cm_initialize.dm @@ -350,7 +350,7 @@ Additional game mode variables. if(cur_xeno.aghosted) continue //aghosted xenos don't count var/area/area = get_area(cur_xeno) - if(is_admin_level(cur_xeno.z) && (!area || !(area.flags_area & AREA_ALLOW_XENO_JOIN))) + if(should_block_game_interaction(cur_xeno) && (!area || !(area.flags_area & AREA_ALLOW_XENO_JOIN))) continue //xenos on admin z level don't count if(!istype(cur_xeno)) continue diff --git a/code/game/gamemodes/colonialmarines/colonialmarines.dm b/code/game/gamemodes/colonialmarines/colonialmarines.dm index bc5d6b69228c..f64c2432486b 100644 --- a/code/game/gamemodes/colonialmarines/colonialmarines.dm +++ b/code/game/gamemodes/colonialmarines/colonialmarines.dm @@ -329,7 +329,7 @@ var/datum/hive_status/HS for(var/HN in GLOB.hive_datum) HS = GLOB.hive_datum[HN] - if(HS.living_xeno_queen && !is_admin_level(HS.living_xeno_queen.loc.z)) + if(HS.living_xeno_queen && !should_block_game_interaction(HS.living_xeno_queen.loc)) //Some Queen is alive, we shouldn't end the game yet return round_finished = MODE_INFESTATION_M_MINOR diff --git a/code/game/gamemodes/colonialmarines/whiskey_outpost/whiskey_output_waves.dm b/code/game/gamemodes/colonialmarines/whiskey_outpost/whiskey_output_waves.dm index 6e2738a83788..1ec07b9d8fec 100644 --- a/code/game/gamemodes/colonialmarines/whiskey_outpost/whiskey_output_waves.dm +++ b/code/game/gamemodes/colonialmarines/whiskey_outpost/whiskey_output_waves.dm @@ -32,7 +32,7 @@ for(var/mob/living/carbon/xenomorph/X as anything in GLOB.living_xeno_list) var/area/A = get_area(X) - if(is_admin_level(X.z) && (!A || !(A.flags_area & AREA_ALLOW_XENO_JOIN)) || X.aghosted) continue //xenos on admin z level and aghosted ones don't count + if(should_block_game_interaction(X) && (!A || !(A.flags_area & AREA_ALLOW_XENO_JOIN)) || X.aghosted) continue //xenos on admin z level and aghosted ones don't count if(istype(X) && !X.client) if((X.away_timer >= XENO_LEAVE_TIMER) || (islarva(X) && X.away_timer >= XENO_LEAVE_TIMER_LARVA)) available_xenos += X diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm index 56decd8f0c02..094b899c1691 100644 --- a/code/game/jobs/job/job.dm +++ b/code/game/jobs/job/job.dm @@ -237,32 +237,10 @@ if(!istype(NP)) return - NP.spawning = TRUE - NP.close_spawn_windows() - var/mob/living/carbon/human/new_character = new(NP.loc) new_character.lastarea = get_area(NP.loc) - NP.client.prefs.copy_all_to(new_character, title) - - if (NP.client.prefs.be_random_body) - var/datum/preferences/TP = new() - TP.randomize_appearance(new_character) - - new_character.job = NP.job - new_character.name = NP.real_name - new_character.voice = NP.real_name - - if(NP.mind) - NP.mind_initialize() - NP.mind.transfer_to(new_character, TRUE) - NP.mind.setup_human_stats() - - // Update the character icons - // This is done in set_species when the mob is created as well, but - INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, regenerate_icons)) - INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, update_body), 1, 0) - INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, update_hair)) + setup_human(new_character, NP) return new_character diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index b9ea018ba98f..190d51d3f7b8 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -4,7 +4,7 @@ /mob/living/silicon/ai/proc/InvalidTurf(turf/T as turf) if(!T) return 1 - if(is_admin_level(T.z)) + if(should_block_game_interaction(T)) return 1 if(T.z > 6) return 1 diff --git a/code/game/machinery/computer/camera_console.dm b/code/game/machinery/computer/camera_console.dm index cad4fd4fc747..1a00e194b5eb 100644 --- a/code/game/machinery/computer/camera_console.dm +++ b/code/game/machinery/computer/camera_console.dm @@ -69,7 +69,7 @@ return attack_hand(user) /obj/structure/machinery/computer/cameras/attack_hand(mob/user) - if(!admin_console && is_admin_level(z)) + if(!admin_console && should_block_game_interaction(src)) to_chat(user, SPAN_DANGER("Unable to establish a connection: \black You're too far away from the ship!")) return if(inoperable()) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index ab5dc6448f4b..69c2c897e276 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -519,7 +519,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li if(mob.client) to_chat(mob, SPAN_NOTICE("You feel cool air surround you. You go numb as your senses turn inward.")) to_chat(mob, SPAN_BOLDNOTICE("If you log out or close your client now, your character will permanently removed from the round in 10 minutes. If you ghost, timer will be decreased to 2 minutes.")) - if(!is_admin_level(src.z)) // Set their queue time now because the client has to actually leave to despawn and at that point the client is lost + if(!should_block_game_interaction(src)) // Set their queue time now because the client has to actually leave to despawn and at that point the client is lost mob.client.player_details.larva_queue_time = max(mob.client.player_details.larva_queue_time, world.time) var/area/location = get_area(src) if(mob.job != GET_MAPPED_ROLE(JOB_SQUAD_MARINE)) @@ -536,6 +536,7 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li icon_state = "body_scanner_open" set_light(0) playsound(src, 'sound/machines/pod_open.ogg', 30) + SEND_SIGNAL(src, COMSIG_CRYOPOD_GO_OUT) #ifdef OBJECTS_PROXY_SPEECH // Transfers speech to occupant @@ -554,3 +555,40 @@ GLOBAL_LIST_INIT(frozen_items, list(SQUAD_MARINE_1 = list(), SQUAD_MARINE_2 = li return move_inside(target) + + +/obj/structure/machinery/cryopod/tutorial + silent_exit = TRUE + +/obj/structure/machinery/cryopod/tutorial/process() + return + +/obj/structure/machinery/cryopod/tutorial/go_in_cryopod(mob/mob, silent = FALSE, del_them = TRUE) + if(occupant) + return + mob.forceMove(src) + occupant = mob + icon_state = "body_scanner_closed" + set_light(2) + time_entered = world.time + if(del_them) + despawn_occupant() + +/obj/structure/machinery/cryopod/tutorial/despawn_occupant() + SSminimaps.remove_marker(occupant) + + if(ishuman(occupant)) + var/mob/living/carbon/human/man = occupant + man.species.handle_cryo(man) + + icon_state = "body_scanner_open" + set_light(0) + + + var/mob/new_player/new_player = new + + if(!occupant.mind) + occupant.mind_initialize() + + occupant.mind.transfer_to(new_player) + SEND_SIGNAL(occupant, COMSIG_MOB_END_TUTORIAL) diff --git a/code/game/machinery/telecomms/machine_interactions.dm b/code/game/machinery/telecomms/machine_interactions.dm index 942d70f80705..e43598c4e248 100644 --- a/code/game/machinery/telecomms/machine_interactions.dm +++ b/code/game/machinery/telecomms/machine_interactions.dm @@ -177,7 +177,7 @@ if(src.listening_level == TELECOMM_GROUND_Z) // equals the station src.listening_level = position.z return 1 - else if(is_admin_level(position.z)) + else if(should_block_game_interaction(position)) src.listening_level = TELECOMM_GROUND_Z return 1 return 0 @@ -229,7 +229,7 @@ /obj/structure/machinery/telecomms/relay/Options_Menu() var/dat = "" - if(is_admin_level(z)) + if(should_block_game_interaction(src)) dat += "
Signal Locked to Station: [listening_level == TELECOMM_GROUND_Z ? "TRUE" : "FALSE"]" dat += "
Broadcasting: [broadcasting ? "YES" : "NO"]" dat += "
Receiving: [receiving ? "YES" : "NO"]" diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 8ea00ce4061d..8b6622121b86 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -98,7 +98,7 @@ var/turf/T = get_turf(R) if (!T) continue - if(is_admin_level(T.z)) + if(should_block_game_interaction(T)) continue var/tmpname = T.loc.name if(areaindex[tmpname]) @@ -118,7 +118,7 @@ continue var/turf/T = get_turf(M) if(T) continue - if(is_admin_level(T.z)) continue + if(should_block_game_interaction(T)) continue var/tmpname = M.real_name if(areaindex[tmpname]) tmpname = "[tmpname] ([++areaindex[tmpname]])" diff --git a/code/game/machinery/vending/cm_vending.dm b/code/game/machinery/vending/cm_vending.dm index 6415e1d0acd5..5568a5fda600 100644 --- a/code/game/machinery/vending/cm_vending.dm +++ b/code/game/machinery/vending/cm_vending.dm @@ -1239,8 +1239,10 @@ GLOBAL_LIST_INIT(cm_vending_gear_corresponding_types_list, list( if(islist(prod_type)) for(var/each_type in prod_type) vendor_successful_vend_one(each_type, user, target_turf, itemspec[4] == MARINE_CAN_BUY_UNIFORM) + SEND_SIGNAL(src, COMSIG_VENDOR_SUCCESSFUL_VEND, src, itemspec, user) else vendor_successful_vend_one(prod_type, user, target_turf, itemspec[4] == MARINE_CAN_BUY_UNIFORM) + SEND_SIGNAL(src, COMSIG_VENDOR_SUCCESSFUL_VEND, src, itemspec, user) if(vend_flags & VEND_LIMITED_INVENTORY) itemspec[2]-- diff --git a/code/game/machinery/vending/vendor_types/food.dm b/code/game/machinery/vending/vendor_types/food.dm index 10e1a035cb0b..62ed5124727e 100644 --- a/code/game/machinery/vending/vendor_types/food.dm +++ b/code/game/machinery/vending/vendor_types/food.dm @@ -25,6 +25,27 @@ list("W-Y Flask", 5, /obj/item/reagent_container/food/drinks/flask/weylandyutani, VENDOR_ITEM_REGULAR) ) +/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial + hackable = FALSE + wrenchable = FALSE + req_access = list(ACCESS_TUTORIAL_LOCKED) + +/obj/structure/machinery/cm_vending/sorted/marine_food/tutorial/populate_product_list(scale) + listed_products = list( + list("PREPARED MEALS", -1, null, null), + list("USCM Prepared Meal (Chicken)", 0, /obj/item/reagent_container/food/snacks/mre_pack/meal5, VENDOR_ITEM_REGULAR), + list("USCM Prepared Meal (Cornbread)", 0, /obj/item/reagent_container/food/snacks/mre_pack/meal1, VENDOR_ITEM_REGULAR), + list("USCM Prepared Meal (Pasta)", 0, /obj/item/reagent_container/food/snacks/mre_pack/meal3, VENDOR_ITEM_REGULAR), + list("USCM Prepared Meal (Pizza)", 0, /obj/item/reagent_container/food/snacks/mre_pack/meal4, VENDOR_ITEM_REGULAR), + list("USCM Prepared Meal (Pork)", 0, /obj/item/reagent_container/food/snacks/mre_pack/meal2, VENDOR_ITEM_REGULAR), + list("USCM Prepared Meal (Tofu)", 0, /obj/item/reagent_container/food/snacks/mre_pack/meal6, VENDOR_ITEM_REGULAR), + list("USCM Protein Bar", 1, /obj/item/reagent_container/food/snacks/protein_pack, VENDOR_ITEM_RECOMMENDED), + list("FLASKS", -1, null, null), + list("Canteen", 0, /obj/item/reagent_container/food/drinks/flask/canteen, VENDOR_ITEM_REGULAR), + list("Metal Flask", 0, /obj/item/reagent_container/food/drinks/flask, VENDOR_ITEM_REGULAR), + list("USCM Flask", 0, /obj/item/reagent_container/food/drinks/flask/marine, VENDOR_ITEM_REGULAR), + list("W-Y Flask", 0, /obj/item/reagent_container/food/drinks/flask/weylandyutani, VENDOR_ITEM_REGULAR) + ) //------------BOOZE-O-MAT VENDOR--------------- /obj/structure/machinery/cm_vending/sorted/boozeomat diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm index 6a770e89984e..e021b6fe0879 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_prep.dm @@ -53,6 +53,34 @@ list("M94 Marking Flare Pack", round(scale * 10), /obj/item/storage/box/m94, VENDOR_ITEM_RECOMMENDED) ) +/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad_prep/tutorial + name = "\improper ColMarTech Automated Weapons Rack" + desc = "An automated weapon rack hooked up to a big storage of standard-issue weapons." + icon_state = "guns" + req_access = list(ACCESS_TUTORIAL_LOCKED) + req_one_access = list() + hackable = FALSE + vend_flags = VEND_CLUTTER_PROTECTION | VEND_LIMITED_INVENTORY | VEND_TO_HAND + +/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad_prep/tutorial/populate_product_list(scale) + listed_products = list( + list("PRIMARY FIREARMS", -1, null, null), + list("M41A Pulse Rifle MK2", 1, /obj/item/weapon/gun/rifle/m41a, VENDOR_ITEM_RECOMMENDED), + + list("PRIMARY AMMUNITION", -1, null, null), + list("M41A Magazine (10x24mm)", 1, /obj/item/ammo_magazine/rifle, VENDOR_ITEM_RECOMMENDED), + ) + +/// Called if the tutorial mob somehow uses an entire magazine without the xeno dying +/obj/structure/machinery/cm_vending/sorted/cargo_guns/squad_prep/tutorial/proc/load_ammo() + listed_products = list( + list("PRIMARY FIREARMS", -1, null, null), + list("M41A Pulse Rifle MK2", 0, /obj/item/weapon/gun/rifle/m41a, VENDOR_ITEM_RECOMMENDED), + + list("PRIMARY AMMUNITION", -1, null, null), + list("M41A Magazine (10x24mm)", 99, /obj/item/ammo_magazine/rifle, VENDOR_ITEM_RECOMMENDED), + ) + //------------SQUAD PREP UNIFORM VENDOR--------------- diff --git a/code/game/machinery/vending/vendor_types/squad_prep/tutorial.dm b/code/game/machinery/vending/vendor_types/squad_prep/tutorial.dm new file mode 100644 index 000000000000..c1cedd85c7fc --- /dev/null +++ b/code/game/machinery/vending/vendor_types/squad_prep/tutorial.dm @@ -0,0 +1,30 @@ +GLOBAL_LIST_INIT(cm_vending_clothing_tutorial, list( + list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), + list("Standard Marine Apparel", 0, list(/obj/item/clothing/under/marine, /obj/item/clothing/shoes/marine/knife, /obj/item/clothing/gloves/marine, /obj/item/clothing/head/helmet/marine), MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_MANDATORY), + + list("ARMOR (CHOOSE 1)", 0, null, null, null), + list("Medium Armor", 0, /obj/item/clothing/suit/storage/marine/medium, MARINE_CAN_BUY_ARMOR, VENDOR_ITEM_REGULAR), + + list("BACKPACK (CHOOSE 1)", 0, null, null, null), + list("Satchel", 0, /obj/item/storage/backpack/marine/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_RECOMMENDED), + + list("BELT (CHOOSE 1)", 0, null, null, null), + list("M276 Ammo Load Rig", 0, /obj/item/storage/belt/marine, MARINE_CAN_BUY_BELT, VENDOR_ITEM_RECOMMENDED), + + list("POUCHES (CHOOSE 1)", 0, null, null, null), + list("Flare Pouch (Full)", 0, /obj/item/storage/pouch/flare/full, MARINE_CAN_BUY_GLASSES, VENDOR_ITEM_RECOMMENDED), + + )) // The pouch uses a different category so they only get one + +/obj/structure/machinery/cm_vending/clothing/tutorial + name = "\improper ColMarTech Automated Marine Equipment Rack" + desc = "An automated rack hooked up to a colossal storage of Marine Rifleman standard-issue equipment." + icon_state = "mar_rack" + show_points = TRUE + vendor_theme = VENDOR_THEME_USCM + req_access = list(ACCESS_TUTORIAL_LOCKED) + + vendor_role = list() + +/obj/structure/machinery/cm_vending/clothing/tutorial/get_listed_products(mob/user) + return GLOB.cm_vending_clothing_tutorial diff --git a/code/game/objects/effects/landmarks/landmarks.dm b/code/game/objects/effects/landmarks/landmarks.dm index 5f4a374ba31c..45cc6fd8b5fa 100644 --- a/code/game/objects/effects/landmarks/landmarks.dm +++ b/code/game/objects/effects/landmarks/landmarks.dm @@ -508,3 +508,7 @@ /// In landmarks.dm and not unit_test.dm so it is always active in the mapping tools. /obj/effect/landmark/unit_test_top_right name = "unit test zone top right" + +/// Marks the bottom left of the tutorial zone. +/obj/effect/landmark/tutorial_bottom_left + name = "tutorial bottom left" diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index ef9fcacf5647..7cb2781b253b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -364,6 +364,7 @@ cases. Override_icon_state should be a list.*/ qdel(src) SEND_SIGNAL(src, COMSIG_ITEM_DROPPED, user) + SEND_SIGNAL(user, COMSIG_MOB_ITEM_DROPPED, src) if(drop_sound && (src.loc?.z)) playsound(src, drop_sound, dropvol, drop_vary) src.do_drop_animation(user) diff --git a/code/game/objects/items/devices/teleportation.dm b/code/game/objects/items/devices/teleportation.dm index 793f399ecdf0..8dea3b872cd1 100644 --- a/code/game/objects/items/devices/teleportation.dm +++ b/code/game/objects/items/devices/teleportation.dm @@ -48,7 +48,7 @@ if (usr.stat || usr.is_mob_restrained()) return var/turf/current_location = get_turf(usr)//What turf is the user on? - if(!current_location || is_admin_level(current_location.z))//If turf was not found or they're on z level 2. + if(!current_location || should_block_game_interaction(current_location))//If turf was not found or they're on z level 2. to_chat(usr, "[src] is malfunctioning.") return if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf)))) @@ -140,7 +140,7 @@ ..() var/turf/current_location = get_turf(user)//What turf is the user on? - if(!current_location || is_admin_level(current_location.z))//If turf was not found or they're on z level 2 + if(!current_location || should_block_game_interaction(current_location))//If turf was not found or they're on z level 2 to_chat(user, SPAN_NOTICE("\The [src] is malfunctioning.")) return var/list/L = list( ) diff --git a/code/game/objects/items/reagent_containers/autoinjectors.dm b/code/game/objects/items/reagent_containers/autoinjectors.dm index 46463e628c1d..04a3a15585ab 100644 --- a/code/game/objects/items/reagent_containers/autoinjectors.dm +++ b/code/game/objects/items/reagent_containers/autoinjectors.dm @@ -139,6 +139,12 @@ item_state = "emptyskill" skilllock = SKILL_MEDICAL_DEFAULT +/obj/item/reagent_container/hypospray/autoinjector/tramadol/skillless/one_use + desc = "An EZ autoinjector loaded with 1 use of Tramadol, a weak but effective painkiller for normal wounds. Doesn't require any training to use." + volume = 15 + amount_per_transfer_from_this = 15 + uses_left = 1 + /obj/item/reagent_container/hypospray/autoinjector/oxycodone name = "oxycodone autoinjector (EXTREME PAINKILLER)" chemname = "oxycodone" @@ -164,6 +170,12 @@ item_state = "emptyskill" skilllock = SKILL_MEDICAL_DEFAULT +/obj/item/reagent_container/hypospray/autoinjector/kelotane/skillless/one_use + desc = "An EZ autoinjector loaded with 1 use of Kelotane, a common burn medicine. Doesn't require any training to use." + volume = 15 + amount_per_transfer_from_this = 15 + uses_left = 1 + /obj/item/reagent_container/hypospray/autoinjector/bicaridine name = "bicaridine autoinjector" chemname = "bicaridine" @@ -180,6 +192,12 @@ item_state = "emptyskill" skilllock = SKILL_MEDICAL_DEFAULT +/obj/item/reagent_container/hypospray/autoinjector/bicaridine/skillless/one_use + desc = "An EZ autoinjector loaded with 1 use of Bicaridine, a common brute and circulatory damage medicine. Doesn't require any training to use." + volume = 15 + amount_per_transfer_from_this = 15 + uses_left = 1 + /obj/item/reagent_container/hypospray/autoinjector/inaprovaline name = "inaprovaline autoinjector" chemname = "inaprovaline" diff --git a/code/game/objects/items/reagent_containers/food/snacks.dm b/code/game/objects/items/reagent_containers/food/snacks.dm index 927501286f13..076a4f77cf01 100644 --- a/code/game/objects/items/reagent_containers/food/snacks.dm +++ b/code/game/objects/items/reagent_containers/food/snacks.dm @@ -21,6 +21,7 @@ //Placeholder for effect that trigger on eating that aren't tied to reagents. /obj/item/reagent_container/food/snacks/proc/On_Consume(mob/M) SEND_SIGNAL(src, COMSIG_SNACK_EATEN, M) + SEND_SIGNAL(M, COMSIG_MOB_EATEN_SNACK, src) if(!usr) return if(!reagents.total_volume) diff --git a/code/game/objects/items/reagent_containers/hypospray.dm b/code/game/objects/items/reagent_containers/hypospray.dm index fcea8997f0b5..5e268d35a33d 100644 --- a/code/game/objects/items/reagent_containers/hypospray.dm +++ b/code/game/objects/items/reagent_containers/hypospray.dm @@ -206,6 +206,7 @@ to_chat(user, SPAN_NOTICE(" You inject [M] with [src].")) to_chat(M, SPAN_WARNING("You feel a tiny prick!")) playsound(loc, injectSFX, injectVOL, 1) + SEND_SIGNAL(M, COMSIG_LIVING_HYPOSPRAY_INJECTED, src) reagents.reaction(M, INGEST) if(M.reagents) diff --git a/code/game/objects/items/shards.dm b/code/game/objects/items/shards.dm index 84c3d5b83427..dab573e6f5a5 100644 --- a/code/game/objects/items/shards.dm +++ b/code/game/objects/items/shards.dm @@ -81,7 +81,7 @@ /obj/item/large_shrapnel/proc/on_embedded_movement(mob/living/embedded_mob) return -/obj/item/large_shrapnel/proc/on_embed(mob/embedded_mob, obj/limb/target_organ) +/obj/item/large_shrapnel/proc/on_embed(mob/embedded_mob, obj/limb/target_organ, silent = FALSE) return /obj/item/large_shrapnel/at_rocket_dud @@ -180,14 +180,14 @@ cell_explosion(get_turf(target), 200, 150, EXPLOSION_FALLOFF_SHAPE_LINEAR, direction, create_cause_data("[cause] UXO detonation", user)) qdel(src) -/obj/item/large_shrapnel/at_rocket_dud/on_embed(mob/embedded_mob, obj/limb/target_organ) +/obj/item/large_shrapnel/at_rocket_dud/on_embed(mob/embedded_mob, obj/limb/target_organ, silent = FALSE) if(!ishuman(embedded_mob)) return var/mob/living/carbon/human/H = embedded_mob if(H.species.flags & NO_SHRAPNEL) return if(istype(target_organ)) - target_organ.embed(src) + target_organ.embed(src, silent) /obj/item/large_shrapnel/at_rocket_dud/on_embedded_movement(mob/living/embedded_mob) if(!ishuman(embedded_mob)) @@ -212,14 +212,14 @@ source_sheet_type = null var/damage_on_move = 0.5 -/obj/item/shard/shrapnel/proc/on_embed(mob/embedded_mob, obj/limb/target_organ) +/obj/item/shard/shrapnel/proc/on_embed(mob/embedded_mob, obj/limb/target_organ, silent = FALSE) if(!ishuman(embedded_mob)) return var/mob/living/carbon/human/H = embedded_mob if(H.species.flags & NO_SHRAPNEL) return if(istype(target_organ)) - target_organ.embed(src) + target_organ.embed(src, silent) /obj/item/shard/shrapnel/proc/on_embedded_movement(mob/living/embedded_mob) if(!ishuman(embedded_mob)) @@ -228,7 +228,7 @@ if(H.species.flags & NO_SHRAPNEL) return var/obj/limb/organ = embedded_organ - if(istype(organ)) + if(istype(organ) && damage_on_move) organ.take_damage(damage_on_move * count, 0, 0, no_limb_loss = TRUE) embedded_mob.pain.apply_pain(damage_on_move * count) @@ -261,3 +261,7 @@ name = "alien bone fragments" icon_state = "alienbonechips" desc = "Sharp, jagged fragments of alien bone. Looks like the previous owner exploded violently..." + +/obj/item/shard/shrapnel/tutorial + damage_on_move = 0 + diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm index f96903cfb687..5434aa006137 100644 --- a/code/game/objects/items/stacks/medical.dm +++ b/code/game/objects/items/stacks/medical.dm @@ -95,6 +95,9 @@ to_chat(user, SPAN_WARNING("There are no wounds on [possessive] [affecting.display_name].")) return TRUE +/obj/item/stack/medical/bruise_pack/two + amount = 2 + /obj/item/stack/medical/ointment name = "ointment" desc = "Used to treat burns, infected wounds, and relieve itching in unusual places." diff --git a/code/game/objects/items/weapons/blades.dm b/code/game/objects/items/weapons/blades.dm index 2fe80f123bce..a2a4aa8db75d 100644 --- a/code/game/objects/items/weapons/blades.dm +++ b/code/game/objects/items/weapons/blades.dm @@ -213,6 +213,8 @@ else INVOKE_ASYNC(embedded_human, TYPE_PROC_REF(/mob, emote), "me", 1, pick("winces.", "grimaces.", "flinches.")) + SEND_SIGNAL(embedded_human, COMSIG_HUMAN_SHRAPNEL_REMOVED) + else to_chat(user, SPAN_NOTICE("You couldn't find any shrapnel.")) diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 069d932d991b..bfc3c579f36c 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -1442,7 +1442,7 @@ GLOBAL_DATUM_INIT(supply_controller, /datum/controller/supply, new()) world.log << "## ERROR: Eek. The supply/elevator datum is missing somehow." return - if(!is_admin_level(SSshuttle.vehicle_elevator.z)) + if(!should_block_game_interaction(SSshuttle.vehicle_elevator)) to_chat(usr, SPAN_WARNING("The elevator needs to be in the cargo bay dock to call a vehicle up. Ask someone to send it away.")) return diff --git a/code/modules/admin/player_panel/actions/general.dm b/code/modules/admin/player_panel/actions/general.dm index a47a42d44cc2..e4ebc9fb85dd 100644 --- a/code/modules/admin/player_panel/actions/general.dm +++ b/code/modules/admin/player_panel/actions/general.dm @@ -68,17 +68,9 @@ message_admins("[key_name_admin(user)] has sent [key_name_admin(target)] back to the Lobby.") - var/mob/new_player/NP = new() - - if(!target.mind) - target.mind_initialize() - - target.mind.transfer_to(NP) - - qdel(target) + target.send_to_lobby() return TRUE - /datum/player_action/force_say action_tag = "mob_force_say" name = "Force Say" diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 300c999b885b..e9587319a160 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -378,6 +378,22 @@ Insert("[icon_name]_big", iconBig) return ..() +/datum/asset/spritesheet/tutorial + name = "tutorial" + +/datum/asset/spritesheet/tutorial/register() + for(var/icon_state in icon_states('icons/misc/tutorial.dmi')) + var/icon/icon_sprite = icon('icons/misc/tutorial.dmi', icon_state) + icon_sprite.Scale(128, 128) + Insert(icon_state, icon_sprite) + + var/icon/retrieved_icon = icon('icons/mob/hud/human_dark.dmi', "intent_all") + retrieved_icon.Scale(128, 128) + Insert("intents", retrieved_icon) + + return ..() + + /datum/asset/spritesheet/gun_lineart name = "gunlineart" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index c11d35451656..29676ddb4ac8 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -239,6 +239,8 @@ GLOBAL_LIST_INIT(bgstate_options, list( /// if this client has tooltips enabled var/tooltips = TRUE + /// A list of tutorials that the client has completed, saved across rounds + var/list/completed_tutorials = list() /// If this client has auto observe enabled, used by /datum/orbit_menu var/auto_observe = TRUE @@ -1995,7 +1997,8 @@ GLOBAL_LIST_INIT(bgstate_options, list( if(!istype(character)) return - find_assigned_slot(job_title, is_late_join) + if(job_title) + find_assigned_slot(job_title, is_late_join) if(check_datacore && !(be_random_body && be_random_name)) for(var/datum/data/record/record as anything in GLOB.data_core.locked) if(record.fields["name"] == real_name) @@ -2302,6 +2305,22 @@ GLOBAL_LIST_INIT(bgstate_options, list( show_browser(user, dat, "Character Traits", "character_traits") update_preview_icon(TRUE) +/// Converts a client's list of completed tutorials into a string for saving +/datum/preferences/proc/tutorial_list_to_savestring() + if(!length(completed_tutorials)) + return "" + + var/return_string = "" + var/last_id = completed_tutorials[length(completed_tutorials)] + for(var/tutorial_id in completed_tutorials) + return_string += tutorial_id + (tutorial_id != last_id ? ";" : "") + return return_string + +/// Converts a saved string of completed tutorials into a list for in-game use +/datum/preferences/proc/tutorial_savestring_to_list(savestring) + completed_tutorials = splittext(savestring, ";") + return completed_tutorials + #undef MENU_MARINE #undef MENU_XENOMORPH #undef MENU_CO diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index c67effe90eb1..2261ddf5ebfa 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -480,6 +480,10 @@ S["uplinklocation"] >> uplinklocation S["exploit_record"] >> exploit_record + var/tutorial_string = "" + S["completed_tutorials"] >> tutorial_string + tutorial_savestring_to_list(tutorial_string) + //Sanitize metadata = sanitize_text(metadata, initial(metadata)) real_name = reject_bad_name(real_name) @@ -625,6 +629,8 @@ S["uplinklocation"] << uplinklocation S["exploit_record"] << exploit_record + S["completed_tutorials"] << tutorial_list_to_savestring() + return 1 /// checks through keybindings for outdated unbound keys and updates them diff --git a/code/modules/cm_marines/marines_consoles.dm b/code/modules/cm_marines/marines_consoles.dm index 994e9f1ddcb2..00a8c442b770 100644 --- a/code/modules/cm_marines/marines_consoles.dm +++ b/code/modules/cm_marines/marines_consoles.dm @@ -819,7 +819,7 @@ GLOBAL_LIST_EMPTY_TYPED(crewmonitor, /datum/crewmonitor) var/turf/pos = get_turf(H) if(!pos) continue - if(is_admin_level(pos.z)) + if(should_block_game_interaction(H)) continue // The entry for this human diff --git a/code/modules/cm_preds/yaut_items.dm b/code/modules/cm_preds/yaut_items.dm index c646d929d9f7..22e1318a7358 100644 --- a/code/modules/cm_preds/yaut_items.dm +++ b/code/modules/cm_preds/yaut_items.dm @@ -3,7 +3,7 @@ //Thrall subtypes are located in /code/modules/cm_preds/thrall_items.dm /proc/add_to_missing_pred_gear(obj/item/W) - if(!is_admin_level(W.z)) + if(!should_block_game_interaction(W)) GLOB.loose_yautja_gear |= W /proc/remove_from_missing_pred_gear(obj/item/W) @@ -393,7 +393,7 @@ var/mob/living/carbon/human/H = user var/ship_to_tele = list("Yautja Ship" = -1, "Human Ship" = "Human") - if(!HAS_TRAIT(H, TRAIT_YAUTJA_TECH) || is_admin_level(H.z)) + if(!HAS_TRAIT(H, TRAIT_YAUTJA_TECH) || should_block_game_interaction(H)) to_chat(user, SPAN_WARNING("You fiddle with it, but nothing happens!")) return diff --git a/code/modules/gear_presets/other.dm b/code/modules/gear_presets/other.dm index 3f773f90520e..d97a032337ee 100644 --- a/code/modules/gear_presets/other.dm +++ b/code/modules/gear_presets/other.dm @@ -952,3 +952,21 @@ new_human.equip_to_slot_or_del(new /obj/item/storage/pouch/tools/tank(new_human), WEAR_R_STORE) //*****************************************************************************************************/ + + +/datum/equipment_preset/tutorial + name = "Tutorial" + faction = FACTION_MARINE + flags = EQUIPMENT_PRESET_EXTRA + faction_group = FACTION_LIST_MARINE + languages = list(LANGUAGE_ENGLISH) + idtype = /obj/item/card/id + /// If the player should start out underfed + var/underfed = TRUE + +/datum/equipment_preset/tutorial/load_status(mob/living/carbon/human/new_human) + if(underfed) + new_human.nutrition = NUTRITION_LOW + +/datum/equipment_preset/tutorial/fed + underfed = FALSE diff --git a/code/modules/gear_presets/uscm.dm b/code/modules/gear_presets/uscm.dm index 7cee0802e479..8289bdfe09cb 100644 --- a/code/modules/gear_presets/uscm.dm +++ b/code/modules/gear_presets/uscm.dm @@ -30,7 +30,7 @@ /datum/equipment_preset/uscm/load_preset(mob/living/carbon/human/new_human, randomise, count_participant) . = ..() - if(!auto_squad_name || (is_admin_level(new_human.z) && !ert_squad)) + if(!auto_squad_name || (should_block_game_interaction(new_human) && !ert_squad)) return if(!GLOB.data_core.manifest_modify(new_human.real_name, WEAKREF(new_human), assignment, rank)) GLOB.data_core.manifest_inject(new_human) diff --git a/code/modules/maptext_alerts/screen_alerts.dm b/code/modules/maptext_alerts/screen_alerts.dm index b096d3b3718f..8e59574ecf1f 100644 --- a/code/modules/maptext_alerts/screen_alerts.dm +++ b/code/modules/maptext_alerts/screen_alerts.dm @@ -64,6 +64,26 @@ style_open = "" style_close = "" +/atom/movable/screen/text/screen_text/command_order/tutorial + letters_per_update = 4 // overall, pretty fast while not immediately popping in + play_delay = 0.1 + fade_out_delay = 2.5 SECONDS + fade_out_time = 0.5 SECONDS + +/atom/movable/screen/text/screen_text/command_order/tutorial/end_play() + if(!player) + qdel(src) + return + + if(player.mob || HAS_TRAIT(player.mob, TRAIT_IN_TUTORIAL)) + return ..() + + for(var/atom/movable/screen/text/screen_text/command_order/tutorial/tutorial_message in player.screen_texts) + LAZYREMOVE(player.screen_texts, tutorial_message) + qdel(tutorial_message) + + return ..() + ///proc for actually playing this screen_text on a mob. /atom/movable/screen/text/screen_text/proc/play_to_client() player?.add_to_screen(src) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 430f959a7718..83bc0c3750f7 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -463,7 +463,7 @@ Works together with spawning an observer, noted above. ghost.langchat_make_image() SStgui.on_transfer(src, ghost) - if(is_admin_level((get_turf(src))?.z)) // Gibbed humans ghostize the brain in their head which itself is z 0 + if(should_block_game_interaction(src)) // Gibbed humans ghostize the brain in their head which itself is z 0 ghost.timeofdeath = 1 // Bypass respawn limit if you die on the admin zlevel ghost.key = key @@ -547,7 +547,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp msg_admin_niche("[key_name_admin(client)] has ghosted. [ADMIN_JMP(location)]") log_game("[key_name_admin(client)] has ghosted.") var/mob/dead/observer/ghost = ghostize((is_nested && nest && !QDELETED(nest))) //FALSE parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3 - if(ghost && !is_admin_level(z)) + SEND_SIGNAL(src, COMSIG_LIVING_GHOSTED, ghost) + if(ghost && !should_block_game_interaction(src)) ghost.timeofdeath = world.time // Larva queue: We use the larger of their existing queue time or the new timeofdeath except for facehuggers or lesser drone diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 26be5e97f9dd..d2e0db929624 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1748,3 +1748,28 @@ // clamped to max 500 if(dizziness > 100 && !is_dizzy) INVOKE_ASYNC(src, PROC_REF(dizzy_process)) + +/proc/setup_human(mob/living/carbon/human/target, mob/new_player/new_player, is_late_join = FALSE) + new_player.spawning = TRUE + new_player.close_spawn_windows() + new_player.client.prefs.copy_all_to(target, new_player.job, is_late_join) + + if(new_player.client.prefs.be_random_body) + var/datum/preferences/rand_prefs = new() + rand_prefs.randomize_appearance(target) + + target.job = new_player.job + target.name = new_player.real_name + target.voice = new_player.real_name + + if(new_player.mind) + new_player.mind_initialize() + new_player.mind.transfer_to(target, TRUE) + new_player.mind.setup_human_stats() + + target.sec_hud_set_ID() + target.hud_set_squad() + + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob/living/carbon/human, regenerate_icons)) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob/living/carbon/human, update_body), 1, 0) + INVOKE_ASYNC(target, TYPE_PROC_REF(/mob/living/carbon/human, update_hair)) diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm index 8f032288065b..f14b023b81da 100644 --- a/code/modules/mob/living/carbon/human/human_attackhand.dm +++ b/code/modules/mob/living/carbon/human/human_attackhand.dm @@ -4,9 +4,11 @@ if(..()) return TRUE + SEND_SIGNAL(attacking_mob, COMSIG_LIVING_ATTACKHAND_HUMAN, src) + if((attacking_mob != src) && check_shields(0, attacking_mob.name)) visible_message(SPAN_DANGER("[attacking_mob] attempted to touch [src]!"), null, null, 5) - return 0 + return FALSE switch(attacking_mob.a_intent) if(INTENT_HELP) diff --git a/code/modules/mob/living/carbon/human/human_dummy.dm b/code/modules/mob/living/carbon/human/human_dummy.dm index 061ac3cea05f..1f90c618fd38 100644 --- a/code/modules/mob/living/carbon/human/human_dummy.dm +++ b/code/modules/mob/living/carbon/human/human_dummy.dm @@ -73,3 +73,12 @@ GLOBAL_LIST_EMPTY(dummy_mob_list) /mob/living/carbon/human/dummy/add_to_all_mob_huds() return + + +/mob/living/carbon/human/dummy/tutorial // Effectively an even more disabled dummy + +/mob/living/carbon/human/dummy/tutorial/Initialize(mapload) + . = ..() + status_flags = GODMODE + ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + anchored = TRUE diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm index e799c21d3f20..9a1dfcb0e9a5 100644 --- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm +++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm @@ -160,7 +160,7 @@ /obj/item/alien_embryo/proc/become_larva() // We do not allow chest bursts on the Centcomm Z-level, to prevent // stranded players from admin experiments and other issues - if(!affected_mob || is_admin_level(affected_mob.z)) + if(!affected_mob || should_block_game_interaction(affected_mob)) return stage = 6 // Increase the stage value to prevent this proc getting repeated diff --git a/code/modules/mob/living/carbon/xenomorph/Evolution.dm b/code/modules/mob/living/carbon/xenomorph/Evolution.dm index a2ade5cd0512..d6f963747e33 100644 --- a/code/modules/mob/living/carbon/xenomorph/Evolution.dm +++ b/code/modules/mob/living/carbon/xenomorph/Evolution.dm @@ -143,7 +143,7 @@ return var/area/xeno_area = get_area(new_xeno) - if(!is_admin_level(new_xeno.z) || (xeno_area.flags_atom & AREA_ALLOW_XENO_JOIN)) + if(!should_block_game_interaction(new_xeno) || (xeno_area.flags_atom & AREA_ALLOW_XENO_JOIN)) switch(new_xeno.tier) //They have evolved, add them to the slot count IF they are in regular game space if(2) hive.tier_2_xenos |= new_xeno diff --git a/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm b/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm index 3160c5e20bc7..0b0efbc0f34f 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm @@ -43,12 +43,12 @@ var/list/possible_xenos = list() for(var/mob/living/carbon/xenomorph/T in GLOB.living_xeno_list) - if (T != X && !is_admin_level(T.z) && X.hivenumber == T.hivenumber) // Can't overwatch yourself, Xenos in Thunderdome, or Xenos in other hives + if (T != X && !should_block_game_interaction(T) && X.hivenumber == T.hivenumber) // Can't overwatch yourself, Xenos in Thunderdome, or Xenos in other hives possible_xenos += T var/mob/living/carbon/xenomorph/selected_xeno = tgui_input_list(X, "Target", "Watch which xenomorph?", possible_xenos, theme="hive_status") - if (!selected_xeno || QDELETED(selected_xeno) || selected_xeno == X.observed_xeno || selected_xeno.stat == DEAD || is_admin_level(selected_xeno.z) || !X.check_state(TRUE)) + if (!selected_xeno || QDELETED(selected_xeno) || selected_xeno == X.observed_xeno || selected_xeno.stat == DEAD || should_block_game_interaction(selected_xeno) || !X.check_state(TRUE)) X.overwatch(X.observed_xeno, TRUE) // Cancel OW else if (!isQueen) // Regular Xeno OW vs Queen X.overwatch(selected_xeno) @@ -177,7 +177,7 @@ var/mob/living/carbon/xenomorph/xenoTarget = locate(href_list[XENO_OVERWATCH_TARGET_HREF]) in GLOB.living_xeno_list var/mob/living/carbon/xenomorph/xenoSrc = locate(href_list[XENO_OVERWATCH_SRC_HREF]) in GLOB.living_xeno_list - if(!istype(xenoTarget) || xenoTarget.stat == DEAD || is_admin_level(xenoTarget.z)) + if(!istype(xenoTarget) || xenoTarget.stat == DEAD || should_block_game_interaction(xenoTarget)) return if(!istype(xenoSrc) || xenoSrc.stat == DEAD) diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index d8f92554c8b3..e924835f5882 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -476,7 +476,7 @@ lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE // Only handle free slots if the xeno is not in tdome - if(hive && !is_admin_level(z)) + if(hive && !should_block_game_interaction(src)) var/selected_caste = GLOB.xeno_datum_list[caste_type]?.type hive.used_slots[selected_caste]++ @@ -1040,7 +1040,7 @@ /mob/living/carbon/xenomorph/ghostize(can_reenter_corpse = TRUE, aghosted = FALSE) . = ..() - if(. && !can_reenter_corpse && stat != DEAD && !QDELETED(src) && !is_admin_level(z)) + if(. && !can_reenter_corpse && stat != DEAD && !QDELETED(src) && !should_block_game_interaction(src)) handle_ghost_message() /mob/living/carbon/xenomorph/proc/handle_ghost_message() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm b/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm index 15797041171f..c4c9b11b37e4 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Drone.dm @@ -73,7 +73,11 @@ icon_xeno = 'icons/mob/xenos/drone.dmi' icon_xenonid = 'icons/mob/xenonids/drone.dmi' - weed_food_icon = 'icons/mob/xenos/weeds_48x48.dmi' weed_food_states = list("Drone_1","Drone_2","Drone_3") weed_food_states_flipped = list("Drone_1","Drone_2","Drone_3") + +/mob/living/carbon/xenomorph/drone/tutorial + +/mob/living/carbon/xenomorph/drone/tutorial/gib(datum/cause_data/cause = create_cause_data("gibbing", src)) + death(cause, 1) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm index 7416b85a13c4..6d082b327b48 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Queen.dm @@ -58,7 +58,7 @@ if(hive.living_xeno_queen.hivenumber == hive.hivenumber) continue for(var/mob/living/carbon/xenomorph/queen/Q in GLOB.living_xeno_list) - if(Q.hivenumber == hive.hivenumber && !is_admin_level(Q.z)) + if(Q.hivenumber == hive.hivenumber && !should_block_game_interaction(Q)) hive.living_xeno_queen = Q xeno_message(SPAN_XENOANNOUNCE("A new Queen has risen to lead the Hive! Rejoice!"),3,hive.hivenumber) continue outer_loop @@ -396,7 +396,7 @@ /mob/living/carbon/xenomorph/queen/Initialize() . = ..() SStracking.set_leader("hive_[hivenumber]", src) - if(!is_admin_level(z))//so admins can safely spawn Queens in Thunderdome for tests. + if(!should_block_game_interaction(src))//so admins can safely spawn Queens in Thunderdome for tests. xeno_message(SPAN_XENOANNOUNCE("A new Queen has risen to lead the Hive! Rejoice!"),3,hivenumber) notify_ghosts(header = "New Queen", message = "A new Queen has risen.", source = src, action = NOTIFY_ORBIT) playsound(loc, 'sound/voice/alien_queen_command.ogg', 75, 0) @@ -502,7 +502,7 @@ if(hive && hive.living_xeno_queen == src) var/mob/living/carbon/xenomorph/queen/next_queen = null for(var/mob/living/carbon/xenomorph/queen/queen in hive.totalXenos) - if(!is_admin_level(queen.z) && queen != src && !QDELETED(queen)) + if(!should_block_game_interaction(queen) && queen != src && !QDELETED(queen)) next_queen = queen break hive.set_living_xeno_queen(next_queen) // either null or a queen diff --git a/code/modules/mob/living/carbon/xenomorph/death.dm b/code/modules/mob/living/carbon/xenomorph/death.dm index ea1e674a1faf..503ca11a7631 100644 --- a/code/modules/mob/living/carbon/xenomorph/death.dm +++ b/code/modules/mob/living/carbon/xenomorph/death.dm @@ -26,7 +26,7 @@ hud_used.alien_plasma_display.icon_state = "power_display_empty" update_icons() - if(!is_admin_level(z)) //so xeno players don't get death messages from admin tests + if(!should_block_game_interaction(src)) //so xeno players don't get death messages from admin tests if(isqueen(src)) var/mob/living/carbon/xenomorph/queen/XQ = src playsound(loc, 'sound/voice/alien_queen_died.ogg', 75, 0) diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status.dm b/code/modules/mob/living/carbon/xenomorph/hive_status.dm index c035dd255ce1..83a90ded4205 100644 --- a/code/modules/mob/living/carbon/xenomorph/hive_status.dm +++ b/code/modules/mob/living/carbon/xenomorph/hive_status.dm @@ -206,7 +206,7 @@ // Can only have one queen. if(isqueen(X)) - if(!living_xeno_queen && !is_admin_level(X.z)) // Don't consider xenos in admin level + if(!living_xeno_queen && !should_block_game_interaction(X)) // Don't consider xenos in admin level set_living_xeno_queen(X) X.hivenumber = hivenumber @@ -218,7 +218,7 @@ X.hud_update() var/area/A = get_area(X) - if(!is_admin_level(X.z) || (A.flags_atom & AREA_ALLOW_XENO_JOIN)) + if(!should_block_game_interaction(X) || (A.flags_atom & AREA_ALLOW_XENO_JOIN)) totalXenos += X if(X.tier == 2) tier_2_xenos += X @@ -241,7 +241,7 @@ if(living_xeno_queen == xeno) var/mob/living/carbon/xenomorph/queen/next_queen = null for(var/mob/living/carbon/xenomorph/queen/queen in totalXenos) - if(!is_admin_level(queen.z) && queen != src && !QDELETED(queen)) + if(!should_block_game_interaction(queen) && queen != src && !QDELETED(queen)) next_queen = queen break @@ -264,7 +264,7 @@ tier_3_xenos -= xeno // Only handle free slots if the xeno is not in tdome - if(!is_admin_level(xeno.z)) + if(!should_block_game_interaction(xeno)) var/selected_caste = GLOB.xeno_datum_list[xeno.caste_type]?.type if(used_slots[selected_caste]) used_slots[selected_caste]-- @@ -408,7 +408,7 @@ for(var/mob/living/carbon/xenomorph/X in totalXenos) //don't show xenos in the thunderdome when admins test stuff. - if(is_admin_level(X.z)) + if(should_block_game_interaction(X)) var/area/A = get_area(X) if(!(A.flags_atom & AREA_ALLOW_XENO_JOIN)) continue @@ -427,7 +427,7 @@ var/index = 1 var/useless_slots = 0 for(var/mob/living/carbon/xenomorph/X in totalXenos) - if(is_admin_level(X.z)) + if(should_block_game_interaction(X)) var/area/A = get_area(X) if(!(A.flags_atom & AREA_ALLOW_XENO_JOIN)) useless_slots++ @@ -509,7 +509,7 @@ var/list/xenos = list() for(var/mob/living/carbon/xenomorph/X in totalXenos) - if(is_admin_level(X.z)) + if(should_block_game_interaction(X)) var/area/A = get_area(X) if(!(A.flags_atom & AREA_ALLOW_XENO_JOIN)) continue @@ -540,7 +540,7 @@ var/list/xenos = list() for(var/mob/living/carbon/xenomorph/X in totalXenos) - if(is_admin_level(X.z)) + if(should_block_game_interaction(X)) var/area/A = get_area(X) if(!(A.flags_atom & AREA_ALLOW_XENO_JOIN)) continue diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm index 4fe1be51bfff..a71ddb7de292 100644 --- a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm +++ b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm @@ -175,7 +175,7 @@ var/mob/living/carbon/xenomorph/xenoTarget = locate(params["target_ref"]) in GLOB.living_xeno_list var/mob/living/carbon/xenomorph/xenoSrc = ui.user - if(QDELETED(xenoTarget) || xenoTarget.stat == DEAD || is_admin_level(xenoTarget.z)) + if(QDELETED(xenoTarget) || xenoTarget.stat == DEAD || should_block_game_interaction(xenoTarget)) return if(xenoSrc.stat == DEAD) @@ -188,7 +188,7 @@ var/mob/living/carbon/xenomorph/xenoTarget = locate(params["target_ref"]) in GLOB.living_xeno_list var/mob/living/carbon/xenomorph/xenoSrc = ui.user - if(QDELETED(xenoTarget) || xenoTarget.stat == DEAD || is_admin_level(xenoTarget.z)) + if(QDELETED(xenoTarget) || xenoTarget.stat == DEAD || should_block_game_interaction(xenoTarget)) return if(xenoSrc.stat == DEAD) @@ -201,7 +201,7 @@ var/mob/living/carbon/xenomorph/xenoTarget = locate(params["target_ref"]) in GLOB.living_xeno_list var/mob/living/carbon/xenomorph/xenoSrc = ui.user - if(QDELETED(xenoTarget) || xenoTarget.stat == DEAD || is_admin_level(xenoTarget.z)) + if(QDELETED(xenoTarget) || xenoTarget.stat == DEAD || should_block_game_interaction(xenoTarget)) return if(xenoSrc.stat == DEAD) diff --git a/code/modules/mob/living/carbon/xenomorph/mark_menu.dm b/code/modules/mob/living/carbon/xenomorph/mark_menu.dm index 5f7c1f8bc8c8..dd63f8a4fa70 100644 --- a/code/modules/mob/living/carbon/xenomorph/mark_menu.dm +++ b/code/modules/mob/living/carbon/xenomorph/mark_menu.dm @@ -180,7 +180,7 @@ var/list/possible_xenos = list() possible_xenos |= FunkTownOhyea for(var/mob/living/carbon/xenomorph/T in GLOB.living_xeno_list) - if (T != X && !is_admin_level(T.z) && X.hivenumber == T.hivenumber) + if (T != X && !should_block_game_interaction(T) && X.hivenumber == T.hivenumber) possible_xenos += T var/mob/living/carbon/xenomorph/selected_xeno = tgui_input_list(X, "Target", "Watch which xenomorph?", possible_xenos, theme="hive_status") @@ -195,7 +195,7 @@ . = TRUE update_all_data() return - if (!selected_xeno || QDELETED(selected_xeno) || selected_xeno.stat == DEAD || is_admin_level(selected_xeno.z) || !X.check_state(1)) + if (!selected_xeno || QDELETED(selected_xeno) || selected_xeno.stat == DEAD || should_block_game_interaction(selected_xeno) || !X.check_state(1)) return else selected_xeno.stop_tracking_resin_mark(FALSE, TRUE) diff --git a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm index 7ecaab1c3e79..abb044d474e8 100644 --- a/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm +++ b/code/modules/mob/living/silicon/ai/freelook/update_triggers.dm @@ -1,5 +1,3 @@ -#define BORG_CAMERA_BUFFER 5 - //UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update. // TURFS @@ -66,10 +64,9 @@ if(src.camera && src.camera.network.len) if(!updating) updating = 1 - spawn(BORG_CAMERA_BUFFER) - if(oldLoc != src.loc) - GLOB.cameranet.updatePortableCamera(src.camera) - updating = 0 + if(oldLoc != src.loc) + GLOB.cameranet.updatePortableCamera(src.camera) + updating = 0 /mob/living/carbon/human/var/updating = 0 @@ -83,10 +80,9 @@ if (updating) continue updating = TRUE - spawn(BORG_CAMERA_BUFFER) - if (oldLoc != loc) - GLOB.cameranet.updatePortableCamera(H.camera) - updating = FALSE + if (oldLoc != loc) + GLOB.cameranet.updatePortableCamera(H.camera) + updating = FALSE // CAMERA @@ -114,4 +110,3 @@ GLOB.cameranet.removeCamera(src) . = ..() -//#undef BORG_CAMERA_BUFFER diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 2ed1ee5e126c..5785197fdcd6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -463,6 +463,7 @@ /mob/proc/swap_hand() hand = !hand + SEND_SIGNAL(src, COMSIG_MOB_SWAPPED_HAND) //attempt to pull/grab something. Returns true upon success. /mob/proc/start_pulling(atom/movable/AM, lunge, no_msg) @@ -989,6 +990,7 @@ note dizziness decrements automatically in the mob's Life() proc. /// Adds this list to the output to the stat browser /mob/proc/get_status_tab_items() . = list() + SEND_SIGNAL(src, COMSIG_MOB_GET_STATUS_TAB_ITEMS, .) /mob/proc/get_role_name() return @@ -1056,3 +1058,14 @@ note dizziness decrements automatically in the mob's Life() proc. /mob/proc/update_stat() return + +/// Send src back to the lobby as a `/mob/new_player()` +/mob/proc/send_to_lobby() + var/mob/new_player/new_player = new + + if(!mind) + mind_initialize() + + mind.transfer_to(new_player) + + qdel(src) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index f0e5bc48a855..f7f062295778 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -174,7 +174,7 @@ mouse_drag_pointer = MOUSE_ACTIVE_POINTER - var/status_flags = CANKNOCKDOWN|CANPUSH|STATUS_FLAGS_DEBILITATE //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc) + var/status_flags = DEFAULT_MOB_STATUS_FLAGS //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc) var/area/lastarea = null var/obj/control_object //Used by admins to possess objects. All mobs should have this var diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index e918a00b0984..b9c5dd12a8aa 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -87,6 +87,10 @@ ADD_TRAIT(victim, TRAIT_FLOORED, CHOKEHOLD_TRAIT) /obj/item/grab/proc/progress_passive(mob/living/carbon/human/user, mob/living/victim) + if(SEND_SIGNAL(victim, COMSIG_MOB_AGGRESSIVELY_GRABBED, user) & COMSIG_MOB_AGGRESIVE_GRAB_CANCEL) + to_chat(user, SPAN_WARNING("You can't grab [victim] aggressively!")) + return + user.grab_level = GRAB_AGGRESSIVE playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 25, 1, 7) user.visible_message(SPAN_WARNING("[user] has grabbed [victim] aggressively!"), null, null, 5) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 6abe12eee9b1..693eebabcb99 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -308,6 +308,8 @@ GLOBAL_LIST_INIT(limb_types_by_name, list( if(hud_used && hud_used.action_intent) hud_used.action_intent.icon_state = "intent_[intent_text(a_intent)]" + SEND_SIGNAL(src, COMSIG_MOB_INTENT_CHANGE, a_intent) + /mob/proc/is_mob_restrained() return diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 5e997db240c0..ccf649fb0509 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -42,6 +42,7 @@ var/output = "
Welcome," output +="
[(client.prefs && client.prefs.real_name) ? client.prefs.real_name : client.key]" output +="
[xeno_text]" + output += "

Tutorial

" output += "

Setup Character

" output += "

View Playtimes

" @@ -63,7 +64,7 @@ output += "
" if (refresh) close_browser(src, "playersetup") - show_browser(src, output, null, "playersetup", "size=240x[round_start ? 360 : 460];can_close=0;can_minimize=0") + show_browser(src, output, null, "playersetup", "size=240x[round_start ? 500 : 610];can_close=0;can_minimize=0") return /mob/new_player/Topic(href, href_list[]) @@ -162,6 +163,11 @@ to_chat(src, SPAN_WARNING("Sorry, you cannot late join during [SSticker.mode.name]. You have to start at the beginning of the round. You may observe or try to join as an alien, if possible.")) return + if(client.player_data?.playtime_loaded && (client.get_total_human_playtime() < CONFIG_GET(number/notify_new_player_age)) && !length(client.prefs.completed_tutorials)) + if(tgui_alert(src, "You have little playtime and haven't completed any tutorials. Would you like to go to the tutorial menu?", "Tutorial", list("Yes", "No")) == "Yes") + tutorial_menu() + return + if(client.prefs.species != "Human") if(!is_alien_whitelisted(src, client.prefs.species) && CONFIG_GET(flag/usealienwhitelist)) to_chat(src, "You are currently not whitelisted to play [client.prefs.species].") @@ -224,9 +230,28 @@ AttemptLateSpawn(href_list["job_selected"]) return + if("tutorial") + tutorial_menu() + else new_player_panel() +/mob/new_player/proc/tutorial_menu() + if(SSticker.current_state <= GAME_STATE_SETTING_UP) + to_chat(src, SPAN_WARNING("Please wait for the round to start before entering a tutorial.")) + return + + if(SSticker.current_state == GAME_STATE_FINISHED) + to_chat(src, SPAN_WARNING("The round has ended. Please wait for the next round to enter a tutorial.")) + return + + if(SSticker.tutorial_disabled) + to_chat(src, SPAN_WARNING("Tutorials are currently disabled because something broke, sorry!")) + return + + var/datum/tutorial_menu/menu = new(src) + menu.ui_interact(src) + /mob/new_player/proc/AttemptLateSpawn(rank) var/datum/job/player_rank = GLOB.RoleAuthority.roles_for_mode[rank] if (src != usr) @@ -280,7 +305,7 @@ var/client/client = character.client if(client.player_data && client.player_data.playtime_loaded && length(client.player_data.playtimes) == 0) msg_admin_niche("NEW PLAYER: [key_name(character, 1, 1, 0)]. IP: [character.lastKnownIP], CID: [character.computer_id]") - if(client.player_data && client.player_data.playtime_loaded && ((round(client.get_total_human_playtime() DECISECONDS_TO_HOURS, 0.1)) <= 5)) + if(client.player_data && client.player_data.playtime_loaded && ((round(client.get_total_human_playtime() DECISECONDS_TO_HOURS, 0.1)) <= CONFIG_GET(number/notify_new_player_age))) msg_sea("NEW PLAYER: [key_name(character, 0, 1, 0)] only has [(round(client.get_total_human_playtime() DECISECONDS_TO_HOURS, 0.1))] hours as a human. Current role: [get_actual_job_name(character)] - Current location: [get_area(character)]") character.client.init_verbs() @@ -370,30 +395,8 @@ new_character.lastarea = get_area(loc) - client.prefs.copy_all_to(new_character, job, is_late_join) - - if (client.prefs.be_random_body) - var/datum/preferences/TP = new() - TP.randomize_appearance(new_character) - - if(mind) - mind_initialize() - mind.active = 0 //we wish to transfer the key manually - mind.original = new_character - mind.transfer_to(new_character) //won't transfer key since the mind is not active - mind.setup_human_stats() - - new_character.job = job - new_character.name = real_name - new_character.voice = real_name - - // Update the character icons - // This is done in set_species when the mob is created as well, but - INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, regenerate_icons)) - INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, update_body), 1, 0) - INVOKE_ASYNC(new_character, TYPE_PROC_REF(/mob/living/carbon/human, update_hair)) + setup_human(new_character, src, is_late_join) - new_character.key = key //Manually transfer the key to log them in new_character.client?.change_view(GLOB.world_view_size) return new_character diff --git a/code/modules/organs/limbs.dm b/code/modules/organs/limbs.dm index 8df96650ac50..718aba208f5a 100644 --- a/code/modules/organs/limbs.dm +++ b/code/modules/organs/limbs.dm @@ -547,6 +547,7 @@ This function completely restores a damaged organ to perfect condition. /obj/limb/proc/remove_all_bleeding(external = FALSE, internal = FALSE) + SEND_SIGNAL(src, COMSIG_LIMB_STOP_BLEEDING, external, internal) if(external) for(var/datum/effects/bleeding/external/B in bleeding_effects_list) qdel(B) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index c41a57f53527..3a444e1ad1fc 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -843,6 +843,7 @@ User can be passed as null, (a gun reloading itself for instance), so we need to to_chat(user, SPAN_WARNING("Your reload was interrupted!")) return replace_magazine(user, magazine) + SEND_SIGNAL(user, COMSIG_MOB_RELOADED_GUN, src) else current_mag = magazine magazine.forceMove(src) @@ -1048,6 +1049,7 @@ and you're good to go. user.swap_hand() unload(user, TRUE, drop_to_ground) // We want to quickly autoeject the magazine. This proc does the rest based on magazine type. User can be passed as null. playsound(src, empty_sound, 25, 1) + SEND_SIGNAL(user, COMSIG_MOB_GUN_EMPTY, src) else // Just fired a chambered bullet with no magazine in the gun update_icon() diff --git a/colonialmarines.dme b/colonialmarines.dme index ca8e80ef5067..814674c57f06 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -78,6 +78,7 @@ #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\minimap.dm" #include "code\__DEFINES\misc.dm" +#include "code\__DEFINES\mob.dm" #include "code\__DEFINES\mob_hud.dm" #include "code\__DEFINES\mobs.dm" #include "code\__DEFINES\mode.dm" @@ -111,6 +112,7 @@ #include "code\__DEFINES\tgui.dm" #include "code\__DEFINES\traits.dm" #include "code\__DEFINES\turf_flags.dm" +#include "code\__DEFINES\tutorial.dm" #include "code\__DEFINES\unit_tests.dm" #include "code\__DEFINES\urls.dm" #include "code\__DEFINES\vehicle.dm" @@ -403,6 +405,7 @@ #include "code\datums\components\rename.dm" #include "code\datums\components\speed_modifier.dm" #include "code\datums\components\toxin_buildup.dm" +#include "code\datums\components\tutorial_status.dm" #include "code\datums\components\weed_damage_reduction.dm" #include "code\datums\components\weed_food.dm" #include "code\datums\components\autofire\_automated_fire.dm" @@ -663,6 +666,15 @@ #include "code\datums\supply_packs\spec_ammo.dm" #include "code\datums\supply_packs\vehicle_ammo.dm" #include "code\datums\supply_packs\weapons.dm" +#include "code\datums\tutorial\_tutorial.dm" +#include "code\datums\tutorial\_tutorial_menu.dm" +#include "code\datums\tutorial\tutorial_example.dm" +#include "code\datums\tutorial\marine\_marine.dm" +#include "code\datums\tutorial\marine\basic_marine.dm" +#include "code\datums\tutorial\marine\medical_basic.dm" +#include "code\datums\tutorial\ss13\_ss13.dm" +#include "code\datums\tutorial\ss13\basic_ss13.dm" +#include "code\datums\tutorial\ss13\intents.dm" #include "code\datums\weather\weather_event.dm" #include "code\datums\weather\weather_map_holder.dm" #include "code\datums\weather\weather_events\big_red.dm" @@ -972,6 +984,7 @@ #include "code\game\machinery\vending\vendor_types\squad_prep\squad_smartgunner.dm" #include "code\game\machinery\vending\vendor_types\squad_prep\squad_specialist.dm" #include "code\game\machinery\vending\vendor_types\squad_prep\squad_tl.dm" +#include "code\game\machinery\vending\vendor_types\squad_prep\tutorial.dm" #include "code\game\objects\empulse.dm" #include "code\game\objects\explosion.dm" #include "code\game\objects\explosion_recursive.dm" diff --git a/icons/misc/tutorial.dmi b/icons/misc/tutorial.dmi new file mode 100644 index 0000000000000000000000000000000000000000..d4a4e65963bae84566e373354e0fe2535b60bebc GIT binary patch literal 938 zcmV;b16BNqP)A|G{004JLA3P`!=BJhIv6#4xhgm5AKsqoE7$rG8RU|4vU~7{{QgR~~2x47D zjErpA+3@`Q{0ImW1_%u;EiEi7D>pSYWkoHpf=+m2M{id+Nk~YPaz=w+K*q+kpP-5l z4;~Q_5e*Fu9UUDuHa1dHQcO%tBqSsp9307#Jox|s00DGTPE!Ct=GbNc0044&R9JLG zWpiV4X>fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TB zGg33tGfE(w;*!LYR3K9+H?b%)FI9<)GbOXA7${)K#hF%=n41b=!<7{m8ye$Mq^#iT z=K{7I01MS5Z(0qL_W%F_AW1|)R7i=PREu)jFc8$sk=ukMZCpf&SeaDFiwjV{guDqd>gp(UXZTwYyYUH`bG1Q4k_phKka^8hkMc@zD@b3+wj-11{8 z1v81F-%&I%L<-}Urv#XpVn;NY8frt!Q#3Q!F#%5sv^=#U7(>-R2}zvdiCx^x0}43D zIagsADxMFW<|IXMnr5k=v%Wxa$GI?aHlIl&IKL}8JbXJ80Kpic5O)P^VVN|u`}zIM z$Y#~ez@dux>nv`5^(<(sA#iXYn^i}^E$})xa4umB*AplomZiwW98WIFwe1VA zvSb#mlxU&#i!N3bLje<)_#RgMcn@v4N3VciNDzwIF(^b literal 0 HcmV?d00001 diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi index 8b525fd568d68530afa65fc0f304825857e600cd..c8bf32b00b40b7efdb62aa216bf501c068db2792 100644 GIT binary patch delta 4454 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 tVBwGL{qiPgPefqB=~!`LLf!ghrO$PJMRf { + const { data, act } = useBackend(context); + const { tutorial_categories, completed_tutorials } = data; + const [chosenTutorial, setTutorial] = useLocalState( + context, + 'tutorial', + null + ); + const [categoryIndex, setCategoryIndex] = useLocalState( + context, + 'category_index', + 'Space Station 13' + ); + return ( + + + + + + + {tutorial_categories.map((item, key) => ( + { + setCategoryIndex(item.name); + }}> + {item.name} + + ))} + + + + + +
+ {tutorial_categories.map( + (tutorial_category) => + tutorial_category.name === categoryIndex && + tutorial_category.tutorials.map((tutorial) => ( +
+ +
+ )) + )} +
+
+ + +
+ {chosenTutorial !== null ? ( + + +
+ + + +
+
+ {chosenTutorial.description} + {completed_tutorials.indexOf(chosenTutorial.id) === -1 ? ( +
+ ) : ( + + Tutorial has been completed. + + )} + +
+
+
+
+
+
+ ); +}; From d7feab9569e83acb54a66c77b102d50de4ea5a1c Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 18:04:48 +0000 Subject: [PATCH 23/99] Automatic changelog for PR #5030 [ci skip] --- html/changelogs/AutoChangeLog-pr-5030.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5030.yml diff --git a/html/changelogs/AutoChangeLog-pr-5030.yml b/html/changelogs/AutoChangeLog-pr-5030.yml new file mode 100644 index 000000000000..0cce25ff019a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5030.yml @@ -0,0 +1,4 @@ +author: "Zonespace27" +delete-after: True +changes: + - rscadd: "Added a tutorial system for various roles (and just general information), find it in the lobby screen." \ No newline at end of file From 0ff2e6f1bb00d03b3d1f417849c3df724f7634d0 Mon Sep 17 00:00:00 2001 From: Cthulhu80 <122310258+Cthulhu80@users.noreply.github.com> Date: Fri, 29 Dec 2023 11:13:51 -0800 Subject: [PATCH 24/99] Fixes immobilized mobs being able to buckle onto chairs (#5317) # About the pull request #5277, fixes the issue outlined here, incapacitated marines should not be able to buckle themselves. # Explain why it's good for the game bug bad # Changelog :cl: fix: fixes immobilized mobs being able to buckle themselves /:cl: --- code/game/objects/objs.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index cc9f1fe53fea..7747a45ed9da 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -278,6 +278,11 @@ if (iszombie(user)) return + // mobs that become immobilized should not be able to buckle themselves. + if(M == user && HAS_TRAIT(user, TRAIT_IMMOBILIZED)) + to_chat(user, SPAN_WARNING("You are unable to do this in your current state.")) + return + if(density) density = FALSE if(!step(M, get_dir(M, src)) && loc != M.loc) From 68ccb744450d397030e494751cf258b3208309d0 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 19:21:35 +0000 Subject: [PATCH 25/99] Automatic changelog for PR #5317 [ci skip] --- html/changelogs/AutoChangeLog-pr-5317.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5317.yml diff --git a/html/changelogs/AutoChangeLog-pr-5317.yml b/html/changelogs/AutoChangeLog-pr-5317.yml new file mode 100644 index 000000000000..b5f7cd72accb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5317.yml @@ -0,0 +1,4 @@ +author: "Cthulhu80" +delete-after: True +changes: + - bugfix: "fixes immobilized mobs being able to buckle themselves" \ No newline at end of file From adb5b8e46a8bb488be2a952db5ca1e24c15b7345 Mon Sep 17 00:00:00 2001 From: Paul Mullen <101871009+mullenpaul@users.noreply.github.com> Date: Fri, 29 Dec 2023 19:31:51 +0000 Subject: [PATCH 26/99] migrated js components to jsx (#5307) # About the pull request First round of refactors for TGUI-5 migration. Here all TGUI interfaces and components have been changed from .js to .jsx. This is to closer align us to the standards of tgstation. Within the components themselves there are no functional changes. Files of interest: - tgui/webpack.config.js - tgui/packages/tgui/routes.jsx - tgui/packages/tgui/interfaces/Filteriffic.jsx - tgui/packages/tgui/debug/KitchenSink.jsx The rest of the file changes should just be .js -> .jsx # Explain why it's good for the game Groundwork prep for TGUI 5 # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: refactor: tgui js components now jsx /:cl: --- tgui/packages/tgui/components/{Blink.js => Blink.jsx} | 0 .../tgui/components/{BlockQuote.js => BlockQuote.jsx} | 0 tgui/packages/tgui/components/{Button.js => Button.jsx} | 0 tgui/packages/tgui/components/{ByondUi.js => ByondUi.jsx} | 0 tgui/packages/tgui/components/{Chart.js => Chart.jsx} | 0 .../tgui/components/{Collapsible.js => Collapsible.jsx} | 0 tgui/packages/tgui/components/{ColorBox.js => ColorBox.jsx} | 0 tgui/packages/tgui/components/{Dimmer.js => Dimmer.jsx} | 0 tgui/packages/tgui/components/{Divider.js => Divider.jsx} | 0 .../components/{DraggableControl.js => DraggableControl.jsx} | 0 tgui/packages/tgui/components/{Dropdown.js => Dropdown.jsx} | 0 tgui/packages/tgui/components/{Grid.js => Grid.jsx} | 0 tgui/packages/tgui/components/{Icon.js => Icon.jsx} | 0 .../tgui/components/{InfinitePlane.js => InfinitePlane.jsx} | 0 tgui/packages/tgui/components/{Input.js => Input.jsx} | 0 tgui/packages/tgui/components/{Knob.js => Knob.jsx} | 0 .../components/{LabeledControls.js => LabeledControls.jsx} | 0 tgui/packages/tgui/components/{Modal.js => Modal.jsx} | 0 tgui/packages/tgui/components/{NoticeBox.js => NoticeBox.jsx} | 0 .../tgui/components/{NumberInput.js => NumberInput.jsx} | 0 .../tgui/components/{ProgressBar.js => ProgressBar.jsx} | 0 .../components/{RestrictedInput.js => RestrictedInput.jsx} | 0 .../tgui/components/{RoundGauge.js => RoundGauge.jsx} | 0 tgui/packages/tgui/components/{Slider.js => Slider.jsx} | 0 tgui/packages/tgui/components/{Table.js => Table.jsx} | 0 tgui/packages/tgui/components/{Tabs.js => Tabs.jsx} | 0 tgui/packages/tgui/components/{TextArea.js => TextArea.jsx} | 0 .../tgui/components/{TimeDisplay.js => TimeDisplay.jsx} | 0 tgui/packages/tgui/components/{index.js => index.jsx} | 0 tgui/packages/tgui/debug/{KitchenSink.js => KitchenSink.jsx} | 2 +- tgui/packages/tgui/interfaces/{AcidVest.js => AcidVest.jsx} | 0 .../tgui/interfaces/{AlmayerControl.js => AlmayerControl.jsx} | 0 .../{AltitudeControlConsole.js => AltitudeControlConsole.jsx} | 0 .../tgui/interfaces/{AntiAirConsole.js => AntiAirConsole.jsx} | 0 tgui/packages/tgui/interfaces/{Apc.js => Apc.jsx} | 0 .../tgui/interfaces/{AresInterface.js => AresInterface.jsx} | 0 .../tgui/interfaces/{Autodispenser.js => Autodispenser.jsx} | 0 tgui/packages/tgui/interfaces/{Autolathe.js => Autolathe.jsx} | 0 .../tgui/interfaces/{Binoculars.js => Binoculars.jsx} | 0 .../{BioSyntheticPrinter.js => BioSyntheticPrinter.jsx} | 0 .../tgui/interfaces/{BotanyEditor.js => BotanyEditor.jsx} | 0 .../interfaces/{BotanyExtractor.js => BotanyExtractor.jsx} | 0 tgui/packages/tgui/interfaces/{BrigCell.js => BrigCell.jsx} | 0 .../tgui/interfaces/{CameraConsole.js => CameraConsole.jsx} | 0 .../tgui/interfaces/{CanvasLayer.js => CanvasLayer.jsx} | 0 tgui/packages/tgui/interfaces/{CardMod.js => CardMod.jsx} | 0 .../tgui/interfaces/{Centrifuge.js => Centrifuge.jsx} | 0 tgui/packages/tgui/interfaces/{Changelog.js => Changelog.jsx} | 0 .../tgui/interfaces/{ChemDispenser.js => ChemDispenser.jsx} | 0 .../tgui/interfaces/{ChooseFruit.js => ChooseFruit.jsx} | 0 .../tgui/interfaces/{ChooseResin.js => ChooseResin.jsx} | 0 .../tgui/interfaces/{CommandTablet.js => CommandTablet.jsx} | 0 .../tgui/interfaces/{CrewConsole.js => CrewConsole.jsx} | 0 tgui/packages/tgui/interfaces/{Cryo.js => Cryo.jsx} | 0 tgui/packages/tgui/interfaces/{DemoSim.js => DemoSim.jsx} | 0 tgui/packages/tgui/interfaces/{Disposals.js => Disposals.jsx} | 0 tgui/packages/tgui/interfaces/{DrawnMap.js => DrawnMap.jsx} | 0 .../tgui/interfaces/{FaxMachine.js => FaxMachine.jsx} | 0 .../tgui/interfaces/{Filteriffic.js => Filteriffic.jsx} | 2 +- .../{FiltrationControl.js => FiltrationControl.jsx} | 0 .../tgui/interfaces/{HealthScan.js => HealthScan.jsx} | 0 .../tgui/interfaces/{HiveFaction.js => HiveFaction.jsx} | 0 .../tgui/interfaces/{HiveLeaders.js => HiveLeaders.jsx} | 0 .../tgui/interfaces/{HiveStatus.js => HiveStatus.jsx} | 0 tgui/packages/tgui/interfaces/{KeyBinds.js => KeyBinds.jsx} | 0 tgui/packages/tgui/interfaces/{KillPanel.js => KillPanel.jsx} | 0 .../tgui/interfaces/{LanguageMenu.js => LanguageMenu.jsx} | 0 tgui/packages/tgui/interfaces/{ListInput.js => ListInput.jsx} | 0 .../tgui/interfaces/{MedalsPanel.js => MedalsPanel.jsx} | 0 tgui/packages/tgui/interfaces/{Mortar.js => Mortar.jsx} | 0 .../tgui/interfaces/{NuclearBomb.js => NuclearBomb.jsx} | 0 .../{OrbitalCannonConsole.js => OrbitalCannonConsole.jsx} | 0 .../interfaces/{OverwatchConsole.js => OverwatchConsole.jsx} | 0 .../tgui/interfaces/{PartFabricator.js => PartFabricator.jsx} | 0 tgui/packages/tgui/interfaces/{PhoneMenu.js => PhoneMenu.jsx} | 0 .../tgui/interfaces/{PlayerPanel.js => PlayerPanel.jsx} | 0 .../tgui/interfaces/{PodLauncher.js => PodLauncher.jsx} | 0 tgui/packages/tgui/interfaces/{Proximity.js => Proximity.jsx} | 0 tgui/packages/tgui/interfaces/{Radio.js => Radio.jsx} | 0 .../{ResearchDoorDisplay.js => ResearchDoorDisplay.jsx} | 0 .../interfaces/{ResearchMemories.js => ResearchMemories.jsx} | 0 tgui/packages/tgui/interfaces/{STUI.js => STUI.jsx} | 0 .../{SelfDestructConsole.js => SelfDestructConsole.jsx} | 0 .../tgui/interfaces/{Sentencing.js => Sentencing.jsx} | 0 tgui/packages/tgui/interfaces/{Signaller.js => Signaller.jsx} | 0 .../tgui/interfaces/{SkillsMenu.js => SkillsMenu.jsx} | 0 tgui/packages/tgui/interfaces/{Sleeper.js => Sleeper.jsx} | 0 tgui/packages/tgui/interfaces/{Smes.js => Smes.jsx} | 0 tgui/packages/tgui/interfaces/{SquadMod.js => SquadMod.jsx} | 0 .../{StatbrowserOptions.js => StatbrowserOptions.jsx} | 0 .../{StationAlertConsole.js => StationAlertConsole.jsx} | 0 .../{SupplyDropConsole.js => SupplyDropConsole.jsx} | 0 .../interfaces/{TacmapAdminPanel.js => TacmapAdminPanel.jsx} | 0 tgui/packages/tgui/interfaces/{Tank.js => Tank.jsx} | 0 .../tgui/interfaces/{TechControl.js => TechControl.jsx} | 0 .../tgui/interfaces/{TechMemories.js => TechMemories.jsx} | 0 tgui/packages/tgui/interfaces/{TechNode.js => TechNode.jsx} | 0 .../{TeleporterConsole.js => TeleporterConsole.jsx} | 0 tgui/packages/tgui/interfaces/{Timer.js => Timer.jsx} | 0 .../tgui/interfaces/{VehicleStatus.js => VehicleStatus.jsx} | 0 tgui/packages/tgui/interfaces/{VoteMenu.js => VoteMenu.jsx} | 0 tgui/packages/tgui/interfaces/{VoxPanel.js => VoxPanel.jsx} | 0 .../tgui/interfaces/{WeaponStats.js => WeaponStats.jsx} | 0 tgui/packages/tgui/interfaces/{Wires.js => Wires.jsx} | 0 .../tgui/interfaces/{WorkingJoe.js => WorkingJoe.jsx} | 0 .../tgui/interfaces/common/{AccessList.js => AccessList.jsx} | 0 .../common/{BeakerContents.js => BeakerContents.jsx} | 0 .../{InterfaceLockNoticeBox.js => InterfaceLockNoticeBox.jsx} | 0 tgui/packages/tgui/layouts/{Layout.js => Layout.jsx} | 0 tgui/packages/tgui/layouts/{NtosWindow.js => NtosWindow.jsx} | 0 tgui/packages/tgui/layouts/{Pane.js => Pane.jsx} | 0 tgui/packages/tgui/layouts/{Window.js => Window.jsx} | 0 tgui/packages/tgui/{routes.js => routes.jsx} | 1 + .../tgui/stories/{Blink.stories.js => Blink.stories.jsx} | 0 .../stories/{BlockQuote.stories.js => BlockQuote.stories.jsx} | 0 .../packages/tgui/stories/{Box.stories.js => Box.stories.jsx} | 0 .../tgui/stories/{Button.stories.js => Button.stories.jsx} | 0 .../tgui/stories/{ByondUi.stories.js => ByondUi.stories.jsx} | 0 .../{Collapsible.stories.js => Collapsible.stories.jsx} | 0 .../tgui/stories/{Flex.stories.js => Flex.stories.jsx} | 0 .../tgui/stories/{Input.stories.js => Input.stories.jsx} | 0 .../{LabeledList.stories.js => LabeledList.stories.jsx} | 0 .../tgui/stories/{Popper.stories.js => Popper.stories.jsx} | 0 .../{ProgressBar.stories.js => ProgressBar.stories.jsx} | 0 .../tgui/stories/{Stack.stories.js => Stack.stories.jsx} | 0 .../tgui/stories/{Storage.stories.js => Storage.stories.jsx} | 0 .../tgui/stories/{Tabs.stories.js => Tabs.stories.jsx} | 0 .../tgui/stories/{Themes.stories.js => Themes.stories.jsx} | 0 .../tgui/stories/{Tooltip.stories.js => Tooltip.stories.jsx} | 0 tgui/packages/tgui/stories/{common.js => common.jsx} | 0 tgui/webpack.config.js | 4 ++-- 131 files changed, 5 insertions(+), 4 deletions(-) rename tgui/packages/tgui/components/{Blink.js => Blink.jsx} (100%) rename tgui/packages/tgui/components/{BlockQuote.js => BlockQuote.jsx} (100%) rename tgui/packages/tgui/components/{Button.js => Button.jsx} (100%) rename tgui/packages/tgui/components/{ByondUi.js => ByondUi.jsx} (100%) rename tgui/packages/tgui/components/{Chart.js => Chart.jsx} (100%) rename tgui/packages/tgui/components/{Collapsible.js => Collapsible.jsx} (100%) rename tgui/packages/tgui/components/{ColorBox.js => ColorBox.jsx} (100%) rename tgui/packages/tgui/components/{Dimmer.js => Dimmer.jsx} (100%) rename tgui/packages/tgui/components/{Divider.js => Divider.jsx} (100%) rename tgui/packages/tgui/components/{DraggableControl.js => DraggableControl.jsx} (100%) rename tgui/packages/tgui/components/{Dropdown.js => Dropdown.jsx} (100%) rename tgui/packages/tgui/components/{Grid.js => Grid.jsx} (100%) rename tgui/packages/tgui/components/{Icon.js => Icon.jsx} (100%) rename tgui/packages/tgui/components/{InfinitePlane.js => InfinitePlane.jsx} (100%) rename tgui/packages/tgui/components/{Input.js => Input.jsx} (100%) rename tgui/packages/tgui/components/{Knob.js => Knob.jsx} (100%) rename tgui/packages/tgui/components/{LabeledControls.js => LabeledControls.jsx} (100%) rename tgui/packages/tgui/components/{Modal.js => Modal.jsx} (100%) rename tgui/packages/tgui/components/{NoticeBox.js => NoticeBox.jsx} (100%) rename tgui/packages/tgui/components/{NumberInput.js => NumberInput.jsx} (100%) rename tgui/packages/tgui/components/{ProgressBar.js => ProgressBar.jsx} (100%) rename tgui/packages/tgui/components/{RestrictedInput.js => RestrictedInput.jsx} (100%) rename tgui/packages/tgui/components/{RoundGauge.js => RoundGauge.jsx} (100%) rename tgui/packages/tgui/components/{Slider.js => Slider.jsx} (100%) rename tgui/packages/tgui/components/{Table.js => Table.jsx} (100%) rename tgui/packages/tgui/components/{Tabs.js => Tabs.jsx} (100%) rename tgui/packages/tgui/components/{TextArea.js => TextArea.jsx} (100%) rename tgui/packages/tgui/components/{TimeDisplay.js => TimeDisplay.jsx} (100%) rename tgui/packages/tgui/components/{index.js => index.jsx} (100%) rename tgui/packages/tgui/debug/{KitchenSink.js => KitchenSink.jsx} (95%) rename tgui/packages/tgui/interfaces/{AcidVest.js => AcidVest.jsx} (100%) rename tgui/packages/tgui/interfaces/{AlmayerControl.js => AlmayerControl.jsx} (100%) rename tgui/packages/tgui/interfaces/{AltitudeControlConsole.js => AltitudeControlConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{AntiAirConsole.js => AntiAirConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{Apc.js => Apc.jsx} (100%) rename tgui/packages/tgui/interfaces/{AresInterface.js => AresInterface.jsx} (100%) rename tgui/packages/tgui/interfaces/{Autodispenser.js => Autodispenser.jsx} (100%) rename tgui/packages/tgui/interfaces/{Autolathe.js => Autolathe.jsx} (100%) rename tgui/packages/tgui/interfaces/{Binoculars.js => Binoculars.jsx} (100%) rename tgui/packages/tgui/interfaces/{BioSyntheticPrinter.js => BioSyntheticPrinter.jsx} (100%) rename tgui/packages/tgui/interfaces/{BotanyEditor.js => BotanyEditor.jsx} (100%) rename tgui/packages/tgui/interfaces/{BotanyExtractor.js => BotanyExtractor.jsx} (100%) rename tgui/packages/tgui/interfaces/{BrigCell.js => BrigCell.jsx} (100%) rename tgui/packages/tgui/interfaces/{CameraConsole.js => CameraConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{CanvasLayer.js => CanvasLayer.jsx} (100%) rename tgui/packages/tgui/interfaces/{CardMod.js => CardMod.jsx} (100%) rename tgui/packages/tgui/interfaces/{Centrifuge.js => Centrifuge.jsx} (100%) rename tgui/packages/tgui/interfaces/{Changelog.js => Changelog.jsx} (100%) rename tgui/packages/tgui/interfaces/{ChemDispenser.js => ChemDispenser.jsx} (100%) rename tgui/packages/tgui/interfaces/{ChooseFruit.js => ChooseFruit.jsx} (100%) rename tgui/packages/tgui/interfaces/{ChooseResin.js => ChooseResin.jsx} (100%) rename tgui/packages/tgui/interfaces/{CommandTablet.js => CommandTablet.jsx} (100%) rename tgui/packages/tgui/interfaces/{CrewConsole.js => CrewConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{Cryo.js => Cryo.jsx} (100%) rename tgui/packages/tgui/interfaces/{DemoSim.js => DemoSim.jsx} (100%) rename tgui/packages/tgui/interfaces/{Disposals.js => Disposals.jsx} (100%) rename tgui/packages/tgui/interfaces/{DrawnMap.js => DrawnMap.jsx} (100%) rename tgui/packages/tgui/interfaces/{FaxMachine.js => FaxMachine.jsx} (100%) rename tgui/packages/tgui/interfaces/{Filteriffic.js => Filteriffic.jsx} (99%) rename tgui/packages/tgui/interfaces/{FiltrationControl.js => FiltrationControl.jsx} (100%) rename tgui/packages/tgui/interfaces/{HealthScan.js => HealthScan.jsx} (100%) rename tgui/packages/tgui/interfaces/{HiveFaction.js => HiveFaction.jsx} (100%) rename tgui/packages/tgui/interfaces/{HiveLeaders.js => HiveLeaders.jsx} (100%) rename tgui/packages/tgui/interfaces/{HiveStatus.js => HiveStatus.jsx} (100%) rename tgui/packages/tgui/interfaces/{KeyBinds.js => KeyBinds.jsx} (100%) rename tgui/packages/tgui/interfaces/{KillPanel.js => KillPanel.jsx} (100%) rename tgui/packages/tgui/interfaces/{LanguageMenu.js => LanguageMenu.jsx} (100%) rename tgui/packages/tgui/interfaces/{ListInput.js => ListInput.jsx} (100%) rename tgui/packages/tgui/interfaces/{MedalsPanel.js => MedalsPanel.jsx} (100%) rename tgui/packages/tgui/interfaces/{Mortar.js => Mortar.jsx} (100%) rename tgui/packages/tgui/interfaces/{NuclearBomb.js => NuclearBomb.jsx} (100%) rename tgui/packages/tgui/interfaces/{OrbitalCannonConsole.js => OrbitalCannonConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{OverwatchConsole.js => OverwatchConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{PartFabricator.js => PartFabricator.jsx} (100%) rename tgui/packages/tgui/interfaces/{PhoneMenu.js => PhoneMenu.jsx} (100%) rename tgui/packages/tgui/interfaces/{PlayerPanel.js => PlayerPanel.jsx} (100%) rename tgui/packages/tgui/interfaces/{PodLauncher.js => PodLauncher.jsx} (100%) rename tgui/packages/tgui/interfaces/{Proximity.js => Proximity.jsx} (100%) rename tgui/packages/tgui/interfaces/{Radio.js => Radio.jsx} (100%) rename tgui/packages/tgui/interfaces/{ResearchDoorDisplay.js => ResearchDoorDisplay.jsx} (100%) rename tgui/packages/tgui/interfaces/{ResearchMemories.js => ResearchMemories.jsx} (100%) rename tgui/packages/tgui/interfaces/{STUI.js => STUI.jsx} (100%) rename tgui/packages/tgui/interfaces/{SelfDestructConsole.js => SelfDestructConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{Sentencing.js => Sentencing.jsx} (100%) rename tgui/packages/tgui/interfaces/{Signaller.js => Signaller.jsx} (100%) rename tgui/packages/tgui/interfaces/{SkillsMenu.js => SkillsMenu.jsx} (100%) rename tgui/packages/tgui/interfaces/{Sleeper.js => Sleeper.jsx} (100%) rename tgui/packages/tgui/interfaces/{Smes.js => Smes.jsx} (100%) rename tgui/packages/tgui/interfaces/{SquadMod.js => SquadMod.jsx} (100%) rename tgui/packages/tgui/interfaces/{StatbrowserOptions.js => StatbrowserOptions.jsx} (100%) rename tgui/packages/tgui/interfaces/{StationAlertConsole.js => StationAlertConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{SupplyDropConsole.js => SupplyDropConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{TacmapAdminPanel.js => TacmapAdminPanel.jsx} (100%) rename tgui/packages/tgui/interfaces/{Tank.js => Tank.jsx} (100%) rename tgui/packages/tgui/interfaces/{TechControl.js => TechControl.jsx} (100%) rename tgui/packages/tgui/interfaces/{TechMemories.js => TechMemories.jsx} (100%) rename tgui/packages/tgui/interfaces/{TechNode.js => TechNode.jsx} (100%) rename tgui/packages/tgui/interfaces/{TeleporterConsole.js => TeleporterConsole.jsx} (100%) rename tgui/packages/tgui/interfaces/{Timer.js => Timer.jsx} (100%) rename tgui/packages/tgui/interfaces/{VehicleStatus.js => VehicleStatus.jsx} (100%) rename tgui/packages/tgui/interfaces/{VoteMenu.js => VoteMenu.jsx} (100%) rename tgui/packages/tgui/interfaces/{VoxPanel.js => VoxPanel.jsx} (100%) rename tgui/packages/tgui/interfaces/{WeaponStats.js => WeaponStats.jsx} (100%) rename tgui/packages/tgui/interfaces/{Wires.js => Wires.jsx} (100%) rename tgui/packages/tgui/interfaces/{WorkingJoe.js => WorkingJoe.jsx} (100%) rename tgui/packages/tgui/interfaces/common/{AccessList.js => AccessList.jsx} (100%) rename tgui/packages/tgui/interfaces/common/{BeakerContents.js => BeakerContents.jsx} (100%) rename tgui/packages/tgui/interfaces/common/{InterfaceLockNoticeBox.js => InterfaceLockNoticeBox.jsx} (100%) rename tgui/packages/tgui/layouts/{Layout.js => Layout.jsx} (100%) rename tgui/packages/tgui/layouts/{NtosWindow.js => NtosWindow.jsx} (100%) rename tgui/packages/tgui/layouts/{Pane.js => Pane.jsx} (100%) rename tgui/packages/tgui/layouts/{Window.js => Window.jsx} (100%) rename tgui/packages/tgui/{routes.js => routes.jsx} (98%) rename tgui/packages/tgui/stories/{Blink.stories.js => Blink.stories.jsx} (100%) rename tgui/packages/tgui/stories/{BlockQuote.stories.js => BlockQuote.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Box.stories.js => Box.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Button.stories.js => Button.stories.jsx} (100%) rename tgui/packages/tgui/stories/{ByondUi.stories.js => ByondUi.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Collapsible.stories.js => Collapsible.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Flex.stories.js => Flex.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Input.stories.js => Input.stories.jsx} (100%) rename tgui/packages/tgui/stories/{LabeledList.stories.js => LabeledList.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Popper.stories.js => Popper.stories.jsx} (100%) rename tgui/packages/tgui/stories/{ProgressBar.stories.js => ProgressBar.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Stack.stories.js => Stack.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Storage.stories.js => Storage.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Tabs.stories.js => Tabs.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Themes.stories.js => Themes.stories.jsx} (100%) rename tgui/packages/tgui/stories/{Tooltip.stories.js => Tooltip.stories.jsx} (100%) rename tgui/packages/tgui/stories/{common.js => common.jsx} (100%) diff --git a/tgui/packages/tgui/components/Blink.js b/tgui/packages/tgui/components/Blink.jsx similarity index 100% rename from tgui/packages/tgui/components/Blink.js rename to tgui/packages/tgui/components/Blink.jsx diff --git a/tgui/packages/tgui/components/BlockQuote.js b/tgui/packages/tgui/components/BlockQuote.jsx similarity index 100% rename from tgui/packages/tgui/components/BlockQuote.js rename to tgui/packages/tgui/components/BlockQuote.jsx diff --git a/tgui/packages/tgui/components/Button.js b/tgui/packages/tgui/components/Button.jsx similarity index 100% rename from tgui/packages/tgui/components/Button.js rename to tgui/packages/tgui/components/Button.jsx diff --git a/tgui/packages/tgui/components/ByondUi.js b/tgui/packages/tgui/components/ByondUi.jsx similarity index 100% rename from tgui/packages/tgui/components/ByondUi.js rename to tgui/packages/tgui/components/ByondUi.jsx diff --git a/tgui/packages/tgui/components/Chart.js b/tgui/packages/tgui/components/Chart.jsx similarity index 100% rename from tgui/packages/tgui/components/Chart.js rename to tgui/packages/tgui/components/Chart.jsx diff --git a/tgui/packages/tgui/components/Collapsible.js b/tgui/packages/tgui/components/Collapsible.jsx similarity index 100% rename from tgui/packages/tgui/components/Collapsible.js rename to tgui/packages/tgui/components/Collapsible.jsx diff --git a/tgui/packages/tgui/components/ColorBox.js b/tgui/packages/tgui/components/ColorBox.jsx similarity index 100% rename from tgui/packages/tgui/components/ColorBox.js rename to tgui/packages/tgui/components/ColorBox.jsx diff --git a/tgui/packages/tgui/components/Dimmer.js b/tgui/packages/tgui/components/Dimmer.jsx similarity index 100% rename from tgui/packages/tgui/components/Dimmer.js rename to tgui/packages/tgui/components/Dimmer.jsx diff --git a/tgui/packages/tgui/components/Divider.js b/tgui/packages/tgui/components/Divider.jsx similarity index 100% rename from tgui/packages/tgui/components/Divider.js rename to tgui/packages/tgui/components/Divider.jsx diff --git a/tgui/packages/tgui/components/DraggableControl.js b/tgui/packages/tgui/components/DraggableControl.jsx similarity index 100% rename from tgui/packages/tgui/components/DraggableControl.js rename to tgui/packages/tgui/components/DraggableControl.jsx diff --git a/tgui/packages/tgui/components/Dropdown.js b/tgui/packages/tgui/components/Dropdown.jsx similarity index 100% rename from tgui/packages/tgui/components/Dropdown.js rename to tgui/packages/tgui/components/Dropdown.jsx diff --git a/tgui/packages/tgui/components/Grid.js b/tgui/packages/tgui/components/Grid.jsx similarity index 100% rename from tgui/packages/tgui/components/Grid.js rename to tgui/packages/tgui/components/Grid.jsx diff --git a/tgui/packages/tgui/components/Icon.js b/tgui/packages/tgui/components/Icon.jsx similarity index 100% rename from tgui/packages/tgui/components/Icon.js rename to tgui/packages/tgui/components/Icon.jsx diff --git a/tgui/packages/tgui/components/InfinitePlane.js b/tgui/packages/tgui/components/InfinitePlane.jsx similarity index 100% rename from tgui/packages/tgui/components/InfinitePlane.js rename to tgui/packages/tgui/components/InfinitePlane.jsx diff --git a/tgui/packages/tgui/components/Input.js b/tgui/packages/tgui/components/Input.jsx similarity index 100% rename from tgui/packages/tgui/components/Input.js rename to tgui/packages/tgui/components/Input.jsx diff --git a/tgui/packages/tgui/components/Knob.js b/tgui/packages/tgui/components/Knob.jsx similarity index 100% rename from tgui/packages/tgui/components/Knob.js rename to tgui/packages/tgui/components/Knob.jsx diff --git a/tgui/packages/tgui/components/LabeledControls.js b/tgui/packages/tgui/components/LabeledControls.jsx similarity index 100% rename from tgui/packages/tgui/components/LabeledControls.js rename to tgui/packages/tgui/components/LabeledControls.jsx diff --git a/tgui/packages/tgui/components/Modal.js b/tgui/packages/tgui/components/Modal.jsx similarity index 100% rename from tgui/packages/tgui/components/Modal.js rename to tgui/packages/tgui/components/Modal.jsx diff --git a/tgui/packages/tgui/components/NoticeBox.js b/tgui/packages/tgui/components/NoticeBox.jsx similarity index 100% rename from tgui/packages/tgui/components/NoticeBox.js rename to tgui/packages/tgui/components/NoticeBox.jsx diff --git a/tgui/packages/tgui/components/NumberInput.js b/tgui/packages/tgui/components/NumberInput.jsx similarity index 100% rename from tgui/packages/tgui/components/NumberInput.js rename to tgui/packages/tgui/components/NumberInput.jsx diff --git a/tgui/packages/tgui/components/ProgressBar.js b/tgui/packages/tgui/components/ProgressBar.jsx similarity index 100% rename from tgui/packages/tgui/components/ProgressBar.js rename to tgui/packages/tgui/components/ProgressBar.jsx diff --git a/tgui/packages/tgui/components/RestrictedInput.js b/tgui/packages/tgui/components/RestrictedInput.jsx similarity index 100% rename from tgui/packages/tgui/components/RestrictedInput.js rename to tgui/packages/tgui/components/RestrictedInput.jsx diff --git a/tgui/packages/tgui/components/RoundGauge.js b/tgui/packages/tgui/components/RoundGauge.jsx similarity index 100% rename from tgui/packages/tgui/components/RoundGauge.js rename to tgui/packages/tgui/components/RoundGauge.jsx diff --git a/tgui/packages/tgui/components/Slider.js b/tgui/packages/tgui/components/Slider.jsx similarity index 100% rename from tgui/packages/tgui/components/Slider.js rename to tgui/packages/tgui/components/Slider.jsx diff --git a/tgui/packages/tgui/components/Table.js b/tgui/packages/tgui/components/Table.jsx similarity index 100% rename from tgui/packages/tgui/components/Table.js rename to tgui/packages/tgui/components/Table.jsx diff --git a/tgui/packages/tgui/components/Tabs.js b/tgui/packages/tgui/components/Tabs.jsx similarity index 100% rename from tgui/packages/tgui/components/Tabs.js rename to tgui/packages/tgui/components/Tabs.jsx diff --git a/tgui/packages/tgui/components/TextArea.js b/tgui/packages/tgui/components/TextArea.jsx similarity index 100% rename from tgui/packages/tgui/components/TextArea.js rename to tgui/packages/tgui/components/TextArea.jsx diff --git a/tgui/packages/tgui/components/TimeDisplay.js b/tgui/packages/tgui/components/TimeDisplay.jsx similarity index 100% rename from tgui/packages/tgui/components/TimeDisplay.js rename to tgui/packages/tgui/components/TimeDisplay.jsx diff --git a/tgui/packages/tgui/components/index.js b/tgui/packages/tgui/components/index.jsx similarity index 100% rename from tgui/packages/tgui/components/index.js rename to tgui/packages/tgui/components/index.jsx diff --git a/tgui/packages/tgui/debug/KitchenSink.js b/tgui/packages/tgui/debug/KitchenSink.jsx similarity index 95% rename from tgui/packages/tgui/debug/KitchenSink.js rename to tgui/packages/tgui/debug/KitchenSink.jsx index 246b4f50b478..e25751722c52 100644 --- a/tgui/packages/tgui/debug/KitchenSink.js +++ b/tgui/packages/tgui/debug/KitchenSink.jsx @@ -8,7 +8,7 @@ import { useLocalState } from '../backend'; import { Flex, Section, Tabs } from '../components'; import { Pane, Window } from '../layouts'; -const r = require.context('../stories', false, /\.stories\.js$/); +const r = require.context('../stories', false, /\.stories\.jsx$/); /** * @returns {{ diff --git a/tgui/packages/tgui/interfaces/AcidVest.js b/tgui/packages/tgui/interfaces/AcidVest.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/AcidVest.js rename to tgui/packages/tgui/interfaces/AcidVest.jsx diff --git a/tgui/packages/tgui/interfaces/AlmayerControl.js b/tgui/packages/tgui/interfaces/AlmayerControl.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/AlmayerControl.js rename to tgui/packages/tgui/interfaces/AlmayerControl.jsx diff --git a/tgui/packages/tgui/interfaces/AltitudeControlConsole.js b/tgui/packages/tgui/interfaces/AltitudeControlConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/AltitudeControlConsole.js rename to tgui/packages/tgui/interfaces/AltitudeControlConsole.jsx diff --git a/tgui/packages/tgui/interfaces/AntiAirConsole.js b/tgui/packages/tgui/interfaces/AntiAirConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/AntiAirConsole.js rename to tgui/packages/tgui/interfaces/AntiAirConsole.jsx diff --git a/tgui/packages/tgui/interfaces/Apc.js b/tgui/packages/tgui/interfaces/Apc.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Apc.js rename to tgui/packages/tgui/interfaces/Apc.jsx diff --git a/tgui/packages/tgui/interfaces/AresInterface.js b/tgui/packages/tgui/interfaces/AresInterface.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/AresInterface.js rename to tgui/packages/tgui/interfaces/AresInterface.jsx diff --git a/tgui/packages/tgui/interfaces/Autodispenser.js b/tgui/packages/tgui/interfaces/Autodispenser.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Autodispenser.js rename to tgui/packages/tgui/interfaces/Autodispenser.jsx diff --git a/tgui/packages/tgui/interfaces/Autolathe.js b/tgui/packages/tgui/interfaces/Autolathe.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Autolathe.js rename to tgui/packages/tgui/interfaces/Autolathe.jsx diff --git a/tgui/packages/tgui/interfaces/Binoculars.js b/tgui/packages/tgui/interfaces/Binoculars.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Binoculars.js rename to tgui/packages/tgui/interfaces/Binoculars.jsx diff --git a/tgui/packages/tgui/interfaces/BioSyntheticPrinter.js b/tgui/packages/tgui/interfaces/BioSyntheticPrinter.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/BioSyntheticPrinter.js rename to tgui/packages/tgui/interfaces/BioSyntheticPrinter.jsx diff --git a/tgui/packages/tgui/interfaces/BotanyEditor.js b/tgui/packages/tgui/interfaces/BotanyEditor.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/BotanyEditor.js rename to tgui/packages/tgui/interfaces/BotanyEditor.jsx diff --git a/tgui/packages/tgui/interfaces/BotanyExtractor.js b/tgui/packages/tgui/interfaces/BotanyExtractor.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/BotanyExtractor.js rename to tgui/packages/tgui/interfaces/BotanyExtractor.jsx diff --git a/tgui/packages/tgui/interfaces/BrigCell.js b/tgui/packages/tgui/interfaces/BrigCell.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/BrigCell.js rename to tgui/packages/tgui/interfaces/BrigCell.jsx diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/CameraConsole.js rename to tgui/packages/tgui/interfaces/CameraConsole.jsx diff --git a/tgui/packages/tgui/interfaces/CanvasLayer.js b/tgui/packages/tgui/interfaces/CanvasLayer.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/CanvasLayer.js rename to tgui/packages/tgui/interfaces/CanvasLayer.jsx diff --git a/tgui/packages/tgui/interfaces/CardMod.js b/tgui/packages/tgui/interfaces/CardMod.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/CardMod.js rename to tgui/packages/tgui/interfaces/CardMod.jsx diff --git a/tgui/packages/tgui/interfaces/Centrifuge.js b/tgui/packages/tgui/interfaces/Centrifuge.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Centrifuge.js rename to tgui/packages/tgui/interfaces/Centrifuge.jsx diff --git a/tgui/packages/tgui/interfaces/Changelog.js b/tgui/packages/tgui/interfaces/Changelog.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Changelog.js rename to tgui/packages/tgui/interfaces/Changelog.jsx diff --git a/tgui/packages/tgui/interfaces/ChemDispenser.js b/tgui/packages/tgui/interfaces/ChemDispenser.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/ChemDispenser.js rename to tgui/packages/tgui/interfaces/ChemDispenser.jsx diff --git a/tgui/packages/tgui/interfaces/ChooseFruit.js b/tgui/packages/tgui/interfaces/ChooseFruit.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/ChooseFruit.js rename to tgui/packages/tgui/interfaces/ChooseFruit.jsx diff --git a/tgui/packages/tgui/interfaces/ChooseResin.js b/tgui/packages/tgui/interfaces/ChooseResin.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/ChooseResin.js rename to tgui/packages/tgui/interfaces/ChooseResin.jsx diff --git a/tgui/packages/tgui/interfaces/CommandTablet.js b/tgui/packages/tgui/interfaces/CommandTablet.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/CommandTablet.js rename to tgui/packages/tgui/interfaces/CommandTablet.jsx diff --git a/tgui/packages/tgui/interfaces/CrewConsole.js b/tgui/packages/tgui/interfaces/CrewConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/CrewConsole.js rename to tgui/packages/tgui/interfaces/CrewConsole.jsx diff --git a/tgui/packages/tgui/interfaces/Cryo.js b/tgui/packages/tgui/interfaces/Cryo.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Cryo.js rename to tgui/packages/tgui/interfaces/Cryo.jsx diff --git a/tgui/packages/tgui/interfaces/DemoSim.js b/tgui/packages/tgui/interfaces/DemoSim.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/DemoSim.js rename to tgui/packages/tgui/interfaces/DemoSim.jsx diff --git a/tgui/packages/tgui/interfaces/Disposals.js b/tgui/packages/tgui/interfaces/Disposals.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Disposals.js rename to tgui/packages/tgui/interfaces/Disposals.jsx diff --git a/tgui/packages/tgui/interfaces/DrawnMap.js b/tgui/packages/tgui/interfaces/DrawnMap.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/DrawnMap.js rename to tgui/packages/tgui/interfaces/DrawnMap.jsx diff --git a/tgui/packages/tgui/interfaces/FaxMachine.js b/tgui/packages/tgui/interfaces/FaxMachine.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/FaxMachine.js rename to tgui/packages/tgui/interfaces/FaxMachine.jsx diff --git a/tgui/packages/tgui/interfaces/Filteriffic.js b/tgui/packages/tgui/interfaces/Filteriffic.jsx similarity index 99% rename from tgui/packages/tgui/interfaces/Filteriffic.js rename to tgui/packages/tgui/interfaces/Filteriffic.jsx index a967efafca98..8bda997dff1b 100644 --- a/tgui/packages/tgui/interfaces/Filteriffic.js +++ b/tgui/packages/tgui/interfaces/Filteriffic.jsx @@ -1,6 +1,6 @@ import { map } from 'common/collections'; import { toFixed } from 'common/math'; -import { numberOfDecimalDigits } from '../../common/math'; +import { numberOfDecimalDigits } from 'common/math'; import { useBackend, useLocalState } from '../backend'; import { Box, Button, Collapsible, ColorBox, Dropdown, Input, LabeledList, NoticeBox, NumberInput, Section } from '../components'; import { Window } from '../layouts'; diff --git a/tgui/packages/tgui/interfaces/FiltrationControl.js b/tgui/packages/tgui/interfaces/FiltrationControl.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/FiltrationControl.js rename to tgui/packages/tgui/interfaces/FiltrationControl.jsx diff --git a/tgui/packages/tgui/interfaces/HealthScan.js b/tgui/packages/tgui/interfaces/HealthScan.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/HealthScan.js rename to tgui/packages/tgui/interfaces/HealthScan.jsx diff --git a/tgui/packages/tgui/interfaces/HiveFaction.js b/tgui/packages/tgui/interfaces/HiveFaction.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/HiveFaction.js rename to tgui/packages/tgui/interfaces/HiveFaction.jsx diff --git a/tgui/packages/tgui/interfaces/HiveLeaders.js b/tgui/packages/tgui/interfaces/HiveLeaders.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/HiveLeaders.js rename to tgui/packages/tgui/interfaces/HiveLeaders.jsx diff --git a/tgui/packages/tgui/interfaces/HiveStatus.js b/tgui/packages/tgui/interfaces/HiveStatus.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/HiveStatus.js rename to tgui/packages/tgui/interfaces/HiveStatus.jsx diff --git a/tgui/packages/tgui/interfaces/KeyBinds.js b/tgui/packages/tgui/interfaces/KeyBinds.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/KeyBinds.js rename to tgui/packages/tgui/interfaces/KeyBinds.jsx diff --git a/tgui/packages/tgui/interfaces/KillPanel.js b/tgui/packages/tgui/interfaces/KillPanel.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/KillPanel.js rename to tgui/packages/tgui/interfaces/KillPanel.jsx diff --git a/tgui/packages/tgui/interfaces/LanguageMenu.js b/tgui/packages/tgui/interfaces/LanguageMenu.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/LanguageMenu.js rename to tgui/packages/tgui/interfaces/LanguageMenu.jsx diff --git a/tgui/packages/tgui/interfaces/ListInput.js b/tgui/packages/tgui/interfaces/ListInput.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/ListInput.js rename to tgui/packages/tgui/interfaces/ListInput.jsx diff --git a/tgui/packages/tgui/interfaces/MedalsPanel.js b/tgui/packages/tgui/interfaces/MedalsPanel.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/MedalsPanel.js rename to tgui/packages/tgui/interfaces/MedalsPanel.jsx diff --git a/tgui/packages/tgui/interfaces/Mortar.js b/tgui/packages/tgui/interfaces/Mortar.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Mortar.js rename to tgui/packages/tgui/interfaces/Mortar.jsx diff --git a/tgui/packages/tgui/interfaces/NuclearBomb.js b/tgui/packages/tgui/interfaces/NuclearBomb.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/NuclearBomb.js rename to tgui/packages/tgui/interfaces/NuclearBomb.jsx diff --git a/tgui/packages/tgui/interfaces/OrbitalCannonConsole.js b/tgui/packages/tgui/interfaces/OrbitalCannonConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/OrbitalCannonConsole.js rename to tgui/packages/tgui/interfaces/OrbitalCannonConsole.jsx diff --git a/tgui/packages/tgui/interfaces/OverwatchConsole.js b/tgui/packages/tgui/interfaces/OverwatchConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/OverwatchConsole.js rename to tgui/packages/tgui/interfaces/OverwatchConsole.jsx diff --git a/tgui/packages/tgui/interfaces/PartFabricator.js b/tgui/packages/tgui/interfaces/PartFabricator.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/PartFabricator.js rename to tgui/packages/tgui/interfaces/PartFabricator.jsx diff --git a/tgui/packages/tgui/interfaces/PhoneMenu.js b/tgui/packages/tgui/interfaces/PhoneMenu.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/PhoneMenu.js rename to tgui/packages/tgui/interfaces/PhoneMenu.jsx diff --git a/tgui/packages/tgui/interfaces/PlayerPanel.js b/tgui/packages/tgui/interfaces/PlayerPanel.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/PlayerPanel.js rename to tgui/packages/tgui/interfaces/PlayerPanel.jsx diff --git a/tgui/packages/tgui/interfaces/PodLauncher.js b/tgui/packages/tgui/interfaces/PodLauncher.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/PodLauncher.js rename to tgui/packages/tgui/interfaces/PodLauncher.jsx diff --git a/tgui/packages/tgui/interfaces/Proximity.js b/tgui/packages/tgui/interfaces/Proximity.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Proximity.js rename to tgui/packages/tgui/interfaces/Proximity.jsx diff --git a/tgui/packages/tgui/interfaces/Radio.js b/tgui/packages/tgui/interfaces/Radio.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Radio.js rename to tgui/packages/tgui/interfaces/Radio.jsx diff --git a/tgui/packages/tgui/interfaces/ResearchDoorDisplay.js b/tgui/packages/tgui/interfaces/ResearchDoorDisplay.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/ResearchDoorDisplay.js rename to tgui/packages/tgui/interfaces/ResearchDoorDisplay.jsx diff --git a/tgui/packages/tgui/interfaces/ResearchMemories.js b/tgui/packages/tgui/interfaces/ResearchMemories.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/ResearchMemories.js rename to tgui/packages/tgui/interfaces/ResearchMemories.jsx diff --git a/tgui/packages/tgui/interfaces/STUI.js b/tgui/packages/tgui/interfaces/STUI.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/STUI.js rename to tgui/packages/tgui/interfaces/STUI.jsx diff --git a/tgui/packages/tgui/interfaces/SelfDestructConsole.js b/tgui/packages/tgui/interfaces/SelfDestructConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/SelfDestructConsole.js rename to tgui/packages/tgui/interfaces/SelfDestructConsole.jsx diff --git a/tgui/packages/tgui/interfaces/Sentencing.js b/tgui/packages/tgui/interfaces/Sentencing.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Sentencing.js rename to tgui/packages/tgui/interfaces/Sentencing.jsx diff --git a/tgui/packages/tgui/interfaces/Signaller.js b/tgui/packages/tgui/interfaces/Signaller.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Signaller.js rename to tgui/packages/tgui/interfaces/Signaller.jsx diff --git a/tgui/packages/tgui/interfaces/SkillsMenu.js b/tgui/packages/tgui/interfaces/SkillsMenu.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/SkillsMenu.js rename to tgui/packages/tgui/interfaces/SkillsMenu.jsx diff --git a/tgui/packages/tgui/interfaces/Sleeper.js b/tgui/packages/tgui/interfaces/Sleeper.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Sleeper.js rename to tgui/packages/tgui/interfaces/Sleeper.jsx diff --git a/tgui/packages/tgui/interfaces/Smes.js b/tgui/packages/tgui/interfaces/Smes.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Smes.js rename to tgui/packages/tgui/interfaces/Smes.jsx diff --git a/tgui/packages/tgui/interfaces/SquadMod.js b/tgui/packages/tgui/interfaces/SquadMod.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/SquadMod.js rename to tgui/packages/tgui/interfaces/SquadMod.jsx diff --git a/tgui/packages/tgui/interfaces/StatbrowserOptions.js b/tgui/packages/tgui/interfaces/StatbrowserOptions.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/StatbrowserOptions.js rename to tgui/packages/tgui/interfaces/StatbrowserOptions.jsx diff --git a/tgui/packages/tgui/interfaces/StationAlertConsole.js b/tgui/packages/tgui/interfaces/StationAlertConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/StationAlertConsole.js rename to tgui/packages/tgui/interfaces/StationAlertConsole.jsx diff --git a/tgui/packages/tgui/interfaces/SupplyDropConsole.js b/tgui/packages/tgui/interfaces/SupplyDropConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/SupplyDropConsole.js rename to tgui/packages/tgui/interfaces/SupplyDropConsole.jsx diff --git a/tgui/packages/tgui/interfaces/TacmapAdminPanel.js b/tgui/packages/tgui/interfaces/TacmapAdminPanel.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/TacmapAdminPanel.js rename to tgui/packages/tgui/interfaces/TacmapAdminPanel.jsx diff --git a/tgui/packages/tgui/interfaces/Tank.js b/tgui/packages/tgui/interfaces/Tank.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Tank.js rename to tgui/packages/tgui/interfaces/Tank.jsx diff --git a/tgui/packages/tgui/interfaces/TechControl.js b/tgui/packages/tgui/interfaces/TechControl.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/TechControl.js rename to tgui/packages/tgui/interfaces/TechControl.jsx diff --git a/tgui/packages/tgui/interfaces/TechMemories.js b/tgui/packages/tgui/interfaces/TechMemories.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/TechMemories.js rename to tgui/packages/tgui/interfaces/TechMemories.jsx diff --git a/tgui/packages/tgui/interfaces/TechNode.js b/tgui/packages/tgui/interfaces/TechNode.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/TechNode.js rename to tgui/packages/tgui/interfaces/TechNode.jsx diff --git a/tgui/packages/tgui/interfaces/TeleporterConsole.js b/tgui/packages/tgui/interfaces/TeleporterConsole.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/TeleporterConsole.js rename to tgui/packages/tgui/interfaces/TeleporterConsole.jsx diff --git a/tgui/packages/tgui/interfaces/Timer.js b/tgui/packages/tgui/interfaces/Timer.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Timer.js rename to tgui/packages/tgui/interfaces/Timer.jsx diff --git a/tgui/packages/tgui/interfaces/VehicleStatus.js b/tgui/packages/tgui/interfaces/VehicleStatus.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/VehicleStatus.js rename to tgui/packages/tgui/interfaces/VehicleStatus.jsx diff --git a/tgui/packages/tgui/interfaces/VoteMenu.js b/tgui/packages/tgui/interfaces/VoteMenu.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/VoteMenu.js rename to tgui/packages/tgui/interfaces/VoteMenu.jsx diff --git a/tgui/packages/tgui/interfaces/VoxPanel.js b/tgui/packages/tgui/interfaces/VoxPanel.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/VoxPanel.js rename to tgui/packages/tgui/interfaces/VoxPanel.jsx diff --git a/tgui/packages/tgui/interfaces/WeaponStats.js b/tgui/packages/tgui/interfaces/WeaponStats.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/WeaponStats.js rename to tgui/packages/tgui/interfaces/WeaponStats.jsx diff --git a/tgui/packages/tgui/interfaces/Wires.js b/tgui/packages/tgui/interfaces/Wires.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/Wires.js rename to tgui/packages/tgui/interfaces/Wires.jsx diff --git a/tgui/packages/tgui/interfaces/WorkingJoe.js b/tgui/packages/tgui/interfaces/WorkingJoe.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/WorkingJoe.js rename to tgui/packages/tgui/interfaces/WorkingJoe.jsx diff --git a/tgui/packages/tgui/interfaces/common/AccessList.js b/tgui/packages/tgui/interfaces/common/AccessList.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/common/AccessList.js rename to tgui/packages/tgui/interfaces/common/AccessList.jsx diff --git a/tgui/packages/tgui/interfaces/common/BeakerContents.js b/tgui/packages/tgui/interfaces/common/BeakerContents.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/common/BeakerContents.js rename to tgui/packages/tgui/interfaces/common/BeakerContents.jsx diff --git a/tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.js b/tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.jsx similarity index 100% rename from tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.js rename to tgui/packages/tgui/interfaces/common/InterfaceLockNoticeBox.jsx diff --git a/tgui/packages/tgui/layouts/Layout.js b/tgui/packages/tgui/layouts/Layout.jsx similarity index 100% rename from tgui/packages/tgui/layouts/Layout.js rename to tgui/packages/tgui/layouts/Layout.jsx diff --git a/tgui/packages/tgui/layouts/NtosWindow.js b/tgui/packages/tgui/layouts/NtosWindow.jsx similarity index 100% rename from tgui/packages/tgui/layouts/NtosWindow.js rename to tgui/packages/tgui/layouts/NtosWindow.jsx diff --git a/tgui/packages/tgui/layouts/Pane.js b/tgui/packages/tgui/layouts/Pane.jsx similarity index 100% rename from tgui/packages/tgui/layouts/Pane.js rename to tgui/packages/tgui/layouts/Pane.jsx diff --git a/tgui/packages/tgui/layouts/Window.js b/tgui/packages/tgui/layouts/Window.jsx similarity index 100% rename from tgui/packages/tgui/layouts/Window.js rename to tgui/packages/tgui/layouts/Window.jsx diff --git a/tgui/packages/tgui/routes.js b/tgui/packages/tgui/routes.jsx similarity index 98% rename from tgui/packages/tgui/routes.js rename to tgui/packages/tgui/routes.jsx index eb4ddff15393..0ad869fc63cb 100644 --- a/tgui/packages/tgui/routes.js +++ b/tgui/packages/tgui/routes.jsx @@ -74,6 +74,7 @@ export const getRoutedComponent = (store) => { const name = config?.interface; const interfacePathBuilders = [ (name) => `./${name}.tsx`, + (name) => `./${name}.jsx`, (name) => `./${name}.js`, (name) => `./${name}/index.tsx`, (name) => `./${name}/index.js`, diff --git a/tgui/packages/tgui/stories/Blink.stories.js b/tgui/packages/tgui/stories/Blink.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Blink.stories.js rename to tgui/packages/tgui/stories/Blink.stories.jsx diff --git a/tgui/packages/tgui/stories/BlockQuote.stories.js b/tgui/packages/tgui/stories/BlockQuote.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/BlockQuote.stories.js rename to tgui/packages/tgui/stories/BlockQuote.stories.jsx diff --git a/tgui/packages/tgui/stories/Box.stories.js b/tgui/packages/tgui/stories/Box.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Box.stories.js rename to tgui/packages/tgui/stories/Box.stories.jsx diff --git a/tgui/packages/tgui/stories/Button.stories.js b/tgui/packages/tgui/stories/Button.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Button.stories.js rename to tgui/packages/tgui/stories/Button.stories.jsx diff --git a/tgui/packages/tgui/stories/ByondUi.stories.js b/tgui/packages/tgui/stories/ByondUi.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/ByondUi.stories.js rename to tgui/packages/tgui/stories/ByondUi.stories.jsx diff --git a/tgui/packages/tgui/stories/Collapsible.stories.js b/tgui/packages/tgui/stories/Collapsible.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Collapsible.stories.js rename to tgui/packages/tgui/stories/Collapsible.stories.jsx diff --git a/tgui/packages/tgui/stories/Flex.stories.js b/tgui/packages/tgui/stories/Flex.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Flex.stories.js rename to tgui/packages/tgui/stories/Flex.stories.jsx diff --git a/tgui/packages/tgui/stories/Input.stories.js b/tgui/packages/tgui/stories/Input.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Input.stories.js rename to tgui/packages/tgui/stories/Input.stories.jsx diff --git a/tgui/packages/tgui/stories/LabeledList.stories.js b/tgui/packages/tgui/stories/LabeledList.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/LabeledList.stories.js rename to tgui/packages/tgui/stories/LabeledList.stories.jsx diff --git a/tgui/packages/tgui/stories/Popper.stories.js b/tgui/packages/tgui/stories/Popper.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Popper.stories.js rename to tgui/packages/tgui/stories/Popper.stories.jsx diff --git a/tgui/packages/tgui/stories/ProgressBar.stories.js b/tgui/packages/tgui/stories/ProgressBar.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/ProgressBar.stories.js rename to tgui/packages/tgui/stories/ProgressBar.stories.jsx diff --git a/tgui/packages/tgui/stories/Stack.stories.js b/tgui/packages/tgui/stories/Stack.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Stack.stories.js rename to tgui/packages/tgui/stories/Stack.stories.jsx diff --git a/tgui/packages/tgui/stories/Storage.stories.js b/tgui/packages/tgui/stories/Storage.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Storage.stories.js rename to tgui/packages/tgui/stories/Storage.stories.jsx diff --git a/tgui/packages/tgui/stories/Tabs.stories.js b/tgui/packages/tgui/stories/Tabs.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Tabs.stories.js rename to tgui/packages/tgui/stories/Tabs.stories.jsx diff --git a/tgui/packages/tgui/stories/Themes.stories.js b/tgui/packages/tgui/stories/Themes.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Themes.stories.js rename to tgui/packages/tgui/stories/Themes.stories.jsx diff --git a/tgui/packages/tgui/stories/Tooltip.stories.js b/tgui/packages/tgui/stories/Tooltip.stories.jsx similarity index 100% rename from tgui/packages/tgui/stories/Tooltip.stories.js rename to tgui/packages/tgui/stories/Tooltip.stories.jsx diff --git a/tgui/packages/tgui/stories/common.js b/tgui/packages/tgui/stories/common.jsx similarity index 100% rename from tgui/packages/tgui/stories/common.js rename to tgui/packages/tgui/stories/common.jsx diff --git a/tgui/webpack.config.js b/tgui/webpack.config.js index 19e2975715fa..f90b80926e44 100644 --- a/tgui/webpack.config.js +++ b/tgui/webpack.config.js @@ -55,13 +55,13 @@ module.exports = (env = {}, argv) => { chunkLoadTimeout: 15000, }, resolve: { - extensions: ['.tsx', '.ts', '.js'], + extensions: ['.jsx', '.tsx', '.ts', '.js'], alias: {}, }, module: { rules: [ { - test: /\.(js|cjs|ts|tsx)$/, + test: /\.(js|jsx|cjs|ts|tsx)$/, use: [ { loader: require.resolve('babel-loader'), From 84f65d0c592c3a88da3cdb52498bea6dc57f2079 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 19:43:11 +0000 Subject: [PATCH 27/99] Automatic changelog for PR #5307 [ci skip] --- html/changelogs/AutoChangeLog-pr-5307.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5307.yml diff --git a/html/changelogs/AutoChangeLog-pr-5307.yml b/html/changelogs/AutoChangeLog-pr-5307.yml new file mode 100644 index 000000000000..3047d03d8e82 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5307.yml @@ -0,0 +1,4 @@ +author: "mullenpaul" +delete-after: True +changes: + - refactor: "tgui js components now jsx" \ No newline at end of file From 483f5ae363ff5bcf5f32c2b32b2dcf80c98ff899 Mon Sep 17 00:00:00 2001 From: Birdtalon Date: Fri, 29 Dec 2023 19:33:16 +0000 Subject: [PATCH 28/99] Fixes runtime in stripping (#5320) # About the pull request The dummy as an example doesn't have skills so we runtime when stripping them. ``` [2023-12-27 21:52:42.147] runtime error: Cannot execute null.get skill level(). - proc name: get strip delay (/mob/living/carbon/human/proc/get_strip_delay) - source file: code/modules/mob/living/carbon/human/inventory.dm,498 - usr: (src) - src: Jack Samerus (/mob/living/carbon/human) - src.loc: the floor (140,46,3) (/turf/open/floor/almayer) - call stack: - Jack Samerus (/mob/living/carbon/human): get strip delay(Jack Samerus (/mob/living/carbon/human), Professor DUMMY the Medical Ma... (/mob/living/carbon/human)) - Jack Samerus (/mob/living/carbon/human): stripPanelUnequip(Professor DUMMY tablet (/obj/item/device/professor_dummy_tablet), Professor DUMMY the Medical Ma... (/mob/living/carbon/human), "r_hand") - Professor DUMMY the Medical Ma... (/mob/living/carbon/human): Topic("src=\[0x3000232];item=r_hand", /list (/list)) - **** (/client): Topic("src=\[0x3000232];item=r_hand", /list (/list), Professor DUMMY the Medical Ma... (/mob/living/carbon/human)) ``` # Explain why it's good for the game # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: Runtime in inventory.dm /:cl: --- code/modules/mob/living/carbon/human/inventory.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 34b80d1ce6f9..3d372376d1e7 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -494,7 +494,8 @@ /// Multiplier for how quickly the user can strip things. var/user_speed = user.get_skill_duration_multiplier(SKILL_CQC) /// The total skill level of CQC & Police - var/target_skills = (target.skills.get_skill_level(SKILL_CQC) + target.skills.get_skill_level(SKILL_POLICE)) + var/target_skills = 0 + target_skills += (target.skills?.get_skill_level(SKILL_CQC) + target.skills?.get_skill_level(SKILL_POLICE)) /// Delay then gets + 0.5s per skill level, so long as not dead or cuffed. if(!(target.stat || target.handcuffed)) From 2e87d43ac83abece3fe6ff4098a0c8bc471296e6 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 19:57:35 +0000 Subject: [PATCH 29/99] Automatic changelog for PR #5320 [ci skip] --- html/changelogs/AutoChangeLog-pr-5320.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5320.yml diff --git a/html/changelogs/AutoChangeLog-pr-5320.yml b/html/changelogs/AutoChangeLog-pr-5320.yml new file mode 100644 index 000000000000..32cd4fc8943d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5320.yml @@ -0,0 +1,4 @@ +author: "Birdtalon" +delete-after: True +changes: + - bugfix: "Runtime in inventory.dm" \ No newline at end of file From 5a24a69b1d6a17e63f928d51c6ce636b5c24cb12 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Fri, 29 Dec 2023 19:33:51 +0000 Subject: [PATCH 30/99] Fixes the failure message when trying to switch pyro fuels (#5321) # About the pull request Edits the pyro spec's fuel pack a bit to make it *slightly* more bug-proof, and to fix it sometimes giving weird failure messages like these: ![image](https://github.com/cmss13-devs/cmss13/assets/57483089/2fa746d0-acc6-402b-ad17-e8fff5f4e3cd) ![image](https://github.com/cmss13-devs/cmss13/assets/57483089/67cef060-55a4-4897-9e52-f6d01e43d3d1) This was caused by me in #5121, presumably because I misread how the check was handled. # Explain why it's good for the game I broked it (sorry) # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: Fixed the pyro spec's fuel pack sometimes giving weird failure messages when trying to switch fuel. /:cl: --- code/game/objects/items/storage/large_holster.dm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/code/game/objects/items/storage/large_holster.dm b/code/game/objects/items/storage/large_holster.dm index b02dff1bdbcc..3f653926f8b3 100644 --- a/code/game/objects/items/storage/large_holster.dm +++ b/code/game/objects/items/storage/large_holster.dm @@ -253,9 +253,12 @@ to_chat(user, SPAN_WARNING("[src] must be equipped before you can switch types.")) return - var/obj/item/weapon/gun/flamer/M240T/flamer = user.get_active_hand() - if(!istype(flamer)) - to_chat(user, SPAN_WARNING("You must be holding [flamer] to use [src].")) + if(!linked_flamer) + to_chat(user, SPAN_WARNING("An incinerator unit must be linked in order to switch fuel types.")) + return + + if(user.get_active_hand() != linked_flamer) + to_chat(user, SPAN_WARNING("You must be holding [linked_flamer] to use [src].")) return if(!active_fuel) @@ -276,8 +279,8 @@ to_chat(user, "You switch the fuel tank to [active_fuel.caliber]") playsound(src, 'sound/machines/click.ogg', 25, TRUE) - flamer.current_mag = active_fuel - flamer.update_icon() + linked_flamer.current_mag = active_fuel + linked_flamer.update_icon() return TRUE From d46e38c9318d258de40eac4b530924b9fb4a4b42 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Fri, 29 Dec 2023 20:13:00 +0000 Subject: [PATCH 31/99] Automatic changelog for PR #5321 [ci skip] --- html/changelogs/AutoChangeLog-pr-5321.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5321.yml diff --git a/html/changelogs/AutoChangeLog-pr-5321.yml b/html/changelogs/AutoChangeLog-pr-5321.yml new file mode 100644 index 000000000000..e9e39a2c8c87 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5321.yml @@ -0,0 +1,4 @@ +author: "SabreML" +delete-after: True +changes: + - bugfix: "Fixed the pyro spec's fuel pack sometimes giving weird failure messages when trying to switch fuel." \ No newline at end of file From c4a5c286727951a75e35225a84810a37b9b7cd4d Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sat, 30 Dec 2023 01:08:58 +0000 Subject: [PATCH 32/99] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-5030.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5307.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5308.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5315.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5317.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5319.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5320.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5321.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5323.yml | 5 ----- html/changelogs/archive/2023-12.yml | 21 +++++++++++++++++++++ 10 files changed, 21 insertions(+), 37 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-5030.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5307.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5308.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5315.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5317.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5319.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5320.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5321.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5323.yml diff --git a/html/changelogs/AutoChangeLog-pr-5030.yml b/html/changelogs/AutoChangeLog-pr-5030.yml deleted file mode 100644 index 0cce25ff019a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5030.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Zonespace27" -delete-after: True -changes: - - rscadd: "Added a tutorial system for various roles (and just general information), find it in the lobby screen." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5307.yml b/html/changelogs/AutoChangeLog-pr-5307.yml deleted file mode 100644 index 3047d03d8e82..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5307.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mullenpaul" -delete-after: True -changes: - - refactor: "tgui js components now jsx" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5308.yml b/html/changelogs/AutoChangeLog-pr-5308.yml deleted file mode 100644 index 3adc1465faaf..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5308.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "cuberound" -delete-after: True -changes: - - bugfix: "m56d can not longer shoot backwards when facing north" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5315.yml b/html/changelogs/AutoChangeLog-pr-5315.yml deleted file mode 100644 index c5dc61beb308..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5315.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - qol: "Made the designation of a tunnel display in chat when a player enters it." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5317.yml b/html/changelogs/AutoChangeLog-pr-5317.yml deleted file mode 100644 index b5f7cd72accb..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5317.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Cthulhu80" -delete-after: True -changes: - - bugfix: "fixes immobilized mobs being able to buckle themselves" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5319.yml b/html/changelogs/AutoChangeLog-pr-5319.yml deleted file mode 100644 index d9582b58f9bc..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5319.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed the CAS laser cannon only setting fire to a single tile, rather a 7x7 range." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5320.yml b/html/changelogs/AutoChangeLog-pr-5320.yml deleted file mode 100644 index 32cd4fc8943d..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5320.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Birdtalon" -delete-after: True -changes: - - bugfix: "Runtime in inventory.dm" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5321.yml b/html/changelogs/AutoChangeLog-pr-5321.yml deleted file mode 100644 index e9e39a2c8c87..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5321.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed the pyro spec's fuel pack sometimes giving weird failure messages when trying to switch fuel." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5323.yml b/html/changelogs/AutoChangeLog-pr-5323.yml deleted file mode 100644 index 1a521533c287..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5323.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "InsaneRed" -delete-after: True -changes: - - qol: "\"View Playtime\" is now under the \"Records\" section under OOC" - - qol: "\"Remove Your Splints\" is now under the \"IC\" section." \ No newline at end of file diff --git a/html/changelogs/archive/2023-12.yml b/html/changelogs/archive/2023-12.yml index 73cd5f8771a1..e4245e7d5cbc 100644 --- a/html/changelogs/archive/2023-12.yml +++ b/html/changelogs/archive/2023-12.yml @@ -535,3 +535,24 @@ sleepynecrons: - imageadd: new sprites for predalien, predlarva and weeded corpse - imageadd: added predalien wound overlays +2023-12-30: + Birdtalon: + - bugfix: Runtime in inventory.dm + Cthulhu80: + - bugfix: fixes immobilized mobs being able to buckle themselves + InsaneRed: + - qol: '"View Playtime" is now under the "Records" section under OOC' + - qol: '"Remove Your Splints" is now under the "IC" section.' + SabreML: + - bugfix: Fixed the CAS laser cannon only setting fire to a single tile, rather + a 7x7 range. + - qol: Made the designation of a tunnel display in chat when a player enters it. + - bugfix: Fixed the pyro spec's fuel pack sometimes giving weird failure messages + when trying to switch fuel. + Zonespace27: + - rscadd: Added a tutorial system for various roles (and just general information), + find it in the lobby screen. + cuberound: + - bugfix: m56d can not longer shoot backwards when facing north + mullenpaul: + - refactor: tgui js components now jsx From 0533a419a3007d6dbaa55b91a14b41b3ed64fc05 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Sat, 30 Dec 2023 03:57:02 +0000 Subject: [PATCH 33/99] Fixes the Hive Status error when the Queen dies (#5316) # About the pull request Fixes the Hive Status window showing an error message when the Queen dies. For xeno players, the interface just closes. For observing players, the interface will show 'The Hive has no Queen!' where the queen's location was previously. (The bug actually causing the error should be fixed too now) (Note: I'm not quite sure what the `tgui-panel.bundle.css` diff is from, but it kept modifying itself whenever I compiled so I figured it was something related to this.) # Explain why it's good for the game Fixes #4330 # Testing Photographs and Procedure
Screenshots & Videos **Testing queen spawn and death as the queen, as an observer, and as a xeno:** https://github.com/cmss13-devs/cmss13/assets/57483089/ba3b2960-d4ce-4be4-af6b-6daae2d10ac1
# Changelog :cl: fix: Fixed the Hive Status window showing an error message when the Queen dies. /:cl: --- .../mob/living/carbon/xenomorph/Xenomorph.dm | 6 +++--- .../living/carbon/xenomorph/hive_status.dm | 19 +++++++++---------- .../living/carbon/xenomorph/hive_status_ui.dm | 8 +++++++- tgui/packages/tgui/interfaces/HiveStatus.jsx | 14 ++++++++++---- tgui/public/tgui-panel.bundle.css | 4 ++-- 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index e924835f5882..08f884d3a69d 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -432,6 +432,9 @@ if(mob_size < MOB_SIZE_BIG) mob_flags |= SQUEEZE_UNDER_VEHICLES + GLOB.living_xeno_list += src + GLOB.xeno_mob_list += src + // More setup stuff for names, abilities etc update_icon_source() generate_name() @@ -453,9 +456,6 @@ //Begin SStracking SStracking.start_tracking("hive_[src.hivenumber]", src) - GLOB.living_xeno_list += src - GLOB.xeno_mob_list += src - //WO GAMEMODE if(SSticker?.mode?.hardcore) hardcore = 1 //Prevents healing and queen evolution diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status.dm b/code/modules/mob/living/carbon/xenomorph/hive_status.dm index 83a90ded4205..3c8eb51a8155 100644 --- a/code/modules/mob/living/carbon/xenomorph/hive_status.dm +++ b/code/modules/mob/living/carbon/xenomorph/hive_status.dm @@ -422,28 +422,27 @@ // The idea is that we sort this list, and use it as a "key" for all the other information (especially the nicknumber) // in the hive status UI. That way we can minimize the amount of sorts performed by only calling this when xenos are created/disposed /datum/hive_status/proc/get_xeno_keys() - var/list/xenos[totalXenos.len] + var/list/xenos = list() - var/index = 1 - var/useless_slots = 0 for(var/mob/living/carbon/xenomorph/X in totalXenos) if(should_block_game_interaction(X)) var/area/A = get_area(X) if(!(A.flags_atom & AREA_ALLOW_XENO_JOIN)) - useless_slots++ continue - // Insert without doing list merging - xenos[index++] = list( + if(!(X in GLOB.living_xeno_list)) + continue + + // This looks weird, but in DM adding List A to List B actually adds each item in List B to List A, not List B itself. + // Having a nested list like this sort of tricks it into adding the list instead. + // In this case this results in an array of different 'xeno' dictionaries, rather than just a dictionary. + xenos += list(list( "nicknumber" = X.nicknumber, "tier" = X.tier, // This one is only important for sorting "is_leader" = (IS_XENO_LEADER(X)), "is_queen" = istype(X.caste, /datum/caste_datum/queen), "caste_type" = X.caste_type - ) - - // Clear nulls from the xenos list - xenos.len -= useless_slots + )) // Make it all nice and fancy by sorting the list before returning it var/list/sorted_keys = sort_xeno_keys(xenos) diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm index a71ddb7de292..4e71b9a2202f 100644 --- a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm +++ b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm @@ -123,6 +123,10 @@ if(isobserver(user)) return UI_INTERACTIVE + // If the Queen died or is otherwise missing. + if(!assoc_hive.living_xeno_queen) + return UI_CLOSE + /datum/hive_status_ui/ui_data(mob/user) . = list() .["total_xenos"] = total_xenos @@ -131,7 +135,9 @@ .["xeno_keys"] = xeno_keys .["xeno_info"] = xeno_info .["xeno_vitals"] = xeno_vitals - .["queen_location"] = get_area_name(assoc_hive.living_xeno_queen) + .["queen_location"] = null + if(assoc_hive.living_xeno_queen) + .["queen_location"] = get_area_name(assoc_hive.living_xeno_queen) .["hive_location"] = hive_location .["burrowed_larva"] = burrowed_larva .["evilution_level"] = evilution_level diff --git a/tgui/packages/tgui/interfaces/HiveStatus.jsx b/tgui/packages/tgui/interfaces/HiveStatus.jsx index c621430a9f7c..048eb1f6df7b 100644 --- a/tgui/packages/tgui/interfaces/HiveStatus.jsx +++ b/tgui/packages/tgui/interfaces/HiveStatus.jsx @@ -117,10 +117,16 @@ const GeneralInformation = (props, context) => { return ( - -

The Queen is in:

-

{queen_location}

-
+ {queen_location === null ? ( + +

The Hive has no Queen!

+
+ ) : ( + +

The Queen is in:

+

{queen_location}

+
+ )} {!!hive_location && (

The Hive location is:

diff --git a/tgui/public/tgui-panel.bundle.css b/tgui/public/tgui-panel.bundle.css index a1e5060c698b..10fb3458b06b 100644 --- a/tgui/public/tgui-panel.bundle.css +++ b/tgui/public/tgui-panel.bundle.css @@ -1,2 +1,2 @@ -html,body{box-sizing:border-box;height:100%;margin:0;font-size:12px}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif}*,*:before,*:after{box-sizing:inherit}h1,h2,h3,h4,h5,h6{display:block;margin:0;padding:6px 0;padding:.5rem 0}h1{font-size:18px;font-size:1.5rem}h2{font-size:16px;font-size:1.333rem}h3{font-size:14px;font-size:1.167rem}h4{font-size:12px;font-size:1rem}td,th{vertical-align:baseline;text-align:left}.candystripe:nth-child(odd){background-color:rgba(0,0,0,.25)}.color-black{color:#1a1a1a !important}.color-white{color:#fff !important}.color-red{color:#df3e3e !important}.color-orange{color:#f37f33 !important}.color-yellow{color:#fbda21 !important}.color-olive{color:#cbe41c !important}.color-green{color:#25ca4c !important}.color-teal{color:#00d6cc !important}.color-blue{color:#2e93de !important}.color-dark-blue{color:#005fa7 !important}.color-violet{color:#7349cf !important}.color-purple{color:#ad45d0 !important}.color-pink{color:#e34da1 !important}.color-brown{color:#b97447 !important}.color-grey{color:#848484 !important}.color-light-grey{color:#b3b3b3 !important}.color-good{color:#68c22d !important}.color-average{color:#f29a29 !important}.color-bad{color:#df3e3e !important}.color-label{color:#8b9bb0 !important}.color-xeno{color:#664573 !important}.color-bg-black{background-color:#000 !important}.color-bg-white{background-color:#d9d9d9 !important}.color-bg-red{background-color:#bd2020 !important}.color-bg-orange{background-color:#d95e0c !important}.color-bg-yellow{background-color:#d9b804 !important}.color-bg-olive{background-color:#9aad14 !important}.color-bg-green{background-color:#1b9638 !important}.color-bg-teal{background-color:#009a93 !important}.color-bg-blue{background-color:#1c71b1 !important}.color-bg-dark-blue{background-color:#003e6e !important}.color-bg-violet{background-color:#552dab !important}.color-bg-purple{background-color:#8b2baa !important}.color-bg-pink{background-color:#cf2082 !important}.color-bg-brown{background-color:#8c5836 !important}.color-bg-grey{background-color:#646464 !important}.color-bg-light-grey{background-color:#919191 !important}.color-bg-good{background-color:#4d9121 !important}.color-bg-average{background-color:#cd7a0d !important}.color-bg-bad{background-color:#bd2020 !important}.color-bg-label{background-color:#657a94 !important}.color-bg-xeno{background-color:#462f4e !important}.debug-layout,.debug-layout *:not(g):not(path){color:rgba(255,255,255,.9) !important;background:transparent !important;outline:1px solid rgba(255,255,255,.5) !important;box-shadow:none !important;filter:none !important}.debug-layout:hover,.debug-layout *:not(g):not(path):hover{outline-color:rgba(255,255,255,.8) !important}.outline-dotted{outline-style:dotted !important}.outline-dashed{outline-style:dashed !important}.outline-solid{outline-style:solid !important}.outline-double{outline-style:double !important}.outline-groove{outline-style:groove !important}.outline-ridge{outline-style:ridge !important}.outline-inset{outline-style:inset !important}.outline-outset{outline-style:outset !important}.outline-color-black{outline:.167rem solid #1a1a1a !important}.outline-color-white{outline:.167rem solid #fff !important}.outline-color-red{outline:.167rem solid #df3e3e !important}.outline-color-orange{outline:.167rem solid #f37f33 !important}.outline-color-yellow{outline:.167rem solid #fbda21 !important}.outline-color-olive{outline:.167rem solid #cbe41c !important}.outline-color-green{outline:.167rem solid #25ca4c !important}.outline-color-teal{outline:.167rem solid #00d6cc !important}.outline-color-blue{outline:.167rem solid #2e93de !important}.outline-color-dark-blue{outline:.167rem solid #005fa7 !important}.outline-color-violet{outline:.167rem solid #7349cf !important}.outline-color-purple{outline:.167rem solid #ad45d0 !important}.outline-color-pink{outline:.167rem solid #e34da1 !important}.outline-color-brown{outline:.167rem solid #b97447 !important}.outline-color-grey{outline:.167rem solid #848484 !important}.outline-color-light-grey{outline:.167rem solid #b3b3b3 !important}.outline-color-good{outline:.167rem solid #68c22d !important}.outline-color-average{outline:.167rem solid #f29a29 !important}.outline-color-bad{outline:.167rem solid #df3e3e !important}.outline-color-label{outline:.167rem solid #8b9bb0 !important}.outline-color-xeno{outline:.167rem solid #664573 !important}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-baseline{text-align:baseline}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-pre{white-space:pre}.text-bold{font-weight:bold}.text-italic{font-style:italic}.text-underline{text-decoration:underline}.BlockQuote{color:#8b9bb0;border-left:.1666666667em solid #8b9bb0;padding-left:.5em;margin-bottom:.5em}.BlockQuote:last-child{margin-bottom:0}.Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.Button:last-child{margin-right:0;margin-bottom:0}.Button .fa,.Button .fas,.Button .far{margin-left:-0.25em;margin-right:-0.25em;min-width:1.333em;text-align:center}.Button--hasContent .fa,.Button--hasContent .fas,.Button--hasContent .far{margin-right:.25em}.Button--hasContent.Button--iconPosition--right .fa,.Button--hasContent.Button--iconPosition--right .fas,.Button--hasContent.Button--iconPosition--right .far{margin-right:0px;margin-left:3px}.Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.Button--fluid{display:block;margin-left:0;margin-right:0}.Button--circular{border-radius:50%}.Button--compact{padding:0 .25em;line-height:1.333em}.Button--color--black{transition:color 50ms,background-color 50ms;background-color:#000;color:#fff}.Button--color--black:hover{transition:color 0ms,background-color 0ms}.Button--color--black:focus{transition:color 100ms,background-color 100ms}.Button--color--black:hover,.Button--color--black:focus{background-color:#131313;color:#fff}.Button--color--white{transition:color 50ms,background-color 50ms;background-color:#d9d9d9;color:#000}.Button--color--white:hover{transition:color 0ms,background-color 0ms}.Button--color--white:focus{transition:color 100ms,background-color 100ms}.Button--color--white:hover,.Button--color--white:focus{background-color:#f8f8f8;color:#000}.Button--color--red{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--red:hover{transition:color 0ms,background-color 0ms}.Button--color--red:focus{transition:color 100ms,background-color 100ms}.Button--color--red:hover,.Button--color--red:focus{background-color:#dc4848;color:#fff}.Button--color--orange{transition:color 50ms,background-color 50ms;background-color:#d95e0c;color:#fff}.Button--color--orange:hover{transition:color 0ms,background-color 0ms}.Button--color--orange:focus{transition:color 100ms,background-color 100ms}.Button--color--orange:hover,.Button--color--orange:focus{background-color:#f0853f;color:#fff}.Button--color--yellow{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--yellow:hover{transition:color 0ms,background-color 0ms}.Button--color--yellow:focus{transition:color 100ms,background-color 100ms}.Button--color--yellow:hover,.Button--color--yellow:focus{background-color:#f5d72e;color:#000}.Button--color--olive{transition:color 50ms,background-color 50ms;background-color:#9aad14;color:#fff}.Button--color--olive:hover{transition:color 0ms,background-color 0ms}.Button--color--olive:focus{transition:color 100ms,background-color 100ms}.Button--color--olive:hover,.Button--color--olive:focus{background-color:#c4da2b;color:#fff}.Button--color--green{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--color--green:hover{transition:color 0ms,background-color 0ms}.Button--color--green:focus{transition:color 100ms,background-color 100ms}.Button--color--green:hover,.Button--color--green:focus{background-color:#32c154;color:#fff}.Button--color--teal{transition:color 50ms,background-color 50ms;background-color:#009a93;color:#fff}.Button--color--teal:hover{transition:color 0ms,background-color 0ms}.Button--color--teal:focus{transition:color 100ms,background-color 100ms}.Button--color--teal:hover,.Button--color--teal:focus{background-color:#13c4bc;color:#fff}.Button--color--blue{transition:color 50ms,background-color 50ms;background-color:#1c71b1;color:#fff}.Button--color--blue:hover{transition:color 0ms,background-color 0ms}.Button--color--blue:focus{transition:color 100ms,background-color 100ms}.Button--color--blue:hover,.Button--color--blue:focus{background-color:#3a95d9;color:#fff}.Button--color--dark-blue{transition:color 50ms,background-color 50ms;background-color:#003e6e;color:#fff}.Button--color--dark-blue:hover{transition:color 0ms,background-color 0ms}.Button--color--dark-blue:focus{transition:color 100ms,background-color 100ms}.Button--color--dark-blue:hover,.Button--color--dark-blue:focus{background-color:#135b92;color:#fff}.Button--color--violet{transition:color 50ms,background-color 50ms;background-color:#552dab;color:#fff}.Button--color--violet:hover{transition:color 0ms,background-color 0ms}.Button--color--violet:focus{transition:color 100ms,background-color 100ms}.Button--color--violet:hover,.Button--color--violet:focus{background-color:#7953cc;color:#fff}.Button--color--purple{transition:color 50ms,background-color 50ms;background-color:#8b2baa;color:#fff}.Button--color--purple:hover{transition:color 0ms,background-color 0ms}.Button--color--purple:focus{transition:color 100ms,background-color 100ms}.Button--color--purple:hover,.Button--color--purple:focus{background-color:#ad4fcd;color:#fff}.Button--color--pink{transition:color 50ms,background-color 50ms;background-color:#cf2082;color:#fff}.Button--color--pink:hover{transition:color 0ms,background-color 0ms}.Button--color--pink:focus{transition:color 100ms,background-color 100ms}.Button--color--pink:hover,.Button--color--pink:focus{background-color:#e257a5;color:#fff}.Button--color--brown{transition:color 50ms,background-color 50ms;background-color:#8c5836;color:#fff}.Button--color--brown:hover{transition:color 0ms,background-color 0ms}.Button--color--brown:focus{transition:color 100ms,background-color 100ms}.Button--color--brown:hover,.Button--color--brown:focus{background-color:#b47851;color:#fff}.Button--color--grey{transition:color 50ms,background-color 50ms;background-color:#646464;color:#fff}.Button--color--grey:hover{transition:color 0ms,background-color 0ms}.Button--color--grey:focus{transition:color 100ms,background-color 100ms}.Button--color--grey:hover,.Button--color--grey:focus{background-color:#868686;color:#fff}.Button--color--light-grey{transition:color 50ms,background-color 50ms;background-color:#919191;color:#fff}.Button--color--light-grey:hover{transition:color 0ms,background-color 0ms}.Button--color--light-grey:focus{transition:color 100ms,background-color 100ms}.Button--color--light-grey:hover,.Button--color--light-grey:focus{background-color:#bababa;color:#fff}.Button--color--good{transition:color 50ms,background-color 50ms;background-color:#4d9121;color:#fff}.Button--color--good:hover{transition:color 0ms,background-color 0ms}.Button--color--good:focus{transition:color 100ms,background-color 100ms}.Button--color--good:hover,.Button--color--good:focus{background-color:#6cba39;color:#fff}.Button--color--average{transition:color 50ms,background-color 50ms;background-color:#cd7a0d;color:#fff}.Button--color--average:hover{transition:color 0ms,background-color 0ms}.Button--color--average:focus{transition:color 100ms,background-color 100ms}.Button--color--average:hover,.Button--color--average:focus{background-color:#ed9d35;color:#fff}.Button--color--bad{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--bad:hover{transition:color 0ms,background-color 0ms}.Button--color--bad:focus{transition:color 100ms,background-color 100ms}.Button--color--bad:hover,.Button--color--bad:focus{background-color:#dc4848;color:#fff}.Button--color--label{transition:color 50ms,background-color 50ms;background-color:#657a94;color:#fff}.Button--color--label:hover{transition:color 0ms,background-color 0ms}.Button--color--label:focus{transition:color 100ms,background-color 100ms}.Button--color--label:hover,.Button--color--label:focus{background-color:#91a1b3;color:#fff}.Button--color--xeno{transition:color 50ms,background-color 50ms;background-color:#462f4e;color:#fff}.Button--color--xeno:hover{transition:color 0ms,background-color 0ms}.Button--color--xeno:focus{transition:color 100ms,background-color 100ms}.Button--color--xeno:hover,.Button--color--xeno:focus{background-color:#64496d;color:#fff}.Button--color--default{transition:color 50ms,background-color 50ms;background-color:#3e6189;color:#fff}.Button--color--default:hover{transition:color 0ms,background-color 0ms}.Button--color--default:focus{transition:color 100ms,background-color 100ms}.Button--color--default:hover,.Button--color--default:focus{background-color:#5c83b0;color:#fff}.Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--caution:hover{transition:color 0ms,background-color 0ms}.Button--color--caution:focus{transition:color 100ms,background-color 100ms}.Button--color--caution:hover,.Button--color--caution:focus{background-color:#f5d72e;color:#000}.Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--danger:hover{transition:color 0ms,background-color 0ms}.Button--color--danger:focus{transition:color 100ms,background-color 100ms}.Button--color--danger:hover,.Button--color--danger:focus{background-color:#dc4848;color:#fff}.Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#202020;color:#fff;background-color:rgba(32,32,32,0);color:rgba(255,255,255,.5)}.Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.Button--color--transparent:focus{transition:color 100ms,background-color 100ms}.Button--color--transparent:hover,.Button--color--transparent:focus{background-color:#383838;color:#fff}.Button--disabled{background-color:#999 !important}.Button--selected{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--selected:hover{transition:color 0ms,background-color 0ms}.Button--selected:focus{transition:color 100ms,background-color 100ms}.Button--selected:hover,.Button--selected:focus{background-color:#32c154;color:#fff}.Button--flex{display:inline-flex;flex-direction:column}.Button--flex--fluid{width:100%}.Button--verticalAlignContent--top{justify-content:flex-start}.Button--verticalAlignContent--middle{justify-content:center}.Button--verticalAlignContent--bottom{justify-content:flex-end}.Button__content{display:block;align-self:stretch}.ColorBox{display:inline-block;width:1em;height:1em;line-height:1em;text-align:center}.Dimmer{display:flex;justify-content:center;align-items:center;position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(0,0,0,.75);z-index:1}.Divider--horizontal{margin:.5em 0}.Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Divider--vertical{height:100%;margin:0 .5em}.Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Dropdown{position:relative}.Dropdown__control{position:relative;display:inline-block;font-family:Verdana,sans-serif;font-size:1em;width:8.3333333333em;line-height:1.4166666667em;user-select:none}.Dropdown__arrow-button{float:right;padding-left:.35em;width:1.2em;height:1.8333333333em;border-left:.0833333333em solid #000;border-left:.0833333333em solid rgba(0,0,0,.25)}.Dropdown__menu{position:absolute;overflow-y:auto;z-index:5;width:8.3333333333em;max-height:16.6666666667em;overflow-y:scroll;border-radius:0 0 .1666666667em .1666666667em;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menu-noscroll{position:absolute;overflow-y:auto;z-index:5;width:8.3333333333em;max-height:16.6666666667em;border-radius:0 0 .1666666667em .1666666667em;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menuentry{padding:.1666666667em .3333333333em;font-family:Verdana,sans-serif;font-size:1em;line-height:1.4166666667em;transition:background-color 100ms ease-out}.Dropdown__menuentry:hover{background-color:rgba(255,255,255,.2);transition:background-color 0ms}.Dropdown__over{top:auto;bottom:100%}.Dropdown__selected-text{display:inline-block;text-overflow:ellipsis;white-space:nowrap;height:1.4166666667em;width:calc(100% - 1.2em)}.Flex{display:-ms-flexbox;display:flex}.Flex--inline{display:inline-flex}.Flex--iefix{display:block}.Flex--iefix.Flex--inline{display:inline-block}.Flex__item--iefix{display:inline-block}.Flex--iefix--column>.Flex__item--iefix{display:block}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:"Consolas",monospace}.Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto;margin-bottom:-0.2em;cursor:n-resize}.Knob:after{content:".";color:transparent;line-height:2.5em}.Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 100%);border-radius:50%;box-shadow:0 .05em .5em 0 rgba(0,0,0,.5)}.Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:rgba(255,255,255,.9)}.Knob__popupValue{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.Knob__ringTrackPivot{transform:rotateZ(135deg)}.Knob__ringTrack{fill:transparent;stroke:rgba(255,255,255,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.Knob__ringFillPivot{transform:rotateZ(135deg)}.Knob--bipolar .Knob__ringFillPivot{transform:rotateZ(270deg)}.Knob__ringFill{fill:transparent;stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms ease-out}.Knob--color--black .Knob__ringFill{stroke:#1a1a1a}.Knob--color--white .Knob__ringFill{stroke:#fff}.Knob--color--red .Knob__ringFill{stroke:#df3e3e}.Knob--color--orange .Knob__ringFill{stroke:#f37f33}.Knob--color--yellow .Knob__ringFill{stroke:#fbda21}.Knob--color--olive .Knob__ringFill{stroke:#cbe41c}.Knob--color--green .Knob__ringFill{stroke:#25ca4c}.Knob--color--teal .Knob__ringFill{stroke:#00d6cc}.Knob--color--blue .Knob__ringFill{stroke:#2e93de}.Knob--color--dark-blue .Knob__ringFill{stroke:#005fa7}.Knob--color--violet .Knob__ringFill{stroke:#7349cf}.Knob--color--purple .Knob__ringFill{stroke:#ad45d0}.Knob--color--pink .Knob__ringFill{stroke:#e34da1}.Knob--color--brown .Knob__ringFill{stroke:#b97447}.Knob--color--grey .Knob__ringFill{stroke:#848484}.Knob--color--light-grey .Knob__ringFill{stroke:#b3b3b3}.Knob--color--good .Knob__ringFill{stroke:#68c22d}.Knob--color--average .Knob__ringFill{stroke:#f29a29}.Knob--color--bad .Knob__ringFill{stroke:#df3e3e}.Knob--color--label .Knob__ringFill{stroke:#8b9bb0}.Knob--color--xeno .Knob__ringFill{stroke:#664573}.LabeledList{display:table;width:100%;width:calc(100% + 1em);border-collapse:collapse;border-spacing:0;margin:-0.25em -0.5em;margin-bottom:0;padding:0}.LabeledList__row{display:table-row}.LabeledList__row:last-child .LabeledList__cell{padding-bottom:0}.LabeledList__cell{display:table-cell;margin:0;padding:.25em .5em;border:0;text-align:left}.LabeledList__label--nowrap{width:1%;white-space:nowrap;min-width:5em}.LabeledList__buttons{width:.1%;white-space:nowrap;text-align:right;padding-top:.0833333333em;padding-bottom:0}.Modal{background-color:#202020;max-width:calc(100% - 1rem);padding:1rem}.NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:bold;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg, transparent, transparent 0.8333333333em, rgba(0, 0, 0, 0.1) 0.8333333333em, rgba(0, 0, 0, 0.1) 1.6666666667em)}.NoticeBox--color--black{color:#fff;background-color:#000}.NoticeBox--color--white{color:#000;background-color:#b3b3b3}.NoticeBox--color--red{color:#fff;background-color:#701f1f}.NoticeBox--color--orange{color:#fff;background-color:#854114}.NoticeBox--color--yellow{color:#000;background-color:#83710d}.NoticeBox--color--olive{color:#000;background-color:#576015}.NoticeBox--color--green{color:#fff;background-color:#174e24}.NoticeBox--color--teal{color:#fff;background-color:#064845}.NoticeBox--color--blue{color:#fff;background-color:#1b4565}.NoticeBox--color--dark-blue{color:#fff;background-color:#02121f}.NoticeBox--color--violet{color:#fff;background-color:#3b2864}.NoticeBox--color--purple{color:#fff;background-color:#542663}.NoticeBox--color--pink{color:#fff;background-color:#802257}.NoticeBox--color--brown{color:#fff;background-color:#4c3729}.NoticeBox--color--grey{color:#fff;background-color:#3e3e3e}.NoticeBox--color--light-grey{color:#fff;background-color:#6a6a6a}.NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.NoticeBox--color--average{color:#fff;background-color:#7b4e13}.NoticeBox--color--bad{color:#fff;background-color:#701f1f}.NoticeBox--color--label{color:#fff;background-color:#53565a}.NoticeBox--color--xeno{color:#fff;background-color:#19161b}.NoticeBox--type--info{color:#fff;background-color:#235982}.NoticeBox--type--success{color:#fff;background-color:#1e662f}.NoticeBox--type--warning{color:#fff;background-color:#a95219}.NoticeBox--type--danger{color:#fff;background-color:#8f2828}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:"Consolas",monospace}.NumberInput{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#88bfff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.NumberInput--fluid{display:block}.NumberInput__content{margin-left:.5em}.NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #88bfff;background-color:#88bfff}.NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-width:.0833333333em !important;border-style:solid !important;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color 900ms ease-out}.ProgressBar__fill{position:absolute;top:-0.5px;left:0px;bottom:-0.5px}.ProgressBar__fill--animated{transition:background-color 900ms ease-out,width 900ms ease-out}.ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.ProgressBar--color--default{border:.0833333333em solid #3e6189}.ProgressBar--color--default .ProgressBar__fill{background-color:#3e6189}.ProgressBar--color--black{border-color:#000 !important}.ProgressBar--color--black .ProgressBar__fill{background-color:#000}.ProgressBar--color--white{border-color:#d9d9d9 !important}.ProgressBar--color--white .ProgressBar__fill{background-color:#d9d9d9}.ProgressBar--color--red{border-color:#bd2020 !important}.ProgressBar--color--red .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--orange{border-color:#d95e0c !important}.ProgressBar--color--orange .ProgressBar__fill{background-color:#d95e0c}.ProgressBar--color--yellow{border-color:#d9b804 !important}.ProgressBar--color--yellow .ProgressBar__fill{background-color:#d9b804}.ProgressBar--color--olive{border-color:#9aad14 !important}.ProgressBar--color--olive .ProgressBar__fill{background-color:#9aad14}.ProgressBar--color--green{border-color:#1b9638 !important}.ProgressBar--color--green .ProgressBar__fill{background-color:#1b9638}.ProgressBar--color--teal{border-color:#009a93 !important}.ProgressBar--color--teal .ProgressBar__fill{background-color:#009a93}.ProgressBar--color--blue{border-color:#1c71b1 !important}.ProgressBar--color--blue .ProgressBar__fill{background-color:#1c71b1}.ProgressBar--color--dark-blue{border-color:#003e6e !important}.ProgressBar--color--dark-blue .ProgressBar__fill{background-color:#003e6e}.ProgressBar--color--violet{border-color:#552dab !important}.ProgressBar--color--violet .ProgressBar__fill{background-color:#552dab}.ProgressBar--color--purple{border-color:#8b2baa !important}.ProgressBar--color--purple .ProgressBar__fill{background-color:#8b2baa}.ProgressBar--color--pink{border-color:#cf2082 !important}.ProgressBar--color--pink .ProgressBar__fill{background-color:#cf2082}.ProgressBar--color--brown{border-color:#8c5836 !important}.ProgressBar--color--brown .ProgressBar__fill{background-color:#8c5836}.ProgressBar--color--grey{border-color:#646464 !important}.ProgressBar--color--grey .ProgressBar__fill{background-color:#646464}.ProgressBar--color--light-grey{border-color:#919191 !important}.ProgressBar--color--light-grey .ProgressBar__fill{background-color:#919191}.ProgressBar--color--good{border-color:#4d9121 !important}.ProgressBar--color--good .ProgressBar__fill{background-color:#4d9121}.ProgressBar--color--average{border-color:#cd7a0d !important}.ProgressBar--color--average .ProgressBar__fill{background-color:#cd7a0d}.ProgressBar--color--bad{border-color:#bd2020 !important}.ProgressBar--color--bad .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--label{border-color:#657a94 !important}.ProgressBar--color--label .ProgressBar__fill{background-color:#657a94}.ProgressBar--color--xeno{border-color:#462f4e !important}.ProgressBar--color--xeno .ProgressBar__fill{background-color:#462f4e}.Section{position:relative;margin-bottom:.5em;background-color:#131313;background-color:#131313;box-sizing:border-box}.Section:last-child{margin-bottom:0}.Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.Section__titleText{font-size:1.1666666667em;font-weight:bold;color:#fff}.Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.Section__rest{position:relative}.Section__content{padding:.66em .5em}.Section--fitted>.Section__rest>.Section__content{padding:0}.Section--fill{display:flex;flex-direction:column;height:100%}.Section--fill>.Section__rest{flex-grow:1}.Section--fill>.Section__rest>.Section__content{height:100%}.Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.Section--fill.Section--iefix{display:table !important;width:100% !important;height:100% !important;border-collapse:collapse;border-spacing:0}.Section--fill.Section--iefix>.Section__rest{display:table-row !important;height:100% !important}.Section--scrollable{overflow-x:hidden;overflow-y:hidden}.Section--scrollable>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:hidden}.Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:hidden;overflow-x:scroll}.Section--scrollable.Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.Section--scrollable.Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:scroll}.Section .Section{background-color:transparent;margin-left:-0.5em;margin-right:-0.5em}.Section .Section:first-child{margin-top:-0.5em}.Section .Section .Section__titleText{font-size:1.0833333333em}.Section .Section .Section .Section__titleText{font-size:1em}.Slider{cursor:e-resize}.Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none !important}.Slider__cursor{position:absolute;top:0;right:-.0833333333em;bottom:0;width:0;border-left:.1666666667em solid #fff}.Slider__pointer{position:absolute;right:-.4166666667em;bottom:-.3333333333em;width:0;height:0;border-left:.4166666667em solid transparent;border-right:.4166666667em solid transparent;border-bottom:.4166666667em solid #fff}.Slider__popupValue{position:absolute;right:0;top:-2rem;font-size:1rem;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.Divider--horizontal{margin:.5em 0}.Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Divider--vertical{height:100%;margin:0 .5em}.Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--fill{height:100%}.Stack--horizontal>.Stack__item{margin-left:.5em}.Stack--horizontal>.Stack__item:first-child{margin-left:0}.Stack--vertical>.Stack__item{margin-top:.5em}.Stack--vertical>.Stack__item:first-child{margin-top:0}.Stack--horizontal>.Stack__divider:not(.Stack__divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--vertical>.Stack__divider:not(.Stack__divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Table{display:table;width:100%;border-collapse:collapse;border-spacing:0;margin:0}.Table--collapsing{width:auto}.Table__row{display:table-row}.Table__cell{display:table-cell;padding:0 .25em}.Table__cell:first-child{padding-left:0}.Table__cell:last-child{padding-right:0}.Table__row--header .Table__cell,.Table__cell--header{font-weight:bold;padding-bottom:.5em}.Table__cell--collapsing{width:1%;white-space:nowrap}.Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:#131313}.Tabs--fill{height:100%}.Section .Tabs{background-color:transparent}.Section:not(.Section--fitted) .Tabs{margin:0 -0.5em .5em}.Section:not(.Section--fitted) .Tabs:first-child{margin-top:-0.5em}.Tabs--vertical{flex-direction:column;padding:.25em 0 .25em .25em}.Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0 .25em}.Tabs--horizontal:last-child{margin-bottom:0}.Tabs__Tab{flex-grow:0}.Tabs--fluid .Tabs__Tab{flex-grow:1}.Tab{display:flex;align-items:center;justify-content:space-between;background-color:transparent;color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em}.Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075)}.Tab--selected{background-color:rgba(255,255,255,.125);color:#dfe7f0}.Tab__text{flex-grow:1;margin:0 .5em}.Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.Tabs--horizontal .Tab{border-top:.1666666667em solid transparent;border-bottom:.1666666667em solid transparent;border-top-left-radius:.25em;border-top-right-radius:.25em}.Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #d4dfec}.Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid transparent;border-right:.1666666667em solid transparent;border-top-left-radius:.25em;border-bottom-left-radius:.25em}.Tabs--vertical .Tab--selected{border-right:.1666666667em solid #d4dfec}.Tab--selected.Tab--color--black{color:#535353}.Tabs--horizontal .Tab--selected.Tab--color--black{border-bottom-color:#1a1a1a}.Tabs--vertical .Tab--selected.Tab--color--black{border-right-color:#1a1a1a}.Tab--selected.Tab--color--white{color:#fff}.Tabs--horizontal .Tab--selected.Tab--color--white{border-bottom-color:#fff}.Tabs--vertical .Tab--selected.Tab--color--white{border-right-color:#fff}.Tab--selected.Tab--color--red{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--red{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--red{border-right-color:#df3e3e}.Tab--selected.Tab--color--orange{color:#f69f66}.Tabs--horizontal .Tab--selected.Tab--color--orange{border-bottom-color:#f37f33}.Tabs--vertical .Tab--selected.Tab--color--orange{border-right-color:#f37f33}.Tab--selected.Tab--color--yellow{color:#fce358}.Tabs--horizontal .Tab--selected.Tab--color--yellow{border-bottom-color:#fbda21}.Tabs--vertical .Tab--selected.Tab--color--yellow{border-right-color:#fbda21}.Tab--selected.Tab--color--olive{color:#d8eb55}.Tabs--horizontal .Tab--selected.Tab--color--olive{border-bottom-color:#cbe41c}.Tabs--vertical .Tab--selected.Tab--color--olive{border-right-color:#cbe41c}.Tab--selected.Tab--color--green{color:#53e074}.Tabs--horizontal .Tab--selected.Tab--color--green{border-bottom-color:#25ca4c}.Tabs--vertical .Tab--selected.Tab--color--green{border-right-color:#25ca4c}.Tab--selected.Tab--color--teal{color:#21fff5}.Tabs--horizontal .Tab--selected.Tab--color--teal{border-bottom-color:#00d6cc}.Tabs--vertical .Tab--selected.Tab--color--teal{border-right-color:#00d6cc}.Tab--selected.Tab--color--blue{color:#62aee6}.Tabs--horizontal .Tab--selected.Tab--color--blue{border-bottom-color:#2e93de}.Tabs--vertical .Tab--selected.Tab--color--blue{border-right-color:#2e93de}.Tab--selected.Tab--color--dark-blue{color:#008ffd}.Tabs--horizontal .Tab--selected.Tab--color--dark-blue{border-bottom-color:#005fa7}.Tabs--vertical .Tab--selected.Tab--color--dark-blue{border-right-color:#005fa7}.Tab--selected.Tab--color--violet{color:#9676db}.Tabs--horizontal .Tab--selected.Tab--color--violet{border-bottom-color:#7349cf}.Tabs--vertical .Tab--selected.Tab--color--violet{border-right-color:#7349cf}.Tab--selected.Tab--color--purple{color:#c274db}.Tabs--horizontal .Tab--selected.Tab--color--purple{border-bottom-color:#ad45d0}.Tabs--vertical .Tab--selected.Tab--color--purple{border-right-color:#ad45d0}.Tab--selected.Tab--color--pink{color:#ea79b9}.Tabs--horizontal .Tab--selected.Tab--color--pink{border-bottom-color:#e34da1}.Tabs--vertical .Tab--selected.Tab--color--pink{border-right-color:#e34da1}.Tab--selected.Tab--color--brown{color:#ca9775}.Tabs--horizontal .Tab--selected.Tab--color--brown{border-bottom-color:#b97447}.Tabs--vertical .Tab--selected.Tab--color--brown{border-right-color:#b97447}.Tab--selected.Tab--color--grey{color:#a3a3a3}.Tabs--horizontal .Tab--selected.Tab--color--grey{border-bottom-color:#848484}.Tabs--vertical .Tab--selected.Tab--color--grey{border-right-color:#848484}.Tab--selected.Tab--color--light-grey{color:#c6c6c6}.Tabs--horizontal .Tab--selected.Tab--color--light-grey{border-bottom-color:#b3b3b3}.Tabs--vertical .Tab--selected.Tab--color--light-grey{border-right-color:#b3b3b3}.Tab--selected.Tab--color--good{color:#8cd95a}.Tabs--horizontal .Tab--selected.Tab--color--good{border-bottom-color:#68c22d}.Tabs--vertical .Tab--selected.Tab--color--good{border-right-color:#68c22d}.Tab--selected.Tab--color--average{color:#f5b35e}.Tabs--horizontal .Tab--selected.Tab--color--average{border-bottom-color:#f29a29}.Tabs--vertical .Tab--selected.Tab--color--average{border-right-color:#f29a29}.Tab--selected.Tab--color--bad{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--bad{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--bad{border-right-color:#df3e3e}.Tab--selected.Tab--color--label{color:#a8b4c4}.Tabs--horizontal .Tab--selected.Tab--color--label{border-bottom-color:#8b9bb0}.Tabs--vertical .Tab--selected.Tab--color--label{border-right-color:#8b9bb0}.Tab--selected.Tab--color--xeno{color:#9366a3}.Tabs--horizontal .Tab--selected.Tab--color--xeno{border-bottom-color:#664573}.Tabs--vertical .Tab--selected.Tab--color--xeno{border-right-color:#664573}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:"Consolas",monospace}.TextArea{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;background-color:#0a0a0a;margin-right:.1666666667em;line-height:1.4166666667em;box-sizing:border-box;width:100%}.TextArea--fluid{display:block;width:auto;height:auto}.TextArea--noborder{border:0px}.TextArea__textarea.TextArea__textarea--scrollable{overflow:auto;overflow-x:hidden;overflow-y:scroll}.TextArea__textarea{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;height:100%;font-size:1em;line-height:1.4166666667em;min-height:1.4166666667em;margin:0;padding:0 .5em;font-family:inherit;background-color:transparent;color:inherit;box-sizing:border-box;word-wrap:break-word;overflow:hidden}.TextArea__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.TextArea__textarea_custom{overflow:visible;white-space:pre-wrap}.Tooltip{z-index:2;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity 150ms ease-out;background-color:#000;color:#fff;box-shadow:.1em .1em 1.25em -0.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.Chat{color:#abc6ec}.Chat__badge{display:inline-block;min-width:.5em;font-size:.7em;padding:.2em .3em;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:crimson;border-radius:10px;transition:font-size 200ms ease-out}.Chat__badge:before{content:"x"}.Chat__badge--animate{font-size:.9em;transition:font-size 0ms}.Chat__scrollButton{position:fixed;right:2em;bottom:1em}.Chat__reconnected{font-size:.85em;text-align:center;margin:1em 0 2em}.Chat__reconnected:before{content:"Reconnected";display:inline-block;border-radius:1em;padding:0 .7em;color:#db2828;background-color:#131313}.Chat__reconnected:after{content:"";display:block;margin-top:-0.75em;border-bottom:.1666666667em solid #db2828}.Chat__highlight{color:#000}.Chat__highlight--restricted{color:#fff;background-color:#a00;font-weight:bold}.ChatMessage{word-wrap:break-word}.ChatMessage--highlighted{position:relative;border-left:.1666666667em solid #fd4;padding-left:.5em}.ChatMessage--highlighted:after{content:"";position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(255,221,68,.1);pointer-events:none}.Ping{position:relative;padding:.125em .25em;border:.0833333333em solid rgba(140,140,140,.5);border-radius:.25em;width:3.75em;text-align:right}.Ping__indicator{content:"";position:absolute;top:.5em;left:.5em;width:.5em;height:.5em;background-color:#888;border-radius:.25em}.Notifications{position:absolute;bottom:1em;left:1em;right:2em}.Notification{color:#fff;background-color:crimson;padding:.5em;margin:1em 0}.Notification:first-child{margin-top:0}.Notification:last-child{margin-bottom:0}.Layout,.Layout *{scrollbar-base-color:#181818;scrollbar-face-color:#363636;scrollbar-3dlight-color:#202020;scrollbar-highlight-color:#202020;scrollbar-track-color:#181818;scrollbar-arrow-color:#909090;scrollbar-shadow-color:#363636}.Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow-x:hidden;overflow-y:hidden}.Layout__content--scrollable{overflow-y:scroll;margin-bottom:0}.Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#202020;background-image:linear-gradient(to bottom, #202020 0%, #202020 100%)}.Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.Window__contentPadding:after{height:0}.Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(56,56,56,.25);pointer-events:none}.Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}em{font-style:normal;font-weight:bold}img{margin:0;padding:0;line-height:1;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}img.icon{height:1em;min-height:16px;width:auto;vertical-align:bottom}a{color:#397ea5}a.visited{color:#7c00e6}a:visited{color:#7c00e6}a.popt{text-decoration:none}.popup{position:fixed;top:50%;left:50%;background:#ddd}.popup .close{position:absolute;background:#aaa;top:0;right:0;color:#333;text-decoration:none;z-index:2;padding:0 10px;height:30px;line-height:30px}.popup .close:hover{background:#999}.popup .head{background:#999;color:#ddd;padding:0 10px;height:30px;line-height:30px;text-transform:uppercase;font-size:.9em;font-weight:bold;border-bottom:2px solid green}.popup input{border:1px solid #999;background:#fff;margin:0;padding:5px;outline:none;color:#333}.popup input[type=text]:hover,.popup input[type=text]:active,.popup input[type=text]:focus{border-color:green}.popup input[type=submit]{padding:5px 10px;background:#999;color:#ddd;text-transform:uppercase;font-size:.9em;font-weight:bold}.popup input[type=submit]:hover,.popup input[type=submit]:focus,.popup input[type=submit]:active{background:#aaa;cursor:pointer}.changeFont{padding:10px}.changeFont a{display:block;text-decoration:none;padding:3px;color:#333}.changeFont a:hover{background:#ccc}.highlightPopup{padding:10px;text-align:center}.highlightPopup input[type=text]{display:block;width:215px;text-align:left;margin-top:5px}.highlightPopup input.highlightColor{background-color:#ff0}.highlightPopup input.highlightTermSubmit{margin-top:5px}.contextMenu{background-color:#ddd;position:fixed;margin:2px;width:150px}.contextMenu a{display:block;padding:2px 5px;text-decoration:none;color:#333}.contextMenu a:hover{background-color:#ccc}.filterMessages{padding:5px}.filterMessages div{padding:2px 0}.icon-stack{height:1em;line-height:1em;width:1em;vertical-align:middle;margin-top:-2px}.motd{color:#a4bad6;font-family:Verdana,sans-serif;white-space:normal}.motd h1,.motd h2,.motd h3,.motd h4,.motd h5,.motd h6{color:#a4bad6;text-decoration:underline}.motd a,.motd a:link,.motd a:visited,.motd a:active,.motd a:hover{color:#a4bad6}.bold,.name,.prefix,.ooc,.looc,.adminooc,.admin,.medal,.yell{font-weight:bold}.italic,.italics{font-style:italic}.highlight{background:#ff0}h1,h2,h3,h4,h5,h6{color:#a4bad6;font-family:Georgia,Verdana,sans-serif}h1.alert,h2.alert{color:#a4bad6}em{font-style:normal;font-weight:bold}.ooc{font-weight:bold}.adminobserverooc{color:#09c;font-weight:bold}.adminooc{color:#3d5bc3;font-weight:bold}.adminsay{color:#9611d4;font-weight:bold}.admin{color:#5975da;font-weight:bold}.name{font-weight:bold}.deadsay{color:#e2c1ff}.binarysay{color:#1e90ff}.binarysay a{color:lime}.binarysay a:active,.binarysay a:visited{color:#8f8}.radio{color:#1ecc43}.sciradio{color:#c68cfa}.comradio{color:#fcdf03}.secradio{color:#dd3535}.medradio{color:#57b8f0}.engradio{color:#f37746}.suppradio{color:#b88646}.servradio{color:#6ca729}.syndradio{color:#8f4a4b}.gangradio{color:#ac2ea1}.centcomradio{color:#2681a5}.aiprivradio{color:#d65d95}.redteamradio{color:#f44}.blueteamradio{color:#3434fd}.greenteamradio{color:#34fd34}.yellowteamradio{color:#fdfd34}.yell{font-weight:bold}.alert{color:#d82020}.userdanger{color:#c51e1e;font-weight:bold;font-size:185%}.bolddanger{color:#c51e1e;font-weight:bold}.danger{color:#c51e1e}.warning{color:#c51e1e;font-style:italic}.alertwarning{color:red;font-weight:bold}.boldwarning{color:#c51e1e;font-style:italic;font-weight:bold}.announce{color:#c51e1e;font-weight:bold}.boldannounce{color:#c51e1e;font-weight:bold}.bigannounce{font-weight:bold;font-size:115%}.greenannounce{color:#059223;font-weight:bold}.rose{color:#ff5050}.info{color:#9ab0ff}.notice{color:#6685f5}.staff_ic{color:#6685f5}.tinynotice{color:#6685f5;font-size:85%}.tinynoticeital{color:#6685f5;font-style:italic;font-size:85%}.smallnotice{color:#6685f5;font-size:90%}.smallnoticeital{color:#6685f5;font-style:italic;font-size:90%}.boldnotice{color:#6685f5;font-weight:bold}.hear{color:#6685f5;font-style:italic}.adminnotice{color:#6685f5}.adminhelp{color:red;font-weight:bold}.unconscious{color:#a4bad6;font-weight:bold}.suicide{color:#ff5050;font-style:italic}.green{color:#059223}.grey{color:#838383}.red{color:red}.blue{color:#215cff}.nicegreen{color:#059223}.boldnicegreen{color:#059223;font-weight:bold}.cult{color:#973e3b}.cultitalic{color:#973e3b;font-style:italic}.cultbold{color:#973e3b;font-style:italic;font-weight:bold}.cultboldtalic{color:#973e3b;font-weight:bold;font-size:185%}.cultlarge{color:#973e3b;font-weight:bold;font-size:185%}.narsie{color:#973e3b;font-weight:bold;font-size:925%}.narsiesmall{color:#973e3b;font-weight:bold;font-size:370%}.colossus{color:#7f282a;font-size:310%}.hierophant{color:#b441ee;font-weight:bold;font-style:italic}.hierophant_warning{color:#c56bf1;font-style:italic}.purple{color:#9956d3}.holoparasite{color:#88809c}.revennotice{color:#c099e2}.revenboldnotice{color:#c099e2;font-weight:bold}.revenbignotice{color:#c099e2;font-weight:bold;font-size:185%}.revenminor{color:#823abb}.revenwarning{color:#760fbb;font-style:italic}.revendanger{color:#760fbb;font-weight:bold;font-size:185%}.deconversion_message{color:#a947ff;font-size:185%;font-style:italic}.ghostalert{color:#60f;font-style:italic;font-weight:bold}.alien{color:#855d85}.noticealien{color:#059223}.alertalien{color:#059223;font-weight:bold}.changeling{color:#059223;font-style:italic}.alertsyndie{color:red;font-size:185%;font-weight:bold}.spider{color:#80f;font-weight:bold;font-size:185%}.interface{color:#750e75}.sans{font-family:"Comic Sans MS",cursive,sans-serif}.papyrus{font-family:"Papyrus",cursive,sans-serif}.robot{font-family:"Courier New",cursive,sans-serif}.tape_recorder{color:red;font-family:"Courier New",cursive,sans-serif}.command_headset{font-weight:bold;font-size:160%}.small{font-size:60%}.big{font-size:185%}.reallybig{font-size:245%}.extremelybig{font-size:310%}.greentext{color:#059223;font-size:185%}.redtext{color:#c51e1e;font-size:185%}.clown{color:#ff70c1;font-size:160%;font-family:"Comic Sans MS",cursive,sans-serif;font-weight:bold}.singing{font-family:"Trebuchet MS",cursive,sans-serif;font-style:italic}.his_grace{color:#15d512;font-family:"Courier New",cursive,sans-serif;font-style:italic}.hypnophrase{color:#202020;font-weight:bold;animation:hypnocolor 1500ms infinite;animation-direction:alternate}@keyframes hypnocolor{0%{color:#202020}25%{color:#4b02ac}50%{color:#9f41f1}75%{color:#541c9c}100%{color:#7adbf3}}.phobia{color:#d00;font-weight:bold;animation:phobia 750ms infinite}@keyframes phobia{0%{color:#f75a5a}50%{color:#d00}100%{color:#f75a5a}}.icon{height:1em;width:auto}.bigicon{font-size:2.5em}.memo{color:#638500;text-align:center}.memoedit{text-align:center;font-size:125%}.abductor{color:#c204c2;font-style:italic}.mind_control{color:#df3da9;font-size:100%;font-weight:bold;font-style:italic}.slime{color:#00ced1}.drone{color:#848482}.monkey{color:#975032}.swarmer{color:#2c75ff}.resonate{color:#298f85}.monkeyhive{color:#a56408}.monkeylead{color:#af6805;font-size:80%}.connectionClosed,.fatalError{background:red;color:#fff;padding:5px}.connectionClosed.restored{background:green}.internal.boldnshit{color:#3d5bc3;font-weight:bold}.text-normal{font-weight:normal;font-style:normal}.hidden{display:none;visibility:hidden}.ml-1{margin-left:1em}.ml-2{margin-left:2em}.ml-3{margin-left:3em}.xooc{color:#ac04e9;font-weight:bold;font-size:140%}.mooc{color:#090;font-weight:bold;font-size:140%}.yooc{color:#999600;font-weight:bold;font-size:140%}.headminsay{color:#653d78;font-weight:bold}.radio{color:#b4b4b4}.deptradio{color:#939}.comradio{color:#779cc2}.centradio{color:#5c5c8a}.hcradio{color:#318779}.pvstradio{color:#9b0612}.cryoradio{color:#ad6d48}.airadio{color:#f0f}.secradio{color:#a52929}.engradio{color:#a66300}.sentryradio{color:#844300}.medradio{color:#008160}.supradio{color:#ba8e41}.jtacradio{color:#ad3b98}.intelradio{color:#027d02}.wyradio{color:#fe9b24}.pmcradio{color:#4dc5ce}.vairadio{color:#e3580e}.rmcradio{color:#e3580e}.cmbradio{color:#1b748c}.clfradio{color:#8e83ca}.alpharadio{color:#db2626}.bravoradio{color:#c68610}.charlieradio{color:#a5a}.deltaradio{color:#007fcf}.echoradio{color:#3eb489}.medium{font-size:110%}.big{font-size:115%}.large{font-size:125%}.extra_large{font-size:130%}.huge{font-size:150%}.underline{text-decoration:underline}.orange{color:#eca100}.normal{font-style:normal}.attack{color:#ff3838}.moderate{color:#c00}.disarm{color:#900}.passive{color:#600}.helpful{color:#368f31}.scanner{color:#ff3838}.scannerb{color:#ff3838;font-weight:bold}.scannerburn{color:orange}.scannerburnb{color:orange;font-weight:bold}.rose{color:#ff5050}.debuginfo{color:#493d26;font-style:italic}.xenonotice{color:#51a16c}.xenoboldnotice{color:#51a16c;font-style:italic}.xenowarning{color:#51a16c;font-style:italic}.xenominorwarning{color:#51a16c;font-weight:bold;font-style:italic}.xenodanger{color:#51a16c;font-weight:bold}.avoidharm{color:#72a0e5;font-weight:bold}.highdanger{color:#ff3838;font-weight:bold;font-size:140%}.xenohighdanger{color:#51a16c;font-weight:bold;font-size:140%}.xenoannounce{color:#65c585;font-family:book-antiqua;font-weight:bold;font-size:140%}.yautjabold{color:purple;font-weight:bold}.yautjaboldbig{color:purple;font-weight:bold;font-size:120%}.objectivebig{font-weight:bold;font-size:130%}.objectivegreen{color:lime}.objectivered{color:red}.objectivesuccess{color:lime;font-weight:bold;font-size:110%}.objectivefail{color:red;font-weight:bold;font-size:110%}.xenotalk,.xeno{color:#c048c0;font-style:italic}.xenoleader{color:#996e99;font-style:italic;font-size:125%}.xenoqueen{color:#996e99;font-style:italic;font-weight:bold;font-size:125%}.newscaster{color:maroon}.role_header{color:#e92d2d;display:block;text-align:center;font-weight:bold;font-family:trebuchet-ms;font-size:150%}.role_body{color:#3a3ae9;display:block;text-align:center;font-size:125%}.round_header{color:#e92d2d;display:block;text-align:center;font-family:courier;font-weight:bold;font-size:180%}.round_body{color:#c5c5c5;display:block;text-align:center;font-family:trebuchet-ms;font-weight:bold;font-size:125%}.event_announcement{color:#600d48;font-family:arial-narrow;font-weight:bold;font-size:125%}.announce_header{color:#cecece;font-weight:bold;font-size:150%}.announce_header_blue{color:#7575f3;font-weight:bold;font-size:150%}.announce_header_admin{color:#7575f3;font-weight:bold;font-size:150%}.announce_body{color:#e92d2d;font-weight:normal;font-size:125%}.centerbold{display:block;text-align:center;font-weight:bold}.mod{color:#917455;font-weight:bold}.modooc{color:#184880;font-weight:bold}.adminmod{color:#7c440c;font-weight:bold}.mentorsay{color:#d4af57;font-weight:bold}.mentorhelp{color:#090;font-weight:bold}.mentorbody{color:#da6200;font-weight:bold}.mentorstaff{color:#b5850d;font-weight:bold}.staffsay{color:#b5850d;font-weight:bold}.tajaran{color:#803b56}.tajaran_signlang{color:#941c1c}.skrell{color:#00ced1}.soghun{color:#228b22}.changeling{color:purple}.vox{color:#a0a}.monkey{color:#966c47}.german{color:#858f1e;font-family:"Times New Roman",Times,serif}.spanish{color:#cf982b}.japanese{color:#940927}.chinese{color:#fe1919}.zombie{color:#2dacb1;font-style:italic}.rough{font-family:trebuchet-ms,cursive,sans-serif}.commando{color:#fe9b24;font-style:bold}.say_quote{font-family:Georgia,Verdana,sans-serif}.admin .message{color:#314cad}.admin .prefix{font-weight:bolder}.pm{font-size:110%}.deadsay{color:#8b4dff}.retro_translator{font-weight:bold}.yautja_translator{color:#a00;font-weight:bold;animation:glitch .5s infinite}@keyframes glitch{25%{color:#a00;transform:translate(-2px, -1px)}50%{color:#be0000;transform:translate(1px, -2px)}75%{color:#8d0000;transform:translate(-1px, 2px)}100%{color:#830000;transform:translate(1px, 1px)}}.examine_block{background:#1b1c1e;border:1px solid #a4bad6;margin:.5em;padding:.5em .75em}.examine_block .icon{width:1.5em;height:1.5em;margin:0;padding:0}.tooltip{font-style:italic;border-bottom:1px dashed #fff} -.theme-light .color-black{color:#000 !important}.theme-light .color-white{color:#e6e6e6 !important}.theme-light .color-red{color:#c82121 !important}.theme-light .color-orange{color:#e6630d !important}.theme-light .color-yellow{color:#e5c304 !important}.theme-light .color-olive{color:#a3b816 !important}.theme-light .color-green{color:#1d9f3b !important}.theme-light .color-teal{color:#00a39c !important}.theme-light .color-blue{color:#1e78bb !important}.theme-light .color-dark-blue{color:#004274 !important}.theme-light .color-violet{color:#5a30b5 !important}.theme-light .color-purple{color:#932eb4 !important}.theme-light .color-pink{color:#db228a !important}.theme-light .color-brown{color:#955d39 !important}.theme-light .color-grey{color:#e6e6e6 !important}.theme-light .color-light-grey{color:#999 !important}.theme-light .color-good{color:#529923 !important}.theme-light .color-average{color:#da810e !important}.theme-light .color-bad{color:#c82121 !important}.theme-light .color-label{color:#353535 !important}.theme-light .color-xeno{color:#4a3253 !important}.theme-light .color-bg-black{background-color:#000 !important}.theme-light .color-bg-white{background-color:#bfbfbf !important}.theme-light .color-bg-red{background-color:#a61c1c !important}.theme-light .color-bg-orange{background-color:#c0530b !important}.theme-light .color-bg-yellow{background-color:#bfa303 !important}.theme-light .color-bg-olive{background-color:#889912 !important}.theme-light .color-bg-green{background-color:#188532 !important}.theme-light .color-bg-teal{background-color:#008882 !important}.theme-light .color-bg-blue{background-color:#19649c !important}.theme-light .color-bg-dark-blue{background-color:#003761 !important}.theme-light .color-bg-violet{background-color:#4b2897 !important}.theme-light .color-bg-purple{background-color:#7a2696 !important}.theme-light .color-bg-pink{background-color:#b61d73 !important}.theme-light .color-bg-brown{background-color:#7c4d2f !important}.theme-light .color-bg-grey{background-color:#bfbfbf !important}.theme-light .color-bg-light-grey{background-color:gray !important}.theme-light .color-bg-good{background-color:#44801d !important}.theme-light .color-bg-average{background-color:#b56b0b !important}.theme-light .color-bg-bad{background-color:#a61c1c !important}.theme-light .color-bg-label{background-color:#2c2c2c !important}.theme-light .color-bg-xeno{background-color:#3e2945 !important}.theme-light .Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:#fff}.theme-light .Tabs--fill{height:100%}.theme-light .Section .Tabs{background-color:transparent}.theme-light .Section:not(.Section--fitted) .Tabs{margin:0 -0.5em .5em}.theme-light .Section:not(.Section--fitted) .Tabs:first-child{margin-top:-0.5em}.theme-light .Tabs--vertical{flex-direction:column;padding:.25em 0 .25em .25em}.theme-light .Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0 .25em}.theme-light .Tabs--horizontal:last-child{margin-bottom:0}.theme-light .Tabs__Tab{flex-grow:0}.theme-light .Tabs--fluid .Tabs__Tab{flex-grow:1}.theme-light .Tab{display:flex;align-items:center;justify-content:space-between;background-color:transparent;color:rgba(0,0,0,.5);min-height:2.25em;min-width:4em}.theme-light .Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075)}.theme-light .Tab--selected{background-color:rgba(255,255,255,.125);color:#404040}.theme-light .Tab__text{flex-grow:1;margin:0 .5em}.theme-light .Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.theme-light .Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.theme-light .Tabs--horizontal .Tab{border-top:.1666666667em solid transparent;border-bottom:.1666666667em solid transparent;border-top-left-radius:.25em;border-top-right-radius:.25em}.theme-light .Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #000}.theme-light .Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid transparent;border-right:.1666666667em solid transparent;border-top-left-radius:.25em;border-bottom-left-radius:.25em}.theme-light .Tabs--vertical .Tab--selected{border-right:.1666666667em solid #000}.theme-light .Tab--selected.Tab--color--black{color:#404040}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--black{border-bottom-color:#000}.theme-light .Tabs--vertical .Tab--selected.Tab--color--black{border-right-color:#000}.theme-light .Tab--selected.Tab--color--white{color:#ececec}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--white{border-bottom-color:#e6e6e6}.theme-light .Tabs--vertical .Tab--selected.Tab--color--white{border-right-color:#e6e6e6}.theme-light .Tab--selected.Tab--color--red{color:#e14d4d}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--red{border-bottom-color:#c82121}.theme-light .Tabs--vertical .Tab--selected.Tab--color--red{border-right-color:#c82121}.theme-light .Tab--selected.Tab--color--orange{color:#f48942}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--orange{border-bottom-color:#e6630d}.theme-light .Tabs--vertical .Tab--selected.Tab--color--orange{border-right-color:#e6630d}.theme-light .Tab--selected.Tab--color--yellow{color:#fcdd33}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--yellow{border-bottom-color:#e5c304}.theme-light .Tabs--vertical .Tab--selected.Tab--color--yellow{border-right-color:#e5c304}.theme-light .Tab--selected.Tab--color--olive{color:#d0e732}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--olive{border-bottom-color:#a3b816}.theme-light .Tabs--vertical .Tab--selected.Tab--color--olive{border-right-color:#a3b816}.theme-light .Tab--selected.Tab--color--green{color:#33da5a}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--green{border-bottom-color:#1d9f3b}.theme-light .Tabs--vertical .Tab--selected.Tab--color--green{border-right-color:#1d9f3b}.theme-light .Tab--selected.Tab--color--teal{color:#00faef}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--teal{border-bottom-color:#00a39c}.theme-light .Tabs--vertical .Tab--selected.Tab--color--teal{border-right-color:#00a39c}.theme-light .Tab--selected.Tab--color--blue{color:#419ce1}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--blue{border-bottom-color:#1e78bb}.theme-light .Tabs--vertical .Tab--selected.Tab--color--blue{border-right-color:#1e78bb}.theme-light .Tab--selected.Tab--color--dark-blue{color:#0079d7}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--dark-blue{border-bottom-color:#004274}.theme-light .Tabs--vertical .Tab--selected.Tab--color--dark-blue{border-right-color:#004274}.theme-light .Tab--selected.Tab--color--violet{color:#7f58d3}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--violet{border-bottom-color:#5a30b5}.theme-light .Tabs--vertical .Tab--selected.Tab--color--violet{border-right-color:#5a30b5}.theme-light .Tab--selected.Tab--color--purple{color:#b455d4}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--purple{border-bottom-color:#932eb4}.theme-light .Tabs--vertical .Tab--selected.Tab--color--purple{border-right-color:#932eb4}.theme-light .Tab--selected.Tab--color--pink{color:#e558a7}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--pink{border-bottom-color:#db228a}.theme-light .Tabs--vertical .Tab--selected.Tab--color--pink{border-right-color:#db228a}.theme-light .Tab--selected.Tab--color--brown{color:#c0825a}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--brown{border-bottom-color:#955d39}.theme-light .Tabs--vertical .Tab--selected.Tab--color--brown{border-right-color:#955d39}.theme-light .Tab--selected.Tab--color--grey{color:#ececec}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--grey{border-bottom-color:#e6e6e6}.theme-light .Tabs--vertical .Tab--selected.Tab--color--grey{border-right-color:#e6e6e6}.theme-light .Tab--selected.Tab--color--light-grey{color:#b3b3b3}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--light-grey{border-bottom-color:#999}.theme-light .Tabs--vertical .Tab--selected.Tab--color--light-grey{border-right-color:#999}.theme-light .Tab--selected.Tab--color--good{color:#77d23b}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--good{border-bottom-color:#529923}.theme-light .Tabs--vertical .Tab--selected.Tab--color--good{border-right-color:#529923}.theme-light .Tab--selected.Tab--color--average{color:#f3a23a}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--average{border-bottom-color:#da810e}.theme-light .Tabs--vertical .Tab--selected.Tab--color--average{border-right-color:#da810e}.theme-light .Tab--selected.Tab--color--bad{color:#e14d4d}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--bad{border-bottom-color:#c82121}.theme-light .Tabs--vertical .Tab--selected.Tab--color--bad{border-right-color:#c82121}.theme-light .Tab--selected.Tab--color--label{color:#686868}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--label{border-bottom-color:#353535}.theme-light .Tabs--vertical .Tab--selected.Tab--color--label{border-right-color:#353535}.theme-light .Tab--selected.Tab--color--xeno{color:#7e558e}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--xeno{border-bottom-color:#4a3253}.theme-light .Tabs--vertical .Tab--selected.Tab--color--xeno{border-right-color:#4a3253}.theme-light .Section{position:relative;margin-bottom:.5em;background-color:#fff;background-color:#fff;box-sizing:border-box}.theme-light .Section:last-child{margin-bottom:0}.theme-light .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #fff}.theme-light .Section__titleText{font-size:1.1666666667em;font-weight:bold;color:#000}.theme-light .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-light .Section__rest{position:relative}.theme-light .Section__content{padding:.66em .5em}.theme-light .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-light .Section--fill{display:flex;flex-direction:column;height:100%}.theme-light .Section--fill>.Section__rest{flex-grow:1}.theme-light .Section--fill>.Section__rest>.Section__content{height:100%}.theme-light .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-light .Section--fill.Section--iefix{display:table !important;width:100% !important;height:100% !important;border-collapse:collapse;border-spacing:0}.theme-light .Section--fill.Section--iefix>.Section__rest{display:table-row !important;height:100% !important}.theme-light .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-light .Section--scrollable>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:hidden}.theme-light .Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.theme-light .Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:hidden;overflow-x:scroll}.theme-light .Section--scrollable.Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.theme-light .Section--scrollable.Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:scroll}.theme-light .Section .Section{background-color:transparent;margin-left:-0.5em;margin-right:-0.5em}.theme-light .Section .Section:first-child{margin-top:-0.5em}.theme-light .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-light .Section .Section .Section .Section__titleText{font-size:1em}.theme-light .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-light .Button:last-child{margin-right:0;margin-bottom:0}.theme-light .Button .fa,.theme-light .Button .fas,.theme-light .Button .far{margin-left:-0.25em;margin-right:-0.25em;min-width:1.333em;text-align:center}.theme-light .Button--hasContent .fa,.theme-light .Button--hasContent .fas,.theme-light .Button--hasContent .far{margin-right:.25em}.theme-light .Button--hasContent.Button--iconPosition--right .fa,.theme-light .Button--hasContent.Button--iconPosition--right .fas,.theme-light .Button--hasContent.Button--iconPosition--right .far{margin-right:0px;margin-left:3px}.theme-light .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-light .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-light .Button--circular{border-radius:50%}.theme-light .Button--compact{padding:0 .25em;line-height:1.333em}.theme-light .Button--color--black{transition:color 50ms,background-color 50ms;background-color:#000;color:#fff}.theme-light .Button--color--black:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--black:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--black:hover,.theme-light .Button--color--black:focus{background-color:#131313;color:#fff}.theme-light .Button--color--white{transition:color 50ms,background-color 50ms;background-color:#bfbfbf;color:#000}.theme-light .Button--color--white:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--white:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--white:hover,.theme-light .Button--color--white:focus{background-color:#efefef;color:#000}.theme-light .Button--color--red{transition:color 50ms,background-color 50ms;background-color:#a61c1c;color:#fff}.theme-light .Button--color--red:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--red:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--red:hover,.theme-light .Button--color--red:focus{background-color:#d23333;color:#fff}.theme-light .Button--color--orange{transition:color 50ms,background-color 50ms;background-color:#c0530b;color:#fff}.theme-light .Button--color--orange:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--orange:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--orange:hover,.theme-light .Button--color--orange:focus{background-color:#ea7426;color:#fff}.theme-light .Button--color--yellow{transition:color 50ms,background-color 50ms;background-color:#bfa303;color:#fff}.theme-light .Button--color--yellow:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--yellow:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--yellow:hover,.theme-light .Button--color--yellow:focus{background-color:#efce17;color:#fff}.theme-light .Button--color--olive{transition:color 50ms,background-color 50ms;background-color:#889912;color:#fff}.theme-light .Button--color--olive:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--olive:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--olive:hover,.theme-light .Button--color--olive:focus{background-color:#afc328;color:#fff}.theme-light .Button--color--green{transition:color 50ms,background-color 50ms;background-color:#188532;color:#fff}.theme-light .Button--color--green:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--green:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--green:hover,.theme-light .Button--color--green:focus{background-color:#2fac4c;color:#fff}.theme-light .Button--color--teal{transition:color 50ms,background-color 50ms;background-color:#008882;color:#fff}.theme-light .Button--color--teal:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--teal:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--teal:hover,.theme-light .Button--color--teal:focus{background-color:#13afa9;color:#fff}.theme-light .Button--color--blue{transition:color 50ms,background-color 50ms;background-color:#19649c;color:#fff}.theme-light .Button--color--blue:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--blue:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--blue:hover,.theme-light .Button--color--blue:focus{background-color:#3086c7;color:#fff}.theme-light .Button--color--dark-blue{transition:color 50ms,background-color 50ms;background-color:#003761;color:#fff}.theme-light .Button--color--dark-blue:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--dark-blue:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--dark-blue:hover,.theme-light .Button--color--dark-blue:focus{background-color:#135283;color:#fff}.theme-light .Button--color--violet{transition:color 50ms,background-color 50ms;background-color:#4b2897;color:#fff}.theme-light .Button--color--violet:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--violet:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--violet:hover,.theme-light .Button--color--violet:focus{background-color:#6a41c1;color:#fff}.theme-light .Button--color--purple{transition:color 50ms,background-color 50ms;background-color:#7a2696;color:#fff}.theme-light .Button--color--purple:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--purple:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--purple:hover,.theme-light .Button--color--purple:focus{background-color:#a03fc0;color:#fff}.theme-light .Button--color--pink{transition:color 50ms,background-color 50ms;background-color:#b61d73;color:#fff}.theme-light .Button--color--pink:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--pink:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--pink:hover,.theme-light .Button--color--pink:focus{background-color:#da3f96;color:#fff}.theme-light .Button--color--brown{transition:color 50ms,background-color 50ms;background-color:#7c4d2f;color:#fff}.theme-light .Button--color--brown:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--brown:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--brown:hover,.theme-light .Button--color--brown:focus{background-color:#a26c49;color:#fff}.theme-light .Button--color--grey{transition:color 50ms,background-color 50ms;background-color:#bfbfbf;color:#000}.theme-light .Button--color--grey:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--grey:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--grey:hover,.theme-light .Button--color--grey:focus{background-color:#efefef;color:#000}.theme-light .Button--color--light-grey{transition:color 50ms,background-color 50ms;background-color:gray;color:#fff}.theme-light .Button--color--light-grey:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--light-grey:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--light-grey:hover,.theme-light .Button--color--light-grey:focus{background-color:#a6a6a6;color:#fff}.theme-light .Button--color--good{transition:color 50ms,background-color 50ms;background-color:#44801d;color:#fff}.theme-light .Button--color--good:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--good:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--good:hover,.theme-light .Button--color--good:focus{background-color:#62a635;color:#fff}.theme-light .Button--color--average{transition:color 50ms,background-color 50ms;background-color:#b56b0b;color:#fff}.theme-light .Button--color--average:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--average:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--average:hover,.theme-light .Button--color--average:focus{background-color:#e48f20;color:#fff}.theme-light .Button--color--bad{transition:color 50ms,background-color 50ms;background-color:#a61c1c;color:#fff}.theme-light .Button--color--bad:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--bad:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--bad:hover,.theme-light .Button--color--bad:focus{background-color:#d23333;color:#fff}.theme-light .Button--color--label{transition:color 50ms,background-color 50ms;background-color:#2c2c2c;color:#fff}.theme-light .Button--color--label:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--label:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--label:hover,.theme-light .Button--color--label:focus{background-color:#464646;color:#fff}.theme-light .Button--color--xeno{transition:color 50ms,background-color 50ms;background-color:#3e2945;color:#fff}.theme-light .Button--color--xeno:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--xeno:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--xeno:hover,.theme-light .Button--color--xeno:focus{background-color:#5a4363;color:#fff}.theme-light .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#bbb;color:#000}.theme-light .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--default:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--default:hover,.theme-light .Button--color--default:focus{background-color:#eaeaea;color:#000}.theme-light .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-light .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--caution:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--caution:hover,.theme-light .Button--color--caution:focus{background-color:#ec8420;color:#fff}.theme-light .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-light .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--danger:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--danger:hover,.theme-light .Button--color--danger:focus{background-color:#c4c813;color:#fff}.theme-light .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#eee;color:#000;background-color:rgba(238,238,238,0);color:rgba(0,0,0,.5)}.theme-light .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--transparent:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--transparent:hover,.theme-light .Button--color--transparent:focus{background-color:#fcfcfc;color:#000}.theme-light .Button--disabled{background-color:#363636 !important}.theme-light .Button--selected{transition:color 50ms,background-color 50ms;background-color:#0668b8;color:#fff}.theme-light .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--selected:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--selected:hover,.theme-light .Button--selected:focus{background-color:#1a8be7;color:#fff}.theme-light .Button--flex{display:inline-flex;flex-direction:column}.theme-light .Button--flex--fluid{width:100%}.theme-light .Button--verticalAlignContent--top{justify-content:flex-start}.theme-light .Button--verticalAlignContent--middle{justify-content:center}.theme-light .Button--verticalAlignContent--bottom{justify-content:flex-end}.theme-light .Button__content{display:block;align-self:stretch}.theme-light .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#000;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.theme-light .Input--fluid{display:block;width:auto}.theme-light .Input__baseline{display:inline-block;color:transparent}.theme-light .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#000;color:inherit}.theme-light .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .Input--monospace .Input__input{font-family:"Consolas",monospace}.theme-light .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#000;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.theme-light .Input--fluid{display:block;width:auto}.theme-light .Input__baseline{display:inline-block;color:transparent}.theme-light .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#000;color:inherit}.theme-light .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .Input--monospace .Input__input{font-family:"Consolas",monospace}.theme-light .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#353535;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-light .NumberInput--fluid{display:block}.theme-light .NumberInput__content{margin-left:.5em}.theme-light .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-light .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #353535;background-color:#353535}.theme-light .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#fff;color:#000;text-align:right}.theme-light .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#000;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.theme-light .Input--fluid{display:block;width:auto}.theme-light .Input__baseline{display:inline-block;color:transparent}.theme-light .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#000;color:inherit}.theme-light .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .Input--monospace .Input__input{font-family:"Consolas",monospace}.theme-light .TextArea{position:relative;display:inline-block;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;background-color:#fff;margin-right:.1666666667em;line-height:1.4166666667em;box-sizing:border-box;width:100%}.theme-light .TextArea--fluid{display:block;width:auto;height:auto}.theme-light .TextArea--noborder{border:0px}.theme-light .TextArea__textarea.TextArea__textarea--scrollable{overflow:auto;overflow-x:hidden;overflow-y:scroll}.theme-light .TextArea__textarea{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;height:100%;font-size:1em;line-height:1.4166666667em;min-height:1.4166666667em;margin:0;padding:0 .5em;font-family:inherit;background-color:transparent;color:inherit;box-sizing:border-box;word-wrap:break-word;overflow:hidden}.theme-light .TextArea__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .TextArea__textarea_custom{overflow:visible;white-space:pre-wrap}.theme-light .Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto;margin-bottom:-0.2em;cursor:n-resize}.theme-light .Knob:after{content:".";color:transparent;line-height:2.5em}.theme-light .Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 100%);border-radius:50%;box-shadow:0 .05em .5em 0 rgba(0,0,0,.5)}.theme-light .Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.theme-light .Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:rgba(255,255,255,.9)}.theme-light .Knob__popupValue{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.theme-light .Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.theme-light .Knob__ringTrackPivot{transform:rotateZ(135deg)}.theme-light .Knob__ringTrack{fill:transparent;stroke:rgba(255,255,255,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.theme-light .Knob__ringFillPivot{transform:rotateZ(135deg)}.theme-light .Knob--bipolar .Knob__ringFillPivot{transform:rotateZ(270deg)}.theme-light .Knob__ringFill{fill:transparent;stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms ease-out}.theme-light .Knob--color--black .Knob__ringFill{stroke:#000}.theme-light .Knob--color--white .Knob__ringFill{stroke:#e6e6e6}.theme-light .Knob--color--red .Knob__ringFill{stroke:#c82121}.theme-light .Knob--color--orange .Knob__ringFill{stroke:#e6630d}.theme-light .Knob--color--yellow .Knob__ringFill{stroke:#e5c304}.theme-light .Knob--color--olive .Knob__ringFill{stroke:#a3b816}.theme-light .Knob--color--green .Knob__ringFill{stroke:#1d9f3b}.theme-light .Knob--color--teal .Knob__ringFill{stroke:#00a39c}.theme-light .Knob--color--blue .Knob__ringFill{stroke:#1e78bb}.theme-light .Knob--color--dark-blue .Knob__ringFill{stroke:#004274}.theme-light .Knob--color--violet .Knob__ringFill{stroke:#5a30b5}.theme-light .Knob--color--purple .Knob__ringFill{stroke:#932eb4}.theme-light .Knob--color--pink .Knob__ringFill{stroke:#db228a}.theme-light .Knob--color--brown .Knob__ringFill{stroke:#955d39}.theme-light .Knob--color--grey .Knob__ringFill{stroke:#e6e6e6}.theme-light .Knob--color--light-grey .Knob__ringFill{stroke:#999}.theme-light .Knob--color--good .Knob__ringFill{stroke:#529923}.theme-light .Knob--color--average .Knob__ringFill{stroke:#da810e}.theme-light .Knob--color--bad .Knob__ringFill{stroke:#c82121}.theme-light .Knob--color--label .Knob__ringFill{stroke:#353535}.theme-light .Knob--color--xeno .Knob__ringFill{stroke:#4a3253}.theme-light .Slider{cursor:e-resize}.theme-light .Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none !important}.theme-light .Slider__cursor{position:absolute;top:0;right:-.0833333333em;bottom:0;width:0;border-left:.1666666667em solid #000}.theme-light .Slider__pointer{position:absolute;right:-.4166666667em;bottom:-.3333333333em;width:0;height:0;border-left:.4166666667em solid transparent;border-right:.4166666667em solid transparent;border-bottom:.4166666667em solid #000}.theme-light .Slider__popupValue{position:absolute;right:0;top:-2rem;font-size:1rem;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.theme-light .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-width:.0833333333em !important;border-style:solid !important;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color 900ms ease-out}.theme-light .ProgressBar__fill{position:absolute;top:-0.5px;left:0px;bottom:-0.5px}.theme-light .ProgressBar__fill--animated{transition:background-color 900ms ease-out,width 900ms ease-out}.theme-light .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-light .ProgressBar--color--default{border:.0833333333em solid #bfbfbf}.theme-light .ProgressBar--color--default .ProgressBar__fill{background-color:#bfbfbf}.theme-light .ProgressBar--color--black{border-color:#000 !important}.theme-light .ProgressBar--color--black .ProgressBar__fill{background-color:#000}.theme-light .ProgressBar--color--white{border-color:#bfbfbf !important}.theme-light .ProgressBar--color--white .ProgressBar__fill{background-color:#bfbfbf}.theme-light .ProgressBar--color--red{border-color:#a61c1c !important}.theme-light .ProgressBar--color--red .ProgressBar__fill{background-color:#a61c1c}.theme-light .ProgressBar--color--orange{border-color:#c0530b !important}.theme-light .ProgressBar--color--orange .ProgressBar__fill{background-color:#c0530b}.theme-light .ProgressBar--color--yellow{border-color:#bfa303 !important}.theme-light .ProgressBar--color--yellow .ProgressBar__fill{background-color:#bfa303}.theme-light .ProgressBar--color--olive{border-color:#889912 !important}.theme-light .ProgressBar--color--olive .ProgressBar__fill{background-color:#889912}.theme-light .ProgressBar--color--green{border-color:#188532 !important}.theme-light .ProgressBar--color--green .ProgressBar__fill{background-color:#188532}.theme-light .ProgressBar--color--teal{border-color:#008882 !important}.theme-light .ProgressBar--color--teal .ProgressBar__fill{background-color:#008882}.theme-light .ProgressBar--color--blue{border-color:#19649c !important}.theme-light .ProgressBar--color--blue .ProgressBar__fill{background-color:#19649c}.theme-light .ProgressBar--color--dark-blue{border-color:#003761 !important}.theme-light .ProgressBar--color--dark-blue .ProgressBar__fill{background-color:#003761}.theme-light .ProgressBar--color--violet{border-color:#4b2897 !important}.theme-light .ProgressBar--color--violet .ProgressBar__fill{background-color:#4b2897}.theme-light .ProgressBar--color--purple{border-color:#7a2696 !important}.theme-light .ProgressBar--color--purple .ProgressBar__fill{background-color:#7a2696}.theme-light .ProgressBar--color--pink{border-color:#b61d73 !important}.theme-light .ProgressBar--color--pink .ProgressBar__fill{background-color:#b61d73}.theme-light .ProgressBar--color--brown{border-color:#7c4d2f !important}.theme-light .ProgressBar--color--brown .ProgressBar__fill{background-color:#7c4d2f}.theme-light .ProgressBar--color--grey{border-color:#bfbfbf !important}.theme-light .ProgressBar--color--grey .ProgressBar__fill{background-color:#bfbfbf}.theme-light .ProgressBar--color--light-grey{border-color:gray !important}.theme-light .ProgressBar--color--light-grey .ProgressBar__fill{background-color:gray}.theme-light .ProgressBar--color--good{border-color:#44801d !important}.theme-light .ProgressBar--color--good .ProgressBar__fill{background-color:#44801d}.theme-light .ProgressBar--color--average{border-color:#b56b0b !important}.theme-light .ProgressBar--color--average .ProgressBar__fill{background-color:#b56b0b}.theme-light .ProgressBar--color--bad{border-color:#a61c1c !important}.theme-light .ProgressBar--color--bad .ProgressBar__fill{background-color:#a61c1c}.theme-light .ProgressBar--color--label{border-color:#2c2c2c !important}.theme-light .ProgressBar--color--label .ProgressBar__fill{background-color:#2c2c2c}.theme-light .ProgressBar--color--xeno{border-color:#3e2945 !important}.theme-light .ProgressBar--color--xeno .ProgressBar__fill{background-color:#3e2945}.theme-light .Chat{color:#000}.theme-light .Chat__badge{display:inline-block;min-width:.5em;font-size:.7em;padding:.2em .3em;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:crimson;border-radius:10px;transition:font-size 200ms ease-out}.theme-light .Chat__badge:before{content:"x"}.theme-light .Chat__badge--animate{font-size:.9em;transition:font-size 0ms}.theme-light .Chat__scrollButton{position:fixed;right:2em;bottom:1em}.theme-light .Chat__reconnected{font-size:.85em;text-align:center;margin:1em 0 2em}.theme-light .Chat__reconnected:before{content:"Reconnected";display:inline-block;border-radius:1em;padding:0 .7em;color:#db2828;background-color:#fff}.theme-light .Chat__reconnected:after{content:"";display:block;margin-top:-0.75em;border-bottom:.1666666667em solid #db2828}.theme-light .Chat__highlight{color:#000}.theme-light .Chat__highlight--restricted{color:#fff;background-color:#a00;font-weight:bold}.theme-light .ChatMessage{word-wrap:break-word}.theme-light .ChatMessage--highlighted{position:relative;border-left:.1666666667em solid #fd4;padding-left:.5em}.theme-light .ChatMessage--highlighted:after{content:"";position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(255,221,68,.1);pointer-events:none}.theme-light .Layout,.theme-light .Layout *{scrollbar-base-color:#f2f2f2;scrollbar-face-color:#d6d6d6;scrollbar-3dlight-color:#eee;scrollbar-highlight-color:#eee;scrollbar-track-color:#f2f2f2;scrollbar-arrow-color:#777;scrollbar-shadow-color:#d6d6d6}.theme-light .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow-x:hidden;overflow-y:hidden}.theme-light .Layout__content--scrollable{overflow-y:scroll;margin-bottom:0}.theme-light .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#000;background-color:#eee;background-image:linear-gradient(to bottom, #eeeeee 0%, #eeeeee 100%)}.theme-light .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-light .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-light .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-light .Window__contentPadding:after{height:0}.theme-light .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-light .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(252,252,252,.25);pointer-events:none}.theme-light .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-light .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-light .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-light .TitleBar{background-color:#eee;border-bottom:1px solid rgba(0,0,0,.25);box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-light .TitleBar__clickable{color:rgba(0,0,0,.5);background-color:#eee;transition:color 250ms ease-out,background-color 250ms ease-out}.theme-light .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-light .TitleBar__title{position:absolute;display:inline-block;top:0;left:46px;left:3.8333333333rem;color:rgba(0,0,0,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap;pointer-events:none}.theme-light .TitleBar__buttons{pointer-events:initial;display:inline-block;width:100%;margin-left:10px}.theme-light .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-light .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px !important;line-height:2.6666666667rem !important}.theme-light .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-light .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-light html,.theme-light body{padding:0;margin:0;height:100%;color:#000}.theme-light body{background:#fff;font-family:Verdana,sans-serif;font-size:13px;line-height:1.2;overflow-x:hidden;overflow-y:scroll;word-wrap:break-word}.theme-light em{font-style:normal;font-weight:bold}.theme-light img{margin:0;padding:0;line-height:1;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-light img.icon{height:1em;min-height:16px;width:auto;vertical-align:bottom}.theme-light a{color:blue}.theme-light a.visited{color:#f0f}.theme-light a:visited{color:#f0f}.theme-light a.popt{text-decoration:none}.theme-light .popup{position:fixed;top:50%;left:50%;background:#ddd}.theme-light .popup .close{position:absolute;background:#aaa;top:0;right:0;color:#333;text-decoration:none;z-index:2;padding:0 10px;height:30px;line-height:30px}.theme-light .popup .close:hover{background:#999}.theme-light .popup .head{background:#999;color:#ddd;padding:0 10px;height:30px;line-height:30px;text-transform:uppercase;font-size:.9em;font-weight:bold;border-bottom:2px solid green}.theme-light .popup input{border:1px solid #999;background:#fff;margin:0;padding:5px;outline:none;color:#333}.theme-light .popup input[type=text]:hover,.theme-light .popup input[type=text]:active,.theme-light .popup input[type=text]:focus{border-color:green}.theme-light .popup input[type=submit]{padding:5px 10px;background:#999;color:#ddd;text-transform:uppercase;font-size:.9em;font-weight:bold}.theme-light .popup input[type=submit]:hover,.theme-light .popup input[type=submit]:focus,.theme-light .popup input[type=submit]:active{background:#aaa;cursor:pointer}.theme-light .changeFont{padding:10px}.theme-light .changeFont a{display:block;text-decoration:none;padding:3px;color:#333}.theme-light .changeFont a:hover{background:#ccc}.theme-light .highlightPopup{padding:10px;text-align:center}.theme-light .highlightPopup input[type=text]{display:block;width:215px;text-align:left;margin-top:5px}.theme-light .highlightPopup input.highlightColor{background-color:#ff0}.theme-light .highlightPopup input.highlightTermSubmit{margin-top:5px}.theme-light .contextMenu{background-color:#ddd;position:fixed;margin:2px;width:150px}.theme-light .contextMenu a{display:block;padding:2px 5px;text-decoration:none;color:#333}.theme-light .contextMenu a:hover{background-color:#ccc}.theme-light .filterMessages{padding:5px}.theme-light .filterMessages div{padding:2px 0}.theme-light .icon-stack{height:1em;line-height:1em;width:1em;vertical-align:middle;margin-top:-2px}.theme-light .motd{color:#638500;font-family:Verdana,sans-serif;white-space:normal}.theme-light .motd h1,.theme-light .motd h2,.theme-light .motd h3,.theme-light .motd h4,.theme-light .motd h5,.theme-light .motd h6{color:#638500;text-decoration:underline}.theme-light .motd a,.theme-light .motd a:link,.theme-light .motd a:visited,.theme-light .motd a:active,.theme-light .motd a:hover{color:#638500}.theme-light .bold,.theme-light .name,.theme-light .prefix,.theme-light .ooc,.theme-light .looc,.theme-light .adminooc,.theme-light .admin,.theme-light .medal,.theme-light .yell{font-weight:bold}.theme-light .italic,.theme-light .italics{font-style:italic}.theme-light .highlight{background:#ff0}.theme-light h1,.theme-light h2,.theme-light h3,.theme-light h4,.theme-light h5,.theme-light h6{color:blue;font-family:Georgia,Verdana,sans-serif}.theme-light h1.alert,.theme-light h2.alert{color:#000}.theme-light em{font-style:normal;font-weight:bold}.theme-light .ooc{font-weight:bold}.theme-light .adminobserverooc{color:#09c;font-weight:bold}.theme-light .adminooc{color:#700038;font-weight:bold}.theme-light .adminsay{color:#ff4500;font-weight:bold}.theme-light .admin{color:#4473ff;font-weight:bold}.theme-light .name{font-weight:bold}.theme-light .deadsay{color:#5c00e6}.theme-light .binarysay{color:#20c20e;background-color:#000;display:block}.theme-light .binarysay a{color:lime}.theme-light .binarysay a:active,.theme-light .binarysay a:visited{color:#8f8}.theme-light .radio{color:green}.theme-light .sciradio{color:#939}.theme-light .comradio{color:#948f02}.theme-light .secradio{color:#a30000}.theme-light .medradio{color:#337296}.theme-light .engradio{color:#fb5613}.theme-light .sentryradio{color:#844300}.theme-light .suppradio{color:#a8732b}.theme-light .servradio{color:#6eaa2c}.theme-light .syndradio{color:#6d3f40}.theme-light .gangradio{color:#ac2ea1}.theme-light .centcomradio{color:#686868}.theme-light .aiprivradio{color:#f0f}.theme-light .redteamradio{color:red}.theme-light .blueteamradio{color:blue}.theme-light .greenteamradio{color:lime}.theme-light .yellowteamradio{color:#d1ba22}.theme-light .yell{font-weight:bold}.theme-light .alert{color:red}.theme-light h1.alert,.theme-light h2.alert{color:#000}.theme-light .userdanger{color:red;font-weight:bold;font-size:185%}.theme-light .bolddanger{color:red;font-weight:bold}.theme-light .danger{color:red}.theme-light .tinydanger{color:red;font-size:85%}.theme-light .smalldanger{color:red;font-size:90%}.theme-light .warning{color:red;font-style:italic}.theme-light .alertwarning{color:red;font-weight:bold}.theme-light .boldwarning{color:red;font-style:italic;font-weight:bold}.theme-light .announce{color:#228b22;font-weight:bold}.theme-light .boldannounce{color:red;font-weight:bold}.theme-light .bigannounce{font-weight:bold;font-size:115%}.theme-light .greenannounce{color:lime;font-weight:bold}.theme-light .rose{color:#ff5050}.theme-light .info{color:#00c}.theme-light .notice{color:#009}.theme-light .staff_ic{color:#009}.theme-light .tinynotice{color:#009;font-size:85%}.theme-light .tinynoticeital{color:#009;font-style:italic;font-size:85%}.theme-light .smallnotice{color:#009;font-size:90%}.theme-light .smallnoticeital{color:#009;font-style:italic;font-size:90%}.theme-light .boldnotice{color:#009;font-weight:bold}.theme-light .hear{color:#009;font-style:italic}.theme-light .adminnotice{color:blue}.theme-light .adminhelp{color:red;font-weight:bold}.theme-light .unconscious{color:blue;font-weight:bold}.theme-light .suicide{color:#ff5050;font-style:italic}.theme-light .green{color:#03ff39}.theme-light .grey{color:#838383}.theme-light .red{color:red}.theme-light .blue{color:blue}.theme-light .nicegreen{color:#14a833}.theme-light .boldnicegreen{color:#14a833;font-weight:bold}.theme-light .cult{color:#973e3b}.theme-light .cultitalic{color:#973e3b;font-style:italic}.theme-light .cultbold{color:#973e3b;font-style:italic;font-weight:bold}.theme-light .cultboldtalic{color:#973e3b;font-weight:bold;font-size:185%}.theme-light .cultlarge{color:#973e3b;font-weight:bold;font-size:185%}.theme-light .narsie{color:#973e3b;font-weight:bold;font-size:925%}.theme-light .narsiesmall{color:#973e3b;font-weight:bold;font-size:370%}.theme-light .colossus{color:#7f282a;font-size:310%}.theme-light .hierophant{color:#609;font-weight:bold;font-style:italic}.theme-light .hierophant_warning{color:#609;font-style:italic}.theme-light .purple{color:#5e2d79}.theme-light .holoparasite{color:#35333a}.theme-light .revennotice{color:#1d2953}.theme-light .revenboldnotice{color:#1d2953;font-weight:bold}.theme-light .revenbignotice{color:#1d2953;font-weight:bold;font-size:185%}.theme-light .revenminor{color:#823abb}.theme-light .revenwarning{color:#760fbb;font-style:italic}.theme-light .revendanger{color:#760fbb;font-weight:bold;font-size:185%}.theme-light .deconversion_message{color:#5000a0;font-size:185%;font-style:italic}.theme-light .ghostalert{color:#5c00e6;font-style:italic;font-weight:bold}.theme-light .alien{color:#543354}.theme-light .noticealien{color:#00c000}.theme-light .alertalien{color:#00c000;font-weight:bold}.theme-light .changeling{color:purple;font-style:italic}.theme-light .alertsyndie{color:red;font-size:185%;font-weight:bold}.theme-light .spider{color:#4d004d;font-weight:bold;font-size:185%}.theme-light .interface{color:#303}.theme-light .sans{font-family:"Comic Sans MS",cursive,sans-serif}.theme-light .papyrus{font-family:"Papyrus",cursive,sans-serif}.theme-light .robot{font-family:"Courier New",cursive,sans-serif}.theme-light .tape_recorder{color:maroon;font-family:"Courier New",cursive,sans-serif}.theme-light .command_headset{font-weight:bold;font-size:160%}.theme-light .small{font-size:60%}.theme-light .big{font-size:185%}.theme-light .reallybig{font-size:245%}.theme-light .extremelybig{font-size:310%}.theme-light .greentext{color:lime;font-size:185%}.theme-light .redtext{color:red;font-size:185%}.theme-light .clown{color:#ff69bf;font-size:160%;font-family:"Comic Sans MS",cursive,sans-serif;font-weight:bold}.theme-light .singing{font-family:"Trebuchet MS",cursive,sans-serif;font-style:italic}.theme-light .his_grace{color:#15d512;font-family:"Courier New",cursive,sans-serif;font-style:italic}.theme-light .hypnophrase{color:#0d0d0d;font-weight:bold;animation:hypnocolor 1500ms infinite;animation-direction:alternate}@keyframes hypnocolor{0%{color:#0d0d0d}25%{color:#410194}50%{color:#7f17d8}75%{color:#410194}100%{color:#3bb5d3}}.theme-light .phobia{color:#d00;font-weight:bold;animation:phobia 750ms infinite}@keyframes phobia{0%{color:#0d0d0d}50%{color:#d00}100%{color:#0d0d0d}}.theme-light .icon{height:1em;width:auto}.theme-light .bigicon{font-size:2.5em}.theme-light .memo{color:#638500;text-align:center}.theme-light .memoedit{text-align:center;font-size:125%}.theme-light .abductor{color:purple;font-style:italic}.theme-light .mind_control{color:#a00d6f;font-size:100%;font-weight:bold;font-style:italic}.theme-light .slime{color:#00ced1}.theme-light .drone{color:#848482}.theme-light .monkey{color:#975032}.theme-light .swarmer{color:#2c75ff}.theme-light .resonate{color:#298f85}.theme-light .monkeyhive{color:#774704}.theme-light .monkeylead{color:#774704;font-size:80%}.theme-light .connectionClosed,.theme-light .fatalError{background:red;color:#fff;padding:5px}.theme-light .connectionClosed.restored{background:green}.theme-light .internal.boldnshit{color:blue;font-weight:bold}.theme-light .text-normal{font-weight:normal;font-style:normal}.theme-light .hidden{display:none;visibility:hidden}.theme-light .ml-1{margin-left:1em}.theme-light .ml-2{margin-left:2em}.theme-light .ml-3{margin-left:3em}.theme-light .xooc{color:#6c0094;font-weight:bold;font-size:140%}.theme-light .mooc{color:#090;font-weight:bold;font-size:140%}.theme-light .yooc{color:#999600;font-weight:bold;font-size:140%}.theme-light .headminsay{color:#5a0a7f;font-weight:bold}.theme-light .radio{color:#4e4e4e}.theme-light .deptradio{color:#939}.theme-light .comradio{color:#004080}.theme-light .centradio{color:#5c5c8a}.theme-light .cryoradio{color:#554e3f}.theme-light .hcradio{color:#318779}.theme-light .pvstradio{color:#9b0612}.theme-light .airadio{color:#f0f}.theme-light .secradio{color:#a30000}.theme-light .engradio{color:#a66300}.theme-light .sentryradio{color:#844300}.theme-light .medradio{color:#008160}.theme-light .supradio{color:#5f4519}.theme-light .jtacradio{color:#702963}.theme-light .intelradio{color:#027d02}.theme-light .wyradio{color:#fe9b24}.theme-light .pmcradio{color:#136957}.theme-light .vairadio{color:#943d0a}.theme-light .cmbradio{color:#1b748c}.theme-light .clfradio{color:#6f679c}.theme-light .alpharadio{color:#ea0000}.theme-light .bravoradio{color:#c68610}.theme-light .charlieradio{color:#a5a}.theme-light .deltaradio{color:#007fcf}.theme-light .echoradio{color:#3a7e65}.theme-light .medium{font-size:110%}.theme-light .big{font-size:115%}.theme-light .large{font-size:125%}.theme-light .extra_large{font-size:130%}.theme-light .huge{font-size:150%}.theme-light .underline{text-decoration:underline}.theme-light .orange{color:#eca100}.theme-light .normal{font-style:normal}.theme-light .attack{color:red}.theme-light .moderate{color:#c00}.theme-light .disarm{color:#900}.theme-light .passive{color:#600}.theme-light .helpful{color:#368f31}.theme-light .scanner{color:red}.theme-light .scannerb{color:red;font-weight:bold}.theme-light .scannerburn{color:orange}.theme-light .scannerburnb{color:orange;font-weight:bold}.theme-light .rose{color:#ff5050}.theme-light .debuginfo{color:#493d26;font-style:italic}.theme-light .xenonotice{color:#2a623d}.theme-light .xenoboldnotice{color:#2a623d;font-style:italic}.theme-light .xenowarning{color:#2a623d;font-style:italic}.theme-light .xenominorwarning{color:#2a623d;font-weight:bold;font-style:italic}.theme-light .xenodanger{color:#2a623d;font-weight:bold}.theme-light .avoidharm{color:#72a0e5;font-weight:bold}.theme-light .highdanger{color:red;font-weight:bold;font-size:140%}.theme-light .xenohighdanger{color:#2a623d;font-weight:bold;font-size:140%}.theme-light .xenoannounce{color:#1a472a;font-family:book-antiqua;font-weight:bold;font-size:140%}.theme-light .yautjabold{color:purple;font-weight:bold}.theme-light .yautjaboldbig{color:purple;font-weight:bold;font-size:120%}.theme-light .objectivebig{font-weight:bold;font-size:130%}.theme-light .objectivegreen{color:lime}.theme-light .objectivered{color:red}.theme-light .objectivesuccess{color:lime;font-weight:bold;font-size:110%}.theme-light .objectivefail{color:red;font-weight:bold;font-size:110%}.theme-light .xenotalk,.theme-light .xeno{color:#900090;font-style:italic}.theme-light .xenoleader{color:#730d73;font-style:italic;font-size:125%}.theme-light .xenoqueen{color:#730d73;font-style:italic;font-weight:bold;font-size:125%}.theme-light .newscaster{color:maroon}.theme-light .role_header{color:#db0000;display:block;text-align:center;font-weight:bold;font-family:trebuchet-ms;font-size:150%}.theme-light .role_body{color:#009;display:block;text-align:center;font-size:125%}.theme-light .round_header{color:#db0000;display:block;text-align:center;font-family:courier;font-weight:bold;font-size:180%}.theme-light .round_body{color:#001427;display:block;text-align:center;font-family:trebuchet-ms;font-weight:bold;font-size:125%}.theme-light .event_announcement{color:#600d48;font-family:arial-narrow;font-weight:bold;font-size:125%}.theme-light .announce_header{color:#000;font-weight:bold;font-size:150%}.theme-light .announce_header_blue{color:#009;font-weight:bold;font-size:150%}.theme-light .announce_body{color:red;font-weight:normal;font-size:125%}.theme-light .centerbold{display:block;text-align:center;font-weight:bold}.theme-light .mod{color:#735638;font-weight:bold}.theme-light .modooc{color:#184880;font-weight:bold}.theme-light .adminmod{color:#402a14;font-weight:bold}.theme-light .mentorsay{color:#b38c32;font-weight:bold}.theme-light .mentorhelp{color:#007e00;font-weight:bold}.theme-light .mentorbody{color:#da6200;font-weight:bold}.theme-light .mentorstaff{color:#876101;font-weight:bold}.theme-light .staffsay{color:#876101;font-weight:bold}.theme-light .tajaran{color:#803b56}.theme-light .tajaran_signlang{color:#941c1c}.theme-light .skrell{color:#00ced1}.theme-light .soghun{color:#228b22}.theme-light .changeling{color:purple}.theme-light .vox{color:#a0a}.theme-light .monkey{color:#966c47}.theme-light .german{color:#858f1e;font-family:"Times New Roman",Times,serif}.theme-light .spanish{color:#cf982b}.theme-light .japanese{color:#940927}.theme-light .chinese{color:#fe1919}.theme-light .zombie{color:#216163;font-style:italic}.theme-light .commando{color:#fe9b24;font-style:bold}.theme-light .rough{font-family:trebuchet-ms,cursive,sans-serif}.theme-light .say_quote{font-family:Georgia,Verdana,sans-serif}.theme-light .admin .message{color:#314cad}.theme-light .admin .prefix{font-weight:bolder}.theme-light .pm{font-size:110%}.theme-light .retro_translator{font-weight:bold}.theme-light .yautja_translator{color:#a00;font-weight:bold;animation:glitch .5s infinite}@keyframes glitch{25%{color:#a00;transform:translate(-2px, -1px)}50%{color:#be0000;transform:translate(1px, -2px)}75%{color:#8d0000;transform:translate(-1px, 2px)}100%{color:#830000;transform:translate(1px, 1px)}}.theme-light .examine_block{background:#f2f7fa;border:1px solid #111a27;margin:.5em;padding:.5em .75em}.theme-light .examine_block .icon{width:1.5em;height:1.5em;margin:0;padding:0}.theme-light .tooltip{font-style:italic;border-bottom:1px dashed #000} +html,body{box-sizing:border-box;height:100%;margin:0;font-size:12px}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif}*,*:before,*:after{box-sizing:inherit}h1,h2,h3,h4,h5,h6{display:block;margin:0;padding:6px 0;padding:.5rem 0}h1{font-size:18px;font-size:1.5rem}h2{font-size:16px;font-size:1.333rem}h3{font-size:14px;font-size:1.167rem}h4{font-size:12px;font-size:1rem}td,th{vertical-align:baseline;text-align:left}.candystripe:nth-child(odd){background-color:rgba(0,0,0,.25)}.color-black{color:#1a1a1a !important}.color-white{color:#fff !important}.color-red{color:#df3e3e !important}.color-orange{color:#f37f33 !important}.color-yellow{color:#fbda21 !important}.color-olive{color:#cbe41c !important}.color-green{color:#25ca4c !important}.color-teal{color:#00d6cc !important}.color-blue{color:#2e93de !important}.color-dark-blue{color:#005fa7 !important}.color-violet{color:#7349cf !important}.color-purple{color:#ad45d0 !important}.color-pink{color:#e34da1 !important}.color-brown{color:#b97447 !important}.color-grey{color:#848484 !important}.color-light-grey{color:#b3b3b3 !important}.color-good{color:#68c22d !important}.color-average{color:#f29a29 !important}.color-bad{color:#df3e3e !important}.color-label{color:#8b9bb0 !important}.color-xeno{color:#664573 !important}.color-bg-black{background-color:#000 !important}.color-bg-white{background-color:#d9d9d9 !important}.color-bg-red{background-color:#bd2020 !important}.color-bg-orange{background-color:#d95e0c !important}.color-bg-yellow{background-color:#d9b804 !important}.color-bg-olive{background-color:#9aad14 !important}.color-bg-green{background-color:#1b9638 !important}.color-bg-teal{background-color:#009a93 !important}.color-bg-blue{background-color:#1c71b1 !important}.color-bg-dark-blue{background-color:#003e6e !important}.color-bg-violet{background-color:#552dab !important}.color-bg-purple{background-color:#8b2baa !important}.color-bg-pink{background-color:#cf2082 !important}.color-bg-brown{background-color:#8c5836 !important}.color-bg-grey{background-color:#646464 !important}.color-bg-light-grey{background-color:#919191 !important}.color-bg-good{background-color:#4d9121 !important}.color-bg-average{background-color:#cd7a0d !important}.color-bg-bad{background-color:#bd2020 !important}.color-bg-label{background-color:#657a94 !important}.color-bg-xeno{background-color:#462f4e !important}.debug-layout,.debug-layout *:not(g):not(path){color:rgba(255,255,255,.9) !important;background:transparent !important;outline:1px solid rgba(255,255,255,.5) !important;box-shadow:none !important;filter:none !important}.debug-layout:hover,.debug-layout *:not(g):not(path):hover{outline-color:rgba(255,255,255,.8) !important}.outline-dotted{outline-style:dotted !important}.outline-dashed{outline-style:dashed !important}.outline-solid{outline-style:solid !important}.outline-double{outline-style:double !important}.outline-groove{outline-style:groove !important}.outline-ridge{outline-style:ridge !important}.outline-inset{outline-style:inset !important}.outline-outset{outline-style:outset !important}.outline-color-black{outline:.167rem solid #1a1a1a !important}.outline-color-white{outline:.167rem solid #fff !important}.outline-color-red{outline:.167rem solid #df3e3e !important}.outline-color-orange{outline:.167rem solid #f37f33 !important}.outline-color-yellow{outline:.167rem solid #fbda21 !important}.outline-color-olive{outline:.167rem solid #cbe41c !important}.outline-color-green{outline:.167rem solid #25ca4c !important}.outline-color-teal{outline:.167rem solid #00d6cc !important}.outline-color-blue{outline:.167rem solid #2e93de !important}.outline-color-dark-blue{outline:.167rem solid #005fa7 !important}.outline-color-violet{outline:.167rem solid #7349cf !important}.outline-color-purple{outline:.167rem solid #ad45d0 !important}.outline-color-pink{outline:.167rem solid #e34da1 !important}.outline-color-brown{outline:.167rem solid #b97447 !important}.outline-color-grey{outline:.167rem solid #848484 !important}.outline-color-light-grey{outline:.167rem solid #b3b3b3 !important}.outline-color-good{outline:.167rem solid #68c22d !important}.outline-color-average{outline:.167rem solid #f29a29 !important}.outline-color-bad{outline:.167rem solid #df3e3e !important}.outline-color-label{outline:.167rem solid #8b9bb0 !important}.outline-color-xeno{outline:.167rem solid #664573 !important}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.text-baseline{text-align:baseline}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-pre{white-space:pre}.text-bold{font-weight:bold}.text-italic{font-style:italic}.text-underline{text-decoration:underline}.BlockQuote{color:#8b9bb0;border-left:.1666666667em solid #8b9bb0;padding-left:.5em;margin-bottom:.5em}.BlockQuote:last-child{margin-bottom:0}.Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.Button:last-child{margin-right:0;margin-bottom:0}.Button .fa,.Button .fas,.Button .far{margin-left:-0.25em;margin-right:-0.25em;min-width:1.333em;text-align:center}.Button--hasContent .fa,.Button--hasContent .fas,.Button--hasContent .far{margin-right:.25em}.Button--hasContent.Button--iconPosition--right .fa,.Button--hasContent.Button--iconPosition--right .fas,.Button--hasContent.Button--iconPosition--right .far{margin-right:0px;margin-left:3px}.Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.Button--fluid{display:block;margin-left:0;margin-right:0}.Button--circular{border-radius:50%}.Button--compact{padding:0 .25em;line-height:1.333em}.Button--color--black{transition:color 50ms,background-color 50ms;background-color:#000;color:#fff}.Button--color--black:hover{transition:color 0ms,background-color 0ms}.Button--color--black:focus{transition:color 100ms,background-color 100ms}.Button--color--black:hover,.Button--color--black:focus{background-color:#131313;color:#fff}.Button--color--white{transition:color 50ms,background-color 50ms;background-color:#d9d9d9;color:#000}.Button--color--white:hover{transition:color 0ms,background-color 0ms}.Button--color--white:focus{transition:color 100ms,background-color 100ms}.Button--color--white:hover,.Button--color--white:focus{background-color:#f8f8f8;color:#000}.Button--color--red{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--red:hover{transition:color 0ms,background-color 0ms}.Button--color--red:focus{transition:color 100ms,background-color 100ms}.Button--color--red:hover,.Button--color--red:focus{background-color:#dc4848;color:#fff}.Button--color--orange{transition:color 50ms,background-color 50ms;background-color:#d95e0c;color:#fff}.Button--color--orange:hover{transition:color 0ms,background-color 0ms}.Button--color--orange:focus{transition:color 100ms,background-color 100ms}.Button--color--orange:hover,.Button--color--orange:focus{background-color:#f0853f;color:#fff}.Button--color--yellow{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--yellow:hover{transition:color 0ms,background-color 0ms}.Button--color--yellow:focus{transition:color 100ms,background-color 100ms}.Button--color--yellow:hover,.Button--color--yellow:focus{background-color:#f5d72e;color:#000}.Button--color--olive{transition:color 50ms,background-color 50ms;background-color:#9aad14;color:#fff}.Button--color--olive:hover{transition:color 0ms,background-color 0ms}.Button--color--olive:focus{transition:color 100ms,background-color 100ms}.Button--color--olive:hover,.Button--color--olive:focus{background-color:#c4da2b;color:#fff}.Button--color--green{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--color--green:hover{transition:color 0ms,background-color 0ms}.Button--color--green:focus{transition:color 100ms,background-color 100ms}.Button--color--green:hover,.Button--color--green:focus{background-color:#32c154;color:#fff}.Button--color--teal{transition:color 50ms,background-color 50ms;background-color:#009a93;color:#fff}.Button--color--teal:hover{transition:color 0ms,background-color 0ms}.Button--color--teal:focus{transition:color 100ms,background-color 100ms}.Button--color--teal:hover,.Button--color--teal:focus{background-color:#13c4bc;color:#fff}.Button--color--blue{transition:color 50ms,background-color 50ms;background-color:#1c71b1;color:#fff}.Button--color--blue:hover{transition:color 0ms,background-color 0ms}.Button--color--blue:focus{transition:color 100ms,background-color 100ms}.Button--color--blue:hover,.Button--color--blue:focus{background-color:#3a95d9;color:#fff}.Button--color--dark-blue{transition:color 50ms,background-color 50ms;background-color:#003e6e;color:#fff}.Button--color--dark-blue:hover{transition:color 0ms,background-color 0ms}.Button--color--dark-blue:focus{transition:color 100ms,background-color 100ms}.Button--color--dark-blue:hover,.Button--color--dark-blue:focus{background-color:#135b92;color:#fff}.Button--color--violet{transition:color 50ms,background-color 50ms;background-color:#552dab;color:#fff}.Button--color--violet:hover{transition:color 0ms,background-color 0ms}.Button--color--violet:focus{transition:color 100ms,background-color 100ms}.Button--color--violet:hover,.Button--color--violet:focus{background-color:#7953cc;color:#fff}.Button--color--purple{transition:color 50ms,background-color 50ms;background-color:#8b2baa;color:#fff}.Button--color--purple:hover{transition:color 0ms,background-color 0ms}.Button--color--purple:focus{transition:color 100ms,background-color 100ms}.Button--color--purple:hover,.Button--color--purple:focus{background-color:#ad4fcd;color:#fff}.Button--color--pink{transition:color 50ms,background-color 50ms;background-color:#cf2082;color:#fff}.Button--color--pink:hover{transition:color 0ms,background-color 0ms}.Button--color--pink:focus{transition:color 100ms,background-color 100ms}.Button--color--pink:hover,.Button--color--pink:focus{background-color:#e257a5;color:#fff}.Button--color--brown{transition:color 50ms,background-color 50ms;background-color:#8c5836;color:#fff}.Button--color--brown:hover{transition:color 0ms,background-color 0ms}.Button--color--brown:focus{transition:color 100ms,background-color 100ms}.Button--color--brown:hover,.Button--color--brown:focus{background-color:#b47851;color:#fff}.Button--color--grey{transition:color 50ms,background-color 50ms;background-color:#646464;color:#fff}.Button--color--grey:hover{transition:color 0ms,background-color 0ms}.Button--color--grey:focus{transition:color 100ms,background-color 100ms}.Button--color--grey:hover,.Button--color--grey:focus{background-color:#868686;color:#fff}.Button--color--light-grey{transition:color 50ms,background-color 50ms;background-color:#919191;color:#fff}.Button--color--light-grey:hover{transition:color 0ms,background-color 0ms}.Button--color--light-grey:focus{transition:color 100ms,background-color 100ms}.Button--color--light-grey:hover,.Button--color--light-grey:focus{background-color:#bababa;color:#fff}.Button--color--good{transition:color 50ms,background-color 50ms;background-color:#4d9121;color:#fff}.Button--color--good:hover{transition:color 0ms,background-color 0ms}.Button--color--good:focus{transition:color 100ms,background-color 100ms}.Button--color--good:hover,.Button--color--good:focus{background-color:#6cba39;color:#fff}.Button--color--average{transition:color 50ms,background-color 50ms;background-color:#cd7a0d;color:#fff}.Button--color--average:hover{transition:color 0ms,background-color 0ms}.Button--color--average:focus{transition:color 100ms,background-color 100ms}.Button--color--average:hover,.Button--color--average:focus{background-color:#ed9d35;color:#fff}.Button--color--bad{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--bad:hover{transition:color 0ms,background-color 0ms}.Button--color--bad:focus{transition:color 100ms,background-color 100ms}.Button--color--bad:hover,.Button--color--bad:focus{background-color:#dc4848;color:#fff}.Button--color--label{transition:color 50ms,background-color 50ms;background-color:#657a94;color:#fff}.Button--color--label:hover{transition:color 0ms,background-color 0ms}.Button--color--label:focus{transition:color 100ms,background-color 100ms}.Button--color--label:hover,.Button--color--label:focus{background-color:#91a1b3;color:#fff}.Button--color--xeno{transition:color 50ms,background-color 50ms;background-color:#462f4e;color:#fff}.Button--color--xeno:hover{transition:color 0ms,background-color 0ms}.Button--color--xeno:focus{transition:color 100ms,background-color 100ms}.Button--color--xeno:hover,.Button--color--xeno:focus{background-color:#64496d;color:#fff}.Button--color--default{transition:color 50ms,background-color 50ms;background-color:#3e6189;color:#fff}.Button--color--default:hover{transition:color 0ms,background-color 0ms}.Button--color--default:focus{transition:color 100ms,background-color 100ms}.Button--color--default:hover,.Button--color--default:focus{background-color:#5c83b0;color:#fff}.Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#d9b804;color:#000}.Button--color--caution:hover{transition:color 0ms,background-color 0ms}.Button--color--caution:focus{transition:color 100ms,background-color 100ms}.Button--color--caution:hover,.Button--color--caution:focus{background-color:#f5d72e;color:#000}.Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#bd2020;color:#fff}.Button--color--danger:hover{transition:color 0ms,background-color 0ms}.Button--color--danger:focus{transition:color 100ms,background-color 100ms}.Button--color--danger:hover,.Button--color--danger:focus{background-color:#dc4848;color:#fff}.Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#202020;color:#fff;background-color:rgba(32,32,32,0);color:rgba(255,255,255,.5)}.Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.Button--color--transparent:focus{transition:color 100ms,background-color 100ms}.Button--color--transparent:hover,.Button--color--transparent:focus{background-color:#383838;color:#fff}.Button--disabled{background-color:#999 !important}.Button--selected{transition:color 50ms,background-color 50ms;background-color:#1b9638;color:#fff}.Button--selected:hover{transition:color 0ms,background-color 0ms}.Button--selected:focus{transition:color 100ms,background-color 100ms}.Button--selected:hover,.Button--selected:focus{background-color:#32c154;color:#fff}.Button--flex{display:inline-flex;flex-direction:column}.Button--flex--fluid{width:100%}.Button--verticalAlignContent--top{justify-content:flex-start}.Button--verticalAlignContent--middle{justify-content:center}.Button--verticalAlignContent--bottom{justify-content:flex-end}.Button__content{display:block;align-self:stretch}.ColorBox{display:inline-block;width:1em;height:1em;line-height:1em;text-align:center}.Dimmer{display:flex;justify-content:center;align-items:center;position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(0,0,0,.75);z-index:1}.Divider--horizontal{margin:.5em 0}.Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Divider--vertical{height:100%;margin:0 .5em}.Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Dropdown{position:relative}.Dropdown__control{position:relative;display:inline-block;font-family:Verdana,sans-serif;font-size:1em;width:8.3333333333em;line-height:1.4166666667em;user-select:none}.Dropdown__arrow-button{float:right;padding-left:.35em;width:1.2em;height:1.8333333333em;border-left:.0833333333em solid #000;border-left:.0833333333em solid rgba(0,0,0,.25)}.Dropdown__menu{position:absolute;overflow-y:auto;z-index:5;width:8.3333333333em;max-height:16.6666666667em;overflow-y:scroll;border-radius:0 0 .1666666667em .1666666667em;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menu-noscroll{position:absolute;overflow-y:auto;z-index:5;width:8.3333333333em;max-height:16.6666666667em;border-radius:0 0 .1666666667em .1666666667em;color:#fff;background-color:#000;background-color:rgba(0,0,0,.75)}.Dropdown__menuentry{padding:.1666666667em .3333333333em;font-family:Verdana,sans-serif;font-size:1em;line-height:1.4166666667em;transition:background-color 100ms ease-out}.Dropdown__menuentry:hover{background-color:rgba(255,255,255,.2);transition:background-color 0ms}.Dropdown__over{top:auto;bottom:100%}.Dropdown__selected-text{display:inline-block;text-overflow:ellipsis;white-space:nowrap;height:1.4166666667em;width:calc(100% - 1.2em)}.Flex{display:-ms-flexbox;display:flex}.Flex--inline{display:inline-flex}.Flex--iefix{display:block}.Flex--iefix.Flex--inline{display:inline-block}.Flex__item--iefix{display:inline-block}.Flex--iefix--column>.Flex__item--iefix{display:block}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:"Consolas",monospace}.Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto;margin-bottom:-0.2em;cursor:n-resize}.Knob:after{content:".";color:transparent;line-height:2.5em}.Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 100%);border-radius:50%;box-shadow:0 .05em .5em 0 rgba(0,0,0,.5)}.Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:rgba(255,255,255,.9)}.Knob__popupValue{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.Knob__ringTrackPivot{transform:rotateZ(135deg)}.Knob__ringTrack{fill:transparent;stroke:rgba(255,255,255,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.Knob__ringFillPivot{transform:rotateZ(135deg)}.Knob--bipolar .Knob__ringFillPivot{transform:rotateZ(270deg)}.Knob__ringFill{fill:transparent;stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms ease-out}.Knob--color--black .Knob__ringFill{stroke:#1a1a1a}.Knob--color--white .Knob__ringFill{stroke:#fff}.Knob--color--red .Knob__ringFill{stroke:#df3e3e}.Knob--color--orange .Knob__ringFill{stroke:#f37f33}.Knob--color--yellow .Knob__ringFill{stroke:#fbda21}.Knob--color--olive .Knob__ringFill{stroke:#cbe41c}.Knob--color--green .Knob__ringFill{stroke:#25ca4c}.Knob--color--teal .Knob__ringFill{stroke:#00d6cc}.Knob--color--blue .Knob__ringFill{stroke:#2e93de}.Knob--color--dark-blue .Knob__ringFill{stroke:#005fa7}.Knob--color--violet .Knob__ringFill{stroke:#7349cf}.Knob--color--purple .Knob__ringFill{stroke:#ad45d0}.Knob--color--pink .Knob__ringFill{stroke:#e34da1}.Knob--color--brown .Knob__ringFill{stroke:#b97447}.Knob--color--grey .Knob__ringFill{stroke:#848484}.Knob--color--light-grey .Knob__ringFill{stroke:#b3b3b3}.Knob--color--good .Knob__ringFill{stroke:#68c22d}.Knob--color--average .Knob__ringFill{stroke:#f29a29}.Knob--color--bad .Knob__ringFill{stroke:#df3e3e}.Knob--color--label .Knob__ringFill{stroke:#8b9bb0}.Knob--color--xeno .Knob__ringFill{stroke:#664573}.LabeledList{display:table;width:100%;width:calc(100% + 1em);border-collapse:collapse;border-spacing:0;margin:-0.25em -0.5em;margin-bottom:0;padding:0}.LabeledList__row{display:table-row}.LabeledList__row:last-child .LabeledList__cell{padding-bottom:0}.LabeledList__cell{display:table-cell;margin:0;padding:.25em .5em;border:0;text-align:left}.LabeledList__label--nowrap{width:1%;white-space:nowrap;min-width:5em}.LabeledList__buttons{width:.1%;white-space:nowrap;text-align:right;padding-top:.0833333333em;padding-bottom:0}.Modal{background-color:#202020;max-width:calc(100% - 1rem);padding:1rem}.NoticeBox{padding:.33em .5em;margin-bottom:.5em;box-shadow:none;font-weight:bold;font-style:italic;color:#000;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg, transparent, transparent 0.8333333333em, rgba(0, 0, 0, 0.1) 0.8333333333em, rgba(0, 0, 0, 0.1) 1.6666666667em)}.NoticeBox--color--black{color:#fff;background-color:#000}.NoticeBox--color--white{color:#000;background-color:#b3b3b3}.NoticeBox--color--red{color:#fff;background-color:#701f1f}.NoticeBox--color--orange{color:#fff;background-color:#854114}.NoticeBox--color--yellow{color:#000;background-color:#83710d}.NoticeBox--color--olive{color:#000;background-color:#576015}.NoticeBox--color--green{color:#fff;background-color:#174e24}.NoticeBox--color--teal{color:#fff;background-color:#064845}.NoticeBox--color--blue{color:#fff;background-color:#1b4565}.NoticeBox--color--dark-blue{color:#fff;background-color:#02121f}.NoticeBox--color--violet{color:#fff;background-color:#3b2864}.NoticeBox--color--purple{color:#fff;background-color:#542663}.NoticeBox--color--pink{color:#fff;background-color:#802257}.NoticeBox--color--brown{color:#fff;background-color:#4c3729}.NoticeBox--color--grey{color:#fff;background-color:#3e3e3e}.NoticeBox--color--light-grey{color:#fff;background-color:#6a6a6a}.NoticeBox--color--good{color:#fff;background-color:#2e4b1a}.NoticeBox--color--average{color:#fff;background-color:#7b4e13}.NoticeBox--color--bad{color:#fff;background-color:#701f1f}.NoticeBox--color--label{color:#fff;background-color:#53565a}.NoticeBox--color--xeno{color:#fff;background-color:#19161b}.NoticeBox--type--info{color:#fff;background-color:#235982}.NoticeBox--type--success{color:#fff;background-color:#1e662f}.NoticeBox--type--warning{color:#fff;background-color:#a95219}.NoticeBox--type--danger{color:#fff;background-color:#8f2828}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:"Consolas",monospace}.NumberInput{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#88bfff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.NumberInput--fluid{display:block}.NumberInput__content{margin-left:.5em}.NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #88bfff;background-color:#88bfff}.NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#0a0a0a;color:#fff;text-align:right}.ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-width:.0833333333em !important;border-style:solid !important;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color 900ms ease-out}.ProgressBar__fill{position:absolute;top:-0.5px;left:0px;bottom:-0.5px}.ProgressBar__fill--animated{transition:background-color 900ms ease-out,width 900ms ease-out}.ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.ProgressBar--color--default{border:.0833333333em solid #3e6189}.ProgressBar--color--default .ProgressBar__fill{background-color:#3e6189}.ProgressBar--color--black{border-color:#000 !important}.ProgressBar--color--black .ProgressBar__fill{background-color:#000}.ProgressBar--color--white{border-color:#d9d9d9 !important}.ProgressBar--color--white .ProgressBar__fill{background-color:#d9d9d9}.ProgressBar--color--red{border-color:#bd2020 !important}.ProgressBar--color--red .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--orange{border-color:#d95e0c !important}.ProgressBar--color--orange .ProgressBar__fill{background-color:#d95e0c}.ProgressBar--color--yellow{border-color:#d9b804 !important}.ProgressBar--color--yellow .ProgressBar__fill{background-color:#d9b804}.ProgressBar--color--olive{border-color:#9aad14 !important}.ProgressBar--color--olive .ProgressBar__fill{background-color:#9aad14}.ProgressBar--color--green{border-color:#1b9638 !important}.ProgressBar--color--green .ProgressBar__fill{background-color:#1b9638}.ProgressBar--color--teal{border-color:#009a93 !important}.ProgressBar--color--teal .ProgressBar__fill{background-color:#009a93}.ProgressBar--color--blue{border-color:#1c71b1 !important}.ProgressBar--color--blue .ProgressBar__fill{background-color:#1c71b1}.ProgressBar--color--dark-blue{border-color:#003e6e !important}.ProgressBar--color--dark-blue .ProgressBar__fill{background-color:#003e6e}.ProgressBar--color--violet{border-color:#552dab !important}.ProgressBar--color--violet .ProgressBar__fill{background-color:#552dab}.ProgressBar--color--purple{border-color:#8b2baa !important}.ProgressBar--color--purple .ProgressBar__fill{background-color:#8b2baa}.ProgressBar--color--pink{border-color:#cf2082 !important}.ProgressBar--color--pink .ProgressBar__fill{background-color:#cf2082}.ProgressBar--color--brown{border-color:#8c5836 !important}.ProgressBar--color--brown .ProgressBar__fill{background-color:#8c5836}.ProgressBar--color--grey{border-color:#646464 !important}.ProgressBar--color--grey .ProgressBar__fill{background-color:#646464}.ProgressBar--color--light-grey{border-color:#919191 !important}.ProgressBar--color--light-grey .ProgressBar__fill{background-color:#919191}.ProgressBar--color--good{border-color:#4d9121 !important}.ProgressBar--color--good .ProgressBar__fill{background-color:#4d9121}.ProgressBar--color--average{border-color:#cd7a0d !important}.ProgressBar--color--average .ProgressBar__fill{background-color:#cd7a0d}.ProgressBar--color--bad{border-color:#bd2020 !important}.ProgressBar--color--bad .ProgressBar__fill{background-color:#bd2020}.ProgressBar--color--label{border-color:#657a94 !important}.ProgressBar--color--label .ProgressBar__fill{background-color:#657a94}.ProgressBar--color--xeno{border-color:#462f4e !important}.ProgressBar--color--xeno .ProgressBar__fill{background-color:#462f4e}.Section{position:relative;margin-bottom:.5em;background-color:#131313;background-color:#131313;box-sizing:border-box}.Section:last-child{margin-bottom:0}.Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #4972a1}.Section__titleText{font-size:1.1666666667em;font-weight:bold;color:#fff}.Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.Section__rest{position:relative}.Section__content{padding:.66em .5em}.Section--fitted>.Section__rest>.Section__content{padding:0}.Section--fill{display:flex;flex-direction:column;height:100%}.Section--fill>.Section__rest{flex-grow:1}.Section--fill>.Section__rest>.Section__content{height:100%}.Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.Section--fill.Section--iefix{display:table !important;width:100% !important;height:100% !important;border-collapse:collapse;border-spacing:0}.Section--fill.Section--iefix>.Section__rest{display:table-row !important;height:100% !important}.Section--scrollable{overflow-x:hidden;overflow-y:hidden}.Section--scrollable>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:hidden}.Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:hidden;overflow-x:scroll}.Section--scrollable.Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.Section--scrollable.Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:scroll}.Section .Section{background-color:transparent;margin-left:-0.5em;margin-right:-0.5em}.Section .Section:first-child{margin-top:-0.5em}.Section .Section .Section__titleText{font-size:1.0833333333em}.Section .Section .Section .Section__titleText{font-size:1em}.Slider{cursor:e-resize}.Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none !important}.Slider__cursor{position:absolute;top:0;right:-.0833333333em;bottom:0;width:0;border-left:.1666666667em solid #fff}.Slider__pointer{position:absolute;right:-.4166666667em;bottom:-.3333333333em;width:0;height:0;border-left:.4166666667em solid transparent;border-right:.4166666667em solid transparent;border-bottom:.4166666667em solid #fff}.Slider__popupValue{position:absolute;right:0;top:-2rem;font-size:1rem;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.Divider--horizontal{margin:.5em 0}.Divider--horizontal:not(.Divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Divider--vertical{height:100%;margin:0 .5em}.Divider--vertical:not(.Divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--fill{height:100%}.Stack--horizontal>.Stack__item{margin-left:.5em}.Stack--horizontal>.Stack__item:first-child{margin-left:0}.Stack--vertical>.Stack__item{margin-top:.5em}.Stack--vertical>.Stack__item:first-child{margin-top:0}.Stack--horizontal>.Stack__divider:not(.Stack__divider--hidden){border-left:.1666666667em solid rgba(255,255,255,.1)}.Stack--vertical>.Stack__divider:not(.Stack__divider--hidden){border-top:.1666666667em solid rgba(255,255,255,.1)}.Table{display:table;width:100%;border-collapse:collapse;border-spacing:0;margin:0}.Table--collapsing{width:auto}.Table__row{display:table-row}.Table__cell{display:table-cell;padding:0 .25em}.Table__cell:first-child{padding-left:0}.Table__cell:last-child{padding-right:0}.Table__row--header .Table__cell,.Table__cell--header{font-weight:bold;padding-bottom:.5em}.Table__cell--collapsing{width:1%;white-space:nowrap}.Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:#131313}.Tabs--fill{height:100%}.Section .Tabs{background-color:transparent}.Section:not(.Section--fitted) .Tabs{margin:0 -0.5em .5em}.Section:not(.Section--fitted) .Tabs:first-child{margin-top:-0.5em}.Tabs--vertical{flex-direction:column;padding:.25em 0 .25em .25em}.Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0 .25em}.Tabs--horizontal:last-child{margin-bottom:0}.Tabs__Tab{flex-grow:0}.Tabs--fluid .Tabs__Tab{flex-grow:1}.Tab{display:flex;align-items:center;justify-content:space-between;background-color:transparent;color:rgba(255,255,255,.5);min-height:2.25em;min-width:4em}.Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075)}.Tab--selected{background-color:rgba(255,255,255,.125);color:#dfe7f0}.Tab__text{flex-grow:1;margin:0 .5em}.Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.Tabs--horizontal .Tab{border-top:.1666666667em solid transparent;border-bottom:.1666666667em solid transparent;border-top-left-radius:.25em;border-top-right-radius:.25em}.Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #d4dfec}.Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid transparent;border-right:.1666666667em solid transparent;border-top-left-radius:.25em;border-bottom-left-radius:.25em}.Tabs--vertical .Tab--selected{border-right:.1666666667em solid #d4dfec}.Tab--selected.Tab--color--black{color:#535353}.Tabs--horizontal .Tab--selected.Tab--color--black{border-bottom-color:#1a1a1a}.Tabs--vertical .Tab--selected.Tab--color--black{border-right-color:#1a1a1a}.Tab--selected.Tab--color--white{color:#fff}.Tabs--horizontal .Tab--selected.Tab--color--white{border-bottom-color:#fff}.Tabs--vertical .Tab--selected.Tab--color--white{border-right-color:#fff}.Tab--selected.Tab--color--red{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--red{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--red{border-right-color:#df3e3e}.Tab--selected.Tab--color--orange{color:#f69f66}.Tabs--horizontal .Tab--selected.Tab--color--orange{border-bottom-color:#f37f33}.Tabs--vertical .Tab--selected.Tab--color--orange{border-right-color:#f37f33}.Tab--selected.Tab--color--yellow{color:#fce358}.Tabs--horizontal .Tab--selected.Tab--color--yellow{border-bottom-color:#fbda21}.Tabs--vertical .Tab--selected.Tab--color--yellow{border-right-color:#fbda21}.Tab--selected.Tab--color--olive{color:#d8eb55}.Tabs--horizontal .Tab--selected.Tab--color--olive{border-bottom-color:#cbe41c}.Tabs--vertical .Tab--selected.Tab--color--olive{border-right-color:#cbe41c}.Tab--selected.Tab--color--green{color:#53e074}.Tabs--horizontal .Tab--selected.Tab--color--green{border-bottom-color:#25ca4c}.Tabs--vertical .Tab--selected.Tab--color--green{border-right-color:#25ca4c}.Tab--selected.Tab--color--teal{color:#21fff5}.Tabs--horizontal .Tab--selected.Tab--color--teal{border-bottom-color:#00d6cc}.Tabs--vertical .Tab--selected.Tab--color--teal{border-right-color:#00d6cc}.Tab--selected.Tab--color--blue{color:#62aee6}.Tabs--horizontal .Tab--selected.Tab--color--blue{border-bottom-color:#2e93de}.Tabs--vertical .Tab--selected.Tab--color--blue{border-right-color:#2e93de}.Tab--selected.Tab--color--dark-blue{color:#008ffd}.Tabs--horizontal .Tab--selected.Tab--color--dark-blue{border-bottom-color:#005fa7}.Tabs--vertical .Tab--selected.Tab--color--dark-blue{border-right-color:#005fa7}.Tab--selected.Tab--color--violet{color:#9676db}.Tabs--horizontal .Tab--selected.Tab--color--violet{border-bottom-color:#7349cf}.Tabs--vertical .Tab--selected.Tab--color--violet{border-right-color:#7349cf}.Tab--selected.Tab--color--purple{color:#c274db}.Tabs--horizontal .Tab--selected.Tab--color--purple{border-bottom-color:#ad45d0}.Tabs--vertical .Tab--selected.Tab--color--purple{border-right-color:#ad45d0}.Tab--selected.Tab--color--pink{color:#ea79b9}.Tabs--horizontal .Tab--selected.Tab--color--pink{border-bottom-color:#e34da1}.Tabs--vertical .Tab--selected.Tab--color--pink{border-right-color:#e34da1}.Tab--selected.Tab--color--brown{color:#ca9775}.Tabs--horizontal .Tab--selected.Tab--color--brown{border-bottom-color:#b97447}.Tabs--vertical .Tab--selected.Tab--color--brown{border-right-color:#b97447}.Tab--selected.Tab--color--grey{color:#a3a3a3}.Tabs--horizontal .Tab--selected.Tab--color--grey{border-bottom-color:#848484}.Tabs--vertical .Tab--selected.Tab--color--grey{border-right-color:#848484}.Tab--selected.Tab--color--light-grey{color:#c6c6c6}.Tabs--horizontal .Tab--selected.Tab--color--light-grey{border-bottom-color:#b3b3b3}.Tabs--vertical .Tab--selected.Tab--color--light-grey{border-right-color:#b3b3b3}.Tab--selected.Tab--color--good{color:#8cd95a}.Tabs--horizontal .Tab--selected.Tab--color--good{border-bottom-color:#68c22d}.Tabs--vertical .Tab--selected.Tab--color--good{border-right-color:#68c22d}.Tab--selected.Tab--color--average{color:#f5b35e}.Tabs--horizontal .Tab--selected.Tab--color--average{border-bottom-color:#f29a29}.Tabs--vertical .Tab--selected.Tab--color--average{border-right-color:#f29a29}.Tab--selected.Tab--color--bad{color:#e76e6e}.Tabs--horizontal .Tab--selected.Tab--color--bad{border-bottom-color:#df3e3e}.Tabs--vertical .Tab--selected.Tab--color--bad{border-right-color:#df3e3e}.Tab--selected.Tab--color--label{color:#a8b4c4}.Tabs--horizontal .Tab--selected.Tab--color--label{border-bottom-color:#8b9bb0}.Tabs--vertical .Tab--selected.Tab--color--label{border-right-color:#8b9bb0}.Tab--selected.Tab--color--xeno{color:#9366a3}.Tabs--horizontal .Tab--selected.Tab--color--xeno{border-bottom-color:#664573}.Tabs--vertical .Tab--selected.Tab--color--xeno{border-right-color:#664573}.Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;color:#fff;background-color:#0a0a0a;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.Input--fluid{display:block;width:auto}.Input__baseline{display:inline-block;color:transparent}.Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#fff;color:inherit}.Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.Input--monospace .Input__input{font-family:"Consolas",monospace}.TextArea{position:relative;display:inline-block;border:.0833333333em solid #88bfff;border:.0833333333em solid rgba(136,191,255,.75);border-radius:.16em;background-color:#0a0a0a;margin-right:.1666666667em;line-height:1.4166666667em;box-sizing:border-box;width:100%}.TextArea--fluid{display:block;width:auto;height:auto}.TextArea--noborder{border:0px}.TextArea__textarea.TextArea__textarea--scrollable{overflow:auto;overflow-x:hidden;overflow-y:scroll}.TextArea__textarea{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;height:100%;font-size:1em;line-height:1.4166666667em;min-height:1.4166666667em;margin:0;padding:0 .5em;font-family:inherit;background-color:transparent;color:inherit;box-sizing:border-box;word-wrap:break-word;overflow:hidden}.TextArea__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.TextArea__textarea_custom{overflow:visible;white-space:pre-wrap}.Tooltip{z-index:2;padding:.5em .75em;pointer-events:none;text-align:left;transition:opacity 150ms ease-out;background-color:#000;color:#fff;box-shadow:.1em .1em 1.25em -0.1em rgba(0,0,0,.5);border-radius:.16em;max-width:20.8333333333em}.Chat{color:#abc6ec}.Chat__badge{display:inline-block;min-width:.5em;font-size:.7em;padding:.2em .3em;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:crimson;border-radius:10px;transition:font-size 200ms ease-out}.Chat__badge:before{content:"x"}.Chat__badge--animate{font-size:.9em;transition:font-size 0ms}.Chat__scrollButton{position:fixed;right:2em;bottom:1em}.Chat__reconnected{font-size:.85em;text-align:center;margin:1em 0 2em}.Chat__reconnected:before{content:"Reconnected";display:inline-block;border-radius:1em;padding:0 .7em;color:#db2828;background-color:#131313}.Chat__reconnected:after{content:"";display:block;margin-top:-0.75em;border-bottom:.1666666667em solid #db2828}.Chat__highlight{color:#000}.Chat__highlight--restricted{color:#fff;background-color:#a00;font-weight:bold}.ChatMessage{word-wrap:break-word}.ChatMessage--highlighted{position:relative;border-left:.1666666667em solid #fd4;padding-left:.5em}.ChatMessage--highlighted:after{content:"";position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(255,221,68,.1);pointer-events:none}.Ping{position:relative;padding:.125em .25em;border:.0833333333em solid rgba(140,140,140,.5);border-radius:.25em;width:3.75em;text-align:right}.Ping__indicator{content:"";position:absolute;top:.5em;left:.5em;width:.5em;height:.5em;background-color:#888;border-radius:.25em}.Notifications{position:absolute;bottom:1em;left:1em;right:2em}.Notification{color:#fff;background-color:crimson;padding:.5em;margin:1em 0}.Notification:first-child{margin-top:0}.Notification:last-child{margin-bottom:0}.Layout,.Layout *{scrollbar-base-color:#181818;scrollbar-face-color:#363636;scrollbar-3dlight-color:#202020;scrollbar-highlight-color:#202020;scrollbar-track-color:#181818;scrollbar-arrow-color:#909090;scrollbar-shadow-color:#363636}.Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow-x:hidden;overflow-y:hidden}.Layout__content--scrollable{overflow-y:scroll;margin-bottom:0}.Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#fff;background-color:#202020;background-image:linear-gradient(to bottom, #202020 0%, #202020 100%)}.Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.Window__contentPadding:after{height:0}.Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(56,56,56,.25);pointer-events:none}.Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}em{font-style:normal;font-weight:bold}img{margin:0;padding:0;line-height:1;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}img.icon{height:1em;min-height:16px;width:auto;vertical-align:bottom}a{color:#397ea5}a.visited{color:#7c00e6}a:visited{color:#7c00e6}a.popt{text-decoration:none}.popup{position:fixed;top:50%;left:50%;background:#ddd}.popup .close{position:absolute;background:#aaa;top:0;right:0;color:#333;text-decoration:none;z-index:2;padding:0 10px;height:30px;line-height:30px}.popup .close:hover{background:#999}.popup .head{background:#999;color:#ddd;padding:0 10px;height:30px;line-height:30px;text-transform:uppercase;font-size:.9em;font-weight:bold;border-bottom:2px solid green}.popup input{border:1px solid #999;background:#fff;margin:0;padding:5px;outline:none;color:#333}.popup input[type=text]:hover,.popup input[type=text]:active,.popup input[type=text]:focus{border-color:green}.popup input[type=submit]{padding:5px 10px;background:#999;color:#ddd;text-transform:uppercase;font-size:.9em;font-weight:bold}.popup input[type=submit]:hover,.popup input[type=submit]:focus,.popup input[type=submit]:active{background:#aaa;cursor:pointer}.changeFont{padding:10px}.changeFont a{display:block;text-decoration:none;padding:3px;color:#333}.changeFont a:hover{background:#ccc}.highlightPopup{padding:10px;text-align:center}.highlightPopup input[type=text]{display:block;width:215px;text-align:left;margin-top:5px}.highlightPopup input.highlightColor{background-color:#ff0}.highlightPopup input.highlightTermSubmit{margin-top:5px}.contextMenu{background-color:#ddd;position:fixed;margin:2px;width:150px}.contextMenu a{display:block;padding:2px 5px;text-decoration:none;color:#333}.contextMenu a:hover{background-color:#ccc}.filterMessages{padding:5px}.filterMessages div{padding:2px 0}.icon-stack{height:1em;line-height:1em;width:1em;vertical-align:middle;margin-top:-2px}.motd{color:#a4bad6;font-family:Verdana,sans-serif;white-space:normal}.motd h1,.motd h2,.motd h3,.motd h4,.motd h5,.motd h6{color:#a4bad6;text-decoration:underline}.motd a,.motd a:link,.motd a:visited,.motd a:active,.motd a:hover{color:#a4bad6}.bold,.name,.prefix,.ooc,.looc,.adminooc,.admin,.medal,.yell{font-weight:bold}.italic,.italics{font-style:italic}.highlight{background:#ff0}h1,h2,h3,h4,h5,h6{color:#a4bad6;font-family:Georgia,Verdana,sans-serif}h1.alert,h2.alert{color:#a4bad6}em{font-style:normal;font-weight:bold}.ooc{font-weight:bold}.adminobserverooc{color:#09c;font-weight:bold}.adminooc{color:#3d5bc3;font-weight:bold}.adminsay{color:#9611d4;font-weight:bold}.admin{color:#5975da;font-weight:bold}.name{font-weight:bold}.deadsay{color:#e2c1ff}.binarysay{color:#1e90ff}.binarysay a{color:lime}.binarysay a:active,.binarysay a:visited{color:#8f8}.radio{color:#1ecc43}.sciradio{color:#c68cfa}.comradio{color:#fcdf03}.secradio{color:#dd3535}.medradio{color:#57b8f0}.engradio{color:#f37746}.suppradio{color:#b88646}.servradio{color:#6ca729}.syndradio{color:#8f4a4b}.gangradio{color:#ac2ea1}.centcomradio{color:#2681a5}.aiprivradio{color:#d65d95}.redteamradio{color:#f44}.blueteamradio{color:#3434fd}.greenteamradio{color:#34fd34}.yellowteamradio{color:#fdfd34}.yell{font-weight:bold}.alert{color:#d82020}.userdanger{color:#c51e1e;font-weight:bold;font-size:185%}.bolddanger{color:#c51e1e;font-weight:bold}.danger{color:#c51e1e}.warning{color:#c51e1e;font-style:italic}.alertwarning{color:red;font-weight:bold}.boldwarning{color:#c51e1e;font-style:italic;font-weight:bold}.announce{color:#c51e1e;font-weight:bold}.boldannounce{color:#c51e1e;font-weight:bold}.bigannounce{font-weight:bold;font-size:115%}.greenannounce{color:#059223;font-weight:bold}.rose{color:#ff5050}.info{color:#9ab0ff}.notice{color:#6685f5}.staff_ic{color:#6685f5}.tinynotice{color:#6685f5;font-size:85%}.tinynoticeital{color:#6685f5;font-style:italic;font-size:85%}.smallnotice{color:#6685f5;font-size:90%}.smallnoticeital{color:#6685f5;font-style:italic;font-size:90%}.boldnotice{color:#6685f5;font-weight:bold}.hear{color:#6685f5;font-style:italic}.adminnotice{color:#6685f5}.adminhelp{color:red;font-weight:bold}.unconscious{color:#a4bad6;font-weight:bold}.suicide{color:#ff5050;font-style:italic}.green{color:#059223}.grey{color:#838383}.red{color:red}.blue{color:#215cff}.nicegreen{color:#059223}.boldnicegreen{color:#059223;font-weight:bold}.cult{color:#973e3b}.cultitalic{color:#973e3b;font-style:italic}.cultbold{color:#973e3b;font-style:italic;font-weight:bold}.cultboldtalic{color:#973e3b;font-weight:bold;font-size:185%}.cultlarge{color:#973e3b;font-weight:bold;font-size:185%}.narsie{color:#973e3b;font-weight:bold;font-size:925%}.narsiesmall{color:#973e3b;font-weight:bold;font-size:370%}.colossus{color:#7f282a;font-size:310%}.hierophant{color:#b441ee;font-weight:bold;font-style:italic}.hierophant_warning{color:#c56bf1;font-style:italic}.purple{color:#9956d3}.holoparasite{color:#88809c}.revennotice{color:#c099e2}.revenboldnotice{color:#c099e2;font-weight:bold}.revenbignotice{color:#c099e2;font-weight:bold;font-size:185%}.revenminor{color:#823abb}.revenwarning{color:#760fbb;font-style:italic}.revendanger{color:#760fbb;font-weight:bold;font-size:185%}.deconversion_message{color:#a947ff;font-size:185%;font-style:italic}.ghostalert{color:#60f;font-style:italic;font-weight:bold}.alien{color:#855d85}.noticealien{color:#059223}.alertalien{color:#059223;font-weight:bold}.changeling{color:#059223;font-style:italic}.alertsyndie{color:red;font-size:185%;font-weight:bold}.spider{color:#80f;font-weight:bold;font-size:185%}.interface{color:#750e75}.sans{font-family:"Comic Sans MS",cursive,sans-serif}.papyrus{font-family:"Papyrus",cursive,sans-serif}.robot{font-family:"Courier New",cursive,sans-serif}.tape_recorder{color:red;font-family:"Courier New",cursive,sans-serif}.command_headset{font-weight:bold;font-size:160%}.small{font-size:60%}.big{font-size:185%}.reallybig{font-size:245%}.extremelybig{font-size:310%}.greentext{color:#059223;font-size:185%}.redtext{color:#c51e1e;font-size:185%}.clown{color:#ff70c1;font-size:160%;font-family:"Comic Sans MS",cursive,sans-serif;font-weight:bold}.singing{font-family:"Trebuchet MS",cursive,sans-serif;font-style:italic}.his_grace{color:#15d512;font-family:"Courier New",cursive,sans-serif;font-style:italic}.hypnophrase{color:#202020;font-weight:bold;animation:hypnocolor 1500ms infinite;animation-direction:alternate}@keyframes hypnocolor{0%{color:#202020}25%{color:#4b02ac}50%{color:#9f41f1}75%{color:#541c9c}100%{color:#7adbf3}}.phobia{color:#d00;font-weight:bold;animation:phobia 750ms infinite}@keyframes phobia{0%{color:#f75a5a}50%{color:#d00}100%{color:#f75a5a}}.icon{height:1em;width:auto}.bigicon{font-size:2.5em}.memo{color:#638500;text-align:center}.memoedit{text-align:center;font-size:125%}.abductor{color:#c204c2;font-style:italic}.mind_control{color:#df3da9;font-size:100%;font-weight:bold;font-style:italic}.slime{color:#00ced1}.drone{color:#848482}.monkey{color:#975032}.swarmer{color:#2c75ff}.resonate{color:#298f85}.monkeyhive{color:#a56408}.monkeylead{color:#af6805;font-size:80%}.connectionClosed,.fatalError{background:red;color:#fff;padding:5px}.connectionClosed.restored{background:green}.internal.boldnshit{color:#3d5bc3;font-weight:bold}.text-normal{font-weight:normal;font-style:normal}.hidden{display:none;visibility:hidden}.ml-1{margin-left:1em}.ml-2{margin-left:2em}.ml-3{margin-left:3em}.xooc{color:#ac04e9;font-weight:bold;font-size:140%}.mooc{color:#090;font-weight:bold;font-size:140%}.yooc{color:#999600;font-weight:bold;font-size:140%}.headminsay{color:#653d78;font-weight:bold}.radio{color:#b4b4b4}.deptradio{color:#939}.comradio{color:#779cc2}.centradio{color:#5c5c8a}.hcradio{color:#318779}.pvstradio{color:#9b0612}.cryoradio{color:#ad6d48}.airadio{color:#f0f}.secradio{color:#a52929}.engradio{color:#a66300}.sentryradio{color:#844300}.medradio{color:#008160}.supradio{color:#ba8e41}.jtacradio{color:#ad3b98}.intelradio{color:#027d02}.wyradio{color:#fe9b24}.pmcradio{color:#4dc5ce}.vairadio{color:#e3580e}.rmcradio{color:#e3580e}.cmbradio{color:#1b748c}.clfradio{color:#8e83ca}.alpharadio{color:#db2626}.bravoradio{color:#c68610}.charlieradio{color:#a5a}.deltaradio{color:#007fcf}.echoradio{color:#3eb489}.medium{font-size:110%}.big{font-size:115%}.large{font-size:125%}.extra_large{font-size:130%}.huge{font-size:150%}.underline{text-decoration:underline}.orange{color:#eca100}.normal{font-style:normal}.attack{color:#ff3838}.moderate{color:#c00}.disarm{color:#900}.passive{color:#600}.helpful{color:#368f31}.scanner{color:#ff3838}.scannerb{color:#ff3838;font-weight:bold}.scannerburn{color:orange}.scannerburnb{color:orange;font-weight:bold}.rose{color:#ff5050}.debuginfo{color:#493d26;font-style:italic}.xenonotice{color:#51a16c}.xenoboldnotice{color:#51a16c;font-weight:bold}.xenowarning{color:#51a16c;font-style:italic}.xenominorwarning{color:#51a16c;font-weight:bold;font-style:italic}.xenodanger{color:#51a16c;font-weight:bold}.avoidharm{color:#72a0e5;font-weight:bold}.highdanger{color:#ff3838;font-weight:bold;font-size:140%}.xenohighdanger{color:#51a16c;font-weight:bold;font-size:140%}.xenoannounce{color:#65c585;font-family:book-antiqua;font-weight:bold;font-size:140%}.yautjabold{color:purple;font-weight:bold}.yautjaboldbig{color:purple;font-weight:bold;font-size:120%}.objectivebig{font-weight:bold;font-size:130%}.objectivegreen{color:lime}.objectivered{color:red}.objectivesuccess{color:lime;font-weight:bold;font-size:110%}.objectivefail{color:red;font-weight:bold;font-size:110%}.xenotalk,.xeno{color:#c048c0;font-style:italic}.xenoleader{color:#996e99;font-style:italic;font-size:125%}.xenoqueen{color:#996e99;font-style:italic;font-weight:bold;font-size:125%}.newscaster{color:maroon}.role_header{color:#e92d2d;display:block;text-align:center;font-weight:bold;font-family:trebuchet-ms;font-size:150%}.role_body{color:#3a3ae9;display:block;text-align:center;font-size:125%}.round_header{color:#e92d2d;display:block;text-align:center;font-family:courier;font-weight:bold;font-size:180%}.round_body{color:#c5c5c5;display:block;text-align:center;font-family:trebuchet-ms;font-weight:bold;font-size:125%}.event_announcement{color:#600d48;font-family:arial-narrow;font-weight:bold;font-size:125%}.announce_header{color:#cecece;font-weight:bold;font-size:150%}.announce_header_blue{color:#7575f3;font-weight:bold;font-size:150%}.announce_header_admin{color:#7575f3;font-weight:bold;font-size:150%}.announce_body{color:#e92d2d;font-weight:normal;font-size:125%}.centerbold{display:block;text-align:center;font-weight:bold}.mod{color:#917455;font-weight:bold}.modooc{color:#184880;font-weight:bold}.adminmod{color:#7c440c;font-weight:bold}.mentorsay{color:#d4af57;font-weight:bold}.mentorhelp{color:#090;font-weight:bold}.mentorbody{color:#da6200;font-weight:bold}.mentorstaff{color:#b5850d;font-weight:bold}.staffsay{color:#b5850d;font-weight:bold}.tajaran{color:#803b56}.tajaran_signlang{color:#941c1c}.skrell{color:#00ced1}.soghun{color:#228b22}.changeling{color:purple}.vox{color:#a0a}.monkey{color:#966c47}.german{color:#858f1e;font-family:"Times New Roman",Times,serif}.spanish{color:#cf982b}.japanese{color:#940927}.chinese{color:#fe1919}.zombie{color:#2dacb1;font-style:italic}.rough{font-family:trebuchet-ms,cursive,sans-serif}.commando{color:#fe9b24;font-style:bold}.say_quote{font-family:Georgia,Verdana,sans-serif}.admin .message{color:#314cad}.admin .prefix{font-weight:bolder}.pm{font-size:110%}.deadsay{color:#8b4dff}.retro_translator{font-weight:bold}.yautja_translator{color:#a00;font-weight:bold;animation:glitch .5s infinite}@keyframes glitch{25%{color:#a00;transform:translate(-2px, -1px)}50%{color:#be0000;transform:translate(1px, -2px)}75%{color:#8d0000;transform:translate(-1px, 2px)}100%{color:#830000;transform:translate(1px, 1px)}}.examine_block{background:#1b1c1e;border:1px solid #a4bad6;margin:.5em;padding:.5em .75em}.examine_block .icon{width:1.5em;height:1.5em;margin:0;padding:0}.tooltip{font-style:italic;border-bottom:1px dashed #fff} +.theme-light .color-black{color:#000 !important}.theme-light .color-white{color:#e6e6e6 !important}.theme-light .color-red{color:#c82121 !important}.theme-light .color-orange{color:#e6630d !important}.theme-light .color-yellow{color:#e5c304 !important}.theme-light .color-olive{color:#a3b816 !important}.theme-light .color-green{color:#1d9f3b !important}.theme-light .color-teal{color:#00a39c !important}.theme-light .color-blue{color:#1e78bb !important}.theme-light .color-dark-blue{color:#004274 !important}.theme-light .color-violet{color:#5a30b5 !important}.theme-light .color-purple{color:#932eb4 !important}.theme-light .color-pink{color:#db228a !important}.theme-light .color-brown{color:#955d39 !important}.theme-light .color-grey{color:#e6e6e6 !important}.theme-light .color-light-grey{color:#999 !important}.theme-light .color-good{color:#529923 !important}.theme-light .color-average{color:#da810e !important}.theme-light .color-bad{color:#c82121 !important}.theme-light .color-label{color:#353535 !important}.theme-light .color-xeno{color:#4a3253 !important}.theme-light .color-bg-black{background-color:#000 !important}.theme-light .color-bg-white{background-color:#bfbfbf !important}.theme-light .color-bg-red{background-color:#a61c1c !important}.theme-light .color-bg-orange{background-color:#c0530b !important}.theme-light .color-bg-yellow{background-color:#bfa303 !important}.theme-light .color-bg-olive{background-color:#889912 !important}.theme-light .color-bg-green{background-color:#188532 !important}.theme-light .color-bg-teal{background-color:#008882 !important}.theme-light .color-bg-blue{background-color:#19649c !important}.theme-light .color-bg-dark-blue{background-color:#003761 !important}.theme-light .color-bg-violet{background-color:#4b2897 !important}.theme-light .color-bg-purple{background-color:#7a2696 !important}.theme-light .color-bg-pink{background-color:#b61d73 !important}.theme-light .color-bg-brown{background-color:#7c4d2f !important}.theme-light .color-bg-grey{background-color:#bfbfbf !important}.theme-light .color-bg-light-grey{background-color:gray !important}.theme-light .color-bg-good{background-color:#44801d !important}.theme-light .color-bg-average{background-color:#b56b0b !important}.theme-light .color-bg-bad{background-color:#a61c1c !important}.theme-light .color-bg-label{background-color:#2c2c2c !important}.theme-light .color-bg-xeno{background-color:#3e2945 !important}.theme-light .Tabs{display:flex;align-items:stretch;overflow:hidden;background-color:#fff}.theme-light .Tabs--fill{height:100%}.theme-light .Section .Tabs{background-color:transparent}.theme-light .Section:not(.Section--fitted) .Tabs{margin:0 -0.5em .5em}.theme-light .Section:not(.Section--fitted) .Tabs:first-child{margin-top:-0.5em}.theme-light .Tabs--vertical{flex-direction:column;padding:.25em 0 .25em .25em}.theme-light .Tabs--horizontal{margin-bottom:.5em;padding:.25em .25em 0 .25em}.theme-light .Tabs--horizontal:last-child{margin-bottom:0}.theme-light .Tabs__Tab{flex-grow:0}.theme-light .Tabs--fluid .Tabs__Tab{flex-grow:1}.theme-light .Tab{display:flex;align-items:center;justify-content:space-between;background-color:transparent;color:rgba(0,0,0,.5);min-height:2.25em;min-width:4em}.theme-light .Tab:not(.Tab--selected):hover{background-color:rgba(255,255,255,.075)}.theme-light .Tab--selected{background-color:rgba(255,255,255,.125);color:#404040}.theme-light .Tab__text{flex-grow:1;margin:0 .5em}.theme-light .Tab__left{min-width:1.5em;text-align:center;margin-left:.25em}.theme-light .Tab__right{min-width:1.5em;text-align:center;margin-right:.25em}.theme-light .Tabs--horizontal .Tab{border-top:.1666666667em solid transparent;border-bottom:.1666666667em solid transparent;border-top-left-radius:.25em;border-top-right-radius:.25em}.theme-light .Tabs--horizontal .Tab--selected{border-bottom:.1666666667em solid #000}.theme-light .Tabs--vertical .Tab{min-height:2em;border-left:.1666666667em solid transparent;border-right:.1666666667em solid transparent;border-top-left-radius:.25em;border-bottom-left-radius:.25em}.theme-light .Tabs--vertical .Tab--selected{border-right:.1666666667em solid #000}.theme-light .Tab--selected.Tab--color--black{color:#404040}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--black{border-bottom-color:#000}.theme-light .Tabs--vertical .Tab--selected.Tab--color--black{border-right-color:#000}.theme-light .Tab--selected.Tab--color--white{color:#ececec}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--white{border-bottom-color:#e6e6e6}.theme-light .Tabs--vertical .Tab--selected.Tab--color--white{border-right-color:#e6e6e6}.theme-light .Tab--selected.Tab--color--red{color:#e14d4d}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--red{border-bottom-color:#c82121}.theme-light .Tabs--vertical .Tab--selected.Tab--color--red{border-right-color:#c82121}.theme-light .Tab--selected.Tab--color--orange{color:#f48942}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--orange{border-bottom-color:#e6630d}.theme-light .Tabs--vertical .Tab--selected.Tab--color--orange{border-right-color:#e6630d}.theme-light .Tab--selected.Tab--color--yellow{color:#fcdd33}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--yellow{border-bottom-color:#e5c304}.theme-light .Tabs--vertical .Tab--selected.Tab--color--yellow{border-right-color:#e5c304}.theme-light .Tab--selected.Tab--color--olive{color:#d0e732}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--olive{border-bottom-color:#a3b816}.theme-light .Tabs--vertical .Tab--selected.Tab--color--olive{border-right-color:#a3b816}.theme-light .Tab--selected.Tab--color--green{color:#33da5a}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--green{border-bottom-color:#1d9f3b}.theme-light .Tabs--vertical .Tab--selected.Tab--color--green{border-right-color:#1d9f3b}.theme-light .Tab--selected.Tab--color--teal{color:#00faef}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--teal{border-bottom-color:#00a39c}.theme-light .Tabs--vertical .Tab--selected.Tab--color--teal{border-right-color:#00a39c}.theme-light .Tab--selected.Tab--color--blue{color:#419ce1}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--blue{border-bottom-color:#1e78bb}.theme-light .Tabs--vertical .Tab--selected.Tab--color--blue{border-right-color:#1e78bb}.theme-light .Tab--selected.Tab--color--dark-blue{color:#0079d7}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--dark-blue{border-bottom-color:#004274}.theme-light .Tabs--vertical .Tab--selected.Tab--color--dark-blue{border-right-color:#004274}.theme-light .Tab--selected.Tab--color--violet{color:#7f58d3}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--violet{border-bottom-color:#5a30b5}.theme-light .Tabs--vertical .Tab--selected.Tab--color--violet{border-right-color:#5a30b5}.theme-light .Tab--selected.Tab--color--purple{color:#b455d4}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--purple{border-bottom-color:#932eb4}.theme-light .Tabs--vertical .Tab--selected.Tab--color--purple{border-right-color:#932eb4}.theme-light .Tab--selected.Tab--color--pink{color:#e558a7}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--pink{border-bottom-color:#db228a}.theme-light .Tabs--vertical .Tab--selected.Tab--color--pink{border-right-color:#db228a}.theme-light .Tab--selected.Tab--color--brown{color:#c0825a}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--brown{border-bottom-color:#955d39}.theme-light .Tabs--vertical .Tab--selected.Tab--color--brown{border-right-color:#955d39}.theme-light .Tab--selected.Tab--color--grey{color:#ececec}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--grey{border-bottom-color:#e6e6e6}.theme-light .Tabs--vertical .Tab--selected.Tab--color--grey{border-right-color:#e6e6e6}.theme-light .Tab--selected.Tab--color--light-grey{color:#b3b3b3}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--light-grey{border-bottom-color:#999}.theme-light .Tabs--vertical .Tab--selected.Tab--color--light-grey{border-right-color:#999}.theme-light .Tab--selected.Tab--color--good{color:#77d23b}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--good{border-bottom-color:#529923}.theme-light .Tabs--vertical .Tab--selected.Tab--color--good{border-right-color:#529923}.theme-light .Tab--selected.Tab--color--average{color:#f3a23a}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--average{border-bottom-color:#da810e}.theme-light .Tabs--vertical .Tab--selected.Tab--color--average{border-right-color:#da810e}.theme-light .Tab--selected.Tab--color--bad{color:#e14d4d}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--bad{border-bottom-color:#c82121}.theme-light .Tabs--vertical .Tab--selected.Tab--color--bad{border-right-color:#c82121}.theme-light .Tab--selected.Tab--color--label{color:#686868}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--label{border-bottom-color:#353535}.theme-light .Tabs--vertical .Tab--selected.Tab--color--label{border-right-color:#353535}.theme-light .Tab--selected.Tab--color--xeno{color:#7e558e}.theme-light .Tabs--horizontal .Tab--selected.Tab--color--xeno{border-bottom-color:#4a3253}.theme-light .Tabs--vertical .Tab--selected.Tab--color--xeno{border-right-color:#4a3253}.theme-light .Section{position:relative;margin-bottom:.5em;background-color:#fff;background-color:#fff;box-sizing:border-box}.theme-light .Section:last-child{margin-bottom:0}.theme-light .Section__title{position:relative;padding:.5em;border-bottom:.1666666667em solid #fff}.theme-light .Section__titleText{font-size:1.1666666667em;font-weight:bold;color:#000}.theme-light .Section__buttons{position:absolute;display:inline-block;right:.5em;margin-top:-.0833333333em}.theme-light .Section__rest{position:relative}.theme-light .Section__content{padding:.66em .5em}.theme-light .Section--fitted>.Section__rest>.Section__content{padding:0}.theme-light .Section--fill{display:flex;flex-direction:column;height:100%}.theme-light .Section--fill>.Section__rest{flex-grow:1}.theme-light .Section--fill>.Section__rest>.Section__content{height:100%}.theme-light .Section--fill.Section--scrollable>.Section__rest>.Section__content{position:absolute;top:0;left:0;right:0;bottom:0}.theme-light .Section--fill.Section--iefix{display:table !important;width:100% !important;height:100% !important;border-collapse:collapse;border-spacing:0}.theme-light .Section--fill.Section--iefix>.Section__rest{display:table-row !important;height:100% !important}.theme-light .Section--scrollable{overflow-x:hidden;overflow-y:hidden}.theme-light .Section--scrollable>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:hidden}.theme-light .Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.theme-light .Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:hidden;overflow-x:scroll}.theme-light .Section--scrollable.Section--scrollableHorizontal{overflow-x:hidden;overflow-y:hidden}.theme-light .Section--scrollable.Section--scrollableHorizontal>.Section__rest>.Section__content{overflow-y:scroll;overflow-x:scroll}.theme-light .Section .Section{background-color:transparent;margin-left:-0.5em;margin-right:-0.5em}.theme-light .Section .Section:first-child{margin-top:-0.5em}.theme-light .Section .Section .Section__titleText{font-size:1.0833333333em}.theme-light .Section .Section .Section .Section__titleText{font-size:1em}.theme-light .Button{position:relative;display:inline-block;line-height:1.667em;padding:0 .5em;margin-right:.1666666667em;white-space:nowrap;outline:0;border-radius:.16em;margin-bottom:.1666666667em;user-select:none;-ms-user-select:none}.theme-light .Button:last-child{margin-right:0;margin-bottom:0}.theme-light .Button .fa,.theme-light .Button .fas,.theme-light .Button .far{margin-left:-0.25em;margin-right:-0.25em;min-width:1.333em;text-align:center}.theme-light .Button--hasContent .fa,.theme-light .Button--hasContent .fas,.theme-light .Button--hasContent .far{margin-right:.25em}.theme-light .Button--hasContent.Button--iconPosition--right .fa,.theme-light .Button--hasContent.Button--iconPosition--right .fas,.theme-light .Button--hasContent.Button--iconPosition--right .far{margin-right:0px;margin-left:3px}.theme-light .Button--ellipsis{overflow:hidden;text-overflow:ellipsis}.theme-light .Button--fluid{display:block;margin-left:0;margin-right:0}.theme-light .Button--circular{border-radius:50%}.theme-light .Button--compact{padding:0 .25em;line-height:1.333em}.theme-light .Button--color--black{transition:color 50ms,background-color 50ms;background-color:#000;color:#fff}.theme-light .Button--color--black:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--black:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--black:hover,.theme-light .Button--color--black:focus{background-color:#131313;color:#fff}.theme-light .Button--color--white{transition:color 50ms,background-color 50ms;background-color:#bfbfbf;color:#000}.theme-light .Button--color--white:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--white:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--white:hover,.theme-light .Button--color--white:focus{background-color:#efefef;color:#000}.theme-light .Button--color--red{transition:color 50ms,background-color 50ms;background-color:#a61c1c;color:#fff}.theme-light .Button--color--red:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--red:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--red:hover,.theme-light .Button--color--red:focus{background-color:#d23333;color:#fff}.theme-light .Button--color--orange{transition:color 50ms,background-color 50ms;background-color:#c0530b;color:#fff}.theme-light .Button--color--orange:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--orange:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--orange:hover,.theme-light .Button--color--orange:focus{background-color:#ea7426;color:#fff}.theme-light .Button--color--yellow{transition:color 50ms,background-color 50ms;background-color:#bfa303;color:#fff}.theme-light .Button--color--yellow:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--yellow:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--yellow:hover,.theme-light .Button--color--yellow:focus{background-color:#efce17;color:#fff}.theme-light .Button--color--olive{transition:color 50ms,background-color 50ms;background-color:#889912;color:#fff}.theme-light .Button--color--olive:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--olive:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--olive:hover,.theme-light .Button--color--olive:focus{background-color:#afc328;color:#fff}.theme-light .Button--color--green{transition:color 50ms,background-color 50ms;background-color:#188532;color:#fff}.theme-light .Button--color--green:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--green:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--green:hover,.theme-light .Button--color--green:focus{background-color:#2fac4c;color:#fff}.theme-light .Button--color--teal{transition:color 50ms,background-color 50ms;background-color:#008882;color:#fff}.theme-light .Button--color--teal:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--teal:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--teal:hover,.theme-light .Button--color--teal:focus{background-color:#13afa9;color:#fff}.theme-light .Button--color--blue{transition:color 50ms,background-color 50ms;background-color:#19649c;color:#fff}.theme-light .Button--color--blue:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--blue:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--blue:hover,.theme-light .Button--color--blue:focus{background-color:#3086c7;color:#fff}.theme-light .Button--color--dark-blue{transition:color 50ms,background-color 50ms;background-color:#003761;color:#fff}.theme-light .Button--color--dark-blue:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--dark-blue:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--dark-blue:hover,.theme-light .Button--color--dark-blue:focus{background-color:#135283;color:#fff}.theme-light .Button--color--violet{transition:color 50ms,background-color 50ms;background-color:#4b2897;color:#fff}.theme-light .Button--color--violet:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--violet:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--violet:hover,.theme-light .Button--color--violet:focus{background-color:#6a41c1;color:#fff}.theme-light .Button--color--purple{transition:color 50ms,background-color 50ms;background-color:#7a2696;color:#fff}.theme-light .Button--color--purple:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--purple:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--purple:hover,.theme-light .Button--color--purple:focus{background-color:#a03fc0;color:#fff}.theme-light .Button--color--pink{transition:color 50ms,background-color 50ms;background-color:#b61d73;color:#fff}.theme-light .Button--color--pink:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--pink:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--pink:hover,.theme-light .Button--color--pink:focus{background-color:#da3f96;color:#fff}.theme-light .Button--color--brown{transition:color 50ms,background-color 50ms;background-color:#7c4d2f;color:#fff}.theme-light .Button--color--brown:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--brown:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--brown:hover,.theme-light .Button--color--brown:focus{background-color:#a26c49;color:#fff}.theme-light .Button--color--grey{transition:color 50ms,background-color 50ms;background-color:#bfbfbf;color:#000}.theme-light .Button--color--grey:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--grey:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--grey:hover,.theme-light .Button--color--grey:focus{background-color:#efefef;color:#000}.theme-light .Button--color--light-grey{transition:color 50ms,background-color 50ms;background-color:gray;color:#fff}.theme-light .Button--color--light-grey:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--light-grey:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--light-grey:hover,.theme-light .Button--color--light-grey:focus{background-color:#a6a6a6;color:#fff}.theme-light .Button--color--good{transition:color 50ms,background-color 50ms;background-color:#44801d;color:#fff}.theme-light .Button--color--good:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--good:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--good:hover,.theme-light .Button--color--good:focus{background-color:#62a635;color:#fff}.theme-light .Button--color--average{transition:color 50ms,background-color 50ms;background-color:#b56b0b;color:#fff}.theme-light .Button--color--average:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--average:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--average:hover,.theme-light .Button--color--average:focus{background-color:#e48f20;color:#fff}.theme-light .Button--color--bad{transition:color 50ms,background-color 50ms;background-color:#a61c1c;color:#fff}.theme-light .Button--color--bad:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--bad:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--bad:hover,.theme-light .Button--color--bad:focus{background-color:#d23333;color:#fff}.theme-light .Button--color--label{transition:color 50ms,background-color 50ms;background-color:#2c2c2c;color:#fff}.theme-light .Button--color--label:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--label:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--label:hover,.theme-light .Button--color--label:focus{background-color:#464646;color:#fff}.theme-light .Button--color--xeno{transition:color 50ms,background-color 50ms;background-color:#3e2945;color:#fff}.theme-light .Button--color--xeno:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--xeno:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--xeno:hover,.theme-light .Button--color--xeno:focus{background-color:#5a4363;color:#fff}.theme-light .Button--color--default{transition:color 50ms,background-color 50ms;background-color:#bbb;color:#000}.theme-light .Button--color--default:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--default:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--default:hover,.theme-light .Button--color--default:focus{background-color:#eaeaea;color:#000}.theme-light .Button--color--caution{transition:color 50ms,background-color 50ms;background-color:#be6209;color:#fff}.theme-light .Button--color--caution:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--caution:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--caution:hover,.theme-light .Button--color--caution:focus{background-color:#ec8420;color:#fff}.theme-light .Button--color--danger{transition:color 50ms,background-color 50ms;background-color:#9a9d00;color:#fff}.theme-light .Button--color--danger:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--danger:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--danger:hover,.theme-light .Button--color--danger:focus{background-color:#c4c813;color:#fff}.theme-light .Button--color--transparent{transition:color 50ms,background-color 50ms;background-color:#eee;color:#000;background-color:rgba(238,238,238,0);color:rgba(0,0,0,.5)}.theme-light .Button--color--transparent:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--color--transparent:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--color--transparent:hover,.theme-light .Button--color--transparent:focus{background-color:#fcfcfc;color:#000}.theme-light .Button--disabled{background-color:#363636 !important}.theme-light .Button--selected{transition:color 50ms,background-color 50ms;background-color:#0668b8;color:#fff}.theme-light .Button--selected:hover{transition:color 0ms,background-color 0ms}.theme-light .Button--selected:focus{transition:color 100ms,background-color 100ms}.theme-light .Button--selected:hover,.theme-light .Button--selected:focus{background-color:#1a8be7;color:#fff}.theme-light .Button--flex{display:inline-flex;flex-direction:column}.theme-light .Button--flex--fluid{width:100%}.theme-light .Button--verticalAlignContent--top{justify-content:flex-start}.theme-light .Button--verticalAlignContent--middle{justify-content:center}.theme-light .Button--verticalAlignContent--bottom{justify-content:flex-end}.theme-light .Button__content{display:block;align-self:stretch}.theme-light .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#000;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.theme-light .Input--fluid{display:block;width:auto}.theme-light .Input__baseline{display:inline-block;color:transparent}.theme-light .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#000;color:inherit}.theme-light .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .Input--monospace .Input__input{font-family:"Consolas",monospace}.theme-light .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#000;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.theme-light .Input--fluid{display:block;width:auto}.theme-light .Input__baseline{display:inline-block;color:transparent}.theme-light .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#000;color:inherit}.theme-light .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .Input--monospace .Input__input{font-family:"Consolas",monospace}.theme-light .NumberInput{position:relative;display:inline-block;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#353535;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;text-align:right;overflow:visible;cursor:n-resize}.theme-light .NumberInput--fluid{display:block}.theme-light .NumberInput__content{margin-left:.5em}.theme-light .NumberInput__barContainer{position:absolute;top:.1666666667em;bottom:.1666666667em;left:.1666666667em}.theme-light .NumberInput__bar{position:absolute;bottom:0;left:0;width:.25em;box-sizing:border-box;border-bottom:.0833333333em solid #353535;background-color:#353535}.theme-light .NumberInput__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:#fff;color:#000;text-align:right}.theme-light .Input{position:relative;display:inline-block;width:10em;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;color:#000;background-color:#fff;padding:0 .3333333333em;margin-right:.1666666667em;line-height:1.4166666667em;overflow:visible}.theme-light .Input--fluid{display:block;width:auto}.theme-light .Input__baseline{display:inline-block;color:transparent}.theme-light .Input__input{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;font-size:1em;line-height:1.4166666667em;height:1.4166666667em;margin:0;padding:0 .5em;font-family:Verdana,sans-serif;background-color:transparent;color:#000;color:inherit}.theme-light .Input__input:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .Input--monospace .Input__input{font-family:"Consolas",monospace}.theme-light .TextArea{position:relative;display:inline-block;border:.0833333333em solid #353535;border:.0833333333em solid rgba(53,53,53,.75);border-radius:.16em;background-color:#fff;margin-right:.1666666667em;line-height:1.4166666667em;box-sizing:border-box;width:100%}.theme-light .TextArea--fluid{display:block;width:auto;height:auto}.theme-light .TextArea--noborder{border:0px}.theme-light .TextArea__textarea.TextArea__textarea--scrollable{overflow:auto;overflow-x:hidden;overflow-y:scroll}.theme-light .TextArea__textarea{display:block;position:absolute;top:0;bottom:0;left:0;right:0;border:0;outline:0;width:100%;height:100%;font-size:1em;line-height:1.4166666667em;min-height:1.4166666667em;margin:0;padding:0 .5em;font-family:inherit;background-color:transparent;color:inherit;box-sizing:border-box;word-wrap:break-word;overflow:hidden}.theme-light .TextArea__textarea:-ms-input-placeholder{font-style:italic;color:#777;color:rgba(255,255,255,.45)}.theme-light .TextArea__textarea_custom{overflow:visible;white-space:pre-wrap}.theme-light .Knob{position:relative;font-size:1rem;width:2.6em;height:2.6em;margin:0 auto;margin-bottom:-0.2em;cursor:n-resize}.theme-light .Knob:after{content:".";color:transparent;line-height:2.5em}.theme-light .Knob__circle{position:absolute;top:.1em;bottom:.1em;left:.1em;right:.1em;margin:.3em;background-color:#333;background-image:linear-gradient(to bottom, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 100%);border-radius:50%;box-shadow:0 .05em .5em 0 rgba(0,0,0,.5)}.theme-light .Knob__cursorBox{position:absolute;top:0;bottom:0;left:0;right:0}.theme-light .Knob__cursor{position:relative;top:.05em;margin:0 auto;width:.2em;height:.8em;background-color:rgba(255,255,255,.9)}.theme-light .Knob__popupValue{position:absolute;top:-2rem;right:50%;font-size:1rem;text-align:center;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.theme-light .Knob__ring{position:absolute;top:0;bottom:0;left:0;right:0;padding:.1em}.theme-light .Knob__ringTrackPivot{transform:rotateZ(135deg)}.theme-light .Knob__ringTrack{fill:transparent;stroke:rgba(255,255,255,.1);stroke-width:8;stroke-linecap:round;stroke-dasharray:235.62}.theme-light .Knob__ringFillPivot{transform:rotateZ(135deg)}.theme-light .Knob--bipolar .Knob__ringFillPivot{transform:rotateZ(270deg)}.theme-light .Knob__ringFill{fill:transparent;stroke:#6a96c9;stroke-width:8;stroke-linecap:round;stroke-dasharray:314.16;transition:stroke 50ms ease-out}.theme-light .Knob--color--black .Knob__ringFill{stroke:#000}.theme-light .Knob--color--white .Knob__ringFill{stroke:#e6e6e6}.theme-light .Knob--color--red .Knob__ringFill{stroke:#c82121}.theme-light .Knob--color--orange .Knob__ringFill{stroke:#e6630d}.theme-light .Knob--color--yellow .Knob__ringFill{stroke:#e5c304}.theme-light .Knob--color--olive .Knob__ringFill{stroke:#a3b816}.theme-light .Knob--color--green .Knob__ringFill{stroke:#1d9f3b}.theme-light .Knob--color--teal .Knob__ringFill{stroke:#00a39c}.theme-light .Knob--color--blue .Knob__ringFill{stroke:#1e78bb}.theme-light .Knob--color--dark-blue .Knob__ringFill{stroke:#004274}.theme-light .Knob--color--violet .Knob__ringFill{stroke:#5a30b5}.theme-light .Knob--color--purple .Knob__ringFill{stroke:#932eb4}.theme-light .Knob--color--pink .Knob__ringFill{stroke:#db228a}.theme-light .Knob--color--brown .Knob__ringFill{stroke:#955d39}.theme-light .Knob--color--grey .Knob__ringFill{stroke:#e6e6e6}.theme-light .Knob--color--light-grey .Knob__ringFill{stroke:#999}.theme-light .Knob--color--good .Knob__ringFill{stroke:#529923}.theme-light .Knob--color--average .Knob__ringFill{stroke:#da810e}.theme-light .Knob--color--bad .Knob__ringFill{stroke:#c82121}.theme-light .Knob--color--label .Knob__ringFill{stroke:#353535}.theme-light .Knob--color--xeno .Knob__ringFill{stroke:#4a3253}.theme-light .Slider{cursor:e-resize}.theme-light .Slider__cursorOffset{position:absolute;top:0;left:0;bottom:0;transition:none !important}.theme-light .Slider__cursor{position:absolute;top:0;right:-.0833333333em;bottom:0;width:0;border-left:.1666666667em solid #000}.theme-light .Slider__pointer{position:absolute;right:-.4166666667em;bottom:-.3333333333em;width:0;height:0;border-left:.4166666667em solid transparent;border-right:.4166666667em solid transparent;border-bottom:.4166666667em solid #000}.theme-light .Slider__popupValue{position:absolute;right:0;top:-2rem;font-size:1rem;padding:.25rem .5rem;color:#fff;background-color:#000;transform:translateX(50%);white-space:nowrap}.theme-light .ProgressBar{display:inline-block;position:relative;width:100%;padding:0 .5em;border-width:.0833333333em !important;border-style:solid !important;border-radius:.16em;background-color:rgba(0,0,0,0);transition:border-color 900ms ease-out}.theme-light .ProgressBar__fill{position:absolute;top:-0.5px;left:0px;bottom:-0.5px}.theme-light .ProgressBar__fill--animated{transition:background-color 900ms ease-out,width 900ms ease-out}.theme-light .ProgressBar__content{position:relative;line-height:1.4166666667em;width:100%;text-align:right}.theme-light .ProgressBar--color--default{border:.0833333333em solid #bfbfbf}.theme-light .ProgressBar--color--default .ProgressBar__fill{background-color:#bfbfbf}.theme-light .ProgressBar--color--black{border-color:#000 !important}.theme-light .ProgressBar--color--black .ProgressBar__fill{background-color:#000}.theme-light .ProgressBar--color--white{border-color:#bfbfbf !important}.theme-light .ProgressBar--color--white .ProgressBar__fill{background-color:#bfbfbf}.theme-light .ProgressBar--color--red{border-color:#a61c1c !important}.theme-light .ProgressBar--color--red .ProgressBar__fill{background-color:#a61c1c}.theme-light .ProgressBar--color--orange{border-color:#c0530b !important}.theme-light .ProgressBar--color--orange .ProgressBar__fill{background-color:#c0530b}.theme-light .ProgressBar--color--yellow{border-color:#bfa303 !important}.theme-light .ProgressBar--color--yellow .ProgressBar__fill{background-color:#bfa303}.theme-light .ProgressBar--color--olive{border-color:#889912 !important}.theme-light .ProgressBar--color--olive .ProgressBar__fill{background-color:#889912}.theme-light .ProgressBar--color--green{border-color:#188532 !important}.theme-light .ProgressBar--color--green .ProgressBar__fill{background-color:#188532}.theme-light .ProgressBar--color--teal{border-color:#008882 !important}.theme-light .ProgressBar--color--teal .ProgressBar__fill{background-color:#008882}.theme-light .ProgressBar--color--blue{border-color:#19649c !important}.theme-light .ProgressBar--color--blue .ProgressBar__fill{background-color:#19649c}.theme-light .ProgressBar--color--dark-blue{border-color:#003761 !important}.theme-light .ProgressBar--color--dark-blue .ProgressBar__fill{background-color:#003761}.theme-light .ProgressBar--color--violet{border-color:#4b2897 !important}.theme-light .ProgressBar--color--violet .ProgressBar__fill{background-color:#4b2897}.theme-light .ProgressBar--color--purple{border-color:#7a2696 !important}.theme-light .ProgressBar--color--purple .ProgressBar__fill{background-color:#7a2696}.theme-light .ProgressBar--color--pink{border-color:#b61d73 !important}.theme-light .ProgressBar--color--pink .ProgressBar__fill{background-color:#b61d73}.theme-light .ProgressBar--color--brown{border-color:#7c4d2f !important}.theme-light .ProgressBar--color--brown .ProgressBar__fill{background-color:#7c4d2f}.theme-light .ProgressBar--color--grey{border-color:#bfbfbf !important}.theme-light .ProgressBar--color--grey .ProgressBar__fill{background-color:#bfbfbf}.theme-light .ProgressBar--color--light-grey{border-color:gray !important}.theme-light .ProgressBar--color--light-grey .ProgressBar__fill{background-color:gray}.theme-light .ProgressBar--color--good{border-color:#44801d !important}.theme-light .ProgressBar--color--good .ProgressBar__fill{background-color:#44801d}.theme-light .ProgressBar--color--average{border-color:#b56b0b !important}.theme-light .ProgressBar--color--average .ProgressBar__fill{background-color:#b56b0b}.theme-light .ProgressBar--color--bad{border-color:#a61c1c !important}.theme-light .ProgressBar--color--bad .ProgressBar__fill{background-color:#a61c1c}.theme-light .ProgressBar--color--label{border-color:#2c2c2c !important}.theme-light .ProgressBar--color--label .ProgressBar__fill{background-color:#2c2c2c}.theme-light .ProgressBar--color--xeno{border-color:#3e2945 !important}.theme-light .ProgressBar--color--xeno .ProgressBar__fill{background-color:#3e2945}.theme-light .Chat{color:#000}.theme-light .Chat__badge{display:inline-block;min-width:.5em;font-size:.7em;padding:.2em .3em;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:crimson;border-radius:10px;transition:font-size 200ms ease-out}.theme-light .Chat__badge:before{content:"x"}.theme-light .Chat__badge--animate{font-size:.9em;transition:font-size 0ms}.theme-light .Chat__scrollButton{position:fixed;right:2em;bottom:1em}.theme-light .Chat__reconnected{font-size:.85em;text-align:center;margin:1em 0 2em}.theme-light .Chat__reconnected:before{content:"Reconnected";display:inline-block;border-radius:1em;padding:0 .7em;color:#db2828;background-color:#fff}.theme-light .Chat__reconnected:after{content:"";display:block;margin-top:-0.75em;border-bottom:.1666666667em solid #db2828}.theme-light .Chat__highlight{color:#000}.theme-light .Chat__highlight--restricted{color:#fff;background-color:#a00;font-weight:bold}.theme-light .ChatMessage{word-wrap:break-word}.theme-light .ChatMessage--highlighted{position:relative;border-left:.1666666667em solid #fd4;padding-left:.5em}.theme-light .ChatMessage--highlighted:after{content:"";position:absolute;top:0;bottom:0;left:0;right:0;background-color:rgba(255,221,68,.1);pointer-events:none}.theme-light .Layout,.theme-light .Layout *{scrollbar-base-color:#f2f2f2;scrollbar-face-color:#d6d6d6;scrollbar-3dlight-color:#eee;scrollbar-highlight-color:#eee;scrollbar-track-color:#f2f2f2;scrollbar-arrow-color:#777;scrollbar-shadow-color:#d6d6d6}.theme-light .Layout__content{position:absolute;top:0;bottom:0;left:0;right:0;overflow-x:hidden;overflow-y:hidden}.theme-light .Layout__content--scrollable{overflow-y:scroll;margin-bottom:0}.theme-light .Window{position:fixed;top:0;bottom:0;left:0;right:0;color:#000;background-color:#eee;background-image:linear-gradient(to bottom, #eeeeee 0%, #eeeeee 100%)}.theme-light .Window__titleBar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;height:2.6666666667rem}.theme-light .Window__rest{position:fixed;top:32px;top:2.6666666667rem;bottom:0;left:0;right:0}.theme-light .Window__contentPadding{margin:.5rem;height:100%;height:calc(100% - 1.01rem)}.theme-light .Window__contentPadding:after{height:0}.theme-light .Layout__content--scrollable .Window__contentPadding:after{display:block;content:"";height:.5rem}.theme-light .Window__dimmer{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(252,252,252,.25);pointer-events:none}.theme-light .Window__resizeHandle__se{position:fixed;bottom:0;right:0;width:20px;width:1.6666666667rem;height:20px;height:1.6666666667rem;cursor:se-resize}.theme-light .Window__resizeHandle__s{position:fixed;bottom:0;left:0;right:0;height:6px;height:.5rem;cursor:s-resize}.theme-light .Window__resizeHandle__e{position:fixed;top:0;bottom:0;right:0;width:3px;width:.25rem;cursor:e-resize}.theme-light .TitleBar{background-color:#eee;border-bottom:1px solid rgba(0,0,0,.25);box-shadow:0 2px 2px rgba(0,0,0,.1);box-shadow:0 .1666666667rem .1666666667rem rgba(0,0,0,.1);user-select:none;-ms-user-select:none}.theme-light .TitleBar__clickable{color:rgba(0,0,0,.5);background-color:#eee;transition:color 250ms ease-out,background-color 250ms ease-out}.theme-light .TitleBar__clickable:hover{color:#fff;background-color:#c00;transition:color 0ms,background-color 0ms}.theme-light .TitleBar__title{position:absolute;display:inline-block;top:0;left:46px;left:3.8333333333rem;color:rgba(0,0,0,.75);font-size:14px;font-size:1.1666666667rem;line-height:31px;line-height:2.5833333333rem;white-space:nowrap;pointer-events:none}.theme-light .TitleBar__buttons{pointer-events:initial;display:inline-block;width:100%;margin-left:10px}.theme-light .TitleBar__dragZone{position:absolute;top:0;left:0;right:0;height:32px;height:2.6666666667rem}.theme-light .TitleBar__statusIcon{position:absolute;top:0;left:12px;left:1rem;transition:color .5s;font-size:20px;font-size:1.6666666667rem;line-height:32px !important;line-height:2.6666666667rem !important}.theme-light .TitleBar__close{position:absolute;top:-1px;right:0;width:45px;width:3.75rem;height:32px;height:2.6666666667rem;font-size:20px;font-size:1.6666666667rem;line-height:31px;line-height:2.5833333333rem;text-align:center}.theme-light .TitleBar__devBuildIndicator{position:absolute;top:6px;top:.5rem;right:52px;right:4.3333333333rem;min-width:20px;min-width:1.6666666667rem;padding:2px 4px;padding:.1666666667rem .3333333333rem;background-color:rgba(91,170,39,.75);color:#fff;text-align:center}.theme-light html,.theme-light body{padding:0;margin:0;height:100%;color:#000}.theme-light body{background:#fff;font-family:Verdana,sans-serif;font-size:13px;line-height:1.2;overflow-x:hidden;overflow-y:scroll;word-wrap:break-word}.theme-light em{font-style:normal;font-weight:bold}.theme-light img{margin:0;padding:0;line-height:1;-ms-interpolation-mode:nearest-neighbor;image-rendering:pixelated}.theme-light img.icon{height:1em;min-height:16px;width:auto;vertical-align:bottom}.theme-light a{color:blue}.theme-light a.visited{color:#f0f}.theme-light a:visited{color:#f0f}.theme-light a.popt{text-decoration:none}.theme-light .popup{position:fixed;top:50%;left:50%;background:#ddd}.theme-light .popup .close{position:absolute;background:#aaa;top:0;right:0;color:#333;text-decoration:none;z-index:2;padding:0 10px;height:30px;line-height:30px}.theme-light .popup .close:hover{background:#999}.theme-light .popup .head{background:#999;color:#ddd;padding:0 10px;height:30px;line-height:30px;text-transform:uppercase;font-size:.9em;font-weight:bold;border-bottom:2px solid green}.theme-light .popup input{border:1px solid #999;background:#fff;margin:0;padding:5px;outline:none;color:#333}.theme-light .popup input[type=text]:hover,.theme-light .popup input[type=text]:active,.theme-light .popup input[type=text]:focus{border-color:green}.theme-light .popup input[type=submit]{padding:5px 10px;background:#999;color:#ddd;text-transform:uppercase;font-size:.9em;font-weight:bold}.theme-light .popup input[type=submit]:hover,.theme-light .popup input[type=submit]:focus,.theme-light .popup input[type=submit]:active{background:#aaa;cursor:pointer}.theme-light .changeFont{padding:10px}.theme-light .changeFont a{display:block;text-decoration:none;padding:3px;color:#333}.theme-light .changeFont a:hover{background:#ccc}.theme-light .highlightPopup{padding:10px;text-align:center}.theme-light .highlightPopup input[type=text]{display:block;width:215px;text-align:left;margin-top:5px}.theme-light .highlightPopup input.highlightColor{background-color:#ff0}.theme-light .highlightPopup input.highlightTermSubmit{margin-top:5px}.theme-light .contextMenu{background-color:#ddd;position:fixed;margin:2px;width:150px}.theme-light .contextMenu a{display:block;padding:2px 5px;text-decoration:none;color:#333}.theme-light .contextMenu a:hover{background-color:#ccc}.theme-light .filterMessages{padding:5px}.theme-light .filterMessages div{padding:2px 0}.theme-light .icon-stack{height:1em;line-height:1em;width:1em;vertical-align:middle;margin-top:-2px}.theme-light .motd{color:#638500;font-family:Verdana,sans-serif;white-space:normal}.theme-light .motd h1,.theme-light .motd h2,.theme-light .motd h3,.theme-light .motd h4,.theme-light .motd h5,.theme-light .motd h6{color:#638500;text-decoration:underline}.theme-light .motd a,.theme-light .motd a:link,.theme-light .motd a:visited,.theme-light .motd a:active,.theme-light .motd a:hover{color:#638500}.theme-light .bold,.theme-light .name,.theme-light .prefix,.theme-light .ooc,.theme-light .looc,.theme-light .adminooc,.theme-light .admin,.theme-light .medal,.theme-light .yell{font-weight:bold}.theme-light .italic,.theme-light .italics{font-style:italic}.theme-light .highlight{background:#ff0}.theme-light h1,.theme-light h2,.theme-light h3,.theme-light h4,.theme-light h5,.theme-light h6{color:blue;font-family:Georgia,Verdana,sans-serif}.theme-light h1.alert,.theme-light h2.alert{color:#000}.theme-light em{font-style:normal;font-weight:bold}.theme-light .ooc{font-weight:bold}.theme-light .adminobserverooc{color:#09c;font-weight:bold}.theme-light .adminooc{color:#700038;font-weight:bold}.theme-light .adminsay{color:#ff4500;font-weight:bold}.theme-light .admin{color:#4473ff;font-weight:bold}.theme-light .name{font-weight:bold}.theme-light .deadsay{color:#5c00e6}.theme-light .binarysay{color:#20c20e;background-color:#000;display:block}.theme-light .binarysay a{color:lime}.theme-light .binarysay a:active,.theme-light .binarysay a:visited{color:#8f8}.theme-light .radio{color:green}.theme-light .sciradio{color:#939}.theme-light .comradio{color:#948f02}.theme-light .secradio{color:#a30000}.theme-light .medradio{color:#337296}.theme-light .engradio{color:#fb5613}.theme-light .sentryradio{color:#844300}.theme-light .suppradio{color:#a8732b}.theme-light .servradio{color:#6eaa2c}.theme-light .syndradio{color:#6d3f40}.theme-light .gangradio{color:#ac2ea1}.theme-light .centcomradio{color:#686868}.theme-light .aiprivradio{color:#f0f}.theme-light .redteamradio{color:red}.theme-light .blueteamradio{color:blue}.theme-light .greenteamradio{color:lime}.theme-light .yellowteamradio{color:#d1ba22}.theme-light .yell{font-weight:bold}.theme-light .alert{color:red}.theme-light h1.alert,.theme-light h2.alert{color:#000}.theme-light .userdanger{color:red;font-weight:bold;font-size:185%}.theme-light .bolddanger{color:red;font-weight:bold}.theme-light .danger{color:red}.theme-light .tinydanger{color:red;font-size:85%}.theme-light .smalldanger{color:red;font-size:90%}.theme-light .warning{color:red;font-style:italic}.theme-light .alertwarning{color:red;font-weight:bold}.theme-light .boldwarning{color:red;font-style:italic;font-weight:bold}.theme-light .announce{color:#228b22;font-weight:bold}.theme-light .boldannounce{color:red;font-weight:bold}.theme-light .bigannounce{font-weight:bold;font-size:115%}.theme-light .greenannounce{color:lime;font-weight:bold}.theme-light .rose{color:#ff5050}.theme-light .info{color:#00c}.theme-light .notice{color:#009}.theme-light .staff_ic{color:#009}.theme-light .tinynotice{color:#009;font-size:85%}.theme-light .tinynoticeital{color:#009;font-style:italic;font-size:85%}.theme-light .smallnotice{color:#009;font-size:90%}.theme-light .smallnoticeital{color:#009;font-style:italic;font-size:90%}.theme-light .boldnotice{color:#009;font-weight:bold}.theme-light .hear{color:#009;font-style:italic}.theme-light .adminnotice{color:blue}.theme-light .adminhelp{color:red;font-weight:bold}.theme-light .unconscious{color:blue;font-weight:bold}.theme-light .suicide{color:#ff5050;font-style:italic}.theme-light .green{color:#03ff39}.theme-light .grey{color:#838383}.theme-light .red{color:red}.theme-light .blue{color:blue}.theme-light .nicegreen{color:#14a833}.theme-light .boldnicegreen{color:#14a833;font-weight:bold}.theme-light .cult{color:#973e3b}.theme-light .cultitalic{color:#973e3b;font-style:italic}.theme-light .cultbold{color:#973e3b;font-style:italic;font-weight:bold}.theme-light .cultboldtalic{color:#973e3b;font-weight:bold;font-size:185%}.theme-light .cultlarge{color:#973e3b;font-weight:bold;font-size:185%}.theme-light .narsie{color:#973e3b;font-weight:bold;font-size:925%}.theme-light .narsiesmall{color:#973e3b;font-weight:bold;font-size:370%}.theme-light .colossus{color:#7f282a;font-size:310%}.theme-light .hierophant{color:#609;font-weight:bold;font-style:italic}.theme-light .hierophant_warning{color:#609;font-style:italic}.theme-light .purple{color:#5e2d79}.theme-light .holoparasite{color:#35333a}.theme-light .revennotice{color:#1d2953}.theme-light .revenboldnotice{color:#1d2953;font-weight:bold}.theme-light .revenbignotice{color:#1d2953;font-weight:bold;font-size:185%}.theme-light .revenminor{color:#823abb}.theme-light .revenwarning{color:#760fbb;font-style:italic}.theme-light .revendanger{color:#760fbb;font-weight:bold;font-size:185%}.theme-light .deconversion_message{color:#5000a0;font-size:185%;font-style:italic}.theme-light .ghostalert{color:#5c00e6;font-style:italic;font-weight:bold}.theme-light .alien{color:#543354}.theme-light .noticealien{color:#00c000}.theme-light .alertalien{color:#00c000;font-weight:bold}.theme-light .changeling{color:purple;font-style:italic}.theme-light .alertsyndie{color:red;font-size:185%;font-weight:bold}.theme-light .spider{color:#4d004d;font-weight:bold;font-size:185%}.theme-light .interface{color:#303}.theme-light .sans{font-family:"Comic Sans MS",cursive,sans-serif}.theme-light .papyrus{font-family:"Papyrus",cursive,sans-serif}.theme-light .robot{font-family:"Courier New",cursive,sans-serif}.theme-light .tape_recorder{color:maroon;font-family:"Courier New",cursive,sans-serif}.theme-light .command_headset{font-weight:bold;font-size:160%}.theme-light .small{font-size:60%}.theme-light .big{font-size:185%}.theme-light .reallybig{font-size:245%}.theme-light .extremelybig{font-size:310%}.theme-light .greentext{color:lime;font-size:185%}.theme-light .redtext{color:red;font-size:185%}.theme-light .clown{color:#ff69bf;font-size:160%;font-family:"Comic Sans MS",cursive,sans-serif;font-weight:bold}.theme-light .singing{font-family:"Trebuchet MS",cursive,sans-serif;font-style:italic}.theme-light .his_grace{color:#15d512;font-family:"Courier New",cursive,sans-serif;font-style:italic}.theme-light .hypnophrase{color:#0d0d0d;font-weight:bold;animation:hypnocolor 1500ms infinite;animation-direction:alternate}@keyframes hypnocolor{0%{color:#0d0d0d}25%{color:#410194}50%{color:#7f17d8}75%{color:#410194}100%{color:#3bb5d3}}.theme-light .phobia{color:#d00;font-weight:bold;animation:phobia 750ms infinite}@keyframes phobia{0%{color:#0d0d0d}50%{color:#d00}100%{color:#0d0d0d}}.theme-light .icon{height:1em;width:auto}.theme-light .bigicon{font-size:2.5em}.theme-light .memo{color:#638500;text-align:center}.theme-light .memoedit{text-align:center;font-size:125%}.theme-light .abductor{color:purple;font-style:italic}.theme-light .mind_control{color:#a00d6f;font-size:100%;font-weight:bold;font-style:italic}.theme-light .slime{color:#00ced1}.theme-light .drone{color:#848482}.theme-light .monkey{color:#975032}.theme-light .swarmer{color:#2c75ff}.theme-light .resonate{color:#298f85}.theme-light .monkeyhive{color:#774704}.theme-light .monkeylead{color:#774704;font-size:80%}.theme-light .connectionClosed,.theme-light .fatalError{background:red;color:#fff;padding:5px}.theme-light .connectionClosed.restored{background:green}.theme-light .internal.boldnshit{color:blue;font-weight:bold}.theme-light .text-normal{font-weight:normal;font-style:normal}.theme-light .hidden{display:none;visibility:hidden}.theme-light .ml-1{margin-left:1em}.theme-light .ml-2{margin-left:2em}.theme-light .ml-3{margin-left:3em}.theme-light .xooc{color:#6c0094;font-weight:bold;font-size:140%}.theme-light .mooc{color:#090;font-weight:bold;font-size:140%}.theme-light .yooc{color:#999600;font-weight:bold;font-size:140%}.theme-light .headminsay{color:#5a0a7f;font-weight:bold}.theme-light .radio{color:#4e4e4e}.theme-light .deptradio{color:#939}.theme-light .comradio{color:#004080}.theme-light .centradio{color:#5c5c8a}.theme-light .cryoradio{color:#554e3f}.theme-light .hcradio{color:#318779}.theme-light .pvstradio{color:#9b0612}.theme-light .airadio{color:#f0f}.theme-light .secradio{color:#a30000}.theme-light .engradio{color:#a66300}.theme-light .sentryradio{color:#844300}.theme-light .medradio{color:#008160}.theme-light .supradio{color:#5f4519}.theme-light .jtacradio{color:#702963}.theme-light .intelradio{color:#027d02}.theme-light .wyradio{color:#fe9b24}.theme-light .pmcradio{color:#136957}.theme-light .vairadio{color:#943d0a}.theme-light .cmbradio{color:#1b748c}.theme-light .clfradio{color:#6f679c}.theme-light .alpharadio{color:#ea0000}.theme-light .bravoradio{color:#c68610}.theme-light .charlieradio{color:#a5a}.theme-light .deltaradio{color:#007fcf}.theme-light .echoradio{color:#3a7e65}.theme-light .medium{font-size:110%}.theme-light .big{font-size:115%}.theme-light .large{font-size:125%}.theme-light .extra_large{font-size:130%}.theme-light .huge{font-size:150%}.theme-light .underline{text-decoration:underline}.theme-light .orange{color:#eca100}.theme-light .normal{font-style:normal}.theme-light .attack{color:red}.theme-light .moderate{color:#c00}.theme-light .disarm{color:#900}.theme-light .passive{color:#600}.theme-light .helpful{color:#368f31}.theme-light .scanner{color:red}.theme-light .scannerb{color:red;font-weight:bold}.theme-light .scannerburn{color:orange}.theme-light .scannerburnb{color:orange;font-weight:bold}.theme-light .rose{color:#ff5050}.theme-light .debuginfo{color:#493d26;font-style:italic}.theme-light .xenonotice{color:#2a623d}.theme-light .xenoboldnotice{color:#2a623d;font-weight:bold}.theme-light .xenowarning{color:#2a623d;font-style:italic}.theme-light .xenominorwarning{color:#2a623d;font-weight:bold;font-style:italic}.theme-light .xenodanger{color:#2a623d;font-weight:bold}.theme-light .avoidharm{color:#72a0e5;font-weight:bold}.theme-light .highdanger{color:red;font-weight:bold;font-size:140%}.theme-light .xenohighdanger{color:#2a623d;font-weight:bold;font-size:140%}.theme-light .xenoannounce{color:#1a472a;font-family:book-antiqua;font-weight:bold;font-size:140%}.theme-light .yautjabold{color:purple;font-weight:bold}.theme-light .yautjaboldbig{color:purple;font-weight:bold;font-size:120%}.theme-light .objectivebig{font-weight:bold;font-size:130%}.theme-light .objectivegreen{color:lime}.theme-light .objectivered{color:red}.theme-light .objectivesuccess{color:lime;font-weight:bold;font-size:110%}.theme-light .objectivefail{color:red;font-weight:bold;font-size:110%}.theme-light .xenotalk,.theme-light .xeno{color:#900090;font-style:italic}.theme-light .xenoleader{color:#730d73;font-style:italic;font-size:125%}.theme-light .xenoqueen{color:#730d73;font-style:italic;font-weight:bold;font-size:125%}.theme-light .newscaster{color:maroon}.theme-light .role_header{color:#db0000;display:block;text-align:center;font-weight:bold;font-family:trebuchet-ms;font-size:150%}.theme-light .role_body{color:#009;display:block;text-align:center;font-size:125%}.theme-light .round_header{color:#db0000;display:block;text-align:center;font-family:courier;font-weight:bold;font-size:180%}.theme-light .round_body{color:#001427;display:block;text-align:center;font-family:trebuchet-ms;font-weight:bold;font-size:125%}.theme-light .event_announcement{color:#600d48;font-family:arial-narrow;font-weight:bold;font-size:125%}.theme-light .announce_header{color:#000;font-weight:bold;font-size:150%}.theme-light .announce_header_blue{color:#009;font-weight:bold;font-size:150%}.theme-light .announce_body{color:red;font-weight:normal;font-size:125%}.theme-light .centerbold{display:block;text-align:center;font-weight:bold}.theme-light .mod{color:#735638;font-weight:bold}.theme-light .modooc{color:#184880;font-weight:bold}.theme-light .adminmod{color:#402a14;font-weight:bold}.theme-light .mentorsay{color:#b38c32;font-weight:bold}.theme-light .mentorhelp{color:#007e00;font-weight:bold}.theme-light .mentorbody{color:#da6200;font-weight:bold}.theme-light .mentorstaff{color:#876101;font-weight:bold}.theme-light .staffsay{color:#876101;font-weight:bold}.theme-light .tajaran{color:#803b56}.theme-light .tajaran_signlang{color:#941c1c}.theme-light .skrell{color:#00ced1}.theme-light .soghun{color:#228b22}.theme-light .changeling{color:purple}.theme-light .vox{color:#a0a}.theme-light .monkey{color:#966c47}.theme-light .german{color:#858f1e;font-family:"Times New Roman",Times,serif}.theme-light .spanish{color:#cf982b}.theme-light .japanese{color:#940927}.theme-light .chinese{color:#fe1919}.theme-light .zombie{color:#216163;font-style:italic}.theme-light .commando{color:#fe9b24;font-style:bold}.theme-light .rough{font-family:trebuchet-ms,cursive,sans-serif}.theme-light .say_quote{font-family:Georgia,Verdana,sans-serif}.theme-light .admin .message{color:#314cad}.theme-light .admin .prefix{font-weight:bolder}.theme-light .pm{font-size:110%}.theme-light .retro_translator{font-weight:bold}.theme-light .yautja_translator{color:#a00;font-weight:bold;animation:glitch .5s infinite}@keyframes glitch{25%{color:#a00;transform:translate(-2px, -1px)}50%{color:#be0000;transform:translate(1px, -2px)}75%{color:#8d0000;transform:translate(-1px, 2px)}100%{color:#830000;transform:translate(1px, 1px)}}.theme-light .examine_block{background:#f2f7fa;border:1px solid #111a27;margin:.5em;padding:.5em .75em}.theme-light .examine_block .icon{width:1.5em;height:1.5em;margin:0;padding:0}.theme-light .tooltip{font-style:italic;border-bottom:1px dashed #000} From 8432fc6d43ee3ba07428d08243105bf63541ab5d Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 04:05:04 +0000 Subject: [PATCH 34/99] Automatic changelog for PR #5316 [ci skip] --- html/changelogs/AutoChangeLog-pr-5316.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5316.yml diff --git a/html/changelogs/AutoChangeLog-pr-5316.yml b/html/changelogs/AutoChangeLog-pr-5316.yml new file mode 100644 index 000000000000..50b3a094ab2d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5316.yml @@ -0,0 +1,4 @@ +author: "SabreML" +delete-after: True +changes: + - bugfix: "Fixed the Hive Status window showing an error message when the Queen dies." \ No newline at end of file From 4ee4a86cca381a1d06d726b8d1ccb2af35f89448 Mon Sep 17 00:00:00 2001 From: cuberound <122645057+cuberound@users.noreply.github.com> Date: Sat, 30 Dec 2023 07:14:54 +0100 Subject: [PATCH 35/99] gives trucker construction skills (#5231) # About the pull request Gives trucker engineering construction skills # Explain why it's good for the game It is strange to have engineering survivor who can not build cades and walls and it sucks when you have 3 truckers but none able to build openable cades. Giving more skills to survivors should make playing survivor more fun. Trucker still has other diferent skill and gets diferent loudout from engineer # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: balance: gives trucker engineer level construction skill /:cl: --- code/datums/skills/civilian.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/datums/skills/civilian.dm b/code/datums/skills/civilian.dm index 53b7cb8c2194..9dc4afd78826 100644 --- a/code/datums/skills/civilian.dm +++ b/code/datums/skills/civilian.dm @@ -160,6 +160,7 @@ CIVILIAN name = "Survivor Trucker" additional_skills = list( SKILL_ENGINEER = SKILL_ENGINEER_ENGI, + SKILL_CONSTRUCTION = SKILL_CONSTRUCTION_ENGI, SKILL_VEHICLE = SKILL_VEHICLE_CREWMAN, ) From 4f797b05653cc3f90de6ee785e6f2584732f4ee9 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 06:23:14 +0000 Subject: [PATCH 36/99] Automatic changelog for PR #5231 [ci skip] --- html/changelogs/AutoChangeLog-pr-5231.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5231.yml diff --git a/html/changelogs/AutoChangeLog-pr-5231.yml b/html/changelogs/AutoChangeLog-pr-5231.yml new file mode 100644 index 000000000000..63ee5031277c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5231.yml @@ -0,0 +1,4 @@ +author: "cuberound" +delete-after: True +changes: + - balance: "gives trucker engineer level construction skill" \ No newline at end of file From 0f886022c37879ec867cf4bcf0f305bb8569f2db Mon Sep 17 00:00:00 2001 From: blackdragonTOW <31581761+blackdragonTOW@users.noreply.github.com> Date: Fri, 29 Dec 2023 22:15:44 -0800 Subject: [PATCH 37/99] CL Headsets can utilize two more keys. (#5234) # About the pull request CLs have access to more keys now for CL purposes. This bump should allow them to utilize the new keys without feeling awkwardly limited by the key count. # Explain why it's good for the game You use utility by having limited key access, this should allow people who use keys more frequently to take part in broader information spaces. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: add: Max CL Headset radio keys from 3 to 5. (+2 increase) /:cl: --- code/game/objects/items/devices/radio/headset.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 7ec941f1192b..e5c717e699f0 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -520,6 +520,7 @@ name = "corporate liaison radio headset" desc = "Used by the CL to convince people to sign NDAs. Channels are as follows: :v - marine command, :a - alpha squad, :b - bravo squad, :c - charlie squad, :d - delta squad, :n - engineering, :m - medbay, :u - requisitions, :j - JTAC, :t - intel, :y for WY." icon_state = "wy_headset" + maximum_keys = 5 initial_keys = list(/obj/item/device/encryptionkey/mcom/cl) /obj/item/device/radio/headset/almayer/reporter From b45c7d8685ccb5e326c0936078e50492e34b1fa5 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 06:37:11 +0000 Subject: [PATCH 38/99] Automatic changelog for PR #5234 [ci skip] --- html/changelogs/AutoChangeLog-pr-5234.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5234.yml diff --git a/html/changelogs/AutoChangeLog-pr-5234.yml b/html/changelogs/AutoChangeLog-pr-5234.yml new file mode 100644 index 000000000000..270ff64cc103 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5234.yml @@ -0,0 +1,4 @@ +author: "blackdragonTOW" +delete-after: True +changes: + - rscadd: "Max CL Headset radio keys from 3 to 5. (+2 increase)" \ No newline at end of file From ec9be92834268fbce257f40c4fd1b1133e93c42d Mon Sep 17 00:00:00 2001 From: Birdtalon Date: Sat, 30 Dec 2023 06:24:56 +0000 Subject: [PATCH 39/99] Refactors some other xeno throws to throw_carbon() (#5237) # About the pull request Reduce boilerplate # Explain why it's good for the game # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: code: Refactors some code to new throw_carbon proc /:cl: --- .../xenomorph/abilities/defender/defender_powers.dm | 10 +--------- .../xenomorph/abilities/ravager/ravager_powers.dm | 10 +--------- .../xenomorph/abilities/warrior/warrior_powers.dm | 11 +---------- 3 files changed, 3 insertions(+), 28 deletions(-) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm index 0cb803e67b96..ef084c9b5b59 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm @@ -85,20 +85,12 @@ var/facing = get_dir(fendy, carbone) var/headbutt_distance = 1 + (fendy.crest_defense * 2) + (fendy.fortify * 2) - var/turf/thrown_turf = get_turf(fendy) - var/turf/temp = get_turf(fendy) - - for(var/x in 0 to headbutt_distance) - temp = get_step(thrown_turf, facing) - if(!temp) - break - thrown_turf = temp // Hmm today I will kill a marine while looking away from them fendy.face_atom(carbone) fendy.animation_attack_on(carbone) fendy.flick_attack_overlay(carbone, "punch") - carbone.throw_atom(thrown_turf, headbutt_distance, SPEED_SLOW, src) + fendy.throw_carbon(carbone, facing, headbutt_distance, SPEED_SLOW, shake_camera = FALSE, immobilize = FALSE) playsound(carbone,'sound/weapons/alien_claw_block.ogg', 50, 1) apply_cooldown() return ..() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm index c70c3cae6cd3..5f8853a066a7 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/ravager/ravager_powers.dm @@ -132,16 +132,8 @@ human.attack_alien(xeno, rand(xeno.melee_damage_lower, xeno.melee_damage_upper)) var/facing = get_dir(xeno, human) - var/turf/turf = xeno.loc - var/turf/temp = xeno.loc - - for(var/step in 0 to behavior.fling_distance-1) - temp = get_step(turf, facing) - if (!temp) - break - turf = temp - human.throw_atom(turf, behavior.fling_distance, SPEED_VERY_FAST, xeno, TRUE) + xeno.throw_carbon(human, facing, behavior.fling_distance, SPEED_VERY_FAST, shake_camera = FALSE, immobilize = TRUE) /datum/action/xeno_action/activable/scissor_cut/use_ability(atom/target_atom) var/mob/living/carbon/xenomorph/ravager_user = owner diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm index be550e50f0e2..bbb4a584e2a5 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/warrior/warrior_powers.dm @@ -86,23 +86,14 @@ if(carbon.slowed < slowdown) carbon.apply_effect(slowdown, SLOW) carbon.last_damage_data = create_cause_data(initial(xeno.caste_type), xeno) - shake_camera(carbon, 2, 1) var/facing = get_dir(xeno, carbon) - var/turf/throw_turf = xeno.loc - var/turf/temp = xeno.loc - - for (var/step in 0 to fling_distance-1) - temp = get_step(throw_turf, facing) - if (!temp) - break - throw_turf = temp // Hmm today I will kill a marine while looking away from them xeno.face_atom(carbon) xeno.animation_attack_on(carbon) xeno.flick_attack_overlay(carbon, "disarm") - carbon.throw_atom(throw_turf, fling_distance, SPEED_VERY_FAST, xeno, TRUE) + xeno.throw_carbon(carbon, facing, fling_distance, SPEED_VERY_FAST, shake_camera = TRUE, immobilize = TRUE) apply_cooldown() return ..() From 28c942315eb710bd381757752c3af6c592da1196 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 06:50:34 +0000 Subject: [PATCH 40/99] Automatic changelog for PR #5237 [ci skip] --- html/changelogs/AutoChangeLog-pr-5237.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5237.yml diff --git a/html/changelogs/AutoChangeLog-pr-5237.yml b/html/changelogs/AutoChangeLog-pr-5237.yml new file mode 100644 index 000000000000..2e75583fc134 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5237.yml @@ -0,0 +1,4 @@ +author: "Birdtalon" +delete-after: True +changes: + - code_imp: "Refactors some code to new throw_carbon proc" \ No newline at end of file From b9b88fd2ccf3a2ebb50c5dc6adf3117827193e2b Mon Sep 17 00:00:00 2001 From: BeagleGaming1 <56142455+BeagleGaming1@users.noreply.github.com> Date: Sat, 30 Dec 2023 03:22:30 -0500 Subject: [PATCH 41/99] Adds a verb to hide action buttons (#5304) # About the pull request Adds a verb on /client to show/hide action buttons Makes it a new variable, as var/hidden also prevents the action from being used ![image](https://github.com/cmss13-devs/cmss13/assets/56142455/1d78441c-5085-4165-a2b7-f7c3e9f7e2c3) # Changelog :cl: qol: Adds the ability to hide your action buttons /:cl: --- code/datums/action.dm | 8 ++++---- code/modules/client/client_procs.dm | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/code/datums/action.dm b/code/datums/action.dm index 0510a43415a7..3a597ad262b1 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -11,9 +11,9 @@ var/cost = 0 // By default an action has no cost -> will be utilized by skill actions/xeno actions var/action_flags = 0 // Check out __game.dm for flags /// Whether the action is hidden from its owner - /// Useful for when you want to preserve action state while preventing - /// a mob from using said action - var/hidden = FALSE + var/hidden = FALSE //Preserve action state while preventing mob from using action + ///Hide the action from the owner without preventing them from using it (incase of keybind listen_signal) + var/player_hidden = FALSE var/unique = TRUE /// A signal on the mob that will cause the action to activate var/listen_signal @@ -227,7 +227,7 @@ var/atom/movable/screen/action_button/B = A.button if(reload_screen) client.add_to_screen(B) - if(A.hidden) + if(A.hidden || A.player_hidden) B.screen_loc = null continue button_number++ diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 6d5efba2645f..a085cb7634d6 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -848,3 +848,32 @@ GLOBAL_LIST_INIT(whitelisted_client_procs, list( total_t3_playtime += get_job_playtime(src, caste_name) return total_t3_playtime + +/client/verb/action_hide_menu() + set name = "Show/Hide Actions" + set category = "IC" + + var/mob/user = usr + + var/list/actions_list = list() + for(var/datum/action/action as anything in user.actions) + var/action_name = action.name + if(action.player_hidden) + action_name += " (Hidden)" + actions_list[action_name] += action + + if(!LAZYLEN(actions_list)) + to_chat(user, SPAN_WARNING("You have no actions available.")) + return + + var/selected_action_name = tgui_input_list(user, "Show or hide selected action", "Show/Hide Actions", actions_list, 30 SECONDS) + if(!selected_action_name) + to_chat(user, SPAN_WARNING("You did not select an action.")) + return + + var/datum/action/selected_action = actions_list[selected_action_name] + selected_action.player_hidden = !selected_action.player_hidden + user.update_action_buttons() + + if(!selected_action.player_hidden && selected_action.hidden) //Inform the player that even if they are unhiding it, itll still not be visible + to_chat(user, SPAN_NOTICE("[selected_action] is forcefully hidden, bypassing player unhiding.")) From 891b1b46d41665f74bed40891fbd37c9684e6455 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 08:30:37 +0000 Subject: [PATCH 42/99] Automatic changelog for PR #5304 [ci skip] --- html/changelogs/AutoChangeLog-pr-5304.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5304.yml diff --git a/html/changelogs/AutoChangeLog-pr-5304.yml b/html/changelogs/AutoChangeLog-pr-5304.yml new file mode 100644 index 000000000000..eeada8e1ae61 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5304.yml @@ -0,0 +1,4 @@ +author: "BeagleGaming1" +delete-after: True +changes: + - qol: "Adds the ability to hide your action buttons" \ No newline at end of file From 4affa1dd228c2f67640b0eea3e778b185ec0a33e Mon Sep 17 00:00:00 2001 From: Paul Mullen <101871009+mullenpaul@users.noreply.github.com> Date: Sat, 30 Dec 2023 08:56:22 +0000 Subject: [PATCH 43/99] sentry laptop now uses camera manager (#5309) # About the pull request The sentry laptop had a bunch of custom code for handling gunsight cameras. This PR refactors it to exclusively use the camera_manager component. # Explain why it's good for the game Reduction of duplicated code. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: refactor: sentry laptop now uses camera manager component /:cl: --- code/modules/defenses/sentry_computer.dm | 119 ++++------------------- 1 file changed, 21 insertions(+), 98 deletions(-) diff --git a/code/modules/defenses/sentry_computer.dm b/code/modules/defenses/sentry_computer.dm index e2cbd5d5858e..6107bc3d7ee8 100644 --- a/code/modules/defenses/sentry_computer.dm +++ b/code/modules/defenses/sentry_computer.dm @@ -48,41 +48,18 @@ // Stuff needed to render the map /// asset name for the game map - var/map_name - - /// camera screen which renders the world - var/atom/movable/screen/map_view/cam_screen - - /// camera screen which shows a blank error - var/atom/movable/screen/background/cam_background - - var/list/cam_plane_masters + var/camera_map_name /obj/item/device/sentry_computer/Initialize(mapload) . = ..() if(cell_type) cell = new cell_type() cell.charge = cell.maxcharge - // set up cameras - map_name = "sentry_computer_[REF(src)]_map" - cam_screen = new - cam_screen.name = "screen" - cam_screen.assigned_map = map_name - cam_screen.del_on_map_removal = FALSE - cam_screen.screen_loc = "[map_name]:1,1" - cam_background = new - cam_background.assigned_map = map_name - cam_background.del_on_map_removal = FALSE - - cam_plane_masters = list() - for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/blackness) - var/atom/movable/screen/plane_master/instance = new plane() - instance.assigned_map = map_name - instance.del_on_map_removal = FALSE - if(instance.blend_mode_override) - instance.blend_mode = instance.blend_mode_override - instance.screen_loc = "[map_name]:CENTER" - cam_plane_masters += instance + + RegisterSignal(src, COMSIG_CAMERA_MAPNAME_ASSIGNED, PROC_REF(camera_mapname_update)) + + AddComponent(/datum/component/camera_manager) + SEND_SIGNAL(src, COMSIG_CAMERA_CLEAR) faction_group = FACTION_LIST_MARINE transceiver.forceMove(src) @@ -94,9 +71,8 @@ /obj/item/device/sentry_computer/Destroy() . = ..() + UnregisterSignal(src, COMSIG_CAMERA_MAPNAME_ASSIGNED) QDEL_NULL(cell) - QDEL_NULL(cam_background) - QDEL_NULL(cam_screen) QDEL_NULL(transceiver) QDEL_NULL(voice) last_camera_turf = null @@ -104,6 +80,9 @@ registered_tools = null paired_sentry = null +/obj/item/device/sentry_computer/proc/camera_mapname_update(source, value) + camera_map_name = value + /obj/item/device/sentry_computer/Move(NewLoc, direct) ..() if(table_setup || open || on) @@ -321,7 +300,7 @@ if(current == target) current = null - update_active_camera() + SEND_SIGNAL(src, COMSIG_CAMERA_CLEAR) /obj/item/device/sentry_computer/ui_status(mob/user, datum/ui_state/state) . = ..() @@ -332,15 +311,13 @@ /obj/item/device/sentry_computer/ui_close(mob/user) - - // Unregister map objects - user.client.clear_map(map_name) + SEND_SIGNAL(src, COMSIG_CAMERA_UNREGISTER_UI, user) /obj/item/device/sentry_computer/ui_static_data(mob/user) . = list() .["sentry_static"] = list() - .["mapRef"] = map_name + .["mapRef"] = camera_map_name var/index = 1 for(var/sentry in paired_sentry) var/list/sentry_holder = list() @@ -396,13 +373,8 @@ /obj/item/device/sentry_computer/tgui_interact(mob/user, datum/tgui/ui) ui = SStgui.try_update_ui(user, src, ui) - update_active_camera() if (!ui) - // Register map objects - user.client.register_map_obj(cam_background) - user.client.register_map_obj(cam_screen) - for(var/plane in cam_plane_masters) - user.client.register_map_obj(plane) + SEND_SIGNAL(src, COMSIG_CAMERA_REGISTER_UI, user) ui = new(user, src, "SentryGunUI", name) ui.open() @@ -426,7 +398,12 @@ if("set-camera") current = sentry playsound(src, get_sfx("terminal_button"), 25, FALSE) - update_active_camera() + var/obj/structure/machinery/defenses/sentry/defense = sentry + if (defense.has_camera) + defense.set_range() + var/datum/shape/rectangle/current_bb = defense.range_bounds + SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, current_bb.center_x, current_bb.center_y, defense.loc.z, current_bb.width, current_bb.height) + return TRUE if("ping") playsound(sentry, 'sound/machines/twobeep.ogg', 50, 1) @@ -439,62 +416,8 @@ if("clear-camera") current = null playsound(src, get_sfx("terminal_button"), 25, FALSE) - update_active_camera() + SEND_SIGNAL(src, COMSIG_CAMERA_CLEAR) return TRUE if("ui-interact") playsound(src, get_sfx("terminal_button"), 25, FALSE) return FALSE - -/** - * Set the displayed camera to the static not-connected. - */ -/obj/item/device/sentry_computer/proc/show_camera_static() - cam_screen.vis_contents.Cut() - last_camera_turf = null - cam_background.icon_state = "scanline2" - cam_background.fill_rect(1, 1, 15, 15) - -/** - * Update camera settings and redraw camera on the current variable. - */ -/obj/item/device/sentry_computer/proc/update_active_camera() - // Show static if can't use the camera - if(isnull(current) || !current.has_camera || current.placed != 1) - show_camera_static() - return - - // Is this camera located in or attached to a living thing, Vehicle or helmet? If so, assume the camera's loc is the living (or non) thing. - var/cam_location = current - if(isliving(current.loc) || isVehicle(current.loc)) - cam_location = current.loc - else if(istype(current.loc, /obj/item/clothing/head/helmet/marine)) - var/obj/item/clothing/head/helmet/marine/helmet = current.loc - cam_location = helmet.loc - // If we're not forcing an update for some reason and the cameras are in the same location, - // we don't need to update anything. - // Most security cameras will end here as they're not moving. - if(last_camera_turf == get_turf(cam_location)) - return - - // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. - last_camera_turf = get_turf(cam_location) - current.set_range() - var/datum/shape/rectangle/current_bb = current.range_bounds - var/x_size = current_bb.width - var/y_size = current_bb.height - var/target = locate(current_bb.center_x, current_bb.center_y, current.loc.z) - var/list/guncamera_zone = range("[x_size]x[y_size]", target) - - var/list/visible_turfs = list() - - for(var/turf/visible_turf in guncamera_zone) - visible_turfs += visible_turf - - var/list/bbox = get_bbox_of_atoms(visible_turfs) - var/size_x = bbox[3] - bbox[1] + 1 - var/size_y = bbox[4] - bbox[2] + 1 - cam_screen.icon = null - cam_screen.icon_state = "clear" - cam_screen.vis_contents = visible_turfs - cam_background.icon_state = "clear" - cam_background.fill_rect(1, 1, size_x, size_y) From b1f422b3b1f41cd29893fe9788f53d6ba830b23b Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 09:04:35 +0000 Subject: [PATCH 44/99] Automatic changelog for PR #5309 [ci skip] --- html/changelogs/AutoChangeLog-pr-5309.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5309.yml diff --git a/html/changelogs/AutoChangeLog-pr-5309.yml b/html/changelogs/AutoChangeLog-pr-5309.yml new file mode 100644 index 000000000000..cf471ddf7e95 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5309.yml @@ -0,0 +1,4 @@ +author: "mullenpaul" +delete-after: True +changes: + - refactor: "sentry laptop now uses camera manager component" \ No newline at end of file From 71d1f9368f0aca4d856940662c8c17eb662c30ab Mon Sep 17 00:00:00 2001 From: Birdtalon Date: Sat, 30 Dec 2023 09:41:27 +0000 Subject: [PATCH 45/99] Fixes a couple of runtimes with xenos dying (#5322) # About the pull request Trying to call `post_attack()` on something which has already been qdeleted within gib() ``` [2023-12-27 22:10:14.636] runtime error: Cannot read null.comp_lookup - proc name: UnregisterSignal (/datum/proc/UnregisterSignal) - source file: code/datums/components/_component.dm,219 - usr: null - src: Hide (/datum/action/xeno_action/onclick/xenohide) - call stack: - Hide (/datum/action/xeno_action/onclick/xenohide): UnregisterSignal(null, "mob_statchange") - Hide (/datum/action/xeno_action/onclick/xenohide): post attack() - Hide (/datum/action/xeno_action/onclick/xenohide): unhide on stat(Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger), 2, 0) - CallAsync(Hide (/datum/action/xeno_action/onclick/xenohide), "unhide_on_stat", /list (/list)) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): SendSignal("mob_statchange", /list (/list)) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): set stat(2) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): set stat(2) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): set stat(2) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): death(/datum/cause_data (/datum/cause_data), 1, "lets out a waning guttural scr...") - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): death(/datum/cause_data (/datum/cause_data), 1) - ... - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): updatehealth() - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): apply damage(36, "brute", "r_foot", null, 0, 0, 0) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): bullet act(the rifle bullet (/obj/projectile)) - the rifle bullet (/obj/projectile): handle mob(Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger)) - the rifle bullet (/obj/projectile): scan a turf(the catwalk (20,151,2) (/turf/open/floor/plating/plating_catwalk/shiva), 8) - the rifle bullet (/obj/projectile): process(1.19104) - Projectiles (/datum/controller/subsystem/projectiles): handle projectile flight(the rifle bullet (/obj/projectile), 5) - Projectiles (/datum/controller/subsystem/projectiles): ignite(0) - Master (/datum/controller/master): Loop(2) - Master (/datum/controller/master): StartProcessing(0) - [2023-12-27 22:10:14.636] runtime error: Cannot read null.layer - proc name: post attack (/datum/action/xeno_action/onclick/xenohide/proc/post_attack) - source file: code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm,398 - usr: null - src: Hide (/datum/action/xeno_action/onclick/xenohide) - call stack: - Hide (/datum/action/xeno_action/onclick/xenohide): post attack() - Hide (/datum/action/xeno_action/onclick/xenohide): unhide on stat(Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger), 2, 0) - CallAsync(Hide (/datum/action/xeno_action/onclick/xenohide), "unhide_on_stat", /list (/list)) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): SendSignal("mob_statchange", /list (/list)) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): set stat(2) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): set stat(2) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): set stat(2) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): death(/datum/cause_data (/datum/cause_data), 1, "lets out a waning guttural scr...") - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): death(/datum/cause_data (/datum/cause_data), 1) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): gib(/datum/cause_data (/datum/cause_data)) - ... - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): apply damage(36, "brute", "r_foot", null, 0, 0, 0) - Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger): bullet act(the rifle bullet (/obj/projectile)) - the rifle bullet (/obj/projectile): handle mob(Veteran Facehugger (896) (/mob/living/carbon/xenomorph/facehugger)) - the rifle bullet (/obj/projectile): scan a turf(the catwalk (20,151,2) (/turf/open/floor/plating/plating_catwalk/shiva), 8) - the rifle bullet (/obj/projectile): fly() - Projectiles (/datum/controller/subsystem/projectiles): process wrapper(the rifle bullet (/obj/projectile), 5) - Projectiles (/datum/controller/subsystem/projectiles): fire(0) - Master (/datum/controller/master): RunQueue() - Master (/datum/controller/master): StartProcessing(0) - ``` # Explain why it's good for the game # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: Fixes runtime calling post_attack() on a mob which has already been qdeleted via gibbing. /:cl: --- .../mob/living/carbon/xenomorph/abilities/general_powers.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index 63c8ed6da21b..63cc4cb93431 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -512,7 +512,7 @@ /datum/action/xeno_action/onclick/xenohide/proc/unhide_on_stat(mob/living/carbon/xenomorph/source, new_stat, old_stat) SIGNAL_HANDLER - if(new_stat >= UNCONSCIOUS && old_stat <= UNCONSCIOUS) + if(!QDELETED(source) && (new_stat >= UNCONSCIOUS && old_stat <= UNCONSCIOUS)) post_attack() /datum/action/xeno_action/onclick/place_trap/use_ability(atom/A) From 8d965a58c339def30be2823bf0f40254dab72261 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 09:51:24 +0000 Subject: [PATCH 46/99] Automatic changelog for PR #5322 [ci skip] --- html/changelogs/AutoChangeLog-pr-5322.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5322.yml diff --git a/html/changelogs/AutoChangeLog-pr-5322.yml b/html/changelogs/AutoChangeLog-pr-5322.yml new file mode 100644 index 000000000000..fdff7e6c3e9a --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5322.yml @@ -0,0 +1,4 @@ +author: "Birdtalon" +delete-after: True +changes: + - bugfix: "Fixes runtime calling post_attack() on a mob which has already been qdeleted via gibbing." \ No newline at end of file From 2e8e334b214a0a454a1e2791789ebfd5554e6bdc Mon Sep 17 00:00:00 2001 From: Birdtalon Date: Sat, 30 Dec 2023 09:44:02 +0000 Subject: [PATCH 47/99] Fixes runtime on death by decapitation (#5328) # About the pull request Fixes two runtimes caused by passing an invalid argument type to `death()` it should be `/datum/cause_data` and we passed a `/mob`. Player decapitated themselves by shooting themselves in the head. The extra typechecks are there because I don't want to assume that `cause` is always going to be a `mob`. If it's not a `mob` or `cause_data` already then we create a cause data with mob = null so at least we're passing it correctly to `death()` ``` [2023-12-28 17:54:11.462] runtime error: death called with string cause (Unknown (as Sherri Baker)) instead of datum - proc name: stack trace (/proc/stack_trace) - source file: code/__HELPERS/unsorted.dm,1888 - usr: Unknown (as Sherri Baker) (/mob/living/carbon/human) - src: null - usr.loc: the floor (288,32,4) (/turf/open/floor/almayer) - call stack: - stack trace("death called with string cause...") - Unknown (as Sherri Baker) (/mob/living/carbon/human): death(Unknown (as Sherri Baker) (/mob/living/carbon/human), 0, "seizes up and falls limp, thei...") - Unknown (as Sherri Baker) (/mob/living/carbon/human): death(Unknown (as Sherri Baker) (/mob/living/carbon/human), null) - the head (/obj/limb/head): droplimb(0, 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), null) - the head (/obj/limb/head): limb delimb(Unknown (as Sherri Baker) (/mob/living/carbon/human)) - the head (/obj/limb/head): take damage(44, 0, 0, 0, null, /list (/list), 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), -1, 0, 0) - the head (/obj/limb/head): take damage(44, 0, 0, 0, null, /list (/list), 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), -1, -1) - Unknown (as Sherri Baker) (/mob/living/carbon/human): apply damage(44, "brute", "head", 0, 0, null, 0, 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), 0) - Unknown (as Sherri Baker) (/mob/living/carbon/human): bullet act(the rifle bullet (/obj/projectile)) - the M41A pulse rifle MK2 (Wiel... (/obj/item/weapon/gun/rifle/m41a): attack(Unknown (as Sherri Baker) (/mob/living/carbon/human), Unknown (as Sherri Baker) (/mob/living/carbon/human), null) - Unknown (as Sherri Baker) (/mob/living/carbon/human): attackby(the M41A pulse rifle MK2 (Wiel... (/obj/item/weapon/gun/rifle/m41a), Unknown (as Sherri Baker) (/mob/living/carbon/human), /list (/list)) - Unknown (as Sherri Baker) (/mob/living/carbon/human): attackby(the M41A pulse rifle MK2 (Wiel... (/obj/item/weapon/gun/rifle/m41a), Unknown (as Sherri Baker) (/mob/living/carbon/human), /list (/list)) - Unknown (as Sherri Baker) (/mob/living/carbon/human): click adjacent(Unknown (as Sherri Baker) (/mob/living/carbon/human), the M41A pulse rifle MK2 (Wiel... (/obj/item/weapon/gun/rifle/m41a), /list (/list)) - Unknown (as Sherri Baker) (/mob/living/carbon/human): do click(Unknown (as Sherri Baker) (/mob/living/carbon/human), the floor (288,32,4) (/turf/open/floor/almayer), "icon-x=17;icon-y=19;left=1;but...") - **** (/client): Click(Unknown (as Sherri Baker) (/mob/living/carbon/human), the floor (288,32,4) (/turf/open/floor/almayer), "mapwindow.map", "icon-x=17;icon-y=19;left=1;but...") - [2023-12-28 17:54:11.465] runtime error: undefined variable /mob/living/carbon/human/var/cause_name - proc name: death (/mob/living/carbon/human/death) - source file: code/modules/mob/living/carbon/human/death.dm,117 - usr: (src) - src: Unknown (as Sherri Baker) (/mob/living/carbon/human) - src.loc: the floor (288,32,4) (/turf/open/floor/almayer) - call stack: - Unknown (as Sherri Baker) (/mob/living/carbon/human): death(Unknown (as Sherri Baker) (/mob/living/carbon/human), null) - the head (/obj/limb/head): droplimb(0, 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), null) - the head (/obj/limb/head): limb delimb(Unknown (as Sherri Baker) (/mob/living/carbon/human)) - the head (/obj/limb/head): take damage(44, 0, 0, 0, null, /list (/list), 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), -1, 0, 0) - the head (/obj/limb/head): take damage(44, 0, 0, 0, null, /list (/list), 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), -1, -1) - Unknown (as Sherri Baker) (/mob/living/carbon/human): apply damage(44, "brute", "head", 0, 0, null, 0, 0, Unknown (as Sherri Baker) (/mob/living/carbon/human), 0) - Unknown (as Sherri Baker) (/mob/living/carbon/human): bullet act(the rifle bullet (/obj/projectile)) - the M41A pulse rifle MK2 (/obj/item/weapon/gun/rifle/m41a): attack(Unknown (as Sherri Baker) (/mob/living/carbon/human), Unknown (as Sherri Baker) (/mob/living/carbon/human), null) - Unknown (as Sherri Baker) (/mob/living/carbon/human): attackby(the M41A pulse rifle MK2 (/obj/item/weapon/gun/rifle/m41a), Unknown (as Sherri Baker) (/mob/living/carbon/human), /list (/list)) - Unknown (as Sherri Baker) (/mob/living/carbon/human): attackby(the M41A pulse rifle MK2 (/obj/item/weapon/gun/rifle/m41a), Unknown (as Sherri Baker) (/mob/living/carbon/human), /list (/list)) - Unknown (as Sherri Baker) (/mob/living/carbon/human): click adjacent(Unknown (as Sherri Baker) (/mob/living/carbon/human), the M41A pulse rifle MK2 (/obj/item/weapon/gun/rifle/m41a), /list (/list)) - Unknown (as Sherri Baker) (/mob/living/carbon/human): do click(Unknown (as Sherri Baker) (/mob/living/carbon/human), the floor (288,32,4) (/turf/open/floor/almayer), "icon-x=17;icon-y=19;left=1;but...") - **** (/client): Click(Unknown (as Sherri Baker) (/mob/living/carbon/human), the floor (288,32,4) (/turf/open/floor/almayer), "mapwindow.map", "icon-x=17;icon-y=19;left=1;but...") - ``` # Explain why it's good for the game # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: Fixes a runtime on decapping one's self. /:cl: --- code/modules/organs/limbs.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/organs/limbs.dm b/code/modules/organs/limbs.dm index 718aba208f5a..949104c5d673 100644 --- a/code/modules/organs/limbs.dm +++ b/code/modules/organs/limbs.dm @@ -955,7 +955,13 @@ This function completely restores a damaged organ to perfect condition. // OK so maybe your limb just flew off, but if it was attached to a pair of cuffs then hooray! Freedom! release_restraints() - if(vital) owner.death(cause) + if(vital) + var/mob/caused_mob + if(istype(cause, /mob)) + caused_mob = cause + if(!istype(cause, /datum/cause_data)) + cause = create_cause_data("lost vital limb", caused_mob) + owner.death(cause) /* HELPERS From 5cc1b72507fec1dd3c095212fbd7d7de0a6a31db Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 10:04:27 +0000 Subject: [PATCH 48/99] Automatic changelog for PR #5328 [ci skip] --- html/changelogs/AutoChangeLog-pr-5328.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5328.yml diff --git a/html/changelogs/AutoChangeLog-pr-5328.yml b/html/changelogs/AutoChangeLog-pr-5328.yml new file mode 100644 index 000000000000..cfd4dba8f96d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5328.yml @@ -0,0 +1,4 @@ +author: "Birdtalon" +delete-after: True +changes: + - bugfix: "Fixes a runtime on decapping one's self." \ No newline at end of file From 0c7443c355c0ecb92f03b1543edb5455a5076d20 Mon Sep 17 00:00:00 2001 From: Julian56 <117036822+Huffie56@users.noreply.github.com> Date: Sat, 30 Dec 2023 11:31:50 +0100 Subject: [PATCH 49/99] Modify organization for vendors of the Rifleman and the Team Leader role. (#5187) # About the pull request added binocular to rifleman because he access to the higher tier of it already. added the advance tier to team leader because their is no reason for rifleman to have it and not their leader. added the section because it's a section other job have to store engi item(SL and comtech) # Explain why it's good for the game better logic on what items are available for marines for binoculars change. the new section is on other job so it will probably make it better to orient ourself in vendors. the two new item because i think they aren't OP and are under-used items that some marine might take if they can buy them. # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: qol: creating a new section called engineering supplies for the rifleman and the team leader. balance: added standard binocular to the rifleman vendor at a cost of 5. balance: added Range Finder and Laser Designator binoculars to Team leader at a cost of 10 and 20. balance: added ES-11 Mobile Fuel Canister and ME3 hand welder to Team leader and rifleman for 5 each. /:cl: --------- Co-authored-by: Julien --- .../vending/vendor_types/squad_prep/squad_rifleman.dm | 9 +++++++-- .../vending/vendor_types/squad_prep/squad_tl.dm | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm index 3a15229182b4..15661cc4b661 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_rifleman.dm @@ -45,6 +45,12 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list( list("Heat Absorbent Coif", 0, /obj/item/clothing/mask/rebreather/scarf, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR), list("Rebreather", 0, /obj/item/clothing/mask/rebreather, MARINE_CAN_BUY_MASK, VENDOR_ITEM_REGULAR), + list("ENGINEERING SUPPLIES", 0, null, null, null), + list("E-Tool", 5, /obj/item/tool/shovel/etool/folded, null, VENDOR_ITEM_REGULAR), + list("Sandbags", 20, /obj/item/stack/sandbags_empty/half, null, VENDOR_ITEM_REGULAR), + list("ES-11 Mobile Fuel Canister", 5, /obj/item/tool/weldpack/minitank, null, VENDOR_ITEM_REGULAR), + list("ME3 Hand Welder", 5, /obj/item/tool/weldingtool/simple, null, VENDOR_ITEM_REGULAR), + list("RESTRICTED FIREARMS", 0, null, null, null), list("VP78 Pistol", 15, /obj/item/storage/box/guncase/vp78, null, VENDOR_ITEM_REGULAR), list("SU-6 Smart Pistol", 15, /obj/item/storage/box/guncase/smartpistol, null, VENDOR_ITEM_REGULAR), @@ -88,8 +94,6 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list( list("Large General Pouch", 15, /obj/item/storage/pouch/general/large, null, VENDOR_ITEM_REGULAR), list("UTILITIES", 0, null, null, null), - list("E-Tool", 5, /obj/item/tool/shovel/etool/folded, null, VENDOR_ITEM_REGULAR), - list("Sandbags", 20, /obj/item/stack/sandbags_empty/half, null, VENDOR_ITEM_REGULAR), list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR), list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR), list("Fire Extinguisher (Portable)", 5, /obj/item/tool/extinguisher/mini, null, VENDOR_ITEM_REGULAR), @@ -98,6 +102,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_marine, list( list("Whistle", 5, /obj/item/device/whistle, null, VENDOR_ITEM_REGULAR), list("BINOCULARS", 0, null, null, null), + list("Binoculars", 5, /obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR), list("Range Finder", 10, /obj/item/device/binoculars/range, null, VENDOR_ITEM_REGULAR), list("Laser Designator", 15, /obj/item/device/binoculars/range/designator, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm index 7ddcf14eccde..d9ba7ee97c26 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm @@ -42,10 +42,14 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list( list("Insulated Gloves", 3, /obj/item/clothing/gloves/yellow, null, VENDOR_ITEM_REGULAR), list("Night Vision Optic", 30, /obj/item/device/helmet_visor/night_vision, null, VENDOR_ITEM_RECOMMENDED), - list("UTILITIES", 0, null, null, null), - list("Motion Detector", 15, /obj/item/device/motiondetector, null, VENDOR_ITEM_RECOMMENDED), + list("ENGINEERING SUPPLIES", 0, null, null, null), list("Plastic Explosive", 10, /obj/item/explosive/plastic, null, VENDOR_ITEM_REGULAR), list("Breaching Charge", 10, /obj/item/explosive/plastic/breaching_charge, null, VENDOR_ITEM_REGULAR), + list("ES-11 Mobile Fuel Canister", 5, /obj/item/tool/weldpack/minitank, null, VENDOR_ITEM_REGULAR), + list("ME3 Hand Welder", 5, /obj/item/tool/weldingtool/simple, null, VENDOR_ITEM_REGULAR), + + list("UTILITIES", 0, null, null, null), + list("Motion Detector", 15, /obj/item/device/motiondetector, null, VENDOR_ITEM_RECOMMENDED), list("Roller Bed", 5, /obj/item/roller, null, VENDOR_ITEM_REGULAR), list("Fulton Device Stack", 5, /obj/item/stack/fulton, null, VENDOR_ITEM_REGULAR), list("Fire Extinguisher (Portable)", 5, /obj/item/tool/extinguisher/mini, null, VENDOR_ITEM_REGULAR), @@ -53,6 +57,8 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list( list("BINOCULARS", 0, null, null, null), list("Binoculars", 5, /obj/item/device/binoculars, null, VENDOR_ITEM_REGULAR), + list("Range Finder", 10, /obj/item/device/binoculars/range, null, VENDOR_ITEM_REGULAR), + list("Laser Designator", 15, /obj/item/device/binoculars/range/designator, null, VENDOR_ITEM_REGULAR), list("HELMET OPTICS", 0, null, null, null), list("Medical Helmet Optic", 15, /obj/item/device/helmet_visor/medical, null, VENDOR_ITEM_REGULAR), From 87179fdb934c2590969797425f05ac2b01a32bac Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 10:39:47 +0000 Subject: [PATCH 50/99] Automatic changelog for PR #5187 [ci skip] --- html/changelogs/AutoChangeLog-pr-5187.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5187.yml diff --git a/html/changelogs/AutoChangeLog-pr-5187.yml b/html/changelogs/AutoChangeLog-pr-5187.yml new file mode 100644 index 000000000000..0e4a496510dc --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5187.yml @@ -0,0 +1,7 @@ +author: "Huffie56" +delete-after: True +changes: + - qol: "creating a new section called engineering supplies for the rifleman and the team leader." + - balance: "added standard binocular to the rifleman vendor at a cost of 5." + - balance: "added Range Finder and Laser Designator binoculars to Team leader at a cost of 10 and 20." + - balance: "added ES-11 Mobile Fuel Canister and ME3 hand welder to Team leader and rifleman for 5 each." \ No newline at end of file From 2764eaa8df2da0ee7aef0c43e118790e479aaa42 Mon Sep 17 00:00:00 2001 From: Birdtalon Date: Sat, 30 Dec 2023 13:06:17 +0000 Subject: [PATCH 51/99] Fixes milk runtime in on_mob_life() (and maybe other reagents) (#5327) # About the pull request Seen this runtime a couple of times now with milk specifically. But this situation I believe could also occur in other `reagent/on_mob_life()` `holder` being null can occur if we qdel the reagent during `remove_reagent()` and we then try to call procs on the now null holder further down the thread of `on_mob_life()`. We now check again if `!holder` after calling `remove_reagent()` at `/datum/reagent` level which will cause us to return early in `on_mob_life()` which should call parent when implemented and not operate on a null `holder` ``` [2023-12-28 17:57:27.386] runtime error: Cannot execute null.remove reagent(). - proc name: on mob life (/datum/reagent/drink/milk/on_mob_life) - source file: code/modules/reagents/chemistry_reagents/drink.dm,168 - usr: null - src: Milk (/datum/reagent/drink/milk) - call stack: - Milk (/datum/reagent/drink/milk): on mob life(Gilles Liebreich (/mob/living/carbon/human), 0, 2) - /datum/reagents (/datum/reagents): metabolize(Gilles Liebreich (/mob/living/carbon/human), 0, 2) - Gilles Liebreich (/mob/living/carbon/human): handle chemicals in body(2) - Gilles Liebreich (/mob/living/carbon/human): Life(2) - Human Life (/datum/controller/subsystem/human): fire(0) - Human Life (/datum/controller/subsystem/human): ignite(0) - Master (/datum/controller/master): RunQueue() - Master (/datum/controller/master): Loop(2) - Master (/datum/controller/master): StartProcessing(0) - ``` # Explain why it's good for the game # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: fix: Runtime with milk and possibly other reagent's on_mob_life() /:cl: --- code/modules/reagents/Chemistry-Reagents.dm | 3 +++ code/modules/reagents/chemistry_reagents/drink.dm | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 6d36765146ed..4e3f3a91449d 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -152,6 +152,9 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) handle_processing(M, mods, delta_time) holder.remove_reagent(id, custom_metabolism * delta_time) + if(!holder) + return FALSE + return TRUE //Pre-processing diff --git a/code/modules/reagents/chemistry_reagents/drink.dm b/code/modules/reagents/chemistry_reagents/drink.dm index 9739687dec20..3a49429d664e 100644 --- a/code/modules/reagents/chemistry_reagents/drink.dm +++ b/code/modules/reagents/chemistry_reagents/drink.dm @@ -163,8 +163,10 @@ /datum/reagent/drink/milk/on_mob_life(mob/living/M) . = ..() - if(!.) return - if(M.getBruteLoss() && prob(20)) M.heal_limb_damage(1,0) + if(!.) + return + if(M.getBruteLoss() && prob(20)) + M.heal_limb_damage(1,0) holder.remove_reagent("capsaicin", 10*REAGENTS_METABOLISM) holder.remove_reagent("hotsauce", 10*REAGENTS_METABOLISM) From 291fcd95a423bf58980bde41ccc3767d13582644 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 13:14:10 +0000 Subject: [PATCH 52/99] Automatic changelog for PR #5327 [ci skip] --- html/changelogs/AutoChangeLog-pr-5327.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5327.yml diff --git a/html/changelogs/AutoChangeLog-pr-5327.yml b/html/changelogs/AutoChangeLog-pr-5327.yml new file mode 100644 index 000000000000..5184b272d156 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5327.yml @@ -0,0 +1,4 @@ +author: "Birdtalon" +delete-after: True +changes: + - bugfix: "Runtime with milk and possibly other reagent's on_mob_life()" \ No newline at end of file From b9db0b88f44336d67dd8667871386323f0757a3d Mon Sep 17 00:00:00 2001 From: Cthulhu80 <122310258+Cthulhu80@users.noreply.github.com> Date: Sat, 30 Dec 2023 07:15:45 -0800 Subject: [PATCH 53/99] Fixes movement delay stacking when crossing weeds. (#5332) # About the pull request Fixes #2227 . Shadow nerfing warrior and praetorian with this one boys. # Explain why it's good for the game bug bad, and fuck oppressor. # Changelog :cl: fix: Fixes movement delay stacking on weeds /:cl: --- code/modules/cm_aliens/XenoStructures.dm | 5 ++--- code/modules/cm_aliens/weeds.dm | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/code/modules/cm_aliens/XenoStructures.dm b/code/modules/cm_aliens/XenoStructures.dm index e78756f1eda6..7e4f7996d3f8 100644 --- a/code/modules/cm_aliens/XenoStructures.dm +++ b/code/modules/cm_aliens/XenoStructures.dm @@ -160,13 +160,12 @@ /obj/effect/alien/resin/sticky/Crossed(atom/movable/AM) . = ..() var/mob/living/carbon/human/H = AM - // Wait doesn't this stack slows if you get dragged over it? What's going on here? if(istype(H) && !H.ally_of_hivenumber(hivenumber)) - H.next_move_slowdown = H.next_move_slowdown + slow_amt + H.next_move_slowdown = max(H.next_move_slowdown, slow_amt) return . var/mob/living/carbon/xenomorph/X = AM if(istype(X) && !X.ally_of_hivenumber(hivenumber)) - X.next_move_slowdown = X.next_move_slowdown + slow_amt + X.next_move_slowdown = max(X.next_move_slowdown, slow_amt) return . /obj/effect/alien/resin/sticky/proc/forsaken_handling() diff --git a/code/modules/cm_aliens/weeds.dm b/code/modules/cm_aliens/weeds.dm index 4be1ce63ac25..45c78b979105 100644 --- a/code/modules/cm_aliens/weeds.dm +++ b/code/modules/cm_aliens/weeds.dm @@ -186,7 +186,7 @@ SEND_SIGNAL(crossing_mob, COMSIG_MOB_WEED_SLOWDOWN, slowdata, src) var/final_slowdown = slowdata["movement_slowdown"] - crossing_mob.next_move_slowdown += POSITIVE(final_slowdown) + crossing_mob.next_move_slowdown = max(crossing_mob.next_move_slowdown, POSITIVE(final_slowdown)) // Uh oh, we might be dying! // I know this is bad proc naming but it was too good to pass on and it's only used in this file anyways From 312ec96fdb934125f56802a0cd098f710d962967 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:28:38 +0000 Subject: [PATCH 54/99] Automatic changelog for PR #5332 [ci skip] --- html/changelogs/AutoChangeLog-pr-5332.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5332.yml diff --git a/html/changelogs/AutoChangeLog-pr-5332.yml b/html/changelogs/AutoChangeLog-pr-5332.yml new file mode 100644 index 000000000000..108f2cb25ab8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5332.yml @@ -0,0 +1,4 @@ +author: "Cthulhu80" +delete-after: True +changes: + - bugfix: "Fixes movement delay stacking on weeds" \ No newline at end of file From 5517c1ed523549b0c4893109c7cb2cee4d84506f Mon Sep 17 00:00:00 2001 From: HaultyAnonie <131271192+HaultyAnonie@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:15:48 +0000 Subject: [PATCH 55/99] Fixes a grammar mistake seen in the requisitions vendor. (#5333) # About the pull request Fixes a grammar mistake left behind. # Explain why it's good for the game Proper English is good and encouraged. # Testing Photographs and Procedure No screenshots or videos. # Changelog :cl: AnonHault spellcheck: fixed a typo /:cl: --- code/game/machinery/vending/vendor_types/requisitions.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/vending/vendor_types/requisitions.dm b/code/game/machinery/vending/vendor_types/requisitions.dm index 1ea56c9fc0f5..24f58c8f6ae3 100644 --- a/code/game/machinery/vending/vendor_types/requisitions.dm +++ b/code/game/machinery/vending/vendor_types/requisitions.dm @@ -50,7 +50,7 @@ list("M40 HPDP White Phosphorus Smoke Grenade", round(scale * 4), /obj/item/explosive/grenade/phosphorus, VENDOR_ITEM_REGULAR), list("M40 HSDP Smoke Grenade", round(scale * 5), /obj/item/explosive/grenade/smokebomb, VENDOR_ITEM_REGULAR), list("M74 AGM-Frag Airburst Grenade", round(scale * 4), /obj/item/explosive/grenade/high_explosive/airburst, VENDOR_ITEM_REGULAR), - list("M74 AGM-Icendiary Airburst Grenade", round(scale * 4), /obj/item/explosive/grenade/incendiary/airburst, VENDOR_ITEM_REGULAR), + list("M74 AGM-Incendiary Airburst Grenade", round(scale * 4), /obj/item/explosive/grenade/incendiary/airburst, VENDOR_ITEM_REGULAR), list("M74 AGM-Smoke Airburst Grenade", round(scale * 4), /obj/item/explosive/grenade/smokebomb/airburst, VENDOR_ITEM_REGULAR), list("M74 AGM-Star Shell", round(scale * 2), /obj/item/explosive/grenade/high_explosive/airburst/starshell, VENDOR_ITEM_REGULAR), list("M74 AGM-Hornet Shell", round(scale * 4), /obj/item/explosive/grenade/high_explosive/airburst/hornet_shell, VENDOR_ITEM_REGULAR), From 4383f1b517b3f7339dd0bea4f6225d68afdd64b1 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:43:54 +0000 Subject: [PATCH 56/99] Automatic changelog for PR #5333 [ci skip] --- html/changelogs/AutoChangeLog-pr-5333.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5333.yml diff --git a/html/changelogs/AutoChangeLog-pr-5333.yml b/html/changelogs/AutoChangeLog-pr-5333.yml new file mode 100644 index 000000000000..67fea80ab849 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5333.yml @@ -0,0 +1,4 @@ +author: "AnonHault" +delete-after: True +changes: + - spellcheck: "fixed a typo" \ No newline at end of file From 81f565418773be417b164e3835610855d09afbe6 Mon Sep 17 00:00:00 2001 From: Cthulhu80 <122310258+Cthulhu80@users.noreply.github.com> Date: Sat, 30 Dec 2023 07:15:52 -0800 Subject: [PATCH 57/99] Fixes evac pods launching with more than three occupants (#5335) # About the pull request Fixes #3650 , Evac pods can no longer launch if the occupant number is greater than three. # Explain why it's good for the game bug bad # Changelog :cl: fix: Fixes evac pods launching with more than the occupant limit /:cl: --- code/modules/shuttle/shuttles/crashable/escape_shuttle.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/shuttle/shuttles/crashable/escape_shuttle.dm b/code/modules/shuttle/shuttles/crashable/escape_shuttle.dm index 1f0a8fd502cf..c2c6b818b37b 100644 --- a/code/modules/shuttle/shuttles/crashable/escape_shuttle.dm +++ b/code/modules/shuttle/shuttles/crashable/escape_shuttle.dm @@ -73,6 +73,8 @@ for(var/mob/living/occupant in interior_area) occupant_count++ for(var/obj/structure/machinery/cryopod/evacuation/cryotube in interior_area) + if(cryotube.occupant) + occupant_count++ cryos += list(cryotube) if (occupant_count > max_capacity) playsound(src,'sound/effects/escape_pod_warmup.ogg', 50, 1) From 785ab31d0ec80091100e736f6496ef75f719e296 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:59:10 +0000 Subject: [PATCH 58/99] Automatic changelog for PR #5335 [ci skip] --- html/changelogs/AutoChangeLog-pr-5335.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5335.yml diff --git a/html/changelogs/AutoChangeLog-pr-5335.yml b/html/changelogs/AutoChangeLog-pr-5335.yml new file mode 100644 index 000000000000..dcc844cb6b29 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5335.yml @@ -0,0 +1,4 @@ +author: "Cthulhu80" +delete-after: True +changes: + - bugfix: "Fixes evac pods launching with more than the occupant limit" \ No newline at end of file From dc43dbec1eeb40abf5c69c05d996dfc754ea0d5a Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:29:17 +0000 Subject: [PATCH 59/99] Adds a 'Time Since Death' counter to the status tab (#5314) # About the pull request Adds a 'Time Since Death' counter to the status tab, which shows in minutes and seconds how long it's been since the player died. (The counter isn't shown to players who joined as observers, just ghosts.) (also for the record I asked and this is fine in regards to the freeze: https://discord.com/channels/150315577943130112/745447048261795890/1189329387397578912) # Explain why it's good for the game Primarily, it would be very useful for tracking how long until it's possible to spawn as a lesser drone/facehugger without having to keep clicking the buttons to see the failure message. # Testing Photographs and Procedure
Screenshots & Videos **Normal:** ![after normal](https://github.com/cmss13-devs/cmss13/assets/57483089/99b10552-a0a1-4288-a106-802cc52cd9e6)
**With larva queue:** ![after with queue](https://github.com/cmss13-devs/cmss13/assets/57483089/a862c4f7-615f-4979-8d50-16c2551eb31d)
**With hijack:** ![after with hijack](https://github.com/cmss13-devs/cmss13/assets/57483089/e7992cac-13a4-4202-a4ba-203653b0e468)
**With both:** ![after](https://github.com/cmss13-devs/cmss13/assets/57483089/6cca3520-673d-4e7c-a718-edbc3ee02f9d)
# Changelog :cl: qol: Added a 'Time Since Death' counter to the status tab for ghosts. /:cl: --- code/modules/mob/dead/observer/observer.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 83bc0c3750f7..529d13636b2d 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -1232,6 +1232,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp if(client.prefs?.be_special & BE_ALIEN_AFTER_DEATH) if(larva_queue_cached_message) . += larva_queue_cached_message + . += "" + + if(timeofdeath) + . += "Time Since Death: [duration2text_sec(world.time - timeofdeath)]" /proc/message_ghosts(message) From 61a891a8448e4a70d5ef883ea72015d70973084b Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 16:12:13 +0000 Subject: [PATCH 60/99] Automatic changelog for PR #5314 [ci skip] --- html/changelogs/AutoChangeLog-pr-5314.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5314.yml diff --git a/html/changelogs/AutoChangeLog-pr-5314.yml b/html/changelogs/AutoChangeLog-pr-5314.yml new file mode 100644 index 000000000000..617641b9ef23 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5314.yml @@ -0,0 +1,4 @@ +author: "SabreML" +delete-after: True +changes: + - qol: "Added a 'Time Since Death' counter to the status tab for ghosts." \ No newline at end of file From 42d355f156f3f4874be32f0abefb8c9d90e7ca35 Mon Sep 17 00:00:00 2001 From: InsaneRed <47158596+InsaneRed@users.noreply.github.com> Date: Sun, 31 Dec 2023 00:08:40 +0300 Subject: [PATCH 61/99] "Fixes" predator stun durations (#5302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # About the pull request (this is up for debate from the council / pred players) After fira fixed the code it actually works which has resulted in predators gettiing up from stuns way faster then ""intended"" im using intended because it was balanced around a system which didnt work, and now that it works they get up "faster" # Explain why it's good for the game predators are already busted to fight against as a xenomorph and their only counter (stuns) not working properly is not fun to play against # Testing Photographs and Procedure
https://github.com/cmss13-devs/cmss13/assets/47158596/0226dd1e-0a7b-4cf6-8f9b-f873f28616d6 https://github.com/cmss13-devs/cmss13/assets/47158596/bc16e62f-924e-40a6-a969-a83840867db7 https://github.com/cmss13-devs/cmss13/assets/47158596/3af3f5e1-faea-4ae8-bc34-e162cb2238b5 ^^^^ NEW ā†“ ā†“ ā†“ OLD https://github.com/cmss13-devs/cmss13/assets/47158596/6755d095-81fd-40f9-89c2-89532cb1a50e https://github.com/cmss13-devs/cmss13/assets/47158596/66327438-4e2c-45fa-bc2b-bafe041e2607 https://github.com/cmss13-devs/cmss13/assets/47158596/3b9fad3b-559a-4a74-9968-0f818a27ac04
# Changelog :cl: balance: Properly tweaks predator stun resist back to what it should have been. /:cl: --------- Co-authored-by: InsaneRed --- .../mob/living/carbon/human/species/yautja/_species.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/yautja/_species.dm b/code/modules/mob/living/carbon/human/species/yautja/_species.dm index f8937279d8b9..a69d94afaca7 100644 --- a/code/modules/mob/living/carbon/human/species/yautja/_species.dm +++ b/code/modules/mob/living/carbon/human/species/yautja/_species.dm @@ -53,8 +53,8 @@ /mob/living/carbon/human/proc/mark_panel, ) - knock_down_reduction = 4 - stun_reduction = 4 + knock_down_reduction = 1.5 + stun_reduction = 1.5 weed_slowdown_mult = 0 // no slowdown! icobase = 'icons/mob/humans/species/r_predator.dmi' From 7838ceaa8086c17d3b56a2f41ffe2d5f7543f464 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sat, 30 Dec 2023 21:16:44 +0000 Subject: [PATCH 62/99] Automatic changelog for PR #5302 [ci skip] --- html/changelogs/AutoChangeLog-pr-5302.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5302.yml diff --git a/html/changelogs/AutoChangeLog-pr-5302.yml b/html/changelogs/AutoChangeLog-pr-5302.yml new file mode 100644 index 000000000000..c423a926897d --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5302.yml @@ -0,0 +1,4 @@ +author: "InsaneRed" +delete-after: True +changes: + - balance: "Properly tweaks predator stun resist back to what it should have been." \ No newline at end of file From 24f3ba1fee8574795c5f5ef6a99ff7caef337e33 Mon Sep 17 00:00:00 2001 From: Changelogs Date: Sun, 31 Dec 2023 01:15:33 +0000 Subject: [PATCH 63/99] Automatic changelog compile [ci skip] --- html/changelogs/AutoChangeLog-pr-5187.yml | 7 ----- html/changelogs/AutoChangeLog-pr-5231.yml | 4 --- html/changelogs/AutoChangeLog-pr-5234.yml | 4 --- html/changelogs/AutoChangeLog-pr-5237.yml | 4 --- html/changelogs/AutoChangeLog-pr-5302.yml | 4 --- html/changelogs/AutoChangeLog-pr-5304.yml | 4 --- html/changelogs/AutoChangeLog-pr-5309.yml | 4 --- html/changelogs/AutoChangeLog-pr-5314.yml | 4 --- html/changelogs/AutoChangeLog-pr-5316.yml | 4 --- html/changelogs/AutoChangeLog-pr-5322.yml | 4 --- html/changelogs/AutoChangeLog-pr-5327.yml | 4 --- html/changelogs/AutoChangeLog-pr-5328.yml | 4 --- html/changelogs/AutoChangeLog-pr-5332.yml | 4 --- html/changelogs/AutoChangeLog-pr-5333.yml | 4 --- html/changelogs/AutoChangeLog-pr-5335.yml | 4 --- html/changelogs/archive/2023-12.yml | 33 +++++++++++++++++++++++ 16 files changed, 33 insertions(+), 63 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-5187.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5231.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5234.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5237.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5302.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5304.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5309.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5314.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5316.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5322.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5327.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5328.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5332.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5333.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5335.yml diff --git a/html/changelogs/AutoChangeLog-pr-5187.yml b/html/changelogs/AutoChangeLog-pr-5187.yml deleted file mode 100644 index 0e4a496510dc..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5187.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "Huffie56" -delete-after: True -changes: - - qol: "creating a new section called engineering supplies for the rifleman and the team leader." - - balance: "added standard binocular to the rifleman vendor at a cost of 5." - - balance: "added Range Finder and Laser Designator binoculars to Team leader at a cost of 10 and 20." - - balance: "added ES-11 Mobile Fuel Canister and ME3 hand welder to Team leader and rifleman for 5 each." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5231.yml b/html/changelogs/AutoChangeLog-pr-5231.yml deleted file mode 100644 index 63ee5031277c..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5231.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "cuberound" -delete-after: True -changes: - - balance: "gives trucker engineer level construction skill" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5234.yml b/html/changelogs/AutoChangeLog-pr-5234.yml deleted file mode 100644 index 270ff64cc103..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5234.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "blackdragonTOW" -delete-after: True -changes: - - rscadd: "Max CL Headset radio keys from 3 to 5. (+2 increase)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5237.yml b/html/changelogs/AutoChangeLog-pr-5237.yml deleted file mode 100644 index 2e75583fc134..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5237.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Birdtalon" -delete-after: True -changes: - - code_imp: "Refactors some code to new throw_carbon proc" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5302.yml b/html/changelogs/AutoChangeLog-pr-5302.yml deleted file mode 100644 index c423a926897d..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5302.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "InsaneRed" -delete-after: True -changes: - - balance: "Properly tweaks predator stun resist back to what it should have been." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5304.yml b/html/changelogs/AutoChangeLog-pr-5304.yml deleted file mode 100644 index eeada8e1ae61..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5304.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "BeagleGaming1" -delete-after: True -changes: - - qol: "Adds the ability to hide your action buttons" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5309.yml b/html/changelogs/AutoChangeLog-pr-5309.yml deleted file mode 100644 index cf471ddf7e95..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5309.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "mullenpaul" -delete-after: True -changes: - - refactor: "sentry laptop now uses camera manager component" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5314.yml b/html/changelogs/AutoChangeLog-pr-5314.yml deleted file mode 100644 index 617641b9ef23..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5314.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - qol: "Added a 'Time Since Death' counter to the status tab for ghosts." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5316.yml b/html/changelogs/AutoChangeLog-pr-5316.yml deleted file mode 100644 index 50b3a094ab2d..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5316.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "SabreML" -delete-after: True -changes: - - bugfix: "Fixed the Hive Status window showing an error message when the Queen dies." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5322.yml b/html/changelogs/AutoChangeLog-pr-5322.yml deleted file mode 100644 index fdff7e6c3e9a..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5322.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Birdtalon" -delete-after: True -changes: - - bugfix: "Fixes runtime calling post_attack() on a mob which has already been qdeleted via gibbing." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5327.yml b/html/changelogs/AutoChangeLog-pr-5327.yml deleted file mode 100644 index 5184b272d156..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5327.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Birdtalon" -delete-after: True -changes: - - bugfix: "Runtime with milk and possibly other reagent's on_mob_life()" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5328.yml b/html/changelogs/AutoChangeLog-pr-5328.yml deleted file mode 100644 index cfd4dba8f96d..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5328.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Birdtalon" -delete-after: True -changes: - - bugfix: "Fixes a runtime on decapping one's self." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5332.yml b/html/changelogs/AutoChangeLog-pr-5332.yml deleted file mode 100644 index 108f2cb25ab8..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5332.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Cthulhu80" -delete-after: True -changes: - - bugfix: "Fixes movement delay stacking on weeds" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5333.yml b/html/changelogs/AutoChangeLog-pr-5333.yml deleted file mode 100644 index 67fea80ab849..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5333.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "AnonHault" -delete-after: True -changes: - - spellcheck: "fixed a typo" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-5335.yml b/html/changelogs/AutoChangeLog-pr-5335.yml deleted file mode 100644 index dcc844cb6b29..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5335.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Cthulhu80" -delete-after: True -changes: - - bugfix: "Fixes evac pods launching with more than the occupant limit" \ No newline at end of file diff --git a/html/changelogs/archive/2023-12.yml b/html/changelogs/archive/2023-12.yml index e4245e7d5cbc..6f487820ae46 100644 --- a/html/changelogs/archive/2023-12.yml +++ b/html/changelogs/archive/2023-12.yml @@ -556,3 +556,36 @@ - bugfix: m56d can not longer shoot backwards when facing north mullenpaul: - refactor: tgui js components now jsx +2023-12-31: + AnonHault: + - spellcheck: fixed a typo + BeagleGaming1: + - qol: Adds the ability to hide your action buttons + Birdtalon: + - bugfix: Fixes a runtime on decapping one's self. + - bugfix: Runtime with milk and possibly other reagent's on_mob_life() + - bugfix: Fixes runtime calling post_attack() on a mob which has already been qdeleted + via gibbing. + - code_imp: Refactors some code to new throw_carbon proc + Cthulhu80: + - bugfix: Fixes movement delay stacking on weeds + - bugfix: Fixes evac pods launching with more than the occupant limit + Huffie56: + - qol: creating a new section called engineering supplies for the rifleman and the + team leader. + - balance: added standard binocular to the rifleman vendor at a cost of 5. + - balance: added Range Finder and Laser Designator binoculars to Team leader at + a cost of 10 and 20. + - balance: added ES-11 Mobile Fuel Canister and ME3 hand welder to Team leader and + rifleman for 5 each. + InsaneRed: + - balance: Properly tweaks predator stun resist back to what it should have been. + SabreML: + - bugfix: Fixed the Hive Status window showing an error message when the Queen dies. + - qol: Added a 'Time Since Death' counter to the status tab for ghosts. + blackdragonTOW: + - rscadd: Max CL Headset radio keys from 3 to 5. (+2 increase) + cuberound: + - balance: gives trucker engineer level construction skill + mullenpaul: + - refactor: sentry laptop now uses camera manager component From 1f63e72b1ccb54ba87ed4a19448c94bef9cb0d0c Mon Sep 17 00:00:00 2001 From: fira Date: Sun, 31 Dec 2023 02:18:03 +0100 Subject: [PATCH 64/99] Fixes Nuke failing to detonate (#5338) # About the pull request Under very specific circumstances (seen 2x or more on live), the nuke broken logic of checking eligbile mobs for explosion will cause it to crash completely and fail to detonate. The problem is primarily the `loc` check at top, which is not a sufficient safeguard. Also moves the explosion delay so that people die when the nuke explode and not before... # Testing Photographs and Procedure Spawn in nuke and testers, safety off, proccall explode # Changelog :cl: fix: Fixed Nuke failing to detonate under specific circumstances. It may involve a little rodent. fix: Nuke explosion will now kill mobs on its actual explosion rather than at the start of the cinematic sequence. /:cl: --- code/game/machinery/nuclearbomb.dm | 52 +++++++++++++----------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/code/game/machinery/nuclearbomb.dm b/code/game/machinery/nuclearbomb.dm index cfb0d1abb94f..aac4f82ccff1 100644 --- a/code/game/machinery/nuclearbomb.dm +++ b/code/game/machinery/nuclearbomb.dm @@ -396,45 +396,39 @@ GLOBAL_VAR_INIT(bomb_set, FALSE) playsound(src, 'sound/machines/Alarm.ogg', 75, 0, 30) world << pick('sound/theme/nuclear_detonation1.ogg','sound/theme/nuclear_detonation2.ogg') - var/list/alive_mobs = list() //Everyone who will be destroyed on the zlevel(s). - var/list/dead_mobs = list() //Everyone who only needs to see the cinematic. for(var/mob/current_mob as anything in GLOB.mob_list) - if(!current_mob?.loc) - continue - if(current_mob.stat == DEAD) - dead_mobs |= current_mob - continue var/turf/current_turf = get_turf(current_mob) - if(z == current_turf.z) - alive_mobs |= current_mob + if(current_turf?.z == z && current_mob.stat != DEAD) shake_camera(current_mob, 110, 4) + sleep(10 SECONDS) + + var/list/mob/alive_mobs = list() //Everyone who will be destroyed on the zlevel(s). + var/list/mob/dead_mobs = list() //Everyone that needs embryos cleared + for(var/mob/current_mob as anything in GLOB.mob_list) + var/turf/current_turf = get_turf(current_mob) + if(current_turf?.z == z) + if(current_mob.stat == DEAD) + dead_mobs |= current_mob + continue + alive_mobs |= current_mob + for(var/mob/current_mob in alive_mobs) - if(current_mob && current_mob.loc) - var/turf/current_mob_turf = get_turf(current_mob) - if(z == current_mob_turf.z) - if(istype(current_mob.loc, /obj/structure/closet/secure_closet/freezer/fridge)) - continue - current_mob.death(create_cause_data("nuclear explosion")) - - for(var/mob/current_mob in (alive_mobs + dead_mobs)) - if(current_mob && current_mob.loc) - var/turf/current_mob_turf = get_turf(current_mob) - if(z == current_mob_turf.z) - if(istype(current_mob.loc, /obj/structure/closet/secure_closet/freezer/fridge)) - continue - for(var/obj/item/alien_embryo/embryo in current_mob) - qdel(embryo) - - sleep(100) + if(istype(current_mob.loc, /obj/structure/closet/secure_closet/freezer/fridge)) + continue + current_mob.death(create_cause_data("nuclear explosion")) + + for(var/mob/living/current_mob in (alive_mobs + dead_mobs)) + if(istype(current_mob.loc, /obj/structure/closet/secure_closet/freezer/fridge)) + continue + for(var/obj/item/alien_embryo/embryo in current_mob) + qdel(embryo) + cell_explosion(loc, 500, 150, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, create_cause_data(initial(name))) qdel(src) return TRUE /obj/structure/machinery/nuclearbomb/Destroy() - if(timing != -1) - message_admins("\The [src] has been unexpectedly deleted at ([x],[y],[x]). [ADMIN_JMP(src)]") - log_game("\The [src] has been unexpectedly deleted at ([x],[y],[x]).") GLOB.bomb_set = FALSE SSminimaps.remove_marker(src) return ..() From 22b345eae2b3a355f3483e86218dea6cc14cc819 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 31 Dec 2023 01:26:00 +0000 Subject: [PATCH 65/99] Automatic changelog for PR #5338 [ci skip] --- html/changelogs/AutoChangeLog-pr-5338.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5338.yml diff --git a/html/changelogs/AutoChangeLog-pr-5338.yml b/html/changelogs/AutoChangeLog-pr-5338.yml new file mode 100644 index 000000000000..e87c3ad81c78 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5338.yml @@ -0,0 +1,5 @@ +author: "fira" +delete-after: True +changes: + - bugfix: "Fixed Nuke failing to detonate under specific circumstances. It may involve a little rodent." + - bugfix: "Nuke explosion will now kill mobs on its actual explosion rather than at the start of the cinematic sequence." \ No newline at end of file From 7dd1f070a1b6d28b64719d7f54b66361908b6d93 Mon Sep 17 00:00:00 2001 From: Cthulhu80 <122310258+Cthulhu80@users.noreply.github.com> Date: Sat, 30 Dec 2023 18:15:15 -0800 Subject: [PATCH 66/99] Fixes vulture sniper rifle applying permanent nvg (#5341) # About the pull request Fixes #5300 , scoping on vulture sniper rifle no longer applies a permanent lighting buff. # Explain why it's good for the game bug bad # Changelog :cl: fix: Fixes permanent lighting buff after using the vulture sniper rifle. /:cl: --- code/modules/projectiles/gun_attachables.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm index e0dda3203d96..0f3fde8f3c9b 100644 --- a/code/modules/projectiles/gun_attachables.dm +++ b/code/modules/projectiles/gun_attachables.dm @@ -1586,7 +1586,7 @@ Defined in conflicts.dm of the #defines folder. scoper.clear_fullscreen("vulture") scoper.client.remove_from_screen(scope_element) scoper.see_in_dark -= darkness_view - scoper.lighting_alpha = 127 + scoper.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE scoper.sync_lighting_plane_alpha() QDEL_NULL(scope_element) recalculate_scope_pos() From 6e0235ba81cd115949651a4531a02d4943adf793 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 31 Dec 2023 02:23:29 +0000 Subject: [PATCH 67/99] Automatic changelog for PR #5341 [ci skip] --- html/changelogs/AutoChangeLog-pr-5341.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5341.yml diff --git a/html/changelogs/AutoChangeLog-pr-5341.yml b/html/changelogs/AutoChangeLog-pr-5341.yml new file mode 100644 index 000000000000..fdbd4ed00896 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5341.yml @@ -0,0 +1,4 @@ +author: "Cthulhu80" +delete-after: True +changes: + - bugfix: "Fixes permanent lighting buff after using the vulture sniper rifle." \ No newline at end of file From 192e412889eb526f1191f5df0a4ec7f570d968b5 Mon Sep 17 00:00:00 2001 From: private-tristan <54422837+private-tristan@users.noreply.github.com> Date: Sat, 30 Dec 2023 21:15:28 -0500 Subject: [PATCH 68/99] Eggs are now properly converted to forsaken on evac (#5340) # About the pull request half of #4376 eggs now become forsaken on hijack, like everything else. tested and it works. # Explain why it's good for the game bugs should be fixed # Testing Photographs and Procedure
Screenshots & Videos Put screenshots and videos here with an empty line between the screenshots and the `
` tags.
# Changelog :cl: Private Tristan fix: Eggs are properly converted to Forsaken hive on evac /:cl: --- code/modules/cm_aliens/structures/egg.dm | 11 +++++++++++ .../xenomorph/abilities/ability_helper_procs.dm | 1 - code/modules/mob/living/carbon/xenomorph/egg_item.dm | 11 +++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/code/modules/cm_aliens/structures/egg.dm b/code/modules/cm_aliens/structures/egg.dm index 5b0654d05b55..889359bb7eef 100644 --- a/code/modules/cm_aliens/structures/egg.dm +++ b/code/modules/cm_aliens/structures/egg.dm @@ -23,10 +23,21 @@ if (hive) hivenumber = hive + if(hivenumber == XENO_HIVE_NORMAL) + RegisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING, PROC_REF(forsaken_handling)) + set_hive_data(src, hivenumber) update_icon() addtimer(CALLBACK(src, PROC_REF(Grow)), rand(EGG_MIN_GROWTH_TIME, EGG_MAX_GROWTH_TIME)) +/obj/effect/alien/egg/proc/forsaken_handling() + SIGNAL_HANDLER + if(is_ground_level(z)) + hivenumber = XENO_HIVE_FORSAKEN + set_hive_data(src, XENO_HIVE_FORSAKEN) + + UnregisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING) + /obj/effect/alien/egg/Destroy() . = ..() for(var/obj/effect/egg_trigger/trigger as anything in egg_triggers) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm b/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm index 7f3d886deb3a..68312b77936d 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/ability_helper_procs.dm @@ -31,7 +31,6 @@ if(isobj(O)) I = O - wait_time = I.get_applying_acid_time() if(wait_time == -1) to_chat(src, SPAN_WARNING("We cannot dissolve \the [I].")) diff --git a/code/modules/mob/living/carbon/xenomorph/egg_item.dm b/code/modules/mob/living/carbon/xenomorph/egg_item.dm index e4cc7bd39fe0..6f00ae1798e9 100644 --- a/code/modules/mob/living/carbon/xenomorph/egg_item.dm +++ b/code/modules/mob/living/carbon/xenomorph/egg_item.dm @@ -25,6 +25,17 @@ set_hive_data(src, hivenumber) . = ..() + if(hivenumber == XENO_HIVE_NORMAL) + RegisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING, PROC_REF(forsaken_handling)) + +/obj/item/xeno_egg/proc/forsaken_handling() + SIGNAL_HANDLER + if(is_ground_level(z)) + hivenumber = XENO_HIVE_FORSAKEN + set_hive_data(src, XENO_HIVE_FORSAKEN) + + UnregisterSignal(SSdcs, COMSIG_GLOB_GROUNDSIDE_FORSAKEN_HANDLING) + /obj/item/xeno_egg/get_examine_text(mob/user) . = ..() if(isxeno(user)) From e6593fc412ba9f059ca42771933792dd9da64343 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 31 Dec 2023 02:38:05 +0000 Subject: [PATCH 69/99] Automatic changelog for PR #5340 [ci skip] --- html/changelogs/AutoChangeLog-pr-5340.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5340.yml diff --git a/html/changelogs/AutoChangeLog-pr-5340.yml b/html/changelogs/AutoChangeLog-pr-5340.yml new file mode 100644 index 000000000000..49bd725b0596 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5340.yml @@ -0,0 +1,4 @@ +author: "Private Tristan" +delete-after: True +changes: + - bugfix: "Eggs are properly converted to Forsaken hive on evac" \ No newline at end of file From 158f87fc3992bdf57ec49edad01dc4eb60e34f8f Mon Sep 17 00:00:00 2001 From: Cthulhu80 <122310258+Cthulhu80@users.noreply.github.com> Date: Sat, 30 Dec 2023 22:01:13 -0800 Subject: [PATCH 70/99] Fixes photos only being viewable from adjacent tiles as an observer (#5343) # About the pull request Fixes #3855 , observer mobs can now view photos from any distance. # Explain why it's good for the game bug bad # Changelog :cl: fix: Fixes photos not being viewable from any distance as an observer /:cl: --- code/modules/paperwork/paper.dm | 2 +- code/modules/paperwork/photography.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index b572b5d9e87b..7a0fe71b4fc6 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -75,7 +75,7 @@ /obj/item/paper/get_examine_text(mob/user) . = ..() - if(in_range(user, src) || istype(user, /mob/dead/observer)) + if(in_range(user, src) || isobserver(user)) if(!(istype(user, /mob/dead/observer) || istype(user, /mob/living/carbon/human) || isRemoteControlling(user))) // Show scrambled paper if they aren't a ghost, human, or silicone. if(photo_list) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index cebb4ad613b0..40d88f684791 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -46,7 +46,7 @@ ..() /obj/item/photo/get_examine_text(mob/user) - if(in_range(user, src)) + if(in_range(user, src) || isobserver(user)) show(user) return list(desc) else From f3113a03bd9d7dd89d6f8f7d2318dd3eab6e308e Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 31 Dec 2023 06:10:04 +0000 Subject: [PATCH 71/99] Automatic changelog for PR #5343 [ci skip] --- html/changelogs/AutoChangeLog-pr-5343.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5343.yml diff --git a/html/changelogs/AutoChangeLog-pr-5343.yml b/html/changelogs/AutoChangeLog-pr-5343.yml new file mode 100644 index 000000000000..31eedc2e1940 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5343.yml @@ -0,0 +1,4 @@ +author: "Cthulhu80" +delete-after: True +changes: + - bugfix: "Fixes photos not being viewable from any distance as an observer" \ No newline at end of file From 672be37da571684e65dbd9439f1595bf1ccc2ac2 Mon Sep 17 00:00:00 2001 From: Cthulhu80 <122310258+Cthulhu80@users.noreply.github.com> Date: Sat, 30 Dec 2023 22:01:20 -0800 Subject: [PATCH 72/99] Fixes mobs in crit being able to understand other languages (#5342) # About the pull request Fixes #3778 , mobs should no longer be able to comprehend other languages while in crit. # Explain why it's good for the game bug bad # Changelog :cl: fix: Fixes mobs being able to understand other languages while in crit. /:cl: --- code/modules/mob/hear_say.dm | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/hear_say.dm b/code/modules/mob/hear_say.dm index c66d096c6c68..dd71180e2dfe 100644 --- a/code/modules/mob/hear_say.dm +++ b/code/modules/mob/hear_say.dm @@ -202,18 +202,21 @@ /mob/living/hear_say(message, verb, datum/language/language, alt_name, italics, mob/speaker, sound/speech_sound, sound_vol) if(client && mind && stat == UNCONSCIOUS) - hear_sleep(src, message, src == speaker, Adjacent(speaker)) + hear_sleep(speaker, message, src == speaker, Adjacent(speaker), language) return return ..() /mob/living/hear_radio(message, verb, datum/language/language, part_a, part_b, mob/speaker, hard_to_hear, vname, command, no_paygrade) if(client && mind && stat == UNCONSCIOUS) - hear_sleep(src, message, FALSE, FALSE) + hear_sleep(speaker, message, FALSE, FALSE, language) return return ..() -/mob/living/proc/hear_sleep(mob/speaker = null, message, hearing_self = FALSE, proximity_flag = FALSE) +/mob/living/proc/hear_sleep(mob/speaker = null, message, hearing_self = FALSE, proximity_flag = FALSE, datum/language/language = null) var/heard = "" + var/clear_char_probability = 90 + if(!say_understands(speaker, language)) + clear_char_probability = 25 if(sdisabilities & DISABILITY_DEAF || ear_deaf) if(speaker == src) @@ -226,7 +229,7 @@ heard = SPAN_LOCALSAY("You mutter something about... [stars(message, clear_char_probability = 99)]") else if(!sleeping && proximity_flag) - heard = SPAN_LOCALSAY("You hear someone near you say something... [stars(message, clear_char_probability = 90)]") + heard = SPAN_LOCALSAY("You hear someone near you say something... [stars(message, clear_char_probability)]") else if(prob(15)) From 9d9139aa75fba645236913eeec48f086081d4447 Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 31 Dec 2023 06:23:41 +0000 Subject: [PATCH 73/99] Automatic changelog for PR #5342 [ci skip] --- html/changelogs/AutoChangeLog-pr-5342.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5342.yml diff --git a/html/changelogs/AutoChangeLog-pr-5342.yml b/html/changelogs/AutoChangeLog-pr-5342.yml new file mode 100644 index 000000000000..f70005834713 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5342.yml @@ -0,0 +1,4 @@ +author: "Cthulhu80" +delete-after: True +changes: + - bugfix: "Fixes mobs being able to understand other languages while in crit." \ No newline at end of file From 988a56a1c9220f4d85e5ba638b44ba2522cc7540 Mon Sep 17 00:00:00 2001 From: InsaneRed <47158596+InsaneRed@users.noreply.github.com> Date: Sun, 31 Dec 2023 11:59:26 +0300 Subject: [PATCH 74/99] Changes hit alerts from you to WE (#5295) # About the pull request This makes you are hit by x to We for the xeno side i dont know if this is a good way to do this, however. # Explain why it's good for the game Consistency is good, also more hiveminded alerts # Testing Photographs and Procedure text based # Changelog :cl: spellcheck: Changed hit alerts to We instead of You on the xeno side. /:cl: --------- Co-authored-by: InsaneRed --- .../mob/living/carbon/human/powers/human_powers.dm | 14 +++++++------- .../mob/living/carbon/xenomorph/damage_procs.dm | 2 +- code/modules/projectiles/guns/flamer/flamer.dm | 4 ++-- code/modules/projectiles/projectile.dm | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/code/modules/mob/living/carbon/human/powers/human_powers.dm b/code/modules/mob/living/carbon/human/powers/human_powers.dm index be7848b2a936..36eb927eb7fb 100644 --- a/code/modules/mob/living/carbon/human/powers/human_powers.dm +++ b/code/modules/mob/living/carbon/human/powers/human_powers.dm @@ -202,7 +202,7 @@ if(new_resting == resting) return if(!COOLDOWN_FINISHED(src, rest_cooldown)) - to_chat(src, SPAN_WARNING("You can't 'rest' that fast. Take a breather!")) + to_chat(src, SPAN_WARNING("[isxeno(src) ? "We" : "You"] can't 'rest' that fast. Take a breather!")) return COOLDOWN_START(src, rest_cooldown, 1 SECONDS) @@ -211,24 +211,24 @@ if(new_resting) if(body_position == LYING_DOWN) if(!silent) - to_chat(src, SPAN_NOTICE("You will now try to stay lying down on the floor.")) + to_chat(src, SPAN_NOTICE("[isxeno(src) ? "We" : "You"] will now try to stay lying down on the floor.")) else if(HAS_TRAIT(src, TRAIT_FORCED_STANDING) || (buckled && buckled.buckle_lying != NO_BUCKLE_LYING)) if(!silent) - to_chat(src, SPAN_NOTICE("You will now lay down as soon as you are able to.")) + to_chat(src, SPAN_NOTICE("[isxeno(src) ? "We" : "You"] will now lay down as soon as [isxeno(src) ? "we" : "you"] are able to.")) else if(!silent) - to_chat(src, SPAN_NOTICE("You lay down.")) + to_chat(src, SPAN_NOTICE("[isxeno(src) ? "We" : "You"] lay down.")) set_lying_down() else if(body_position == STANDING_UP) if(!silent) - to_chat(src, SPAN_NOTICE("You will now try to remain standing up.")) + to_chat(src, SPAN_NOTICE("[isxeno(src) ? "We" : "You"] will now try to remain standing up.")) else if(HAS_TRAIT(src, TRAIT_FLOORED) || (buckled && buckled.buckle_lying != NO_BUCKLE_LYING)) if(!silent) - to_chat(src, SPAN_NOTICE("You will now stand up as soon as you are able to.")) + to_chat(src, SPAN_NOTICE("[isxeno(src) ? "We" : "You"] will now stand up as soon as [isxeno(src) ? "we" : "you"] are able to.")) else if(!silent) - to_chat(src, SPAN_NOTICE("You stand up.")) + to_chat(src, SPAN_NOTICE("[isxeno(src) ? "We" : "You"] stand up.")) get_up(instant) // SEND_SIGNAL(src, COMSIG_LIVING_RESTING, new_resting, silent, instant) diff --git a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm index e372b03e68d9..624c9df25f3e 100644 --- a/code/modules/mob/living/carbon/xenomorph/damage_procs.dm +++ b/code/modules/mob/living/carbon/xenomorph/damage_procs.dm @@ -313,4 +313,4 @@ fire.set_on_fire(src) //Deals an extra proc of fire when you're crossing it. 30 damage per tile crossed, plus 15 per Process(). next_move_slowdown = next_move_slowdown + (SLOWDOWN_AMT_GREENFIRE * resist_modifier) if(resist_modifier > 0) - to_chat(src, SPAN_DANGER("You feel pieces of your exoskeleton fusing with the viscous fluid below and tearing off as you struggle to move through the flames!")) + to_chat(src, SPAN_DANGER("We feel pieces of our exoskeleton fusing with the viscous fluid below and tearing off as we struggle to move through the flames!")) diff --git a/code/modules/projectiles/guns/flamer/flamer.dm b/code/modules/projectiles/guns/flamer/flamer.dm index 18fb0bf44cd8..282edcab9fd6 100644 --- a/code/modules/projectiles/guns/flamer/flamer.dm +++ b/code/modules/projectiles/guns/flamer/flamer.dm @@ -621,7 +621,7 @@ burn_damage = 0 if(!burn_damage) - to_chat(M, SPAN_DANGER("You step over the flames.")) + to_chat(M, SPAN_DANGER("[isxeno(M) ? "We" : "You"] step over the flames.")) return M.last_damage_data = weapon_cause_data @@ -632,7 +632,7 @@ if(FIRE_VARIANT_TYPE_B) if(isxeno(M)) var/mob/living/carbon/xenomorph/X = M - X.armor_deflection?(variant_burn_msg=" You feel the flames weakening your exoskeleton!"):(variant_burn_msg=" You feel the flaming chemicals eating into your body!") + X.armor_deflection?(variant_burn_msg=" We feel the flames weakening our exoskeleton!"):(variant_burn_msg=" You feel the flaming chemicals eating into your body!") to_chat(M, SPAN_DANGER("You are burned![variant_burn_msg?"[variant_burn_msg]":""]")) M.updatehealth() diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 38ee9c55b2a8..ee9caa61d7a7 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -1227,9 +1227,10 @@ return if(COOLDOWN_FINISHED(src, shot_cooldown)) visible_message(SPAN_DANGER("[src] is hit by the [P.name] in the [parse_zone(P.def_zone)]!"), \ - SPAN_HIGHDANGER("You are hit by the [P.name] in the [parse_zone(P.def_zone)]!"), null, 4, CHAT_TYPE_TAKING_HIT) + SPAN_HIGHDANGER("[isxeno(src) ? "We" : "You"] are hit by the [P.name] in the [parse_zone(P.def_zone)]!"), null, 4, CHAT_TYPE_TAKING_HIT) COOLDOWN_START(src, shot_cooldown, 1 SECONDS) + last_damage_data = P.weapon_cause_data if(P.firer && ismob(P.firer)) var/mob/firingMob = P.firer From 798ed883fc2d22054f7c89a81d72021185cd2a8c Mon Sep 17 00:00:00 2001 From: cm13-github <128137806+cm13-github@users.noreply.github.com> Date: Sun, 31 Dec 2023 09:07:26 +0000 Subject: [PATCH 75/99] Automatic changelog for PR #5295 [ci skip] --- html/changelogs/AutoChangeLog-pr-5295.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5295.yml diff --git a/html/changelogs/AutoChangeLog-pr-5295.yml b/html/changelogs/AutoChangeLog-pr-5295.yml new file mode 100644 index 000000000000..c8d0b6b0a189 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5295.yml @@ -0,0 +1,4 @@ +author: "InsaneRed" +delete-after: True +changes: + - spellcheck: "Changed hit alerts to We instead of You on the xeno side." \ No newline at end of file From 4d7f5489c5b9a5919d724f66fc43ffc3e0b3335a Mon Sep 17 00:00:00 2001 From: Cthulhu80 <122310258+Cthulhu80@users.noreply.github.com> Date: Sun, 31 Dec 2023 03:59:06 -0800 Subject: [PATCH 76/99] Fixes users getting locked in simulation view / simulation refactor (#5318) # About the pull request Initially I thought I introduced this bug, but it looks like it's existed for a few years. Fixes #4927. Also did some minor refactoring for the simulator. # Explain why it's good for the game bug bad # Changelog :cl: fix: fixes users getting stuck inside of the simulator /:cl: --- code/game/machinery/computer/demo_sim.dm | 4 +--- .../machinery/computer/dropship_weapons.dm | 4 +--- code/game/sim_manager/datums/simulator.dm | 22 ++++++++++++------- tgui/packages/tgui/interfaces/CasSim.tsx | 19 ++++++++++++---- tgui/packages/tgui/interfaces/DemoSim.jsx | 19 ++++++++++++---- 5 files changed, 46 insertions(+), 22 deletions(-) diff --git a/code/game/machinery/computer/demo_sim.dm b/code/game/machinery/computer/demo_sim.dm index 15261cfc8f4b..f633e8f351d4 100644 --- a/code/game/machinery/computer/demo_sim.dm +++ b/code/game/machinery/computer/demo_sim.dm @@ -55,7 +55,6 @@ var/list/data = list() data["configuration"] = configuration - data["looking"] = simulation.looking_at_simulation data["dummy_mode"] = simulation.dummy_mode data["worldtime"] = world.time @@ -104,8 +103,7 @@ /obj/structure/machinery/computer/demo_sim/ui_close(mob/user) . = ..() - if(simulation.looking_at_simulation) - simulation.stop_watching(user) + simulation.stop_watching(user) // DEMOLITIONS TGUI SHIT END \\ diff --git a/code/game/machinery/computer/dropship_weapons.dm b/code/game/machinery/computer/dropship_weapons.dm index 2f9047abc63c..db376c40029c 100644 --- a/code/game/machinery/computer/dropship_weapons.dm +++ b/code/game/machinery/computer/dropship_weapons.dm @@ -152,8 +152,7 @@ /obj/structure/machinery/computer/dropship_weapons/ui_close(mob/user) . = ..() SEND_SIGNAL(src, COMSIG_CAMERA_UNREGISTER_UI, user) - if(simulation.looking_at_simulation) - simulation.stop_watching(user) + simulation.stop_watching(user) /obj/structure/machinery/computer/dropship_weapons/ui_status(mob/user, datum/ui_state/state) . = ..() @@ -239,7 +238,6 @@ .["firemission_selected_laser"] = firemission_envelope.recorded_loc ? firemission_envelope.recorded_loc.get_name() : "NOT SELECTED" .["configuration"] = configuration - .["looking"] = simulation.looking_at_simulation .["dummy_mode"] = simulation.dummy_mode .["worldtime"] = world.time .["nextdetonationtime"] = simulation.detonation_cooldown diff --git a/code/game/sim_manager/datums/simulator.dm b/code/game/sim_manager/datums/simulator.dm index bf99c65ee66f..1f1aedad8153 100644 --- a/code/game/sim_manager/datums/simulator.dm +++ b/code/game/sim_manager/datums/simulator.dm @@ -1,18 +1,21 @@ +#define GRID_CLEARING_SIZE 16 + /datum/simulator // Necessary to prevent multiple users from simulating at the same time. var/static/detonation_cooldown = 0 + var/static/detonation_cooldown_time = 2 MINUTES var/static/sim_reboot_state = TRUE - var/looking_at_simulation = FALSE - var/detonation_cooldown_time = 2 MINUTES var/dummy_mode = CLF_MODE var/obj/structure/machinery/camera/simulation/sim_camera - var/grid_clearing_size = 16 // garbage collection, var/static/list/delete_targets = list() + // list of users currently inside the simulator + var/static/list/users_in_sim = list() + /* unarmoured humans are unnencessary clutter as they tend to explode easily and litter the sim room with body parts, best left out. @@ -29,7 +32,7 @@ /datum/simulator/proc/start_watching(mob/living/user) - if(looking_at_simulation) + if(user in users_in_sim) to_chat(user, SPAN_WARNING("You are already looking at the simulation.")) return if(!sim_camera) @@ -41,13 +44,15 @@ to_chat(user, SPAN_WARNING("You're too busy looking at something else.")) return user.reset_view(sim_camera) - looking_at_simulation = TRUE + users_in_sim += user /datum/simulator/proc/stop_watching(mob/living/user) + if(!(user in users_in_sim)) + return user.unset_interaction() user.reset_view(null) user.cameraFollow = null - looking_at_simulation = FALSE + users_in_sim -= user /datum/simulator/proc/sim_turf_garbage_collection() @@ -67,8 +72,8 @@ y:2 | x: 1 2 3 4 ... 16 y:1 | x: 1 2 3 4 ... 16 */ - for (var/y_pos in 1 to grid_clearing_size)// outer y - for (var/x_pos in 1 to grid_clearing_size) // inner x + for (var/y_pos in 1 to GRID_CLEARING_SIZE)// outer y + for (var/x_pos in 1 to GRID_CLEARING_SIZE) // inner x var/turf/current_grid = locate(sim_grid_start_pos.x + x_pos,sim_grid_start_pos.y + y_pos,sim_grid_start_pos.z) current_grid.empty(/turf/open/floor/engine) @@ -101,3 +106,4 @@ addtimer(CALLBACK(src, PROC_REF(sim_turf_garbage_collection)), 30 SECONDS, TIMER_STOPPABLE) +#undef GRID_CLEARING_SIZE diff --git a/tgui/packages/tgui/interfaces/CasSim.tsx b/tgui/packages/tgui/interfaces/CasSim.tsx index b81e1baafe9c..ba5990bd81ce 100644 --- a/tgui/packages/tgui/interfaces/CasSim.tsx +++ b/tgui/packages/tgui/interfaces/CasSim.tsx @@ -1,4 +1,4 @@ -import { useBackend } from '../backend'; +import { useBackend, useLocalState } from '../backend'; import { Box, Button, Section, ProgressBar, NoticeBox, Stack } from '../components'; interface CasSimData { @@ -12,6 +12,11 @@ interface CasSimData { export const CasSim = (_props, context) => { const { act, data } = useBackend(context); + const [simulationView, setSimulationView] = useLocalState( + context, + 'simulation_view', + false + ); const timeLeft = data.nextdetonationtime - data.worldtime; const timeLeftPct = timeLeft / data.detonation_cooldown; @@ -48,13 +53,16 @@ export const CasSim = (_props, context) => {
- {(!data.looking && ( + {(!simulationView && (