From ac410d69459304f2e51e4c0ce7b5a53604bb9829 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 4 Feb 2025 14:50:38 -0500 Subject: [PATCH 001/512] Fix incorrect usage of to_chat --- code/game/machinery/hologram.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index fbe1a3235357..db4ff0e95e6f 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -357,7 +357,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/ end_call() if (caller_id&&sourcepad) if(caller_id.loc!=sourcepad.loc) - sourcepad.to_chat(caller_id, "Severing connection to distant holopad.") + to_chat(sourcepad.caller_id, "Severing connection to distant holopad.") end_call() audible_message("The connection has been terminated by the caller.") return 1 From 3f9bd762b1ce63a862f824671c5d6968756a3662 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 9 Feb 2025 14:56:23 +1100 Subject: [PATCH 002/512] Adds an industrial centrifuge to replace the honey extractor. --- code/game/machinery/centrifuge.dm | 183 ++++++++++++++++++ code/game/objects/items/__item.dm | 53 +++-- .../circuitboards/machinery/household.dm | 10 + .../imprinter/designs_misc_circuits.dm | 3 + code/modules/hydroponics/grown.dm | 12 ++ .../liquids/materials_liquid_toxins.dm | 2 +- icons/obj/machines/centrifuge.dmi | Bin 0 -> 715 bytes maps/exodus/exodus-2.dmm | 2 +- maps/ministation/ministation-1.dmm | 2 +- maps/tradeship/tradeship-0.dmm | 2 +- mods/content/beekeeping/_beekeeping.dm | 15 ++ mods/content/beekeeping/items.dm | 10 + nebula.dme | 1 + 13 files changed, 272 insertions(+), 23 deletions(-) create mode 100644 code/game/machinery/centrifuge.dm create mode 100644 icons/obj/machines/centrifuge.dmi diff --git a/code/game/machinery/centrifuge.dm b/code/game/machinery/centrifuge.dm new file mode 100644 index 000000000000..661521014abe --- /dev/null +++ b/code/game/machinery/centrifuge.dm @@ -0,0 +1,183 @@ +/datum/storage/hopper/industrial/centrifuge + can_hold = list( + /obj/item/food, + ) + expected_type = /obj/machinery/centrifuge + +/datum/storage/hopper/industrial/centrifuge/proc/should_ingest(mob/user, obj/item/thing) + if(thing.reagents?.total_volume <= 0) + if(user) + to_chat(user, SPAN_WARNING("\The [thing] is empty.")) + return FALSE + return TRUE + +/datum/storage/hopper/industrial/centrifuge/can_be_inserted(obj/item/W, mob/user, stop_messages, click_params) + . = ..() + if(. && !should_ingest(user, W)) + return FALSE + +/obj/machinery/centrifuge + name = "industrial centrifuge" + desc = "A machine used to extract reagents and materials from objects via spinning them at extreme speed." + icon = 'icons/obj/machines/centrifuge.dmi' + icon_state = ICON_STATE_WORLD + anchored = TRUE + density = TRUE + construct_state = /decl/machine_construction/default/panel_closed + uncreated_component_parts = null + storage = /datum/storage/hopper/industrial/centrifuge + base_type = /obj/machinery/centrifuge + stat_immune = 0 + + // Reference to our reagent container. Set to a path to create on init. + var/obj/item/loaded_beaker + + // Stolen from fabricators. + var/sound_id + var/datum/sound_token/sound_token + var/work_sound = 'sound/machines/fabricator_loop.ogg' + +/obj/machinery/centrifuge/mapped + loaded_beaker = /obj/item/chems/glass/beaker/large + +/obj/machinery/centrifuge/Initialize() + . = ..() + if(ispath(loaded_beaker)) + loaded_beaker = new loaded_beaker + +/obj/machinery/centrifuge/get_stored_inventory() + . = ..() + if(LAZYLEN(.)) + LAZYREMOVE(., loaded_beaker) + +/obj/machinery/centrifuge/Destroy() + QDEL_NULL(loaded_beaker) + return ..() + +/obj/machinery/centrifuge/dismantle() + if(loaded_beaker) + loaded_beaker.dropInto(loc) + loaded_beaker = null + return ..() + +/obj/machinery/centrifuge/components_are_accessible(path) + return use_power != POWER_USE_ACTIVE && ..() + +/obj/machinery/centrifuge/cannot_transition_to(state_path, mob/user) + if(use_power == POWER_USE_ACTIVE) + return SPAN_NOTICE("You must wait for \the [src] to finish first!") + return ..() + +/obj/machinery/centrifuge/attackby(obj/item/used_item, mob/user) + + if(use_power == POWER_USE_ACTIVE) + to_chat(user, SPAN_NOTICE("\The [src] is currently spinning, wait until it's finished.")) + return TRUE + + if((. = component_attackby(used_item, user))) + return + + // Load in a new container for products. + if(istype(used_item, /obj/item/chems/glass/beaker)) + if(loaded_beaker) + to_chat(user, SPAN_WARNING("\The [src] already has a beaker loaded.")) + return TRUE + if(user.try_unequip(used_item, src)) + loaded_beaker = used_item + to_chat(user, SPAN_NOTICE("You load \the [loaded_beaker] into \the [src].")) + return TRUE + + // Parent call handles inserting the frame into our contents, + return ..() + +/obj/machinery/centrifuge/attack_hand(mob/user) + + if(use_power == POWER_USE_ACTIVE) + user.visible_message("\The [user] disengages \the [src].") + update_use_power(POWER_USE_IDLE) + return TRUE + + if(use_power == POWER_USE_IDLE) + if(!loaded_beaker || QDELETED(loaded_beaker)) + to_chat(user, SPAN_WARNING("\The [src] has no beaker loaded to receive any products.")) + loaded_beaker = null // just in case + return TRUE + + if(length(get_stored_inventory())) + user.visible_message("\The [user] engages \the [src].") + update_use_power(POWER_USE_ACTIVE) + else + to_chat(user, SPAN_WARNING("\The [src]'s hopper is empty.")) + return TRUE + + if(use_power == POWER_USE_OFF || !operable()) + to_chat(user, SPAN_WARNING("\The [src]'s interface is unresponsive.")) + return TRUE + + return ..() + +/obj/machinery/centrifuge/Process(wait, tick) + ..() + + if(use_power != POWER_USE_ACTIVE) + return + + if(!loaded_beaker) + visible_message("\The [src] stops spinning and flashes a red light.") + update_use_power(POWER_USE_IDLE) + return + + var/list/processing_items = get_stored_inventory() + if(!length(processing_items)) + visible_message("\The [src] stops spinning and flashes a green light.") + update_use_power(POWER_USE_IDLE) + return + + var/obj/item/thing = processing_items[1] + thing.handle_centrifuge_process(src) + if(!QDELETED(thing) && loc) + thing.dropInto(loc) + +/obj/machinery/centrifuge/Initialize() + sound_id = "[work_sound]" + return ..() + +/obj/machinery/centrifuge/Destroy() + QDEL_NULL(sound_token) + return ..() + +/obj/machinery/centrifuge/update_use_power() + . = ..() + if(use_power == POWER_USE_ACTIVE) + if(!sound_token) + sound_token = play_looping_sound(src, sound_id, work_sound, volume = 30) + else + QDEL_NULL(sound_token) + +/obj/machinery/centrifuge/on_update_icon() + icon_state = initial(icon_state) + if(stat & BROKEN) + icon_state = "[icon_state]-broken" + else if(use_power == POWER_USE_OFF || !operable()) + icon_state = "[icon_state]-off" + else if(use_power == POWER_USE_ACTIVE) + icon_state = "[icon_state]-working" + +/obj/machinery/centrifuge/get_quick_interaction_handler(mob/user) + return loaded_beaker ? GET_DECL(/decl/interaction_handler/remove_centrifuge_beaker) : null + +/obj/machinery/centrifuge/get_alt_interactions(var/mob/user) + . = ..() + if(loaded_beaker) + LAZYADD(., /decl/interaction_handler/remove_centrifuge_beaker) + +/decl/interaction_handler/remove_centrifuge_beaker + name = "Remove Beaker" + expected_target_type = /obj/machinery/centrifuge + +/decl/interaction_handler/remove_centrifuge_beaker/invoked(atom/target, mob/user, obj/item/prop) + var/obj/machinery/centrifuge/centrifuge = target + if(centrifuge.loaded_beaker) + centrifuge.loaded_beaker.dropInto(centrifuge.loc) + user.put_in_hands(centrifuge.loaded_beaker) + centrifuge.loaded_beaker = null diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 83baef59cca6..bc8a7f9958f1 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -472,27 +472,11 @@ return ..() && (!strict || loc == user) /obj/item/proc/squash_item(skip_qdel = FALSE) - if(!istype(material) || material.hardness > MAT_VALUE_MALLEABLE) return null - - var/list/leftover_mats = list() - for(var/mat in matter) - var/decl/material/material_decl = GET_DECL(mat) - if(material_decl.hardness <= MAT_VALUE_MALLEABLE) - var/spawn_amount = round(matter[mat] / SHEET_MATERIAL_AMOUNT) - if(spawn_amount > 0) - var/obj/item/stack/material/lump/lump = new(loc, spawn_amount, mat) - LAZYADD(., lump) - continue - leftover_mats[mat] = matter[mat] - - if(length(leftover_mats)) - var/obj/item/debris/scraps/remains = new(loc) - remains.matter = leftover_mats?.Copy() - remains.update_primary_material() - LAZYADD(., remains) - + var/list/results = convert_matter_to_lumps(skip_qdel) + if(length(results)) + . = results if(!skip_qdel) matter = null material = null @@ -1319,3 +1303,34 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. coating_string = FONT_COLORED(coating.get_color(), coating_string) return coating_string return ..() + +// Bespoke proc for handling when a centrifuge smooshes us, only currently used by growns and hive frames. +/obj/item/proc/handle_centrifuge_process(obj/machinery/centrifuge/centrifuge) + SHOULD_CALL_PARENT(TRUE) + return istype(centrifuge) && !QDELETED(centrifuge.loaded_beaker) && istype(centrifuge.loaded_beaker) + +/obj/item/proc/convert_matter_to_lumps(skip_qdel = FALSE) + + var/list/scrap_matter = list() + for(var/mat in matter) + var/mat_amount = matter[mat] + var/obj/item/stack/material/mat_stack = /obj/item/stack/material/lump + var/mat_per_stack = SHEET_MATERIAL_AMOUNT * initial(mat_stack.matter_multiplier) + var/sheet_amount = round(mat_amount / mat_per_stack) + if(sheet_amount) + var/obj/item/stack/material/lump/lump = new(loc, sheet_amount, mat) + LAZYADD(., lump) + mat_amount -= sheet_amount * mat_per_stack + if(mat_amount) + scrap_matter[mat] += mat_amount + + if(length(scrap_matter)) + var/obj/item/debris/scraps/scraps = new(loc) + scraps.matter = scrap_matter.Copy() + scraps.update_primary_material() + LAZYADD(., scraps) + + matter = null + material = null + if(!skip_qdel) + qdel(src) diff --git a/code/game/objects/items/circuitboards/machinery/household.dm b/code/game/objects/items/circuitboards/machinery/household.dm index 5ce6f6ead15f..7035bedba94e 100644 --- a/code/game/objects/items/circuitboards/machinery/household.dm +++ b/code/game/objects/items/circuitboards/machinery/household.dm @@ -46,6 +46,16 @@ /obj/item/stock_parts/circuitboard/cooker/get_buildable_types() return subtypesof(/obj/machinery/cooker) +/obj/item/stock_parts/circuitboard/centrifuge + name = "circuitboard (industrial centrifuge)" + build_path = /obj/machinery/centrifuge + board_type = "machine" + origin_tech = @'{"biotech":2,"engineering":1}' + req_components = list( + /obj/item/stock_parts/manipulator = 2, + /obj/item/stock_parts/matter_bin = 2 + ) + /obj/item/stock_parts/circuitboard/seed_extractor name = "circuitboard (seed extractor)" build_path = /obj/machinery/seed_extractor diff --git a/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm b/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm index 845dfd8ed1c1..48070e2e7e7a 100644 --- a/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm +++ b/code/modules/fabrication/designs/imprinter/designs_misc_circuits.dm @@ -344,6 +344,9 @@ /datum/fabricator_recipe/imprinter/circuit/cooker path = /obj/item/stock_parts/circuitboard/cooker +/datum/fabricator_recipe/imprinter/circuit/centrifuge + path = /obj/item/stock_parts/circuitboard/centrifuge + /datum/fabricator_recipe/imprinter/circuit/seed_extractor path = /obj/item/stock_parts/circuitboard/seed_extractor diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index e453199fe213..bd7b83ef9d64 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -15,6 +15,18 @@ var/seeds_extracted = FALSE var/datum/seed/seed +// This is sort of pointless while food is a valid input on the ChemMaster but maybe +// in the future there will be some more interesting ways to process growns/food. +/obj/item/food/grown/handle_centrifuge_process(obj/machinery/centrifuge/centrifuge) + if(!(. = ..())) + return + if(reagents?.total_volume) + reagents.trans_to_holder(centrifuge.loaded_beaker.reagents, reagents.total_volume) + for(var/obj/item/thing in contents) + thing.dropInto(centrifuge.loc) + for(var/atom/movable/thing in convert_matter_to_lumps()) + thing.dropInto(centrifuge.loc) + /obj/item/food/grown/get_examine_strings(mob/user, distance, infix, suffix) . = ..() if(user && distance <= 1 && seed && user.skill_check(work_skill, SKILL_BASIC)) diff --git a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm index 08eaa22b0c95..ad32f11030a8 100644 --- a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm +++ b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm @@ -65,7 +65,7 @@ name = "spider venom" uid = "liquid_spider_venom" lore_text = "A deadly necrotic toxin produced by giant spiders to disable their prey." - taste_description = "absolutely vile" + taste_description = "vile poison" color = "#91d895" toxicity_targets_organ = BP_LIVER toxicity = 5 diff --git a/icons/obj/machines/centrifuge.dmi b/icons/obj/machines/centrifuge.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6cae1e66cf3235f822686b1eb7c65b7b0e730798 GIT binary patch literal 715 zcmV;+0yO=JP)#Jyup`A0H=$iIls+$+(0taz!dObI+py0004WQchCV=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRL zOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5sXV_ZCq;>iGbOXA7|1u|;!G<_%uR)`QB~i|rDIoZ1{6)rNvs43>%bwp5&3CpxGYmvaP@Nmdl&$0H%4!!ge-{w z00Fm2L_t(oh3%IyQ^GJ9hCdv7j3#JxYA9hOx95A)rq|x(xdQwy2w}%$RNi-cgB!=-ep%n}u3VR3o!j~ivpt-9 zn7EiY8n>r5tSYe>gh`StuAlb{!Zb~zj?Q{72jcn#))okk zsL86|?GU@>4l&m_NmA9z!B{@yomx=J0L$RR^Ss;lU|x-(Is1AG@vI^P#M}A2D%Yt~ zoV*_naNZB4{DU7#S)Ttw0L0PQ#U|(cAP!G85X`B`IX{RC3_pmommTnfuloTr%2=5n z2(y{t158+{ALNdP55%O@4}wh}h!ua`4{6p9Ns{%0;);GyoIC$_ob>~*{ZQw>r1nGY xhhy?Xu@AEU69;`zKh!yvd;;?tXJWJc$shm#002ovPDHLkV1mzJMcM!W literal 0 HcmV?d00001 diff --git a/maps/exodus/exodus-2.dmm b/maps/exodus/exodus-2.dmm index f323c39ad5fd..2c90ba1f9c28 100644 --- a/maps/exodus/exodus-2.dmm +++ b/maps/exodus/exodus-2.dmm @@ -26489,7 +26489,7 @@ pixel_x = -21; pixel_y = -10 }, -/obj/machinery/honey_extractor, +/obj/machinery/centrifuge/mapped, /turf/floor/tiled/steel_grid, /area/exodus/hydroponics/garden) "bev" = ( diff --git a/maps/ministation/ministation-1.dmm b/maps/ministation/ministation-1.dmm index 68b588d80e87..9ab4635ba0c4 100644 --- a/maps/ministation/ministation-1.dmm +++ b/maps/ministation/ministation-1.dmm @@ -6040,7 +6040,7 @@ "zj" = ( /obj/effect/floor_decal/corner/beige/half, /obj/structure/table/glass, -/obj/machinery/honey_extractor, +/obj/machinery/centrifuge/mapped, /turf/floor/tiled, /area/ministation/hydro) "zl" = ( diff --git a/maps/tradeship/tradeship-0.dmm b/maps/tradeship/tradeship-0.dmm index ff571e169d9f..05ce95d98f90 100644 --- a/maps/tradeship/tradeship-0.dmm +++ b/maps/tradeship/tradeship-0.dmm @@ -1562,7 +1562,7 @@ /turf/floor/tiled/steel_grid, /area/ship/trade/loading_bay) "yT" = ( -/obj/machinery/honey_extractor, +/obj/machinery/centrifuge/mapped, /obj/item/seeds/tomatoseed, /turf/floor, /area/ship/trade/aft_port_underside_maint) diff --git a/mods/content/beekeeping/_beekeeping.dm b/mods/content/beekeeping/_beekeeping.dm index cfa1427bbeb1..d026d7d1f576 100644 --- a/mods/content/beekeeping/_beekeeping.dm +++ b/mods/content/beekeeping/_beekeeping.dm @@ -1,2 +1,17 @@ /decl/modpack/beekeeping name = "Beekeeping Content" + +/datum/storage/hopper/industrial/centrifuge/New() + ..() + can_hold |= /obj/item/honey_frame + +// Terrible, will be replaced in beewrite. +/datum/storage/hopper/industrial/centrifuge/should_ingest(mob/user, obj/item/thing) + if(istype(thing, /obj/item/honey_frame)) + var/obj/item/honey_frame/frame = thing + if(frame.honey > 0) + return TRUE + if(user) + to_chat(user, SPAN_WARNING("\The [thing] is empty.")) + return FALSE + return ..() diff --git a/mods/content/beekeeping/items.dm b/mods/content/beekeeping/items.dm index 69a888b28830..58778d369034 100644 --- a/mods/content/beekeeping/items.dm +++ b/mods/content/beekeeping/items.dm @@ -48,6 +48,16 @@ . = ..() overlays += "honeycomb" +// This is crap, will be replaced in beewrite PR. +/obj/item/honey_frame/handle_centrifuge_process(obj/machinery/centrifuge/centrifuge) + if(!(. = ..()) || !honey) + return + centrifuge?.loaded_beaker?.add_to_reagents(/decl/material/liquid/nutriment/honey, honey) + honey = 0 + new /obj/item/honey_frame(centrifuge.loc) + new /obj/item/stack/material/bar(centrifuge.loc, 1, /decl/material/solid/organic/wax) + qdel(src) + /obj/item/bee_pack name = "bee pack" desc = "Contains a queen bee and some worker bees. Everything you'll need to start a hive!" diff --git a/nebula.dme b/nebula.dme index d1296a75367d..2f57515e37d4 100644 --- a/nebula.dme +++ b/nebula.dme @@ -833,6 +833,7 @@ #include "code\game\machinery\buttons.dm" #include "code\game\machinery\CableLayer.dm" #include "code\game\machinery\cell_charger.dm" +#include "code\game\machinery\centrifuge.dm" #include "code\game\machinery\commsrelay.dm" #include "code\game\machinery\constructable_frame.dm" #include "code\game\machinery\cracker.dm" From a5986d79c1f8407665c471dc9e638c24010a0eb4 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 12 Feb 2025 22:02:50 +1100 Subject: [PATCH 003/512] Condensing sign macros/procs to fix OD issue. --- code/__defines/math_physics.dm | 7 +++++-- code/_helpers/game.dm | 6 +++--- code/_helpers/unsorted.dm | 7 ++----- code/_helpers/vector.dm | 26 +++++++++++++------------- code/modules/power/stirling.dm | 6 +++--- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/code/__defines/math_physics.dm b/code/__defines/math_physics.dm index 5560282337ea..4edf99ad88af 100644 --- a/code/__defines/math_physics.dm +++ b/code/__defines/math_physics.dm @@ -34,5 +34,8 @@ #define TICKS_IN_DAY 24*60*60*10 #define TICKS_IN_SECOND 10 -#define SIMPLE_SIGN(X) ((X) < 0 ? -1 : 1) -#define SIGN(X) ((X) ? SIMPLE_SIGN(X) : 0) +#if DM_VERSION < 516 +#define SIGN(X) ( (X) ? ( (X) < 0 ? -1 : 1 ) : 0 ) +#else +#define SIGN(X) sign(X) +#endif diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index fa69c6a25d48..ed24cf936518 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -233,7 +233,7 @@ if(Y1==Y2) return 1 //Light cannot be blocked on same tile else - var/s = SIMPLE_SIGN(Y2-Y1) + var/s = SIGN(Y2-Y1) Y1+=s while(Y1!=Y2) T=locate(X1,Y1,Z) @@ -243,8 +243,8 @@ else var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1)) var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles - var/signX = SIMPLE_SIGN(X2-X1) - var/signY = SIMPLE_SIGN(Y2-Y1) + var/signX = SIGN(X2-X1) + var/signY = SIGN(Y2-Y1) if(X1 abs(dx)) offset_x = Cot(abs(angle)) // otherwise set the offsets - offset_y = sign(dy) + offset_y = SIGN(dy) else - offset_x = sign(dx) + offset_x = SIGN(dx) offset_y = Tan(angle) if(dx < 0) offset_y = -offset_y @@ -119,7 +119,7 @@ return_location() data.pixel_y = loc_y - (data.turf.y * world.icon_size) return data -/* +/* vector_loc is a helper datum for returning precise location data from plot_vector. It includes the turf the object is in as well as the pixel offsets. diff --git a/code/modules/power/stirling.dm b/code/modules/power/stirling.dm index b3e94d0f3e51..4efd393e457b 100644 --- a/code/modules/power/stirling.dm +++ b/code/modules/power/stirling.dm @@ -56,8 +56,8 @@ // Some passive equilibrium between the lines. var/passive_heat_transfer = min(HEAT_TRANSFER*abs(delta_t), line_equilibrium_heat) - air1.add_thermal_energy(-sign(delta_t)*passive_heat_transfer) - air2.add_thermal_energy(sign(delta_t)*passive_heat_transfer) + air1.add_thermal_energy(-(SIGN(delta_t))*passive_heat_transfer) + air2.add_thermal_energy( (SIGN(delta_t))*passive_heat_transfer) if(!istype(inserted_cylinder)) return @@ -102,7 +102,7 @@ var/work_coefficient = working_volume.get_total_moles()*R_IDEAL_GAS_EQUATION*log(1.5) // Direction of heat flow, 1 for air1 -> air 2, -1 for air2 -> air 1 - var/heat_dir = sign(delta_t) + var/heat_dir = SIGN(delta_t) // We multiply by the cycle frequency to get reasonable values for power generation. // Energy is still conserved, but the efficiency of the engine is slightly overestimated. From f1ad600d21752846cc0dae8ab17541de0ef48b9f Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 26 Jan 2025 14:05:25 +1100 Subject: [PATCH 004/512] Converting auras, cloaking and stasis into mob modifiers, something like the HUD effect markers on Polaris. HUD datum no longer keeps a hard mob reference. Removing debugging modifier. Renaming obj/var for mob modifiers HUD holder Narrows the mob modifier icons. --- code/__defines/hud.dm | 1 + code/__defines/misc.dm | 11 + code/__defines/mob_status.dm | 4 +- code/__defines/mobs.dm | 16 +- code/__defines/xenoarcheaology.dm | 13 -- code/_macros.dm | 4 +- .../hud/hud_elements/hud_auxilliary.dm | 3 + code/_onclick/hud/hud_types/_hud.dm | 212 ++++++++++++------ code/_onclick/hud/hud_types/robot.dm | 81 ++++--- .../hud/screen/screen_mob_modifier.dm | 155 +++++++++++++ code/_onclick/item_attack.dm | 3 +- code/datums/cinematic.dm | 4 +- code/datums/wires/camera.dm | 2 +- code/game/atoms.dm | 2 +- code/game/atoms_movable.dm | 2 + .../gamemodes/endgame/ftl_jump/ftl_jump.dm | 4 +- code/game/machinery/Sleeper.dm | 5 +- .../stock_parts/_stock_parts.dm | 6 +- .../stock_parts/power/battery.dm | 4 +- .../stock_parts/power/terminal.dm | 4 +- code/game/machinery/camera/camera.dm | 6 +- code/game/machinery/cryopod.dm | 5 +- .../machinery/doors/airlock_interactions.dm | 4 +- code/game/machinery/jukebox.dm | 4 +- code/game/objects/auras/aura.dm | 58 ----- .../auras/personal_shields/personal_shield.dm | 34 --- code/game/objects/auras/radiant_aura.dm | 20 -- code/game/objects/auras/regenerating_aura.dm | 121 ---------- code/game/objects/items/cryobag.dm | 7 +- .../objects/items/devices/personal_shield.dm | 51 +++-- code/game/objects/items/robot/robot_items.dm | 6 +- code/game/objects/items/weapons/stunbaton.dm | 6 +- code/game/objects/structures/mineral_bath.dm | 37 ++- code/game/objects/structures/signs.dm | 2 +- code/modules/abstract/_abstract.dm | 24 +- code/modules/abstract/follower.dm | 18 ++ code/modules/admin/admin.dm | 4 +- code/modules/admin/topic.dm | 2 +- code/modules/admin/view_variables/helpers.dm | 4 +- code/modules/admin/view_variables/topic.dm | 60 +++-- code/modules/augment/passive/nanoaura.dm | 64 ++---- code/modules/client/ui_styles/_ui_style.dm | 3 +- .../client/ui_styles/_ui_style_states.dm | 7 +- .../client/ui_styles/ui_style_subtypes.dm | 18 +- code/modules/clothing/_clothing.dm | 2 +- .../modules/clothing/_clothing_accessories.dm | 4 +- .../gloves/jewelry/rings/ring_aura.dm | 29 --- .../gloves/jewelry/rings/ring_effect.dm | 18 ++ code/modules/clothing/head/fated_key.dm | 2 +- .../modules/clothing/sensors/vitals_sensor.dm | 2 +- .../spacesuits/rig/modules/infiltration.dm | 4 +- code/modules/clothing/spacesuits/rig/rig.dm | 2 +- .../modules/clothing/spacesuits/spacesuits.dm | 4 +- code/modules/clothing/webbing/holster.dm | 2 +- code/modules/events/ailments.dm | 2 +- code/modules/hydroponics/seed_mobs.dm | 2 +- .../implants/implant_types/adrenaline.dm | 6 +- code/modules/item_effects/item_effect_aura.dm | 28 --- .../modules/item_effects/item_effect_debug.dm | 2 +- .../item_effects/item_effect_modifier.dm | 27 +++ code/modules/mechs/equipment/combat.dm | 185 ++------------- code/modules/mechs/mech_damage_immunity.dm | 2 +- code/modules/mob/death.dm | 2 +- code/modules/mob/grab/grab_object.dm | 2 +- code/modules/mob/living/bot/bot.dm | 6 +- code/modules/mob/living/bot/secbot.dm | 4 +- code/modules/mob/living/human/human.dm | 1 - .../mob/living/human/human_attackhand.dm | 2 +- code/modules/mob/living/human/human_grabs.dm | 2 +- .../modules/mob/living/human/human_helpers.dm | 66 ------ code/modules/mob/living/human/life.dm | 6 +- code/modules/mob/living/human/update_icons.dm | 2 +- code/modules/mob/living/life.dm | 11 +- code/modules/mob/living/living.dm | 54 +---- code/modules/mob/living/living_appearance.dm | 32 ++- code/modules/mob/living/living_defense.dm | 36 +-- code/modules/mob/living/living_defines.dm | 3 - code/modules/mob/living/living_status.dm | 19 +- code/modules/mob/living/silicon/login.dm | 2 +- .../mob/living/silicon/pai/software.dm | 7 +- code/modules/mob/living/silicon/robot/life.dm | 4 +- .../mob/living/silicon/robot/robot_items.dm | 4 +- code/modules/mob/living/stasis.dm | 23 -- code/modules/mob/mob.dm | 4 + code/modules/mob/mob_defines.dm | 2 +- code/modules/mob/mob_status.dm | 21 +- code/modules/mob/transform_procs.dm | 4 +- code/modules/mob_modifiers/_modifiers.dm | 89 ++++++++ .../definitions/modifiers_cloaked.dm | 17 ++ .../definitions/modifiers_light.dm | 39 ++++ .../definitions/modifiers_mech_shields.dm | 166 ++++++++++++++ .../definitions/modifiers_nanoswarm.dm | 34 +++ .../definitions/modifiers_object.dm | 19 ++ .../definitions/modifiers_prone.dm | 10 + .../definitions/modifiers_regeneration.dm | 123 ++++++++++ .../definitions/modifiers_restrained.dm | 9 + .../definitions/modifiers_shield.dm | 45 ++++ .../definitions/modifiers_stasis.dm | 26 +++ code/modules/mob_modifiers/modifiers_datum.dm | 75 +++++++ .../mob_modifiers/modifiers_helpers.dm | 78 +++++++ .../modular_computers/hardware/lan_port.dm | 2 +- code/modules/nano/nanoui.dm | 4 +- .../organs/external/_external_icons.dm | 4 +- code/modules/organs/external/head.dm | 2 +- code/modules/organs/internal/brain.dm | 2 +- code/modules/organs/internal/heart.dm | 4 +- code/modules/projectiles/projectile.dm | 2 +- code/modules/reagents/chems/chems_drinks.dm | 2 +- code/modules/species/species.dm | 18 -- .../{_status.dm => _status_condition.dm} | 20 +- .../status_conditions/_status_markers.dm | 19 +- .../{ => definitions}/status_dizzy.dm | 0 .../{ => definitions}/status_jittery.dm | 0 .../{ => definitions}/status_paralyzed.dm | 0 .../{ => definitions}/status_sleeping.dm | 0 .../{ => definitions}/status_stunned.dm | 0 .../{ => definitions}/status_weakened.dm | 0 code/modules/xenoarcheaology/_xenoarch.dm | 12 + .../artifacts/effects/_effect.dm | 28 +-- .../artifacts/effects/badfeeling.dm | 2 +- .../artifacts/effects/cellcharge.dm | 2 +- .../artifacts/effects/celldrain.dm | 2 +- .../artifacts/effects/dnaswitch.dm | 4 +- .../xenoarcheaology/artifacts/effects/emp.dm | 4 +- .../artifacts/effects/forcefield.dm | 2 +- .../artifacts/effects/gas_generation.dm | 4 +- .../artifacts/effects/goodfeeling.dm | 2 +- .../xenoarcheaology/artifacts/effects/heal.dm | 2 +- .../xenoarcheaology/artifacts/effects/hurt.dm | 2 +- .../artifacts/effects/radiate.dm | 2 +- .../artifacts/effects/roboheal.dm | 2 +- .../artifacts/effects/robohurt.dm | 2 +- .../artifacts/effects/sleepy.dm | 6 +- .../xenoarcheaology/artifacts/effects/stun.dm | 2 +- .../artifacts/effects/teleport.dm | 2 +- .../artifacts/effects/temperature.dm | 8 +- .../machinery/artifact_harvester.dm | 2 +- .../tools/ano_device_battery.dm | 6 +- .../mob/screen/styles/midnight/modifiers.dmi | Bin 0 -> 372 bytes .../screen/styles/minimalist/modifiers.dmi | Bin 0 -> 336 bytes icons/mob/screen/styles/modifiers.dmi | Bin 0 -> 233 bytes icons/mob/screen/styles/old/modifiers.dmi | Bin 0 -> 360 bytes .../screen/styles/old_noborder/modifiers.dmi | Bin 0 -> 233 bytes icons/mob/screen/styles/orange/modifiers.dmi | Bin 0 -> 425 bytes .../screen/styles/underworld/modifiers.dmi | Bin 0 -> 417 bytes icons/mob/screen/styles/white/modifiers.dmi | Bin 0 -> 312 bytes icons/obj/decals.dmi | Bin 568 -> 0 bytes icons/screen/mob_modifiers.dmi | Bin 0 -> 1725 bytes .../system/psionics/faculties/coercion.dm | 2 +- .../cult/mobs/constructs/constructs.dm | 2 +- mods/mobs/borers/mob/borer/borer.dm | 4 +- .../drakes/drake_abilities_friendly.dm | 6 +- mods/species/drakes/drake_modifiers.dm | 77 +++---- mods/species/drakes/icons/sifsap.dmi | Bin 0 -> 619 bytes mods/species/serpentid/datum/species.dm | 2 +- .../serpentid/mobs/bodyparts_serpentid.dm | 10 +- .../patches/fantasy/drake_fantasy.dm | 4 +- nebula.dme | 38 ++-- 158 files changed, 1647 insertions(+), 1148 deletions(-) create mode 100644 code/_onclick/hud/screen/screen_mob_modifier.dm delete mode 100644 code/game/objects/auras/aura.dm delete mode 100644 code/game/objects/auras/personal_shields/personal_shield.dm delete mode 100644 code/game/objects/auras/radiant_aura.dm delete mode 100644 code/game/objects/auras/regenerating_aura.dm create mode 100644 code/modules/abstract/follower.dm delete mode 100644 code/modules/clothing/gloves/jewelry/rings/ring_aura.dm create mode 100644 code/modules/clothing/gloves/jewelry/rings/ring_effect.dm delete mode 100644 code/modules/item_effects/item_effect_aura.dm create mode 100644 code/modules/item_effects/item_effect_modifier.dm create mode 100644 code/modules/mob_modifiers/_modifiers.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_cloaked.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_light.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_mech_shields.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_nanoswarm.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_object.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_prone.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_regeneration.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_restrained.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_shield.dm create mode 100644 code/modules/mob_modifiers/definitions/modifiers_stasis.dm create mode 100644 code/modules/mob_modifiers/modifiers_datum.dm create mode 100644 code/modules/mob_modifiers/modifiers_helpers.dm rename code/modules/status_conditions/{_status.dm => _status_condition.dm} (67%) rename code/modules/status_conditions/{ => definitions}/status_dizzy.dm (100%) rename code/modules/status_conditions/{ => definitions}/status_jittery.dm (100%) rename code/modules/status_conditions/{ => definitions}/status_paralyzed.dm (100%) rename code/modules/status_conditions/{ => definitions}/status_sleeping.dm (100%) rename code/modules/status_conditions/{ => definitions}/status_stunned.dm (100%) rename code/modules/status_conditions/{ => definitions}/status_weakened.dm (100%) create mode 100644 code/modules/xenoarcheaology/_xenoarch.dm create mode 100644 icons/mob/screen/styles/midnight/modifiers.dmi create mode 100644 icons/mob/screen/styles/minimalist/modifiers.dmi create mode 100644 icons/mob/screen/styles/modifiers.dmi create mode 100644 icons/mob/screen/styles/old/modifiers.dmi create mode 100644 icons/mob/screen/styles/old_noborder/modifiers.dmi create mode 100644 icons/mob/screen/styles/orange/modifiers.dmi create mode 100644 icons/mob/screen/styles/underworld/modifiers.dmi create mode 100644 icons/mob/screen/styles/white/modifiers.dmi delete mode 100644 icons/obj/decals.dmi create mode 100644 icons/screen/mob_modifiers.dmi create mode 100644 mods/species/drakes/icons/sifsap.dmi diff --git a/code/__defines/hud.dm b/code/__defines/hud.dm index 3353b89d20ae..edd1ff5ea4d5 100644 --- a/code/__defines/hud.dm +++ b/code/__defines/hud.dm @@ -24,6 +24,7 @@ #define HUD_FIRE /decl/hud_element/fire #define HUD_CHARGE /decl/hud_element/charge #define HUD_ROBOT_MODULE /decl/hud_element/module_selection +#define HUD_MODIFIERS /decl/hud_element/modifiers #define GET_HUD_ALERT(M, A) ((istype(M?.hud_used, /datum/hud) && (A in M.hud_used.alerts)) ? M.hud_used.alerts[A] : 0) #define CLEAR_HUD_ALERTS(M) if(istype(M?.hud_used, /datum/hud) && M.hud_used.alerts) { M.hud_used.alerts = null; } diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 85583c6cedf8..b9c5a60b173e 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -390,3 +390,14 @@ // Default UI style applied to client prefs. #define DEFAULT_UI_STYLE /decl/ui_style/midnight +// Indicates a modifier will never expire. +#define MOB_MODIFIER_INDEFINITE (-1) + +// Indicators for attack checking proc. +#define MM_ATTACK_TYPE_WEAPON 0 +#define MM_ATTACK_TYPE_THROWN 1 +#define MM_ATTACK_TYPE_PROJECTILE 2 + +#define MM_ATTACK_RESULT_NONE 0 +#define MM_ATTACK_RESULT_DEFLECTED BITFLAG(0) +#define MM_ATTACK_RESULT_BLOCKED BITFLAG(1) diff --git a/code/__defines/mob_status.dm b/code/__defines/mob_status.dm index 42bc8854a7a4..238ac560411c 100644 --- a/code/__defines/mob_status.dm +++ b/code/__defines/mob_status.dm @@ -1,5 +1,5 @@ #define PENDING_STATUS(MOB, COND) (LAZYACCESS(MOB.pending_status_counters, COND) || LAZYACCESS(MOB.status_counters, COND)) #define GET_STATUS(MOB, COND) (LAZYACCESS(MOB.status_counters, COND)) #define HAS_STATUS(MOB, COND) (GET_STATUS(MOB, COND) > 0) -#define ADJ_STATUS(MOB, COND, AMT) (MOB.set_status(COND, PENDING_STATUS(MOB, COND) + AMT)) -#define SET_STATUS_MAX(MOB, COND, AMT) (MOB.set_status(COND, max(PENDING_STATUS(MOB, COND), AMT))) \ No newline at end of file +#define ADJ_STATUS(MOB, COND, AMT) (MOB.set_status_condition(COND, PENDING_STATUS(MOB, COND) + AMT)) +#define SET_STATUS_MAX(MOB, COND, AMT) (MOB.set_status_condition(COND, max(PENDING_STATUS(MOB, COND), AMT))) \ No newline at end of file diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 00633e438b2f..3ea4d3cde8da 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -3,7 +3,7 @@ #define UNCONSCIOUS 1 #define DEAD 2 -// Bitflags defining which status effects could be or are inflicted on a mob. +// Bitflags defining which status conditions could be or are inflicted on a mob. #define CANSTUN BITFLAG(0) #define CANWEAKEN BITFLAG(1) #define CANPARALYSE BITFLAG(2) @@ -278,17 +278,6 @@ #define SURGERY_RETRACTED 2 #define SURGERY_ENCASED 3 -#define STASIS_MISC "misc" -#define STASIS_CRYOBAG "cryobag" -#define STASIS_COLD "cold" - -#define AURA_CANCEL 1 -#define AURA_FALSE 2 -#define AURA_TYPE_BULLET "Bullet" -#define AURA_TYPE_WEAPON "Weapon" -#define AURA_TYPE_THROWN "Thrown" -#define AURA_TYPE_LIFE "Life" - #define SPECIES_BLOOD_DEFAULT 560 #define SLIME_EVOLUTION_THRESHOLD 15 @@ -387,7 +376,8 @@ var/global/list/dexterity_levels = list( #define HO_HANDCUFF_LAYER 25 #define HO_INHAND_LAYER 26 #define HO_FIRE_LAYER 27 //If you're on fire -#define TOTAL_OVER_LAYERS 27 +#define HO_EFFECT_LAYER 28 +#define TOTAL_OVER_LAYERS 28 ////////////////////////////////// // Underlay defines; vestigal implementation currently. diff --git a/code/__defines/xenoarcheaology.dm b/code/__defines/xenoarcheaology.dm index 52667268b7d6..488ff4790670 100644 --- a/code/__defines/xenoarcheaology.dm +++ b/code/__defines/xenoarcheaology.dm @@ -1,16 +1,3 @@ #define XENOFIND_APPLY_PREFIX BITFLAG(0) #define XENOFIND_APPLY_DECOR BITFLAG(1) #define XENOFIND_REPLACE_ICON BITFLAG(2) - -#define EFFECT_TOUCH 0 -#define EFFECT_AURA 1 -#define EFFECT_PULSE 2 -#define MAX_EFFECT 2 - -#define EFFECT_UNKNOWN 0 -#define EFFECT_ENERGY 1 -#define EFFECT_PSIONIC 2 -#define EFFECT_ELECTRO 3 -#define EFFECT_PARTICLE 4 -#define EFFECT_ORGANIC 5 -#define EFFECT_SYNTH 6 \ No newline at end of file diff --git a/code/_macros.dm b/code/_macros.dm index 11e6c146b5d5..fba1b139fae3 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -147,9 +147,9 @@ #define JOINTEXT(X) jointext(X, null) -#define SPAN_STYLE(S, X) "[X]" +#define SPAN_STYLE(S, X) "" + X + "" +#define SPAN_CLASS(C, X) "" + X + "" -#define SPAN_CLASS(C, X) "[X]" #define SPAN_ITALIC(X) SPAN_CLASS("italic", X) #define SPAN_BOLD(X) SPAN_CLASS("bold", X) #define SPAN_NOTICE(X) SPAN_CLASS("notice", X) diff --git a/code/_onclick/hud/hud_elements/hud_auxilliary.dm b/code/_onclick/hud/hud_elements/hud_auxilliary.dm index 42ae7a89178c..bcf8503f5a4b 100644 --- a/code/_onclick/hud/hud_elements/hud_auxilliary.dm +++ b/code/_onclick/hud/hud_elements/hud_auxilliary.dm @@ -25,6 +25,9 @@ /decl/hud_element/attack elem_type = /obj/screen/default_attack_selector +/decl/hud_element/modifiers + elem_type = /obj/screen/mob_modifiers + /decl/hud_element/stamina elem_type = /obj/screen/stamina elem_updates_in_life = TRUE diff --git a/code/_onclick/hud/hud_types/_hud.dm b/code/_onclick/hud/hud_types/_hud.dm index d0a95fe197f5..f0d9c880d61d 100644 --- a/code/_onclick/hud/hud_types/_hud.dm +++ b/code/_onclick/hud/hud_types/_hud.dm @@ -29,7 +29,7 @@ /datum/hud /// A reference to our owning mob. - var/mob/mymob + VAR_PRIVATE/weakref/owner /// Used for the HUD toggle (F12) VAR_PRIVATE/hud_shown = TRUE // Used for showing or hiding the equipment buttons on the left. @@ -79,7 +79,8 @@ /decl/hud_element/oxygen, /decl/hud_element/toxins, /decl/hud_element/bodytemp, - /decl/hud_element/pressure + /decl/hud_element/pressure, + /decl/hud_element/modifiers ) /// /decl/hud_element types to be inserted into hud_elements_to_create during init. VAR_PROTECTED/list/additional_hud_elements @@ -100,9 +101,10 @@ VAR_PRIVATE/obj/screen/gun/radio/gun_radio_use_toggle -/datum/hud/New(mob/owner) - mymob = owner - instantiate() +/datum/hud/New(mob/_owner) + if(istype(_owner)) + owner = weakref(_owner) + instantiate(_owner) ..() /datum/hud/Destroy() @@ -117,10 +119,11 @@ LAZYCLEARLIST(hud_elem_decl_to_object) QDEL_NULL_LIST(all_hud_elements) - if(mymob) + var/mob/mymob = owner?.resolve() + if(istype(mymob)) if(mymob.hud_used == src) mymob.hud_used = null - mymob = null + QDEL_NULL(owner) /datum/hud/proc/is_hud_shown() return hud_shown @@ -133,8 +136,10 @@ return elem?.update_icon() || FALSE /datum/hud/proc/refresh_hud_icons() - for(var/obj/screen/elem in mymob?.client?.screen) - elem.queue_icon_update() + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) + for(var/obj/screen/elem in mymob.client.screen) + elem.queue_icon_update() /datum/hud/proc/is_inventory_shown() return inventory_shown @@ -142,29 +147,39 @@ /datum/hud/proc/hide_inventory() inventory_shown = FALSE if(LAZYLEN(hud_elements_hidable)) - mymob?.client?.screen -= hud_elements_hidable + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) + mymob.client.screen -= hud_elements_hidable hidden_inventory_update() persistent_inventory_update() /datum/hud/proc/show_inventory() inventory_shown = TRUE if(LAZYLEN(hud_elements_hidable)) - mymob?.client?.screen += hud_elements_hidable + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) + mymob.client.screen += hud_elements_hidable hidden_inventory_update() persistent_inventory_update() /datum/hud/proc/hidden_inventory_update() - var/decl/species/species = mymob?.get_species() + var/mob/mymob = owner?.resolve() + var/decl/species/species = istype(mymob) && mymob.get_species() if(istype(species?.species_hud)) refresh_inventory_slots(species.species_hud.hidden_slots, (inventory_shown && hud_shown)) /datum/hud/proc/persistent_inventory_update() - var/decl/species/species = mymob?.get_species() + var/mob/mymob = owner?.resolve() + var/decl/species/species = istype(mymob) && mymob.get_species() if(istype(species?.species_hud)) refresh_inventory_slots(species.species_hud.persistent_slots, hud_shown) /datum/hud/proc/refresh_inventory_slots(var/list/checking_slots, var/show_hud) + var/mob/mymob = owner?.resolve() + if(!istype(mymob)) + return FALSE + for(var/slot in checking_slots) var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(slot) @@ -183,18 +198,36 @@ else inv_slot.show_slot() -/datum/hud/proc/instantiate() - if(ismob(mymob) && mymob.client) - finalize_instantiation() + return TRUE + +/datum/hud/proc/instantiate(mob/_owner) + if(ismob(_owner) && _owner.client) + finalize_instantiation(_owner) refresh_hud_icons() return TRUE return FALSE /datum/hud/proc/handle_life_hud_update() + + var/mob/mymob = owner?.resolve() + if(!istype(mymob)) + return FALSE + + if(mymob.buckled || mymob.restrained()) + mymob.add_mob_modifier(/decl/mob_modifier/restrained, source = mymob) + else + mymob.remove_mob_modifier(/decl/mob_modifier/restrained, source = mymob) + + if(mymob.current_posture?.prone) + mymob.add_mob_modifier(/decl/mob_modifier/prone, source = mymob) + else + mymob.remove_mob_modifier(/decl/mob_modifier/prone, source = mymob) + for(var/obj/screen/elem as anything in hud_elements_update_in_life) elem.update_icon() + return TRUE -/datum/hud/proc/finalize_instantiation() +/datum/hud/proc/finalize_instantiation(mob/_owner) SHOULD_CALL_PARENT(TRUE) @@ -215,11 +248,11 @@ //Handle the gun settings buttons if(!gun_mode_toggle && gun_mode_toggle_type) - gun_mode_toggle = new gun_mode_toggle_type(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + gun_mode_toggle = new gun_mode_toggle_type(null, _owner, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) LAZYADD(hud_elements_auxilliary, gun_mode_toggle) - gun_item_use_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) - gun_move_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) - gun_radio_use_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + gun_item_use_toggle = new(null, _owner, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + gun_move_toggle = new(null, _owner, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + gun_radio_use_toggle = new(null, _owner, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) build_inventory_ui() build_hands_ui() @@ -239,16 +272,17 @@ all_hud_elements |= hud_elements_auxilliary UNSETEMPTY(all_hud_elements) - if(mymob.client) - mymob.client.screen = list() + if(_owner.client) + _owner.client.screen = list() if(LAZYLEN(all_hud_elements)) - mymob.client.screen |= all_hud_elements + _owner.client.screen |= all_hud_elements hide_inventory() /datum/hud/proc/get_ui_style_data() RETURN_TYPE(/decl/ui_style) - . = GET_DECL(mymob?.client?.prefs?.UI_style) || GET_DECL(default_ui_style) + var/mob/mymob = owner?.resolve() + . = (istype(mymob) && GET_DECL(mymob.client?.prefs?.UI_style)) || GET_DECL(default_ui_style) if(!.) var/list/available_styles = get_ui_styles() if(length(available_styles)) @@ -258,13 +292,19 @@ var/decl/ui_style/ui_style = get_ui_style_data() if(!ui_style?.use_ui_color) return COLOR_WHITE - return mymob?.client?.prefs?.UI_style_color || COLOR_WHITE + var/mob/mymob = owner?.resolve() + return (istype(mymob) && mymob.client?.prefs?.UI_style_color) || COLOR_WHITE /datum/hud/proc/get_ui_alpha() - return mymob?.client?.prefs?.UI_style_alpha || 255 + var/mob/mymob = owner?.resolve() + return (istype(mymob) && mymob.client?.prefs?.UI_style_alpha) || 255 /datum/hud/proc/rebuild_hands() + var/mob/mymob = owner?.resolve() + if(!istype(mymob)) + return FALSE + var/decl/ui_style/ui_style = get_ui_style_data() var/ui_color = get_ui_color() var/ui_alpha = get_ui_alpha() @@ -355,8 +395,14 @@ if(mymob.client) mymob.client.screen |= swap_elem + return TRUE + /datum/hud/proc/build_inventory_ui() + var/mob/mymob = owner?.resolve() + if(!istype(mymob)) + return FALSE + var/decl/ui_style/ui_style = get_ui_style_data() var/ui_color = get_ui_color() var/ui_alpha = get_ui_alpha() @@ -392,11 +438,17 @@ if(has_hidden_gear) hud_elements_auxilliary += new /obj/screen/toggle(null, mymob, ui_style, ui_color, ui_alpha, HUD_INVENTORY) + return TRUE + /datum/hud/proc/build_hands_ui() + var/mob/mymob = owner?.resolve() + if(!istype(mymob)) + return FALSE + var/list/held_slots = mymob.get_held_item_slots() if(length(held_slots) <= 0) - return + return FALSE var/decl/ui_style/ui_style = get_ui_style_data() var/ui_color = get_ui_color() @@ -414,6 +466,7 @@ // Actual hand elems. rebuild_hands() + return TRUE /datum/hud/proc/toggle_show_inventory() if(inventory_shown) @@ -427,57 +480,63 @@ return action_buttons_hidden /datum/hud/proc/toggle_minimize(var/full) - if(hud_shown) - hud_shown = FALSE - if(hud_elements_auxilliary) - mymob?.client?.screen -= hud_elements_auxilliary - if(hud_elements_hidable) - mymob?.client?.screen -= hud_elements_hidable - if(hud_elements_hotkeys) - mymob?.client?.screen -= hud_elements_hotkeys - if(!full) - if(LAZYLEN(hud_elements_hands)) - mymob?.client?.screen += hud_elements_hands // we want the hands to be visible - if(LAZYLEN(hud_elements_swap)) - mymob?.client?.screen += hud_elements_swap // we want the hands swap thingy to be visible - else - hud_shown = TRUE - if(LAZYLEN(hud_elements_auxilliary)) - mymob?.client?.screen |= hud_elements_auxilliary - if(LAZYLEN(hud_elements_hidable) && inventory_shown) - mymob?.client?.screen |= hud_elements_hidable - if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden) - mymob?.client?.screen |= hud_elements_hotkeys + hud_shown = !hud_shown + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) + if(hud_shown) + if(LAZYLEN(hud_elements_auxilliary)) + mymob.client.screen |= hud_elements_auxilliary + if(LAZYLEN(hud_elements_hidable) && inventory_shown) + mymob.client.screen |= hud_elements_hidable + if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden) + mymob.client.screen |= hud_elements_hotkeys + else + if(hud_elements_auxilliary) + mymob.client.screen -= hud_elements_auxilliary + if(hud_elements_hidable) + mymob.client.screen -= hud_elements_hidable + if(hud_elements_hotkeys) + mymob.client.screen -= hud_elements_hotkeys + if(!full) + if(LAZYLEN(hud_elements_hands)) + mymob.client.screen += hud_elements_hands // we want the hands to be visible + if(LAZYLEN(hud_elements_swap)) + mymob.client.screen += hud_elements_swap // we want the hands swap thingy to be visible + hidden_inventory_update() persistent_inventory_update() + return TRUE /datum/hud/proc/toggle_zoom_hud() - if(hud_shown) - hud_shown = FALSE - if(LAZYLEN(hud_elements_auxilliary)) - mymob?.client?.screen -= hud_elements_auxilliary - if(LAZYLEN(hud_elements_hidable)) - mymob?.client?.screen -= hud_elements_hidable - if(LAZYLEN(hud_elements_hotkeys)) - mymob?.client?.screen -= hud_elements_hotkeys - else - hud_shown = TRUE - if(LAZYLEN(hud_elements_auxilliary)) - mymob?.client?.screen += hud_elements_auxilliary - if(LAZYLEN(hud_elements_hidable) && inventory_shown) - mymob?.client?.screen += hud_elements_hidable - if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden) - mymob?.client?.screen += hud_elements_hotkeys + hud_shown = !hud_shown + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) + if(hud_shown) + if(LAZYLEN(hud_elements_auxilliary)) + mymob.client.screen += hud_elements_auxilliary + if(LAZYLEN(hud_elements_hidable) && inventory_shown) + mymob.client.screen += hud_elements_hidable + if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden) + mymob.client.screen += hud_elements_hotkeys + else + if(LAZYLEN(hud_elements_auxilliary)) + mymob.client.screen -= hud_elements_auxilliary + if(LAZYLEN(hud_elements_hidable)) + mymob.client.screen -= hud_elements_hidable + if(LAZYLEN(hud_elements_hotkeys)) + mymob.client.screen -= hud_elements_hotkeys + hidden_inventory_update() persistent_inventory_update() /datum/hud/proc/toggle_hotkeys() - if(hotkey_ui_hidden) - mymob?.client?.screen += hud_elements_hotkeys - hotkey_ui_hidden = 0 - else - mymob?.client?.screen -= hud_elements_hotkeys - hotkey_ui_hidden = TRUE + hotkey_ui_hidden = !hotkey_ui_hidden + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) + if(hotkey_ui_hidden) + mymob.client.screen -= hud_elements_hotkeys + else + mymob.client.screen += hud_elements_hotkeys /mob/verb/toggle_hotkey_verbs() set category = "OOC" @@ -537,13 +596,15 @@ // This can runtime if someone manages to throw a gun out of their hand before the proc is called. if(!gun_item_use_toggle) return TRUE - if(mymob?.client) + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) mymob.client.screen |= gun_item_use_toggle mymob.client.screen |= gun_move_toggle mymob.client.screen |= gun_radio_use_toggle /datum/hud/proc/remove_gun_icons() - if(mymob?.client) + var/mob/mymob = owner?.resolve() + if(istype(mymob) && mymob.client) mymob.client.screen -= gun_item_use_toggle mymob.client.screen -= gun_move_toggle mymob.client.screen -= gun_radio_use_toggle @@ -574,8 +635,11 @@ gun_radio_use_toggle.update_icon() /datum/hud/proc/create_and_register_element(decl/hud_element/ui_elem, decl/ui_style/ui_style, ui_color, ui_alpha) - if(!istype(ui_elem) || !ui_elem.elem_type) + + var/mob/mymob = owner?.resolve() + if(!istype(mymob) || !istype(ui_elem) || !ui_elem.elem_type) return FALSE + var/obj/screen/elem = new ui_elem.elem_type(null, mymob, ui_style, ui_color, ui_alpha, ui_elem.elem_reference_type) if(ui_elem.elem_is_hotkey) LAZYDISTINCTADD(hud_elements_hotkeys, elem) diff --git a/code/_onclick/hud/hud_types/robot.dm b/code/_onclick/hud/hud_types/robot.dm index 9dd085ffe9c3..051484a4acd4 100644 --- a/code/_onclick/hud/hud_types/robot.dm +++ b/code/_onclick/hud/hud_types/robot.dm @@ -11,50 +11,47 @@ return 255 // TODO: Convert robots to use inventory slots. -/datum/hud/robot/finalize_instantiation() - var/mob/living/silicon/robot/R = mymob - if(!istype(R)) +/datum/hud/robot/finalize_instantiation(mob/_owner) + var/mob/living/silicon/robot/robit = _owner + if(!istype(robit)) return ..() - R.inv1 = new(null, mymob) - R.inv2 = new(null, mymob) - R.inv3 = new(null, mymob) + robit.inv1 = new(null, _owner) + robit.inv2 = new(null, _owner) + robit.inv3 = new(null, _owner) LAZYINITLIST(hud_elements_auxilliary) - hud_elements_auxilliary += R.inv1 - hud_elements_auxilliary += R.inv2 - hud_elements_auxilliary += R.inv3 + hud_elements_auxilliary += robit.inv1 + hud_elements_auxilliary += robit.inv2 + hud_elements_auxilliary += robit.inv3 ..() /datum/hud/proc/toggle_show_robot_modules() - if(!isrobot(mymob)) - return - var/mob/living/silicon/robot/r = mymob - r.shown_robot_modules = !r.shown_robot_modules - update_robot_modules_display() - + var/mob/living/silicon/robot/robit = owner?.resolve() + if(istype(robit)) + robit.shown_robot_modules = !robit.shown_robot_modules + update_robot_modules_display() /datum/hud/proc/update_robot_modules_display() - if(!isrobot(mymob) || !mymob.client) + var/mob/living/silicon/robot/robit = owner?.resolve() + if(!istype(robit) || !robit.client) return - var/mob/living/silicon/robot/R = mymob - - if(R.shown_robot_modules) - if(R.active_storage) - R.active_storage.close(R) //Closes the inventory ui. + if(robit.shown_robot_modules) + if(robit.active_storage) + robit.active_storage.close(robit) //Closes the inventory ui. - if(!R.module) - to_chat(R, SPAN_WARNING("No module selected.")) + if(!robit.module) + to_chat(robit, SPAN_WARNING("No module selected.")) return - if(!R.module.equipment) - to_chat(R, SPAN_WARNING("Selected module has no equipment available.")) + if(!robit.module.equipment) + to_chat(robit, SPAN_WARNING("Selected module has no equipment available.")) return - if(!R.robot_modules_background) + if(!robit.robot_modules_background) return - var/display_rows = ceil(R.module.equipment.len / 8) - R.robot_modules_background.screen_loc = "CENTER-4:16,BOTTOM+1:7 to CENTER+3:16,BOTTOM+[display_rows]:7" - R.client.screen += R.robot_modules_background + var/display_rows = ceil(robit.module.equipment.len / 8) + robit.robot_modules_background.screen_loc = "CENTER-4:16,BOTTOM+1:7 to CENTER+3:16,BOTTOM+[display_rows]:7" + robit.client.screen += robit.robot_modules_background var/x = -4 //Start at CENTER-4,SOUTH+1 var/y = 1 @@ -62,17 +59,17 @@ //Unfortunately adding the emag module to the list of modules has to be here. This is because a borg can //be emagged before they actually select a module. - or some situation can cause them to get a new module // - or some situation might cause them to get de-emagged or something. - if(R.emagged) - if(!(R.module.emag in R.module.equipment)) - R.module.equipment.Add(R.module.emag) + if(robit.emagged) + if(!(robit.module.emag in robit.module.equipment)) + robit.module.equipment.Add(robit.module.emag) else - if(R.module.emag in R.module.equipment) - R.module.equipment.Remove(R.module.emag) + if(robit.module.emag in robit.module.equipment) + robit.module.equipment.Remove(robit.module.emag) - for(var/atom/movable/A in R.module.equipment) - if( (A != R.module_state_1) && (A != R.module_state_2) && (A != R.module_state_3) ) + for(var/atom/movable/A in robit.module.equipment) + if( (A != robit.module_state_1) && (A != robit.module_state_2) && (A != robit.module_state_3) ) //Module is not currently active - R.client.screen += A + robit.client.screen += A if(x < 0) A.screen_loc = "CENTER[x]:[WORLD_ICON_SIZE/2],BOTTOM+[y]:7" else @@ -86,9 +83,9 @@ else //Modules display is hidden - for(var/atom/A in R.module.equipment) - if( (A != R.module_state_1) && (A != R.module_state_2) && (A != R.module_state_3) ) + for(var/atom/A in robit.module.equipment) + if( (A != robit.module_state_1) && (A != robit.module_state_2) && (A != robit.module_state_3) ) //Module is not currently active - R.client.screen -= A - R.shown_robot_modules = 0 - R.client.screen -= R.robot_modules_background + robit.client.screen -= A + robit.shown_robot_modules = 0 + robit.client.screen -= robit.robot_modules_background diff --git a/code/_onclick/hud/screen/screen_mob_modifier.dm b/code/_onclick/hud/screen/screen_mob_modifier.dm new file mode 100644 index 000000000000..da38d783020e --- /dev/null +++ b/code/_onclick/hud/screen/screen_mob_modifier.dm @@ -0,0 +1,155 @@ +/obj/screen/mob_modifiers + screen_loc = "CENTER,TOP" + icon_state = "blank" + requires_ui_style = FALSE + + // Disable these due to vis_contents behaving oddly with them. + use_supplied_ui_color = FALSE + use_supplied_ui_alpha = FALSE + + // TODO: consider pooling these. + var/list/elements + var/const/modifier_size = 18 + +/obj/screen/mob_modifiers/Initialize(mapload, mob/_owner, decl/ui_style/ui_style, ui_color, ui_alpha, ui_cat) + . = ..() + START_PROCESSING(SSprocessing, src) + +/obj/screen/mob_modifiers/Destroy() + STOP_PROCESSING(SSprocessing, src) + QDEL_NULL_LIST(elements) + return ..() + +/obj/screen/mob_modifiers/Process() + if(QDELETED(src)) + return PROCESS_KILL + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner)) + return PROCESS_KILL + for(var/obj/screen/mob_modifier/element in elements) + var/expire_time = MOB_MODIFIER_INDEFINITE + for(var/datum/mob_modifier/modifier in LAZYACCESS(owner._mob_modifiers, element.archetype)) + if(modifier.expire_time == MOB_MODIFIER_INDEFINITE) + expire_time = MOB_MODIFIER_INDEFINITE + break + expire_time = max(expire_time, modifier.expire_time) + if(istype(element)) + element.update_maptext(expire_time == MOB_MODIFIER_INDEFINITE ? MOB_MODIFIER_INDEFINITE : (expire_time - world.time)) + +/obj/screen/mob_modifiers/on_update_icon() + + if(QDELETED(src)) + return + + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner) || !istype(owner.hud_used)) + return + + var/list/seen_archetypes + var/list/elements_to_keep + var/list/elements_to_add + var/list/elements_to_remove + + // Track deltas for keeping/removing existing elements. + for(var/obj/screen/mob_modifier/element in elements) + var/list/modifiers = LAZYACCESS(owner._mob_modifiers, element.archetype) + if(length(modifiers)) + LAZYADD(elements_to_keep, element) + else + LAZYADD(elements_to_remove, element) + LAZYDISTINCTADD(seen_archetypes, element.archetype) + + var/decl/ui_style/ui_style = owner.hud_used.get_ui_style_data() + var/ui_color = owner.hud_used.get_ui_color() + var/ui_alpha = owner.hud_used.get_ui_alpha() + + // Create elements for new modifiers. + for(var/decl/mob_modifier/archetype in owner._mob_modifiers) + if(archetype in seen_archetypes) + continue + var/obj/screen/mob_modifier/element = new(null, owner, ui_style, ui_color, ui_alpha, HUD_MODIFIERS) + element.archetype = archetype + element.holder = src + element.pixel_y = 32 + element.alpha = 0 + element.update_icon() + LAZYADD(elements_to_add, element) + + // Fade out and delete expired markers. + if(LAZYLEN(elements_to_remove)) + LAZYREMOVE(elements, elements_to_remove) + for(var/obj/screen/mob_modifier/element in elements_to_remove) + animate(element, alpha = 0, pixel_y = 32, time = 5) + QDEL_IN(element, 5) + + // Add our new records. + if(LAZYLEN(elements_to_add)) + LAZYADD(elements, elements_to_add) + add_vis_contents(elements_to_add) + + // Adjust positions and fade in new elements. + if(length(elements)) + var/offset_x = -(((length(elements)-1) * modifier_size) / 2) + for(var/obj/screen/element in elements) + if(element in elements_to_add) + pixel_x = offset_x + animate(element, alpha = 255, pixel_x = offset_x, pixel_y = 0, time = 5) + offset_x += modifier_size + +/obj/screen/mob_modifier + alpha = 0 + screen_loc = null // not handled via screen loc, but via vis contents of the holder object. + maptext_x = -8 + maptext_y = -3 + icon_state = "modifier_base" + var/decl/mob_modifier/archetype + var/obj/screen/mob_modifiers/holder + +/obj/screen/mob_modifier/Destroy() + if(holder) + LAZYREMOVE(holder.elements, src) + holder.remove_vis_contents(src) + holder = null + return ..() + +/obj/screen/mob_modifier/rebuild_screen_overlays() + . = ..() + if(archetype) + add_overlay(overlay_image(archetype.hud_icon, archetype.hud_icon_state, COLOR_WHITE, RESET_COLOR)) + +/obj/screen/mob_modifier/proc/update_maptext(duration) + if(archetype.hide_expiry) + maptext = null + return + + if(duration == MOB_MODIFIER_INDEFINITE) + if(archetype.show_indefinite_duration) + maptext = STYLE_SMALLFONTS_OUTLINE("
", 12, COLOR_WHITE, COLOR_BLACK) + else + maptext = null + else if(duration <= 0) + maptext = STYLE_SMALLFONTS_OUTLINE("
0
", 7, COLOR_WHITE, COLOR_BLACK) + else + maptext = STYLE_SMALLFONTS_OUTLINE("
[ticks2shortreadable(duration) || 0]
", 7, COLOR_WHITE, COLOR_BLACK) + +/obj/screen/mob_modifier/handle_click(mob/user, params) + if((. = ..())) + var/mob/living/owner = owner_ref?.resolve() + if(istype(owner) && archetype) + var/list/modifiers = LAZYACCESS(owner._mob_modifiers, archetype) + for(var/datum/mob_modifier/modifier in modifiers) + modifier.on_modifier_click(params) + return + +/obj/screen/mob_modifier/MouseEntered(location, control, params) + if(archetype && (archetype.name || archetype.desc)) + openToolTip(user = usr, tip_src = src, params = params, title = archetype.name, content = archetype.desc) + ..() + +/obj/screen/mob_modifier/MouseDown() + closeToolTip(usr) + ..() + +/obj/screen/mob_modifier/MouseExited() + closeToolTip(usr) + ..() diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index b92356b4a145..f60ad5c1ca4a 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -154,7 +154,8 @@ avoid code duplication. This includes items that may sometimes act as a standard user.setClickCooldown(attack_cooldown + w_class) if(animate) user.do_attack_animation(target) - if(!user.aura_check(AURA_TYPE_WEAPON, src, user)) + + if(target.mob_modifiers_block_attack(MM_ATTACK_TYPE_WEAPON, user, src)) return FALSE var/hit_zone = target.resolve_item_attack(src, user, user.get_target_zone()) diff --git a/code/datums/cinematic.dm b/code/datums/cinematic.dm index 86ddc55b91f6..bf03370505e8 100644 --- a/code/datums/cinematic.dm +++ b/code/datums/cinematic.dm @@ -27,7 +27,7 @@ var/global/datum/cinematic/cinematic = new if(M.client) M.client.screen += cinematic_screen //show every client the cinematic viewers[M.client] = GET_STATUS(M, STAT_STUN) - M.set_status(STAT_STUN, 8000) + M.set_status_condition(STAT_STUN, 8000) override.nuke_act(cinematic_screen, station_missed) //cinematic happens here, as does mob death. //If it's actually the end of the round, wait for it to end. @@ -36,6 +36,6 @@ var/global/datum/cinematic/cinematic = new for(var/client/C in viewers) if(C.mob) - C.mob.set_status(STAT_STUN, viewers[C]) + C.mob.set_status_condition(STAT_STUN, viewers[C]) C.screen -= cinematic_screen QDEL_NULL(cinematic_screen) \ No newline at end of file diff --git a/code/datums/wires/camera.dm b/code/datums/wires/camera.dm index 09046ea83f19..c1e09d292805 100644 --- a/code/datums/wires/camera.dm +++ b/code/datums/wires/camera.dm @@ -42,7 +42,7 @@ var/global/const/CAMERA_WIRE_ALARM = 8 if(CAMERA_WIRE_POWER) C.cut_power = !mended - C.set_status(mended, usr) + C.set_camera_status(mended, usr) if(CAMERA_WIRE_LIGHT) C.light_disabled = !mended diff --git a/code/game/atoms.dm b/code/game/atoms.dm index fb3c08684708..e1788ccc207a 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -145,7 +145,7 @@ /atom/proc/try_on_reagent_change() SHOULD_NOT_OVERRIDE(TRUE) set waitfor = FALSE - if(QDELETED(src) ||_reagent_update_started >= world.time) + if(QDELETED(src) || _reagent_update_started >= world.time) return FALSE _reagent_update_started = world.time sleep(0) // Defer to end of tick so we don't drop subsequent reagent updates. diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 73011d930265..4ba136ff11ac 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -603,3 +603,5 @@ return TRUE return FALSE +/atom/movable/proc/get_cryogenic_power() + return 0 diff --git a/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm b/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm index 77f579113835..8f8d2f43e3cd 100644 --- a/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm +++ b/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm @@ -53,14 +53,14 @@ if(M.client) to_chat(M,"You feel oddly light, and somewhat disoriented as everything around you shimmers and warps ever so slightly.") M.overlay_fullscreen("wormhole", /obj/screen/fullscreen/wormhole_overlay) - M.set_status(STAT_CONFUSE, 20) + M.set_status_condition(STAT_CONFUSE, 20) bluegoasts += new/obj/effect/bluegoast/(get_turf(M),M) /datum/universal_state/jump/proc/clear_duplicated(var/mob/living/M) if(M.client) to_chat(M,"You feel rooted in material world again.") M.clear_fullscreen("wormhole") - M.set_status(STAT_CONFUSE, 0) + M.set_status_condition(STAT_CONFUSE, 0) for(var/mob/goast in global.ghost_mob_list) goast.mouse_opacity = initial(goast.mouse_opacity) goast.set_invisibility(initial(goast.invisibility)) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 24e826c1739b..00b91ddfdc76 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -42,6 +42,9 @@ add_reagent_canister(null, new /obj/item/chems/chem_disp_cartridge/antitoxins()) add_reagent_canister(null, new /obj/item/chems/chem_disp_cartridge/oxy_meds()) +/obj/machinery/sleeper/get_cryogenic_power() + return stasis + /obj/machinery/sleeper/Destroy() QDEL_NULL(beaker) QDEL_NULL_LIST(loaded_canisters) @@ -168,7 +171,7 @@ toggle_lavage() if(isliving(occupant) && stasis > 1) - occupant.set_stasis(stasis) + occupant.add_mob_modifier(/decl/mob_modifier/stasis, 2 SECONDS, source = src) /obj/machinery/sleeper/on_update_icon() cut_overlays() diff --git a/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm b/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm index c8fdd39f53bd..38cc9bbe24db 100644 --- a/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm +++ b/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm @@ -15,7 +15,7 @@ return FALSE // Can potentially add uninstall code here, but not currently supported. return ..() -/obj/item/stock_parts/proc/set_status(var/obj/machinery/machine, var/flag) +/obj/item/stock_parts/proc/set_component_status(var/obj/machinery/machine, var/flag) var/old_stat = status status |= flag if(old_stat != status) @@ -34,7 +34,7 @@ machine.component_stat_change(src, old_stat, flag) /obj/item/stock_parts/proc/on_install(var/obj/machinery/machine) - set_status(machine, PART_STAT_INSTALLED) + set_component_status(machine, PART_STAT_INSTALLED) /obj/item/stock_parts/proc/on_uninstall(var/obj/machinery/machine, var/temporary = FALSE) unset_status(machine, PART_STAT_INSTALLED) @@ -48,7 +48,7 @@ if(istype(machine)) LAZYDISTINCTADD(machine.processing_parts, src) START_PROCESSING_MACHINE(machine, MACHINERY_PROCESS_COMPONENTS) - set_status(machine, PART_STAT_PROCESSING) + set_component_status(machine, PART_STAT_PROCESSING) /obj/item/stock_parts/proc/stop_processing(var/obj/machinery/machine) if(istype(machine)) diff --git a/code/game/machinery/_machines_base/stock_parts/power/battery.dm b/code/game/machinery/_machines_base/stock_parts/power/battery.dm index c78b358aea6b..c3f9cadf208b 100644 --- a/code/game/machinery/_machines_base/stock_parts/power/battery.dm +++ b/code/game/machinery/_machines_base/stock_parts/power/battery.dm @@ -49,7 +49,7 @@ if(istype(machine)) machine.power_change() machine.queue_icon_update() - set_status(machine, PART_STAT_CONNECTED) + set_component_status(machine, PART_STAT_CONNECTED) update_icon() return cell @@ -112,7 +112,7 @@ /obj/item/stock_parts/power/battery/can_provide_power(var/obj/machinery/machine) if(is_functional() && cell && cell.check_charge(CELLRATE * machine.get_power_usage())) machine.update_power_channel(LOCAL) - set_status(machine, PART_STAT_ACTIVE) + set_component_status(machine, PART_STAT_ACTIVE) return TRUE return FALSE diff --git a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm index 79cdd75518dd..e533d5ec02c5 100644 --- a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm +++ b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm @@ -48,7 +48,7 @@ //Is willing to provide power if the wired contribution is nonnegligible and there is enough total local power to run the machine. /obj/item/stock_parts/power/terminal/can_provide_power(var/obj/machinery/machine) if(is_functional() && terminal && terminal.surplus() && machine.can_use_power_oneoff(machine.get_power_usage(), LOCAL) <= 0) - set_status(machine, PART_STAT_ACTIVE) + set_component_status(machine, PART_STAT_ACTIVE) machine.update_power_channel(LOCAL) return TRUE return FALSE @@ -76,7 +76,7 @@ terminal.queue_icon_update() set_extension(src, /datum/extension/event_registration/shuttle_stationary, GET_DECL(/decl/observ/moved), machine, PROC_REF(machine_moved), get_area(src)) - set_status(machine, PART_STAT_CONNECTED) + set_component_status(machine, PART_STAT_CONNECTED) start_processing(machine) /obj/item/stock_parts/power/terminal/proc/machine_moved(var/obj/machinery/machine, var/turf/old_loc, var/turf/new_loc) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 98bac3c1fd33..6f6b8ec45963 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -86,7 +86,7 @@ set_extension(src, /datum/extension/network_device/camera, null, null, null, TRUE, preset_channels, c_tag, cameranet_enabled, requires_connection) /obj/machinery/camera/Destroy() - set_status(0) //kick anyone viewing out + set_camera_status(0) //kick anyone viewing out return ..() /obj/machinery/camera/Process() @@ -227,7 +227,7 @@ //sparks spark_at(loc, amount=5) -/obj/machinery/camera/proc/set_status(var/newstatus, var/mob/user) +/obj/machinery/camera/proc/set_camera_status(var/newstatus, var/mob/user) if (status != newstatus && (!cut_power || status == TRUE)) status = newstatus // The only way for AI to reactivate cameras are malf abilities, this gives them different messages. @@ -337,7 +337,7 @@ ) /obj/machinery/camera/proc/toggle_status() - set_status(!status) + set_camera_status(!status) /decl/public_access/public_method/toggle_camera name = "toggle camera" diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 1892189e038e..059d35045c0e 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -299,11 +299,14 @@ if (occupant && user.Adjacent(src)) . += occupant.get_examine_strings(user, distance, infix, suffix) +/obj/machinery/cryopod/get_cryogenic_power() + return applies_stasis ? 1 : 0 + //Lifted from Unity stasis.dm and refactored. /obj/machinery/cryopod/Process() if(occupant) if(applies_stasis && (world.time > time_entered + 20 SECONDS)) - occupant.set_stasis(2) + occupant.add_mob_modifier(/decl/mob_modifier/stasis, 2 SECONDS, source = src) //Allow a ten minute gap between entering the pod and actually despawning. // Only provide the gap if the occupant hasn't ghosted diff --git a/code/game/machinery/doors/airlock_interactions.dm b/code/game/machinery/doors/airlock_interactions.dm index 2ad96280a52c..2406735f21a7 100644 --- a/code/game/machinery/doors/airlock_interactions.dm +++ b/code/game/machinery/doors/airlock_interactions.dm @@ -59,8 +59,8 @@ for(var/i in 1 to round(crush_damage/AIRLOCK_CRUSH_INCREMENT, 1)) apply_damage(AIRLOCK_CRUSH_INCREMENT, BRUTE) - set_status(STAT_STUN, round(crush_damage / 8, 1)) - set_status(STAT_WEAK, round(crush_damage / 8, 1)) + set_status_condition(STAT_STUN, round(crush_damage / 8, 1)) + set_status_condition(STAT_WEAK, round(crush_damage / 8, 1)) var/turf/T = loc if(!istype(T)) diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 1fb6b7666b72..1f9777dfac90 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -126,7 +126,7 @@ var/mob/living/human/H = M if(H.get_sound_volume_multiplier() < 0.2) continue - M.set_status(STAT_ASLEEP, 0) + M.set_status_condition(STAT_ASLEEP, 0) ADJ_STATUS(M, STAT_STUTTER, 20) SET_STATUS_MAX(M, STAT_DEAF, 30) SET_STATUS_MAX(M, STAT_WEAK, 3) @@ -134,7 +134,7 @@ SET_STATUS_MAX(M, STAT_STUN, 10) SET_STATUS_MAX(M, STAT_PARA, 4) else - M.set_status(STAT_JITTER, 400) + M.set_status_condition(STAT_JITTER, 400) spawn(15) explode() diff --git a/code/game/objects/auras/aura.dm b/code/game/objects/auras/aura.dm deleted file mode 100644 index 5de18f3adf62..000000000000 --- a/code/game/objects/auras/aura.dm +++ /dev/null @@ -1,58 +0,0 @@ -/*Auras are simple: They are simple overriders for attackbys, bullet_act, damage procs, etc. They also tick after their respective mob. -They should be used for undeterminate mob effects, like for instance a toggle-able forcefield, or indestructability as long as you don't move. -They should also be used for when you want to effect the ENTIRE mob, like having an armor buff or showering candy everytime you walk. -*/ - -/obj/aura - var/mob/living/user - -/obj/aura/Initialize() - . = ..() - if(isliving(loc)) - added_to(loc) - user.add_aura(src) - -/obj/aura/Destroy() - if(user) - user.remove_aura(src) - removed() - return ..() - -/obj/aura/proc/added_to(var/mob/living/target) - user = target - -/obj/aura/proc/removed() - user = null - -/obj/aura/proc/life_tick() - return 0 - -/obj/aura/attackby(var/obj/item/I, var/mob/user) - return 0 - -/obj/aura/bullet_act(var/obj/item/projectile/P, var/def_zone) - return 0 - -/obj/aura/hitby() - SHOULD_CALL_PARENT(FALSE) - return FALSE - -/obj/aura/debug - var/returning = FALSE - -/obj/aura/debug/attackby(var/obj/item/I, var/mob/user) - log_debug("Attackby for \ref[src]: [I], [user]") - return returning - -/obj/aura/debug/bullet_act(var/obj/item/projectile/P, var/def_zone) - log_debug("Bullet Act for \ref[src]: [P], [def_zone]") - return returning - -/obj/aura/debug/life_tick() - log_debug("Life tick") - return returning - -/obj/aura/debug/hitby(var/atom/movable/M, var/datum/thrownthing/TT) - SHOULD_CALL_PARENT(FALSE) - log_debug("Hit By for \ref[src]: [M], [TT.speed]") - return returning \ No newline at end of file diff --git a/code/game/objects/auras/personal_shields/personal_shield.dm b/code/game/objects/auras/personal_shields/personal_shield.dm deleted file mode 100644 index 934005ceb4f9..000000000000 --- a/code/game/objects/auras/personal_shields/personal_shield.dm +++ /dev/null @@ -1,34 +0,0 @@ -/obj/aura/personal_shield - name = "personal shield" - -/obj/aura/personal_shield/added_to(var/mob/living/L) - ..() - playsound(user,'sound/weapons/flash.ogg',35,1) - to_chat(user,"You feel your body prickle as \the [src] comes online.") - -/obj/aura/personal_shield/bullet_act(var/obj/item/projectile/P, var/def_zone) - user.visible_message("\The [user]'s [src.name] flashes before \the [P] can hit them!") - new /obj/effect/temporary(get_turf(src), 2 SECONDS,'icons/obj/machines/shielding.dmi',"shield_impact") - playsound(user,'sound/effects/basscannon.ogg',35,1) - return AURA_FALSE|AURA_CANCEL - -/obj/aura/personal_shield/removed() - to_chat(user,"\The [src] goes offline!") - playsound(user,'sound/mecha/internaldmgalarm.ogg',25,1) - ..() - -/obj/aura/personal_shield/device - var/obj/item/personal_shield/shield - -/obj/aura/personal_shield/device/bullet_act() - . = ..() - if(shield) - shield.take_charge() - -/obj/aura/personal_shield/device/Initialize(mapload, var/user_shield) - . = ..() - shield = user_shield - -/obj/aura/personal_shield/device/Destroy() - shield = null - return ..() \ No newline at end of file diff --git a/code/game/objects/auras/radiant_aura.dm b/code/game/objects/auras/radiant_aura.dm deleted file mode 100644 index d25cfa807b95..000000000000 --- a/code/game/objects/auras/radiant_aura.dm +++ /dev/null @@ -1,20 +0,0 @@ -/obj/aura/radiant_aura - name = "radiant aura" - icon = 'icons/effects/effects.dmi' - icon_state = "fire_goon" - layer = ABOVE_WINDOW_LAYER - -/obj/aura/radiant_aura/added_to(var/mob/living/L) - ..() - to_chat(L,"A bubble of light appears around you, exuding protection and warmth.") - set_light(6, 6, "#e09d37") - -/obj/aura/radiant_aura/removed() - to_chat(user, "Your protective aura dissipates, leaving you feeling cold and unsafe.") - ..() - -/obj/aura/radiant_aura/bullet_act(var/obj/item/projectile/P, var/def_zone) - if(P.damage_flags() & DAM_LASER) - user.visible_message("\The [P] refracts, bending into \the [user]'s aura.") - return AURA_FALSE - return 0 diff --git a/code/game/objects/auras/regenerating_aura.dm b/code/game/objects/auras/regenerating_aura.dm deleted file mode 100644 index 7c313fc2d1c3..000000000000 --- a/code/game/objects/auras/regenerating_aura.dm +++ /dev/null @@ -1,121 +0,0 @@ -/obj/aura/regenerating - name = "regenerating aura" - var/brute_mult = 1 - var/fire_mult = 1 - var/tox_mult = 1 - -/obj/aura/regenerating/life_tick() - user.heal_damage(BRUTE, brute_mult, do_update_health = FALSE) - user.heal_damage(BURN, fire_mult, do_update_health = FALSE) - user.heal_damage(TOX, tox_mult) - -/obj/aura/regenerating/human - var/nutrition_damage_mult = 1 //How much nutrition it takes to heal regular damage - var/external_nutrition_mult = 50 // How much nutrition it takes to regrow a limb - var/organ_mult = 2 - var/regen_message = "Your body throbs as you feel your ORGAN regenerate." - var/grow_chance = 0 - var/grow_threshold = 0 - var/ignore_tag = BP_BRAIN //organ tag to ignore - var/last_nutrition_warning = 0 - var/innate_heal = TRUE // Whether the aura is on, basically. - - -/obj/aura/regenerating/human/proc/external_regeneration_effect(var/obj/item/organ/external/O, var/mob/living/human/H) - return - -/obj/aura/regenerating/human/life_tick() - var/mob/living/human/H = user - if(!istype(H)) - . = 0 - CRASH("Someone gave [user.type] a [src.type] aura. This is invalid.") - if(!innate_heal || H.is_in_stasis() || H.stat == DEAD) - return 0 - if(H.nutrition < nutrition_damage_mult) - low_nut_warning() - return 0 - - var/update_health = FALSE - var/organ_regen = get_config_value(/decl/config/num/health_organ_regeneration_multiplier) - if(brute_mult && H.get_damage(BRUTE)) - update_health = TRUE - H.heal_damage(BRUTE, brute_mult * organ_regen, do_update_health = FALSE) - H.adjust_nutrition(-nutrition_damage_mult) - if(fire_mult && H.get_damage(BURN)) - update_health = TRUE - H.heal_damage(BURN, fire_mult * organ_regen, do_update_health = FALSE) - H.adjust_nutrition(-nutrition_damage_mult) - if(tox_mult && H.get_damage(TOX)) - update_health = TRUE - H.heal_damage(TOX, tox_mult * organ_regen, do_update_health = FALSE) - H.adjust_nutrition(-nutrition_damage_mult) - if(update_health) - H.update_health() - - if(!can_regenerate_organs()) - return 1 - if(organ_mult) - if(prob(10) && H.nutrition >= 150 && !H.get_damage(BRUTE) && !H.get_damage(BURN)) - var/obj/item/organ/external/D = GET_EXTERNAL_ORGAN(H, BP_HEAD) - if (D.status & ORGAN_DISFIGURED) - if (H.nutrition >= 20) - D.status &= ~ORGAN_DISFIGURED - H.adjust_nutrition(-20) - else - low_nut_warning(BP_HEAD) - - var/list/organs = H.get_internal_organs() - for(var/obj/item/organ/internal/regen_organ in shuffle(organs.Copy())) - if(BP_IS_PROSTHETIC(regen_organ) || regen_organ.organ_tag == ignore_tag) - continue - if(istype(regen_organ)) - if(regen_organ.get_organ_damage() > 0 && !(regen_organ.status & ORGAN_DEAD)) - if (H.nutrition >= organ_mult) - regen_organ.adjust_organ_damage(-(organ_mult)) - H.adjust_nutrition(-organ_mult) - if(prob(5)) - to_chat(H, replacetext(regen_message,"ORGAN", regen_organ.name)) - else - low_nut_warning(regen_organ.name) - - if(prob(grow_chance)) - var/decl/bodytype/root_bodytype = H.get_bodytype() - for(var/limb_type in root_bodytype.has_limbs) - var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(H, limb_type) - if(E && E.organ_tag != BP_HEAD && !E.is_vital_to_owner() && !E.is_usable()) //Skips heads and vital bits... - if (H.nutrition > grow_threshold) - H.remove_organ(E) //...because no one wants their head to explode to make way for a new one. - qdel(E) - E= null - else - low_nut_warning(E.name) - if(!E) - var/list/organ_data = root_bodytype.has_limbs[limb_type] - var/limb_path = organ_data["path"] - var/obj/item/organ/external/O = new limb_path(H) - external_regeneration_effect(O,H) - H.adjust_nutrition(-external_nutrition_mult) - organ_data["descriptor"] = O.name - H.update_body() - return - else if (H.nutrition > grow_threshold) //We don't subtract any nut here, but let's still only heal wounds when we have nut. - for(var/datum/wound/W in E.wounds) - if(W.wound_damage() == 0 && prob(50)) - qdel(W) - return 1 - -/obj/aura/regenerating/human/proc/low_nut_warning(var/wound_type) - if (last_nutrition_warning + 1 MINUTE < world.time) - to_chat(user, "You need more energy to regenerate your [wound_type || "wounds"].") - last_nutrition_warning = world.time - return 1 - return 0 - -/obj/aura/regenerating/human/proc/toggle() - innate_heal = !innate_heal - -/obj/aura/regenerating/human/proc/can_toggle() - return TRUE - -/obj/aura/regenerating/human/proc/can_regenerate_organs() - return TRUE diff --git a/code/game/objects/items/cryobag.dm b/code/game/objects/items/cryobag.dm index f045c550ad9d..87d328458c74 100644 --- a/code/game/objects/items/cryobag.dm +++ b/code/game/objects/items/cryobag.dm @@ -14,6 +14,9 @@ ) var/stasis_power +/obj/item/bodybag/cryobag/get_cryogenic_power() + return stasis_power + /obj/item/bodybag/cryobag/attack_self(mob/user) var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc) if(stasis_power) @@ -92,9 +95,7 @@ stasis_power = round(0.75 * stasis_power) animate(src, color = color_matrix_saturation(get_saturation()), time = 10) update_icon() - - if(LAZYACCESS(patient.stasis_sources, STASIS_CRYOBAG) != stasis_power) - patient.set_stasis(stasis_power, STASIS_CRYOBAG) + patient.add_mob_modifier(/decl/mob_modifier/stasis, 2 SECONDS, source = src) /obj/structure/closet/body_bag/cryobag/return_air() //Used to make stasis bags protect from vacuum. if(airtank) diff --git a/code/game/objects/items/devices/personal_shield.dm b/code/game/objects/items/devices/personal_shield.dm index c83b7522cc8d..c88b59712e98 100644 --- a/code/game/objects/items/devices/personal_shield.dm +++ b/code/game/objects/items/devices/personal_shield.dm @@ -11,36 +11,45 @@ /decl/material/solid/metal/uranium = MATTER_AMOUNT_TRACE, ) var/uses = 5 - var/obj/aura/personal_shield/device/shield + var/shield_effect_type = /decl/mob_modifier/shield/device /obj/item/personal_shield/attack_self(var/mob/user) - if(uses && !shield) - shield = new(user,src) - else - QDEL_NULL(shield) + if(loc == user && isliving(user)) + var/mob/living/holder = user + if(holder.has_mob_modifier(shield_effect_type, source = src)) + holder.remove_mob_modifier(shield_effect_type, source = src) + else if(uses && shield_effect_type) + holder.add_mob_modifier(shield_effect_type, source = src) + else + return ..() + return TRUE + return ..() /obj/item/personal_shield/Move() - QDEL_NULL(shield) - return ..() + var/mob/living/holder = loc + . = ..() + if(. && istype(holder) && holder.has_mob_modifier(shield_effect_type, source = src)) + holder.remove_mob_modifier(shield_effect_type, source = src) /obj/item/personal_shield/forceMove() - QDEL_NULL(shield) - return ..() + var/mob/living/holder = loc + . = ..() + if(. && istype(holder) && holder.has_mob_modifier(shield_effect_type, source = src)) + holder.remove_mob_modifier(shield_effect_type, source = src) -/obj/item/personal_shield/proc/take_charge() - if(!--uses) - QDEL_NULL(shield) - to_chat(loc,"\The [src] begins to spark as it breaks!") +/obj/item/personal_shield/proc/expend_charge() + if(uses <= 0) + return FALSE + uses-- + if(uses <= 0 && ismob(loc)) + var/mob/living/holder = loc + if(istype(holder) && holder.has_mob_modifier(shield_effect_type, source = src)) + holder.remove_mob_modifier(shield_effect_type, source = src) + to_chat(holder, SPAN_DANGER("\The [src] begins to spark as it breaks!")) update_icon() - return + return TRUE /obj/item/personal_shield/on_update_icon() . = ..() if(uses) - icon_state = "batterer" - else - icon_state = "battererburnt" - -/obj/item/personal_shield/Destroy() - QDEL_NULL(shield) - return ..() \ No newline at end of file + add_overlay("[icon_state]-on") \ No newline at end of file diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 16d7f1eddcd5..cbe87ec2d299 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -7,15 +7,15 @@ ***********************************************************************/ /obj/item/borg/overdrive name = "overdrive" - icon = 'icons/obj/decals.dmi' + icon = 'icons/obj/signs/warnings.dmi' icon_state = "shock" /********************************************************************** HUD/SIGHT things ***********************************************************************/ /obj/item/borg/sight - icon = 'icons/obj/decals.dmi' - icon_state = "securearea" + icon = 'icons/obj/signs/warnings.dmi' + icon_state = "secureareaold" var/sight_mode = null var/glasses_hud_type diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 4a176ec5298b..7b661c24a28d 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -35,7 +35,7 @@ /obj/item/baton/infinite/Initialize(var/ml, var/material_key, var/loaded_cell_type) . = ..(ml, material_key, loaded_cell_type = /obj/item/cell/device/infinite) - set_status(1, null) + set_cell_status(1, null) /obj/item/baton/proc/update_status() var/obj/item/cell/cell = get_cell() @@ -66,10 +66,10 @@ set_light(0) /obj/item/baton/attack_self(mob/user) - set_status(!status, user) + set_cell_status(!status, user) add_fingerprint(user) -/obj/item/baton/proc/set_status(var/newstatus, mob/user) +/obj/item/baton/proc/set_cell_status(var/newstatus, mob/user) var/obj/item/cell/cell = get_cell() if(cell?.charge >= hitcost) if(status != newstatus) diff --git a/code/game/objects/structures/mineral_bath.dm b/code/game/objects/structures/mineral_bath.dm index 3180e095a765..0129a5e61f74 100644 --- a/code/game/objects/structures/mineral_bath.dm +++ b/code/game/objects/structures/mineral_bath.dm @@ -108,18 +108,17 @@ if(occupant.has_body_flag(BODY_FLAG_CRYSTAL_REFORM) && prob(10)) var/decl/bodytype/root_bodytype = occupant.get_bodytype() for(var/limb_type in root_bodytype.has_limbs) - var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(occupant, limb_type) - if(E && !E.is_usable() && !(E.limb_flags & ORGAN_FLAG_HEALS_OVERKILL)) - occupant.remove_organ(E) - qdel(E) - E = null - if(!E) + var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(occupant, limb_type) + if(limb && !limb.is_usable() && !(limb.limb_flags & ORGAN_FLAG_HEALS_OVERKILL)) + occupant.remove_organ(limb) + qdel(limb) + limb = null + if(!limb) var/list/organ_data = root_bodytype.has_limbs[limb_type] var/limb_path = organ_data["path"] - E = new limb_path(occupant) - organ_data["descriptor"] = E.name - to_chat(occupant, SPAN_NOTICE("You feel your [E.name] reform in the crystal bath.")) - occupant.update_body() + limb = new limb_path(occupant) + occupant.add_organ(limb, GET_EXTERNAL_ORGAN(occupant, limb.parent_organ), FALSE, FALSE) + to_chat(occupant, SPAN_NOTICE("You feel your [limb.name] reform in the crystal bath.")) repaired_organ = TRUE break @@ -133,18 +132,18 @@ // Repair robotic external organs. if(!repaired_organ && prob(25)) - for(var/obj/item/organ/external/E in occupant.get_external_organs()) - if(BP_IS_PROSTHETIC(E)) - for(var/obj/implanted_object in E.implants) + for(var/obj/item/organ/external/limb in occupant.get_external_organs()) + if(BP_IS_PROSTHETIC(limb)) + for(var/obj/implanted_object in limb.implants) if(!istype(implanted_object,/obj/item/implant) && !istype(implanted_object,/obj/item/organ/internal/augment) && prob(25)) // We don't want to remove REAL implants. Just shrapnel etc. - LAZYREMOVE(E.implants, implanted_object) + LAZYREMOVE(limb.implants, implanted_object) to_chat(occupant, SPAN_NOTICE("The mineral-rich bath dissolves the [implanted_object.name].")) qdel(implanted_object) - if(E.brute_dam || E.burn_dam) - E.heal_damage(rand(3,5), rand(3,5), robo_repair = 1) + if(limb.brute_dam || limb.burn_dam) + limb.heal_damage(rand(3,5), rand(3,5), robo_repair = 1) if(prob(25)) - to_chat(occupant, SPAN_NOTICE("The mineral-rich bath mends your [E.name].")) - if(!BP_IS_CRYSTAL(E) && !BP_IS_BRITTLE(E)) - E.status |= ORGAN_BRITTLE + to_chat(occupant, SPAN_NOTICE("The mineral-rich bath mends your [limb.name].")) + if(!BP_IS_CRYSTAL(limb) && !BP_IS_BRITTLE(limb)) + limb.status |= ORGAN_BRITTLE to_chat(occupant, SPAN_WARNING("It feels a bit brittle, though...")) break diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index d5fcfd514556..22861d9d861f 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -87,7 +87,7 @@ ///A wall mountable sign structure /obj/structure/sign name = "sign" - icon = 'icons/obj/decals.dmi' + icon = 'icons/obj/signs/warnings.dmi' anchored = TRUE opacity = FALSE density = FALSE diff --git a/code/modules/abstract/_abstract.dm b/code/modules/abstract/_abstract.dm index 11d081248ecb..9f944be9cb33 100644 --- a/code/modules/abstract/_abstract.dm +++ b/code/modules/abstract/_abstract.dm @@ -1,20 +1,22 @@ /obj/abstract - name = "" - icon = 'icons/effects/landmarks.dmi' - icon_state = "x2" - simulated = FALSE - density = FALSE - anchored = TRUE - abstract_type = /obj/abstract - invisibility = INVISIBILITY_ABSTRACT + name = "" + icon = 'icons/effects/landmarks.dmi' + icon_state = "x2" + simulated = FALSE + density = FALSE + anchored = TRUE + abstract_type = /obj/abstract + invisibility = INVISIBILITY_ABSTRACT + var/hide_on_init = TRUE /obj/abstract/Initialize() . = ..() verbs.Cut() - //Let mappers see the damn thing by just making them invisible here opacity = FALSE - alpha = 0 - mouse_opacity = MOUSE_OPACITY_UNCLICKABLE + //Let mappers see the damn thing by just making them invisible here + if(hide_on_init) + alpha = 0 + mouse_opacity = MOUSE_OPACITY_UNCLICKABLE /obj/abstract/explosion_act() SHOULD_CALL_PARENT(FALSE) diff --git a/code/modules/abstract/follower.dm b/code/modules/abstract/follower.dm new file mode 100644 index 000000000000..42611d1131d2 --- /dev/null +++ b/code/modules/abstract/follower.dm @@ -0,0 +1,18 @@ +// Simple obj for following another obj around (for light effects or such that need a physical reference) +/obj/abstract/follower + anchored = TRUE + simulated = FALSE + invisibility = INVISIBILITY_ABSTRACT + +/obj/abstract/follower/Initialize() + . = ..() + name = "" + verbs.Cut() + +/obj/abstract/follower/proc/follow_owner(atom/movable/owner) + if(istype(owner) && !QDELETED(owner)) + set_dir(owner.dir) + if(owner.loc) + forceMove(owner.loc) + else + forceMove(null) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index c211f274d603..9594f9dd3dd3 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1415,10 +1415,10 @@ var/global/BSACooldown = 0 SPAN_OCCULT("OOC: \The [M] has been paralyzed by a staff member. Please hold all interactions with them until staff have finished with them."), SPAN_OCCULT("OOC: You have been paralyzed by a staff member. Please refer to your currently open admin help ticket or, if you don't have one, admin help for assistance.") ) - M.set_status(STAT_PARA, 8000) + M.set_status_condition(STAT_PARA, 8000) M.admin_paralyzed = TRUE else - M.set_status(STAT_PARA, 0) + M.set_status_condition(STAT_PARA, 0) M.admin_paralyzed = FALSE M.visible_message(SPAN_OCCULT("OOC: \The [M] has been released from paralysis by staff. You may resume interactions with them.")) to_chat(M, SPAN_OCCULT("OOC: You have been released from paralysis by staff and can return to your game.")) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index c9e2798773b2..45976fa23812 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -992,7 +992,7 @@ M.take_damage(min(99, M.current_health - 1)) SET_STATUS_MAX(M, STAT_STUN, 20) SET_STATUS_MAX(M, STAT_WEAK, 20) - M.set_status(STAT_STUTTER, 20) + M.set_status_condition(STAT_STUTTER, 20) else if(href_list["CentcommReply"]) var/mob/living/L = locate(href_list["CentcommReply"]) diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm index 7b7155b8391c..77e8826c5a98 100644 --- a/code/modules/admin/view_variables/helpers.dm +++ b/code/modules/admin/view_variables/helpers.dm @@ -62,8 +62,8 @@ /mob/living/get_view_variables_options() return ..() + {" - - + + diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 971e7a394bcd..114f3bd55106 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -590,26 +590,6 @@ var/datum/called_proc = locate(href_list["call_proc"]) if(istype(called_proc) || istype(called_proc, /client)) // can call on clients too, not just datums callproc_targetpicked(1, called_proc) - else if(href_list["addaura"]) - if(!check_rights(R_DEBUG|R_ADMIN|R_FUN)) return - var/mob/living/victim = locate(href_list["addaura"]) - if(!istype(victim)) - return - var/choice = input("Please choose an aura to add", "Auras", null) as null|anything in typesof(/obj/aura) - if(!choice || !victim) - return - var/obj/new_aura = new choice(victim) - log_and_message_admins("added \the [new_aura] to \the [victim]") - else if(href_list["removeaura"]) - if(!check_rights(R_DEBUG|R_ADMIN|R_FUN)) return - var/mob/living/victim = locate(href_list["removeaura"]) - if(!istype(victim)) - return - var/choice = input("Please choose an aura to remove", "Auras", null) as null|anything in victim.auras - if(!choice || !victim) - return - log_and_message_admins("removed \the [choice] to \the [victim]") - qdel(choice) else if(href_list["addstressor"]) if(!check_rights(R_DEBUG)) @@ -658,7 +638,7 @@ return if(amt < 0) amt += GET_STATUS(victim, selected_condition.type) - victim.set_status(selected_condition.type, amt) + victim.set_status_condition(selected_condition.type, amt) log_and_message_admins("set [selected_condition.name] to [amt] on \the [victim].") else if(href_list["setmaterial"]) @@ -705,6 +685,44 @@ else to_chat(usr, SPAN_WARNING("Failed to remove [ability] from [target]!")) + else if (href_list["add_mob_modifier"]) + var/mob/living/target = locate(href_list["add_mob_modifier"]) + if(!istype(target) || QDELETED(target)) + to_chat(usr, SPAN_WARNING("Only /mob/living mobs can have mob modifiers.")) + else + var/list/modifiers = list() + for(var/decl/mob_modifier/modifier in decls_repository.get_decls_of_type_unassociated(/decl/mob_modifier)) + if(modifier.can_be_admin_granted) + modifiers += modifier + // Evil pyramid due to apparently not being able to return early in this Topic() + var/decl/mob_modifier/modifier = input(usr, "Which modifier do you wish to give?", "Add Mob Modifier") as null|anything in modifiers + if(istype(modifier) && !QDELETED(target)) + var/duration = input(usr, "How long do you wish this modifier to last, in seconds? Enter -1 for a permanent modifier.", "Add Mob Modifier") as num|null + if(!isnull(duration)) + if(duration != MOB_MODIFIER_INDEFINITE) + duration = max(0, duration SECONDS) + if(duration != 0 && !QDELETED(target)) + if(target.add_mob_modifier(modifier, duration, source = target)) + to_chat(usr, SPAN_NOTICE("Added [modifier] to [target] for [duration] second\s.")) + else + to_chat(usr, SPAN_WARNING("Failed to add [modifier] to [target].")) + + else if (href_list["remove_mob_modifier"]) + var/mob/living/target = locate(href_list["remove_mob_modifier"]) + if(!istype(target) && !QDELETED(target)) + to_chat(usr, SPAN_WARNING("Only /mob/living mobs can have mob modifiers.")) + else + var/list/modifiers = list() + for(var/decl/mob_modifier/modifier in target._mob_modifiers) + if(modifier.can_be_admin_granted) + modifiers += modifier + var/decl/mob_modifier/modifier = input(usr, "Which modifier do you wish to remove?", "Remove Mob Modifier") as null|anything in modifiers + if(istype(modifier)) + if(target.remove_mob_modifier(modifier, source = target)) + to_chat(usr, SPAN_NOTICE("Removed [modifier] from [target].")) + else + to_chat(usr, SPAN_WARNING("Failed to remove [modifier] from [target].")) + if(href_list["datumrefresh"]) var/datum/datum_to_refresh = locate(href_list["datumrefresh"]) if(istype(datum_to_refresh, /datum) || istype(datum_to_refresh, /client)) diff --git a/code/modules/augment/passive/nanoaura.dm b/code/modules/augment/passive/nanoaura.dm index b18920b72e8f..751ed5541abc 100644 --- a/code/modules/augment/passive/nanoaura.dm +++ b/code/modules/augment/passive/nanoaura.dm @@ -1,13 +1,3 @@ -//This handy augment protects you to a degree, keeping it online after critical damage however is bad - -/obj/aura/nanoaura - name = "Nanoaura" - var/obj/item/organ/internal/augment/active/nanounit/unit = null - var/active = 0 - - -//The organ itself - /obj/item/organ/internal/augment/active/nanounit name = "nanite MCU" allowed_organs = list(BP_AUGMENT_CHEST_ACTIVE) @@ -16,7 +6,8 @@ action_button_name = "Toggle Nanomachines" material = /decl/material/solid/metal/steel origin_tech = @'{"materials":4,"magnets":4,"engineering":5,"biotech":3}' - var/obj/aura/nanoaura/aura = null + var/active = FALSE + var/modifier_archetype = /decl/mob_modifier/nanoswarm var/charges = 4 /obj/item/organ/internal/augment/active/nanounit/reset_matter() @@ -28,58 +19,39 @@ /obj/item/organ/internal/augment/active/nanounit/on_add_effects() . = ..() - if(owner) - aura = new /obj/aura/nanoaura(owner, src) + if(owner && modifier_archetype) + owner.add_mob_modifier(modifier_archetype, source = src) /obj/item/organ/internal/augment/active/nanounit/on_remove_effects(mob/living/last_owner) - QDEL_NULL(aura) + if(istype(last_owner) && modifier_archetype) + last_owner.remove_mob_modifier(modifier_archetype, source = src) . = ..() /obj/item/organ/internal/augment/active/nanounit/proc/catastrophic_failure() playsound(owner,'sound/mecha/internaldmgalarm.ogg',25,1) + charges = -1 + active = FALSE owner.visible_message(SPAN_WARNING("The nanites attempt to harden. But they seem... brittle.")) for(var/obj/item/organ/external/E in owner.get_external_organs()) if(prob(25)) E.status |= ORGAN_BRITTLE //Some nanites are not responding and you're out of luck to_chat(owner, SPAN_DANGER("Your [E.name] feels cold and rigid.")) - QDEL_NULL(aura) + owner.remove_mob_modifier(modifier_archetype, source = src) /obj/item/organ/internal/augment/active/nanounit/activate() - if(!aura || !can_activate()) + if(!owner || !modifier_archetype || !can_activate()) return - if(aura.active) - aura.active = 0 + if(owner.has_mob_modifier(modifier_archetype, source = src)) + active = FALSE to_chat(owner,SPAN_NOTICE("Nanites entering sleep mode.")) - else - aura.active = 1 + owner.remove_mob_modifier(modifier_archetype, source = src) + else if(charges > 0) to_chat(owner,SPAN_NOTICE("Activation sequence in progress.")) + active = TRUE + owner.add_mob_modifier(modifier_archetype, source = src) playsound(owner,'sound/weapons/flash.ogg',35,1) - /obj/item/organ/internal/augment/active/nanounit/Destroy() + if(owner && modifier_archetype) + owner.remove_mob_modifier(modifier_archetype, source = src) . = ..() - QDEL_NULL(aura) - -/obj/aura/nanoaura/Initialize(var/maploading, var/obj/item/organ/internal/augment/active/nanounit/holder) - . = ..() - unit = holder - playsound(loc,'sound/weapons/flash.ogg',35,1) - to_chat(loc,SPAN_NOTICE("Your skin tingles as the nanites spread over your body.")) - -/obj/aura/nanoaura/bullet_act(var/obj/item/projectile/P, var/def_zone) - if(!active) - return - if(unit.charges > 0) - user.visible_message(SPAN_WARNING("The nanomachines harden as a response to physical trauma!")) - playsound(user,'sound/effects/basscannon.ogg',35,1) - unit.charges -= 1 - if(unit.charges <= 0) - to_chat(user, SPAN_DANGER("Warning: Critical damage threshold passed. Shut down unit to avoid further damage.")) - return AURA_FALSE|AURA_CANCEL - else unit.catastrophic_failure() - - -/obj/aura/nanoaura/Destroy() - to_chat(user, SPAN_WARNING("The nanites dissolve!")) - unit = null - return ..() diff --git a/code/modules/client/ui_styles/_ui_style.dm b/code/modules/client/ui_styles/_ui_style.dm index 808709107dcd..a1a4664efe0e 100644 --- a/code/modules/client/ui_styles/_ui_style.dm +++ b/code/modules/client/ui_styles/_ui_style.dm @@ -29,7 +29,8 @@ (HUD_UP_HINT) = 'icons/mob/screen/styles/midnight/uphint.dmi', (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/midnight/zone_selector.dmi', (HUD_CHARGE) = 'icons/mob/screen/styles/charge.dmi', - (HUD_INTENT) = 'icons/screen/intents.dmi' + (HUD_INTENT) = 'icons/screen/intents.dmi', + (HUD_MODIFIERS) = 'icons/mob/screen/styles/midnight/modifiers.dmi' ) /// A subset of UI keys to icon files used to override the above. var/list/override_icons diff --git a/code/modules/client/ui_styles/_ui_style_states.dm b/code/modules/client/ui_styles/_ui_style_states.dm index 95f6558e61a6..6a060e6dbdef 100644 --- a/code/modules/client/ui_styles/_ui_style_states.dm +++ b/code/modules/client/ui_styles/_ui_style_states.dm @@ -20,7 +20,8 @@ var/global/list/_ui_all_keys = list( (HUD_CHARGE), (HUD_THROW), (HUD_MANEUVER), - (HUD_INTENT) + (HUD_INTENT), + (HUD_MODIFIERS) ) var/global/list/_ui_expected_states @@ -175,6 +176,10 @@ var/global/list/_ui_expected_states (HUD_THROW) = list( "act_throw_on", "act_throw_off" + ), + (HUD_MODIFIERS) = list( + "blank", + "modifier_base" ) ) diff --git a/code/modules/client/ui_styles/ui_style_subtypes.dm b/code/modules/client/ui_styles/ui_style_subtypes.dm index 7de6cc1183cd..e37aef4a9aba 100644 --- a/code/modules/client/ui_styles/ui_style_subtypes.dm +++ b/code/modules/client/ui_styles/ui_style_subtypes.dm @@ -17,7 +17,8 @@ (HUD_INVENTORY) = 'icons/mob/screen/styles/orange/inventory.dmi', (HUD_MOVEMENT) = 'icons/mob/screen/styles/orange/movement.dmi', (HUD_UP_HINT) = 'icons/mob/screen/styles/orange/uphint.dmi', - (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/orange/zone_selector.dmi' + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/orange/zone_selector.dmi', + (HUD_MODIFIERS) = 'icons/mob/screen/styles/orange/modifiers.dmi' ) /decl/ui_style/old @@ -34,7 +35,8 @@ (HUD_INVENTORY) = 'icons/mob/screen/styles/old/inventory.dmi', (HUD_MOVEMENT) = 'icons/mob/screen/styles/old/movement.dmi', (HUD_UP_HINT) = 'icons/mob/screen/styles/old/uphint.dmi', - (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/old/zone_selector.dmi' + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/old/zone_selector.dmi', + (HUD_MODIFIERS) = 'icons/mob/screen/styles/old/modifiers.dmi' ) /decl/ui_style/old_noborder @@ -51,7 +53,8 @@ (HUD_INVENTORY) = 'icons/mob/screen/styles/old_noborder/inventory.dmi', (HUD_MOVEMENT) = 'icons/mob/screen/styles/old/movement.dmi', (HUD_UP_HINT) = 'icons/mob/screen/styles/old_noborder/uphint.dmi', - (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/old_noborder/zone_selector.dmi' + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/old_noborder/zone_selector.dmi', + (HUD_MODIFIERS) = 'icons/mob/screen/styles/old_noborder/modifiers.dmi' ) /decl/ui_style/white @@ -68,7 +71,8 @@ (HUD_INVENTORY) = 'icons/mob/screen/styles/white/inventory.dmi', (HUD_MOVEMENT) = 'icons/mob/screen/styles/white/movement.dmi', (HUD_UP_HINT) = 'icons/mob/screen/styles/white/uphint.dmi', - (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/white/zone_selector.dmi' + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/white/zone_selector.dmi', + (HUD_MODIFIERS) = 'icons/mob/screen/styles/white/modifiers.dmi' ) use_overlay_color = TRUE use_ui_color = TRUE @@ -87,7 +91,8 @@ (HUD_INVENTORY) = 'icons/mob/screen/styles/minimalist/inventory.dmi', (HUD_MOVEMENT) = 'icons/mob/screen/styles/minimalist/movement.dmi', (HUD_UP_HINT) = 'icons/mob/screen/styles/minimalist/uphint.dmi', - (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/minimalist/zone_selector.dmi' + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/minimalist/zone_selector.dmi', + (HUD_MODIFIERS) = 'icons/mob/screen/styles/minimalist/modifiers.dmi' ) use_overlay_color = TRUE use_ui_color = TRUE @@ -106,7 +111,8 @@ (HUD_INVENTORY) = 'icons/mob/screen/styles/underworld/inventory.dmi', (HUD_MOVEMENT) = 'icons/mob/screen/styles/underworld/movement.dmi', (HUD_UP_HINT) = 'icons/mob/screen/styles/underworld/uphint.dmi', - (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/underworld/zone_selector.dmi' + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/underworld/zone_selector.dmi', + (HUD_MODIFIERS) = 'icons/mob/screen/styles/underworld/modifiers.dmi' ) use_overlay_color = TRUE use_ui_color = TRUE diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index 64d08080a018..588c193fbd94 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -71,7 +71,7 @@ /obj/item/clothing/Destroy() if(is_accessory()) - on_removed() + on_accessory_removed() return ..() /obj/item/clothing/get_fallback_slot(slot) diff --git a/code/modules/clothing/_clothing_accessories.dm b/code/modules/clothing/_clothing_accessories.dm index 0469f605d014..d958fc571e7a 100644 --- a/code/modules/clothing/_clothing_accessories.dm +++ b/code/modules/clothing/_clothing_accessories.dm @@ -91,7 +91,7 @@ /obj/item/clothing/proc/remove_accessory(mob/user, obj/item/clothing/accessory) if(!accessory || !(accessory in accessories) || !accessory.accessory_removable || !accessory.canremove) return - accessory.on_removed(user) + accessory.on_accessory_removed(user) update_icon() /obj/item/clothing/proc/removetie_verb() @@ -178,7 +178,7 @@ return TRUE return FALSE -/obj/item/clothing/proc/on_removed(var/mob/user) +/obj/item/clothing/proc/on_accessory_removed(var/mob/user) var/obj/item/clothing/holder = loc if(istype(holder)) if(user) diff --git a/code/modules/clothing/gloves/jewelry/rings/ring_aura.dm b/code/modules/clothing/gloves/jewelry/rings/ring_aura.dm deleted file mode 100644 index 2a6c167d7feb..000000000000 --- a/code/modules/clothing/gloves/jewelry/rings/ring_aura.dm +++ /dev/null @@ -1,29 +0,0 @@ -/obj/item/clothing/gloves/ring/aura_ring - icon = 'icons/clothing/accessories/jewelry/rings/ring_band_thick.dmi' - can_inscribe = FALSE - material = /decl/material/solid/metal/silver - abstract_type = /obj/item/clothing/gloves/ring/aura_ring - material_alteration = MAT_FLAG_ALTERATION_COLOR - var/obj/aura/granted_aura - -/obj/item/clothing/gloves/ring/aura_ring/update_name() - return - -/obj/item/clothing/gloves/ring/aura_ring/Initialize() - if(ispath(granted_aura)) - granted_aura = new granted_aura - . = ..() - -/obj/item/clothing/gloves/ring/aura_ring/Destroy() - QDEL_NULL(granted_aura) - . = ..() - -/obj/item/clothing/gloves/ring/aura_ring/equipped(var/mob/living/L, var/slot) - ..() - if(istype(granted_aura) && slot == slot_gloves_str) - L.add_aura(granted_aura) - -/obj/item/clothing/gloves/ring/aura_ring/dropped(var/mob/living/L) - ..() - if(istype(granted_aura)) - L.remove_aura(granted_aura) diff --git a/code/modules/clothing/gloves/jewelry/rings/ring_effect.dm b/code/modules/clothing/gloves/jewelry/rings/ring_effect.dm new file mode 100644 index 000000000000..cf46a141cceb --- /dev/null +++ b/code/modules/clothing/gloves/jewelry/rings/ring_effect.dm @@ -0,0 +1,18 @@ +/obj/item/clothing/gloves/ring/effect + icon = 'icons/clothing/accessories/jewelry/rings/ring_band_thick.dmi' + can_inscribe = FALSE + material = /decl/material/solid/metal/silver + abstract_type = /obj/item/clothing/gloves/ring/effect + material_alteration = MAT_FLAG_ALTERATION_COLOR + var/granted_effect + +/obj/item/clothing/gloves/ring/effect/update_name() + return + +/obj/item/clothing/gloves/ring/effect/Initialize() + if(granted_effect) + add_item_effect(granted_effect, list( + (IE_CAT_EXAMINE), + (IE_CAT_WIELDED) + )) + . = ..() diff --git a/code/modules/clothing/head/fated_key.dm b/code/modules/clothing/head/fated_key.dm index 626126d50c93..7b0052e22387 100644 --- a/code/modules/clothing/head/fated_key.dm +++ b/code/modules/clothing/head/fated_key.dm @@ -26,7 +26,7 @@ if(istype(starbearer) && !canremove) name = "halo of starfire" desc = "Beware the fire of the star-bearers; it is too terrible to touch." - starbearer.add_aura(new /obj/aura/regenerating(starbearer)) + starbearer.add_mob_modifier(/decl/mob_modifier/regeneration, source = src) body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_ARMS|SLOT_HEAD|SLOT_FACE|SLOT_EYES|SLOT_HANDS|SLOT_FEET|SLOT_TAIL item_flags |= ITEM_FLAG_AIRTIGHT diff --git a/code/modules/clothing/sensors/vitals_sensor.dm b/code/modules/clothing/sensors/vitals_sensor.dm index 706d9b99dd2d..396dc1dfc18a 100644 --- a/code/modules/clothing/sensors/vitals_sensor.dm +++ b/code/modules/clothing/sensors/vitals_sensor.dm @@ -44,7 +44,7 @@ . = ..() update_removable() -/obj/item/clothing/sensor/vitals/on_removed(mob/user) +/obj/item/clothing/sensor/vitals/on_accessory_removed(mob/user) . = ..() update_removable() diff --git a/code/modules/clothing/spacesuits/rig/modules/infiltration.dm b/code/modules/clothing/spacesuits/rig/modules/infiltration.dm index 59df2f32fcbc..0fe76208c172 100644 --- a/code/modules/clothing/spacesuits/rig/modules/infiltration.dm +++ b/code/modules/clothing/spacesuits/rig/modules/infiltration.dm @@ -46,7 +46,7 @@ var/mob/living/human/H = holder.wearer - if(H.add_cloaking_source(src)) + if(H.add_mob_modifier(/decl/mob_modifier/cloaked, source = src)) anim(H, 'icons/effects/effects.dmi', "electricity",null,20,null) /obj/item/rig_module/stealth_field/deactivate() @@ -56,7 +56,7 @@ var/mob/living/human/H = holder.wearer - if(H.remove_cloaking_source(src)) + if(H.remove_mob_modifier(/decl/mob_modifier/cloaked, source = src)) anim(H,'icons/mob/mob.dmi',,"uncloak",,H.dir) anim(H, 'icons/effects/effects.dmi', "electricity",null,20,null) diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 0eeb19c3a578..a132830f78d1 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -565,7 +565,7 @@ for(var/obj/item/thing in list(chest, boots, gloves, helmet)) thing.update_icon() - if(equipment_overlay_icon && LAZYLEN(installed_modules)) + if(equipment_overlay_icon && LAZYLEN(installed_modules) && istype(chest, /obj/item)) for(var/obj/item/rig_module/module in installed_modules) if(module.suit_overlay) chest.add_overlay(image("icon" = equipment_overlay_icon, "icon_state" = "[module.suit_overlay]", "dir" = SOUTH)) diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 95b0612b4f9e..bf3381bca6e7 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -60,10 +60,10 @@ if(ispath(camera)) camera = new camera(src) - camera.set_status(0) + camera.set_camera_status(0) if(camera) - camera.set_status(!camera.status) + camera.set_camera_status(!camera.status) if(camera.status) camera.c_tag = user.get_id_name() to_chat(user, "User scanned as [camera.c_tag]. Camera activated.") diff --git a/code/modules/clothing/webbing/holster.dm b/code/modules/clothing/webbing/holster.dm index c607d16c13e9..9269f35844ed 100644 --- a/code/modules/clothing/webbing/holster.dm +++ b/code/modules/clothing/webbing/holster.dm @@ -36,7 +36,7 @@ if(istype(holder)) holder.verbs |= /atom/proc/holster_verb -/obj/item/clothing/webbing/holster/on_removed(mob/user) +/obj/item/clothing/webbing/holster/on_accessory_removed(mob/user) var/obj/item/clothing/holder = loc if(istype(holder)) var/remove_verb = TRUE diff --git a/code/modules/events/ailments.dm b/code/modules/events/ailments.dm index a1d6fc894e85..cf49cd2110d1 100644 --- a/code/modules/events/ailments.dm +++ b/code/modules/events/ailments.dm @@ -1,7 +1,7 @@ /datum/event/ailments/start() var/list/candidates = list() for(var/mob/living/human/H in global.living_mob_list_) - if(H.client && !length(H.stasis_sources)) + if(H.client && !H.has_mob_modifier(/decl/mob_modifier/stasis)) candidates += H if(!length(candidates)) return diff --git a/code/modules/hydroponics/seed_mobs.dm b/code/modules/hydroponics/seed_mobs.dm index 852c7eaae74f..6f12b930e6e0 100644 --- a/code/modules/hydroponics/seed_mobs.dm +++ b/code/modules/hydroponics/seed_mobs.dm @@ -7,7 +7,7 @@ spawn(15 SECONDS) if(!host.ckey && !host.client) - host.death() // This seems redundant, but a lot of mobs don't + host.death() // This seems redundant, but a lot of mobs don't host.set_stat(DEAD) // handle death() properly. Better safe than etc. host.visible_message("\The [host] is malformed and unable to survive. It expires pitifully, leaving behind some seeds.") diff --git a/code/modules/implants/implant_types/adrenaline.dm b/code/modules/implants/implant_types/adrenaline.dm index e93b99158db2..ec6f6166e42b 100644 --- a/code/modules/implants/implant_types/adrenaline.dm +++ b/code/modules/implants/implant_types/adrenaline.dm @@ -26,9 +26,9 @@ uses-- to_chat(imp_in, "You feel a sudden surge of energy!") - imp_in.set_status(STAT_STUN, 0) - imp_in.set_status(STAT_WEAK, 0) - imp_in.set_status(STAT_PARA, 0) + imp_in.set_status_condition(STAT_STUN, 0) + imp_in.set_status_condition(STAT_WEAK, 0) + imp_in.set_status_condition(STAT_PARA, 0) /obj/item/implant/adrenalin/implanted(mob/source) source.StoreMemory("\A [src] can be activated by using the pale emote, say *pale to attempt to activate.", /decl/memory_options/system) diff --git a/code/modules/item_effects/item_effect_aura.dm b/code/modules/item_effects/item_effect_aura.dm deleted file mode 100644 index c30e3a36461a..000000000000 --- a/code/modules/item_effects/item_effect_aura.dm +++ /dev/null @@ -1,28 +0,0 @@ -/decl/item_effect/aura - abstract_type = /decl/item_effect/aura - var/aura_type - -/decl/item_effect/aura/can_do_wielded_effect(mob/user, obj/item/item, list/parameters) - return !!aura_type -/decl/item_effect/aura/do_wielded_effect(mob/user, obj/item/item, list/parameters) - if(!user.has_aura(aura_type)) - user.add_aura(aura_type) - return TRUE - -/decl/item_effect/aura/can_do_unwielded_effect(mob/user, obj/item/item, list/parameters) - return !!aura_type -/decl/item_effect/aura/do_unwielded_effect(mob/user, obj/item/item, list/parameters) - if(user.has_aura(aura_type)) - user.remove_aura(aura_type) - return TRUE - -/decl/item_effect/aura/on_examined(obj/item/item, mob/user) - var/obj/aura/aura = aura_type - to_chat(user, SPAN_NOTICE("\The [item] grants \a [initial(aura.name)] to the wielder.")) - -// Example effect; applies a regeneration aura. -/decl/item_effect/aura/regeneration - aura_type = /obj/aura/regenerating/item - -// Distinct type to avoid removing the wrong type on unwield. -/obj/aura/regenerating/item diff --git a/code/modules/item_effects/item_effect_debug.dm b/code/modules/item_effects/item_effect_debug.dm index 1533abda4836..ae834c4bf2c5 100644 --- a/code/modules/item_effects/item_effect_debug.dm +++ b/code/modules/item_effects/item_effect_debug.dm @@ -58,7 +58,7 @@ (IE_CAT_EXAMINE), (IE_CAT_RANGED) = list(IE_PAR_USES = 5) )) - add_item_effect(/decl/item_effect/aura/regeneration, list( + add_item_effect(/decl/item_effect/mob_modifier/regeneration, list( (IE_CAT_EXAMINE), (IE_CAT_WIELDED) )) diff --git a/code/modules/item_effects/item_effect_modifier.dm b/code/modules/item_effects/item_effect_modifier.dm new file mode 100644 index 000000000000..4535ccf073a1 --- /dev/null +++ b/code/modules/item_effects/item_effect_modifier.dm @@ -0,0 +1,27 @@ +/decl/item_effect/mob_modifier + abstract_type = /decl/item_effect/mob_modifier + var/modifier_archetype + +/decl/item_effect/mob_modifier/can_do_wielded_effect(mob/user, obj/item/item, list/parameters) + return !!modifier_archetype + +/decl/item_effect/mob_modifier/do_wielded_effect(mob/user, obj/item/item, list/parameters) + if(!user.has_mob_modifier(modifier_archetype, source = src)) + user.add_mob_modifier(modifier_archetype, source = item) + return TRUE + +/decl/item_effect/mob_modifier/can_do_unwielded_effect(mob/user, obj/item/item, list/parameters) + return !!modifier_archetype + +/decl/item_effect/mob_modifier/do_unwielded_effect(mob/user, obj/item/item, list/parameters) + if(user.has_mob_modifier(modifier_archetype, source = src)) + user.remove_mob_modifier(modifier_archetype, source = src) + return TRUE + +/decl/item_effect/mob_modifier/on_examined(obj/item/item, mob/user) + var/decl/mob_modifier/archetype = GET_DECL(modifier_archetype) + to_chat(user, SPAN_NOTICE("\The [item] grants \a [archetype] to the wielder.")) + +// Example effect; applies a regeneration modifier. +/decl/item_effect/mob_modifier/regeneration + modifier_archetype = /decl/mob_modifier/regeneration/item diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index fbc24657a603..e0fece6b5124 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -62,8 +62,6 @@ /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE ) - - var/obj/aura/mechshield/aura = null var/max_charge = 150 var/charge = 150 var/last_recharge = 0 @@ -72,10 +70,12 @@ /obj/item/mech_equipment/shields/installed(var/mob/living/exosuit/_owner) . = ..() - aura = new(owner, src) + if(owner) + owner.add_mob_modifier(/decl/mob_modifier/mechshield, source = src) /obj/item/mech_equipment/shields/uninstalled() - QDEL_NULL(aura) + if(owner) + owner.remove_mob_modifier(/decl/mob_modifier/mechshield, source = src) . = ..() /obj/item/mech_equipment/shields/attack_self(var/mob/user) @@ -91,23 +91,27 @@ if(difference > 0) for(var/mob/pilot in owner.pilots) - to_chat(pilot, SPAN_DANGER("Warning: Deflector shield failure detect, shutting down!")) + to_chat(pilot, SPAN_DANGER("Warning: Deflector shield failure detected, shutting down!")) toggle() playsound(owner.loc,'sound/mecha/internaldmgalarm.ogg',35,1) return difference else return 0 /obj/item/mech_equipment/shields/proc/toggle() - if(!aura) - return - aura.toggle() + + if(owner?.has_mob_modifier(/decl/mob_modifier/mechshield, source = src)) + owner.remove_mob_modifier(/decl/mob_modifier/mechshield, source = src) + else if(owner) + owner.add_mob_modifier(/decl/mob_modifier/mechshield, source = src) + + active = owner?.has_mob_modifier(/decl/mob_modifier/mechshield, source = src) + playsound(owner,'sound/weapons/flash.ogg',35,1) update_icon() - if(aura.active) + if(active) START_PROCESSING(SSobj, src) else STOP_PROCESSING(SSobj, src) - active = aura.active passive_power_use = active ? 1 KILOWATTS : 0 owner.update_icon() @@ -118,9 +122,7 @@ /obj/item/mech_equipment/shields/on_update_icon() . = ..() - if(!aura) - return - if(aura.active) + if(owner?.has_mob_modifier(/decl/mob_modifier/mechshield, source = src)) icon_state = "shield_droid_a" else icon_state = "shield_droid" @@ -141,91 +143,7 @@ return charge / max_charge /obj/item/mech_equipment/shields/get_hardpoint_maptext() - return "[(aura && aura.active) ? "ONLINE" : "OFFLINE"]: [round((charge / max_charge) * 100)]%" - -/obj/aura/mechshield - icon = 'icons/mecha/shield.dmi' - name = "mechshield" - var/obj/item/mech_equipment/shields/shields = null - var/active = 0 - layer = ABOVE_HUMAN_LAYER - var/north_layer = MECH_UNDER_LAYER - plane = DEFAULT_PLANE - pixel_x = 8 - pixel_y = 4 - mouse_opacity = MOUSE_OPACITY_UNCLICKABLE - -/obj/aura/mechshield/Initialize(var/maploading, var/obj/item/mech_equipment/shields/holder) - . = ..() - shields = holder - -/obj/aura/mechshield/added_to(var/mob/living/target) - . = ..() - target.add_vis_contents(src) - set_dir(target.dir) - events_repository.register(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mechshield, update_dir)) - -/obj/aura/mechshield/proc/update_dir(var/user, var/old_dir, var/dir) - set_dir(dir) - -/obj/aura/mechshield/set_dir(new_dir) - . = ..() - if(dir == NORTH) - layer = north_layer - else layer = initial(layer) - -/obj/aura/mechshield/Destroy() - if(user) - events_repository.unregister(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mechshield, update_dir)) - user.remove_vis_contents(src) - shields = null - . = ..() - -/obj/aura/mechshield/proc/toggle() - active = !active - - update_icon() - - if(active) - flick("shield_raise", src) - else - flick("shield_drop", src) - - -/obj/aura/mechshield/on_update_icon() - . = ..() - if(active) - icon_state = "shield" - else - icon_state = "shield_null" - -/obj/aura/mechshield/bullet_act(var/obj/item/projectile/P, var/def_zone) - if(!active) - return - if(shields) - if(shields.charge) - P.damage = shields.stop_damage(P.damage) - user.visible_message(SPAN_WARNING("\The [shields.owner]'s shields flash and crackle.")) - flick("shield_impact", src) - playsound(user,'sound/effects/basscannon.ogg',35,1) - //light up the night. - new /obj/effect/effect/smoke/illumination(user.loc, 5, 4, 1, "#ffffff") - if(P.damage <= 0) - return AURA_FALSE|AURA_CANCEL - - spark_at(user, amount=5) - -/obj/aura/mechshield/hitby(atom/movable/M, var/datum/thrownthing/TT) - . = ..() - if(.) - if(!active) - return - if(shields.charge && TT.speed <= 5) - user.visible_message(SPAN_WARNING("\The [shields.owner]'s shields flash briefly as they deflect \the [M].")) - flick("shield_impact", src) - playsound(user,'sound/effects/basscannon.ogg',10,1) - return AURA_FALSE|AURA_CANCEL - //Too fast! + return "[owner?.has_mob_modifier(/decl/mob_modifier/mechshield, source = src) ? "ONLINE" : "OFFLINE"]: [round((charge / max_charge) * 100)]%" //Melee! As a general rule I would recommend using regular objects and putting logic in them. /obj/item/mech_equipment/mounted_system/melee @@ -287,11 +205,10 @@ /obj/item/mech_equipment/ballistic_shield name = "exosuit ballistic shield" desc = "This formidable line of defense, sees widespread use in planetary peacekeeping operations and military formations alike." - icon_state = "mech_shield" //Rendering is handled by aura due to layering issues: TODO, figure out a better way to do this + icon_state = "mech_shield" restricted_hardpoints = list(HARDPOINT_LEFT_HAND, HARDPOINT_RIGHT_HAND) restricted_software = list(MECH_SOFTWARE_UTILITY) origin_tech = @'{"materials":2,"engineering":2}' - var/obj/aura/mech_ballistic/aura = null var/last_push = 0 var/chance = 60 //For attacks from the front, diminishing returns var/last_max_block = 0 //Blocking during a perfect block window resets this, else there is an anti spam @@ -300,10 +217,10 @@ /obj/item/mech_equipment/ballistic_shield/installed(mob/living/exosuit/_owner) . = ..() - aura = new(owner, src) + owner?.add_mob_modifier(/decl/mob_modifier/mech_ballistic, source = src) /obj/item/mech_equipment/ballistic_shield/uninstalled() - QDEL_NULL(aura) + owner?.remove_mob_modifier(/decl/mob_modifier/mech_ballistic, source = src) . = ..() /obj/item/mech_equipment/ballistic_shield/afterattack(atom/target, mob/living/user, inrange, params) @@ -379,70 +296,6 @@ //Reset timer for maximum chainblocks last_max_block = 0 -/obj/aura/mech_ballistic - icon = 'icons/mecha/ballistic_shield.dmi' - name = "mech_ballistic_shield" - var/obj/item/mech_equipment/ballistic_shield/shield = null - layer = MECH_UNDER_LAYER - plane = DEFAULT_PLANE - mouse_opacity = MOUSE_OPACITY_UNCLICKABLE - -/obj/aura/mech_ballistic/Initialize(maploading, obj/item/mech_equipment/ballistic_shield/holder) - . = ..() - shield = holder - - //Get where we are attached so we know what icon to use - if (holder && holder.owner) - var/mob/living/exosuit/E = holder.owner - for (var/hardpoint in E.hardpoints) - var/obj/item/mech_equipment/hardpoint_object = E.hardpoints[hardpoint] - if (holder == hardpoint_object) - icon_state = "mech_shield_[hardpoint]" - var/image/I = image(icon, "[icon_state]_over") - I.layer = ABOVE_HUMAN_LAYER - overlays.Add(I) - -/obj/aura/mech_ballistic/added_to(mob/living/target) - . = ..() - target.add_vis_contents(src) - set_dir(target.dir) - global.events_repository.register(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mech_ballistic, update_dir)) - -/obj/aura/mech_ballistic/proc/update_dir(user, old_dir, dir) - set_dir(dir) - -/obj/aura/mech_ballistic/Destroy() - if (user) - global.events_repository.unregister(/decl/observ/dir_set, user, src, TYPE_PROC_REF(/obj/aura/mech_ballistic, update_dir)) - user.remove_vis_contents(src) - shield = null - . = ..() - -/obj/aura/mech_ballistic/bullet_act(obj/item/projectile/P, def_zone) - . = ..() - if (shield && prob(shield.block_chance(P.damage, P.armor_penetration, source = P))) - user.visible_message(SPAN_WARNING("\The [P] is blocked by \the [user]'s [shield.name].")) - user.bullet_impact_visuals(P, def_zone, 0) - shield.on_block_attack() - return AURA_FALSE|AURA_CANCEL - -/obj/aura/mech_ballistic/hitby(atom/movable/AM, datum/thrownthing/TT) - . = ..() - if (. && shield) - var/throw_damage = AM.get_thrown_attack_force() * (TT.speed/THROWFORCE_SPEED_DIVISOR) - if (prob(shield.block_chance(throw_damage, 0, source = AM, attacker = TT.thrower))) - user.visible_message(SPAN_WARNING("\The [AM] bounces off \the [user]'s [shield].")) - playsound(user.loc, 'sound/weapons/Genhit.ogg', 50, 1) - shield.on_block_attack() - return AURA_FALSE|AURA_CANCEL - -/obj/aura/mech_ballistic/attackby(obj/item/I, mob/user) - . = ..() - if (shield && prob(shield.block_chance(I.get_attack_force(), I.armor_penetration, source = I, attacker = user))) - user.visible_message(SPAN_WARNING("\The [I] is blocked by \the [user]'s [shield.name].")) - playsound(user.loc, 'sound/weapons/Genhit.ogg', 50, 1) - return AURA_FALSE|AURA_CANCEL - /obj/item/mech_equipment/flash name = "exosuit flash" icon_state = "mech_flash" diff --git a/code/modules/mechs/mech_damage_immunity.dm b/code/modules/mechs/mech_damage_immunity.dm index 067c613d56d0..01a8ef4a0f13 100644 --- a/code/modules/mechs/mech_damage_immunity.dm +++ b/code/modules/mechs/mech_damage_immunity.dm @@ -5,7 +5,7 @@ STAT_PARA ) -/mob/living/exosuit/set_status(condition, amount) +/mob/living/exosuit/set_status_condition(condition, amount) . = !(condition in ignore_status_conditions) && ..() /mob/living/exosuit/getOxyLoss() diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm index 0ae0efae9437..65c207b4ec7c 100644 --- a/code/modules/mob/death.dm +++ b/code/modules/mob/death.dm @@ -92,7 +92,7 @@ reset_plane_and_layer() update_posture() if(!gibbed) - clear_status_effects() + clear_status_conditions() set_sight(sight|SEE_TURFS|SEE_MOBS|SEE_OBJS) set_see_in_dark(8) diff --git a/code/modules/mob/grab/grab_object.dm b/code/modules/mob/grab/grab_object.dm index 5c5e427cea5a..dc0614ccbac2 100644 --- a/code/modules/mob/grab/grab_object.dm +++ b/code/modules/mob/grab/grab_object.dm @@ -204,7 +204,7 @@ /obj/item/grab/proc/action_used() if(ishuman(assailant)) var/mob/living/human/H = assailant - H.remove_cloaking_source(H.species) + H.remove_mob_modifier(/decl/mob_modifier/cloaked, source = H.species) last_action = world.time leave_forensic_traces() diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index b553c2c59af0..cf61d2ef7576 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -57,9 +57,9 @@ /mob/living/bot/handle_regular_status_updates() . = ..() if(.) - set_status(STAT_WEAK, 0) - set_status(STAT_STUN, 0) - set_status(STAT_PARA, 0) + set_status_condition(STAT_WEAK, 0) + set_status_condition(STAT_STUN, 0) + set_status_condition(STAT_PARA, 0) /mob/living/bot/get_life_damage_types() var/static/list/life_damage_types = list( diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index faca3a286c20..e612a4e3d72c 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -51,11 +51,11 @@ /mob/living/bot/secbot/turn_on() ..() - stun_baton.set_status(on, null) + stun_baton.set_cell_status(on, null) /mob/living/bot/secbot/turn_off() ..() - stun_baton.set_status(on, null) + stun_baton.set_cell_status(on, null) /mob/living/bot/secbot/on_update_icon() ..() diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index 9cf4a04aee72..0472a5074e30 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -496,7 +496,6 @@ //Handle old species transition if(species) - species.remove_base_auras(src) species.remove_inherent_verbs(src) //Update our species diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm index 00c8a932b860..747a1d5439cb 100644 --- a/code/modules/mob/living/human/human_attackhand.dm +++ b/code/modules/mob/living/human/human_attackhand.dm @@ -232,7 +232,7 @@ /mob/living/human/attack_hand(mob/user) - remove_cloaking_source(species) + remove_mob_modifier(/decl/mob_modifier/cloaked, source = species) if(!user.check_intent(I_FLAG_GRAB)) for (var/obj/item/grab/grab as anything in user.get_active_grabs()) if(grab.assailant == user && grab.affecting == src && grab.resolve_openhand_attack()) diff --git a/code/modules/mob/living/human/human_grabs.dm b/code/modules/mob/living/human/human_grabs.dm index c9fadf93e18a..38987122e3b7 100644 --- a/code/modules/mob/living/human/human_grabs.dm +++ b/code/modules/mob/living/human/human_grabs.dm @@ -25,4 +25,4 @@ /mob/living/human/make_grab(atom/movable/target, grab_tag = /decl/grab/simple, defer_hand = FALSE, force_grab_tag = FALSE) . = ..() if(.) - remove_cloaking_source(species) + remove_mob_modifier(/decl/mob_modifier/cloaked, source = species) diff --git a/code/modules/mob/living/human/human_helpers.dm b/code/modules/mob/living/human/human_helpers.dm index 90035988c32d..39847bceef8c 100644 --- a/code/modules/mob/living/human/human_helpers.dm +++ b/code/modules/mob/living/human/human_helpers.dm @@ -181,72 +181,6 @@ SET_STATUS_MAX(src, STAT_BLURRY, 5) add_genetic_condition(GENE_COND_NEARSIGHTED, 10 SECONDS) -/mob/living/human - var/list/cloaking_sources - -// Returns true if, and only if, the human has gone from uncloaked to cloaked -/mob/living/human/proc/add_cloaking_source(var/datum/cloaking_source) - var/has_uncloaked = clean_cloaking_sources() - LAZYDISTINCTADD(cloaking_sources, weakref(cloaking_source)) - - // We don't present the cloaking message if the human was already cloaked just before cleanup. - if(!has_uncloaked && LAZYLEN(cloaking_sources) == 1) - update_icon() - src.visible_message("\The [src] seems to disappear before your eyes!", "You feel completely invisible.") - return TRUE - return FALSE - -#define CLOAK_APPEAR_OTHER "\The [src] appears from thin air!" -#define CLOAK_APPEAR_SELF "You have re-appeared." - -// Returns true if, and only if, the human has gone from cloaked to uncloaked -/mob/living/human/proc/remove_cloaking_source(var/datum/cloaking_source) - var/was_cloaked = LAZYLEN(cloaking_sources) - clean_cloaking_sources() - LAZYREMOVE(cloaking_sources, weakref(cloaking_source)) - - if(was_cloaked && !LAZYLEN(cloaking_sources)) - update_icon() - visible_message(CLOAK_APPEAR_OTHER, CLOAK_APPEAR_SELF) - return TRUE - return FALSE - -// Returns true if the human is cloaked, otherwise false (technically returns the number of cloaking sources) -/mob/proc/is_cloaked() - return FALSE - -/mob/living/human/is_cloaked() - if(clean_cloaking_sources()) - update_icon() - visible_message(CLOAK_APPEAR_OTHER, CLOAK_APPEAR_SELF) - return LAZYLEN(cloaking_sources) - -#undef CLOAK_APPEAR_OTHER -#undef CLOAK_APPEAR_SELF - -// Returns true if the human is cloaked by the given source -/mob/living/human/proc/is_cloaked_by(var/cloaking_source) - return LAZYISIN(cloaking_sources, weakref(cloaking_source)) - -// Returns true if this operation caused the mob to go from cloaked to uncloaked -/mob/living/human/proc/clean_cloaking_sources() - if(!cloaking_sources) - return FALSE - - var/list/rogue_entries = list() - for(var/entry in cloaking_sources) - var/weakref/W = entry - if(!W.resolve()) - cloaking_sources -= W - rogue_entries += W - - if(rogue_entries.len) // These entries did not cleanup after themselves before being destroyed - var/rogue_entries_as_string = jointext(map(rogue_entries, /proc/log_info_line), ", ") - PRINT_STACK_TRACE("[log_info_line(src)] - Following cloaking entries were removed during cleanup: [rogue_entries_as_string]") - - UNSETEMPTY(cloaking_sources) - return !cloaking_sources // If cloaking_sources wasn't initially null but is now, we've uncloaked - /mob/living/human/proc/has_meson_effect() var/datum/global_hud/global_hud = get_global_hud() return (global_hud.meson in equipment_overlays) diff --git a/code/modules/mob/living/human/life.dm b/code/modules/mob/living/human/life.dm index 83b79d2bf9cd..8514c5a6d80f 100644 --- a/code/modules/mob/living/human/life.dm +++ b/code/modules/mob/living/human/life.dm @@ -125,8 +125,8 @@ vision = GET_INTERNAL_ORGAN(src, vision_organ_tag) if(!vision_organ_tag) // Presumably if a species has no vision organs, they see via some other means. - set_status(STAT_BLIND, 0) - set_status(STAT_BLURRY, 0) + set_status_condition(STAT_BLIND, 0) + set_status_condition(STAT_BLURRY, 0) else if(!vision || (vision && !vision.is_usable())) // Vision organs cut out or broken? Permablind. SET_STATUS_MAX(src, STAT_BLIND, 2) SET_STATUS_MAX(src, STAT_BLURRY, 1) @@ -224,7 +224,7 @@ burn_dam = COLD_DAMAGE_LEVEL_2 else burn_dam = COLD_DAMAGE_LEVEL_3 - set_stasis(get_cryogenic_factor(bodytemperature), STASIS_COLD) + add_mob_modifier(/decl/mob_modifier/stasis, 2 SECONDS, source = src) if(!has_chemical_effect(CE_CRYO, 1)) take_overall_damage(burn=burn_dam, used_weapon = "Low Body Temperature") SET_HUD_ALERT_MAX(src, HUD_FIRE, 1) diff --git a/code/modules/mob/living/human/update_icons.dm b/code/modules/mob/living/human/update_icons.dm index ff824d2389b8..07d4bbbf6b9e 100644 --- a/code/modules/mob/living/human/update_icons.dm +++ b/code/modules/mob/living/human/update_icons.dm @@ -340,7 +340,7 @@ Please contact me on #coderbus IRC. ~Carn x /mob/living/human/update_hair(var/update_icons=1) var/obj/item/organ/external/head/head_organ = get_organ(BP_HEAD, /obj/item/organ/external/head) - var/list/new_accessories = head_organ?.get_mob_overlays() + var/list/new_accessories = head_organ?.get_limb_mob_overlays() set_current_mob_overlay(HO_HAIR_LAYER, new_accessories, update_icons) /mob/living/human/proc/update_skin(var/update_icons=1) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 7c8dd1bf7c89..0715ea9f3dd4 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -25,12 +25,9 @@ if(QDELETED(src)) // Destroyed by fire or pressure damage in handle_environment() return PROCESS_KILL handle_regular_status_updates() // Status & health update, are we dead or alive etc. - handle_stasis() - if(stat != DEAD) - if(!is_in_stasis()) - . = handle_living_non_stasis_processes() - aura_check(AURA_TYPE_LIFE) + if(stat != DEAD && !has_mob_modifier(/decl/mob_modifier/stasis)) + . = handle_living_non_stasis_processes() for(var/obj/item/grab/grab as anything in get_active_grabs()) grab.Process() @@ -42,7 +39,8 @@ handle_grasp() handle_stance() handle_regular_hud_updates() - handle_status_effects() + handle_status_conditions() + handle_mob_modifiers() return 1 /mob/living/proc/handle_grasp() @@ -445,6 +443,7 @@ //this handles hud updates. Calls update_vision() and handle_hud_icons() /mob/living/proc/handle_regular_hud_updates() + SHOULD_CALL_PARENT(TRUE) if(!should_do_hud_updates()) return FALSE diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a2bb5d26fa26..03966f65b00d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -233,8 +233,8 @@ default behaviour is: if(stat != DEAD && should_be_dead()) death() if(!QDELETED(src)) // death() may delete or remove us - set_status(STAT_BLIND, 1) - set_status(STAT_SILENCE, 0) + set_status_condition(STAT_BLIND, 1) + set_status_condition(STAT_SILENCE, 0) return TRUE //This proc is used for mobs which are affected by pressure to calculate the amount of pressure that actually @@ -330,17 +330,17 @@ default behaviour is: set_damage(OXY, 0) set_damage(CLONE, 0) set_damage(BRAIN, 0) - set_status(STAT_PARA, 0) - set_status(STAT_STUN, 0) - set_status(STAT_WEAK, 0) + set_status_condition(STAT_PARA, 0) + set_status_condition(STAT_STUN, 0) + set_status_condition(STAT_WEAK, 0) // shut down ongoing problems radiation = 0 bodytemperature = get_species()?.body_temperature || initial(bodytemperature) reset_genetic_conditions() - // fix all status conditions including blind/deaf - clear_status_effects() + // clear all status conditions including blind/deaf + clear_status_conditions() heal_overall_damage(get_damage(BRUTE), get_damage(BURN)) @@ -745,48 +745,14 @@ default behaviour is: to_chat(src, "Remember to stay in character for a mob of this type!") return 1 -/mob/proc/add_aura(var/obj/aura/aura, skip_icon_update = FALSE) - return FALSE - -/mob/living/add_aura(var/obj/aura/aura, skip_icon_update = FALSE) - if(ispath(aura)) - aura = new aura(src) - if(!istype(aura)) - return FALSE - LAZYDISTINCTADD(auras,aura) - if(!skip_icon_update) - update_icon() - return TRUE - -/mob/proc/has_aura(aura_type) - return FALSE - -/mob/living/has_aura(aura_type) - return length(auras) && (locate(aura_type) in auras) - -/mob/proc/remove_aura(var/obj/aura/aura, skip_icon_update = FALSE) - return FALSE - -/mob/living/remove_aura(var/obj/aura/aura, skip_icon_update = FALSE) - if(ispath(aura)) - aura = locate() in auras - if(!istype(aura)) - return FALSE - LAZYREMOVE(auras,aura) - if(!skip_icon_update) - update_icon() - return TRUE - /mob/living/Destroy() + clear_mob_modifiers() QDEL_NULL(aiming) QDEL_NULL_LIST(_hallucinations) QDEL_NULL_LIST(aimed_at_by) LAZYCLEARLIST(smell_cooldown) if(stressors) // Do not QDEL_NULL, keys are managed instances. stressors = null - if(auras) - for(var/a in auras) - remove_aura(a) // done in this order so that icon updates aren't triggered once all our organs are obliterated delete_inventory(TRUE) delete_organs() @@ -889,7 +855,7 @@ default behaviour is: if(!HAS_STATUS(src, STAT_PARA) && stat == CONSCIOUS) visible_message(SPAN_DANGER("\The [src] starts having a seizure!")) SET_STATUS_MAX(src, STAT_PARA, rand(8,16)) - set_status(STAT_JITTER, rand(150,200)) + set_status_condition(STAT_JITTER, rand(150,200)) take_damage(rand(50, 60), PAIN) /mob/living/proc/get_digestion_product() @@ -2024,3 +1990,5 @@ default behaviour is: pulling_punches = !pulling_punches to_chat(src, SPAN_NOTICE("You are now [pulling_punches ? "pulling your punches" : "not pulling your punches"].")) +/mob/living/is_cloaked() + return has_mob_modifier(/decl/mob_modifier/cloaked) diff --git a/code/modules/mob/living/living_appearance.dm b/code/modules/mob/living/living_appearance.dm index ea2bb37147ee..0b34b88f1405 100644 --- a/code/modules/mob/living/living_appearance.dm +++ b/code/modules/mob/living/living_appearance.dm @@ -10,17 +10,6 @@ SHOULD_CALL_PARENT(TRUE) ..() cut_overlays() - if(auras) - var/decl/bodytype/my_bodytype = get_bodytype() - for(var/obj/aura/aura as anything in auras) - var/image/A = new() - A.appearance = aura - if(my_bodytype) - if(my_bodytype.pixel_offset_x) - A.pixel_x += -(my_bodytype.pixel_offset_x) - if(my_bodytype.pixel_offset_y) - A.pixel_y += -(my_bodytype.pixel_offset_y) - add_overlay(A) try_refresh_visible_overlays() /mob/living/proc/set_organ_sprite_accessory(var/accessory_type, var/accessory_category, var/accessory_metadata, var/organ_tag, var/skip_update = FALSE) @@ -77,3 +66,24 @@ /mob/living/get_current_mob_underlay(var/underlay_layer) return mob_underlays[underlay_layer] + +/mob/living/refresh_visible_overlays() + . = ..() + var/list/modifier_overlays = null + for(var/decl/mob_modifier/archetype in _mob_modifiers) + var/image/status_overlay = archetype.get_modifier_mob_overlay(src) + if(status_overlay) + LAZYADD(modifier_overlays, status_overlay) + set_current_mob_overlay(HO_EFFECT_LAYER, modifier_overlays, FALSE) + +/decl/mob_modifier/proc/get_modifier_mob_overlay(mob/living/_owner) + if(!mob_overlay_icon || !mob_overlay_state || !istype(_owner)) + return null + var/image/mob_overlay = overlay_image(mob_overlay_icon, mob_overlay_state, COLOR_WHITE, RESET_COLOR) + var/decl/bodytype/owner_bodytype = _owner.get_bodytype() + if(owner_bodytype) + if(owner_bodytype.pixel_offset_x) + mob_overlay.pixel_x += -(owner_bodytype.pixel_offset_x) + if(owner_bodytype.pixel_offset_y) + mob_overlay.pixel_y += -(owner_bodytype.pixel_offset_y) + return mob_overlay diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index f6b7d220a18d..88842cb634e2 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -60,28 +60,6 @@ /mob/living/get_bullet_impact_effect_type(var/def_zone) return BULLET_IMPACT_MEAT -/mob/living/proc/aura_check(var/type) - if(!auras) - return TRUE - . = TRUE - var/list/newargs = args - args[1] - for(var/obj/aura/aura as anything in auras) - var/result = 0 - switch(type) - if(AURA_TYPE_WEAPON) - result = aura.attackby(arglist(newargs)) - if(AURA_TYPE_BULLET) - result = aura.bullet_act(arglist(newargs)) - if(AURA_TYPE_THROWN) - result = aura.hitby(arglist(newargs)) - if(AURA_TYPE_LIFE) - result = aura.life_tick() - if(result & AURA_FALSE) - . = FALSE - if(result & AURA_CANCEL) - break - - //Handles the effects of "stun" weapons /mob/living/proc/stun_effect_act(stun_amount, agony_amount, def_zone, used_weapon) flash_pain() @@ -139,7 +117,7 @@ if(31 to INFINITY) SET_STATUS_MAX(src, STAT_WEAK, 10) //This should work for now, more is really silly and makes you lay there forever - set_status(STAT_JITTER, min(shock_damage*5, 200)) + set_status_condition(STAT_JITTER, min(shock_damage*5, 200)) spark_at(loc, amount=5, cardinal_only = TRUE) @@ -192,7 +170,7 @@ SET_STATUS_MAX(M, STAT_WEAK, rand(4,8)) M.visible_message(SPAN_DANGER("\The [M] collides with \the [src]!")) - if(!aura_check(AURA_TYPE_THROWN, AM, TT.speed)) + if(mob_modifiers_block_attack(MM_ATTACK_TYPE_THROWN, AM, TT.speed)) return FALSE if(istype(AM, /obj)) @@ -402,3 +380,13 @@ if(shield.handle_shield(src, damage, damage_source, attacker, def_zone, attack_text)) return TRUE return FALSE + +/mob/living/mob_modifiers_block_attack(attack_type, atom/movable/attacker, additional_data) + . = FALSE + if(length(_mob_modifiers)) + for(var/decl/mob_modifier/archetype in _mob_modifiers) + var/result = archetype.check_modifiers_block_attack(src, _mob_modifiers[archetype], attack_type, attacker, additional_data) + if(result & MM_ATTACK_RESULT_DEFLECTED) + . = TRUE + if(result & MM_ATTACK_RESULT_BLOCKED) + break diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index b7ae767787e1..f7be925f7e9c 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -38,7 +38,6 @@ var/possession_candidate = FALSE // Can be possessed by ghosts if unplayed. var/job = null//Living - var/list/obj/aura/auras = null //Basically a catch-all aura/force-field thing. var/last_resist = 0 var/admin_paralyzed = FALSE @@ -56,8 +55,6 @@ var/list/stressors var/life_tick - var/list/stasis_sources - var/stasis_value var/nutrition = 400 var/hydration = 400 diff --git a/code/modules/mob/living/living_status.dm b/code/modules/mob/living/living_status.dm index 645b53234486..179412f6a7a7 100644 --- a/code/modules/mob/living/living_status.dm +++ b/code/modules/mob/living/living_status.dm @@ -1,9 +1,13 @@ -/mob // Defined on /mob to avoid having to pass args to every single attack_foo() proc. +// Defined on /mob to avoid having to pass args to every single attack_foo() proc. +/mob + // A STATUS CONDITION is a counter on an general incapacitating effect like sleep or blindness. + // STATUS CONDITION TRACKERS: var/list/status_counters var/list/pending_status_counters var/datum/status_marker_holder/status_markers -/mob/living/set_status(var/condition, var/amount) +// Status condition procs: +/mob/living/set_status_condition(var/condition, var/amount) if(QDELETED(src)) return FALSE if(!ispath(condition, /decl/status_condition)) @@ -57,7 +61,7 @@ var/decl/status_condition/status = GET_DECL(condition) status.handle_changed_amount(src, new_amount, last_amount) -/mob/living/handle_status_effects() +/mob/living/handle_status_conditions() . = ..() var/refresh_icon = FALSE for(var/condition in status_counters) @@ -66,13 +70,18 @@ if(GET_STATUS(src, condition) <= 0) status_counters -= condition refresh_icon = TRUE + if(status.associated_mob_modifier) + remove_mob_modifier(status.associated_mob_modifier, source = src) + else if(status.associated_mob_modifier) + add_mob_modifier(status.associated_mob_modifier, source = src) + if(refresh_icon) update_icon() -/mob/living/clear_status_effects() +/mob/living/clear_status_conditions() var/had_counters = !!LAZYLEN(status_counters) for(var/stype in status_counters) - set_status(stype, 0) + set_status_condition(stype, 0) status_counters = null pending_status_counters = null if(had_counters) diff --git a/code/modules/mob/living/silicon/login.dm b/code/modules/mob/living/silicon/login.dm index 3ff4653c93df..9f5a88f6cd1f 100644 --- a/code/modules/mob/living/silicon/login.dm +++ b/code/modules/mob/living/silicon/login.dm @@ -1,3 +1,3 @@ /mob/living/silicon/Login() ..() - set_status(STAT_ASLEEP, 0) + set_status_condition(STAT_ASLEEP, 0) diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index b53b8a9cfe2d..058e882d06b5 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -38,16 +38,15 @@ var/global/list/default_pai_software = list() /mob/living/silicon/pai/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1) if(user != src || !istype(card)) - if(ui) - ui.set_status(STATUS_CLOSE, 0) + ui?.set_nano_status(STATUS_CLOSE, 0) return if(ui_key != "main") var/datum/pai_software/S = software[ui_key] if(S && !S.toggle) S.on_ui_interact(src, ui, force_open) - else - if(ui) ui.set_status(STATUS_CLOSE, 0) + else if(ui) + ui.set_nano_status(STATUS_CLOSE, 0) return var/data[0] diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index ea41b012d303..765cf2b43f60 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -48,7 +48,7 @@ SHOULD_CALL_PARENT(FALSE) update_health() - set_status(STAT_PARA, min(GET_STATUS(src, STAT_PARA), 30)) + set_status_condition(STAT_PARA, min(GET_STATUS(src, STAT_PARA), 30)) if(HAS_STATUS(src, STAT_ASLEEP)) SET_STATUS_MAX(src, STAT_PARA, 3) @@ -68,7 +68,7 @@ SET_STATUS_MAX(src, STAT_BLIND, 2) if(has_genetic_condition(GENE_COND_DEAFENED)) - src.set_status(STAT_DEAF, 1) + src.set_status_condition(STAT_DEAF, 1) //update the state of modules and components here if (stat != CONSCIOUS) diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index c2fde015d1df..8787fc156965 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -192,7 +192,7 @@ /obj/item/borg/combat/shield name = "personal shielding" desc = "A powerful experimental module that turns aside or absorbs incoming attacks at the cost of charge." - icon = 'icons/obj/decals.dmi' + icon = 'icons/obj/signs/warnings.dmi' icon_state = "shock" var/shield_level = 0.5 //Percentage of damage absorbed by the shield. @@ -208,7 +208,7 @@ /obj/item/borg/combat/mobility name = "mobility module" desc = "By retracting limbs and tucking in its head, a combat android can roll at high speeds." - icon = 'icons/obj/decals.dmi' + icon = 'icons/obj/signs/warnings.dmi' icon_state = "shock" /obj/item/inflatable_dispenser diff --git a/code/modules/mob/living/stasis.dm b/code/modules/mob/living/stasis.dm index 76fda177df5f..256e98026747 100644 --- a/code/modules/mob/living/stasis.dm +++ b/code/modules/mob/living/stasis.dm @@ -1,26 +1,3 @@ -/mob/living/proc/set_stasis(var/factor, var/source = "misc") - var/decl/bodytype/my_bodytype = get_bodytype() - if(my_bodytype?.body_flags & BODY_FLAG_NO_STASIS) - return - LAZYSET(stasis_sources, source, factor) - -/mob/living/proc/is_in_stasis() - return stasis_value ? !!(life_tick % stasis_value) : FALSE - -/mob/living/proc/handle_stasis() - stasis_value = 0 - if(stasis_sources) - var/decl/bodytype/my_bodytype = get_bodytype() - if(!(my_bodytype?.body_flags & BODY_FLAG_NO_STASIS)) - for(var/source in stasis_sources) - stasis_value += stasis_sources[source] - stasis_sources = null - - if(stasis_value > 1 && GET_STATUS(src, STAT_DROWSY) < stasis_value * 4) - ADJ_STATUS(src, STAT_DROWSY, min(stasis_value, 3)) - if(stat == CONSCIOUS && prob(1)) - to_chat(src, SPAN_NOTICE("You feel slow and sluggish...")) - /mob/living/proc/get_cryogenic_factor(var/bodytemperature) if(isSynthetic()) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 982be328b221..aaef91f9a84d 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1477,3 +1477,7 @@ /mob/proc/isSynthetic() return FALSE +// Returns true if the mob is cloaked, otherwise false +/mob/proc/is_cloaked() + return FALSE + diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index a383f3b30fca..e11b0ff37c6e 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -92,7 +92,7 @@ //The last mob/living to push/drag/grab this mob (mostly used by slimes friend recognition) var/weakref/last_handled_by_mob - var/status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH //bitflags defining which status effects can be inflicted (replaces canweaken, canstun, etc) + var/status_flags = CANSTUN|CANWEAKEN|CANPARALYSE|CANPUSH //bitflags defining which status conditions can be inflicted (replaces canweaken, canstun, etc) var/area/lastarea = null diff --git a/code/modules/mob/mob_status.dm b/code/modules/mob/mob_status.dm index 0e2c45822b99..5e08a530c40b 100644 --- a/code/modules/mob/mob_status.dm +++ b/code/modules/mob/mob_status.dm @@ -1,9 +1,24 @@ // Stubs; see living_status.dm -/mob/proc/handle_status_effects() +/mob/proc/handle_status_conditions() SHOULD_CALL_PARENT(TRUE) -/mob/proc/clear_status_effects() +/mob/proc/clear_status_conditions() return -/mob/proc/set_status(var/condition, var/amount) +/mob/proc/set_status_condition(var/condition, var/amount) return + +/mob/proc/clear_mob_modifiers() + return FALSE + +/mob/proc/remove_mob_modifier(decl/mob_modifier/archetype, datum/source, skip_update = FALSE) + return FALSE + +/mob/proc/has_mob_modifier(decl/mob_modifier/archetype, datum/source) + return FALSE + +/mob/proc/add_mob_modifier(decl/mob_modifier/archetype, duration = MOB_MODIFIER_INDEFINITE, datum/source, skip_update = FALSE) + return FALSE + +/mob/proc/mob_modifiers_block_attack(...) + return FALSE // see living_defense.dm diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 6ec207ea1b87..21e905f85a66 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -5,7 +5,7 @@ drop_from_inventory(W) try_refresh_visible_overlays() ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) - set_status(STAT_STUN, 1) + set_status_condition(STAT_STUN, 1) icon = null set_invisibility(INVISIBILITY_ABSTRACT) for(var/t in get_external_organs()) @@ -18,7 +18,7 @@ //animation = null DEL_TRANSFORMATION_MOVEMENT_HANDLER(src) - set_status(STAT_STUN, 0) + set_status_condition(STAT_STUN, 0) update_posture() set_invisibility(initial(invisibility)) diff --git a/code/modules/mob_modifiers/_modifiers.dm b/code/modules/mob_modifiers/_modifiers.dm new file mode 100644 index 000000000000..677608454afb --- /dev/null +++ b/code/modules/mob_modifiers/_modifiers.dm @@ -0,0 +1,89 @@ +// Notes on mob modifiers: +// - added/removed from mob with add_mob_modifier(/decl/mob_modifier/foo, DURATION IN DS, source = SOME ATOM) +// - decl will generate a decl/mob_modifier based on the source of the modifier +// - decl heartbeat logic (actual modifier) will run once per life tick regardless of number of sources, if you want +// stacking modifiers it has to be implemented within the decl. + +/// Instanced 'modifiers' that sit on top of a mob and can expire over time or linger until dispelled. +/// Some are purely visual, others have associated modifiers. +/decl/mob_modifier + abstract_type = /decl/mob_modifier + /// Tooltip name of this modifier. + var/name + /// Tooltip description of this modifier. + var/desc + /// Icon to use for the HUD element. + var/hud_icon = 'icons/screen/mob_modifiers.dmi' + /// State to use for the HUD element. + var/hud_icon_state + /// Icon to draw from for the mob overlay modifier is present. + var/mob_overlay_icon + /// State to draw over the mob when modifier is present. + var/mob_overlay_state + /// Metadata type to create for this status modifier. + var/modifier_type = /datum/mob_modifier + /// Message shown to the target when modifier begins. + var/on_add_message_1p + /// Message shown to the audience when modifier begins. + var/on_add_message_3p + /// Message shown to the target when modifier ends. + var/on_end_message_1p + /// Message shown to the audience when modifier ends. + var/on_end_message_3p + /// Whether or not this modifier can be granted by admin (source-ambivalent) + var/can_be_admin_granted = FALSE + /// Whether or not this modifier shows a lemniscate when set to indefinite duration. + var/show_indefinite_duration = TRUE + /// Whether or not this modifier shows remaining time before expiry. + var/hide_expiry= FALSE + +/decl/mob_modifier/validate() + . = ..() + if(!hud_icon) + . += "no hud_icon set" + if(!istext(hud_icon_state)) + . += "null or invalid hud_icon_state" + if(hud_icon && hud_icon_state && !check_state_in_icon(hud_icon_state, hud_icon)) + . += "hud_icon '[hud_icon]' missing hud_icon_state '[hud_icon_state]'" + + if(mob_overlay_icon) + if(istext(mob_overlay_state)) + if(!check_state_in_icon(mob_overlay_state, mob_overlay_icon)) + . += "mob_overlay_icon '[mob_overlay_icon]' missing mob_overlay_state '[mob_overlay_state]'" + else + . += "null or invalid mob_overlay_state" + else if(mob_overlay_state) + . += "mob_overlay_state set but mob_overlay_icon not set" + +/decl/mob_modifier/proc/replace_tokens(message, mob/user) + return capitalize(emote_replace_user_tokens(message, user)) + +/decl/mob_modifier/proc/on_modifier_datum_added(mob/living/_owner, datum/mob_modifier/modifier) + if(on_add_message_3p) + _owner.visible_message(replace_tokens(on_add_message_3p, _owner), replace_tokens((on_add_message_3p || on_add_message_1p), _owner)) + else if(on_add_message_1p) + to_chat(_owner, replace_tokens(on_add_message_1p, _owner)) + return TRUE + +/decl/mob_modifier/proc/on_modifier_datum_removed(mob/living/_owner, datum/mob_modifier/modifier) + if(on_end_message_3p) + _owner.visible_message(replace_tokens(on_end_message_3p, _owner), replace_tokens((on_end_message_3p || on_end_message_1p), _owner)) + else if(on_end_message_1p) + to_chat(_owner, replace_tokens(on_end_message_1p, _owner)) + return TRUE + +/decl/mob_modifier/proc/on_modifier_datum_expiry(mob/living/_owner, datum/mob_modifier/modifier) + return TRUE + +/decl/mob_modifier/proc/on_modifier_datum_mob_life(mob/living/_owner, list/modifiers) + SHOULD_CALL_PARENT(TRUE) + . = FALSE + for(var/datum/mob_modifier/modifier in modifiers) + if(modifier.on_modifier_mob_life()) + . = TRUE + +/decl/mob_modifier/proc/on_modifier_datum_click(mob/living/_owner, datum/mob_modifier/modifier, params) + return FALSE + +/decl/mob_modifier/proc/check_modifiers_block_attack(mob/living/_owner, list/modifiers, attack_type, atom/movable/attacker, additional_data) + return FALSE diff --git a/code/modules/mob_modifiers/definitions/modifiers_cloaked.dm b/code/modules/mob_modifiers/definitions/modifiers_cloaked.dm new file mode 100644 index 000000000000..5ac1889ce59e --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_cloaked.dm @@ -0,0 +1,17 @@ +/decl/mob_modifier/cloaked + name = "Cloaked" + desc = "You are hidden from casual sight." + hud_icon_state = "cloaked" + on_add_message_1p = SPAN_NOTICE("You feel completely invisible.") + on_add_message_3p = SPAN_WARNING("$USER$ seems to disappear before your eyes!") + on_end_message_1p = SPAN_NOTICE("You have re-appeared.") + on_end_message_3p = SPAN_WARNING("$USER$ appears from thin air!") + can_be_admin_granted = TRUE + +// Not ideal, but existing cloaking code is iffy about removing cloaking sources appropriately (specifically rig modules) +/decl/mob_modifier/cloaked/on_modifier_datum_mob_life(mob/living/_owner, list/modifiers) + . = ..() + for(var/datum/mob_modifier/modifier in modifiers) + var/atom/source = modifier.source?.resolve() + if(istype(source) && source.get_recursive_loc_of_type(/mob/living) != _owner) + _owner.remove_mob_modifier(src, source = source) diff --git a/code/modules/mob_modifiers/definitions/modifiers_light.dm b/code/modules/mob_modifiers/definitions/modifiers_light.dm new file mode 100644 index 000000000000..9b352184cb7f --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_light.dm @@ -0,0 +1,39 @@ +/datum/mob_modifier/object/light + var/light_range = 6 + var/light_power = 6 + var/light_color = COLOR_BEIGE + +/decl/mob_modifier/light + name = "Light Aura" + desc = "You are emitting a gentle radiance." + hud_icon_state = "light" + on_add_message_1p = SPAN_NOTICE("A gentle radiance emanates from your body.") + on_end_message_1p = SPAN_NOTICE("The light spilling from your body fades.") + modifier_type = /datum/mob_modifier/object/light + can_be_admin_granted = TRUE + +/datum/mob_modifier/object/light/on_modifier_added(skip_update) + . = ..() + if(istype(object) && (light_range || light_power || light_color)) + object.set_light(light_range, light_power, light_color) + +/decl/mob_modifier/light/radiant + name = "Radiant Aura" + desc = "You are guarded from laser weapons by a radiant aura." + mob_overlay_icon = 'icons/effects/effects.dmi' + mob_overlay_state = "fire_goon" + on_add_message_1p = SPAN_NOTICE("A bubble of light appears around you, exuding protection and warmth.") + on_end_message_1p = SPAN_DANGER("Your protective aura dissipates, leaving you feeling cold and unsafe.") + modifier_type = /datum/mob_modifier/object/light + +/datum/mob_modifier/object/light/radiant + light_color = "#e09d37" + +/decl/mob_modifier/light/radiant/check_modifiers_block_attack(mob/living/_owner, list/modifiers, attack_type, atom/movable/attacker, additional_data) + if(attack_type != MM_ATTACK_TYPE_PROJECTILE) + return ..() + var/obj/item/projectile/projectile = attacker + if(istype(projectile) && (projectile.damage_flags() & DAM_LASER)) + _owner.visible_message(SPAN_WARNING("\The [projectile] refracts, bending into \the [_owner]'s radiance.")) + return (MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED) + return MM_ATTACK_RESULT_NONE diff --git a/code/modules/mob_modifiers/definitions/modifiers_mech_shields.dm b/code/modules/mob_modifiers/definitions/modifiers_mech_shields.dm new file mode 100644 index 000000000000..0c8d4112507f --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_mech_shields.dm @@ -0,0 +1,166 @@ +/decl/mob_modifier/mechshield + name = "Mech Energy Shield" + hud_icon_state = "shield" + modifier_type = /datum/mob_modifier/object/mechshield + +/decl/mob_modifier/mechshield/on_modifier_datum_added(mob/living/_owner, datum/mob_modifier/modifier) + . = ..() + if(istype(modifier, /datum/mob_modifier/object)) + var/datum/mob_modifier/object/obj_modifier = modifier + if(istype(obj_modifier.object)) + flick("shield_raise", obj_modifier.object) + +/decl/mob_modifier/mechshield/on_modifier_datum_removed(mob/living/_owner, datum/mob_modifier/modifier) + if(istype(modifier, /datum/mob_modifier/object)) + var/datum/mob_modifier/object/obj_modifier = modifier + if(istype(obj_modifier.object)) + var/obj/effect/temporary/drop_shield = new(get_turf(_owner)) + drop_shield.appearance = obj_modifier.object + flick("shield_drop", drop_shield) + QDEL_IN(drop_shield, 1 SECOND) + return ..() + +/datum/mob_modifier/object/mechshield + object = /obj/abstract/follower/mechshield + +/obj/abstract/follower/mechshield + name = "mechshield" + layer = ABOVE_HUMAN_LAYER + plane = DEFAULT_PLANE + icon = 'icons/mecha/shield.dmi' + icon_state = "shield" + pixel_x = 8 + pixel_y = 4 + mouse_opacity = MOUSE_OPACITY_UNCLICKABLE + invisibility = INVISIBILITY_NONE + alpha = 255 + hide_on_init = FALSE + +/obj/abstract/follower/mechshield/follow_owner(atom/movable/owner) + . = ..() + layer = (dir == NORTH) ? MECH_UNDER_LAYER : initial(layer) + +/decl/mob_modifier/mechshield/check_modifiers_block_attack(mob/living/_owner, list/modifiers, attack_type, atom/movable/attacker, additional_data) + + if(attack_type == MM_ATTACK_TYPE_WEAPON) + return ..() + + . = MM_ATTACK_RESULT_NONE + var/shield_hit = FALSE + if(attack_type == MM_ATTACK_TYPE_PROJECTILE) + + var/obj/item/projectile/projectile = attacker + if(!istype(projectile)) + return + + for(var/datum/mob_modifier/modifier in modifiers) + var/obj/item/mech_equipment/shields/shield = modifier.source?.resolve() + if(!istype(shield) || !shield.charge) + continue + if(!shield_hit) + _owner.visible_message(SPAN_WARNING("\The [shield.owner]'s shields flash and crackle.")) + shield_hit = TRUE + new /obj/effect/effect/smoke/illumination(_owner.loc, 5, 4, 1, "#ffffff") + spark_at(_owner, amount=5) + projectile.damage = shield.stop_damage(projectile.damage) + if(projectile.damage <= 0) + . = (MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED) + + else if(attack_type == MM_ATTACK_TYPE_THROWN) + + var/datum/thrownthing/thrown = additional_data + if(!istype(thrown) || thrown.speed > 5) + return + + for(var/datum/mob_modifier/modifier in modifiers) + var/obj/item/mech_equipment/shields/shield = modifier.source?.resolve() + if(istype(shield) && shield.charge) + _owner.visible_message(SPAN_WARNING("\The [shield.owner]'s shields flash briefly as they deflect \the [thrown.thrownthing].")) + shield_hit = TRUE + . = (MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED) + break + + //light up the night. + if(shield_hit) + playsound(_owner,'sound/effects/basscannon.ogg', 20, 1) + for(var/datum/mob_modifier/object/mechshield/obj_modifier in modifiers) + if(obj_modifier.object) + flick("shield_impact", obj_modifier.object) + +/decl/mob_modifier/mech_ballistic + name = "Mech Ballistic Shield" + hud_icon_state = "nanomachines" + modifier_type = /datum/mob_modifier/object/mechshield_ballistic + +/datum/mob_modifier/object/mechshield_ballistic + object = /obj/abstract/follower/mechshield_ballistic + +/datum/mob_modifier/object/mechshield_ballistic/on_modifier_added(skip_update = FALSE) + . = ..() + var/obj/item/mech_equipment/source_atom = source?.resolve() + if(!istype(source_atom) || !istype(object) || !istype(owner, /mob/living/exosuit)) + return + var/mob/living/exosuit/mech = owner + for(var/hardpoint in mech.hardpoints) + var/obj/item/mech_equipment/hardpoint_object = mech.hardpoints[hardpoint] + if(source_atom != hardpoint_object) + continue + object.icon_state = "mech_shield_[hardpoint]" + var/image/mech_overlay = image(object.icon, "[object.icon_state]_over") + mech_overlay.layer = ABOVE_HUMAN_LAYER + object.add_overlay(mech_overlay, priority = TRUE) + +/obj/abstract/follower/mechshield_ballistic + icon = 'icons/mecha/ballistic_shield.dmi' + layer = MECH_UNDER_LAYER + plane = DEFAULT_PLANE + mouse_opacity = MOUSE_OPACITY_UNCLICKABLE + invisibility = INVISIBILITY_NONE + alpha = 255 + hide_on_init = FALSE + +/decl/mob_modifier/mech_ballistic/check_modifiers_block_attack(mob/living/_owner, list/modifiers, attack_type, atom/movable/attacker, additional_data) + + if(attack_type == MM_ATTACK_TYPE_PROJECTILE) + + var/obj/item/projectile/projectile = attacker + if(istype(projectile)) + + var/target_zone = BP_CHEST + if(isliving(attacker)) + var/mob/living/attacker_mob = attacker + target_zone = attacker_mob.get_target_zone() + + for(var/datum/mob_modifier/modifier in modifiers) + var/obj/item/mech_equipment/ballistic_shield/shield = modifier.source?.resolve() + if(istype(shield) && prob(shield.block_chance(projectile.damage, projectile.armor_penetration, source = projectile))) + _owner.visible_message(SPAN_WARNING("\The [projectile] is blocked by \the [_owner]'s [shield.name].")) + _owner.bullet_impact_visuals(projectile, target_zone, 0) + shield.on_block_attack() + return (MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED) + + else if(attack_type == MM_ATTACK_TYPE_THROWN) + + var/datum/thrownthing/thrown = additional_data + if(istype(thrown)) + var/throw_damage = thrown.thrownthing.get_thrown_attack_force() * (thrown.speed/THROWFORCE_SPEED_DIVISOR) + for(var/datum/mob_modifier/modifier in modifiers) + var/obj/item/mech_equipment/ballistic_shield/shield = modifier.source?.resolve() + if(istype(shield) && prob(shield.block_chance(throw_damage, 0, source = thrown.thrownthing, attacker = thrown.thrower))) + _owner.visible_message(SPAN_WARNING("\The [thrown.thrownthing] bounces off \the [_owner]'s [shield].")) + playsound(_owner.loc, 'sound/weapons/Genhit.ogg', 50, 1) + shield.on_block_attack() + return (MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED) + + else if(attack_type == MM_ATTACK_TYPE_WEAPON) + + var/obj/item/weapon = additional_data + if(istype(weapon)) + for(var/datum/mob_modifier/modifier in modifiers) + var/obj/item/mech_equipment/ballistic_shield/shield = modifier.source?.resolve() + if(shield && prob(shield.block_chance(weapon.get_attack_force(), weapon.armor_penetration, source = weapon, attacker = _owner))) + _owner.visible_message(SPAN_WARNING("\The [weapon] is blocked by \the [_owner]'s [shield.name].")) + playsound(_owner.loc, 'sound/weapons/Genhit.ogg', 50, 1) + return (MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED) + + return ..() diff --git a/code/modules/mob_modifiers/definitions/modifiers_nanoswarm.dm b/code/modules/mob_modifiers/definitions/modifiers_nanoswarm.dm new file mode 100644 index 000000000000..ddb6d6023eae --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_nanoswarm.dm @@ -0,0 +1,34 @@ +//This handy augment protects you to a degree, keeping it online after critical damage however is bad +/decl/mob_modifier/nanoswarm + name = "Defensive Nanoswarm" + desc = "You are surrounded by nanomachines that harden in response to projectiles." + hud_icon_state = "nanomachines" + on_add_message_1p = SPAN_NOTICE("Your skin tingles as the nanites spread over your body.") + on_end_message_1p = SPAN_WARNING("The nanites dissolve!") + +/decl/mob_modifier/nanoswarm/on_modifier_datum_added(mob/living/_owner, decl/mob_modifier/modifier) + . = ..() + playsound(_owner.loc,'sound/weapons/flash.ogg',35,1) + +/decl/mob_modifier/nanoswarm/check_modifiers_block_attack(mob/living/_owner, list/modifiers, attack_type, atom/movable/attacker, additional_data) + if(attack_type != MM_ATTACK_TYPE_PROJECTILE) + return ..() + + var/obj/item/organ/internal/augment/active/nanounit/unit + for(var/datum/mob_modifier/modifier in modifiers) + var/obj/item/organ/internal/augment/active/nanounit/implant = modifier.source?.resolve() + if(istype(implant) && implant.active && implant.charges >= 0) // active with 0 charges means it's about to critically fail. + unit = implant + break + + if(!istype(unit)) + return ..() + + _owner.visible_message(SPAN_WARNING("The nanomachines harden as a response to physical trauma!")) + playsound(_owner, 'sound/effects/basscannon.ogg',35,1) + unit.charges-- + if(unit.charges <= 0) + to_chat(_owner, SPAN_DANGER("Warning: Critical damage threshold passed. Shut down unit to avoid further damage.")) + else + unit.catastrophic_failure() + return MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED diff --git a/code/modules/mob_modifiers/definitions/modifiers_object.dm b/code/modules/mob_modifiers/definitions/modifiers_object.dm new file mode 100644 index 000000000000..2904208d8c5e --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_object.dm @@ -0,0 +1,19 @@ +/datum/mob_modifier/object + var/obj/object = /obj/abstract/follower + +/datum/mob_modifier/object/Destroy(force) + if(istype(object)) + if(owner) + events_repository.unregister(/decl/observ/moved, owner, object) + events_repository.unregister(/decl/observ/dir_set, owner, object) + QDEL_NULL(object) + return ..() + +/datum/mob_modifier/object/on_modifier_added(skip_update = FALSE) + . = ..() + if(istype(owner)) + if(ispath(object)) + object = new object(get_turf(owner)) + if(istype(object)) + events_repository.register(/decl/observ/moved, owner, object, TYPE_PROC_REF(/obj/abstract/follower, follow_owner)) + events_repository.register(/decl/observ/dir_set, owner, object, TYPE_PROC_REF(/obj/abstract/follower, follow_owner)) diff --git a/code/modules/mob_modifiers/definitions/modifiers_prone.dm b/code/modules/mob_modifiers/definitions/modifiers_prone.dm new file mode 100644 index 000000000000..caf5b30c53b6 --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_prone.dm @@ -0,0 +1,10 @@ +/decl/mob_modifier/prone + name = "Prone" + desc = "You are lying prone and may need to stand up before taking action." + hud_icon_state = "prone" + show_indefinite_duration = FALSE + +/decl/mob_modifier/prone/on_modifier_datum_click(mob/living/_owner, decl/mob_modifier/modifier, params) + if(_owner.current_posture?.prone) + _owner.lay_down() + return TRUE diff --git a/code/modules/mob_modifiers/definitions/modifiers_regeneration.dm b/code/modules/mob_modifiers/definitions/modifiers_regeneration.dm new file mode 100644 index 000000000000..da18d3f80594 --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_regeneration.dm @@ -0,0 +1,123 @@ +/decl/mob_modifier/regeneration + name = "Regeneration" + desc = "You are rapidly recovering from physical trauma and poisons." + hud_icon_state = "regeneration" + can_be_admin_granted = TRUE + + var/brute_mult = 1 + var/fire_mult = 1 + var/tox_mult = 1 + +/decl/mob_modifier/regeneration/on_modifier_datum_mob_life(mob/living/_owner, list/modifiers) + . = ..() + _owner.heal_damage(BRUTE, brute_mult, do_update_health = FALSE) + _owner.heal_damage(BURN, fire_mult, do_update_health = FALSE) + _owner.heal_damage(TOX, tox_mult) + +/decl/mob_modifier/regeneration/organ + name = "Organ Regeneration" + desc = "Your body is rapidly recovering from physical trauma and poisons, so long as you can feed it." + var/nutrition_damage_mult = 1 //How much nutrition it takes to heal regular damage + var/external_nutrition_mult = 50 // How much nutrition it takes to regrow a limb + var/organ_mult = 2 + var/regen_message = SPAN_WARNING("Your body throbs as you feel your ORGAN regenerate.") + var/grow_chance = 15 + var/grow_threshold = 200 + var/ignore_tag = BP_BRAIN //organ tag to ignore + var/last_nutrition_warning = 0 + var/innate_heal = TRUE // Whether the aura is on, basically. + +/decl/mob_modifier/regeneration/organ/proc/external_regeneration_effect(mob/living/_owner, obj/item/organ/external/limb) + return + +/decl/mob_modifier/regeneration/organ/on_modifier_datum_mob_life(mob/living/_owner, list/modifiers) + . = ..() + if(!length(_owner.get_external_organs())) + return + if(!innate_heal || _owner.has_mob_modifier(/decl/mob_modifier/stasis) || _owner.stat == DEAD) + return + if(_owner.get_nutrition() < nutrition_damage_mult) + low_nut_warning(_owner) + return + + var/update_health = FALSE + var/organ_regen = get_config_value(/decl/config/num/health_organ_regeneration_multiplier) + if(brute_mult && _owner.get_damage(BRUTE)) + update_health = TRUE + _owner.heal_damage(BRUTE, brute_mult * organ_regen, do_update_health = FALSE) + _owner.adjust_nutrition(-nutrition_damage_mult) + if(fire_mult && _owner.get_damage(BURN)) + update_health = TRUE + _owner.heal_damage(BURN, fire_mult * organ_regen, do_update_health = FALSE) + _owner.adjust_nutrition(-nutrition_damage_mult) + if(tox_mult && _owner.get_damage(TOX)) + update_health = TRUE + _owner.heal_damage(TOX, tox_mult * organ_regen, do_update_health = FALSE) + _owner.adjust_nutrition(-nutrition_damage_mult) + if(update_health) + _owner.update_health() + if(!can_regenerate_organs()) + return + if(organ_mult) + if(prob(10) && _owner.nutrition >= 150 && !_owner.get_damage(BRUTE) && !_owner.get_damage(BURN)) + var/obj/item/organ/external/D = GET_EXTERNAL_ORGAN(_owner, BP_HEAD) + if (D.status & ORGAN_DISFIGURED) + if (_owner.nutrition >= 20) + D.status &= ~ORGAN_DISFIGURED + _owner.adjust_nutrition(-20) + else + low_nut_warning(_owner, BP_HEAD) + + var/list/organs = _owner.get_internal_organs() + for(var/obj/item/organ/internal/regen_organ in shuffle(organs.Copy())) + if(BP_IS_PROSTHETIC(regen_organ) || regen_organ.organ_tag == ignore_tag) + continue + if(istype(regen_organ)) + if(regen_organ.get_organ_damage() > 0 && !(regen_organ.status & ORGAN_DEAD)) + if (_owner.nutrition >= organ_mult) + regen_organ.adjust_organ_damage(-(organ_mult)) + _owner.adjust_nutrition(-(organ_mult)) + if(prob(5)) + to_chat(_owner, replacetext(regen_message,"ORGAN", regen_organ.name)) + else + low_nut_warning(_owner, regen_organ.name) + + if(prob(grow_chance)) + var/decl/bodytype/root_bodytype = _owner.get_bodytype() + for(var/limb_type in root_bodytype.has_limbs) + var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(_owner, limb_type) + if(limb && limb.organ_tag != BP_HEAD && !limb.is_vital_to_owner() && !limb.is_usable()) //Skips heads and vital bits... + if (_owner.nutrition > grow_threshold) + _owner.remove_organ(limb) //...because no one wants their head to explode to make way for a new one. + qdel(limb) + limb = null + else + low_nut_warning(_owner, limb.name) + if(!limb) + var/list/organ_data = root_bodytype.has_limbs[limb_type] + var/limb_path = organ_data["path"] + limb = new limb_path(_owner) + _owner.add_organ(limb, GET_EXTERNAL_ORGAN(_owner, limb.parent_organ), FALSE, FALSE) + _owner.adjust_nutrition(-external_nutrition_mult) + external_regeneration_effect(_owner, limb) + return + else if (_owner.nutrition > grow_threshold) //We don't subtract any nut here, but let's still only heal wounds when we have nut. + for(var/datum/wound/wound in limb.wounds) + if(wound.wound_damage() == 0 && prob(50)) + qdel(wound) + +/decl/mob_modifier/regeneration/organ/proc/low_nut_warning(mob/living/_owner, var/wound_type) + if (last_nutrition_warning + 1 MINUTE < world.time) + to_chat(_owner, SPAN_WARNING("You need more energy to regenerate your [wound_type || "wounds"].")) + last_nutrition_warning = world.time + return TRUE + return FALSE + +/decl/mob_modifier/regeneration/organ/proc/can_regenerate_organs() + return TRUE + +// Distinct type to avoid removing the wrong type on unwield. +/decl/mob_modifier/regeneration/item + name = "Regenerative Aura" + desc = "An item is helping your body heal physical damage and toxins." + can_be_admin_granted = FALSE \ No newline at end of file diff --git a/code/modules/mob_modifiers/definitions/modifiers_restrained.dm b/code/modules/mob_modifiers/definitions/modifiers_restrained.dm new file mode 100644 index 000000000000..6e281db036be --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_restrained.dm @@ -0,0 +1,9 @@ +/decl/mob_modifier/restrained + name = "Restrained" + desc = "You are restrained and need to resist to get out of your bindings." + hud_icon_state = "restrained" + show_indefinite_duration = FALSE + +/decl/mob_modifier/restrained/on_modifier_datum_click(mob/living/_owner, decl/mob_modifier/modifier, params) + _owner.resist() + return TRUE diff --git a/code/modules/mob_modifiers/definitions/modifiers_shield.dm b/code/modules/mob_modifiers/definitions/modifiers_shield.dm new file mode 100644 index 000000000000..1dcda7a53e11 --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_shield.dm @@ -0,0 +1,45 @@ +/decl/mob_modifier/shield + name = "Energy Shield" + desc = "You are protected from incoming projectiles." + hud_icon_state = "shield" + on_add_message_1p = SPAN_NOTICE("You feel your body prickle as your shield comes online.") + on_end_message_1p = SPAN_WARNING("Your shield goes offline!") + can_be_admin_granted = TRUE + +/decl/mob_modifier/shield/on_modifier_datum_added(mob/living/_owner, decl/mob_modifier/modifier) + . = ..() + if(. && _owner) + playsound(get_turf(_owner), 'sound/weapons/flash.ogg', 35, 1) + +/decl/mob_modifier/shield/on_modifier_datum_removed(mob/living/_owner, decl/mob_modifier/modifier) + . = ..() + if(. && _owner) + playsound(get_turf(_owner), 'sound/mecha/internaldmgalarm.ogg', 25,1) + +/decl/mob_modifier/shield/check_modifiers_block_attack(mob/living/_owner, list/modifiers, attack_type, atom/movable/attacker, additional_data) + if(attack_type != MM_ATTACK_TYPE_PROJECTILE) + return ..() + var/obj/item/projectile/projectile = attacker + if(istype(projectile)) + _owner.visible_message(SPAN_WARNING("\The [_owner]'s [src] flashes before \the [projectile] can hit them!")) + new /obj/effect/temporary(get_turf(_owner), 2 SECONDS, 'icons/obj/machines/shielding.dmi', "shield_impact") + playsound(_owner,'sound/effects/basscannon.ogg', 35, 1) + return (MM_ATTACK_RESULT_BLOCKED|MM_ATTACK_RESULT_DEFLECTED) + return MM_ATTACK_RESULT_NONE + +/decl/mob_modifier/shield/device + name = "Personal Shield" + desc = "You are protected from incoming projectiles by a personal shielding device - at least until it runs out of charges." + can_be_admin_granted = FALSE // Needs an item. + +/decl/mob_modifier/shield/device/check_modifiers_block_attack(mob/living/_owner, list/modifiers, attack_type, atom/movable/attacker, additional_data) + var/obj/item/projectile/projectile = attacker + if(!istype(projectile) || attack_type != MM_ATTACK_TYPE_PROJECTILE) + return ..() + var/found_shield = FALSE + for(var/datum/mob_modifier/modifier in modifiers) + var/obj/item/personal_shield/shield = modifier.source?.resolve() + if(istype(shield) && shield.expend_charge()) + found_shield = TRUE + break + return found_shield ? ..() : MM_ATTACK_RESULT_NONE diff --git a/code/modules/mob_modifiers/definitions/modifiers_stasis.dm b/code/modules/mob_modifiers/definitions/modifiers_stasis.dm new file mode 100644 index 000000000000..e855920a734c --- /dev/null +++ b/code/modules/mob_modifiers/definitions/modifiers_stasis.dm @@ -0,0 +1,26 @@ +/decl/mob_modifier/stasis + name = "Stasis" + desc = "Your life processes have been reduced or halted by stasis." + hud_icon_state = "stasis" + hide_expiry = TRUE + +/decl/mob_modifier/stasis/on_modifier_datum_mob_life(mob/living/_owner, list/modifiers) + . = ..() + + var/decl/bodytype/my_bodytype = _owner.get_bodytype() + if(my_bodytype?.body_flags & BODY_FLAG_NO_STASIS) + return + + var/stasis_power = 0 + for(var/datum/mob_modifier/modifier in modifiers) + var/atom/movable/source_atom = modifier.source?.resolve() + if(istype(source_atom)) + var/add_stasis = source_atom.get_cryogenic_power() + if(add_stasis) + stasis_power += add_stasis + to_chat(_owner, "[source_atom] gave [add_stasis]") + + if(stasis_power > 1 && GET_STATUS(_owner, STAT_DROWSY) < stasis_power * 4) + ADJ_STATUS(_owner, STAT_DROWSY, min(stasis_power, 3)) + if(_owner.stat == CONSCIOUS)// && prob(1)) + to_chat(_owner, SPAN_NOTICE("You feel slow and sluggish...")) diff --git a/code/modules/mob_modifiers/modifiers_datum.dm b/code/modules/mob_modifiers/modifiers_datum.dm new file mode 100644 index 000000000000..d7bc334dc528 --- /dev/null +++ b/code/modules/mob_modifiers/modifiers_datum.dm @@ -0,0 +1,75 @@ +// Subtype for tracking timer etc. No actual behavior associated with these. +/datum/mob_modifier + var/mob/living/owner + var/decl/mob_modifier/archetype + var/expire_time = MOB_MODIFIER_INDEFINITE + var/weakref/source + +/datum/mob_modifier/New(decl/mob_modifier/_archetype, mob/living/_owner, datum/_source) + archetype = istype(_archetype) ? _archetype : GET_DECL(_archetype) + owner = _owner + source = weakref(_source) + +/datum/mob_modifier/Destroy(force) + owner = null + return ..() + +// returns TRUE if the owner needs to run an update on mob modifiers following this run. +/datum/mob_modifier/proc/on_modifier_mob_life() + SHOULD_CALL_PARENT(TRUE) + . = FALSE + // We should not exist without an owner. + if(!istype(owner)) + qdel(src) + return TRUE + // Count down our timer, if necessary. + if(expire_time != MOB_MODIFIER_INDEFINITE) + . = TRUE + if(world.time >= expire_time) + on_modifier_expiry() + +/datum/mob_modifier/proc/on_modifier_removed(skip_update = FALSE) + SHOULD_CALL_PARENT(TRUE) + if(!istype(owner)) + return FALSE + var/list/modifiers = LAZYACCESS(owner._mob_modifiers, archetype) + if(!length(modifiers)) + return FALSE + modifiers -= src + // If this was our last modifier, clear the list. + if(!length(modifiers)) + LAZYREMOVE(owner._mob_modifiers, archetype) + archetype.on_modifier_datum_removed(owner, src) + if(!skip_update) + owner.refresh_hud_element(HUD_MODIFIERS) + if(archetype.mob_overlay_icon || archetype.mob_overlay_state) + owner.queue_icon_update() + qdel(src) + return TRUE + +/datum/mob_modifier/proc/on_modifier_added(skip_update = FALSE) + SHOULD_CALL_PARENT(TRUE) + if(!istype(owner)) + return FALSE + var/list/modifiers = LAZYACCESS(owner._mob_modifiers, archetype) + if(!modifiers) + modifiers = list() + LAZYSET(owner._mob_modifiers, archetype, modifiers) + if(src in modifiers) + return FALSE + modifiers += src + archetype.on_modifier_datum_added(owner, src) + if(!skip_update) + owner.refresh_hud_element(HUD_MODIFIERS) + if(archetype.mob_overlay_icon || archetype.mob_overlay_state) + owner.queue_icon_update() + return TRUE + +/datum/mob_modifier/proc/on_modifier_expiry() + SHOULD_CALL_PARENT(TRUE) + archetype.on_modifier_datum_expiry(owner, src) + return on_modifier_removed() + +/datum/mob_modifier/proc/on_modifier_click(params) + SHOULD_CALL_PARENT(TRUE) + archetype.on_modifier_datum_click(owner, src, params) diff --git a/code/modules/mob_modifiers/modifiers_helpers.dm b/code/modules/mob_modifiers/modifiers_helpers.dm new file mode 100644 index 000000000000..339ee093a855 --- /dev/null +++ b/code/modules/mob_modifiers/modifiers_helpers.dm @@ -0,0 +1,78 @@ + +/mob/living + // A modifier is a generalised effect on the mob, positive or negative, like buckling, healing or a curse. + var/list/_mob_modifiers + +/mob/living/proc/handle_mob_modifiers() + SHOULD_CALL_PARENT(TRUE) + for(var/decl/mob_modifier/archetype as anything in _mob_modifiers) + if(archetype.on_modifier_datum_mob_life(src, _mob_modifiers[archetype])) + . = TRUE + if(.) + refresh_hud_element(HUD_MODIFIERS) + +/mob/living/clear_mob_modifiers() + for(var/archetype as anything in _mob_modifiers) + for(var/datum/mob_modifier/modifier in _mob_modifiers[archetype]) + modifier.on_modifier_removed() + +/mob/living/remove_mob_modifier(decl/mob_modifier/archetype, datum/source, skip_update = FALSE) + + if(ispath(archetype)) + archetype = GET_DECL(archetype) + if(!istype(archetype)) + return FALSE + + // If we have no data, we can't clear it. + var/list/modifiers = LAZYACCESS(_mob_modifiers, archetype) + if(!length(modifiers)) + return FALSE + + // Source datum means we only remove an modifier that matches the source. + for(var/datum/mob_modifier/modifier as anything in modifiers) + if(!source || modifier.source?.resolve() == source) + modifier.on_modifier_removed() + . = TRUE + if(source) + return + + // We didn't find one to remove. Tragic. + return FALSE + +// If source is not provided, we only care that we have SOMETHING providing this modifier. +/mob/living/has_mob_modifier(decl/mob_modifier/archetype, datum/source) + if(ispath(archetype)) + archetype = GET_DECL(archetype) + if(!istype(archetype)) + return FALSE + var/list/modifiers = LAZYACCESS(_mob_modifiers, archetype) + if(!length(modifiers)) + return FALSE + if(!source) // We don't care about specifics. + return TRUE + for(var/datum/mob_modifier/modifier in modifiers) + if(modifier.source?.resolve() == source) + return TRUE + return FALSE + +/mob/living/add_mob_modifier(decl/mob_modifier/archetype, duration = MOB_MODIFIER_INDEFINITE, datum/source, skip_update = FALSE) + if(ispath(archetype)) + archetype = GET_DECL(archetype) + if(!istype(archetype) || !istype(source)) + return FALSE + + var/list/modifiers = LAZYACCESS(_mob_modifiers, archetype) + var/datum/mob_modifier/modifier + for(var/datum/mob_modifier/existing_modifier in modifiers) + if(existing_modifier.source?.resolve() == source) + modifier = existing_modifier + break + + if(!istype(modifier)) + modifier = new archetype.modifier_type(archetype, src, source) + if(duration != MOB_MODIFIER_INDEFINITE) + modifier.expire_time = world.time + duration + else + modifier.expire_time = MOB_MODIFIER_INDEFINITE + modifier.on_modifier_added(skip_update) + return TRUE diff --git a/code/modules/modular_computers/hardware/lan_port.dm b/code/modules/modular_computers/hardware/lan_port.dm index 8ffecb3d26a6..c55d9da47a32 100644 --- a/code/modules/modular_computers/hardware/lan_port.dm +++ b/code/modules/modular_computers/hardware/lan_port.dm @@ -31,7 +31,7 @@ terminal = new(get_turf(parent)) set_extension(src, /datum/extension/event_registration/shuttle_stationary, GET_DECL(/decl/observ/moved), parent, PROC_REF(check_terminal_prox), get_area(src)) events_repository.register(/decl/observ/destroyed, terminal, src, PROC_REF(unset_terminal)) - set_status(parent, PART_STAT_CONNECTED) + set_component_status(parent, PART_STAT_CONNECTED) /obj/item/stock_parts/computer/lan_port/proc/unset_terminal() remove_extension(src, /datum/extension/event_registration/shuttle_stationary) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index f2125ae38e31..c1dff1b5bf27 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -134,7 +134,7 @@ nanoui is used to open and update nano browser uis * * @return nothing */ -/datum/nanoui/proc/set_status(state, push_update) +/datum/nanoui/proc/set_nano_status(state, push_update) if (state != status) // Only update if it is different if (status == STATUS_DISABLED) status = state @@ -164,7 +164,7 @@ nanoui is used to open and update nano browser uis if(new_status == STATUS_CLOSE) close() return 1 - set_status(new_status, push_update) + set_nano_status(new_status, push_update) /** * Set the ui to auto update (every master_controller tick) diff --git a/code/modules/organs/external/_external_icons.dm b/code/modules/organs/external/_external_icons.dm index 61ed76c361c8..e10a803445c8 100644 --- a/code/modules/organs/external/_external_icons.dm +++ b/code/modules/organs/external/_external_icons.dm @@ -109,7 +109,7 @@ var/global/list/organ_icon_cache = list() global.organ_icon_cache[_icon_cache_key] = ret return ret -/obj/item/organ/external/proc/get_mob_overlays() +/obj/item/organ/external/proc/get_limb_mob_overlays() for(var/accessory_category in _sprite_accessories) var/list/draw_accessories = _sprite_accessories[accessory_category] for(var/accessory in draw_accessories) @@ -305,7 +305,7 @@ var/global/list/organ_icon_cache = list() icon = mob_icon // We may have some overlays of our own (hair, glowing eyes, layered markings) - var/list/additional_overlays = get_mob_overlays() + var/list/additional_overlays = get_limb_mob_overlays() if(length(additional_overlays)) for(var/new_overlay in additional_overlays) add_overlay(new_overlay) diff --git a/code/modules/organs/external/head.dm b/code/modules/organs/external/head.dm index e2d32062fb37..4b1886424b9f 100644 --- a/code/modules/organs/external/head.dm +++ b/code/modules/organs/external/head.dm @@ -125,7 +125,7 @@ ret.Blend(eyes_icon, ICON_OVERLAY) return ret -/obj/item/organ/external/head/get_mob_overlays() +/obj/item/organ/external/head/get_limb_mob_overlays() . = ..() var/image/eye_glow = get_organ_eyes_overlay() if(eye_glow) diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 0a83423de539..008ef91f52f4 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -213,7 +213,7 @@ owner.custom_pain("Your head feels numb and painful.",10) if(is_bruised() && prob(1) && !HAS_STATUS(owner, STAT_BLURRY)) to_chat(owner, "It becomes hard to see for some reason.") - owner.set_status(STAT_BLURRY, 10) + owner.set_status_condition(STAT_BLURRY, 10) var/held = owner.get_active_held_item() if(_organ_damage >= 0.5*max_damage && prob(1) && held) to_chat(owner, "Your hand won't respond properly, and you drop what you are holding!") diff --git a/code/modules/organs/internal/heart.dm b/code/modules/organs/internal/heart.dm index 8930a70e6b96..785a2da44382 100644 --- a/code/modules/organs/internal/heart.dm +++ b/code/modules/organs/internal/heart.dm @@ -114,7 +114,7 @@ return //Dead or cryosleep people do not pump the blood. - if(!owner || owner.is_in_stasis() || owner.stat == DEAD || owner.bodytemperature < 170) + if(!owner || owner.has_mob_modifier(/decl/mob_modifier/stasis) || owner.stat == DEAD || owner.bodytemperature < 170) return if(pulse != PULSE_NONE || BP_IS_PROSTHETIC(src)) @@ -173,7 +173,7 @@ FONT_HUGE(SPAN_DANGER("Blood sprays out from your [spray_organ]!")) ) SET_STATUS_MAX(owner, STAT_STUN, 1) - owner.set_status(STAT_BLURRY, 2) + owner.set_status_condition(STAT_BLURRY, 2) //AB occurs every heartbeat, this only throttles the visible effect next_blood_squirt = world.time + 80 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 365338cf6cac..4feed2fd06c9 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -227,7 +227,7 @@ var/result = PROJECTILE_FORCE_MISS if(hit_zone) def_zone = hit_zone //set def_zone, so if the projectile ends up hitting someone else later (to be implemented), it is more likely to hit the same part - if(!target_mob.aura_check(AURA_TYPE_BULLET, src,def_zone)) + if(target_mob.mob_modifiers_block_attack(MM_ATTACK_TYPE_PROJECTILE, src, def_zone)) return TRUE result = target_mob.bullet_act(src, def_zone) diff --git a/code/modules/reagents/chems/chems_drinks.dm b/code/modules/reagents/chems/chems_drinks.dm index b9ea85a8a9c7..899ecf64a652 100644 --- a/code/modules/reagents/chems/chems_drinks.dm +++ b/code/modules/reagents/chems/chems_drinks.dm @@ -549,7 +549,7 @@ SET_STATUS_MAX(M, STAT_DIZZY, 20) ADJ_STATUS(M, STAT_DIZZY, 2) ADJ_STATUS(M, STAT_JITTER, 2) - M.set_status(STAT_DROWSY, 0) + M.set_status_condition(STAT_DROWSY, 0) /decl/material/liquid/drink/grenadine name = "grenadine syrup" diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 82e201d287f5..2e8495de0a87 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -174,8 +174,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/pass_flags = 0 var/breathing_sound = 'sound/voice/monkey.ogg' - var/list/base_auras - var/job_skill_buffs = list() // A list containing jobs (/datum/job), with values the extra points that job receives. var/standing_jump_range = 2 @@ -412,21 +410,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 /decl/species/proc/get_manual_dexterity(var/mob/living/human/H) . = manual_dexterity -/decl/species/proc/add_base_auras(var/mob/living/human/H) - if(base_auras) - for(var/type in base_auras) - H.add_aura(new type(H), skip_icon_update = TRUE) - -/decl/species/proc/remove_base_auras(var/mob/living/human/H) - if(base_auras) - var/list/bcopy = base_auras.Copy() - for(var/a in H.auras) - var/obj/aura/A = a - if(is_type_in_list(a, bcopy)) - bcopy -= A.type - H.remove_aura(A) - qdel(A) - /decl/species/proc/remove_inherent_verbs(var/mob/living/human/H) if(inherent_verbs) for(var/verb_path in inherent_verbs) @@ -441,7 +424,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 /decl/species/proc/handle_post_spawn(var/mob/living/human/H) //Handles anything not already covered by basic species assignment. add_inherent_verbs(H) - add_base_auras(H) handle_movement_flags_setup(H) /decl/species/proc/handle_pre_spawn(var/mob/living/human/H) diff --git a/code/modules/status_conditions/_status.dm b/code/modules/status_conditions/_status_condition.dm similarity index 67% rename from code/modules/status_conditions/_status.dm rename to code/modules/status_conditions/_status_condition.dm index 49750b10a033..285748a63b88 100644 --- a/code/modules/status_conditions/_status.dm +++ b/code/modules/status_conditions/_status_condition.dm @@ -1,15 +1,31 @@ var/global/list/status_marker_holders = list() -// Check code/modules/mob/mob_status.dm code/modules/mob/living/living_status.dm -// for the procs that check/set/process these status conditions. +// Check code/modules/mob/mob_status.dm code/modules/mob/living/living_status.dm +// for the procs that check/set/process these status conditions. /decl/status_condition var/name var/check_flags = 0 var/list/victim_data + + var/hud_icon + var/hud_state + + var/decl/mob_modifier/associated_mob_modifier + var/status_marker_icon = 'icons/effects/status.dmi' var/status_marker_state var/status_marker_private = FALSE +/decl/status_condition/Initialize() + . = ..() + if(ispath(associated_mob_modifier)) + associated_mob_modifier = GET_DECL(associated_mob_modifier) + +/decl/status_condition/validate() + . = ..() + if(associated_mob_modifier && !istype(associated_mob_modifier)) + . += "invalid associated_mob_modifier '[associated_mob_modifier]'" + /decl/status_condition/proc/handle_changed_amount(var/mob/living/victim, var/new_amount, var/last_amount) set waitfor = FALSE diff --git a/code/modules/status_conditions/_status_markers.dm b/code/modules/status_conditions/_status_markers.dm index 9731e1881e67..c6e0f8ec8e58 100644 --- a/code/modules/status_conditions/_status_markers.dm +++ b/code/modules/status_conditions/_status_markers.dm @@ -1,3 +1,12 @@ +var/global/list/_status_marker_decls +/proc/get_status_marker_decls() + if(!global._status_marker_decls) + global._status_marker_decls = list() + for(var/decl/status_condition/cond as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/status_condition)) + if(cond.status_marker_icon && cond.status_marker_state) + global._status_marker_decls += cond + return global._status_marker_decls + /obj/status_marker name = "" mouse_opacity = MOUSE_OPACITY_UNCLICKABLE @@ -58,18 +67,14 @@ mob_image_personal.layer = POINTER_LAYER animate(mob_image_personal, pixel_z = 1, time = 3, easing = (SINE_EASING | EASE_OUT), loop = -1) - animate( pixel_z = -1, time = 6, easing = SINE_EASING, loop = -1) - animate( pixel_z = 0, time = 3, easing = (SINE_EASING | EASE_IN), loop = -1) + animate( pixel_z = -1, time = 6, easing = SINE_EASING, loop = -1) + animate( pixel_z = 0, time = 3, easing = (SINE_EASING | EASE_IN), loop = -1) - var/list/all_status = decls_repository.get_decls_of_subtype(/decl/status_condition) - for(var/status_type in all_status) - var/decl/status_condition/status = all_status[status_type] + for(var/decl/status_condition/status in get_status_marker_decls()) if(status.status_marker_icon && status.status_marker_state) - var/obj/status_marker/marker = new(null, status) mob_image.add_vis_contents(marker) LAZYSET(markers, status, marker) - marker = new(null, status) mob_image_personal.add_vis_contents(marker) LAZYSET(markers_personal, status, marker) diff --git a/code/modules/status_conditions/status_dizzy.dm b/code/modules/status_conditions/definitions/status_dizzy.dm similarity index 100% rename from code/modules/status_conditions/status_dizzy.dm rename to code/modules/status_conditions/definitions/status_dizzy.dm diff --git a/code/modules/status_conditions/status_jittery.dm b/code/modules/status_conditions/definitions/status_jittery.dm similarity index 100% rename from code/modules/status_conditions/status_jittery.dm rename to code/modules/status_conditions/definitions/status_jittery.dm diff --git a/code/modules/status_conditions/status_paralyzed.dm b/code/modules/status_conditions/definitions/status_paralyzed.dm similarity index 100% rename from code/modules/status_conditions/status_paralyzed.dm rename to code/modules/status_conditions/definitions/status_paralyzed.dm diff --git a/code/modules/status_conditions/status_sleeping.dm b/code/modules/status_conditions/definitions/status_sleeping.dm similarity index 100% rename from code/modules/status_conditions/status_sleeping.dm rename to code/modules/status_conditions/definitions/status_sleeping.dm diff --git a/code/modules/status_conditions/status_stunned.dm b/code/modules/status_conditions/definitions/status_stunned.dm similarity index 100% rename from code/modules/status_conditions/status_stunned.dm rename to code/modules/status_conditions/definitions/status_stunned.dm diff --git a/code/modules/status_conditions/status_weakened.dm b/code/modules/status_conditions/definitions/status_weakened.dm similarity index 100% rename from code/modules/status_conditions/status_weakened.dm rename to code/modules/status_conditions/definitions/status_weakened.dm diff --git a/code/modules/xenoarcheaology/_xenoarch.dm b/code/modules/xenoarcheaology/_xenoarch.dm new file mode 100644 index 000000000000..b0ccad3e1f21 --- /dev/null +++ b/code/modules/xenoarcheaology/_xenoarch.dm @@ -0,0 +1,12 @@ +#define XA_EFFECT_TOUCH 0 +#define XA_EFFECT_AURA 1 +#define XA_EFFECT_PULSE 2 +#define XA_MAX_EFFECT 2 + +#define XA_EFFECT_UNKNOWN 0 +#define XA_EFFECT_ENERGY 1 +#define XA_EFFECT_PSIONIC 2 +#define XA_EFFECT_ELECTRO 3 +#define XA_EFFECT_PARTICLE 4 +#define XA_EFFECT_ORGANIC 5 +#define XA_EFFECT_SYNTH 6 \ No newline at end of file diff --git a/code/modules/xenoarcheaology/artifacts/effects/_effect.dm b/code/modules/xenoarcheaology/artifacts/effects/_effect.dm index 6d441a98c4ca..f831aa2dd23d 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/_effect.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/_effect.dm @@ -1,6 +1,6 @@ /datum/artifact_effect var/name = "unknown" - var/operation_type = EFFECT_TOUCH + var/operation_type = XA_EFFECT_TOUCH var/effect_range = 4 var/atom/holder var/activated = 0 @@ -14,7 +14,7 @@ /datum/artifact_effect/New(var/atom/location) ..() holder = location - operation_type = rand(0, MAX_EFFECT) + operation_type = rand(0, XA_MAX_EFFECT) var/triggertype = pick(subtypesof(/datum/artifact_trigger)) trigger = new triggertype @@ -39,7 +39,7 @@ /datum/artifact_effect/Destroy() QDEL_NULL(trigger) . = ..() - + /datum/artifact_effect/proc/ToggleActivate(var/reveal_toggle = 1) if(activated) activated = 0 @@ -64,9 +64,9 @@ /datum/artifact_effect/proc/process() if(activated) - if(operation_type == EFFECT_AURA) + if(operation_type == XA_EFFECT_AURA) DoEffectAura() - if(operation_type == EFFECT_PULSE) + if(operation_type == XA_EFFECT_PULSE) pulse_tick++ if(pulse_tick >= pulse_period) pulse_tick = 0 @@ -75,17 +75,17 @@ /datum/artifact_effect/proc/getDescription() . = "" switch(origin_type) - if(EFFECT_ENERGY) + if(XA_EFFECT_ENERGY) . += "Concentrated energy emissions" - if(EFFECT_PSIONIC) + if(XA_EFFECT_PSIONIC) . += "Intermittent psionic wavefront" - if(EFFECT_ELECTRO) + if(XA_EFFECT_ELECTRO) . += "Electromagnetic energy" - if(EFFECT_PARTICLE) + if(XA_EFFECT_PARTICLE) . += "High frequency particles" - if(EFFECT_ORGANIC) + if(XA_EFFECT_ORGANIC) . += "Organically reactive exotic particles" - if(EFFECT_SYNTH) + if(XA_EFFECT_SYNTH) . += "Atomic synthesis" else . += "Low level energy emissions" @@ -93,11 +93,11 @@ . += " have been detected " switch(operation_type) - if(EFFECT_TOUCH) + if(XA_EFFECT_TOUCH) . += "interspersed throughout substructure and shell." - if(EFFECT_AURA) + if(XA_EFFECT_AURA) . += "emitting in an ambient energy field." - if(EFFECT_PULSE) + if(XA_EFFECT_PULSE) . += "emitting in periodic bursts." else . += "emitting in an unknown way." diff --git a/code/modules/xenoarcheaology/artifacts/effects/badfeeling.dm b/code/modules/xenoarcheaology/artifacts/effects/badfeeling.dm index 02f4612a86d2..8c9f2d98694e 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/badfeeling.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/badfeeling.dm @@ -1,6 +1,6 @@ /datum/artifact_effect/badfeeling name = "badfeeling" - origin_type = EFFECT_PSIONIC + origin_type = XA_EFFECT_PSIONIC var/static/list/messages = list("You feel worried.", "Something doesn't feel right.", "You get a strange feeling in your gut.", diff --git a/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm b/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm index d441c9dd2dde..34b02a83da74 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm @@ -1,7 +1,7 @@ //todo /datum/artifact_effect/cellcharge name = "cell charge" - origin_type = EFFECT_ELECTRO + origin_type = XA_EFFECT_ELECTRO var/last_message /datum/artifact_effect/cellcharge/DoEffectTouch(var/mob/user) diff --git a/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm b/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm index 13cc32c5161c..af5e8c2640ec 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm @@ -1,7 +1,7 @@ //todo /datum/artifact_effect/celldrain name = "cell drain" - origin_type = EFFECT_ELECTRO + origin_type = XA_EFFECT_ELECTRO var/last_message /datum/artifact_effect/celldrain/DoEffectTouch(var/mob/user) diff --git a/code/modules/xenoarcheaology/artifacts/effects/dnaswitch.dm b/code/modules/xenoarcheaology/artifacts/effects/dnaswitch.dm index 4f4fa21b0872..b599c8ab178c 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/dnaswitch.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/dnaswitch.dm @@ -1,6 +1,6 @@ /datum/artifact_effect/dnaswitch name = "dnaswitch" - origin_type = EFFECT_ORGANIC + origin_type = XA_EFFECT_ORGANIC var/severity var/static/list/feels = list( "You feel a little different.", @@ -14,7 +14,7 @@ /datum/artifact_effect/dnaswitch/New() ..() - if(operation_type == EFFECT_AURA) + if(operation_type == XA_EFFECT_AURA) severity = rand(5,30) else severity = rand(25,95) diff --git a/code/modules/xenoarcheaology/artifacts/effects/emp.dm b/code/modules/xenoarcheaology/artifacts/effects/emp.dm index e22dd21e5b2a..3fb29851f6e5 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/emp.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/emp.dm @@ -1,10 +1,10 @@ /datum/artifact_effect/emp name = "emp" - origin_type = EFFECT_ELECTRO + origin_type = XA_EFFECT_ELECTRO /datum/artifact_effect/emp/New() ..() - operation_type = EFFECT_PULSE + operation_type = XA_EFFECT_PULSE /datum/artifact_effect/emp/DoEffectPulse() if(holder) diff --git a/code/modules/xenoarcheaology/artifacts/effects/forcefield.dm b/code/modules/xenoarcheaology/artifacts/effects/forcefield.dm index 08df28860c2b..63dce1535476 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/forcefield.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/forcefield.dm @@ -1,6 +1,6 @@ /datum/artifact_effect/forcefield name = "force field" - origin_type = EFFECT_PARTICLE + origin_type = XA_EFFECT_PARTICLE var/list/created_field var/field_color diff --git a/code/modules/xenoarcheaology/artifacts/effects/gas_generation.dm b/code/modules/xenoarcheaology/artifacts/effects/gas_generation.dm index dd66a9c58655..0d636d1a9bb5 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/gas_generation.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/gas_generation.dm @@ -6,8 +6,8 @@ ..() if(!spawned_gas) spawned_gas = pick(decls_repository.get_decl_paths_of_subtype(/decl/material/gas)) - operation_type = pick(EFFECT_TOUCH, EFFECT_AURA) - origin_type = EFFECT_SYNTH + operation_type = pick((XA_EFFECT_TOUCH), (XA_EFFECT_AURA)) + origin_type = XA_EFFECT_SYNTH /datum/artifact_effect/gas/DoEffectTouch(var/mob/user) if(holder) diff --git a/code/modules/xenoarcheaology/artifacts/effects/goodfeeling.dm b/code/modules/xenoarcheaology/artifacts/effects/goodfeeling.dm index e5d88d10a300..ab6db622cf1f 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/goodfeeling.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/goodfeeling.dm @@ -1,6 +1,6 @@ /datum/artifact_effect/goodfeeling name = "good feeling" - origin_type = EFFECT_PSIONIC + origin_type = XA_EFFECT_PSIONIC var/static/list/messages = list("You feel good.", "Everything seems to be going alright.", "You've got a good feeling about this.", diff --git a/code/modules/xenoarcheaology/artifacts/effects/heal.dm b/code/modules/xenoarcheaology/artifacts/effects/heal.dm index 73bf53bc022a..8add3c135107 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/heal.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/heal.dm @@ -1,6 +1,6 @@ /datum/artifact_effect/heal name = "heal" - origin_type = EFFECT_ORGANIC + origin_type = XA_EFFECT_ORGANIC /datum/artifact_effect/heal/DoEffectTouch(var/mob/toucher) if(isliving(toucher)) diff --git a/code/modules/xenoarcheaology/artifacts/effects/hurt.dm b/code/modules/xenoarcheaology/artifacts/effects/hurt.dm index 238e8b998656..71d2cbd211a9 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/hurt.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/hurt.dm @@ -1,6 +1,6 @@ /datum/artifact_effect/hurt name = "hurt" - origin_type = EFFECT_ORGANIC + origin_type = XA_EFFECT_ORGANIC /datum/artifact_effect/hurt/DoEffectTouch(var/mob/toucher) if(isliving(toucher)) diff --git a/code/modules/xenoarcheaology/artifacts/effects/radiate.dm b/code/modules/xenoarcheaology/artifacts/effects/radiate.dm index 591dd8c3a81a..e4f24857c52b 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/radiate.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/radiate.dm @@ -5,7 +5,7 @@ /datum/artifact_effect/radiate/New() ..() radiation_strength = rand(10, 50) - origin_type = pick(EFFECT_PARTICLE, EFFECT_ORGANIC) + origin_type = pick((XA_EFFECT_PARTICLE), (XA_EFFECT_ORGANIC)) /datum/artifact_effect/radiate/DoEffectTouch(var/mob/living/user) if(istype(user)) diff --git a/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm b/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm index 3b9b2668484f..e2ad7fd09678 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm @@ -4,7 +4,7 @@ /datum/artifact_effect/roboheal/New() ..() - origin_type = pick(EFFECT_ELECTRO, EFFECT_PARTICLE) + origin_type = pick((XA_EFFECT_ELECTRO), (XA_EFFECT_PARTICLE)) /datum/artifact_effect/roboheal/DoEffectTouch(var/mob/user) if(isrobot(user)) diff --git a/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm b/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm index 0a83ddf57de3..c5dde6b16b62 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm @@ -4,7 +4,7 @@ /datum/artifact_effect/robohurt/New() ..() - origin_type = pick(EFFECT_ELECTRO, EFFECT_PARTICLE) + origin_type = pick((XA_EFFECT_ELECTRO), (XA_EFFECT_PARTICLE)) /datum/artifact_effect/robohurt/DoEffectTouch(var/mob/user) if(isrobot(user)) diff --git a/code/modules/xenoarcheaology/artifacts/effects/sleepy.dm b/code/modules/xenoarcheaology/artifacts/effects/sleepy.dm index 6bb1478a0ba7..f872eeccf491 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/sleepy.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/sleepy.dm @@ -9,7 +9,7 @@ /datum/artifact_effect/sleepy/New() ..() - origin_type = pick(EFFECT_PSIONIC, EFFECT_ORGANIC) + origin_type = pick((XA_EFFECT_PSIONIC), (XA_EFFECT_ORGANIC)) /datum/artifact_effect/sleepy/DoEffectTouch(var/mob/living/toucher) if(istype(toucher)) @@ -40,5 +40,5 @@ return if(prob(message_prob)) to_chat(H, SPAN_NOTICE(pick(sleepy_messages))) - H.set_status(STAT_DROWSY, min(GET_STATUS(H, STAT_DROWSY) + speed * weakness, limit * weakness)) - H.set_status(STAT_BLURRY, min(GET_STATUS(H, STAT_BLURRY) + speed * weakness, limit * weakness)) \ No newline at end of file + H.set_status_condition(STAT_DROWSY, min(GET_STATUS(H, STAT_DROWSY) + speed * weakness, limit * weakness)) + H.set_status_condition(STAT_BLURRY, min(GET_STATUS(H, STAT_BLURRY) + speed * weakness, limit * weakness)) \ No newline at end of file diff --git a/code/modules/xenoarcheaology/artifacts/effects/stun.dm b/code/modules/xenoarcheaology/artifacts/effects/stun.dm index 257a9976bf46..ac0c9598f888 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/stun.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/stun.dm @@ -3,7 +3,7 @@ /datum/artifact_effect/stun/New() ..() - origin_type = pick(EFFECT_PSIONIC, EFFECT_ORGANIC) + origin_type = pick((XA_EFFECT_PSIONIC), (XA_EFFECT_ORGANIC)) /datum/artifact_effect/stun/DoEffectTouch(var/mob/toucher) if(isliving(toucher)) diff --git a/code/modules/xenoarcheaology/artifacts/effects/teleport.dm b/code/modules/xenoarcheaology/artifacts/effects/teleport.dm index ac710fc71a36..255bdd62d2e4 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/teleport.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/teleport.dm @@ -1,6 +1,6 @@ /datum/artifact_effect/teleport name = "teleport" - origin_type = EFFECT_PSIONIC + origin_type = XA_EFFECT_PSIONIC /datum/artifact_effect/teleport/DoEffectTouch(var/mob/user) teleport_away(user) diff --git a/code/modules/xenoarcheaology/artifacts/effects/temperature.dm b/code/modules/xenoarcheaology/artifacts/effects/temperature.dm index a50047249fbe..4ca5b5e72bc8 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/temperature.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/temperature.dm @@ -7,10 +7,10 @@ /datum/artifact_effect/temperature/New() ..() - operation_type = pick(EFFECT_TOUCH, EFFECT_AURA) - origin_type = pick(EFFECT_ORGANIC, EFFECT_SYNTH) + operation_type = pick((XA_EFFECT_TOUCH), (XA_EFFECT_AURA)) + origin_type = pick((XA_EFFECT_ORGANIC), (XA_EFFECT_SYNTH)) if(!direction) - direction = pick(ANOM_EFFECT_COOLING, ANOM_EFFECT_HEATING) + direction = pick((ANOM_EFFECT_COOLING), (ANOM_EFFECT_HEATING)) switch(direction) if(ANOM_EFFECT_COOLING) target_temp = rand(TCMB, T0C - 30) @@ -38,7 +38,7 @@ return air.temperature > target_temp if(ANOM_EFFECT_HEATING) return air.temperature < target_temp - + /datum/artifact_effect/temperature/proc/change_air_temp(datum/gas_mixture/air, degrees) var/new_temp = air.temperature + degrees if(direction == ANOM_EFFECT_COOLING) diff --git a/code/modules/xenoarcheaology/machinery/artifact_harvester.dm b/code/modules/xenoarcheaology/machinery/artifact_harvester.dm index 848a0033f32a..15c69a09bbeb 100644 --- a/code/modules/xenoarcheaology/machinery/artifact_harvester.dm +++ b/code/modules/xenoarcheaology/machinery/artifact_harvester.dm @@ -130,7 +130,7 @@ inserted_battery.battery_effect.process() //if the effect works by touch, activate it on anyone near the console - if(inserted_battery.battery_effect.operation_type == EFFECT_TOUCH) + if(inserted_battery.battery_effect.operation_type == (XA_EFFECT_TOUCH)) for(var/mob/M in hearers(1, src)) inserted_battery.battery_effect.DoEffectTouch(M) diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm index 86f037fd0f88..fcc690b4642f 100644 --- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm +++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm @@ -110,12 +110,12 @@ if(!inserted_battery.battery_effect.activated) inserted_battery.battery_effect.ToggleActivate(1) switch(inserted_battery.battery_effect.operation_type) - if(EFFECT_TOUCH) + if(XA_EFFECT_TOUCH) visible_message("\The [src] shudders.") if(ismob(loc)) inserted_battery.battery_effect.DoEffectTouch(loc) inserted_battery.use_power(energy_consumed_on_touch) - if(EFFECT_PULSE) + if(XA_EFFECT_PULSE) inserted_battery.battery_effect.pulse_tick = inserted_battery.battery_effect.pulse_period //consume power relative to the time the artifact takes to charge and the effect range inserted_battery.use_power(inserted_battery.battery_effect.effect_range * inserted_battery.battery_effect.effect_range * inserted_battery.battery_effect.pulse_period) @@ -192,7 +192,7 @@ /obj/item/anodevice/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) if (!istype(target)) return ..() - if(activated && inserted_battery?.battery_effect?.operation_type == EFFECT_TOUCH) + if(activated && inserted_battery?.battery_effect?.operation_type == XA_EFFECT_TOUCH) inserted_battery.battery_effect.DoEffectTouch(target) inserted_battery.use_power(energy_consumed_on_touch) user.visible_message(SPAN_NOTICE("\The [user] taps [target] with \the [src], and it shudders on contact.")) diff --git a/icons/mob/screen/styles/midnight/modifiers.dmi b/icons/mob/screen/styles/midnight/modifiers.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6cc3b0b6b5d5ed77a6e0d0d91a428d293c4f9504 GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ=Bkj05|`BCNNYRZm}jcXw6GIF(?Ma_x!v&tKcODZf}X z>DkfrpWCx}Cb!DU)-n`NQ2#T7o8t%2Icq#!977^n-%dB=YB3OS4c{=MY=X$PP3fC% zFy}qgEE4dXoirgcIA`Njp_K4uK8{cIQy-~+{MxuRZ$maiUl8Ih`ACxciLvn1NYw7 zv$7>HAfX3wY)%rLJ8#DLe42YeX}NNYRZm}jcXw6GIF(?Ma_x!v&tKcODZf}X z>DkfrpWCx}Cb!DU)-n`NQ2#T7o8t%2IUSxZjv*1PZ?A9UZ7|?rIlz7~rANL&bAnNc z%91w+7~~G?h6X8$91uFYyY8lXx&76skI!`iyNk~Ko?N4u%G{v&i21F>$%T7nmb%0Uyp9yT3_&9uKz=7F<4h)Pe0x-gf@!dYVvn{5|#>^)bU9w#r0?b+J d^p?jzV`-8%2)+2M_$$y&44$rjF6*2UngAN{h;#q| literal 0 HcmV?d00001 diff --git a/icons/mob/screen/styles/modifiers.dmi b/icons/mob/screen/styles/modifiers.dmi new file mode 100644 index 0000000000000000000000000000000000000000..fb652724b08c79f42d97b816ac23078be37ee300 GIT binary patch literal 233 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnL3?x0byx0z;m;-!5Tn`*LkmkKF1;}MA3GxeO zaCmkj4aljf3W+FjNi9w;$}A|!%+F(BsF)KRR!~&>{Y!Ac$FEPcymhtCojD)8A=Kca z@qJFl6i-n9lmGqL1)w{4JY5_^IA$g% bNZbMP7BDbAmG)l;WHETU`njxgN@xNAV=-0C=2r%CQcDFc1ddx%U)*U^gO!?G{sFI>0NCk{~iFMJ8yi#XZg2l43mW&9en_EkSF|@3kdiC005v#L_t(og=0K$-~huw0v2i+T5mNPb;Buc~oI&+vKs1^cn%Y(}Ct6SFzQ44hh6V)7mY&pj_ z>==s!sp|lk{Y!Ac$FEPcymhtCojD)8A=Kca z@qJFl6i-n9lmGqL1)w{4JY5_^IA$g% bNZbMP7BDbAmG)l;WHETU`njxgN@xNAV=-0C=2r%CQcDFc1ddx%U)*U^gO!?G{sFI>0NCk{~iFMJ8yi#XZg2l43mW&9en_EkSF|@3kdiC007}hL_t(oh3%KI4Z|Q1MGutHF|;U> z=kOX#;MqI@E4cIo82~AwJxFh*h%DI&v4nEAoBJKQ13pg__r)*_aHcL)2U**VCH>Cz zEdYR^AYg4bYTXp=LG<8U-;xnn9Bj7gS~p?2CN+TQOsawd^V|*AyZ?_f z#t73ieO08a0>E=ch}?iuDtr0cfP|FRaL5h(di`wRQ%qnN0$VzSK#7NfC(@G zo(FdO1Nou!00Q3M&DK~h#F_%B0j-;W=uJu?8%~6f`v#NQL`gqMHUv01oc^O1xo46K T(qe6*00000NkvXXu0mjf2Y0hA literal 0 HcmV?d00001 diff --git a/icons/mob/screen/styles/underworld/modifiers.dmi b/icons/mob/screen/styles/underworld/modifiers.dmi new file mode 100644 index 0000000000000000000000000000000000000000..f70a3571afb3d9ac8ed7365232b25bc752a6038a GIT binary patch literal 417 zcmV;S0bc%zP)$Sad{Xb7OL8aCB*J zZU6vyoKseCa&`CgQ*iP1^X@3b0oqnLDJt z{}JkDC^l99#?#~5V9ejZk$OHkqRF}Q7jzdynyzyNs~eqL1xRn6y0byfU8e%p291y(#T?t@iM;`-%m!*aG@Xxt11YmL*h>3}5Ya9Fd`4tux zCMPHVo-|7aD9cz9eukTAW;zSx}OhpU1#ZF(){zps4iwm*9er zU!Q1s>uQ}lb3S-OsKG_!2aj~l`)HnIDB?N0!@@Yo__DEAgG{pWx<`|aObSs5*3?ut z)Q|4$HdfudLSji@xA9sHLvztXZL3e6^*`xz+DEs`-%H2u=+dajgICY9zTsdfo}m6G z|NF5EKzI0fx;TbtOiWHVz{zru;b3}*85@%_V@t!v#S0d67*1;F^vGDT*mzPy;)abI zR~l?;$j-><_^^V@D?~y#C{ZaZN9IM3{-O(ug_JiXGBBvGRX3a+>huw4E`z75pUXO@ GgeCwAM|5le literal 0 HcmV?d00001 diff --git a/icons/obj/decals.dmi b/icons/obj/decals.dmi deleted file mode 100644 index f876357570a600200ab89209db0c652d8e554d85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 568 zcmV-80>}M{P)|NqPY00000|M39kxB$$|0L%dY0L%aYng9Qp z0Q&7amH+?%0d!JMQvg8b*k%9#0C{>;Sad{Xb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1 zyZsY&Qt#E@e{$V5 zf?;X(k6a4DnBJ0lf#|T_r9widmuml`}#Dh9R+#0)FcOKp{jx zo*@I+SP3D7_y#Kg-lKm?;9`apfCi|N>i2hIfdN#6?FhXB=tYEe zk5K3XH~~QE1HZ22RwfJK1PE4k;?*qVx1h|z#*?7Ug6u^(jegtQYnDFP2lWUI8)=%x z@+~9?btfWVZ^4oSMijPk%TleWajn-0O&^vD;g6rTZ|VsVX&pfqfCfDP0000V=-0C=2@&#?-^KoA7b`tB>1q!*)Nca0=SisT=bWX&xmce1E;x zcy|-r=##(nAvsY|X=GZ00005&q+i)`nrnbj^y zhmOD7W0nR5L6CW#*9=0rzg0x={EUno*t0l=L_HE_W+F`T2o4WL)$@iPAc|tm_+qh0 z4Uk7mYlnN|wXwX09M({&^SsRvFieBQ?Tf`C#>U35v9aM98yiEhSOm}W5Cp-L=_Zi4 zJJvJ@X?GM%4-iFB2JUA*6bgCB-&icxD#HnkX3%_QX&7Y!hIi-)5JgdrL?RwC!#2z8Sg+iWmIxYKrK9tMlx?_05^D1W@mn6>W_?yCNAYm8=tAT_z4XQ$b7{9c%B*)`% z&-wW|0H9nhBNmIv#PC9)U`Yg*gF!3@gAH2JAj~v?(WfGS7@ta|JbU5&T416JDgq=)0-gKm3a}Bl-TeWI0J`d<3m-ucWIG-}t3MqAq`hs~ zU^~BNI|P7x<9$9K{C>YJ(IZ$629c{&kgF(MeE#$)rZ}$s9#O9<#9bC3vrkujgM)(r z0KeaFtLht%R>? z642=ZbQ+HYbb0`thHKN{)>b@AU$3tV({`Sp-x*Ln|9a(u`MfLB;MP_=J2y9{Dp>aS z_gAfwFuya9_4})Nx~)*~23RDxE(BP{1Hjze+_u&$SYR0s0DgZpuk{MRWds-*Pf(8p z+W4N~`*w29B0;ACn?HVSx}1#u^t-FS5%dfLHzngfXtp?X8t`q%oPgibttG(B3#{nC z{LVmjVpbml0B~}k*8ye-{QLJM^JoXw*M;f*{e9h<-l_<`Ub&b)Iq(KAjXsPp;>E2gu`LE zQn^+x?t+E;ptshaOePIO$V>pO^b-NRDXB&9t}XBP>xpqR3xvaAxmYaX)vK4_xL$no z%V+rH`wIZT-rgRf(I~>9Q8N(b$% zTe-(D1O`^r8UWPSfJ)^W3kwUXw(Ri{fMINIZr1K;H3|hUwC>Jo157-C7Cp-X=mEIJ z62AO-5FdW`Ppz3-EP-1r;mKEj0r=nWahCeqx##4-i=JTv5uB}}XIQz1hT|bHJ^2jT z<0ITwZ&mG=Z*S4}@%v7{PKyA*j(MsrK)0K&28UkQe7y|(@k1Ga5@_6_^47|)%C+*b zy!9bq2aeVO9M_Azy*&V^X~E@N#S@~@C;-&7z%4Kg0c{;%2So9;Zr|)rZtUWDz>DVr zujxIGZipn4NzcNi{k2bY~?!YEdY7nde$CJ>a9!KD+O02^uk+LO^3UbBU}YVDgJ5Ug= PSI_RANK_GRANDMASTER) ADJ_STATUS(target, STAT_PARA, -1) - target.set_status(STAT_DROWSY, 0) + target.set_status_condition(STAT_DROWSY, 0) if(isliving(target)) var/mob/living/M = target M.adjust_hallucination(-30) diff --git a/mods/gamemodes/cult/mobs/constructs/constructs.dm b/mods/gamemodes/cult/mobs/constructs/constructs.dm index 228b834cc2d9..14290066b310 100644 --- a/mods/gamemodes/cult/mobs/constructs/constructs.dm +++ b/mods/gamemodes/cult/mobs/constructs/constructs.dm @@ -124,7 +124,7 @@ _base_attack_force = 30 /mob/living/simple_animal/construct/armoured/handle_regular_status_updates() - set_status(STAT_WEAK, 0) + set_status_condition(STAT_WEAK, 0) if ((. = ..())) return diff --git a/mods/mobs/borers/mob/borer/borer.dm b/mods/mobs/borers/mob/borer/borer.dm index f83d77f9fb03..379bbca678cc 100644 --- a/mods/mobs/borers/mob/borer/borer.dm +++ b/mods/mobs/borers/mob/borer/borer.dm @@ -102,8 +102,8 @@ /mob/living/simple_animal/borer/handle_vision() . = ..() - set_status(STAT_BLIND, host ? GET_STATUS(host, STAT_BLIND) : 0) - set_status(STAT_BLURRY, host ? GET_STATUS(host, STAT_BLURRY) : 0) + set_status_condition(STAT_BLIND, host ? GET_STATUS(host, STAT_BLIND) : 0) + set_status_condition(STAT_BLURRY, host ? GET_STATUS(host, STAT_BLURRY) : 0) /mob/living/simple_animal/borer/handle_disabilities() . = ..() diff --git a/mods/species/drakes/drake_abilities_friendly.dm b/mods/species/drakes/drake_abilities_friendly.dm index a224540e9889..55d0ccaabd9f 100644 --- a/mods/species/drakes/drake_abilities_friendly.dm +++ b/mods/species/drakes/drake_abilities_friendly.dm @@ -49,7 +49,7 @@ var/global/list/_wounds_being_tended_by_drakes = list() return TRUE // Are we already regenerating? - if(friend.has_aura(/obj/aura/sifsap_salve)) + if(friend.has_mob_modifier(/decl/mob_modifier/sifsap_salve)) if(friend == user) to_chat(user, SPAN_WARNING("Your wounds have already been cleaned.")) else @@ -72,7 +72,7 @@ var/global/list/_wounds_being_tended_by_drakes = list() var/friend_ref = "\ref[friend]" global._wounds_being_tended_by_drakes[friend_ref] = world.time + (8 SECONDS) - if(!do_after(user, 8 SECONDS, friend) || QDELETED(friend) || friend.has_aura(/obj/aura/sifsap_salve) || user.incapacitated() || !drake_spend_sap(user, 10)) + if(!do_after(user, 8 SECONDS, friend) || QDELETED(friend) || friend.has_mob_modifier(/decl/mob_modifier/sifsap_salve) || user.incapacitated() || !drake_spend_sap(user, 10)) global._wounds_being_tended_by_drakes -= friend_ref return TRUE @@ -86,7 +86,7 @@ var/global/list/_wounds_being_tended_by_drakes = list() // Sivian animals get a heal buff from the modifier, others just // get it to stop friendly drakes constantly licking their wounds. // Organ wounds are closed, but the owners get sifsap injected via open wounds. - friend.add_aura(new /obj/aura/sifsap_salve(friend, 60 SECONDS)) + friend.add_mob_modifier(/decl/mob_modifier/sifsap_salve, 60 SECONDS, source = user) var/list/friend_organs = friend.get_external_organs() if(length(friend_organs)) for (var/obj/item/organ/external/E in friend_organs) diff --git a/mods/species/drakes/drake_modifiers.dm b/mods/species/drakes/drake_modifiers.dm index a540b0f0c3b0..59366e7cfa73 100644 --- a/mods/species/drakes/drake_modifiers.dm +++ b/mods/species/drakes/drake_modifiers.dm @@ -1,46 +1,33 @@ -/obj/aura/sifsap_salve - name = "Sifsap Salve" - icon = 'icons/effects/sparkles.dmi' - icon_state = "cyan_sparkles" - var/expiry - var/descriptor = "glowing sap" - -/obj/aura/sifsap_salve/Initialize(ml, _lifetime) - expiry = world.time + _lifetime - return ..() - -/obj/aura/sifsap_salve/added_to(var/mob/living/L) - ..() - to_chat(user, SPAN_NOTICE("The [descriptor] seethes and bubbles in your wounds, tingling and stinging.")) - -/obj/aura/sifsap_salve/removed() - to_chat(user, SPAN_NOTICE("The last of the [descriptor] in your wounds fizzles away.")) - ..() - -/obj/aura/sifsap_salve/life_tick() - - if(!user || user.stat == DEAD || user.isSynthetic()) - return 0 - - if(world.time >= expiry) - if(user) - user.remove_aura(src) - return 0 - - if(!user.has_trait(/decl/trait/sivian_biochemistry)) - user.heal_damage(BRUTE, 1, do_update_health = FALSE) - user.heal_damage(BURN, 1, do_update_health = TRUE) - return 1 - - if(user.current_health >= user.get_max_health()) - return 0 - - if(user.current_posture?.prone) - user.heal_damage(BRUTE, 3, do_update_health = FALSE) - user.heal_damage(BURN, 3, do_update_health = FALSE) - user.heal_damage(TOX, 2, do_update_health = TRUE) +/decl/mob_modifier/sifsap_salve + name = "Sifsap Salve" + desc = "Your wounds have been cleaned with drake spittle, which is beneficial to drakes - and not great for anyone else." + hud_icon = 'mods/species/drakes/icons/sifsap.dmi' + hud_icon_state = "sifsap_hud" + mob_overlay_icon = 'icons/effects/sparkles.dmi' + mob_overlay_state = "cyan_sparkles" + /// Defined here to allow overriding in fantasy modpack. + var/descriptor = "glowing sap" + +/decl/mob_modifier/sifsap_salve/Initialize() + on_add_message_1p = SPAN_NOTICE("The [descriptor] seethes and bubbles in your wounds, tingling and stinging.") + on_end_message_1p = SPAN_NOTICE("The last of the [descriptor] in your wounds fizzles away.") + . = ..() + +/decl/mob_modifier/sifsap_salve/on_modifier_datum_mob_life(mob/living/owner, decl/mob_modifier/modifier) + . = ..() + if(!owner || owner.stat == DEAD || owner.isSynthetic()) + return + if(!owner.has_trait(/decl/trait/sivian_biochemistry)) + owner.heal_damage(BRUTE, 1, do_update_health = FALSE) + owner.heal_damage(BURN, 1, do_update_health = TRUE) + return + if(owner.current_health >= owner.get_max_health()) + return + if(owner.current_posture?.prone) + owner.heal_damage(BRUTE, 3, do_update_health = FALSE) + owner.heal_damage(BURN, 3, do_update_health = FALSE) + owner.heal_damage(TOX, 2, do_update_health = TRUE) else - user.heal_damage(BRUTE, 2, do_update_health = FALSE) - user.heal_damage(BURN, 2, do_update_health = FALSE) - user.heal_damage(TOX, 1, do_update_health = TRUE) - return 1 + owner.heal_damage(BRUTE, 2, do_update_health = FALSE) + owner.heal_damage(BURN, 2, do_update_health = FALSE) + owner.heal_damage(TOX, 1, do_update_health = TRUE) diff --git a/mods/species/drakes/icons/sifsap.dmi b/mods/species/drakes/icons/sifsap.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6942ef6d839b6d1a2cf3dec26dc3805630a4d526 GIT binary patch literal 619 zcmV-x0+juUP)V=-0C=1w$FUBBAQT1AnfDbpxHne2vKWYAkY6w)V0lAZ!$bS~4sPdknB43G z?BeOnRrvRX!RyhJ`g3Xp2ID}gWPX=+M_Ozd23mNNxUc0%npEN{FnE&MYW(Ee9bB-m zi>C|UWE?U1U`Ag600FZ}L_t(oh3!`%Z-YP>{YWZEPLZZfHrY%}VNg~4i;AIUR)g9P zsjAt`6chawoT@r=s-nRnNQ1hhqGAHRYoSLu3KX-aD7k*$doOp7`;0IQVX=5S!2sB7 zen-Z1`h1#9o{mEhNRrqbm0vuf@ugr%0GrQdFP*yazNO@6?h5=JMSC+zViQRe9I&kM zF-_A>8oL1}jsx%k0I;QmF#zh>BI|LGPL~K+003aGDdGN^^*!LeD|p@<9l-i&dXVc1 z1W>)>0ML${VC-C1g#v+sZ97gF%apVszrZhRN(cG^W@}4s`VCo@RQ)H4_9ph!+59k}QA)R_afGC~(O9jH^seOD~=HBC}f+X0 Date: Tue, 11 Feb 2025 17:09:32 +1100 Subject: [PATCH 005/512] Reworking hive frames. --- maps/ministation/ministation-1.dmm | 6 +- mods/content/beekeeping/_beekeeping.dm | 12 +--- mods/content/beekeeping/_beekeeping.dme | 2 +- mods/content/beekeeping/centrifuge.dm | 53 --------------- mods/content/beekeeping/closets.dm | 10 +-- mods/content/beekeeping/hive_frame.dm | 62 ++++++++++++++++++ mods/content/beekeeping/hives/_hive.dm | 8 +-- .../{ => icons}/apiary_bees_etc.dmi | Bin mods/content/beekeeping/icons/frame.dmi | Bin 0 -> 1311 bytes mods/content/beekeeping/items.dm | 40 +---------- mods/content/beekeeping/recipes.dm | 6 +- mods/content/beekeeping/trading.dm | 18 ++--- 12 files changed, 88 insertions(+), 129 deletions(-) delete mode 100644 mods/content/beekeeping/centrifuge.dm create mode 100644 mods/content/beekeeping/hive_frame.dm rename mods/content/beekeeping/{ => icons}/apiary_bees_etc.dmi (100%) create mode 100644 mods/content/beekeeping/icons/frame.dmi diff --git a/maps/ministation/ministation-1.dmm b/maps/ministation/ministation-1.dmm index 9ab4635ba0c4..34871f8e955d 100644 --- a/maps/ministation/ministation-1.dmm +++ b/maps/ministation/ministation-1.dmm @@ -5716,9 +5716,9 @@ /obj/item/tool/hoe/mini, /obj/item/tool/spade, /obj/item/tool/spade, -/obj/item/honey_frame, -/obj/item/honey_frame, -/obj/item/honey_frame, +/obj/item/hive_frame/crafted, +/obj/item/hive_frame/crafted, +/obj/item/hive_frame/crafted, /turf/floor/tiled, /area/ministation/hydro) "yg" = ( diff --git a/mods/content/beekeeping/_beekeeping.dm b/mods/content/beekeeping/_beekeeping.dm index d026d7d1f576..d3b58be746d6 100644 --- a/mods/content/beekeeping/_beekeeping.dm +++ b/mods/content/beekeeping/_beekeeping.dm @@ -3,15 +3,5 @@ /datum/storage/hopper/industrial/centrifuge/New() ..() - can_hold |= /obj/item/honey_frame + can_hold |= /obj/item/hive_frame -// Terrible, will be replaced in beewrite. -/datum/storage/hopper/industrial/centrifuge/should_ingest(mob/user, obj/item/thing) - if(istype(thing, /obj/item/honey_frame)) - var/obj/item/honey_frame/frame = thing - if(frame.honey > 0) - return TRUE - if(user) - to_chat(user, SPAN_WARNING("\The [thing] is empty.")) - return FALSE - return ..() diff --git a/mods/content/beekeeping/_beekeeping.dme b/mods/content/beekeeping/_beekeeping.dme index 2d950fe7a392..75778704f368 100644 --- a/mods/content/beekeeping/_beekeeping.dme +++ b/mods/content/beekeeping/_beekeeping.dme @@ -2,8 +2,8 @@ #define MODPACK_BEEKEEPING // BEGIN_INCLUDE #include "_beekeeping.dm" -#include "centrifuge.dm" #include "closets.dm" +#include "hive_frame.dm" #include "items.dm" #include "recipes.dm" #include "trading.dm" diff --git a/mods/content/beekeeping/centrifuge.dm b/mods/content/beekeeping/centrifuge.dm deleted file mode 100644 index 9b04168d744a..000000000000 --- a/mods/content/beekeeping/centrifuge.dm +++ /dev/null @@ -1,53 +0,0 @@ -/obj/machinery/honey_extractor - name = "honey extractor" - desc = "A machine used to extract honey and wax from a beehive frame." - icon = 'icons/obj/virology.dmi' - icon_state = "centrifuge" - anchored = TRUE - density = TRUE - construct_state = /decl/machine_construction/default/panel_closed - uncreated_component_parts = null - stat_immune = 0 - - var/processing = 0 - var/honey = 0 - -/obj/machinery/honey_extractor/components_are_accessible(path) - return !processing && ..() - -/obj/machinery/honey_extractor/cannot_transition_to(state_path, mob/user) - if(processing) - return SPAN_NOTICE("You must wait for \the [src] to finish first!") - return ..() - -/obj/machinery/honey_extractor/attackby(var/obj/item/I, var/mob/user) - if(processing) - to_chat(user, "\The [src] is currently spinning, wait until it's finished.") - return - if((. = component_attackby(I, user))) - return - if(istype(I, /obj/item/honey_frame)) - var/obj/item/honey_frame/H = I - if(!H.honey) - to_chat(user, "\The [H] is empty, put it into a beehive.") - return - user.visible_message("\The [user] loads \the [H] into \the [src] and turns it on.", "You load \the [H] into \the [src] and turn it on.") - processing = H.honey - icon_state = "centrifuge_moving" - qdel(H) - spawn(50) - new /obj/item/honey_frame(loc) - new /obj/item/stack/material/bar/wax(loc, 1) - honey += processing - processing = 0 - icon_state = "centrifuge" - else if(istype(I, /obj/item/chems/glass)) - if(!honey) - to_chat(user, "There is no honey in \the [src].") - return - var/obj/item/chems/glass/G = I - var/transferred = min(G.reagents.maximum_volume - G.reagents.total_volume, honey) - G.add_to_reagents(/decl/material/liquid/nutriment/honey, transferred) - honey -= transferred - user.visible_message("\The [user] collects honey from \the [src] into \the [G].", "You collect [transferred] units of honey from \the [src] into \the [G].") - return 1 diff --git a/mods/content/beekeeping/closets.dm b/mods/content/beekeeping/closets.dm index 224ff0561eb8..c39e70dbb457 100644 --- a/mods/content/beekeeping/closets.dm +++ b/mods/content/beekeeping/closets.dm @@ -6,10 +6,10 @@ . = ..() new /obj/item/beehive_assembly(src) new /obj/item/bee_smoker(src) - new /obj/item/honey_frame(src) - new /obj/item/honey_frame(src) - new /obj/item/honey_frame(src) - new /obj/item/honey_frame(src) - new /obj/item/honey_frame(src) + new /obj/item/hive_frame/crafted(src) + new /obj/item/hive_frame/crafted(src) + new /obj/item/hive_frame/crafted(src) + new /obj/item/hive_frame/crafted(src) + new /obj/item/hive_frame/crafted(src) new /obj/item/bee_pack(src) new /obj/item/crowbar(src) diff --git a/mods/content/beekeeping/hive_frame.dm b/mods/content/beekeeping/hive_frame.dm new file mode 100644 index 000000000000..787210811ac4 --- /dev/null +++ b/mods/content/beekeeping/hive_frame.dm @@ -0,0 +1,62 @@ +/obj/item/hive_frame + abstract_type = /obj/item/hive_frame + icon_state = ICON_STATE_WORLD + w_class = ITEM_SIZE_SMALL + material_alteration = MAT_FLAG_ALTERATION_ALL + var/destroy_on_centrifuge = FALSE + +/obj/item/hive_frame/Initialize(ml, material_key) + . = ..() + initialize_reagents() + +/obj/item/hive_frame/initialize_reagents(populate = TRUE) + create_reagents(20) + . = ..() + +/obj/item/hive_frame/on_reagent_change() + . = ..() + if(reagents?.total_volume) + SetName("filled [initial(name)] ([reagents.get_primary_reagent_name()])") + else + SetName(initial(name)) + queue_icon_update() + +/obj/item/hive_frame/on_update_icon() + . = ..() + var/mesh_state = "[icon_state]-mesh" + if(check_state_in_icon(mesh_state, icon)) + add_overlay(overlay_image(icon, mesh_state, COLOR_WHITE, RESET_COLOR)) + if(reagents?.total_volume) + var/comb_state = "[icon_state]-comb" + if(check_state_in_icon(comb_state, icon)) + add_overlay(overlay_image(icon, comb_state, reagents.get_color(), RESET_COLOR)) + compile_overlays() + +/obj/item/hive_frame/handle_centrifuge_process(obj/machinery/centrifuge/centrifuge) + if(!(. = ..())) + return + if(reagents.total_volume) + reagents.trans_to_holder(centrifuge.loaded_beaker.reagents, reagents.total_volume) + for(var/obj/item/thing in contents) + thing.dropInto(centrifuge.loc) + if(destroy_on_centrifuge) + for(var/atom/movable/thing in convert_matter_to_lumps()) + thing.dropInto(centrifuge.loc) + +// Crafted frame used in apiaries. +/obj/item/hive_frame/crafted + name = "hive frame" + desc = "A wooden frame for insect hives that the workers will fill with products like honey." + icon = 'mods/content/beekeeping/icons/frame.dmi' + material = /decl/material/solid/organic/wood + material_alteration = MAT_FLAG_ALTERATION_ALL + +// TEMP until beewrite redoes hives. +/obj/item/hive_frame/crafted/filled/Initialize() + . = ..() + new /obj/item/stack/material/bar/wax(src) + update_icon() + +/obj/item/hive_frame/crafted/filled/populate_reagents() + . = ..() + reagents.add_reagent(/decl/material/liquid/nutriment/honey, reagents?.maximum_volume) diff --git a/mods/content/beekeeping/hives/_hive.dm b/mods/content/beekeeping/hives/_hive.dm index edea2885862b..515fe39f8dc0 100644 --- a/mods/content/beekeeping/hives/_hive.dm +++ b/mods/content/beekeeping/hives/_hive.dm @@ -63,15 +63,15 @@ smoked = 30 update_icon() return TRUE - else if(istype(I, /obj/item/honey_frame)) + else if(istype(I, /obj/item/hive_frame/crafted)) if(closed) to_chat(user, "You need to open \the [src] with a crowbar before inserting \the [I].") return TRUE if(frames >= maxFrames) to_chat(user, "There is no place for an another frame.") return TRUE - var/obj/item/honey_frame/H = I - if(H.honey) + var/obj/item/hive_frame/crafted/H = I + if(H.reagents?.total_volume) to_chat(user, "\The [I] is full with beeswax and honey, empty it in the extractor first.") return TRUE ++frames @@ -140,7 +140,7 @@ return user.visible_message("\The [user] starts taking the honeycombs out of \the [src].", "You start taking the honeycombs out of \the [src]...") while(honeycombs >= 100 && do_after(user, 30, src)) - new /obj/item/honey_frame/filled(loc) + new /obj/item/hive_frame/crafted/filled(loc) honeycombs -= 100 --frames update_icon() diff --git a/mods/content/beekeeping/apiary_bees_etc.dmi b/mods/content/beekeeping/icons/apiary_bees_etc.dmi similarity index 100% rename from mods/content/beekeeping/apiary_bees_etc.dmi rename to mods/content/beekeeping/icons/apiary_bees_etc.dmi diff --git a/mods/content/beekeeping/icons/frame.dmi b/mods/content/beekeeping/icons/frame.dmi new file mode 100644 index 0000000000000000000000000000000000000000..136c77b72d6ffd1b1bd1cdb9b96318c6b54b6c05 GIT binary patch literal 1311 zcmV+)1>pLLP)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex7wuvIWN;^NFm z%}mcIfpCgT5=&AQY!#Hs^NVs)l(;xkGK-28Y!wW-IMa#}b5kK~R8_jUsl^#YDoxJM zO~R#AS;5uMMZv|_lM4XHeKTkF(4LV100dh}L_t(|ob8%VNF!Gq$GM|Y zp(G6p;z1&F5Zcj$f<1@_K}0Aicr3jwvPVzL_Ts&NZh{06JbE+ks@NcuQUYO28dgm- zf2MIrCTkp%^iT|OQ8VVxK5gc6N#+f_-}m=@zc+brUUWX653NiaX#u3s3?MClG@1dV z1(2rY4WRC7^!xuVH9F8yFo=ckzST9l-+H;z004OT^7~uY@80_H^*7vuZSUUt%ilk4 zKMDrx7TXN&G~g&0yp;?99Q+=5@cO>ChuWV4_f~+~1fOHlmFVtU3cq>%YeSy{ORpB6 z-24X~FaY?^1bcrUe*W#vKPM+AU>F99qTuT43Jk*_7K?#pS;S(o^1WCrhFmTOv)POv ze^@r#`}^vC`0+e1))GG&jeb$B?|Y{}C81CVcDo%H7Z=E8vj9;3j6@;;fOtHP?(S}| zEQ@$NUURaaI=(6coK7chMxedD{mv0cBofGGv!E!dJOYiPnekOu0DxQ0R*rz(Zim5O zD7WeLdL$BwMiAU+`0B+A{Pg;l znt#(8u>-tsLG$6m2LPz6+8$g90`)D4pX&0rlBx#$-)Z?bLYe`j1&~HFfV2S8Xal0-?8MD6eIf7a2_k=fkb z{Bm}7w))BB6F`*#%gf7uS}c|eo6XifFfb6Cn3#wqlS#eRYV8;r8cLf?rt5q@f9>&j z&cfkv=gP{;ACr@lsb-6B1gZ=W1Oc)vTRa|5NS0+wBocw!?Y^3tnulAA zOL@Is%iP>tN)UwRDsK>~PlkA&-xdS`E|&{yYilgWaj8Hc09lqT9LJ>`4u^bm|Aw8N zo$+e@KC2fZE|&{}AYgue{(YfPkf*1oWuwuU^85XkT9SVXJnC$a=lSis+UrT4bOk)> zo#0JkJkM`eCi(I8bAtHkFzE_t`K7RC0BHfF(F`ChfHax`qy>;hGk~-J(zLt*{{mX> Vni&pM#1Q}h002ovPDHLkV1g+&Tdx2B literal 0 HcmV?d00001 diff --git a/mods/content/beekeeping/items.dm b/mods/content/beekeeping/items.dm index 58778d369034..c55a11d7d20f 100644 --- a/mods/content/beekeeping/items.dm +++ b/mods/content/beekeeping/items.dm @@ -1,7 +1,7 @@ /obj/item/beehive_assembly name = "beehive assembly" desc = "Contains everything you need to build a beehive." - icon = 'mods/content/beekeeping/apiary_bees_etc.dmi' + icon = 'mods/content/beekeeping/icons/apiary_bees_etc.dmi' icon_state = "apiary" material = /decl/material/solid/organic/wood @@ -12,15 +12,6 @@ new /obj/machinery/beehive(get_turf(user)) qdel(src) -/obj/item/stock_parts/circuitboard/honey - name = "circuitboard (honey extractor)" - build_path = /obj/machinery/honey_extractor - board_type = "machine" - origin_tech = @'{"biotech":2,"engineering":1}' - req_components = list( - /obj/item/stock_parts/manipulator = 2, - /obj/item/stock_parts/matter_bin = 2) - /obj/item/bee_smoker name = "bee smoker" desc = "A device used to calm down bees before harvesting honey." @@ -29,35 +20,6 @@ w_class = ITEM_SIZE_SMALL material = /decl/material/solid/metal/steel -/obj/item/honey_frame - name = "beehive frame" - desc = "A frame for the beehive that the bees will fill with honeycombs." - icon = 'mods/content/beekeeping/icons/beekeeping.dmi' - icon_state = "honeyframe" - w_class = ITEM_SIZE_SMALL - material = /decl/material/solid/organic/wood - var/honey = 0 - -/obj/item/honey_frame/filled - name = "filled beehive frame" - desc = "A frame for the beehive that the bees have filled with honeycombs." - honey = 20 - material = /decl/material/solid/organic/wood - -/obj/item/honey_frame/filled/Initialize() - . = ..() - overlays += "honeycomb" - -// This is crap, will be replaced in beewrite PR. -/obj/item/honey_frame/handle_centrifuge_process(obj/machinery/centrifuge/centrifuge) - if(!(. = ..()) || !honey) - return - centrifuge?.loaded_beaker?.add_to_reagents(/decl/material/liquid/nutriment/honey, honey) - honey = 0 - new /obj/item/honey_frame(centrifuge.loc) - new /obj/item/stack/material/bar(centrifuge.loc, 1, /decl/material/solid/organic/wax) - qdel(src) - /obj/item/bee_pack name = "bee pack" desc = "Contains a queen bee and some worker bees. Everything you'll need to start a hive!" diff --git a/mods/content/beekeeping/recipes.dm b/mods/content/beekeeping/recipes.dm index 03089d932ab9..8494617d3477 100644 --- a/mods/content/beekeeping/recipes.dm +++ b/mods/content/beekeeping/recipes.dm @@ -1,10 +1,6 @@ - /decl/stack_recipe/planks/beehive_assembly result_type = /obj/item/beehive_assembly category = "furniture" /decl/stack_recipe/planks/beehive_frame - result_type = /obj/item/honey_frame - -/datum/fabricator_recipe/imprinter/circuit/honey_extractor - path = /obj/item/stock_parts/circuitboard/honey + result_type = /obj/item/hive_frame/crafted diff --git a/mods/content/beekeeping/trading.dm b/mods/content/beekeeping/trading.dm index 1a119ddc99be..45009265f1bf 100644 --- a/mods/content/beekeeping/trading.dm +++ b/mods/content/beekeeping/trading.dm @@ -1,15 +1,17 @@ /datum/trader/trading_beacon/manufacturing/New() - LAZYSET(possible_trading_items, /obj/item/bee_pack, TRADER_THIS_TYPE) - LAZYSET(possible_trading_items, /obj/item/bee_smoker, TRADER_THIS_TYPE) - LAZYSET(possible_trading_items, /obj/item/beehive_assembly, TRADER_THIS_TYPE) - LAZYSET(possible_trading_items, /obj/item/honey_frame, TRADER_THIS_TYPE) + LAZYSET(possible_trading_items, /obj/item/bee_pack, TRADER_THIS_TYPE) + LAZYSET(possible_trading_items, /obj/item/bee_smoker, TRADER_THIS_TYPE) + LAZYSET(possible_trading_items, /obj/item/beehive_assembly, TRADER_THIS_TYPE) + LAZYSET(possible_trading_items, /obj/item/hive_frame/crafted, TRADER_THIS_TYPE) ..() /decl/hierarchy/supply_pack/hydroponics/bee_keeper name = "Equipment - Beekeeping" - contains = list(/obj/item/beehive_assembly, - /obj/item/bee_smoker, - /obj/item/honey_frame = 5, - /obj/item/bee_pack) + contains = list( + /obj/item/beehive_assembly, + /obj/item/bee_smoker, + /obj/item/hive_frame/crafted = 5, + /obj/item/bee_pack + ) containername = "beekeeping crate" access = access_hydroponics From ec201b85a8c25754a22cebfb7ab606cb0b2e8d1f Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Mon, 17 Feb 2025 12:01:26 +1100 Subject: [PATCH 006/512] Automatic changelog generation for PR #4818 [ci skip] --- html/changelogs/AutoChangeLog-pr-4818.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4818.yml diff --git a/html/changelogs/AutoChangeLog-pr-4818.yml b/html/changelogs/AutoChangeLog-pr-4818.yml new file mode 100644 index 000000000000..d176c86c33af --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4818.yml @@ -0,0 +1,5 @@ +author: MistakeNot4892 +changes: + - {tweak: Modifiers like regeneration or personal shielding will now show at the + top of the screen.} +delete-after: true From 320856e8aecebaf72e093a44d9ad2bc0ac73bb90 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 15 Feb 2025 14:52:29 +1100 Subject: [PATCH 007/512] Janitor module and flying modules cannot slip. --- code/modules/mob/living/silicon/robot/flying/module_flying.dm | 3 +++ .../modules/mob/living/silicon/robot/modules/module_janitor.dm | 1 + 2 files changed, 4 insertions(+) diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying.dm b/code/modules/mob/living/silicon/robot/flying/module_flying.dm index 5cc0ee8c6ca0..68e682d02e02 100644 --- a/code/modules/mob/living/silicon/robot/flying/module_flying.dm +++ b/code/modules/mob/living/silicon/robot/flying/module_flying.dm @@ -1,3 +1,6 @@ /obj/item/robot_module/flying module_category = ROBOT_MODULE_TYPE_FLYING can_be_pushed = TRUE + has_nonslip_feet = TRUE + has_magnetic_feet = TRUE + diff --git a/code/modules/mob/living/silicon/robot/modules/module_janitor.dm b/code/modules/mob/living/silicon/robot/modules/module_janitor.dm index e88d8b131125..854355939132 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_janitor.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_janitor.dm @@ -22,6 +22,7 @@ /obj/item/weldingtool ) emag = /obj/item/chems/spray + has_nonslip_feet = TRUE /obj/item/robot_module/janitor/handle_turf(turf/target, mob/user) target.clean() From 6ac03824cf4c93cf007f9c96c729c64f72a9c4b4 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Tue, 18 Feb 2025 00:49:46 +0000 Subject: [PATCH 008/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 4 ++++ html/changelogs/AutoChangeLog-pr-4818.yml | 5 ----- 3 files changed, 10 insertions(+), 5 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4818.yml diff --git a/html/changelog.html b/html/changelog.html index e8361317d54b..5f133c463f78 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
+

18 February 2025

+

MistakeNot4892 updated:

+
    +
  • Modifiers like regeneration or personal shielding will now show at the top of the screen.
  • +
+

07 February 2025

Penelope Haze updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 07cfc97b702b..4e9e0fdd738c 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14982,3 +14982,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Penelope Haze: - tweak: Shears are now used to add or remove padding from objects. Wirecutters still work as a backup, though. +2025-02-18: + MistakeNot4892: + - tweak: Modifiers like regeneration or personal shielding will now show at the + top of the screen. diff --git a/html/changelogs/AutoChangeLog-pr-4818.yml b/html/changelogs/AutoChangeLog-pr-4818.yml deleted file mode 100644 index d176c86c33af..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4818.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: MistakeNot4892 -changes: - - {tweak: Modifiers like regeneration or personal shielding will now show at the - top of the screen.} -delete-after: true From 2fbb646f6fd6e78de64a85195c45e85754cc04e7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 17 Feb 2025 12:34:38 +1100 Subject: [PATCH 009/512] Replacing many R variables with robot or similar. --- code/_helpers/mobs.dm | 4 +- .../screen/robot/screen_robot_drop_grab.dm | 4 +- .../screen/robot/screen_robot_inventory.dm | 8 +- .../hud/screen/robot/screen_robot_module.dm | 4 +- .../hud/screen/robot/screen_robot_panel.dm | 4 +- .../hud/screen/robot/screen_robot_radio.dm | 4 +- .../hud/screen/robot/screen_robot_store.dm | 10 +- code/datums/mind/mind.dm | 58 ++++----- code/datums/repositories/follow.dm | 8 +- code/datums/wires/robot.dm | 44 ++++--- code/game/machinery/camera/robot_camera.dm | 12 +- code/game/machinery/computer/robot.dm | 58 ++++----- code/game/machinery/rechargestation.dm | 18 +-- code/game/objects/items/__item.dm | 8 +- .../objects/items/devices/lightreplacer.dm | 9 +- .../objects/items/devices/radio/radio_borg.dm | 8 +- .../objects/items/robot/robot_upgrades.dm | 100 +++++++-------- code/game/objects/items/stacks/nanopaste.dm | 14 +-- code/game/objects/items/weapons/AI_modules.dm | 6 +- code/game/objects/items/weapons/RCD.dm | 8 +- code/game/objects/items/weapons/RSF.dm | 10 +- code/game/objects/items/weapons/defib.dm | 24 ++-- code/game/objects/items/weapons/stunbaton.dm | 4 +- code/game/world_topic_commands.dm | 6 +- code/modules/admin/admin.dm | 4 +- code/modules/events/event_dynamic.dm | 6 +- code/modules/events/ion_storm.dm | 4 +- code/modules/keybindings/robot.dm | 22 ++-- code/modules/mob/language/synthetic.dm | 6 +- code/modules/mob/living/silicon/ai/laws.dm | 6 +- .../mob/living/silicon/robot/component.dm | 4 +- .../robot/flying/module_flying_emergency.dm | 2 +- .../robot/flying/module_flying_forensics.dm | 2 +- .../robot/flying/module_flying_repair.dm | 4 +- .../living/silicon/robot/modules/_module.dm | 116 +++++++++--------- .../silicon/robot/modules/module_clerical.dm | 12 +- .../robot/modules/module_engineering.dm | 4 +- .../silicon/robot/modules/module_illegal.dm | 8 +- .../silicon/robot/modules/module_janitor.dm | 4 +- .../robot/modules/module_maintenance_drone.dm | 10 +- .../silicon/robot/modules/module_medical.dm | 4 +- .../silicon/robot/modules/module_security.dm | 2 +- .../modules/mob/living/silicon/robot/robot.dm | 9 +- .../mob/living/silicon/robot/robot_items.dm | 18 +-- code/modules/mob/mob_movement.dm | 4 +- .../modular_computers/os/subtypes/silicon.dm | 8 +- code/modules/nano/modules/law_manager.dm | 10 +- code/modules/power/cable.dm | 4 +- code/modules/power/cell.dm | 4 +- code/modules/projectiles/projectile/change.dm | 12 +- .../reagents/reagent_containers/borghydro.dm | 18 +-- .../artifacts/effects/cellcharge.dm | 6 +- .../artifacts/effects/celldrain.dm | 6 +- .../artifacts/effects/roboheal.dm | 6 +- .../artifacts/effects/robohurt.dm | 6 +- code/modules/xenoarcheaology/boulder.dm | 6 +- mods/gamemodes/traitor/special_role.dm | 8 +- mods/species/ascent/mobs/drone.dm | 2 +- 58 files changed, 385 insertions(+), 395 deletions(-) diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 6c040f5a57c9..5684048f9301 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -28,8 +28,8 @@ return FALSE if(!isrobot(thing.loc)) return FALSE - var/mob/living/silicon/robot/R = thing.loc - return (thing in R.module.equipment) + var/mob/living/silicon/robot/robot = thing.loc + return (thing in robot.module.equipment) /proc/get_exposed_defense_zone(var/atom/movable/target) return pick(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG, BP_CHEST, BP_GROIN) diff --git a/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm b/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm index c3e71cef3d06..bff32e2bc888 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm @@ -8,8 +8,8 @@ /obj/screen/robot/drop_grab/handle_click(mob/user, params) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.drop_item() + var/mob/living/silicon/robot/robot = user + robot.drop_item() update_icon() /obj/screen/robot/drop_grab/on_update_icon() diff --git a/code/_onclick/hud/screen/robot/screen_robot_inventory.dm b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm index a6360e2eaaab..fa79e6cb1b48 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_inventory.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm @@ -5,8 +5,8 @@ /obj/screen/robot/inventory/handle_click(mob/user, params) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.module) - R.hud_used.toggle_show_robot_modules() + var/mob/living/silicon/robot/robot = user + if(robot.module) + robot.hud_used.toggle_show_robot_modules() return 1 - to_chat(R, "You haven't selected a module yet.") + to_chat(robot, "You haven't selected a module yet.") diff --git a/code/_onclick/hud/screen/robot/screen_robot_module.dm b/code/_onclick/hud/screen/robot/screen_robot_module.dm index 95e662167ec2..188715d51dff 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_module.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_module.dm @@ -13,5 +13,5 @@ /obj/screen/robot/module/select/handle_click(mob/user, params) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.pick_module() + var/mob/living/silicon/robot/robot = user + robot.pick_module() diff --git a/code/_onclick/hud/screen/robot/screen_robot_panel.dm b/code/_onclick/hud/screen/robot/screen_robot_panel.dm index 9f39909a52f9..d092bffc3180 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_panel.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_panel.dm @@ -5,5 +5,5 @@ /obj/screen/robot/panel/handle_click(mob/user, params) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.installed_modules() + var/mob/living/silicon/robot/robot = user + robot.installed_modules() diff --git a/code/_onclick/hud/screen/robot/screen_robot_radio.dm b/code/_onclick/hud/screen/robot/screen_robot_radio.dm index 5207edef2b47..96f2364ca600 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_radio.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_radio.dm @@ -6,5 +6,5 @@ /obj/screen/robot/radio/handle_click(mob/user, params) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.radio_menu() \ No newline at end of file + var/mob/living/silicon/robot/robot = user + robot.radio_menu() \ No newline at end of file diff --git a/code/_onclick/hud/screen/robot/screen_robot_store.dm b/code/_onclick/hud/screen/robot/screen_robot_store.dm index 93f1a652b96e..36db253a4af0 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_store.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_store.dm @@ -5,9 +5,9 @@ /obj/screen/robot/store/handle_click(mob/user, params) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.module) - R.uneq_active() - R.hud_used.update_robot_modules_display() + var/mob/living/silicon/robot/robot = user + if(robot.module) + robot.uneq_active() + robot.hud_used.update_robot_modules_display() else - to_chat(R, "You haven't selected a module yet.") + to_chat(robot, "You haven't selected a module yet.") diff --git a/code/datums/mind/mind.dm b/code/datums/mind/mind.dm index 1db348880015..1ea040862ecc 100644 --- a/code/datums/mind/mind.dm +++ b/code/datums/mind/mind.dm @@ -394,39 +394,39 @@ switch(href_list["silicon"]) if("unemag") - var/mob/living/silicon/robot/R = current - if (istype(R)) - R.emagged = 0 - if (R.activated(R.module.emag)) - R.module_active = null - if(R.module_state_1 == R.module.emag) - R.module_state_1 = null - R.module.emag.forceMove(null) - else if(R.module_state_2 == R.module.emag) - R.module_state_2 = null - R.module.emag.forceMove(null) - else if(R.module_state_3 == R.module.emag) - R.module_state_3 = null - R.module.emag.forceMove(null) - log_admin("[key_name_admin(usr)] has unemag'ed [R].") + var/mob/living/silicon/robot/robot = current + if (istype(robot)) + robot.emagged = 0 + if (robot.activated(robot.module.emag)) + robot.module_active = null + if(robot.module_state_1 == robot.module.emag) + robot.module_state_1 = null + robot.module.emag.forceMove(null) + else if(robot.module_state_2 == robot.module.emag) + robot.module_state_2 = null + robot.module.emag.forceMove(null) + else if(robot.module_state_3 == robot.module.emag) + robot.module_state_3 = null + robot.module.emag.forceMove(null) + log_admin("[key_name_admin(usr)] has unemag'ed [robot].") if("unemagcyborgs") if (isAI(current)) var/mob/living/silicon/ai/ai = current - for (var/mob/living/silicon/robot/R in ai.connected_robots) - R.emagged = 0 - if (R.module) - if (R.activated(R.module.emag)) - R.module_active = null - if(R.module_state_1 == R.module.emag) - R.module_state_1 = null - R.module.emag.forceMove(null) - else if(R.module_state_2 == R.module.emag) - R.module_state_2 = null - R.module.emag.forceMove(null) - else if(R.module_state_3 == R.module.emag) - R.module_state_3 = null - R.module.emag.forceMove(null) + for (var/mob/living/silicon/robot/robot in ai.connected_robots) + robot.emagged = 0 + if (robot.module) + if (robot.activated(robot.module.emag)) + robot.module_active = null + if(robot.module_state_1 == robot.module.emag) + robot.module_state_1 = null + robot.module.emag.forceMove(null) + else if(robot.module_state_2 == robot.module.emag) + robot.module_state_2 = null + robot.module.emag.forceMove(null) + else if(robot.module_state_3 == robot.module.emag) + robot.module_state_3 = null + robot.module.emag.forceMove(null) log_admin("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.") else if (href_list["common"]) diff --git a/code/datums/repositories/follow.dm b/code/datums/repositories/follow.dm index fb12909997cb..b4a48a2b0e48 100644 --- a/code/datums/repositories/follow.dm +++ b/code/datums/repositories/follow.dm @@ -158,11 +158,11 @@ var/global/repository/follow/follow_repository = new() followed_type = /mob/living/silicon/robot /datum/follow_holder/robot/show_entry() - var/mob/living/silicon/robot/R = followed_instance - return ..() && R.braintype + var/mob/living/silicon/robot/robot = followed_instance + return ..() && robot.braintype -/datum/follow_holder/robot/get_suffix(var/mob/living/silicon/robot/R) - suffix = "\[[R.braintype]\][R.module ? " \[[R.module.name]\]" : ""]" +/datum/follow_holder/robot/get_suffix(var/mob/living/silicon/robot/robot) + suffix = "\[[robot.braintype]\][robot.module ? " \[[robot.module.name]\]" : ""]" return ..() /datum/follow_holder/human diff --git a/code/datums/wires/robot.dm b/code/datums/wires/robot.dm index 8bbba0d8da59..2a5576b5fb9e 100644 --- a/code/datums/wires/robot.dm +++ b/code/datums/wires/robot.dm @@ -19,61 +19,59 @@ var/global/const/BORG_WIRE_CAMERA = 16 /datum/wires/robot/GetInteractWindow(mob/user) . = ..() - var/mob/living/silicon/robot/R = holder + var/mob/living/silicon/robot/robot = holder var/datum/extension/network_device/camera/D = get_extension(holder, /datum/extension/network_device/) - . += text("
    \n[(R.lawupdate ? "The LawSync light is on." : "The LawSync light is off.")]") - . += text("
    \n[(R.connected_ai ? "The AI link light is on." : "The AI link light is off.")]") + . += text("
    \n[(robot.lawupdate ? "The LawSync light is on." : "The LawSync light is off.")]") + . += text("
    \n[(robot.connected_ai ? "The AI link light is on." : "The AI link light is off.")]") . += text("
    \n[(D.is_functional() ? "The Camera light is on." : "The Camera light is off.")]") - . += text("
    \n[(R.lockcharge ? "The lockdown light is on." : "The lockdown light is off.")]") + . += text("
    \n[(robot.lockcharge ? "The lockdown light is on." : "The lockdown light is off.")]") return . /datum/wires/robot/UpdateCut(var/index, var/mended) - var/mob/living/silicon/robot/R = holder + var/mob/living/silicon/robot/robot = holder switch(index) if(BORG_WIRE_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI if(!mended) - if (R.lawupdate == 1) - to_chat(R, "LawSync protocol engaged.") - R.show_laws() + if (robot.lawupdate == 1) + to_chat(robot, "LawSync protocol engaged.") + robot.show_laws() else - if (R.lawupdate == 0 && !R.emagged) - R.lawupdate = 1 + if (robot.lawupdate == 0 && !robot.emagged) + robot.lawupdate = 1 if (BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control if(!mended) - R.disconnect_from_ai() + robot.disconnect_from_ai() if (BORG_WIRE_CAMERA) cameranet.update_visibility(src, FALSE) if(BORG_WIRE_LOCKED_DOWN) - R.SetLockdown(!mended) + robot.SetLockdown(!mended) /datum/wires/robot/UpdatePulsed(var/index) - var/mob/living/silicon/robot/R = holder + var/mob/living/silicon/robot/robot = holder switch(index) if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI - if(!R.emagged) - var/mob/living/silicon/ai/new_ai = select_active_ai(R, get_z(R)) - R.connect_to_ai(new_ai) + if(!robot.emagged) + var/mob/living/silicon/ai/new_ai = select_active_ai(robot, get_z(robot)) + robot.connect_to_ai(new_ai) if (BORG_WIRE_CAMERA) var/datum/extension/network_device/camera/robot/D = get_extension(src, /datum/extension/network_device) if(D && D.is_functional()) - R.visible_message("[R]'s camera lens focuses loudly.") - to_chat(R, "Your camera lense focuses loudly.") + robot.visible_message("[robot]'s camera lens focuses loudly.") + to_chat(robot, "Your camera lense focuses loudly.") if(BORG_WIRE_LOCKED_DOWN) - R.SetLockdown(!R.lockcharge) // Toggle + robot.SetLockdown(!robot.lockcharge) // Toggle /datum/wires/robot/CanUse(var/mob/living/L) - var/mob/living/silicon/robot/R = holder - if(R.wiresexposed) - return 1 - return 0 + var/mob/living/silicon/robot/robot = holder + return robot.wiresexposed /datum/wires/robot/proc/IsCameraCut() return wires_status & BORG_WIRE_CAMERA diff --git a/code/game/machinery/camera/robot_camera.dm b/code/game/machinery/camera/robot_camera.dm index fc74d78f8096..cf3463664fa9 100644 --- a/code/game/machinery/camera/robot_camera.dm +++ b/code/game/machinery/camera/robot_camera.dm @@ -1,14 +1,14 @@ /datum/extension/network_device/camera/robot - expected_type = /mob/living/silicon/robot + expected_type = /mob/living/silicon/robot /datum/extension/network_device/camera/robot/is_functional() - var/mob/living/silicon/robot/R = holder - if(R.wires.IsIndexCut(BORG_WIRE_CAMERA)) + var/mob/living/silicon/robot/robot = holder + if(robot.wires.IsIndexCut(BORG_WIRE_CAMERA)) return FALSE - if(!R.has_power) + if(!robot.has_power) return FALSE - if(R.stat == DEAD) + if(robot.stat == DEAD) return FALSE - if(!R.is_component_functioning("camera")) + if(!robot.is_component_functioning("camera")) return FALSE return TRUE \ No newline at end of file diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 4b1d38034e52..81e3a6b26706 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -108,47 +108,47 @@ /obj/machinery/computer/robotics/proc/get_cyborgs(var/mob/user) var/list/robots = list() - for(var/mob/living/silicon/robot/R in global.silicon_mob_list) + for(var/mob/living/silicon/robot/robot in global.silicon_mob_list) // Ignore drones - if(isdrone(R)) + if(isdrone(robot)) continue // Ignore antagonistic cyborgs - if(R.scrambledcodes) + if(robot.scrambledcodes) continue - var/list/robot = list() - robot["name"] = R.name - var/turf/T = get_turf(R) + var/list/robot_data = list() + robot_data["name"] = robot.name + var/turf/T = get_turf(robot) var/area/A = get_area(T) if(istype(T) && istype(A) && isContactLevel(T.z)) - robot["location"] = "[A.proper_name] ([T.x], [T.y])" + robot_data["location"] = "[A.proper_name] ([T.x], [T.y])" else - robot["location"] = "Unknown" + robot_data["location"] = "Unknown" - if(R.stat) - robot["status"] = "Not Responding" - else if (R.lockcharge) - robot["status"] = "Lockdown" + if(robot.stat) + robot_data["status"] = "Not Responding" + else if (robot.lockcharge) + robot_data["status"] = "Lockdown" else - robot["status"] = "Operational" + robot_data["status"] = "Operational" - if(R.cell) - robot["cell"] = 1 - robot["cell_capacity"] = R.cell.maxcharge - robot["cell_current"] = R.cell.charge - robot["cell_percentage"] = round(R.cell.percent()) + if(robot.cell) + robot_data["cell"] = 1 + robot_data["cell_capacity"] = robot.cell.maxcharge + robot_data["cell_current"] = robot.cell.charge + robot_data["cell_percentage"] = round(robot.cell.percent()) else - robot["cell"] = 0 + robot_data["cell"] = 0 - robot["module"] = R.module ? R.module.name : "None" - robot["master_ai"] = R.connected_ai ? R.connected_ai.name : "None" - robot["hackable"] = 0 + robot_data["module"] = robot.module ? robot.module.name : "None" + robot_data["master_ai"] = robot.connected_ai ? robot.connected_ai.name : "None" + robot_data["hackable"] = 0 // Antag AIs know whether linked cyborgs are hacked or not. - if(user && isAI(user) && (R.connected_ai == user) && player_is_antag(user.mind)) - robot["hacked"] = R.emagged ? 1 : 0 - robot["hackable"] = R.emagged? 0 : 1 - robots.Add(list(robot)) + if(user && isAI(user) && (robot.connected_ai == user) && player_is_antag(user.mind)) + robot_data["hacked"] = robot.emagged ? 1 : 0 + robot_data["hackable"] = robot.emagged? 0 : 1 + robots.Add(list(robot_data)) return robots // Proc: get_cyborg_by_name() @@ -157,6 +157,6 @@ /obj/machinery/computer/robotics/proc/get_cyborg_by_name(var/name) if (!name) return - for(var/mob/living/silicon/robot/R in global.silicon_mob_list) - if(R.name == name) - return R + for(var/mob/living/silicon/robot/robot in global.silicon_mob_list) + if(robot.name == name) + return robot diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index 1be2e054aaaa..7d175c177a9a 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -70,12 +70,12 @@ var/obj/item/cell/target if(isrobot(occupant)) - var/mob/living/silicon/robot/R = occupant - target = R.cell - if(R.module) - R.module.respawn_consumable(R, charging_power * CELLRATE / 250) //consumables are magical, apparently + var/mob/living/silicon/robot/robot = occupant + target = robot.cell + if(robot.module) + robot.module.respawn_consumable(robot, charging_power * CELLRATE / 250) //consumables are magical, apparently // If we are capable of repairing damage, reboot destroyed components and allow them to be repaired for very large power spike. - var/list/damaged = R.get_damaged_components(1,1,1) + var/list/damaged = robot.get_damaged_components(1,1,1) if(damaged.len && wire_rate && weld_rate) for(var/datum/robot_component/C in damaged) if((C.installed == -1) && use_power_oneoff(100 KILOWATTS, LOCAL) <= 0) @@ -174,8 +174,8 @@ last_overlay_state = overlay_state() overlays = list(image(overlay_icon, overlay_state())) -/obj/machinery/recharge_station/Bumped(var/mob/living/silicon/robot/R) - addtimer(CALLBACK(src, PROC_REF(go_in), R), 1) +/obj/machinery/recharge_station/Bumped(var/mob/living/silicon/robot/robot) + addtimer(CALLBACK(src, PROC_REF(go_in), robot), 1) /obj/machinery/recharge_station/proc/go_in(var/mob/M) @@ -191,8 +191,8 @@ /obj/machinery/recharge_station/proc/hascell(var/mob/M) if(isrobot(M)) - var/mob/living/silicon/robot/R = M - return (R.cell) + var/mob/living/silicon/robot/robot = M + return (robot.cell) if(ishuman(M)) var/mob/living/human/H = M if(H.isSynthetic()) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 67aabeb3f57e..df4905d658c8 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -586,10 +586,10 @@ //If the item is part of a cyborg module, equip it if(!isrobot(user)) return - var/mob/living/silicon/robot/R = user - R.activate_module(src) - if(R.hud_used) - R.hud_used.update_robot_modules_display() + var/mob/living/silicon/robot/robot = user + robot.activate_module(src) + if(robot.hud_used) + robot.hud_used.update_robot_modules_display() /obj/item/proc/try_slapcrafting(obj/item/W, mob/user) if(SSfabrication.try_craft_with(src, W, user)) diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 4d9877a67ead..7b04cb53c3f2 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -119,15 +119,8 @@ return ..() /obj/item/lightreplacer/attack_self(mob/user) - /* // This would probably be a bit OP. If you want it though, uncomment the code. - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.emagged) - src.Emag() - to_chat(usr, "You shortcircuit \the [src].") - return - */ to_chat(usr, "It has [uses] lights remaining.") + return TRUE /obj/item/lightreplacer/on_update_icon() . = ..() diff --git a/code/game/objects/items/devices/radio/radio_borg.dm b/code/game/objects/items/devices/radio/radio_borg.dm index c8c6935215e0..eab3b5bd6e08 100644 --- a/code/game/objects/items/devices/radio/radio_borg.dm +++ b/code/game/objects/items/devices/radio/radio_borg.dm @@ -13,8 +13,8 @@ /obj/item/radio/borg/can_receive_message(var/check_network_membership) . = ..() && isrobot(loc) if(.) - var/mob/living/silicon/robot/R = loc - if(!R.handle_radio_transmission()) + var/mob/living/silicon/robot/robot = loc + if(!robot.handle_radio_transmission()) return FALSE /obj/item/radio/borg/ert @@ -32,8 +32,8 @@ /obj/item/radio/borg/talk_into(mob/living/M, message, message_mode, var/verb = "says", var/decl/language/speaking = null) . = ..() if(isrobot(loc)) - var/mob/living/silicon/robot/R = src.loc - R.handle_radio_transmission() + var/mob/living/silicon/robot/robot = src.loc + robot.handle_radio_transmission() /obj/item/radio/borg/OnTopic(mob/user, href_list, datum/topic_state/state) if((. = ..())) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 1dd4881d7c09..7230cd94476d 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -11,8 +11,8 @@ var/locked = 0 var/require_module = 0 -/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/R) - if(R.stat == DEAD) +/obj/item/borg/upgrade/proc/action(var/mob/living/silicon/robot/robot) + if(robot.stat == DEAD) to_chat(usr, "\The [src] will not function on a deceased robot.") return 1 return 0 @@ -23,10 +23,10 @@ icon = 'icons/obj/modules/module_cyborg_1.dmi' require_module = 1 -/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/reset/action(var/mob/living/silicon/robot/robot) if((. = ..())) return 0 - R.reset_module() + robot.reset_module() return 1 /obj/item/borg/upgrade/uncertified @@ -36,15 +36,15 @@ require_module = 0 var/new_module = null -/obj/item/borg/upgrade/uncertified/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/uncertified/action(var/mob/living/silicon/robot/robot) if((. = ..())) return 0 if(!new_module) - to_chat(usr, "[R]'s error lights strobe repeatedly - something seems to be wrong with the chip.") + to_chat(usr, "[robot]'s error lights strobe repeatedly - something seems to be wrong with the chip.") return 0 // Suppress the alert so the AI doesn't see a reset message. - R.reset_module(TRUE) - R.pick_module(new_module) + robot.reset_module(TRUE) + robot.pick_module(new_module) return 1 /obj/item/borg/upgrade/uncertified/party @@ -72,12 +72,12 @@ /obj/item/borg/upgrade/rename/attack_self(mob/user) heldname = sanitize_safe(input(user, "Enter new robot name", "Robot Reclassification", heldname), MAX_NAME_LEN) -/obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/rename/action(var/mob/living/silicon/robot/robot) if(..()) return 0 - R.notify_ai(ROBOT_NOTIFICATION_NEW_NAME, R.name, heldname) - R.SetName(heldname) - R.custom_name = heldname - R.real_name = heldname + robot.notify_ai(ROBOT_NOTIFICATION_NEW_NAME, robot.name, heldname) + robot.SetName(heldname) + robot.custom_name = heldname + robot.real_name = heldname return 1 @@ -86,16 +86,16 @@ desc = "Used to boost cyborg's light intensity." icon = 'icons/obj/modules/module_cyborg_1.dmi' -/obj/item/borg/upgrade/floodlight/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/floodlight/action(var/mob/living/silicon/robot/robot) if(..()) return 0 - if(R.intenselight) + if(robot.intenselight) to_chat(usr, "This cyborg's light was already upgraded.") return 0 else - R.intenselight = 1 - R.update_robot_light() - to_chat(R, "Lighting systems upgrade detected.") + robot.intenselight = 1 + robot.update_robot_light() + to_chat(robot, "Lighting systems upgrade detected.") return 1 /obj/item/borg/upgrade/restart @@ -105,19 +105,19 @@ material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) -/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/R) - if(R.current_health < 0) +/obj/item/borg/upgrade/restart/action(var/mob/living/silicon/robot/robot) + if(robot.current_health < 0) to_chat(usr, "You have to repair the robot before using this module!") return 0 - if(!R.key) + if(!robot.key) for(var/mob/observer/ghost/ghost in global.player_list) - if(ghost.mind && ghost.mind.current == R) - R.key = ghost.key + if(ghost.mind && ghost.mind.current == robot) + robot.key = ghost.key - R.set_stat(CONSCIOUS) - R.switch_from_dead_to_living_mob_list() - R.notify_ai(ROBOT_NOTIFICATION_NEW_UNIT) + robot.set_stat(CONSCIOUS) + robot.switch_from_dead_to_living_mob_list() + robot.notify_ai(ROBOT_NOTIFICATION_NEW_UNIT) return 1 @@ -132,14 +132,14 @@ /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE ) -/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/vtec/action(var/mob/living/silicon/robot/robot) if(..()) return FALSE - if(R.vtec == TRUE) + if(robot.vtec == TRUE) return FALSE - R.speed-- - R.vtec = TRUE + robot.speed-- + robot.vtec = TRUE return TRUE @@ -156,23 +156,23 @@ ) origin_tech = @'{"materials":2,"engineering":3,"programming":3,"powerstorage":2,"combat":2}' -/obj/item/borg/upgrade/weaponcooler/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/weaponcooler/action(var/mob/living/silicon/robot/robot) if(..()) return 0 - if(!R.module || !(type in R.module.supported_upgrades)) - to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + if(!robot.module || !(type in robot.module.supported_upgrades)) + to_chat(robot, "Upgrade mounting error! No suitable hardpoint detected!") to_chat(usr, "There's no mounting point for the module!") return 0 - var/obj/item/gun/energy/gun/secure/mounted/T = locate() in R.module + var/obj/item/gun/energy/gun/secure/mounted/T = locate() in robot.module if(!T) - T = locate() in R.module.equipment + T = locate() in robot.module.equipment if(!T) to_chat(usr, "This robot has had its energy gun removed!") return 0 if(T.recharge_time <= 2) - to_chat(R, "Maximum cooling achieved for this hardpoint!") + to_chat(robot, "Maximum cooling achieved for this hardpoint!") to_chat(usr, "There's no room for another cooling unit!") return 0 @@ -193,18 +193,18 @@ ) origin_tech = @'{"materials":2,"engineering":3,"programming":3,"magnets":3}' -/obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/robot) if(..()) return 0 - if(!R.module || !(type in R.module.supported_upgrades)) - to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + if(!robot.module || !(type in robot.module.supported_upgrades)) + to_chat(robot, "Upgrade mounting error! No suitable hardpoint detected!") to_chat(usr, "There's no mounting point for the module!") return 0 else - R.module.equipment += new/obj/item/tank/jetpack/carbondioxide - for(var/obj/item/tank/jetpack/carbondioxide in R.module.equipment) - R.set_internals(src) - //R.icon_state="Miner+j" + robot.module.equipment += new/obj/item/tank/jetpack/carbondioxide + for(var/obj/item/tank/jetpack/carbondioxide in robot.module.equipment) + robot.set_internals(src) + //robot.icon_state="Miner+j" return 1 /obj/item/borg/upgrade/rcd @@ -219,15 +219,15 @@ ) origin_tech = @'{"materials":4,"engineering":4,"programming":3}' -/obj/item/borg/upgrade/rcd/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/rcd/action(var/mob/living/silicon/robot/robot) if(..()) return 0 - if(!R.module || !(type in R.module.supported_upgrades)) - to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!") + if(!robot.module || !(type in robot.module.supported_upgrades)) + to_chat(robot, "Upgrade mounting error! No suitable hardpoint detected!") to_chat(usr, "There's no mounting point for the module!") return 0 else - R.module.equipment += new/obj/item/rcd/borg(R.module) + robot.module.equipment += new/obj/item/rcd/borg(robot.module) return 1 /obj/item/borg/upgrade/syndicate @@ -242,11 +242,11 @@ ) origin_tech = @'{"materials":2,"engineering":2,"programming":3,"esoteric":2,"combat":2}' -/obj/item/borg/upgrade/syndicate/action(var/mob/living/silicon/robot/R) +/obj/item/borg/upgrade/syndicate/action(var/mob/living/silicon/robot/robot) if(..()) return 0 - if(R.emagged == 1) + if(robot.emagged == 1) return 0 - R.emagged = 1 + robot.emagged = 1 return 1 diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm index 405c08b1f34c..0c4581d6c17f 100644 --- a/code/game/objects/items/stacks/nanopaste.dm +++ b/code/game/objects/items/stacks/nanopaste.dm @@ -21,18 +21,18 @@ return TRUE if (isrobot(target)) //Repairing cyborgs - var/mob/living/silicon/robot/R = target - if (R.getBruteLoss() || R.getFireLoss() ) + var/mob/living/silicon/robot/robot = target + if (robot.getBruteLoss() || robot.getFireLoss() ) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - R.heal_damage(BRUTE, 15, do_update_health = FALSE) - R.heal_damage(BURN, 15) + robot.heal_damage(BRUTE, 15, do_update_health = FALSE) + robot.heal_damage(BURN, 15) use(1) user.visible_message( - SPAN_NOTICE("\The [user] applied some [name] to \the [R]'s damaged areas."), - SPAN_NOTICE("You apply some [name] to \the [R]'s damaged areas.") + SPAN_NOTICE("\The [user] applied some [name] to \the [robot]'s damaged areas."), + SPAN_NOTICE("You apply some [name] to \the [robot]'s damaged areas.") ) else - to_chat(user, SPAN_NOTICE("\The [R]'s systems are all nominal.")) + to_chat(user, SPAN_NOTICE("\The [robot]'s systems are all nominal.")) return TRUE //Repairing robolimbs diff --git a/code/game/objects/items/weapons/AI_modules.dm b/code/game/objects/items/weapons/AI_modules.dm index edaf4f9a0e5c..efc2e1ac52de 100644 --- a/code/game/objects/items/weapons/AI_modules.dm +++ b/code/game/objects/items/weapons/AI_modules.dm @@ -64,9 +64,9 @@ AI MODULES if(!istype(ai)) return //We don't have slaves if we are not an AI - for(var/mob/living/silicon/robot/R in ai.connected_robots) - to_chat(R, "These are your laws now:") - R.show_laws() + for(var/mob/living/silicon/robot/robot in ai.connected_robots) + to_chat(robot, "These are your laws now:") + robot.show_laws() /obj/item/aiModule/proc/log_law_changes(mob/living/silicon/target, mob/sender) var/time = time2text(world.realtime,"hh:mm:ss") diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 88fd20ce3f67..0168e93f7a00 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -150,11 +150,11 @@ /obj/item/rcd/borg/useResource(var/amount, var/mob/user) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.cell) + var/mob/living/silicon/robot/robot = user + if(robot.cell) var/cost = amount*30 - if(R.cell.charge >= cost) - R.cell.use(cost) + if(robot.cell.charge >= cost) + robot.cell.use(cost) return 1 return 0 diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index 19fd6dc47b10..4ff86c966b5b 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -67,8 +67,8 @@ RSF if(!proximity) return if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.stat || !R.cell || R.cell.charge <= 0) + var/mob/living/silicon/robot/robot = user + if(robot.stat || !robot.cell || robot.cell.charge <= 0) return else if(stored_matter <= 0) @@ -106,9 +106,9 @@ RSF product.dropInto(A.loc) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - if(R.cell) - R.cell.use(used_energy) + var/mob/living/silicon/robot/robot = user + if(robot.cell) + robot.cell.use(used_energy) else stored_matter-- to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.") diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 8fb5342ed6e6..ff4c6ca763d4 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -471,14 +471,14 @@ cooldowntime = (3 SECONDS) /obj/item/shockpaddles/robot/check_charge(var/charge_amt) - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - return (R.cell && R.cell.check_charge(charge_amt)) + if(isrobot(loc)) + var/mob/living/silicon/robot/robot = loc + return robot.cell?.check_charge(charge_amt) /obj/item/shockpaddles/robot/checked_use(var/charge_amt) - if(isrobot(src.loc)) - var/mob/living/silicon/robot/R = src.loc - return (R.cell && R.cell.checked_use(charge_amt)) + if(isrobot(loc)) + var/mob/living/silicon/robot/robot = loc + return robot.cell?.checked_use(charge_amt) /obj/item/shockpaddles/rig name = "mounted defibrillator" @@ -490,19 +490,19 @@ wielded = 1 /obj/item/shockpaddles/rig/check_charge(var/charge_amt) - if(istype(src.loc, /obj/item/rig_module/device/defib)) - var/obj/item/rig_module/device/defib/module = src.loc + if(istype(loc, /obj/item/rig_module/device/defib)) + var/obj/item/rig_module/device/defib/module = loc return (module.holder && module.holder.cell && module.holder.cell.check_charge(charge_amt)) /obj/item/shockpaddles/rig/checked_use(var/charge_amt) - if(istype(src.loc, /obj/item/rig_module/device/defib)) - var/obj/item/rig_module/device/defib/module = src.loc + if(istype(loc, /obj/item/rig_module/device/defib)) + var/obj/item/rig_module/device/defib/module = loc return (module.holder && module.holder.cell && module.holder.cell.checked_use(charge_amt)) /obj/item/shockpaddles/rig/set_cooldown(var/delay) ..() - if(istype(src.loc, /obj/item/rig_module/device/defib)) - var/obj/item/rig_module/device/defib/module = src.loc + if(istype(loc, /obj/item/rig_module/device/defib)) + var/obj/item/rig_module/device/defib/module = loc module.next_use = world.time + delay /* Shockpaddles that are linked to a base unit diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 7b661c24a28d..eeacd5889360 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -161,8 +161,8 @@ // usability without proper checks. // Also hard-coded to be unuseable outside their righteous synthetic owners. /obj/item/baton/robot/attack_self(mob/user) - var/mob/living/silicon/robot/R = isrobot(user) ? user : null // null if the user is NOT a robot - if (R) + var/mob/living/silicon/robot/robot = isrobot(user) ? user : null // null if the user is NOT a robot + if (robot) return ..() else // Stop pretending and get out of your cardborg suit, human. to_chat(user, "You don't seem to be able to interact with this by yourself.") diff --git a/code/game/world_topic_commands.dm b/code/game/world_topic_commands.dm index cfd86601053b..b9babe9b5791 100644 --- a/code/game/world_topic_commands.dm +++ b/code/game/world_topic_commands.dm @@ -212,9 +212,9 @@ info["key"] = S.key if(isrobot(S)) - var/mob/living/silicon/robot/R = S - info["master"] = R.connected_ai?.name - info["sync"] = R.lawupdate + var/mob/living/silicon/robot/robot = S + info["master"] = robot.connected_ai?.name + info["sync"] = robot.lawupdate if(!S.laws) info["laws"] = null diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 9594f9dd3dd3..fe81cc6bc2f7 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1252,8 +1252,8 @@ var/global/BSACooldown = 0 if(isAI(S)) to_chat(usr, "AI [key_name(S, usr)]'s laws:") else if(isrobot(S)) - var/mob/living/silicon/robot/R = S - to_chat(usr, "CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independant)"]: laws:") + var/mob/living/silicon/robot/robot = S + to_chat(usr, "CYBORG [key_name(S, usr)] [robot.connected_ai?"(Slaved to: [robot.connected_ai])":"(Independant)"]: laws:") else if (ispAI(S)) to_chat(usr, "pAI [key_name(S, usr)]'s laws:") else diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm index 5b854a937467..e70154af3f76 100644 --- a/code/modules/events/event_dynamic.dm +++ b/code/modules/events/event_dynamic.dm @@ -12,9 +12,9 @@ .["Any"]++ if(isrobot(M)) - var/mob/living/silicon/robot/R = M - if(R.module?.associated_department) - var/decl/department/dept = GET_DECL(R.module.associated_department) + var/mob/living/silicon/robot/robot = M + if(robot.module?.associated_department) + var/decl/department/dept = GET_DECL(robot.module.associated_department) .[dept.name] = .[dept.name] + 1 else for(var/dtype in M.mind?.assigned_job?.department_types) diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index c19e7c42b325..b75e55818938 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -37,8 +37,8 @@ if(!(S.z in affecting_z)) continue if(isrobot(S)) - var/mob/living/silicon/robot/R = S - if(R.connected_ai) + var/mob/living/silicon/robot/robot = S + if(robot.connected_ai) continue var/random_player = get_random_humanoid_player_name("The Captain") var/list/laws = list( "You must always lie.", diff --git a/code/modules/keybindings/robot.dm b/code/modules/keybindings/robot.dm index e01ab94ae717..37ecc1772d3d 100644 --- a/code/modules/keybindings/robot.dm +++ b/code/modules/keybindings/robot.dm @@ -11,8 +11,8 @@ description = "Equips or unequips the first module" /datum/keybinding/robot/moduleone/down(client/user) - var/mob/living/silicon/robot/R = user.mob - R.toggle_module(1) + var/mob/living/silicon/robot/robot = user.mob + robot.toggle_module(1) return TRUE /datum/keybinding/robot/moduletwo @@ -22,8 +22,8 @@ description = "Equips or unequips the second module" /datum/keybinding/robot/moduletwo/down(client/user) - var/mob/living/silicon/robot/R = user.mob - R.toggle_module(2) + var/mob/living/silicon/robot/robot = user.mob + robot.toggle_module(2) return TRUE /datum/keybinding/robot/modulethree @@ -33,8 +33,8 @@ description = "Equips or unequips the third module" /datum/keybinding/robot/modulethree/down(client/user) - var/mob/living/silicon/robot/R = user.mob - R.toggle_module(3) + var/mob/living/silicon/robot/robot = user.mob + robot.toggle_module(3) return TRUE /datum/keybinding/robot/intent_cycle @@ -54,8 +54,8 @@ description = "Cycles your modules" /datum/keybinding/robot/module_cycle/down(client/user) - var/mob/living/silicon/robot/R = user.mob - R.cycle_modules() + var/mob/living/silicon/robot/robot = user.mob + robot.cycle_modules() return TRUE /datum/keybinding/robot/unequip_module @@ -65,7 +65,7 @@ description = "Unequips the active module" /datum/keybinding/robot/unequip_module/down(client/user) - var/mob/living/silicon/robot/R = user.mob - if(R.module) - R.uneq_active() + var/mob/living/silicon/robot/robot = user.mob + if(robot.module) + robot.uneq_active() return TRUE diff --git a/code/modules/mob/language/synthetic.dm b/code/modules/mob/language/synthetic.dm index 6f8a751bcac5..ffcc87c400cd 100644 --- a/code/modules/mob/language/synthetic.dm +++ b/code/modules/mob/language/synthetic.dm @@ -71,9 +71,9 @@ //robot binary xmitter component power usage if (isrobot(speaker)) - var/mob/living/silicon/robot/R = speaker - var/datum/robot_component/C = R.components["comms"] - R.cell_use_power(C.active_usage) + var/mob/living/silicon/robot/robot = speaker + var/datum/robot_component/C = robot.components["comms"] + robot.cell_use_power(C.active_usage) /decl/language/binary/drone name = "Drone Talk" diff --git a/code/modules/mob/living/silicon/ai/laws.dm b/code/modules/mob/living/silicon/ai/laws.dm index c1dba7c7b1c4..2fb329fc4b80 100644 --- a/code/modules/mob/living/silicon/ai/laws.dm +++ b/code/modules/mob/living/silicon/ai/laws.dm @@ -18,9 +18,9 @@ /mob/living/silicon/ai/add_ion_law(var/law) ..() - for(var/mob/living/silicon/robot/R in global.silicon_mob_list) - if(R.lawupdate && (R.connected_ai == src)) - R.show_laws() + for(var/mob/living/silicon/robot/robot in global.silicon_mob_list) + if(robot.lawupdate && (robot.connected_ai == src)) + robot.show_laws() /mob/living/silicon/ai/proc/ai_checklaws() set category = "Silicon Commands" diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm index 137c8c9fd44d..3d4a7b1000d8 100644 --- a/code/modules/mob/living/silicon/robot/component.dm +++ b/code/modules/mob/living/silicon/robot/component.dm @@ -19,8 +19,8 @@ /// The wrapped device(e.g. radio), only set if external_type isn't null var/obj/item/wrapped -/datum/robot_component/New(mob/living/silicon/robot/R) - src.owner = R +/datum/robot_component/New(mob/living/silicon/robot/robot) + src.owner = robot /datum/robot_component/proc/accepts_component(var/obj/item/thing) . = istype(thing, external_type) diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm b/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm index eb762b5f8ad0..49a95a47aa63 100644 --- a/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm +++ b/code/modules/mob/living/silicon/robot/flying/module_flying_emergency.dm @@ -68,7 +68,7 @@ var/obj/item/stack/medical/stack = locate(thing) in equipment stack.synths = list(medicine) -/obj/item/robot_module/flying/emergency/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/flying/emergency/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) var/obj/item/chems/spray/PS = emag if(PS && PS.reagents.total_volume < PS.volume) var/adding = min(PS.volume-PS.reagents.total_volume, 2*amount) diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm b/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm index f90d4d68887a..2a942c74e968 100644 --- a/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm +++ b/code/modules/mob/living/silicon/robot/flying/module_flying_forensics.dm @@ -36,7 +36,7 @@ SKILL_ANATOMY = SKILL_ADEPT ) -/obj/item/robot_module/flying/forensics/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/flying/forensics/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) var/obj/item/chems/spray/luminol/luminol = locate() in equipment if(!luminol) luminol = new(src) diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm b/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm index 259ac5bf9a58..83f08c2c46d1 100644 --- a/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm +++ b/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm @@ -90,8 +90,8 @@ PL.synths = list(plasteel) . = ..() -/obj/item/robot_module/flying/repair/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/flying/repair/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) var/obj/item/lightreplacer/LR = locate() in equipment if(LR) - LR.Charge(R, amount) + LR.Charge(robot, amount) ..() diff --git a/code/modules/mob/living/silicon/robot/modules/_module.dm b/code/modules/mob/living/silicon/robot/modules/_module.dm index 7bd571e00d42..3647dd37935a 100644 --- a/code/modules/mob/living/silicon/robot/modules/_module.dm +++ b/code/modules/mob/living/silicon/robot/modules/_module.dm @@ -46,29 +46,29 @@ . = ..() - var/mob/living/silicon/robot/R = loc - if(!istype(R)) + var/mob/living/silicon/robot/robot = loc + if(!istype(robot)) return INITIALIZE_HINT_QDEL - R.module = src + robot.module = src - grant_skills(R) - grant_software(R) - add_camera_channels(R) - add_languages(R) - add_subsystems(R) - apply_status_flags(R) + grant_skills(robot) + grant_software(robot) + add_camera_channels(robot) + add_languages(robot) + add_subsystems(robot) + apply_status_flags(robot) - build_equipment(R) - build_emag(R) - build_synths(R) + build_equipment(robot) + build_emag(robot) + build_synths(robot) - finalize_equipment(R) - finalize_emag(R) - finalize_synths(R) + finalize_equipment(robot) + finalize_emag(robot) + finalize_synths(robot) - if(R.client) - R.choose_icon(get_sprites_for(R)) + if(robot.client) + robot.choose_icon(get_sprites_for(robot)) /obj/item/robot_module/proc/build_equipment() var/list/created_equipment = list() @@ -115,19 +115,19 @@ log_debug("Invalid var type in [type] emag creation - [emag]") emag = null -/obj/item/robot_module/proc/Reset(var/mob/living/silicon/robot/R) - remove_camera_channels(R) - remove_languages(R) - remove_subsystems(R) - remove_status_flags(R) - reset_skills(R) - R.choose_icon(list("Basic" = initial(R.icon))) +/obj/item/robot_module/proc/Reset(var/mob/living/silicon/robot/robot) + remove_camera_channels(robot) + remove_languages(robot) + remove_subsystems(robot) + remove_status_flags(robot) + reset_skills(robot) + robot.choose_icon(list("Basic" = initial(robot.icon))) -/obj/item/robot_module/proc/get_sprites_for(var/mob/living/silicon/robot/R) +/obj/item/robot_module/proc/get_sprites_for(var/mob/living/silicon/robot/robot) . = module_sprites - if(R.ckey) - for(var/datum/custom_icon/cicon as anything in SScustomitems.custom_icons_by_ckey[R.ckey]) - if(cicon.category == display_name && lowertext(R.real_name) == cicon.character_name) + if(robot.ckey) + for(var/datum/custom_icon/cicon as anything in SScustomitems.custom_icons_by_ckey[robot.ckey]) + if(cicon.category == display_name && lowertext(robot.real_name) == cicon.character_name) for(var/state in cicon.ids_to_icons) .[state] = cicon.ids_to_icons[state] @@ -136,9 +136,9 @@ QDEL_NULL_LIST(synths) QDEL_NULL(emag) QDEL_NULL(jetpack) - var/mob/living/silicon/robot/R = loc - if(istype(R) && R.module == src) - R.module = null + var/mob/living/silicon/robot/robot = loc + if(istype(robot) && robot.module == src) + robot.module = null . = ..() /obj/item/robot_module/emp_act(severity) @@ -152,7 +152,7 @@ S.emp_act(severity) ..() -/obj/item/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate) +/obj/item/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/robot, var/rate) var/obj/item/flash/F = locate() in equipment if(F) if(F.broken) @@ -166,27 +166,27 @@ for(var/datum/matter_synth/T in synths) T.add_charge(T.recharge_rate * rate) -/obj/item/robot_module/proc/add_languages(var/mob/living/silicon/robot/R) +/obj/item/robot_module/proc/add_languages(var/mob/living/silicon/robot/robot) // Stores the languages as they were before receiving the module, and whether they could be synthezized. - for(var/decl/language/language_datum in R.languages) - original_languages[language_datum] = (language_datum in R.speech_synthesizer_langs) + for(var/decl/language/language_datum in robot.languages) + original_languages[language_datum] = (language_datum in robot.speech_synthesizer_langs) for(var/language in languages) - R.add_language(language, languages[language]) + robot.add_language(language, languages[language]) -/obj/item/robot_module/proc/remove_languages(var/mob/living/silicon/robot/R) +/obj/item/robot_module/proc/remove_languages(var/mob/living/silicon/robot/robot) // Clear all added languages, whether or not we originally had them. for(var/language in languages) - R.remove_language(language) + robot.remove_language(language) // Then add back all the original languages, and the relevant synthezising ability for(var/original_language in original_languages) var/decl/language/language_datum = original_language - R.add_language(language_datum.type, original_languages[original_language]) + robot.add_language(language_datum.type, original_languages[original_language]) original_languages.Cut() -/obj/item/robot_module/proc/add_camera_channels(var/mob/living/silicon/robot/R) - var/datum/extension/network_device/camera/robot/D = get_extension(R, /datum/extension/network_device/camera) +/obj/item/robot_module/proc/add_camera_channels(var/mob/living/silicon/robot/robot) + var/datum/extension/network_device/camera/robot/D = get_extension(robot, /datum/extension/network_device/camera) if(D) var/list/robot_channels = D.channels if(CAMERA_CHANNEL_ROBOTS in robot_channels) @@ -195,43 +195,43 @@ D.add_channels(channel) added_channels |= channel -/obj/item/robot_module/proc/remove_camera_channels(var/mob/living/silicon/robot/R) - var/datum/extension/network_device/camera/robot/D = get_extension(R, /datum/extension/network_device/camera) +/obj/item/robot_module/proc/remove_camera_channels(var/mob/living/silicon/robot/robot) + var/datum/extension/network_device/camera/robot/D = get_extension(robot, /datum/extension/network_device/camera) D.remove_channels(added_channels) added_channels.Cut() -/obj/item/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R) +/obj/item/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/robot) for(var/subsystem_type in subsystems) - R.init_subsystem(subsystem_type) + robot.init_subsystem(subsystem_type) -/obj/item/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R) +/obj/item/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/robot) for(var/subsystem_type in subsystems) - R.remove_subsystem(subsystem_type) + robot.remove_subsystem(subsystem_type) -/obj/item/robot_module/proc/apply_status_flags(var/mob/living/silicon/robot/R) +/obj/item/robot_module/proc/apply_status_flags(var/mob/living/silicon/robot/robot) if(!can_be_pushed) - R.status_flags &= ~CANPUSH + robot.status_flags &= ~CANPUSH -/obj/item/robot_module/proc/remove_status_flags(var/mob/living/silicon/robot/R) +/obj/item/robot_module/proc/remove_status_flags(var/mob/living/silicon/robot/robot) if(!can_be_pushed) - R.status_flags |= CANPUSH + robot.status_flags |= CANPUSH /obj/item/robot_module/proc/handle_emagged() return -/obj/item/robot_module/proc/grant_skills(var/mob/living/silicon/robot/R) - reset_skills(R) // for safety +/obj/item/robot_module/proc/grant_skills(var/mob/living/silicon/robot/robot) + reset_skills(robot) // for safety var/list/skill_mod = list() for(var/skill_type in skills) skill_mod[skill_type] = skills[skill_type] - SKILL_MIN // the buff is additive, so normalize accordingly - R.buff_skill(skill_mod, buff_type = /datum/skill_buff/robot) + robot.buff_skill(skill_mod, buff_type = /datum/skill_buff/robot) -/obj/item/robot_module/proc/reset_skills(var/mob/living/silicon/robot/R) - for(var/datum/skill_buff/buff in R.fetch_buffs_of_type(/datum/skill_buff/robot)) +/obj/item/robot_module/proc/reset_skills(var/mob/living/silicon/robot/robot) + for(var/datum/skill_buff/buff in robot.fetch_buffs_of_type(/datum/skill_buff/robot)) buff.remove() -/obj/item/robot_module/proc/grant_software(var/mob/living/silicon/robot/R) - var/datum/extension/interactive/os/os = get_extension(R, /datum/extension/interactive/os) +/obj/item/robot_module/proc/grant_software(var/mob/living/silicon/robot/robot) + var/datum/extension/interactive/os/os = get_extension(robot, /datum/extension/interactive/os) if(os && os.has_component(PART_HDD)) var/obj/item/stock_parts/computer/hard_drive/disk = os.get_component(PART_HDD) for(var/T in software) diff --git a/code/modules/mob/living/silicon/robot/modules/module_clerical.dm b/code/modules/mob/living/silicon/robot/modules/module_clerical.dm index 94f73f0d6370..dac31f36f3e8 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_clerical.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_clerical.dm @@ -62,14 +62,14 @@ /obj/item/robot_module/clerical/butler/finalize_emag() . = ..() if(emag) - var/datum/reagents/R = emag.create_reagents(50) - R.add_reagent(/decl/material/liquid/paralytics, 10) - R.add_reagent(/decl/material/liquid/sedatives, 15) - R.add_reagent(/decl/material/liquid/alcohol/beer, 20) - R.add_reagent(/decl/material/solid/ice, 5) + var/datum/reagents/reagent = emag.create_reagents(50) + reagent.add_reagent(/decl/material/liquid/paralytics, 10) + reagent.add_reagent(/decl/material/liquid/sedatives, 15) + reagent.add_reagent(/decl/material/liquid/alcohol/beer, 20) + reagent.add_reagent(/decl/material/solid/ice, 5) emag.SetName("Mickey Finn's Special Brew") -/obj/item/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/general/butler/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) ..() var/obj/item/chems/condiment/enzyme/E = locate() in equipment E.add_to_reagents(/decl/material/liquid/enzyme, 2 * amount) diff --git a/code/modules/mob/living/silicon/robot/modules/module_engineering.dm b/code/modules/mob/living/silicon/robot/modules/module_engineering.dm index fb3406b346d2..bab3a53ce0bf 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_engineering.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_engineering.dm @@ -107,7 +107,7 @@ var/obj/item/stack/material/cyborg/plasteel/PL = locate() in equipment PL.synths = list(plasteel) -/obj/item/robot_module/engineering/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/engineering/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) var/obj/item/lightreplacer/LR = locate() in equipment - LR.Charge(R, amount) + LR.Charge(robot, amount) ..() \ No newline at end of file diff --git a/code/modules/mob/living/silicon/robot/modules/module_illegal.dm b/code/modules/mob/living/silicon/robot/modules/module_illegal.dm index e899ec1a2221..6b0ab320b8ea 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_illegal.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_illegal.dm @@ -21,13 +21,13 @@ skills[skill.type] = SKILL_EXPERT . = ..() -/obj/item/robot_module/syndicate/build_equipment(var/mob/living/silicon/robot/R) +/obj/item/robot_module/syndicate/build_equipment(var/mob/living/silicon/robot/robot) . = ..() - id = R.idcard + id = robot.idcard equipment += id -/obj/item/robot_module/syndicate/finalize_equipment(var/mob/living/silicon/robot/R) - R.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment) +/obj/item/robot_module/syndicate/finalize_equipment(var/mob/living/silicon/robot/robot) + robot.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment) . = ..() /obj/item/robot_module/syndicate/Destroy() diff --git a/code/modules/mob/living/silicon/robot/modules/module_janitor.dm b/code/modules/mob/living/silicon/robot/modules/module_janitor.dm index e88d8b131125..92fe81b5f20f 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_janitor.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_janitor.dm @@ -31,10 +31,10 @@ emag.add_to_reagents(/decl/material/liquid/lube, 250) emag.SetName("lubricant spray") -/obj/item/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/janitor/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) ..() var/obj/item/lightreplacer/LR = locate() in equipment - LR.Charge(R, amount) + LR.Charge(robot, amount) if(emag) var/obj/item/chems/spray/S = emag S.add_to_reagents(/decl/material/liquid/lube, 20 * amount) diff --git a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm index 6d683809f001..d23e9445afc4 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm @@ -58,10 +58,10 @@ SKILL_ELECTRICAL = SKILL_EXPERT ) -/obj/item/robot_module/drone/finalize_equipment(var/mob/living/silicon/robot/R) +/obj/item/robot_module/drone/finalize_equipment(var/mob/living/silicon/robot/robot) . = ..() - if(istype(R)) - R.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment) + if(istype(robot)) + robot.set_internals(locate(/obj/item/tank/jetpack/carbondioxide) in equipment) /obj/item/robot_module/drone/finalize_emag() . = ..() @@ -112,12 +112,12 @@ var/obj/item/stack/material/cyborg/plastic/P = locate() in equipment P.synths = list(plastic) -/obj/item/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/drone/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) ..() var/obj/item/chems/spray/cleaner/drone/SC = locate() in equipment SC.add_to_reagents(/decl/material/liquid/cleaner, 8 * amount) var/obj/item/lightreplacer/LR = locate() in equipment - LR.Charge(R, amount) + LR.Charge(robot, amount) /obj/item/robot_module/drone/construction name = "construction drone module" diff --git a/code/modules/mob/living/silicon/robot/modules/module_medical.dm b/code/modules/mob/living/silicon/robot/modules/module_medical.dm index 7ec7e413ce6f..e4d027c4daec 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_medical.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_medical.dm @@ -83,7 +83,7 @@ var/obj/item/stack/medical/stack = locate(thing) in equipment stack.synths = list(medicine) -/obj/item/robot_module/medical/surgeon/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/medical/surgeon/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) if(emag) var/obj/item/chems/spray/PS = emag PS.add_to_reagents(/decl/material/liquid/acid/polyacid, 2 * amount) @@ -157,7 +157,7 @@ var/obj/item/stack/medical/stack = locate(thing) in equipment stack.synths = list(medicine) -/obj/item/robot_module/medical/crisis/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/medical/crisis/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) var/obj/item/chems/syringe/S = locate() in equipment if(S.mode == 2) S.reagents.clear_reagents() diff --git a/code/modules/mob/living/silicon/robot/modules/module_security.dm b/code/modules/mob/living/silicon/robot/modules/module_security.dm index 9322a91f7441..96bec1265129 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_security.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_security.dm @@ -20,7 +20,7 @@ SKILL_FORENSICS = SKILL_EXPERT ) -/obj/item/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/security/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) ..() for(var/obj/item/gun/energy/T in equipment) var/obj/item/cell/power_supply = T.get_cell() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2a481872bb61..a264865486ad 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -825,11 +825,10 @@ set name = "Reset Identity Codes" set desc = "Scrambles your security and identification codes and resets your current buffers. Unlocks you and but permanently severs you from your AI and the robotics console and will deactivate your camera system." - var/mob/living/silicon/robot/R = src - - if(R) - R.UnlinkSelf() - to_chat(R, "Buffers flushed and reset. Camera system shutdown. All systems operational.") + var/mob/living/silicon/robot/robot = src + if(robot) + robot.UnlinkSelf() + to_chat(robot, "Buffers flushed and reset. Camera system shutdown. All systems operational.") src.verbs -= /mob/living/silicon/robot/proc/ResetSecurityCodes /mob/living/silicon/robot/proc/SetLockdown(var/state = 1) diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index 8787fc156965..0ed14bd60fe1 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -339,12 +339,12 @@ if(!length(held)) to_chat(user, "The rack is empty.") return - var/obj/item/R = held[length(held)] - R.dropInto(loc) - held -= R - R.attack_self(user) // deploy it - to_chat(user, "You deploy [R].") - R.add_fingerprint(user) + var/obj/item/rack = held[length(held)] + rack.dropInto(loc) + held -= rack + rack.attack_self(user) // deploy it + to_chat(user, "You deploy [rack].") + rack.add_fingerprint(user) /obj/item/robot_rack/resolve_attackby(obj/O, mob/user, click_params) if(istype(O, object_type)) @@ -407,8 +407,8 @@ . = ..() /obj/item/bioreactor/Process() - var/mob/living/silicon/robot/R = loc - if(!istype(R) || !R.cell || R.cell.fully_charged() || !contents.len) + var/mob/living/silicon/robot/robot = loc + if(!istype(robot) || !robot.cell || robot.cell.fully_charged() || !contents.len) return var/generating_power @@ -435,4 +435,4 @@ qdel(using_item) if(generating_power) - R.cell.give(generating_power * CELLRATE) + robot.cell.give(generating_power * CELLRATE) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 99f0b0fe161b..65a7437dfd92 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -65,8 +65,8 @@ var/mob/M = mob M.swap_hand() if(isrobot(mob)) - var/mob/living/silicon/robot/R = mob - R.cycle_modules() + var/mob/living/silicon/robot/robot = mob + robot.cycle_modules() return /client/verb/attack_self() diff --git a/code/modules/modular_computers/os/subtypes/silicon.dm b/code/modules/modular_computers/os/subtypes/silicon.dm index 0d96b436353b..06a7f0d58143 100644 --- a/code/modules/modular_computers/os/subtypes/silicon.dm +++ b/code/modules/modular_computers/os/subtypes/silicon.dm @@ -16,9 +16,9 @@ return M.stock_parts.Copy() /datum/extension/interactive/os/silicon/emagged() - var/mob/living/silicon/robot/R = holder - if(istype(R)) - return R.emagged + var/mob/living/silicon/robot/robot = holder + if(istype(robot)) + return robot.emagged return FALSE /datum/extension/interactive/os/silicon/host_status() @@ -37,7 +37,7 @@ var/datum/extension/interactive/os/os = get_extension(src, /datum/extension/interactive/os) if(os) return os.check_eye() - else + else return ..() /datum/extension/interactive/os/silicon/small/get_hardware_flag() diff --git a/code/modules/nano/modules/law_manager.dm b/code/modules/nano/modules/law_manager.dm index fe0a427807ab..235e64cde9b4 100644 --- a/code/modules/nano/modules/law_manager.dm +++ b/code/modules/nano/modules/law_manager.dm @@ -138,9 +138,9 @@ owner.laws.show_laws(owner) if(isAI(owner)) var/mob/living/silicon/ai/AI = owner - for(var/mob/living/silicon/robot/R in AI.connected_robots) - to_chat(R, "Law Notice") - R.laws.show_laws(R) + for(var/mob/living/silicon/robot/robot in AI.connected_robots) + to_chat(robot, "Law Notice") + robot.laws.show_laws(robot) if(usr != owner) to_chat(usr, "Laws displayed.") return 1 @@ -214,6 +214,6 @@ /datum/nano_module/law_manager/proc/sync_laws(var/mob/living/silicon/ai/AI) if(!AI) return - for(var/mob/living/silicon/robot/R in AI.connected_robots) - R.sync() + for(var/mob/living/silicon/robot/robot in AI.connected_robots) + robot.sync() log_and_message_admins("has syncronized [AI]'s laws with its borgs.") diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index f00722b2d3c9..0eb0729530dd 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -899,8 +899,8 @@ By design, d1 is the smallest direction and d2 is the highest var/obj/item/rig_module/module = loc return module.get_cell() if(isrobot(loc)) - var/mob/living/silicon/robot/R = loc - return R.get_cell() + var/mob/living/silicon/robot/robot = loc + return robot.get_cell() /obj/item/stack/cable_coil/fabricator/use(var/used) var/obj/item/cell/cell = get_cell() diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 8af653291679..dc9234516221 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -88,8 +88,8 @@ // remove this if EMPs are ever rebalanced so that they don't instantly drain borg cells // todo: containers (partially) shielding contents? if(isrobot(loc)) - var/mob/living/silicon/robot/R = loc - severity *= R.cell_emp_mult + var/mob/living/silicon/robot/robot = loc + severity *= robot.cell_emp_mult // Lose 1/2, 1/4, 1/6 of the current charge per hit or 1/4, 1/8, 1/12 of the max charge per hit, whichever is highest charge -= max(charge / (2 * severity), maxcharge/(4 * severity)) diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index ff77df0fa33d..1c3821119369 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -22,12 +22,12 @@ /obj/item/projectile/change/proc/apply_transformation(var/mob/M, var/choice) if(choice == "robot") - var/mob/living/silicon/robot/R = new(get_turf(M)) - R.set_gender(M.get_gender()) - R.job = ASSIGNMENT_ROBOT - R.central_processor = new /obj/item/organ/internal/brain_interface(R) - transfer_key_from_mob_to_mob(M, R) - return R + var/mob/living/silicon/robot/robot = new(get_turf(M)) + robot.set_gender(M.get_gender()) + robot.job = ASSIGNMENT_ROBOT + robot.central_processor = new /obj/item/organ/internal/brain_interface(robot) + transfer_key_from_mob_to_mob(M, robot) + return robot if(get_species_by_key(choice)) var/mob/living/human/H = M diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index bf1306f42ce1..1e2271efa3ad 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -35,8 +35,8 @@ for(var/T in reagent_ids) reagent_volumes[T] = volume - var/decl/material/R = T - reagent_names += initial(R.name) + var/decl/material/robot = T + reagent_names += initial(robot.name) START_PROCESSING(SSobj, src) /obj/item/chems/borghypo/Destroy() @@ -49,11 +49,11 @@ charge_tick = 0 if(isrobot(loc)) - var/mob/living/silicon/robot/R = loc - if(R && R.cell) + var/mob/living/silicon/robot/robot = loc + if(robot && robot.cell) for(var/T in reagent_ids) if(reagent_volumes[T] < volume) - R.cell.use(charge_cost) + robot.cell.use(charge_cost) reagent_volumes[T] = min(reagent_volumes[T] + 5, volume) return 1 @@ -103,16 +103,16 @@ if(index > 0 && index <= reagent_ids.len) playsound(loc, 'sound/effects/pop.ogg', 50, 0) mode = index - var/decl/material/R = reagent_ids[mode] - to_chat(user, "Synthesizer is now producing '[initial(R.name)]'.") + var/decl/material/robot = reagent_ids[mode] + to_chat(user, "Synthesizer is now producing '[initial(robot.name)]'.") return TOPIC_REFRESH /obj/item/chems/borghypo/get_examine_strings(mob/user, distance, infix, suffix) . = ..() if(distance > 2) return - var/decl/material/R = reagent_ids[mode] - . += SPAN_NOTICE("It is currently producing [initial(R.name)] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left.") + var/decl/material/robot = reagent_ids[mode] + . += SPAN_NOTICE("It is currently producing [initial(robot.name)] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left.") /obj/item/chems/borghypo/service name = "cyborg drink synthesizer" diff --git a/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm b/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm index 34b02a83da74..1af0fa44e757 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm @@ -7,11 +7,11 @@ /datum/artifact_effect/cellcharge/DoEffectTouch(var/mob/user) if(user) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - var/obj/item/cell/C = R.get_cell() + var/mob/living/silicon/robot/robot = user + var/obj/item/cell/C = robot.get_cell() if(C) C.give(100) - to_chat(R, SPAN_NOTICE("SYSTEM ALERT: Energy boost detected!")) + to_chat(robot, SPAN_NOTICE("SYSTEM ALERT: Energy boost detected!")) return 1 /datum/artifact_effect/cellcharge/DoEffectAura() diff --git a/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm b/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm index af5e8c2640ec..dba19e3b67ee 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm @@ -7,11 +7,11 @@ /datum/artifact_effect/celldrain/DoEffectTouch(var/mob/user) if(user) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - var/obj/item/cell/C = R.get_cell() + var/mob/living/silicon/robot/robot = user + var/obj/item/cell/C = robot.get_cell() if(C) C.use(100) - to_chat(R, SPAN_WARNING("SYSTEM ALERT: Energy drain detected!")) + to_chat(robot, SPAN_WARNING("SYSTEM ALERT: Energy drain detected!")) return 1 /datum/artifact_effect/celldrain/DoEffectAura() diff --git a/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm b/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm index e2ad7fd09678..ead27ed391b6 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/roboheal.dm @@ -8,9 +8,9 @@ /datum/artifact_effect/roboheal/DoEffectTouch(var/mob/user) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - to_chat(R, "Your systems report damaged components mending by themselves!") - R.heal_overall_damage(rand(10,30), rand(10,30)) + var/mob/living/silicon/robot/robot = user + to_chat(robot, "Your systems report damaged components mending by themselves!") + robot.heal_overall_damage(rand(10,30), rand(10,30)) return 1 /datum/artifact_effect/roboheal/DoEffectAura() diff --git a/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm b/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm index c5dde6b16b62..ff66d2659af8 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/robohurt.dm @@ -8,9 +8,9 @@ /datum/artifact_effect/robohurt/DoEffectTouch(var/mob/user) if(isrobot(user)) - var/mob/living/silicon/robot/R = user - to_chat(R, "Your systems report severe damage has been inflicted!") - R.take_overall_damage(rand(10,50), rand(10,50)) + var/mob/living/silicon/robot/robot = user + to_chat(robot, "Your systems report severe damage has been inflicted!") + robot.take_overall_damage(rand(10,50), rand(10,50)) return 1 /datum/artifact_effect/robohurt/DoEffectAura() diff --git a/code/modules/xenoarcheaology/boulder.dm b/code/modules/xenoarcheaology/boulder.dm index ba7a38c2f3d2..75b6df14520b 100644 --- a/code/modules/xenoarcheaology/boulder.dm +++ b/code/modules/xenoarcheaology/boulder.dm @@ -95,6 +95,6 @@ attackby(P, H) return else if(isrobot(AM)) - var/mob/living/silicon/robot/R = AM - if(IS_PICK(R.module_active)) - attackby(R.module_active,R) + var/mob/living/silicon/robot/robot = AM + if(IS_PICK(robot.module_active)) + attackby(robot.module_active,robot) diff --git a/mods/gamemodes/traitor/special_role.dm b/mods/gamemodes/traitor/special_role.dm index 4ae85327394f..495156274c05 100644 --- a/mods/gamemodes/traitor/special_role.dm +++ b/mods/gamemodes/traitor/special_role.dm @@ -107,10 +107,10 @@ if(issilicon(player)) // this needs to be here because ..() returns false if the mob isn't human add_law_zero(player) if(isrobot(player)) - var/mob/living/silicon/robot/R = player - R.SetLockdown(FALSE) - R.emagged = TRUE // Provides a traitor robot with its module's emag item - R.verbs |= /mob/living/silicon/robot/proc/ResetSecurityCodes + var/mob/living/silicon/robot/robot = player + robot.SetLockdown(FALSE) + robot.emagged = TRUE // Provides a traitor robot with its module's emag item + robot.verbs |= /mob/living/silicon/robot/proc/ResetSecurityCodes . = TRUE else if(.) spawn_uplink(player) diff --git a/mods/species/ascent/mobs/drone.dm b/mods/species/ascent/mobs/drone.dm index 2294585ee151..5c972fe7887a 100644 --- a/mods/species/ascent/mobs/drone.dm +++ b/mods/species/ascent/mobs/drone.dm @@ -121,7 +121,7 @@ . = ..() -/obj/item/robot_module/flying/ascent/respawn_consumable(var/mob/living/silicon/robot/R, var/amount) +/obj/item/robot_module/flying/ascent/respawn_consumable(var/mob/living/silicon/robot/robot, var/amount) var/obj/item/stack/medical/resin/drone/resin = locate() in equipment if(!resin) resin = new(src, 1) From da40763035dfbc085d4e471a86612fceb43e445f Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 17 Feb 2025 12:51:29 +1100 Subject: [PATCH 010/512] R -> relation --- mods/content/matchmaking/matchmaker.dm | 110 ++++++++++---------- mods/content/matchmaking/relations.dm | 27 +++-- mods/content/matchmaking/relations_types.dm | 12 +-- 3 files changed, 74 insertions(+), 75 deletions(-) diff --git a/mods/content/matchmaking/matchmaker.dm b/mods/content/matchmaking/matchmaker.dm index ee7d49c6be8d..8f6bb706cb5d 100644 --- a/mods/content/matchmaking/matchmaker.dm +++ b/mods/content/matchmaking/matchmaker.dm @@ -10,9 +10,9 @@ if(character.mind && character.client?.prefs.relations.len) for(var/T in character.client.prefs.relations) var/TT = relation_types[T] - var/datum/relation/R = new TT - R.holder = character.mind - R.info = character.client.prefs.relations_info[T] + var/datum/relation/relation = new TT + relation.holder = character.mind + relation.info = character.client.prefs.relations_info[T] character.mind.gen_relations_info = character.client.prefs.relations_info["general"] if(!ishuman(character)) return TRUE @@ -35,31 +35,31 @@ /decl/modpack/matchmaking/Initialize() . = ..() for(var/T in subtypesof(/datum/relation/)) - var/datum/relation/R = T - relation_types[initial(R.name)] = T + var/datum/relation/relation = T + relation_types[initial(relation.name)] = T /decl/modpack/matchmaking/proc/do_matchmaking() var/list/to_warn = list() - for(var/datum/relation/R in relations) - if(R.other) + for(var/datum/relation/relation in relations) + if(relation.other) continue // don't warn about already-matched relations, even if they aren't finalised - R.find_match() - if(R.other && !R.finalized) - to_warn |= R.holder.current + relation.find_match() + if(relation.other && !relation.finalized) + to_warn |= relation.holder.current for(var/mob/M in to_warn) to_chat(M,"You have new connections. Use \"See Relationship Info\" to view and finalize them.") /decl/modpack/matchmaking/proc/get_relationships(datum/mind/M, finalized_only) . = list() - for(var/datum/relation/R in relations) - if(R.holder == M && R.other && (R.finalized || !finalized_only)) - . += R + for(var/datum/relation/relation in relations) + if(relation.holder == M && relation.other && (relation.finalized || !finalized_only)) + . += relation /decl/modpack/matchmaking/proc/get_relationships_between(datum/mind/holder, datum/mind/target, finalized_only) . = list() - for(var/datum/relation/R in relations) - if(R.holder == holder && R.other && R.other.holder == target && (R.finalized || !finalized_only)) - . += R + for(var/datum/relation/relation in relations) + if(relation.holder == holder && relation.other && relation.other.holder == target && (relation.finalized || !finalized_only)) + . += relation /decl/human_examination/matchmaking/do_examine(var/mob/living/user, var/distance, var/mob/living/source) //These can either return text, or should return nothing at all if you're doing to_chat() if(!istype(source) || !istype(user)) @@ -94,10 +94,10 @@ /datum/relation/proc/get_candidates() .= list() var/decl/modpack/matchmaking/matchmaker = IMPLIED_DECL - for(var/datum/relation/R in matchmaker.relations) - if(!valid_candidate(R.holder) || !can_connect(R)) + for(var/datum/relation/relation in matchmaker.relations) + if(!valid_candidate(relation.holder) || !can_connect(relation)) continue - . += R + . += relation /datum/relation/proc/valid_candidate(datum/mind/M) if(M == holder) //no, you NEED other people @@ -112,31 +112,31 @@ return TRUE -/datum/relation/proc/can_connect(var/datum/relation/R) +/datum/relation/proc/can_connect(var/datum/relation/relation) var/decl/modpack/matchmaking/matchmaker = IMPLIED_DECL for(var/datum/relation/D in matchmaker.relations) //have to check all connections between us and them - if(D.holder == R.holder && D.other && D.other.holder == holder) + if(D.holder == relation.holder && D.other && D.other.holder == holder) if(D.type in incompatible) return 0 - return (R.type in can_connect_to) && !(R.type in incompatible) && R.open + return (relation.type in can_connect_to) && !(relation.type in incompatible) && relation.open /datum/relation/proc/get_copy() - var/datum/relation/R = new type - R.holder = holder - R.info = holder.current && holder.current.client ? holder.current.client.prefs.relations_info[R.name] : info - R.open = 0 - return R + var/datum/relation/relation = new type + relation.holder = holder + relation.info = holder.current && holder.current.client ? holder.current.client.prefs.relations_info[relation.name] : info + relation.open = 0 + return relation /datum/relation/proc/find_match() var/list/candidates = get_candidates() if(!candidates.len) //bwoop bwoop return 0 - var/datum/relation/R = pick(candidates) - R.open-- - if(R.other) - R = R.get_copy() - other = R - R.other = src + var/datum/relation/relation = pick(candidates) + relation.open-- + if(relation.other) + relation = relation.get_copy() + other = relation + relation.other = src return 1 /datum/relation/proc/sever() @@ -198,16 +198,16 @@ dat += "Things they all know about you:
    [mind.gen_relations_info]
    " dat += "An \[F\] indicates that the other player has finalized the connection.
    " dat += "
    " - for(var/datum/relation/R in relations) - dat += "[R.other.finalized ? "\[F\] " : ""][R.other.holder], [R.other.holder.role_alt_title ? R.other.holder.role_alt_title : R.other.holder.assigned_role]." - if (!R.finalized) - dat += " Remove" + for(var/datum/relation/relation in relations) + dat += "[relation.other.finalized ? "\[F\] " : ""][relation.other.holder], [relation.other.holder.role_alt_title ? relation.other.holder.role_alt_title : relation.other.holder.assigned_role]." + if (!relation.finalized) + dat += " Remove" editable = 1 - dat += "
    [R.desc]" + dat += "
    [relation.desc]" dat += "
    " - dat += "Things they know about you:[!R.finalized ?"Edit" : ""]
    [R.info ? "[R.info]" : " Nothing specific."]" - if(R.other.info) - dat += "
    Things you know about them:
    [R.other.info]
    [R.other.holder.gen_relations_info]" + dat += "Things they know about you:[!relation.finalized ?"Edit" : ""]
    [relation.info ? "[relation.info]" : " Nothing specific."]" + if(relation.other.info) + dat += "
    Things you know about them:
    [relation.other.info]
    [relation.other.holder.gen_relations_info]" dat += "
    " if(mind.known_connections && mind.known_connections.len) @@ -231,12 +231,12 @@ if(mind.gen_relations_info) dat += "Things they know about you:
    [mind.gen_relations_info]
    " dat += "
    " - for(var/datum/relation/R in relations) - dat += "
    [R.desc]" + for(var/datum/relation/relation in relations) + dat += "
    [relation.desc]" dat += "
    " - dat += "Things they know about you:
    [R.info ? "[R.info]" : " Nothing specific."]" - if(R.other.info) - dat += "
    Things you know about them:
    [R.other.info]
    [R.other.holder.gen_relations_info]" + dat += "Things they know about you:
    [relation.info ? "[relation.info]" : " Nothing specific."]" + if(relation.other.info) + dat += "
    Things you know about them:
    [relation.other.info]
    [relation.other.holder.gen_relations_info]" dat += "
    " var/datum/browser/popup = new(usr, "relations", "Relationship Info") @@ -256,17 +256,17 @@ /mob/living/OnSelfTopic(href_list) if(href_list["del_relation"]) - var/datum/relation/R = locate(href_list["del_relation"]) - if(istype(R)) - R.sever() + var/datum/relation/relation = locate(href_list["del_relation"]) + if(istype(relation)) + relation.sever() see_relationship_info() return TOPIC_HANDLED if(href_list["info_relation"]) - var/datum/relation/R = locate(href_list["info_relation"]) - if(istype(R)) - var/info = sanitize(input("What would you like the other party for this connection to know about your character?","Character info",R.info) as message|null) + var/datum/relation/relation = locate(href_list["info_relation"]) + if(istype(relation)) + var/info = sanitize(input("What would you like the other party for this connection to know about your character?","Character info",relation.info) as message|null) if(info) - R.info = info + relation.info = info see_relationship_info() return TOPIC_HANDLED if(href_list["relations_close"]) @@ -275,8 +275,8 @@ if(ok == "Close anyway") var/decl/modpack/matchmaking/matchmaker = IMPLIED_DECL var/list/relations = matchmaker.get_relationships(mind) - for(var/datum/relation/R in relations) - R.finalize() + for(var/datum/relation/relation in relations) + relation.finalize() show_browser(src,null, "window=relations") else show_browser(src,null, "window=relations") diff --git a/mods/content/matchmaking/relations.dm b/mods/content/matchmaking/relations.dm index e516f04e83f0..69f14f086b67 100644 --- a/mods/content/matchmaking/relations.dm +++ b/mods/content/matchmaking/relations.dm @@ -32,30 +32,29 @@ . += "
    What do they know about you? This is the general info that all kinds of your connections would know. Edit" . += "
    [pref.relations_info["general"] ? pref.relations_info["general"] : "Nothing specific."]" . += "
    " - for(var/T in subtypesof(/datum/relation)) - var/datum/relation/R = T - . += "[initial(R.name)]\t" - if(initial(R.name) in pref.relations) + for(var/datum/relation/relation as anything in subtypesof(/datum/relation)) + . += "[initial(relation.name)]\t" + if(initial(relation.name) in pref.relations) . += "On" - . += "Off" + . += "Off" else - . += "On" + . += "On" . += "Off" - . += "
    [initial(R.desc)]" - . += "
    What do they know about you?Edit" - . += "
    [pref.relations_info[initial(R.name)] ? pref.relations_info[initial(R.name)] : "Nothing specific."]" + . += "
    [initial(relation.desc)]" + . += "
    What do they know about you?Edit" + . += "
    [pref.relations_info[initial(relation.name)] ? pref.relations_info[initial(relation.name)] : "Nothing specific."]" . += "
    " . = jointext(.,null) /datum/category_item/player_setup_item/relations/OnTopic(var/href,var/list/href_list, var/mob/user) if(href_list["relation"]) - var/R = href_list["relation"] - pref.relations ^= R + var/relation = href_list["relation"] + pref.relations ^= relation return TOPIC_REFRESH if(href_list["relation_info"]) - var/R = href_list["relation_info"] - var/info = sanitize(input("Character info", "What would you like the other party for this connection to know about your character?",html_decode(pref.relations_info[R])) as message|null) + var/relation = href_list["relation_info"] + var/info = sanitize(input("Character info", "What would you like the other party for this connection to know about your character?",html_decode(pref.relations_info[relation])) as message|null) if(info) - pref.relations_info[R] = info + pref.relations_info[relation] = info return TOPIC_REFRESH return ..() diff --git a/mods/content/matchmaking/relations_types.dm b/mods/content/matchmaking/relations_types.dm index e6b35612b5c1..8f244851084c 100644 --- a/mods/content/matchmaking/relations_types.dm +++ b/mods/content/matchmaking/relations_types.dm @@ -66,13 +66,13 @@ var/list/rest = ..() var/list/best = list() var/list/good = list() - for(var/datum/relation/R in rest) - if(!R.holder.assigned_job || !holder.assigned_job) + for(var/datum/relation/relation in rest) + if(!relation.holder.assigned_job || !holder.assigned_job) continue - if(R.holder.assigned_job == holder.assigned_job) - best += R - if(LAZYLEN(R.holder.assigned_job.department_types & holder.assigned_job.department_types)) - good += R + if(relation.holder.assigned_job == holder.assigned_job) + best += relation + if(LAZYLEN(relation.holder.assigned_job.department_types & holder.assigned_job.department_types)) + good += relation if(best.len) return best else if (good.len) From 8cee422c60f340bde87b95cd44aa93e3f2250bf2 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 17 Feb 2025 12:51:50 +1100 Subject: [PATCH 011/512] Many single-letter vars changed in list helpers. --- code/_helpers/lists.dm | 319 +++++++++--------- code/datums/uplink/uplink_sources.dm | 14 +- code/datums/wires/radio.dm | 24 +- .../networking/machinery/telecomms.dm | 18 +- 4 files changed, 188 insertions(+), 187 deletions(-) diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index 074d04728d4d..1d3dc695e8bf 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -114,7 +114,7 @@ return TRUE return FALSE -//returns a new list with only atoms that are in typecache L +//returns a new list with only atoms that are in typecache atoms /proc/typecache_filter_list(list/atoms, list/typecache) . = list() for(var/thing in atoms) @@ -150,37 +150,36 @@ types = list(path) else types = ignore_root_path ? subtypesof(path) : typesof(path) - var/list/L = list() + var/list/typelist = list() for(var/T in types) - L[T] = TRUE - return L + typelist[T] = TRUE + return typelist else if(islist(path)) var/list/pathlist = path - var/list/L = list() + var/list/typelist = list() if(ignore_root_path) for(var/P in pathlist) for(var/T in subtypesof(P)) - L[T] = TRUE + typelist[T] = TRUE else for(var/P in pathlist) if(only_root_path) - L[P] = TRUE + typelist[P] = TRUE else for(var/T in typesof(P)) - L[T] = TRUE - return L + typelist[T] = TRUE + return typelist //Checks for specific types in specifically structured (Assoc "type" = TRUE) lists ('typecaches') -/proc/is_type_in_typecache(atom/A, list/L) - if(!L || !L.len || !A) - +/proc/is_type_in_typecache(atom/A, list/cache) + if(!cache || !cache.len || !A) return 0 - return L[A.type] + return cache[A.type] -/proc/instances_of_type_in_list(var/atom/A, var/list/L) +/proc/instances_of_type_in_list(var/atom/A, var/list/target_list) var/instances = 0 - for(var/type in L) + for(var/type in target_list) if(istype(A, type)) instances++ return instances @@ -270,17 +269,17 @@ Checks if a list has the same entries and values as an element of big. .[key] = call(merge_method)(.[key], b_value) //Pretends to pick an element based on its weight but really just seems to pick a random element. -/proc/pickweight(list/L) +/proc/pickweight(list/target_list) var/total = 0 var/item - for (item in L) - if (!L[item]) - L[item] = 1 - total += L[item] + for (item in target_list) + if (!target_list[item]) + target_list[item] = 1 + total += target_list[item] total = rand(1, total) - for (item in L) - total -=L [item] + for (item in target_list) + total -=target_list [item] if (total <= 0) return item @@ -303,87 +302,87 @@ Checks if a list has the same entries and values as an element of big. return null //Returns the first element from the list and removes it from the list -/proc/popleft(list/L) - if(length(L)) - . = L[1] - L.Cut(1,2) +/proc/popleft(list/target_list) + if(length(target_list)) + . = target_list[1] + target_list.Cut(1,2) //Returns the next element in parameter list after first appearance of parameter element. If it is the last element of the list or not present in list, returns first element. -/proc/next_in_list(element, list/L) - for(var/i = 1 to L.len) - if(L[i] == element) - if(i >= L.len) - return L[1] - return L[i+1] - return L[1] +/proc/next_in_list(element, list/target_list) + for(var/i = 1 to target_list.len) + if(target_list[i] == element) + if(i >= target_list.len) + return target_list[1] + return target_list[i+1] + return target_list[1] //Returns the previous element in parameter list after first appearance of parameter element. If it is the first element of the list or not present in list, returns first element. -/proc/previous_in_list(element, list/L) - for(var/i = 1 to L.len) - if(L[i] == element) +/proc/previous_in_list(element, list/target_list) + for(var/i = 1 to target_list.len) + if(target_list[i] == element) if(i <= 1) - return L[L.len] - return L[i-1] - return L[L.len] + return target_list[target_list.len] + return target_list[i-1] + return target_list[target_list.len] /* * Sorting */ //Reverses the order of items in the list -/proc/reverselist(list/L) +/proc/reverselist(list/target_list) var/list/output = list() - if(L) - for(var/i = L.len; i >= 1; i--) - output += L[i] + if(target_list) + for(var/i = target_list.len; i >= 1; i--) + output += target_list[i] return output //Randomize: Return the list in a random order -/proc/shuffle(var/list/L) - if(!L) +/proc/shuffle(var/list/target_list) + if(!target_list) return - L = L.Copy() + target_list = target_list.Copy() - for(var/i=1; i 0) ? i : i+1 + if(i == 1 || i == target_list.len) // Edge cases + return (call(cmp)(target_list[i],A) > 0) ? i : i+1 else return i -/proc/dd_sortedObjectList(var/list/L, var/cache=list()) - if(L.len < 2) - return L - var/middle = L.len / 2 + 1 // Copy is first,second-1 - return dd_mergeObjectList(dd_sortedObjectList(L.Copy(0,middle), cache), dd_sortedObjectList(L.Copy(middle), cache), cache) //second parameter null = to end of list +/proc/dd_sortedObjectList(var/list/target_list, var/cache=list()) + if(target_list.len < 2) + return target_list + var/middle = target_list.len / 2 + 1 // Copy is first,second-1 + return dd_mergeObjectList(dd_sortedObjectList(target_list.Copy(0,middle), cache), dd_sortedObjectList(target_list.Copy(middle), cache), cache) //second parameter null = to end of list -/proc/dd_mergeObjectList(var/list/L, var/list/R, var/list/cache) - var/Li=1 - var/Ri=1 +/proc/dd_mergeObjectList(var/list/target_list, var/list/right, var/list/cache) + var/left_index=1 + var/right_index=1 var/list/result = new() - while(Li <= L.len && Ri <= R.len) - var/LLi = L[Li] - var/RRi = R[Ri] + while(left_index <= target_list.len && right_index <= right.len) + var/LLi = target_list[left_index] + var/RRi = right[right_index] var/LLiV = cache[LLi] var/RRiV = cache[RRi] if(!LLiV) @@ -484,31 +483,31 @@ Checks if a list has the same entries and values as an element of big. RRiV = RRi:dd_SortValue() cache[RRi] = RRiV if(LLiV < RRiV) - result += L[Li++] + result += target_list[left_index++] else - result += R[Ri++] + result += right[right_index++] - if(Li <= L.len) - return (result + L.Copy(Li, 0)) - return (result + R.Copy(Ri, 0)) + if(left_index <= target_list.len) + return (result + target_list.Copy(left_index, 0)) + return (result + right.Copy(right_index, 0)) // Insert an object into a sorted list, preserving sortedness -/proc/dd_insertObjectList(var/list/L, var/O) +/proc/dd_insertObjectList(var/list/target_list, var/O) var/min = 1 - var/max = L.len + 1 + var/max = target_list.len + 1 var/Oval = O:dd_SortValue() while(1) var/mid = min+round((max-min)/2) if(mid == max) - L.Insert(mid, O) + target_list.Insert(mid, O) return - var/Lmid = L[mid] + var/Lmid = target_list[mid] var/midval = Lmid:dd_SortValue() if(Oval == midval) - L.Insert(mid, O) + target_list.Insert(mid, O) return else if(Oval < midval) max = mid @@ -644,27 +643,29 @@ proc/dd_sortedObjectList(list/incoming) /datum/alarm/dd_SortValue() return "[sanitize_old(last_name)]" -//creates every subtype of prototype (excluding prototype) and adds it to list L. -//if no list/L is provided, one is created. -/proc/init_subtypes(prototype, list/L) - if(!istype(L)) L = list() +//creates every subtype of prototype (excluding prototype) and adds it to list target_list. +//if no list/target_list is provided, one is created. +/proc/init_subtypes(prototype, list/target_list) + if(!islist(target_list)) + target_list = list() for(var/path in subtypesof(prototype)) - L += new path() - return L - -//creates every subtype of prototype (excluding prototype) and adds it to list L as a type/instance pair. -//if no list/L is provided, one is created. -/proc/init_subtypes_assoc(prototype, list/L) - if(!istype(L)) L = list() + target_list += new path() + return target_list + +//creates every subtype of prototype (excluding prototype) and adds it to list target_list as a type/instance pair. +//if no list/target_list is provided, one is created. +/proc/init_subtypes_assoc(prototype, list/target_list) + if(!islist(target_list)) + target_list = list() for(var/path in subtypesof(prototype)) - L[path] = new path() - return L + target_list[path] = new path() + return target_list #define listequal(A, B) (A.len == B.len && !length(A^B)) -/proc/filter_list(var/list/L, var/type) +/proc/filter_list(var/list/target_list, var/type) . = list() - for(var/entry in L) + for(var/entry in target_list) if(istype(entry, type)) . += entry @@ -676,10 +677,10 @@ proc/dd_sortedObjectList(list/incoming) values += value -/proc/duplicates(var/list/L) +/proc/duplicates(var/list/target_list) . = list() var/list/checked = list() - for(var/value in L) + for(var/value in target_list) if(value in checked) . |= value else @@ -687,24 +688,24 @@ proc/dd_sortedObjectList(list/incoming) //Move a single element from position fromIndex within a list, to position toIndex //All elements in the range [1,toIndex) before the move will be before the pivot afterwards -//All elements in the range [toIndex, L.len+1) before the move will be after the pivot afterwards +//All elements in the range [toIndex, target_list.len+1) before the move will be after the pivot afterwards //In other words, it's as if the range [fromIndex,toIndex) have been rotated using a <<< operation common to other languages. -//fromIndex and toIndex must be in the range [1,L.len+1] +//fromIndex and toIndex must be in the range [1,target_list.len+1] //This will preserve associations ~Carnie -/proc/moveElement(list/L, fromIndex, toIndex) +/proc/moveElement(list/target_list, fromIndex, toIndex) if(fromIndex == toIndex || fromIndex+1 == toIndex) //no need to move return if(fromIndex > toIndex) ++fromIndex //since a null will be inserted before fromIndex, the index needs to be nudged right by one - L.Insert(toIndex, null) - L.Swap(fromIndex, toIndex) - L.Cut(fromIndex, fromIndex+1) + target_list.Insert(toIndex, null) + target_list.Swap(fromIndex, toIndex) + target_list.Cut(fromIndex, fromIndex+1) //Move elements [fromIndex,fromIndex+len) to [toIndex-len, toIndex) //Same as moveElement but for ranges of elements //This will preserve associations ~Carnie -/proc/moveRange(list/L, fromIndex, toIndex, len=1) +/proc/moveRange(list/target_list, fromIndex, toIndex, len=1) var/distance = abs(toIndex - fromIndex) if(len >= distance) //there are more elements to be moved than the distance to be moved. Therefore the same result can be achieved (with fewer operations) by moving elements between where we are and where we are going. The result being, our range we are moving is shifted left or right by dist elements if(fromIndex <= toIndex) @@ -712,33 +713,33 @@ proc/dd_sortedObjectList(list/incoming) fromIndex += len //we want to shift left instead of right for(var/i=0, i toIndex) fromIndex += len for(var/i=0, i 0 && index <= list.len) // Returns the first key where T fulfills ispath -/proc/get_ispath_key(var/list/L, var/T) - for(var/key in L) +/proc/get_ispath_key(var/list/target_list, var/T) + for(var/key in target_list) if(ispath(T, key)) return key // Gets the first instance that is of the given type (strictly) -/proc/get_instance_of_strict_type(var/list/L, var/T) - for(var/key in L) +/proc/get_instance_of_strict_type(var/list/target_list, var/T) + for(var/key in target_list) var/atom/A = key if(A.type == T) return A @@ -865,5 +866,5 @@ var/global/list/json_cache = list() ) /// Is this a dense (all keys have non-null values) associative list with at least one entry? -/proc/is_dense_assoc(var/list/L) - return length(L) > 0 && !isnull(L[L[1]]) +/proc/is_dense_assoc(var/list/target_list) + return length(target_list) > 0 && !isnull(target_list[target_list[1]]) diff --git a/code/datums/uplink/uplink_sources.dm b/code/datums/uplink/uplink_sources.dm index a0dc90c3bf93..cb3f5f775ace 100644 --- a/code/datums/uplink/uplink_sources.dm +++ b/code/datums/uplink/uplink_sources.dm @@ -54,15 +54,15 @@ var/global/list/default_uplink_source_priority = list( . = ..() /decl/uplink_source/radio/setup_uplink_source(var/mob/M, var/amount) - var/obj/item/radio/R = find_in_mob(M, /obj/item/radio) - if(!R) + var/obj/item/radio/radio = find_in_mob(M, /obj/item/radio) + if(!radio) return SETUP_FAILED - var/obj/item/uplink/T = new(R, M.mind, amount) - R.hidden_uplink = T - R.traitor_frequency = sanitize_frequency(rand(PUBLIC_LOW_FREQ+1, PUB_FREQ-1)) - to_chat(M, "A portable object teleportation relay has been installed in your [R.name]. Simply dial the frequency [format_frequency(R.traitor_frequency)] to unlock its hidden features.") - M.StoreMemory("Radio Freq: [format_frequency(R.traitor_frequency)] ([R.name]).", /decl/memory_options/system) + var/obj/item/uplink/T = new(radio, M.mind, amount) + radio.hidden_uplink = T + radio.traitor_frequency = sanitize_frequency(rand(PUBLIC_LOW_FREQ+1, PUB_FREQ-1)) + to_chat(M, "A portable object teleportation relay has been installed in your [radio.name]. Simply dial the frequency [format_frequency(radio.traitor_frequency)] to unlock its hidden features.") + M.StoreMemory("Radio Freq: [format_frequency(radio.traitor_frequency)] ([radio.name]).", /decl/memory_options/system) /decl/uplink_source/implant name = "Implant" diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm index d2d868a4a7d1..5de478c9dd76 100644 --- a/code/datums/wires/radio.dm +++ b/code/datums/wires/radio.dm @@ -12,35 +12,35 @@ var/global/const/WIRE_RECEIVE = 2 var/global/const/WIRE_TRANSMIT = 4 /datum/wires/radio/CanUse(var/mob/living/L) - var/obj/item/radio/R = holder - if(R.panel_open) + var/obj/item/radio/radio = holder + if(radio.panel_open) return 1 return 0 /datum/wires/radio/UpdatePulsed(var/index) - var/obj/item/radio/R = holder + var/obj/item/radio/radio = holder switch(index) if(WIRE_SIGNAL) - R.listening = !R.listening && !IsIndexCut(WIRE_RECEIVE) - R.broadcasting = R.listening && !IsIndexCut(WIRE_TRANSMIT) + radio.listening = !radio.listening && !IsIndexCut(WIRE_RECEIVE) + radio.broadcasting = radio.listening && !IsIndexCut(WIRE_TRANSMIT) if(WIRE_RECEIVE) - R.listening = !R.listening && !IsIndexCut(WIRE_SIGNAL) + radio.listening = !radio.listening && !IsIndexCut(WIRE_SIGNAL) if(WIRE_TRANSMIT) - R.broadcasting = !R.broadcasting && !IsIndexCut(WIRE_SIGNAL) + radio.broadcasting = !radio.broadcasting && !IsIndexCut(WIRE_SIGNAL) SSnano.update_uis(holder) /datum/wires/radio/UpdateCut(var/index, var/mended) - var/obj/item/radio/R = holder + var/obj/item/radio/radio = holder switch(index) if(WIRE_SIGNAL) - R.listening = mended && !IsIndexCut(WIRE_RECEIVE) - R.broadcasting = mended && !IsIndexCut(WIRE_TRANSMIT) + radio.listening = mended && !IsIndexCut(WIRE_RECEIVE) + radio.broadcasting = mended && !IsIndexCut(WIRE_TRANSMIT) if(WIRE_RECEIVE) - R.listening = mended && !IsIndexCut(WIRE_SIGNAL) + radio.listening = mended && !IsIndexCut(WIRE_SIGNAL) if(WIRE_TRANSMIT) - R.broadcasting = mended && !IsIndexCut(WIRE_SIGNAL) + radio.broadcasting = mended && !IsIndexCut(WIRE_SIGNAL) SSnano.update_uis(holder) \ No newline at end of file diff --git a/code/modules/modular_computers/networking/machinery/telecomms.dm b/code/modules/modular_computers/networking/machinery/telecomms.dm index 93f7f7cd4914..00d213dd49de 100644 --- a/code/modules/modular_computers/networking/machinery/telecomms.dm +++ b/code/modules/modular_computers/networking/machinery/telecomms.dm @@ -101,8 +101,8 @@ var/global/list/telecomms_hubs = list() var/datum/extension/network_device/network_device = get_extension(src, /datum/extension/network_device) var/datum/computer_network/network = network_device?.get_network() - for(var/weakref/R in network?.connected_radios) - var/obj/item/radio/radio = R.resolve() + for(var/weakref/radio_ref in network?.connected_radios) + var/obj/item/radio/radio = radio_ref.resolve() if(istype(radio) && !QDELETED(radio)) radio.sync_channels_with_network() @@ -163,17 +163,17 @@ var/global/list/telecomms_hubs = list() var/send_name = istype(speaker) ? speaker.GetVoice() : ("[speaker]" || "unknown") var/list/listeners = list() // Dictionary of listener -> boolean (include overmap origin) // Broadcast to all radio devices in our network. - for(var/weakref/W as anything in network.connected_radios) - var/obj/item/radio/R = W.resolve() - if(!istype(R) || QDELETED(R) || !R.can_receive_message(network)) + for(var/weakref/radio_ref as anything in network.connected_radios) + var/obj/item/radio/radio = radio_ref.resolve() + if(!istype(radio) || QDELETED(radio) || !radio.can_receive_message(network)) continue - var/turf/speaking_from = get_turf(R) + var/turf/speaking_from = get_turf(radio) if(!speaking_from) continue - if(!R.can_decrypt(encryption)) + if(!radio.can_decrypt(encryption)) continue // TODO: This check seems extraneous, given how headsets find their available channels. - var/list/check_channels = R.get_available_channels() + var/list/check_channels = radio.get_available_channels() if(!LAZYACCESS(check_channels, channel)) continue @@ -181,7 +181,7 @@ var/global/list/telecomms_hubs = list() // then append the overmap object name to it, so they know where we're from var/listener_overmap_object = istype(speaking_from) && global.overmap_sectors[num2text(speaking_from.z)] var/send_overmap = send_overmap_object && send_overmap_object.ident_transmitter && send_overmap_object != listener_overmap_object - for(var/mob/listener as anything in R.get_radio_listeners()) + for(var/mob/listener as anything in radio.get_radio_listeners()) listeners[listener] = send_overmap // Ghostship is magic: Ghosts can hear radio chatter from anywhere From 6030ea620852f166f6b7c172b4cbbd7923367aa1 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 17 Feb 2025 12:57:12 +1100 Subject: [PATCH 012/512] L -> my_queue --- code/__datastructures/priority_queue.dm | 34 ++++++++++--------- code/datums/appearances/appearance_manager.dm | 6 ++-- code/datums/repositories/crew/crew.dm | 4 +-- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/code/__datastructures/priority_queue.dm b/code/__datastructures/priority_queue.dm index 1c29024a1ca7..3505149d034d 100644 --- a/code/__datastructures/priority_queue.dm +++ b/code/__datastructures/priority_queue.dm @@ -1,7 +1,7 @@ /// An automatically ordered list, using the cmp proc to weight the list items /datum/priority_queue /// The actual queue - var/list/L + var/list/my_queue = list() // For some reason putting VAR_PRIVATE on this causes it to be relatively pathed?? /// The weight function used to order the queue var/cmp @@ -9,50 +9,52 @@ /// * Param `comparer` take two arguments and return the difference in their weight /// * For example: /proc/CompareItems(atom/A, atom/B) return A.size - B.size /datum/priority_queue/New(comparer) - L = new() cmp = comparer /// * Returns: `TRUE` if the queue is empty, otherwise `FALSE` /datum/priority_queue/proc/IsEmpty() - return !L.len + return !my_queue.len /// Add an `item` to the list, immediatly ordering it to its position using dichotomic search /datum/priority_queue/proc/Enqueue(item) - ADD_SORTED(L, item, cmp) + ADD_SORTED(my_queue, item, cmp) /// Removes and returns the first item in the queue /// * Returns: The first `item` in the queue, otherwise `FALSE` /datum/priority_queue/proc/Dequeue() - if(!L.len) + if(!my_queue.len) return FALSE - . = L[1] + . = my_queue[1] Remove(.) /// Removes an `item` from the list /// * Returns: `TRUE` if succesfully removed, otherwise `FALSE` /datum/priority_queue/proc/Remove(item) - . = L.Remove(item) + . = my_queue.Remove(item) /// * Returns: A copy of the item list /datum/priority_queue/proc/List() - . = L.Copy() + . = my_queue.Copy() /// Finds an `item` in the list /// * Returns: The position of the `item`, or `0` if not found /datum/priority_queue/proc/Seek(item) - . = L.Find(item) + . = my_queue.Find(item) /// Gets the item at the positon `index` /// * Returns: The `item` at the index, or `0` if outside the range of the queue /datum/priority_queue/proc/Get(index) - if(index > L.len || index < 1) + if(index > my_queue.len || index < 1) return 0 - return L[index] + return my_queue[index] /// * Returns: The length of the queue /datum/priority_queue/proc/Length() - . = L.len + . = my_queue.len + +/datum/priority_queue/proc/GetQueue() + return my_queue /// Resorts the `item` to its correct position in the queue. /// * For example: The queue is sorted based on weight and atom A changes weight after being added @@ -60,9 +62,9 @@ var/i = Seek(item) if(i == 0) return - while(i < L.len && call(cmp)(L[i],L[i+1]) > 0) - L.Swap(i,i+1) + while(i < my_queue.len && call(cmp)(my_queue[i],my_queue[i+1]) > 0) + my_queue.Swap(i,i+1) i++ - while(i > 1 && call(cmp)(L[i],L[i-1]) <= 0) // Last inserted element being first in case of ties (optimization) - L.Swap(i,i-1) + while(i > 1 && call(cmp)(my_queue[i],my_queue[i-1]) <= 0) // Last inserted element being first in case of ties (optimization) + my_queue.Swap(i,i-1) i-- diff --git a/code/datums/appearances/appearance_manager.dm b/code/datums/appearances/appearance_manager.dm index d196a89303dc..be42ee3bd184 100644 --- a/code/datums/appearances/appearance_manager.dm +++ b/code/datums/appearances/appearance_manager.dm @@ -23,7 +23,7 @@ /decl/appearance_manager/proc/remove_appearances(var/mob/viewer) var/datum/priority_queue/pq = appearances_[viewer] - for(var/entry in pq.L) + for(var/entry in pq.GetQueue()) var/datum/appearance_data/ad = entry ad.RemoveViewer(viewer, FALSE) if(viewer in appearances_) @@ -39,7 +39,7 @@ var/datum/priority_queue/pq = appearances_[viewer] if(!pq) return - for(var/entry in pq.L) + for(var/entry in pq.GetQueue()) var/datum/appearance_data/ad = entry viewer.client.images -= ad.images @@ -49,6 +49,6 @@ var/datum/priority_queue/pq = appearances_[viewer] if(!pq) return - for(var/entry in pq.L) + for(var/entry in pq.GetQueue()) var/datum/appearance_data/ad = entry viewer.client.images |= ad.images diff --git a/code/datums/repositories/crew/crew.dm b/code/datums/repositories/crew/crew.dm index 35bd0ecfb515..4a0e5b2c53a7 100644 --- a/code/datums/repositories/crew/crew.dm +++ b/code/datums/repositories/crew/crew.dm @@ -98,7 +98,7 @@ var/global/datum/repository/crew/crew_repository = new() var/current_priority = INFINITY var/list/modifiers_of_this_priority = list() - for(var/crew_sensor_modifier/csm in modifiers.L) + for(var/crew_sensor_modifier/csm in modifiers.GetQueue()) if(csm.priority < current_priority) . = check_queue(modifiers_of_this_priority, H, S, pos, crew_data) if(. != MOD_SUIT_SENSORS_NONE) @@ -123,7 +123,7 @@ var/global/datum/repository/crew/crew_repository = new() var/datum/priority_queue/pq = modifier_queues_by_type[base_type] if(!pq) CRASH("The given base type was not a valid base type.") - if(csm in pq.L) + if(csm in pq.GetQueue()) CRASH("This crew sensor modifier has already been supplied.") pq.Enqueue(csm) return TRUE From a1ce33c021a454373dad6a35388ba155f51485f7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 17 Feb 2025 13:07:52 +1100 Subject: [PATCH 013/512] Lots of bespoke single-letter var replacement. --- code/_helpers/game.dm | 6 +-- code/_helpers/matrices.dm | 22 ++++---- code/_helpers/medical_scans.dm | 30 +++++------ code/_helpers/text.dm | 6 +-- .../subsystems/initialization/fabrication.dm | 3 +- .../traits/prosthetics/prosthetic_limbs.dm | 6 +-- code/game/atoms.dm | 8 +-- code/game/jobs/access.dm | 21 ++++---- code/game/jobs/job/_job.dm | 27 +++++----- .../_machines_base/machinery_components.dm | 22 ++++---- code/game/machinery/computer/prisoner.dm | 4 +- code/game/machinery/doors/airlock_control.dm | 8 +-- code/game/machinery/kitchen/icecream.dm | 26 +++++----- code/game/machinery/nuclear_bomb.dm | 6 +-- code/game/machinery/seed_extractor.dm | 3 +- code/game/machinery/teleporter.dm | 8 +-- code/game/machinery/vending/_vending.dm | 42 ++++++++-------- code/game/machinery/vending_deconstruction.dm | 14 +++--- code/game/movietitles.dm | 6 +-- code/game/objects/_obj_edibility.dm | 4 +- code/game/objects/compass/compass_overmap.dm | 8 +-- code/game/objects/effects/chem/foam.dm | 8 +-- code/game/objects/items/books/skill/_skill.dm | 14 +++--- code/game/objects/items/devices/pinpointer.dm | 10 ++-- code/game/objects/items/robot/robot_parts.dm | 12 ++--- code/game/objects/items/weapons/autopsy.dm | 5 +- code/game/objects/structures/barricade.dm | 10 ++-- code/game/objects/structures/inflatable.dm | 27 +++++----- code/game/objects/structures/ironing_board.dm | 6 +-- code/game/objects/structures/lattice.dm | 6 +-- code/game/objects/structures/railing.dm | 50 +++++++++---------- code/game/turfs/space/space.dm | 6 +-- code/modules/admin/buildmode/mode_areas.dm | 6 +-- .../reagents/reagent_containers/borghydro.dm | 22 ++++---- 34 files changed, 228 insertions(+), 234 deletions(-) diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index c33ecb8a33a8..2b6e0d2c7fa3 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -171,8 +171,8 @@ return L -// Returns a list of mobs and/or objects in range of R from source. Used in radio and say code. -/proc/get_mobs_or_objects_in_view(var/R, var/atom/source, var/include_mobs = 1, var/include_objects = 1) +// Returns a list of mobs and/or objects in range of get_range from source. Used in radio and say code. +/proc/get_mobs_or_objects_in_view(var/get_range, var/atom/source, var/include_mobs = 1, var/include_objects = 1) var/turf/T = get_turf(source) var/list/hear = list() @@ -180,7 +180,7 @@ if(!T) return hear - var/list/range = hear(R, T) + var/list/range = hear(get_range, T) for(var/I in range) if(ismob(I)) hear |= recursive_content_check(I, hear, 3, 1, 0, include_mobs, include_objects) diff --git a/code/_helpers/matrices.dm b/code/_helpers/matrices.dm index e705300c4f30..0b5c1f55b1be 100644 --- a/code/_helpers/matrices.dm +++ b/code/_helpers/matrices.dm @@ -94,12 +94,12 @@ /// Changes distance hues have from grey while maintaining the overall lightness. Greys are unaffected. /// * 1 is identity, 0 is greyscale, >1 oversaturates colors /proc/color_matrix_saturation(value) - var/inv = 1 - value - var/R = round(LUMA_R * inv, 0.001) - var/G = round(LUMA_G * inv, 0.001) - var/B = round(LUMA_B * inv, 0.001) + var/inv = 1 - value + var/red = round(LUMA_R * inv, 0.001) + var/green = round(LUMA_G * inv, 0.001) + var/blue = round(LUMA_B * inv, 0.001) - return list(R + value,R,R,0, G,G + value,G,0, B,B,B + value,0, 0,0,0,1, 0,0,0,0) + return list(red + value,red,red,0, green,green + value,green,0, blue,blue,blue + value,0, 0,0,0,1, 0,0,0,0) #define LUMR 0.2126 #define LUMG 0.7152 @@ -111,11 +111,13 @@ if(value > 0) value *= 3 var/x = 1 + value / 100 - var/inv = 1 - x - var/R = LUMR * inv - var/G = LUMG * inv - var/B = LUMB * inv - return list(R + x,R,R, G,G + x,G, B,B,B + x) + + var/inv = 1 - x + var/red = LUMR * inv + var/green = LUMG * inv + var/blue = LUMB * inv + return list(red + x,red,red, green,green + x,green, blue,blue,blue + x) + #undef LUMR #undef LUMG #undef LUMB diff --git a/code/_helpers/medical_scans.dm b/code/_helpers/medical_scans.dm index 8e26d3d74db2..fcb3fa78e88e 100644 --- a/code/_helpers/medical_scans.dm +++ b/code/_helpers/medical_scans.dm @@ -44,20 +44,20 @@ if(reagents?.total_volume) for(var/liquid_type in reagents.liquid_volumes) - var/decl/material/R = GET_DECL(liquid_type) - var/list/reagent = list() - reagent["name"]= R.get_reagent_name(reagents, MAT_PHASE_LIQUID) - reagent["quantity"] = round(REAGENT_VOLUME(reagents, R.type),1) - reagent["scannable"] = R.scannable - .["reagents"] += list(reagent) + var/decl/material/reagent = GET_DECL(liquid_type) + var/list/reagent_data = list() + reagent_data["name"]= reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID) + reagent_data["quantity"] = round(REAGENT_VOLUME(reagents, reagent.type),1) + reagent_data["scannable"] = reagent.scannable + .["reagents"] += list(reagent_data) for(var/solid_type in reagents.solid_volumes) - var/decl/material/R = GET_DECL(solid_type) - var/list/reagent = list() - reagent["name"]= R.get_reagent_name(reagents, MAT_PHASE_SOLID) - reagent["quantity"] = round(REAGENT_VOLUME(reagents, R.type),1) - reagent["scannable"] = R.scannable - .["reagents"] += list(reagent) + var/decl/material/reagent = GET_DECL(solid_type) + var/list/reagent_data = list() + reagent_data["name"]= reagent.get_reagent_name(reagents, MAT_PHASE_SOLID) + reagent_data["quantity"] = round(REAGENT_VOLUME(reagents, reagent.type),1) + reagent_data["scannable"] = reagent.scannable + .["reagents"] += list(reagent_data) .["external_organs"] = list() for(var/obj/item/organ/external/limb in get_external_organs()) @@ -241,9 +241,9 @@ dat += "Antibody levels and immune system perfomance are at [scan["immune_system"]*100]% of baseline." var/other_reagent = FALSE - for(var/list/R in scan["reagents"]) - if(R["scannable"]) - subdat += "[R["quantity"]]u [R["name"]]" + for(var/list/reagent_data in scan["reagents"]) + if(reagent_data["scannable"]) + subdat += "[reagent_data["quantity"]]u [reagent_data["name"]]" else other_reagent = TRUE if(subdat) diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index adccbbc543df..a264a7fff67a 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -614,9 +614,9 @@ var/global/regex/starts_lowercase_regex = regex(@"^[a-z]") // If char isn't part of the text the entire text is returned /proc/copytext_after_last(var/text, var/char) - var/regex/R = regex("(\[^[char]\]*)$") - R.Find(text) - return R.group[1] + var/regex/copytext_regex = regex("(\[^[char]\]*)$") + copytext_regex.Find(text) + return copytext_regex.group[1] /proc/sql_sanitize_text(var/text) text = replacetext(text, "'", "''") diff --git a/code/controllers/subsystems/initialization/fabrication.dm b/code/controllers/subsystems/initialization/fabrication.dm index 37a6d57dfae0..6fd2b5c28dbd 100644 --- a/code/controllers/subsystems/initialization/fabrication.dm +++ b/code/controllers/subsystems/initialization/fabrication.dm @@ -15,8 +15,7 @@ SUBSYSTEM_DEF(fabrication) /datum/controller/subsystem/fabrication/Initialize() // Fab recipes. - for(var/R in subtypesof(/datum/fabricator_recipe)) - var/datum/fabricator_recipe/recipe = R + for(var/datum/fabricator_recipe/recipe as anything in subtypesof(/datum/fabricator_recipe)) if(!initial(recipe.path)) continue recipe = new recipe diff --git a/code/datums/traits/prosthetics/prosthetic_limbs.dm b/code/datums/traits/prosthetics/prosthetic_limbs.dm index 0ea2e8c06580..245e4db88063 100644 --- a/code/datums/traits/prosthetics/prosthetic_limbs.dm +++ b/code/datums/traits/prosthetics/prosthetic_limbs.dm @@ -84,12 +84,12 @@ if(!bodytype?.is_robotic) return FALSE if(model) - var/decl/bodytype/prosthetic/R = GET_DECL(model) - if(!istype(R)) + var/decl/bodytype/prosthetic/robot_model = GET_DECL(model) + if(!istype(robot_model)) return FALSE var/decl/species/S = get_species_by_key(pref.species) || get_species_by_key(global.using_map.default_species) var/decl/bodytype/B = S.get_bodytype_by_name(pref.bodytype) - if(!R.check_can_install(apply_to_limb, target_bodytype = (check_bodytype || B.bodytype_category))) + if(!robot_model.check_can_install(apply_to_limb, target_bodytype = (check_bodytype || B.bodytype_category))) return FALSE // If we're a duplicate of our parent due to get_base_model(), hide this one. var/decl/trait/prosthetic_limb/parent_limb = parent diff --git a/code/game/atoms.dm b/code/game/atoms.dm index e1788ccc207a..311d01d6a95c 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -428,8 +428,8 @@ /atom/proc/get_contained_matter() if(length(reagents?.reagent_volumes)) LAZYINITLIST(.) - for(var/R in reagents.reagent_volumes) - .[R] += floor(REAGENT_VOLUME(reagents, R) / REAGENT_UNITS_PER_MATERIAL_UNIT) + for(var/reagent in reagents.reagent_volumes) + .[reagent] += floor(REAGENT_VOLUME(reagents, reagent) / REAGENT_UNITS_PER_MATERIAL_UNIT) for(var/atom/contained_obj as anything in get_contained_external_atoms()) // machines handle component parts separately . = MERGE_ASSOCS_WITH_NUM_VALUES(., contained_obj.get_contained_matter()) @@ -486,8 +486,8 @@ /atom/proc/try_detonate_reagents(var/severity = 3) if(reagents) for(var/r_type in reagents.reagent_volumes) - var/decl/material/R = GET_DECL(r_type) - R.explosion_act(src, severity) + var/decl/material/reagent = GET_DECL(r_type) + reagent.explosion_act(src, severity) /** Handle an explosion of `severity` affecting this atom diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 014baac33a14..20cd9d5a395b 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -58,19 +58,19 @@ /atom/movable/proc/check_access(atom/movable/A) return check_access_list(A ? A.GetAccess() : list()) -/atom/movable/proc/check_access_list(list/L) - var/list/R = get_req_access() +/atom/movable/proc/check_access_list(list/supplied_access) + var/list/required_access = get_req_access() - if(!R) - R = list() - if(!istype(L, /list)) + if(!required_access) + required_access = list() + if(!istype(supplied_access, /list)) return FALSE if(maint_all_access) - L = L.Copy() - L |= access_maint_tunnels + supplied_access = supplied_access.Copy() + supplied_access |= access_maint_tunnels - return has_access(R, L) + return has_access(required_access, supplied_access) /proc/has_access(list/req_access, list/accesses) for(var/req in req_access) @@ -143,11 +143,10 @@ var/global/list/datum/access/priv_all_access_datums_region return priv_all_access_datums_region.Copy() /proc/get_access_ids(var/access_types = ACCESS_TYPE_ALL) - var/list/L = new() + . = list() for(var/datum/access/A in get_all_access_datums()) if(A.access_type & access_types) - L += A.id - return L + . += A.id var/global/list/priv_all_access /proc/get_all_accesses() diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index 06e985a8772d..9e085a1c4415 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -173,8 +173,8 @@ remembered_info += "Your account pin is: [account.remote_access_pin]
    " remembered_info += "Your account funds are: [account.format_value_by_currency(account.money)]
    " if(account.transaction_log.len) - var/datum/transaction/T = account.transaction_log[1] - remembered_info += "Your account was created: [T.time], [T.date] at [T.get_source_name()]
    " + var/datum/transaction/transaction = account.transaction_log[1] + remembered_info += "Your account was created: [transaction.time], [transaction.date] at [transaction.get_source_name()]
    " if(cash_on_hand > 0) var/decl/currency/cur = GET_DECL(global.using_map.default_currency) remembered_info += "Your cash on hand is: [cur.format_value(cash_on_hand)]
    " @@ -356,22 +356,21 @@ //Returns human-readable list of branches this job allows. /datum/job/proc/get_branches() - var/list/res = list() - for(var/T in allowed_branches) - var/datum/mil_branch/B = mil_branches.get_branch_by_type(T) - res += B.name - return english_list(res) + . = list() + for(var/branch in allowed_branches) + var/datum/mil_branch/branch_datum = mil_branches.get_branch_by_type(branch) + . += branch_datum.name + return english_list(.) //Same as above but ranks /datum/job/proc/get_ranks(branch) - var/list/res = list() - var/datum/mil_branch/B = mil_branches.get_branch(branch) - for(var/T in allowed_ranks) - var/datum/mil_rank/R = T - if(B && !(initial(R.name) in B.ranks)) + . = list() + var/datum/mil_branch/branch_datum = mil_branches.get_branch(branch) + for(var/datum/mil_rank/rank as anything in allowed_ranks) + if(branch_datum && !(initial(rank.name) in branch_datum.ranks)) continue - res |= initial(R.name) - return english_list(res) + . |= initial(rank.name) + return english_list(.) /datum/job/proc/get_description_blurb() return description diff --git a/code/game/machinery/_machines_base/machinery_components.dm b/code/game/machinery/_machines_base/machinery_components.dm index 032e31d058a3..b648635ed74e 100644 --- a/code/game/machinery/_machines_base/machinery_components.dm +++ b/code/game/machinery/_machines_base/machinery_components.dm @@ -187,15 +187,15 @@ var/global/list/machine_path_to_circuit_type events_repository.unregister(/decl/observ/destroyed, part, src) return part -/obj/machinery/proc/replace_part(mob/user, var/obj/item/part_replacer/R, var/obj/item/stock_parts/old_part, var/obj/item/stock_parts/new_part) +/obj/machinery/proc/replace_part(mob/user, var/obj/item/part_replacer/replacer, var/obj/item/stock_parts/old_part, var/obj/item/stock_parts/new_part) if(ispath(old_part)) old_part = get_component_of_type(old_part, TRUE) old_part = uninstall_component(old_part) - if(R) - if(R.storage) - R.storage.remove_from_storage(null, new_part, src) - R.storage.handle_item_insertion(null, old_part, TRUE) - R.part_replacement_sound() + if(replacer) + if(replacer.storage) + replacer.storage.remove_from_storage(null, new_part, src) + replacer.storage.handle_item_insertion(null, old_part, TRUE) + replacer.part_replacement_sound() install_component(new_part) to_chat(user, "[old_part.name] replaced with [new_part.name].") @@ -279,15 +279,15 @@ var/global/list/machine_path_to_circuit_type Standard helpers for users interacting with machinery parts. */ -/obj/machinery/proc/part_replacement(mob/user, obj/item/part_replacer/R) +/obj/machinery/proc/part_replacement(mob/user, obj/item/part_replacer/replacer) for(var/obj/item/stock_parts/A in component_parts) if(!A.base_type) continue if(!(A.part_flags & PART_FLAG_HAND_REMOVE)) continue - for(var/obj/item/stock_parts/B in R.contents) + for(var/obj/item/stock_parts/B in replacer.contents) if(istype(B, A.base_type) && B.rating > A.rating) - replace_part(user, R, A, B) + replace_part(user, replacer, A, B) return TRUE for(var/path in uncreated_component_parts) var/obj/item/stock_parts/A = path @@ -295,9 +295,9 @@ Standard helpers for users interacting with machinery parts. continue var/base_type = initial(A.base_type) if(base_type) - for(var/obj/item/stock_parts/B in R.contents) + for(var/obj/item/stock_parts/B in replacer.contents) if(istype(B, base_type) && B.rating > initial(A.rating)) - replace_part(user, R, A, B) + replace_part(user, replacer, A, B) return TRUE /obj/machinery/proc/part_insertion(mob/user, obj/item/stock_parts/part) // Second argument may actually be an arbitrary item. diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index b3903352d555..aa9eb1647d52 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -78,5 +78,5 @@ if(!warning) return TOPIC_HANDLED var/obj/item/implant/I = locate(href_list["warn"]) if(I?.imp_in) - var/mob/living/R = I.imp_in - to_chat(R, "You hear a voice in your head saying: '[warning]'") + var/mob/living/victim = I.imp_in + to_chat(victim, "You hear a voice in your head saying: '[warning]'") diff --git a/code/game/machinery/doors/airlock_control.dm b/code/game/machinery/doors/airlock_control.dm index 579e29e33112..c1f9b50ebf6d 100644 --- a/code/game/machinery/doors/airlock_control.dm +++ b/code/game/machinery/doors/airlock_control.dm @@ -181,8 +181,8 @@ /obj/machinery/airlock_sensor/set_id_tag(var/new_id_tag) . = ..() - for(var/obj/item/stock_parts/radio/R in get_all_components_of_type(/obj/item/stock_parts/radio)) - R.set_id_tag(id_tag) + for(var/obj/item/stock_parts/radio/radio in get_all_components_of_type(/obj/item/stock_parts/radio)) + radio.set_id_tag(id_tag) /decl/public_access/public_variable/airlock_pressure expected_type = /obj/machinery/airlock_sensor @@ -331,8 +331,8 @@ /obj/machinery/button/access/set_id_tag(var/new_id_tag) . = ..() - for(var/obj/item/stock_parts/radio/R in get_all_components_of_type(/obj/item/stock_parts/radio)) - R.set_id_tag(id_tag) + for(var/obj/item/stock_parts/radio/radio in get_all_components_of_type(/obj/item/stock_parts/radio)) + radio.set_id_tag(id_tag) // // Button Part Presets diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index cd751f4d64af..4d95949cde61 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -101,14 +101,14 @@ dat += "
    " dat += "VAT CONTENT
    " for(var/liquid_type in reagents?.liquid_volumes) - var/decl/material/R = GET_DECL(liquid_type) - dat += "[R.get_reagent_name(reagents, MAT_PHASE_LIQUID)]: [LIQUID_VOLUME(reagents, liquid_type)]" - dat += "Purge
    " + var/decl/material/reagent = GET_DECL(liquid_type) + dat += "[reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID)]: [LIQUID_VOLUME(reagents, liquid_type)]" + dat += "Purge
    " for(var/solid_type in reagents?.solid_volumes) - var/decl/material/R = GET_DECL(solid_type) - dat += "[R.get_reagent_name(reagents, MAT_PHASE_SOLID)]: [SOLID_VOLUME(reagents, solid_type)]" - dat += "Purge
    " + var/decl/material/reagent = GET_DECL(solid_type) + dat += "[reagent.get_reagent_name(reagents, MAT_PHASE_SOLID)]: [SOLID_VOLUME(reagents, solid_type)]" + dat += "Purge
    " dat += "Refresh Close" @@ -139,14 +139,14 @@ return ..() /obj/machinery/icecream_vat/proc/make(var/mob/user, var/make_type, var/amount) - for(var/R in get_ingredient_list(make_type)) - if(reagents.has_reagent(R, amount)) + for(var/reagent in get_ingredient_list(make_type)) + if(reagents.has_reagent(reagent, amount)) continue amount = 0 break if(amount) - for(var/R in get_ingredient_list(make_type)) - remove_from_reagents(R, amount) + for(var/reagent in get_ingredient_list(make_type)) + remove_from_reagents(reagent, amount) product_types[make_type] += amount var/flavour = get_flavour_name(make_type) if(make_type > 6) @@ -188,9 +188,9 @@ . = TOPIC_REFRESH else if(href_list["disposeI"]) - var/decl/material/R = locate(href_list["disposeI"]) - if(R) - reagents.clear_reagent(R.type) + var/decl/material/reagent = locate(href_list["disposeI"]) + if(reagent) + reagents.clear_reagent(reagent.type) . = TOPIC_REFRESH if(href_list["refresh"]) diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm index ac2a4f67cec2..7159004c54c3 100644 --- a/code/game/machinery/nuclear_bomb.dm +++ b/code/game/machinery/nuclear_bomb.dm @@ -418,8 +418,8 @@ var/global/bomb_set /obj/item/folder/envelope/nuke_instructions/Initialize() . = ..() - var/obj/item/paper/R = new(src) - R.set_content({"
    Warning: Classified
    [global.using_map.station_name] Self-Destruct System - Instructions


    + var/obj/item/paper/codes = new(src) + codes.set_content({"
    Warning: Classified
    [global.using_map.station_name] Self-Destruct System - Instructions


    In the event of a Delta-level emergency, this document will guide you through the activation of the vessel's on-board nuclear self-destruct system. Please read carefully.

    1) (Optional) Announce the imminent activation to any surviving crew members, and begin evacuation procedures.
    @@ -442,7 +442,7 @@ var/global/bomb_set "vessel self-destruct instructions") //stamp the paper - R.apply_custom_stamp('icons/obj/items/stamps/stamp_cos.dmi', "'Top Secret'") + codes.apply_custom_stamp('icons/obj/items/stamps/stamp_cos.dmi', "'Top Secret'") //====vessel self-destruct system==== /obj/machinery/nuclearbomb/station diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm index 28bcefc71584..de1b7c1cc8a4 100644 --- a/code/game/machinery/seed_extractor.dm +++ b/code/game/machinery/seed_extractor.dm @@ -37,8 +37,7 @@ return TRUE if(istype(O, /obj/item/fossil/plant)) // Fossils - var/obj/item/seeds/random/R = new(get_turf(src)) - to_chat(user, SPAN_NOTICE("\The [src] scans \the [O] and spits out \a [R].")) + to_chat(user, SPAN_NOTICE("\The [src] scans \the [O] and spits out \a [new /obj/item/seeds/random(get_turf(src))].")) qdel(O) return TRUE diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 0b61d1782680..ad900bea6662 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -83,10 +83,10 @@ var/list/areaindex = list() . = TRUE - for(var/obj/item/radio/beacon/R in global.radio_beacons) - if(!R.functioning) + for(var/obj/item/radio/beacon/radio in global.radio_beacons) + if(!radio.functioning) continue - var/turf/T = get_turf(R) + var/turf/T = get_turf(radio) if (!T) continue if(!isPlayerLevel(T.z)) @@ -96,7 +96,7 @@ tmpname = "[tmpname] ([++areaindex[tmpname]])" else areaindex[tmpname] = 1 - L[tmpname] = R + L[tmpname] = radio for (var/obj/item/implant/tracking/I in global.tracking_implants) if (!I.implanted || !ismob(I.loc)) diff --git a/code/game/machinery/vending/_vending.dm b/code/game/machinery/vending/_vending.dm index b3036e173176..ea38940b2dcd 100644 --- a/code/game/machinery/vending/_vending.dm +++ b/code/game/machinery/vending/_vending.dm @@ -120,8 +120,8 @@ product_records.Add(product) /obj/machinery/vending/Destroy() - for(var/datum/stored_items/vending_products/R in product_records) - qdel(R) + for(var/datum/stored_items/vending_products/product_record in product_records) + qdel(product_record) product_records = null return ..() @@ -196,9 +196,9 @@ SSnano.update_uis(src) /obj/machinery/vending/proc/attempt_to_stock(var/obj/item/I, var/mob/user) - for(var/datum/stored_items/vending_products/R in product_records) - if(I.type == R.item_path) - stock(I, R, user) + for(var/datum/stored_items/vending_products/product_record in product_records) + if(I.type == product_record.item_path) + stock(I, product_record, user) return 1 /** @@ -309,20 +309,20 @@ if (href_list["vend"] && !currently_vending) var/key = text2num(href_list["vend"]) - var/datum/stored_items/vending_products/R = LAZYACCESS(product_records, key) - if(!R) + var/datum/stored_items/vending_products/product_record = LAZYACCESS(product_records, key) + if(!product_record) return TOPIC_REFRESH // This should not happen unless the request from NanoUI was bad - if(!(R.category & categories)) + if(!(product_record.category & categories)) return TOPIC_REFRESH - if(R.price <= 0) - vend(R, user) + if(product_record.price <= 0) + vend(product_record, user) else if(issilicon(user)) //If the item is not free, provide feedback if a synth is trying to buy something. to_chat(user, SPAN_DANGER("Artificial unit recognized. Artificial units cannot complete this transaction. Purchase canceled.")) else - currently_vending = R + currently_vending = product_record if(!vendor_account || vendor_account.suspended) status_message = "This machine is currently unable to process payments due to problems with the associated account." status_error = 1 @@ -344,7 +344,7 @@ return list() return ..() -/obj/machinery/vending/proc/vend(var/datum/stored_items/vending_products/R, mob/user) +/obj/machinery/vending/proc/vend(var/datum/stored_items/vending_products/product_record, mob/user) if(!vend_ready) return if((!allowed(user)) && !emagged && scan_id) //For SECURE VENDING MACHINES YEAH @@ -365,7 +365,7 @@ var/vend_state = "[icon_state]-vend" if (check_state_in_icon(vend_state, icon)) //Show the vending animation if needed flick(vend_state, src) - addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/vending, finish_vending), R), vend_delay) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/vending, finish_vending), product_record), vend_delay) /obj/machinery/vending/proc/do_vending_reply() set waitfor = FALSE @@ -394,13 +394,13 @@ * Add item to the machine * * Checks if item is vendable in this machine should be performed before - * calling. W is the item being inserted, R is the associated vending_product entry. + * calling. W is the item being inserted, product_record is the associated vending_product entry. */ -/obj/machinery/vending/proc/stock(obj/item/W, var/datum/stored_items/vending_products/R, var/mob/user) +/obj/machinery/vending/proc/stock(obj/item/W, var/datum/stored_items/vending_products/product_record, var/mob/user) if(!user.try_unequip(W)) return - if(R.add_product(W)) + if(product_record.add_product(W)) to_chat(user, SPAN_NOTICE("You insert \the [W] in the product receptor.")) SSnano.update_uis(src) return 1 @@ -456,9 +456,9 @@ //Oh no we're malfunctioning! Dump out some product and break. /obj/machinery/vending/proc/malfunction() set waitfor = FALSE - for(var/datum/stored_items/vending_products/R in product_records) - while(R.get_amount()>0) - R.get_product(loc) + for(var/datum/stored_items/vending_products/product_record in product_records) + while(product_record.get_amount()>0) + product_record.get_product(loc) break set_broken(TRUE) @@ -469,8 +469,8 @@ if(!target) return 0 - for(var/datum/stored_items/vending_products/R in shuffle(product_records)) - throw_item = R.get_product(loc) + for(var/datum/stored_items/vending_products/product_record in shuffle(product_records)) + throw_item = product_record.get_product(loc) if(!QDELETED(throw_item)) break if(QDELETED(throw_item)) diff --git a/code/game/machinery/vending_deconstruction.dm b/code/game/machinery/vending_deconstruction.dm index 958f9d71d4b3..2577f8fc61b7 100644 --- a/code/game/machinery/vending_deconstruction.dm +++ b/code/game/machinery/vending_deconstruction.dm @@ -25,13 +25,13 @@ var/obj/machinery/vending/vendor = over var/target_type = vendor.base_type || vendor.type if(ispath(expected_type, target_type)) - for(var/datum/stored_items/R in product_records) + for(var/datum/stored_items/product_record in product_records) for(var/datum/stored_items/record in vendor.product_records) - if(record.merge(R)) + if(record.merge(product_record)) break - if(!QDELETED(R)) - R.migrate(over) - vendor.product_records += R + if(!QDELETED(product_record)) + product_record.migrate(over) + vendor.product_records += product_record product_records = null SSnano.update_uis(vendor) qdel(src) @@ -52,8 +52,8 @@ var/obj/structure/vending_refill/dump = new(loc) dump.SetName("[dump.name] ([name])") dump.expected_type = base_type || type - for(var/datum/stored_items/vending_products/R in product_records) - R.migrate(dump) + for(var/datum/stored_items/vending_products/product_record in product_records) + product_record.migrate(dump) dump.product_records = product_records product_records = null . = ..() \ No newline at end of file diff --git a/code/game/movietitles.dm b/code/game/movietitles.dm index 5361529c1593..38b4dcf87ccf 100644 --- a/code/game/movietitles.dm +++ b/code/game/movietitles.dm @@ -66,9 +66,9 @@ var/global/list/end_titles if(GetAssignment(H) != "Unassigned") job = ", [uppertext(GetAssignment(H))]" var/used_name = H.real_name - var/datum/computer_file/report/crew_record/R = get_crewmember_record(H.real_name) - if(R && R.get_rank()) - var/datum/mil_rank/rank = mil_branches.get_rank(R.get_branch(), R.get_rank()) + var/datum/computer_file/report/crew_record/record = get_crewmember_record(H.real_name) + if(record && record.get_rank()) + var/datum/mil_rank/rank = mil_branches.get_rank(record.get_branch(), record.get_rank()) if(rank.name_short) used_name = "[rank.name_short] [used_name]" var/showckey = 0 diff --git a/code/game/objects/_obj_edibility.dm b/code/game/objects/_obj_edibility.dm index 9fa4ec70827f..b95791a80684 100644 --- a/code/game/objects/_obj_edibility.dm +++ b/code/game/objects/_obj_edibility.dm @@ -156,8 +156,8 @@ show_feed_message_end(user, target, consumption_method) if(consumption_method == EATING_METHOD_DRINK && target?.has_personal_goal(/datum/goal/achievement/specific_object/drink)) - for(var/R in reagents.reagent_volumes) - target.update_personal_goal(/datum/goal/achievement/specific_object/drink, R) + for(var/reagent in reagents.reagent_volumes) + target.update_personal_goal(/datum/goal/achievement/specific_object/drink, reagent) handle_consumed(user, target, consumption_method) return EATEN_SUCCESS diff --git a/code/game/objects/compass/compass_overmap.dm b/code/game/objects/compass/compass_overmap.dm index 31ef3d2bb1fe..11ee76eef866 100644 --- a/code/game/objects/compass/compass_overmap.dm +++ b/code/game/objects/compass/compass_overmap.dm @@ -30,10 +30,10 @@ var/list/seen_waypoint_ids = list() for(var/key in owner.known_sectors) - var/datum/computer_file/data/waypoint/R = owner.known_sectors[key] - var/wp_id = "\ref[R]" - set_waypoint(wp_id, uppertext(R.fields["name"]), R.fields["x"], R.fields["y"], owner_turf.z, R.fields["color"] || COLOR_SILVER) - if(!R.fields["tracking"]) + var/datum/computer_file/data/waypoint/waypoint = owner.known_sectors[key] + var/wp_id = "\ref[waypoint]" + set_waypoint(wp_id, uppertext(waypoint.fields["name"]), waypoint.fields["x"], waypoint.fields["y"], owner_turf.z, waypoint.fields["color"] || COLOR_SILVER) + if(!waypoint.fields["tracking"]) hide_waypoint(wp_id) seen_waypoint_ids += wp_id for(var/id in compass_waypoints) diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm index 70d5c86bb2e0..6211ee65c261 100644 --- a/code/game/objects/effects/chem/foam.dm +++ b/code/game/objects/effects/chem/foam.dm @@ -59,8 +59,8 @@ if(!metal) F.create_reagents(10) if(reagents) - for(var/R in reagents.reagent_volumes) - F.add_to_reagents(R, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react + for(var/reagent in reagents.reagent_volumes) + F.add_to_reagents(reagent, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react /obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) // foam disolves when heated, except metal foams if(!metal && prob(max(0, exposed_temperature - 475))) @@ -93,8 +93,8 @@ // bit of a hack here. Foam carries along any reagent also present in the glass it is mixed with (defaults to water if none is present). Rather than actually transfer the reagents, this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves. if(carry && !metal) - for(var/R in carry.reagent_volumes) - carried_reagents += R + for(var/reagent in carry.reagent_volumes) + carried_reagents += reagent /datum/effect/effect/system/foam_spread/start() spawn(0) diff --git a/code/game/objects/items/books/skill/_skill.dm b/code/game/objects/items/books/skill/_skill.dm index 9c9bf06db827..39ed2b3cdfe0 100644 --- a/code/game/objects/items/books/skill/_skill.dm +++ b/code/game/objects/items/books/skill/_skill.dm @@ -213,17 +213,17 @@ Skill books that increase your skills while you activate and hold them /obj/item/book/skill/proc/check_buff() if(!reading) return - var/mob/R = reading.resolve() - if(!istype(R) || !CanPhysicallyInteract(R)) + var/mob/reader = reading.resolve() + if(!istype(reader) || !CanPhysicallyInteract(reader)) remove_buff() /obj/item/book/skill/proc/remove_buff() - var/mob/R = reading?.resolve() + var/mob/reader = reading?.resolve() reading = null - if(istype(R)) - to_chat(R, SPAN_DANGER("You lose the page you were on! You can't cross-reference using [title] like this!")) - if(R.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0)) - unlearn(R) + if(istype(reader)) + to_chat(reader, SPAN_DANGER("You lose the page you were on! You can't cross-reference using [title] like this!")) + if(reader.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0)) + unlearn(reader) STOP_PROCESSING(SSprocessing, src) /obj/item/book/skill/Destroy() diff --git a/code/game/objects/items/devices/pinpointer.dm b/code/game/objects/items/devices/pinpointer.dm index f187965a533c..b9624ebf4803 100644 --- a/code/game/objects/items/devices/pinpointer.dm +++ b/code/game/objects/items/devices/pinpointer.dm @@ -126,14 +126,14 @@ var/turf/T = get_turf(src) var/zlevels = SSmapping.get_connected_levels(T.z) var/cur_dist = world.maxx+world.maxy - for(var/obj/item/radio/beacon/R in global.radio_beacons) - if(!R.functioning) + for(var/obj/item/radio/beacon/radio in global.radio_beacons) + if(!radio.functioning) continue - if((R.z in zlevels) && R.frequency == tracking_freq) - var/check_dist = get_dist(src,R) + if((radio.z in zlevels) && radio.frequency == tracking_freq) + var/check_dist = get_dist(src, radio) if(check_dist < cur_dist) cur_dist = check_dist - . = weakref(R) + . = weakref(radio) /obj/item/pinpointer/radio/attack_self(var/mob/user) interact(user) diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 3e99d2da0c52..8eabec403ce8 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -22,12 +22,12 @@ if(!ispath(model, /decl/bodytype/prosthetic)) model = /decl/bodytype/prosthetic/basic_human model_info = model - var/decl/bodytype/prosthetic/R = GET_DECL(model) - if(R) - SetName("[R.name] [initial(name)]") - desc = "[R.desc]" - if(icon_state in icon_states(R.icon_base)) - icon = R.icon_base + var/decl/bodytype/prosthetic/robot_model = GET_DECL(model) + if(robot_model) + SetName("[robot_model.name] [initial(name)]") + desc = "[robot_model.desc]" + if(icon_state in icon_states(robot_model.icon_base)) + icon = robot_model.icon_base else SetDefaultName() diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index e7e5cb527e9b..61aa021a7dc8 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -35,9 +35,8 @@ return add_autopsy_data(S) - for(var/T in M.chem_doses) - var/decl/material/R = T - chemtraces |= initial(R.name) + for(var/decl/material/dose as anything in M.chem_doses) + chemtraces |= initial(dose.name) else if(istype(A, /obj/item/organ/external)) set_target(A, user) diff --git a/code/game/objects/structures/barricade.dm b/code/game/objects/structures/barricade.dm index b5708b8f18f2..e62e7675c4c3 100644 --- a/code/game/objects/structures/barricade.dm +++ b/code/game/objects/structures/barricade.dm @@ -51,14 +51,14 @@ /obj/structure/barricade/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/stack/material/rods) && !reinf_material) - var/obj/item/stack/material/rods/R = W - if(R.get_amount() < 5) + var/obj/item/stack/material/rods/rods = W + if(rods.get_amount() < 5) to_chat(user, SPAN_WARNING("You need more rods to build a cheval de frise.")) else visible_message(SPAN_NOTICE("\The [user] begins to work on \the [src].")) - if(do_after(user, 4 SECONDS, src) && !reinf_material && R.use(5)) - visible_message(SPAN_NOTICE("\The [user] fastens \the [R] to \the [src].")) - reinf_material = R.material + if(do_after(user, 4 SECONDS, src) && !reinf_material && rods.use(5)) + visible_message(SPAN_NOTICE("\The [user] fastens \the [rods] to \the [src].")) + reinf_material = rods.material update_materials(TRUE) . = ..() diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 6963ec745c48..1f7913057f0d 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -19,11 +19,11 @@ return playsound(loc, 'sound/items/zip.ogg', 75, 1) user.visible_message(SPAN_NOTICE("[user] inflates \the [src]."), SPAN_NOTICE("You inflate \the [src].")) - var/obj/structure/inflatable/R = new deploy_path(user.loc) - transfer_fingerprints_to(R) - R.add_fingerprint(user) + var/obj/structure/inflatable/debris = new deploy_path(user.loc) + transfer_fingerprints_to(debris) + debris.add_fingerprint(user) if(inflatable_health) - R.current_health = inflatable_health + debris.current_health = inflatable_health qdel(src) /obj/item/inflatable/door @@ -160,17 +160,16 @@ playsound(loc, 'sound/machines/hiss.ogg', 75, 1) if(violent) visible_message("[src] rapidly deflates!") - var/obj/item/inflatable/torn/R = new(loc) - src.transfer_fingerprints_to(R) + transfer_fingerprints_to(new /obj/item/inflatable/torn(loc)) qdel(src) else if(!undeploy_path) return visible_message("\The [src] slowly deflates.") spawn(50) - var/obj/item/inflatable/R = new undeploy_path(src.loc) - src.transfer_fingerprints_to(R) - R.inflatable_health = current_health + var/obj/item/inflatable/door_item = new undeploy_path(src.loc) + src.transfer_fingerprints_to(door_item) + door_item.inflatable_health = current_health qdel(src) /obj/structure/inflatable/verb/hand_deflate() @@ -270,15 +269,15 @@ playsound(loc, 'sound/machines/hiss.ogg', 75, 1) if(violent) visible_message("[src] rapidly deflates!") - var/obj/item/inflatable/door/torn/R = new /obj/item/inflatable/door/torn(loc) - src.transfer_fingerprints_to(R) + transfer_fingerprints_to(new /obj/item/inflatable/door/torn(loc)) qdel(src) else visible_message("[src] slowly deflates.") spawn(50) - var/obj/item/inflatable/door/R = new /obj/item/inflatable/door(loc) - src.transfer_fingerprints_to(R) - qdel(src) + if(!QDELETED(src)) + if(loc) + transfer_fingerprints_to(new /obj/item/inflatable/door(loc)) + qdel(src) /obj/item/inflatable/torn name = "torn inflatable wall" diff --git a/code/game/objects/structures/ironing_board.dm b/code/game/objects/structures/ironing_board.dm index 3248822f656e..4853908a3654 100644 --- a/code/game/objects/structures/ironing_board.dm +++ b/code/game/objects/structures/ironing_board.dm @@ -81,7 +81,7 @@ update_icon() return TRUE else if(istype(I,/obj/item/ironingiron)) - var/obj/item/ironingiron/R = I + var/obj/item/ironingiron/iron = I // anti-wrinkle "massage" if(buckled_mob && ishuman(buckled_mob)) @@ -100,8 +100,8 @@ return TRUE if(!cloth) - if(!holding && !R.enabled && user.try_unequip(I, src)) - holding = R + if(!holding && !iron.enabled && user.try_unequip(I, src)) + holding = iron events_repository.register(/decl/observ/destroyed, I, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) update_icon() return TRUE diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 3de7c1dba7b2..6f5f9c950c80 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -87,14 +87,14 @@ to_chat(user, SPAN_WARNING("\The [ladder] is in the way.")) return TRUE - var/obj/item/stack/material/rods/R = C + var/obj/item/stack/material/rods/rods = C var/turf/my_turf = get_turf(src) if(my_turf?.get_supporting_platform()) to_chat(user, SPAN_WARNING("There is already a platform here.")) return TRUE - else if(R.use(2)) + else if(rods.use(2)) playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) - new /obj/structure/catwalk(my_turf, R.material.type) + new /obj/structure/catwalk(my_turf, rods.material.type) return TRUE else to_chat(user, SPAN_WARNING("You require at least two rods to complete the catwalk.")) diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index ae06bb484e42..b453621b6a5c 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -88,8 +88,8 @@ WOOD_RAILING_SUBTYPE(yew) broken = TRUE for(var/thing in RANGE_TURFS(src, 1)) var/turf/T = thing - for(var/obj/structure/railing/R in T.contents) - R.update_icon() + for(var/obj/structure/railing/rail in T.contents) + rail.update_icon() . = ..() /obj/structure/railing/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) @@ -105,41 +105,41 @@ WOOD_RAILING_SUBTYPE(yew) var/Rturn = turn(dir, -90) var/Lturn = turn(dir, 90) - for(var/obj/structure/railing/R in loc) - if ((R.dir == Lturn) && R.anchored) + for(var/obj/structure/railing/rail in loc) + if ((rail.dir == Lturn) && rail.anchored) neighbor_status |= 32 if (propagate) - R.update_connections() - R.update_icon() - if ((R.dir == Rturn) && R.anchored) + rail.update_connections() + rail.update_icon() + if ((rail.dir == Rturn) && rail.anchored) neighbor_status |= 2 if (propagate) - R.update_connections() - R.update_icon() - for (var/obj/structure/railing/R in get_step(src, Lturn)) - if ((R.dir == dir) && R.anchored) + rail.update_connections() + rail.update_icon() + for (var/obj/structure/railing/rail in get_step(src, Lturn)) + if ((rail.dir == dir) && rail.anchored) neighbor_status |= 16 if (propagate) - R.update_connections() - R.update_icon() - for (var/obj/structure/railing/R in get_step(src, Rturn)) - if ((R.dir == dir) && R.anchored) + rail.update_connections() + rail.update_icon() + for (var/obj/structure/railing/rail in get_step(src, Rturn)) + if ((rail.dir == dir) && rail.anchored) neighbor_status |= 1 if (propagate) - R.update_connections() - R.update_icon() - for (var/obj/structure/railing/R in get_step(src, (Lturn + dir))) - if ((R.dir == Rturn) && R.anchored) + rail.update_connections() + rail.update_icon() + for (var/obj/structure/railing/rail in get_step(src, (Lturn + dir))) + if ((rail.dir == Rturn) && rail.anchored) neighbor_status |= 64 if (propagate) - R.update_connections() - R.update_icon() - for (var/obj/structure/railing/R in get_step(src, (Rturn + dir))) - if ((R.dir == Lturn) && R.anchored) + rail.update_connections() + rail.update_icon() + for (var/obj/structure/railing/rail in get_step(src, (Rturn + dir))) + if ((rail.dir == Lturn) && rail.anchored) neighbor_status |= 4 if (propagate) - R.update_connections() - R.update_icon() + rail.update_connections() + rail.update_icon() /obj/structure/railing/on_update_icon() ..() diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 874422eae0b8..a5b145bc5abd 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -98,11 +98,11 @@ var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) return L.attackby(C, user) - var/obj/item/stack/material/rods/R = C - if (R.use(1)) + var/obj/item/stack/material/rods/rods = C + if (rods.use(1)) to_chat(user, "Constructing support lattice ...") playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) - new /obj/structure/lattice(src, R.material.type) + new /obj/structure/lattice(src, rods.material.type) return TRUE if (istype(C, /obj/item/stack/tile/floor)) diff --git a/code/modules/admin/buildmode/mode_areas.dm b/code/modules/admin/buildmode/mode_areas.dm index 9ddfcf18fc4c..39b28fa353c1 100644 --- a/code/modules/admin/buildmode/mode_areas.dm +++ b/code/modules/admin/buildmode/mode_areas.dm @@ -41,9 +41,9 @@ if (mode == "Pick") var/area/path = select_subpath((selected_area?.type || /area/space), /area) if (path) - for (var/area/R in global.areas) - if (R.type == path) - SelectArea(R) + for (var/area/build_area in global.areas) + if (build_area.type == path) + SelectArea(build_area) to_chat(user, "Picked area [selected_area.proper_name]") break else if (mode == "Create") diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 1e2271efa3ad..a04958de0005 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -32,11 +32,9 @@ /obj/item/chems/borghypo/Initialize() . = ..() - - for(var/T in reagent_ids) - reagent_volumes[T] = volume - var/decl/material/robot = T - reagent_names += initial(robot.name) + for(var/decl/material/reagent as anything in reagent_ids) + reagent_volumes[reagent] = volume + reagent_names += initial(reagent.name) START_PROCESSING(SSobj, src) /obj/item/chems/borghypo/Destroy() @@ -51,10 +49,10 @@ if(isrobot(loc)) var/mob/living/silicon/robot/robot = loc if(robot && robot.cell) - for(var/T in reagent_ids) - if(reagent_volumes[T] < volume) + for(var/reagent in reagent_ids) + if(reagent_volumes[reagent] < volume) robot.cell.use(charge_cost) - reagent_volumes[T] = min(reagent_volumes[T] + 5, volume) + reagent_volumes[reagent] = min(reagent_volumes[reagent] + 5, volume) return 1 /obj/item/chems/borghypo/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) @@ -103,16 +101,16 @@ if(index > 0 && index <= reagent_ids.len) playsound(loc, 'sound/effects/pop.ogg', 50, 0) mode = index - var/decl/material/robot = reagent_ids[mode] - to_chat(user, "Synthesizer is now producing '[initial(robot.name)]'.") + var/decl/material/reagent = reagent_ids[mode] + to_chat(user, "Synthesizer is now producing '[initial(reagent.name)]'.") return TOPIC_REFRESH /obj/item/chems/borghypo/get_examine_strings(mob/user, distance, infix, suffix) . = ..() if(distance > 2) return - var/decl/material/robot = reagent_ids[mode] - . += SPAN_NOTICE("It is currently producing [initial(robot.name)] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left.") + var/decl/material/reagent = reagent_ids[mode] + . += SPAN_NOTICE("It is currently producing [initial(reagent.name)] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left.") /obj/item/chems/borghypo/service name = "cyborg drink synthesizer" From 94df2126f58b0fd3b702288c33b6d7b75e09d558 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 17 Feb 2025 15:40:31 +1100 Subject: [PATCH 014/512] Generalising some bodybag code. --- code/game/objects/items/bodybag.dm | 10 ++++++++-- code/game/objects/items/cryobag.dm | 13 ++++++------- code/game/objects/items/rescuebag.dm | 12 ++++++------ 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 4313657b12dc..120f974374b8 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -7,11 +7,17 @@ icon_state = "bodybag_folded" w_class = ITEM_SIZE_SMALL material = /decl/material/solid/organic/plastic + var/bag_type = /obj/structure/closet/body_bag + +/obj/item/bodybag/proc/create_bag_structure(mob/user) + var/atom/bag = new bag_type(user.loc) + bag.add_fingerprint(user) + return bag /obj/item/bodybag/attack_self(mob/user) - var/obj/structure/closet/body_bag/R = new /obj/structure/closet/body_bag(user.loc) - R.add_fingerprint(user) + create_bag_structure(user) qdel(src) + return TRUE /obj/item/box/bodybags name = "body bags" diff --git a/code/game/objects/items/cryobag.dm b/code/game/objects/items/cryobag.dm index 87d328458c74..ba01e37bc1d0 100644 --- a/code/game/objects/items/cryobag.dm +++ b/code/game/objects/items/cryobag.dm @@ -12,18 +12,17 @@ /decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE, /decl/material/solid/metal/gold = MATTER_AMOUNT_TRACE ) + bag_type = /obj/structure/closet/body_bag/cryobag var/stasis_power /obj/item/bodybag/cryobag/get_cryogenic_power() return stasis_power -/obj/item/bodybag/cryobag/attack_self(mob/user) - var/obj/structure/closet/body_bag/cryobag/R = new /obj/structure/closet/body_bag/cryobag(user.loc) - if(stasis_power) - R.stasis_power = stasis_power - R.update_icon() - R.add_fingerprint(user) - qdel(src) +/obj/item/bodybag/cryobag/create_bag_structure(mob/user) + var/obj/structure/closet/body_bag/cryobag/bag = ..() + if(istype(bag) && stasis_power) + bag.stasis_power = stasis_power + return bag /obj/structure/closet/body_bag/cryobag name = "stasis bag" diff --git a/code/game/objects/items/rescuebag.dm b/code/game/objects/items/rescuebag.dm index 4ae13e1cd418..15fbf7a53dea 100644 --- a/code/game/objects/items/rescuebag.dm +++ b/code/game/objects/items/rescuebag.dm @@ -8,6 +8,7 @@ origin_tech = @'{"biotech":2}' material = /decl/material/solid/organic/plastic matter = list(/decl/material/solid/silicon = MATTER_AMOUNT_SECONDARY) + bag_type = /obj/structure/closet/body_bag/rescue var/obj/item/tank/airtank /obj/item/bodybag/rescue/loaded @@ -23,13 +24,12 @@ QDEL_NULL(airtank) return ..() -/obj/item/bodybag/rescue/attack_self(mob/user) - var/obj/structure/closet/body_bag/rescue/R = new /obj/structure/closet/body_bag/rescue(user.loc) - R.add_fingerprint(user) - if(airtank) - R.set_tank(airtank) +/obj/item/bodybag/rescue/create_bag_structure(mob/user) + var/obj/structure/closet/body_bag/rescue/bag = ..() + if(istype(bag) && airtank) + bag.set_tank(airtank) airtank = null - qdel(src) + return bag /obj/item/bodybag/rescue/attackby(obj/item/W, mob/user, var/click_params) if(istype(W,/obj/item/tank)) From eea5d03ef479e5afb218cffb350dff37fbb422c6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 18 Feb 2025 16:03:05 +1100 Subject: [PATCH 015/512] Tweaks from review, squash before merge. --- code/_helpers/lists.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_helpers/lists.dm b/code/_helpers/lists.dm index 1d3dc695e8bf..b9d16ba65ab1 100644 --- a/code/_helpers/lists.dm +++ b/code/_helpers/lists.dm @@ -279,7 +279,7 @@ Checks if a list has the same entries and values as an element of big. total = rand(1, total) for (item in target_list) - total -=target_list [item] + total -= target_list[item] if (total <= 0) return item From 7b8c58308582e1d43de7a73cb8d27d77611a8dea Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 18 Feb 2025 16:08:33 +1100 Subject: [PATCH 016/512] Moves priority queue files into _helpers, privates vars. --- .../datastructures}/priority_queue.dm | 4 ++-- code/{__datastructures => _helpers/datastructures}/stack.dm | 0 nebula.dme | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename code/{__datastructures => _helpers/datastructures}/priority_queue.dm (94%) rename code/{__datastructures => _helpers/datastructures}/stack.dm (100%) diff --git a/code/__datastructures/priority_queue.dm b/code/_helpers/datastructures/priority_queue.dm similarity index 94% rename from code/__datastructures/priority_queue.dm rename to code/_helpers/datastructures/priority_queue.dm index 3505149d034d..f75f71dabbb7 100644 --- a/code/__datastructures/priority_queue.dm +++ b/code/_helpers/datastructures/priority_queue.dm @@ -1,9 +1,9 @@ /// An automatically ordered list, using the cmp proc to weight the list items /datum/priority_queue /// The actual queue - var/list/my_queue = list() // For some reason putting VAR_PRIVATE on this causes it to be relatively pathed?? + VAR_PRIVATE/list/my_queue = list() /// The weight function used to order the queue - var/cmp + VAR_PRIVATE/cmp /// Takes a proc `comparer` that will be used to compare the items inserted /// * Param `comparer` take two arguments and return the difference in their weight diff --git a/code/__datastructures/stack.dm b/code/_helpers/datastructures/stack.dm similarity index 100% rename from code/__datastructures/stack.dm rename to code/_helpers/datastructures/stack.dm diff --git a/nebula.dme b/nebula.dme index 1b46214d4be9..da54dd18fb41 100644 --- a/nebula.dme +++ b/nebula.dme @@ -17,8 +17,6 @@ #include "code\client_macros.dm" #include "code\hub.dm" #include "code\world.dm" -#include "code\__datastructures\priority_queue.dm" -#include "code\__datastructures\stack.dm" #include "code\__defines\_byond_version_compat.dm" #include "code\__defines\_compile_helpers.dm" #include "code\__defines\_planes+layers.dm" @@ -164,6 +162,8 @@ #include "code\_helpers\view.dm" #include "code\_helpers\visual_filters.dm" #include "code\_helpers\washing.dm" +#include "code\_helpers\datastructures\priority_queue.dm" +#include "code\_helpers\datastructures\stack.dm" #include "code\_helpers\sorts\__main.dm" #include "code\_helpers\sorts\TimSort.dm" #include "code\_onclick\adjacent.dm" From 294cf92f5b400b2d0f4a55e4bcd4bb529b2e2ecf Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 18 Feb 2025 16:11:50 +1100 Subject: [PATCH 017/512] C -> cell --- code/game/machinery/recharger.dm | 14 ++-- code/game/objects/items/devices/inducer.dm | 12 +-- code/game/objects/items/weapons/defib.dm | 4 +- code/modules/admin/verbs/debug.dm | 6 +- .../designs/protolathe/designs_power_cells.dm | 4 +- .../integrated_electronics/subtypes/input.dm | 10 +-- code/modules/mechs/equipment/combat.dm | 14 ++-- code/modules/mechs/equipment/engineering.dm | 12 +-- code/modules/mechs/equipment/utility.dm | 12 +-- code/modules/mechs/interface/_interface.dm | 4 +- code/modules/mechs/mech_movement.dm | 4 +- code/modules/power/batteryrack.dm | 84 +++++++++---------- code/modules/vehicles/bike.dm | 6 +- code/modules/vehicles/cargo_train.dm | 44 +++++----- code/modules/vehicles/vehicle.dm | 38 ++++----- .../artifacts/effects/cellcharge.dm | 18 ++-- .../artifacts/effects/celldrain.dm | 18 ++-- 17 files changed, 152 insertions(+), 152 deletions(-) diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 9a05621916b9..05196878a6f7 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -83,11 +83,11 @@ update_use_power(POWER_USE_IDLE) icon_state = icon_state_idle else - var/obj/item/cell/C = charging.get_cell() - if(istype(C)) - if(!C.fully_charged()) + var/obj/item/cell/cell = charging.get_cell() + if(istype(cell)) + if(!cell.fully_charged()) icon_state = icon_state_charging - C.give(active_power_usage*CELLRATE) + cell.give(active_power_usage*CELLRATE) update_use_power(POWER_USE_ACTIVE) else icon_state = icon_state_charged @@ -98,9 +98,9 @@ ..(severity) return if(charging) - var/obj/item/cell/C = charging.get_cell() - if(istype(C)) - C.emp_act(severity) + var/obj/item/cell/cell = charging.get_cell() + if(istype(cell)) + cell.emp_act(severity) ..(severity) /obj/machinery/recharger/on_update_icon() //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier. diff --git a/code/game/objects/items/devices/inducer.dm b/code/game/objects/items/devices/inducer.dm index 132fcc0e82fe..77527d8e98a0 100644 --- a/code/game/objects/items/devices/inducer.dm +++ b/code/game/objects/items/devices/inducer.dm @@ -59,15 +59,15 @@ else recharging = TRUE var/obj/item/cell/MyC = get_cell() - var/obj/item/cell/C = A.get_cell() + var/obj/item/cell/cell = A.get_cell() var/obj/O if(istype(A, /obj)) O = A - if(C) + if(cell) var/charge_length = 10 var/done_any = FALSE spark_at(user, amount = 1, cardinal_only = TRUE) - if(C.charge >= C.maxcharge) + if(cell.charge >= cell.maxcharge) to_chat(user, "\The [A] is fully charged!") recharging = FALSE return TRUE @@ -78,15 +78,15 @@ charge_length += rand(10, 30) if (user.get_skill_value(SKILL_ELECTRICAL) < SKILL_ADEPT) charge_length += rand(40, 60) - while(C.charge < C.maxcharge) + while(cell.charge < cell.maxcharge) if(MyC.charge > max(0, MyC.charge*failsafe) && do_after(user, charge_length, target = user)) if(CannotUse(user)) return TRUE - if(QDELETED(C)) + if(QDELETED(cell)) return TRUE spark_at(user, amount = 1, cardinal_only = TRUE) done_any = TRUE - induce(C) + induce(cell) if(O) O.update_icon() else diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index ff4c6ca763d4..133eb87f0a57 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -365,8 +365,8 @@ H.resuscitate() var/obj/item/organ/internal/cell/potato = H.get_organ(BP_CELL, /obj/item/organ/internal/cell) if(potato && potato.cell) - var/obj/item/cell/C = potato.cell - C.give(chargecost) + var/obj/item/cell/cell = potato.cell + cell.give(chargecost) ADJ_STATUS(H, STAT_ASLEEP, -60) log_and_message_admins("used \a [src] to revive [key_name(H)].") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 6878930ff4ae..96c051a8b9a4 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -80,9 +80,9 @@ set desc = "Specify a location to spawn a pAI device, then specify a key to play that pAI" var/list/available = list() - for(var/mob/C in SSmobs.mob_list) - if(C.key) - available.Add(C) + for(var/mob/player in SSmobs.mob_list) + if(player.key) + available.Add(player) var/mob/choice = input("Choose a player to play the pAI", "Spawn pAI") in available if(!choice) return 0 diff --git a/code/modules/fabrication/designs/protolathe/designs_power_cells.dm b/code/modules/fabrication/designs/protolathe/designs_power_cells.dm index 829d07e5de2e..cbf075f8fc08 100644 --- a/code/modules/fabrication/designs/protolathe/designs_power_cells.dm +++ b/code/modules/fabrication/designs/protolathe/designs_power_cells.dm @@ -8,8 +8,8 @@ /datum/fabricator_recipe/protolathe/cell/build() . = ..() - for(var/obj/item/cell/C in .) - C.charge = 0 + for(var/obj/item/cell/cell in .) + cell.charge = 0 /datum/fabricator_recipe/protolathe/cell/get_product_name() . = "power cell model ([..()])" diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 336cf7b55443..d94349734ba9 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -987,13 +987,13 @@ set_pin_data(IC_OUTPUT, 2, null) set_pin_data(IC_OUTPUT, 3, null) if(O) - var/obj/item/cell/C = O.get_cell() - if(C) + var/obj/item/cell/cell = O.get_cell() + if(cell) var/turf/A = get_turf(src) if(get_turf(O) in view(A)) - set_pin_data(IC_OUTPUT, 1, C.charge) - set_pin_data(IC_OUTPUT, 2, C.maxcharge) - set_pin_data(IC_OUTPUT, 3, C.percent()) + set_pin_data(IC_OUTPUT, 1, cell.charge) + set_pin_data(IC_OUTPUT, 2, cell.maxcharge) + set_pin_data(IC_OUTPUT, 3, cell.percent()) push_data() activate_pin(2) return diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index e0fece6b5124..6ab5b456ccbc 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -45,9 +45,9 @@ return "[round(power_supply.charge / charge_cost)]/[max_shots]" /obj/item/gun/energy/get_hardpoint_status_value() - var/obj/item/cell/C = get_cell() - if(istype(C)) - return C.charge/C.maxcharge + var/obj/item/cell/cell = get_cell() + if(istype(cell)) + return cell.charge/cell.maxcharge return null /obj/item/mech_equipment/shields @@ -312,8 +312,8 @@ playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) var/flash_time = (rand(flash_min,flash_max) - 1) - var/obj/item/cell/C = owner.get_cell() - C.use(active_power_use * CELLRATE) + var/obj/item/cell/cell = owner.get_cell() + cell.use(active_power_use * CELLRATE) for (var/mob/living/O in oviewers(flash_range, owner)) if(istype(O)) @@ -360,8 +360,8 @@ playsound(src.loc, 'sound/weapons/flash.ogg', 100, 1) var/flash_time = (rand(flash_min,flash_max)) - var/obj/item/cell/C = owner.get_cell() - C.use(active_power_use * CELLRATE) + var/obj/item/cell/cell = owner.get_cell() + cell.use(active_power_use * CELLRATE) var/protection = O.eyecheck() if(protection >= FLASH_PROTECTION_MAJOR) diff --git a/code/modules/mechs/equipment/engineering.dm b/code/modules/mechs/equipment/engineering.dm index f2f7448b2d64..b287ef5713e3 100644 --- a/code/modules/mechs/equipment/engineering.dm +++ b/code/modules/mechs/equipment/engineering.dm @@ -14,17 +14,17 @@ /obj/item/rcd/mounted/get_hardpoint_maptext() var/obj/item/mech_equipment/mounted_system/MS = loc if(istype(MS) && MS.owner) - var/obj/item/cell/C = MS.owner.get_cell() - if(istype(C)) - return "[round(C.charge)]/[round(C.maxcharge)]" + var/obj/item/cell/cell = MS.owner.get_cell() + if(istype(cell)) + return "[round(cell.charge)]/[round(cell.maxcharge)]" return null /obj/item/rcd/mounted/get_hardpoint_status_value() var/obj/item/mech_equipment/mounted_system/MS = loc if(istype(MS) && MS.owner) - var/obj/item/cell/C = MS.owner.get_cell() - if(istype(C)) - return C.charge/C.maxcharge + var/obj/item/cell/cell = MS.owner.get_cell() + if(istype(cell)) + return cell.charge/cell.maxcharge return null /obj/item/chems/spray/extinguisher/mech diff --git a/code/modules/mechs/equipment/utility.dm b/code/modules/mechs/equipment/utility.dm index bfd2be06d01f..903d50deb30d 100644 --- a/code/modules/mechs/equipment/utility.dm +++ b/code/modules/mechs/equipment/utility.dm @@ -305,9 +305,9 @@ log_and_message_admins("used [src] to throw [locked] at [target].", user, owner.loc) locked = null - var/obj/item/cell/C = owner.get_cell() - if(istype(C)) - C.use(active_power_use * CELLRATE) + var/obj/item/cell/cell = owner.get_cell() + if(istype(cell)) + cell.use(active_power_use * CELLRATE) else locked = null @@ -326,9 +326,9 @@ log_and_message_admins("used [src]'s area throw on [target].", user, owner.loc) - var/obj/item/cell/C = owner.get_cell() - if(istype(C)) - C.use(active_power_use * CELLRATE * 2) //bit more expensive to throw all + var/obj/item/cell/cell = owner.get_cell() + if(istype(cell)) + cell.use(active_power_use * CELLRATE * 2) //bit more expensive to throw all diff --git a/code/modules/mechs/interface/_interface.dm b/code/modules/mechs/interface/_interface.dm index e314bcf27a81..f9090602be10 100644 --- a/code/modules/mechs/interface/_interface.dm +++ b/code/modules/mechs/interface/_interface.dm @@ -72,8 +72,8 @@ handle_hud_icons_health() var/maptext_string = "CHECK
    POWER" - var/obj/item/cell/C = get_cell() - if(istype(C)) + var/obj/item/cell/cell = get_cell() + if(istype(cell)) maptext_string = "[round(get_cell().charge)]/[round(get_cell().maxcharge)]" hud_power.maptext = STYLE_SMALLFONTS_OUTLINE("
    [maptext_string]
    ", 5, COLOR_WHITE, COLOR_BLACK) refresh_hud() diff --git a/code/modules/mechs/mech_movement.dm b/code/modules/mechs/mech_movement.dm index 790bce7f715c..184ab0767e55 100644 --- a/code/modules/mechs/mech_movement.dm +++ b/code/modules/mechs/mech_movement.dm @@ -72,8 +72,8 @@ to_chat(mover, SPAN_WARNING("Maintenance protocols are in effect.")) exosuit.SetMoveCooldown(3) return MOVEMENT_STOP - var/obj/item/cell/C = exosuit.get_cell() - if(!C || !C.check_charge(exosuit.legs.power_use * CELLRATE)) + var/obj/item/cell/cell = exosuit.get_cell() + if(!cell || !cell.check_charge(exosuit.legs.power_use * CELLRATE)) to_chat(mover, SPAN_WARNING("The power indicator flashes briefly.")) exosuit.SetMoveCooldown(3) //On fast exosuits this got annoying fast return MOVEMENT_STOP diff --git a/code/modules/power/batteryrack.dm b/code/modules/power/batteryrack.dm index 27524a6eb2c4..8ccfa5e609c9 100644 --- a/code/modules/power/batteryrack.dm +++ b/code/modules/power/batteryrack.dm @@ -37,8 +37,8 @@ ..() /obj/machinery/power/smes/batteryrack/Destroy() - for(var/obj/item/cell/C in internal_cells) - qdel(C) + for(var/obj/item/cell/cell in internal_cells) + qdel(cell) internal_cells = null return ..() @@ -52,19 +52,19 @@ overlays += "charge[charge_level]" - for(var/obj/item/cell/C in internal_cells) + for(var/obj/item/cell/cell in internal_cells) cellcount++ overlays += "cell[cellcount]" - if(C.fully_charged()) + if(cell.fully_charged()) overlays += "cell[cellcount]f" - else if(!C.charge) + else if(!cell.charge) overlays += "cell[cellcount]e" // Recalculate maxcharge and similar variables. /obj/machinery/power/smes/batteryrack/proc/update_maxcharge() var/newmaxcharge = 0 - for(var/obj/item/cell/C in internal_cells) - newmaxcharge += C.maxcharge + for(var/obj/item/cell/cell in internal_cells) + newmaxcharge += cell.maxcharge capacity = newmaxcharge charge = clamp(charge, 0, newmaxcharge) @@ -99,8 +99,8 @@ if(!amount) return // We're still here, so it means the least charged cell was full OR we don't care about equalising the charge. Give power to other cells instead. - for(var/obj/item/cell/C in internal_cells) - amount -= C.give(amount) + for(var/obj/item/cell/cell in internal_cells) + amount -= cell.give(amount) // No more power to input so return. if(!amount) return @@ -115,8 +115,8 @@ if(!amount) return // We're still here, so it means the most charged cell didn't have enough power OR we don't care about equalising the charge. Use power from other cells instead. - for(var/obj/item/cell/C in internal_cells) - amount -= C.use(amount) + for(var/obj/item/cell/cell in internal_cells) + amount -= cell.use(amount) // No more power to output so return. if(!amount) return @@ -124,31 +124,31 @@ // Helper procs to get most/least charged cells. /obj/machinery/power/smes/batteryrack/proc/get_most_charged_cell() var/obj/item/cell/CL = null - for(var/obj/item/cell/C in internal_cells) + for(var/obj/item/cell/cell in internal_cells) if(CL == null) - CL = C - else if(CL.percent() < C.percent()) - CL = C + CL = cell + else if(CL.percent() < cell.percent()) + CL = cell return CL /obj/machinery/power/smes/batteryrack/proc/get_least_charged_cell() var/obj/item/cell/CL = null - for(var/obj/item/cell/C in internal_cells) + for(var/obj/item/cell/cell in internal_cells) if(CL == null) - CL = C - else if(CL.percent() > C.percent()) - CL = C + CL = cell + else if(CL.percent() > cell.percent()) + CL = cell return CL -/obj/machinery/power/smes/batteryrack/proc/insert_cell(var/obj/item/cell/C, var/mob/user) - if(!istype(C)) +/obj/machinery/power/smes/batteryrack/proc/insert_cell(var/obj/item/cell/cell, var/mob/user) + if(!istype(cell)) return 0 if(internal_cells.len >= max_cells) return 0 - if(user && !user.try_unequip(C)) + if(user && !user.try_unequip(cell)) return 0 - internal_cells.Add(C) - C.forceMove(src) + internal_cells.Add(cell) + cell.forceMove(src) RefreshParts() update_maxcharge() update_icon() @@ -157,8 +157,8 @@ /obj/machinery/power/smes/batteryrack/Process() charge = 0 - for(var/obj/item/cell/C in internal_cells) - charge += C.charge + for(var/obj/item/cell/cell in internal_cells) + charge += cell.charge ..() ui_tick = !ui_tick @@ -200,19 +200,19 @@ data["cells_cur"] = internal_cells.len var/list/cells = list() var/cell_index = 1 - for(var/obj/item/cell/C in internal_cells) - var/list/cell[0] - cell["slot"] = cell_index - cell["used"] = 1 - cell["percentage"] = round(C.percent(), 0.01) + for(var/obj/item/cell/cell in internal_cells) + var/list/cell_data = list() + cell_data["slot"] = cell_index + cell_data["used"] = 1 + cell_data["percentage"] = round(cell.percent(), 0.01) cell_index++ - cells += list(cell) + cells += list(cell_data) while(cell_index <= PSU_MAXCELLS) - var/list/cell[0] - cell["slot"] = cell_index - cell["used"] = 0 + var/list/cell_data = list() + cell_data["slot"] = cell_index + cell_data["used"] = 0 cell_index++ - cells += list(cell) + cells += list(cell_data) data["cells_list"] = cells ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) @@ -223,9 +223,9 @@ ui.set_auto_update(1) /obj/machinery/power/smes/batteryrack/dismantle() - for(var/obj/item/cell/C in internal_cells) - C.dropInto(loc) - internal_cells -= C + for(var/obj/item/cell/cell in internal_cells) + cell.dropInto(loc) + internal_cells -= cell return ..() /obj/machinery/power/smes/batteryrack/attackby(var/obj/item/W, var/mob/user) @@ -273,10 +273,10 @@ var/slot_number = text2num(href_list["ejectcell"]) if(slot_number != clamp(round(slot_number), 1, length(internal_cells))) return TOPIC_HANDLED - var/obj/item/cell/C = internal_cells[slot_number] + var/obj/item/cell/cell = internal_cells[slot_number] - C.dropInto(loc) - internal_cells -= C + cell.dropInto(loc) + internal_cells -= cell RefreshParts() update_maxcharge() return TOPIC_REFRESH \ No newline at end of file diff --git a/code/modules/vehicles/bike.dm b/code/modules/vehicles/bike.dm index 038fc40bbf4f..794dcf366849 100644 --- a/code/modules/vehicles/bike.dm +++ b/code/modules/vehicles/bike.dm @@ -92,8 +92,8 @@ qdel(trail) trail = null -/obj/vehicle/bike/load(var/atom/movable/C) - var/mob/living/M = C +/obj/vehicle/bike/load(var/atom/movable/loading) + var/mob/living/M = loading if(!istype(M)) return 0 if(M.buckled || M.anchored || M.restrained() || !Adjacent(M) || !M.Adjacent(src)) return 0 @@ -104,7 +104,7 @@ engine.emp_act(severity) ..() -/obj/vehicle/bike/insert_cell(var/obj/item/cell/C, var/mob/living/human/H) +/obj/vehicle/bike/insert_cell(var/obj/item/cell/cell, var/mob/living/human/H) return /obj/vehicle/bike/attackby(obj/item/W, mob/user) diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index 740bef47107c..299563fa806b 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -95,10 +95,10 @@ else icon_state = initial(icon_state) -/obj/vehicle/train/cargo/trolley/insert_cell(var/obj/item/cell/C, var/mob/living/human/H) +/obj/vehicle/train/cargo/trolley/insert_cell(var/obj/item/cell/cell, var/mob/living/human/H) return -/obj/vehicle/train/cargo/engine/insert_cell(var/obj/item/cell/C, var/mob/living/human/H) +/obj/vehicle/train/cargo/engine/insert_cell(var/obj/item/cell/cell, var/mob/living/human/H) ..() update_stats() @@ -252,24 +252,24 @@ //------------------------------------------- // Loading/unloading procs //------------------------------------------- -/obj/vehicle/train/cargo/trolley/load(var/atom/movable/C) - if(ismob(C) && !passenger_allowed) +/obj/vehicle/train/cargo/trolley/load(var/atom/movable/loading) + if(ismob(loading) && !passenger_allowed) return 0 - if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !ishuman(C)) + if(!istype(loading,/obj/machinery) && !istype(loading,/obj/structure/closet) && !istype(loading,/obj/structure/largecrate) && !istype(loading,/obj/structure/reagent_dispensers) && !istype(loading,/obj/structure/ore_box) && !ishuman(loading)) return 0 //if there are any items you don't want to be able to interact with, add them to this check // ~no more shielded, emitter armed death trains - if(istype(C, /obj/machinery)) - load_object(C) + if(istype(loading, /obj/machinery)) + load_object(loading) else ..() if(load) return 1 -/obj/vehicle/train/cargo/engine/load(var/atom/movable/C) - if(!ishuman(C)) +/obj/vehicle/train/cargo/engine/load(var/atom/movable/loading) + if(!ishuman(loading)) return 0 return ..() @@ -278,10 +278,10 @@ //This prevents the object from being interacted with until it has // been unloaded. A dummy object is loaded instead so the loading // code knows to handle it correctly. -/obj/vehicle/train/cargo/trolley/proc/load_object(var/atom/movable/C) - if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. +/obj/vehicle/train/cargo/trolley/proc/load_object(var/atom/movable/loading) + if(!isturf(loading.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. return 0 - if(load || C.anchored) + if(load || loading.anchored) return 0 var/datum/vehicle_dummy_load/dummy_load = new() @@ -289,21 +289,21 @@ if(!load) return - dummy_load.actual_load = C - C.forceMove(src) + dummy_load.actual_load = loading + loading.forceMove(src) if(load_item_visible) - C.pixel_x += load_offset_x - C.pixel_y += load_offset_y - C.plane = plane - C.layer = VEHICLE_LOAD_LAYER + loading.pixel_x += load_offset_x + loading.pixel_y += load_offset_y + loading.plane = plane + loading.layer = VEHICLE_LOAD_LAYER - overlays += C + overlays += loading //we can set these back now since we have already cloned the icon into the overlay - C.pixel_x = initial(C.pixel_x) - C.pixel_y = initial(C.pixel_y) - C.reset_plane_and_layer() + loading.pixel_x = initial(loading.pixel_x) + loading.pixel_y = initial(loading.pixel_y) + loading.reset_plane_and_layer() /obj/vehicle/train/cargo/trolley/unload(var/mob/user, var/direction) if(istype(load, /datum/vehicle_dummy_load)) diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 1098bd2bf01b..30fe371f57e9 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -234,16 +234,16 @@ turn_on() return -/obj/vehicle/proc/insert_cell(var/obj/item/cell/C, var/mob/living/user) +/obj/vehicle/proc/insert_cell(var/obj/item/cell/cell, var/mob/living/user) if(cell) return - if(!istype(C)) + if(!istype(cell)) return - if(!user.try_unequip(C, src)) + if(!user.try_unequip(cell, src)) return - cell = C + cell = cell powercheck() - to_chat(user, "You install [C] in [src].") + to_chat(user, "You install [cell] in [src].") /obj/vehicle/proc/remove_cell(var/mob/living/user) if(!cell) @@ -261,34 +261,34 @@ // the vehicle load() definition before // calling this parent proc. //------------------------------------------- -/obj/vehicle/proc/load(var/atom/movable/C) +/obj/vehicle/proc/load(var/atom/movable/loading) //This loads objects onto the vehicle so they can still be interacted with. //Define allowed items for loading in specific vehicle definitions. - if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. + if(!isturf(loading.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. return 0 - if(load || C.anchored) + if(load || loading.anchored) return 0 // if a create/closet, close before loading - var/obj/structure/closet/crate = C + var/obj/structure/closet/crate = loading if(istype(crate) && crate.opened && !crate.close()) return 0 - C.forceMove(loc) - C.set_dir(dir) - C.anchored = TRUE + loading.forceMove(loc) + loading.set_dir(dir) + loading.anchored = TRUE - load = C + load = loading if(load_item_visible) - C.plane = plane - C.layer = VEHICLE_LOAD_LAYER //so it sits above the vehicle + loading.plane = plane + loading.layer = VEHICLE_LOAD_LAYER //so it sits above the vehicle - if(ismob(C)) - buckle_mob(C) + if(ismob(loading)) + buckle_mob(loading) else if(load_item_visible) - C.pixel_x += load_offset_x - C.pixel_y += load_offset_y + loading.pixel_x += load_offset_x + loading.pixel_y += load_offset_y return 1 diff --git a/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm b/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm index 1af0fa44e757..1ccf80abd710 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/cellcharge.dm @@ -8,9 +8,9 @@ if(user) if(isrobot(user)) var/mob/living/silicon/robot/robot = user - var/obj/item/cell/C = robot.get_cell() - if(C) - C.give(100) + var/obj/item/cell/cell = robot.get_cell() + if(cell) + cell.give(100) to_chat(robot, SPAN_NOTICE("SYSTEM ALERT: Energy boost detected!")) return 1 @@ -27,15 +27,15 @@ /datum/artifact_effect/cellcharge/proc/charge_cells_in_range(amount) var/turf/T = get_turf(holder) for (var/obj/machinery/power/apc/A in range(effect_range, T)) - var/obj/item/cell/C = A.get_cell() - if(C) - C.give(amount) + var/obj/item/cell/cell = A.get_cell() + if(cell) + cell.give(amount) for (var/obj/machinery/power/smes/S in range(effect_range, T)) S.add_charge(amount / CELLRATE) for (var/mob/living/silicon/robot/M in range(effect_range, T)) - var/obj/item/cell/C = M.get_cell() - if(C) - C.give(amount) + var/obj/item/cell/cell = M.get_cell() + if(cell) + cell.give(amount) if(world.time - last_message > 200) to_chat(M, SPAN_NOTICE("SYSTEM ALERT: Energy boost detected!")) last_message = world.time diff --git a/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm b/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm index dba19e3b67ee..9d5a6b626ac0 100644 --- a/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm +++ b/code/modules/xenoarcheaology/artifacts/effects/celldrain.dm @@ -8,9 +8,9 @@ if(user) if(isrobot(user)) var/mob/living/silicon/robot/robot = user - var/obj/item/cell/C = robot.get_cell() - if(C) - C.use(100) + var/obj/item/cell/cell = robot.get_cell() + if(cell) + cell.use(100) to_chat(robot, SPAN_WARNING("SYSTEM ALERT: Energy drain detected!")) return 1 @@ -27,15 +27,15 @@ /datum/artifact_effect/celldrain/proc/drain_cells_in_range(amount) var/turf/T = get_turf(holder) for (var/obj/machinery/power/apc/A in range(effect_range, T)) - var/obj/item/cell/C = A.get_cell() - if(C) - C.use(amount) + var/obj/item/cell/cell = A.get_cell() + if(cell) + cell.use(amount) for (var/obj/machinery/power/smes/S in range(effect_range, T)) S.remove_charge(amount / CELLRATE) for (var/mob/living/silicon/robot/M in range(effect_range, T)) - var/obj/item/cell/C = M.get_cell() - if(C) - C.use(amount) + var/obj/item/cell/cell = M.get_cell() + if(cell) + cell.use(amount) if(world.time - last_message > 200) to_chat(M, SPAN_WARNING("SYSTEM ALERT: Energy drain detected!")) last_message = world.time From e8dd8f70c8de6b994c6abf22537f6b58cfbfd77b Mon Sep 17 00:00:00 2001 From: Neerti Date: Tue, 18 Feb 2025 17:20:44 -0500 Subject: [PATCH 018/512] Makes airlock helpers for buttons actually work. --- code/modules/abstract/airlock_helper.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/abstract/airlock_helper.dm b/code/modules/abstract/airlock_helper.dm index 3e70efba8d44..0dd25032a27d 100644 --- a/code/modules/abstract/airlock_helper.dm +++ b/code/modules/abstract/airlock_helper.dm @@ -145,4 +145,7 @@ You still need to set the controller's "id_tag" to something unique. /obj/abstract/airlock_helper/button my_device = /obj/machinery/button/access icon_state = "button" - tag_addon = "_airlock" + +/obj/abstract/airlock_helper/button/configure_associated_device() + var/obj/machinery/button/access/my_button = my_device + my_button.set_id_tag(my_controller.id_tag) \ No newline at end of file From 35b73bed09842500c6bd4ab5aa5b47c21d45dfd3 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 21:04:44 -0500 Subject: [PATCH 019/512] Fix humans and unathi having the wrong brightness --- code/modules/species/station/human_bodytypes.dm | 1 - mods/species/unathi/datum/species_bodytypes.dm | 1 - 2 files changed, 2 deletions(-) diff --git a/code/modules/species/station/human_bodytypes.dm b/code/modules/species/station/human_bodytypes.dm index b6c753b55143..20f450c46dfb 100644 --- a/code/modules/species/station/human_bodytypes.dm +++ b/code/modules/species/station/human_bodytypes.dm @@ -6,7 +6,6 @@ icon_deformed = 'icons/mob/human_races/species/human/deformed_body_female.dmi' blood_overlays = 'icons/mob/human_races/species/human/blood_overlays.dmi' bandages_icon = 'icons/mob/bandage.dmi' - limb_icon_intensity = 0.7 associated_gender = FEMALE onmob_state_modifiers = list((slot_w_uniform_str) = "f") appearance_flags = HAS_SKIN_TONE_NORMAL | HAS_UNDERWEAR | HAS_EYE_COLOR diff --git a/mods/species/unathi/datum/species_bodytypes.dm b/mods/species/unathi/datum/species_bodytypes.dm index 1cf2fe31d668..cad31a0824b4 100644 --- a/mods/species/unathi/datum/species_bodytypes.dm +++ b/mods/species/unathi/datum/species_bodytypes.dm @@ -7,7 +7,6 @@ cosmetics_icon = 'mods/species/unathi/icons/cosmetics.dmi' blood_overlays = 'icons/mob/human_races/species/human/blood_overlays.dmi' bandages_icon = 'icons/mob/bandage.dmi' - limb_icon_intensity = 0.7 health_hud_intensity = 2 associated_gender = FEMALE onmob_state_modifiers = list((slot_w_uniform_str) = "f") From b11faf1c0d88040c8416c2ec476b40a88feeaca5 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 20:02:27 -0500 Subject: [PATCH 020/512] Fix recipe unit test not catching conflicts for each category --- code/unit_tests/food_tests.dm | 158 +++++++++++++++++----------------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/code/unit_tests/food_tests.dm b/code/unit_tests/food_tests.dm index c1a682a5e0d3..d9192ca4a272 100644 --- a/code/unit_tests/food_tests.dm +++ b/code/unit_tests/food_tests.dm @@ -65,92 +65,96 @@ var/failures = list() var/obj/container = new // dummy container for holding ingredients container.create_reagents(1000) + var/static/list/all_recipe_categories = list( + RECIPE_CATEGORY_MICROWAVE, + RECIPE_CATEGORY_POT, + RECIPE_CATEGORY_SKILLET, + RECIPE_CATEGORY_BAKING_DISH, + ) for (var/decl/recipe/recipe in decls_repository.get_decls_of_subtype_unassociated(/decl/recipe)) - // assume all recipes are valid because /decl/recipe/validate() handles other things - for(var/item_path in recipe.items) - var/count = recipe.items[item_path] || 1 - if(ispath(item_path, /obj/item/stack)) - if(ispath(item_path, /obj/item/stack/material)) - new item_path(container, count, /decl/material/solid/organic/bone) // placeholder - else - new item_path(container, count) - else - for(var/i in 1 to count) - if(ispath(item_path, /obj/item/food/grown)) - new item_path(container, null, null, "carrot") // placeholder - else if(ispath(item_path, /obj/item/food/processed_grown)) - new item_path(container, null, null, "carrot") // placeholder - else if(ispath(item_path, /obj/item/paper)) - new item_path(container, null, "This is so that fortune cookies work properly. TODO: Make this generic somehow?") - else - new item_path(container) var/recipe_is_valid = TRUE - for(var/fruit_key in recipe.fruit) - var/list/key_components = splittext(fruit_key, " ") - var/fruit_index = 1 - var/dry = FALSE - if(key_components[1] == "dried") - fruit_index = 2 - dry = TRUE - var/seed = seeds_by_tag[key_components[fruit_index]] - if(!seed) - failures += "Unable to find seed with grown_tag [key_components[fruit_index]] from recipe [recipe.type]" - recipe_is_valid = FALSE - continue - if(length(key_components) > fruit_index) // processed grown! - var/processed_type = processed_growns_by_tag[key_components[fruit_index + 1]] - if(!processed_type) - failures += "Unable to find processed grown type with tag [key_components[fruit_index + 1]] from recipe [recipe.type]" + // check each category, not just the first one + // null -> all categories are valid + var/list/container_categories = recipe.container_categories || all_recipe_categories + for(var/container_category in container_categories) + if(!recipe_is_valid) + break // something is fundamentally wrong with the recipe, don't check the other categories + // assume all recipes are valid because /decl/recipe/validate() handles other things + for(var/item_path in recipe.items) + var/count = recipe.items[item_path] || 1 + if(ispath(item_path, /obj/item/stack)) + if(ispath(item_path, /obj/item/stack/material)) + new item_path(container, count, /decl/material/solid/organic/bone) // placeholder + else + new item_path(container, count) + else + for(var/i in 1 to count) + if(ispath(item_path, /obj/item/food/grown)) + new item_path(container, null, null, "carrot") // placeholder + else if(ispath(item_path, /obj/item/food/processed_grown)) + new item_path(container, null, null, "carrot") // placeholder + else if(ispath(item_path, /obj/item/paper)) + new item_path(container, null, "This is so that fortune cookies work properly. TODO: Make this generic somehow?") + else + new item_path(container) + for(var/fruit_key in recipe.fruit) + var/list/key_components = splittext(fruit_key, " ") + var/fruit_index = 1 + var/dry = FALSE + if(key_components[1] == "dried") + fruit_index = 2 + dry = TRUE + var/seed = seeds_by_tag[key_components[fruit_index]] + if(!seed) + failures += "Unable to find seed with grown_tag [key_components[fruit_index]] from recipe [recipe.type]" recipe_is_valid = FALSE continue - for(var/i in 1 to recipe.fruit[fruit_key]) - var/obj/item/food/processed_grown/processed = new processed_type(container, null, null, seed) - if(dry) - processed = processed.dry_out(null, processed.get_max_drying_wetness() + 1) - processed.forceMove(container) - else - for(var/i in 1 to recipe.fruit[fruit_key]) - var/obj/item/food/grown/grown = new /obj/item/food/grown(container, null, null, seed) - if(dry) - grown = grown.dry_out(null, grown.get_max_drying_wetness() + 1) - grown.forceMove(container) - - for(var/material_key in recipe.reagents) - container.add_to_reagents(material_key, recipe.reagents[material_key]) + if(length(key_components) > fruit_index) // processed grown! + var/processed_type = processed_growns_by_tag[key_components[fruit_index + 1]] + if(!processed_type) + failures += "Unable to find processed grown type with tag [key_components[fruit_index + 1]] from recipe [recipe.type]" + recipe_is_valid = FALSE + continue + for(var/i in 1 to recipe.fruit[fruit_key]) + var/obj/item/food/processed_grown/processed = new processed_type(container, null, null, seed) + if(dry) + processed = processed.dry_out(null, processed.get_max_drying_wetness() + 1) + processed.forceMove(container) + else + for(var/i in 1 to recipe.fruit[fruit_key]) + var/obj/item/food/grown/grown = new /obj/item/food/grown(container, null, null, seed) + if(dry) + grown = grown.dry_out(null, grown.get_max_drying_wetness() + 1) + grown.forceMove(container) - if(!recipe_is_valid) - QDEL_LIST(container.contents) // clean up prematurely - container.reagents.clear_reagents() - continue + for(var/material_key in recipe.reagents) + container.add_to_reagents(material_key, recipe.reagents[material_key]) - // continue with validation - var/container_category = RECIPE_CATEGORY_MICROWAVE - if(recipe.container_categories) - container_category = recipe.container_categories[recipe.container_categories.len] - if(!container_category) - failures += "Invalid container categories [json_encode(recipe.container_categories)] on [recipe.type]" + if(!recipe_is_valid) QDEL_LIST(container.contents) // clean up prematurely container.reagents.clear_reagents() continue - var/cooking_temperature = T20C - if(recipe.minimum_temperature > 0) - cooking_temperature = max(cooking_temperature, recipe.minimum_temperature) - if(recipe.maximum_temperature < INFINITY) - cooking_temperature = min(cooking_temperature, recipe.maximum_temperature) - var/decl/recipe/new_recipe = select_recipe(container_category, container, cooking_temperature) - if(new_recipe && new_recipe != recipe) - failures += "Recipe [recipe.type]'s ingredients selected [new_recipe.type] instead!" - else if(!new_recipe) - failures += "Recipe [recipe.type]'s ingredients selected NULL instead!" - else - recipe.produce_result(container) - if(ispath(recipe.result, /decl/material) && !container.reagents.has_reagent(recipe.result)) - failures += "Recipe [recipe.type] did not produce the expected output [recipe.result]" - if(ispath(recipe.result, /atom/movable) && !locate(recipe.result) in container) - failures += "Recipe [recipe.type] did not produce the expected output [recipe.result]" - - QDEL_LIST(container.contents) // clean up - container.reagents.clear_reagents() + + // continue with validation + var/cooking_temperature = T20C + if(recipe.minimum_temperature > 0) + cooking_temperature = max(cooking_temperature, recipe.minimum_temperature) + if(recipe.maximum_temperature < INFINITY) + cooking_temperature = min(cooking_temperature, recipe.maximum_temperature) + var/decl/recipe/new_recipe = select_recipe(container_category, container, cooking_temperature) + if(new_recipe && new_recipe != recipe) + failures += "Recipe [recipe.type]'s ingredients selected [new_recipe.type] instead!" + else if(!new_recipe) + failures += "Recipe [recipe.type]'s ingredients selected NULL instead!" + else + recipe.produce_result(container) + if(ispath(recipe.result, /decl/material) && !container.reagents.has_reagent(recipe.result)) + failures += "Recipe [recipe.type] did not produce the expected output [recipe.result]" + if(ispath(recipe.result, /atom/movable) && !locate(recipe.result) in container) + failures += "Recipe [recipe.type] did not produce the expected output [recipe.result]" + + QDEL_LIST(container.contents) // clean up + container.reagents.clear_reagents() if(length(failures)) fail("Some recipes failed to produce the right result:\n\t-[jointext(failures, "\n\t-")]") From 7680cd5eeafccdd56017a1ff57fccaa7b5eff390 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 20:06:43 -0500 Subject: [PATCH 021/512] Fix conflict between waffle and plain cake recipe --- code/modules/food/cooking/recipes/recipe_fried.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/food/cooking/recipes/recipe_fried.dm b/code/modules/food/cooking/recipes/recipe_fried.dm index 784b619335ed..c08b6abfe1f8 100644 --- a/code/modules/food/cooking/recipes/recipe_fried.dm +++ b/code/modules/food/cooking/recipes/recipe_fried.dm @@ -8,7 +8,8 @@ ) /decl/recipe/fried/waffles - reagents = list(/decl/material/liquid/nutriment/batter/cakebatter = 20) + // salt is to disambiguate from vanilla cake + reagents = list(/decl/material/liquid/nutriment/batter/cakebatter = 20, /decl/material/solid/sodiumchloride = 1) result = /obj/item/food/waffles completion_message = "The waffles firm up and brown as the batter is cooked through." From 3b8cea509e92e14d4190e33f00aaeeb48d7a489b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 23:58:01 -0500 Subject: [PATCH 022/512] Fix shields becoming frames when damaged --- code/modules/shieldgen/emergency_shield.dm | 81 ++++++++----------- code/modules/shieldgen/shieldwallgen.dm | 92 ++++++++++------------ 2 files changed, 77 insertions(+), 96 deletions(-) diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index 125228346633..d85080893f9a 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -7,9 +7,29 @@ opacity = FALSE anchored = TRUE max_health = 200 + frame_type = null + construct_state = /decl/machine_construction/noninteractive var/shield_generate_power = 7500 //how much power we use when regenerating var/shield_idle_power = 1500 //how much power we use when just being sustained. +/obj/machinery/shield/take_damage(amount, damtype, silent) + if(amount <= 0) + return + if(damtype != BRUTE && damtype != BURN && damtype != ELECTROCUTE) + return + if(!silent) + playsound(src.loc, 'sound/effects/EMPulse.ogg', 75, TRUE) + current_health -= amount + set_opacity(TRUE) + check_failure() + if(!QDELETED(src)) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_opacity), FALSE), 2 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + +// This should never be damaged via anything but the shield's health dropping. +/obj/machinery/shield/dismantle() + check_failure() + return QDELING(src) // return true if deleted, false otherwise + /obj/machinery/shield/malfai name = "emergency forcefield" desc = "A weak forcefield which seems to be projected by the emergency atmosphere containment field." @@ -21,7 +41,7 @@ /obj/machinery/shield/proc/check_failure() if (current_health <= 0) - visible_message("\The [src] dissipates!") + visible_message(SPAN_NOTICE("\The [src] dissipates!")) qdel(src) return @@ -31,40 +51,16 @@ update_nearby_tiles(need_rebuild=1) /obj/machinery/shield/Destroy() - set_opacity(0) - set_density(0) + set_opacity(FALSE) + set_density(FALSE) update_nearby_tiles() . = ..() /obj/machinery/shield/CanPass(atom/movable/mover, turf/target, height, air_group) + // blocks air, normal behavior for everything else if(!height || air_group) return 0 else return ..() -/obj/machinery/shield/attackby(obj/item/W, mob/user) - if(!istype(W)) return - - //Calculate damage - var/aforce = W.force - if(W.damtype == BRUTE || W.damtype == BURN) - current_health -= aforce - - //Play a fitting sound - playsound(src.loc, 'sound/effects/EMPulse.ogg', 75, 1) - - check_failure() - set_opacity(1) - spawn(20) if(!QDELETED(src)) set_opacity(0) - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - - ..() - -/obj/machinery/shield/bullet_act(var/obj/item/projectile/Proj) - current_health -= Proj.get_structure_damage() - ..() - check_failure() - set_opacity(1) - spawn(20) if(!QDELETED(src)) set_opacity(0) - /obj/machinery/shield/explosion_act(severity) . = ..() if(. && ((severity == 1 && prob(75)) || (severity == 2 && prob(50)) || (severity == 3 && prob(25)))) @@ -78,28 +74,21 @@ if(prob(50)) qdel(src) -/obj/machinery/shield/hitby(AM, var/datum/thrownthing/TT) +/obj/machinery/shield/hitby(atom/movable/hitter, var/datum/thrownthing/thrownthing) . = ..() if(.) //Let everyone know we've been hit! - visible_message(SPAN_DANGER("\The [src] was hit by \the [AM].")) + visible_message(SPAN_DANGER("\The [src] was hit by \the [hitter].")) //Super realistic, resource-intensive, real-time damage calculations. var/tforce = 0 - if(ismob(AM)) // All mobs have a multiplier and a size according to mob_defines.dm - var/mob/I = AM - tforce = I.mob_size * (TT.speed/THROWFORCE_SPEED_DIVISOR) + if(ismob(hitter)) // All mobs have a multiplier and a size according to mob_defines.dm + var/mob/mob_hitter = hitter + tforce = mob_hitter.mob_size * (thrownthing.speed/THROWFORCE_SPEED_DIVISOR) else - var/obj/O = AM - tforce = O.throwforce * (TT.speed/THROWFORCE_SPEED_DIVISOR) - current_health -= tforce - //This seemed to be the best sound for hitting a force field. - playsound(src.loc, 'sound/effects/EMPulse.ogg', 100, 1) - check_failure() - //The shield becomes dense to absorb the blow. Purely asthetic. - set_opacity(1) - spawn(20) - if(!QDELETED(src)) - set_opacity(0) + var/obj/obj_hitter = hitter + tforce = obj_hitter.throwforce * (thrownthing.speed/THROWFORCE_SPEED_DIVISOR) + if(tforce > 0) + take_damage(tforce, BRUTE) /obj/machinery/shieldgen name = "Emergency shield projector" @@ -196,12 +185,12 @@ else check_delay-- +// todo: roll this into normal machinery damage stuff? maybe it only blows up if active when it's destroyed? /obj/machinery/shieldgen/proc/checkhp() if(current_health <= 30) src.malfunction = 1 if(current_health <= 0) - spawn(0) - explosion(get_turf(src.loc), 0, 0, 1, 0, 0, 0) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(explosion), get_turf(src), 0, 0, 1, 0, 0, 0), 0) qdel(src) update_icon() return diff --git a/code/modules/shieldgen/shieldwallgen.dm b/code/modules/shieldgen/shieldwallgen.dm index 1ee46b4635a5..4f91bdff485f 100644 --- a/code/modules/shieldgen/shieldwallgen.dm +++ b/code/modules/shieldgen/shieldwallgen.dm @@ -265,86 +265,78 @@ anchored = TRUE density = TRUE light_range = 3 - var/needs_power = 0 + frame_type = null + construct_state = /decl/machine_construction/noninteractive + var/needs_power = FALSE var/obj/machinery/shieldwallgen/gen_primary var/obj/machinery/shieldwallgen/gen_secondary var/power_usage = 800 //how much power it takes to sustain the shield var/generate_power_usage = 5000 //how much power it takes to start up the shield +/obj/machinery/shieldwall/proc/use_generator_power(amount) + if(!needs_power) + return + var/obj/machinery/shieldwallgen/G = pick(gen_primary, gen_secondary) // if we use power and still exist, we assume we have both generators + G.storedpower -= amount + +/obj/machinery/shieldwall/take_damage(amount, damtype, silent) + if(amount <= 0) + return + if(damtype != BRUTE && damtype != BURN && damtype != ELECTROCUTE) + return + . = ..() // mostly just plays sound effects on damage + use_generator_power(500 * amount) + +// This should never be deleted via anything but the generator running out of power. +/obj/machinery/shieldwall/dismantle() + return FALSE // nope! + /obj/machinery/shieldwall/Initialize(mapload, obj/machinery/shieldwallgen/A, obj/machinery/shieldwallgen/B) . = ..(mapload) update_nearby_tiles() gen_primary = A gen_secondary = B - if(A && B && A.active && B.active) - needs_power = 1 - if(prob(50)) - A.storedpower -= generate_power_usage - else - B.storedpower -= generate_power_usage + if(gen_primary?.active && gen_secondary?.active) + needs_power = TRUE + use_generator_power(generate_power_usage) else return INITIALIZE_HINT_QDEL /obj/machinery/shieldwall/Destroy() + gen_primary = null + gen_secondary = null update_nearby_tiles() . = ..() -/obj/machinery/shieldwall/attackby(var/obj/item/I, var/mob/user) - var/obj/machinery/shieldwallgen/G = prob(50) ? gen_primary : gen_secondary - G.storedpower -= I.force*2500 - user.visible_message("\The [user] hits \the [src] with \the [I]!") - user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - user.do_attack_animation(src) - playsound(loc, 'sound/weapons/smash.ogg', 75, 1) - /obj/machinery/shieldwall/Process() - if(needs_power) - if(isnull(gen_primary)||isnull(gen_secondary)) - qdel(src) - return - - if(!(gen_primary.active)||!(gen_secondary.active)) - qdel(src) - return - - var/obj/machinery/shieldwallgen/G = prob(50) ? gen_primary : gen_secondary - G.storedpower -= power_usage - - -/obj/machinery/shieldwall/bullet_act(var/obj/item/projectile/Proj) - if(needs_power) - var/obj/machinery/shieldwallgen/G = prob(50) ? gen_primary : gen_secondary - G.storedpower -= 400 * Proj.get_structure_damage() - ..() - return + if(!needs_power) + return + if(QDELETED(gen_primary) || QDELETED(gen_secondary)) + qdel(src) + return + if(!gen_primary.active || !gen_secondary.active) + qdel(src) + return + use_generator_power(power_usage) /obj/machinery/shieldwall/explosion_act(severity) SHOULD_CALL_PARENT(FALSE) if(!needs_power) return - var/obj/machinery/shieldwallgen/G = prob(50) ? gen_primary : gen_secondary - switch(severity) - if(1) - G.storedpower -= rand(30000, min(G.storedpower, 60000)) - if(2) - G.storedpower -= rand(15000, min(G.storedpower, 30000)) - if(3) - G.storedpower -= rand(5000, min(G.storedpower, 15000)) + take_damage(100/severity, BRUTE, TRUE) // will drain power according to damage /obj/machinery/shieldwall/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - + if(!height || air_group || !density) + return TRUE if(istype(mover) && mover.checkpass(PASS_FLAG_GLASS)) return prob(20) - else - if (istype(mover, /obj/item/projectile)) - return prob(10) - else - return !src.density + if (istype(mover, /obj/item/projectile)) + return prob(10) + return FALSE /obj/machinery/shieldwallgen/online anchored = TRUE - active = 1 + active = TRUE /obj/machinery/shieldwallgen/online/Initialize() storedpower = max_stored_power From 2ce565c714872bff00ef40526f3ddf00bdf4c3a5 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 18 Feb 2025 16:22:28 +1100 Subject: [PATCH 023/512] W -> used_item, inserting, removing, various WT -> welder --- code/__defines/fluids.dm | 8 +- code/_onclick/adjacent.dm | 4 +- code/_onclick/item_attack.dm | 4 +- code/datums/ai/beast.dm | 4 +- .../assembly/assembly_interaction.dm | 54 ++++----- code/datums/extensions/lockable.dm | 6 +- code/datums/mind/mind.dm | 4 +- code/datums/outfits/outfit.dm | 22 ++-- code/datums/storage/_storage.dm | 104 ++++++++--------- code/datums/storage/_storage_ui.dm | 10 +- code/datums/storage/subtypes_backpack.dm | 6 +- code/datums/storage/subtypes_bag.dm | 10 +- code/datums/storage/subtypes_box.dm | 12 +- code/datums/storage/subtypes_excavation.dm | 2 +- code/datums/storage/subtypes_misc.dm | 6 +- code/datums/storage/subtypes_pills.dm | 10 +- code/datums/storage/subtypes_secure.dm | 2 +- code/datums/storage/subtypes_sheets.dm | 14 +-- code/datums/storage/subtypes_slides.dm | 8 +- code/datums/storage/subtypes_tray.dm | 8 +- code/datums/storage/subtypes_wallet.dm | 16 +-- .../machine_construction/frame.dm | 6 +- .../machine_construction/pipe.dm | 8 +- .../_machines_base/machinery_damage.dm | 10 +- .../_machines_base/stock_parts/access_lock.dm | 4 +- .../_machines_base/stock_parts/card_reader.dm | 4 +- .../_machines_base/stock_parts/item_holder.dm | 6 +- .../stock_parts/network_lock.dm | 6 +- code/game/machinery/ai_slipper.dm | 2 +- code/game/machinery/alarm.dm | 2 +- code/game/machinery/atmoalter/canister.dm | 10 +- code/game/machinery/buttons.dm | 4 +- code/game/machinery/camera/camera.dm | 6 +- code/game/machinery/cell_charger.dm | 4 +- code/game/machinery/centrifuge.dm | 4 +- code/game/machinery/computer/ai_core.dm | 6 +- code/game/machinery/cryopod.dm | 8 +- code/game/machinery/deployable.dm | 12 +- code/game/machinery/doors/_door.dm | 8 +- code/game/machinery/doors/airlock.dm | 10 +- code/game/machinery/doors/braces.dm | 14 +-- code/game/machinery/doors/double.dm | 8 +- code/game/machinery/doors/firedoor.dm | 10 +- .../airlock_docking_controller.dm | 6 +- code/game/machinery/flasher.dm | 10 +- code/game/machinery/floor_light.dm | 16 +-- code/game/machinery/floorlayer.dm | 14 +-- code/game/machinery/igniter.dm | 4 +- code/game/machinery/jukebox.dm | 6 +- code/game/machinery/kitchen/gibber.dm | 10 +- code/game/machinery/newscaster.dm | 6 +- code/game/machinery/nuclear_bomb.dm | 16 +-- code/game/machinery/oxygen_pump.dm | 12 +- code/game/machinery/pipe/construction.dm | 8 +- code/game/machinery/pipe/pipelayer.dm | 20 ++-- code/game/machinery/self_destruct.dm | 16 +-- code/game/machinery/singularitybeacon.dm | 4 +- code/game/machinery/supplybeacon.dm | 4 +- code/game/machinery/teleporter.dm | 2 +- code/game/machinery/turret_control.dm | 4 +- code/game/machinery/turrets/_turrets.dm | 10 +- code/game/machinery/turrets/turret_ammo.dm | 12 +- code/game/machinery/vending/_vending.dm | 30 ++--- code/game/machinery/wall_frames.dm | 16 +-- code/game/machinery/washing_machine.dm | 30 ++--- .../effects/decals/Cleanable/humans.dm | 4 +- code/game/objects/effects/gateway.dm | 8 +- code/game/objects/effects/misc.dm | 18 +-- code/game/objects/effects/spiders.dm | 20 ++-- code/game/objects/items/__item.dm | 6 +- code/game/objects/items/blades/axe.dm | 4 +- code/game/objects/items/bodybag.dm | 4 +- code/game/objects/items/books/_book.dm | 8 +- code/game/objects/items/candelabra.dm | 2 +- code/game/objects/items/devices/boombox.dm | 18 +-- code/game/objects/items/devices/hacktool.dm | 4 +- .../game/objects/items/devices/holowarrant.dm | 10 +- code/game/objects/items/devices/inducer.dm | 4 +- .../objects/items/devices/lightreplacer.dm | 10 +- .../objects/items/devices/paint_sprayer.dm | 34 +++--- .../items/devices/radio/encryptionkey.dm | 10 +- .../game/objects/items/devices/radio/radio.dm | 10 +- code/game/objects/items/devices/spy_bug.dm | 18 ++- .../objects/items/devices/suit_cooling.dm | 10 +- code/game/objects/items/devices/tvcamera.dm | 20 ++-- code/game/objects/items/glassjar.dm | 8 +- code/game/objects/items/latexballoon.dm | 4 +- code/game/objects/items/rescuebag.dm | 26 ++--- code/game/objects/items/robot/robot_frame.dm | 38 +++---- code/game/objects/items/robot/robot_parts.dm | 32 +++--- code/game/objects/items/rock.dm | 4 +- code/game/objects/items/stacks/rods.dm | 14 +-- code/game/objects/items/stacks/stack.dm | 6 +- code/game/objects/items/stools.dm | 4 +- code/game/objects/items/tools/wrench.dm | 4 +- code/game/objects/items/weapons/RCD.dm | 10 +- code/game/objects/items/weapons/RPD.dm | 14 +-- code/game/objects/items/weapons/RSF.dm | 6 +- code/game/objects/items/weapons/autopsy.dm | 18 +-- code/game/objects/items/weapons/cane.dm | 11 +- code/game/objects/items/weapons/defib.dm | 14 +-- .../objects/items/weapons/flamethrower.dm | 22 ++-- .../objects/items/weapons/gift_wrappaper.dm | 4 +- .../items/weapons/grenades/chem_grenade.dm | 24 ++-- .../objects/items/weapons/grenades/grenade.dm | 4 +- code/game/objects/items/weapons/locator.dm | 20 ++-- .../objects/items/weapons/material/ashtray.dm | 14 +-- .../objects/items/weapons/material/shards.dm | 12 +- .../objects/items/weapons/material/stick.dm | 14 +-- .../objects/items/weapons/secrets_disk.dm | 6 +- .../items/weapons/shields/shield_riot.dm | 6 +- .../objects/items/weapons/storage/backpack.dm | 10 +- .../objects/items/weapons/storage/bags.dm | 6 +- .../objects/items/weapons/storage/bible.dm | 2 +- .../items/weapons/storage/fancy/vials.dm | 2 +- .../objects/items/weapons/storage/lockbox.dm | 10 +- .../objects/items/weapons/storage/matches.dm | 12 +- .../objects/items/weapons/storage/secure.dm | 4 +- .../items/weapons/storage/wall_mirror.dm | 11 +- code/game/objects/items/weapons/stunbaton.dm | 2 +- .../game/objects/items/weapons/tanks/tanks.dm | 36 +++--- code/game/objects/items/weapons/tape.dm | 18 +-- code/game/objects/items/weapons/weaponry.dm | 4 +- .../objects/items/welding/electric_welder.dm | 2 +- .../objects/items/welding/weldbackpack.dm | 2 +- .../game/objects/items/welding/weldingtool.dm | 16 +-- code/game/objects/structures/__structure.dm | 18 +-- .../objects/structures/_structure_icon.dm | 8 +- code/game/objects/structures/barricade.dm | 6 +- .../objects/structures/chairs/wheelchair.dm | 10 +- code/game/objects/structures/coathanger.dm | 12 +- code/game/objects/structures/compost.dm | 18 +-- .../crates_lockers/closets/__closet.dm | 18 +-- .../crates_lockers/closets/coffin.dm | 4 +- .../closets/secure/_secure_closets.dm | 2 +- .../structures/crates_lockers/crates.dm | 16 +-- .../structures/crates_lockers/largecrate.dm | 4 +- code/game/objects/structures/curtains.dm | 8 +- .../objects/structures/defensive_barrier.dm | 10 +- code/game/objects/structures/displaycase.dm | 14 +-- code/game/objects/structures/door_assembly.dm | 38 +++---- code/game/objects/structures/drain.dm | 4 +- code/game/objects/structures/drying_rack.dm | 10 +- code/game/objects/structures/fishtanks.dm | 6 +- code/game/objects/structures/fitness.dm | 4 +- code/game/objects/structures/flaps.dm | 6 +- code/game/objects/structures/fuel_port.dm | 8 +- code/game/objects/structures/girders.dm | 30 ++--- code/game/objects/structures/grille.dm | 18 +-- code/game/objects/structures/holosigns.dm | 4 +- code/game/objects/structures/inflatable.dm | 8 +- code/game/objects/structures/iv_drip.dm | 10 +- code/game/objects/structures/lattice.dm | 4 +- code/game/objects/structures/quicksand.dm | 4 +- code/game/objects/structures/railing.dm | 18 +-- code/game/objects/structures/signs.dm | 6 +- code/game/objects/structures/signs/diploma.dm | 6 +- code/game/objects/structures/skele_stand.dm | 14 +-- code/game/objects/structures/tables.dm | 46 ++++---- code/game/objects/structures/wall_frame.dm | 18 +-- code/game/objects/structures/wall_sconce.dm | 16 +-- .../objects/structures/wallframe_spawner.dm | 8 +- .../objects/structures/windoor_assembly.dm | 18 +-- code/game/objects/structures/window.dm | 26 ++--- .../game/objects/structures/window_spawner.dm | 8 +- code/game/turfs/floors/floor_acts.dm | 6 +- code/game/turfs/floors/floor_layers.dm | 4 +- code/game/turfs/turf.dm | 48 ++++---- code/game/turfs/turf_changing.dm | 42 +++---- code/game/turfs/walls/_wall.dm | 14 +-- code/game/turfs/walls/wall_attacks.dm | 106 +++++++++--------- code/game/turfs/walls/wall_icon.dm | 22 ++-- code/game/turfs/walls/wall_natural.dm | 24 ++-- .../game/turfs/walls/wall_natural_xenoarch.dm | 6 +- code/game/turfs/walls/wall_wattle.dm | 6 +- code/modules/ZAS/ConnectionManager.dm | 61 +++++----- code/modules/admin/verbs/mapping.dm | 4 +- code/modules/admin/verbs/randomverbs.dm | 4 +- code/modules/assembly/holder.dm | 4 +- .../components/unary/vent_pump.dm | 14 +-- .../components/unary/vent_scrubber.dm | 12 +- code/modules/augment/active/circuit.dm | 10 +- code/modules/augment/active/cyberbrain.dm | 4 +- code/modules/augment/augment.dm | 4 +- code/modules/awaymissions/gateway.dm | 8 +- code/modules/blob/blob.dm | 20 ++-- code/modules/butchery/butchery_hook.dm | 12 +- code/modules/butchery/butchery_products.dm | 6 +- .../antagonism/01_candidacy.dm | 6 +- .../preference_setup/antagonism/02_setup.dm | 6 +- .../preference_setup/background/01_species.dm | 4 +- .../background/02_background.dm | 4 +- .../background/03_language.dm | 4 +- .../controls/01_keybindings.dm | 4 +- .../preference_setup/general/01_basic.dm | 12 +- .../preference_setup/general/02_body.dm | 16 +-- .../preference_setup/general/03_traits.dm | 4 +- .../preference_setup/general/04_equipment.dm | 16 +-- .../preference_setup/general/05_flavor.dm | 24 ++-- .../client/preference_setup/global/01_ui.dm | 22 ++-- .../preference_setup/global/02_prefixes.dm | 4 +- .../client/preference_setup/global/03_pai.dm | 2 +- .../client/preference_setup/global/04_ooc.dm | 4 +- .../preference_setup/global/05_settings.dm | 10 +- .../preference_setup/loadout/loadout.dm | 6 +- .../preference_setup/occupation/occupation.dm | 20 ++-- .../preference_setup/preference_setup.dm | 20 ++-- code/modules/client/preferences_persist.dm | 14 +-- code/modules/clothing/head/misc_special.dm | 10 +- code/modules/clothing/masks/smokable.dm | 32 +++--- code/modules/clothing/spacesuits/breaches.dm | 22 ++-- .../spacesuits/rig/modules/modules.dm | 18 +-- .../spacesuits/rig/modules/utility.dm | 14 +-- .../clothing/spacesuits/rig/rig_attackby.dm | 54 ++++----- code/modules/clothing/spacesuits/void/void.dm | 28 ++--- code/modules/codex/codex_cataloguer.dm | 10 +- .../crafting/pottery/pottery_moulds.dm | 10 +- .../crafting/slapcrafting/_crafting_holder.dm | 14 +-- .../working/textiles/twisting_bench.dm | 6 +- .../microscope/_forensic_machine.dm | 14 +-- code/modules/detectivework/tools/rag.dm | 8 +- code/modules/economy/worth_cash.dm | 26 ++--- code/modules/events/brand_intelligence.dm | 16 +-- code/modules/events/meteors.dm | 4 +- code/modules/events/wallrot.dm | 4 +- code/modules/events/wormholes.dm | 6 +- .../fabrication/fabricator_bioprinter.dm | 8 +- code/modules/fabrication/recycler.dm | 18 +-- code/modules/fishing/fishing_rod.dm | 12 +- code/modules/food/assembled.dm | 40 +++---- .../cooking_vessels/_cooking_vessel.dm | 12 +- code/modules/food/plates/_plate.dm | 4 +- code/modules/food/plates/plate_tray.dm | 26 ++--- .../goals/definitions/department_clerical.dm | 6 +- code/modules/holodeck/HolodeckObjects.dm | 8 +- code/modules/hydroponics/grown.dm | 22 ++-- code/modules/hydroponics/grown_inedible.dm | 6 +- code/modules/hydroponics/seed_machines.dm | 26 ++--- .../hydroponics/spreading/spreading.dm | 10 +- .../random_exoplanet/planetoid_data.dm | 4 +- code/modules/materials/_material_stack.dm | 30 ++--- code/modules/materials/material_debris.dm | 6 +- .../materials/material_stack_animal.dm | 8 +- code/modules/materials/materials_ore.dm | 6 +- code/modules/mechs/components/_components.dm | 10 +- code/modules/mechs/components/frame.dm | 8 +- code/modules/mechs/equipment/utility.dm | 4 +- code/modules/mechs/mech_wreckage.dm | 18 +-- code/modules/mining/abandonedcrates.dm | 4 +- code/modules/mining/mine_items.dm | 2 +- code/modules/mining/ore_box.dm | 18 +-- code/modules/mob/grab/grab_object.dm | 4 +- code/modules/mob/grab/normal/grab_normal.dm | 30 ++--- code/modules/mob/inventory.dm | 90 +++++++-------- .../modules/mob/living/human/human_defense.dm | 16 +-- code/modules/mob/living/human/human_organs.dm | 6 +- code/modules/mob/living/human/human_verbs.dm | 12 +- code/modules/mob/living/inventory.dm | 6 +- code/modules/mob/living/silicon/ai/ai.dm | 12 +- code/modules/mob/living/silicon/pai/pai.dm | 16 +-- .../mob/living/silicon/robot/drone/drone.dm | 10 +- .../living/silicon/robot/drone/drone_items.dm | 29 ++--- .../mob/living/silicon/robot/inventory.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 76 ++++++------- code/modules/mob/living/silicon/silicon.dm | 14 +-- .../hostile/giant_spiders/ai_nurse.dm | 4 +- code/modules/mob/transform_procs.dm | 24 ++-- code/modules/mob_holder/_holder.dm | 4 +- .../programs/security/digitalwarrant.dm | 44 ++++---- .../modular_computers/hardware/_hardware.dm | 4 +- .../modular_computers/hardware/ai_slot.dm | 10 +- .../modular_computers/hardware/card_slot.dm | 2 +- .../hardware/charge_stick_slot.dm | 2 +- .../modular_computers/hardware/disk_slot.dm | 2 +- .../modular_computers/hardware/drive_slot.dm | 2 +- .../hardware/nano_printer.dm | 18 +-- .../hardware/scanners/scanner.dm | 4 +- code/modules/multiz/zmimic/mimic_movable.dm | 10 +- .../organs/external/_external_damage.dm | 18 +-- code/modules/organs/external/diagnostics.dm | 20 ++-- code/modules/organs/internal/cell.dm | 12 +- code/modules/organs/internal/heart.dm | 12 +- code/modules/overmap/contacts/_contacts.dm | 8 +- code/modules/overmap/ftl_shunt/core.dm | 4 +- .../overmap/internet/internet_uplink.dm | 8 +- code/modules/overmap/sectors.dm | 4 +- code/modules/overmap/ships/computers/ship.dm | 6 +- code/modules/paperwork/clipboard.dm | 14 +-- code/modules/paperwork/folders.dm | 12 +- code/modules/paperwork/handlabeler.dm | 14 +-- code/modules/paperwork/paper_bundle.dm | 24 ++-- code/modules/paperwork/papershredder.dm | 6 +- code/modules/paperwork/printer.dm | 12 +- code/modules/persistence/graffiti.dm | 4 +- .../persistence/persistence_datum_graffiti.dm | 2 +- code/modules/posters/_poster.dm | 28 ++--- code/modules/power/apc.dm | 4 +- code/modules/power/batteryrack.dm | 10 +- code/modules/power/breaker_box.dm | 4 +- code/modules/power/fission/core.dm | 12 +- code/modules/power/fission/core_control.dm | 4 +- code/modules/power/fusion/core/_core.dm | 6 +- .../fusion/fuel_injector/fuel_injector.dm | 16 +-- .../modules/power/fusion/gyrotron/gyrotron.dm | 4 +- code/modules/power/generator.dm | 4 +- code/modules/power/lighting.dm | 24 ++-- code/modules/power/power.dm | 6 +- code/modules/power/singularity/collector.dm | 14 +-- code/modules/power/singularity/emitter.dm | 18 +-- .../power/singularity/field_generator.dm | 16 +-- code/modules/power/singularity/generator.dm | 4 +- .../particle_accelerator.dm | 12 +- code/modules/power/smes.dm | 6 +- code/modules/power/smes_construction.dm | 6 +- code/modules/power/solar.dm | 22 ++-- code/modules/power/stirling.dm | 14 +-- code/modules/power/terminal.dm | 4 +- code/modules/power/tracker.dm | 4 +- code/modules/projectiles/ammunition.dm | 10 +- .../projectiles/guns/energy/capacitor.dm | 16 +-- .../guns/launcher/bows/bow_interaction.dm | 8 +- .../guns/launcher/bows/crossbow_powered.dm | 28 ++--- .../projectiles/guns/launcher/money_cannon.dm | 6 +- .../projectiles/guns/launcher/pneumatic.dm | 10 +- .../projectiles/guns/projectile/revolver.dm | 4 +- code/modules/projectiles/secure.dm | 6 +- .../dungeon/winding_dungeon_verb.dm | 4 +- .../modules/reagents/chems/chems_medicines.dm | 6 +- .../condiments/__condiment.dm | 4 +- .../drinkingglass/drinkingglass.dm | 4 +- .../reagent_containers/drinks/bottle.dm | 10 +- .../food/baking/leavened_dough.dm | 4 +- .../reagent_containers/food/canned/_canned.dm | 10 +- .../reagents/reagent_containers/food/eggs.dm | 6 +- .../reagent_containers/food/sandwich.dm | 26 ++--- .../reagents/reagent_containers/hypospray.dm | 6 +- code/modules/reagents/reagent_dispenser.dm | 26 ++--- .../recycling/disposal-construction.dm | 6 +- code/modules/recycling/disposal.dm | 6 +- code/modules/recycling/disposalpipe.dm | 6 +- code/modules/recycling/sortingmachinery.dm | 6 +- code/modules/recycling/wrapped_package.dm | 12 +- code/modules/sealant_gun/sealant_gun.dm | 6 +- .../security_levels/keycard_authentication.dm | 8 +- code/modules/shieldgen/emergency_shield.dm | 22 ++-- code/modules/shieldgen/shieldwallgen.dm | 6 +- code/modules/shuttles/shuttle_emergency.dm | 4 +- code/modules/surgery/generic.dm | 16 +-- code/modules/surgery/suture_wounds.dm | 22 ++-- code/modules/vehicles/bike.dm | 12 +- code/modules/vehicles/cargo_train.dm | 12 +- code/modules/vehicles/vehicle.dm | 20 ++-- .../xenoarcheaology/artifacts/artifact.dm | 6 +- .../artifacts/standalone/replicator.dm | 8 +- .../finds/find_types/fossils.dm | 14 +-- .../finds/find_types/statuette.dm | 8 +- .../xenoarcheaology/finds/strange_rock.dm | 6 +- code/unit_tests/override_tests.dm | 16 +-- maps/away/errant_pisces/errant_pisces.dm | 16 +-- maps/away/magshield/magshield.dm | 12 +- maps/away/mobius_rift/mobius_rift.dm | 26 ++--- .../datacapsule/datacapsule.dm | 4 +- mods/content/matchmaking/relations.dm | 6 +- .../psionics/complexus/complexus_process.dm | 10 +- .../system/psionics/faculties/redaction.dm | 12 +- mods/content/shackles/laws_pref.dm | 6 +- .../endgame_cascade/cascade_blob.dm | 10 +- .../supermatter/machinery/supermatter.dm | 20 ++-- mods/content/xenobiology/slime/_slime.dm | 6 +- mods/gamemodes/cult/cultify/turf.dm | 6 +- mods/gamemodes/cult/ghosts.dm | 16 +-- mods/gamemodes/cult/structures.dm | 4 +- mods/gamemodes/heist/special_role.dm | 6 +- .../drakes/drake_abilities_friendly.dm | 8 +- 374 files changed, 2309 insertions(+), 2313 deletions(-) diff --git a/code/__defines/fluids.dm b/code/__defines/fluids.dm index 96ebc2a93398..926a89950e37 100644 --- a/code/__defines/fluids.dm +++ b/code/__defines/fluids.dm @@ -40,11 +40,11 @@ if(!QDELETED(TURF) && TURF._fluid_turf_is_active) { \ #define UPDATE_FLUID_BLOCKED_DIRS(TURF) \ if(isnull(TURF.fluid_blocked_dirs)) { \ TURF.fluid_blocked_dirs = 0; \ - for(var/obj/structure/window/W in TURF) { \ - if(W.density) TURF.fluid_blocked_dirs |= W.dir; \ + for(var/obj/structure/window/window in TURF) { \ + if(window.density) TURF.fluid_blocked_dirs |= window.dir; \ } \ - for(var/obj/machinery/door/window/D in TURF) { \ - if(D.density) TURF.fluid_blocked_dirs |= D.dir; \ + for(var/obj/machinery/door/window/windoor in TURF) { \ + if(windoor.density) TURF.fluid_blocked_dirs |= windoor.dir; \ } \ } diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm index 328becddbbfe..8aea97cf30db 100644 --- a/code/_onclick/adjacent.dm +++ b/code/_onclick/adjacent.dm @@ -144,8 +144,8 @@ Quick adjacency (to turf): if(O.atom_flags & ATOM_FLAG_CHECKS_BORDER) // windows have throwpass but are on border, check them first if( O.dir & target_dir || O.dir&(O.dir-1) ) // full tile windows are just diagonals mechanically - var/obj/structure/window/W = target_atom - if(istype(W) && W.is_fulltile()) //exception for breaking full tile windows on top of single pane windows + var/obj/structure/window/window = target_atom + if(istype(window) && window.is_fulltile()) //exception for breaking full tile windows on top of single pane windows return 1 if(target_atom && (target_atom.atom_flags & ATOM_FLAG_ADJACENT_EXCEPTION)) // exception for atoms that should always be reachable return 1 diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index f60ad5c1ca4a..5634e0385d39 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -48,10 +48,10 @@ avoid code duplication. This includes items that may sometimes act as a standard return FALSE -/atom/movable/attackby(obj/item/W, mob/user) +/atom/movable/attackby(used_item, mob/user) . = ..() if(!.) - return bash(W,user) + return bash(used_item,user) // Return TRUE if further actions (afterattack, etc) should be prevented, FALSE if they can proceed. /atom/movable/proc/bash(obj/item/weapon, mob/user) diff --git a/code/datums/ai/beast.dm b/code/datums/ai/beast.dm index 9090698f55aa..f730e939e913 100644 --- a/code/datums/ai/beast.dm +++ b/code/datums/ai/beast.dm @@ -41,8 +41,8 @@ if(!length(.)) if(LAZYLEN(prey)) . = list() - for(var/weakref/W in prey) - var/mob/M = W.resolve() + for(var/weakref/prey_ref in prey) + var/mob/M = prey_ref.resolve() if(M) . |= M else if(body.get_nutrition() < body.get_max_nutrition() * 0.75) //time to look for some food diff --git a/code/datums/extensions/assembly/assembly_interaction.dm b/code/datums/extensions/assembly/assembly_interaction.dm index a4c4c8b2f920..7987ee9f8fd6 100644 --- a/code/datums/extensions/assembly/assembly_interaction.dm +++ b/code/datums/extensions/assembly/assembly_interaction.dm @@ -1,5 +1,5 @@ -/datum/extension/assembly/proc/attackby(var/obj/item/W, var/mob/user) - if(IS_WRENCH(W)) +/datum/extension/assembly/proc/attackby(var/obj/item/used_item, var/mob/user) + if(IS_WRENCH(used_item)) if(parts.len) to_chat(user, "Remove all components from \the [holder] before disassembling it.") return TRUE @@ -9,10 +9,10 @@ qdel(holder) return TRUE - if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W - if(!WT.isOn()) - to_chat(user, "\The [W] is off.") + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item + if(!welder.isOn()) + to_chat(user, "\The [used_item] is off.") return TRUE if(!damage) @@ -20,12 +20,12 @@ return TRUE to_chat(user, "You begin repairing damage to \the [holder]...") - if(WT.weld(round(damage/75)) && do_after(user, damage/10)) + if(welder.weld(round(damage/75)) && do_after(user, damage/10)) damage = 0 to_chat(user, "You repair \the [holder].") return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) if(!parts.len) to_chat(user, "This device doesn't have any components installed.") return TRUE @@ -47,24 +47,24 @@ uninstall_component(user, H) return TRUE - if(istype(W, /obj/item/card/id)) // ID Card, try to insert it. + if(istype(used_item, /obj/item/card/id)) // ID Card, try to insert it. var/obj/item/stock_parts/computer/card_slot/card_slot = get_component(PART_CARD) if(!card_slot) - to_chat(user, SPAN_WARNING("You try to insert [W] into [holder], but it does not have an ID card slot installed.")) + to_chat(user, SPAN_WARNING("You try to insert [used_item] into [holder], but it does not have an ID card slot installed.")) return TRUE - card_slot.insert_id(W, user) + card_slot.insert_id(used_item, user) return TRUE - if(istype(W, /obj/item/charge_stick)) // Try to insert charge stick. + if(istype(used_item, /obj/item/charge_stick)) // Try to insert charge stick. var/obj/item/stock_parts/computer/charge_stick_slot/mstick_slot = get_component(PART_MSTICK) if(!mstick_slot) - to_chat(user, SPAN_WARNING("You try to insert [W] into [holder], but it does not have a charge-stick slot installed.")) + to_chat(user, SPAN_WARNING("You try to insert [used_item] into [holder], but it does not have a charge-stick slot installed.")) return TRUE - mstick_slot.insert_stick(W, user) + mstick_slot.insert_stick(used_item, user) return TRUE - if(istype(W, PART_DRIVE)) // Portable HDD, try to insert it. - var/obj/item/stock_parts/computer/hard_drive/portable/I = W + if(istype(used_item, PART_DRIVE)) // Portable HDD, try to insert it. + var/obj/item/stock_parts/computer/hard_drive/portable/I = used_item var/obj/item/stock_parts/computer/drive_slot/drive_slot = get_component(PART_D_SLOT) if(!drive_slot) to_chat(user, SPAN_WARNING("You try to insert [I] into [holder], but it does not have a drive slot installed.")) @@ -72,8 +72,8 @@ drive_slot.insert_drive(I, user) return TRUE - if(istype(W, /obj/item/disk)) - var/obj/item/disk/disk = W + if(istype(used_item, /obj/item/disk)) + var/obj/item/disk/disk = used_item var/obj/item/stock_parts/computer/data_disk_drive/disk_drive = get_component(PART_DSKSLOT) if(!disk_drive) to_chat(user, SPAN_WARNING("You try to insert [disk] into [holder], but it does not have a disk slot installed.")) @@ -81,26 +81,26 @@ disk_drive.insert_disk(disk, user) return TRUE - if(istype(W, /obj/item/paper)) - var/obj/item/paper/paper = W + if(istype(used_item, /obj/item/paper)) + var/obj/item/paper/paper = used_item if(paper.info) var/obj/item/stock_parts/computer/scanner/scanner = get_component(PART_SCANNER) if(scanner) - scanner.attackby(user, W) + scanner.attackby(user, used_item) return TRUE - if(istype(W, /obj/item/paper) || istype(W, /obj/item/paper_bundle)) + if(istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/paper_bundle)) var/obj/item/stock_parts/computer/scanner/scanner = get_component(PART_SCANNER) if(scanner) - scanner.attackby(W, user) + scanner.attackby(used_item, user) return TRUE - if(istype(W, /obj/item/aicard)) + if(istype(used_item, /obj/item/aicard)) var/obj/item/stock_parts/computer/ai_slot/ai_slot = get_component(PART_AI) if(ai_slot) - ai_slot.attackby(W, user) + ai_slot.attackby(used_item, user) return TRUE - if(istype(W, /obj/item/stock_parts)) - return try_install_component(user, W) + if(istype(used_item, /obj/item/stock_parts)) + return try_install_component(user, used_item) return FALSE \ No newline at end of file diff --git a/code/datums/extensions/lockable.dm b/code/datums/extensions/lockable.dm index 095522d2f9b3..12fd928839ba 100644 --- a/code/datums/extensions/lockable.dm +++ b/code/datums/extensions/lockable.dm @@ -395,13 +395,13 @@ /** Called when a multitool is used on the holder to hack the device. */ -/datum/extension/lockable/proc/try_hack(obj/item/multitool/W, mob/user) +/datum/extension/lockable/proc/try_hack(obj/item/multitool/multitool, mob/user) //Don't do anything if the panel isn't opened, or if we're already hacking it. if(!open || l_hacking) return FALSE //Show a message to let the user know how likely this is to even succeed. - var/fail_chance = hack_fail_chance(W, user) + var/fail_chance = hack_fail_chance(multitool, user) var/skill_msg if(fail_chance >= 90) skill_msg = SPAN_WARNING("But, you struggle to make sense of this thing..") @@ -436,7 +436,7 @@ /** Returns a percent chance of the given user failing at hacking this lock. */ -/datum/extension/lockable/proc/hack_fail_chance(obj/item/multitool/W, mob/user) +/datum/extension/lockable/proc/hack_fail_chance(obj/item/multitool/multitool, mob/user) //In order to make the lock actually any use at all, make sure not just anybody with a multitool can open it. return user.skill_fail_chance(SKILL_DEVICES, 99, SKILL_MAX, 0.35) diff --git a/code/datums/mind/mind.dm b/code/datums/mind/mind.dm index 1ea040862ecc..584ca62c3bb9 100644 --- a/code/datums/mind/mind.dm +++ b/code/datums/mind/mind.dm @@ -432,8 +432,8 @@ else if (href_list["common"]) switch(href_list["common"]) if("undress") - for(var/obj/item/W in current) - current.drop_from_inventory(W) + for(var/obj/item/undressing in current) + current.drop_from_inventory(undressing) if("takeuplink") take_uplink() if("crystals") diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index c3728f48a2a5..0aa0c9ea9923 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -241,22 +241,22 @@ return if(OUTFIT_ADJUSTMENT_SKIP_ID_PDA & equip_adjustments) return - var/obj/item/card/id/W = new id_type(wearer) + var/obj/item/card/id/id_card = new id_type(wearer) if(id_desc) - W.desc = id_desc + id_card.desc = id_desc if(assignment) - W.assignment = assignment + id_card.assignment = assignment if(job) - W.position = job.title - LAZYDISTINCTADD(W.access, job.get_access()) - if(!W.detail_color) - W.detail_color = job.selection_color - W.update_icon() + id_card.position = job.title + LAZYDISTINCTADD(id_card.access, job.get_access()) + if(!id_card.detail_color) + id_card.detail_color = job.selection_color + id_card.update_icon() wearer.update_icon() - wearer.set_id_info(W) + wearer.set_id_info(id_card) equip_pda(wearer, id_pda_assignment || assignment, equip_adjustments) - if(wearer.equip_to_slot_or_store_or_drop(W, id_slot)) - return W + if(wearer.equip_to_slot_or_store_or_drop(id_card, id_slot)) + return id_card /decl/outfit/proc/equip_pda(var/mob/living/wearer, var/label_assignment, var/equip_adjustments) if(!pda_slot || !pda_type) diff --git a/code/datums/storage/_storage.dm b/code/datums/storage/_storage.dm index 07d0d0871521..dcd00f9f16a0 100644 --- a/code/datums/storage/_storage.dm +++ b/code/datums/storage/_storage.dm @@ -121,13 +121,13 @@ var/global/list/_test_storage_items = list() //This proc return 1 if the item can be picked up and 0 if it can't. //Set the stop_messages to stop it from printing messages -/datum/storage/proc/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params = null) - if(!istype(W)) return //Not an item +/datum/storage/proc/can_be_inserted(obj/item/inserting, mob/user, stop_messages = 0, click_params = null) + if(!istype(inserting)) return //Not an item - if(user && !user.canUnEquip(W)) + if(user && !user.canUnEquip(inserting)) return 0 - if(!holder || holder.loc == W) + if(!holder || holder.loc == inserting) return 0 //Means the item is already in the storage item if(storage_slots != null && length(get_contents()) >= storage_slots) @@ -135,51 +135,51 @@ var/global/list/_test_storage_items = list() to_chat(user, SPAN_WARNING("\The [holder] is full, make some space.")) return 0 //Storage item is full - if(W.anchored) + if(inserting.anchored) return 0 if(can_hold.len) - if(!is_type_in_list(W, can_hold)) - if(!stop_messages && ! istype(W, /obj/item/hand_labeler)) - to_chat(user, SPAN_WARNING("\The [holder] cannot hold \the [W].")) + if(!is_type_in_list(inserting, can_hold)) + if(!stop_messages && ! istype(inserting, /obj/item/hand_labeler)) + to_chat(user, SPAN_WARNING("\The [holder] cannot hold \the [inserting].")) return 0 - var/max_instances = can_hold[W.type] - if(max_instances && instances_of_type_in_list(W, get_contents()) >= max_instances) - if(!stop_messages && !istype(W, /obj/item/hand_labeler)) - to_chat(user, SPAN_WARNING("\The [holder] has no more space specifically for \the [W].")) + var/max_instances = can_hold[inserting.type] + if(max_instances && instances_of_type_in_list(inserting, get_contents()) >= max_instances) + if(!stop_messages && !istype(inserting, /obj/item/hand_labeler)) + to_chat(user, SPAN_WARNING("\The [holder] has no more space specifically for \the [inserting].")) return 0 //If attempting to lable the storage item, silently fail to allow it - if(istype(W, /obj/item/hand_labeler) && !user?.check_intent(I_FLAG_HELP)) + if(istype(inserting, /obj/item/hand_labeler) && !user?.check_intent(I_FLAG_HELP)) return FALSE //Prevent package wrapper from being inserted by default - if(istype(W, /obj/item/stack/package_wrap) && !user?.check_intent(I_FLAG_HELP)) + if(istype(inserting, /obj/item/stack/package_wrap) && !user?.check_intent(I_FLAG_HELP)) return FALSE // Don't allow insertion of unsafed compressed matter implants // Since they are sucking something up now, their afterattack will delete the storage - if(istype(W, /obj/item/implanter/compressed)) - var/obj/item/implanter/compressed/impr = W + if(istype(inserting, /obj/item/implanter/compressed)) + var/obj/item/implanter/compressed/impr = inserting if(!impr.safe) stop_messages = 1 return 0 - if(cant_hold.len && is_type_in_list(W, cant_hold)) + if(cant_hold.len && is_type_in_list(inserting, cant_hold)) if(!stop_messages) - to_chat(user, SPAN_WARNING("\The [holder] cannot hold \the [W].")) + to_chat(user, SPAN_WARNING("\The [holder] cannot hold \the [inserting].")) return 0 - if (max_w_class != null && W.w_class > max_w_class) + if (max_w_class != null && inserting.w_class > max_w_class) if(!stop_messages) - to_chat(user, SPAN_WARNING("\The [W] is too big for \the [holder].")) + to_chat(user, SPAN_WARNING("\The [inserting] is too big for \the [holder].")) return 0 - if(W.obj_flags & OBJ_FLAG_NO_STORAGE) + if(inserting.obj_flags & OBJ_FLAG_NO_STORAGE) if(!stop_messages) - to_chat(user, SPAN_WARNING("\The [W] cannot be placed in \the [holder].")) + to_chat(user, SPAN_WARNING("\The [inserting] cannot be placed in \the [holder].")) return 0 - var/total_storage_space = W.get_storage_cost() + storage_space_used() //Adds up the combined w_classes which will be in the storage item if the item is added to it. + var/total_storage_space = inserting.get_storage_cost() + storage_space_used() //Adds up the combined w_classes which will be in the storage item if the item is added to it. if(total_storage_space > max_storage_space) if(!stop_messages) to_chat(user, SPAN_WARNING("\The [holder] is too full, make some space.")) @@ -190,35 +190,35 @@ var/global/list/_test_storage_items = list() //This proc handles items being inserted. It does not perform any checks of whether an item can or can't be inserted. That's done by can_be_inserted() //The stop_warning parameter will stop the insertion message from being displayed. It is intended for cases where you are inserting multiple items at once, //such as when picking up all the items on a tile with one click. -/datum/storage/proc/handle_item_insertion(mob/user, obj/item/W, prevent_warning, skip_update, click_params) - if(!istype(W)) +/datum/storage/proc/handle_item_insertion(mob/user, obj/item/inserting, prevent_warning, skip_update, click_params) + if(!istype(inserting)) return FALSE - if(ismob(W.loc)) - var/mob/M = W.loc - if(!M.try_unequip(W)) + if(ismob(inserting.loc)) + var/mob/M = inserting.loc + if(!M.try_unequip(inserting)) return FALSE if(holder.reagents?.total_volume) - W.fluid_act(holder.reagents) - if(QDELETED(W)) + inserting.fluid_act(holder.reagents) + if(QDELETED(inserting)) return FALSE - W.forceMove(holder) - W.on_enter_storage(src) + inserting.forceMove(holder) + inserting.on_enter_storage(src) if(user) holder.add_fingerprint(user) if(!prevent_warning) for(var/mob/M in viewers(user, null)) if (M == user) - to_chat(user, SPAN_NOTICE("You put \the [W] into [holder].")) + to_chat(user, SPAN_NOTICE("You put \the [inserting] into [holder].")) else if (get_dist(holder, M) <= 1) //If someone is standing close enough, they can tell what it is... - M.show_message(SPAN_NOTICE("\The [user] puts [W] into [holder]."), VISIBLE_MESSAGE) - else if (W && W.w_class >= ITEM_SIZE_NORMAL) //Otherwise they can only see large or normal items from a distance... - M.show_message(SPAN_NOTICE("\The [user] puts [W] into [holder]."), VISIBLE_MESSAGE) + M.show_message(SPAN_NOTICE("\The [user] puts [inserting] into [holder]."), VISIBLE_MESSAGE) + else if (inserting && inserting.w_class >= ITEM_SIZE_NORMAL) //Otherwise they can only see large or normal items from a distance... + M.show_message(SPAN_NOTICE("\The [user] puts [inserting] into [holder]."), VISIBLE_MESSAGE) // Run this regardless of update flag, as it impacts our remaining storage space. consolidate_stacks() if(!skip_update) - update_ui_after_item_insertion(W, click_params) + update_ui_after_item_insertion(inserting, click_params) holder.storage_inserted() if(!skip_update) holder.update_icon() @@ -258,34 +258,34 @@ var/global/list/_test_storage_items = list() storage_ui?.on_post_remove() //Call this proc to handle the removal of an item from the storage item. The item will be moved to the atom sent as new_target -/datum/storage/proc/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) - if(!istype(W)) +/datum/storage/proc/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) + if(!istype(removing)) return FALSE new_location = new_location || get_turf(holder) - storage_ui?.on_pre_remove(W) + storage_ui?.on_pre_remove(removing) if(ismob(holder?.loc)) - W.dropped(user) + removing.dropped(user) if(ismob(new_location)) - W.hud_layerise() + removing.hud_layerise() else - W.reset_plane_and_layer() - W.forceMove(new_location) + removing.reset_plane_and_layer() + removing.forceMove(new_location) if(!skip_update) - update_ui_after_item_removal(W) - if(W.maptext) - W.maptext = "" - W.on_exit_storage(src) + update_ui_after_item_removal(removing) + if(removing.maptext) + removing.maptext = "" + removing.on_exit_storage(src) if(!skip_update && holder) holder.update_icon() return TRUE // Only do ui functions for now; the obj is responsible for anything else. -/datum/storage/proc/on_item_pre_deletion(obj/item/W) - storage_ui?.on_pre_remove(W) // Supposed to be able to handle null user. +/datum/storage/proc/on_item_pre_deletion(obj/item/deleting) + storage_ui?.on_pre_remove(deleting) // Supposed to be able to handle null user. // Only do ui functions for now; the obj is responsible for anything else. -/datum/storage/proc/on_item_post_deletion(obj/item/W) - update_ui_after_item_removal(W) +/datum/storage/proc/on_item_post_deletion(obj/item/deleting) + update_ui_after_item_removal(deleting) holder?.queue_icon_update() //Run once after using remove_from_storage with skip_update = 1 diff --git a/code/datums/storage/_storage_ui.dm b/code/datums/storage/_storage_ui.dm index a3e1f23bfcb5..59ee69e5acc6 100644 --- a/code/datums/storage/_storage_ui.dm +++ b/code/datums/storage/_storage_ui.dm @@ -35,10 +35,10 @@ /datum/storage_ui/proc/on_insertion() return -/datum/storage_ui/proc/on_pre_remove(obj/item/W) +/datum/storage_ui/proc/on_pre_remove(obj/item/removing) return -/datum/storage_ui/proc/on_post_remove(obj/item/W) +/datum/storage_ui/proc/on_post_remove(obj/item/removing) return /datum/storage_ui/proc/on_hand_attack(mob/user) @@ -93,12 +93,12 @@ /datum/storage_ui/default/on_insertion() refresh_viewers() -/datum/storage_ui/default/on_post_remove(obj/item/W) +/datum/storage_ui/default/on_post_remove(obj/item/removing) refresh_viewers() -/datum/storage_ui/default/on_pre_remove(obj/item/W) +/datum/storage_ui/default/on_pre_remove(obj/item/removing) for(var/mob/user in is_seeing) - user.client?.screen -= W + user.client?.screen -= removing /datum/storage_ui/default/on_hand_attack(mob/user) for(var/mob/other_user in is_seeing) diff --git a/code/datums/storage/subtypes_backpack.dm b/code/datums/storage/subtypes_backpack.dm index 360c835727d1..30c6027aa028 100644 --- a/code/datums/storage/subtypes_backpack.dm +++ b/code/datums/storage/subtypes_backpack.dm @@ -6,10 +6,8 @@ /datum/storage/backpack/holding max_storage_space = 56 -/datum/storage/backpack/holding/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params) - if(istype(W, /obj/item/backpack/holding)) - return 1 - return ..() +/datum/storage/backpack/holding/can_be_inserted(obj/item/inserting, mob/user, stop_messages = 0, click_params) + return istype(inserting, /obj/item/backpack/holding) || ..() /datum/storage/backpack/santa max_w_class = ITEM_SIZE_NORMAL diff --git a/code/datums/storage/subtypes_bag.dm b/code/datums/storage/subtypes_bag.dm index 07cdaf12cd2d..401ea28d1dad 100644 --- a/code/datums/storage/subtypes_bag.dm +++ b/code/datums/storage/subtypes_bag.dm @@ -3,19 +3,19 @@ allow_quick_empty = 1 use_to_pickup = 1 -/datum/storage/bag/handle_item_insertion(mob/user, obj/item/W, prevent_warning, skip_update, click_params) +/datum/storage/bag/handle_item_insertion(mob/user, obj/item/inserting, prevent_warning, skip_update, click_params) . = ..() if(. && istype(holder, /obj/item/bag)) var/obj/item/bag/bag = holder bag.update_w_class() -/datum/storage/bag/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/bag/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) . = ..() if(. && istype(holder, /obj/item/bag)) var/obj/item/bag/bag = holder bag.update_w_class() -/datum/storage/bag/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params = null) +/datum/storage/bag/can_be_inserted(obj/item/inserting, mob/user, stop_messages = 0, click_params = null) var/mob/living/human/H = ishuman(user) ? user : null // if we're human, then we need to check if bag in a pocket if(holder.loc?.storage || H?.is_in_pocket(holder)) if(!stop_messages) @@ -41,9 +41,9 @@ max_w_class = ITEM_SIZE_HUGE can_hold = list(/obj/item/coin, /obj/item/cash) -/datum/storage/bag/cash/infinite/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/bag/cash/infinite/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) . = ..() - if(. && istype(W,/obj/item/cash)) //only matters if its spacecash. + if(. && istype(removing, /obj/item/cash)) //only matters if its spacecash. handle_item_insertion(null, new /obj/item/cash/c1000, TRUE) /datum/storage/bag/quantum diff --git a/code/datums/storage/subtypes_box.dm b/code/datums/storage/subtypes_box.dm index dd94c30e1f32..479c9460eb88 100644 --- a/code/datums/storage/subtypes_box.dm +++ b/code/datums/storage/subtypes_box.dm @@ -47,23 +47,23 @@ max_w_class = ITEM_SIZE_TINY storage_slots = 7 -/datum/storage/box/cigar/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) - if(istype(W, /obj/item/clothing/mask/smokable/cigarette/cigar) && isatom(holder)) +/datum/storage/box/cigar/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) + if(istype(removing, /obj/item/clothing/mask/smokable/cigarette/cigar) && isatom(holder)) var/atom/atom_holder = holder if(atom_holder.reagents) - atom_holder.reagents.trans_to_obj(W, (atom_holder.reagents.total_volume/max(1, length(get_contents())))) + atom_holder.reagents.trans_to_obj(removing, (atom_holder.reagents.total_volume/max(1, length(get_contents())))) return ..() /datum/storage/box/cigarettes max_w_class = ITEM_SIZE_TINY max_storage_space = 6 -/datum/storage/box/cigarettes/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/box/cigarettes/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) // Don't try to transfer reagents to lighters - if(istype(W, /obj/item/clothing/mask/smokable/cigarette) && isatom(holder)) + if(istype(removing, /obj/item/clothing/mask/smokable/cigarette) && isatom(holder)) var/atom/atom_holder = holder if(atom_holder.reagents) - atom_holder.reagents.trans_to_obj(W, (atom_holder.reagents.total_volume/max(1, length(get_contents())))) + atom_holder.reagents.trans_to_obj(removing, (atom_holder.reagents.total_volume/max(1, length(get_contents())))) return ..() /datum/storage/box/cigarettes/cigarello diff --git a/code/datums/storage/subtypes_excavation.dm b/code/datums/storage/subtypes_excavation.dm index dacbdf2d2440..ec23be327fae 100644 --- a/code/datums/storage/subtypes_excavation.dm +++ b/code/datums/storage/subtypes_excavation.dm @@ -5,7 +5,7 @@ max_w_class = ITEM_SIZE_NORMAL use_to_pickup = 1 -/datum/storage/excavation/handle_item_insertion(mob/user, obj/item/W, prevent_warning, skip_update, click_params) +/datum/storage/excavation/handle_item_insertion(mob/user, obj/item/inserting, prevent_warning, skip_update, click_params) . = ..() var/obj/item/excavation/picks = holder if(istype(picks)) diff --git a/code/datums/storage/subtypes_misc.dm b/code/datums/storage/subtypes_misc.dm index fec9cd65cdf9..5f51b0ffc9de 100644 --- a/code/datums/storage/subtypes_misc.dm +++ b/code/datums/storage/subtypes_misc.dm @@ -106,16 +106,16 @@ can_hold = list(/obj/item) expected_type = /obj/structure/reagent_dispensers/compost_bin -/datum/storage/hopper/industrial/compost/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params = null) +/datum/storage/hopper/industrial/compost/can_be_inserted(obj/item/inserting, mob/user, stop_messages = 0, click_params = null) . = ..() if(!.) return - if(istype(W, /obj/item/food/worm) && istype(holder, /obj/structure/reagent_dispensers/compost_bin)) + if(istype(inserting, /obj/item/food/worm) && istype(holder, /obj/structure/reagent_dispensers/compost_bin)) var/worms = 0 for(var/obj/item/food/worm/worm in get_contents()) worms++ return worms < COMPOST_MAX_WORMS - return W.is_compostable() + return inserting.is_compostable() /datum/storage/hopper/mortar max_w_class = ITEM_SIZE_NORMAL * 2 diff --git a/code/datums/storage/subtypes_pills.dm b/code/datums/storage/subtypes_pills.dm index ca8287f168c6..29d2ba18f8f2 100644 --- a/code/datums/storage/subtypes_pills.dm +++ b/code/datums/storage/subtypes_pills.dm @@ -10,20 +10,20 @@ use_to_pickup = 1 use_sound = 'sound/effects/storage/pillbottle.ogg' -/datum/storage/pillbottle/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/pillbottle/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) . = ..() if(. && istype(holder, /obj/item/pill_bottle/foil_pack)) var/obj/item/pill_bottle/foil_pack/pop = holder if(pop.pop_sound) playsound(get_turf(pop), pop.pop_sound, 50) -/datum/storage/pillbottle/foil/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params = null) +/datum/storage/pillbottle/foil/can_be_inserted(obj/item/inserting, mob/user, stop_messages = 0, click_params = null) return FALSE -/datum/storage/pillbottle/foil/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/pillbottle/foil/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) . = ..() - if(. && W.loc != holder && istype(W, /obj/item/pill_bottle/foil_pack)) + if(. && removing.loc != holder && istype(removing, /obj/item/pill_bottle/foil_pack)) var/obj/item/pill_bottle/foil_pack/pop = holder if(pop.pill_positions) - pop.pill_positions -= W + pop.pill_positions -= removing pop.update_icon() diff --git a/code/datums/storage/subtypes_secure.dm b/code/datums/storage/subtypes_secure.dm index bf501d186be7..8427c0d7579d 100644 --- a/code/datums/storage/subtypes_secure.dm +++ b/code/datums/storage/subtypes_secure.dm @@ -16,7 +16,7 @@ . = ..() //Must be overriden to prevent gathering from tile and using on items when locked! -/datum/storage/secure/can_be_inserted(obj/item/W, mob/user, stop_messages, click_params = null) +/datum/storage/secure/can_be_inserted(inserting, mob/user, stop_messages, click_params = null) if(is_locked()) if(!stop_messages) to_chat(user, SPAN_WARNING("\The [holder] is locked, you cannot put anything inside.")) diff --git a/code/datums/storage/subtypes_sheets.dm b/code/datums/storage/subtypes_sheets.dm index 578282c8d4b9..7bc7504efca3 100644 --- a/code/datums/storage/subtypes_sheets.dm +++ b/code/datums/storage/subtypes_sheets.dm @@ -9,10 +9,10 @@ /datum/storage/sheets/robot capacity = 500 //Borgs get more because >specialization -/datum/storage/sheets/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params = null) - if(!istype(W,/obj/item/stack/material)) +/datum/storage/sheets/can_be_inserted(obj/item/inserting, mob/user, stop_messages = 0, click_params = null) + if(!istype(inserting,/obj/item/stack/material)) if(!stop_messages) - to_chat(user, "\The [holder] does not accept [W].") + to_chat(user, "\The [holder] does not accept [inserting].") return FALSE var/current = 0 for(var/obj/item/stack/material/S in get_contents()) @@ -24,8 +24,8 @@ return TRUE // Modified handle_item_insertion. Would prefer not to, but... -/datum/storage/sheets/handle_item_insertion(mob/user, obj/item/W, prevent_warning, skip_update, click_params) - var/obj/item/stack/material/S = W +/datum/storage/sheets/handle_item_insertion(mob/user, obj/item/inserting, prevent_warning, skip_update, click_params) + var/obj/item/stack/material/S = inserting if(!istype(S)) return FALSE var/amount @@ -71,8 +71,8 @@ atom_holder.update_icon() // Instead of removing -/datum/storage/sheets/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) - var/obj/item/stack/material/S = W +/datum/storage/sheets/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) + var/obj/item/stack/material/S = removing if(!istype(S)) return FALSE diff --git a/code/datums/storage/subtypes_slides.dm b/code/datums/storage/subtypes_slides.dm index 1f1e76f069a2..3630191a176f 100644 --- a/code/datums/storage/subtypes_slides.dm +++ b/code/datums/storage/subtypes_slides.dm @@ -3,15 +3,15 @@ max_storage_space = BASE_STORAGE_CAPACITY(ITEM_SIZE_SMALL) use_sound = 'sound/effects/storage/toolbox.ogg' -/datum/storage/slide_projector/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/slide_projector/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) . = ..() var/obj/item/slide_projector/projector = holder - if(. && istype(projector) && W == projector.current_slide) + if(. && istype(projector) && removing == projector.current_slide) var/list/contents = get_contents() projector.set_slide(length(contents) ? contents[1] : null) -/datum/storage/slide_projector/handle_item_insertion(mob/user, obj/item/W, prevent_warning, skip_update, click_params) +/datum/storage/slide_projector/handle_item_insertion(mob/user, obj/item/inserting, prevent_warning, skip_update, click_params) . = ..() var/obj/item/slide_projector/projector = holder if(. && istype(projector) && !projector.current_slide) - projector.set_slide(W) + projector.set_slide(inserting) diff --git a/code/datums/storage/subtypes_tray.dm b/code/datums/storage/subtypes_tray.dm index fd17ea8d7e45..f0d79ec39b46 100644 --- a/code/datums/storage/subtypes_tray.dm +++ b/code/datums/storage/subtypes_tray.dm @@ -4,11 +4,11 @@ allow_quick_gather = 1 use_sound = null -/datum/storage/tray/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/tray/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) . = ..() - W.vis_flags = initial(W.vis_flags) - W.appearance_flags = initial(W.appearance_flags) - W.update_icon() // in case it updates vis_flags + removing.vis_flags = initial(removing.vis_flags) + removing.appearance_flags = initial(removing.appearance_flags) + removing.update_icon() // in case it updates vis_flags /datum/storage/tray/gather_all(var/turf/T, var/mob/user) ..() diff --git a/code/datums/storage/subtypes_wallet.dm b/code/datums/storage/subtypes_wallet.dm index c9318f0146d6..75aed5045327 100644 --- a/code/datums/storage/subtypes_wallet.dm +++ b/code/datums/storage/subtypes_wallet.dm @@ -39,23 +39,23 @@ /obj/item/clothing/armor_attachment/tag, ) -/datum/storage/wallet/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) +/datum/storage/wallet/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) . = ..() if(. && istype(holder, /obj/item/wallet)) var/obj/item/wallet/wallet = holder - if(W == wallet.front_id) + if(removing == wallet.front_id) wallet.front_id = null wallet.SetName(initial(wallet.name)) wallet.update_icon() - if(W == wallet.front_stick) + if(removing == wallet.front_stick) wallet.front_stick = null -/datum/storage/wallet/handle_item_insertion(mob/user, obj/item/W, prevent_warning, skip_update, click_params) +/datum/storage/wallet/handle_item_insertion(mob/user, obj/item/inserting, prevent_warning, skip_update, click_params) . = ..() if(. && istype(holder, /obj/item/wallet)) var/obj/item/wallet/wallet = holder - if(!wallet.front_id && istype(W, /obj/item/card/id)) - wallet.front_id = W + if(!wallet.front_id && istype(inserting, /obj/item/card/id)) + wallet.front_id = inserting wallet.update_icon() - if(!wallet.front_stick && istype(W, /obj/item/charge_stick)) - wallet.front_stick = W + if(!wallet.front_stick && istype(inserting, /obj/item/charge_stick)) + wallet.front_stick = inserting diff --git a/code/game/machinery/_machines_base/machine_construction/frame.dm b/code/game/machinery/_machines_base/machine_construction/frame.dm index 1913c959fbed..33b0630b3a96 100644 --- a/code/game/machinery/_machines_base/machine_construction/frame.dm +++ b/code/game/machinery/_machines_base/machine_construction/frame.dm @@ -19,13 +19,13 @@ to_chat(user, "You wrench \the [machine] into place.") machine.anchored = TRUE if(IS_WELDER(I)) - var/obj/item/weldingtool/WT = I - if(!WT.weld(0, user)) + var/obj/item/weldingtool/welder = I + if(!welder.weld(0, user)) to_chat(user, "The welding tool must be on to complete this task.") return TRUE playsound(machine.loc, 'sound/items/Welder.ogg', 50, 1) if(do_after(user, 20, machine)) - if(!WT.isOn()) + if(!welder.isOn()) return TRUE TRANSFER_STATE(/decl/machine_construction/default/deconstructed) to_chat(user, "You deconstruct \the [machine].") diff --git a/code/game/machinery/_machines_base/machine_construction/pipe.dm b/code/game/machinery/_machines_base/machine_construction/pipe.dm index 4667327dd0e0..9434855686c4 100644 --- a/code/game/machinery/_machines_base/machine_construction/pipe.dm +++ b/code/game/machinery/_machines_base/machine_construction/pipe.dm @@ -25,10 +25,10 @@ // Same, but uses different tool. /decl/machine_construction/pipe/welder/deconstruct_transition(obj/item/I, mob/user, obj/machinery/machine) if(IS_WELDER(I)) - var/obj/item/weldingtool/WT = I - if(!WT.isOn()) + var/obj/item/weldingtool/welder = I + if(!welder.isOn()) return FALSE - if(!WT.weld(0,user)) + if(!welder.weld(0,user)) return FALSE var/fail = machine.cannot_transition_to(/decl/machine_construction/default/deconstructed, user) if(istext(fail)) @@ -40,7 +40,7 @@ playsound(get_turf(machine), 'sound/items/Welder.ogg', 50, 1) if(!do_after(user, 5 SECONDS, machine)) return TRUE - if(!WT.isOn()) + if(!welder.isOn()) return TRUE playsound(get_turf(machine), 'sound/items/Welder2.ogg', 50, 1) TRANSFER_STATE(/decl/machine_construction/default/deconstructed) diff --git a/code/game/machinery/_machines_base/machinery_damage.dm b/code/game/machinery/_machines_base/machinery_damage.dm index bba75011ff7a..29a821716b0c 100644 --- a/code/game/machinery/_machines_base/machinery_damage.dm +++ b/code/game/machinery/_machines_base/machinery_damage.dm @@ -82,13 +82,13 @@ . = ..() take_damage(P.damage, P.atom_damage_type) -/obj/machinery/bash(obj/item/W, mob/user) - if(!istype(W)) +/obj/machinery/bash(obj/item/used_item, mob/user) + if(!istype(used_item)) return FALSE - var/force = W.expend_attack_force(user) + var/force = used_item.expend_attack_force(user) if(force <= 5) return FALSE . = ..() if(.) - user.setClickCooldown(W.attack_cooldown + W.w_class) - take_damage(force, W.atom_damage_type) \ No newline at end of file + user.setClickCooldown(used_item.attack_cooldown + used_item.w_class) + take_damage(force, used_item.atom_damage_type) \ No newline at end of file diff --git a/code/game/machinery/_machines_base/stock_parts/access_lock.dm b/code/game/machinery/_machines_base/stock_parts/access_lock.dm index 2f4935ed6731..8d6b4aec8cea 100644 --- a/code/game/machinery/_machines_base/stock_parts/access_lock.dm +++ b/code/game/machinery/_machines_base/stock_parts/access_lock.dm @@ -54,10 +54,10 @@ if(emagged && user.skill_check_multiple(list(SKILL_FORENSICS = SKILL_EXPERT, SKILL_COMPUTER = SKILL_EXPERT))) . += SPAN_WARNING("On close inspection, there is something odd about the interface. You suspect it may have been tampered with.") -/obj/item/stock_parts/access_lock/attackby(obj/item/W, mob/user) +/obj/item/stock_parts/access_lock/attackby(obj/item/used_item, mob/user) var/obj/machinery/machine = loc if(!emagged && istype(machine)) - var/obj/item/card/id/I = W.GetIdCard() + var/obj/item/card/id/I = used_item.GetIdCard() if(I && check_access(I)) locked = !locked visible_message(SPAN_NOTICE("\The [src] beeps and flashes green twice: it is now [locked ? "" : "un"]locked.")) diff --git a/code/game/machinery/_machines_base/stock_parts/card_reader.dm b/code/game/machinery/_machines_base/stock_parts/card_reader.dm index 3f92564a8d7e..05472503c246 100644 --- a/code/game/machinery/_machines_base/stock_parts/card_reader.dm +++ b/code/game/machinery/_machines_base/stock_parts/card_reader.dm @@ -46,8 +46,8 @@ return swipe_card(O, user) . = ..() -/obj/item/stock_parts/item_holder/card_reader/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W) && !istype(loc, /obj/machinery)) //Only if not in the machine, to prevent hijacking tool interactions with the machine +/obj/item/stock_parts/item_holder/card_reader/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item) && !istype(loc, /obj/machinery)) //Only if not in the machine, to prevent hijacking tool interactions with the machine should_swipe = !should_swipe to_chat(user, SPAN_NOTICE("You toggle \the [src] into [should_swipe? "swipe" : "insert"] card mode.")) return TRUE diff --git a/code/game/machinery/_machines_base/stock_parts/item_holder.dm b/code/game/machinery/_machines_base/stock_parts/item_holder.dm index 707acd2dbd00..cb875fa65dec 100644 --- a/code/game/machinery/_machines_base/stock_parts/item_holder.dm +++ b/code/game/machinery/_machines_base/stock_parts/item_holder.dm @@ -17,9 +17,9 @@ unregister_on_eject() . = ..() -/obj/item/stock_parts/item_holder/attackby(obj/item/W, mob/user) - if(is_accepted_type(W)) - insert_item(W, user) +/obj/item/stock_parts/item_holder/attackby(obj/item/used_item, mob/user) + if(is_accepted_type(used_item)) + insert_item(used_item, user) return TRUE . = ..() diff --git a/code/game/machinery/_machines_base/stock_parts/network_lock.dm b/code/game/machinery/_machines_base/stock_parts/network_lock.dm index d5d6e187fdee..d5cd653186e4 100644 --- a/code/game/machinery/_machines_base/stock_parts/network_lock.dm +++ b/code/game/machinery/_machines_base/stock_parts/network_lock.dm @@ -75,10 +75,10 @@ if(emagged && user.skill_check_multiple(list(SKILL_FORENSICS = SKILL_EXPERT, SKILL_COMPUTER = SKILL_EXPERT))) . += SPAN_WARNING("On closer inspection, there is something odd about the interface. You suspect it may have been tampered with.") -/obj/item/stock_parts/network_receiver/network_lock/attackby(obj/item/W, mob/user) +/obj/item/stock_parts/network_receiver/network_lock/attackby(obj/item/used_item, mob/user) . = ..() - if(istype(W, /obj/item/card/id)) - if(check_access(W)) + if(istype(used_item, /obj/item/card/id)) + if(check_access(used_item)) playsound(src, 'sound/machines/ping.ogg', 20, 0) else playsound(src, 'sound/machines/buzz-two.ogg', 20, 0) diff --git a/code/game/machinery/ai_slipper.dm b/code/game/machinery/ai_slipper.dm index e571411e9730..e8aab501f355 100644 --- a/code/game/machinery/ai_slipper.dm +++ b/code/game/machinery/ai_slipper.dm @@ -23,7 +23,7 @@ src.uses = uses src.power_change() -/obj/machinery/ai_slipper/attackby(obj/item/W, mob/user) +/obj/machinery/ai_slipper/attackby(obj/item/used_item, mob/user) if(stat & (NOPOWER|BROKEN)) return FALSE if (issilicon(user)) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 4096611b87e7..928b331c9292 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -913,7 +913,7 @@ FIRE ALARM alarm(rand(30/severity, 60/severity)) ..() -/obj/machinery/firealarm/attackby(obj/item/W, mob/user) +/obj/machinery/firealarm/attackby(obj/item/used_item, mob/user) if((. = ..())) return src.alarm() diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 52613f16121d..e3e7866689b7 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -197,15 +197,15 @@ EMPTY_CANISTER(hydrogen, /obj/machinery/portable_atmospherics/canister/hydrogen) healthcheck() return ..() -/obj/machinery/portable_atmospherics/canister/bash(var/obj/item/W, var/mob/user) +/obj/machinery/portable_atmospherics/canister/bash(var/obj/item/used_item, var/mob/user) . = ..() if(.) - current_health -= W.expend_attack_force(user) + current_health -= used_item.expend_attack_force(user) healthcheck() -/obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/W, var/mob/user) - if(isrobot(user) && istype(W, /obj/item/tank/jetpack)) - var/obj/item/tank/jetpack/pack = W +/obj/machinery/portable_atmospherics/canister/attackby(var/obj/item/used_item, var/mob/user) + if(isrobot(user) && istype(used_item, /obj/item/tank/jetpack)) + var/obj/item/tank/jetpack/pack = used_item var/datum/gas_mixture/thejetpack = pack.air_contents if(thejetpack) var/env_pressure = thejetpack.return_pressure() diff --git a/code/game/machinery/buttons.dm b/code/game/machinery/buttons.dm index 10f382fb55be..9e19104b483a 100644 --- a/code/game/machinery/buttons.dm +++ b/code/game/machinery/buttons.dm @@ -40,8 +40,8 @@ . = ..() update_icon() -/obj/machinery/button/attackby(obj/item/W, mob/user) - if(!(. = component_attackby(W, user))) +/obj/machinery/button/attackby(obj/item/used_item, mob/user) + if(!(. = component_attackby(used_item, user))) return attack_hand_with_interaction_checks(user) /obj/machinery/button/interface_interact(user) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 6f6b8ec45963..94e397e7ed3d 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -196,10 +196,10 @@ return TRUE return FALSE -/obj/machinery/camera/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/paper)) +/obj/machinery/camera/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/paper)) var/datum/extension/network_device/camera/D = get_extension(src, /datum/extension/network_device) - D.show_paper(W, user) + D.show_paper(used_item, user) return ..() /obj/machinery/camera/interface_interact(mob/user) diff --git a/code/game/machinery/cell_charger.dm b/code/game/machinery/cell_charger.dm index 5a27cca96219..9cc55afa80f1 100644 --- a/code/game/machinery/cell_charger.dm +++ b/code/game/machinery/cell_charger.dm @@ -52,8 +52,8 @@ STOP_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF) update_icon() -/obj/machinery/cell_charger/attackby(obj/item/W, mob/user) - if(IS_WRENCH(W) && !panel_open) +/obj/machinery/cell_charger/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item) && !panel_open) . = TRUE if(get_cell()) to_chat(user, "Remove the cell first!") diff --git a/code/game/machinery/centrifuge.dm b/code/game/machinery/centrifuge.dm index 661521014abe..217e63809e5e 100644 --- a/code/game/machinery/centrifuge.dm +++ b/code/game/machinery/centrifuge.dm @@ -11,9 +11,9 @@ return FALSE return TRUE -/datum/storage/hopper/industrial/centrifuge/can_be_inserted(obj/item/W, mob/user, stop_messages, click_params) +/datum/storage/hopper/industrial/centrifuge/can_be_inserted(obj/item/inserting, mob/user, stop_messages, click_params) . = ..() - if(. && !should_ingest(user, W)) + if(. && !should_ingest(user, inserting)) return FALSE /obj/machinery/centrifuge diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index c76905972bca..622914bad742 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -224,9 +224,9 @@ var/global/list/deactivated_ai_cores = list() card.clear() qdel(src) -/obj/structure/aicore/deactivated/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/aicard)) - var/obj/item/aicard/card = W +/obj/structure/aicore/deactivated/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/aicard)) + var/obj/item/aicard/card = used_item var/mob/living/silicon/ai/transfer = locate() in card if(transfer) load_ai(transfer,card,user) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 059d35045c0e..2557a9767f3c 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -420,8 +420,8 @@ var/list/items = get_contained_external_atoms() if(occupant) items -= occupant - for(var/obj/item/W in items) - W.dropInto(loc) + for(var/obj/item/thing in items) + thing.dropInto(loc) src.go_out() add_fingerprint(usr) @@ -523,14 +523,14 @@ to_chat(user, SPAN_NOTICE("The glass is already open.")) return TRUE -/obj/structure/broken_cryo/attackby(obj/item/W, mob/user) +/obj/structure/broken_cryo/attackby(obj/item/used_item, mob/user) if (busy) to_chat(user, SPAN_NOTICE("Someone else is attempting to open this.")) return TRUE if (!closed) to_chat(user, SPAN_NOTICE("The glass cover is already open.")) return TRUE - if (IS_CROWBAR(W)) + if (IS_CROWBAR(used_item)) busy = 1 visible_message("[user] starts to pry the glass cover off of \the [src].") if (!do_after(user, 50, src)) diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm index 345a6b0359aa..7172c5958187 100644 --- a/code/game/machinery/deployable.dm +++ b/code/game/machinery/deployable.dm @@ -19,8 +19,8 @@ . = ..() icon_state = "barrier[src.locked]" -/obj/machinery/deployable/barrier/attackby(obj/item/W, mob/user) - if (istype(W, /obj/item/card/id)) +/obj/machinery/deployable/barrier/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/card/id)) if (src.allowed(user)) if (src.emagged < 2.0) src.locked = !src.locked @@ -36,7 +36,7 @@ spark_at(src, amount=2, cardinal_only = TRUE) visible_message("BZZzZZzZZzZT") return TRUE - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) var/current_max_health = get_max_health() if (current_health < current_max_health) current_health = current_max_health @@ -50,11 +50,11 @@ visible_message("[user] repairs \the [src]!") return TRUE else - switch(W.atom_damage_type) + switch(used_item.atom_damage_type) if(BURN) - current_health -= W.expend_attack_force(user) * 0.75 + current_health -= used_item.expend_attack_force(user) * 0.75 if(BRUTE) - current_health -= W.expend_attack_force(user) * 0.5 + current_health -= used_item.expend_attack_force(user) * 0.5 if (current_health <= 0) explode() return TRUE diff --git a/code/game/machinery/doors/_door.dm b/code/game/machinery/doors/_door.dm index 39628fe7da0b..e62ada86f20f 100644 --- a/code/game/machinery/doors/_door.dm +++ b/code/game/machinery/doors/_door.dm @@ -537,10 +537,10 @@ if( istype(T, /turf/wall)) success = 1 if(propagate) - for(var/turf/wall/W in RANGE_TURFS(T, 1)) - W.wall_connections = null - W.other_connections = null - W.queue_icon_update() + for(var/turf/wall/wall in RANGE_TURFS(T, 1)) + wall.wall_connections = null + wall.other_connections = null + wall.queue_icon_update() else if(istype(T, /turf/unsimulated/wall)) success = 1 diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 004f0fc02a44..b6323631bfe0 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -643,8 +643,8 @@ About the new airlock wires panel: var/cut_sound if(IS_WELDER(item)) - var/obj/item/weldingtool/WT = item - if(!WT.weld(0,user)) + var/obj/item/weldingtool/welder = item + if(!welder.weld(0,user)) return FALSE cut_verb = "cutting" cut_sound = 'sound/items/Welder.ogg' @@ -752,9 +752,9 @@ About the new airlock wires panel: return if(!repairing && IS_WELDER(C) && !operating && density) - var/obj/item/weldingtool/W = C - if(!W.weld(0,user)) - to_chat(user, SPAN_NOTICE("Your [W.name] doesn't have enough fuel.")) + var/obj/item/weldingtool/welder = C + if(!welder.weld(0,user)) + to_chat(user, SPAN_NOTICE("Your [welder.name] doesn't have enough fuel.")) return TRUE playsound(src, 'sound/items/Welder.ogg', 50, 1) user.visible_message(SPAN_WARNING("\The [user] begins welding \the [src] [welded ? "open" : "closed"]!"), diff --git a/code/game/machinery/doors/braces.dm b/code/game/machinery/doors/braces.dm index 137c4cddb4f1..92846b45c43d 100644 --- a/code/game/machinery/doors/braces.dm +++ b/code/game/machinery/doors/braces.dm @@ -68,12 +68,12 @@ /obj/item/airlock_brace/attack_self(mob/user) electronics.attack_self(user) -/obj/item/airlock_brace/attackby(obj/item/W, mob/user) - if (istype(W.GetIdCard(), /obj/item/card/id)) +/obj/item/airlock_brace/attackby(obj/item/used_item, mob/user) + if (istype(used_item.GetIdCard(), /obj/item/card/id)) if(!airlock) return attack_self(user) else - var/obj/item/card/id/C = W.GetIdCard() + var/obj/item/card/id/C = used_item.GetIdCard() if(check_access(C)) to_chat(user, "You swipe \the [C] through \the [src].") if(do_after(user, 10, airlock)) @@ -83,18 +83,18 @@ to_chat(user, "You swipe \the [C] through \the [src], but it does not react.") return TRUE - if (istype(W, /obj/item/crowbar/brace_jack)) + if (istype(used_item, /obj/item/crowbar/brace_jack)) if(!airlock) return FALSE - var/obj/item/crowbar/brace_jack/C = W + var/obj/item/crowbar/brace_jack/C = used_item to_chat(user, "You begin forcibly removing \the [src] with \the [C].") if(do_after(user, rand(150,300), airlock)) to_chat(user, "You finish removing \the [src].") unlock_brace(user) return TRUE - if(IS_WELDER(W)) - var/obj/item/weldingtool/C = W + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/C = used_item if(!is_damaged()) to_chat(user, "\The [src] does not require repairs.") return TRUE diff --git a/code/game/machinery/doors/double.dm b/code/game/machinery/doors/double.dm index 1cd2c99b2669..4bfc77f73631 100644 --- a/code/game/machinery/doors/double.dm +++ b/code/game/machinery/doors/double.dm @@ -58,10 +58,10 @@ if( istype(T, /turf/wall)) success = 1 if(propagate) - var/turf/wall/W = T - W.wall_connections = null - W.other_connections = null - W.queue_icon_update() + var/turf/wall/wall = T + wall.wall_connections = null + wall.other_connections = null + wall.queue_icon_update() else for(var/obj/O in T) for(var/blend_type in get_blend_objects()) diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 673d87c5bdde..b2727a79621b 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -222,14 +222,14 @@ if(operating) return TRUE //Already doing something. if(IS_WELDER(C) && !repairing) - var/obj/item/weldingtool/W = C - if(W.weld(0, user)) + var/obj/item/weldingtool/welder = C + if(welder.weld(0, user)) playsound(src, 'sound/items/Welder.ogg', 100, 1) if(do_after(user, 2 SECONDS, src)) - if(!W.isOn()) return TRUE + if(!welder.isOn()) return TRUE blocked = !blocked - user.visible_message("\The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [W].",\ - "You [blocked ? "weld" : "unweld"] \the [src] with \the [W].",\ + user.visible_message("\The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [welder].",\ + "You [blocked ? "weld" : "unweld"] \the [src] with \the [welder].",\ "You hear something being welded.") playsound(src, 'sound/items/Welder.ogg', 100, 1) update_icon() diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller.dm b/code/game/machinery/embedded_controller/airlock_docking_controller.dm index 026318090b40..0605e8f0ff8e 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller.dm @@ -12,15 +12,15 @@ var/datum/computer/file/embedded_program/docking/airlock/docking_program = program docking_program.display_name = display_name -/obj/machinery/embedded_controller/radio/airlock/docking_port/attackby(obj/item/W, mob/user) - if(IS_MULTITOOL(W)) //give them part of code, would take few tries to get full +/obj/machinery/embedded_controller/radio/airlock/docking_port/attackby(obj/item/used_item, mob/user) + if(IS_MULTITOOL(used_item)) //give them part of code, would take few tries to get full var/datum/computer/file/embedded_program/docking/airlock/docking_program = program var/code = docking_program.docking_codes if(!code) code = "N/A" else code = stars(code) - to_chat(user,"[W]'s screen displays '[code]'") + to_chat(user,"[used_item]'s screen displays '[code]'") return TRUE else return ..() diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index eeef5d6c7deb..375bc0653cd4 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -35,9 +35,9 @@ // src.sd_SetLuminosity(0) //Don't want to render prison breaks impossible -/obj/machinery/flasher/attackby(obj/item/W, mob/user) - if(IS_WIRECUTTER(W)) - add_fingerprint(user, 0, W) +/obj/machinery/flasher/attackby(obj/item/used_item, mob/user) + if(IS_WIRECUTTER(used_item)) + add_fingerprint(user, 0, used_item) src.disable = !src.disable if (src.disable) user.visible_message("[user] has disconnected \the [src]'s flashbulb!", "You disconnect \the [src]'s flashbulb!") @@ -123,8 +123,8 @@ if(!MOVING_DELIBERATELY(M)) flash() -/obj/machinery/flasher/portable/attackby(obj/item/W, mob/user) - if(IS_WRENCH(W)) +/obj/machinery/flasher/portable/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item)) add_fingerprint(user) src.anchored = !src.anchored diff --git a/code/game/machinery/floor_light.dm b/code/game/machinery/floor_light.dm index b6fefd1fe27b..c9c4e8571b5f 100644 --- a/code/game/machinery/floor_light.dm +++ b/code/game/machinery/floor_light.dm @@ -29,28 +29,28 @@ var/global/list/floor_light_cache = list() . = ..() update_icon() -/obj/machinery/floor_light/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/floor_light/attackby(var/obj/item/used_item, var/mob/user) - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) anchored = !anchored if(use_power) update_use_power(POWER_USE_OFF) visible_message(SPAN_NOTICE("\The [user] has [anchored ? "attached" : "detached"] \the [src].")) return TRUE - if(IS_WELDER(W) && (damaged || (stat & BROKEN))) - var/obj/item/weldingtool/WT = W - if(!WT.weld(0, user)) + if(IS_WELDER(used_item) && (damaged || (stat & BROKEN))) + var/obj/item/weldingtool/welder = used_item + if(!welder.weld(0, user)) to_chat(user, SPAN_WARNING("\The [src] must be on to complete this task.")) return TRUE playsound(src.loc, 'sound/items/Welder.ogg', 50, 1) - if(do_after(user, 20, src) && !QDELETED(src) && WT.isOn()) + if(do_after(user, 20, src) && !QDELETED(src) && welder.isOn()) visible_message(SPAN_NOTICE("\The [user] has repaired \the [src].")) set_broken(FALSE) damaged = null return TRUE - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) to_chat(user, SPAN_NOTICE("You dismantle the floor light.")) SSmaterials.create_object(/decl/material/solid/metal/steel, loc, 1) @@ -58,7 +58,7 @@ var/global/list/floor_light_cache = list() qdel(src) return TRUE - if(W.get_attack_force(user) && user.check_intent(I_FLAG_HARM)) + if(used_item.get_attack_force(user) && user.check_intent(I_FLAG_HARM)) return physical_attack_hand(user) return ..() diff --git a/code/game/machinery/floorlayer.dm b/code/game/machinery/floorlayer.dm index ea04c68ba826..92b6260ce5b6 100644 --- a/code/game/machinery/floorlayer.dm +++ b/code/game/machinery/floorlayer.dm @@ -35,23 +35,23 @@ user.visible_message("[user] has [!on?"de":""]activated \the [src].", "You [!on?"de":""]activate \the [src].") return TRUE -/obj/machinery/floorlayer/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/floorlayer/attackby(var/obj/item/used_item, var/mob/user) - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) var/m = input("Choose work mode", "Mode") as null|anything in mode mode[m] = !mode[m] var/O = mode[m] user.visible_message("[user] has set \the [src] [m] mode [!O?"off":"on"].", "You set \the [src] [m] mode [!O?"off":"on"].") return TRUE - if(istype(W, /obj/item/stack/tile)) - if(!user.try_unequip(W, T)) + if(istype(used_item, /obj/item/stack/tile)) + if(!user.try_unequip(used_item, T)) return TRUE - to_chat(user, "\The [W] successfully loaded.") + to_chat(user, "\The [used_item] successfully loaded.") TakeTile(T) return TRUE - if(IS_CROWBAR(W)) + if(IS_CROWBAR(used_item)) if(!length(contents)) to_chat(user, "\The [src] is empty.") else @@ -62,7 +62,7 @@ T = null return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) T = input("Choose tile type.", "Tiles") as null|anything in contents return TRUE return ..() diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 26a071ea6aef..9cbd9367bf7e 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -119,8 +119,8 @@ else icon_state = "[base_state]-p" -/obj/machinery/sparker/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/machinery/sparker/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) add_fingerprint(user) disable = !disable if(disable) diff --git a/code/game/machinery/jukebox.dm b/code/game/machinery/jukebox.dm index 1f9777dfac90..530e66903cbb 100644 --- a/code/game/machinery/jukebox.dm +++ b/code/game/machinery/jukebox.dm @@ -152,10 +152,10 @@ new /obj/effect/decal/cleanable/blood/oil(src.loc) qdel(src) -/obj/machinery/media/jukebox/attackby(obj/item/W, mob/user) - if((IS_WRENCH(W) || IS_HAMMER(W)) && !panel_open) +/obj/machinery/media/jukebox/attackby(obj/item/used_item, mob/user) + if((IS_WRENCH(used_item) || IS_HAMMER(used_item)) && !panel_open) add_fingerprint(user) - wrench_floor_bolts(user, 0, W) + wrench_floor_bolts(user, 0, used_item) power_change() return TRUE return ..() diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index aa537a6a9965..d319eee7d987 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -79,11 +79,11 @@ to_chat(user, SPAN_DANGER("You need a better grip to do that!")) return TRUE -/obj/machinery/gibber/attackby(var/obj/item/W, var/mob/user) - if(!operating && istype(W, /obj/item/organ)) - if(user.try_unequip(W)) - qdel(W) - user.visible_message(SPAN_DANGER("\The [user] feeds \the [W] into \the [src], obliterating it.")) +/obj/machinery/gibber/attackby(var/obj/item/used_item, var/mob/user) + if(!operating && istype(used_item, /obj/item/organ)) + if(user.try_unequip(used_item)) + qdel(used_item) + user.visible_message(SPAN_DANGER("\The [user] feeds \the [used_item] into \the [src], obliterating it.")) return TRUE return ..() diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 20c88ea60823..50533238ce2a 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -882,8 +882,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to src.attack_self(src.loc) -/obj/item/newspaper/attackby(obj/item/W, mob/user) - if(IS_PEN(W)) +/obj/item/newspaper/attackby(obj/item/used_item, mob/user) + if(IS_PEN(used_item)) if(src.scribble_page == src.curr_page) to_chat(user, SPAN_WARNING("There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?")) return TRUE @@ -893,7 +893,7 @@ var/global/list/allCasters = list() //Global list that will contain reference to if(!CanPhysicallyInteractWith(user, src)) to_chat(user, SPAN_WARNING("You must stay close to \the [src]!")) return TRUE - if(W.do_tool_interaction(TOOL_PEN, user, src, 0, fuel_expenditure = 1) && !QDELETED(src)) //Make it instant, since handle_writing_literacy does the waiting + if(used_item.do_tool_interaction(TOOL_PEN, user, src, 0, fuel_expenditure = 1) && !QDELETED(src)) //Make it instant, since handle_writing_literacy does the waiting s = sanitize(s) s = user.handle_writing_literacy(user, s) src.scribble_page = src.curr_page diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm index 7159004c54c3..d00b5f51746c 100644 --- a/code/game/machinery/nuclear_bomb.dm +++ b/code/game/machinery/nuclear_bomb.dm @@ -84,16 +84,16 @@ var/global/bomb_set switch(removal_stage) if(0) if(IS_WELDER(O)) - var/obj/item/weldingtool/WT = O - if(!WT.isOn()) return TRUE - if(WT.get_fuel() < 5) // uses up 5 fuel. + var/obj/item/weldingtool/welder = O + if(!welder.isOn()) return TRUE + if(welder.get_fuel() < 5) // uses up 5 fuel. to_chat(user, "You need more fuel to complete this task.") return TRUE user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...") if(do_after(user, 4 SECONDS, src)) - if(QDELETED(src) || QDELETED(user) || !WT.weld(5, user)) return TRUE + if(QDELETED(src) || QDELETED(user) || !welder.weld(5, user)) return TRUE user.visible_message("\The [user] cuts through the bolt covers on \the [src].", "You cut through the bolt cover.") removal_stage = 1 return TRUE @@ -110,16 +110,16 @@ var/global/bomb_set if(2) if(IS_WELDER(O)) - var/obj/item/weldingtool/WT = O - if(!WT.isOn()) return TRUE - if (WT.get_fuel() < 5) // uses up 5 fuel. + var/obj/item/weldingtool/welder = O + if(!welder.isOn()) return TRUE + if (welder.get_fuel() < 5) // uses up 5 fuel. to_chat(user, "You need more fuel to complete this task.") return TRUE user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...") if(do_after(user, 4 SECONDS, src)) - if(QDELETED(src) || QDELETED(user) || !WT.weld(5, user)) return TRUE + if(QDELETED(src) || QDELETED(user) || !welder.weld(5, user)) return TRUE user.visible_message("\The [user] cuts apart the anchoring system sealant on \the [src].", "You cut apart the anchoring system's sealant.") removal_stage = 3 return TRUE diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm index 3cfa2dd57bbe..103628176c11 100644 --- a/code/game/machinery/oxygen_pump.dm +++ b/code/game/machinery/oxygen_pump.dm @@ -135,8 +135,8 @@ return return 1 -/obj/machinery/oxygen_pump/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/machinery/oxygen_pump/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) stat ^= MAINT user.visible_message(SPAN_NOTICE("\The [user] [stat & MAINT ? "opens" : "closes"] \the [src]."), SPAN_NOTICE("You [stat & MAINT ? "open" : "close"] \the [src].")) if(stat & MAINT) @@ -144,17 +144,17 @@ if(!stat) icon_state = icon_state_closed return TRUE - if(istype(W, /obj/item/tank) && (stat & MAINT)) + if(istype(used_item, /obj/item/tank) && (stat & MAINT)) if(tank) to_chat(user, SPAN_WARNING("\The [src] already has a tank installed!")) return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - tank = W + tank = used_item user.visible_message(SPAN_NOTICE("\The [user] installs \the [tank] into \the [src]."), SPAN_NOTICE("You install \the [tank] into \the [src].")) src.add_fingerprint(user) return TRUE - if(istype(W, /obj/item/tank) && !stat) + if(istype(used_item, /obj/item/tank) && !stat) to_chat(user, SPAN_WARNING("Please open the maintenance hatch first.")) return TRUE return FALSE // TODO: should this be a parent call? do we want this to be (de)constructable? diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm index e117f2087257..005f27ca3465 100644 --- a/code/game/machinery/pipe/construction.dm +++ b/code/game/machinery/pipe/construction.dm @@ -71,8 +71,8 @@ Buildable meters /obj/item/pipe/attack_self(mob/user) return rotate(user) -/obj/item/pipe/attackby(var/obj/item/W, var/mob/user) - if(!IS_WRENCH(W)) +/obj/item/pipe/attackby(var/obj/item/used_item, var/mob/user) + if(!IS_WRENCH(used_item)) return ..() if (!isturf(loc)) return 1 @@ -117,8 +117,8 @@ Buildable meters . = ..() set_extension(src, /datum/extension/parts_stash) -/obj/item/machine_chassis/attackby(var/obj/item/W, var/mob/user) - if(!IS_WRENCH(W)) +/obj/item/machine_chassis/attackby(var/obj/item/used_item, var/mob/user) + if(!IS_WRENCH(used_item)) return ..() var/obj/machinery/machine = new build_type(get_turf(src), dir, TRUE) var/datum/extension/parts_stash/stash = get_extension(src, /datum/extension/parts_stash) diff --git a/code/game/machinery/pipe/pipelayer.dm b/code/game/machinery/pipe/pipelayer.dm index d34c2d094474..6287eafed099 100644 --- a/code/game/machinery/pipe/pipelayer.dm +++ b/code/game/machinery/pipe/pipelayer.dm @@ -14,12 +14,12 @@ var/P_type_t = "" var/max_metal = 50 var/metal = 10 - var/obj/item/wrench/W + var/obj/item/wrench/wrench var/list/Pipes = list("regular pipes"=0,"scrubbers pipes"=31,"supply pipes"=29,"heat exchange pipes"=2, "fuel pipes"=45) /obj/machinery/pipelayer/Initialize() . = ..() - W = new(src) + wrench = new(src) /obj/machinery/pipelayer/Move(new_turf,M_Dir) . = ..() @@ -39,24 +39,24 @@ user.visible_message("[user] has [!on?"de":""]activated \the [src].", "You [!on?"de":""]activate \the [src].") return TRUE -/obj/machinery/pipelayer/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/pipelayer/attackby(var/obj/item/used_item, var/mob/user) - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) P_type_t = input("Choose pipe type", "Pipe type") as null|anything in Pipes P_type = Pipes[P_type_t] user.visible_message("[user] has set \the [src] to manufacture [P_type_t].", "You set \the [src] to manufacture [P_type_t].") return TRUE - if(IS_CROWBAR(W)) + if(IS_CROWBAR(used_item)) a_dis=!a_dis user.visible_message("[user] has [!a_dis?"de":""]activated auto-dismantling.", "You [!a_dis?"de":""]activate auto-dismantling.") return TRUE - if(istype(W, /obj/item/stack/material) && W.get_material_type() == /decl/material/solid/metal/steel) + if(istype(used_item, /obj/item/stack/material) && used_item.get_material_type() == /decl/material/solid/metal/steel) - var/result = load_metal(W) + var/result = load_metal(used_item) if(isnull(result)) - to_chat(user, "Unable to load [W] - no metal found.") + to_chat(user, "Unable to load [used_item] - no metal found.") else if(!result) to_chat(user, "\The [src] is full.") else @@ -64,7 +64,7 @@ return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) if(metal) var/m = round(input(usr,"Please specify the amount of metal to remove","Remove metal",min(round(metal),50)) as num, 1) m = min(m, 50) @@ -129,6 +129,6 @@ var/obj/item/pipe/P = new(w_turf) P.set_dir(p_dir) - P.attackby(W , src) + P.attackby(wrench , src) return 1 diff --git a/code/game/machinery/self_destruct.dm b/code/game/machinery/self_destruct.dm index badb1853918b..a987fa104aee 100644 --- a/code/game/machinery/self_destruct.dm +++ b/code/game/machinery/self_destruct.dm @@ -9,31 +9,31 @@ var/armed = 0 var/damaged = 0 -/obj/machinery/self_destruct/attackby(obj/item/W, mob/user) - if(IS_WELDER(W)) +/obj/machinery/self_destruct/attackby(obj/item/used_item, mob/user) + if(IS_WELDER(used_item)) if(!damaged) return FALSE user.visible_message("[user] begins to repair [src].", "You begin repairing [src].") if(do_after(user, 100, src)) - var/obj/item/weldingtool/w = W + var/obj/item/weldingtool/w = used_item if(w.weld(10)) damaged = 0 user.visible_message("[user] repairs [src].", "You repair [src].") else to_chat(user, "There is not enough fuel to repair [src].") return TRUE - if(istype(W, /obj/item/nuclear_cylinder)) + if(istype(used_item, /obj/item/nuclear_cylinder)) if(damaged) to_chat(user, "[src] is damaged, you cannot place the cylinder.") return TRUE if(cylinder) to_chat(user, "There is already a cylinder here.") return TRUE - user.visible_message("[user] begins to carefully place [W] onto [src].", "You begin to carefully place [W] onto [src].") - if(do_after(user, 80, src) && user.try_unequip(W, src)) - cylinder = W + user.visible_message("[user] begins to carefully place [used_item] onto [src].", "You begin to carefully place [used_item] onto [src].") + if(do_after(user, 80, src) && user.try_unequip(used_item, src)) + cylinder = used_item density = TRUE - user.visible_message("[user] places [W] onto [src].", "You place [W] onto [src].") + user.visible_message("[user] places [used_item] onto [src].", "You place [used_item] onto [src].") update_icon() return TRUE return ..() diff --git a/code/game/machinery/singularitybeacon.dm b/code/game/machinery/singularitybeacon.dm index 5d8690d56765..e9f6d6381be5 100644 --- a/code/game/machinery/singularitybeacon.dm +++ b/code/game/machinery/singularitybeacon.dm @@ -54,8 +54,8 @@ var/global/list/singularity_beacons = list() else to_chat(user, SPAN_DANGER("You need to screw the beacon to the floor first!")) -/obj/machinery/singularity_beacon/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/machinery/singularity_beacon/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) if(use_power) to_chat(user, SPAN_DANGER("You need to deactivate the beacon first!")) return TRUE diff --git a/code/game/machinery/supplybeacon.dm b/code/game/machinery/supplybeacon.dm index b74a93b635dc..6b5e01a6d6cd 100644 --- a/code/game/machinery/supplybeacon.dm +++ b/code/game/machinery/supplybeacon.dm @@ -41,8 +41,8 @@ if(!drop_type) drop_type = pick(supply_drop_random_loot_types()) -/obj/structure/supply_beacon/attackby(var/obj/item/W, var/mob/user) - if(!activated && IS_WRENCH(W)) +/obj/structure/supply_beacon/attackby(var/obj/item/used_item, var/mob/user) + if(!activated && IS_WRENCH(used_item)) anchored = !anchored user.visible_message(SPAN_NOTICE("\The [user] [anchored ? "secures" : "unsecures"] \the [src].")) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index ad900bea6662..6c442f851c18 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -248,7 +248,7 @@ else z_flags &= ~ZMM_MANGLE_PLANES -/obj/machinery/teleport/station/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/teleport/station/attackby(var/obj/item/used_item, var/mob/user) return attack_hand_with_interaction_checks(user) || ..() /obj/machinery/teleport/station/interface_interact(var/mob/user) diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm index 235da1f889fd..4955f4173658 100644 --- a/code/game/machinery/turret_control.dm +++ b/code/game/machinery/turret_control.dm @@ -84,11 +84,11 @@ return ..() -/obj/machinery/turretid/attackby(obj/item/W, mob/user) +/obj/machinery/turretid/attackby(obj/item/used_item, mob/user) if(stat & BROKEN) return FALSE - if(istype(W, /obj/item/card/id)||istype(W, /obj/item/modular_computer)) + if(istype(used_item, /obj/item/card/id)||istype(used_item, /obj/item/modular_computer)) if(src.allowed(user)) if(emagged) to_chat(user, "The turret control is unresponsive.") diff --git a/code/game/machinery/turrets/_turrets.dm b/code/game/machinery/turrets/_turrets.dm index dd6109cdf461..d61ef7495687 100644 --- a/code/game/machinery/turrets/_turrets.dm +++ b/code/game/machinery/turrets/_turrets.dm @@ -323,12 +323,12 @@ else if(length(potential_targets)) while(length(potential_targets)) - var/weakref/W = potential_targets[1] - potential_targets -= W - if(is_valid_target(W.resolve())) - target = W + var/weakref/target_ref = potential_targets[1] + potential_targets -= target_ref + if(is_valid_target(target_ref.resolve())) + target = target_ref track_target() - return W + return target_ref target = null return null diff --git a/code/game/machinery/turrets/turret_ammo.dm b/code/game/machinery/turrets/turret_ammo.dm index 2ae590923072..9ecc6a049f79 100644 --- a/code/game/machinery/turrets/turret_ammo.dm +++ b/code/game/machinery/turrets/turret_ammo.dm @@ -17,9 +17,9 @@ QDEL_NULL_LIST(stored_ammo) . = ..() -/obj/item/stock_parts/ammo_box/attackby(obj/item/W, mob/user) +/obj/item/stock_parts/ammo_box/attackby(obj/item/used_item, mob/user) . = ..() - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) to_chat(user, SPAN_NOTICE("You dump the ammo stored in \the [src] on the ground.")) for(var/obj/item/ammo_casing/casing as anything in stored_ammo) casing.forceMove(get_turf(src)) @@ -28,8 +28,8 @@ stored_caliber = null return TRUE - if(istype(W, /obj/item/ammo_casing)) - var/obj/item/ammo_casing/casing = W + if(istype(used_item, /obj/item/ammo_casing)) + var/obj/item/ammo_casing/casing = used_item if(stored_caliber && casing.caliber != stored_caliber) to_chat(user, SPAN_WARNING("The caliber of \the [casing] does not match the caliber stored in \the [src]!")) return TRUE @@ -45,8 +45,8 @@ playsound(user, 'sound/weapons/guns/interaction/bullet_insert.ogg', 50, 1) return TRUE - if(istype(W, /obj/item/ammo_magazine)) - var/obj/item/ammo_magazine/magazine = W + if(istype(used_item, /obj/item/ammo_magazine)) + var/obj/item/ammo_magazine/magazine = used_item if(stored_caliber && magazine.caliber != stored_caliber) to_chat(user, SPAN_WARNING("The caliber of \the [magazine] does not match the caliber stored in \the [src]!")) return TRUE diff --git a/code/game/machinery/vending/_vending.dm b/code/game/machinery/vending/_vending.dm index ea38940b2dcd..ae09bc84adad 100644 --- a/code/game/machinery/vending/_vending.dm +++ b/code/game/machinery/vending/_vending.dm @@ -144,9 +144,9 @@ if(!(. = ..()) && isitem(dropping) && istype(user) && user.check_intent(I_FLAG_HELP) && CanPhysicallyInteract(user)) return attempt_to_stock(dropping, user) -/obj/machinery/vending/attackby(obj/item/W, mob/user) +/obj/machinery/vending/attackby(obj/item/used_item, mob/user) - var/obj/item/charge_stick/CS = W.GetChargeStick() + var/obj/item/charge_stick/CS = used_item.GetChargeStick() if (currently_vending && vendor_account && !vendor_account.suspended) if(!vend_ready) @@ -159,8 +159,8 @@ if (CS) paid = pay_with_charge_card(CS) handled = 1 - else if (istype(W, /obj/item/cash)) - var/obj/item/cash/C = W + else if (istype(used_item, /obj/item/cash)) + var/obj/item/cash/C = used_item paid = pay_with_cash(C) handled = 1 @@ -171,23 +171,23 @@ SSnano.update_uis(src) return TRUE // don't smack that machine with your $2 - if (istype(W, /obj/item/cash)) + if (istype(used_item, /obj/item/cash)) attack_hand_with_interaction_checks(user) return TRUE - if(IS_MULTITOOL(W) || IS_WIRECUTTER(W)) + if(IS_MULTITOOL(used_item) || IS_WIRECUTTER(used_item)) if(panel_open) attack_hand_with_interaction_checks(user) return TRUE - if((. = component_attackby(W, user))) + if((. = component_attackby(used_item, user))) return - if((user.check_intent(I_FLAG_HELP)) && attempt_to_stock(W, user)) + if((user.check_intent(I_FLAG_HELP)) && attempt_to_stock(used_item, user)) return TRUE - if((obj_flags & OBJ_FLAG_ANCHORABLE) && (IS_WRENCH(W) || IS_HAMMER(W))) - wrench_floor_bolts(user, null, W) + if((obj_flags & OBJ_FLAG_ANCHORABLE) && (IS_WRENCH(used_item) || IS_HAMMER(used_item))) + wrench_floor_bolts(user, null, used_item) power_change() return @@ -394,14 +394,14 @@ * Add item to the machine * * Checks if item is vendable in this machine should be performed before - * calling. W is the item being inserted, product_record is the associated vending_product entry. + * calling. used_item is the item being inserted, product_record is the associated vending_product entry. */ -/obj/machinery/vending/proc/stock(obj/item/W, var/datum/stored_items/vending_products/product_record, var/mob/user) - if(!user.try_unequip(W)) +/obj/machinery/vending/proc/stock(obj/item/used_item, var/datum/stored_items/vending_products/product_record, var/mob/user) + if(!user.try_unequip(used_item)) return - if(product_record.add_product(W)) - to_chat(user, SPAN_NOTICE("You insert \the [W] in the product receptor.")) + if(product_record.add_product(used_item)) + to_chat(user, SPAN_NOTICE("You insert \the [used_item] in the product receptor.")) SSnano.update_uis(src) return 1 diff --git a/code/game/machinery/wall_frames.dm b/code/game/machinery/wall_frames.dm index f06099ed6e37..19d63aeebfab 100644 --- a/code/game/machinery/wall_frames.dm +++ b/code/game/machinery/wall_frames.dm @@ -16,8 +16,8 @@ for(var/key in cost) .[key] += cost[key] -/obj/item/frame/attackby(obj/item/W, mob/user) - if(IS_WRENCH(W)) +/obj/item/frame/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item)) for(var/key in matter) SSmaterials.create_object(key, get_turf(src), round(matter[key]/SHEET_MATERIAL_AMOUNT)) qdel(src) @@ -278,10 +278,10 @@ return TRUE master_controller_id_tag = null -/obj/item/frame/button/airlock_controller/attackby(obj/item/W, mob/user) - if(!istype(W, /obj/item/stock_parts/circuitboard)) +/obj/item/frame/button/airlock_controller/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/stock_parts/circuitboard)) return ..() - var/obj/item/stock_parts/circuitboard/board = W + var/obj/item/stock_parts/circuitboard/board = used_item var/obj/machinery/M if(ispath(board.build_path, /obj/machinery/embedded_controller/radio)) build_machine_type = board.build_path @@ -291,7 +291,7 @@ . = TRUE if(.) M = build_machine_type - to_chat(user, SPAN_NOTICE("You setup \the [src]'s software to work as a '[initial(M.name)]', using \the [W].")) + to_chat(user, SPAN_NOTICE("You setup \the [src]'s software to work as a '[initial(M.name)]', using \the [used_item].")) return TRUE return FALSE @@ -305,8 +305,8 @@ to_chat(user, SPAN_WARNING("First, use a multitool on the kit to properly setup the controller's software!")) //Let them also hit it with a circuitboard if they so wish. But multitool is better when you don't want to print one for nothing. -/obj/item/frame/button/airlock_controller/kit/attackby(obj/item/W, mob/user) - if(!IS_MULTITOOL(W)) +/obj/item/frame/button/airlock_controller/kit/attackby(obj/item/used_item, mob/user) + if(!IS_MULTITOOL(used_item)) return ..() //Handle kit configuration var/obj/machinery/M = /obj/machinery/dummy_airlock_controller diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 1beca6b072f1..e8fbd8701a10 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -93,20 +93,20 @@ state &= ~WASHER_STATE_RUNNING update_use_power(POWER_USE_IDLE) -/obj/machinery/washing_machine/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/chems/pill/detergent)) +/obj/machinery/washing_machine/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/chems/pill/detergent)) if(!(atom_flags & ATOM_FLAG_OPEN_CONTAINER)) to_chat(user, SPAN_WARNING("Open the detergent port first!")) return TRUE if(reagents.total_volume >= reagents.maximum_volume) to_chat(user, SPAN_WARNING("The detergent port is full!")) return TRUE - if(!user.try_unequip(W)) + if(!user.try_unequip(used_item)) return TRUE // Directly transfer to the holder to avoid touch reactions. - W.reagents?.trans_to_holder(reagents, W.reagents.total_volume) - to_chat(user, SPAN_NOTICE("You dissolve \the [W] in the detergent port.")) - qdel(W) + used_item.reagents?.trans_to_holder(reagents, used_item.reagents.total_volume) + to_chat(user, SPAN_NOTICE("You dissolve \the [used_item] in the detergent port.")) + qdel(used_item) return TRUE if(state & WASHER_STATE_RUNNING) @@ -114,30 +114,30 @@ return TRUE // If the detergent port is open and the item is an open container, assume we're trying to fill the detergent port. - if(!(state & WASHER_STATE_CLOSED) && !((atom_flags & W.atom_flags) & ATOM_FLAG_OPEN_CONTAINER)) + if(!(state & WASHER_STATE_CLOSED) && !((atom_flags & used_item.atom_flags) & ATOM_FLAG_OPEN_CONTAINER)) var/list/wash_whitelist = get_wash_whitelist() var/list/wash_blacklist = get_wash_blacklist() var/list/washing_atoms = get_contained_external_atoms() if(length(washing_atoms) < 5) - if(istype(W, /obj/item/holder)) // Mob holder - for(var/mob/living/doggy in W) + if(istype(used_item, /obj/item/holder)) // Mob holder + for(var/mob/living/doggy in used_item) doggy.forceMove(src) - qdel(W) + qdel(used_item) state |= WASHER_STATE_LOADED update_icon() return TRUE // An empty whitelist implies all items can be washed. - else if((!length(wash_whitelist) || is_type_in_list(W, wash_whitelist)) && !is_type_in_list(W, wash_blacklist)) - if(W.w_class > max_item_size) - to_chat(user, SPAN_WARNING("\The [W] is too large for \the [src]!")) + else if((!length(wash_whitelist) || is_type_in_list(used_item, wash_whitelist)) && !is_type_in_list(used_item, wash_blacklist)) + if(used_item.w_class > max_item_size) + to_chat(user, SPAN_WARNING("\The [used_item] is too large for \the [src]!")) return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE state |= WASHER_STATE_LOADED update_icon() else - to_chat(user, SPAN_WARNING("You can't put \the [W] in \the [src].")) + to_chat(user, SPAN_WARNING("You can't put \the [used_item] in \the [src].")) return TRUE else to_chat(user, SPAN_NOTICE("\The [src] is full.")) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index 5fae22fc6003..9540a4d466ac 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -196,8 +196,8 @@ /obj/effect/decal/cleanable/blood/writing/Initialize() . = ..() if(LAZYLEN(random_icon_states)) - for(var/obj/effect/decal/cleanable/blood/writing/W in loc) - random_icon_states.Remove(W.icon_state) + for(var/obj/effect/decal/cleanable/blood/writing/writing in loc) + random_icon_states.Remove(writing.icon_state) icon_state = pick(random_icon_states) else icon_state = "writing1" diff --git a/code/game/objects/effects/gateway.dm b/code/game/objects/effects/gateway.dm index 2b6be989f274..61c3250d6462 100644 --- a/code/game/objects/effects/gateway.dm +++ b/code/game/objects/effects/gateway.dm @@ -54,10 +54,10 @@ var/mob/living/silicon/robot/Robot = victim QDEL_NULL(Robot.central_processor) else - for(var/obj/item/W in victim) - victim.drop_from_inventory(W) - if(istype(W, /obj/item/implant)) - qdel(W) + for(var/obj/item/thing in victim) + victim.drop_from_inventory(thing) + if(istype(thing, /obj/item/implant)) + qdel(thing) var/mob/living/new_mob = new /mob/living/simple_animal/corgi(AM.loc) new_mob.set_intent(I_FLAG_HARM) diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index bcfac656cfd2..48f931aef161 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -26,11 +26,11 @@ return INITIALIZE_HINT_LATELOAD /obj/effect/paint/LateInitialize() - var/turf/wall/W = get_turf(src) - if(istype(W)) - W.paint_color = color - W.stripe_color = color - W.update_icon() + var/turf/wall/wall = get_turf(src) + if(istype(wall)) + wall.paint_color = color + wall.stripe_color = color + wall.update_icon() var/obj/structure/wall_frame/WF = locate() in loc if(WF) WF.paint_color = color @@ -72,10 +72,10 @@ return INITIALIZE_HINT_LATELOAD /obj/effect/paint_stripe/LateInitialize() - var/turf/wall/W = get_turf(src) - if(istype(W)) - W.stripe_color = color - W.update_icon() + var/turf/wall/wall = get_turf(src) + if(istype(wall)) + wall.stripe_color = color + wall.update_icon() var/obj/structure/wall_frame/WF = locate() in loc if(WF) WF.stripe_color = color diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 2aae839cd613..c2e1269fd6d6 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -33,23 +33,23 @@ die() return TRUE -/obj/effect/spider/attackby(var/obj/item/W, var/mob/user) +/obj/effect/spider/attackby(var/obj/item/used_item, var/mob/user) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - if(W.attack_verb.len) - visible_message("\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]") + if(used_item.attack_verb.len) + visible_message("\The [src] has been [pick(used_item.attack_verb)] with \the [used_item][(user ? " by [user]." : ".")]") else - visible_message("\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]") + visible_message("\The [src] has been attacked with \the [used_item][(user ? " by [user]." : ".")]") - var/damage = W.expend_attack_force(user) / 4 + var/damage = used_item.expend_attack_force(user) / 4 - if(W.has_edge()) + if(used_item.has_edge()) damage += 5 - if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item - if(WT.weld(0, user)) + if(welder.weld(0, user)) damage = 15 playsound(loc, 'sound/items/Welder.ogg', 100, 1) @@ -194,7 +194,7 @@ stop_automove() . = ..() -/obj/effect/spider/spiderling/attackby(var/obj/item/W, var/mob/user) +/obj/effect/spider/spiderling/attackby(var/obj/item/used_item, var/mob/user) . = ..() if(current_health > 0) disturbed() diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index df4905d658c8..539765bd32ec 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -591,10 +591,10 @@ if(robot.hud_used) robot.hud_used.update_robot_modules_display() -/obj/item/proc/try_slapcrafting(obj/item/W, mob/user) - if(SSfabrication.try_craft_with(src, W, user)) +/obj/item/proc/try_slapcrafting(obj/item/used_item, mob/user) + if(SSfabrication.try_craft_with(src, used_item, user)) return TRUE - if(SSfabrication.try_craft_with(W, src, user)) + if(SSfabrication.try_craft_with(used_item, src, user)) return TRUE return FALSE diff --git a/code/game/objects/items/blades/axe.dm b/code/game/objects/items/blades/axe.dm index 9bda1a9a1345..ab902f9187a4 100644 --- a/code/game/objects/items/blades/axe.dm +++ b/code/game/objects/items/blades/axe.dm @@ -19,8 +19,8 @@ . = ..() if(proximity && A && is_held_twohanded()) if(istype(A,/obj/structure/window)) - var/obj/structure/window/W = A - W.shatter() + var/obj/structure/window/window = A + window.shatter() else if(istype(A,/obj/structure/grille)) qdel(A) else if(istype(A,/obj/effect/vine)) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 120f974374b8..f3b1c0e3a00a 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -62,8 +62,8 @@ if(LAZYLEN(lbls?.labels)) add_overlay("bodybag_label") -/obj/structure/closet/body_bag/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/hand_labeler)) +/obj/structure/closet/body_bag/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/hand_labeler)) return FALSE //Prevent the labeler from opening the bag when trying to apply a label . = ..() diff --git a/code/game/objects/items/books/_book.dm b/code/game/objects/items/books/_book.dm index a71fd39032a7..437c18ebf6be 100644 --- a/code/game/objects/items/books/_book.dm +++ b/code/game/objects/items/books/_book.dm @@ -84,9 +84,9 @@ else to_chat(user, SPAN_WARNING("This book is completely blank!")) -/obj/item/book/attackby(obj/item/W, mob/user) +/obj/item/book/attackby(obj/item/used_item, mob/user) - if(IS_PEN(W)) + if(IS_PEN(used_item)) if(unique) to_chat(user, SPAN_WARNING("These pages don't seem to take the ink well. Looks like you can't modify it.")) return TRUE @@ -113,7 +113,7 @@ if(content) last_modified_ckey = user.ckey pencode_dat = content - dat = formatpencode(usr, content, W) + dat = formatpencode(usr, content, used_item) if("Author") var/newauthor = sanitize(input(usr, "Write the author's name:")) @@ -126,7 +126,7 @@ author = newauthor return TRUE - if((IS_KNIFE(W) || IS_WIRECUTTER(W)) && user.check_intent(I_FLAG_HARM) && try_carve(user, W)) + if((IS_KNIFE(used_item) || IS_WIRECUTTER(used_item)) && user.check_intent(I_FLAG_HARM) && try_carve(user, used_item)) return TRUE return ..() diff --git a/code/game/objects/items/candelabra.dm b/code/game/objects/items/candelabra.dm index 1f82ec443aa7..2d1f10f3d77e 100644 --- a/code/game/objects/items/candelabra.dm +++ b/code/game/objects/items/candelabra.dm @@ -7,7 +7,7 @@ list("x" = 6, "y" = 17) ) -/datum/storage/candelabra/can_be_inserted(obj/item/W, mob/user, stop_messages, click_params) +/datum/storage/candelabra/can_be_inserted(obj/item/used_item, mob/user, stop_messages, click_params) . = ..() && holder && length(holder.get_stored_inventory()) < length(candle_offsets) /obj/item/candelabra diff --git a/code/game/objects/items/devices/boombox.dm b/code/game/objects/items/devices/boombox.dm index fc3850c843bc..aae620ddeddb 100644 --- a/code/game/objects/items/devices/boombox.dm +++ b/code/game/objects/items/devices/boombox.dm @@ -91,22 +91,22 @@ change_volume(volume - 10) return TOPIC_HANDLED -/obj/item/boombox/attackby(var/obj/item/W, var/mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/boombox/attackby(var/obj/item/used_item, var/mob/user) + if(IS_SCREWDRIVER(used_item)) if(!panel) - user.visible_message(SPAN_NOTICE("\The [user] re-attaches \the [src]'s front panel with \the [W]."), SPAN_NOTICE("You re-attach \the [src]'s front panel.")) + user.visible_message(SPAN_NOTICE("\The [user] re-attaches \the [src]'s front panel with \the [used_item]."), SPAN_NOTICE("You re-attach \the [src]'s front panel.")) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) panel = TRUE return TRUE if(!broken) - AdjustFrequency(W, user) + AdjustFrequency(used_item, user) return TRUE else if(panel) - user.visible_message(SPAN_NOTICE("\The [user] unhinges \the [src]'s front panel with \the [W]."), SPAN_NOTICE("You unhinge \the [src]'s front panel.")) + user.visible_message(SPAN_NOTICE("\The [user] unhinges \the [src]'s front panel with \the [used_item]."), SPAN_NOTICE("You unhinge \the [src]'s front panel.")) playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) panel = FALSE - if(istype(W,/obj/item/stack/nanopaste)) - var/obj/item/stack/S = W + if(istype(used_item,/obj/item/stack/nanopaste)) + var/obj/item/stack/S = used_item if(broken && !panel) if(S.use(1)) user.visible_message(SPAN_NOTICE("\The [user] pours some of \the [S] onto \the [src]."), SPAN_NOTICE("You pour some of \the [S] over \the [src]'s internals and watch as it retraces and resolders paths.")) @@ -116,7 +116,7 @@ else . = ..() -/obj/item/boombox/proc/AdjustFrequency(var/obj/item/W, var/mob/user) +/obj/item/boombox/proc/AdjustFrequency(var/obj/item/used_item, var/mob/user) var/const/MIN_FREQUENCY = 0.5 var/const/MAX_FREQUENCY = 1.5 @@ -137,7 +137,7 @@ return FALSE if(!MayAdjust(user)) return FALSE - if(W != user.get_active_held_item()) + if(used_item != user.get_active_held_item()) return FALSE if(!CanPhysicallyInteract(user)) diff --git a/code/game/objects/items/devices/hacktool.dm b/code/game/objects/items/devices/hacktool.dm index 1b06acd9f0d3..88ebe70cf775 100644 --- a/code/game/objects/items/devices/hacktool.dm +++ b/code/game/objects/items/devices/hacktool.dm @@ -23,8 +23,8 @@ hack_state = null return ..() -/obj/item/multitool/hacktool/attackby(var/obj/item/W, var/mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/multitool/hacktool/attackby(var/obj/item/used_item, var/mob/user) + if(IS_SCREWDRIVER(used_item)) in_hack_mode = !in_hack_mode playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, 1) return TRUE diff --git a/code/game/objects/items/devices/holowarrant.dm b/code/game/objects/items/devices/holowarrant.dm index ff3fe45f5725..624d4f818656 100644 --- a/code/game/objects/items/devices/holowarrant.dm +++ b/code/game/objects/items/devices/holowarrant.dm @@ -58,9 +58,9 @@ if(href_list["select"]) var/list/active_warrants = list() - for(var/datum/computer_file/report/warrant/W in global.all_warrants) - if(!W.archived) - active_warrants["[capitalize(W.get_category())] - [W.get_name()]"] = W + for(var/datum/computer_file/report/warrant/warrant in global.all_warrants) + if(!warrant.archived) + active_warrants["[capitalize(warrant.get_category())] - [warrant.get_name()]"] = warrant if(!length(active_warrants)) to_chat(user,SPAN_WARNING("There are no active warrants available.")) return TOPIC_HANDLED @@ -81,10 +81,10 @@ D.ui_interact(user) return TOPIC_HANDLED -/obj/item/holowarrant/attackby(obj/item/W, mob/user) +/obj/item/holowarrant/attackby(obj/item/used_item, mob/user) if(!active) return ..() - var/obj/item/card/id/I = W.GetIdCard() + var/obj/item/card/id/I = used_item.GetIdCard() if(I && check_access_list(I.GetAccess())) var/choice = alert(user, "Would you like to authorize this warrant?","Warrant authorization","Yes","No") var/datum/report_field/signature/auth = active.field_from_name("Authorized by") diff --git a/code/game/objects/items/devices/inducer.dm b/code/game/objects/items/devices/inducer.dm index 77527d8e98a0..bb84d497a164 100644 --- a/code/game/objects/items/devices/inducer.dm +++ b/code/game/objects/items/devices/inducer.dm @@ -46,8 +46,8 @@ return TRUE return FALSE -/obj/item/inducer/attackby(obj/item/W, mob/user) - if(CannotUse(user) || recharge(W, user)) +/obj/item/inducer/attackby(obj/item/used_item, mob/user) + if(CannotUse(user) || recharge(used_item, user)) return TRUE return ..() diff --git a/code/game/objects/items/devices/lightreplacer.dm b/code/game/objects/items/devices/lightreplacer.dm index 7b04cb53c3f2..df209e9cc0d5 100644 --- a/code/game/objects/items/devices/lightreplacer.dm +++ b/code/game/objects/items/devices/lightreplacer.dm @@ -91,9 +91,9 @@ . = ..() // TODO: Refactor this to check matter or maybe even just use the fabricator recipe for lights directly -/obj/item/lightreplacer/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/stack/material) && W.get_material_type() == /decl/material/solid/glass) - var/obj/item/stack/G = W +/obj/item/lightreplacer/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/stack/material) && used_item.get_material_type() == /decl/material/solid/glass) + var/obj/item/stack/G = used_item if(uses >= max_uses) to_chat(user, "\The [src] is full.") else if(G.use(1)) @@ -103,8 +103,8 @@ to_chat(user, "You need one sheet of glass to replace lights.") return TRUE - if(istype(W, /obj/item/light)) - var/obj/item/light/L = W + if(istype(used_item, /obj/item/light)) + var/obj/item/light/L = used_item if(L.status == 0) // LIGHT OKAY if(uses < max_uses) if(!user.try_unequip(L)) diff --git a/code/game/objects/items/devices/paint_sprayer.dm b/code/game/objects/items/devices/paint_sprayer.dm index 90c99edcaacc..33f49ba11395 100644 --- a/code/game/objects/items/devices/paint_sprayer.dm +++ b/code/game/objects/items/devices/paint_sprayer.dm @@ -143,46 +143,46 @@ return . -/obj/item/paint_sprayer/proc/paint_wall(var/turf/wall/W, var/mob/user) - if(istype(W) && (!W.material || !W.material.wall_flags)) +/obj/item/paint_sprayer/proc/paint_wall(var/turf/wall/wall, var/mob/user) + if(istype(wall) && (!wall.material || !wall.material.wall_flags)) to_chat(user, SPAN_WARNING("You can't paint this wall type.")) return var/choice - if(W.material.wall_flags & PAINT_PAINTABLE && W.material.wall_flags & PAINT_STRIPABLE) + if(wall.material.wall_flags & PAINT_PAINTABLE && wall.material.wall_flags & PAINT_STRIPABLE) choice = input(user, "What do you wish to paint?") as null|anything in list(PAINT_REGION_PAINT,PAINT_REGION_STRIPE) - else if(W.material.wall_flags & PAINT_PAINTABLE) + else if(wall.material.wall_flags & PAINT_PAINTABLE) choice = PAINT_REGION_PAINT - else if(W.material.wall_flags & PAINT_STRIPABLE) + else if(wall.material.wall_flags & PAINT_STRIPABLE) choice = PAINT_REGION_STRIPE - if (user.incapacitated() || !W || !user.Adjacent(W)) + if (user.incapacitated() || !wall || !user.Adjacent(wall)) return FALSE if(choice == PAINT_REGION_PAINT) - W.paint_wall(spray_color) + wall.paint_wall(spray_color) else if(choice == PAINT_REGION_STRIPE) - W.stripe_wall(spray_color) + wall.stripe_wall(spray_color) -/obj/item/paint_sprayer/proc/pick_color_from_wall(var/turf/wall/W, var/mob/user) - if (!W.material || !W.material.wall_flags) +/obj/item/paint_sprayer/proc/pick_color_from_wall(var/turf/wall/wall, var/mob/user) + if (!wall.material || !wall.material.wall_flags) return FALSE - switch (select_wall_region(W, user, "Where do you wish to select the color from?")) + switch (select_wall_region(wall, user, "Where do you wish to select the color from?")) if (PAINT_REGION_PAINT) - return W.paint_color + return wall.paint_color if (PAINT_REGION_STRIPE) - return W.stripe_color + return wall.stripe_color else return FALSE -/obj/item/paint_sprayer/proc/select_wall_region(var/turf/wall/W, var/mob/user, var/input_text) +/obj/item/paint_sprayer/proc/select_wall_region(var/turf/wall/wall, var/mob/user, var/input_text) var/list/choices = list() - if (W.material.wall_flags & PAINT_PAINTABLE) + if (wall.material.wall_flags & PAINT_PAINTABLE) choices |= PAINT_REGION_PAINT - if (W.material.wall_flags & PAINT_STRIPABLE) + if (wall.material.wall_flags & PAINT_STRIPABLE) choices |= PAINT_REGION_STRIPE var/choice = input(user, input_text) as null|anything in sortTim(choices, /proc/cmp_text_asc) - if (user.incapacitated() || !W || !user.Adjacent(W)) + if (user.incapacitated() || !wall || !user.Adjacent(wall)) return FALSE return choice diff --git a/code/game/objects/items/devices/radio/encryptionkey.dm b/code/game/objects/items/devices/radio/encryptionkey.dm index dc29d7b3e4b4..bcc1ab952fbe 100644 --- a/code/game/objects/items/devices/radio/encryptionkey.dm +++ b/code/game/objects/items/devices/radio/encryptionkey.dm @@ -43,17 +43,17 @@ return TRUE . = ..() -/obj/item/encryptionkey/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/card/id)) - var/obj/item/card/id/id = W +/obj/item/encryptionkey/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/card/id)) + var/obj/item/card/id/id = used_item var/list/access = id.GetAccess() if(!length(access)) - to_chat(user, SPAN_WARNING("\The [W] has no access keys to copy.")) + to_chat(user, SPAN_WARNING("\The [used_item] has no access keys to copy.")) return TRUE LAZYINITLIST(can_decrypt) can_decrypt |= access UNSETEMPTY(can_decrypt) - to_chat(user, SPAN_NOTICE("You pass \the [W] across \the [src], copying the access keys into the encryption cache.")) + to_chat(user, SPAN_NOTICE("You pass \the [used_item] across \the [src], copying the access keys into the encryption cache.")) return TRUE . = ..() diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 081365675f01..7277834d2d25 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -456,22 +456,22 @@ if(panel_open) . += SPAN_WARNING("A panel on the back of \the [src] is hanging open.") -/obj/item/radio/attackby(obj/item/W, mob/user) +/obj/item/radio/attackby(obj/item/used_item, mob/user) user.set_machine(src) - if(istype(W, /obj/item/encryptionkey)) + if(istype(used_item, /obj/item/encryptionkey)) if(!encryption_key_capacity) to_chat(user, SPAN_WARNING("\The [src] cannot accept an encryption key.")) return TRUE if(length(encryption_keys) >= encryption_key_capacity) to_chat(user, SPAN_WARNING("\The [src] cannot fit any more encryption keys.")) return TRUE - if(user.try_unequip(W, src)) - LAZYADD(encryption_keys, W) + if(user.try_unequip(used_item, src)) + LAZYADD(encryption_keys, used_item) channels = null return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) if(length(encryption_keys)) var/obj/item/encryptionkey/ekey = pick(encryption_keys) ekey.dropInto(loc) diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm index c3cf46fe3b81..518b43c3d377 100644 --- a/code/game/objects/items/devices/spy_bug.dm +++ b/code/game/objects/items/devices/spy_bug.dm @@ -38,13 +38,12 @@ /obj/item/spy_bug/attack_self(mob/user) radio.attack_self(user) -/obj/item/spy_bug/attackby(obj/W, mob/user) - if(istype(W, /obj/item/spy_monitor)) - var/obj/item/spy_monitor/SM = W +/obj/item/spy_bug/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/spy_monitor)) + var/obj/item/spy_monitor/SM = used_item SM.pair(src, user) return TRUE - else - return ..() + return ..() /obj/item/spy_bug/hear_talk(mob/M, var/msg, verb, decl/language/speaking) radio.hear_talk(M, msg, speaking) @@ -88,12 +87,11 @@ radio.attack_self(user) view_cameras(user) -/obj/item/spy_monitor/attackby(obj/W, mob/user) - if(istype(W, /obj/item/spy_bug)) - pair(W, user) +/obj/item/spy_monitor/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/spy_bug)) + pair(used_item, user) return TRUE - else - return ..() + return ..() /obj/item/spy_monitor/proc/pair(var/obj/item/spy_bug/SB, var/mob/living/user) to_chat(user, SPAN_NOTICE("\The [SB] has been paired with \the [src].")) diff --git a/code/game/objects/items/devices/suit_cooling.dm b/code/game/objects/items/devices/suit_cooling.dm index 27b044c6a1d0..a8cbf50f10b3 100644 --- a/code/game/objects/items/devices/suit_cooling.dm +++ b/code/game/objects/items/devices/suit_cooling.dm @@ -106,8 +106,8 @@ turn_on() to_chat(user, "You switch \the [src] [on ? "on" : "off"].") -/obj/item/suit_cooling_unit/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/suit_cooling_unit/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) if(cover_open) cover_open = 0 to_chat(user, "You screw the panel into place.") @@ -117,14 +117,14 @@ update_icon() return TRUE - if (istype(W, /obj/item/cell)) + if (istype(used_item, /obj/item/cell)) if(cover_open) if(cell) to_chat(user, "There is a [cell] already installed here.") else - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - cell = W + cell = used_item to_chat(user, "You insert \the [cell].") update_icon() return TRUE diff --git a/code/game/objects/items/devices/tvcamera.dm b/code/game/objects/items/devices/tvcamera.dm index 914286faa0f3..753ead692e42 100644 --- a/code/game/objects/items/devices/tvcamera.dm +++ b/code/game/objects/items/devices/tvcamera.dm @@ -120,25 +120,25 @@ Using robohead because of restricting to roboticist */ material = /decl/material/solid/metal/steel // TODO: refactor this to use slapcrafting? remove entirely? -/obj/item/TVAssembly/attackby(var/obj/item/W, var/mob/user) +/obj/item/TVAssembly/attackby(var/obj/item/used_item, var/mob/user) switch(buildstep) if(0) - if(istype(W, /obj/item/robot_parts/robot_component/camera)) + if(istype(used_item, /obj/item/robot_parts/robot_component/camera)) to_chat(user, "You add the camera module to [src]") - qdel(W) + qdel(used_item) desc = "This TV camera assembly has a camera module." buildstep++ return TRUE if(1) - if(istype(W, /obj/item/taperecorder)) - qdel(W) + if(istype(used_item, /obj/item/taperecorder)) + qdel(used_item) buildstep++ to_chat(user, "You add the tape recorder to [src]") desc = "This TV camera assembly has a camera and audio module." return TRUE if(2) - if(IS_COIL(W)) - var/obj/item/stack/cable_coil/C = W + if(IS_COIL(used_item)) + var/obj/item/stack/cable_coil/C = used_item if(!C.use(3)) to_chat(user, "You need three cable coils to wire the devices.") return TRUE @@ -147,14 +147,14 @@ Using robohead because of restricting to roboticist */ desc = "This TV camera assembly has wires sticking out." return TRUE if(3) - if(IS_WIRECUTTER(W)) + if(IS_WIRECUTTER(used_item)) to_chat(user, " You trim the wires.") buildstep++ desc = "This TV camera assembly needs casing." return TRUE if(4) - if(istype(W, /obj/item/stack/material)) - var/obj/item/stack/material/S = W + if(istype(used_item, /obj/item/stack/material)) + var/obj/item/stack/material/S = used_item if(S.material?.type == /decl/material/solid/metal/steel && S.use(1)) buildstep++ to_chat(user, "You encase the assembly.") diff --git a/code/game/objects/items/glassjar.dm b/code/game/objects/items/glassjar.dm index 22e99321baa3..6c6a654fb2fc 100644 --- a/code/game/objects/items/glassjar.dm +++ b/code/game/objects/items/glassjar.dm @@ -71,15 +71,15 @@ update_icon() return -/obj/item/glass_jar/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/cash)) +/obj/item/glass_jar/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/cash)) if(contains == 0) contains = 1 if(contains != 1) return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - var/obj/item/cash/S = W + var/obj/item/cash/S = used_item user.visible_message("[user] puts \the [S] into \the [src].") update_icon() return TRUE diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm index 6066fbeaedef..cf070a49deef 100644 --- a/code/game/objects/items/latexballoon.dm +++ b/code/game/objects/items/latexballoon.dm @@ -43,8 +43,8 @@ burst() return ..() -/obj/item/latexballon/attackby(obj/item/W, mob/user) - if (W.can_puncture()) +/obj/item/latexballon/attackby(obj/item/used_item, mob/user) + if (used_item.can_puncture()) burst() return TRUE return FALSE diff --git a/code/game/objects/items/rescuebag.dm b/code/game/objects/items/rescuebag.dm index 15fbf7a53dea..df7b9225027f 100644 --- a/code/game/objects/items/rescuebag.dm +++ b/code/game/objects/items/rescuebag.dm @@ -31,17 +31,17 @@ airtank = null return bag -/obj/item/bodybag/rescue/attackby(obj/item/W, mob/user, var/click_params) - if(istype(W,/obj/item/tank)) +/obj/item/bodybag/rescue/attackby(obj/item/used_item, mob/user, var/click_params) + if(istype(used_item,/obj/item/tank)) if(airtank) to_chat(user, "\The [src] already has an air tank installed.") return TRUE - if(user.try_unequip(W)) - W.forceMove(src) - airtank = W - to_chat(user, "You install \the [W] in \the [src].") + if(user.try_unequip(used_item)) + used_item.forceMove(src) + airtank = used_item + to_chat(user, "You install \the [used_item] in \the [src].") return TRUE - else if(airtank && IS_SCREWDRIVER(W)) + else if(airtank && IS_SCREWDRIVER(used_item)) to_chat(user, "You remove \the [airtank] from \the [src].") airtank.dropInto(loc) airtank = null @@ -88,15 +88,15 @@ if(airtank) add_overlay("tank") -/obj/structure/closet/body_bag/rescue/attackby(obj/item/W, mob/user, var/click_params) - if(istype(W,/obj/item/tank)) +/obj/structure/closet/body_bag/rescue/attackby(obj/item/used_item, mob/user, var/click_params) + if(istype(used_item,/obj/item/tank)) if(airtank) to_chat(user, "\The [src] already has an air tank installed.") - else if(user.try_unequip(W, src)) - set_tank(W) - to_chat(user, "You install \the [W] in \the [src].") + else if(user.try_unequip(used_item, src)) + set_tank(used_item) + to_chat(user, "You install \the [used_item] in \the [src].") return TRUE - else if(airtank && IS_SCREWDRIVER(W)) + else if(airtank && IS_SCREWDRIVER(used_item)) to_chat(user, "You remove \the [airtank] from \the [src].") airtank.dropInto(loc) airtank = null diff --git a/code/game/objects/items/robot/robot_frame.dm b/code/game/objects/items/robot/robot_frame.dm index 24f7474aa6e1..2759cbc834e3 100644 --- a/code/game/objects/items/robot/robot_frame.dm +++ b/code/game/objects/items/robot/robot_frame.dm @@ -32,10 +32,10 @@ SSstatistics.add_field("cyborg_frames_built",1) return TRUE -/obj/item/robot_parts/robot_suit/attackby(obj/item/W, mob/user) +/obj/item/robot_parts/robot_suit/attackby(obj/item/used_item, mob/user) // Uninstall a robotic part. - if(IS_CROWBAR(W)) + if(IS_CROWBAR(used_item)) if(!parts.len) to_chat(user, SPAN_WARNING("\The [src] has no parts to remove.")) return TRUE @@ -49,40 +49,40 @@ return TRUE // Install a robotic part. - else if (istype(W, /obj/item/robot_parts)) - var/obj/item/robot_parts/part = W - if(!required_parts[part.bp_tag] || !istype(W, required_parts[part.bp_tag])) - to_chat(user, SPAN_WARNING("\The [src] is not compatible with \the [W].")) + else if (istype(used_item, /obj/item/robot_parts)) + var/obj/item/robot_parts/part = used_item + if(!required_parts[part.bp_tag] || !istype(used_item, required_parts[part.bp_tag])) + to_chat(user, SPAN_WARNING("\The [src] is not compatible with \the [used_item].")) else if(parts[part.bp_tag]) - to_chat(user, SPAN_WARNING("\The [src] already has \a [W] installed.")) - else if(part.can_install(user) && user.try_unequip(W, src)) + to_chat(user, SPAN_WARNING("\The [src] already has \a [used_item] installed.")) + else if(part.can_install(user) && user.try_unequip(used_item, src)) parts[part.bp_tag] = part update_icon() return TRUE // Install a brain. - else if(istype(W, /obj/item/organ/internal/brain_interface)) + else if(istype(used_item, /obj/item/organ/internal/brain_interface)) if(!isturf(loc)) - to_chat(user, SPAN_WARNING("You can't put \the [W] in without the frame being on the ground.")) + to_chat(user, SPAN_WARNING("You can't put \the [used_item] in without the frame being on the ground.")) return TRUE if(!check_completion()) to_chat(user, SPAN_WARNING("The frame is not ready for the central processor to be installed.")) return TRUE - var/obj/item/organ/internal/brain_interface/M = W + var/obj/item/organ/internal/brain_interface/M = used_item var/mob/living/brainmob = M?.get_brainmob() if(!brainmob) - to_chat(user, SPAN_WARNING("Sticking an empty [W.name] into the frame would sort of defeat the purpose.")) + to_chat(user, SPAN_WARNING("Sticking an empty [used_item.name] into the frame would sort of defeat the purpose.")) return TRUE if(jobban_isbanned(brainmob, ASSIGNMENT_ROBOT)) - to_chat(user, SPAN_WARNING("\The [W] does not seem to fit.")) + to_chat(user, SPAN_WARNING("\The [used_item] does not seem to fit.")) return TRUE if(brainmob.stat == DEAD) - to_chat(user, SPAN_WARNING("Sticking a dead [W.name] into the frame would sort of defeat the purpose.")) + to_chat(user, SPAN_WARNING("Sticking a dead [used_item.name] into the frame would sort of defeat the purpose.")) return TRUE var/ghost_can_reenter = 0 @@ -95,10 +95,10 @@ else ghost_can_reenter = 1 if(!ghost_can_reenter) - to_chat(user, SPAN_WARNING("\The [W] is completely unresponsive; there's no point.")) + to_chat(user, SPAN_WARNING("\The [used_item] is completely unresponsive; there's no point.")) return TRUE - if(!user.try_unequip(W)) + if(!user.try_unequip(used_item)) return TRUE SSstatistics.add_field("cyborg_frames_built",1) @@ -106,7 +106,7 @@ if(!O) return TRUE - O.central_processor = W + O.central_processor = used_item O.set_invisibility(INVISIBILITY_NONE) O.custom_name = created_name O.updatename("Default") @@ -120,7 +120,7 @@ var/obj/item/robot_parts/chest/chest = parts[BP_CHEST] chest.cell.forceMove(O) - W.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. + used_item.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame. // Since we "magically" installed a cell, we also have to update the correct component. if(O.cell) @@ -134,7 +134,7 @@ qdel(src) return TRUE - else if(IS_PEN(W)) + else if(IS_PEN(used_item)) var/t = sanitize_safe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN) if(t && (in_range(src, user) || loc == user)) created_name = t diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm index 8eabec403ce8..3fde339bc303 100644 --- a/code/game/objects/items/robot/robot_parts.dm +++ b/code/game/objects/items/robot/robot_parts.dm @@ -106,54 +106,54 @@ success = FALSE return success && ..() -/obj/item/robot_parts/chest/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/cell)) +/obj/item/robot_parts/chest/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/cell)) if(src.cell) to_chat(user, "You have already inserted a cell!") else - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - src.cell = W + src.cell = used_item to_chat(user, "You insert the cell!") return TRUE - if(IS_COIL(W)) + if(IS_COIL(used_item)) if(src.wires) to_chat(user, "You have already inserted wire!") else - var/obj/item/stack/cable_coil/coil = W + var/obj/item/stack/cable_coil/coil = used_item if(coil.use(1)) src.wires = 1.0 to_chat(user, "You insert the wire!") return TRUE return ..() -/obj/item/robot_parts/head/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/flash)) +/obj/item/robot_parts/head/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/flash)) if(isrobot(user)) var/current_module = user.get_active_held_item() - if(current_module == W) + if(current_module == used_item) to_chat(user, "How do you propose to do that?") return TRUE else - add_flashes(W,user) + add_flashes(used_item,user) else - add_flashes(W,user) + add_flashes(used_item,user) return TRUE return ..() -/obj/item/robot_parts/head/proc/add_flashes(obj/item/W, mob/user) //Made into a seperate proc to avoid copypasta +/obj/item/robot_parts/head/proc/add_flashes(obj/item/used_item, mob/user) //Made into a seperate proc to avoid copypasta if(src.flash1 && src.flash2) to_chat(user, "You have already inserted the eyes!") return else if(src.flash1) - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return - src.flash2 = W + src.flash2 = used_item to_chat(user, "You insert the flash into the eye socket!") else - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return - src.flash1 = W + src.flash1 = used_item to_chat(user, "You insert the flash into the eye socket!") diff --git a/code/game/objects/items/rock.dm b/code/game/objects/items/rock.dm index 4a57b5ab4dde..ff0f5189bb5c 100644 --- a/code/game/objects/items/rock.dm +++ b/code/game/objects/items/rock.dm @@ -17,9 +17,9 @@ )) // TODO: craft a flint striker from a flint and a piece of metal -/obj/item/rock/attackby(obj/item/W, mob/user) +/obj/item/rock/attackby(obj/item/used_item, mob/user) - var/decl/material/weapon_material = W.get_striking_material() + var/decl/material/weapon_material = used_item.get_striking_material() var/decl/material/our_material = get_material() if((weapon_material?.ferrous && our_material?.type == /decl/material/solid/stone/flint) || (our_material?.ferrous && weapon_material?.type == /decl/material/solid/stone/flint)) var/turf/spark_turf = get_turf(src) diff --git a/code/game/objects/items/stacks/rods.dm b/code/game/objects/items/stacks/rods.dm index 7e244c18453f..1a8d655c9dd1 100644 --- a/code/game/objects/items/stacks/rods.dm +++ b/code/game/objects/items/stacks/rods.dm @@ -47,17 +47,17 @@ icon_state = base_state // TODO: slapcrafting recipes to replace this block. -/obj/item/stack/material/rods/attackby(obj/item/W, mob/user) +/obj/item/stack/material/rods/attackby(obj/item/used_item, mob/user) - if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(!can_use(2)) to_chat(user, SPAN_WARNING("You need at least two rods to do this.")) return TRUE - if(WT.weld(0,user)) - visible_message(SPAN_NOTICE("\The [src] is fused together by \the [user] with \the [WT]."), 3, SPAN_NOTICE("You hear welding."), 2) + if(welder.weld(0,user)) + visible_message(SPAN_NOTICE("\The [src] is fused together by \the [user] with \the [welder]."), 3, SPAN_NOTICE("You hear welding."), 2) for(var/obj/item/stack/material/new_item in SSmaterials.create_object((material?.type || /decl/material/solid/metal/steel), usr.loc, 1)) new_item.add_to_stacks(usr) if(user.is_holding_offhand(src)) @@ -65,8 +65,8 @@ use(2) return TRUE - if (istype(W, /obj/item/stack/tape_roll/duct_tape)) - var/obj/item/stack/tape_roll/duct_tape/T = W + if (istype(used_item, /obj/item/stack/tape_roll/duct_tape)) + var/obj/item/stack/tape_roll/duct_tape/T = used_item if(!T.can_use(4)) to_chat(user, SPAN_WARNING("You need 4 [T.plural_name] to make a splint!")) return TRUE diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index b95475cea8fe..5b2d75d6a559 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -448,9 +448,9 @@ src.interact(usr) return TRUE -/obj/item/stack/attackby(obj/item/W, mob/user) - if (istype(W, /obj/item/stack) && can_merge_stacks(W)) - var/obj/item/stack/S = W +/obj/item/stack/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/stack) && can_merge_stacks(used_item)) + var/obj/item/stack/S = used_item . = src.transfer_to(S) spawn(0) //give the stacks a chance to delete themselves if necessary diff --git a/code/game/objects/items/stools.dm b/code/game/objects/items/stools.dm index 31c54d503a53..528ff6abad1e 100644 --- a/code/game/objects/items/stools.dm +++ b/code/game/objects/items/stools.dm @@ -96,8 +96,8 @@ padding_extension?.remove_padding(do_icon_update = FALSE) qdel(src) -/obj/item/stool/attackby(obj/item/W, mob/user) - if(IS_WRENCH(W)) +/obj/item/stool/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item)) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) dismantle() return TRUE diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index c117895cea1b..ea8c1ac9e68a 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -60,5 +60,5 @@ /obj/item/wrench/pipe/afterattack(atom/A, mob/user, proximity) . = ..() if(proximity && istype(A,/obj/structure/window) && is_held_twohanded()) - var/obj/structure/window/W = A - W.shatter() + var/obj/structure/window/window = A + window.shatter() diff --git a/code/game/objects/items/weapons/RCD.dm b/code/game/objects/items/weapons/RCD.dm index 0168e93f7a00..2d17c5eef94c 100644 --- a/code/game/objects/items/weapons/RCD.dm +++ b/code/game/objects/items/weapons/RCD.dm @@ -46,19 +46,19 @@ . += "The current mode is '[work_mode]'." . += "It currently holds [stored_matter]/[max_stored_matter] matter-units." -/obj/item/rcd/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/rcd_ammo)) - var/obj/item/rcd_ammo/cartridge = W +/obj/item/rcd/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/rcd_ammo)) + var/obj/item/rcd_ammo/cartridge = used_item if((stored_matter + cartridge.remaining) > max_stored_matter) to_chat(user, "The RCD can't hold that many additional matter-units.") return TRUE stored_matter += cartridge.remaining - qdel(W) + qdel(used_item) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) to_chat(user, "The RCD now holds [stored_matter]/[max_stored_matter] matter-units.") update_icon() return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) crafting = !crafting if(!crafting) to_chat(user, SPAN_NOTICE("You reassemble the RCD.")) diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm index 6a4725991050..47c2b199b9c3 100644 --- a/code/game/objects/items/weapons/RPD.dm +++ b/code/game/objects/items/weapons/RPD.dm @@ -162,17 +162,17 @@ var/global/list/rpd_pipe_selection_skilled = list() interact(user) add_fingerprint(user) -/obj/item/rpd/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/pipe)) - if(!user.try_unequip(W)) +/obj/item/rpd/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/pipe)) + if(!user.try_unequip(used_item)) return TRUE - recycle(W,user) + recycle(used_item,user) return TRUE return ..() -/obj/item/rpd/proc/recycle(var/obj/item/W,var/mob/user) +/obj/item/rpd/proc/recycle(var/obj/item/used_item,var/mob/user) if(!user.skill_check(SKILL_ATMOS,SKILL_BASIC)) - user.visible_message("\The [user] struggles with \the [src] as they futilely jam \the [W] against it.") + user.visible_message("\The [user] struggles with \the [src] as they futilely jam \the [used_item] against it.") return playsound(src.loc, 'sound/effects/pop.ogg', 50, 1) - qdel(W) \ No newline at end of file + qdel(used_item) \ No newline at end of file diff --git a/code/game/objects/items/weapons/RSF.dm b/code/game/objects/items/weapons/RSF.dm index 4ff86c966b5b..977b8c1909c3 100644 --- a/code/game/objects/items/weapons/RSF.dm +++ b/code/game/objects/items/weapons/RSF.dm @@ -27,12 +27,12 @@ RSF if(distance <= 1) . += "It currently holds [stored_matter]/30 fabrication-units." -/obj/item/rsf/attackby(obj/item/W, mob/user) - if (istype(W, /obj/item/rcd_ammo)) +/obj/item/rsf/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/rcd_ammo)) if ((stored_matter + 10) > 30) to_chat(user, "The RSF can't hold any more matter.") return TRUE - qdel(W) + qdel(used_item) stored_matter += 10 playsound(src.loc, 'sound/machines/click.ogg', 10, 1) to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.") diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index 61aa021a7dc8..1b4e4386c12f 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -51,13 +51,13 @@ return for(var/V in O.autopsy_data) - var/datum/autopsy_data/W = O.autopsy_data[V] + var/datum/autopsy_data/wound_data = O.autopsy_data[V] if(weapon_data[V]) var/datum/autopsy_data/data = weapon_data[V]["data"] - data.merge_with(W) + data.merge_with(wound_data) weapon_data[V]["organs"] |= O.name else - weapon_data[V] = list("data" = W.copy(), "organs" = list(O.name)) + weapon_data[V] = list("data" = wound_data.copy(), "organs" = list(O.name)) /obj/item/scanner/autopsy/proc/get_formatted_data() var/list/scan_data = list("Subject: [target_name]") @@ -110,12 +110,12 @@ var/time_inflicted = 0 /datum/autopsy_data/proc/copy() - var/datum/autopsy_data/W = new() - W.weapon = weapon - W.damage = damage - W.hits = hits - W.time_inflicted = time_inflicted - return W + var/datum/autopsy_data/wound_data = new() + wound_data.weapon = weapon + wound_data.damage = damage + wound_data.hits = hits + wound_data.time_inflicted = time_inflicted + return wound_data /datum/autopsy_data/proc/merge_with(var/datum/autopsy_data/other) damage += other.damage diff --git a/code/game/objects/items/weapons/cane.dm b/code/game/objects/items/weapons/cane.dm index e78dcbfe9502..2fef3513ae38 100644 --- a/code/game/objects/items/weapons/cane.dm +++ b/code/game/objects/items/weapons/cane.dm @@ -61,14 +61,13 @@ return TRUE return ..() -/obj/item/cane/fancy/sword/attackby(var/obj/item/knife/folding/W, var/mob/user) - - if(!istype(concealed_blade) && istype(W) && user.try_unequip(W, src)) +/obj/item/cane/fancy/sword/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(concealed_blade) && istype(used_item, /obj/item/knife/folding) && user.try_unequip(used_item, src)) user.visible_message( - SPAN_NOTICE("\The [user] has sheathed \a [W] into \the [src]."), - SPAN_NOTICE("You sheathe \the [W] into \the [src].") + SPAN_NOTICE("\The [user] has sheathed \a [used_item] into \the [src]."), + SPAN_NOTICE("You sheathe \the [used_item] into \the [src].") ) - concealed_blade = W + concealed_blade = used_item update_icon() user.update_inhand_overlays() return TRUE diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 133eb87f0a57..828d94861e61 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -69,23 +69,23 @@ return TRUE // TODO: This should really use the cell extension -/obj/item/defibrillator/attackby(obj/item/W, mob/user, params) - if(W == paddles) +/obj/item/defibrillator/attackby(obj/item/used_item, mob/user, params) + if(used_item == paddles) reattach_paddles(user) return TRUE - else if(istype(W, /obj/item/cell)) + else if(istype(used_item, /obj/item/cell)) if(bcell) to_chat(user, "\The [src] already has a cell.") else - if(!user.try_unequip(W)) + if(!user.try_unequip(used_item)) return TRUE - W.forceMove(src) - bcell = W + used_item.forceMove(src) + bcell = used_item to_chat(user, "You install a cell in \the [src].") update_icon() return TRUE - else if(IS_SCREWDRIVER(W)) + else if(IS_SCREWDRIVER(used_item)) if(bcell) bcell.update_icon() bcell.dropInto(loc) diff --git a/code/game/objects/items/weapons/flamethrower.dm b/code/game/objects/items/weapons/flamethrower.dm index 99b4cb049def..f50b680ff129 100644 --- a/code/game/objects/items/weapons/flamethrower.dm +++ b/code/game/objects/items/weapons/flamethrower.dm @@ -106,11 +106,11 @@ /obj/item/flamethrower/isflamesource() return lit -/obj/item/flamethrower/attackby(obj/item/W, mob/user) +/obj/item/flamethrower/attackby(obj/item/used_item, mob/user) if(user.incapacitated()) return TRUE - if(IS_WRENCH(W) && !secured)//Taking this apart + if(IS_WRENCH(used_item) && !secured)//Taking this apart var/turf/T = get_turf(src) if(welding_tool) welding_tool.dropInto(T) @@ -128,14 +128,14 @@ qdel(src) return TRUE - if(IS_SCREWDRIVER(W) && igniter && !lit) + if(IS_SCREWDRIVER(used_item) && igniter && !lit) secured = !secured to_chat(user, SPAN_NOTICE("\The [igniter] is now [secured ? "secured" : "unsecured"]!")) update_icon() return TRUE - if(isigniter(W)) - var/obj/item/assembly/igniter/I = W + if(isigniter(used_item)) + var/obj/item/assembly/igniter/I = used_item if(I.secured) to_chat(user, SPAN_WARNING("\The [I] is not ready to attach yet! Use a screwdriver on it first.")) return TRUE @@ -149,23 +149,23 @@ update_icon() return TRUE - if(istype(W, /obj/item/tank)) + if(istype(used_item, /obj/item/tank)) if(tank) to_chat(user, SPAN_WARNING("There appears to already be a tank loaded in \the [src]!")) return TRUE - user.drop_from_inventory(W, src) - tank = W + user.drop_from_inventory(used_item, src) + tank = used_item update_icon() return TRUE - if(istype(W, /obj/item/scanner/gas)) - var/obj/item/scanner/gas/A = W + if(istype(used_item, /obj/item/scanner/gas)) + var/obj/item/scanner/gas/A = used_item A.analyze_gases(src, user) return TRUE - if(W.isflamesource()) // you can light it with external input, even without an igniter + if(used_item.isflamesource()) // you can light it with external input, even without an igniter attempt_lighting(user, TRUE) update_icon() return TRUE diff --git a/code/game/objects/items/weapons/gift_wrappaper.dm b/code/game/objects/items/weapons/gift_wrappaper.dm index 62f1c7e3fe4a..331c51c130ee 100644 --- a/code/game/objects/items/weapons/gift_wrappaper.dm +++ b/code/game/objects/items/weapons/gift_wrappaper.dm @@ -35,8 +35,8 @@ return to_chat(user, "You can't move.") -/obj/effect/spresent/attackby(obj/item/W, mob/user) - if(!IS_WIRECUTTER(W)) +/obj/effect/spresent/attackby(obj/item/used_item, mob/user) + if(!IS_WIRECUTTER(used_item)) to_chat(user, "I need wirecutters for that.") return TRUE diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index be47c0d7390d..060c4864e227 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -48,9 +48,9 @@ if(path == 1) add_overlay("[icon_state]-locked") -/obj/item/grenade/chem_grenade/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/assembly_holder) && (!stage || stage==1) && path != 2) - var/obj/item/assembly_holder/det = W +/obj/item/grenade/chem_grenade/attackby(obj/item/used_item, mob/user) + if(istype(used_item,/obj/item/assembly_holder) && (!stage || stage==1) && path != 2) + var/obj/item/assembly_holder/det = used_item if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right))) to_chat(user, "Assembly must contain one igniter.") return TRUE @@ -60,8 +60,8 @@ if(!user.try_unequip(det, src)) return TRUE path = 1 - log_and_message_admins("has attached \a [W] to \the [src].") - to_chat(user, "You add [W] to the metal casing.") + log_and_message_admins("has attached \a [used_item] to \the [src].") + to_chat(user, "You add [used_item] to the metal casing.") playsound(src.loc, 'sound/items/Screwdriver2.ogg', 25, -3) detonator = det if(istimer(detonator.a_left)) @@ -73,7 +73,7 @@ SetName("unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]") stage = 1 . = TRUE - else if(IS_SCREWDRIVER(W) && path != 2) + else if(IS_SCREWDRIVER(used_item) && path != 2) if(stage == 1) path = 1 if(beakers.len) @@ -97,22 +97,22 @@ stage = 1 active = FALSE . = TRUE - else if(is_type_in_list(W, allowed_containers) && (!stage || stage==1) && path != 2) + else if(is_type_in_list(used_item, allowed_containers) && (!stage || stage==1) && path != 2) path = 1 if(beakers.len == 2) to_chat(user, "The grenade can not hold more containers.") return TRUE else - if(W.reagents.total_volume) - if(!user.try_unequip(W, src)) + if(used_item.reagents.total_volume) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, "You add \the [W] to the assembly.") - beakers += W + to_chat(user, "You add \the [used_item] to the assembly.") + beakers += used_item stage = 1 SetName("unsecured grenade with [beakers.len] containers[detonator?" and detonator":""]") . = TRUE else - to_chat(user, "\The [W] is empty.") + to_chat(user, "\The [used_item] is empty.") return TRUE if(.) update_icon() diff --git a/code/game/objects/items/weapons/grenades/grenade.dm b/code/game/objects/items/weapons/grenades/grenade.dm index 29b99d979ac2..42ef0fe712ed 100644 --- a/code/game/objects/items/weapons/grenades/grenade.dm +++ b/code/game/objects/items/weapons/grenades/grenade.dm @@ -81,8 +81,8 @@ if(T) T.hotspot_expose(700,125) -/obj/item/grenade/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/grenade/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) switch(det_time) if (1) det_time = 10 diff --git a/code/game/objects/items/weapons/locator.dm b/code/game/objects/items/weapons/locator.dm index a6ad7b1def9d..01fe0fcc8c02 100644 --- a/code/game/objects/items/weapons/locator.dm +++ b/code/game/objects/items/weapons/locator.dm @@ -51,11 +51,11 @@ Frequency: if (sr) src.temp += "Located Beacons:
    " - for(var/obj/item/radio/beacon/W in global.radio_beacons) - if(!W.functioning) + for(var/obj/item/radio/beacon/radio in global.radio_beacons) + if(!radio.functioning) continue - if (W.frequency == src.frequency) - var/turf/tr = get_turf(W) + if (radio.frequency == src.frequency) + var/turf/tr = get_turf(radio) if (tr.z == sr.z && tr) var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) if (direct < 5) @@ -68,19 +68,19 @@ Frequency: direct = "weak" else direct = "very weak" - src.temp += "[W.code]-[dir2text(get_dir(sr, tr))]-[direct]
    " + src.temp += "[radio.code]-[dir2text(get_dir(sr, tr))]-[direct]
    " src.temp += "Extranneous Signals:
    " - for (var/obj/item/implant/tracking/W in global.tracking_implants) - if (!W.implanted || !(istype(W.loc,/obj/item/organ/external) || ismob(W.loc))) + for (var/obj/item/implant/tracking/implant in global.tracking_implants) + if (!implant.implanted || !(istype(implant.loc,/obj/item/organ/external) || ismob(implant.loc))) continue else - var/mob/M = W.loc + var/mob/M = implant.loc if (M.stat == DEAD) if (M.timeofdeath + 6000 < world.time) continue - var/turf/tr = get_turf(W) + var/turf/tr = get_turf(implant) if (tr.z == sr.z && tr) var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y)) if (direct < 20) @@ -91,7 +91,7 @@ Frequency: direct = "strong" else direct = "weak" - src.temp += "[W.id]-[dir2text(get_dir(sr, tr))]-[direct]
    " + src.temp += "[implant.id]-[dir2text(get_dir(sr, tr))]-[direct]
    " src.temp += "You are at \[[sr.x],[sr.y],[sr.z]\] in orbital coordinates.

    Refresh
    " else diff --git a/code/game/objects/items/weapons/material/ashtray.dm b/code/game/objects/items/weapons/material/ashtray.dm index babc46c5ba58..305f721f1730 100644 --- a/code/game/objects/items/weapons/material/ashtray.dm +++ b/code/game/objects/items/weapons/material/ashtray.dm @@ -22,23 +22,23 @@ else if (contents.len >= max_butts/2) add_overlay("ashtray_half") -/obj/item/ashtray/attackby(obj/item/W, mob/user) - if (istype(W,/obj/item/trash/cigbutt) || istype(W,/obj/item/clothing/mask/smokable/cigarette) || istype(W, /obj/item/flame/match)) +/obj/item/ashtray/attackby(obj/item/used_item, mob/user) + if (istype(used_item,/obj/item/trash/cigbutt) || istype(used_item,/obj/item/clothing/mask/smokable/cigarette) || istype(used_item, /obj/item/flame/match)) if (contents.len >= max_butts) to_chat(user, "\The [src] is full.") return TRUE - if (istype(W,/obj/item/clothing/mask/smokable/cigarette)) - var/obj/item/clothing/mask/smokable/cigarette/cig = W + if (istype(used_item,/obj/item/clothing/mask/smokable/cigarette)) + var/obj/item/clothing/mask/smokable/cigarette/cig = used_item if (cig.lit == 1) visible_message(SPAN_NOTICE("\The [user] crushes \the [cig] in \the [src], putting it out.")) - W = cig.extinguish_fire(no_message = TRUE) + used_item = cig.extinguish_fire(no_message = TRUE) else if (cig.lit == 0) to_chat(user, SPAN_NOTICE("You place \the [cig] in \the [src] without even smoking it. Why would you do that?")) else - visible_message(SPAN_NOTICE("\The [user] places \the [W] in \the [src].")) + visible_message(SPAN_NOTICE("\The [user] places \the [used_item] in \the [src].")) - if(user.try_unequip(W, src)) + if(user.try_unequip(used_item, src)) set_extension(src, /datum/extension/scent/ashtray) update_icon() return TRUE diff --git a/code/game/objects/items/weapons/material/shards.dm b/code/game/objects/items/weapons/material/shards.dm index cd4ddfb14100..12b2e317060c 100644 --- a/code/game/objects/items/weapons/material/shards.dm +++ b/code/game/objects/items/weapons/material/shards.dm @@ -56,14 +56,14 @@ if(has_handle) add_overlay(overlay_image(icon, "handle", has_handle, RESET_COLOR)) -/obj/item/shard/attackby(obj/item/W, mob/user) - if(IS_WELDER(W) && material.shard_can_repair) - var/obj/item/weldingtool/WT = W - if(WT.weld(0, user)) +/obj/item/shard/attackby(obj/item/used_item, mob/user) + if(IS_WELDER(used_item) && material.shard_can_repair) + var/obj/item/weldingtool/welder = used_item + if(welder.weld(0, user)) material.create_object(get_turf(src)) qdel(src) return TRUE - if(istype(W, /obj/item/stack/cable_coil)) + if(istype(used_item, /obj/item/stack/cable_coil)) if(!material || (material.shard_name in list(SHARD_SPLINTER, SHARD_SHRAPNEL))) to_chat(user, SPAN_WARNING("\The [src] is not suitable for using as a shank.")) @@ -71,7 +71,7 @@ if(has_handle) to_chat(user, SPAN_WARNING("\The [src] already has a handle.")) return TRUE - var/obj/item/stack/cable_coil/cable = W + var/obj/item/stack/cable_coil/cable = used_item if(cable.use(3)) to_chat(user, SPAN_NOTICE("You wind some cable around the thick end of \the [src].")) has_handle = cable.color diff --git a/code/game/objects/items/weapons/material/stick.dm b/code/game/objects/items/weapons/material/stick.dm index d752ca73f46d..f0d002b89087 100644 --- a/code/game/objects/items/weapons/material/stick.dm +++ b/code/game/objects/items/weapons/material/stick.dm @@ -14,22 +14,22 @@ user.visible_message("\The [user] snaps [src].", "You snap [src].") shatter(0) -/obj/item/stick/attackby(obj/item/W, mob/user) +/obj/item/stick/attackby(obj/item/used_item, mob/user) - if(W.is_sharp() && W.has_edge() && !sharp) - user.visible_message("[user] sharpens [src] with [W].", "You sharpen [src] using [W].") + if(used_item.is_sharp() && used_item.has_edge() && !sharp) + user.visible_message("[user] sharpens [src] with [used_item].", "You sharpen [src] using [used_item].") set_sharp(TRUE) SetName("sharpened " + name) update_attack_force() return TRUE - if(!sharp && (istype(W, /obj/item/stack/material/bolt) || istype(W, /obj/item/stack/material/bundle))) + if(!sharp && (istype(used_item, /obj/item/stack/material/bolt) || istype(used_item, /obj/item/stack/material/bundle))) var/choice = input(user, "Do you want to make a torch, or a splint?", "Stick Crafting") as null|anything in list("Torch", "Splint") - if(!choice || QDELETED(user) || user.get_active_held_item() != W || QDELETED(W) || !QDELETED(src) || (loc != user && !Adjacent(user)) || sharp) + if(!choice || QDELETED(user) || user.get_active_held_item() != used_item || QDELETED(used_item) || !QDELETED(src) || (loc != user && !Adjacent(user)) || sharp) return TRUE - var/obj/item/stack/material/cloth = W + var/obj/item/stack/material/cloth = used_item var/atom/product_type var/cloth_cost @@ -53,7 +53,7 @@ var/was_held = (loc == user) cloth.use(cloth_cost) if(!was_held || user.try_unequip(src)) - var/obj/item/thing = new product_type(get_turf(src), material?.type, W.material?.type) + var/obj/item/thing = new product_type(get_turf(src), material?.type, used_item.material?.type) if(was_held) user.put_in_hands(thing) to_chat(user, SPAN_NOTICE("You fashion \the [src] into \a [thing].")) diff --git a/code/game/objects/items/weapons/secrets_disk.dm b/code/game/objects/items/weapons/secrets_disk.dm index afcf3d485403..70a6c4036b17 100644 --- a/code/game/objects/items/weapons/secrets_disk.dm +++ b/code/game/objects/items/weapons/secrets_disk.dm @@ -58,9 +58,9 @@ to_chat(user, "The cryptographic lock on this disk is far too complex. Your sequencer can't break the code.") return 0 -/obj/item/disk/secret_project/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/card/id)) - var/obj/item/card/id/ID = W +/obj/item/disk/secret_project/attackby(obj/item/used_item, mob/user) + if(istype(used_item,/obj/item/card/id)) + var/obj/item/card/id/ID = used_item if(check_access(ID)) locked = !locked to_chat(user, "You swipe your card and [locked ? "lock":"unlock"] the disk.") diff --git a/code/game/objects/items/weapons/shields/shield_riot.dm b/code/game/objects/items/weapons/shields/shield_riot.dm index 0cc0c9324f0a..afd8e5959e44 100644 --- a/code/game/objects/items/weapons/shields/shield_riot.dm +++ b/code/game/objects/items/weapons/shields/shield_riot.dm @@ -30,10 +30,10 @@ return 0 return base_block_chance -/obj/item/shield/riot/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/baton)) +/obj/item/shield/riot/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/baton)) if(cooldown < world.time - 25) - user.visible_message("[user] bashes [src] with [W]!") + user.visible_message("[user] bashes [src] with [used_item]!") playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1) cooldown = world.time return TRUE diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 7a234732c98e..3ba1614419cd 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -17,7 +17,7 @@ /obj/item/backpack/can_contaminate() return FALSE -/obj/item/backpack/attackby(obj/item/W, mob/user) +/obj/item/backpack/attackby(obj/item/used_item, mob/user) if (storage?.use_sound) playsound(src.loc, storage.use_sound, 50, 1, -5) return ..() @@ -51,10 +51,10 @@ explosion(src.loc,(dist),(dist*2),(dist*4)) return 1000 -/obj/item/backpack/holding/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/backpack/holding) || istype(W, /obj/item/bag/trash/advanced)) +/obj/item/backpack/holding/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/backpack/holding) || istype(used_item, /obj/item/bag/trash/advanced)) to_chat(user, "The spatial interfaces of the two devices conflict and malfunction.") - qdel(W) + qdel(used_item) return 1 return ..() @@ -344,7 +344,7 @@ anchored = i ? TRUE : FALSE alpha = i ? 128 : initial(alpha) -/obj/item/backpack/satchel/flat/attackby(obj/item/W, mob/user) +/obj/item/backpack/satchel/flat/attackby(obj/item/used_item, mob/user) var/turf/T = get_turf(src) if(hides_under_flooring() && isturf(T) && !T.is_plating()) to_chat(user, "You must remove the plating first.") diff --git a/code/game/objects/items/weapons/storage/bags.dm b/code/game/objects/items/weapons/storage/bags.dm index 5b60770ac977..6e4dde21a2b7 100644 --- a/code/game/objects/items/weapons/storage/bags.dm +++ b/code/game/objects/items/weapons/storage/bags.dm @@ -58,10 +58,10 @@ origin_tech = @'{"exoticmatter":5,"materials":6}' storage = /datum/storage/bag/trash/advanced -/obj/item/bag/trash/advanced/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/backpack/holding) || istype(W, /obj/item/bag/trash/advanced)) +/obj/item/bag/trash/advanced/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/backpack/holding) || istype(used_item, /obj/item/bag/trash/advanced)) to_chat(user, "The spatial interfaces of the two devices conflict and malfunction.") - qdel(W) + qdel(used_item) return 1 return ..() diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index 9c123d4624dc..b0f2429fd34e 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -91,7 +91,7 @@ to_chat(user, SPAN_NOTICE("You bless \the [A].")) // I wish it was this easy in nethack LAZYSET(A.reagents.reagent_data, /decl/material/liquid/water, list("holy" = TRUE)) -/obj/item/bible/attackby(obj/item/W, mob/user) +/obj/item/bible/attackby(obj/item/used_item, mob/user) if(storage?.use_sound) playsound(loc, storage.use_sound, 50, 1, -5) return ..() diff --git a/code/game/objects/items/weapons/storage/fancy/vials.dm b/code/game/objects/items/weapons/storage/fancy/vials.dm index 23cbb2db06bc..de59950c7674 100644 --- a/code/game/objects/items/weapons/storage/fancy/vials.dm +++ b/code/game/objects/items/weapons/storage/fancy/vials.dm @@ -46,6 +46,6 @@ else add_overlay("ledb") -/obj/item/lockbox/vials/attackby(obj/item/W, mob/user) +/obj/item/lockbox/vials/attackby(obj/item/used_item, mob/user) . = ..() update_icon() \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/lockbox.dm b/code/game/objects/items/weapons/storage/lockbox.dm index 3ad6fb923d8c..341efc0954d0 100644 --- a/code/game/objects/items/weapons/storage/lockbox.dm +++ b/code/game/objects/items/weapons/storage/lockbox.dm @@ -18,8 +18,8 @@ var/icon_broken = "lockbox+b" -/obj/item/lockbox/attackby(obj/item/W as obj, mob/user as mob) - if (istype(W, /obj/item/card/id)) +/obj/item/lockbox/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/card/id)) if(src.broken) to_chat(user, "It appears to be broken.") return TRUE @@ -35,9 +35,9 @@ else to_chat(user, "Access Denied") return TRUE - else if(istype(W, /obj/item/energy_blade)) - var/obj/item/energy_blade/blade = W - if(blade.is_special_cutting_tool() && emag_act(INFINITY, user, W, "The locker has been sliced open by [user] with an energy blade!", "You hear metal being sliced and sparks flying.")) + else if(istype(used_item, /obj/item/energy_blade)) + var/obj/item/energy_blade/blade = used_item + if(blade.is_special_cutting_tool() && emag_act(INFINITY, user, used_item, "The locker has been sliced open by [user] with an energy blade!", "You hear metal being sliced and sparks flying.")) spark_at(src.loc, amount=5) playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) return TRUE diff --git a/code/game/objects/items/weapons/storage/matches.dm b/code/game/objects/items/weapons/storage/matches.dm index 8312621ce0cb..fe883451bf5a 100644 --- a/code/game/objects/items/weapons/storage/matches.dm +++ b/code/game/objects/items/weapons/storage/matches.dm @@ -11,15 +11,15 @@ /obj/item/box/matches/WillContain() return list(/obj/item/flame/match = 10) -/obj/item/box/matches/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/flame/match)) - var/obj/item/flame/match/match = W +/obj/item/box/matches/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/flame/match)) + var/obj/item/flame/match/match = used_item if(match.light(null, no_message = TRUE)) playsound(src.loc, 'sound/items/match.ogg', 60, 1, -4) user.visible_message( - SPAN_NOTICE("[user] strikes [W] on \the [src]."), - SPAN_NOTICE("You strike [W] on \the [src].") + SPAN_NOTICE("[user] strikes [used_item] on \the [src]."), + SPAN_NOTICE("You strike [used_item] on \the [src].") ) - W.update_icon() + used_item.update_icon() return TRUE return ..() diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index 860536919b89..fb7ff59d4049 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -46,9 +46,9 @@ if(new_locked) storage?.close_all() -/obj/item/secure_storage/attackby(obj/item/W, mob/user) +/obj/item/secure_storage/attackby(obj/item/used_item, mob/user) var/datum/extension/lockable/lock = get_extension(src, /datum/extension/lockable) - if(lock.attackby(W, user)) + if(lock.attackby(used_item, user)) return TRUE // -> storage/attackby() what with handle insertion, etc diff --git a/code/game/objects/items/weapons/storage/wall_mirror.dm b/code/game/objects/items/weapons/storage/wall_mirror.dm index 91b5554585d3..a69b0d5e135f 100644 --- a/code/game/objects/items/weapons/storage/wall_mirror.dm +++ b/code/game/objects/items/weapons/storage/wall_mirror.dm @@ -97,18 +97,17 @@ if(!ishuman(user)) return - var/W = weakref(user) - var/datum/nano_module/appearance_changer/AC = LAZYACCESS(ui_users, W) + var/weakref/user_ref = weakref(user) + var/datum/nano_module/appearance_changer/AC = LAZYACCESS(ui_users, user_ref) if(!AC) AC = new(mirror, user) AC.name = title if(flags) AC.flags = flags - LAZYSET(ui_users, W, AC) + LAZYSET(ui_users, user_ref, AC) AC.ui_interact(user) /proc/clear_ui_users(var/list/ui_users) - for(var/W in ui_users) - var/AC = ui_users[W] - qdel(AC) + for(var/user_ref in ui_users) + qdel(ui_users[user_ref]) LAZYCLEARLIST(ui_users) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index eeacd5889360..f09735ff89c9 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -169,7 +169,7 @@ add_fingerprint(user) return 0 -/obj/item/baton/robot/attackby(obj/item/W, mob/user) +/obj/item/baton/robot/attackby(obj/item/used_item, mob/user) return FALSE /obj/item/baton/robot/setup_power_supply(loaded_cell_type, accepted_cell_type, power_supply_extension_type, charge_value) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 23aa1b6ab20e..24c7dda61fba 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -114,28 +114,28 @@ var/global/list/global/tank_gauge_cache = list() if(valve_welded) . += SPAN_WARNING("\The [src] emergency relief valve has been welded shut!") -/obj/item/tank/attackby(var/obj/item/W, var/mob/user) +/obj/item/tank/attackby(var/obj/item/used_item, var/mob/user) if (istype(loc, /obj/item/assembly)) icon = loc - if (istype(W, /obj/item/scanner/gas)) + if (istype(used_item, /obj/item/scanner/gas)) return TRUE - if (istype(W,/obj/item/latexballon)) - var/obj/item/latexballon/LB = W + if (istype(used_item,/obj/item/latexballon)) + var/obj/item/latexballon/LB = used_item LB.blow(src) add_fingerprint(user) return TRUE - if(IS_COIL(W)) - var/obj/item/stack/cable_coil/C = W + if(IS_COIL(used_item)) + var/obj/item/stack/cable_coil/C = used_item if(C.use(1)) wired = 1 to_chat(user, "You attach the wires to the tank.") update_icon() return TRUE - if(IS_WIRECUTTER(W)) + if(IS_WIRECUTTER(used_item)) if(wired && proxyassembly.assembly) to_chat(user, "You carefully begin clipping the wires that attach to the tank.") @@ -173,23 +173,23 @@ var/global/list/global/tank_gauge_cache = list() to_chat(user, "There are no wires to cut!") return TRUE - if(istype(W, /obj/item/assembly_holder)) + if(istype(used_item, /obj/item/assembly_holder)) if(wired) to_chat(user, "You begin attaching the assembly to \the [src].") if(do_after(user, 50, src)) to_chat(user, "You finish attaching the assembly to \the [src].") global.bombers += "[key_name(user)] attached an assembly to a wired [src]. Temp: [air_contents.temperature-T0C]" log_and_message_admins("attached an assembly to a wired [src]. Temp: [air_contents.temperature-T0C]", user) - assemble_bomb(W,user) + assemble_bomb(used_item,user) else to_chat(user, "You stop attaching the assembly.") else to_chat(user, "You need to wire the device up first.") return TRUE - if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W - if(WT.weld(1,user)) + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item + if(welder.weld(1,user)) if(!valve_welded) to_chat(user, "You begin welding \the [src] emergency pressure relief valve.") if(do_after(user, 40,src)) @@ -199,8 +199,8 @@ var/global/list/global/tank_gauge_cache = list() else global.bombers += "[key_name(user)] attempted to weld \a [src]. [air_contents.temperature-T0C]" log_and_message_admins("attempted to weld \a [src]. [air_contents.temperature-T0C]", user) - if(WT.welding) - to_chat(user, "You accidentally rake \the [W] across \the [src]!") + if(welder.welding) + to_chat(user, "You accidentally rake \the [used_item] across \the [src]!") maxintegrity -= rand(2,6) integrity = min(integrity,maxintegrity) air_contents.add_thermal_energy(rand(2000,50000)) @@ -209,8 +209,8 @@ var/global/list/global/tank_gauge_cache = list() add_fingerprint(user) return TRUE - if(istype(W, /obj/item/flamethrower)) - var/obj/item/flamethrower/F = W + if(istype(used_item, /obj/item/flamethrower)) + var/obj/item/flamethrower/F = used_item if(!F.secured || F.tank || !user.try_unequip(src, F)) return TRUE @@ -550,8 +550,8 @@ var/global/list/global/tank_gauge_cache = list() /obj/item/tankassemblyproxy/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. tank.cause_explosion() //boom (or not boom if you made shijwtty mix) -/obj/item/tank/proc/assemble_bomb(W,user) //Bomb assembly proc. This turns assembly+tank into a bomb - var/obj/item/assembly_holder/S = W +/obj/item/tank/proc/assemble_bomb(used_item,user) //Bomb assembly proc. This turns assembly+tank into a bomb + var/obj/item/assembly_holder/S = used_item var/mob/M = user if(!S.secured) //Check if the assembly is secured return diff --git a/code/game/objects/items/weapons/tape.dm b/code/game/objects/items/weapons/tape.dm index eaec2caa5867..d10c34c4f8e3 100644 --- a/code/game/objects/items/weapons/tape.dm +++ b/code/game/objects/items/weapons/tape.dm @@ -147,14 +147,14 @@ return ..() -/obj/item/stack/tape_roll/duct_tape/proc/stick(var/obj/item/W, mob/user) - if(!(W.item_flags & ITEM_FLAG_CAN_TAPE) || !user.try_unequip(W)) +/obj/item/stack/tape_roll/duct_tape/proc/stick(var/obj/item/used_item, mob/user) + if(!(used_item.item_flags & ITEM_FLAG_CAN_TAPE) || !user.try_unequip(used_item)) return FALSE if(!can_use(1)) return FALSE use(1) var/obj/item/duct_tape/tape = new(get_turf(src)) - tape.attach(W) + tape.attach(used_item) user.put_in_hands(tape) return TRUE @@ -184,17 +184,17 @@ anchored = FALSE // Unattach it from whereever it's on, if anything. return ..() -/obj/item/duct_tape/attackby(obj/item/W, mob/user) - return stuck? stuck.attackby(W, user) : ..() +/obj/item/duct_tape/attackby(obj/item/used_item, mob/user) + return stuck? stuck.attackby(used_item, user) : ..() /obj/item/duct_tape/examined_by(mob/user, distance, infix, suffix) return stuck ? stuck.examined_by(user, distance, infix, suffix) : ..() -/obj/item/duct_tape/proc/attach(var/obj/item/W) - stuck = W +/obj/item/duct_tape/proc/attach(var/obj/item/used_item) + stuck = used_item anchored = TRUE - SetName("[W.name] (taped)") - W.forceMove(src) + SetName("[used_item.name] (taped)") + used_item.forceMove(src) playsound(src, 'sound/effects/tape.ogg', 25) update_icon() diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 61276713a388..445f92be6909 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -200,8 +200,8 @@ healthcheck() return TRUE -/obj/effect/energy_net/attackby(obj/item/W, mob/user) - current_health -= W.expend_attack_force(user) +/obj/effect/energy_net/attackby(obj/item/used_item, mob/user) + current_health -= used_item.expend_attack_force(user) healthcheck() return TRUE diff --git a/code/game/objects/items/welding/electric_welder.dm b/code/game/objects/items/welding/electric_welder.dm index c46aa882f571..382690a971b4 100644 --- a/code/game/objects/items/welding/electric_welder.dm +++ b/code/game/objects/items/welding/electric_welder.dm @@ -47,7 +47,7 @@ /obj/item/weldingtool/electric/insert_tank(var/obj/item/chems/welder_tank/T, var/mob/user, var/no_updates = FALSE, var/quiet = FALSE) return FALSE // No tanks! -/obj/item/weldingtool/electric/attempt_modify(var/obj/item/W, var/mob/user) +/obj/item/weldingtool/electric/attempt_modify(var/obj/item/used_item, var/mob/user) return FALSE // NO ELECTRIC FLAMETHROWER /obj/item/weldingtool/electric/use_fuel(var/amount) diff --git a/code/game/objects/items/welding/weldbackpack.dm b/code/game/objects/items/welding/weldbackpack.dm index 5b8bdbb036a9..661197c56601 100644 --- a/code/game/objects/items/welding/weldbackpack.dm +++ b/code/game/objects/items/welding/weldbackpack.dm @@ -30,7 +30,7 @@ /obj/item/weldingtool/weldpack/toggle_unscrewed(mob/user) return FALSE -/obj/item/weldingtool/weldpack/attempt_modify(obj/item/W, mob/user) +/obj/item/weldingtool/weldpack/attempt_modify(obj/item/used_item, mob/user) return FALSE /obj/item/weldingtool/weldpack/dropped(mob/user) diff --git a/code/game/objects/items/welding/weldingtool.dm b/code/game/objects/items/welding/weldingtool.dm index f46f50010915..720957f0b6d0 100644 --- a/code/game/objects/items/welding/weldingtool.dm +++ b/code/game/objects/items/welding/weldingtool.dm @@ -137,27 +137,27 @@ to_chat(user, SPAN_NOTICE("The welder can now be attached and modified.")) return TRUE -/obj/item/weldingtool/proc/attempt_modify(var/obj/item/W, var/mob/user) - if(!status && istype(W, /obj/item/stack/material/rods)) - var/obj/item/stack/material/rods/R = W +/obj/item/weldingtool/proc/attempt_modify(var/obj/item/used_item, var/mob/user) + if(!status && istype(used_item, /obj/item/stack/material/rods)) + var/obj/item/stack/material/rods/R = used_item R.use(1) user.drop_from_inventory(src) user.put_in_hands(new /obj/item/flamethrower(get_turf(src), src)) qdel(src) return TRUE -/obj/item/weldingtool/attackby(obj/item/W, mob/user) +/obj/item/weldingtool/attackby(obj/item/used_item, mob/user) if(welding) to_chat(user, SPAN_WARNING("Stop welding first!")) return TRUE - if (istype(W, /obj/item/chems/welder_tank)) - return insert_tank(W, user) + if (istype(used_item, /obj/item/chems/welder_tank)) + return insert_tank(used_item, user) - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) return toggle_unscrewed(user) - if(attempt_modify(W, user)) + if(attempt_modify(used_item, user)) return TRUE return ..() diff --git a/code/game/objects/structures/__structure.dm b/code/game/objects/structures/__structure.dm index dfe3a96be019..2a90385995b3 100644 --- a/code/game/objects/structures/__structure.dm +++ b/code/game/objects/structures/__structure.dm @@ -301,11 +301,11 @@ auto_align() will then place the sprite so the defined center_of_mass is at the closest to where the cursor has clicked on. Note: This proc can be overwritten to allow for different types of auto-alignment. */ -/obj/structure/proc/auto_align(obj/item/W, click_params) - if (!W.center_of_mass) // Clothing, material stacks, generally items with large sprites where exact placement would be unhandy. - W.pixel_x = rand(-W.randpixel, W.randpixel) - W.pixel_y = rand(-W.randpixel, W.randpixel) - W.pixel_z = 0 +/obj/structure/proc/auto_align(obj/item/aligning, click_params) + if (!aligning.center_of_mass) // Clothing, material stacks, generally items with large sprites where exact placement would be unhandy. + aligning.pixel_x = rand(-aligning.randpixel, aligning.randpixel) + aligning.pixel_y = rand(-aligning.randpixel, aligning.randpixel) + aligning.pixel_z = 0 return if (!click_params) return @@ -324,10 +324,10 @@ Note: This proc can be overwritten to allow for different types of auto-alignmen span_y = bound_height / CELLSIZE var/cell_x = clamp(round(mouse_x/CELLSIZE), 0, span_x-1) // Ranging from 0 to span_x-1 var/cell_y = clamp(round(mouse_y/CELLSIZE), 0, span_y-1) - var/list/center = cached_json_decode(W.center_of_mass) - W.pixel_x = (CELLSIZE * (cell_x + 0.5)) - center["x"] - W.pixel_y = (CELLSIZE * (cell_y + 0.5)) - center["y"] - W.pixel_z = 0 + var/list/center = cached_json_decode(aligning.center_of_mass) + aligning.pixel_x = (CELLSIZE * (cell_x + 0.5)) - center["x"] + aligning.pixel_y = (CELLSIZE * (cell_y + 0.5)) - center["y"] + aligning.pixel_z = 0 // Does this structure override turf depth for the purposes of mob offsets? /obj/structure/proc/is_platform() diff --git a/code/game/objects/structures/_structure_icon.dm b/code/game/objects/structures/_structure_icon.dm index 12bbc26f1602..966df9a1cc4c 100644 --- a/code/game/objects/structures/_structure_icon.dm +++ b/code/game/objects/structures/_structure_icon.dm @@ -35,10 +35,10 @@ var/global/list/default_noblend_objects = list(/obj/machinery/door/window, /obj/ /obj/structure/proc/find_blendable_obj_in_turf(var/turf/T, var/propagate) if(is_type_in_list(T, global.default_blend_objects)) if(propagate && istype(T, /turf/wall)) - for(var/turf/wall/W in RANGE_TURFS(T, 1)) - W.wall_connections = null - W.other_connections = null - W.queue_icon_update() + for(var/turf/wall/wall in RANGE_TURFS(T, 1)) + wall.wall_connections = null + wall.other_connections = null + wall.queue_icon_update() return TRUE for(var/obj/O in T) if(!is_type_in_list(O, global.default_blend_objects)) diff --git a/code/game/objects/structures/barricade.dm b/code/game/objects/structures/barricade.dm index e62e7675c4c3..ece9d0fa5244 100644 --- a/code/game/objects/structures/barricade.dm +++ b/code/game/objects/structures/barricade.dm @@ -49,9 +49,9 @@ else icon_state = "barricade" -/obj/structure/barricade/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/stack/material/rods) && !reinf_material) - var/obj/item/stack/material/rods/rods = W +/obj/structure/barricade/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/stack/material/rods) && !reinf_material) + var/obj/item/stack/material/rods/rods = used_item if(rods.get_amount() < 5) to_chat(user, SPAN_WARNING("You need more rods to build a cheval de frise.")) else diff --git a/code/game/objects/structures/chairs/wheelchair.dm b/code/game/objects/structures/chairs/wheelchair.dm index 31fb6781e1a7..97b79c15d7af 100644 --- a/code/game/objects/structures/chairs/wheelchair.dm +++ b/code/game/objects/structures/chairs/wheelchair.dm @@ -73,9 +73,9 @@ bloodiness-- /proc/equip_wheelchair(mob/living/human/H) //Proc for spawning in a wheelchair if a new character has no legs. Used in new_player.dm - var/obj/structure/chair/wheelchair/W = new(get_turf(H)) + var/obj/structure/chair/wheelchair/wheelchair = new(get_turf(H)) if(isturf(H.loc)) - W.buckle_mob(H) + wheelchair.buckle_mob(H) /obj/structure/chair/wheelchair/verb/collapse() set name = "Collapse Wheelchair" @@ -136,9 +136,9 @@ user.visible_message("[user] starts to lay out \the [src].") if(do_after(user, 4 SECONDS, src)) - var/obj/structure/chair/wheelchair/W = new structure_form_type(get_turf(user)) - user.visible_message("[user] lays out \the [W].") - W.add_fingerprint(user) + var/obj/structure/chair/wheelchair/wheelchair = new structure_form_type(get_turf(user)) + user.visible_message("[user] lays out \the [wheelchair].") + wheelchair.add_fingerprint(user) qdel(src) /obj/item/wheelchair_kit/physically_destroyed(skip_qdel) diff --git a/code/game/objects/structures/coathanger.dm b/code/game/objects/structures/coathanger.dm index 3462edc0b082..155a7eeff3dc 100644 --- a/code/game/objects/structures/coathanger.dm +++ b/code/game/objects/structures/coathanger.dm @@ -70,16 +70,16 @@ if(thing.slot_flags & slots_allowed[slot]) return TRUE -/obj/structure/coatrack/attackby(obj/item/W, mob/user) - if(!can_hang(W)) +/obj/structure/coatrack/attackby(obj/item/used_item, mob/user) + if(!can_hang(used_item)) return ..() if(length(contents) >= max_items) - to_chat(user, SPAN_NOTICE("There is no room on \the [src] to hang \the [W].")) + to_chat(user, SPAN_NOTICE("There is no room on \the [src] to hang \the [used_item].")) return TRUE - if(user.try_unequip(W, src)) + if(user.try_unequip(used_item, src)) user.visible_message( \ - SPAN_NOTICE("\The [user] hangs \the [W] on \the [src]."), \ - SPAN_NOTICE("You hang \the [W] on \the [src].") \ + SPAN_NOTICE("\The [user] hangs \the [used_item] on \the [src]."), \ + SPAN_NOTICE("You hang \the [used_item] on \the [src].") \ ) update_icon() return TRUE diff --git a/code/game/objects/structures/compost.dm b/code/game/objects/structures/compost.dm index 407a6d38600d..a8149da99c96 100644 --- a/code/game/objects/structures/compost.dm +++ b/code/game/objects/structures/compost.dm @@ -88,28 +88,28 @@ var/global/const/COMPOST_WORM_HUNGER_FACTOR = MINIMUM_CHEMICAL_VOLUME reagents.trans_to(loc, reagents.total_volume) return ..() -/obj/structure/reagent_dispensers/compost_bin/attackby(obj/item/W, mob/user) +/obj/structure/reagent_dispensers/compost_bin/attackby(obj/item/used_item, mob/user) if(user.check_intent(I_FLAG_HARM)) return ..() - if(W.storage) + if(used_item.storage) var/emptied = FALSE - for(var/obj/item/O in W.get_stored_inventory()) + for(var/obj/item/O in used_item.get_stored_inventory()) if(storage.can_be_inserted(O)) - W.storage.remove_from_storage(null, O, loc, skip_update = TRUE) + used_item.storage.remove_from_storage(null, O, loc, skip_update = TRUE) storage.handle_item_insertion(null, O, skip_update = TRUE) emptied = TRUE if(emptied) - W.storage.finish_bulk_removal() + used_item.storage.finish_bulk_removal() storage.update_ui_after_item_insertion() - if(length(W.get_stored_inventory())) - to_chat(user, SPAN_NOTICE("You partially empty \the [W] into \the [src]'s hopper.")) + if(length(used_item.get_stored_inventory())) + to_chat(user, SPAN_NOTICE("You partially empty \the [used_item] into \the [src]'s hopper.")) else - to_chat(user, SPAN_NOTICE("You empty \the [W] into \the [src]'s hopper.")) - W.update_icon() + to_chat(user, SPAN_NOTICE("You empty \the [used_item] into \the [src]'s hopper.")) + used_item.update_icon() return TRUE return ..() diff --git a/code/game/objects/structures/crates_lockers/closets/__closet.dm b/code/game/objects/structures/crates_lockers/closets/__closet.dm index 67dda1ac39ba..9e18b1611a33 100644 --- a/code/game/objects/structures/crates_lockers/closets/__closet.dm +++ b/code/game/objects/structures/crates_lockers/closets/__closet.dm @@ -265,9 +265,9 @@ var/global/list/closets = list() receive_mouse_drop(grab.affecting, user) //act like they were dragged onto the closet return TRUE if(IS_WELDER(used_item)) - var/obj/item/weldingtool/WT = used_item - if(WT.weld(0,user)) - slice_into_parts(WT, user) + var/obj/item/weldingtool/welder = used_item + if(welder.weld(0,user)) + slice_into_parts(welder, user) return TRUE if(istype(used_item, /obj/item/gun/energy/plasmacutter)) var/obj/item/gun/energy/plasmacutter/cutter = used_item @@ -315,9 +315,9 @@ var/global/list/closets = list() return FALSE //Return false to get afterattack to be called if(IS_WELDER(used_item) && (setup & CLOSET_CAN_BE_WELDED)) - var/obj/item/weldingtool/WT = used_item - if(!WT.weld(0,user)) - if(WT.isOn()) + var/obj/item/weldingtool/welder = used_item + if(!welder.weld(0,user)) + if(welder.isOn()) to_chat(user, SPAN_NOTICE("You need more welding fuel to complete this task.")) return TRUE welded = !welded @@ -330,10 +330,10 @@ var/global/list/closets = list() return attack_hand_with_interaction_checks(user) -/obj/structure/closet/proc/slice_into_parts(obj/W, mob/user) +/obj/structure/closet/proc/slice_into_parts(obj/item/used_item, mob/user) user.visible_message( - SPAN_NOTICE("\The [src] has been cut apart by [user] with \the [W]."), - SPAN_NOTICE("You have cut \the [src] apart with \the [W]."), + SPAN_NOTICE("\The [src] has been cut apart by [user] with \the [used_item]."), + SPAN_NOTICE("You have cut \the [src] apart with \the [used_item]."), "You hear welding." ) physically_destroyed() diff --git a/code/game/objects/structures/crates_lockers/closets/coffin.dm b/code/game/objects/structures/crates_lockers/closets/coffin.dm index 7b06ff2b19d8..236153f78f39 100644 --- a/code/game/objects/structures/crates_lockers/closets/coffin.dm +++ b/code/game/objects/structures/crates_lockers/closets/coffin.dm @@ -17,8 +17,8 @@ if(locked) return FALSE -/obj/structure/closet/coffin/attackby(obj/item/W, mob/user) - if(!opened && IS_SCREWDRIVER(W)) +/obj/structure/closet/coffin/attackby(obj/item/used_item, mob/user) + if(!opened && IS_SCREWDRIVER(used_item)) to_chat(user, SPAN_NOTICE("You begin screwing [src]'s lid [locked ? "open" : "shut"].")) playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) if(do_after(user, screwdriver_time_needed, src)) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/_secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/_secure_closets.dm index b18ae84828b6..ff568d29a611 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/_secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/_secure_closets.dm @@ -9,5 +9,5 @@ wall_mounted = 0 //never solid (You can always pass over it) current_health = 200 -/obj/structure/closet/secure_closet/slice_into_parts(obj/item/weldingtool/WT, mob/user) +/obj/structure/closet/secure_closet/slice_into_parts(obj/item/weldingtool/welder, mob/user) to_chat(user, "\The [src] is too strong to be taken apart.") diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 59d02b4c8c5a..edbdf78c3222 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -32,13 +32,13 @@ devices += A . += "There are some wires attached to the lid, connected to [english_list(devices)]." -/obj/structure/closet/crate/attackby(obj/item/W, mob/user) +/obj/structure/closet/crate/attackby(obj/item/used_item, mob/user) if(opened) return ..() - else if(istype(W, /obj/item/stack/package_wrap)) + else if(istype(used_item, /obj/item/stack/package_wrap)) return FALSE // let afterattack run - else if(istype(W, /obj/item/stack/cable_coil)) - var/obj/item/stack/cable_coil/C = W + else if(istype(used_item, /obj/item/stack/cable_coil)) + var/obj/item/stack/cable_coil/C = used_item if(rigged) to_chat(user, "[src] is already rigged!") return TRUE @@ -47,12 +47,12 @@ rigged = 1 return TRUE return FALSE - else if((istype(W, /obj/item/assembly_holder) || istype(W, /obj/item/assembly)) && rigged) - if(!user.try_unequip(W, src)) + else if((istype(used_item, /obj/item/assembly_holder) || istype(used_item, /obj/item/assembly)) && rigged) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, "You attach [W] to [src].") + to_chat(user, "You attach [used_item] to [src].") return TRUE - else if(IS_WIRECUTTER(W)) + else if(IS_WIRECUTTER(used_item)) if(rigged) to_chat(user, "You cut away the wiring.") playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1) diff --git a/code/game/objects/structures/crates_lockers/largecrate.dm b/code/game/objects/structures/crates_lockers/largecrate.dm index 4e4e37090ac1..2ed4e74f0b4e 100644 --- a/code/game/objects/structures/crates_lockers/largecrate.dm +++ b/code/game/objects/structures/crates_lockers/largecrate.dm @@ -20,8 +20,8 @@ to_chat(user, SPAN_WARNING("You need a crowbar to pry this open!")) return TRUE -/obj/structure/largecrate/attackby(obj/item/W, mob/user) - if(IS_CROWBAR(W)) +/obj/structure/largecrate/attackby(obj/item/used_item, mob/user) + if(IS_CROWBAR(used_item)) user.visible_message( SPAN_NOTICE("\The [user] pries \the [src] open."), SPAN_NOTICE("You pry open \the [src]."), diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm index 4e1bafbf36eb..0ef9f5dfbce3 100644 --- a/code/game/objects/structures/curtains.dm +++ b/code/game/objects/structures/curtains.dm @@ -23,8 +23,8 @@ matter = atom_info_repository.get_matter_for(/obj/structure/curtain, kind.material_key) update_icon() -/obj/item/curtain/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/curtain/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) if(!curtain_kind_path) return TRUE @@ -110,8 +110,8 @@ return TRUE return ..() -/obj/structure/curtain/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W) && curtain_kind_path) +/obj/structure/curtain/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item) && curtain_kind_path) user.visible_message( SPAN_NOTICE("\The [user] begins uninstalling \the [src]."), SPAN_NOTICE("You begin uninstalling \the [src].")) diff --git a/code/game/objects/structures/defensive_barrier.dm b/code/game/objects/structures/defensive_barrier.dm index 97b999566c0b..889d3a94bdff 100644 --- a/code/game/objects/structures/defensive_barrier.dm +++ b/code/game/objects/structures/defensive_barrier.dm @@ -127,9 +127,9 @@ update_icon() return TRUE -/obj/structure/defensive_barrier/attackby(obj/item/W, mob/user) +/obj/structure/defensive_barrier/attackby(obj/item/used_item, mob/user) - if(IS_SCREWDRIVER(W) && density) + if(IS_SCREWDRIVER(used_item) && density) user.visible_message(SPAN_NOTICE("\The [user] begins to [secured ? "secure" : "unsecure"] \the [src]...")) playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) if(!do_after(user, 30, src)) @@ -199,9 +199,9 @@ user.drop_from_inventory(src) qdel(src) -/obj/item/defensive_barrier/attackby(obj/item/W, mob/user) - if(stored_health < stored_max_health && IS_WELDER(W)) - if(W.do_tool_interaction(TOOL_WELDER, user, src, \ +/obj/item/defensive_barrier/attackby(obj/item/used_item, mob/user) + if(stored_health < stored_max_health && IS_WELDER(used_item)) + if(used_item.do_tool_interaction(TOOL_WELDER, user, src, \ max(5, round((stored_max_health-stored_health) / 5)), \ "repairing the damage to", "repairing the damage to", \ "You fail to patch the damage to \the [src].", \ diff --git a/code/game/objects/structures/displaycase.dm b/code/game/objects/structures/displaycase.dm index 06455c87a1fc..2223ada43936 100644 --- a/code/game/objects/structures/displaycase.dm +++ b/code/game/objects/structures/displaycase.dm @@ -92,9 +92,9 @@ for(var/atom/movable/AM in contents) underlays += AM.appearance -/obj/structure/displaycase/attackby(obj/item/W, mob/user) +/obj/structure/displaycase/attackby(obj/item/used_item, mob/user) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - var/obj/item/card/id/id = W.GetIdCard() + var/obj/item/card/id/id = used_item.GetIdCard() if(istype(id)) if(allowed(user)) locked = !locked @@ -103,13 +103,13 @@ to_chat(user, "\The [src]'s card reader denies you access.") return TRUE - if(isitem(W) && (!locked || destroyed)) - if(!W.simulated || W.anchored) + if(isitem(used_item) && (!locked || destroyed)) + if(!used_item.simulated || used_item.anchored) return FALSE - if(user.try_unequip(W, src)) - W.pixel_x = 0 - W.pixel_y = -7 + if(user.try_unequip(used_item, src)) + used_item.pixel_x = 0 + used_item.pixel_y = -7 update_icon() return TRUE . = ..() diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 9aba1e77c074..cf7af2c01748 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -123,9 +123,9 @@ icon_state = "shutter1" airlock_type = /obj/machinery/door/blast/shutters -/obj/structure/door_assembly/attackby(obj/item/W, mob/user) +/obj/structure/door_assembly/attackby(obj/item/used_item, mob/user) - if(IS_PEN(W)) + if(IS_PEN(used_item)) var/t = sanitize_safe(input(user, "Enter the name for the door.", src.name, src.created_name), MAX_NAME_LEN) if(!length(t)) return TRUE @@ -135,9 +135,9 @@ created_name = t return TRUE - if(IS_WELDER(W) && (glass == 1 || !anchored)) - var/obj/item/weldingtool/WT = W - if (WT.weld(0, user)) + if(IS_WELDER(used_item) && (glass == 1 || !anchored)) + var/obj/item/weldingtool/welder = used_item + if (welder.weld(0, user)) playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1) if(glass == 1) var/decl/material/glass_material_datum = GET_DECL(glass_material) @@ -145,7 +145,7 @@ var/mat_name = glass_material_datum.solid_name || glass_material_datum.name user.visible_message("[user] welds the [mat_name] plating off the airlock assembly.", "You start to weld the [mat_name] plating off the airlock assembly.") if(do_after(user, 4 SECONDS, src)) - if(!WT.isOn()) + if(!welder.isOn()) return TRUE to_chat(user, "You welded the [mat_name] plating off!") glass_material_datum.create_object(get_turf(src), 2) @@ -155,7 +155,7 @@ if(!anchored) user.visible_message("[user] dissassembles the airlock assembly.", "You start to dissassemble the airlock assembly.") if(do_after(user, 4 SECONDS, src)) - if(!WT.isOn()) + if(!welder.isOn()) return TRUE to_chat(user, "You dissasembled the airlock assembly!") dismantle_structure(user) @@ -164,7 +164,7 @@ to_chat(user, "You need more welding fuel.") return TRUE - if(IS_WRENCH(W) && state == 0) + if(IS_WRENCH(used_item) && state == 0) playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1) if(anchored) user.visible_message("[user] begins unsecuring the airlock assembly from the floor.", "You begin unsecuring the airlock assembly from the floor.") @@ -179,8 +179,8 @@ return TRUE - else if(IS_COIL(W) && state == 0 && anchored) - var/obj/item/stack/cable_coil/C = W + else if(IS_COIL(used_item) && state == 0 && anchored) + var/obj/item/stack/cable_coil/C = used_item if (C.get_amount() < 1) to_chat(user, "You need one length of coil to wire the airlock assembly.") return TRUE @@ -192,7 +192,7 @@ update_icon() return TRUE - else if(IS_WIRECUTTER(W) && state == 1 ) + else if(IS_WIRECUTTER(used_item) && state == 1 ) playsound(src.loc, 'sound/items/Wirecutter.ogg', 100, 1) user.visible_message("[user] cuts the wires from the airlock assembly.", "You start to cut the wires from airlock assembly.") @@ -204,8 +204,8 @@ update_icon() return TRUE - else if(istype(W, /obj/item/stock_parts/circuitboard/airlock_electronics) && state == 1) - var/obj/item/stock_parts/circuitboard/airlock_electronics/E = W + else if(istype(used_item, /obj/item/stock_parts/circuitboard/airlock_electronics) && state == 1) + var/obj/item/stock_parts/circuitboard/airlock_electronics/E = used_item if(!ispath(airlock_type, E.build_path)) return FALSE playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) @@ -213,16 +213,16 @@ if(do_after(user, 40,src)) if(QDELETED(src)) return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE to_chat(user, "You installed the airlock electronics!") src.state = 2 src.SetName("Near finished Airlock Assembly") - src.electronics = W + src.electronics = used_item update_icon() return TRUE - else if(IS_CROWBAR(W) && state == 2 ) + else if(IS_CROWBAR(used_item) && state == 2 ) //This should never happen, but just in case I guess if (!electronics) to_chat(user, "There was nothing to remove.") @@ -243,8 +243,8 @@ update_icon() return TRUE - else if(istype(W, /obj/item/stack/material) && !glass) - var/obj/item/stack/material/S = W + else if(istype(used_item, /obj/item/stack/material) && !glass) + var/obj/item/stack/material/S = used_item var/material_name = S.get_material_type() if (S.get_amount() >= 2) playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1) @@ -258,7 +258,7 @@ return TRUE return FALSE - else if(IS_SCREWDRIVER(W) && state == 2 ) + else if(IS_SCREWDRIVER(used_item) && state == 2 ) playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) to_chat(user, "Now finishing the airlock.") diff --git a/code/game/objects/structures/drain.dm b/code/game/objects/structures/drain.dm index 3b8e57ce9f49..7863c0f7c171 100644 --- a/code/game/objects/structures/drain.dm +++ b/code/game/objects/structures/drain.dm @@ -18,8 +18,8 @@ /obj/structure/hygiene/drain/attackby(var/obj/item/thing, var/mob/user) if(IS_WELDER(thing)) - var/obj/item/weldingtool/WT = thing - if(WT.isOn()) + var/obj/item/weldingtool/welder = thing + if(welder.isOn()) welded = !welded to_chat(user, "You weld \the [src] [welded ? "closed" : "open"].") else diff --git a/code/game/objects/structures/drying_rack.dm b/code/game/objects/structures/drying_rack.dm index 6bfacec89299..40f44e2c3fc6 100644 --- a/code/game/objects/structures/drying_rack.dm +++ b/code/game/objects/structures/drying_rack.dm @@ -54,12 +54,12 @@ if(drying_state) add_overlay(drying_state) -/obj/structure/drying_rack/attackby(var/obj/item/W, var/mob/user) +/obj/structure/drying_rack/attackby(var/obj/item/used_item, var/mob/user) - if(!drying && W.is_dryable()) - if(user.try_unequip(W)) - W.forceMove(src) - drying = W + if(!drying && used_item.is_dryable()) + if(user.try_unequip(used_item)) + used_item.forceMove(src) + drying = used_item if(!is_processing) START_PROCESSING(SSobj, src) update_icon() diff --git a/code/game/objects/structures/fishtanks.dm b/code/game/objects/structures/fishtanks.dm index f11786c8c397..313c92a5ccd7 100644 --- a/code/game/objects/structures/fishtanks.dm +++ b/code/game/objects/structures/fishtanks.dm @@ -70,10 +70,10 @@ var/global/list/fishtank_cache = list() visible_message(SPAN_NOTICE("\The [user] taps on \the [src].")) return TRUE -/obj/structure/glass_tank/attackby(var/obj/item/W, var/mob/user) - if(W.get_attack_force(user) < 5 || !user.check_intent(I_FLAG_HARM)) +/obj/structure/glass_tank/attackby(var/obj/item/used_item, var/mob/user) + if(used_item.get_attack_force(user) < 5 || !user.check_intent(I_FLAG_HARM)) attack_animation(user) - visible_message(SPAN_NOTICE("\The [user] taps \the [src] with \the [W].")) + visible_message(SPAN_NOTICE("\The [user] taps \the [src] with \the [used_item].")) else . = ..() diff --git a/code/game/objects/structures/fitness.dm b/code/game/objects/structures/fitness.dm index 6cbc033c7a37..f467fab29b45 100644 --- a/code/game/objects/structures/fitness.dm +++ b/code/game/objects/structures/fitness.dm @@ -42,8 +42,8 @@ var/list/success_message = list("with great effort", "straining hard", "without any trouble", "with ease") var/list/fail_message = list(", lifting them part of the way and then letting them drop", ", unable to even budge them") -/obj/structure/fitness/weightlifter/attackby(obj/item/W, mob/user) - if(IS_WRENCH(W)) +/obj/structure/fitness/weightlifter/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item)) playsound(src.loc, 'sound/items/Deconstruct.ogg', 75, 1) weight = (weight % max_weight) + 1 to_chat(user, "You set the machine's weight level to [weight].") diff --git a/code/game/objects/structures/flaps.dm b/code/game/objects/structures/flaps.dm index 3208d09cc814..b3b305a9f946 100644 --- a/code/game/objects/structures/flaps.dm +++ b/code/game/objects/structures/flaps.dm @@ -41,14 +41,14 @@ return ..() -/obj/structure/flaps/attackby(obj/item/W, mob/user) - if(IS_CROWBAR(W) && !anchored) +/obj/structure/flaps/attackby(obj/item/used_item, mob/user) + if(IS_CROWBAR(used_item) && !anchored) user.visible_message("\The [user] begins deconstructing \the [src].", "You start deconstructing \the [src].") if(user.do_skilled(3 SECONDS, SKILL_CONSTRUCTION, src)) user.visible_message("\The [user] deconstructs \the [src].", "You deconstruct \the [src].") qdel(src) return TRUE - if(IS_SCREWDRIVER(W) && anchored) + if(IS_SCREWDRIVER(used_item) && anchored) airtight = !airtight airtight ? become_airtight() : clear_airtight() user.visible_message("\The [user] adjusts \the [src], [airtight ? "preventing" : "allowing"] air flow.") diff --git a/code/game/objects/structures/fuel_port.dm b/code/game/objects/structures/fuel_port.dm index 91eef126f0bb..6488d9972ad2 100644 --- a/code/game/objects/structures/fuel_port.dm +++ b/code/game/objects/structures/fuel_port.dm @@ -51,9 +51,9 @@ else add_overlay("[icon_state]_closed") -/obj/structure/fuel_port/attackby(obj/item/W, mob/user) +/obj/structure/fuel_port/attackby(obj/item/used_item, mob/user) . = FALSE - if(W.do_tool_interaction(TOOL_CROWBAR, user, src, 1 SECOND)) + if(used_item.do_tool_interaction(TOOL_CROWBAR, user, src, 1 SECOND)) if(open) playsound(src, sound_open, 25, 0, -3) open = FALSE @@ -62,7 +62,7 @@ open = TRUE . = TRUE - else if(istype(W, /obj/item/tank)) + else if(istype(used_item, /obj/item/tank)) if(!open) to_chat(user, SPAN_WARNING("\The [src] door is still closed!")) return TRUE @@ -71,7 +71,7 @@ to_chat(user, SPAN_WARNING("\The [src] already has a tank inside!")) return TRUE else - user.try_unequip(W, src) + user.try_unequip(used_item, src) . = TRUE if(.) diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm index a82c4c7733da..d168182cdcc2 100644 --- a/code/game/objects/structures/girders.dm +++ b/code/game/objects/structures/girders.dm @@ -92,37 +92,37 @@ return FALSE . = ..() -/obj/structure/girder/attackby(var/obj/item/W, var/mob/user) +/obj/structure/girder/attackby(var/obj/item/used_item, var/mob/user) // Other methods of quickly destroying a girder. - if(W.is_special_cutting_tool(TRUE)) - if(istype(W, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = W + if(used_item.is_special_cutting_tool(TRUE)) + if(istype(used_item, /obj/item/gun/energy/plasmacutter)) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(!cutter.slice(user)) return TRUE playsound(src.loc, 'sound/items/Welder.ogg', 100, 1) - visible_message(SPAN_NOTICE("\The [user] begins slicing apart \the [src] with \the [W].")) + visible_message(SPAN_NOTICE("\The [user] begins slicing apart \the [src] with \the [used_item].")) if(do_after(user,reinf_material ? 40: 20,src)) - visible_message(SPAN_NOTICE("\The [user] slices apart \the [src] with \the [W].")) + visible_message(SPAN_NOTICE("\The [user] slices apart \the [src] with \the [used_item].")) dismantle_structure(user) return TRUE - if(IS_PICK(W)) - if(W.material?.hardness < material.hardness) - to_chat(user, SPAN_WARNING("\The [W] is not hard enough to excavate [material.solid_name].")) - else if(W.get_tool_quality(TOOL_PICK) < TOOL_QUALITY_GOOD) - to_chat(user, SPAN_WARNING("\The [W] is not capable of destroying \the [src].")) - else if(W.do_tool_interaction(TOOL_PICK, user, src, (reinf_material ? 6 : 4) SECONDS, set_cooldown = TRUE)) + if(IS_PICK(used_item)) + if(used_item.material?.hardness < material.hardness) + to_chat(user, SPAN_WARNING("\The [used_item] is not hard enough to excavate [material.solid_name].")) + else if(used_item.get_tool_quality(TOOL_PICK) < TOOL_QUALITY_GOOD) + to_chat(user, SPAN_WARNING("\The [used_item] is not capable of destroying \the [src].")) + else if(used_item.do_tool_interaction(TOOL_PICK, user, src, (reinf_material ? 6 : 4) SECONDS, set_cooldown = TRUE)) dismantle_structure(user) return TRUE // Reinforcing a girder, or turning it into a wall. - if(istype(W, /obj/item/stack/material)) + if(istype(used_item, /obj/item/stack/material)) if(anchored) - return construct_wall(W, user) + return construct_wall(used_item, user) else if(reinf_material) to_chat(user, SPAN_WARNING("\The [src] is already reinforced with [reinf_material.solid_name].")) else - return reinforce_with_material(W, user) + return reinforce_with_material(used_item, user) return TRUE . = ..() diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index f1717f3be263..2577519149b1 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -166,13 +166,13 @@ parts_amount = 1 update_icon() -/obj/structure/grille/attackby(obj/item/W, mob/user) - if(IS_WIRECUTTER(W)) +/obj/structure/grille/attackby(obj/item/used_item, mob/user) + if(IS_WIRECUTTER(used_item)) if(!material.conductive || !shock(user, 100)) cut_grille() return TRUE - if((IS_SCREWDRIVER(W))) + if((IS_SCREWDRIVER(used_item))) var/turf/turf = loc if(((istype(turf) && turf.simulated) || anchored)) if(!shock(user, 90)) @@ -187,8 +187,8 @@ return TRUE //window placing - if(istype(W,/obj/item/stack/material)) - var/obj/item/stack/material/ST = W + if(istype(used_item,/obj/item/stack/material)) + var/obj/item/stack/material/ST = used_item if(ST.material.opacity > 0.7) return FALSE @@ -204,15 +204,15 @@ place_window(user, loc, dir_to_set, ST) return TRUE - if(!(W.obj_flags & OBJ_FLAG_CONDUCTIBLE) || !shock(user, 70)) + if(!(used_item.obj_flags & OBJ_FLAG_CONDUCTIBLE) || !shock(user, 70)) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) playsound(loc, 'sound/effects/grillehit.ogg', 80, 1) - switch(W.atom_damage_type) + switch(used_item.atom_damage_type) if(BURN) - take_damage(W.expend_attack_force(user)) + take_damage(used_item.expend_attack_force(user)) if(BRUTE) - take_damage(W.expend_attack_force(user) * 0.1) + take_damage(used_item.expend_attack_force(user) * 0.1) return TRUE return ..() diff --git a/code/game/objects/structures/holosigns.dm b/code/game/objects/structures/holosigns.dm index 5e9ace14110d..d0c2b590a36f 100644 --- a/code/game/objects/structures/holosigns.dm +++ b/code/game/objects/structures/holosigns.dm @@ -25,8 +25,8 @@ deactivate(user) return TRUE -/obj/structure/holosign/attackby(obj/W, mob/user) - visible_message(SPAN_NOTICE("\The [user] waves \a [W] through \the [src], causing it to dissipate.")) +/obj/structure/holosign/attackby(obj/item/used_item, mob/user) + visible_message(SPAN_NOTICE("\The [user] waves \a [used_item] through \the [src], causing it to dissipate.")) deactivate(user) return TRUE diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm index 1f7913057f0d..137ce1cba193 100644 --- a/code/game/objects/structures/inflatable.dm +++ b/code/game/objects/structures/inflatable.dm @@ -137,14 +137,14 @@ current_health = clamp(current_health + 3, 0, get_max_health()) taped = TRUE -/obj/structure/inflatable/attackby(obj/item/W, mob/user) +/obj/structure/inflatable/attackby(obj/item/used_item, mob/user) - if((W.atom_damage_type == BRUTE || W.atom_damage_type == BURN) && (W.can_puncture() || W.expend_attack_force(user) > 10)) - visible_message(SPAN_DANGER("\The [user] pierces \the [src] with \the [W]!")) + if((used_item.atom_damage_type == BRUTE || used_item.atom_damage_type == BURN) && (used_item.can_puncture() || used_item.expend_attack_force(user) > 10)) + visible_message(SPAN_DANGER("\The [user] pierces \the [src] with \the [used_item]!")) deflate(TRUE) return TRUE - if(!istype(W, /obj/item/inflatable_dispenser)) + if(!istype(used_item, /obj/item/inflatable_dispenser)) return ..() return FALSE diff --git a/code/game/objects/structures/iv_drip.dm b/code/game/objects/structures/iv_drip.dm index ffc24bfd1b37..796690f63565 100644 --- a/code/game/objects/structures/iv_drip.dm +++ b/code/game/objects/structures/iv_drip.dm @@ -84,15 +84,15 @@ return TRUE . = ..() -/obj/structure/iv_drip/attackby(obj/item/W, mob/user) - if (istype(W, /obj/item/chems)) +/obj/structure/iv_drip/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/chems)) if(!isnull(src.beaker)) to_chat(user, "There is already a reagent container loaded!") return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - beaker = W - to_chat(user, "You attach \the [W] to \the [src].") + beaker = used_item + to_chat(user, "You attach \the [used_item] to \the [src].") queue_icon_update() return TRUE else diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 6f5f9c950c80..6681b61e3e99 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -70,8 +70,8 @@ T.attackby(C, user) //BubbleWrap - hand this off to the underlying turf instead return TRUE if(IS_WELDER(C)) - var/obj/item/weldingtool/WT = C - if(WT.weld(0, user)) + var/obj/item/weldingtool/welder = C + if(welder.weld(0, user)) deconstruct(user) return TRUE if(istype(C, /obj/item/gun/energy/plasmacutter)) diff --git a/code/game/objects/structures/quicksand.dm b/code/game/objects/structures/quicksand.dm index fbbd3393c87e..b3e1cffa4809 100644 --- a/code/game/objects/structures/quicksand.dm +++ b/code/game/objects/structures/quicksand.dm @@ -79,8 +79,8 @@ exposed = 1 update_icon() -/obj/effect/quicksand/attackby(obj/item/W, mob/user) - if(!exposed && W.expend_attack_force(user)) +/obj/effect/quicksand/attackby(obj/item/used_item, mob/user) + if(!exposed && used_item.expend_attack_force(user)) expose() return TRUE else diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index b453621b6a5c..bc8b5c27e301 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -247,9 +247,9 @@ WOOD_RAILING_SUBTYPE(yew) return TRUE // TODO: rewrite to use handle_default_wrench_attackby, bash, etc -/obj/structure/railing/attackby(var/obj/item/W, var/mob/user) +/obj/structure/railing/attackby(var/obj/item/used_item, var/mob/user) // Dismantle - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) if(!anchored) playsound(loc, 'sound/items/Ratchet.ogg', 50, 1) if(do_after(user, 2 SECONDS, src)) @@ -272,8 +272,8 @@ WOOD_RAILING_SUBTYPE(yew) update_icon() return TRUE // Repair - if(IS_WELDER(W)) - var/obj/item/weldingtool/F = W + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/F = used_item if(F.isOn()) var/current_max_health = get_max_health() if(current_health >= current_max_health) @@ -288,7 +288,7 @@ WOOD_RAILING_SUBTYPE(yew) return TRUE // Install - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) if(!density) to_chat(user, "You need to wrench \the [src] from back into place first.") return TRUE @@ -301,11 +301,11 @@ WOOD_RAILING_SUBTYPE(yew) update_icon() return TRUE - var/force = W.expend_attack_force(user) - if(force && (W.atom_damage_type == BURN || W.atom_damage_type == BRUTE)) + var/force = used_item.expend_attack_force(user) + if(force && (used_item.atom_damage_type == BURN || used_item.atom_damage_type == BRUTE)) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - visible_message("\The [src] has been [LAZYLEN(W.attack_verb) ? pick(W.attack_verb) : "attacked"] with \the [W] by \the [user]!") - take_damage(force, W.atom_damage_type) + visible_message("\The [src] has been [LAZYLEN(used_item.attack_verb) ? pick(used_item.attack_verb) : "attacked"] with \the [used_item] by \the [user]!") + take_damage(force, used_item.atom_damage_type) return TRUE . = ..() diff --git a/code/game/objects/structures/signs.dm b/code/game/objects/structures/signs.dm index 22861d9d861f..0b1245e25d7c 100644 --- a/code/game/objects/structures/signs.dm +++ b/code/game/objects/structures/signs.dm @@ -23,9 +23,9 @@ try_install(target, user) return TRUE -/obj/item/sign/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W) && W.CanUseTopic(user, global.inventory_topic_state) && isturf(user.loc)) - return try_install(W, user) +/obj/item/sign/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item) && used_item.CanUseTopic(user, global.inventory_topic_state) && isturf(user.loc)) + return try_install(used_item, user) return ..() /obj/item/sign/on_update_icon() diff --git a/code/game/objects/structures/signs/diploma.dm b/code/game/objects/structures/signs/diploma.dm index a6bbf52d992b..f3e929982b6d 100644 --- a/code/game/objects/structures/signs/diploma.dm +++ b/code/game/objects/structures/signs/diploma.dm @@ -125,9 +125,9 @@ if(distance <= 2) . += details.get_examine_string() -/obj/item/sign/diploma/attackby(obj/item/pen/W, mob/user) - if(IS_PEN(W)) - sign_diploma(W, user) +/obj/item/sign/diploma/attackby(obj/item/used_item, mob/user) + if(IS_PEN(used_item)) + sign_diploma(used_item, user) return TRUE return ..() diff --git a/code/game/objects/structures/skele_stand.dm b/code/game/objects/structures/skele_stand.dm index 95ce5fb549c2..4b3d9d944d18 100644 --- a/code/game/objects/structures/skele_stand.dm +++ b/code/game/objects/structures/skele_stand.dm @@ -56,25 +56,25 @@ swagnames += C.get_examine_line() . += "[gender == MALE ? "He" : "She"] is wearing [english_list(swagnames)]." -/obj/structure/skele_stand/attackby(obj/item/W, mob/user) - if(IS_PEN(W)) +/obj/structure/skele_stand/attackby(obj/item/used_item, mob/user) + if(IS_PEN(used_item)) var/nuname = sanitize(input(user,"What do you want to name this skeleton as?","Skeleton Christening",name) as text|null) if(nuname && CanPhysicallyInteract(user)) SetName(nuname) return TRUE - if(istype(W,/obj/item/clothing)) - var/obj/item/clothing/clothes = W + if(istype(used_item,/obj/item/clothing)) + var/obj/item/clothing/clothes = used_item if(!clothes.fallback_slot) return FALSE if(swag[clothes.fallback_slot]) to_chat(user,SPAN_NOTICE("There is already that kind of clothing on \the [src].")) - else if(user.try_unequip(W, src)) - swag[clothes.fallback_slot] = W + else if(user.try_unequip(used_item, src)) + swag[clothes.fallback_slot] = used_item update_icon() return TRUE . = ..() if(!.) - rattle_bones(user, W) + rattle_bones(user, used_item) return TRUE /obj/structure/skele_stand/Destroy() diff --git a/code/game/objects/structures/tables.dm b/code/game/objects/structures/tables.dm index 98a4918cb530..85874e57021d 100644 --- a/code/game/objects/structures/tables.dm +++ b/code/game/objects/structures/tables.dm @@ -179,9 +179,9 @@ update_materials() return TRUE -/obj/structure/table/attackby(obj/item/W, mob/user, click_params) +/obj/structure/table/attackby(obj/item/used_item, mob/user, click_params) - if(user.check_intent(I_FLAG_HARM) && W.is_special_cutting_tool()) + if(user.check_intent(I_FLAG_HARM) && used_item.is_special_cutting_tool()) spark_at(src.loc, amount=5) playsound(src.loc, 'sound/weapons/blade1.ogg', 50, 1) user.visible_message(SPAN_DANGER("\The [src] was sliced apart by \the [user]!")) @@ -189,14 +189,14 @@ return TRUE if(!reinf_material) - if(istype(W, /obj/item/stack/material/rods)) - return reinforce_table(W, user) - if(istype(W, /obj/item/stack/material)) - return finish_table(W, user) + if(istype(used_item, /obj/item/stack/material/rods)) + return reinforce_table(used_item, user) + if(istype(used_item, /obj/item/stack/material)) + return finish_table(used_item, user) return ..() - if(!felted && istype(W, /obj/item/stack/tile/carpet)) - var/obj/item/stack/tile/carpet/C = W + if(!felted && istype(used_item, /obj/item/stack/tile/carpet)) + var/obj/item/stack/tile/carpet/C = used_item if(C.use(1)) user.visible_message( SPAN_NOTICE("\The [user] adds \the [C] to \the [src]."), @@ -208,15 +208,15 @@ return TRUE //playing cards - if(istype(W, /obj/item/hand)) - var/obj/item/hand/H = W + if(istype(used_item, /obj/item/hand)) + var/obj/item/hand/H = used_item if(H.cards && length(H.cards) == 1) user.visible_message("\The [user] plays \the [H.cards[1]].") return TRUE - if(istype(W, /obj/item/deck)) //playing cards + if(istype(used_item, /obj/item/deck)) //playing cards if(user.check_intent(I_FLAG_GRAB)) - var/obj/item/deck/D = W + var/obj/item/deck/D = used_item if(!length(D.cards)) to_chat(user, "There are no cards in the deck.") else @@ -226,8 +226,8 @@ . = ..() // Finally we can put the object onto the table. - if(!. && can_place_items && !isrobot(user) && W.loc == user && user.try_unequip(W, src.loc)) - auto_align(W, click_params) + if(!. && can_place_items && !isrobot(user) && used_item.loc == user && user.try_unequip(used_item, src.loc)) + auto_align(used_item, click_params) return TRUE /obj/structure/table/proc/reinforce_table(obj/item/stack/material/S, mob/user) @@ -393,26 +393,26 @@ return var/list/blocked_dirs = list() - for(var/obj/structure/window/W in get_turf(src)) - if(W.is_fulltile()) + for(var/obj/structure/window/used_item in get_turf(src)) + if(used_item.is_fulltile()) connections = list("0", "0", "0", "0") return - blocked_dirs |= W.dir + blocked_dirs |= used_item.dir for(var/D in list(NORTH, SOUTH, EAST, WEST) - blocked_dirs) var/turf/T = get_step(src, D) - for(var/obj/structure/window/W in T) - if(W.is_fulltile() || W.dir == global.reverse_dir[D]) + for(var/obj/structure/window/used_item in T) + if(used_item.is_fulltile() || used_item.dir == global.reverse_dir[D]) blocked_dirs |= D break else - if(W.dir != D) // it's off to the side - blocked_dirs |= W.dir|D // blocks the diagonal + if(used_item.dir != D) // it's off to the side + blocked_dirs |= used_item.dir|D // blocks the diagonal for(var/D in list(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST) - blocked_dirs) var/turf/T = get_step(src, D) - for(var/obj/structure/window/W in T) - if(W.is_fulltile() || (W.dir & global.reverse_dir[D])) + for(var/obj/structure/window/used_item in T) + if(used_item.is_fulltile() || (used_item.dir & global.reverse_dir[D])) blocked_dirs |= D break diff --git a/code/game/objects/structures/wall_frame.dm b/code/game/objects/structures/wall_frame.dm index b4d8c7a46054..21bf8027cd36 100644 --- a/code/game/objects/structures/wall_frame.dm +++ b/code/game/objects/structures/wall_frame.dm @@ -57,33 +57,33 @@ else return SPAN_DANGER("It's nearly falling to pieces.") -/obj/structure/wall_frame/attackby(var/obj/item/W, var/mob/user) +/obj/structure/wall_frame/attackby(var/obj/item/used_item, var/mob/user) . = ..() if(!.) //grille placing - if(istype(W, /obj/item/stack/material/rods)) + if(istype(used_item, /obj/item/stack/material/rods)) for(var/obj/structure/window/WINDOW in loc) if(WINDOW.dir == get_dir(src, user)) to_chat(user, SPAN_WARNING("There is a window in the way.")) return TRUE - place_grille(user, loc, W) + place_grille(user, loc, used_item) return TRUE //window placing - if(istype(W,/obj/item/stack/material)) - var/obj/item/stack/material/ST = W + if(istype(used_item,/obj/item/stack/material)) + var/obj/item/stack/material/ST = used_item if(ST.material.opacity <= 0.7) place_window(user, loc, SOUTHWEST, ST) return TRUE - if(istype(W, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = W + if(istype(used_item, /obj/item/gun/energy/plasmacutter)) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(!cutter.slice(user)) return playsound(src.loc, 'sound/items/Welder.ogg', 100, 1) - visible_message(SPAN_NOTICE("\The [user] begins slicing through \the [src] with \the [W].")) + visible_message(SPAN_NOTICE("\The [user] begins slicing through \the [src] with \the [used_item].")) if(do_after(user, 20,src)) - visible_message(SPAN_NOTICE("\The [user] slices \the [src] apart with \the [W].")) + visible_message(SPAN_NOTICE("\The [user] slices \the [src] apart with \the [used_item].")) dismantle_structure(user) return TRUE diff --git a/code/game/objects/structures/wall_sconce.dm b/code/game/objects/structures/wall_sconce.dm index c1211712b3c8..c87951094585 100644 --- a/code/game/objects/structures/wall_sconce.dm +++ b/code/game/objects/structures/wall_sconce.dm @@ -86,22 +86,22 @@ return ..() -/obj/structure/wall_sconce/attackby(obj/item/W, mob/user) +/obj/structure/wall_sconce/attackby(obj/item/used_item, mob/user) if(user.check_intent(I_FLAG_HARM)) return ..() - if(IS_HAMMER(W) || IS_WRENCH(W)) + if(IS_HAMMER(used_item) || IS_WRENCH(used_item)) dismantle_structure(user) return TRUE - if(W.isflamesource() && light_source && !light_source.lit) - light_source.attackby(W, user) + if(used_item.isflamesource() && light_source && !light_source.lit) + light_source.attackby(used_item, user) update_icon() return TRUE - if(istype(W, /obj/item/flame)) - var/obj/item/flame/flame = W + if(istype(used_item, /obj/item/flame)) + var/obj/item/flame/flame = used_item if(flame.sconce_can_hold) if(light_source) @@ -115,8 +115,8 @@ return TRUE // Refilling - if(light_source && istype(W, /obj/item/chems)) - var/obj/item/chems/chem_source = W + if(light_source && istype(used_item, /obj/item/chems)) + var/obj/item/chems/chem_source = used_item if(chem_source.standard_pour_into(user, light_source)) return TRUE diff --git a/code/game/objects/structures/wallframe_spawner.dm b/code/game/objects/structures/wallframe_spawner.dm index 2573ad0514fb..c9cd8a5043da 100644 --- a/code/game/objects/structures/wallframe_spawner.dm +++ b/code/game/objects/structures/wallframe_spawner.dm @@ -53,10 +53,10 @@ if(!other) var/found_connection if(locate(/obj/structure/grille) in T) - for(var/obj/structure/window/W in T) - if(W.type == win_path && W.dir == get_dir(T,src)) + for(var/obj/structure/window/window in T) + if(window.type == win_path && window.dir == get_dir(T,src)) found_connection = 1 - qdel(W) + qdel(window) if(!found_connection) var/obj/structure/window/new_win = new win_path(loc) new_win.set_dir(dir) @@ -84,7 +84,7 @@ D.update_connections() D.update_icon() -/obj/effect/wallframe_spawn/proc/handle_window_spawn(var/obj/structure/window/W) +/obj/effect/wallframe_spawn/proc/handle_window_spawn(var/obj/structure/window/window) return /obj/effect/wallframe_spawn/proc/handle_grille_spawn(var/obj/structure/grille/G) diff --git a/code/game/objects/structures/windoor_assembly.dm b/code/game/objects/structures/windoor_assembly.dm index 56324d48a196..8fbd7f7f983e 100644 --- a/code/game/objects/structures/windoor_assembly.dm +++ b/code/game/objects/structures/windoor_assembly.dm @@ -115,11 +115,11 @@ return TRUE return FALSE -/obj/structure/windoor_assembly/attackby(obj/item/W, mob/user) +/obj/structure/windoor_assembly/attackby(obj/item/used_item, mob/user) . = ..() if(!. && anchored) - if(!secure && istype(W, /obj/item/stack/material/rods)) - var/obj/item/stack/material/rods/R = W + if(!secure && istype(used_item, /obj/item/stack/material/rods)) + var/obj/item/stack/material/rods/R = used_item if(R.get_amount() < 4) to_chat(user, SPAN_WARNING("You need more rods to do this.")) return TRUE @@ -128,14 +128,14 @@ visible_message(SPAN_NOTICE("\The [user] finishes reinforcing \the [src].")) secure = TRUE . = TRUE - else if(wired && !electronics && istype(W, /obj/item/stock_parts/circuitboard/airlock_electronics/windoor)) + else if(wired && !electronics && istype(used_item, /obj/item/stock_parts/circuitboard/airlock_electronics/windoor)) playsound(loc, 'sound/items/Screwdriver.ogg', 100, 1) - visible_message(SPAN_NOTICE("\The [user] starts installing \the [W] into \the [src].")) - if(do_after(user, 4 SECONDS, src) && wired && !electronics && anchored && !QDELETED(src) && user.try_unequip(W, src)) - visible_message(SPAN_NOTICE("\The [user] finishes installing \the [W] into \the [src].")) - electronics = W + visible_message(SPAN_NOTICE("\The [user] starts installing \the [used_item] into \the [src].")) + if(do_after(user, 4 SECONDS, src) && wired && !electronics && anchored && !QDELETED(src) && user.try_unequip(used_item, src)) + visible_message(SPAN_NOTICE("\The [user] finishes installing \the [used_item] into \the [src].")) + electronics = used_item else - W.dropInto(loc) + used_item.dropInto(loc) . = TRUE update_icon() update_name() diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index dcc075f7e4f6..0ce9a908ac93 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -252,9 +252,9 @@ to_chat(user, SPAN_NOTICE("You cut the wiring and remove the polarization from \the [src].")) return TRUE -/obj/structure/window/attackby(obj/item/W, mob/user) +/obj/structure/window/attackby(obj/item/used_item, mob/user) // bespoke interactions not handled by the prior procs - if(IS_MULTITOOL(W)) + if(IS_MULTITOOL(used_item)) if (!polarized) to_chat(user, SPAN_WARNING("\The [src] is not polarized.")) return TRUE @@ -264,13 +264,13 @@ toggle() else var/response = input(user, "New Window ID:", name, id) as null | text - if (isnull(response) || user.incapacitated() || !user.Adjacent(src) || user.get_active_held_item() != W) + if (isnull(response) || user.incapacitated() || !user.Adjacent(src) || user.get_active_held_item() != used_item) return TRUE id = sanitize_safe(response, MAX_NAME_LEN) to_chat(user, SPAN_NOTICE("The new ID of \the [src] is [id].")) return TRUE - else if(istype(W, /obj/item/gun/energy/plasmacutter) && anchored) - var/obj/item/gun/energy/plasmacutter/cutter = W + else if(istype(used_item, /obj/item/gun/energy/plasmacutter) && anchored) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(!cutter.slice(user)) return TRUE // failed to finish or otherwise failed, prevent further interactions playsound(src, 'sound/items/Welder.ogg', 80, 1) @@ -279,7 +279,7 @@ visible_message(SPAN_WARNING("[user] has sliced through the window's frame!")) playsound(src, 'sound/items/Welder.ogg', 80, 1) set_anchored(FALSE) - if (istype(W, /obj/item/paint_sprayer)) + if (istype(used_item, /obj/item/paint_sprayer)) return FALSE // allow afterattack to run return ..() // handle generic interactions, bashing, etc @@ -414,8 +414,8 @@ //This proc is used to update the icons of nearby windows. It should not be confused with update_nearby_tiles(), which is an atmos proc! /obj/structure/window/proc/update_nearby_icons() update_icon() - for(var/obj/structure/window/W in orange(src, 1)) - W.update_icon() + for(var/obj/structure/window/window in orange(src, 1)) + window.update_icon() // Visually connect with every type of window as long as it's full-tile. /obj/structure/window/can_visually_connect() @@ -564,8 +564,8 @@ construct_state = /decl/machine_construction/wall_frame/panel_closed/simple base_type = /obj/machinery/button/windowtint -/obj/machinery/button/windowtint/attackby(obj/item/W, mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/button/windowtint/attackby(obj/item/used_item, mob/user) + if(IS_MULTITOOL(used_item)) var/t = sanitize_safe(input(user, "Enter the ID for the button.", name, id_tag), MAX_NAME_LEN) if(!CanPhysicallyInteract(user)) return TRUE @@ -579,9 +579,9 @@ /obj/machinery/button/windowtint/activate() if(operating) return - for(var/obj/structure/window/W in range(src,range)) - if(W.polarized && (W.id == id_tag || !W.id)) - W.toggle() + for(var/obj/structure/window/window in range(src,range)) + if(window.polarized && (window.id == id_tag || !window.id)) + window.toggle() ..() /obj/machinery/button/windowtint/power_change() diff --git a/code/game/objects/structures/window_spawner.dm b/code/game/objects/structures/window_spawner.dm index 95f24c0fd089..2178e5227954 100644 --- a/code/game/objects/structures/window_spawner.dm +++ b/code/game/objects/structures/window_spawner.dm @@ -50,10 +50,10 @@ if(!other) var/found_connection if(locate(/obj/structure/grille) in T) - for(var/obj/structure/window/W in T) - if(W.type == win_path && W.dir == get_dir(T,src)) + for(var/obj/structure/window/window in T) + if(window.type == win_path && window.dir == get_dir(T,src)) found_connection = 1 - qdel(W) + qdel(window) if(!found_connection) var/obj/structure/window/new_win = new win_path(loc) new_win.set_dir(dir) @@ -71,7 +71,7 @@ for(var/obj/effect/wingrille_spawn/other in neighbours) if(!other.activated) other.activate() -/obj/effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/W) +/obj/effect/wingrille_spawn/proc/handle_window_spawn(var/obj/structure/window/window) return // Currently unused, could be useful for pre-wired electrified windows. diff --git a/code/game/turfs/floors/floor_acts.dm b/code/game/turfs/floors/floor_acts.dm index 1280fd30cfa9..b231da61241b 100644 --- a/code/game/turfs/floors/floor_acts.dm +++ b/code/game/turfs/floors/floor_acts.dm @@ -54,6 +54,6 @@ /turf/floor/adjacent_fire_act(turf/adj_turf, datum/gas_mixture/adj_air, adj_temp, adj_volume) var/dir_to = get_dir(src, adj_turf) - for(var/obj/structure/window/W in src) - if(W.dir == dir_to || W.is_fulltile()) //Same direction or diagonal (full tile) - W.fire_act(adj_air, adj_temp, adj_volume) + for(var/obj/structure/window/window in src) + if(window.dir == dir_to || window.is_fulltile()) //Same direction or diagonal (full tile) + window.fire_act(adj_air, adj_temp, adj_volume) diff --git a/code/game/turfs/floors/floor_layers.dm b/code/game/turfs/floors/floor_layers.dm index e482d21fc5a4..7283ebaaf9c6 100644 --- a/code/game/turfs/floors/floor_layers.dm +++ b/code/game/turfs/floors/floor_layers.dm @@ -100,8 +100,8 @@ return LAZYCLEARLIST(decals) - for(var/obj/effect/decal/writing/W in src) - qdel(W) + for(var/obj/effect/decal/writing/writing in src) + qdel(writing) flooring.on_flooring_remove(src) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 36812e0f3f53..abd365c4f356 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -242,20 +242,20 @@ grab.affecting.DoMove(get_dir(grab.affecting.loc, src), user, TRUE) return TRUE -/turf/attackby(obj/item/W, mob/user) +/turf/attackby(obj/item/used_item, mob/user) if(is_floor()) - if(istype(W, /obj/item/stack/tile)) - var/obj/item/stack/tile/T = W + if(istype(used_item, /obj/item/stack/tile)) + var/obj/item/stack/tile/T = used_item T.try_build_turf(user, src) return TRUE - if(IS_HOE(W) && can_dig_farm(W.material?.hardness)) - try_dig_farm(user, W) + if(IS_HOE(used_item) && can_dig_farm(used_item.material?.hardness)) + try_dig_farm(user, used_item) return TRUE - if(IS_SHOVEL(W)) + if(IS_SHOVEL(used_item)) // TODO: move these checks into the interaction handlers. var/atom/platform = get_supporting_platform() @@ -263,20 +263,20 @@ to_chat(user, SPAN_WARNING("\The [platform] [platform.get_pronouns().is] in the way!")) return TRUE - if(!can_be_dug(W.material?.hardness)) - to_chat(user, SPAN_WARNING("\The [src] is too hard to be dug with \the [W].")) + if(!can_be_dug(used_item.material?.hardness)) + to_chat(user, SPAN_WARNING("\The [src] is too hard to be dug with \the [used_item].")) return TRUE - if(user.check_intent(I_FLAG_HELP) && can_dig_pit(W.material?.hardness)) - try_dig_pit(user, W) - else if(can_dig_trench(W.material?.hardness)) - try_dig_trench(user, W) + if(user.check_intent(I_FLAG_HELP) && can_dig_pit(used_item.material?.hardness)) + try_dig_pit(user, used_item) + else if(can_dig_trench(used_item.material?.hardness)) + try_dig_trench(user, used_item) else - to_chat(user, SPAN_WARNING("You cannot dig anything out of \the [src] with \the [W].")) + to_chat(user, SPAN_WARNING("You cannot dig anything out of \the [src] with \the [used_item].")) return TRUE var/decl/material/material = get_material() - if(IS_PICK(W) && material) + if(IS_PICK(used_item) && material) // TODO: move these checks into the interaction handlers. var/atom/platform = get_supporting_platform() @@ -285,29 +285,29 @@ return TRUE if(material?.hardness <= MAT_VALUE_FLEXIBLE) - to_chat(user, SPAN_WARNING("\The [src] is too soft to be excavated with \the [W]. Use a shovel.")) + to_chat(user, SPAN_WARNING("\The [src] is too soft to be excavated with \the [used_item]. Use a shovel.")) return TRUE // Let picks dig out hard turfs, but not dig pits. - if(!can_be_dug(W.material?.hardness, using_tool = TOOL_PICK)) - to_chat(user, SPAN_WARNING("\The [src] is too hard to be excavated with \the [W].")) + if(!can_be_dug(used_item.material?.hardness, using_tool = TOOL_PICK)) + to_chat(user, SPAN_WARNING("\The [src] is too hard to be excavated with \the [used_item].")) return TRUE - if(can_dig_trench(W.material?.hardness, using_tool = TOOL_PICK)) - try_dig_trench(user, W, using_tool = TOOL_PICK) + if(can_dig_trench(used_item.material?.hardness, using_tool = TOOL_PICK)) + try_dig_trench(user, used_item, using_tool = TOOL_PICK) else - to_chat(user, SPAN_WARNING("You cannot excavate \the [src] with \the [W].")) + to_chat(user, SPAN_WARNING("You cannot excavate \the [src] with \the [used_item].")) return TRUE - if(W?.storage?.collection_mode && W.storage.gather_all(src, user)) + if(used_item?.storage?.collection_mode && used_item.storage.gather_all(src, user)) return TRUE - if(istype(W, /obj/item) && storage && storage.use_to_pickup && storage.collection_mode) + if(istype(used_item, /obj/item) && storage && storage.use_to_pickup && storage.collection_mode) storage.gather_all(src, user) return TRUE - if(IS_COIL(W) && try_build_cable(W, user)) + if(IS_COIL(used_item) && try_build_cable(used_item, user)) return TRUE return ..() @@ -475,7 +475,7 @@ return var/too_much_graffiti = 0 - for(var/obj/effect/decal/writing/W in src) + for(var/obj/effect/decal/writing/writing in src) too_much_graffiti++ if(too_much_graffiti >= 5) to_chat(vandal, "There's too much graffiti here to add more.") diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index a43c8994c4d4..c320bdf00c46 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -95,34 +95,34 @@ qdel(src) . = new N(src) - var/turf/W = . - W.above = old_above // Multiz ref tracking. - W.prev_type = old_prev_type // Shuttle transition turf tracking. + var/turf/changed_turf = . + changed_turf.above = old_above // Multiz ref tracking. + changed_turf.prev_type = old_prev_type // Shuttle transition turf tracking. - W.affecting_heat_sources = old_affecting_heat_sources + changed_turf.affecting_heat_sources = old_affecting_heat_sources if (permit_ao) regenerate_ao() // Update ZAS, atmos and fire. - if(keep_air && W.can_inherit_air) - W.air = old_air + if(keep_air && changed_turf.can_inherit_air) + changed_turf.air = old_air if(old_fire) - if(W.simulated) - W.fire = old_fire + if(changed_turf.simulated) + changed_turf.fire = old_fire else if(old_fire) qdel(old_fire) - if(old_flooded != W.flooded) + if(old_flooded != changed_turf.flooded) set_flooded(old_flooded) // Raise appropriate events. - W.post_change() + changed_turf.post_change() if(tell_universe) - global.universe.OnTurfChange(W) + global.universe.OnTurfChange(changed_turf) - if(W.density != old_density) - RAISE_EVENT(/decl/observ/density_set, W, old_density, W.density) + if(changed_turf.density != old_density) + RAISE_EVENT(/decl/observ/density_set, changed_turf, old_density, changed_turf.density) // lighting stuff @@ -153,12 +153,12 @@ // end of lighting stuff // we check the var rather than the proc, because area outside values usually shouldn't be set on turfs - W.last_outside_check = OUTSIDE_UNCERTAIN - if(W.is_outside != old_outside) + changed_turf.last_outside_check = OUTSIDE_UNCERTAIN + if(changed_turf.is_outside != old_outside) // This will check the exterior atmos participation of this turf and all turfs connected by open space below. - W.set_outside(old_outside, skip_weather_update = TRUE) + changed_turf.set_outside(old_outside, skip_weather_update = TRUE) else // We didn't already update our external atmos participation in set_outside. - if(HasBelow(z) && (W.is_open() != old_is_open)) // Otherwise, we do it here if the open status of the turf has changed. + if(HasBelow(z) && (changed_turf.is_open() != old_is_open)) // Otherwise, we do it here if the open status of the turf has changed. var/turf/checking = src while(HasBelow(checking.z)) checking = GetBelow(checking) @@ -168,19 +168,19 @@ if(!checking.is_open()) break // In case the turf isn't marked for update in Initialize (e.g. space), we call this to create any unsimulated edges necessary. - if(W.zone_membership_candidate != old_zone_membership_candidate) + if(changed_turf.zone_membership_candidate != old_zone_membership_candidate) update_external_atmos_participation() - W.update_weather(force_update_below = W.is_open() != old_is_open) + changed_turf.update_weather(force_update_below = changed_turf.is_open() != old_is_open) if(keep_height) - W.set_physical_height(old_height) + changed_turf.set_physical_height(old_height) if(update_open_turfs_above) update_open_above(old_open_turf_type) if(old_alpha_mask_state != get_movable_alpha_mask_state(null)) - for(var/atom/movable/AM as anything in W) + for(var/atom/movable/AM as anything in changed_turf) AM.update_turf_alpha_mask() /turf/proc/transport_properties_from(turf/other, transport_air) diff --git a/code/game/turfs/walls/_wall.dm b/code/game/turfs/walls/_wall.dm index 3ad1fc1f62d8..22141ceed4d8 100644 --- a/code/game/turfs/walls/_wall.dm +++ b/code/game/turfs/walls/_wall.dm @@ -103,10 +103,10 @@ var/global/list/wall_fullblend_objects = list( . = ..() var/turf/debris = locate(old_x, old_y, old_z) if(debris) - for(var/turf/wall/W in RANGE_TURFS(debris, 1)) - W.wall_connections = null - W.other_connections = null - W.queue_icon_update() + for(var/turf/wall/wall in RANGE_TURFS(debris, 1)) + wall.wall_connections = null + wall.other_connections = null + wall.queue_icon_update() // Walls always hide the stuff below them. /turf/wall/levelupdate() @@ -301,9 +301,9 @@ var/global/list/wall_fullblend_objects = list( /turf/wall/proc/burn(temperature) if(!QDELETED(src) && istype(material) && material.combustion_effect(src, temperature, 0.7)) - for(var/turf/wall/W in range(3,src)) - if(W != src) - addtimer(CALLBACK(W, TYPE_PROC_REF(/turf/wall, burn), temperature/4), 2) + for(var/turf/wall/wall in range(3,src)) + if(wall != src) + addtimer(CALLBACK(wall, TYPE_PROC_REF(/turf/wall, burn), temperature/4), 2) physically_destroyed() /turf/wall/set_color(new_color) diff --git a/code/game/turfs/walls/wall_attacks.dm b/code/game/turfs/walls/wall_attacks.dm index 9e8eb62472e5..08f45bedcafe 100644 --- a/code/game/turfs/walls/wall_attacks.dm +++ b/code/game/turfs/walls/wall_attacks.dm @@ -111,48 +111,48 @@ if(!.) return try_touch(user, (locate(/obj/effect/overlay/wallrot) in src)) -/turf/wall/proc/handle_wall_tool_interactions(obj/item/W, mob/user) +/turf/wall/proc/handle_wall_tool_interactions(obj/item/used_item, mob/user) //get the user's location if(!isturf(user.loc)) return FALSE //can't do this stuff whilst inside objects and such - if(!construction_stage && try_graffiti(user, W)) + if(!construction_stage && try_graffiti(user, used_item)) return TRUE - if(W) + if(used_item) radiate() - if(W.get_heat() >= T100C) - burn(W.get_heat()) + if(used_item.get_heat() >= T100C) + burn(used_item.get_heat()) . = TRUE if(locate(/obj/effect/overlay/wallrot) in src) - if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W - if( WT.weld(0,user) ) - to_chat(user, "You burn away the fungi with \the [WT].") + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item + if( welder.weld(0,user) ) + to_chat(user, "You burn away the fungi with \the [welder].") playsound(src, 'sound/items/Welder.ogg', 10, 1) for(var/obj/effect/overlay/wallrot/WR in src) qdel(WR) return TRUE else - var/force = W.expend_attack_force(user) - if((!W.is_sharp() && !W.has_edge() && force >= 10) || force >= 20) - to_chat(user, "\The [src] crumbles away under the force of your [W.name].") + var/force = used_item.expend_attack_force(user) + if((!used_item.is_sharp() && !used_item.has_edge() && force >= 10) || force >= 20) + to_chat(user, "\The [src] crumbles away under the force of your [used_item.name].") physically_destroyed() return TRUE var/turf/T = user.loc //get user's location for delay checks - if(damage && istype(W, /obj/item/weldingtool)) + if(damage && istype(used_item, /obj/item/weldingtool)) - var/obj/item/weldingtool/WT = W + var/obj/item/weldingtool/welder = used_item - if(WT.weld(0,user)) + if(welder.weld(0,user)) to_chat(user, "You start repairing the damage to [src].") playsound(src, 'sound/items/Welder.ogg', 100, 1) - if(do_after(user, max(5, damage / 5), src) && WT && WT.isOn()) + if(do_after(user, max(5, damage / 5), src) && welder && welder.isOn()) to_chat(user, "You finish repairing the damage to [src].") take_damage(-damage) return TRUE // Basic dismantling. if(isnull(construction_stage) || !reinf_material) - var/datum/extension/demolisher/demolition = get_extension(W, /datum/extension/demolisher) + var/datum/extension/demolisher/demolition = get_extension(used_item, /datum/extension/demolisher) if(istype(demolition) && demolition.try_demolish(user, src)) return TRUE @@ -161,9 +161,9 @@ switch(construction_stage) if(6) - if(W.is_special_cutting_tool(TRUE)) + if(used_item.is_special_cutting_tool(TRUE)) - to_chat(user, "You drive \the [W] into the wall and begin trying to rip out the support frame...") + to_chat(user, "You drive \the [used_item] into the wall and begin trying to rip out the support frame...") playsound(src, 'sound/items/Welder.ogg', 100, 1) . = TRUE @@ -175,14 +175,14 @@ user.visible_message("The wall was torn open by [user]!") playsound(src, 'sound/items/Welder.ogg', 100, 1) - else if(IS_WIRECUTTER(W)) + else if(IS_WIRECUTTER(used_item)) playsound(src, 'sound/items/Wirecutter.ogg', 100, 1) construction_stage = 5 to_chat(user, "You cut the outer grille.") update_icon() return TRUE if(5) - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) to_chat(user, "You begin removing the support lines.") playsound(src, 'sound/items/Screwdriver.ogg', 100, 1) . = TRUE @@ -192,24 +192,24 @@ update_icon() to_chat(user, "You remove the support lines.") return - else if(istype(W,/obj/item/weldingtool)) - var/obj/item/weldingtool/WT = W - if(WT.weld(0,user)) + else if(istype(used_item,/obj/item/weldingtool)) + var/obj/item/weldingtool/welder = used_item + if(welder.weld(0,user)) construction_stage = 6 update_icon() to_chat(user, SPAN_NOTICE("You repair the outer grille.")) return TRUE if(4) var/cut_cover - if(istype(W,/obj/item/weldingtool)) - var/obj/item/weldingtool/WT = W - if(WT.weld(0,user)) + if(istype(used_item,/obj/item/weldingtool)) + var/obj/item/weldingtool/welder = used_item + if(welder.weld(0,user)) cut_cover=1 else return - else if (W.is_special_cutting_tool()) - if(istype(W, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = W + else if (used_item.is_special_cutting_tool()) + if(istype(used_item, /obj/item/gun/energy/plasmacutter)) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(!cutter.slice(user)) return cut_cover = 1 @@ -224,7 +224,7 @@ to_chat(user, "You press firmly on the cover, dislodging it.") return if(3) - if(IS_CROWBAR(W)) + if(IS_CROWBAR(used_item)) to_chat(user, "You struggle to pry off the cover.") playsound(src, 'sound/items/Crowbar.ogg', 100, 1) . = TRUE @@ -235,7 +235,7 @@ to_chat(user, "You pry off the cover.") return if(2) - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) to_chat(user, "You start loosening the anchoring bolts which secure the support rods to their frame.") playsound(src, 'sound/items/Ratchet.ogg', 100, 1) . = TRUE @@ -247,15 +247,15 @@ return if(1) var/cut_cover - if(istype(W, /obj/item/weldingtool)) - var/obj/item/weldingtool/WT = W - if( WT.weld(0,user) ) + if(istype(used_item, /obj/item/weldingtool)) + var/obj/item/weldingtool/welder = used_item + if( welder.weld(0,user) ) cut_cover=1 else return - else if(W.is_special_cutting_tool()) - if(istype(W, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = W + else if(used_item.is_special_cutting_tool()) + if(istype(used_item, /obj/item/gun/energy/plasmacutter)) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(!cutter.slice(user)) return cut_cover = 1 @@ -270,51 +270,51 @@ to_chat(user, "You cut the support rods loose from the frame.") return if(0) - if(IS_CROWBAR(W)) + if(IS_CROWBAR(used_item)) to_chat(user, "You struggle to pry off the outer sheath.") playsound(src, 'sound/items/Crowbar.ogg', 100, 1) . = TRUE - if(!do_after(user,100,src) || !istype(src, /turf/wall) || !user || !W || !T ) return - if(user.loc == T && user.get_active_held_item() == W ) + if(!do_after(user,100,src) || !istype(src, /turf/wall) || !user || !used_item || !T ) return + if(user.loc == T && user.get_active_held_item() == used_item ) to_chat(user, "You pry off the outer sheath.") dismantle_turf() return return FALSE -/turf/wall/attackby(var/obj/item/W, var/mob/user, click_params) +/turf/wall/attackby(var/obj/item/used_item, var/mob/user, click_params) - if(istype(W, /obj/item/stack/tile/roof) || !user.check_dexterity(DEXTERITY_SIMPLE_MACHINES) || !W.user_can_attack_with(user)) + if(istype(used_item, /obj/item/stack/tile/roof) || !user.check_dexterity(DEXTERITY_SIMPLE_MACHINES) || !used_item.user_can_attack_with(user)) return ..() - if(handle_wall_tool_interactions(W, user)) + if(handle_wall_tool_interactions(used_item, user)) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) return TRUE - if(istype(W,/obj/item/frame)) - var/obj/item/frame/F = W + if(istype(used_item,/obj/item/frame)) + var/obj/item/frame/F = used_item F.try_build(src, click_params) return TRUE // Attack the wall with items - var/force = W.expend_attack_force(user) - if(istype(W,/obj/item/rcd) || istype(W, /obj/item/chems) || !force || user.check_intent(I_FLAG_HELP)) + var/force = used_item.expend_attack_force(user) + if(istype(used_item,/obj/item/rcd) || istype(used_item, /obj/item/chems) || !force || user.check_intent(I_FLAG_HELP)) return ..() user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) var/material_divisor = max(material.brute_armor, reinf_material?.brute_armor) - if(W.atom_damage_type == BURN) + if(used_item.atom_damage_type == BURN) material_divisor = max(material.burn_armor, reinf_material?.burn_armor) var/effective_force = round(force / material_divisor) if(effective_force < 2) - visible_message(SPAN_DANGER("\The [user] [pick(W.attack_verb)] \the [src] with \the [W], but it had no effect!")) + visible_message(SPAN_DANGER("\The [user] [pick(used_item.attack_verb)] \the [src] with \the [used_item], but it had no effect!")) playsound(src, hitsound, 25, 1) return TRUE // Check for a glancing blow. - var/dam_prob = max(0, 100 - material.hardness + effective_force + W.armor_penetration) + var/dam_prob = max(0, 100 - material.hardness + effective_force + used_item.armor_penetration) if(!prob(dam_prob)) - visible_message(SPAN_DANGER("\The [user] [pick(W.attack_verb)] \the [src] with \the [W], but it bounced off!")) + visible_message(SPAN_DANGER("\The [user] [pick(used_item.attack_verb)] \the [src] with \the [used_item], but it bounced off!")) playsound(src, hitsound, 25, 1) if(user.skill_fail_prob(SKILL_HAULING, 40, SKILL_ADEPT)) SET_STATUS_MAX(user, STAT_WEAK, 2) @@ -322,6 +322,6 @@ return TRUE playsound(src, get_hit_sound(), 50, 1) - visible_message(SPAN_DANGER("\The [user] [pick(W.attack_verb)] \the [src] with \the [W]!")) + visible_message(SPAN_DANGER("\The [user] [pick(used_item.attack_verb)] \the [src] with \the [used_item]!")) take_damage(effective_force) return TRUE \ No newline at end of file diff --git a/code/game/turfs/walls/wall_icon.dm b/code/game/turfs/walls/wall_icon.dm index 08732bbecaf9..fb2b4640b418 100644 --- a/code/game/turfs/walls/wall_icon.dm +++ b/code/game/turfs/walls/wall_icon.dm @@ -24,13 +24,13 @@ if(update_neighbors) var/iterate_turfs = list() for(var/direction in global.alldirs) - var/turf/wall/W = get_step_resolving_mimic(src, direction) - if(istype(W)) - W.wall_connections = null - W.other_connections = null - iterate_turfs += W - for(var/turf/wall/W as anything in iterate_turfs) - W.update_icon() + var/turf/wall/wall = get_step_resolving_mimic(src, direction) + if(istype(wall)) + wall.wall_connections = null + wall.other_connections = null + iterate_turfs += wall + for(var/turf/wall/wall as anything in iterate_turfs) + wall.update_icon() else wall_connections = null other_connections = null @@ -219,13 +219,13 @@ integrity += reinf_material.integrity add_overlay(SSmaterials.wall_damage_overlays[clamp(round(damage / integrity * DAMAGE_OVERLAY_COUNT) + 1, 1, DAMAGE_OVERLAY_COUNT)]) -/turf/wall/proc/can_join_with(var/turf/wall/W) - if(unique_merge_identifier != W.unique_merge_identifier) +/turf/wall/proc/can_join_with(var/turf/wall/wall) + if(unique_merge_identifier != wall.unique_merge_identifier) return 0 else if(unique_merge_identifier) return 1 - else if(material && istype(W.material)) - var/other_wall_icon = W.get_wall_icon() + else if(material && istype(wall.material)) + var/other_wall_icon = wall.get_wall_icon() if(get_wall_icon() == other_wall_icon) return 1 if(material.wall_blend_icons[other_wall_icon]) diff --git a/code/game/turfs/walls/wall_natural.dm b/code/game/turfs/walls/wall_natural.dm index ce8ea3dbbce8..095e8f7ed26e 100644 --- a/code/game/turfs/walls/wall_natural.dm +++ b/code/game/turfs/walls/wall_natural.dm @@ -50,42 +50,42 @@ update_neighboring_ramps(destroying_self = TRUE) . = ..() -/turf/wall/natural/attackby(obj/item/W, mob/user, click_params) +/turf/wall/natural/attackby(obj/item/used_item, mob/user, click_params) if(user.check_dexterity(DEXTERITY_COMPLEX_TOOLS) && !ramp_slope_direction) - if(istype(W, /obj/item/depth_scanner)) - var/obj/item/depth_scanner/C = W + if(istype(used_item, /obj/item/depth_scanner)) + var/obj/item/depth_scanner/C = used_item C.scan_atom(user, src) return TRUE - if (istype(W, /obj/item/measuring_tape)) - var/obj/item/measuring_tape/P = W + if (istype(used_item, /obj/item/measuring_tape)) + var/obj/item/measuring_tape/P = used_item user.visible_message(SPAN_NOTICE("\The [user] extends [P] towards [src]."),SPAN_NOTICE("You extend [P] towards [src].")) if(do_after(user,10, src)) to_chat(user, SPAN_NOTICE("\The [src] has been excavated to a depth of [excavation_level]cm.")) return TRUE - if(istype(W, /obj/item/tool/xeno)) - return handle_xenoarch_tool_interaction(W, user) + if(istype(used_item, /obj/item/tool/xeno)) + return handle_xenoarch_tool_interaction(used_item, user) . = ..() // Drill out natural walls. -/turf/wall/natural/handle_wall_tool_interactions(obj/item/W, mob/user) - if(IS_PICK(W) && !being_mined) +/turf/wall/natural/handle_wall_tool_interactions(obj/item/used_item, mob/user) + if(IS_PICK(used_item) && !being_mined) var/check_material_hardness if(material) check_material_hardness = material.hardness if(reinf_material && (isnull(check_material_hardness) || check_material_hardness > reinf_material.hardness)) check_material_hardness = reinf_material.hardness - if(isnull(check_material_hardness) || W.material?.hardness < check_material_hardness) - to_chat(user, SPAN_WARNING("\The [W] is not hard enough to dig through \the [src].")) + if(isnull(check_material_hardness) || used_item.material?.hardness < check_material_hardness) + to_chat(user, SPAN_WARNING("\The [used_item] is not hard enough to dig through \the [src].")) return TRUE if(being_mined) return TRUE being_mined = TRUE - if(W.do_tool_interaction(TOOL_PICK, user, src, 2 SECONDS, suffix_message = destroy_artifacts(W, INFINITY))) + if(used_item.do_tool_interaction(TOOL_PICK, user, src, 2 SECONDS, suffix_message = destroy_artifacts(used_item, INFINITY))) dismantle_turf() if(istype(src, /turf/wall/natural)) // dismantle_turf() can change our type being_mined = FALSE diff --git a/code/game/turfs/walls/wall_natural_xenoarch.dm b/code/game/turfs/walls/wall_natural_xenoarch.dm index e24be7d65b39..85a49e5282fb 100644 --- a/code/game/turfs/walls/wall_natural_xenoarch.dm +++ b/code/game/turfs/walls/wall_natural_xenoarch.dm @@ -112,13 +112,13 @@ if(amount_rocks > 0) pass_geodata_to(new /obj/item/stack/material/ore(src, amount_rocks, material?.type)) -/turf/wall/natural/proc/destroy_artifacts(var/obj/item/W, var/newDepth) +/turf/wall/natural/proc/destroy_artifacts(var/obj/item/used_item, var/newDepth) if(!length(finds)) return var/datum/find/F = finds[1] if(newDepth > F.excavation_required) // Digging too deep can break the item. At least you won't summon a Balrog (probably) - if(W) - . = ". [pick("There is a crunching noise","[W] collides with some different rock","Part of the rock face crumbles away","Something breaks under [W]")]" + if(used_item) + . = ". [pick("There is a crunching noise","[used_item] collides with some different rock","Part of the rock face crumbles away","Something breaks under [used_item]")]" if(prob(10)) return if(prob(25)) diff --git a/code/game/turfs/walls/wall_wattle.dm b/code/game/turfs/walls/wall_wattle.dm index 42a93e90fc08..8a3156c4d282 100644 --- a/code/game/turfs/walls/wall_wattle.dm +++ b/code/game/turfs/walls/wall_wattle.dm @@ -21,16 +21,16 @@ return list("", "paint") // paint should always be available because of plastering! // Daubing with clay or soil -/turf/wall/wattle/attackby(obj/item/W, mob/user, click_params) +/turf/wall/wattle/attackby(obj/item/used_item, mob/user, click_params) if(isnull(daubing_material)) var/static/list/daub_materials = list( // Does not include subtypes. /decl/material/solid/soil = TRUE, /decl/material/solid/clay = TRUE ) - if(istype(W, /obj/item/stack/material) && daub_materials[W.material?.type]) + if(istype(used_item, /obj/item/stack/material) && daub_materials[used_item.material?.type]) if(!user.check_dexterity(DEXTERITY_WIELD_ITEM)) return TRUE - var/obj/item/stack/material/stack = W + var/obj/item/stack/material/stack = used_item var/sheets_to_use = stack.matter_units_to_sheets(matter_to_daub) if(stack.can_use(sheets_to_use) && user.do_skilled(1 SECOND, daubing_skill, target = src) && stack.can_use(sheets_to_use)) to_chat(user, SPAN_NOTICE("You daub \the [src] with \the [stack].")) diff --git a/code/modules/ZAS/ConnectionManager.dm b/code/modules/ZAS/ConnectionManager.dm index 3890cd85f5cd..de4e36c81129 100644 --- a/code/modules/ZAS/ConnectionManager.dm +++ b/code/modules/ZAS/ConnectionManager.dm @@ -36,70 +36,71 @@ Macros: /turf/var/tmp/connection_manager/connections -/connection_manager/var/connection/N -/connection_manager/var/connection/S -/connection_manager/var/connection/E -/connection_manager/var/connection/W +/connection_manager + var/connection/north_connection + var/connection/south_connection + var/connection/east_connection + var/connection/west_connection #ifdef MULTIZAS -/connection_manager/var/connection/U -/connection_manager/var/connection/D + var/connection/upward_connection + var/connection/downward_connection #endif /connection_manager/proc/get(d) switch(d) if(NORTH) - if(check(N)) return N + if(check(north_connection)) return north_connection else return null if(SOUTH) - if(check(S)) return S + if(check(south_connection)) return south_connection else return null if(EAST) - if(check(E)) return E + if(check(east_connection)) return east_connection else return null if(WEST) - if(check(W)) return W + if(check(west_connection)) return west_connection else return null #ifdef MULTIZAS if(UP) - if(check(U)) return U + if(check(upward_connection)) return upward_connection else return null if(DOWN) - if(check(D)) return D + if(check(downward_connection)) return downward_connection else return null #endif /connection_manager/proc/place(connection/c, d) switch(d) - if(NORTH) N = c - if(SOUTH) S = c - if(EAST) E = c - if(WEST) W = c + if(NORTH) north_connection = c + if(SOUTH) south_connection = c + if(EAST) east_connection = c + if(WEST) west_connection = c #ifdef MULTIZAS - if(UP) U = c - if(DOWN) D = c + if(UP) upward_connection = c + if(DOWN) downward_connection = c #endif /connection_manager/proc/update_all() - if(check(N)) N.update() - if(check(S)) S.update() - if(check(E)) E.update() - if(check(W)) W.update() + if(check(north_connection)) north_connection.update() + if(check(south_connection)) south_connection.update() + if(check(east_connection)) east_connection.update() + if(check(west_connection)) west_connection.update() #ifdef MULTIZAS - if(check(U)) U.update() - if(check(D)) D.update() + if(check(upward_connection)) upward_connection.update() + if(check(downward_connection)) downward_connection.update() #endif /connection_manager/proc/erase_all() - if(check(N)) N.erase() - if(check(S)) S.erase() - if(check(E)) E.erase() - if(check(W)) W.erase() + if(check(north_connection)) north_connection.erase() + if(check(south_connection)) south_connection.erase() + if(check(east_connection)) east_connection.erase() + if(check(west_connection)) west_connection.erase() #ifdef MULTIZAS - if(check(U)) U.erase() - if(check(D)) D.erase() + if(check(upward_connection)) upward_connection.erase() + if(check(downward_connection)) downward_connection.erase() #endif #undef check diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm index b599e3845e62..a9e734c065d7 100644 --- a/code/modules/admin/verbs/mapping.dm +++ b/code/modules/admin/verbs/mapping.dm @@ -108,8 +108,8 @@ var/global/list/mapping_debugging_markers = list() if(!T || !isturf(T) || !T.density ) if(!(locate(/obj/structure/grille,T))) var/window_check = 0 - for(var/obj/structure/window/W in T) - if (W.dir == turn(C1.dir,180) || (W.dir in list(NORTHEAST,SOUTHEAST,SOUTHWEST,NORTHWEST)) ) + for(var/obj/structure/window/window in T) + if (window.dir == turn(C1.dir,180) || (window.dir in list(NORTHEAST,SOUTHEAST,SOUTHWEST,NORTHWEST)) ) window_check = 1 break if(!window_check) diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index 017f1c2bb561..39e5e364fc4c 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -9,8 +9,8 @@ if(confirm != "Yes") return - for(var/obj/item/W in M.get_contained_external_atoms()) - M.drop_from_inventory(W) + for(var/obj/item/thing in M.get_contained_external_atoms()) + M.drop_from_inventory(thing) log_admin("[key_name(usr)] made [key_name(M)] drop everything!") message_admins("[key_name_admin(usr)] made [key_name_admin(M)] drop everything!", 1) diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index d809c53896d6..390085e33848 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -118,8 +118,8 @@ a_right.holder_movement() return ..() -/obj/item/assembly_holder/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/assembly_holder/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) if(!a_left || !a_right) to_chat(user, "BUG:Assembly part missing, please report this!") return TRUE diff --git a/code/modules/atmospherics/components/unary/vent_pump.dm b/code/modules/atmospherics/components/unary/vent_pump.dm index 33a2df620b92..20f4d41f2594 100644 --- a/code/modules/atmospherics/components/unary/vent_pump.dm +++ b/code/modules/atmospherics/components/unary/vent_pump.dm @@ -278,16 +278,16 @@ . = ..() toggle_input_toggle() -/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/W, mob/user) - if(IS_WELDER(W)) +/obj/machinery/atmospherics/unary/vent_pump/attackby(obj/item/used_item, mob/user) + if(IS_WELDER(used_item)) - var/obj/item/weldingtool/WT = W + var/obj/item/weldingtool/welder = used_item - if(!WT.isOn()) + if(!welder.isOn()) to_chat(user, "The welding tool needs to be on to start this task.") return 1 - if(!WT.weld(0,user)) + if(!welder.weld(0,user)) to_chat(user, "You need more welding fuel to complete this task.") return 1 @@ -301,7 +301,7 @@ if(!src) return 1 - if(!WT.isOn()) + if(!welder.isOn()) to_chat(user, "The welding tool needs to be on to finish this task.") return 1 @@ -312,7 +312,7 @@ "You [welded ? "weld \the [src] shut" : "unweld \the [src]"].", \ "You hear welding.") return 1 - if(IS_MULTITOOL(W)) + if(IS_MULTITOOL(used_item)) var/datum/browser/written_digital/popup = new(user, "Vent Configuration Utility", "[src] Configuration Panel", 600, 200) popup.set_content(jointext(get_console_data(),"
    ")) popup.open() diff --git a/code/modules/atmospherics/components/unary/vent_scrubber.dm b/code/modules/atmospherics/components/unary/vent_scrubber.dm index b5b6b81e8fde..4ff8c0e85b87 100644 --- a/code/modules/atmospherics/components/unary/vent_scrubber.dm +++ b/code/modules/atmospherics/components/unary/vent_scrubber.dm @@ -203,16 +203,16 @@ return SPAN_WARNING("You cannot take this [src] apart, it too exerted due to internal pressure.") return ..() -/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/weldingtool)) +/obj/machinery/atmospherics/unary/vent_scrubber/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/weldingtool)) - var/obj/item/weldingtool/WT = W + var/obj/item/weldingtool/welder = used_item - if(!WT.isOn()) + if(!welder.isOn()) to_chat(user, "The welding tool needs to be on to start this task.") return 1 - if(!WT.weld(0,user)) + if(!welder.weld(0,user)) to_chat(user, "You need more welding fuel to complete this task.") return 1 @@ -226,7 +226,7 @@ if(!src) return 1 - if(!WT.isOn()) + if(!welder.isOn()) to_chat(user, "The welding tool needs to be on to finish this task.") return 1 diff --git a/code/modules/augment/active/circuit.dm b/code/modules/augment/active/circuit.dm index 913820ec2763..a6a86bd6ad61 100644 --- a/code/modules/augment/active/circuit.dm +++ b/code/modules/augment/active/circuit.dm @@ -10,8 +10,8 @@ material = /decl/material/solid/metal/steel origin_tech = @'{"materials":1,"magnets":1,"engineering":1,"programming":2}' -/obj/item/organ/internal/augment/active/simple/circuit/attackby(obj/item/W, mob/user) - if(IS_CROWBAR(W)) +/obj/item/organ/internal/augment/active/simple/circuit/attackby(obj/item/used_item, mob/user) + if(IS_CROWBAR(used_item)) //Remove internal circuit if(holding) holding.canremove = 1 @@ -21,11 +21,11 @@ playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) else to_chat(user, SPAN_WARNING("The augment is empty!")) return TRUE - if(istype(W, /obj/item/electronic_assembly/augment)) + if(istype(used_item, /obj/item/electronic_assembly/augment)) if(holding) to_chat(user, SPAN_WARNING("There's already an assembly in there.")) - else if(user.try_unequip(W, src)) - holding = W + else if(user.try_unequip(used_item, src)) + holding = used_item holding.canremove = 0 playsound(loc, 'sound/items/Crowbar.ogg', 50, 1) return TRUE diff --git a/code/modules/augment/active/cyberbrain.dm b/code/modules/augment/active/cyberbrain.dm index caa75054b299..c508f4cfcedd 100644 --- a/code/modules/augment/active/cyberbrain.dm +++ b/code/modules/augment/active/cyberbrain.dm @@ -54,9 +54,9 @@ else if(!assembly.enabled && assembly.screen_on) assembly.turn_on(owner) -/obj/item/organ/internal/augment/active/cyberbrain/attackby(var/obj/item/W, var/mob/user) +/obj/item/organ/internal/augment/active/cyberbrain/attackby(var/obj/item/used_item, var/mob/user) var/datum/extension/assembly/assembly = get_extension(src, /datum/extension/assembly) - . = assembly.attackby(W, user) + . = assembly.attackby(used_item, user) if(.) return return ..() diff --git a/code/modules/augment/augment.dm b/code/modules/augment/augment.dm index b65a6776d09c..63105dc6e02b 100644 --- a/code/modules/augment/augment.dm +++ b/code/modules/augment/augment.dm @@ -22,8 +22,8 @@ update_parent_organ() reagents?.clear_reagents() // Removing meat from the reagents list. -/obj/item/organ/internal/augment/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W) && allowed_organs.len > 1) +/obj/item/organ/internal/augment/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item) && allowed_organs.len > 1) //Here we can adjust location for implants that allow multiple slots organ_tag = input(user, "Adjust installation parameters") as null|anything in allowed_organs update_parent_organ() diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 13f96d15a009..3696cdeec715 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -127,8 +127,8 @@ M.set_dir(SOUTH) return -/obj/machinery/gateway/centerstation/attackby(obj/item/W, mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/gateway/centerstation/attackby(obj/item/used_item, mob/user) + if(IS_MULTITOOL(used_item)) to_chat(user, "The gate is already calibrated, there is no work for you to do here.") return TRUE return FALSE @@ -223,8 +223,8 @@ M.forceMove(get_step(stationgate.loc, SOUTH)) M.set_dir(SOUTH) -/obj/machinery/gateway/centeraway/attackby(obj/item/W, mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/gateway/centeraway/attackby(obj/item/used_item, mob/user) + if(IS_MULTITOOL(used_item)) if(calibrated) to_chat(user, "The gate is already calibrated, there is no work for you to do here.") return TRUE diff --git a/code/modules/blob/blob.dm b/code/modules/blob/blob.dm index 5780a8f2ca98..f1956867947e 100644 --- a/code/modules/blob/blob.dm +++ b/code/modules/blob/blob.dm @@ -80,9 +80,9 @@ if(prob(40)) G.dismantle_structure() return - var/obj/structure/window/W = locate() in T - if(W) - W.shatter() + var/obj/structure/window/used_item = locate() in T + if(used_item) + used_item.shatter() return var/obj/structure/grille/GR = locate() in T if(GR) @@ -161,11 +161,11 @@ take_damage((Proj.damage / laser_damage_divisor) / fire_damage_divisor, Proj.atom_damage_type) return 0 -/obj/effect/blob/attackby(var/obj/item/W, var/mob/user) +/obj/effect/blob/attackby(var/obj/item/used_item, var/mob/user) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) playsound(loc, 'sound/effects/attackblob.ogg', 50, 1) - if(IS_WIRECUTTER(W)) + if(IS_WIRECUTTER(used_item)) if(prob(user.skill_fail_chance(SKILL_SCIENCE, 90, SKILL_EXPERT))) to_chat(user, SPAN_WARNING("You fail to collect a sample from \the [src].")) return TRUE @@ -180,15 +180,15 @@ return TRUE var/damage = 0 - switch(W.atom_damage_type) + switch(used_item.atom_damage_type) if(BURN) - damage = (W.expend_attack_force(user) / fire_damage_divisor) - if(IS_WELDER(W)) + damage = (used_item.expend_attack_force(user) / fire_damage_divisor) + if(IS_WELDER(used_item)) playsound(loc, 'sound/items/Welder.ogg', 100, 1) if(BRUTE) - damage = (W.expend_attack_force(user) / brute_damage_divisor) + damage = (used_item.expend_attack_force(user) / brute_damage_divisor) - take_damage(damage, W.atom_damage_type) + take_damage(damage, used_item.atom_damage_type) return TRUE /obj/effect/blob/core diff --git a/code/modules/butchery/butchery_hook.dm b/code/modules/butchery/butchery_hook.dm index 58945994cd87..47c7161471dd 100644 --- a/code/modules/butchery/butchery_hook.dm +++ b/code/modules/butchery/butchery_hook.dm @@ -60,10 +60,10 @@ return TRUE return ..() -/obj/structure/meat_hook/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/holder)) - var/mob/victim = (locate() in W) - if(istype(victim) && user.try_unequip(W)) +/obj/structure/meat_hook/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/holder)) + var/mob/victim = (locate() in used_item) + if(istype(victim) && user.try_unequip(used_item)) try_spike(victim, user, 1) // Delay to allow the holder to despawn and drop the mob in the loc. return TRUE return ..() @@ -177,8 +177,8 @@ else if(occupant_state == CARCASS_EMPTY) for(var/obj/item/embedded in occupant.embedded) occupant.remove_implant(occupant.embedded, TRUE) // surgical removal to prevent pointless damage pre-deletion - for(var/obj/item/W in occupant) - occupant.drop_from_inventory(W) + for(var/obj/item/thing in occupant) + occupant.drop_from_inventory(thing) qdel(occupant) clear_occupant() update_icon() diff --git a/code/modules/butchery/butchery_products.dm b/code/modules/butchery/butchery_products.dm index bc653e3776f9..edfdfa65796c 100644 --- a/code/modules/butchery/butchery_products.dm +++ b/code/modules/butchery/butchery_products.dm @@ -147,9 +147,9 @@ else if(!drying_wetness) . += "\The [src] can be soaked in water to prepare it for drying." -/obj/item/food/butchery/offal/attackby(obj/item/W, mob/user) - if(IS_KNIFE(W) && !_cleaned && !dry) - if(W.do_tool_interaction(TOOL_KNIFE, user, src, 3 SECONDS, "scraping", "scraping", check_skill = work_skill, set_cooldown = TRUE) && !_cleaned) +/obj/item/food/butchery/offal/attackby(obj/item/used_item, mob/user) + if(IS_KNIFE(used_item) && !_cleaned && !dry) + if(used_item.do_tool_interaction(TOOL_KNIFE, user, src, 3 SECONDS, "scraping", "scraping", check_skill = work_skill, set_cooldown = TRUE) && !_cleaned) _cleaned = TRUE SetName("cleaned [name]") return TRUE diff --git a/code/modules/client/preference_setup/antagonism/01_candidacy.dm b/code/modules/client/preference_setup/antagonism/01_candidacy.dm index 40ad53d76f03..679ab38206c9 100644 --- a/code/modules/client/preference_setup/antagonism/01_candidacy.dm +++ b/code/modules/client/preference_setup/antagonism/01_candidacy.dm @@ -10,9 +10,9 @@ pref.be_special_role = R.read("be_special") pref.may_be_special_role = R.read("may_be_special") -/datum/category_item/player_setup_item/antagonism/candidacy/save_character(datum/pref_record_writer/W) - W.write("be_special", pref.be_special_role) - W.write("may_be_special", pref.may_be_special_role) +/datum/category_item/player_setup_item/antagonism/candidacy/save_character(datum/pref_record_writer/writer) + writer.write("be_special", pref.be_special_role) + writer.write("may_be_special", pref.may_be_special_role) /datum/category_item/player_setup_item/antagonism/candidacy/sanitize_character() if(!istype(pref.be_special_role)) diff --git a/code/modules/client/preference_setup/antagonism/02_setup.dm b/code/modules/client/preference_setup/antagonism/02_setup.dm index efd83fc0e06e..ca6da3330fc5 100644 --- a/code/modules/client/preference_setup/antagonism/02_setup.dm +++ b/code/modules/client/preference_setup/antagonism/02_setup.dm @@ -24,14 +24,14 @@ if(uplink_source) pref.uplink_sources += uplink_source -/datum/category_item/player_setup_item/antagonism/basic/save_character(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/antagonism/basic/save_character(datum/pref_record_writer/writer) var/uplink_order = list() for(var/entry in pref.uplink_sources) var/decl/uplink_source/UL = entry uplink_order += UL.name - W.write("uplink_sources", uplink_order) - W.write("exploit_record", pref.exploit_record) + writer.write("uplink_sources", uplink_order) + writer.write("exploit_record", pref.exploit_record) /datum/category_item/player_setup_item/antagonism/basic/sanitize_character() if(!istype(pref.uplink_sources)) diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index 3f8e52d19e78..2ce0daf85387 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -3,8 +3,8 @@ sort_order = 1 var/hide_species = TRUE -/datum/category_item/player_setup_item/background/species/save_character(datum/pref_record_writer/W) - W.write("species", pref.species) +/datum/category_item/player_setup_item/background/species/save_character(datum/pref_record_writer/writer) + writer.write("species", pref.species) /datum/category_item/player_setup_item/background/species/preload_character(datum/pref_record_reader/R) pref.species = R.read("species") diff --git a/code/modules/client/preference_setup/background/02_background.dm b/code/modules/client/preference_setup/background/02_background.dm index 29a06ce70059..762520d1c435 100644 --- a/code/modules/client/preference_setup/background/02_background.dm +++ b/code/modules/client/preference_setup/background/02_background.dm @@ -77,12 +77,12 @@ if(istype(background)) pref.background_info[cat.type] = background.type -/datum/category_item/player_setup_item/background/details/save_character(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/background/details/save_character(datum/pref_record_writer/writer) for(var/background_cat_type in pref.background_info) var/decl/background_category/cat = GET_DECL(background_cat_type) var/decl/background_detail/entry = GET_DECL(pref.background_info[background_cat_type]) if(istype(cat) && istype(entry)) - W.write(cat.uid, entry.uid) + writer.write(cat.uid, entry.uid) /datum/category_item/player_setup_item/background/details/content() . = list() diff --git a/code/modules/client/preference_setup/background/03_language.dm b/code/modules/client/preference_setup/background/03_language.dm index 9196389ebc21..490b4bb5bfa3 100644 --- a/code/modules/client/preference_setup/background/03_language.dm +++ b/code/modules/client/preference_setup/background/03_language.dm @@ -15,13 +15,13 @@ if(istype(lang_decl)) pref.alternate_languages |= lang_decl.type -/datum/category_item/player_setup_item/background/languages/save_character(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/background/languages/save_character(datum/pref_record_writer/writer) var/list/language_names = list() for(var/lang in pref.alternate_languages) var/decl/language/lang_decl = GET_DECL(lang) if(istype(lang_decl)) language_names |= lang_decl.name - W.write("language", language_names) + writer.write("language", language_names) /datum/category_item/player_setup_item/background/languages/sanitize_character() if(!islist(pref.alternate_languages)) diff --git a/code/modules/client/preference_setup/controls/01_keybindings.dm b/code/modules/client/preference_setup/controls/01_keybindings.dm index eccfd9ecccf3..20621c185762 100644 --- a/code/modules/client/preference_setup/controls/01_keybindings.dm +++ b/code/modules/client/preference_setup/controls/01_keybindings.dm @@ -58,8 +58,8 @@ pref.key_bindings = sanitize_keybindings(pref.key_bindings) pref.check_keybindings() -/datum/category_item/player_setup_item/controls/keybindings/save_preferences(datum/pref_record_writer/W) - W.write("key_bindings", pref.key_bindings) +/datum/category_item/player_setup_item/controls/keybindings/save_preferences(datum/pref_record_writer/writer) + writer.write("key_bindings", pref.key_bindings) /datum/category_item/player_setup_item/controls/keybindings/content(mob/user) . = list() diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index b33b09d48bf7..f9ad83a7a49a 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -32,14 +32,14 @@ else pref.spawnpoint = global.using_map.default_spawn -/datum/category_item/player_setup_item/physical/basic/save_character(datum/pref_record_writer/W) - W.write("gender", pref.gender) - W.write("bodytype", pref.bodytype) - W.write("real_name", pref.real_name) - W.write("name_is_always_random", pref.be_random_name) +/datum/category_item/player_setup_item/physical/basic/save_character(datum/pref_record_writer/writer) + writer.write("gender", pref.gender) + writer.write("bodytype", pref.bodytype) + writer.write("real_name", pref.real_name) + writer.write("name_is_always_random", pref.be_random_name) var/decl/spawnpoint/spawnpoint = GET_DECL(pref.spawnpoint) if(spawnpoint) - W.write("spawnpoint", spawnpoint.uid) + writer.write("spawnpoint", spawnpoint.uid) /datum/category_item/player_setup_item/physical/basic/sanitize_character() diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index 4c24a880b2f4..38ea82db935b 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -82,7 +82,7 @@ if(!pref.bgstate || !(pref.bgstate in global.using_map.char_preview_bgstate_options)) pref.bgstate = global.using_map.char_preview_bgstate_options[1] -/datum/category_item/player_setup_item/physical/body/save_character(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/physical/body/save_character(datum/pref_record_writer/writer) var/decl/species/mob_species = get_species_by_key(pref.species) var/list/save_accessories = list() @@ -99,13 +99,13 @@ serialize_metadata[metadata.uid] = pref.sprite_accessories[acc_cat][acc][metadata_type] save_accessories[accessory_category.uid][accessory.uid] = serialize_metadata - W.write("sprite_accessories", save_accessories) - W.write("skin_tone", pref.skin_tone) - W.write("skin_colour", pref.skin_colour) - W.write("eye_colour", pref.eye_colour) - W.write("b_type", pref.blood_type) - W.write("appearance_descriptors", pref.appearance_descriptors) - W.write("bgstate", pref.bgstate) + writer.write("sprite_accessories", save_accessories) + writer.write("skin_tone", pref.skin_tone) + writer.write("skin_colour", pref.skin_colour) + writer.write("eye_colour", pref.eye_colour) + writer.write("b_type", pref.blood_type) + writer.write("appearance_descriptors", pref.appearance_descriptors) + writer.write("bgstate", pref.bgstate) /datum/category_item/player_setup_item/physical/body/sanitize_character() diff --git a/code/modules/client/preference_setup/general/03_traits.dm b/code/modules/client/preference_setup/general/03_traits.dm index 22f02be9f2b2..d5120bff0a00 100644 --- a/code/modules/client/preference_setup/general/03_traits.dm +++ b/code/modules/client/preference_setup/general/03_traits.dm @@ -39,13 +39,13 @@ else pref.prune_invalid_traits() -/datum/category_item/player_setup_item/traits/save_character(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/traits/save_character(datum/pref_record_writer/writer) var/list/trait_ids = list() for(var/trait_type in pref.traits) var/decl/trait/trait_decl = GET_DECL(trait_type) if(istype(trait_decl)) trait_ids |= trait_decl.uid - W.write("traits", trait_ids) + writer.write("traits", trait_ids) /datum/category_item/player_setup_item/traits/proc/get_trait_total() var/trait_cost = 0 diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index 4f24dd14b785..79a4edfe91e0 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -36,14 +36,14 @@ var/load_backbag = R.read("backpack") pref.backpack = backpacks_by_name[load_backbag] || get_default_outfit_backpack() -/datum/category_item/player_setup_item/physical/equipment/save_character(datum/pref_record_writer/W) - W.write("all_underwear", pref.all_underwear) - W.write("all_underwear_metadata", pref.all_underwear_metadata) - W.write("backpack", pref.backpack.name) - W.write("backpack_metadata", pref.backpack_metadata) - W.write("survival_box", pref.survival_box_choice?.uid) - W.write("starting_cash_choice", pref.starting_cash_choice?.uid) - W.write("passport", pref.give_passport) +/datum/category_item/player_setup_item/physical/equipment/save_character(datum/pref_record_writer/writer) + writer.write("all_underwear", pref.all_underwear) + writer.write("all_underwear_metadata", pref.all_underwear_metadata) + writer.write("backpack", pref.backpack.name) + writer.write("backpack_metadata", pref.backpack_metadata) + writer.write("survival_box", pref.survival_box_choice?.uid) + writer.write("starting_cash_choice", pref.starting_cash_choice?.uid) + writer.write("passport", pref.give_passport) /datum/category_item/player_setup_item/physical/equipment/sanitize_character() if(!istype(pref.all_underwear)) diff --git a/code/modules/client/preference_setup/general/05_flavor.dm b/code/modules/client/preference_setup/general/05_flavor.dm index 803e65cee7cb..27c6b79580eb 100644 --- a/code/modules/client/preference_setup/general/05_flavor.dm +++ b/code/modules/client/preference_setup/general/05_flavor.dm @@ -22,20 +22,20 @@ for(var/module in SSrobots.all_module_names) pref.flavour_texts_robot[module] = R.read("flavour_texts_robot_[module]") -/datum/category_item/player_setup_item/physical/flavor/save_character(datum/pref_record_writer/W) - W.write("flavor_texts_general", pref.flavor_texts["general"]) - W.write("flavor_texts_head", pref.flavor_texts["head"]) - W.write("flavor_texts_face", pref.flavor_texts["face"]) - W.write("flavor_texts_eyes", pref.flavor_texts["eyes"]) - W.write("flavor_texts_torso", pref.flavor_texts["torso"]) - W.write("flavor_texts_arms", pref.flavor_texts["arms"]) - W.write("flavor_texts_hands", pref.flavor_texts["hands"]) - W.write("flavor_texts_legs", pref.flavor_texts["legs"]) - W.write("flavor_texts_feet", pref.flavor_texts["feet"]) +/datum/category_item/player_setup_item/physical/flavor/save_character(datum/pref_record_writer/writer) + writer.write("flavor_texts_general", pref.flavor_texts["general"]) + writer.write("flavor_texts_head", pref.flavor_texts["head"]) + writer.write("flavor_texts_face", pref.flavor_texts["face"]) + writer.write("flavor_texts_eyes", pref.flavor_texts["eyes"]) + writer.write("flavor_texts_torso", pref.flavor_texts["torso"]) + writer.write("flavor_texts_arms", pref.flavor_texts["arms"]) + writer.write("flavor_texts_hands", pref.flavor_texts["hands"]) + writer.write("flavor_texts_legs", pref.flavor_texts["legs"]) + writer.write("flavor_texts_feet", pref.flavor_texts["feet"]) - W.write("flavour_texts_robot_Default", pref.flavour_texts_robot["Default"]) + writer.write("flavour_texts_robot_Default", pref.flavour_texts_robot["Default"]) for(var/module in SSrobots.all_module_names) - W.write("flavour_texts_robot_[module]", pref.flavour_texts_robot[module]) + writer.write("flavour_texts_robot_[module]", pref.flavour_texts_robot[module]) /datum/category_item/player_setup_item/physical/flavor/sanitize_character() if(!istype(pref.flavor_texts)) pref.flavor_texts = list() diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index f48998316cc7..560527977a12 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -35,19 +35,19 @@ var/global/list/valid_icon_sizes = list(32, 48, 64, 96, 128) pref.ooccolor = R.read("ooccolor") pref.clientfps = R.read("clientfps") -/datum/category_item/player_setup_item/player_global/ui/save_preferences(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/player_global/ui/save_preferences(datum/pref_record_writer/writer) var/decl/ui_style/ui_style = GET_DECL(pref.UI_style) - W.write("UI_style", ui_style.uid) - - W.write("icon_size", pref.icon_size) - W.write("UI_mouseover_color", pref.UI_mouseover_color) - W.write("UI_mouseover_alpha", pref.UI_mouseover_alpha) - W.write("UI_style_color", pref.UI_style_color) - W.write("UI_style_highlight_color", pref.UI_style_highlight_color) - W.write("UI_style_alpha", pref.UI_style_alpha) - W.write("ooccolor", pref.ooccolor) - W.write("clientfps", pref.clientfps) + writer.write("UI_style", ui_style.uid) + + writer.write("icon_size", pref.icon_size) + writer.write("UI_mouseover_color", pref.UI_mouseover_color) + writer.write("UI_mouseover_alpha", pref.UI_mouseover_alpha) + writer.write("UI_style_color", pref.UI_style_color) + writer.write("UI_style_highlight_color", pref.UI_style_highlight_color) + writer.write("UI_style_alpha", pref.UI_style_alpha) + writer.write("ooccolor", pref.ooccolor) + writer.write("clientfps", pref.clientfps) /datum/category_item/player_setup_item/player_global/ui/sanitize_preferences() diff --git a/code/modules/client/preference_setup/global/02_prefixes.dm b/code/modules/client/preference_setup/global/02_prefixes.dm index 935feeda7f22..2e249179f8be 100644 --- a/code/modules/client/preference_setup/global/02_prefixes.dm +++ b/code/modules/client/preference_setup/global/02_prefixes.dm @@ -22,13 +22,13 @@ if(prefix_instance) pref.prefix_keys_by_type[prefix_instance.type] = prefix_keys_by_name[prefix_name] -/datum/category_item/player_setup_item/player_global/prefixes/save_preferences(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/player_global/prefixes/save_preferences(datum/pref_record_writer/writer) var/list/prefix_keys_by_name = list() for(var/prefix_type in pref.prefix_keys_by_type) var/decl/prefix/prefix_instance = GET_DECL(prefix_type) prefix_keys_by_name[prefix_instance.name] = pref.prefix_keys_by_type[prefix_type] - W.write("prefix_keys", prefix_keys_by_name) + writer.write("prefix_keys", prefix_keys_by_name) /datum/category_item/player_setup_item/player_global/prefixes/sanitize_preferences() if(!istype(pref.prefix_keys_by_type)) diff --git a/code/modules/client/preference_setup/global/03_pai.dm b/code/modules/client/preference_setup/global/03_pai.dm index aeef174d4ffd..fe206bf11696 100644 --- a/code/modules/client/preference_setup/global/03_pai.dm +++ b/code/modules/client/preference_setup/global/03_pai.dm @@ -16,7 +16,7 @@ candidate.savefile_load(preference_mob()) update_pai_preview() -/datum/category_item/player_setup_item/player_global/pai/save_preferences(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/player_global/pai/save_preferences(datum/pref_record_writer/writer) if(!candidate) return diff --git a/code/modules/client/preference_setup/global/04_ooc.dm b/code/modules/client/preference_setup/global/04_ooc.dm index 923d75f458ee..17146b980818 100644 --- a/code/modules/client/preference_setup/global/04_ooc.dm +++ b/code/modules/client/preference_setup/global/04_ooc.dm @@ -10,8 +10,8 @@ pref.ignored_players = R.read("ignored_players") -/datum/category_item/player_setup_item/player_global/ooc/save_preferences(datum/pref_record_writer/W) - W.write("ignored_players", pref.ignored_players) +/datum/category_item/player_setup_item/player_global/ooc/save_preferences(datum/pref_record_writer/writer) + writer.write("ignored_players", pref.ignored_players) /datum/category_item/player_setup_item/player_global/ooc/sanitize_preferences() diff --git a/code/modules/client/preference_setup/global/05_settings.dm b/code/modules/client/preference_setup/global/05_settings.dm index 0548d22fc6e8..42ee3bdecdce 100644 --- a/code/modules/client/preference_setup/global/05_settings.dm +++ b/code/modules/client/preference_setup/global/05_settings.dm @@ -11,11 +11,11 @@ pref.slot_names = R.read("slot_names") pref.preference_values = R.read("preference_values") -/datum/category_item/player_setup_item/player_global/settings/save_preferences(datum/pref_record_writer/W) - W.write("lastchangelog", pref.lastchangelog) - W.write("default_slot", pref.default_slot) - W.write("slot_names", pref.slot_names) - W.write("preference_values", pref.preference_values) +/datum/category_item/player_setup_item/player_global/settings/save_preferences(datum/pref_record_writer/writer) + writer.write("lastchangelog", pref.lastchangelog) + writer.write("default_slot", pref.default_slot) + writer.write("slot_names", pref.slot_names) + writer.write("preference_values", pref.preference_values) /datum/category_item/player_setup_item/player_global/settings/sanitize_preferences() // Ensure our preferences are lists. diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 1555f26fd222..78e21dbdeb9d 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -21,9 +21,9 @@ pref.gear_list = R.read("gear_list") pref.gear_slot = R.read("gear_slot") -/datum/category_item/player_setup_item/loadout/save_character(datum/pref_record_writer/W) - W.write("gear_list", pref.gear_list) - W.write("gear_slot", pref.gear_slot) +/datum/category_item/player_setup_item/loadout/save_character(datum/pref_record_writer/writer) + writer.write("gear_list", pref.gear_list) + writer.write("gear_slot", pref.gear_slot) /datum/category_item/player_setup_item/loadout/proc/skill_check(var/list/jobs, var/list/skills_required) for(var/datum/job/J in jobs) diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index d4a99e6b0252..ed49536a4ddf 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -34,17 +34,17 @@ pref.hiding_maps = R.read("hiding_maps") load_skills() -/datum/category_item/player_setup_item/occupation/save_character(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/occupation/save_character(datum/pref_record_writer/writer) save_skills() - W.write("alternate_option", pref.alternate_option) - W.write("job_high", pref.job_high) - W.write("job_medium", pref.job_medium) - W.write("job_low", pref.job_low) - W.write("player_alt_titles", pref.player_alt_titles) - W.write("skills_saved", pref.skills_saved) - W.write("branches", pref.branches) - W.write("ranks", pref.ranks) - W.write("hiding_maps", pref.hiding_maps) + writer.write("alternate_option", pref.alternate_option) + writer.write("job_high", pref.job_high) + writer.write("job_medium", pref.job_medium) + writer.write("job_low", pref.job_low) + writer.write("player_alt_titles", pref.player_alt_titles) + writer.write("skills_saved", pref.skills_saved) + writer.write("branches", pref.branches) + writer.write("ranks", pref.ranks) + writer.write("hiding_maps", pref.hiding_maps) /datum/category_item/player_setup_item/occupation/sanitize_character() if(!istype(pref.job_medium)) pref.job_medium = list() diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index 06bdf434ba50..c7a65cfcc11a 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -79,17 +79,17 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" for(var/datum/category_group/player_setup_category/PS in categories) PS.load_character(R) -/datum/category_collection/player_setup_collection/proc/save_character(datum/pref_record_writer/W) +/datum/category_collection/player_setup_collection/proc/save_character(datum/pref_record_writer/writer) for(var/datum/category_group/player_setup_category/PS in categories) - PS.save_character(W) + PS.save_character(writer) /datum/category_collection/player_setup_collection/proc/load_preferences(datum/pref_record_reader/R) for(var/datum/category_group/player_setup_category/PS in categories) PS.load_preferences(R) -/datum/category_collection/player_setup_collection/proc/save_preferences(datum/pref_record_writer/W) +/datum/category_collection/player_setup_collection/proc/save_preferences(datum/pref_record_writer/writer) for(var/datum/category_group/player_setup_category/PS in categories) - PS.save_preferences(W) + PS.save_preferences(writer) /datum/category_collection/player_setup_collection/proc/header() var/dat = "" @@ -143,24 +143,24 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" for(var/datum/category_item/player_setup_item/PI in items) PI.finalize_character() -/datum/category_group/player_setup_category/proc/save_character(datum/pref_record_writer/W) +/datum/category_group/player_setup_category/proc/save_character(datum/pref_record_writer/writer) // Sanitize all data, then save it for(var/datum/category_item/player_setup_item/PI in items) PI.sanitize_character() for(var/datum/category_item/player_setup_item/PI in items) PI.finalize_character() for(var/datum/category_item/player_setup_item/PI in items) - PI.save_character(W) + PI.save_character(writer) /datum/category_group/player_setup_category/proc/load_preferences(datum/pref_record_reader/R) for(var/datum/category_item/player_setup_item/PI in items) PI.load_preferences(R) -/datum/category_group/player_setup_category/proc/save_preferences(datum/pref_record_writer/W) +/datum/category_group/player_setup_category/proc/save_preferences(datum/pref_record_writer/writer) for(var/datum/category_item/player_setup_item/PI in items) PI.sanitize_preferences() for(var/datum/category_item/player_setup_item/PI in items) - PI.save_preferences(W) + PI.save_preferences(writer) /datum/category_group/player_setup_category/proc/content(var/mob/user) . = "
    " @@ -211,7 +211,7 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" /* * Called when the item is asked to save per character settings */ -/datum/category_item/player_setup_item/proc/save_character(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/proc/save_character(datum/pref_record_writer/writer) return /* @@ -223,7 +223,7 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" /* * Called when the item is asked to save user/global settings */ -/datum/category_item/player_setup_item/proc/save_preferences(datum/pref_record_writer/W) +/datum/category_item/player_setup_item/proc/save_preferences(datum/pref_record_writer/writer) return /datum/category_item/player_setup_item/proc/content() diff --git a/code/modules/client/preferences_persist.dm b/code/modules/client/preferences_persist.dm index a5fbeba06604..c537e3adb84e 100644 --- a/code/modules/client/preferences_persist.dm +++ b/code/modules/client/preferences_persist.dm @@ -62,11 +62,11 @@ comments_record_id = comments.record_id /datum/preferences/proc/save_preferences() - var/datum/pref_record_writer/json_list/W = new(PREF_SER_VERSION) - player_setup.save_preferences(W) + var/datum/pref_record_writer/json_list/writer = new(PREF_SER_VERSION) + player_setup.save_preferences(writer) if(istext(comments_record_id) && length(comments_record_id)) SScharacter_info.queue_to_save(comments_record_id) - save_pref_record("preferences", W.data) + save_pref_record("preferences", writer.data) /datum/preferences/proc/get_slot_key(slot) return "character_[global.using_map.preferences_key()]_[slot]" @@ -98,14 +98,14 @@ update_preview_icon() /datum/preferences/proc/save_character(override_key=null) - var/datum/pref_record_writer/json_list/W = new(PREF_SER_VERSION) - player_setup.save_character(W) + var/datum/pref_record_writer/json_list/writer = new(PREF_SER_VERSION) + player_setup.save_character(writer) var/record_key = override_key || get_slot_key(default_slot) - save_pref_record(record_key, W.data) + save_pref_record(record_key, writer.data) // Cache the character's name for listing - LAZYSET(slot_names, record_key, W.data["real_name"]) + LAZYSET(slot_names, record_key, writer.data["real_name"]) SScharacter_setup.queue_preferences_save(src) /datum/preferences/proc/sanitize_preferences() diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index b4ffdd62b8f6..6f1516e84771 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -152,16 +152,16 @@ var/plant_type = "pumpkin" // Duplicated from growns for now. TODO: move sliceability down to other objects like clay. -/obj/item/clothing/head/pumpkinhead/attackby(obj/item/W, mob/user) - if(IS_KNIFE(W) && !user.check_intent(I_FLAG_HARM)) +/obj/item/clothing/head/pumpkinhead/attackby(obj/item/used_item, mob/user) + if(IS_KNIFE(used_item) && !user.check_intent(I_FLAG_HARM)) var/datum/seed/plant = SSplants.seeds[plant_type] if(!plant) return ..() var/slice_amount = plant.slice_amount - if(W.w_class > ITEM_SIZE_NORMAL || !user.skill_check(SKILL_COOKING, SKILL_BASIC)) + if(used_item.w_class > ITEM_SIZE_NORMAL || !user.skill_check(SKILL_COOKING, SKILL_BASIC)) user.visible_message( - SPAN_NOTICE("\The [user] crudely slices \the [src] with \the [W]!"), - SPAN_NOTICE("You crudely slice \the [src] with your [W.name]!") + SPAN_NOTICE("\The [user] crudely slices \the [src] with \the [used_item]!"), + SPAN_NOTICE("You crudely slice \the [src] with your [used_item.name]!") ) slice_amount = rand(1, max(1, round(slice_amount*0.5))) else diff --git a/code/modules/clothing/masks/smokable.dm b/code/modules/clothing/masks/smokable.dm index 4aa4fd8cb5ef..49aa63a031dd 100644 --- a/code/modules/clothing/masks/smokable.dm +++ b/code/modules/clothing/masks/smokable.dm @@ -172,24 +172,24 @@ to_chat(M, SPAN_NOTICE("Your [name] goes out.")) qdel(src) -/obj/item/clothing/mask/smokable/attackby(var/obj/item/W, var/mob/user) - if(W.isflamesource() || W.get_heat() >= T100C) +/obj/item/clothing/mask/smokable/attackby(var/obj/item/used_item, var/mob/user) + if(used_item.isflamesource() || used_item.get_heat() >= T100C) var/text = matchmes - if(istype(W, /obj/item/flame/match)) + if(istype(used_item, /obj/item/flame/match)) text = matchmes - else if(istype(W, /obj/item/flame/fuelled/lighter/zippo)) + else if(istype(used_item, /obj/item/flame/fuelled/lighter/zippo)) text = zippomes - else if(istype(W, /obj/item/flame/fuelled/lighter)) + else if(istype(used_item, /obj/item/flame/fuelled/lighter)) text = lightermes - else if(IS_WELDER(W)) + else if(IS_WELDER(used_item)) text = weldermes - else if(istype(W, /obj/item/assembly/igniter)) + else if(istype(used_item, /obj/item/assembly/igniter)) text = ignitermes else text = genericmes text = replacetext(text, "USER", "[user]") text = replacetext(text, "NAME", "[name]") - text = replacetext(text, "FLAME", "[W.name]") + text = replacetext(text, "FLAME", "[used_item.name]") light(text) return TRUE return ..() @@ -357,11 +357,11 @@ desc = "A wooden mouthpiece from a cigar. Smells rather bad." material = /decl/material/solid/organic/wood/oak -/obj/item/clothing/mask/smokable/cigarette/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/energy_blade/sword)) - var/obj/item/energy_blade/sword/S = W +/obj/item/clothing/mask/smokable/cigarette/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/energy_blade/sword)) + var/obj/item/energy_blade/sword/S = used_item if(S.active) - light(SPAN_WARNING("[user] swings their [W], barely missing their nose. They light their [name] in the process.")) + light(SPAN_WARNING("[user] swings their [used_item], barely missing their nose. They light their [name] in the process.")) return TRUE return ..() @@ -539,11 +539,11 @@ reagents.clear_reagents() SetName("empty [initial(name)]") -/obj/item/clothing/mask/smokable/pipe/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/energy_blade/sword)) // Can't light a pipe with an esword +/obj/item/clothing/mask/smokable/pipe/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/energy_blade/sword)) // Can't light a pipe with an esword return TRUE - if (istype(W, /obj/item/food/grown)) - var/obj/item/food/grown/grown = W + if (istype(used_item, /obj/item/food/grown)) + var/obj/item/food/grown/grown = used_item if (!grown.dry) to_chat(user, SPAN_NOTICE("\The [grown] must be dried before you stuff it into \the [src].")) return TRUE diff --git a/code/modules/clothing/spacesuits/breaches.dm b/code/modules/clothing/spacesuits/breaches.dm index 158b3754b767..87213ef88351 100644 --- a/code/modules/clothing/spacesuits/breaches.dm +++ b/code/modules/clothing/spacesuits/breaches.dm @@ -180,10 +180,10 @@ //Handles repairs (and also upgrades). -/obj/item/clothing/suit/space/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/stack/material)) +/obj/item/clothing/suit/space/attackby(obj/item/used_item, mob/user) + if(istype(used_item,/obj/item/stack/material)) var/repair_power = 0 - switch(W.get_material_type()) + switch(used_item.get_material_type()) if(/decl/material/solid/metal/steel) repair_power = 2 if(/decl/material/solid/organic/plastic) @@ -202,13 +202,13 @@ to_chat(user, "There is no surface damage on \the [src] to repair.") //maybe change the descriptor to more obvious? idk what return TRUE - var/obj/item/stack/P = W + var/obj/item/stack/P = used_item var/use_amt = min(P.get_amount(), 3) if(use_amt && P.use(use_amt)) repair_breaches(BURN, use_amt * repair_power, user) return TRUE - else if(IS_WELDER(W)) + else if(IS_WELDER(used_item)) if(ishuman(loc)) var/mob/living/human/H = loc @@ -220,15 +220,15 @@ to_chat(user, "There is no structural damage on \the [src] to repair.") return TRUE - var/obj/item/weldingtool/WT = W - if(!WT.weld(5)) + var/obj/item/weldingtool/welder = used_item + if(!welder.weld(5)) to_chat(user, SPAN_WARNING("You need more welding fuel to repair this suit.")) return TRUE repair_breaches(BRUTE, 3, user) return TRUE - else if(istype(W, /obj/item/stack/tape_roll/duct_tape)) + else if(istype(used_item, /obj/item/stack/tape_roll/duct_tape)) var/datum/breach/target_breach //Target the largest unpatched breach. for(var/datum/breach/B in breaches) if(B.patched) @@ -237,9 +237,9 @@ target_breach = B if(!target_breach) - to_chat(user, "There are no open breaches to seal with \the [W].") + to_chat(user, "There are no open breaches to seal with \the [used_item].") else - var/obj/item/stack/tape_roll/duct_tape/D = W + var/obj/item/stack/tape_roll/duct_tape/D = used_item var/amount_needed = ceil(target_breach.class * 2) if(!D.can_use(amount_needed)) to_chat(user, SPAN_WARNING("There's not enough [D.plural_name] in your [src] to seal \the [target_breach.descriptor] on \the [src]! You need at least [amount_needed] [D.plural_name].")) @@ -250,7 +250,7 @@ playsound(src, 'sound/effects/tape.ogg',25) user.visible_message( SPAN_NOTICE("\The [user] uses some [D.plural_name] to seal \the [target_breach.descriptor] on \the [src]."), - SPAN_NOTICE("You use [amount_needed] [D.plural_name] of \the [W] to seal \the [target_breach.descriptor] on \the [src].") + SPAN_NOTICE("You use [amount_needed] [D.plural_name] of \the [used_item] to seal \the [target_breach.descriptor] on \the [src].") ) target_breach.patched = TRUE target_breach.update_descriptor() diff --git a/code/modules/clothing/spacesuits/rig/modules/modules.dm b/code/modules/clothing/spacesuits/rig/modules/modules.dm index 1e7b7d610017..2a8833f0c58f 100644 --- a/code/modules/clothing/spacesuits/rig/modules/modules.dm +++ b/code/modules/clothing/spacesuits/rig/modules/modules.dm @@ -69,9 +69,9 @@ if(2) . += "It is almost completely destroyed." -/obj/item/rig_module/attackby(obj/item/W, mob/user) +/obj/item/rig_module/attackby(obj/item/used_item, mob/user) - if(istype(W,/obj/item/stack/nanopaste)) + if(istype(used_item,/obj/item/stack/nanopaste)) if(damage == 0) to_chat(user, "There is no damage to mend.") @@ -79,16 +79,16 @@ to_chat(user, "You start mending the damaged portions of \the [src]...") - if(!do_after(user,30,src) || !W || !src) + if(!do_after(user,30,src) || !used_item || !src) return TRUE - var/obj/item/stack/nanopaste/paste = W + var/obj/item/stack/nanopaste/paste = used_item damage = 0 - to_chat(user, "You mend the damage to [src] with [W].") + to_chat(user, "You mend the damage to [src] with [used_item].") paste.use(1) return TRUE - else if(IS_COIL(W)) + else if(IS_COIL(used_item)) switch(damage) if(0) @@ -98,17 +98,17 @@ to_chat(user, "There is no damage that you are capable of mending with such crude tools.") return TRUE - var/obj/item/stack/cable_coil/cable = W + var/obj/item/stack/cable_coil/cable = used_item if(!cable.can_use(5)) to_chat(user, "You need five units of cable to repair \the [src].") return TRUE to_chat(user, "You start mending the damaged portions of \the [src]...") - if(!do_after(user,30,src) || !W || !src) + if(!do_after(user,30,src) || !used_item || !src) return TRUE damage = 1 - to_chat(user, "You mend some of the damage to [src] with [W], but you will need more advanced tools to fix it completely.") + to_chat(user, "You mend some of the damage to [src] with [used_item], but you will need more advanced tools to fix it completely.") cable.use(5) return TRUE return ..() diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index abf699315de8..62062d712350 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -379,21 +379,21 @@ ) var/obj/item/tank/jetpack/rig/jets -/obj/item/rig_module/maneuvering_jets/attackby(obj/item/W, mob/user) - if(W.do_tool_interaction(TOOL_WRENCH, user, src, 1, "removing the propellant tank", "removing the propellant tank")) +/obj/item/rig_module/maneuvering_jets/attackby(obj/item/used_item, mob/user) + if(used_item.do_tool_interaction(TOOL_WRENCH, user, src, 1, "removing the propellant tank", "removing the propellant tank")) jets.forceMove(get_turf(user)) user.put_in_hands(jets) jets = null return TRUE - if(istype(W, /obj/item/tank/jetpack/rig)) + if(istype(used_item, /obj/item/tank/jetpack/rig)) if(jets) to_chat(user, SPAN_WARNING("There's already a propellant tank inside of \the [src]!")) return TRUE - if(user.try_unequip(W)) - to_chat(user, SPAN_NOTICE("You insert \the [W] into [src].")) - W.forceMove(src) - jets = W + if(user.try_unequip(used_item)) + to_chat(user, SPAN_NOTICE("You insert \the [used_item] into [src].")) + used_item.forceMove(src) + jets = used_item return TRUE . = ..() diff --git a/code/modules/clothing/spacesuits/rig/rig_attackby.dm b/code/modules/clothing/spacesuits/rig/rig_attackby.dm index 9c15918e7cab..46b880bac891 100644 --- a/code/modules/clothing/spacesuits/rig/rig_attackby.dm +++ b/code/modules/clothing/spacesuits/rig/rig_attackby.dm @@ -1,4 +1,4 @@ -/obj/item/rig/attackby(obj/item/W, mob/user) +/obj/item/rig/attackby(obj/item/used_item, mob/user) if(!isliving(user)) return FALSE @@ -7,11 +7,11 @@ return TRUE // Pass repair items on to the chestpiece. - if(chest && (istype(W,/obj/item/stack/material) || IS_WELDER(W))) - return chest.attackby(W,user) + if(chest && (istype(used_item,/obj/item/stack/material) || IS_WELDER(used_item))) + return chest.attackby(used_item,user) // Lock or unlock the access panel. - if(W.GetIdCard()) + if(used_item.GetIdCard()) if(subverted) locked = 0 to_chat(user, "It looks like the locking system has been shorted out.") @@ -30,7 +30,7 @@ to_chat(user, "You [locked ? "lock" : "unlock"] \the [src] access panel.") return TRUE - else if(IS_CROWBAR(W)) + else if(IS_CROWBAR(used_item)) if(!open && locked) to_chat(user, "The access panel is locked shut.") @@ -40,13 +40,13 @@ to_chat(user, "You [open ? "open" : "close"] the access panel.") return TRUE - else if(IS_SCREWDRIVER(W)) + else if(IS_SCREWDRIVER(used_item)) p_open = !p_open to_chat(user, "You [p_open ? "open" : "close"] the wire cover.") return TRUE // Hacking. - else if(IS_WIRECUTTER(W) || IS_MULTITOOL(W)) + else if(IS_WIRECUTTER(used_item) || IS_MULTITOOL(used_item)) if(p_open) wires.Interact(user) else @@ -57,21 +57,21 @@ // Air tank. - if(istype(W,/obj/item/tank)) //Todo, some kind of check for suits without integrated air supplies. + if(istype(used_item,/obj/item/tank)) //Todo, some kind of check for suits without integrated air supplies. if(air_supply) to_chat(user, "\The [src] already has a tank installed.") return TRUE - if(!user.try_unequip(W)) + if(!user.try_unequip(used_item)) return TRUE - air_supply = W - W.forceMove(src) - to_chat(user, "You slot [W] into [src] and tighten the connecting valve.") + air_supply = used_item + used_item.forceMove(src) + to_chat(user, "You slot [used_item] into [src] and tighten the connecting valve.") return TRUE // Check if this is a hardsuit upgrade or a modification. - else if(istype(W,/obj/item/rig_module)) + else if(istype(used_item,/obj/item/rig_module)) if(ishuman(src.loc)) var/mob/living/human/H = src.loc @@ -79,11 +79,11 @@ to_chat(user, "You can't install a hardsuit module while the suit is being worn.") return TRUE - if(is_type_in_list(W,banned_modules)) + if(is_type_in_list(used_item,banned_modules)) to_chat(user, SPAN_DANGER("\The [src] cannot mount this type of module.")) return TRUE - var/obj/item/rig_module/mod = W + var/obj/item/rig_module/mod = used_item if(!installed_modules) installed_modules = list() if(installed_modules.len) @@ -92,17 +92,17 @@ to_chat(user, SPAN_DANGER("\The [installed_mod] is incompatible with this module.")) return TRUE if(installed_mod.banned_modules.len) - if(is_type_in_list(W,installed_mod.banned_modules)) + if(is_type_in_list(used_item,installed_mod.banned_modules)) to_chat(user, SPAN_DANGER("\The [installed_mod] is incompatible with this module.")) return TRUE - if(!installed_mod.redundant && installed_mod.type == W.type) + if(!installed_mod.redundant && installed_mod.type == used_item.type) to_chat(user, "The hardsuit already has a module of that class installed.") return TRUE to_chat(user, "You begin installing \the [mod] into \the [src].") if(!do_after(user,40,src)) return TRUE - if(!user || !W) + if(!user || !used_item) return TRUE if(!user.try_unequip(mod)) return TRUE to_chat(user, "You install \the [mod] into \the [src].") @@ -112,15 +112,15 @@ update_icon() return TRUE - else if(!cell && istype(W,/obj/item/cell)) + else if(!cell && istype(used_item,/obj/item/cell)) - if(!user.try_unequip(W)) return TRUE - to_chat(user, "You jack \the [W] into \the [src]'s battery mount.") - W.forceMove(src) - src.cell = W + if(!user.try_unequip(used_item)) return TRUE + to_chat(user, "You jack \the [used_item] into \the [src]'s battery mount.") + used_item.forceMove(src) + src.cell = used_item return TRUE - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) var/list/current_mounts = list() if(cell) current_mounts += "cell" @@ -182,8 +182,8 @@ installed_modules -= removed update_icon() - else if(istype(W,/obj/item/stack/nanopaste)) //EMP repair - var/obj/item/stack/S = W + else if(istype(used_item,/obj/item/stack/nanopaste)) //EMP repair + var/obj/item/stack/S = used_item if(malfunctioning || malfunction_delay) if(S.use(1)) to_chat(user, "You pour some of \the [S] over \the [src]'s control circuitry and watch as the nanites do their work with impressive speed and precision.") @@ -198,7 +198,7 @@ // If we've gotten this far, all we have left to do before we pass off to root procs // is check if any of the loaded modules want to use the item we've been given. for(var/obj/item/rig_module/module in installed_modules) - if(module.accepts_item(W,user)) //Item is handled in this proc + if(module.accepts_item(used_item,user)) //Item is handled in this proc return TRUE return ..() diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index 37c5d360b4d2..857ce4ddc377 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -216,9 +216,9 @@ else if(##equipment_var) {\ src.tank = null playsound(loc, 'sound/effects/spray3.ogg', 50) -/obj/item/clothing/suit/space/void/attackby(obj/item/W, mob/user) +/obj/item/clothing/suit/space/void/attackby(obj/item/used_item, mob/user) - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) if(user.get_equipped_slot_for_item(src) == slot_wear_suit_str)//maybe I should make this into a proc? to_chat(user, "You cannot modify \the [src] while it is being worn.") else if(helmet || boots || tank) @@ -241,36 +241,36 @@ else if(##equipment_var) {\ to_chat(user, "\The [src] does not have anything installed.") return TRUE - if(istype(W,/obj/item/clothing/head/helmet/space)) + if(istype(used_item,/obj/item/clothing/head/helmet/space)) if(user.get_equipped_slot_for_item(src) == slot_wear_suit_str) to_chat(user, "You cannot modify \the [src] while it is being worn.") else if(helmet) to_chat(user, "\The [src] already has a helmet installed.") - else if(user.try_unequip(W, src)) - to_chat(user, "You attach \the [W] to \the [src]'s helmet mount.") - src.helmet = W + else if(user.try_unequip(used_item, src)) + to_chat(user, "You attach \the [used_item] to \the [src]'s helmet mount.") + src.helmet = used_item playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) return TRUE - if(istype(W,/obj/item/clothing/shoes/magboots)) + if(istype(used_item,/obj/item/clothing/shoes/magboots)) if(user.get_equipped_slot_for_item(src) == slot_wear_suit_str) to_chat(user, "You cannot modify \the [src] while it is being worn.") else if(boots) to_chat(user, "\The [src] already has magboots installed.") - else if(user.try_unequip(W, src)) - to_chat(user, "You attach \the [W] to \the [src]'s boot mounts.") - boots = W + else if(user.try_unequip(used_item, src)) + to_chat(user, "You attach \the [used_item] to \the [src]'s boot mounts.") + boots = used_item playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) return TRUE - if(istype(W,/obj/item/tank)) + if(istype(used_item,/obj/item/tank)) if(user.get_equipped_slot_for_item(src) == slot_wear_suit_str) to_chat(user, "You cannot modify \the [src] while it is being worn.") else if(tank) to_chat(user, "\The [src] already has an airtank installed.") - else if(user.try_unequip(W, src)) - to_chat(user, "You insert \the [W] into \the [src]'s storage compartment.") - tank = W + else if(user.try_unequip(used_item, src)) + to_chat(user, "You insert \the [used_item] into \the [src]'s storage compartment.") + tank = used_item playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) return TRUE diff --git a/code/modules/codex/codex_cataloguer.dm b/code/modules/codex/codex_cataloguer.dm index 2d9dc6a4803c..a465ab387b48 100644 --- a/code/modules/codex/codex_cataloguer.dm +++ b/code/modules/codex/codex_cataloguer.dm @@ -100,14 +100,14 @@ return TRUE return ..() -/obj/item/cataloguer/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/disk/survey)) +/obj/item/cataloguer/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/disk/survey)) if(loaded_disk) to_chat(user, SPAN_WARNING("\The [src] already has a disk loaded.")) - else if(user.try_unequip(W, src)) - loaded_disk = W + else if(user.try_unequip(used_item, src)) + loaded_disk = used_item playsound(user.loc, 'sound/weapons/flipblade.ogg', 50, 1) - to_chat(user, SPAN_NOTICE("You slot \the [W] into \the [src].")) + to_chat(user, SPAN_NOTICE("You slot \the [used_item] into \the [src].")) return TRUE return ..() diff --git a/code/modules/crafting/pottery/pottery_moulds.dm b/code/modules/crafting/pottery/pottery_moulds.dm index 0075f90ea29f..c099b58d0dcc 100644 --- a/code/modules/crafting/pottery/pottery_moulds.dm +++ b/code/modules/crafting/pottery/pottery_moulds.dm @@ -57,7 +57,7 @@ else QDEL_NULL(reagents) -/obj/item/chems/mould/attackby(obj/item/W, mob/user) +/obj/item/chems/mould/attackby(obj/item/used_item, mob/user) if(user.check_intent(I_FLAG_HARM)) return ..() @@ -65,20 +65,20 @@ // This is kind of gross but getting /chems/attackby() // standard_pour_into() to cooperate is a bit beyond me // at the moment. - if(istype(W, /obj/item/chems/crucible)) + if(istype(used_item, /obj/item/chems/crucible)) if(material?.hardness <= MAT_VALUE_MALLEABLE) to_chat(user, SPAN_WARNING("\The [src] is currently too soft to be used as a mould.")) return TRUE - var/obj/item/chems/vessel = W + var/obj/item/chems/vessel = used_item if(vessel.standard_pour_into(user, src)) return TRUE - if(try_crack_mold(user, W)) + if(try_crack_mold(user, used_item)) return TRUE - if(try_take_impression(user, W)) + if(try_take_impression(user, used_item)) return TRUE return ..() diff --git a/code/modules/crafting/slapcrafting/_crafting_holder.dm b/code/modules/crafting/slapcrafting/_crafting_holder.dm index 4cb7990226cb..28a469af87f6 100644 --- a/code/modules/crafting/slapcrafting/_crafting_holder.dm +++ b/code/modules/crafting/slapcrafting/_crafting_holder.dm @@ -62,19 +62,19 @@ qdel(src) return TRUE -/obj/item/crafting_holder/try_slapcrafting(obj/item/W, mob/user) +/obj/item/crafting_holder/try_slapcrafting(obj/item/used_item, mob/user) if(current_crafting_stage) - var/decl/crafting_stage/next_stage = current_crafting_stage.get_next_stage(W) - if(next_stage && next_stage.is_appropriate_tool(W, src) && next_stage.is_sufficient_amount(user, W) && next_stage.progress_to(W, user, src)) - advance_to(next_stage, user, W) + var/decl/crafting_stage/next_stage = current_crafting_stage.get_next_stage(used_item) + if(next_stage && next_stage.is_appropriate_tool(used_item, src) && next_stage.is_sufficient_amount(user, used_item) && next_stage.progress_to(used_item, user, src)) + advance_to(next_stage, user, used_item) return TRUE return FALSE -/obj/item/crafting_holder/attackby(var/obj/item/W, var/mob/user) +/obj/item/crafting_holder/attackby(var/obj/item/used_item, var/mob/user) - if(IS_PEN(W)) + if(IS_PEN(used_item)) var/new_label = sanitize_safe(input(user, "What do you wish to label this assembly?", "Assembly Labelling", label_name), MAX_NAME_LEN) - if(new_label && !user.incapacitated() && W.loc == user && user.Adjacent(src) && !QDELETED(src)) + if(new_label && !user.incapacitated() && used_item.loc == user && user.Adjacent(src) && !QDELETED(src)) to_chat(user, SPAN_NOTICE("You label \the [src] with '[new_label]'.")) label_name = new_label return TRUE diff --git a/code/modules/crafting/working/textiles/twisting_bench.dm b/code/modules/crafting/working/textiles/twisting_bench.dm index f4934dfb94bb..a434924ca678 100644 --- a/code/modules/crafting/working/textiles/twisting_bench.dm +++ b/code/modules/crafting/working/textiles/twisting_bench.dm @@ -5,9 +5,9 @@ work_sound = /datum/composite_sound/spinning_wheel_working var/accepts_gut_material = /decl/material/solid/organic/leather/gut -/obj/structure/working/spinning_wheel/twisting_bench/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/food/butchery/offal) && !istype(W, /obj/item/food/butchery/offal/small)) - to_chat(user, SPAN_WARNING("\The [W] is too large for \the [src], cut it up first.")) +/obj/structure/working/spinning_wheel/twisting_bench/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/food/butchery/offal) && !istype(used_item, /obj/item/food/butchery/offal/small)) + to_chat(user, SPAN_WARNING("\The [used_item] is too large for \the [src], cut it up first.")) return TRUE return ..() diff --git a/code/modules/detectivework/microscope/_forensic_machine.dm b/code/modules/detectivework/microscope/_forensic_machine.dm index c3db366ce4bb..b9819400f75b 100644 --- a/code/modules/detectivework/microscope/_forensic_machine.dm +++ b/code/modules/detectivework/microscope/_forensic_machine.dm @@ -41,8 +41,8 @@ var/list/res = list("Use harm intent when manipulating with machine with tools.") return res + ..() -/obj/machinery/forensic/attackby(obj/item/W, mob/user) - if((. = component_attackby(W, user))) +/obj/machinery/forensic/attackby(obj/item/used_item, mob/user) + if((. = component_attackby(used_item, user))) return if(user?.check_intent(I_FLAG_HARM)) @@ -52,18 +52,18 @@ to_chat(user, SPAN_WARNING("There is already a sample in \the [src].")) return TRUE - if(istype(W, /obj/item/evidencebag)) - var/obj/item/evidencebag/B = W + if(istype(used_item, /obj/item/evidencebag)) + var/obj/item/evidencebag/B = used_item if(B.stored_item) to_chat(user, SPAN_NOTICE("You insert \the [B.stored_item] from \the [B].")) B.stored_item.forceMove(src) set_sample(B.stored_item) B.empty() return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, SPAN_NOTICE("You insert \the [W] into \the [src].")) - set_sample(W) + to_chat(user, SPAN_NOTICE("You insert \the [used_item] into \the [src].")) + set_sample(used_item) update_icon() return TRUE diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index 3bfc7ebe8944..e286697b3ac4 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -45,16 +45,16 @@ return ..() -/obj/item/chems/rag/attackby(obj/item/W, mob/user) - if(W.isflamesource()) +/obj/item/chems/rag/attackby(obj/item/used_item, mob/user) + if(used_item.isflamesource()) if(is_on_fire()) to_chat(user, SPAN_WARNING("\The [src] is already blazing merrily!")) return TRUE ignite_fire() if(is_on_fire()) - visible_message(SPAN_DANGER("\The [user] lights \the [src] with \the [W].")) + visible_message(SPAN_DANGER("\The [user] lights \the [src] with \the [used_item].")) else - to_chat(user, SPAN_WARNING("You attempt to light \the [src] with \the [W], but it doesn't seem to be flammable.")) + to_chat(user, SPAN_WARNING("You attempt to light \the [src] with \the [used_item], but it doesn't seem to be flammable.")) update_name() return TRUE return ..() diff --git a/code/modules/economy/worth_cash.dm b/code/modules/economy/worth_cash.dm index 6f6c38ca5811..49d04f24ebdf 100644 --- a/code/modules/economy/worth_cash.dm +++ b/code/modules/economy/worth_cash.dm @@ -59,21 +59,21 @@ var/decl/currency/cur = GET_DECL(currency) . = floor(absolute_worth / cur.absolute_value) -/obj/item/cash/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/cash)) - var/obj/item/cash/cash = W +/obj/item/cash/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/cash)) + var/obj/item/cash/cash = used_item if(cash.currency != currency) to_chat(user, SPAN_WARNING("You can't mix two different currencies, it would be uncivilized.")) return TRUE - if(user.try_unequip(W)) + if(user.try_unequip(used_item)) adjust_worth(cash.absolute_worth) var/decl/currency/cur = GET_DECL(currency) to_chat(user, SPAN_NOTICE("You add [cash.get_worth()] [cur.name] to the pile.")) to_chat(user, SPAN_NOTICE("It holds [get_worth()] [cur.name] now.")) - qdel(W) + qdel(used_item) return TRUE - else if(istype(W, /obj/item/gun/launcher/money)) - var/obj/item/gun/launcher/money/L = W + else if(istype(used_item, /obj/item/gun/launcher/money)) + var/obj/item/gun/launcher/money/L = used_item L.absorb_cash(src, user) return TRUE return ..() @@ -247,17 +247,17 @@ /obj/item/charge_stick/get_base_value() . = holographic ? 0 : loaded_worth -/obj/item/charge_stick/attackby(var/obj/item/W, var/mob/user) +/obj/item/charge_stick/attackby(var/obj/item/used_item, var/mob/user) var/datum/extension/lockable/lock = get_extension(src, /datum/extension/lockable) - if(istype(W, /obj/item/charge_stick)) - var/obj/item/charge_stick/sender = W - var/datum/extension/lockable/W_lock = get_extension(W, /datum/extension/lockable) + if(istype(used_item, /obj/item/charge_stick)) + var/obj/item/charge_stick/sender = used_item + var/datum/extension/lockable/W_lock = get_extension(used_item, /datum/extension/lockable) if(lock.locked) to_chat(user, SPAN_WARNING("Cannot transfer funds to a locked [src].")) return TRUE if(W_lock.locked) - to_chat(user, SPAN_WARNING("Cannot transfer funds from a locked [W].")) + to_chat(user, SPAN_WARNING("Cannot transfer funds from a locked [used_item].")) return TRUE if(sender.currency != currency) to_chat(user, SPAN_WARNING("[html_icon(src)] [src] chirps, \"Mismatched currency detected. Unable to transfer.\"")) @@ -276,7 +276,7 @@ to_chat(user, SPAN_NOTICE("[html_icon(src)] [src] chirps, \"Completed transfer of [amount] [cur.name].\"")) return TRUE - if(lock.attackby(W, user)) + if(lock.attackby(used_item, user)) return TRUE return ..() diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm index 89032c9e88de..76d24cbcb800 100644 --- a/code/modules/events/brand_intelligence.dm +++ b/code/modules/events/brand_intelligence.dm @@ -19,8 +19,8 @@ if(!vendingMachines.len) kill() return - var/weakref/W = pick_n_take(vendingMachines) - originMachine = W.resolve() + var/weakref/vendor_ref = pick_n_take(vendingMachines) + originMachine = vendor_ref.resolve() originMachine.shut_up = 0 originMachine.shoot_inventory = 1 originMachine.shooting_chance = 15 @@ -31,11 +31,11 @@ return if(IsMultiple(activeFor, 5) && prob(15)) - var/weakref/W = pick(vendingMachines) - vendingMachines -= W - var/obj/machinery/vending/infectedMachine = W.resolve() + var/weakref/vendor_ref = pick(vendingMachines) + vendingMachines -= vendor_ref + var/obj/machinery/vending/infectedMachine = vendor_ref.resolve() if(infectedMachine) - infectedVendingMachines += W + infectedVendingMachines += vendor_ref infectedMachine.shut_up = 0 infectedMachine.shoot_inventory = 1 @@ -53,8 +53,8 @@ originMachine.shut_up = 1 originMachine.shooting_chance = initial(originMachine.shooting_chance) originMachine = null - for(var/weakref/W in infectedVendingMachines) - var/obj/machinery/vending/infectedMachine = W.resolve() + for(var/weakref/vendor_ref in infectedVendingMachines) + var/obj/machinery/vending/infectedMachine = vendor_ref.resolve() if(!infectedMachine) continue infectedMachine.shut_up = 1 diff --git a/code/modules/events/meteors.dm b/code/modules/events/meteors.dm index 521a4bbb2f2c..5a4d60f7f628 100644 --- a/code/modules/events/meteors.dm +++ b/code/modules/events/meteors.dm @@ -293,8 +293,8 @@ var/global/list/meteors_major = list( SHOULD_CALL_PARENT(FALSE) return -/obj/effect/meteor/attackby(obj/item/W, mob/user, params) - if(IS_PICK(W)) +/obj/effect/meteor/attackby(obj/item/used_item, mob/user, params) + if(IS_PICK(used_item)) qdel(src) return TRUE return ..() diff --git a/code/modules/events/wallrot.dm b/code/modules/events/wallrot.dm index e57cc6ed4f73..2e20e58a2c40 100644 --- a/code/modules/events/wallrot.dm +++ b/code/modules/events/wallrot.dm @@ -22,8 +22,8 @@ // Have a chance to rot lots of other walls. var/rotcount = 0 var/actual_severity = severity * rand(5, 10) - for(var/turf/wall/W in range(5, center)) if(prob(50)) - W.rot() + for(var/turf/wall/wall in range(5, center)) if(prob(50)) + wall.rot() rotcount++ // Only rot up to severity walls diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm index 8d7626575850..98b2eceb41f6 100644 --- a/code/modules/events/wormholes.dm +++ b/code/modules/events/wormholes.dm @@ -50,6 +50,6 @@ /proc/create_wormhole(turf/enter, turf/exit) if(!enter || !exit) return - var/obj/effect/portal/wormhole/W = new (enter) - W.target = exit - return W + var/obj/effect/portal/wormhole/wormhole = new (enter) + wormhole.target = exit + return wormhole diff --git a/code/modules/fabrication/fabricator_bioprinter.dm b/code/modules/fabrication/fabricator_bioprinter.dm index 305322cb3d66..ca0b5905513f 100644 --- a/code/modules/fabrication/fabricator_bioprinter.dm +++ b/code/modules/fabrication/fabricator_bioprinter.dm @@ -32,9 +32,9 @@ O.copy_from_mob_snapshot(D) O.status |= ORGAN_CUT_AWAY -/obj/machinery/fabricator/bioprinter/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/chems/syringe)) - var/obj/item/chems/syringe/S = W +/obj/machinery/fabricator/bioprinter/attackby(obj/item/used_item, mob/user) + if(istype(used_item,/obj/item/chems/syringe)) + var/obj/item/chems/syringe/S = used_item if(REAGENT_VOLUME(S.reagents, /decl/material/liquid/blood)) var/sample = REAGENT_DATA(S.reagents, /decl/material/liquid/blood) if(islist(sample)) @@ -48,7 +48,7 @@ //Tell nano to do its job SSnano.update_uis(src) return TRUE - to_chat(user, SPAN_WARNING("\The [src] displays an error: no viable blood sample could be obtained from \the [W].")) + to_chat(user, SPAN_WARNING("\The [src] displays an error: no viable blood sample could be obtained from \the [used_item].")) return TRUE . = ..() diff --git a/code/modules/fabrication/recycler.dm b/code/modules/fabrication/recycler.dm index 2d4fcb6299ec..347f316b0d80 100644 --- a/code/modules/fabrication/recycler.dm +++ b/code/modules/fabrication/recycler.dm @@ -112,29 +112,29 @@ if(munched_matter[mat] > 0) trace_matter[mat] += munched_matter[mat] * recycling_efficiency -/obj/machinery/recycler/attackby(obj/item/W, mob/user) +/obj/machinery/recycler/attackby(obj/item/used_item, mob/user) if(use_power == POWER_USE_ACTIVE) to_chat(user, SPAN_WARNING("\The [src] is currently processing, please wait for it to finish.")) return TRUE - if(W.storage && !user.check_intent(I_FLAG_HARM)) + if(used_item.storage && !user.check_intent(I_FLAG_HARM)) var/emptied = FALSE - for(var/obj/item/O in W.get_stored_inventory()) + for(var/obj/item/O in used_item.get_stored_inventory()) if(storage.can_be_inserted(O)) - W.storage.remove_from_storage(null, O, loc, skip_update = TRUE) + used_item.storage.remove_from_storage(null, O, loc, skip_update = TRUE) storage.handle_item_insertion(null, O, skip_update = TRUE) emptied = TRUE if(emptied) - W.storage.finish_bulk_removal() + used_item.storage.finish_bulk_removal() storage.update_ui_after_item_insertion() - if(length(W.get_stored_inventory())) - to_chat(user, SPAN_NOTICE("You partially empty \the [W] into \the [src]'s hopper.")) + if(length(used_item.get_stored_inventory())) + to_chat(user, SPAN_NOTICE("You partially empty \the [used_item] into \the [src]'s hopper.")) else - to_chat(user, SPAN_NOTICE("You empty \the [W] into \the [src]'s hopper.")) - W.update_icon() + to_chat(user, SPAN_NOTICE("You empty \the [used_item] into \the [src]'s hopper.")) + used_item.update_icon() return TRUE // Parent call so we can interact with the machinery aspect diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index 33961e74c429..a2935a323cad 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -231,12 +231,12 @@ return ..() -/obj/item/fishing_rod/attackby(obj/item/W, mob/user) +/obj/item/fishing_rod/attackby(obj/item/used_item, mob/user) - if(load_line(user, W)) + if(load_line(user, used_item)) return TRUE - if(istype(W, /obj/item/food)) + if(istype(used_item, /obj/item/food)) if(bait) to_chat(user, SPAN_WARNING("\The [src] already has \a [bait] on the hook.")) @@ -246,9 +246,9 @@ to_chat(user, SPAN_WARNING("\The [src] needs a line before you can bait it.")) return TRUE - if(user.try_unequip(W, src)) - bait = W - to_chat(user, SPAN_NOTICE("You thread \the [W] onto \the [src]'s hook.")) + if(user.try_unequip(used_item, src)) + bait = used_item + to_chat(user, SPAN_NOTICE("You thread \the [used_item] onto \the [src]'s hook.")) update_icon() return TRUE diff --git a/code/modules/food/assembled.dm b/code/modules/food/assembled.dm index 9df85094417f..4007ffbdeccf 100644 --- a/code/modules/food/assembled.dm +++ b/code/modules/food/assembled.dm @@ -6,31 +6,31 @@ /obj/item/food/proc/get_combined_food_products() return -/obj/item/food/attackby(obj/item/W, mob/living/user) +/obj/item/food/attackby(obj/item/used_item, mob/living/user) - if(W?.storage) + if(used_item?.storage) return ..() // Plating food. - if(istype(W, /obj/item/plate)) - var/obj/item/plate/plate = W + if(istype(used_item, /obj/item/plate)) + var/obj/item/plate/plate = used_item if(plate.try_plate_food(src, user)) return TRUE // Eating with forks - if(user.check_intent(I_FLAG_HELP) && do_utensil_interaction(W, user)) + if(user.check_intent(I_FLAG_HELP) && do_utensil_interaction(used_item, user)) return TRUE // Hiding items inside larger food items. - if(!user.check_intent(I_FLAG_HARM) && is_sliceable() && W.w_class < w_class && !is_robot_module(W) && !istype(W, /obj/item/chems/condiment)) - if(user.try_unequip(W, src)) - to_chat(user, SPAN_NOTICE("You slip \the [W] inside \the [src].")) + if(!user.check_intent(I_FLAG_HARM) && is_sliceable() && used_item.w_class < w_class && !is_robot_module(used_item) && !istype(used_item, /obj/item/chems/condiment)) + if(user.try_unequip(used_item, src)) + to_chat(user, SPAN_NOTICE("You slip \the [used_item] inside \the [src].")) add_fingerprint(user) - W.forceMove(src) + used_item.forceMove(src) return TRUE // Creating food combinations. - if(try_create_combination(W, user)) + if(try_create_combination(used_item, user)) return TRUE return ..() @@ -38,8 +38,8 @@ /obj/item/food/proc/get_grown_tag() return -/obj/item/food/proc/try_create_combination(obj/item/W, mob/user) - if(!length(get_combined_food_products()) || !istype(W) || QDELETED(src) || QDELETED(W)) +/obj/item/food/proc/try_create_combination(obj/item/used_item, mob/user) + if(!length(get_combined_food_products()) || !istype(used_item) || QDELETED(src) || QDELETED(used_item)) return FALSE // See if we can make anything with this. @@ -47,9 +47,9 @@ if(!length(combined_food_products)) return FALSE - var/create_type = combined_food_products[W.type] - if(!create_type && istype(W, /obj/item/food)) - var/obj/item/food/food = W + var/create_type = combined_food_products[used_item.type] + if(!create_type && istype(used_item, /obj/item/food)) + var/obj/item/food/food = used_item var/check_grown_tag = food.get_grown_tag() if(check_grown_tag) create_type = combined_food_products[check_grown_tag] @@ -59,7 +59,7 @@ for(var/food_type in create_type) names[atom_info_repository.get_name_for(food_type)] = food_type create_type = input(user, "What do you want to make?", "Food Assembly") as null|anything in names - if(!create_type || QDELETED(user) || user.incapacitated() || QDELETED(src) || QDELETED(W)) + if(!create_type || QDELETED(user) || user.incapacitated() || QDELETED(src) || QDELETED(used_item)) return TRUE create_type = names[create_type] @@ -71,8 +71,8 @@ // Create the food with no plate, and move over any existing plate. result = new create_type(null, null, TRUE) // Skip plate creation. - if(istype(W, /obj/item/food)) - var/obj/item/food/other_food = W + if(istype(used_item, /obj/item/food)) + var/obj/item/food/other_food = used_item result.plate = other_food.plate other_food.plate = null @@ -92,13 +92,13 @@ user.put_in_hands(result) else result.dropInto(loc) - qdel(W) + qdel(used_item) qdel(src) to_chat(user, SPAN_NOTICE("You make \the [result]!")) return TRUE // Reverse the interaction to avoid the dumb thing where combinations aren't commutative. - var/obj/item/food/food = W + var/obj/item/food/food = used_item if(istype(food)) return food.try_create_combination(src, user) return FALSE diff --git a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm index 0258f2e665a8..189106c5b238 100644 --- a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm +++ b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm @@ -16,19 +16,19 @@ var/decl/recipe/last_recipe // TODO: ladle -/obj/item/chems/cooking_vessel/attackby(obj/item/W, mob/user) +/obj/item/chems/cooking_vessel/attackby(obj/item/used_item, mob/user) if(user.check_intent(I_FLAG_HARM)) return ..() // Fill or take from the vessel. - if(W.reagents && ATOM_IS_OPEN_CONTAINER(W)) - if(W.reagents.total_volume) - if(istype(W, /obj/item/chems)) - var/obj/item/chems/vessel = W + if(used_item.reagents && ATOM_IS_OPEN_CONTAINER(used_item)) + if(used_item.reagents.total_volume) + if(istype(used_item, /obj/item/chems)) + var/obj/item/chems/vessel = used_item if(vessel.standard_pour_into(user, src)) return TRUE - else if(standard_pour_into(user, W)) + else if(standard_pour_into(user, used_item)) return TRUE return ..() diff --git a/code/modules/food/plates/_plate.dm b/code/modules/food/plates/_plate.dm index 869b44baab8e..79cae23dbd0a 100644 --- a/code/modules/food/plates/_plate.dm +++ b/code/modules/food/plates/_plate.dm @@ -53,9 +53,9 @@ food.update_icon() return TRUE -/obj/item/plate/attackby(obj/item/W, mob/living/user) +/obj/item/plate/attackby(obj/item/used_item, mob/living/user) // Plating food. - if(try_plate_food(W, user)) + if(try_plate_food(used_item, user)) return TRUE return ..() diff --git a/code/modules/food/plates/plate_tray.dm b/code/modules/food/plates/plate_tray.dm index d38ce43225d5..d99819116a59 100644 --- a/code/modules/food/plates/plate_tray.dm +++ b/code/modules/food/plates/plate_tray.dm @@ -50,23 +50,23 @@ if(.) scatter_contents() -/obj/item/plate/tray/attackby(obj/item/W, mob/user, click_params) - if(istype(W, /obj/item/kitchen/rollingpin)) +/obj/item/plate/tray/attackby(obj/item/used_item, mob/user, click_params) + if(istype(used_item, /obj/item/kitchen/rollingpin)) if(cooldown < world.time - 25) - user.visible_message(SPAN_WARNING("\The [user] bashes \the [src] with \the [W]!")) + user.visible_message(SPAN_WARNING("\The [user] bashes \the [src] with \the [used_item]!")) playsound(user.loc, 'sound/effects/shieldbash.ogg', 50, 1) cooldown = world.time return TRUE . = ..() if (.) - auto_align(W, click_params) + auto_align(used_item, click_params) //This proc handles alignment on trays, a la tables. -/obj/item/plate/tray/proc/auto_align(obj/item/W, click_params) - if (!W.center_of_mass) // Clothing, material stacks, generally items with large sprites where exact placement would be unhandy. - W.pixel_x = rand(-W.randpixel, W.randpixel) - W.pixel_y = rand(-W.randpixel, W.randpixel) - W.pixel_z = 0 +/obj/item/plate/tray/proc/auto_align(obj/item/aligning, click_params) + if (!aligning.center_of_mass) // Clothing, material stacks, generally items with large sprites where exact placement would be unhandy. + aligning.pixel_x = rand(-aligning.randpixel, aligning.randpixel) + aligning.pixel_y = rand(-aligning.randpixel, aligning.randpixel) + aligning.pixel_z = 0 return if (!click_params) @@ -83,11 +83,11 @@ var/cell_x = clamp(round(mouse_x/CELLSIZE), 0, CELLS-1) // Ranging from 0 to CELLS-1 var/cell_y = clamp(round(mouse_y/CELLSIZE), 0, CELLS-1) - var/list/center = cached_json_decode(W.center_of_mass) + var/list/center = cached_json_decode(aligning.center_of_mass) - W.pixel_x = (CELLSIZE * (cell_x + 0.5)) - center["x"] - W.pixel_y = (CELLSIZE * (cell_y + 0.5)) - center["y"] - W.pixel_z = 0 + aligning.pixel_x = (CELLSIZE * (cell_x + 0.5)) - center["x"] + aligning.pixel_y = (CELLSIZE * (cell_y + 0.5)) - center["y"] + aligning.pixel_z = 0 /obj/item/plate/tray/dump_contents(atom/forced_loc = loc, mob/user) if(!isturf(forced_loc)) //to handle hand switching diff --git a/code/modules/goals/definitions/department_clerical.dm b/code/modules/goals/definitions/department_clerical.dm index 75ac548eb873..7b2abd0a1e58 100644 --- a/code/modules/goals/definitions/department_clerical.dm +++ b/code/modules/goals/definitions/department_clerical.dm @@ -128,8 +128,8 @@ if(length(has_signed)) . += SPAN_NOTICE("It has been signed by: [english_list(has_signed)].") -/obj/item/paperwork/attackby(obj/item/W, mob/user) - if(IS_PEN(W)) +/obj/item/paperwork/attackby(obj/item/used_item, mob/user) + if(IS_PEN(used_item)) if(user.real_name in has_signed) to_chat(user, SPAN_WARNING("You have already signed \the [src].")) return TRUE @@ -138,7 +138,7 @@ return TRUE LAZYADD(has_signed, user.real_name) LAZYREMOVE(needs_signed, user.real_name) - user.visible_message(SPAN_NOTICE("\The [user] signs \the [src] with \the [W].")) + user.visible_message(SPAN_NOTICE("\The [user] signs \the [src] with \the [used_item].")) associated_goal?.update_strings() update_icon() return TRUE diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index f6da2d3ceaac..254a5efd3ffc 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -9,7 +9,7 @@ /turf/floor/holofloor/get_lumcount(var/minlum = 0, var/maxlum = 1) return 0.8 -/turf/floor/holofloor/attackby(obj/item/W, mob/user) +/turf/floor/holofloor/attackby(obj/item/used_item, mob/user) return TRUE // HOLOFLOOR DOES NOT GIVE A FUCK @@ -320,7 +320,7 @@ to_chat(user, "The AI is not to interact with these devices!") return -/obj/machinery/readybutton/attackby(obj/item/W, mob/user) +/obj/machinery/readybutton/attackby(obj/item/used_item, mob/user) to_chat(user, "The device is a solid button, there's nothing you can do with it!") return TRUE @@ -359,8 +359,8 @@ eventstarted = 1 - for(var/obj/structure/window/reinforced/holowindow/disappearing/W in currentarea) - qdel(W) + for(var/obj/structure/window/reinforced/holowindow/disappearing/window in currentarea) + qdel(window) for(var/mob/M in currentarea) to_chat(M, "FIGHT!") diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index bd7b83ef9d64..9da7ffda83e3 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -231,13 +231,13 @@ var/global/list/_wood_materials = list( if(!seed?.show_slice_message_poor(user, tool, src)) ..() -/obj/item/food/grown/attackby(var/obj/item/W, var/mob/user) +/obj/item/food/grown/attackby(var/obj/item/used_item, var/mob/user) if(!seed || user.check_intent(I_FLAG_HARM)) return ..() - if(seed.get_trait(TRAIT_PRODUCES_POWER) && IS_COIL(W)) - var/obj/item/stack/cable_coil/C = W + if(seed.get_trait(TRAIT_PRODUCES_POWER) && IS_COIL(used_item)) + var/obj/item/stack/cable_coil/C = used_item if(C.use(5)) //TODO: generalize this. to_chat(user, SPAN_NOTICE("You add some cable to \the [src] and slide it inside the battery casing.")) @@ -248,15 +248,15 @@ var/global/list/_wood_materials = list( pocell.charge = pocell.maxcharge return TRUE - if(IS_KNIFE(W) && !seeds_extracted && !seed.grown_is_seed && seed.min_seed_extracted && user.skill_check(work_skill, SKILL_BASIC)) + if(IS_KNIFE(used_item) && !seeds_extracted && !seed.grown_is_seed && seed.min_seed_extracted && user.skill_check(work_skill, SKILL_BASIC)) var/seed_result = max(1, rand(seed.min_seed_extracted, seed.max_seed_extracted)) - visible_message(SPAN_NOTICE("\The [user] uses \the [W] to lever [seed_result] seed\s out of \the [src].")) + visible_message(SPAN_NOTICE("\The [user] uses \the [used_item] to lever [seed_result] seed\s out of \the [src].")) for(var/i = 1 to seed_result) new /obj/item/seeds/extracted(get_turf(user), material?.type, seed) seeds_extracted = TRUE return TRUE - if(IS_HATCHET(W) && seed.chems) + if(IS_HATCHET(used_item) && seed.chems) for(var/wood_mat in global._wood_materials) if(!isnull(seed.chems[wood_mat])) user.visible_message(SPAN_NOTICE("\The [user] makes planks out of \the [src].")) @@ -265,13 +265,13 @@ var/global/list/_wood_materials = list( qdel(src) return TRUE - if(istype(W, /obj/item/paper)) + if(istype(used_item, /obj/item/paper)) if(!dry) to_chat(user, SPAN_WARNING("You need to dry \the [src] first!")) return TRUE - if(!user.try_unequip(W)) + if(!user.try_unequip(used_item)) return TRUE var/obj/item/clothing/mask/smokable/cigarette/rolled/R = new(get_turf(src)) @@ -282,11 +282,11 @@ var/global/list/_wood_materials = list( else R.create_reagents(R.chem_volume) - R.brand = "[src] handrolled in \the [W]." + R.brand = "[src] handrolled in \the [used_item]." reagents.trans_to_holder(R.reagents, R.chem_volume) - to_chat(user, SPAN_NOTICE("You roll \the [src] into \the [W].")) + to_chat(user, SPAN_NOTICE("You roll \the [src] into \the [used_item].")) user.put_in_active_hand(R) - qdel(W) + qdel(used_item) qdel(src) return TRUE diff --git a/code/modules/hydroponics/grown_inedible.dm b/code/modules/hydroponics/grown_inedible.dm index e9cdda705d9f..173d19639f9d 100644 --- a/code/modules/hydroponics/grown_inedible.dm +++ b/code/modules/hydroponics/grown_inedible.dm @@ -9,9 +9,9 @@ throw_range = 20 material = /decl/material/solid/organic/plantmatter -/obj/item/corncob/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/circular_saw) || IS_HATCHET(W) || istype(W, /obj/item/knife)) - to_chat(user, "You use [W] to fashion a pipe out of the corn cob!") +/obj/item/corncob/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/circular_saw) || IS_HATCHET(used_item) || istype(used_item, /obj/item/knife)) + to_chat(user, "You use [used_item] to fashion a pipe out of the corn cob!") new /obj/item/clothing/mask/smokable/pipe/cobpipe (user.loc) qdel(src) return TRUE diff --git a/code/modules/hydroponics/seed_machines.dm b/code/modules/hydroponics/seed_machines.dm index 17fbe753529f..af1d79e8cbd5 100644 --- a/code/modules/hydroponics/seed_machines.dm +++ b/code/modules/hydroponics/seed_machines.dm @@ -66,33 +66,33 @@ visible_message("[html_icon(src)] [src] beeps and spits out [loaded_disk].") loaded_disk = null -/obj/machinery/botany/attackby(obj/item/W, mob/user) - if(istype(W,/obj/item/seeds)) +/obj/machinery/botany/attackby(obj/item/used_item, mob/user) + if(istype(used_item,/obj/item/seeds)) if(seed) to_chat(user, "There is already a seed loaded.") return TRUE - var/obj/item/seeds/S = W + var/obj/item/seeds/S = used_item if(S.seed && S.seed.get_trait(TRAIT_IMMUTABLE) > 0) to_chat(user, "That seed is not compatible with our genetics technology.") - else if(user.try_unequip(W, src)) - seed = W - to_chat(user, "You load [W] into [src].") + else if(user.try_unequip(used_item, src)) + seed = used_item + to_chat(user, "You load [used_item] into [src].") return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) open = !open to_chat(user, "You [open ? "open" : "close"] the maintenance panel.") return TRUE - if(open && IS_CROWBAR(W)) + if(open && IS_CROWBAR(used_item)) dismantle() return TRUE - if(istype(W,/obj/item/disk/botany)) + if(istype(used_item,/obj/item/disk/botany)) if(loaded_disk) to_chat(user, "There is already a data disk loaded.") return TRUE - var/obj/item/disk/botany/B = W + var/obj/item/disk/botany/B = used_item if(B.genes && B.genes.len) if(!disk_needs_genes) to_chat(user, "That disk already has gene data loaded.") @@ -101,10 +101,10 @@ if(disk_needs_genes) to_chat(user, "That disk does not have any gene data loaded.") return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - loaded_disk = W - to_chat(user, "You load [W] into [src].") + loaded_disk = used_item + to_chat(user, "You load [used_item] into [src].") return TRUE return ..() diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm index 0980347c73d7..2b772c7f15f4 100644 --- a/code/modules/hydroponics/spreading/spreading.dm +++ b/code/modules/hydroponics/spreading/spreading.dm @@ -197,10 +197,10 @@ floor = 1 return 1 -/obj/effect/vine/attackby(var/obj/item/W, var/mob/user) +/obj/effect/vine/attackby(var/obj/item/used_item, var/mob/user) START_PROCESSING(SSvines, src) - if(W.has_edge() && W.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) + if(used_item.has_edge() && used_item.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) if(!is_mature()) to_chat(user, SPAN_WARNING("\The [src] is not mature enough to yield a sample yet.")) return TRUE @@ -216,11 +216,11 @@ return TRUE else . = ..() - var/damage = W.expend_attack_force(user) - if(W.has_edge()) + var/damage = used_item.expend_attack_force(user) + if(used_item.has_edge()) damage *= 2 adjust_health(-damage) - playsound(get_turf(src), W.hitsound, 100, 1) + playsound(get_turf(src), used_item.hitsound, 100, 1) //handles being overrun by vines - note that attacker_parent may be null in some cases /obj/effect/vine/proc/vine_overrun(datum/seed/attacker_seed, obj/effect/vine/attacker_parent) diff --git a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm index 8947d15a5de3..741bc5d94a5f 100644 --- a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm +++ b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm @@ -155,8 +155,8 @@ atmosphere = A.Clone() ///Resets the given weather state to our planet replacing the old one, and trigger updates. Can be a type path or instance. -/datum/planetoid_data/proc/reset_weather(var/decl/state/weather/W) - initial_weather_state = W +/datum/planetoid_data/proc/reset_weather(var/decl/state/weather/weather) + initial_weather_state = weather if(!(topmost_level_id in SSmapping.levels_by_id)) return //It's entire possible the levels weren't initialized yet, so don't bother. //Tells all our levels exposed to the sky to force change the weather. diff --git a/code/modules/materials/_material_stack.dm b/code/modules/materials/_material_stack.dm index a956e5678de8..eab2ce44036a 100644 --- a/code/modules/materials/_material_stack.dm +++ b/code/modules/materials/_material_stack.dm @@ -120,36 +120,36 @@ /obj/item/stack/material/proc/get_stack_conversion_dictionary() return -/obj/item/stack/material/attackby(var/obj/item/W, var/mob/user) +/obj/item/stack/material/attackby(var/obj/item/used_item, var/mob/user) - if(can_be_reinforced && istype(W, /obj/item/stack/material)) - if(is_same(W)) + if(can_be_reinforced && istype(used_item, /obj/item/stack/material)) + if(is_same(used_item)) return ..() if(!reinf_material) - material.reinforce(user, W, src) + material.reinforce(user, used_item, src) return TRUE // TODO: convert to converts_into entry. - if(can_be_pulverized && IS_HAMMER(W) && material?.hardness >= MAT_VALUE_RIGID && user.check_intent(I_FLAG_HARM)) + if(can_be_pulverized && IS_HAMMER(used_item) && material?.hardness >= MAT_VALUE_RIGID && user.check_intent(I_FLAG_HARM)) - if(W.material?.hardness < material.hardness) - to_chat(user, SPAN_WARNING("\The [W] is not hard enough to pulverize [material.solid_name].")) + if(used_item.material?.hardness < material.hardness) + to_chat(user, SPAN_WARNING("\The [used_item] is not hard enough to pulverize [material.solid_name].")) return TRUE var/converting = clamp(get_amount(), 0, 5) - if(converting && W.do_tool_interaction(TOOL_HAMMER, user, src, 1 SECOND, "pulverizing", "pulverizing", set_cooldown = TRUE) && !QDELETED(src) && get_amount() >= converting) + if(converting && used_item.do_tool_interaction(TOOL_HAMMER, user, src, 1 SECOND, "pulverizing", "pulverizing", set_cooldown = TRUE) && !QDELETED(src) && get_amount() >= converting) // TODO: make a gravel type? // TODO: pass actual stone material to gravel? new /obj/item/stack/material/ore/handful/sand(get_turf(user), converting) - user.visible_message("\The [user] pulverizes [converting == 1 ? "a [singular_name]" : "some [plural_name]"] with \the [W].") + user.visible_message("\The [user] pulverizes [converting == 1 ? "a [singular_name]" : "some [plural_name]"] with \the [used_item].") use(converting) return TRUE - if(reinf_material?.default_solid_form && IS_WELDER(W)) - var/obj/item/weldingtool/WT = W - if(WT.isOn() && WT.get_fuel() > 2 && use(2)) - WT.weld(2, user) + if(reinf_material?.default_solid_form && IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item + if(welder.isOn() && welder.get_fuel() > 2 && use(2)) + welder.weld(2, user) to_chat(user, SPAN_NOTICE("You recover some [reinf_material.use_name] from \the [src].")) reinf_material.create_object(get_turf(user), 1) return TRUE @@ -160,7 +160,7 @@ var/convert_tool var/obj/item/stack/convert_type for(var/tool_type in can_be_converted_into) - if(IS_TOOL(W, tool_type)) + if(IS_TOOL(used_item, tool_type)) convert_tool = tool_type convert_type = can_be_converted_into[tool_type] break @@ -172,7 +172,7 @@ if(get_amount() < minimum_per_one_product) to_chat(user, SPAN_WARNING("You will need [minimum_per_one_product] [minimum_per_one_product == 1 ? singular_name : plural_name] to produce [product_per_sheet] [product_per_sheet == 1 ? initial(convert_type.singular_name) : initial(convert_type.plural_name)].")) - else if(W.do_tool_interaction(convert_tool, user, src, 1 SECOND, set_cooldown = TRUE) && !QDELETED(src) && get_amount() >= minimum_per_one_product) + else if(used_item.do_tool_interaction(convert_tool, user, src, 1 SECOND, set_cooldown = TRUE) && !QDELETED(src) && get_amount() >= minimum_per_one_product) var/obj/item/stack/product = new convert_type(loc, ceil(product_per_sheet), material?.type, reinf_material?.type) product.dropInto(loc) use(minimum_per_one_product) diff --git a/code/modules/materials/material_debris.dm b/code/modules/materials/material_debris.dm index 8c4844a81247..7e9043609376 100644 --- a/code/modules/materials/material_debris.dm +++ b/code/modules/materials/material_debris.dm @@ -71,9 +71,9 @@ return ..() -/obj/item/debris/scraps/attackby(obj/item/W, mob/user) - if(istype(W, type) && user.try_unequip(W)) - var/obj/item/debris/scraps/other = W +/obj/item/debris/scraps/attackby(obj/item/used_item, mob/user) + if(istype(used_item, type) && user.try_unequip(used_item)) + var/obj/item/debris/scraps/other = used_item var/space_remaining = MAX_SCRAP_MATTER - get_total_matter() var/other_total_matter = other.get_total_matter() LAZYINITLIST(matter) diff --git a/code/modules/materials/material_stack_animal.dm b/code/modules/materials/material_stack_animal.dm index f4d1d30f8090..eaa7a353bb21 100644 --- a/code/modules/materials/material_stack_animal.dm +++ b/code/modules/materials/material_stack_animal.dm @@ -26,12 +26,12 @@ _cleaned = TRUE name_modifier = "cleaned" -/obj/item/stack/material/skin/attackby(obj/item/W, mob/user) - if(IS_KNIFE(W) && !_cleaned) +/obj/item/stack/material/skin/attackby(obj/item/used_item, mob/user) + if(IS_KNIFE(used_item) && !_cleaned) var/cleaned_sheets = 0 - while(W.do_tool_interaction(TOOL_KNIFE, user, src, 2 SECONDS, "scraping", "scraping", check_skill = work_skill, set_cooldown = TRUE)) + while(used_item.do_tool_interaction(TOOL_KNIFE, user, src, 2 SECONDS, "scraping", "scraping", check_skill = work_skill, set_cooldown = TRUE)) - if(QDELETED(src) || _cleaned || get_amount() <= 0 || QDELETED(user) || (loc != user && !user.Adjacent(src)) || QDELETED(W) || user.get_active_held_item() != W) + if(QDELETED(src) || _cleaned || get_amount() <= 0 || QDELETED(user) || (loc != user && !user.Adjacent(src)) || QDELETED(used_item) || user.get_active_held_item() != used_item) break var/sheets = min(5, get_amount()) diff --git a/code/modules/materials/materials_ore.dm b/code/modules/materials/materials_ore.dm index b2eb776014b3..4ac278611253 100644 --- a/code/modules/materials/materials_ore.dm +++ b/code/modules/materials/materials_ore.dm @@ -99,10 +99,10 @@ SetName("[(material.ore_name ? material.ore_name : "[material.name] chunk")][(amount > 1? " pile" : "")]") desc = material.ore_desc ? material.ore_desc : "A lump of ore." -/obj/item/stack/material/ore/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/stack/material) && !is_same(W)) +/obj/item/stack/material/ore/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/stack/material) && !is_same(used_item)) return FALSE //Don't reinforce - if(reinf_material && reinf_material.default_solid_form && IS_WELDER(W)) + if(reinf_material && reinf_material.default_solid_form && IS_WELDER(used_item)) return FALSE //Don't melt stuff with welder return ..() diff --git a/code/modules/mechs/components/_components.dm b/code/modules/mechs/components/_components.dm index 6f93e83e1a93..281d3c4ade7b 100644 --- a/code/modules/mechs/components/_components.dm +++ b/code/modules/mechs/components/_components.dm @@ -136,16 +136,16 @@ /obj/item/mech_component/proc/update_components() return -/obj/item/mech_component/proc/repair_brute_generic(var/obj/item/weldingtool/WT, var/mob/user) - if(!istype(WT)) +/obj/item/mech_component/proc/repair_brute_generic(var/obj/item/weldingtool/welder, var/mob/user) + if(!istype(welder)) return if(!brute_damage) to_chat(user, SPAN_NOTICE("You inspect \the [src] but find nothing to weld.")) return - if(!WT.isOn()) - to_chat(user, SPAN_WARNING("Turn \the [WT] on, first.")) + if(!welder.isOn()) + to_chat(user, SPAN_WARNING("Turn \the [welder] on, first.")) return - if(WT.weld((SKILL_MAX + 1) - user.get_skill_value(SKILL_CONSTRUCTION), user)) + if(welder.weld((SKILL_MAX + 1) - user.get_skill_value(SKILL_CONSTRUCTION), user)) user.visible_message( SPAN_NOTICE("\The [user] begins welding the damage on \the [src]..."), SPAN_NOTICE("You begin welding the damage on \the [src]...") diff --git a/code/modules/mechs/components/frame.dm b/code/modules/mechs/components/frame.dm index 16a24e639de0..e92325c92105 100644 --- a/code/modules/mechs/components/frame.dm +++ b/code/modules/mechs/components/frame.dm @@ -229,17 +229,17 @@ is_reinforced = (is_reinforced == FRAME_REINFORCED_SECURE) ? FRAME_REINFORCED : FRAME_REINFORCED_SECURE // Welding metal. else if(IS_WELDER(thing)) - var/obj/item/weldingtool/WT = thing + var/obj/item/weldingtool/welder = thing if(!is_reinforced) to_chat(user, SPAN_WARNING("There is no metal to secure inside \the [src].")) return TRUE if(is_reinforced == FRAME_REINFORCED) to_chat(user, SPAN_WARNING("The reinforcement inside \the [src] has not been secured.")) return TRUE - if(!WT.isOn()) - to_chat(user, SPAN_WARNING("Turn \the [WT] on, first.")) + if(!welder.isOn()) + to_chat(user, SPAN_WARNING("Turn \the [welder] on, first.")) return TRUE - if(WT.weld(1, user)) + if(welder.weld(1, user)) var/last_reinforced_state = is_reinforced visible_message("\The [user] begins welding the metal reinforcement inside \the [src].") diff --git a/code/modules/mechs/equipment/utility.dm b/code/modules/mechs/equipment/utility.dm index 903d50deb30d..7d7d057c652d 100644 --- a/code/modules/mechs/equipment/utility.dm +++ b/code/modules/mechs/equipment/utility.dm @@ -755,10 +755,10 @@ passive_power_use = 0 . = ..() -/obj/item/mech_equipment/camera/attackby(obj/item/W, mob/user) +/obj/item/mech_equipment/camera/attackby(obj/item/used_item, mob/user) . = ..() - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) var/datum/extension/network_device/camera/mech/D = get_extension(src, /datum/extension/network_device) D.ui_interact(user) diff --git a/code/modules/mechs/mech_wreckage.dm b/code/modules/mechs/mech_wreckage.dm index 3f0c08020156..f52c3812e14a 100644 --- a/code/modules/mechs/mech_wreckage.dm +++ b/code/modules/mechs/mech_wreckage.dm @@ -58,16 +58,16 @@ to_chat(user, "You retrieve \the [thing] from \the [src].") return TRUE -/obj/structure/mech_wreckage/attackby(var/obj/item/W, var/mob/user) +/obj/structure/mech_wreckage/attackby(var/obj/item/used_item, var/mob/user) var/cutting - if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W - if(WT.isOn()) + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item + if(welder.isOn()) cutting = TRUE else - to_chat(user, SPAN_WARNING("Turn \the [WT] on, first.")) - else if(istype(W, /obj/item/gun/energy/plasmacutter)) + to_chat(user, SPAN_WARNING("Turn \the [welder] on, first.")) + else if(istype(used_item, /obj/item/gun/energy/plasmacutter)) cutting = TRUE if(cutting) @@ -78,7 +78,7 @@ to_chat(user, SPAN_WARNING("\The [src] has already been weakened.")) return 1 - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) if(prepared) to_chat(user, SPAN_NOTICE("You finish dismantling \the [src].")) SSmaterials.create_object(/decl/material/solid/metal/steel, get_turf(src), rand(5, 10)) @@ -86,8 +86,8 @@ else to_chat(user, SPAN_WARNING("It's too solid to dismantle. Try cutting through some of the bigger bits.")) return 1 - else if(istype(W) && W.expend_attack_force(user) > 20) - visible_message(SPAN_DANGER("\The [src] has been smashed with \the [W] by \the [user]!")) + else if(istype(used_item) && used_item.expend_attack_force(user) > 20) + visible_message(SPAN_DANGER("\The [src] has been smashed with \the [used_item] by \the [user]!")) if(prob(20)) physically_destroyed() return 1 diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 15c5846a8a46..06ff4ce3e1b9 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -172,8 +172,8 @@ if(guesschar != code[i]) . = 0 -/obj/structure/closet/crate/secure/loot/attackby(obj/item/W, mob/user) - if(!locked || !IS_MULTITOOL(W)) +/obj/structure/closet/crate/secure/loot/attackby(obj/item/used_item, mob/user) + if(!locked || !IS_MULTITOOL(used_item)) return ..() // Greetings Urist McProfessor, how about a nice game of cows and bulls? to_chat(user, "DECA-CODE LOCK ANALYSIS:") diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 5836b2ed9796..bd70d153e5e8 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -58,7 +58,7 @@ . = ..() update_icon() -/obj/item/stack/flag/attackby(var/obj/item/W, var/mob/user) +/obj/item/stack/flag/attackby(var/obj/item/used_item, var/mob/user) if(upright) return attack_hand_with_interaction_checks(user) return ..() diff --git a/code/modules/mining/ore_box.dm b/code/modules/mining/ore_box.dm index 84acc94e834e..ab20aa117d11 100644 --- a/code/modules/mining/ore_box.dm +++ b/code/modules/mining/ore_box.dm @@ -26,21 +26,21 @@ to_chat(user, SPAN_NOTICE("You grab a random ore pile from \the [src].")) return TRUE -/obj/structure/ore_box/attackby(obj/item/W, mob/user) - if (istype(W, /obj/item/stack/material/ore)) - return insert_ore(W, user) - if(W.storage) +/obj/structure/ore_box/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/stack/material/ore)) + return insert_ore(used_item, user) + if(used_item.storage) var/added_ore = FALSE - W.storage.hide_from(user) - for(var/obj/item/stack/material/ore/O in W.storage.get_contents()) + used_item.storage.hide_from(user) + for(var/obj/item/stack/material/ore/O in used_item.storage.get_contents()) if(total_ores >= maximum_ores) break - W.storage.remove_from_storage(user, O, src, TRUE) + used_item.storage.remove_from_storage(user, O, src, TRUE) insert_ore(O) added_ore = TRUE if(added_ore) - W.storage.finish_bulk_removal() - to_chat(user, SPAN_NOTICE("You empty \the [W] into \the [src].")) + used_item.storage.finish_bulk_removal() + to_chat(user, SPAN_NOTICE("You empty \the [used_item] into \the [src].")) return TRUE return ..() diff --git a/code/modules/mob/grab/grab_object.dm b/code/modules/mob/grab/grab_object.dm index dc0614ccbac2..52e18ee93eb8 100644 --- a/code/modules/mob/grab/grab_object.dm +++ b/code/modules/mob/grab/grab_object.dm @@ -279,9 +279,9 @@ /obj/item/grab/proc/stop_move() return current_grab.stop_move -/obj/item/grab/attackby(obj/W, mob/user) +/obj/item/grab/attackby(obj/item/used_item, mob/user) if(user == assailant) - return current_grab.item_attack(src, W) + return current_grab.item_attack(src, used_item) return FALSE /obj/item/grab/proc/assailant_reverse_facing() diff --git a/code/modules/mob/grab/normal/grab_normal.dm b/code/modules/mob/grab/normal/grab_normal.dm index df950514b867..dc9af610c6c9 100644 --- a/code/modules/mob/grab/normal/grab_normal.dm +++ b/code/modules/mob/grab/normal/grab_normal.dm @@ -221,16 +221,16 @@ else return attack_tendons(grab, I, user, grab.target_zone) -/decl/grab/normal/proc/attack_throat(var/obj/item/grab/grab, var/obj/item/W, mob/user) +/decl/grab/normal/proc/attack_throat(var/obj/item/grab/grab, var/obj/item/used_item, mob/user) var/mob/living/affecting = grab.get_affecting_mob() if(!affecting) return if(!user.check_intent(I_FLAG_HARM)) return 0 // Not trying to hurt them. - if(!W.has_edge() || !W.get_attack_force(user) || W.atom_damage_type != BRUTE) + if(!used_item.has_edge() || !used_item.get_attack_force(user) || used_item.atom_damage_type != BRUTE) return 0 //unsuitable weapon - user.visible_message("\The [user] begins to slit [affecting]'s throat with \the [W]!") + user.visible_message("\The [user] begins to slit [affecting]'s throat with \the [used_item]!") user.next_move = world.time + 20 //also should prevent user from triggering this repeatedly if(!do_after(user, 20*user.skill_delay_mult(SKILL_COMBAT) , progress = 0)) @@ -239,33 +239,33 @@ return 0 var/damage_mod = 1 - var/damage_flags = W.damage_flags() + var/damage_flags = used_item.damage_flags() //presumably, if they are wearing a helmet that stops pressure effects, then it probably covers the throat as well - var/force = W.expend_attack_force(user) + var/force = used_item.expend_attack_force(user) var/obj/item/clothing/head/helmet = affecting.get_equipped_item(slot_head_str) if(istype(helmet) && (helmet.body_parts_covered & SLOT_HEAD) && (helmet.item_flags & ITEM_FLAG_AIRTIGHT) && !isnull(helmet.max_pressure_protection)) var/datum/extension/armor/armor_datum = get_extension(helmet, /datum/extension/armor) if(armor_datum) - damage_mod -= armor_datum.get_blocked(BRUTE, damage_flags, W.armor_penetration, force*1.5) + damage_mod -= armor_datum.get_blocked(BRUTE, damage_flags, used_item.armor_penetration, force*1.5) var/total_damage = 0 for(var/i in 1 to 3) var/damage = min(force*1.5, 20)*damage_mod - affecting.apply_damage(damage, W.atom_damage_type, BP_HEAD, damage_flags, armor_pen = 100, used_weapon=W) + affecting.apply_damage(damage, used_item.atom_damage_type, BP_HEAD, damage_flags, armor_pen = 100, used_weapon=used_item) total_damage += damage if(total_damage) - user.visible_message("\The [user] slit [affecting]'s throat open with \the [W]!") + user.visible_message("\The [user] slit [affecting]'s throat open with \the [used_item]!") - if(W.hitsound) - playsound(affecting.loc, W.hitsound, 50, 1, -1) + if(used_item.hitsound) + playsound(affecting.loc, used_item.hitsound, 50, 1, -1) grab.last_action = world.time admin_attack_log(user, affecting, "Knifed their victim", "Was knifed", "knifed") return 1 -/decl/grab/normal/proc/attack_tendons(var/obj/item/grab/grab, var/obj/item/W, mob/user, var/target_zone) +/decl/grab/normal/proc/attack_tendons(var/obj/item/grab/grab, var/obj/item/used_item, mob/user, var/target_zone) var/mob/living/affecting = grab.get_affecting_mob() if(!affecting) return @@ -273,12 +273,12 @@ return if(!user.check_intent(I_FLAG_HARM)) return 0 // Not trying to hurt them. - if(!W.has_edge() || !W.expend_attack_force(user) || W.atom_damage_type != BRUTE) + if(!used_item.has_edge() || !used_item.expend_attack_force(user) || used_item.atom_damage_type != BRUTE) return 0 //unsuitable weapon var/obj/item/organ/external/O = grab.get_targeted_organ() if(!O || !(O.limb_flags & ORGAN_FLAG_HAS_TENDON) || (O.status & ORGAN_TENDON_CUT)) return FALSE - user.visible_message(SPAN_DANGER("\The [user] begins to cut \the [affecting]'s [O.tendon_name] with \the [W]!")) + user.visible_message(SPAN_DANGER("\The [user] begins to cut \the [affecting]'s [O.tendon_name] with \the [used_item]!")) user.next_move = world.time + 20 if(!do_after(user, 20, progress=0)) return 0 @@ -286,8 +286,8 @@ return 0 if(!O || !O.sever_tendon()) return 0 - user.visible_message(SPAN_DANGER("\The [user] cut \the [affecting]'s [O.tendon_name] with \the [W]!")) - if(W.hitsound) playsound(affecting.loc, W.hitsound, 50, 1, -1) + user.visible_message(SPAN_DANGER("\The [user] cut \the [affecting]'s [O.tendon_name] with \the [used_item]!")) + if(used_item.hitsound) playsound(affecting.loc, used_item.hitsound, 50, 1, -1) grab.last_action = world.time admin_attack_log(user, affecting, "hamstrung their victim", "was hamstrung", "hamstrung") return 1 diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index a1f9db81bd94..ced4a913ece7 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -11,18 +11,18 @@ equip_to_slot_if_possible(holding, slot) //This is a SAFE proc. Use this instead of equip_to_slot()! -//set del_on_fail to have it delete W if it fails to equip +//set del_on_fail to have it delete prop if it fails to equip //set disable_warning to disable the 'you are unable to equip that' warning. //unset redraw_mob to prevent the mob from being redrawn at the end. //set force to replace items in the slot and ignore blocking overwear -/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1, force = FALSE, delete_old_item = TRUE, ignore_equipped = FALSE) - if(!istype(W) || !slot) +/mob/proc/equip_to_slot_if_possible(obj/item/prop, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1, force = FALSE, delete_old_item = TRUE, ignore_equipped = FALSE) + if(!istype(prop) || !slot) return FALSE - . = (canUnEquip(W) && can_equip_anything_to_slot(slot) && has_organ_for_slot(slot) && W.mob_can_equip(src, slot, disable_warning, force, ignore_equipped = ignore_equipped)) + . = (canUnEquip(prop) && can_equip_anything_to_slot(slot) && has_organ_for_slot(slot) && prop.mob_can_equip(src, slot, disable_warning, force, ignore_equipped = ignore_equipped)) if(.) - equip_to_slot(W, slot, redraw_mob, delete_old_item = delete_old_item) //This proc should not ever fail. + equip_to_slot(prop, slot, redraw_mob, delete_old_item = delete_old_item) //This proc should not ever fail. else if(del_on_fail) - qdel(W) + qdel(prop) else if(!disable_warning) to_chat(src, SPAN_WARNING("You are unable to equip that.")) @@ -47,19 +47,19 @@ //This is an UNSAFE proc. It merely handles the actual job of equipping. All the checks on whether you can or can't eqip need to be done before! Use mob_can_equip() for that task. //In most cases you will want to use equip_to_slot_if_possible() -/mob/proc/equip_to_slot(obj/item/W, slot, redraw_mob = TRUE, delete_old_item = TRUE) +/mob/proc/equip_to_slot(obj/item/prop, slot, redraw_mob = TRUE, delete_old_item = TRUE) SHOULD_CALL_PARENT(TRUE) - if(!istype(W) || isnull(slot)) + if(!istype(prop) || isnull(slot)) return FALSE // Handle some special slots. if(slot == slot_in_backpack_str) - remove_from_mob(W) + remove_from_mob(prop) var/obj/item/back = get_equipped_item(slot_back_str) if(back) - W.forceMove(back) + prop.forceMove(back) else - W.dropInto(loc) + prop.dropInto(loc) return TRUE // Attempt to equip accessories if the slot is already blocked. @@ -75,51 +75,51 @@ check_slots -= slot check_slots.Insert(1, slot) - var/try_equip_slot = W.get_fallback_slot() + var/try_equip_slot = prop.get_fallback_slot() if(try_equip_slot && slot != try_equip_slot) check_slots -= try_equip_slot check_slots.Insert(1, try_equip_slot) for(var/slot_string in check_slots) var/obj/item/clothing/clothes = get_equipped_item(slot_string) - if(istype(clothes) && clothes.can_attach_accessory(W, src)) - clothes.attach_accessory(src, W) + if(istype(clothes) && clothes.can_attach_accessory(prop, src)) + clothes.attach_accessory(src, prop) attached = TRUE break if(attached) return TRUE - unequip(W) + unequip(prop) var/datum/inventory_slot/inv_slot = get_inventory_slot_datum(slot) if(inv_slot) - inv_slot.equipped(src, W, redraw_mob, delete_old_item) - if(W.action_button_name) + inv_slot.equipped(src, prop, redraw_mob, delete_old_item) + if(prop.action_button_name) update_action_buttons() return TRUE to_chat(src, SPAN_WARNING("You are trying to equip this item to an unsupported inventory slot. If possible, please write a ticket with steps to reproduce. Slot was: [slot]")) return FALSE //This is just a commonly used configuration for the equip_to_slot_if_possible() proc, used to equip people when the rounds tarts and when events happen and such. -/mob/proc/equip_to_slot_or_del(obj/item/W, slot) - return equip_to_slot_if_possible(W, slot, 1, 1, 0) +/mob/proc/equip_to_slot_or_del(obj/item/prop, slot) + return equip_to_slot_if_possible(prop, slot, 1, 1, 0) -/mob/proc/equip_to_slot_or_store_or_drop(obj/item/W, slot) - var/store = equip_to_slot_if_possible(W, slot, 0, 1, 0) +/mob/proc/equip_to_slot_or_store_or_drop(obj/item/prop, slot) + var/store = equip_to_slot_if_possible(prop, slot, 0, 1, 0) if(!store) - return equip_to_storage_or_drop(W) + return equip_to_storage_or_drop(prop) return store -//puts the item "W" into an appropriate slot in a human's inventory +//puts the item "prop" into an appropriate slot in a human's inventory //returns 0 if it cannot, 1 if successful -/mob/proc/equip_to_appropriate_slot(obj/item/W, var/skip_store = 0) - if(!istype(W)) +/mob/proc/equip_to_appropriate_slot(obj/item/prop, var/skip_store = 0) + if(!istype(prop)) return FALSE for(var/slot in get_inventory_slot_priorities()) if(skip_store) if(slot == slot_s_store_str || slot == slot_l_store_str || slot == slot_r_store_str) continue - if(equip_to_slot_if_possible(W, slot, del_on_fail=0, disable_warning=1, redraw_mob=1)) + if(equip_to_slot_if_possible(prop, slot, del_on_fail=0, disable_warning=1, redraw_mob=1)) return TRUE return FALSE @@ -176,39 +176,39 @@ /mob/proc/get_empty_hand_slots() return -/mob/proc/put_in_active_hand(var/obj/item/W) - . = equip_to_slot_if_possible(W, get_active_held_item_slot(), disable_warning = TRUE) +/mob/proc/put_in_active_hand(var/obj/item/prop) + . = equip_to_slot_if_possible(prop, get_active_held_item_slot(), disable_warning = TRUE) //Puts the item into (one of) our inactive hand(s) if possible. returns 1 on success. -/mob/proc/put_in_inactive_hand(var/obj/item/W) +/mob/proc/put_in_inactive_hand(var/obj/item/prop) var/active_slot = get_active_held_item_slot() for(var/slot in get_empty_hand_slots()) if(slot == active_slot) continue - . = equip_to_slot_if_possible(W, slot, disable_warning = TRUE) + . = equip_to_slot_if_possible(prop, slot, disable_warning = TRUE) if(.) break //Puts the item our active hand if possible. Failing that it tries our inactive hand. Returns 1 on success. //If both fail it drops it on the floor and returns 0. //This is probably the main one you need to know :) -/mob/proc/put_in_hands_or_del(var/obj/item/W) - . = put_in_hands(W) - if(!. && !QDELETED(W)) - qdel(W) +/mob/proc/put_in_hands_or_del(var/obj/item/prop) + . = put_in_hands(prop) + if(!. && !QDELETED(prop)) + qdel(prop) -/mob/proc/put_in_hands(var/obj/item/W) - if(!W) +/mob/proc/put_in_hands(var/obj/item/prop) + if(!prop) return FALSE - if(put_in_active_hand(W) || put_in_inactive_hand(W)) + if(put_in_active_hand(prop) || put_in_inactive_hand(prop)) return TRUE - drop_from_inventory(W) + drop_from_inventory(prop) return FALSE -/mob/proc/put_in_hands_or_store_or_drop(var/obj/item/W) - . = put_in_hands(W) +/mob/proc/put_in_hands_or_store_or_drop(var/obj/item/prop) + . = put_in_hands(prop) if(!.) - . = equip_to_storage_or_drop(W) + . = equip_to_storage_or_drop(prop) // Removes an item from inventory and places it in the target atom. // If canremove or other conditions need to be checked then use unEquip instead. @@ -249,13 +249,13 @@ As far as I can tell the proc exists so that mobs with different inventory slots can override the search through all the slots, without having to duplicate the rest of the item dropping. */ -/mob/proc/unequip(obj/W) +/mob/proc/unequip(obj/prop) SHOULD_CALL_PARENT(TRUE) - if(!istype(W)) + if(!istype(prop)) return FALSE - var/datum/inventory_slot/inv_slot = get_inventory_slot_datum(get_equipped_slot_for_item(W)) + var/datum/inventory_slot/inv_slot = get_inventory_slot_datum(get_equipped_slot_for_item(prop)) if(inv_slot) - return inv_slot.unequipped(src, W) + return inv_slot.unequipped(src, prop) return FALSE /mob/proc/isEquipped(obj/item/I) diff --git a/code/modules/mob/living/human/human_defense.dm b/code/modules/mob/living/human/human_defense.dm index 6b25c9c15803..1852dc2890c4 100644 --- a/code/modules/mob/living/human/human_defense.dm +++ b/code/modules/mob/living/human/human_defense.dm @@ -175,22 +175,22 @@ meteor_act animate_receive_damage(src) return 1 -/mob/living/human/proc/attack_bloody(obj/item/W, mob/attacker, var/effective_force, var/hit_zone) - if(W.atom_damage_type != BRUTE) +/mob/living/human/proc/attack_bloody(obj/item/used_item, mob/attacker, var/effective_force, var/hit_zone) + if(used_item.atom_damage_type != BRUTE) return if(!should_have_organ(BP_HEART)) return //make non-sharp low-force weapons less likely to be bloodied - if(W.is_sharp() || prob(effective_force*4)) - if(!(W.atom_flags & ATOM_FLAG_NO_BLOOD)) - W.add_blood(src) + if(used_item.is_sharp() || prob(effective_force*4)) + if(!(used_item.atom_flags & ATOM_FLAG_NO_BLOOD)) + used_item.add_blood(src) else return //if the weapon itself didn't get bloodied than it makes little sense for the target to be bloodied either //getting the weapon bloodied is easier than getting the target covered in blood, so run prob() again - if(prob(33 + W.is_sharp() * 10)) + if(prob(33 + used_item.is_sharp() * 10)) var/turf/location = loc if(istype(location) && location.simulated) location.add_blood(src) @@ -234,10 +234,10 @@ meteor_act C.add_blood(src) C.update_clothing_icon() -/mob/living/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked) +/mob/living/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/used_item, var/effective_force, var/dislocate_mult, var/blocked) if(!organ || organ.is_dislocated() || !(organ.limb_flags & ORGAN_FLAG_CAN_DISLOCATE) || blocked >= 100) return 0 - if(W.atom_damage_type != BRUTE) + if(used_item.atom_damage_type != BRUTE) return 0 //want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb diff --git a/code/modules/mob/living/human/human_organs.dm b/code/modules/mob/living/human/human_organs.dm index ef79bb493f7c..85c54cca6b24 100644 --- a/code/modules/mob/living/human/human_organs.dm +++ b/code/modules/mob/living/human/human_organs.dm @@ -201,9 +201,9 @@ SET_STATUS_MAX(src, STAT_STUN, 2) //Moving makes open wounds get infected much faster - for(var/datum/wound/W in E.wounds) - if (W.infection_check()) - W.germ_level += 1 + for(var/datum/wound/wound in E.wounds) + if (wound.infection_check()) + wound.germ_level += 1 /mob/living/human/proc/Check_Proppable_Object() for(var/turf/T as anything in RANGE_TURFS(src, 1)) //we only care for non-space turfs diff --git a/code/modules/mob/living/human/human_verbs.dm b/code/modules/mob/living/human/human_verbs.dm index 35812110f18b..7fc6f619c808 100644 --- a/code/modules/mob/living/human/human_verbs.dm +++ b/code/modules/mob/living/human/human_verbs.dm @@ -162,7 +162,7 @@ return var/num_doodles = 0 - for (var/obj/effect/decal/cleanable/blood/writing/W in T) + for (var/obj/effect/decal/cleanable/blood/writing/writing in T) num_doodles++ if (num_doodles > 4) to_chat(src, "There is no space to write on!") @@ -179,11 +179,11 @@ if (length(message) > max_length) message += "-" to_chat(src, "You ran out of blood to write with!") - var/obj/effect/decal/cleanable/blood/writing/W = new(T) - W.basecolor = (hand_blood_color) ? hand_blood_color : COLOR_BLOOD_HUMAN - W.update_icon() - W.message = message - W.add_fingerprint(src) + var/obj/effect/decal/cleanable/blood/writing/writing = new(T) + writing.basecolor = (hand_blood_color) ? hand_blood_color : COLOR_BLOOD_HUMAN + writing.update_icon() + writing.message = message + writing.add_fingerprint(src) /mob/living/human/proc/undislocate() set category = "Object" diff --git a/code/modules/mob/living/inventory.dm b/code/modules/mob/living/inventory.dm index cbfd9853c9cc..21b92392fbdd 100644 --- a/code/modules/mob/living/inventory.dm +++ b/code/modules/mob/living/inventory.dm @@ -195,12 +195,12 @@ if(!equip_to_appropriate_slot(I)) to_chat(src, SPAN_WARNING("You are unable to equip that.")) -/mob/living/proc/equip_in_one_of_slots(obj/item/W, list/slots, del_on_fail = 1) +/mob/living/proc/equip_in_one_of_slots(obj/item/prop, list/slots, del_on_fail = 1) for (var/slot in slots) - if (equip_to_slot_if_possible(W, slots[slot], del_on_fail = 0)) + if (equip_to_slot_if_possible(prop, slots[slot], del_on_fail = 0)) return slot if (del_on_fail) - qdel(W) + qdel(prop) return null //Same as get_covering_equipped_items, but using target zone instead of bodyparts flags diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 230f370eda24..b487dfc897c4 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -549,12 +549,12 @@ var/global/list/custom_ai_icons_by_ckey_and_name = list() camera_light_on = world.timeofday + 1 * 20 // Update the light every 2 seconds. -/mob/living/silicon/ai/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/aicard)) - var/obj/item/aicard/card = W +/mob/living/silicon/ai/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/aicard)) + var/obj/item/aicard/card = used_item card.grab_ai(src, user) - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) if(anchored) user.visible_message("\The [user] starts to unbolt \the [src] from the plating...") if(!do_after(user,40, src)) @@ -571,9 +571,9 @@ var/global/list/custom_ai_icons_by_ckey_and_name = list() user.visible_message("\The [user] finishes fastening down \the [src]!") anchored = TRUE return TRUE - if(try_stock_parts_install(W, user)) + if(try_stock_parts_install(used_item, user)) return TRUE - if(try_stock_parts_removal(W, user)) + if(try_stock_parts_removal(used_item, user)) return TRUE return ..() diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 49224c032f54..db413c265061 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -275,24 +275,24 @@ var/global/list/possible_say_verbs = list( icon_state = "[icon_state]-rest" //Overriding this will stop a number of headaches down the track. -/mob/living/silicon/pai/attackby(obj/item/W, mob/user) - var/obj/item/card/id/card = W.GetIdCard() +/mob/living/silicon/pai/attackby(obj/item/used_item, mob/user) + var/obj/item/card/id/card = used_item.GetIdCard() if(card && user.check_intent(I_FLAG_HELP)) var/list/new_access = card.GetAccess() idcard.access = new_access - visible_message("[user] slides [W] across [src].") + visible_message("[user] slides [used_item] across [src].") to_chat(src, SPAN_NOTICE("Your access has been updated!")) return FALSE // don't continue processing click callstack. - if(try_stock_parts_install(W, user)) + if(try_stock_parts_install(used_item, user)) return TRUE - if(try_stock_parts_removal(W, user)) + if(try_stock_parts_removal(used_item, user)) return TRUE - var/force = W.expend_attack_force(user) + var/force = used_item.expend_attack_force(user) if(force) - visible_message(SPAN_DANGER("[user] attacks [src] with [W]!")) + visible_message(SPAN_DANGER("[user] attacks [src] with [used_item]!")) take_damage(force) else - visible_message(SPAN_WARNING("[user] bonks [src] harmlessly with [W].")) + visible_message(SPAN_WARNING("[user] bonks [src] harmlessly with [used_item].")) spawn(1) if(stat != DEAD) fold() diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index c1b984b8a6d5..6397a7d91d5b 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -166,14 +166,14 @@ return //Drones cannot be upgraded with borg modules so we need to catch some items before they get used in ..(). -/mob/living/silicon/robot/drone/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/borg/upgrade)) - to_chat(user, "\The [src] is not compatible with \the [W].") +/mob/living/silicon/robot/drone/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/borg/upgrade)) + to_chat(user, "\The [src] is not compatible with \the [used_item].") return TRUE - else if(IS_CROWBAR(W) && !user.check_intent(I_FLAG_HARM)) + else if(IS_CROWBAR(used_item) && !user.check_intent(I_FLAG_HARM)) to_chat(user, "\The [src] is hermetically sealed. You can't open the case.") return TRUE - else if (istype(W, /obj/item/card/id)||istype(W, /obj/item/modular_computer)) + else if (istype(used_item, /obj/item/card/id)||istype(used_item, /obj/item/modular_computer)) if(stat == DEAD) if(!get_config_value(/decl/config/toggle/on/allow_drone_spawn) || emagged || should_be_dead()) //It's dead, Dave. to_chat(user, "The interface is fried, and a distressing burned smell wafts from the robot's interior. You're not rebooting this one.") diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index ff180bd1016f..bf450cb99a61 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -342,18 +342,19 @@ else continue - for(var/obj/W in T) + // TODO: Jesus Christ, use matter or the procs the decompiler nades use. + for(var/obj/thing in T) //Different classes of items give different commodities. - if(istype(W,/obj/item/trash/cigbutt)) + if(istype(thing,/obj/item/trash/cigbutt)) if(plastic) plastic.add_charge(500) - else if(istype(W,/obj/effect/spider/spiderling)) + else if(istype(thing,/obj/effect/spider/spiderling)) if(wood) wood.add_charge(2000) if(plastic) plastic.add_charge(2000) - else if(istype(W,/obj/item/light)) - var/obj/item/light/L = W + else if(istype(thing,/obj/item/light)) + var/obj/item/light/L = thing if(L.status >= 2) if(metal) metal.add_charge(250) @@ -361,42 +362,42 @@ glass.add_charge(250) else continue - else if(istype(W,/obj/item/remains/robot)) + else if(istype(thing,/obj/item/remains/robot)) if(metal) metal.add_charge(2000) if(plastic) plastic.add_charge(2000) if(glass) glass.add_charge(1000) - else if(istype(W,/obj/item/trash)) + else if(istype(thing,/obj/item/trash)) if(metal) metal.add_charge(1000) if(plastic) plastic.add_charge(3000) - else if(istype(W,/obj/effect/decal/cleanable/blood/gibs/robot)) + else if(istype(thing,/obj/effect/decal/cleanable/blood/gibs/robot)) if(metal) metal.add_charge(2000) if(glass) glass.add_charge(2000) - else if(istype(W,/obj/item/ammo_casing)) + else if(istype(thing,/obj/item/ammo_casing)) if(metal) metal.add_charge(1000) - else if(istype(W,/obj/item/shard/shrapnel)) + else if(istype(thing,/obj/item/shard/shrapnel)) if(metal) metal.add_charge(1000) - else if(istype(W,/obj/item/shard)) + else if(istype(thing,/obj/item/shard)) if(glass) glass.add_charge(1000) - else if(istype(W,/obj/item/food/grown)) + else if(istype(thing,/obj/item/food/grown)) if(wood) wood.add_charge(4000) - else if(istype(W,/obj/item/pipe)) + else if(istype(thing,/obj/item/pipe)) // This allows drones and engiborgs to clear pipe assemblies from floors. pass() else continue - qdel(W) + qdel(thing) grabbed_something = 1 if(grabbed_something) diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index da4adc553fd5..a867511c8a42 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -247,8 +247,8 @@ else to_chat(src, SPAN_NOTICE("You need to disable a module first!")) -/mob/living/silicon/robot/put_in_hands(var/obj/item/W) // No hands. - W.forceMove(get_turf(src)) +/mob/living/silicon/robot/put_in_hands(var/obj/item/prop) // No hands. + prop.forceMove(get_turf(src)) return 1 //Robots don't use inventory slots, so we need to override this. diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index a264865486ad..323d3d876e4b 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -425,41 +425,41 @@ spark_at(src, 5, holder=src) return 2 -/mob/living/silicon/robot/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/inducer) || istype(W, /obj/item/handcuffs)) +/mob/living/silicon/robot/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/inducer) || istype(used_item, /obj/item/handcuffs)) return TRUE if(opened) // Are they trying to insert something? for(var/V in components) var/datum/robot_component/C = components[V] - if(!C.installed && C.accepts_component(W)) - if(!user.try_unequip(W)) + if(!C.installed && C.accepts_component(used_item)) + if(!user.try_unequip(used_item)) return TRUE C.installed = 1 - C.wrapped = W + C.wrapped = used_item C.install() - W.forceMove(null) + used_item.forceMove(null) - var/obj/item/robot_parts/robot_component/WC = W + var/obj/item/robot_parts/robot_component/WC = used_item if(istype(WC)) C.brute_damage = WC.brute_damage C.burn_damage = WC.burn_damage - to_chat(user, "You install the [W.name].") + to_chat(user, "You install the [used_item.name].") return TRUE // If the robot is having something inserted which will remain inside it, self-inserting must be handled before exiting to avoid logic errors. Use the handle_selfinsert proc. - if(try_stock_parts_install(W, user)) + if(try_stock_parts_install(used_item, user)) return TRUE - if(IS_WELDER(W) && !user.check_intent(I_FLAG_HARM)) + if(IS_WELDER(used_item) && !user.check_intent(I_FLAG_HARM)) if (src == user) to_chat(user, "You lack the reach to be able to repair yourself.") return TRUE if (!get_damage(BRUTE)) to_chat(user, "Nothing to fix here!") return TRUE - var/obj/item/weldingtool/WT = W - if (WT.weld(0)) + var/obj/item/weldingtool/welder = used_item + if (welder.weld(0)) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) heal_damage(BRUTE, 30) add_fingerprint(user) @@ -468,18 +468,18 @@ to_chat(user, "Need more welding fuel!") return TRUE - else if(istype(W, /obj/item/stack/cable_coil) && (wiresexposed || isdrone(src))) + else if(istype(used_item, /obj/item/stack/cable_coil) && (wiresexposed || isdrone(src))) if (!get_damage(BURN)) to_chat(user, "Nothing to fix here!") return TRUE - var/obj/item/stack/cable_coil/coil = W + var/obj/item/stack/cable_coil/coil = used_item if (coil.use(1)) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) heal_damage(BURN, 30) user.visible_message(SPAN_NOTICE("\The [user] has fixed some of the burnt wires on \the [src]!")) return TRUE - else if(IS_CROWBAR(W) && !user.check_intent(I_FLAG_HARM)) // crowbar means open or close the cover - we all know what a crowbar is by now + else if(IS_CROWBAR(used_item) && !user.check_intent(I_FLAG_HARM)) // crowbar means open or close the cover - we all know what a crowbar is by now if(opened) if(cell) user.visible_message( @@ -543,50 +543,50 @@ opened = 1 update_icon() return TRUE - else if (istype(W, /obj/item/cell) && opened) // trying to put a cell inside + else if (istype(used_item, /obj/item/cell) && opened) // trying to put a cell inside var/datum/robot_component/C = components["power cell"] if(wiresexposed) to_chat(user, "Close the panel first.") else if(cell) to_chat(user, "There is a power cell already installed.") - else if(W.w_class != ITEM_SIZE_NORMAL) - to_chat(user, "\The [W] is too [W.w_class < ITEM_SIZE_NORMAL? "small" : "large"] to fit here.") - else if(user.try_unequip(W, src)) - cell = W - handle_selfinsert(W, user) //Just in case. + else if(used_item.w_class != ITEM_SIZE_NORMAL) + to_chat(user, "\The [used_item] is too [used_item.w_class < ITEM_SIZE_NORMAL? "small" : "large"] to fit here.") + else if(user.try_unequip(used_item, src)) + cell = used_item + handle_selfinsert(used_item, user) //Just in case. to_chat(user, "You insert the power cell.") C.installed = 1 - C.wrapped = W + C.wrapped = used_item C.install() // This means that removing and replacing a power cell will repair the mount. C.brute_damage = 0 C.burn_damage = 0 return TRUE - else if(IS_WIRECUTTER(W) || IS_MULTITOOL(W)) + else if(IS_WIRECUTTER(used_item) || IS_MULTITOOL(used_item)) if (wiresexposed) wires.Interact(user) else to_chat(user, "You can't reach the wiring.") return TRUE - else if(IS_SCREWDRIVER(W) && opened && !cell) // haxing + else if(IS_SCREWDRIVER(used_item) && opened && !cell) // haxing wiresexposed = !wiresexposed to_chat(user, "The wires have been [wiresexposed ? "exposed" : "unexposed"].") update_icon() return TRUE - else if(IS_SCREWDRIVER(W) && opened && cell) // radio + else if(IS_SCREWDRIVER(used_item) && opened && cell) // radio if(silicon_radio) - silicon_radio.attackby(W,user)//Push it to the radio to let it handle everything + silicon_radio.attackby(used_item,user)//Push it to the radio to let it handle everything else to_chat(user, "Unable to locate a radio.") update_icon() return TRUE - else if(istype(W, /obj/item/encryptionkey/) && opened) + else if(istype(used_item, /obj/item/encryptionkey/) && opened) if(silicon_radio)//sanityyyyyy - silicon_radio.attackby(W,user)//GTFO, you have your own procs + silicon_radio.attackby(used_item,user)//GTFO, you have your own procs else to_chat(user, "Unable to locate a radio.") return TRUE - else if (istype(W, /obj/item/card/id)||istype(W, /obj/item/modular_computer)||istype(W, /obj/item/card/robot)) // trying to unlock the interface with an ID card + else if (istype(used_item, /obj/item/card/id)||istype(used_item, /obj/item/modular_computer)||istype(used_item, /obj/item/card/robot)) // trying to unlock the interface with an ID card if(emagged)//still allow them to open the cover to_chat(user, "The interface seems slightly damaged.") if(opened) @@ -599,8 +599,8 @@ else to_chat(user, "Access denied.") return TRUE - else if(istype(W, /obj/item/borg/upgrade)) - var/obj/item/borg/upgrade/U = W + else if(istype(used_item, /obj/item/borg/upgrade)) + var/obj/item/borg/upgrade/U = used_item if(!opened) to_chat(user, "You must access [src]'s internals!") else if(!src.module && U.require_module) @@ -612,20 +612,20 @@ if(!user.try_unequip(U, src)) return TRUE to_chat(user, "You apply the upgrade to [src]!") - handle_selfinsert(W, user) + handle_selfinsert(used_item, user) else to_chat(user, "Upgrade error!") return TRUE - if(!(istype(W, /obj/item/robotanalyzer) || istype(W, /obj/item/scanner/health)) && !user.check_intent(I_FLAG_HELP) && W.expend_attack_force(user)) + if(!(istype(used_item, /obj/item/robotanalyzer) || istype(used_item, /obj/item/scanner/health)) && !user.check_intent(I_FLAG_HELP) && used_item.expend_attack_force(user)) spark_at(src, 5, holder=src) return ..() -/mob/living/silicon/robot/proc/handle_selfinsert(obj/item/W, mob/user) +/mob/living/silicon/robot/proc/handle_selfinsert(obj/item/used_item, mob/user) if ((user == src) && istype(get_active_held_item(),/obj/item/gripper)) var/obj/item/gripper/H = get_active_held_item() - if (W.loc == H) //if this triggers something has gone very wrong, and it's safest to abort + if (used_item.loc == H) //if this triggers something has gone very wrong, and it's safest to abort return - else if (H.wrapped == W) + else if (H.wrapped == used_item) H.wrapped = null /mob/living/silicon/robot/try_awaken(mob/user) @@ -1041,12 +1041,12 @@ chassis.dismantled_from(src) qdel(src) -/mob/living/silicon/robot/try_stock_parts_install(obj/item/stock_parts/W, mob/user) +/mob/living/silicon/robot/try_stock_parts_install(obj/item/stock_parts/used_item, mob/user) if(!opened) return . = ..() if(.) - handle_selfinsert(W, user) + handle_selfinsert(used_item, user) recalculate_synth_capacities() /mob/living/silicon/robot/get_admin_job_string() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index a402c51add3b..a8a18aa126fc 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -363,15 +363,15 @@ return os.get_network() -/mob/living/silicon/proc/try_stock_parts_install(obj/item/stock_parts/W, mob/user) - if(istype(W) && user.try_unequip(W)) - W.forceMove(src) - stock_parts += W - to_chat(user, "You install the [W.name].") +/mob/living/silicon/proc/try_stock_parts_install(obj/item/stock_parts/used_item, mob/user) + if(istype(used_item) && user.try_unequip(used_item)) + used_item.forceMove(src) + stock_parts += used_item + to_chat(user, "You install the [used_item.name].") return TRUE -/mob/living/silicon/proc/try_stock_parts_removal(obj/item/W, mob/user) - if(!IS_CROWBAR(W) || user.check_intent(I_FLAG_HARM)) +/mob/living/silicon/proc/try_stock_parts_removal(obj/item/used_item, mob/user) + if(!IS_CROWBAR(used_item) || user.check_intent(I_FLAG_HARM)) return if(!length(stock_parts)) to_chat(user, SPAN_WARNING("There are no parts in \the [src] left to remove.")) diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm b/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm index b2e49edc2b09..5d2dd604740f 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spiders/ai_nurse.dm @@ -34,8 +34,8 @@ return //second, spin a sticky spiderweb on this tile - var/obj/effect/spider/stickyweb/W = locate() in get_turf(body) - if(!W) + var/obj/effect/spider/stickyweb/web = locate() in get_turf(body) + if(!web) set_activity(AI_ACTIVITY_BUILDING) body.visible_message(SPAN_NOTICE("\The [body] begins to secrete a sticky substance.")) pause() diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 21e905f85a66..fa65282b349a 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -1,8 +1,8 @@ /mob/living/human/proc/monkeyize() if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return - for(var/obj/item/W in get_contained_external_atoms()) - drop_from_inventory(W) + for(var/obj/item/thing in get_contained_external_atoms()) + drop_from_inventory(thing) try_refresh_visible_overlays() ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) set_status_condition(STAT_STUN, 1) @@ -26,8 +26,8 @@ gib() return - for(var/obj/item/W in src) - drop_from_inventory(W) + for(var/obj/item/thing in src) + drop_from_inventory(thing) change_species(species.primitive_form) to_chat(src, "You are now [species.name]. ") @@ -53,8 +53,8 @@ return for(var/t in get_external_organs()) qdel(t) - for(var/obj/item/W in src) - drop_from_inventory(W) + for(var/obj/item/thing in src) + drop_from_inventory(thing) ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) icon = null set_invisibility(INVISIBILITY_ABSTRACT) @@ -106,8 +106,8 @@ if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return QDEL_NULL_LIST(worn_underwear) - for(var/obj/item/W in src) - drop_from_inventory(W) + for(var/obj/item/thing in src) + drop_from_inventory(thing) try_refresh_visible_overlays() ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) icon = null @@ -141,8 +141,8 @@ /mob/living/human/proc/corgize() if (HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return - for(var/obj/item/W in src) - drop_from_inventory(W) + for(var/obj/item/thing in src) + drop_from_inventory(thing) try_refresh_visible_overlays() ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) icon = null @@ -169,8 +169,8 @@ if(HAS_TRANSFORMATION_MOVEMENT_HANDLER(src)) return - for(var/obj/item/W in src) - drop_from_inventory(W) + for(var/obj/item/thing in src) + drop_from_inventory(thing) try_refresh_visible_overlays() ADD_TRANSFORMATION_MOVEMENT_HANDLER(src) diff --git a/code/modules/mob_holder/_holder.dm b/code/modules/mob_holder/_holder.dm index 18a1f358dd90..150f526f489b 100644 --- a/code/modules/mob_holder/_holder.dm +++ b/code/modules/mob_holder/_holder.dm @@ -151,9 +151,9 @@ update_icon() update_held_icon() -/obj/item/holder/attackby(obj/item/W, mob/user) +/obj/item/holder/attackby(obj/item/used_item, mob/user) for(var/mob/M in src.contents) - . = M.attackby(W,user) + . = M.attackby(used_item,user) if(.) return return FALSE \ No newline at end of file diff --git a/code/modules/modular_computers/file_system/programs/security/digitalwarrant.dm b/code/modules/modular_computers/file_system/programs/security/digitalwarrant.dm index 28c21f6b4217..f96c61e63609 100644 --- a/code/modules/modular_computers/file_system/programs/security/digitalwarrant.dm +++ b/code/modules/modular_computers/file_system/programs/security/digitalwarrant.dm @@ -24,15 +24,15 @@ var/global/list/all_warrants if(network) return network.get_all_files_of_type(/datum/computer_file/report/warrant, accesses = accesses) -/datum/nano_module/program/proc/remove_warrant(datum/computer_file/report/warrant/W, list/accesses, mob/user) +/datum/nano_module/program/proc/remove_warrant(datum/computer_file/report/warrant/warrant, list/accesses, mob/user) var/datum/computer_network/network = program?.computer?.get_network() if(network) - return network.remove_file(W, accesses, user) + return network.remove_file(warrant, accesses, user) -/datum/nano_module/program/proc/save_warrant(datum/computer_file/report/warrant/W, list/accesses, mob/user) +/datum/nano_module/program/proc/save_warrant(datum/computer_file/report/warrant/warrant, list/accesses, mob/user) var/datum/computer_network/network = program?.computer?.get_network() if(network) - return network.store_file(W, OS_DOCUMENTS_DIR, TRUE, accesses = accesses, user = user) + return network.store_file(warrant, OS_DOCUMENTS_DIR, TRUE, accesses = accesses, user = user) /datum/nano_module/program/digitalwarrant/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = global.default_topic_state) var/list/data = host.initial_data() @@ -43,8 +43,8 @@ var/global/list/all_warrants data["details"] = active.generate_nano_data(accesses, user) else var/list/avail_warrants = get_warrants(accesses, user) - for(var/datum/computer_file/report/warrant/W in avail_warrants) - LAZYADD(data[W.get_category()], W.get_nano_summary()) + for(var/datum/computer_file/report/warrant/warrant in avail_warrants) + LAZYADD(data[warrant.get_category()], warrant.get_nano_summary()) ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) if (!ui) @@ -61,33 +61,33 @@ var/global/list/all_warrants if(href_list["editwarrant"]) . = 1 - for(var/datum/computer_file/report/warrant/W in avail_warrants) - if(W.uid == text2num(href_list["editwarrant"])) - active = W + for(var/datum/computer_file/report/warrant/warrant in avail_warrants) + if(warrant.uid == text2num(href_list["editwarrant"])) + active = warrant break if(href_list["sendtoarchive"]) . = 1 - for(var/datum/computer_file/report/warrant/W in avail_warrants) - if(W.uid == text2num(href_list["sendtoarchive"])) - W.archived = TRUE + for(var/datum/computer_file/report/warrant/warrant in avail_warrants) + if(warrant.uid == text2num(href_list["sendtoarchive"])) + warrant.archived = TRUE break if(href_list["restore"]) . = 1 - for(var/datum/computer_file/report/warrant/W in avail_warrants) - if(W.uid == text2num(href_list["restore"])) - W.archived = FALSE + for(var/datum/computer_file/report/warrant/warrant in avail_warrants) + if(warrant.uid == text2num(href_list["restore"])) + warrant.archived = FALSE break if(href_list["addwarrant"]) . = 1 - var/datum/computer_file/report/warrant/W + var/datum/computer_file/report/warrant/warrant if(href_list["addwarrant"] == "arrest") - W = new /datum/computer_file/report/warrant/arrest + warrant = new /datum/computer_file/report/warrant/arrest else - W = new /datum/computer_file/report/warrant/search - active = W + warrant = new /datum/computer_file/report/warrant/search + active = warrant if(href_list["savewarrant"]) . = 1 @@ -104,9 +104,9 @@ var/global/list/all_warrants if(href_list["deletewarrant"]) . = 1 if(!active) - for(var/datum/computer_file/report/warrant/W in avail_warrants) - if(W.uid == text2num(href_list["deletewarrant"])) - active = W + for(var/datum/computer_file/report/warrant/warrant in avail_warrants) + if(warrant.uid == text2num(href_list["deletewarrant"])) + active = warrant break var/success = remove_warrant(active, accesses, usr) if(success != OS_FILE_SUCCESS) diff --git a/code/modules/modular_computers/hardware/_hardware.dm b/code/modules/modular_computers/hardware/_hardware.dm index 64fc7f971be5..2d87a04d59ad 100644 --- a/code/modules/modular_computers/hardware/_hardware.dm +++ b/code/modules/modular_computers/hardware/_hardware.dm @@ -10,9 +10,9 @@ var/usage_flags = PROGRAM_ALL var/external_slot // Whether attackby will be passed on it even with a closed panel -/obj/item/stock_parts/computer/attackby(var/obj/item/W, var/mob/user) +/obj/item/stock_parts/computer/attackby(var/obj/item/used_item, var/mob/user) // Multitool. Runs diagnostics - if(IS_MULTITOOL(W)) + if(IS_MULTITOOL(used_item)) to_chat(user, "***** DIAGNOSTICS REPORT *****") to_chat(user, jointext(diagnostics(), "\n")) to_chat(user, "******************************") diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index 72345bf49394..8550bb17b542 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -21,16 +21,16 @@ power_usage = power_usage_occupied ..() -/obj/item/stock_parts/computer/ai_slot/attackby(var/obj/item/W, var/mob/user) - if(istype(W, /obj/item/aicard)) +/obj/item/stock_parts/computer/ai_slot/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/aicard)) if(stored_card) to_chat(user, "\The [src] is already occupied.") return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - do_insert_ai(user, W) + do_insert_ai(user, used_item) return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) to_chat(user, "You manually remove \the [stored_card] from \the [src].") do_eject_ai(user) return TRUE diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index cb62d1049e90..2d9c574d3a08 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -1,7 +1,7 @@ /obj/item/stock_parts/computer/card_slot name = "RFID card slot" desc = "Slot that allows this computer to write data on RFID cards. Necessary for some programs to run properly." - power_usage = 10 //W + power_usage = 10 // W critical = 0 icon_state = "cardreader" hardware_size = 1 diff --git a/code/modules/modular_computers/hardware/charge_stick_slot.dm b/code/modules/modular_computers/hardware/charge_stick_slot.dm index 451696ff85d7..d7988d6298b4 100644 --- a/code/modules/modular_computers/hardware/charge_stick_slot.dm +++ b/code/modules/modular_computers/hardware/charge_stick_slot.dm @@ -1,7 +1,7 @@ /obj/item/stock_parts/computer/charge_stick_slot name = "charge-stick slot" desc = "Slot that allows this computer to pay for transactions using an inserted charge-stick." - power_usage = 10 //W + power_usage = 10 // W critical = 0 icon_state = "cardreader" hardware_size = 1 diff --git a/code/modules/modular_computers/hardware/disk_slot.dm b/code/modules/modular_computers/hardware/disk_slot.dm index cae1cb5fccf1..1cb1a6f7d93b 100644 --- a/code/modules/modular_computers/hardware/disk_slot.dm +++ b/code/modules/modular_computers/hardware/disk_slot.dm @@ -1,7 +1,7 @@ /obj/item/stock_parts/computer/data_disk_drive name = "data disk slot" desc = "Slot that allows this computer to accept data disks." - power_usage = 10 //W + power_usage = 10 // W critical = 0 icon_state = "cardreader" hardware_size = 1 diff --git a/code/modules/modular_computers/hardware/drive_slot.dm b/code/modules/modular_computers/hardware/drive_slot.dm index 8da6019f7744..0dec813de9e6 100644 --- a/code/modules/modular_computers/hardware/drive_slot.dm +++ b/code/modules/modular_computers/hardware/drive_slot.dm @@ -1,7 +1,7 @@ /obj/item/stock_parts/computer/drive_slot name = "removable drive slot" desc = "Slot that allows this computer to accept removable drives." - power_usage = 10 //W + power_usage = 10 // W critical = 0 icon_state = "cardreader" hardware_size = 1 diff --git a/code/modules/modular_computers/hardware/nano_printer.dm b/code/modules/modular_computers/hardware/nano_printer.dm index 6495b77d0ed2..4932c7264d83 100644 --- a/code/modules/modular_computers/hardware/nano_printer.dm +++ b/code/modules/modular_computers/hardware/nano_printer.dm @@ -38,20 +38,20 @@ return 1 // TODO: unify with /obj/item/stock_parts/printer somehow? -/obj/item/stock_parts/computer/nano_printer/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/paper)) +/obj/item/stock_parts/computer/nano_printer/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/paper)) if(stored_paper >= max_paper) - to_chat(user, "You try to add \the [W] into \the [src], but its paper bin is full.") + to_chat(user, "You try to add \the [used_item] into \the [src], but its paper bin is full.") return TRUE - to_chat(user, "You insert \the [W] into [src].") - qdel(W) + to_chat(user, "You insert \the [used_item] into [src].") + qdel(used_item) stored_paper++ - else if(istype(W, /obj/item/paper_bundle)) - var/obj/item/paper_bundle/B = W + else if(istype(used_item, /obj/item/paper_bundle)) + var/obj/item/paper_bundle/B = used_item var/num_of_pages_added = 0 if(stored_paper >= max_paper) - to_chat(user, "You try to add \the [W] into \the [src], but its paper bin is full.") + to_chat(user, "You try to add \the [used_item] into \the [src], but its paper bin is full.") return TRUE if(!B.is_blank()) if(user) @@ -74,6 +74,6 @@ qdel(B) else //if at least two items remain, just update the bundle icon B.update_icon() - to_chat(user, "You add [num_of_pages_added] papers from \the [W] into \the [src].") + to_chat(user, "You add [num_of_pages_added] papers from \the [used_item] into \the [src].") return TRUE return ..() diff --git a/code/modules/modular_computers/hardware/scanners/scanner.dm b/code/modules/modular_computers/hardware/scanners/scanner.dm index ea42566d7a0a..9f7c3fdb1f19 100644 --- a/code/modules/modular_computers/hardware/scanners/scanner.dm +++ b/code/modules/modular_computers/hardware/scanners/scanner.dm @@ -55,8 +55,8 @@ /obj/item/stock_parts/computer/scanner/proc/do_on_afterattack(mob/user, atom/target, proximity) // TODO: Revisit to see if we can make do_on_attackby return a bool so that normal afterattack can run. -/obj/item/stock_parts/computer/scanner/attackby(obj/W, mob/user) - do_on_attackby(user, W) +/obj/item/stock_parts/computer/scanner/attackby(obj/item/used_item, mob/user) + do_on_attackby(user, used_item) return TRUE /obj/item/stock_parts/computer/scanner/proc/do_on_attackby(mob/user, atom/target) diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm index 7fa5849e54f8..5e280ffe60b4 100644 --- a/code/modules/multiz/zmimic/mimic_movable.dm +++ b/code/modules/multiz/zmimic/mimic_movable.dm @@ -146,7 +146,7 @@ return ..() -/atom/movable/openspace/mimic/attackby(obj/item/W, mob/user) +/atom/movable/openspace/mimic/attackby(obj/item/used_item, mob/user) to_chat(user, SPAN_NOTICE("\The [src] is too far away.")) return TRUE @@ -195,8 +195,8 @@ mouse_opacity = MOUSE_OPACITY_UNCLICKABLE z_flags = ZMM_IGNORE // Only one of these should ever be visible at a time, the mimic logic will handle that. -/atom/movable/openspace/turf_proxy/attackby(obj/item/W, mob/user) - return loc.attackby(W, user) +/atom/movable/openspace/turf_proxy/attackby(obj/item/used_item, mob/user) + return loc.attackby(used_item, user) /atom/movable/openspace/turf_proxy/attack_hand(mob/user as mob) SHOULD_CALL_PARENT(FALSE) @@ -223,8 +223,8 @@ ASSERT(isturf(loc)) delegate = loc:below -/atom/movable/openspace/turf_mimic/attackby(obj/item/W, mob/user) - return loc.attackby(W, user) +/atom/movable/openspace/turf_mimic/attackby(obj/item/used_item, mob/user) + return loc.attackby(used_item, user) /atom/movable/openspace/turf_mimic/attack_hand(mob/user as mob) SHOULD_CALL_PARENT(FALSE) diff --git a/code/modules/organs/external/_external_damage.dm b/code/modules/organs/external/_external_damage.dm index ee09b245d2fe..6ca145d43361 100644 --- a/code/modules/organs/external/_external_damage.dm +++ b/code/modules/organs/external/_external_damage.dm @@ -96,11 +96,11 @@ //Disturb treated burns if(brute > 5) var/disturbed = 0 - for(var/datum/wound/burn/W in wounds) - if((W.disinfected || W.salved) && prob(brute + W.damage)) - W.disinfected = 0 - W.salved = 0 - disturbed += W.damage + for(var/datum/wound/burn/wound in wounds) + if((wound.disinfected || wound.salved) && prob(brute + wound.damage)) + wound.disinfected = 0 + wound.salved = 0 + disturbed += wound.damage if(disturbed) to_chat(owner,"Ow! Your burns were disturbed.") add_pain(0.5*disturbed) @@ -177,15 +177,15 @@ return //Heal damage on the individual wounds - for(var/datum/wound/W in wounds) + for(var/datum/wound/wound in wounds) if(brute == 0 && burn == 0) break // heal brute damage - if(W.damage_type == BURN) - burn = W.heal_damage(burn) + if(wound.damage_type == BURN) + burn = wound.heal_damage(burn) else - brute = W.heal_damage(brute) + brute = wound.heal_damage(brute) if(internal) status &= ~ORGAN_BROKEN diff --git a/code/modules/organs/external/diagnostics.dm b/code/modules/organs/external/diagnostics.dm index 973c506b9fcd..b78c313b71c7 100644 --- a/code/modules/organs/external/diagnostics.dm +++ b/code/modules/organs/external/diagnostics.dm @@ -27,28 +27,28 @@ flavor_text += "a tear at the [amputation_point] so severe that it hangs by a scrap of flesh" var/list/wound_descriptors = list() - for(var/datum/wound/W in wounds) - var/this_wound_desc = W.desc - if(W.damage_type == BURN && W.salved) + for(var/datum/wound/wound in wounds) + var/this_wound_desc = wound.desc + if(wound.damage_type == BURN && wound.salved) this_wound_desc = "salved [this_wound_desc]" - if(W.bleeding()) - if(W.wound_damage() > W.bleed_threshold) + if(wound.bleeding()) + if(wound.wound_damage() > wound.bleed_threshold) this_wound_desc = "bleeding [this_wound_desc]" else this_wound_desc = "bleeding [this_wound_desc]" - else if(W.bandaged) + else if(wound.bandaged) this_wound_desc = "bandaged [this_wound_desc]" - if(W.germ_level > 600) + if(wound.germ_level > 600) this_wound_desc = "badly infected [this_wound_desc]" - else if(W.germ_level > 330) + else if(wound.germ_level > 330) this_wound_desc = "lightly infected [this_wound_desc]" if(wound_descriptors[this_wound_desc]) - wound_descriptors[this_wound_desc] += W.amount + wound_descriptors[this_wound_desc] += wound.amount else - wound_descriptors[this_wound_desc] = W.amount + wound_descriptors[this_wound_desc] = wound.amount if(how_open() >= SURGERY_RETRACTED) var/bone = encased ? encased : "bone" diff --git a/code/modules/organs/internal/cell.dm b/code/modules/organs/internal/cell.dm index 4087194c2a6b..e778d84defe7 100644 --- a/code/modules/organs/internal/cell.dm +++ b/code/modules/organs/internal/cell.dm @@ -62,8 +62,8 @@ // TODO: Make this use the cell extension instead? // Or have it grant a subtype of cell extension to the mob, maybe? -/obj/item/organ/internal/cell/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/organ/internal/cell/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) if(open) open = FALSE to_chat(user, SPAN_NOTICE("You screw the battery panel in place.")) @@ -72,17 +72,17 @@ to_chat(user, SPAN_NOTICE("You unscrew the battery panel.")) return TRUE else if(open) - if(IS_CROWBAR(W)) + if(IS_CROWBAR(used_item)) if(cell) user.put_in_hands(cell) to_chat(user, SPAN_NOTICE("You remove \the [cell] from \the [src].")) cell = null return TRUE - else if (istype(W, /obj/item/cell)) + else if (istype(used_item, /obj/item/cell)) if(cell) to_chat(user, SPAN_WARNING("There is a power cell already installed.")) - else if(user.try_unequip(W, src)) - cell = W + else if(user.try_unequip(used_item, src)) + cell = used_item to_chat(user, SPAN_NOTICE("You insert \the [cell].")) return TRUE return ..() diff --git a/code/modules/organs/internal/heart.dm b/code/modules/organs/internal/heart.dm index 785a2da44382..371c957ffc26 100644 --- a/code/modules/organs/internal/heart.dm +++ b/code/modules/organs/internal/heart.dm @@ -129,22 +129,22 @@ var/open_wound if(temp.status & ORGAN_BLEEDING) - for(var/datum/wound/W in temp.wounds) + for(var/datum/wound/wound in temp.wounds) - if(!open_wound && (W.damage_type == CUT || W.damage_type == PIERCE) && W.damage && !W.is_treated()) + if(!open_wound && (wound.damage_type == CUT || wound.damage_type == PIERCE) && wound.damage && !wound.is_treated()) open_wound = TRUE - if(W.bleeding()) + if(wound.bleeding()) if(temp.applied_pressure) if(ishuman(temp.applied_pressure)) var/mob/living/human/H = temp.applied_pressure H.bloody_hands(src, 0) //somehow you can apply pressure to every wound on the organ at the same time //you're basically forced to do nothing at all, so let's make it pretty effective - var/min_eff_damage = max(0, W.damage - 10) / 6 //still want a little bit to drip out, for effect - blood_max += max(min_eff_damage, W.damage - 30) / 40 + var/min_eff_damage = max(0, wound.damage - 10) / 6 //still want a little bit to drip out, for effect + blood_max += max(min_eff_damage, wound.damage - 30) / 40 else - blood_max += W.damage / 40 + blood_max += wound.damage / 40 if(temp.status & ORGAN_ARTERY_CUT) var/bleed_amount = floor((owner.vessel.total_volume / (temp.applied_pressure || !open_wound ? 400 : 250))*temp.arterial_bleed_severity) diff --git a/code/modules/overmap/contacts/_contacts.dm b/code/modules/overmap/contacts/_contacts.dm index bde9a41d1717..069f914a4d9c 100644 --- a/code/modules/overmap/contacts/_contacts.dm +++ b/code/modules/overmap/contacts/_contacts.dm @@ -68,8 +68,8 @@ return var/list/showing = owner.linked?.navigation_viewers || owner.viewers if(length(showing)) - for(var/weakref/W in showing) - var/mob/M = W.resolve() + for(var/weakref/viewer_ref in showing) + var/mob/M = viewer_ref.resolve() if(istype(M) && M.client) M.client.images |= images @@ -78,8 +78,8 @@ return var/list/showing = owner.linked?.navigation_viewers || owner.viewers if(length(showing)) - for(var/weakref/W in showing) - var/mob/M = W.resolve() + for(var/weakref/viewer_ref in showing) + var/mob/M = viewer_ref.resolve() if(istype(M) && M.client) M.client.images -= images diff --git a/code/modules/overmap/ftl_shunt/core.dm b/code/modules/overmap/ftl_shunt/core.dm index a6e6e567046e..f01dcb55a319 100644 --- a/code/modules/overmap/ftl_shunt/core.dm +++ b/code/modules/overmap/ftl_shunt/core.dm @@ -279,8 +279,8 @@ if(O) var/destination = locate(shunt_x, shunt_y, O.z) var/jumpdist = get_dist(get_turf(ftl_computer.linked), destination) - var/obj/effect/portal/wormhole/W = new(destination) //Generate a wormhole effect on overmap to give some indication that something is about to happen. - QDEL_IN(W, 6 SECONDS) + var/obj/effect/portal/wormhole/wormhole = new(destination) //Generate a wormhole effect on overmap to give some indication that something is about to happen. + QDEL_IN(wormhole, 6 SECONDS) addtimer(CALLBACK(src, PROC_REF(do_shunt), shunt_x, shunt_y, jumpdist, destination), 6 SECONDS) jumping = TRUE update_icon() diff --git a/code/modules/overmap/internet/internet_uplink.dm b/code/modules/overmap/internet/internet_uplink.dm index cd38e4509feb..c79bec98fc93 100644 --- a/code/modules/overmap/internet/internet_uplink.dm +++ b/code/modules/overmap/internet/internet_uplink.dm @@ -39,8 +39,8 @@ var/global/list/internet_uplinks = list() global.internet_uplinks -= src . = ..() -/obj/machinery/internet_uplink/attackby(var/obj/item/W, var/mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/internet_uplink/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/uplink = get_extension(src, /datum/extension/local_network_member) uplink.get_new_tag(user) return TRUE @@ -173,8 +173,8 @@ var/global/list/internet_uplinks = list() var/datum/extension/local_network_member/uplink_comp = get_extension(src, /datum/extension/local_network_member) uplink_comp.set_tag(null, initial_id_tag) -/obj/machinery/computer/internet_uplink/attackby(var/obj/item/W, var/mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/computer/internet_uplink/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/uplink_comp = get_extension(src, /datum/extension/local_network_member) uplink_comp.get_new_tag(user) return TRUE diff --git a/code/modules/overmap/sectors.dm b/code/modules/overmap/sectors.dm index 9ffc9a1bf3c4..891382ad00ac 100644 --- a/code/modules/overmap/sectors.dm +++ b/code/modules/overmap/sectors.dm @@ -244,8 +244,8 @@ var/global/list/known_overmap_sectors for(var/thing in get_linked_machines_of_type(/obj/machinery/computer/ship)) var/obj/machinery/computer/ship/machine = thing if(machine.z in map_z) - for(var/weakref/W in machine.viewers) - var/mob/M = W.resolve() + for(var/weakref/viewer_ref in machine.viewers) + var/mob/M = viewer_ref.resolve() if(istype(M) && M.client) M.client.default_pixel_x = pixel_x M.client.default_pixel_y = pixel_y diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm index b5ce7950effc..33aff495d218 100644 --- a/code/modules/overmap/ships/computers/ship.dm +++ b/code/modules/overmap/ships/computers/ship.dm @@ -113,10 +113,10 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov /obj/machinery/computer/ship/sensors/Destroy() sensor_ref = null if(LAZYLEN(viewers)) - for(var/weakref/W in viewers) - var/M = W.resolve() + for(var/weakref/viewer_ref in viewers) + var/M = viewer_ref.resolve() if(M) INVOKE_ASYNC(PROC_REF(unlook), M) if(linked) - LAZYREMOVE(linked.navigation_viewers, W) + LAZYREMOVE(linked.navigation_viewers, viewer_ref) . = ..() diff --git a/code/modules/paperwork/clipboard.dm b/code/modules/paperwork/clipboard.dm index 4b0f3ee39662..c3f87b29d4d9 100644 --- a/code/modules/paperwork/clipboard.dm +++ b/code/modules/paperwork/clipboard.dm @@ -66,21 +66,21 @@ add_overlay(overlay_image(icon, "clipboard_pen", stored_pen.color, RESET_COLOR)) add_overlay(overlay_image(icon, "clipboard_over", flags=RESET_COLOR)) -/obj/item/clipboard/attackby(obj/item/W, mob/user) +/obj/item/clipboard/attackby(obj/item/used_item, mob/user) var/obj/item/top_paper = top_paper() - if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo)) - if(!user.try_unequip(W, src)) + if(istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo)) + if(!user.try_unequip(used_item, src)) return TRUE - push_paper(W) - to_chat(user, SPAN_NOTICE("You clip the [W] onto \the [src].")) + push_paper(used_item) + to_chat(user, SPAN_NOTICE("You clip the [used_item] onto \the [src].")) return TRUE - else if(top_paper?.attackby(W, user)) + else if(top_paper?.attackby(used_item, user)) updateUsrDialog() update_icon() return TRUE - else if(IS_PEN(W) && add_pen(W, user)) //If we don't have any paper, and hit it with a pen, try slotting it in + else if(IS_PEN(used_item) && add_pen(used_item, user)) //If we don't have any paper, and hit it with a pen, try slotting it in return TRUE return ..() diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm index ccc5e1d77c8c..f8f0e65df56b 100644 --- a/code/modules/paperwork/folders.dm +++ b/code/modules/paperwork/folders.dm @@ -35,16 +35,16 @@ if(has_paper_overlay && length(contents)) add_overlay("folder_paper") -/obj/item/folder/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo) || istype(W, /obj/item/paper_bundle)) - if(!user.try_unequip(W, src)) +/obj/item/folder/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo) || istype(used_item, /obj/item/paper_bundle)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, SPAN_NOTICE("You put the [W] into \the [src].")) + to_chat(user, SPAN_NOTICE("You put the [used_item] into \the [src].")) updateUsrDialog() update_icon() return TRUE - else if(IS_PEN(W)) + else if(IS_PEN(used_item)) updateUsrDialog() var/n_name = sanitize_safe(input(user, "What would you like to label the folder?", "Folder Labelling", null) as text, MAX_NAME_LEN) if(!CanPhysicallyInteractWith(user, src)) @@ -119,7 +119,7 @@ else ..() -/obj/item/folder/envelope/attackby(obj/item/W, mob/user) +/obj/item/folder/envelope/attackby(obj/item/used_item, mob/user) if(sealed) sealcheck(user) return TRUE diff --git a/code/modules/paperwork/handlabeler.dm b/code/modules/paperwork/handlabeler.dm index 225646088bf6..9121d00b60e3 100644 --- a/code/modules/paperwork/handlabeler.dm +++ b/code/modules/paperwork/handlabeler.dm @@ -147,11 +147,11 @@ update_icon() return TRUE -/obj/item/hand_labeler/attackby(obj/item/W, mob/user) +/obj/item/hand_labeler/attackby(obj/item/used_item, mob/user) //Allow refilling with paper sheets too - if(istype(W, /obj/item/paper)) - var/obj/item/paper/P = W + if(istype(used_item, /obj/item/paper)) + var/obj/item/paper/P = used_item if(!P.is_blank()) to_chat(user, SPAN_WARNING("\The [P] is not blank. You can't use that for refilling \the [src].")) return TRUE @@ -166,18 +166,18 @@ if(((incoming_amt + current_amt) / LABEL_MATERIAL_COST) > max_labels) to_chat(user, SPAN_WARNING("There's not enough room in \the [src] for the [label_added] label(s) \the [P] is worth.")) return TRUE - if(!user.do_skilled(2 SECONDS, SKILL_LITERACY, src) || (QDELETED(W) || QDELETED(src))) + if(!user.do_skilled(2 SECONDS, SKILL_LITERACY, src) || (QDELETED(used_item) || QDELETED(src))) return TRUE to_chat(user, SPAN_NOTICE("You slice \the [P] into [label_added] small strips and insert them into \the [src]'s paper feed.")) add_paper_labels(label_added) - qdel(W) + qdel(used_item) update_icon() return TRUE //Allow reloading from stacks much faster - else if(istype(W, /obj/item/stack/material)) - var/obj/item/stack/material/ST = W + else if(istype(used_item, /obj/item/stack/material)) + var/obj/item/stack/material/ST = used_item var/decl/material/M = ST.material var/max_accepted_labels = max_labels - get_labels_left() var/max_accepted_units = max_accepted_labels * LABEL_MATERIAL_COST diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index 27d047e94b87..3f0200c3f89c 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -28,40 +28,40 @@ LAZYCLEARLIST(pages) //Get rid of refs return ..() -/obj/item/paper_bundle/attackby(obj/item/W, mob/user) +/obj/item/paper_bundle/attackby(obj/item/used_item, mob/user) // adding sheets - if(istype(W, /obj/item/paper) || istype(W, /obj/item/photo)) - var/obj/item/paper/paper = W + if(istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo)) + var/obj/item/paper/paper = used_item if(istype(paper) && !paper.can_bundle()) return TRUE //non-paper or bundlable paper only - merge(W, user, cur_page) + merge(used_item, user, cur_page) return TRUE // merging bundles - else if(istype(W, /obj/item/paper_bundle) && merge(W, user, cur_page)) - to_chat(user, SPAN_NOTICE("You add \the [W] to \the [name].")) + else if(istype(used_item, /obj/item/paper_bundle) && merge(used_item, user, cur_page)) + to_chat(user, SPAN_NOTICE("You add \the [used_item] to \the [name].")) return TRUE // burning - else if(W.isflamesource()) - burnpaper(W, user) + else if(used_item.isflamesource()) + burnpaper(used_item, user) return TRUE - else if(istype(W, /obj/item/stack/tape_roll/duct_tape)) + else if(istype(used_item, /obj/item/stack/tape_roll/duct_tape)) var/obj/P = LAZYACCESS(pages, cur_page) if(P) - . = P.attackby(W, user) + . = P.attackby(used_item, user) update_icon() updateUsrDialog() return // How did we not have a page? Dunno, fall through to parent call anyway, I guess - else if(IS_PEN(W) || istype(W, /obj/item/stamp)) + else if(IS_PEN(used_item) || istype(used_item, /obj/item/stamp)) close_browser(user, "window=[name]") var/obj/P = LAZYACCESS(pages, cur_page) if(P) - . = P.attackby(W, user) + . = P.attackby(used_item, user) update_icon() updateUsrDialog() return diff --git a/code/modules/paperwork/papershredder.dm b/code/modules/paperwork/papershredder.dm index 7f79ad78b273..6a48a772660d 100644 --- a/code/modules/paperwork/papershredder.dm +++ b/code/modules/paperwork/papershredder.dm @@ -227,9 +227,9 @@ if(material) SetName("[initial(name)] [material.solid_name]") -/obj/item/shreddedp/attackby(var/obj/item/W, var/mob/user) - if(W.isflamesource()) - burnpaper(W, user) +/obj/item/shreddedp/attackby(var/obj/item/used_item, var/mob/user) + if(used_item.isflamesource()) + burnpaper(used_item, user) return TRUE return ..() diff --git a/code/modules/paperwork/printer.dm b/code/modules/paperwork/printer.dm index cfb02e78a147..802624d7d04b 100644 --- a/code/modules/paperwork/printer.dm +++ b/code/modules/paperwork/printer.dm @@ -58,18 +58,18 @@ unregister_on_status_changed() return ..() -/obj/item/stock_parts/printer/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/chems/toner_cartridge)) +/obj/item/stock_parts/printer/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/chems/toner_cartridge)) if(toner) - to_chat(user, SPAN_WARNING("There is already \a [W] in \the [src]!")) + to_chat(user, SPAN_WARNING("There is already \a [used_item] in \the [src]!")) return TRUE - return insert_toner(W, user) + return insert_toner(used_item, user) - else if(istype(W, /obj/item/paper) || istype(W, /obj/item/paper_bundle)) + else if(istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/paper_bundle)) if(paper_left >= paper_max) to_chat(user, SPAN_WARNING("There is no more room for paper in \the [src]!")) return TRUE - return insert_paper(W, user) + return insert_paper(used_item, user) . = ..() /obj/item/stock_parts/printer/attack_hand(mob/user) diff --git a/code/modules/persistence/graffiti.dm b/code/modules/persistence/graffiti.dm index ea6e391a7909..050fa7ffc267 100644 --- a/code/modules/persistence/graffiti.dm +++ b/code/modules/persistence/graffiti.dm @@ -15,8 +15,8 @@ /obj/effect/decal/writing/Initialize(mapload, var/_age, var/_message, var/_author) var/list/random_icon_states = get_states_in_icon(icon) - for(var/obj/effect/decal/writing/W in loc) - random_icon_states -= W.icon_state + for(var/obj/effect/decal/writing/writing in loc) + random_icon_states -= writing.icon_state if(length(random_icon_states)) icon_state = pick(random_icon_states) SSpersistence.track_value(src, /decl/persistence_handler/graffiti) diff --git a/code/modules/persistence/persistence_datum_graffiti.dm b/code/modules/persistence/persistence_datum_graffiti.dm index 83861418d67e..460aca908ef3 100644 --- a/code/modules/persistence/persistence_datum_graffiti.dm +++ b/code/modules/persistence/persistence_datum_graffiti.dm @@ -10,7 +10,7 @@ /decl/persistence_handler/graffiti/CheckTurfContents(var/turf/T, var/list/tokens) var/too_much_graffiti = 0 - for(var/obj/effect/decal/writing/W in .) + for(var/obj/effect/decal/writing/writing in .) too_much_graffiti++ if(too_much_graffiti >= 5) return FALSE diff --git a/code/modules/posters/_poster.dm b/code/modules/posters/_poster.dm index d874171cc744..0152edebfad3 100644 --- a/code/modules/posters/_poster.dm +++ b/code/modules/posters/_poster.dm @@ -46,9 +46,9 @@ //If we weren't ruined, mark us as ruined, so next time we get destroyed set_ruined(TRUE) -/obj/structure/sign/poster/attackby(obj/item/W, mob/user) +/obj/structure/sign/poster/attackby(obj/item/used_item, mob/user) //Prevent the sign implementation from removing us from the wall via unscrewing us - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) return FALSE //#FIXME: once /obj/structure/sign use the generic structure tools procs we won't need to intercept this here anymore. return ..() @@ -158,44 +158,44 @@ return //must place on a wall and user must not be inside a closet/exosuit/whatever - var/turf/W = get_turf(A) - if(!istype(W) || !W.is_wall() || !isturf(user.loc)) + var/turf/used_item = get_turf(A) + if(!istype(used_item) || !used_item.is_wall() || !isturf(user.loc)) to_chat(user, SPAN_WARNING("You can't place this here!")) return - var/placement_dir = get_dir(user, W) + var/placement_dir = get_dir(user, used_item) if (!(placement_dir in global.cardinal)) to_chat(user, SPAN_WARNING("You must stand directly in front of the wall you wish to place that on.")) return - if (ArePostersOnWall(W)) + if (ArePostersOnWall(used_item)) to_chat(user, SPAN_WARNING("There is already a poster there!")) return user.visible_message( - SPAN_NOTICE("\The [user] starts placing a poster on \the [W]."), - SPAN_NOTICE("You start placing the poster on \the [W].")) + SPAN_NOTICE("\The [user] starts placing a poster on \the [used_item]."), + SPAN_NOTICE("You start placing the poster on \the [used_item].")) var/obj/structure/sign/poster/P = new (user.loc, null, null, placement_dir, poster_design) qdel(src) flick("poster_being_set", P) // Time to place is equal to the time needed to play the flick animation - if(do_after(user, 28, W) && W.is_wall() && !ArePostersOnWall(W, P)) + if(do_after(user, 28, used_item) && used_item.is_wall() && !ArePostersOnWall(used_item, P)) user.visible_message( - SPAN_NOTICE("\The [user] has placed a poster on \the [W]."), - SPAN_NOTICE("You have placed the poster on \the [W].")) + SPAN_NOTICE("\The [user] has placed a poster on \the [used_item]."), + SPAN_NOTICE("You have placed the poster on \the [used_item].")) else // We cannot rely on user being on the appropriate turf when placement fails P.dismantle_structure(user) -/obj/item/poster/proc/ArePostersOnWall(var/turf/W, var/placed_poster) +/obj/item/poster/proc/ArePostersOnWall(var/turf/used_item, var/placed_poster) //just check if there is a poster on or adjacent to the wall - if (locate(/obj/structure/sign/poster) in W) + if (locate(/obj/structure/sign/poster) in used_item) return TRUE //crude, but will cover most cases. We could do stuff like check pixel_x/y but it's not really worth it. for (var/dir in global.cardinal) - var/turf/T = get_step(W, dir) + var/turf/T = get_step(used_item, dir) var/poster = locate(/obj/structure/sign/poster) in T if (poster && placed_poster != poster) return TRUE diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 52776be8e59f..0df866c15b71 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -438,8 +438,8 @@ var/global/list/all_apcs = list() panel_open = TRUE queue_icon_update() -/obj/machinery/power/apc/attackby(obj/item/W, mob/user) - if (istype(construct_state, /decl/machine_construction/wall_frame/panel_closed/hackable/hacking) && (IS_MULTITOOL(W) || IS_WIRECUTTER(W) || istype(W, /obj/item/assembly/signaler))) +/obj/machinery/power/apc/attackby(obj/item/used_item, mob/user) + if (istype(construct_state, /decl/machine_construction/wall_frame/panel_closed/hackable/hacking) && (IS_MULTITOOL(used_item) || IS_WIRECUTTER(used_item) || istype(used_item, /obj/item/assembly/signaler))) wires.Interact(user) return TRUE return ..() diff --git a/code/modules/power/batteryrack.dm b/code/modules/power/batteryrack.dm index 8ccfa5e609c9..144d6f5b2703 100644 --- a/code/modules/power/batteryrack.dm +++ b/code/modules/power/batteryrack.dm @@ -228,15 +228,15 @@ internal_cells -= cell return ..() -/obj/machinery/power/smes/batteryrack/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/power/smes/batteryrack/attackby(var/obj/item/used_item, var/mob/user) . = ..() if(.) return - if(istype(W, /obj/item/cell)) // ID Card, try to insert it. - if(insert_cell(W, user)) - to_chat(user, "You insert \the [W] into \the [src].") + if(istype(used_item, /obj/item/cell)) // ID Card, try to insert it. + if(insert_cell(used_item, user)) + to_chat(user, "You insert \the [used_item] into \the [src].") else - to_chat(user, "\The [src] has no empty slot for \the [W].") + to_chat(user, "\The [src] has no empty slot for \the [used_item].") return TRUE /obj/machinery/power/smes/batteryrack/interface_interact(var/mob/user) diff --git a/code/modules/power/breaker_box.dm b/code/modules/power/breaker_box.dm index 38477765ac00..9674fb2e47e8 100644 --- a/code/modules/power/breaker_box.dm +++ b/code/modules/power/breaker_box.dm @@ -85,8 +85,8 @@ busy = 0 return TRUE -/obj/machinery/power/breakerbox/attackby(var/obj/item/W, var/mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/power/breakerbox/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/newtag = input(user, "Enter new RCON tag. Use \"NO_TAG\" to disable RCON or leave empty to cancel.", "SMES RCON system") as text if(!CanPhysicallyInteract(user)) return TRUE diff --git a/code/modules/power/fission/core.dm b/code/modules/power/fission/core.dm index d8a6abb38b29..06ca2a1f6740 100644 --- a/code/modules/power/fission/core.dm +++ b/code/modules/power/fission/core.dm @@ -198,8 +198,8 @@ /obj/machinery/atmospherics/unary/fission_core/proc/check_active() return neutron_flux >= ACTIVE_THRESHOLD -/obj/machinery/atmospherics/unary/fission_core/attackby(var/obj/item/W, var/mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/atmospherics/unary/fission_core/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/fission = get_extension(src, /datum/extension/local_network_member) fission.get_new_tag(user) return TRUE @@ -209,14 +209,14 @@ to_chat(user, SPAN_WARNING("You cannot do that while \the [src] is active!")) return TRUE - if(istype(W, /obj/item/fuel_assembly)) + if(istype(used_item, /obj/item/fuel_assembly)) if(length(fuel_rods) >= MAX_RODS) to_chat(user, SPAN_WARNING("\The [src] is full!")) return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - fuel_rods[W] = FALSE // Rod is not exposed to begin with. - user.visible_message(SPAN_NOTICE("\The [user] inserts \a [W] into \the [src]."), SPAN_NOTICE("You insert \a [W] into \the [src].")) + fuel_rods[used_item] = FALSE // Rod is not exposed to begin with. + user.visible_message(SPAN_NOTICE("\The [user] inserts \a [used_item] into \the [src]."), SPAN_NOTICE("You insert \a [used_item] into \the [src].")) return TRUE . = ..() diff --git a/code/modules/power/fission/core_control.dm b/code/modules/power/fission/core_control.dm index 8432ef6463be..2b56f3d892ab 100644 --- a/code/modules/power/fission/core_control.dm +++ b/code/modules/power/fission/core_control.dm @@ -18,8 +18,8 @@ var/datum/extension/local_network_member/fission = get_extension(src, /datum/extension/local_network_member) fission.set_tag(null, initial_id_tag) -/obj/machinery/computer/fission/attackby(var/obj/item/W, var/mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/computer/fission/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/fission = get_extension(src, /datum/extension/local_network_member) fission.get_new_tag(user) return TRUE diff --git a/code/modules/power/fusion/core/_core.dm b/code/modules/power/fusion/core/_core.dm index 31a3fff21fa3..178fb68d31ca 100644 --- a/code/modules/power/fusion/core/_core.dm +++ b/code/modules/power/fusion/core/_core.dm @@ -99,18 +99,18 @@ Shutdown() return TRUE -/obj/machinery/fusion_core/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/fusion_core/attackby(var/obj/item/used_item, var/mob/user) if(owned_field) to_chat(user,"Shut \the [src] off first!") return TRUE - if(IS_MULTITOOL(W)) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/fusion = get_extension(src, /datum/extension/local_network_member) fusion.get_new_tag(user) return TRUE - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) anchored = !anchored playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) if(anchored) diff --git a/code/modules/power/fusion/fuel_injector/fuel_injector.dm b/code/modules/power/fusion/fuel_injector/fuel_injector.dm index 3bbf1a2dcfbf..4f01ce973614 100644 --- a/code/modules/power/fusion/fuel_injector/fuel_injector.dm +++ b/code/modules/power/fusion/fuel_injector/fuel_injector.dm @@ -45,31 +45,31 @@ else Inject() -/obj/machinery/fusion_fuel_injector/attackby(obj/item/W, mob/user) +/obj/machinery/fusion_fuel_injector/attackby(obj/item/used_item, mob/user) - if(IS_MULTITOOL(W)) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/fusion = get_extension(src, /datum/extension/local_network_member) fusion.get_new_tag(user) return TRUE - if(istype(W, /obj/item/fuel_assembly)) + if(istype(used_item, /obj/item/fuel_assembly)) if(injecting) to_chat(user, "Shut \the [src] off before playing with the fuel rod!") return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE if(cur_assembly) - visible_message("\The [user] swaps \the [src]'s [cur_assembly] for \a [W].") + visible_message("\The [user] swaps \the [src]'s [cur_assembly] for \a [used_item].") else - visible_message("\The [user] inserts \a [W] into \the [src].") + visible_message("\The [user] inserts \a [used_item] into \the [src].") if(cur_assembly) cur_assembly.dropInto(loc) user.put_in_hands(cur_assembly) - cur_assembly = W + cur_assembly = used_item return TRUE - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) if(injecting) to_chat(user, "Shut \the [src] off first!") return TRUE diff --git a/code/modules/power/fusion/gyrotron/gyrotron.dm b/code/modules/power/fusion/gyrotron/gyrotron.dm index d8a6425977eb..f70c73ffb5d1 100644 --- a/code/modules/power/fusion/gyrotron/gyrotron.dm +++ b/code/modules/power/fusion/gyrotron/gyrotron.dm @@ -57,8 +57,8 @@ else icon_state = "emitter-off" -/obj/machinery/emitter/gyrotron/attackby(var/obj/item/W, var/mob/user) - if(IS_MULTITOOL(W)) +/obj/machinery/emitter/gyrotron/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/fusion = get_extension(src, /datum/extension/local_network_member) fusion.get_new_tag(user) return TRUE diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 06b68c985316..01ab115896a3 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -153,8 +153,8 @@ generate_power(effective_gen) -/obj/machinery/generator/attackby(obj/item/W, mob/user) - if(!IS_WRENCH(W)) +/obj/machinery/generator/attackby(obj/item/used_item, mob/user) + if(!IS_WRENCH(used_item)) return ..() playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) anchored = !anchored diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index c2866b277c96..419650f03819 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -255,23 +255,23 @@ return SPAN_WARNING("You must first remove the lightbulb!") return ..() -/obj/machinery/light/attackby(obj/item/W, mob/user) +/obj/machinery/light/attackby(obj/item/used_item, mob/user) . = ..() if(. || panel_open) return // attempt to insert light - if(istype(W, /obj/item/light)) + if(istype(used_item, /obj/item/light)) if(lightbulb) to_chat(user, "There is a [get_fitting_name()] already inserted.") return - if(!istype(W, accepts_light_type)) + if(!istype(used_item, accepts_light_type)) to_chat(user, "This type of light requires a [get_fitting_name()].") return - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return - to_chat(user, "You insert [W].") - insert_bulb(W) + to_chat(user, "You insert [used_item].") + insert_bulb(used_item) src.add_fingerprint(user) // attempt to break the light @@ -279,10 +279,10 @@ else if(lightbulb && (lightbulb.status != LIGHT_BROKEN) && !user.check_intent(I_FLAG_HELP)) - if(prob(1 + W.expend_attack_force(user) * 5)) + if(prob(1 + used_item.expend_attack_force(user) * 5)) user.visible_message("[user.name] smashed the light!", "You smash the light!", "You hear a tinkle of breaking glass.") - if(on && (W.obj_flags & OBJ_FLAG_CONDUCTIBLE)) + if(on && (used_item.obj_flags & OBJ_FLAG_CONDUCTIBLE)) if (prob(12)) electrocute_mob(user, get_area(src), src, 0.3) broken() @@ -292,8 +292,8 @@ // attempt to stick weapon into light socket else if(!lightbulb) - to_chat(user, "You stick \the [W] into the light socket!") - if(expected_to_be_on() && (W.obj_flags & OBJ_FLAG_CONDUCTIBLE)) + to_chat(user, "You stick \the [used_item] into the light socket!") + if(expected_to_be_on() && (used_item.obj_flags & OBJ_FLAG_CONDUCTIBLE)) spark_at(src, cardinal_only = TRUE) if (prob(75)) electrocute_mob(user, get_area(src), src, rand(0.7,1.0)) @@ -455,9 +455,9 @@ . = ..() // this will handle pixel offsets icon_state = "nav[delay][!!(lightbulb && on)]" -/obj/machinery/light/navigation/attackby(obj/item/W, mob/user) +/obj/machinery/light/navigation/attackby(obj/item/used_item, mob/user) . = ..() - if(!. && IS_MULTITOOL(W)) + if(!. && IS_MULTITOOL(used_item)) delay = 5 + ((delay + 1) % 5) to_chat(user, SPAN_NOTICE("You adjust the delay on \the [src].")) return TRUE diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index 8afd72314cea..a3560b8c8db9 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -82,11 +82,11 @@ // attach a wire to a power machine - leads from the turf you are standing on //almost never called, overwritten by all power machines but terminal and generator -/obj/machinery/power/attackby(obj/item/W, mob/user) +/obj/machinery/power/attackby(obj/item/used_item, mob/user) if((. = ..())) return - if(IS_COIL(W)) - var/obj/item/stack/cable_coil/coil = W + if(IS_COIL(used_item)) + var/obj/item/stack/cable_coil/coil = used_item var/turf/T = user.loc if(!istype(T) || T.density || T.cannot_build_cable()) return diff --git a/code/modules/power/singularity/collector.dm b/code/modules/power/singularity/collector.dm index d915bac98433..f85c32b16eb0 100644 --- a/code/modules/power/singularity/collector.dm +++ b/code/modules/power/singularity/collector.dm @@ -89,24 +89,24 @@ var/global/list/rad_collectors = list() else to_chat(user, "The controls are locked!") -/obj/machinery/rad_collector/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/tank/hydrogen)) +/obj/machinery/rad_collector/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/tank/hydrogen)) if(!src.anchored) to_chat(user, "\The [src] needs to be secured to the floor first.") return TRUE if(src.loaded_tank) to_chat(user, "There's already a tank loaded.") return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - src.loaded_tank = W + src.loaded_tank = used_item update_icon() return TRUE - else if(IS_CROWBAR(W)) + else if(IS_CROWBAR(used_item)) if(loaded_tank && !src.locked) eject() return TRUE - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) if(loaded_tank) to_chat(user, "Remove the tank first.") return TRUE @@ -120,7 +120,7 @@ var/global/list/rad_collectors = list() "You [anchored? "secure":"undo"] the external bolts.", \ "You hear a ratchet.") return TRUE - else if(istype(W, /obj/item/card/id)||istype(W, /obj/item/modular_computer)) + else if(istype(used_item, /obj/item/card/id)||istype(used_item, /obj/item/modular_computer)) if (src.allowed(user)) if(active) src.locked = !src.locked diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index c2b62b6059ff..192376cc994f 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -133,9 +133,9 @@ powered = TRUE update_icon() -/obj/machinery/emitter/attackby(obj/item/W, mob/user) +/obj/machinery/emitter/attackby(obj/item/used_item, mob/user) - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) if(active) to_chat(user, "Turn off [src] first.") return TRUE @@ -158,8 +158,8 @@ to_chat(user, "\The [src] needs to be unwelded from the floor.") return TRUE - if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(active) to_chat(user, "Turn off [src] first.") return TRUE @@ -167,7 +167,7 @@ if(0) to_chat(user, "\The [src] needs to be wrenched to the floor.") if(1) - if (!WT.weld(0,user)) + if (!welder.weld(0,user)) to_chat(user, "You need more welding fuel to complete this task.") return TRUE playsound(loc, 'sound/items/Welder2.ogg', 50, 1) @@ -176,25 +176,25 @@ "You hear welding.") if (!do_after(user, 2 SECONDS, src)) return TRUE - if(!src || !WT.isOn()) return TRUE + if(!src || !welder.isOn()) return TRUE state = 2 to_chat(user, "You weld [src] to the floor.") if(2) - if (WT.weld(0,user)) + if (welder.weld(0,user)) playsound(loc, 'sound/items/Welder2.ogg', 50, 1) user.visible_message("[user.name] starts to cut [src] free from the floor.", \ "You start to cut [src] free from the floor.", \ "You hear welding.") if (!do_after(user, 2 SECONDS, src)) return TRUE - if(!src || !WT.isOn()) return TRUE + if(!src || !welder.isOn()) return TRUE state = 1 to_chat(user, "You cut [src] free from the floor.") else to_chat(user, "You need more welding fuel to complete this task.") return TRUE - if(istype(W, /obj/item/card/id) || istype(W, /obj/item/modular_computer)) + if(istype(used_item, /obj/item/card/id) || istype(used_item, /obj/item/modular_computer)) if(emagged) to_chat(user, "The lock seems to be broken.") return TRUE diff --git a/code/modules/power/singularity/field_generator.dm b/code/modules/power/singularity/field_generator.dm index bf7de4d3974f..ae6c9ec7eda3 100644 --- a/code/modules/power/singularity/field_generator.dm +++ b/code/modules/power/singularity/field_generator.dm @@ -97,11 +97,11 @@ field_generator power level display to_chat(user, "\The [src] needs to be firmly secured to the floor first.") return TRUE -/obj/machinery/field_generator/attackby(obj/item/W, mob/user) +/obj/machinery/field_generator/attackby(obj/item/used_item, mob/user) if(active) to_chat(user, "\The [src] needs to be off.") return TRUE - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) switch(state) if(0) state = 1 @@ -122,14 +122,14 @@ field_generator power level display if(2) to_chat(user, " \The [src] needs to be unwelded from the floor.") return TRUE - else if(IS_WELDER(W)) - var/obj/item/weldingtool/WT = W + else if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item switch(state) if(0) to_chat(user, "\The [src] needs to be wrenched to the floor.") return TRUE if(1) - if (!WT.weld(0,user)) + if (!welder.weld(0,user)) return TRUE playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1) user.visible_message("[user.name] starts to weld \the [src] to the floor.", \ @@ -137,12 +137,12 @@ field_generator power level display "You hear welding.") if (!do_after(user, 2 SECONDS, src)) return TRUE - if(!src || !WT.isOn()) return TRUE + if(!src || !welder.isOn()) return TRUE state = 2 to_chat(user, "You weld the field generator to the floor.") return TRUE if(2) - if (!WT.weld(0,user)) + if (!welder.weld(0,user)) return TRUE playsound(src.loc, 'sound/items/Welder2.ogg', 50, 1) user.visible_message("[user.name] starts to cut \the [src] free from the floor.", \ @@ -150,7 +150,7 @@ field_generator power level display "You hear welding.") if (!do_after(user, 2 SECONDS, src)) return TRUE - if(!src || !WT.isOn()) return TRUE + if(!src || !welder.isOn()) return TRUE state = 1 to_chat(user, "You cut \the [src] free from the floor.") return TRUE diff --git a/code/modules/power/singularity/generator.dm b/code/modules/power/singularity/generator.dm index 00976a216f0c..82a33b48a77e 100644 --- a/code/modules/power/singularity/generator.dm +++ b/code/modules/power/singularity/generator.dm @@ -39,8 +39,8 @@ if(!QDELETED(src)) qdel(src) -/obj/machinery/singularity_generator/attackby(obj/item/W, mob/user) - if(!IS_WRENCH(W)) +/obj/machinery/singularity_generator/attackby(obj/item/used_item, mob/user) + if(!IS_WRENCH(used_item)) return ..() anchored = !anchored playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) diff --git a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm index 7e5c523ea0f5..aab6c0dc67a3 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_accelerator.dm @@ -101,9 +101,9 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin else . += "\The [src] is assembled." -/obj/structure/particle_accelerator/attackby(obj/item/W, mob/user) - if(has_extension(W, /datum/extension/tool)) - if(process_tool_hit(W,user)) +/obj/structure/particle_accelerator/attackby(obj/item/used_item, mob/user) + if(has_extension(used_item, /datum/extension/tool)) + if(process_tool_hit(used_item,user)) return TRUE return ..() @@ -241,9 +241,9 @@ So, hopefully this is helpful if any more icons are to be added/changed/wonderin else . += "\The [src] is assembled." -/obj/machinery/particle_accelerator/attackby(obj/item/W, mob/user) - if(has_extension(W, /datum/extension/tool)) - if(process_tool_hit(W,user)) +/obj/machinery/particle_accelerator/attackby(obj/item/used_item, mob/user) + if(has_extension(used_item, /datum/extension/tool)) + if(process_tool_hit(used_item,user)) return TRUE return ..() diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index 99f418ed6272..f075340d7aa0 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -220,10 +220,10 @@ ui_interact(user) return TRUE -/obj/machinery/power/smes/attackby(var/obj/item/W, var/mob/user) - if((. = component_attackby(W, user))) +/obj/machinery/power/smes/attackby(var/obj/item/used_item, var/mob/user) + if((. = component_attackby(used_item, user))) return - return bash(W, user) + return bash(used_item, user) /obj/machinery/power/smes/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1) // this is the data which will be sent to the ui diff --git a/code/modules/power/smes_construction.dm b/code/modules/power/smes_construction.dm index cccc10631e3f..4d8d462e7a95 100644 --- a/code/modules/power/smes_construction.dm +++ b/code/modules/power/smes_construction.dm @@ -328,9 +328,9 @@ ..() // Proc: attackby() -// Parameters: 2 (W - object that was used on this machine, user - person which used the object) +// Parameters: 2 (used_item - object that was used on this machine, user - person which used the object) // Description: Handles tool interaction. Allows deconstruction/upgrading/fixing. -/obj/machinery/power/smes/buildable/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/power/smes/buildable/attackby(var/obj/item/used_item, var/mob/user) // No more disassembling of overloaded SMESs. You broke it, now enjoy the consequences. if (failing) to_chat(user, "\The [src]'s screen is flashing with alerts. It seems to be overloaded! Touching it now is probably not a good idea.") @@ -339,7 +339,7 @@ if(.) return // Multitool - change RCON tag - if(IS_MULTITOOL(W)) + if(IS_MULTITOOL(used_item)) var/newtag = input(user, "Enter new RCON tag. Use \"NO_TAG\" to disable RCON or leave empty to cancel.", "SMES RCON system") as text if(newtag) RCon_tag = newtag diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 23e5f846473c..e76803494d6a 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -73,8 +73,8 @@ var/global/list/solars_list = list() -/obj/machinery/power/solar/attackby(obj/item/W, mob/user) - if(IS_CROWBAR(W)) +/obj/machinery/power/solar/attackby(obj/item/used_item, mob/user) + if(IS_CROWBAR(used_item)) playsound(loc, 'sound/machines/click.ogg', 50, 1) user.visible_message("[user] begins to take the glass off the solar panel.") if(do_after(user, 50,src)) @@ -86,9 +86,9 @@ var/global/list/solars_list = list() user.visible_message("[user] takes the glass off the solar panel.") qdel(src) return TRUE - else if (W) + else if (used_item) add_fingerprint(user) - current_health -= W.expend_attack_force(user) + current_health -= used_item.expend_attack_force(user) healthcheck() return ..() @@ -240,8 +240,8 @@ var/global/list/solars_list = list() glass_type = null glass_reinforced = null -/obj/item/solar_assembly/attackby(var/obj/item/W, var/mob/user) - if(IS_WRENCH(W)) +/obj/item/solar_assembly/attackby(var/obj/item/used_item, var/mob/user) + if(IS_WRENCH(used_item)) if(!anchored && isturf(loc)) anchored = TRUE default_pixel_x = 0 @@ -256,8 +256,8 @@ var/global/list/solars_list = list() user.visible_message("[user] unwrenches the solar assembly from its place.") playsound(loc, 'sound/items/Ratchet.ogg', 75, 1) return TRUE - else if(istype(W, /obj/item/stack/material) && W.get_material_type() == /decl/material/solid/glass) - var/obj/item/stack/material/S = W + else if(istype(used_item, /obj/item/stack/material) && used_item.get_material_type() == /decl/material/solid/glass) + var/obj/item/stack/material/S = used_item if(!S.use(2)) to_chat(user, "You need two sheets of glass to put them into a solar panel.") return TRUE @@ -270,12 +270,12 @@ var/global/list/solars_list = list() else new /obj/machinery/power/solar(get_turf(src), src) return TRUE - if(!tracker && istype(W, /obj/item/tracker_electronics)) + if(!tracker && istype(used_item, /obj/item/tracker_electronics)) tracker = TRUE - qdel(W) + qdel(used_item) user.visible_message("[user] inserts the electronics into the solar assembly.") return TRUE - else if(IS_CROWBAR(W)) + else if(IS_CROWBAR(used_item)) new /obj/item/tracker_electronics(loc) tracker = 0 user.visible_message("[user] takes out the electronics from the solar assembly.") diff --git a/code/modules/power/stirling.dm b/code/modules/power/stirling.dm index fb1adc9ef8c7..ea7b725c4cb1 100644 --- a/code/modules/power/stirling.dm +++ b/code/modules/power/stirling.dm @@ -141,26 +141,26 @@ if(!inserted_cylinder) . += "There is no piston cylinder inserted into \the [src]." -/obj/machinery/atmospherics/binary/stirling/attackby(var/obj/item/W, var/mob/user) - if((istype(W, /obj/item/tank/stirling))) +/obj/machinery/atmospherics/binary/stirling/attackby(var/obj/item/used_item, var/mob/user) + if((istype(used_item, /obj/item/tank/stirling))) if(inserted_cylinder) return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, SPAN_NOTICE("You insert \the [W] into \the [src].")) - inserted_cylinder = W + to_chat(user, SPAN_NOTICE("You insert \the [used_item] into \the [src].")) + inserted_cylinder = used_item update_icon() return TRUE if(!panel_open) - if(IS_CROWBAR(W) && inserted_cylinder) + if(IS_CROWBAR(used_item) && inserted_cylinder) inserted_cylinder.dropInto(get_turf(src)) to_chat(user, SPAN_NOTICE("You remove \the [inserted_cylinder] from \the [src].")) inserted_cylinder = null stop_engine() return TRUE - if(IS_WRENCH(W)) + if(IS_WRENCH(used_item)) var/target_frequency = input(user, "Enter the cycle frequency you would like \the [src] to operate at ([MAX_FREQUENCY/4] - [MAX_FREQUENCY] Hz)", "Stirling Frequency", cycle_frequency) as num | null if(!CanPhysicallyInteract(user) || !target_frequency) return TRUE diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm index ac6c076a7029..7e6227927a0c 100644 --- a/code/modules/power/terminal.dm +++ b/code/modules/power/terminal.dm @@ -27,8 +27,8 @@ master = null . = ..() -/obj/machinery/power/terminal/attackby(obj/item/W, mob/user) - if(IS_WIRECUTTER(W)) +/obj/machinery/power/terminal/attackby(obj/item/used_item, mob/user) + if(IS_WIRECUTTER(used_item)) var/turf/T = get_turf(src) var/obj/machinery/machine = master_machine() diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index 2c99034e7f3b..b6f3bfb0274d 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -55,9 +55,9 @@ if(powernet && (powernet == control.powernet)) //update if we're still in the same powernet control.cdir = angle -/obj/machinery/power/tracker/attackby(var/obj/item/W, var/mob/user) +/obj/machinery/power/tracker/attackby(var/obj/item/used_item, var/mob/user) - if(IS_CROWBAR(W)) + if(IS_CROWBAR(used_item)) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) user.visible_message("[user] begins to take the glass off the solar tracker.") if(!do_after(user, 5 SECONDS, src)) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 8fceb8e096d6..a10c5770ff88 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -89,8 +89,8 @@ var/datum/extension/forensic_evidence/forensics = get_or_create_extension(A, /datum/extension/forensic_evidence) forensics.add_from_atom(/datum/forensics/gunshot_residue, src) -/obj/item/ammo_casing/attackby(obj/item/W, mob/user) - if(!IS_SCREWDRIVER(W)) +/obj/item/ammo_casing/attackby(obj/item/used_item, mob/user) + if(!IS_SCREWDRIVER(used_item)) return ..() if(!BB) to_chat(user, "There is no bullet in the casing to inscribe anything into.") @@ -198,10 +198,10 @@ SetName("[name] ([english_list(labels, and_text = ", ")])") update_icon() -/obj/item/ammo_magazine/attackby(obj/item/W, mob/user) - if(!istype(W, /obj/item/ammo_casing)) +/obj/item/ammo_magazine/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/ammo_casing)) return ..() - var/obj/item/ammo_casing/C = W + var/obj/item/ammo_casing/C = used_item if(C.caliber != caliber) to_chat(user, "[C] does not fit into [src].") return TRUE diff --git a/code/modules/projectiles/guns/energy/capacitor.dm b/code/modules/projectiles/guns/energy/capacitor.dm index c9e7239f2100..ac72d5d1e52b 100644 --- a/code/modules/projectiles/guns/energy/capacitor.dm +++ b/code/modules/projectiles/guns/energy/capacitor.dm @@ -103,12 +103,12 @@ var/global/list/laser_wavelengths /obj/item/gun/energy/capacitor/afterattack(atom/A, mob/living/user, adjacent, params) . = !charging && ..() -/obj/item/gun/energy/capacitor/attackby(obj/item/W, mob/user) +/obj/item/gun/energy/capacitor/attackby(obj/item/used_item, mob/user) if(charging) return ..() - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) // Unload the cell before the caps. if(get_cell()) return ..() @@ -121,12 +121,12 @@ var/global/list/laser_wavelengths update_icon() return TRUE - if(istype(W, /obj/item/stock_parts/capacitor)) + if(istype(used_item, /obj/item/stock_parts/capacitor)) if(length(capacitors) >= max_capacitors) to_chat(user, SPAN_WARNING("\The [src] cannot fit any additional capacitors.")) - else if(user.try_unequip(W, src)) - LAZYADD(capacitors, W) - to_chat(user, SPAN_NOTICE("You fit \the [W] into \the [src].")) + else if(user.try_unequip(used_item, src)) + LAZYADD(capacitors, used_item) + to_chat(user, SPAN_NOTICE("You fit \the [used_item] into \the [src].")) update_icon() return TRUE @@ -279,8 +279,8 @@ var/global/list/laser_wavelengths /obj/item/gun/energy/capacitor/rifle/linear_fusion/setup_power_supply(loaded_cell_type, accepted_cell_type, power_supply_extension_type, charge_value) return ..(/obj/item/cell/infinite, accepted_cell_type, /datum/extension/loaded_cell/unremovable, charge_value) -/obj/item/gun/energy/capacitor/rifle/linear_fusion/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/item/gun/energy/capacitor/rifle/linear_fusion/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) to_chat(user, SPAN_WARNING("\The [src] is hermetically sealed; you can't get the components out.")) return TRUE . = ..() diff --git a/code/modules/projectiles/guns/launcher/bows/bow_interaction.dm b/code/modules/projectiles/guns/launcher/bows/bow_interaction.dm index f2b8a389b4a5..de3c0073c98e 100644 --- a/code/modules/projectiles/guns/launcher/bows/bow_interaction.dm +++ b/code/modules/projectiles/guns/launcher/bows/bow_interaction.dm @@ -101,13 +101,13 @@ return TRUE return FALSE -/obj/item/gun/launcher/bow/attackby(obj/item/W, mob/user) - if(can_load_arrow(W)) +/obj/item/gun/launcher/bow/attackby(obj/item/used_item, mob/user) + if(can_load_arrow(used_item)) if(_loaded) to_chat(user, SPAN_WARNING("\The [src] already has \the [_loaded] ready.")) else - load_arrow(user, W) + load_arrow(user, used_item) return TRUE - if(istype(W, /obj/item/bowstring) && try_string(user, W)) + if(istype(used_item, /obj/item/bowstring) && try_string(user, used_item)) return TRUE return ..() diff --git a/code/modules/projectiles/guns/launcher/bows/crossbow_powered.dm b/code/modules/projectiles/guns/launcher/bows/crossbow_powered.dm index c048a4141f93..290878f861b3 100644 --- a/code/modules/projectiles/guns/launcher/bows/crossbow_powered.dm +++ b/code/modules/projectiles/guns/launcher/bows/crossbow_powered.dm @@ -24,10 +24,10 @@ QDEL_NULL(cell) return ..() -/obj/item/gun/launcher/bow/crossbow/powered/attackby(obj/item/W, mob/user) +/obj/item/gun/launcher/bow/crossbow/powered/attackby(obj/item/used_item, mob/user) - if(istype(W, /obj/item/rcd)) - var/obj/item/rcd/rcd = W + if(istype(used_item, /obj/item/rcd)) + var/obj/item/rcd/rcd = used_item if(rcd.crafting && user.try_unequip(rcd) && user.try_unequip(src)) new /obj/item/gun/launcher/bow/crossbow/powered/rapidcrossbowdevice(get_turf(src)) qdel(rcd) @@ -36,21 +36,21 @@ to_chat(user, SPAN_WARNING("\The [rcd] is not prepared for installation in \the [src].")) return TRUE - if(istype(W, /obj/item/cell)) + if(istype(used_item, /obj/item/cell)) if(!cell) - if(user.try_unequip(W, src)) - cell = W + if(user.try_unequip(used_item, src)) + cell = used_item to_chat(user, SPAN_NOTICE("You jam [cell] into [src] and wire it to the firing coil.")) superheat_rod(user) else to_chat(user, SPAN_NOTICE("[src] already has a cell installed.")) return TRUE - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) if(cell) var/obj/item/C = cell C.dropInto(user.loc) - to_chat(user, SPAN_NOTICE("You jimmy [cell] out of [src] with [W].")) + to_chat(user, SPAN_NOTICE("You jimmy [cell] out of [src] with [used_item].")) cell = null else to_chat(user, SPAN_WARNING("[src] doesn't have a cell installed.")) @@ -116,20 +116,20 @@ generate_bolt(user) return ..() -/obj/item/gun/launcher/bow/crossbow/powered/rapidcrossbowdevice/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/rcd_ammo)) - var/obj/item/rcd_ammo/cartridge = W +/obj/item/gun/launcher/bow/crossbow/powered/rapidcrossbowdevice/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/rcd_ammo)) + var/obj/item/rcd_ammo/cartridge = used_item if((stored_matter + cartridge.remaining) > max_stored_matter) to_chat(user, SPAN_NOTICE("The RCD can't hold that many additional matter-units.")) return TRUE stored_matter += cartridge.remaining - qdel(W) + qdel(used_item) playsound(src.loc, 'sound/machines/click.ogg', 50, 1) to_chat(user, SPAN_NOTICE("The RCD now holds [stored_matter]/[max_stored_matter] matter-units.")) update_icon() return TRUE - if(istype(W, /obj/item/stack/material/bow_ammo/bolt/rcd)) - var/obj/item/stack/material/bow_ammo/bolt/rcd/A = W + if(istype(used_item, /obj/item/stack/material/bow_ammo/bolt/rcd)) + var/obj/item/stack/material/bow_ammo/bolt/rcd/A = used_item if((stored_matter + 10) > max_stored_matter) to_chat(user, SPAN_NOTICE("Unable to reclaim flashforged bolt. The RCD can't hold that many additional matter-units.")) return TRUE diff --git a/code/modules/projectiles/guns/launcher/money_cannon.dm b/code/modules/projectiles/guns/launcher/money_cannon.dm index 64755e6f24ca..fff167aa5032 100644 --- a/code/modules/projectiles/guns/launcher/money_cannon.dm +++ b/code/modules/projectiles/guns/launcher/money_cannon.dm @@ -111,9 +111,9 @@ unload_receptacle(user) return TRUE -/obj/item/gun/launcher/money/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/cash)) - var/obj/item/cash/bling = W +/obj/item/gun/launcher/money/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/cash)) + var/obj/item/cash/bling = used_item if(bling.absolute_worth < 1) to_chat(user, "You can't seem to get \the [bling] to slide into the receptacle.") return TRUE diff --git a/code/modules/projectiles/guns/launcher/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm index 3c0b6e2885c9..5e1dcb93e82d 100644 --- a/code/modules/projectiles/guns/launcher/pneumatic.dm +++ b/code/modules/projectiles/guns/launcher/pneumatic.dm @@ -61,12 +61,12 @@ unload_hopper(user) return TRUE -/obj/item/gun/launcher/pneumatic/attackby(obj/item/W, mob/user) - if(!tank && istype(W, /obj/item/tank) && user.try_unequip(W, src)) - tank = W +/obj/item/gun/launcher/pneumatic/attackby(obj/item/used_item, mob/user) + if(!tank && istype(used_item, /obj/item/tank) && user.try_unequip(used_item, src)) + tank = used_item user.visible_message( - "\The [user] jams \the [W] into [src]'s valve and twists it closed.", - "You jam \the [W] into \the [src]'s valve and twist it closed." + "\The [user] jams \the [used_item] into [src]'s valve and twists it closed.", + "You jam \the [used_item] into \the [src]'s valve and twist it closed." ) update_icon() return TRUE diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm index 464ce437f7c3..44b580822317 100644 --- a/code/modules/projectiles/guns/projectile/revolver.dm +++ b/code/modules/projectiles/guns/projectile/revolver.dm @@ -57,8 +57,8 @@ if(cap) add_overlay("[icon_state]-toy") -/obj/item/gun/projectile/revolver/capgun/attackby(obj/item/wirecutters/W, mob/user) - if(!istype(W) || !cap) +/obj/item/gun/projectile/revolver/capgun/attackby(obj/item/used_item, mob/user) + if(!IS_WIRECUTTER(used_item) || !cap) return ..() to_chat(user, "You snip off the toy markings off \the [src].") name = "revolver" diff --git a/code/modules/projectiles/secure.dm b/code/modules/projectiles/secure.dm index a9196955008e..88fd79c91ef1 100644 --- a/code/modules/projectiles/secure.dm +++ b/code/modules/projectiles/secure.dm @@ -26,11 +26,11 @@ if(distance <= 0 && is_secure_gun()) . += "The registration screen shows, \"" + (registered_owner ? "[registered_owner]" : "unregistered") + "\"." -/obj/item/gun/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/card/id) && is_secure_gun()) +/obj/item/gun/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/card/id) && is_secure_gun()) user.visible_message("[user] swipes an ID through \the [src].", range = 3) if(!registered_owner) - var/obj/item/card/id/id = W + var/obj/item/card/id/id = used_item global.registered_weapons += src verbs += /obj/item/gun/proc/reset_registration registered_owner = id.registered_name diff --git a/code/modules/random_map/dungeon/winding_dungeon_verb.dm b/code/modules/random_map/dungeon/winding_dungeon_verb.dm index 9bf9129a0bd4..4e8bae557fee 100644 --- a/code/modules/random_map/dungeon/winding_dungeon_verb.dm +++ b/code/modules/random_map/dungeon/winding_dungeon_verb.dm @@ -95,7 +95,7 @@ if(alert("Are you sure you want to create this? It will appear at your position.",,"No","Yes") != "Yes") return - var/datum/random_map/winding_dungeon/W = /datum/random_map/winding_dungeon + var/datum/random_map/winding_dungeon/dungeon = /datum/random_map/winding_dungeon for(var/x in 1 to vars["limit_x"]) for(var/y in 1 to vars["limit_y"]) @@ -104,5 +104,5 @@ if(!T) to_chat(src, "Error, turf could not be located. Probably out of bounds.") return - T.ChangeTurf(initial(W.target_turf_type)) + T.ChangeTurf(initial(dungeon.target_turf_type)) new /datum/random_map/winding_dungeon(usr.x, usr.y, usr.z, variable_list = vars) diff --git a/code/modules/reagents/chems/chems_medicines.dm b/code/modules/reagents/chems/chems_medicines.dm index 12e16eef954d..954942cd8781 100644 --- a/code/modules/reagents/chems/chems_medicines.dm +++ b/code/modules/reagents/chems/chems_medicines.dm @@ -387,9 +387,9 @@ break if(limb.status & ORGAN_BLEEDING) var/closed_wound = FALSE - for(var/datum/wound/W in limb.wounds) - if(W.bleeding() && !W.clamped) - W.clamped = TRUE + for(var/datum/wound/wound in limb.wounds) + if(wound.bleeding() && !wound.clamped) + wound.clamped = TRUE closed_wound = TRUE break if(closed_wound) diff --git a/code/modules/reagents/reagent_containers/condiments/__condiment.dm b/code/modules/reagents/reagent_containers/condiments/__condiment.dm index b450ee555497..9b5af2524d70 100644 --- a/code/modules/reagents/reagent_containers/condiments/__condiment.dm +++ b/code/modules/reagents/reagent_containers/condiments/__condiment.dm @@ -19,8 +19,8 @@ if(condiment?.condiment_type) add_to_reagents(condiment.condiment_type, reagents.maximum_volume) -/obj/item/chems/condiment/attackby(var/obj/item/W, var/mob/user) - if(IS_PEN(W)) +/obj/item/chems/condiment/attackby(var/obj/item/used_item, var/mob/user) + if(IS_PEN(used_item)) var/tmp_label = sanitize_safe(input(user, "Enter a label for [name]", "Label", label_text), MAX_NAME_LEN) if(tmp_label == label_text) return TRUE diff --git a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm index 6bc197a3de5f..e4fc8df99e23 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm @@ -199,8 +199,8 @@ var/global/const/DRINK_ICON_NOISY = "noise" else continue side = "right" -/obj/item/chems/drinks/glass2/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/utensil/spoon)) +/obj/item/chems/drinks/glass2/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/utensil/spoon)) if(user.check_intent(I_FLAG_HARM)) user.visible_message("[user] bashes \the [src] with a spoon, shattering it to pieces! What a rube.") playsound(src, "shatter", 30, 1) diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index 7797e94b0e32..eea5c56987d9 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -93,13 +93,13 @@ qdel(src) return B -/obj/item/chems/drinks/bottle/attackby(obj/item/W, mob/user) +/obj/item/chems/drinks/bottle/attackby(obj/item/used_item, mob/user) if(!rag) - if(istype(W, /obj/item/chems/rag)) - insert_rag(W, user) + if(istype(used_item, /obj/item/chems/rag)) + insert_rag(used_item, user) return TRUE - else if(W.isflamesource()) - return rag.attackby(W, user) + else if(used_item.isflamesource()) + return rag.attackby(used_item, user) return ..() /obj/item/chems/drinks/bottle/attack_self(mob/user) diff --git a/code/modules/reagents/reagent_containers/food/baking/leavened_dough.dm b/code/modules/reagents/reagent_containers/food/baking/leavened_dough.dm index f9e86d7cd552..74d7283e2916 100644 --- a/code/modules/reagents/reagent_containers/food/baking/leavened_dough.dm +++ b/code/modules/reagents/reagent_containers/food/baking/leavened_dough.dm @@ -12,8 +12,8 @@ backyard_grilling_announcement = "is baked into a simple bun." // Dough + rolling pin = flat dough -/obj/item/food/dough/attackby(obj/item/W, mob/user) - if(!istype(W,/obj/item/kitchen/rollingpin)) +/obj/item/food/dough/attackby(obj/item/used_item, mob/user) + if(!istype(used_item,/obj/item/kitchen/rollingpin)) return ..() var/obj/item/food/sliceable/flatdough/result = new() result.dropInto(loc) diff --git a/code/modules/reagents/reagent_containers/food/canned/_canned.dm b/code/modules/reagents/reagent_containers/food/canned/_canned.dm index 0959b584dbcd..28c53e81f5cd 100644 --- a/code/modules/reagents/reagent_containers/food/canned/_canned.dm +++ b/code/modules/reagents/reagent_containers/food/canned/_canned.dm @@ -34,21 +34,21 @@ to_chat(user, SPAN_NOTICE("You unseal \the [src] with a crack of metal.")) unseal() -/obj/item/food/can/attackby(obj/item/W, mob/user) +/obj/item/food/can/attackby(obj/item/used_item, mob/user) if(!ATOM_IS_OPEN_CONTAINER(src)) - if(istype(W, /obj/item/knife)) + if(istype(used_item, /obj/item/knife)) user.visible_message( - SPAN_NOTICE("\The [user] starts trying to open \the [src] with \the [W]."), + SPAN_NOTICE("\The [user] starts trying to open \the [src] with \the [used_item]."), SPAN_NOTICE("You start to open \the [src].") ) - var/open_timer = istype(W, /obj/item/knife/opener) ? 5 SECONDS : 15 SECONDS + var/open_timer = istype(used_item, /obj/item/knife/opener) ? 5 SECONDS : 15 SECONDS if(!do_after(user, open_timer, src)) to_chat(user, SPAN_WARNING("You must remain uninterrupted to open \the [src].")) return TRUE to_chat(user, SPAN_NOTICE("You unseal \the [src] with a crack of metal.")) unseal() return TRUE - else if(istype(W,/obj/item/utensil)) + else if(istype(used_item,/obj/item/utensil)) to_chat(user, SPAN_WARNING("You need a can opener to open this!")) return TRUE return ..() diff --git a/code/modules/reagents/reagent_containers/food/eggs.dm b/code/modules/reagents/reagent_containers/food/eggs.dm index 955ea9d8d10b..8c4b82aa292e 100644 --- a/code/modules/reagents/reagent_containers/food/eggs.dm +++ b/code/modules/reagents/reagent_containers/food/eggs.dm @@ -34,9 +34,9 @@ visible_message("\The [src] has been squashed!","You hear a smack.") qdel(src) -/obj/item/food/egg/attackby(obj/item/W, mob/user) - if(IS_PEN(W)) - var/clr = W.get_tool_property(TOOL_PEN, TOOL_PROP_COLOR_NAME) +/obj/item/food/egg/attackby(obj/item/used_item, mob/user) + if(IS_PEN(used_item)) + var/clr = used_item.get_tool_property(TOOL_PEN, TOOL_PROP_COLOR_NAME) if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow"))) to_chat(user, SPAN_WARNING("The egg refuses to take on this color!")) diff --git a/code/modules/reagents/reagent_containers/food/sandwich.dm b/code/modules/reagents/reagent_containers/food/sandwich.dm index a3451736dbde..0b68fb355dad 100644 --- a/code/modules/reagents/reagent_containers/food/sandwich.dm +++ b/code/modules/reagents/reagent_containers/food/sandwich.dm @@ -1,9 +1,9 @@ -/obj/item/food/slice/bread/attackby(obj/item/W, mob/user) +/obj/item/food/slice/bread/attackby(obj/item/used_item, mob/user) - if(istype(W,/obj/item/shard) || istype(W,/obj/item/food)) + if(istype(used_item,/obj/item/shard) || istype(used_item,/obj/item/food)) var/obj/item/food/csandwich/S = new() S.dropInto(loc) - S.attackby(W,user) + S.attackby(used_item,user) qdel(src) return TRUE return ..() @@ -17,8 +17,8 @@ var/list/ingredients = list() -/obj/item/food/csandwich/attackby(obj/item/W, mob/user) - if(!istype(W, /obj/item/food) && !istype(W, /obj/item/shard)) +/obj/item/food/csandwich/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/food) && !istype(used_item, /obj/item/shard)) return ..() var/sandwich_limit = 4 @@ -29,19 +29,19 @@ if(src.contents.len > sandwich_limit) to_chat(user, "If you put anything else on \the [src] it's going to collapse.") return TRUE - if(istype(W,/obj/item/shard)) - if(!user.try_unequip(W, src)) + if(istype(used_item,/obj/item/shard)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, "You hide [W] in \the [src].") + to_chat(user, "You hide [used_item] in \the [src].") update_icon() return TRUE - else if(istype(W,/obj/item/food)) - if(!user.try_unequip(W, src)) + else if(istype(used_item,/obj/item/food)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, "You layer [W] over \the [src].") - var/obj/item/chems/F = W + to_chat(user, "You layer [used_item] over \the [src].") + var/obj/item/chems/F = used_item F.reagents.trans_to_obj(src, F.reagents.total_volume) - ingredients += W + ingredients += used_item update_icon() return TRUE return FALSE // This shouldn't ever happen but okay. diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm index 98b6ee139ba9..908e70a81d5d 100644 --- a/code/modules/reagents/reagent_containers/hypospray.dm +++ b/code/modules/reagents/reagent_containers/hypospray.dm @@ -151,12 +151,12 @@ remove_vial(user) return TRUE -/obj/item/chems/hypospray/vial/attackby(obj/item/W, mob/user) - if(!istype(W, /obj/item/chems/glass/beaker/vial)) +/obj/item/chems/hypospray/vial/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/chems/glass/beaker/vial)) return ..() if(!do_after(user, 1 SECOND, src)) return TRUE - insert_vial(W, user) + insert_vial(used_item, user) return TRUE /obj/item/chems/hypospray/vial/afterattack(obj/target, mob/user, proximity) // hyposprays can be dumped into, why not out? uses standard_pour_into helper checks. diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index 3e6f4ac50d7f..cd4493277c46 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -82,17 +82,17 @@ if(reagents?.maximum_volume) . += "It may contain up to [reagents.maximum_volume] unit\s of fluid." -/obj/structure/reagent_dispensers/attackby(obj/item/W, mob/user) +/obj/structure/reagent_dispensers/attackby(obj/item/used_item, mob/user) // We do this here to avoid putting the vessel straight into storage. // This is usually handled by afterattack on /chems. - if(storage && ATOM_IS_OPEN_CONTAINER(W) && user.check_intent(I_FLAG_HELP)) - if(W.standard_dispenser_refill(user, src)) + if(storage && ATOM_IS_OPEN_CONTAINER(used_item) && user.check_intent(I_FLAG_HELP)) + if(used_item.standard_dispenser_refill(user, src)) return TRUE - if(W.standard_pour_into(user, src)) + if(used_item.standard_pour_into(user, src)) return TRUE - if(wrenchable && IS_WRENCH(W)) + if(wrenchable && IS_WRENCH(used_item)) unwrenched = !unwrenched visible_message(SPAN_NOTICE("\The [user] wrenches \the [src]'s tap [unwrenched ? "open" : "shut"].")) if(unwrenched) @@ -145,11 +145,11 @@ name = "firefighting water reserve" volume = 50000 -/obj/structure/reagent_dispensers/watertank/attackby(obj/item/W, mob/user) +/obj/structure/reagent_dispensers/watertank/attackby(obj/item/used_item, mob/user) //FIXME: Maybe this should be handled differently? Since it can essentially make the tank unusable. - if((istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm)) && user.try_unequip(W)) - to_chat(user, "You add \the [W] arm to \the [src].") - qdel(W) + if((istype(used_item, /obj/item/robot_parts/l_arm) || istype(used_item, /obj/item/robot_parts/r_arm)) && user.try_unequip(used_item)) + to_chat(user, "You add \the [used_item] arm to \the [src].") + qdel(used_item) new /obj/item/farmbot_arm_assembly(loc, src) return TRUE . = ..() @@ -283,14 +283,14 @@ to_chat(user, "\The [src]'s cup dispenser is empty.") return TRUE -/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/W, mob/user) +/obj/structure/reagent_dispensers/water_cooler/attackby(obj/item/used_item, mob/user) //Allow refilling with a box - if(cups < max_cups && W?.storage) - for(var/obj/item/chems/drinks/C in W.storage.get_contents()) + if(cups < max_cups && used_item?.storage) + for(var/obj/item/chems/drinks/C in used_item.storage.get_contents()) if(cups >= max_cups) break if(istype(C, cup_type)) - W.storage.remove_from_storage(user, C, src) + used_item.storage.remove_from_storage(user, C, src) qdel(C) cups++ return TRUE diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index 132771035d47..d9db75c58358 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -146,12 +146,12 @@ return TRUE else if(istype(I, /obj/item/weldingtool)) if(anchored) - var/obj/item/weldingtool/W = I - if(W.weld(0,user)) + var/obj/item/weldingtool/welder = I + if(welder.weld(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) to_chat(user, "Welding \the [src] in place.") if(do_after(user, 2 SECONDS, src)) - if(!src || !W.isOn()) return TRUE + if(!src || !welder.isOn()) return TRUE to_chat(user, "\The [src] has been welded in place!") build(CP) qdel(src) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index a50fa92e738f..a330ae36e09b 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -588,14 +588,14 @@ var/global/list/diversion_junctions = list() else // This should be invalid? return FALSE else if(istype(I,/obj/item/weldingtool) && mode==1) - var/obj/item/weldingtool/W = I - if(W.weld(0,user)) + var/obj/item/weldingtool/welder = I + if(welder.weld(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) to_chat(user, "You start slicing the floorweld off the disposal outlet.") if(!do_after(user, 2 SECONDS, src)) to_chat(user, "You must remain still to deconstruct \the [src].") return TRUE - if(QDELETED(src) || !W.isOn()) + if(QDELETED(src) || !welder.isOn()) return TRUE to_chat(user, "You sliced the floorweld off the disposal outlet.") var/obj/structure/disposalconstruct/machine/outlet/C = new (loc, src) diff --git a/code/modules/recycling/disposalpipe.dm b/code/modules/recycling/disposalpipe.dm index 6727ee5fbfa8..3755fda1b1dd 100644 --- a/code/modules/recycling/disposalpipe.dm +++ b/code/modules/recycling/disposalpipe.dm @@ -207,14 +207,14 @@ if(!can_deconstruct()) return TRUE src.add_fingerprint(user, 0, I) - var/obj/item/weldingtool/W = I - if(W.weld(0,user)) + var/obj/item/weldingtool/welder = I + if(welder.weld(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) to_chat(user, "You begin slicing \the [src].") if(!do_after(user, 3 SECONDS, src)) to_chat(user, "You must stay still while welding the pipe.") return TRUE - if(!W.isOn()) + if(!welder.isOn()) return TRUE welded() return TRUE diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index afae8f24b694..bf275817f0bf 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -92,15 +92,15 @@ to_chat(user, "You attach the screws around the power connection.") return TRUE else if(IS_WELDER(I) && c_mode==1) - var/obj/item/weldingtool/W = I - if(!W.weld(1,user)) // 'you need more welding fuel' messages are already handled + var/obj/item/weldingtool/welder = I + if(!welder.weld(1,user)) // 'you need more welding fuel' messages are already handled return TRUE to_chat(user, "You start slicing the floorweld off the delivery chute.") if(!do_after(user, 2 SECONDS, src)) to_chat(user, "You stop slicing the floorweld off the delivery chute.") return TRUE playsound(src.loc, 'sound/items/Welder2.ogg', 100, TRUE) - if(!src || !W.isOn()) return TRUE + if(!src || !welder.isOn()) return TRUE to_chat(user, "You slice the floorweld off the delivery chute.") var/obj/structure/disposalconstruct/C = new (loc, src) C.update() diff --git a/code/modules/recycling/wrapped_package.dm b/code/modules/recycling/wrapped_package.dm index a18575b5f536..65d8fcd62610 100644 --- a/code/modules/recycling/wrapped_package.dm +++ b/code/modules/recycling/wrapped_package.dm @@ -176,10 +176,10 @@ return TRUE return ..() -/obj/item/parcel/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/destTagger)) +/obj/item/parcel/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/destTagger)) user.setClickCooldown(attack_cooldown) - var/obj/item/destTagger/O = W + var/obj/item/destTagger/O = used_item if(length(O.current_tag)) to_chat(user, SPAN_NOTICE("You have labeled the destination as '[O.current_tag]'.")) attach_destination_tag(O, user) @@ -187,15 +187,15 @@ to_chat(user, SPAN_WARNING("You need to set a destination tag first!")) return TRUE - else if(IS_PEN(W)) + else if(IS_PEN(used_item)) var/old_note = attached_note var/new_note = sanitize(input(user, "What note would you like to add to \the [src]?", "Add Note", attached_note)) - if((new_note != old_note) && user.Adjacent(src) && W.do_tool_interaction(TOOL_PEN, user, src, 2 SECONDS) && user.Adjacent(src)) + if((new_note != old_note) && user.Adjacent(src) && used_item.do_tool_interaction(TOOL_PEN, user, src, 2 SECONDS) && user.Adjacent(src)) attached_note = new_note update_icon() return TRUE - else if(W.is_sharp() && user.check_intent(I_FLAG_HELP)) + else if(used_item.is_sharp() && user.check_intent(I_FLAG_HELP)) //You can alternative cut the wrapper off with a sharp item unwrap(user) return TRUE diff --git a/code/modules/sealant_gun/sealant_gun.dm b/code/modules/sealant_gun/sealant_gun.dm index 37d42c36a6e8..23be0cf3efcd 100644 --- a/code/modules/sealant_gun/sealant_gun.dm +++ b/code/modules/sealant_gun/sealant_gun.dm @@ -62,9 +62,9 @@ else . += SPAN_WARNING("\The [src] has no sealant loaded.") -/obj/item/gun/launcher/sealant/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/sealant_tank) && user.try_unequip(W, src)) - loaded_tank = W +/obj/item/gun/launcher/sealant/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/sealant_tank) && user.try_unequip(used_item, src)) + loaded_tank = used_item to_chat(user, SPAN_NOTICE("You slot \the [loaded_tank] into \the [src].")) update_icon() return TRUE diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index 41df847379cf..eca9534b53ce 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -28,14 +28,14 @@ to_chat(user, "A firewall prevents you from interfacing with this device!") return TRUE -/obj/machinery/keycard_auth/attackby(obj/item/W, mob/user) - if(!istype(W,/obj/item/card/id)) +/obj/machinery/keycard_auth/attackby(obj/item/used_item, mob/user) + if(!istype(used_item,/obj/item/card/id)) return ..() if(stat & (NOPOWER|BROKEN)) to_chat(user, "This device is not powered.") return TRUE - visible_message(SPAN_NOTICE("[user] swipes \the [W] through \the [src].")) - var/obj/item/card/id/ID = W + visible_message(SPAN_NOTICE("[user] swipes \the [used_item] through \the [src].")) + var/obj/item/card/id/ID = used_item if(!(access_keycard_auth in ID.access)) // you get nothing! return TRUE if(active) diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index 0cb3ee417b94..467db3a92f6c 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -45,17 +45,17 @@ /obj/machinery/shield/attackby(obj/item/I, mob/user) return bash(I, user) -/obj/machinery/shield/bash(obj/item/W, mob/user) +/obj/machinery/shield/bash(obj/item/used_item, mob/user) if(isliving(user) && user.check_intent(I_FLAG_HELP)) return FALSE - if(!W.user_can_attack_with(user)) + if(!used_item.user_can_attack_with(user)) return FALSE - if(W.item_flags & ITEM_FLAG_NO_BLUDGEON) + if(used_item.item_flags & ITEM_FLAG_NO_BLUDGEON) return FALSE //Calculate damage - switch(W.atom_damage_type) + switch(used_item.atom_damage_type) if(BRUTE, BURN) - current_health -= W.expend_attack_force(user) + current_health -= used_item.expend_attack_force(user) else return FALSE @@ -266,8 +266,8 @@ update_icon() return 1 -/obj/machinery/shieldgen/attackby(obj/item/W, mob/user) - if(IS_SCREWDRIVER(W)) +/obj/machinery/shieldgen/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item)) playsound(src.loc, 'sound/items/Screwdriver.ogg', 100, 1) if(is_open) to_chat(user, "You close the panel.") @@ -276,8 +276,8 @@ to_chat(user, "You open the panel and expose the wiring.") is_open = 1 return TRUE - else if(IS_COIL(W) && malfunction && is_open) - var/obj/item/stack/cable_coil/coil = W + else if(IS_COIL(used_item) && malfunction && is_open) + var/obj/item/stack/cable_coil/coil = used_item to_chat(user, "You begin to replace the wires.") if(!do_after(user, 3 SECONDS, src)) to_chat(user, SPAN_NOTICE("You stop repairing \the [src].")) @@ -288,7 +288,7 @@ to_chat(user, "You repair \the [src]!") update_icon() return TRUE - else if(IS_WRENCH(W)) + else if(IS_WRENCH(used_item)) if(locked) to_chat(user, "The bolts are covered, unlocking this would retract the covers.") return TRUE @@ -304,7 +304,7 @@ to_chat(user, "You secure \the [src] to the floor!") anchored = TRUE return TRUE - else if(istype(W, /obj/item/card/id) || istype(W, /obj/item/modular_computer/pda)) + else if(istype(used_item, /obj/item/card/id) || istype(used_item, /obj/item/modular_computer/pda)) if(src.allowed(user)) src.locked = !src.locked to_chat(user, "The controls are now [src.locked ? "locked." : "unlocked."]") diff --git a/code/modules/shieldgen/shieldwallgen.dm b/code/modules/shieldgen/shieldwallgen.dm index 0ca75384784e..5f85f83f107f 100644 --- a/code/modules/shieldgen/shieldwallgen.dm +++ b/code/modules/shieldgen/shieldwallgen.dm @@ -203,8 +203,8 @@ CF.set_dir(field_dir) -/obj/machinery/shieldwallgen/attackby(obj/item/W, mob/user) - if(IS_WRENCH(W)) +/obj/machinery/shieldwallgen/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item)) if(active) to_chat(user, "Turn off the field generator first.") return TRUE @@ -218,7 +218,7 @@ src.anchored = FALSE return TRUE - if(istype(W, /obj/item/card/id)||istype(W, /obj/item/modular_computer)) + if(istype(used_item, /obj/item/card/id)||istype(used_item, /obj/item/modular_computer)) if (src.allowed(user)) src.locked = !src.locked to_chat(user, "Controls are now [src.locked ? "locked." : "unlocked."]") diff --git a/code/modules/shuttles/shuttle_emergency.dm b/code/modules/shuttles/shuttle_emergency.dm index f78010c50559..bea008962935 100644 --- a/code/modules/shuttles/shuttle_emergency.dm +++ b/code/modules/shuttles/shuttle_emergency.dm @@ -174,8 +174,8 @@ emagged = 1 return 1 -/obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/W, mob/user) - if(read_authorization(W)) +/obj/machinery/computer/shuttle_control/emergency/attackby(obj/item/used_item, mob/user) + if(read_authorization(used_item)) return TRUE return ..() diff --git a/code/modules/surgery/generic.dm b/code/modules/surgery/generic.dm index 5b5843eb77af..f0a7f693e1d9 100644 --- a/code/modules/surgery/generic.dm +++ b/code/modules/surgery/generic.dm @@ -191,19 +191,19 @@ /decl/surgery_step/generic/cauterize/begin_step(mob/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - var/datum/wound/W = affected.get_incision() - user.visible_message("[user] is beginning to [cauterize_term][W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool]." , \ - "You are beginning to [cauterize_term][W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].") + var/datum/wound/wound = affected.get_incision() + user.visible_message("[user] is beginning to [cauterize_term][wound ? " \a [wound.desc] on" : ""] \the [target]'s [affected.name] with \the [tool]." , \ + "You are beginning to [cauterize_term][wound ? " \a [wound.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].") target.custom_pain("Your [affected.name] is being burned!",40,affecting = affected) ..() /decl/surgery_step/generic/cauterize/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - var/datum/wound/W = affected.get_incision() - user.visible_message("[user] [post_cauterize_term][W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].", \ - "You [cauterize_term][W ? " \a [W.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].") - if(istype(W)) - W.close() + var/datum/wound/wound = affected.get_incision() + user.visible_message("[user] [post_cauterize_term][wound ? " \a [wound.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].", \ + "You [cauterize_term][wound ? " \a [wound.desc] on" : ""] \the [target]'s [affected.name] with \the [tool].") + if(istype(wound)) + wound.close() affected.update_wounds() if(affected.clamped()) affected.remove_clamps() diff --git a/code/modules/surgery/suture_wounds.dm b/code/modules/surgery/suture_wounds.dm index 987107568309..a329518f6ffa 100644 --- a/code/modules/surgery/suture_wounds.dm +++ b/code/modules/surgery/suture_wounds.dm @@ -12,8 +12,8 @@ /decl/surgery_step/suture_wounds/pre_surgery_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) if(affected) - for(var/datum/wound/W in affected.wounds) - if(W.damage_type == CUT && W.damage >= W.autoheal_cutoff) + for(var/datum/wound/wound in affected.wounds) + if(wound.damage_type == CUT && wound.damage >= wound.autoheal_cutoff) return TRUE to_chat(user, SPAN_WARNING("\The [target]'s [affected.name] has no wounds that are large enough to need suturing.")) return FALSE @@ -27,21 +27,21 @@ /decl/surgery_step/suture_wounds/end_step(mob/living/user, mob/living/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = GET_EXTERNAL_ORGAN(target, target_zone) - for(var/datum/wound/W in affected.wounds) - if(W.damage_type == CUT && W.damage >= W.autoheal_cutoff) + for(var/datum/wound/wound in affected.wounds) + if(wound.damage_type == CUT && wound.damage >= wound.autoheal_cutoff) // Close it up to a point that it can be bandaged and heal naturally! - W.heal_damage(rand(10,20)+10) - if(W.damage >= W.autoheal_cutoff) + wound.heal_damage(rand(10,20)+10) + if(wound.damage >= wound.autoheal_cutoff) user.visible_message(SPAN_NOTICE("\The [user] partially closes a wound on [target]'s [affected.name] with \the [tool]."), \ SPAN_NOTICE("You partially close a wound on [target]'s [affected.name] with \the [tool].")) else user.visible_message(SPAN_NOTICE("\The [user] closes a wound on [target]'s [affected.name] with \the [tool]."), \ SPAN_NOTICE("You close a wound on [target]'s [affected.name] with \the [tool].")) - if(!W.damage) - affected.wounds -= W - qdel(W) - else if(W.damage <= 10) - W.clamped = 1 + if(!wound.damage) + affected.wounds -= wound + qdel(wound) + else if(wound.damage <= 10) + wound.clamped = 1 break affected.update_damages() ..() diff --git a/code/modules/vehicles/bike.dm b/code/modules/vehicles/bike.dm index 794dcf366849..2dd01cbc386c 100644 --- a/code/modules/vehicles/bike.dm +++ b/code/modules/vehicles/bike.dm @@ -107,18 +107,18 @@ /obj/vehicle/bike/insert_cell(var/obj/item/cell/cell, var/mob/living/human/H) return -/obj/vehicle/bike/attackby(obj/item/W, mob/user) +/obj/vehicle/bike/attackby(obj/item/used_item, mob/user) if(open) - if(istype(W, /obj/item/engine)) + if(istype(used_item, /obj/item/engine)) if(engine) to_chat(user, "There is already an engine block in \the [src].") return TRUE - user.visible_message("\The [user] installs \the [W] into \the [src].") - load_engine(W) + user.visible_message("\The [user] installs \the [used_item] into \the [src].") + load_engine(used_item) return TRUE - else if(engine && engine.attackby(W,user)) + else if(engine && engine.attackby(used_item,user)) return TRUE - else if(IS_CROWBAR(W) && engine) + else if(IS_CROWBAR(used_item) && engine) to_chat(user, "You pop out \the [engine] from \the [src].") unload_engine() return TRUE diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index 299563fa806b..f828d2f4e1c5 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -67,17 +67,17 @@ return ..() -/obj/vehicle/train/cargo/trolley/attackby(obj/item/W, mob/user) - if(open && IS_WIRECUTTER(W)) +/obj/vehicle/train/cargo/trolley/attackby(obj/item/used_item, mob/user) + if(open && IS_WIRECUTTER(used_item)) passenger_allowed = !passenger_allowed user.visible_message("[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].","You [passenger_allowed ? "cut" : "mend"] the load limiter cable.") return TRUE return ..() -/obj/vehicle/train/cargo/engine/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/key/cargo_train)) - if(!key && user.try_unequip(W, src)) - key = W +/obj/vehicle/train/cargo/engine/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/key/cargo_train)) + if(!key && user.try_unequip(used_item, src)) + key = used_item verbs += /obj/vehicle/train/cargo/engine/verb/remove_key return TRUE return ..() diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index 30fe371f57e9..111eb94818e2 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -29,7 +29,7 @@ var/move_delay = 1 //set this to limit the speed of the vehicle var/obj/item/cell/cell - var/charge_use = 200 //W + var/charge_use = 200 // W var/atom/movable/load //all vehicles can take a load, since they should all be a least drivable var/load_item_visible = 1 //set if the loaded item should be overlayed on the vehicle sprite @@ -68,10 +68,10 @@ else return 0 -/obj/vehicle/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/hand_labeler)) +/obj/vehicle/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/hand_labeler)) return FALSE // allow afterattack to run - if(IS_SCREWDRIVER(W)) + if(IS_SCREWDRIVER(used_item)) if(!locked) open = !open update_icon() @@ -79,13 +79,13 @@ return TRUE to_chat(user, SPAN_WARNING("You can't [open ? "close" : "open"] the maintenance panel while \the [src] is locked!")) return TRUE - else if(IS_CROWBAR(W) && cell && open) + else if(IS_CROWBAR(used_item) && cell && open) remove_cell(user) return TRUE - else if(istype(W, /obj/item/cell) && !cell && open) - insert_cell(W, user) + else if(istype(used_item, /obj/item/cell) && !cell && open) + insert_cell(used_item, user) return TRUE - else if(IS_WELDER(W)) + else if(IS_WELDER(used_item)) var/current_max_health = get_max_health() if(current_health >= current_max_health) to_chat(user, "[src] does not need repairs.") @@ -93,9 +93,9 @@ if(!open) to_chat(user, "Unable to repair with the maintenance panel closed.") return TRUE - var/obj/item/weldingtool/welder = W + var/obj/item/weldingtool/welder = used_item if(!welder.welding) - to_chat(user, "Unable to repair while [W] is off.") + to_chat(user, "Unable to repair while [used_item] is off.") return TRUE if(welder.weld(5, user)) current_health = min(current_max_health, current_health+10) diff --git a/code/modules/xenoarcheaology/artifacts/artifact.dm b/code/modules/xenoarcheaology/artifacts/artifact.dm index a39efb764ce0..96f468938b7b 100644 --- a/code/modules/xenoarcheaology/artifacts/artifact.dm +++ b/code/modules/xenoarcheaology/artifacts/artifact.dm @@ -88,10 +88,10 @@ check_triggers(/datum/artifact_trigger/proc/on_touch, user) touched(user) -/obj/structure/artifact/attackby(obj/item/W, mob/user) +/obj/structure/artifact/attackby(obj/item/used_item, mob/user) . = ..() - visible_message(SPAN_WARNING("[user] hits \the [src] with \the [W].")) - check_triggers(/datum/artifact_trigger/proc/on_hit, W, user) + visible_message(SPAN_WARNING("[user] hits \the [src] with \the [used_item].")) + check_triggers(/datum/artifact_trigger/proc/on_hit, used_item, user) /obj/structure/artifact/Bumped(M) ..() diff --git a/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm b/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm index 736ce1295ea1..c5c32c5fa43f 100644 --- a/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm +++ b/code/modules/xenoarcheaology/artifacts/standalone/replicator.dm @@ -125,11 +125,11 @@ show_browser(user, dat, "window=alien_replicator") -/obj/machinery/replicator/attackby(obj/item/W, mob/user) - if(!user.try_unequip(W, src)) +/obj/machinery/replicator/attackby(obj/item/used_item, mob/user) + if(!user.try_unequip(used_item, src)) return FALSE - stored_materials.Add(W) - user.visible_message(SPAN_NOTICE("\The [user] inserts \the [W] into \the [src]."), SPAN_NOTICE("You insert \the [W] into \the [src].")) + stored_materials.Add(used_item) + user.visible_message(SPAN_NOTICE("\The [user] inserts \the [used_item] into \the [src]."), SPAN_NOTICE("You insert \the [used_item] into \the [src].")) return TRUE /obj/machinery/replicator/OnTopic(user, href_list) diff --git a/code/modules/xenoarcheaology/finds/find_types/fossils.dm b/code/modules/xenoarcheaology/finds/find_types/fossils.dm index f06c6c37784b..bb4fc8f8892d 100644 --- a/code/modules/xenoarcheaology/finds/find_types/fossils.dm +++ b/code/modules/xenoarcheaology/finds/find_types/fossils.dm @@ -52,13 +52,13 @@ /obj/item/fossil/animal/skull/horned icon_state = "hskull" -/obj/item/fossil/skull/attackby(obj/item/W, mob/user) - if(!istype(W, /obj/item/fossil/animal)) +/obj/item/fossil/skull/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/fossil/animal)) return ..() if(!user.try_unequip(src)) return FALSE var/obj/structure/skeleton/skellybones = new (get_turf(src)) - user.try_unequip(W, skellybones) + user.try_unequip(used_item, skellybones) forceMove(skellybones) return TRUE @@ -82,19 +82,19 @@ if(distance <= 1) . += "The plaque reads \'[plaque_contents]\'." -/obj/structure/skeleton/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/fossil/animal)) +/obj/structure/skeleton/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/fossil/animal)) if(bone_count >= required_bones) to_chat(user, SPAN_NOTICE("\The [src] is already complete.")) return TRUE - if(!user.try_unequip(W, src)) + if(!user.try_unequip(used_item, src)) return TRUE bone_count++ if(bone_count == required_bones) icon_state = "skel" set_density(1) return TRUE - else if(IS_PEN(W)) + else if(IS_PEN(used_item)) plaque_contents = sanitize(input("What would you like to write on the plaque:","Skeleton plaque","")) user.visible_message("[user] writes something on the base of [src].","You relabel the plaque on the base of [src].") return TRUE diff --git a/code/modules/xenoarcheaology/finds/find_types/statuette.dm b/code/modules/xenoarcheaology/finds/find_types/statuette.dm index 7ef0251d27de..e5d985de8dc9 100644 --- a/code/modules/xenoarcheaology/finds/find_types/statuette.dm +++ b/code/modules/xenoarcheaology/finds/find_types/statuette.dm @@ -86,12 +86,12 @@ if(wight_check_index > shadow_wights.len) wight_check_index = 1 - var/obj/effect/shadow_wight/W = shadow_wights[wight_check_index] - if(isnull(W)) + var/obj/effect/shadow_wight/wight = shadow_wights[wight_check_index] + if(isnull(wight)) shadow_wights.Remove(wight_check_index) - else if(isnull(W.loc)) + else if(isnull(wight.loc)) shadow_wights.Remove(wight_check_index) - else if(get_dist(W, src) > 10) + else if(get_dist(wight, src) > 10) shadow_wights.Remove(wight_check_index) /obj/item/vampiric/hear_talk(mob/M, text) diff --git a/code/modules/xenoarcheaology/finds/strange_rock.dm b/code/modules/xenoarcheaology/finds/strange_rock.dm index 5e2c8770e9c6..813caba8184c 100644 --- a/code/modules/xenoarcheaology/finds/strange_rock.dm +++ b/code/modules/xenoarcheaology/finds/strange_rock.dm @@ -30,9 +30,9 @@ return TRUE if(IS_WELDER(I)) - var/obj/item/weldingtool/W = I - if(W.isOn()) - if(W.weld(2)) + var/obj/item/weldingtool/welder = I + if(welder.isOn()) + if(welder.weld(2)) if(inside) inside.dropInto(loc) visible_message(SPAN_NOTICE("\The [src] burns away revealing \the [inside].")) diff --git a/code/unit_tests/override_tests.dm b/code/unit_tests/override_tests.dm index 4687b0c72aaa..ea030be4a20c 100644 --- a/code/unit_tests/override_tests.dm +++ b/code/unit_tests/override_tests.dm @@ -43,16 +43,16 @@ name = "OVERRIDE: /datum/atom_creator/weighted shall spawn heaviest" /datum/unit_test/override/atom_creator_weighted_shall_spawn_heaviest/start_test() - var/datum/atom_creator/weighted/W = new/datum/atom_creator/weighted(list(/obj/unit_test_light = 9001, /obj/unit_test_heavy = 1)) + var/datum/atom_creator/weighted/weighted_creator = new/datum/atom_creator/weighted(list(/obj/unit_test_light = 9001, /obj/unit_test_heavy = 1)) var/safe_turf = get_safe_turf() - W.create(safe_turf) + weighted_creator.create(safe_turf) var/created_object = locate(/obj/unit_test_heavy) in safe_turf if(created_object) - pass("[log_info_line(W)] successfully created the heaviest object.") + pass("[log_info_line(weighted_creator)] successfully created the heaviest object.") qdel(created_object) else - fail("[log_info_line(W)] failed to create its heaviest object.") + fail("[log_info_line(weighted_creator)] failed to create its heaviest object.") return 1 @@ -60,7 +60,7 @@ name = "OVERRIDE: /datum/atom_creator/weighted shall spawn heaviest - Recursive" /datum/unit_test/override/atom_creator_weighted_shall_spawn_heaviest_recursive/start_test() - var/datum/atom_creator/weighted/W = new/datum/atom_creator/weighted( + var/datum/atom_creator/weighted/weighted_creator = new/datum/atom_creator/weighted( list( new/datum/atom_creator/weighted(list(/obj/unit_test_light = 9001, /obj/unit_test_heavy = 1)), new/datum/atom_creator/simple(/obj/unit_test_medium, 50) @@ -68,12 +68,12 @@ ) var/safe_turf = get_safe_turf() - W.create(safe_turf) + weighted_creator.create(safe_turf) var/created_object = locate(/obj/unit_test_heavy) in safe_turf if(created_object) - pass("[log_info_line(W)] successfully created the heaviest object.") + pass("[log_info_line(weighted_creator)] successfully created the heaviest object.") qdel(created_object) else - fail("[log_info_line(W)] failed to create its heaviest object.") + fail("[log_info_line(weighted_creator)] failed to create its heaviest object.") return 1 diff --git a/maps/away/errant_pisces/errant_pisces.dm b/maps/away/errant_pisces/errant_pisces.dm index 1060e8f8a9cb..b5179c2bd942 100644 --- a/maps/away/errant_pisces/errant_pisces.dm +++ b/maps/away/errant_pisces/errant_pisces.dm @@ -52,18 +52,18 @@ else return SPAN_NOTICE("A few strands of \the [src] have been severed.") -/obj/structure/net/attackby(obj/item/W, mob/user) - if(W.is_sharp() || W.has_edge()) - var/force = W.expend_attack_force(user) - if (!(W.is_sharp()) || (W.is_sharp() && force < 10))//is not sharp enough or at all - to_chat(user,"You can't cut through \the [src] with \the [W], it's too dull.") +/obj/structure/net/attackby(obj/item/used_item, mob/user) + if(used_item.is_sharp() || used_item.has_edge()) + var/force = used_item.expend_attack_force(user) + if (!(used_item.is_sharp()) || (used_item.is_sharp() && force < 10))//is not sharp enough or at all + to_chat(user,"You can't cut through \the [src] with \the [used_item], it's too dull.") return TRUE - visible_message("[user] starts to cut through \the [src] with \the [W]!") + visible_message("[user] starts to cut through \the [src] with \the [used_item]!") while(current_health > 0 && !QDELETED(src) && !QDELETED(user)) if (!do_after(user, 20, src)) - visible_message("[user] stops cutting through \the [src] with \the [W]!") + visible_message("[user] stops cutting through \the [src] with \the [used_item]!") return TRUE - take_damage(20 * (1 + (force-10)/10), W.atom_damage_type) //the sharper the faster, every point of force above 10 adds 10 % to damage + take_damage(20 * (1 + (force-10)/10), used_item.atom_damage_type) //the sharper the faster, every point of force above 10 adds 10 % to damage new /obj/item/stack/net(src.loc) qdel(src) return TRUE diff --git a/maps/away/magshield/magshield.dm b/maps/away/magshield/magshield.dm index 7344b67ec55c..dc0670443461 100644 --- a/maps/away/magshield/magshield.dm +++ b/maps/away/magshield/magshield.dm @@ -90,12 +90,12 @@ to_chat(user, SPAN_NOTICE("You don't see how you could turn off \the [src]. You could possibly jam something into the rotating spokes.")) return TRUE -/obj/structure/magshield/maggen/attackby(obj/item/W, mob/user) +/obj/structure/magshield/maggen/attackby(obj/item/used_item, mob/user) if (being_stopped) to_chat(user, SPAN_WARNING("Somebody is already interacting with \the [src].")) return TRUE - if(istype(W, /obj/item/stack/material/rods)) - var/obj/item/stack/material/rods/R = W + if(istype(used_item, /obj/item/stack/material/rods)) + var/obj/item/stack/material/rods/R = used_item to_chat(user, SPAN_NOTICE("You start to jam \a [R.singular_name] into the rotating spokes.")) being_stopped = 1 if (!do_after(user, 100, src)) @@ -112,9 +112,9 @@ explosion(T, 2, 3, 4, 10, 1) if(!QDELETED(src)) qdel(src) - if(istype(W, /obj/item/mop)) - to_chat(user, SPAN_NOTICE("You stick \the [W] into the rotating spokes, and it immediately breaks into tiny pieces.")) - qdel(W) + if(istype(used_item, /obj/item/mop)) + to_chat(user, SPAN_NOTICE("You stick \the [used_item] into the rotating spokes, and it immediately breaks into tiny pieces.")) + qdel(used_item) return TRUE return ..() diff --git a/maps/away/mobius_rift/mobius_rift.dm b/maps/away/mobius_rift/mobius_rift.dm index 771f936cf140..48b89d81a81d 100644 --- a/maps/away/mobius_rift/mobius_rift.dm +++ b/maps/away/mobius_rift/mobius_rift.dm @@ -88,19 +88,19 @@ /obj/effect/mobius_rift/chamber/Initialize(var/mapload, var/grid_size)//NORTH, SOUTH, EAST, WEST . = ..() - var/turf/T - T = locate(src.x, src.y + round(grid_size/2), src.z) - var/N = new /obj/effect/step_trigger/mobius_rift/seamless_portal(T, NORTH) - portals["NORTH"] = N - T = locate(src.x, src.y - round(grid_size/2), src.z) - var/S = new /obj/effect/step_trigger/mobius_rift/seamless_portal(T, SOUTH) - portals["SOUTH"] = S - T = locate(src.x + round(grid_size/2), src.y, src.z) - var/E = new /obj/effect/step_trigger/mobius_rift/seamless_portal(T, EAST) - portals["EAST"] = E - T = locate(src.x - round(grid_size/2), src.y, src.z) - var/W = new /obj/effect/step_trigger/mobius_rift/seamless_portal(T, WEST) - portals["WEST"] = W + var/turf/rift_turf + rift_turf = locate(src.x, src.y + round(grid_size/2), src.z) + var/north_portal = new /obj/effect/step_trigger/mobius_rift/seamless_portal(rift_turf, NORTH) + portals["NORTH"] = north_portal + rift_turf = locate(src.x, src.y - round(grid_size/2), src.z) + var/south_portal = new /obj/effect/step_trigger/mobius_rift/seamless_portal(rift_turf, SOUTH) + portals["SOUTH"] = south_portal + rift_turf = locate(src.x + round(grid_size/2), src.y, src.z) + var/east_portal = new /obj/effect/step_trigger/mobius_rift/seamless_portal(rift_turf, EAST) + portals["EAST"] = east_portal + rift_turf = locate(src.x - round(grid_size/2), src.y, src.z) + var/west_portal = new /obj/effect/step_trigger/mobius_rift/seamless_portal(rift_turf, WEST) + portals["WEST"] = west_portal /obj/effect/mobius_rift/chamber/proc/set_portals(var/list/destinations) for (var/iter = 1 to portals.len) diff --git a/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm b/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm index 62b119ba2ef2..5fbaa19d44b8 100644 --- a/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm +++ b/maps/random_ruins/exoplanet_ruins/datacapsule/datacapsule.dm @@ -49,8 +49,8 @@ desc = "Impact resistant server rack. You might be able to pry a disk out." var/disk_looted -/obj/structure/backup_server/attackby(obj/item/W, mob/user, var/click_params) - if(IS_CROWBAR(W)) +/obj/structure/backup_server/attackby(obj/item/used_item, mob/user, var/click_params) + if(IS_CROWBAR(used_item)) if(disk_looted) to_chat(user, SPAN_WARNING("There's no disk in \the [src].")) else diff --git a/mods/content/matchmaking/relations.dm b/mods/content/matchmaking/relations.dm index 69f14f086b67..b1c60305caba 100644 --- a/mods/content/matchmaking/relations.dm +++ b/mods/content/matchmaking/relations.dm @@ -15,9 +15,9 @@ pref.relations = R.read("relations") pref.relations_info = R.read("relations_info") -/datum/category_item/player_setup_item/relations/save_character(datum/pref_record_writer/W) - W.write("relations", pref.relations) - W.write("relations_info", pref.relations_info) +/datum/category_item/player_setup_item/relations/save_character(datum/pref_record_writer/writer) + writer.write("relations", pref.relations) + writer.write("relations_info", pref.relations_info) /datum/category_item/player_setup_item/relations/sanitize_character() if(!pref.relations) diff --git a/mods/content/psionics/system/psionics/complexus/complexus_process.dm b/mods/content/psionics/system/psionics/complexus/complexus_process.dm index 44f3258b9cec..175269b56405 100644 --- a/mods/content/psionics/system/psionics/complexus/complexus_process.dm +++ b/mods/content/psionics/system/psionics/complexus/complexus_process.dm @@ -217,11 +217,11 @@ E.status &= ~ORGAN_TENDON_CUT return TRUE - for(var/datum/wound/W in E.wounds) - if(W.bleeding() && spend_power(heal_rate)) - to_chat(H, SPAN_NOTICE("Your autoredactive faculty knits together severed veins, stemming the bleeding from \a [W.desc] on your [E.name].")) - W.bleed_timer = 0 - W.clamped = TRUE + for(var/datum/wound/wound in E.wounds) + if(wound.bleeding() && spend_power(heal_rate)) + to_chat(H, SPAN_NOTICE("Your autoredactive faculty knits together severed veins, stemming the bleeding from \a [wound.desc] on your [E.name].")) + wound.bleed_timer = 0 + wound.clamped = TRUE E.status &= ~ORGAN_BLEEDING return diff --git a/mods/content/psionics/system/psionics/faculties/redaction.dm b/mods/content/psionics/system/psionics/faculties/redaction.dm index 3ac69fe16179..bc5ece1b7598 100644 --- a/mods/content/psionics/system/psionics/faculties/redaction.dm +++ b/mods/content/psionics/system/psionics/faculties/redaction.dm @@ -99,16 +99,16 @@ E.undislocate(skip_pain = TRUE) return TRUE - for(var/datum/wound/W in E.wounds) - if(W.bleeding()) - if(redaction_rank >= PSI_RANK_MASTER || W.wound_damage() < 30) + for(var/datum/wound/wound in E.wounds) + if(wound.bleeding()) + if(redaction_rank >= PSI_RANK_MASTER || wound.wound_damage() < 30) to_chat(user, SPAN_NOTICE("You knit together severed veins and broken flesh, stemming the bleeding.")) - W.bleed_timer = 0 - W.clamped = TRUE + wound.bleed_timer = 0 + wound.clamped = TRUE E.status &= ~ORGAN_BLEEDING return TRUE else - to_chat(user, SPAN_NOTICE("This [W.desc] is beyond your power to heal.")) + to_chat(user, SPAN_NOTICE("This [wound.desc] is beyond your power to heal.")) if(redaction_rank >= PSI_RANK_GRANDMASTER) for(var/obj/item/organ/internal/organ in E.internal_organs) diff --git a/mods/content/shackles/laws_pref.dm b/mods/content/shackles/laws_pref.dm index 308d2342b23a..23fcfa6a6e2a 100644 --- a/mods/content/shackles/laws_pref.dm +++ b/mods/content/shackles/laws_pref.dm @@ -23,9 +23,9 @@ pref.laws = R.read("laws") pref.is_shackled = R.read("is_shackled") -/datum/category_item/player_setup_item/law_pref/save_character(datum/pref_record_writer/W) - W.write("laws", pref.laws) - W.write("is_shackled", pref.is_shackled) +/datum/category_item/player_setup_item/law_pref/save_character(datum/pref_record_writer/writer) + writer.write("laws", pref.laws) + writer.write("is_shackled", pref.is_shackled) /datum/category_item/player_setup_item/law_pref/sanitize_character() if(!istype(pref.laws)) diff --git a/mods/content/supermatter/endgame_cascade/cascade_blob.dm b/mods/content/supermatter/endgame_cascade/cascade_blob.dm index 92b7c96b491e..5b716d4a4849 100644 --- a/mods/content/supermatter/endgame_cascade/cascade_blob.dm +++ b/mods/content/supermatter/endgame_cascade/cascade_blob.dm @@ -66,15 +66,15 @@ return TRUE return ..() -/turf/unsimulated/wall/cascade/attackby(obj/item/W, mob/user) - user.visible_message("\The [user] touches \a [W] to \the [src] as a silence fills the room...",\ - "You touch \the [W] to \the [src] when everything suddenly goes silent.\"\n\The [W] flashes into dust as you flinch away from \the [src].",\ +/turf/unsimulated/wall/cascade/attackby(obj/item/used_item, mob/user) + user.visible_message("\The [user] touches \a [used_item] to \the [src] as a silence fills the room...",\ + "You touch \the [used_item] to \the [src] when everything suddenly goes silent.\"\n\The [used_item] flashes into dust as you flinch away from \the [src].",\ "Everything suddenly goes silent.") playsound(src, 'sound/effects/supermatter.ogg', 50, 1) - user.drop_from_inventory(W) - Bumped(W) + user.drop_from_inventory(used_item) + Bumped(used_item) return TRUE /turf/unsimulated/wall/cascade/Entered(var/atom/movable/AM) diff --git a/mods/content/supermatter/machinery/supermatter.dm b/mods/content/supermatter/machinery/supermatter.dm index 2a876bd55ea4..e0a41706145b 100644 --- a/mods/content/supermatter/machinery/supermatter.dm +++ b/mods/content/supermatter/machinery/supermatter.dm @@ -624,27 +624,27 @@ var/global/list/supermatter_delam_accent_sounds = list( ui.open() ui.set_auto_update(1) -/obj/machinery/power/supermatter/attackby(obj/item/W, mob/user) +/obj/machinery/power/supermatter/attackby(obj/item/used_item, mob/user) - if(istype(W, /obj/item/stack/tape_roll/duct_tape)) - var/obj/item/stack/tape_roll/duct_tape/T = W + if(istype(used_item, /obj/item/stack/tape_roll/duct_tape)) + var/obj/item/stack/tape_roll/duct_tape/T = used_item if(!T.can_use(20)) to_chat(user, SPAN_WARNING("You need at least 20 [T.plural_name] to repair \the [src].")) return TRUE T.use(20) playsound(src, 'sound/effects/tape.ogg', 100, TRUE) - to_chat(user, SPAN_NOTICE("You begin to repair some of the damage to \the [src] with \the [W].")) + to_chat(user, SPAN_NOTICE("You begin to repair some of the damage to \the [src] with \the [used_item].")) damage = max(damage -10, 0) return TRUE // be nice, the extra duct tape if you have 21 or more doesn't turn to ash and irradiate you. - if(!QDELETED(W)) - user.visible_message(SPAN_WARNING("\The [user] touches \the [src] with \a [W] as silence fills the room..."),\ - SPAN_DANGER("You touch \the [W] to \the [src] when everything suddenly goes quiet."),\ + if(!QDELETED(used_item)) + user.visible_message(SPAN_WARNING("\The [user] touches \the [src] with \a [used_item] as silence fills the room..."),\ + SPAN_DANGER("You touch \the [used_item] to \the [src] when everything suddenly goes quiet."),\ SPAN_WARNING("Everything suddenly goes silent.")) - to_chat(user, SPAN_NOTICE("\The [W] flashes into dust as you flinch away from \the [src].")) - user.drop_from_inventory(W) - Consume(user, W, TRUE) + to_chat(user, SPAN_NOTICE("\The [used_item] flashes into dust as you flinch away from \the [src].")) + user.drop_from_inventory(used_item) + Consume(user, used_item, TRUE) user.apply_damage(150, IRRADIATE, damage_flags = DAM_DISPERSED) return TRUE diff --git a/mods/content/xenobiology/slime/_slime.dm b/mods/content/xenobiology/slime/_slime.dm index 71fda53a3319..37c5ebfb51bc 100644 --- a/mods/content/xenobiology/slime/_slime.dm +++ b/mods/content/xenobiology/slime/_slime.dm @@ -269,15 +269,15 @@ return ..() -/mob/living/slime/attackby(var/obj/item/W, var/mob/user) - var/force = W.expend_attack_force(user) +/mob/living/slime/attackby(var/obj/item/used_item, var/mob/user) + var/force = used_item.expend_attack_force(user) if(force > 0) var/datum/mob_controller/slime/slime_ai = ai if(istype(slime_ai)) slime_ai.attacked += 10 slime_ai.adjust_friendship(user, -5) if(stat == CONSCIOUS && prob(25)) //Only run this check if we're alive or otherwise motile, otherwise surgery will be agonizing for xenobiologists. - to_chat(user, SPAN_WARNING("\The [W] passes right through \the [src]!")) + to_chat(user, SPAN_WARNING("\The [used_item] passes right through \the [src]!")) return TRUE . = ..() if(feeding_on && prob(force * 5)) diff --git a/mods/gamemodes/cult/cultify/turf.dm b/mods/gamemodes/cult/cultify/turf.dm index 77d554cbcea2..428ec614a65e 100644 --- a/mods/gamemodes/cult/cultify/turf.dm +++ b/mods/gamemodes/cult/cultify/turf.dm @@ -51,10 +51,10 @@ cult.remove_cultiness(CULTINESS_PER_TURF) . = ..() -/turf/wall/cult/can_join_with(var/turf/wall/W) - if(material && W.material && material.icon_base == W.material.icon_base) +/turf/wall/cult/can_join_with(var/turf/wall/wall) + if(material && wall.material && material.icon_base == wall.material.icon_base) return FALSE - else if(istype(W, /turf/wall)) + else if(istype(wall, /turf/wall)) return TRUE return FALSE diff --git a/mods/gamemodes/cult/ghosts.dm b/mods/gamemodes/cult/ghosts.dm index 9d9763e6bbf7..2958d3931377 100644 --- a/mods/gamemodes/cult/ghosts.dm +++ b/mods/gamemodes/cult/ghosts.dm @@ -88,7 +88,7 @@ return var/num_doodles = 0 - for(var/obj/effect/decal/cleanable/blood/writing/W in T) + for(var/obj/effect/decal/cleanable/blood/writing/writing in T) num_doodles++ if(num_doodles > 4) to_chat(src, "There is no space to write on!") @@ -124,15 +124,15 @@ message += "-" to_chat(src, "You ran out of blood to write with!") - var/obj/effect/decal/cleanable/blood/writing/W = new(T) - W.basecolor = doodle_color - W.update_icon() - W.message = message - W.add_hiddenprint(src) + var/obj/effect/decal/cleanable/blood/writing/writing = new(T) + writing.basecolor = doodle_color + writing.update_icon() + writing.message = message + writing.add_hiddenprint(src) if(!bloodless) - W.visible_message("Invisible fingers crudely paint something in blood on \the [T].") + writing.visible_message("Invisible fingers crudely paint something in blood on \the [T].") else - W.visible_message("Blood appears out of nowhere as invisible fingers crudely paint something on \the [T].") + writing.visible_message("Blood appears out of nowhere as invisible fingers crudely paint something on \the [T].") log_admin("[src] ([src.key]) used ghost magic to write '[message]' - [x]-[y]-[z]") diff --git a/mods/gamemodes/cult/structures.dm b/mods/gamemodes/cult/structures.dm index 38bfdda57c09..d2cd63b3cc1d 100644 --- a/mods/gamemodes/cult/structures.dm +++ b/mods/gamemodes/cult/structures.dm @@ -27,8 +27,8 @@ attackpylon(user, damage) return TRUE -/obj/structure/cult/pylon/attackby(obj/item/W, mob/user) - attackpylon(user, W.expend_attack_force(user)) +/obj/structure/cult/pylon/attackby(obj/item/used_item, mob/user) + attackpylon(user, used_item.expend_attack_force(user)) return TRUE /obj/structure/cult/pylon/proc/attackpylon(mob/user, var/damage) diff --git a/mods/gamemodes/heist/special_role.dm b/mods/gamemodes/heist/special_role.dm index e56fb6bd4b11..81f043b491f9 100644 --- a/mods/gamemodes/heist/special_role.dm +++ b/mods/gamemodes/heist/special_role.dm @@ -20,11 +20,11 @@ var/list/outfits_per_species /decl/special_role/raider/update_access(var/mob/living/player) - for(var/obj/item/wallet/W in player.contents) - for(var/obj/item/card/id/id in W.contents) + for(var/obj/item/wallet/wallet in player.contents) + for(var/obj/item/card/id/id in wallet.contents) id.SetName("[player.real_name]'s Passport") id.registered_name = player.real_name - W.SetName("[initial(W.name)] ([id.name])") + wallet.SetName("[initial(wallet.name)] ([id.name])") /decl/special_role/raider/create_global_objectives() diff --git a/mods/species/drakes/drake_abilities_friendly.dm b/mods/species/drakes/drake_abilities_friendly.dm index 55d0ccaabd9f..658adbe07ebd 100644 --- a/mods/species/drakes/drake_abilities_friendly.dm +++ b/mods/species/drakes/drake_abilities_friendly.dm @@ -95,10 +95,10 @@ var/global/list/_wounds_being_tended_by_drakes = list() var/datum/reagents/bloodstream = friend.get_injected_reagents() if(bloodstream) bloodstream.add_reagent(/decl/material/liquid/sifsap, rand(1,2)) - for (var/datum/wound/W in E.wounds) - W.clamped = TRUE // use this rather than bandaged to avoid message weirdness - W.salve() - W.disinfect() + for (var/datum/wound/wound in E.wounds) + wound.clamped = TRUE // use this rather than bandaged to avoid message weirdness + wound.salve() + wound.disinfect() // Everyone else is just poisoned. else if(!friend.has_trait(/decl/trait/sivian_biochemistry)) friend.take_damage(rand(1,2), TOX) From bbd66b2f6da03338af4ddf98b4b7e927794afbe1 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 18 Feb 2025 17:23:30 +1100 Subject: [PATCH 024/512] Auditing remaining attackby() overrides to use used_item. --- code/_onclick/click.dm | 2 +- code/_onclick/item_attack.dm | 2 +- code/game/atoms_movable_overlay.dm | 4 +- code/game/machinery/CableLayer.dm | 8 +- code/game/machinery/Sleeper.dm | 14 +-- .../machine_construction/_construction.dm | 4 +- .../machine_construction/airlock.dm | 14 +-- .../machine_construction/computer.dm | 2 +- .../machine_construction/default.dm | 26 ++--- .../machine_construction/frame.dm | 36 +++--- .../machine_construction/item_chassis.dm | 4 +- .../machine_construction/pipe.dm | 14 +-- .../machine_construction/wall_frame.dm | 62 +++++------ .../_machines_base/machinery_components.dm | 10 +- .../stock_parts/power/battery.dm | 12 +- .../stock_parts/power/terminal.dm | 6 +- code/game/machinery/atmoalter/scrubber.dm | 10 +- code/game/machinery/computer/ai_core.dm | 40 +++---- code/game/machinery/computer/guestpass.dm | 24 ++-- code/game/machinery/computer/law.dm | 9 +- code/game/machinery/computer/message.dm | 4 +- code/game/machinery/computer/shuttle.dm | 18 +-- code/game/machinery/doors/_door.dm | 20 ++-- code/game/machinery/doors/airlock.dm | 35 +++--- code/game/machinery/doors/airlock_subtypes.dm | 4 +- code/game/machinery/doors/blast_door.dm | 16 +-- code/game/machinery/doors/firedoor.dm | 38 +++---- .../game/machinery/doors/firedoor_assembly.dm | 10 +- code/game/machinery/doors/windowdoor.dm | 4 +- .../kitchen/cooking_machines/_cooker.dm | 12 +- code/game/machinery/kitchen/icecream.dm | 30 ++--- code/game/machinery/kitchen/microwave.dm | 66 +++++------ code/game/machinery/lightswitch.dm | 4 +- code/game/machinery/message_server.dm | 6 +- code/game/machinery/navbeacon.dm | 6 +- code/game/machinery/nuclear_bomb.dm | 42 +++---- code/game/machinery/portable_turret.dm | 12 +- code/game/machinery/recharger.dm | 20 ++-- code/game/machinery/requests_console.dm | 12 +- code/game/machinery/seed_extractor.dm | 24 ++-- code/game/machinery/self_destruct_storage.dm | 20 ++-- .../machinery/smartfridge/_smartfridge.dm | 74 ++++++------ code/game/machinery/suit_cycler.dm | 28 ++--- code/game/machinery/teleporter.dm | 20 ++-- code/game/machinery/turrets/_turrets.dm | 14 +-- code/game/machinery/turrets/network_turret.dm | 6 +- code/game/objects/effects/chem/foam.dm | 6 +- .../objects/effects/decals/Cleanable/misc.dm | 12 +- .../items/books/skill/_skill_custom.dm | 14 +-- code/game/objects/items/devices/powersink.dm | 4 +- .../objects/items/devices/radio/beacon.dm | 6 +- .../objects/items/devices/taperecorder.dm | 26 ++--- .../objects/items/devices/transfer_valve.dm | 24 ++-- code/game/objects/items/devices/tvcamera.dm | 11 +- code/game/objects/items/paintkit.dm | 12 +- code/game/objects/items/weapons/cards_ids.dm | 10 +- code/game/objects/items/weapons/ecigs.dm | 10 +- code/game/objects/items/weapons/explosives.dm | 6 +- code/game/objects/items/weapons/mop.dm | 4 +- code/game/objects/items/weapons/soap.dm | 8 +- code/game/objects/structures/barsign.dm | 4 +- .../game/objects/structures/beds/rollerbed.dm | 10 +- code/game/objects/structures/bedsheet_bin.dm | 30 ++--- code/game/objects/structures/catwalk.dm | 26 ++--- code/game/objects/structures/charge_pylon.dm | 6 +- .../objects/structures/chemistry/heater.dm | 10 +- .../crates_lockers/closets/statue.dm | 6 +- code/game/objects/structures/drain.dm | 14 +-- code/game/objects/structures/extinguisher.dm | 10 +- code/game/objects/structures/fences.dm | 10 +- .../objects/structures/fireaxe_cabinet.dm | 16 +-- code/game/objects/structures/fires.dm | 30 ++--- code/game/objects/structures/flora/_flora.dm | 12 +- code/game/objects/structures/flora/plant.dm | 8 +- code/game/objects/structures/ironing_board.dm | 28 ++--- code/game/objects/structures/janicart.dm | 70 ++++++------ code/game/objects/structures/lattice.dm | 18 +-- code/game/objects/structures/memorial.dm | 12 +- code/game/objects/structures/mop_bucket.dm | 12 +- code/game/objects/structures/produce_bin.dm | 16 +-- code/game/objects/structures/racks.dm | 6 +- code/game/objects/structures/rubble.dm | 22 ++-- code/game/objects/structures/safe.dm | 24 ++-- code/game/objects/structures/seaweed.dm | 4 +- code/game/objects/structures/stasis_cage.dm | 6 +- .../game/objects/structures/tank_dispenser.dm | 14 +-- .../game/objects/structures/under_wardrobe.dm | 6 +- code/game/objects/structures/watercloset.dm | 97 ++++++++-------- .../turfs/floors/subtypes/floor_static.dm | 8 +- code/game/turfs/open/_open.dm | 16 +-- code/game/turfs/space/space.dm | 12 +- code/game/turfs/space/transit.dm | 2 +- code/modules/assembly/assembly.dm | 10 +- .../components/unary/outlet_injector.dm | 4 +- code/modules/banners/_banner_frame.dm | 14 +-- .../brain_interface/_brain_interface.dm | 16 +-- code/modules/butchery/butchery_hook.dm | 12 +- code/modules/clothing/_clothing.dm | 24 ++-- .../modules/clothing/_clothing_accessories.dm | 10 +- code/modules/clothing/badges/holobadge.dm | 6 +- .../clothing/gloves/jewelry/rings/_ring.dm | 6 +- code/modules/clothing/masks/cig_crafting.dm | 10 +- code/modules/clothing/shoes/_shoes.dm | 22 ++-- .../tools/sample_kits/_sample.dm | 8 +- code/modules/economy/cael/ATM.dm | 38 +++---- code/modules/economy/cael/Accounts_DB.dm | 8 +- code/modules/economy/cael/EFTPOS.dm | 12 +- code/modules/fabrication/fabricator_intake.dm | 42 +++---- code/modules/games/boardgame.dm | 48 ++++---- code/modules/games/cards.dm | 16 +-- code/modules/holodeck/HolodeckObjects.dm | 34 +++--- code/modules/hydroponics/seed_storage.dm | 61 +++++----- code/modules/hydroponics/trays/tray_soil.dm | 14 +-- code/modules/implants/implant_types/chem.dm | 8 +- code/modules/implants/implantcase.dm | 20 ++-- code/modules/implants/implanter.dm | 8 +- code/modules/implants/implantpad.dm | 14 +-- .../integrated_electronics/core/assemblies.dm | 98 ++++++++-------- .../integrated_electronics/core/printer.dm | 58 +++++----- .../subtypes/manipulation.dm | 105 +++++++++--------- code/modules/locks/lock_construct.dm | 14 +-- code/modules/mechs/components/_components.dm | 14 +-- code/modules/mechs/components/arms.dm | 8 +- code/modules/mechs/components/body.dm | 20 ++-- code/modules/mechs/components/frame.dm | 54 ++++----- code/modules/mechs/components/head.dm | 28 ++--- code/modules/mechs/components/legs.dm | 8 +- .../mechs/equipment/combat_projectile.dm | 8 +- code/modules/mechs/equipment/medical.dm | 16 +-- code/modules/mechs/equipment/utility.dm | 6 +- code/modules/mechs/mech_interaction.dm | 50 ++++----- .../mining/machinery/material_extractor.dm | 12 +- code/modules/mob/living/bot/bot.dm | 8 +- code/modules/mob/living/bot/medibot.dm | 10 +- code/modules/mob/living/bot/mulebot.dm | 2 +- code/modules/mob/living/bot/remotebot.dm | 20 ++-- code/modules/mob/living/bot/secbot.dm | 2 +- .../living/simple_animal/_simple_animal.dm | 6 +- .../mob/living/simple_animal/crow/crow.dm | 4 +- .../living/simple_animal/friendly/corgi.dm | 6 +- .../simple_animal/friendly/farm_animals.dm | 10 +- .../mob/living/simple_animal/hostile/bear.dm | 2 +- .../simple_animal/hostile/retaliate/parrot.dm | 10 +- .../modular_computers/hardware/card_slot.dm | 6 +- .../hardware/charge_stick_slot.dm | 6 +- .../modular_computers/hardware/disk_slot.dm | 6 +- .../modular_computers/hardware/drive_slot.dm | 6 +- .../modular_computers/hardware/lan_port.dm | 8 +- .../modular_computers/laptop_vendor.dm | 5 +- code/modules/multiz/ladder.dm | 32 +++--- .../overmap/contacts/contact_sensors.dm | 4 +- code/modules/overmap/disperser/disperser.dm | 6 +- code/modules/overmap/ftl_shunt/core.dm | 26 ++--- .../overmap/ships/machines/fusion_thruster.dm | 4 +- .../overmap/ships/machines/gas_thruster.dm | 4 +- .../overmap/ships/machines/ion_thruster.dm | 4 +- code/modules/paperwork/faxmachine.dm | 22 ++-- code/modules/paperwork/filingcabinet.dm | 18 +-- code/modules/paperwork/paper.dm | 60 +++++----- code/modules/paperwork/paper_sticky.dm | 6 +- code/modules/paperwork/paperbin.dm | 18 +-- code/modules/paperwork/photocopier.dm | 6 +- code/modules/paperwork/photography.dm | 28 ++--- code/modules/persistence/graffiti.dm | 8 +- code/modules/persistence/noticeboards.dm | 12 +- code/modules/pointdefense/pointdefense.dm | 8 +- code/modules/power/floorlamp.dm | 10 +- .../power/fuel_assembly/fuel_compressor.dm | 4 +- .../power/fusion/consoles/_consoles.dm | 4 +- .../modules/power/fusion/kinetic_harvester.dm | 4 +- code/modules/power/heavycable.dm | 14 +-- code/modules/power/lighting.dm | 12 +- code/modules/power/port_gen.dm | 16 +-- .../projectiles/guns/launcher/foam_gun.dm | 16 +-- .../guns/launcher/grenade_launcher.dm | 9 +- .../projectiles/guns/launcher/rocket.dm | 12 +- .../projectiles/guns/launcher/syringe_gun.dm | 14 +-- .../projectiles/guns/magnetic/magnetic.dm | 20 ++-- .../projectiles/guns/projectile/automatic.dm | 6 +- .../projectiles/guns/projectile/dartgun.dm | 6 +- .../projectiles/guns/projectile/shotgun.dm | 8 +- code/modules/reagents/Chemistry-Grinder.dm | 74 ++++++------ code/modules/reagents/Chemistry-Machinery.dm | 16 +-- code/modules/reagents/dispenser/dispenser2.dm | 12 +- .../reagents/heat_sources/_heat_source.dm | 24 ++-- .../reagents/reagent_containers/bucket.dm | 12 +- .../drinkingglass/extras.dm | 12 +- .../reagents/reagent_containers/food/fish.dm | 6 +- .../food/sliceable/pizza/pizza_box.dm | 28 ++--- .../reagents/reagent_containers/food/sushi.dm | 56 +++++----- .../reagents/reagent_containers/inhaler.dm | 6 +- .../reagents/reagent_containers/mortar.dm | 20 ++-- .../reagents/reagent_containers/syringes.dm | 2 +- code/modules/recycling/conveyor2.dm | 16 +-- .../recycling/disposal-construction.dm | 8 +- code/modules/recycling/disposal.dm | 42 +++---- code/modules/recycling/disposalpipe.dm | 26 ++--- code/modules/recycling/sortingmachinery.dm | 8 +- .../research/design_database_analyzer.dm | 18 +-- code/modules/sealant_gun/sealant_injector.dm | 14 +-- code/modules/sealant_gun/sealant_rack.dm | 14 +-- code/modules/shield_generators/shield.dm | 4 +- code/modules/shieldgen/emergency_shield.dm | 4 +- code/modules/shieldgen/shieldwallgen.dm | 6 +- code/modules/shuttles/docking_beacon.dm | 4 +- .../Synthesizer/synthesizer.dm | 4 +- code/modules/vehicles/engine.dm | 20 ++-- code/modules/xenoarcheaology/boulder.dm | 14 +-- .../xenoarcheaology/finds/strange_rock.dm | 12 +- .../machinery/artifact_harvester.dm | 10 +- .../machinery/geosample_scanner.dm | 24 ++-- .../tools/ano_device_battery.dm | 10 +- mods/content/beekeeping/hives/_hive.dm | 32 +++--- mods/content/xenobiology/slime/items.dm | 20 ++-- .../cult/mobs/constructs/soulstone.dm | 22 ++-- .../dionaea/mob/gestalt/gestalt_attacks.dm | 4 +- mods/species/ascent/effects/razorweb.dm | 12 +- 217 files changed, 1840 insertions(+), 1844 deletions(-) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index d3692ea62f06..7bdd7b8f928b 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -44,7 +44,7 @@ is receiving it. The most common are: * mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves - * atom/attackby(item,user) - used only when adjacent + * atom/attackby(used_item,user) - used only when adjacent * item/afterattack(atom,user,adjacent,params) - used both ranged and adjacent * mob/RangedAttack(atom,params) - used only ranged, only used for tk and laser eyes but could be changed */ diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 5634e0385d39..f38f1a25e243 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -48,7 +48,7 @@ avoid code duplication. This includes items that may sometimes act as a standard return FALSE -/atom/movable/attackby(used_item, mob/user) +/atom/movable/attackby(obj/item/used_item, mob/user) . = ..() if(!.) return bash(used_item,user) diff --git a/code/game/atoms_movable_overlay.dm b/code/game/atoms_movable_overlay.dm index c6beb4d1becd..9f290edc35f7 100644 --- a/code/game/atoms_movable_overlay.dm +++ b/code/game/atoms_movable_overlay.dm @@ -39,9 +39,9 @@ master = null . = ..() -/atom/movable/overlay/attackby(obj/item/I, mob/user) +/atom/movable/overlay/attackby(obj/item/used_item, mob/user) if (master) - return master.attackby(I, user) + return master.attackby(used_item, user) return TRUE /atom/movable/overlay/attack_hand(mob/user) diff --git a/code/game/machinery/CableLayer.dm b/code/game/machinery/CableLayer.dm index e9da96a9a367..ee1ee91f4aa3 100644 --- a/code/game/machinery/CableLayer.dm +++ b/code/game/machinery/CableLayer.dm @@ -26,17 +26,17 @@ user.visible_message("\The [user] [!on?"dea":"a"]ctivates \the [src].", "You switch [src] [on? "on" : "off"]") return TRUE -/obj/machinery/cablelayer/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/stack/cable_coil)) +/obj/machinery/cablelayer/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/stack/cable_coil)) - var/result = load_cable(O) + var/result = load_cable(used_item) if(!result) to_chat(user, "\The [src]'s cable reel is full.") else to_chat(user, "You load [result] lengths of cable into [src].") return TRUE - if(IS_WIRECUTTER(O)) + if(IS_WIRECUTTER(used_item)) if(cable && cable.amount) var/m = round(input(user,"Please specify the length of cable to cut","Cut cable",min(cable.amount,30)) as num, 1) m = min(m, cable.amount) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 00b91ddfdc76..edfca51d3e53 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -303,17 +303,17 @@ updateUsrDialog() go_out() -/obj/machinery/sleeper/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/chems/chem_disp_cartridge)) - add_reagent_canister(user, I) +/obj/machinery/sleeper/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/chems/chem_disp_cartridge)) + add_reagent_canister(user, used_item) return TRUE - if(istype(I, /obj/item/chems/glass)) + if(istype(used_item, /obj/item/chems/glass)) add_fingerprint(user) if(!beaker) - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - beaker = I - user.visible_message(SPAN_NOTICE("\The [user] adds \a [I] to \the [src]."), SPAN_NOTICE("You add \a [I] to \the [src].")) + beaker = used_item + user.visible_message(SPAN_NOTICE("\The [user] adds \a [used_item] to \the [src]."), SPAN_NOTICE("You add \a [used_item] to \the [src].")) else to_chat(user, SPAN_WARNING("\The [src] has a beaker already.")) return TRUE diff --git a/code/game/machinery/_machines_base/machine_construction/_construction.dm b/code/game/machinery/_machines_base/machine_construction/_construction.dm index fa819a58c1a6..8ae207901bbc 100644 --- a/code/game/machinery/_machines_base/machine_construction/_construction.dm +++ b/code/game/machinery/_machines_base/machine_construction/_construction.dm @@ -85,10 +85,10 @@ PRINT_STACK_TRACE("Machine [log_info_line(machine)] violated the state assumptions of the construction state [type]!") machine.attack_hand(user) -/decl/machine_construction/proc/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/proc/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if(!validate_state(machine)) PRINT_STACK_TRACE("Machine [log_info_line(machine)] violated the state assumptions of the construction state [type]!") - return machine.attackby(I, user) + return machine.attackby(used_item, user) return FALSE /decl/machine_construction/proc/mechanics_info() diff --git a/code/game/machinery/_machines_base/machine_construction/airlock.dm b/code/game/machinery/_machines_base/machine_construction/airlock.dm index 27f29d03070d..1d8851614bb7 100644 --- a/code/game/machinery/_machines_base/machine_construction/airlock.dm +++ b/code/game/machinery/_machines_base/machine_construction/airlock.dm @@ -3,22 +3,22 @@ down_state = /decl/machine_construction/default/panel_open/door var/hacking_state = /decl/machine_construction/default/panel_closed/door/hacking -/decl/machine_construction/default/panel_closed/door/attackby(obj/item/I, mob/user, obj/machinery/machine) - if(IS_SCREWDRIVER(I)) +/decl/machine_construction/default/panel_closed/door/attackby(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_SCREWDRIVER(used_item)) TRANSFER_STATE(hacking_state) playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1) to_chat(user, SPAN_NOTICE("You release some of the logic wiring on \the [machine]. The cover panel remains closed.")) machine.update_icon() return TRUE - if(IS_WRENCH(I)) + if(IS_WRENCH(used_item)) TRANSFER_STATE(down_state) playsound(get_turf(machine), 'sound/items/Crowbar.ogg', 50, 1) machine.panel_open = TRUE to_chat(user, SPAN_NOTICE("You open the main cover panel on \the [machine], exposing the internals.")) machine.queue_icon_update() return TRUE - if(istype(I, /obj/item/part_replacer)) - var/obj/item/part_replacer/replacer = I + if(istype(used_item, /obj/item/part_replacer)) + var/obj/item/part_replacer/replacer = used_item if(replacer.remote_interaction) machine.part_replacement(user, replacer) for(var/line in machine.get_part_info_strings(user)) @@ -35,8 +35,8 @@ /decl/machine_construction/default/panel_closed/door/hacking up_state = /decl/machine_construction/default/panel_closed/door -/decl/machine_construction/default/panel_closed/door/hacking/attackby(obj/item/I, mob/user, obj/machinery/machine) - if(IS_SCREWDRIVER(I)) +/decl/machine_construction/default/panel_closed/door/hacking/attackby(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_SCREWDRIVER(used_item)) TRANSFER_STATE(up_state) playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1) to_chat(user, SPAN_NOTICE("You tuck the exposed wiring back into \the [machine] and screw the hatch back into place.")) diff --git a/code/game/machinery/_machines_base/machine_construction/computer.dm b/code/game/machinery/_machines_base/machine_construction/computer.dm index 684f0f4b8c18..797f16ad1ef2 100644 --- a/code/game/machinery/_machines_base/machine_construction/computer.dm +++ b/code/game/machinery/_machines_base/machine_construction/computer.dm @@ -4,7 +4,7 @@ down_state = /decl/machine_construction/default/panel_open/computer needs_board = "computer" -/decl/machine_construction/default/panel_closed/computer/no_deconstruct/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/default/panel_closed/computer/no_deconstruct/attackby(obj/item/used_item, mob/user, obj/machinery/machine) return FALSE /decl/machine_construction/default/panel_open/computer diff --git a/code/game/machinery/_machines_base/machine_construction/default.dm b/code/game/machinery/_machines_base/machine_construction/default.dm index 928954909b4e..727e30cf0315 100644 --- a/code/game/machinery/_machines_base/machine_construction/default.dm +++ b/code/game/machinery/_machines_base/machine_construction/default.dm @@ -5,7 +5,7 @@ var/up_state var/down_state -/decl/machine_construction/default/no_deconstruct/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/default/no_deconstruct/attackby(obj/item/used_item, mob/user, obj/machinery/machine) . = FALSE /decl/machine_construction/default/panel_closed @@ -21,18 +21,18 @@ if(!.) try_change_state(machine, down_state) -/decl/machine_construction/default/panel_closed/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/default/panel_closed/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if((. = ..())) return - if(IS_SCREWDRIVER(I)) + if(IS_SCREWDRIVER(used_item)) TRANSFER_STATE(down_state) playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1) machine.panel_open = TRUE to_chat(user, SPAN_NOTICE("You open the maintenance hatch of \the [machine].")) machine.update_icon() return TRUE - if(istype(I, /obj/item/part_replacer)) - var/obj/item/part_replacer/replacer = I + if(istype(used_item, /obj/item/part_replacer)) + var/obj/item/part_replacer/replacer = used_item if(replacer.remote_interaction) machine.part_replacement(user, replacer) for(var/line in machine.get_part_info_strings(user)) @@ -62,28 +62,28 @@ if(!.) try_change_state(machine, up_state) -/decl/machine_construction/default/panel_open/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/default/panel_open/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if((. = ..())) return - if(IS_CROWBAR(I)) + if(IS_CROWBAR(used_item)) TRANSFER_STATE(down_state) playsound(get_turf(machine), 'sound/items/Crowbar.ogg', 50, 1) machine.visible_message(SPAN_NOTICE("\The [user] deconstructs \the [machine].")) machine.dismantle() return - if(IS_SCREWDRIVER(I)) + if(IS_SCREWDRIVER(used_item)) TRANSFER_STATE(up_state) playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1) machine.panel_open = FALSE to_chat(user, SPAN_NOTICE("You close the maintenance hatch of \the [machine].")) machine.update_icon() return TRUE - if(istype(I, /obj/item/part_replacer)) - return machine.part_replacement(user, I) - if(IS_WRENCH(I)) + if(istype(used_item, /obj/item/part_replacer)) + return machine.part_replacement(user, used_item) + if(IS_WRENCH(used_item)) return machine.part_removal(user) - if(istype(I)) - return machine.part_insertion(user, I) + if(istype(used_item)) + return machine.part_insertion(user, used_item) return FALSE /decl/machine_construction/default/panel_open/mechanics_info() diff --git a/code/game/machinery/_machines_base/machine_construction/frame.dm b/code/game/machinery/_machines_base/machine_construction/frame.dm index 33b0630b3a96..e12a6e5cc80b 100644 --- a/code/game/machinery/_machines_base/machine_construction/frame.dm +++ b/code/game/machinery/_machines_base/machine_construction/frame.dm @@ -11,15 +11,15 @@ else try_change_state(machine, /decl/machine_construction/frame/wrenched) -/decl/machine_construction/frame/unwrenched/attackby(obj/item/I, mob/user, obj/machinery/machine) - if(IS_WRENCH(I)) +/decl/machine_construction/frame/unwrenched/attackby(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_WRENCH(used_item)) playsound(machine.loc, 'sound/items/Ratchet.ogg', 50, 1) if(do_after(user, 20, machine)) TRANSFER_STATE(/decl/machine_construction/frame/wrenched) to_chat(user, "You wrench \the [machine] into place.") machine.anchored = TRUE - if(IS_WELDER(I)) - var/obj/item/weldingtool/welder = I + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(!welder.weld(0, user)) to_chat(user, "The welding tool must be on to complete this task.") return TRUE @@ -48,16 +48,16 @@ else try_change_state(machine, /decl/machine_construction/frame/unwrenched) -/decl/machine_construction/frame/wrenched/attackby(obj/item/I, mob/user, obj/machinery/machine) - if(IS_WRENCH(I)) +/decl/machine_construction/frame/wrenched/attackby(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_WRENCH(used_item)) playsound(machine.loc, 'sound/items/Ratchet.ogg', 50, 1) if(do_after(user, 20, machine)) TRANSFER_STATE(/decl/machine_construction/frame/unwrenched) to_chat(user, "You unfasten \the [machine].") machine.anchored = FALSE return TRUE - if(IS_COIL(I)) - var/obj/item/stack/cable_coil/C = I + if(IS_COIL(used_item)) + var/obj/item/stack/cable_coil/C = used_item if(C.get_amount() < 5) to_chat(user, "You need five lengths of cable to add them to \the [machine].") return TRUE @@ -85,20 +85,20 @@ else try_change_state(machine, /decl/machine_construction/frame/unwrenched) -/decl/machine_construction/frame/awaiting_circuit/attackby(obj/item/I, mob/user, obj/machinery/constructable_frame/machine) - if(istype(I, /obj/item/stock_parts/circuitboard)) - var/obj/item/stock_parts/circuitboard/circuit = I +/decl/machine_construction/frame/awaiting_circuit/attackby(obj/item/used_item, mob/user, obj/machinery/constructable_frame/machine) + if(istype(used_item, /obj/item/stock_parts/circuitboard)) + var/obj/item/stock_parts/circuitboard/circuit = used_item if(circuit.board_type == machine.expected_machine_type) - if(user.canUnEquip(I)) + if(user.canUnEquip(used_item)) TRANSFER_STATE(/decl/machine_construction/frame/awaiting_parts) - user.try_unequip(I, machine) + user.try_unequip(used_item, machine) playsound(machine.loc, 'sound/items/Deconstruct.ogg', 50, 1) to_chat(user, "You add the circuit board to \the [machine].") - machine.circuit = I + machine.circuit = used_item else to_chat(user, "This frame does not accept circuit boards of this type!") return TRUE - if(IS_WIRECUTTER(I)) + if(IS_WIRECUTTER(used_item)) TRANSFER_STATE(/decl/machine_construction/frame/wrenched) playsound(machine.loc, 'sound/items/Wirecutter.ogg', 50, 1) to_chat(user, "You remove the cables.") @@ -122,15 +122,15 @@ else try_change_state(machine, /decl/machine_construction/frame/unwrenched) -/decl/machine_construction/frame/awaiting_parts/attackby(obj/item/I, mob/user, obj/machinery/constructable_frame/machine) - if(IS_CROWBAR(I)) +/decl/machine_construction/frame/awaiting_parts/attackby(obj/item/used_item, mob/user, obj/machinery/constructable_frame/machine) + if(IS_CROWBAR(used_item)) TRANSFER_STATE(/decl/machine_construction/frame/awaiting_circuit) playsound(machine.loc, 'sound/items/Crowbar.ogg', 50, 1) machine.circuit.dropInto(machine.loc) machine.circuit = null to_chat(user, "You remove the circuit board.") return TRUE - if(IS_SCREWDRIVER(I)) + if(IS_SCREWDRIVER(used_item)) playsound(machine.loc, 'sound/items/Screwdriver.ogg', 50, 1) var/obj/machinery/new_machine = new machine.circuit.build_path(machine.loc, machine.dir, FALSE) machine.circuit.construct(new_machine) diff --git a/code/game/machinery/_machines_base/machine_construction/item_chassis.dm b/code/game/machinery/_machines_base/machine_construction/item_chassis.dm index 234319a1bca2..e97190d5d71a 100644 --- a/code/game/machinery/_machines_base/machine_construction/item_chassis.dm +++ b/code/game/machinery/_machines_base/machine_construction/item_chassis.dm @@ -5,8 +5,8 @@ down_state = /decl/machine_construction/default/panel_open/item_chassis -/decl/machine_construction/default/panel_closed/item_chassis/attackby(obj/item/I, mob/user, obj/machinery/machine) - if(IS_WRENCH(I)) +/decl/machine_construction/default/panel_closed/item_chassis/attackby(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_WRENCH(used_item)) TRANSFER_STATE(/decl/machine_construction/default/deconstructed) playsound(get_turf(machine), 'sound/items/Ratchet.ogg', 50, 1) machine.visible_message(SPAN_NOTICE("\The [user] deconstructs \the [machine].")) diff --git a/code/game/machinery/_machines_base/machine_construction/pipe.dm b/code/game/machinery/_machines_base/machine_construction/pipe.dm index 9434855686c4..010428a50e47 100644 --- a/code/game/machinery/_machines_base/machine_construction/pipe.dm +++ b/code/game/machinery/_machines_base/machine_construction/pipe.dm @@ -6,26 +6,26 @@ /decl/machine_construction/pipe/state_is_valid(obj/machinery/machine) return TRUE -/decl/machine_construction/pipe/proc/deconstruct_transition(obj/item/I, mob/user, obj/machinery/machine) - if(IS_WRENCH(I)) +/decl/machine_construction/pipe/proc/deconstruct_transition(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_WRENCH(used_item)) TRANSFER_STATE(/decl/machine_construction/default/deconstructed) playsound(get_turf(machine), 'sound/items/Ratchet.ogg', 50, 1) machine.visible_message(SPAN_NOTICE("\The [user] unfastens \the [machine].")) machine.dismantle() -/decl/machine_construction/pipe/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/pipe/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if((. = ..())) return - return deconstruct_transition(I, user, machine) + return deconstruct_transition(used_item, user, machine) /decl/machine_construction/pipe/mechanics_info() . = list() . += "Use a wrench to deconstruct the machine" // Same, but uses different tool. -/decl/machine_construction/pipe/welder/deconstruct_transition(obj/item/I, mob/user, obj/machinery/machine) - if(IS_WELDER(I)) - var/obj/item/weldingtool/welder = I +/decl/machine_construction/pipe/welder/deconstruct_transition(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(!welder.isOn()) return FALSE if(!welder.weld(0,user)) diff --git a/code/game/machinery/_machines_base/machine_construction/wall_frame.dm b/code/game/machinery/_machines_base/machine_construction/wall_frame.dm index 9c01dcc5db7c..830c3da857e9 100644 --- a/code/game/machinery/_machines_base/machine_construction/wall_frame.dm +++ b/code/game/machinery/_machines_base/machine_construction/wall_frame.dm @@ -25,20 +25,20 @@ else try_change_state(machine, newly_built_state) -/decl/machine_construction/wall_frame/panel_closed/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/wall_frame/panel_closed/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if((. = ..())) return - if(istype(I, /obj/item/part_replacer)) - var/obj/item/part_replacer/replacer = I + if(istype(used_item, /obj/item/part_replacer)) + var/obj/item/part_replacer/replacer = used_item if(replacer.remote_interaction) machine.part_replacement(user, replacer) for(var/line in machine.get_part_info_strings(user)) to_chat(user, line) return TRUE - return down_interaction(I, user, machine) + return down_interaction(used_item, user, machine) -/decl/machine_construction/wall_frame/panel_closed/proc/down_interaction(obj/item/I, mob/user, obj/machinery/machine) - if(IS_SCREWDRIVER(I)) +/decl/machine_construction/wall_frame/panel_closed/proc/down_interaction(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_SCREWDRIVER(used_item)) TRANSFER_STATE(open_state) playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1) machine.panel_open = TRUE @@ -68,11 +68,11 @@ else try_change_state(machine, active_state) -/decl/machine_construction/wall_frame/panel_open/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/wall_frame/panel_open/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if((. = ..())) return - if(IS_WIRECUTTER(I)) + if(IS_WIRECUTTER(used_item)) TRANSFER_STATE(diconnected_state) playsound(get_turf(machine), 'sound/items/Wirecutter.ogg', 50, 1) user.visible_message(SPAN_WARNING("\The [user] has cut the wires inside \the [machine]!"), "You have cut the wires inside \the [machine].") @@ -81,20 +81,20 @@ machine.queue_icon_update() return TRUE - if((. = up_interaction(I, user, machine))) + if((. = up_interaction(used_item, user, machine))) return - if(istype(I, /obj/item/part_replacer)) - return machine.part_replacement(user, I) + if(istype(used_item, /obj/item/part_replacer)) + return machine.part_replacement(user, used_item) - if(IS_WRENCH(I)) + if(IS_WRENCH(used_item)) return machine.part_removal(user) - if(istype(I)) - return machine.part_insertion(user, I) + if(istype(used_item)) + return machine.part_insertion(user, used_item) -/decl/machine_construction/wall_frame/panel_open/proc/up_interaction(obj/item/I, mob/user, obj/machinery/machine) - if(IS_SCREWDRIVER(I)) +/decl/machine_construction/wall_frame/panel_open/proc/up_interaction(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_SCREWDRIVER(used_item)) TRANSFER_STATE(active_state) playsound(get_turf(machine), 'sound/items/Screwdriver.ogg', 50, 1) machine.panel_open = FALSE @@ -124,12 +124,12 @@ else try_change_state(machine, active_state) -/decl/machine_construction/wall_frame/no_wires/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/wall_frame/no_wires/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if((. = ..())) return - if(IS_COIL(I)) - var/obj/item/stack/cable_coil/A = I + if(IS_COIL(used_item)) + var/obj/item/stack/cable_coil/A = used_item if (A.can_use(5)) TRANSFER_STATE(open_state) A.use(5) @@ -140,20 +140,20 @@ to_chat(user, SPAN_WARNING("You need five pieces of cable to wire \the [machine].")) return TRUE - if((. = down_interaction(I, user, machine))) + if((. = down_interaction(used_item, user, machine))) return - if(istype(I, /obj/item/part_replacer)) - return machine.part_replacement(user, I) + if(istype(used_item, /obj/item/part_replacer)) + return machine.part_replacement(user, used_item) - if(IS_WRENCH(I)) + if(IS_WRENCH(used_item)) return machine.part_removal(user) - if(istype(I)) - return machine.part_insertion(user, I) + if(istype(used_item)) + return machine.part_insertion(user, used_item) -/decl/machine_construction/wall_frame/no_wires/proc/down_interaction(obj/item/I, mob/user, obj/machinery/machine) - if(IS_CROWBAR(I)) +/decl/machine_construction/wall_frame/no_wires/proc/down_interaction(obj/item/used_item, mob/user, obj/machinery/machine) + if(IS_CROWBAR(used_item)) TRANSFER_STATE(bottom_state) playsound(get_turf(machine), 'sound/items/Crowbar.ogg', 50, 1) to_chat(user, "You pry out the circuit!") @@ -183,12 +183,12 @@ else try_change_state(machine, active_state) -/decl/machine_construction/wall_frame/no_circuit/attackby(obj/item/I, mob/user, obj/machinery/machine) +/decl/machine_construction/wall_frame/no_circuit/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if((. = ..())) return - if(istype(I, /obj/item/stock_parts/circuitboard)) - var/obj/item/stock_parts/circuitboard/board = I + if(istype(used_item, /obj/item/stock_parts/circuitboard)) + var/obj/item/stock_parts/circuitboard/board = used_item if(board.build_path != (machine.base_type || machine.type)) to_chat(user, SPAN_WARNING("This circuitboard does not fit inside \the [machine]!")) return TRUE @@ -202,7 +202,7 @@ machine.queue_icon_update() return TRUE - if(IS_WRENCH(I)) + if(IS_WRENCH(used_item)) TRANSFER_STATE(/decl/machine_construction/default/deconstructed) playsound(get_turf(machine), 'sound/items/Ratchet.ogg', 50, 1) machine.visible_message(SPAN_NOTICE("\The [user] deconstructs \the [machine].")) diff --git a/code/game/machinery/_machines_base/machinery_components.dm b/code/game/machinery/_machines_base/machinery_components.dm index b648635ed74e..abf8e0d67dc5 100644 --- a/code/game/machinery/_machines_base/machinery_components.dm +++ b/code/game/machinery/_machines_base/machinery_components.dm @@ -254,18 +254,18 @@ var/global/list/machine_path_to_circuit_type // Hook to get updates. /obj/machinery/proc/component_stat_change(var/obj/item/stock_parts/part, old_stat, flag) -/obj/machinery/attackby(obj/item/I, mob/user) - if((. = component_attackby(I, user))) +/obj/machinery/attackby(obj/item/used_item, mob/user) + if((. = component_attackby(used_item, user))) return return ..() -/obj/machinery/proc/component_attackby(obj/item/I, mob/user) +/obj/machinery/proc/component_attackby(obj/item/used_item, mob/user) for(var/obj/item/stock_parts/part in component_parts) if(!components_are_accessible(part.type)) continue - if((. = part.attackby(I, user))) + if((. = part.attackby(used_item, user))) return - return construct_state?.attackby(I, user, src) + return construct_state?.attackby(used_item, user, src) /obj/machinery/proc/component_attack_hand(mob/user) for(var/obj/item/stock_parts/part in component_parts) diff --git a/code/game/machinery/_machines_base/stock_parts/power/battery.dm b/code/game/machinery/_machines_base/stock_parts/power/battery.dm index c3f9cadf208b..ecb17db640aa 100644 --- a/code/game/machinery/_machines_base/stock_parts/power/battery.dm +++ b/code/game/machinery/_machines_base/stock_parts/power/battery.dm @@ -147,24 +147,24 @@ icon_state = "battery[!!cell]" // Cell interaction -/obj/item/stock_parts/power/battery/attackby(obj/item/I, mob/user) +/obj/item/stock_parts/power/battery/attackby(obj/item/used_item, mob/user) var/obj/machinery/machine = loc // Interactions with/without machine - if(istype(I, /obj/item/cell)) + if(istype(used_item, /obj/item/cell)) if(cell) to_chat(user, "There is a power cell already installed.") return TRUE if(istype(machine) && (machine.stat & MAINT)) to_chat(user, "There is no connector for your power cell.") return TRUE - if(I.w_class != ITEM_SIZE_NORMAL) - to_chat(user, "\The [I] is too [I.w_class < ITEM_SIZE_NORMAL? "small" : "large"] to fit here.") + if(used_item.w_class != ITEM_SIZE_NORMAL) + to_chat(user, "\The [used_item] is too [used_item.w_class < ITEM_SIZE_NORMAL? "small" : "large"] to fit here.") return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - add_cell(machine, I) + add_cell(machine, used_item) user.visible_message(\ SPAN_WARNING("\The [user] has inserted the power cell to \the [src]!"),\ SPAN_NOTICE("You insert the power cell.")) diff --git a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm index e533d5ec02c5..2d0347720f4a 100644 --- a/code/game/machinery/_machines_base/stock_parts/power/terminal.dm +++ b/code/game/machinery/_machines_base/stock_parts/power/terminal.dm @@ -115,13 +115,13 @@ to_chat(user, "There is already a terminal here.") return TRUE -/obj/item/stock_parts/power/terminal/attackby(obj/item/I, mob/user) +/obj/item/stock_parts/power/terminal/attackby(obj/item/used_item, mob/user) var/obj/machinery/machine = loc if(!istype(machine)) return ..() // Interactions inside machine only - if (istype(I, /obj/item/stack/cable_coil) && !terminal) + if (istype(used_item, /obj/item/stack/cable_coil) && !terminal) var/turf/T = get_step(machine, terminal_dir) if(terminal_dir && user.loc != T) return FALSE // Wrong terminal handler. @@ -131,7 +131,7 @@ if(istype(T) && !T.is_plating()) to_chat(user, "You must remove the floor plating in front of \the [machine] first.") return TRUE - var/obj/item/stack/cable_coil/C = I + var/obj/item/stack/cable_coil/C = used_item if(!C.can_use(10)) to_chat(user, "You need ten lengths of cable for \the [machine].") return TRUE diff --git a/code/game/machinery/atmoalter/scrubber.dm b/code/game/machinery/atmoalter/scrubber.dm index 06bed379ecea..bf3c3498dda1 100644 --- a/code/game/machinery/atmoalter/scrubber.dm +++ b/code/game/machinery/atmoalter/scrubber.dm @@ -181,8 +181,8 @@ cut_overlays() icon_state = "scrubber:[!!((use_power == POWER_USE_ACTIVE) && !(stat & (NOPOWER|BROKEN)))]" -/obj/machinery/portable_atmospherics/powered/scrubber/huge/attackby(var/obj/item/I, var/mob/user) - if(IS_WRENCH(I)) +/obj/machinery/portable_atmospherics/powered/scrubber/huge/attackby(var/obj/item/used_item, var/mob/user) + if(IS_WRENCH(used_item)) if(use_power == POWER_USE_ACTIVE) to_chat(user, "Turn \the [src] off first!") return TRUE @@ -193,7 +193,7 @@ return TRUE //doesn't hold tanks - if(istype(I, /obj/item/tank)) + if(istype(used_item, /obj/item/tank)) return FALSE return ..() @@ -203,8 +203,8 @@ name = "stationary air scrubber" base_type = /obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary -/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/attackby(var/obj/item/I, var/mob/user) - if(IS_WRENCH(I)) +/obj/machinery/portable_atmospherics/powered/scrubber/huge/stationary/attackby(var/obj/item/used_item, var/mob/user) + if(IS_WRENCH(used_item)) to_chat(user, "The bolts are too tight for you to unscrew!") return TRUE diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm index 622914bad742..79bb78e9540e 100644 --- a/code/game/machinery/computer/ai_core.dm +++ b/code/game/machinery/computer/ai_core.dm @@ -108,59 +108,59 @@ var/global/list/empty_playable_ai_cores = list() else icon_state = "0" -/obj/structure/aicore/attackby(obj/item/P, mob/user) +/obj/structure/aicore/attackby(obj/item/used_item, mob/user) . = ..() if(.) update_icon() else if(!authorized) - if(access_ai_upload in P.GetAccess()) - to_chat(user, SPAN_NOTICE("You swipe [P] at [src] and authorize it to connect into the systems of [global.using_map.full_name].")) + if(access_ai_upload in used_item.GetAccess()) + to_chat(user, SPAN_NOTICE("You swipe [used_item] at [src] and authorize it to connect into the systems of [global.using_map.full_name].")) authorized = 1 if(anchored) if(!glass_installed && wired) - if(istype(P, /obj/item/stock_parts/circuitboard/aicore)) + if(istype(used_item, /obj/item/stock_parts/circuitboard/aicore)) if(circuit) to_chat(user, SPAN_WARNING("There is already a circuit installed in \the [src].")) return TRUE if(!wired) to_chat(user, SPAN_WARNING("Wire \the [src] first.")) return TRUE - if(user.try_unequip(P, src)) + if(user.try_unequip(used_item, src)) playsound(loc, 'sound/items/Deconstruct.ogg', 50, 1) to_chat(user, SPAN_NOTICE("You place the circuit board inside the frame.")) - circuit = P + circuit = used_item update_icon() return TRUE if(circuit && circuit_secured) - if(istype(P, /obj/item/organ/internal) && wired && circuit && circuit_secured) - var/obj/item/organ/internal/M = P + if(istype(used_item, /obj/item/organ/internal) && wired && circuit && circuit_secured) + var/obj/item/organ/internal/M = used_item var/mob/living/brainmob = M.get_brainmob() if(!brainmob) - to_chat(user, SPAN_WARNING("Sticking a mindless [P] into the frame would be pointless.")) + to_chat(user, SPAN_WARNING("Sticking a mindless [used_item] into the frame would be pointless.")) return if(brainmob.stat == DEAD) - to_chat(user, SPAN_WARNING("Sticking a dead [P] into the frame would sort of defeat the purpose.")) + to_chat(user, SPAN_WARNING("Sticking a dead [used_item] into the frame would sort of defeat the purpose.")) return if(jobban_isbanned(brainmob, "AI")) - to_chat(user, SPAN_WARNING("This [P] does not seem to fit.")) + to_chat(user, SPAN_WARNING("This [used_item] does not seem to fit.")) return - if(!user.try_unequip(P, src)) + if(!user.try_unequip(used_item, src)) if(brainmob.mind) clear_antag_roles(brainmob.mind, 1) - brain = P - to_chat(usr, "You connect \the [P] to the frame and slide it into the casing.") + brain = used_item + to_chat(usr, "You connect \the [used_item] to the frame and slide it into the casing.") update_icon() return TRUE - if(istype(P, /obj/item/stack/material)) - var/obj/item/stack/material/RG = P + if(istype(used_item, /obj/item/stack/material)) + var/obj/item/stack/material/RG = used_item if(RG.material.type != /decl/material/solid/glass || !RG.reinf_material || RG.get_amount() < 2) to_chat(user, SPAN_WARNING("You need two sheets of reinforced glass to put in the glass panel.")) return TRUE @@ -175,14 +175,14 @@ var/global/list/empty_playable_ai_cores = list() update_icon() return TRUE - if(istype(P, /obj/item/aiModule/freeform)) - var/obj/item/aiModule/freeform/M = P + if(istype(used_item, /obj/item/aiModule/freeform)) + var/obj/item/aiModule/freeform/M = used_item laws.add_inherent_law(M.newFreeFormLaw) to_chat(usr, "Added a freeform law.") return TRUE - if(istype(P, /obj/item/aiModule)) - var/obj/item/aiModule/module = P + if(istype(used_item, /obj/item/aiModule)) + var/obj/item/aiModule/module = used_item laws.clear_inherent_laws() if(module.laws) for(var/datum/ai_law/AL in module.laws.inherent_laws) diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index 6b52228b8ec4..fb0011651ebf 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -66,11 +66,11 @@ . = ..() uid = "[random_id("guestpass_serial_number",100,999)]-G[rand(10,99)]" -/obj/machinery/computer/guestpass/attackby(obj/O, mob/user) - if(istype(O, /obj/item/card/id)) - if(!giver && user.try_unequip(O)) - O.forceMove(src) - giver = O +/obj/machinery/computer/guestpass/attackby(obj/used_item, mob/user) + if(istype(used_item, /obj/item/card/id)) + if(!giver && user.try_unequip(used_item)) + used_item.forceMove(src) + giver = used_item updateUsrDialog() else if(giver) to_chat(user, SPAN_WARNING("There is already ID card inside.")) @@ -151,19 +151,19 @@ giver = null accesses.Cut() else - var/obj/item/I = user.get_active_held_item() - if (istype(I, /obj/item/card/id) && user.try_unequip(I)) - I.forceMove(src) - giver = I + var/obj/item/used_item = user.get_active_held_item() + if (istype(used_item, /obj/item/card/id) && user.try_unequip(used_item)) + used_item.forceMove(src) + giver = used_item . = TOPIC_REFRESH else if (href_list["print"]) var/dat = "

    Activity log of guest pass terminal #[uid]


    " for (var/entry in internal_log) dat += "[entry]

    " - var/obj/item/paper/P = new/obj/item/paper( loc ) - P.SetName("activity log") - P.info = dat + var/obj/item/paper/paper = new/obj/item/paper( loc ) + paper.SetName("activity log") + paper.info = dat . = TOPIC_REFRESH else if (href_list["issue"]) diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 992d2b211b51..8128cf6e71da 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -4,13 +4,12 @@ icon_screen = "command" var/mob/living/silicon/current -/obj/machinery/computer/upload/attackby(obj/item/O, mob/user) - if(istype(O, /obj/item/aiModule)) - var/obj/item/aiModule/M = O +/obj/machinery/computer/upload/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/aiModule)) + var/obj/item/aiModule/M = used_item M.install(src, user) return TRUE - else - return ..() + return ..() /obj/machinery/computer/upload/ai name = "\improper AI upload console" diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index da48f9028515..ab639d35a2e9 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -41,12 +41,12 @@ break . = tracking_linked_server -/obj/machinery/computer/message_monitor/attackby(obj/item/O, mob/user) +/obj/machinery/computer/message_monitor/attackby(obj/item/used_item, mob/user) if(stat & (NOPOWER|BROKEN)) return ..() if(!istype(user)) return TRUE - if(IS_SCREWDRIVER(O) && emagged) + if(IS_SCREWDRIVER(used_item) && emagged) //Stops people from just unscrewing the monitor and putting it back to get the console working again. to_chat(user, "It is too hot to mess with!") return TRUE diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm index dad8eb391e9a..a63d6d3b2ead 100644 --- a/code/game/machinery/computer/shuttle.dm +++ b/code/game/machinery/computer/shuttle.dm @@ -9,7 +9,7 @@ var/list/authorized = list( ) -/obj/machinery/computer/shuttle/attackby(var/obj/item/card as obj, var/mob/user as mob) +/obj/machinery/computer/shuttle/attackby(var/obj/item/used_item, var/mob/user) if(stat & (BROKEN|NOPOWER)) return TRUE var/datum/evacuation_controller/shuttle/evac_control = SSevac.evacuation_controller @@ -17,20 +17,20 @@ to_chat(user, "This console should not be in use on this map. Please report this to a developer.") return TRUE - if(!istype(card, /obj/item/card)) // don't try to get an ID card if we're an emag - card = card.GetIdCard() // handles stored IDs in modcomps and similar + if(!istype(used_item, /obj/item/card)) // don't try to get an ID card if we're an emag + used_item = used_item.GetIdCard() // handles stored IDs in modcomps and similar - if ((!istype(card, /obj/item/card) || evac_control.has_evacuated() || !user)) + if ((!istype(used_item, /obj/item/card) || evac_control.has_evacuated() || !user)) return FALSE - if (istype(card, /obj/item/card/id)) - var/obj/item/card/id/id_card = card + if (istype(used_item, /obj/item/card/id)) + var/obj/item/card/id/id_card = used_item if(!LAZYISIN(id_card.access, access_bridge)) //doesn't have this access to_chat(user, "The access level of [id_card.registered_name]\'s card is not high enough.") return TRUE var/choice = alert(user, "Would you like to (un)authorize a shortened launch time? [auth_need - authorized.len] authorization\s are still needed. Use abort to cancel all authorizations.", "Shuttle Launch", "Authorize", "Repeal", "Abort") - if(evac_control.is_prepared() && user.get_active_held_item() != card) + if(evac_control.is_prepared() && user.get_active_held_item() != used_item) return TRUE switch(choice) if("Authorize") @@ -59,10 +59,10 @@ src.authorized = list( ) return TRUE - else if (istype(card, /obj/item/card/emag) && !emagged) + else if (istype(used_item, /obj/item/card/emag) && !emagged) var/choice = alert(user, "Would you like to launch the shuttle?","Shuttle control", "Launch", "Cancel") - if(!emagged && !evac_control.is_prepared() && user.get_active_held_item() == card && choice == "Launch") + if(!emagged && !evac_control.is_prepared() && user.get_active_held_item() == used_item && choice == "Launch") to_world("Alert: Shuttle launch time shortened to 10 seconds!") evac_control.set_launch_time(world.time+100) emagged = 1 diff --git a/code/game/machinery/doors/_door.dm b/code/game/machinery/doors/_door.dm index e62ada86f20f..0311a46aba32 100644 --- a/code/game/machinery/doors/_door.dm +++ b/code/game/machinery/doors/_door.dm @@ -251,8 +251,8 @@ update_icon() return TRUE -/obj/machinery/door/proc/handle_repair(obj/item/I, mob/user) - if(istype(I, /obj/item/stack/material) && I.get_material_type() == src.get_material_type()) +/obj/machinery/door/proc/handle_repair(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/stack/material) && used_item.get_material_type() == src.get_material_type()) if(reason_broken & MACHINE_BROKEN_GENERIC) to_chat(user, "It looks like \the [src] is pretty busted. It's going to need more than just patching up now.") return TRUE @@ -268,7 +268,7 @@ var/amount_needed = (current_max_health - current_health) / DOOR_REPAIR_AMOUNT amount_needed = ceil(amount_needed) - var/obj/item/stack/stack = I + var/obj/item/stack/stack = used_item var/transfer if (repairing) transfer = stack.transfer_to(repairing, amount_needed - repairing.amount) @@ -286,12 +286,12 @@ return TRUE - if(repairing && IS_WELDER(I)) + if(repairing && IS_WELDER(used_item)) if(!density) to_chat(user, "\The [src] must be closed before you can repair it.") return TRUE - var/obj/item/weldingtool/welder = I + var/obj/item/weldingtool/welder = used_item if(welder.weld(0,user)) to_chat(user, "You start to fix dents and weld \the [repairing] into place.") playsound(src, 'sound/items/Welder.ogg', 100, 1) @@ -303,15 +303,15 @@ repairing = null return TRUE - if(repairing && IS_CROWBAR(I)) + if(repairing && IS_CROWBAR(used_item)) to_chat(user, "You remove \the [repairing].") playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1) repairing.dropInto(user.loc) repairing = null return TRUE -/obj/machinery/door/attackby(obj/item/I, mob/user) - . = handle_repair(I, user) +/obj/machinery/door/attackby(obj/item/used_item, mob/user) + . = handle_repair(used_item, user) if(.) return return ..() @@ -545,9 +545,9 @@ else if(istype(T, /turf/unsimulated/wall)) success = 1 else - for(var/obj/O in T) + for(var/obj/blend_obj in T) for(var/blend_type in get_blend_objects()) - if( istype(O, blend_type)) + if( istype(blend_obj, blend_type)) success = 1 if(success) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index b6323631bfe0..9264c99f8507 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -716,13 +716,13 @@ About the new airlock wires panel: src.unlock(1) //force it return TRUE -/obj/machinery/door/airlock/attackby(var/obj/item/C, var/mob/user) +/obj/machinery/door/airlock/attackby(var/obj/item/used_item, var/mob/user) // Brace is considered installed on the airlock, so interacting with it is protected from electrification. - if(brace && (istype(C.GetIdCard(), /obj/item/card/id/) || istype(C, /obj/item/crowbar/brace_jack))) - return brace.attackby(C, user) + if(brace && (istype(used_item.GetIdCard(), /obj/item/card/id/) || istype(used_item, /obj/item/crowbar/brace_jack))) + return brace.attackby(used_item, user) - if(!brace && istype(C, /obj/item/airlock_brace)) - var/obj/item/airlock_brace/A = C + if(!brace && istype(used_item, /obj/item/airlock_brace)) + var/obj/item/airlock_brace/A = used_item if(!density) to_chat(user, SPAN_WARNING("You must close \the [src] before installing \the [A]!")) return TRUE @@ -742,17 +742,17 @@ About the new airlock wires panel: if(src.shock(user, 75)) return TRUE - if(bash(C, user)) + if(bash(used_item, user)) return TRUE if (!repairing && (reason_broken & MACHINE_BROKEN_GENERIC) && src.locked) //bolted and broken - . = cut_bolts(C, user) + . = cut_bolts(used_item, user) if(!.) . = ..() return - if(!repairing && IS_WELDER(C) && !operating && density) - var/obj/item/weldingtool/welder = C + if(!repairing && IS_WELDER(used_item) && !operating && density) + var/obj/item/weldingtool/welder = used_item if(!welder.weld(0,user)) to_chat(user, SPAN_NOTICE("Your [welder.name] doesn't have enough fuel.")) return TRUE @@ -769,11 +769,11 @@ About the new airlock wires panel: to_chat(user, SPAN_NOTICE("You must remain still to complete this task.")) return TRUE - else if(IS_WIRECUTTER(C) || IS_MULTITOOL(C) || istype(C, /obj/item/assembly/signaler)) + else if(IS_WIRECUTTER(used_item) || IS_MULTITOOL(used_item) || istype(used_item, /obj/item/assembly/signaler)) return wires.Interact(user) - else if(IS_CROWBAR(C)) - if(density && !can_open(TRUE) && component_attackby(C, user)) + else if(IS_CROWBAR(used_item)) + if(density && !can_open(TRUE) && component_attackby(used_item, user)) return TRUE else if(!repairing) // Add some minor damage as evidence of forcing. @@ -792,8 +792,8 @@ About the new airlock wires panel: close(1) return TRUE - if(istype(C, /obj/item/bladed/axe/fire) && !arePowerSystemsOn() && !(user.check_intent(I_FLAG_HARM))) - var/obj/item/bladed/axe/fire/F = C + if(istype(used_item, /obj/item/bladed/axe/fire) && !arePowerSystemsOn() && !(user.check_intent(I_FLAG_HARM))) + var/obj/item/bladed/axe/fire/F = used_item if(F.is_held_twohanded(user)) if(locked) to_chat(user, SPAN_WARNING("The airlock's bolts prevent it from being forced.")) @@ -805,16 +805,15 @@ About the new airlock wires panel: close(1) else if(user.can_twohand_item(F)) - to_chat(user, SPAN_WARNING("You need to be holding \the [C] in both hands to do that!")) + to_chat(user, SPAN_WARNING("You need to be holding \the [used_item] in both hands to do that!")) else - to_chat(user, SPAN_WARNING("You are too small to lever \the [src] open with \the [C]!")) + to_chat(user, SPAN_WARNING("You are too small to lever \the [src] open with \the [used_item]!")) return TRUE else if((stat & (BROKEN|NOPOWER)) && isanimal(user)) var/mob/living/simple_animal/A = user - var/obj/item/I = A.get_natural_weapon() - if(I?.expend_attack_force(user) >= 10) + if(used_item?.expend_attack_force(user) >= 10) if(density) visible_message(SPAN_DANGER("\The [A] forces \the [src] open!")) open(1) diff --git a/code/game/machinery/doors/airlock_subtypes.dm b/code/game/machinery/doors/airlock_subtypes.dm index 179b0d35d2c8..b3474720a5f6 100644 --- a/code/game/machinery/doors/airlock_subtypes.dm +++ b/code/game/machinery/doors/airlock_subtypes.dm @@ -163,9 +163,9 @@ name = "Escape Pod" locked = TRUE -/obj/machinery/door/airlock/external/escapepod/attackby(obj/item/C, mob/user) +/obj/machinery/door/airlock/external/escapepod/attackby(obj/item/used_item, mob/user) if(panel_open && !arePowerSystemsOn()) - if(IS_WRENCH(C)) + if(IS_WRENCH(used_item)) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) user.visible_message(SPAN_WARNING("[user.name] starts frantically pumping the bolt override mechanism!"), SPAN_WARNING("You start frantically pumping the bolt override mechanism!")) if(do_after(user, 160) && locked) diff --git a/code/game/machinery/doors/blast_door.dm b/code/game/machinery/doors/blast_door.dm index 1fc6bb6afe3a..ca111e877bcf 100644 --- a/code/game/machinery/doors/blast_door.dm +++ b/code/game/machinery/doors/blast_door.dm @@ -142,13 +142,13 @@ return implicit_material // Proc: attackby() -// Parameters: 2 (C - Item this object was clicked with, user - Mob which clicked this object) +// Parameters: 2 (used_item - Item this object was clicked with, user - Mob which clicked this object) // Description: If we are clicked with crowbar or wielded fire axe, try to manually open the door. // This only works on broken doors or doors without power. Also allows repair with Plasteel. -/obj/machinery/door/blast/attackby(obj/item/C, mob/user) - add_fingerprint(user, 0, C) +/obj/machinery/door/blast/attackby(obj/item/used_item, mob/user) + add_fingerprint(user, 0, used_item) if(!panel_open) //Do this here so the door won't change state while prying out the circuit - if(IS_CROWBAR(C) || (istype(C, /obj/item/bladed/axe/fire) && C.is_held_twohanded())) + if(IS_CROWBAR(used_item) || (istype(used_item, /obj/item/bladed/axe/fire) && used_item.is_held_twohanded())) if(((stat & NOPOWER) || (stat & BROKEN)) && !( operating )) to_chat(user, "You begin prying at \the [src]...") if(do_after(user, 2 SECONDS, src)) @@ -158,18 +158,18 @@ else to_chat(user, "[src]'s motors resist your effort.") return TRUE - if(istype(C, /obj/item/stack/material) && C.get_material_type() == /decl/material/solid/metal/plasteel) + if(istype(used_item, /obj/item/stack/material) && used_item.get_material_type() == /decl/material/solid/metal/plasteel) var/amt = ceil((get_max_health() - current_health)/150) if(!amt) to_chat(user, "\The [src] is already fully functional.") return TRUE - var/obj/item/stack/P = C - if(!P.can_use(amt)) + var/obj/item/stack/stack = used_item + if(!stack.can_use(amt)) to_chat(user, "You don't have enough sheets to repair this! You need at least [amt] sheets.") return TRUE to_chat(user, "You begin repairing \the [src]...") if(do_after(user, 5 SECONDS, src)) - if(P.use(amt)) + if(stack.use(amt)) to_chat(user, "You have repaired \the [src].") repair() else diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index b2727a79621b..6952c2f6f6d6 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -217,12 +217,12 @@ nextstate = FIREDOOR_CLOSED close() -/obj/machinery/door/firedoor/attackby(obj/item/C, mob/user) - add_fingerprint(user, 0, C) +/obj/machinery/door/firedoor/attackby(obj/item/used_item, mob/user) + add_fingerprint(user, 0, used_item) if(operating) return TRUE //Already doing something. - if(IS_WELDER(C) && !repairing) - var/obj/item/weldingtool/welder = C + if(IS_WELDER(used_item) && !repairing) + var/obj/item/weldingtool/welder = used_item if(welder.weld(0, user)) playsound(src, 'sound/items/Welder.ogg', 100, 1) if(do_after(user, 2 SECONDS, src)) @@ -237,33 +237,33 @@ to_chat(user, SPAN_WARNING("You must remain still to complete this task.")) return TRUE - if(blocked && IS_CROWBAR(C)) - user.visible_message("\The [user] pries at \the [src] with \a [C], but \the [src] is welded in place!",\ + if(blocked && IS_CROWBAR(used_item)) + user.visible_message("\The [user] pries at \the [src] with \a [used_item], but \the [src] is welded in place!",\ "You try to pry \the [src] [density ? "open" : "closed"], but it is welded in place!",\ "You hear someone struggle and metal straining.") return TRUE - if(!blocked && (IS_CROWBAR(C) || istype(C,/obj/item/bladed/axe/fire))) + if(!blocked && (IS_CROWBAR(used_item) || istype(used_item,/obj/item/bladed/axe/fire))) if(operating) return ..() - if(istype(C,/obj/item/bladed/axe/fire)) - var/obj/item/bladed/axe/fire/F = C + if(istype(used_item,/obj/item/bladed/axe/fire)) + var/obj/item/bladed/axe/fire/F = used_item if(!F.is_held_twohanded()) return ..() - user.visible_message("\The [user] starts to force \the [src] [density ? "open" : "closed"] with \a [C]!",\ - "You start forcing \the [src] [density ? "open" : "closed"] with \the [C]!",\ + user.visible_message("\The [user] starts to force \the [src] [density ? "open" : "closed"] with \a [used_item]!",\ + "You start forcing \the [src] [density ? "open" : "closed"] with \the [used_item]!",\ "You hear metal strain.") if(do_after(user, 3 SECONDS, src)) - if(IS_CROWBAR(C)) + if(IS_CROWBAR(used_item)) if(stat & (BROKEN|NOPOWER) || !density) - user.visible_message("\The [user] forces \the [src] [density ? "open" : "closed"] with \a [C]!",\ - "You force \the [src] [density ? "open" : "closed"] with \the [C]!",\ + user.visible_message("\The [user] forces \the [src] [density ? "open" : "closed"] with \a [used_item]!",\ + "You force \the [src] [density ? "open" : "closed"] with \the [used_item]!",\ "You hear metal strain, and a door [density ? "open" : "close"].") else - user.visible_message("\The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [C]!",\ - "You force \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \the [C]!",\ + user.visible_message("\The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [used_item]!",\ + "You force \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \the [used_item]!",\ "You hear metal strain and groan, and a door [density ? "opening" : "closing"].") if(density) open(1) @@ -377,10 +377,10 @@ ATMOS_CANPASS_TURF(airblock, neighbour, myturf) if(airblock & AIR_BLOCKED) continue - for(var/obj/O in myturf) - if(istype(O, /obj/machinery/door)) + for(var/obj/thing in myturf) + if(istype(thing, /obj/machinery/door)) continue - ATMOS_CANPASS_MOVABLE(airblock, O, neighbour) + ATMOS_CANPASS_MOVABLE(airblock, thing, neighbour) . |= airblock if(. & AIR_BLOCKED) continue diff --git a/code/game/machinery/doors/firedoor_assembly.dm b/code/game/machinery/doors/firedoor_assembly.dm index bc3dcf1ab404..a861aa14a7db 100644 --- a/code/game/machinery/doors/firedoor_assembly.dm +++ b/code/game/machinery/doors/firedoor_assembly.dm @@ -10,19 +10,19 @@ var/result = /obj/machinery/door/firedoor -/obj/structure/firedoor_assembly/attackby(var/obj/item/C, var/mob/user) +/obj/structure/firedoor_assembly/attackby(var/obj/item/used_item, var/mob/user) . = ..() - if(!. && istype(C, /obj/item/stock_parts/circuitboard/airlock_electronics/firedoor) && wired) + if(!. && istype(used_item, /obj/item/stock_parts/circuitboard/airlock_electronics/firedoor) && wired) if(!anchored) to_chat(user, SPAN_WARNING("You must secure \the [src] first!")) else - if(!user.try_unequip(C, src)) + if(!user.try_unequip(used_item, src)) return playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) visible_message(SPAN_NOTICE("\The [user] inserts a circuit into \the [src].")) var/obj/machinery/door/firedoor/D = new result(get_turf(src), dir, FALSE) - var/obj/item/stock_parts/circuitboard/airlock_electronics/firedoor/electronics = C - D.install_component(C) + var/obj/item/stock_parts/circuitboard/airlock_electronics/firedoor/electronics = used_item + D.install_component(used_item) electronics.construct(D) D.construct_state.post_construct(D) D.close() diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index e6366bcc0a0f..f39b5849a088 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -171,12 +171,12 @@ /obj/machinery/door/window/CanFluidPass(var/coming_from) return !density || ((dir in global.cardinal) && coming_from != dir) -/obj/machinery/door/window/attackby(obj/item/I, mob/user) +/obj/machinery/door/window/attackby(obj/item/used_item, mob/user) //If it's in the process of opening/closing, ignore the click if(operating) return TRUE - if(bash(I, user)) + if(bash(used_item, user)) return TRUE . = ..() diff --git a/code/game/machinery/kitchen/cooking_machines/_cooker.dm b/code/game/machinery/kitchen/cooking_machines/_cooker.dm index 699f0670a3b1..a340029c6599 100644 --- a/code/game/machinery/kitchen/cooking_machines/_cooker.dm +++ b/code/game/machinery/kitchen/cooking_machines/_cooker.dm @@ -65,14 +65,14 @@ return TRUE -/obj/machinery/cooker/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/cooker/attackby(var/obj/item/used_item, var/mob/user) set waitfor = 0 //So that any remaining parts of calling proc don't have to wait for the long cooking time ahead. if(cooking) to_chat(user, "\The [src] is running!") return TRUE - if((. = component_attackby(I, user))) + if((. = component_attackby(used_item, user))) return if(!cook_type || (stat & (NOPOWER|BROKEN))) @@ -80,7 +80,7 @@ return TRUE // We're trying to cook something else. Check if it's valid. - var/obj/item/food/check = I + var/obj/item/food/check = used_item if(istype(check) && islist(check.cooked) && (cook_type in check.cooked)) to_chat(user, "\The [check] has already been [cook_type].") return TRUE @@ -100,12 +100,12 @@ M.apply_damage(rand(30,40), BURN, BP_CHEST) // Not sure why a food item that passed the previous checks would fail to drop, but safety first. - if(!user.try_unequip(I)) + if(!user.try_unequip(used_item)) return TRUE // We can actually start cooking now. - user.visible_message("\The [user] puts \the [I] into \the [src].") - cooking_obj = I + user.visible_message("\The [user] puts \the [used_item] into \the [src].") + cooking_obj = used_item cooking_obj.forceMove(src) cooking = 1 icon_state = on_icon diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index 4d95949cde61..43e6c98cbb29 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -116,24 +116,24 @@ popup.set_content(dat) popup.open() -/obj/machinery/icecream_vat/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/food/icecream)) - var/obj/item/food/icecream/I = O - if(!I.ice_creamed) +/obj/machinery/icecream_vat/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/food/icecream)) + var/obj/item/food/icecream/icecream = used_item + if(!icecream.ice_creamed) if(product_types[dispense_flavour] > 0) - src.visible_message("[html_icon(src)] [user] scoops delicious [flavour_name] icecream into [I].") + src.visible_message("[html_icon(src)] [user] scoops delicious [flavour_name] icecream into [icecream].") product_types[dispense_flavour] -= 1 - I.add_ice_cream(flavour_name) + icecream.add_ice_cream(flavour_name) // if(beaker) - // beaker.reagents.trans_to(I, 10) - if(I.reagents.total_volume < 10) - I.add_to_reagents(/decl/material/liquid/nutriment/sugar, 10 - I.reagents.total_volume) + // beaker.reagents.trans_to(icecream, 10) + if(icecream.reagents.total_volume < 10) + icecream.add_to_reagents(/decl/material/liquid/nutriment/sugar, 10 - icecream.reagents.total_volume) else to_chat(user, "There is not enough icecream left!") else - to_chat(user, "[O] already has icecream in it.") + to_chat(user, "[used_item] already has icecream in it.") return TRUE - else if(ATOM_IS_OPEN_CONTAINER(O)) + else if(ATOM_IS_OPEN_CONTAINER(used_item)) return TRUE else return ..() @@ -172,10 +172,10 @@ var/cone_name = get_flavour_name(dispense_cone) if(product_types[dispense_cone] >= 1) product_types[dispense_cone] -= 1 - var/obj/item/food/icecream/I = new(src.loc) - I.cone_type = cone_name - I.icon_state = "icecream_cone_[cone_name]" - I.desc = "Delicious [cone_name] cone, but no ice cream." + var/obj/item/food/icecream/icecream = new(src.loc) + icecream.cone_type = cone_name + icecream.icon_state = "icecream_cone_[cone_name]" + icecream.desc = "Delicious [cone_name] cone, but no ice cream." src.visible_message("[user] dispenses a crunchy [cone_name] cone from [src].") else to_chat(user, "There are no [cone_name] cones left!") diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index 886b8ce43997..f7de6783e2bb 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -53,9 +53,9 @@ to_chat(user, SPAN_WARNING("This is ridiculous. You can not fit \the [grab.affecting] into \the [src].")) return TRUE -/obj/machinery/microwave/attackby(var/obj/item/O, var/mob/user) +/obj/machinery/microwave/attackby(var/obj/item/used_item, var/mob/user) if(broken > 0) - if(broken == 2 && IS_SCREWDRIVER(O)) // If it's broken and they're using a screwdriver + if(broken == 2 && IS_SCREWDRIVER(used_item)) // If it's broken and they're using a screwdriver user.visible_message( SPAN_NOTICE("\The [user] starts to fix part of [src]."), SPAN_NOTICE("You start to fix part of [src].") @@ -66,7 +66,7 @@ SPAN_NOTICE("You have fixed part of [src].") ) broken = 1 // Fix it a bit - else if(broken == 1 && IS_WRENCH(O)) // If it's broken and they're doing the wrench + else if(broken == 1 && IS_WRENCH(used_item)) // If it's broken and they're doing the wrench user.visible_message( SPAN_NOTICE("\The [user] starts to fix part of [src]."), SPAN_NOTICE("You start to fix part of [src].") @@ -83,11 +83,11 @@ else to_chat(user, SPAN_WARNING("It's broken!")) return 1 - else if((. = component_attackby(O, user))) + else if((. = component_attackby(used_item, user))) dispose() return else if(dirty==100) // The microwave is all dirty so can't be used! - if(istype(O, /obj/item/chems/spray/cleaner) || istype(O, /obj/item/chems/rag)) // If they're trying to clean it then let them + if(istype(used_item, /obj/item/chems/spray/cleaner) || istype(used_item, /obj/item/chems/rag)) // If they're trying to clean it then let them user.visible_message( SPAN_NOTICE("\The [user] starts to clean [src]."), SPAN_NOTICE("You start to clean [src].") @@ -104,11 +104,11 @@ else //Otherwise bad luck!! to_chat(user, SPAN_WARNING("It's dirty!")) return 1 - else if(!istype(O, /obj/item/chems/glass/bowl) && (istype(O,/obj/item/chems/glass) || istype(O,/obj/item/chems/drinks) || istype(O,/obj/item/chems/condiment) )) - if (!O.reagents) + else if(!istype(used_item, /obj/item/chems/glass/bowl) && (istype(used_item,/obj/item/chems/glass) || istype(used_item,/obj/item/chems/drinks) || istype(used_item,/obj/item/chems/condiment) )) + if (!used_item.reagents) return 1 return // transfer is handled in afterattack - else if(IS_WRENCH(O)) + else if(IS_WRENCH(used_item)) user.visible_message( SPAN_NOTICE("\The [user] begins [anchored ? "securing" : "unsecuring"] [src]."), SPAN_NOTICE("You attempt to [anchored ? "secure" : "unsecure"] [src].") @@ -121,32 +121,32 @@ ) else to_chat(user, SPAN_NOTICE("You decide not to do that.")) - else if(O.w_class <= ITEM_SIZE_LARGE) // this must be last + else if(used_item.w_class <= ITEM_SIZE_LARGE) // this must be last if (LAZYLEN(get_contained_external_atoms()) >= max_n_of_items) to_chat(user, SPAN_WARNING("This [src] is full of ingredients, you cannot put more.")) return 1 - if(istype(O, /obj/item/stack)) // This is bad, but I can't think of how to change it - var/obj/item/stack/S = O + if(istype(used_item, /obj/item/stack)) // This is bad, but I can't think of how to change it + var/obj/item/stack/S = used_item if(S.get_amount() > 1) var/obj/item/stack/new_stack = S.split(1) if(new_stack) new_stack.forceMove(src) user.visible_message( SPAN_NOTICE("\The [user] has added \a [new_stack.singular_name] to \the [src]."), - SPAN_NOTICE("You add one of [O] to \the [src].") + SPAN_NOTICE("You add one of [used_item] to \the [src].") ) SSnano.update_uis(src) return - if (!user.try_unequip(O, src)) + if (!user.try_unequip(used_item, src)) return user.visible_message( - SPAN_NOTICE("\The [user] has added \the [O] to \the [src]."), - SPAN_NOTICE("You add \the [O] to \the [src].") + SPAN_NOTICE("\The [user] has added \the [used_item] to \the [src]."), + SPAN_NOTICE("You add \the [used_item] to \the [src].") ) SSnano.update_uis(src) return else - to_chat(user, SPAN_WARNING("You have no idea what you can cook with \the [O].")) + to_chat(user, SPAN_WARNING("You have no idea what you can cook with \the [used_item].")) SSnano.update_uis(src) /obj/machinery/microwave/components_are_accessible(path) @@ -176,8 +176,8 @@ . = ..() var/data = list() data["cooking_items"] = list() - for(var/obj/O in get_contained_external_atoms()) - data["cooking_items"][O.name]++ + for(var/obj/used_item in get_contained_external_atoms()) + data["cooking_items"][used_item.name]++ data["cooking_reagents"] = list() for(var/material_type in reagents.reagent_volumes) var/decl/material/mat = GET_DECL(material_type) @@ -278,8 +278,8 @@ SSnano.update_uis(src) /obj/machinery/microwave/proc/has_extra_item() - for(var/obj/O in get_contained_external_atoms()) - if(!istype(O,/obj/item/food)) + for(var/obj/thing in get_contained_external_atoms()) + if(!istype(thing,/obj/item/food)) return TRUE return FALSE @@ -349,8 +349,8 @@ var/list/ingredients = get_contained_external_atoms() if (!LAZYLEN(ingredients) && !reagents.total_volume) return - for (var/obj/O in ingredients) - O.dropInto(loc) + for (var/obj/thing in ingredients) + thing.dropInto(loc) if (reagents.total_volume) dirty++ reagents.clear_reagents() @@ -358,12 +358,12 @@ to_chat(user, SPAN_NOTICE("You empty [src].")) SSnano.update_uis(src) -/obj/machinery/microwave/proc/eject_item(var/mob/user, var/obj/O, var/message = TRUE) - if(!istype(O) || !length(get_contained_external_atoms())) +/obj/machinery/microwave/proc/eject_item(var/mob/user, var/obj/thing, var/message = TRUE) + if(!istype(thing) || !length(get_contained_external_atoms())) return - O.dropInto(loc) + thing.dropInto(loc) if(user && message) - to_chat(user, SPAN_NOTICE("You remove [O] from [src].")) + to_chat(user, SPAN_NOTICE("You remove [thing] from [src].")) SSnano.update_uis(src) /obj/machinery/microwave/proc/eject_reagent(var/mob/user, var/material_type) @@ -403,11 +403,11 @@ M.death() qdel(M) - for (var/obj/O in ingredients) + for (var/obj/thing in ingredients) amount++ - if (O.reagents && O.reagents.primary_reagent) - amount += REAGENT_VOLUME(O.reagents, O.reagents.primary_reagent) - qdel(O) + if (thing.reagents && thing.reagents.primary_reagent) + amount += REAGENT_VOLUME(thing.reagents, thing.reagents.primary_reagent) + qdel(thing) reagents.clear_reagents() SSnano.update_uis(src) var/obj/item/food/badrecipe/ffuu = new(src) @@ -426,9 +426,9 @@ return TOPIC_REFRESH if ("ejectitem") - for(var/obj/O in get_contained_external_atoms()) - if(strip_improper(O.name) == href_list["target"]) - eject_item(user, O) + for(var/obj/thing in get_contained_external_atoms()) + if(strip_improper(thing.name) == href_list["target"]) + eject_item(user, thing) break return TOPIC_REFRESH diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 7bcf166a9089..d598001b671e 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -82,10 +82,10 @@ set_state(!on) return TRUE -/obj/machinery/light_switch/attackby(obj/item/I, mob/user) +/obj/machinery/light_switch/attackby(obj/item/used_item, mob/user) . = ..() if(!.) - to_chat(user, SPAN_NOTICE("You flick \the [src] with \the [I].")) + to_chat(user, SPAN_NOTICE("You flick \the [src] with \the [used_item].")) interface_interact(user) return TRUE diff --git a/code/game/machinery/message_server.dm b/code/game/machinery/message_server.dm index fdec0c2b48ee..9ddf2a4d9f39 100644 --- a/code/game/machinery/message_server.dm +++ b/code/game/machinery/message_server.dm @@ -135,11 +135,11 @@ var/global/list/message_servers = list() update_icon() return TRUE -/obj/machinery/network/message_server/attackby(obj/item/O, mob/user) +/obj/machinery/network/message_server/attackby(obj/item/used_item, mob/user) if (active && !(stat & (BROKEN|NOPOWER)) && (spamfilter_limit < MESSAGE_SERVER_DEFAULT_SPAM_LIMIT*2) && \ - istype(O,/obj/item/stock_parts/circuitboard/message_monitor)) + istype(used_item,/obj/item/stock_parts/circuitboard/message_monitor)) spamfilter_limit += round(MESSAGE_SERVER_DEFAULT_SPAM_LIMIT / 2) - qdel(O) + qdel(used_item) to_chat(user, "You install additional memory and processors into \the [src]. Its filtering capabilities been enhanced.") return TRUE else diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index b129241b2ea4..5a3776da1e39 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -41,18 +41,18 @@ var/global/list/navbeacons = list() else icon_state = "[state]" -/obj/machinery/navbeacon/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/navbeacon/attackby(var/obj/item/used_item, var/mob/user) var/turf/T = loc if(!T.is_plating()) return TRUE // prevent intraction when T-scanner revealed - if(IS_SCREWDRIVER(I)) + if(IS_SCREWDRIVER(used_item)) open = !open user.visible_message("\The [user] [open ? "opens" : "closes"] cover of \the [src].", "You [open ? "open" : "close"] cover of \the [src].") update_icon() return TRUE - else if(I.GetIdCard()) + else if(used_item.GetIdCard()) if(open) if (src.allowed(user)) src.locked = !src.locked diff --git a/code/game/machinery/nuclear_bomb.dm b/code/game/machinery/nuclear_bomb.dm index d00b5f51746c..4260696809b1 100644 --- a/code/game/machinery/nuclear_bomb.dm +++ b/code/game/machinery/nuclear_bomb.dm @@ -44,8 +44,8 @@ var/global/bomb_set addtimer(CALLBACK(src, PROC_REF(explode)), 0) SSnano.update_uis(src) -/obj/machinery/nuclearbomb/attackby(obj/item/O, mob/user, params) - if(IS_SCREWDRIVER(O)) +/obj/machinery/nuclearbomb/attackby(obj/item/used_item, mob/user, params) + if(IS_SCREWDRIVER(used_item)) add_fingerprint(user) if(auth) if(panel_open == 0) @@ -69,28 +69,28 @@ var/global/bomb_set flick("lock", src) return TRUE - if(panel_open && (IS_MULTITOOL(O) || IS_WIRECUTTER(O))) + if(panel_open && (IS_MULTITOOL(used_item) || IS_WIRECUTTER(used_item))) return attack_hand_with_interaction_checks(user) if(extended) - if(istype(O, /obj/item/disk/nuclear)) - if(!user.try_unequip(O, src)) + if(istype(used_item, /obj/item/disk/nuclear)) + if(!user.try_unequip(used_item, src)) return TRUE - auth = O + auth = used_item add_fingerprint(user) return attack_hand_with_interaction_checks(user) if(anchored) switch(removal_stage) if(0) - if(IS_WELDER(O)) - var/obj/item/weldingtool/welder = O + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(!welder.isOn()) return TRUE if(welder.get_fuel() < 5) // uses up 5 fuel. to_chat(user, "You need more fuel to complete this task.") return TRUE - user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [O]...") + user.visible_message("[user] starts cutting loose the anchoring bolt covers on [src].", "You start cutting loose the anchoring bolt covers with [used_item]...") if(do_after(user, 4 SECONDS, src)) if(QDELETED(src) || QDELETED(user) || !welder.weld(5, user)) return TRUE @@ -99,8 +99,8 @@ var/global/bomb_set return TRUE if(1) - if(IS_CROWBAR(O)) - user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [O]...") + if(IS_CROWBAR(used_item)) + user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [used_item]...") if(do_after(user, 1.5 SECONDS, src)) if(QDELETED(src) || QDELETED(user)) return TRUE @@ -109,14 +109,14 @@ var/global/bomb_set return TRUE if(2) - if(IS_WELDER(O)) - var/obj/item/weldingtool/welder = O + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(!welder.isOn()) return TRUE if (welder.get_fuel() < 5) // uses up 5 fuel. to_chat(user, "You need more fuel to complete this task.") return TRUE - user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [O]...") + user.visible_message("[user] starts cutting apart the anchoring system sealant on [src].", "You start cutting apart the anchoring system's sealant with [used_item]...") if(do_after(user, 4 SECONDS, src)) if(QDELETED(src) || QDELETED(user) || !welder.weld(5, user)) return TRUE @@ -125,7 +125,7 @@ var/global/bomb_set return TRUE if(3) - if(IS_WRENCH(O)) + if(IS_WRENCH(used_item)) user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...") if(do_after(user, 5 SECONDS, src)) if(QDELETED(src) || QDELETED(user)) return TRUE @@ -134,7 +134,7 @@ var/global/bomb_set return TRUE if(4) - if(IS_CROWBAR(O)) + if(IS_CROWBAR(used_item)) user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...") if(do_after(user, 8 SECONDS, src)) if(QDELETED(src) || QDELETED(user)) return TRUE @@ -230,11 +230,11 @@ var/global/bomb_set yes_code = 0 auth = null else - var/obj/item/I = user.get_active_held_item() - if(istype(I, /obj/item/disk/nuclear)) - if(!user.try_unequip(I, src)) + var/obj/item/used_item = user.get_active_held_item() + if(istype(used_item, /obj/item/disk/nuclear)) + if(!user.try_unequip(used_item, src)) return TOPIC_HANDLED - auth = I + auth = used_item if(is_auth(user)) if(href_list["type"]) . = TOPIC_REFRESH @@ -475,7 +475,7 @@ var/global/bomb_set for(var/obj/machinery/self_destruct/ch in get_area(src)) inserters += ch -/obj/machinery/nuclearbomb/station/attackby(obj/item/O, mob/user) +/obj/machinery/nuclearbomb/station/attackby(obj/item/used_item, mob/user) return TRUE // cannot be moved /obj/machinery/nuclearbomb/station/OnTopic(mob/user, href_list, datum/topic_state/state) diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 0fde815d1326..99d2fd9681f1 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -236,9 +236,9 @@ var/global/list/turret_icons . = ..() // TODO: remove these or refactor to use construct states -/obj/machinery/porta_turret/attackby(obj/item/I, mob/user) +/obj/machinery/porta_turret/attackby(obj/item/used_item, mob/user) if(stat & BROKEN) - if(IS_CROWBAR(I)) + if(IS_CROWBAR(used_item)) //If the turret is destroyed, you can remove it with a crowbar to //try and salvage its components to_chat(user, "You begin prying the metal coverings off.") @@ -251,7 +251,7 @@ var/global/list/turret_icons return TRUE return FALSE - else if(IS_WRENCH(I)) + else if(IS_WRENCH(used_item)) if(enabled || raised) to_chat(user, "You cannot unsecure an active turret!") return TRUE @@ -277,7 +277,7 @@ var/global/list/turret_icons wrenching = 0 return TRUE - else if(istype(I, /obj/item/card/id)||istype(I, /obj/item/modular_computer)) + else if(istype(used_item, /obj/item/card/id)||istype(used_item, /obj/item/modular_computer)) //Behavior lock/unlock mangement if(allowed(user)) locked = !locked @@ -289,9 +289,9 @@ var/global/list/turret_icons else //if the turret was attacked with the intention of harming it: - var/force = I.expend_attack_force(user) * 0.5 + var/force = used_item.expend_attack_force(user) * 0.5 user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) - take_damage(force, I.atom_damage_type) + take_damage(force, used_item.atom_damage_type) if(force > 1) //if the force of impact dealt at least 1 damage, the turret gets pissed off if(!attacked && !emagged) attacked = 1 diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 05196878a6f7..93ec1b56424e 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -23,10 +23,10 @@ charging = null . = ..() -/obj/machinery/recharger/attackby(obj/item/G, mob/user) +/obj/machinery/recharger/attackby(obj/item/used_item, mob/user) var/allowed = 0 for (var/allowed_type in allowed_devices) - if (istype(G, allowed_type)) allowed = 1 + if (istype(used_item, allowed_type)) allowed = 1 if(allowed) . = TRUE @@ -35,24 +35,24 @@ return // Checks to make sure the recharger is powered. if(stat & NOPOWER) - to_chat(user, "\The [src] blinks red as you try to insert \the [G]!") + to_chat(user, "\The [src] blinks red as you try to insert \the [used_item]!") return - if (istype(G, /obj/item/gun/energy/)) - var/obj/item/gun/energy/E = G + if (istype(used_item, /obj/item/gun/energy/)) + var/obj/item/gun/energy/E = used_item if(E.self_recharge) to_chat(user, "You can't find a charging port on \the [E].") return - if(!G.get_cell()) + if(!used_item.get_cell()) to_chat(user, "This device does not have a battery installed.") return - if(user.try_unequip(G)) - G.forceMove(src) - charging = G + if(user.try_unequip(used_item)) + used_item.forceMove(src) + charging = used_item update_icon() return - if(portable && IS_WRENCH(G) && !panel_open) + if(portable && IS_WRENCH(used_item) && !panel_open) . = TRUE if(charging) to_chat(user, "Remove [charging] first!") diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index 2fe46fa3e1d6..3452f128f8b0 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -206,16 +206,16 @@ var/global/req_console_information = list() set_department(choice) return TOPIC_REFRESH -/obj/machinery/network/requests_console/attackby(var/obj/item/O, var/mob/user) - if (istype(O, /obj/item/card/id)) +/obj/machinery/network/requests_console/attackby(var/obj/item/used_item, var/mob/user) + if (istype(used_item, /obj/item/card/id)) if(inoperable(MAINT)) return TRUE switch(screen) if(RCS_MESSAUTH) - var/obj/item/card/id/T = O + var/obj/item/card/id/T = used_item msgVerified = text("Verified by [T.registered_name] ([T.assignment])") SSnano.update_uis(src) if(RCS_ANNOUNCE) - var/obj/item/card/id/ID = O + var/obj/item/card/id/ID = used_item if (access_RC_announce in ID.GetAccess()) announceAuth = 1 announcement.announcer = ID.assignment ? "[ID.assignment] [ID.registered_name]" : ID.registered_name @@ -224,10 +224,10 @@ var/global/req_console_information = list() to_chat(user, "You are not authorized to send announcements.") SSnano.update_uis(src) return TRUE - if (istype(O, /obj/item/stamp)) + if (istype(used_item, /obj/item/stamp)) if(inoperable(MAINT)) return TRUE if(screen == RCS_MESSAUTH) - var/obj/item/stamp/T = O + var/obj/item/stamp/T = used_item msgStamped = "Stamped with the [T.name]" SSnano.update_uis(src) return TRUE diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm index de1b7c1cc8a4..af07b0a10392 100644 --- a/code/game/machinery/seed_extractor.dm +++ b/code/game/machinery/seed_extractor.dm @@ -12,33 +12,33 @@ uncreated_component_parts = null stat_immune = 0 -/obj/machinery/seed_extractor/attackby(var/obj/item/O, var/mob/user) +/obj/machinery/seed_extractor/attackby(var/obj/item/used_item, var/mob/user) // Fruits and vegetables. - if(istype(O, /obj/item/food/grown)) - if(!user.try_unequip(O)) + if(istype(used_item, /obj/item/food/grown)) + if(!user.try_unequip(used_item)) return TRUE - var/obj/item/food/grown/F = O + var/obj/item/food/grown/F = used_item if(!F.seed) - to_chat(user, SPAN_WARNING("\The [O] doesn't seem to have any usable seeds inside it.")) + to_chat(user, SPAN_WARNING("\The [used_item] doesn't seem to have any usable seeds inside it.")) return TRUE - to_chat(user, SPAN_NOTICE("You extract some seeds from [O].")) + to_chat(user, SPAN_NOTICE("You extract some seeds from [used_item].")) for(var/i = 1 to rand(1,4)) new /obj/item/seeds/modified(get_turf(src), null, F.seed) - qdel(O) + qdel(used_item) return TRUE //Grass. - if(istype(O, /obj/item/stack/tile/grass)) - var/obj/item/stack/tile/grass/S = O + if(istype(used_item, /obj/item/stack/tile/grass)) + var/obj/item/stack/tile/grass/S = used_item if (S.use(1)) to_chat(user, SPAN_NOTICE("You extract some seeds from the grass tile.")) new /obj/item/seeds/grassseed(loc) return TRUE - if(istype(O, /obj/item/fossil/plant)) // Fossils - to_chat(user, SPAN_NOTICE("\The [src] scans \the [O] and spits out \a [new /obj/item/seeds/random(get_turf(src))].")) - qdel(O) + if(istype(used_item, /obj/item/fossil/plant)) // Fossils + to_chat(user, SPAN_NOTICE("\The [src] scans \the [used_item] and spits out \a [new /obj/item/seeds/random(get_turf(src))].")) + qdel(used_item) return TRUE return ..() diff --git a/code/game/machinery/self_destruct_storage.dm b/code/game/machinery/self_destruct_storage.dm index afaf920ef1da..0d97e56de5a7 100644 --- a/code/game/machinery/self_destruct_storage.dm +++ b/code/game/machinery/self_destruct_storage.dm @@ -86,13 +86,13 @@ return TRUE return FALSE -/obj/machinery/nuclear_cylinder_storage/attackby(obj/item/O, mob/user) - if(!open && operable() && istype(O, /obj/item/card/id)) +/obj/machinery/nuclear_cylinder_storage/attackby(obj/item/used_item, mob/user) + if(!open && operable() && istype(used_item, /obj/item/card/id)) if(panel_open) to_chat(user, SPAN_WARNING("\The [src] is currently in maintenance mode!")) return TRUE - var/obj/item/card/id/id = O + var/obj/item/card/id/id = used_item if(check_access(id)) locked = !locked user.visible_message( @@ -102,21 +102,21 @@ update_icon() return TRUE - if(open && istype(O, /obj/item/nuclear_cylinder) && (length(cylinders) < max_cylinders)) + if(open && istype(used_item, /obj/item/nuclear_cylinder) && (length(cylinders) < max_cylinders)) if(panel_open) to_chat(user, SPAN_WARNING("\The [src] is currently in maintenance mode!")) return TRUE user.visible_message( - "\The [user] begins inserting \the [O] into storage.", - "You begin inserting \the [O] into storage." + "\The [user] begins inserting \the [used_item] into storage.", + "You begin inserting \the [used_item] into storage." ) - if(do_after(user, interact_time, src) && open && (length(cylinders) < max_cylinders) && user.try_unequip(O, src)) + if(do_after(user, interact_time, src) && open && (length(cylinders) < max_cylinders) && user.try_unequip(used_item, src)) user.visible_message( - "\The [user] places \the [O] into storage.", - "You place \the [O] into storage." + "\The [user] places \the [used_item] into storage.", + "You place \the [used_item] into storage." ) - cylinders.Add(O) + cylinders.Add(used_item) update_icon() return TRUE diff --git a/code/game/machinery/smartfridge/_smartfridge.dm b/code/game/machinery/smartfridge/_smartfridge.dm index c446e87a4389..68db0c387afd 100644 --- a/code/game/machinery/smartfridge/_smartfridge.dm +++ b/code/game/machinery/smartfridge/_smartfridge.dm @@ -45,8 +45,8 @@ return list() return ..() -/obj/machinery/smartfridge/proc/accept_check(var/obj/item/O) - if(istype(O,/obj/item/food/grown/) || istype(O,/obj/item/seeds/)) +/obj/machinery/smartfridge/proc/accept_check(var/obj/item/stocking_item) + if(istype(stocking_item,/obj/item/food/grown) || istype(stocking_item,/obj/item/seeds)) return 1 return 0 @@ -104,10 +104,10 @@ draw_state = "[icon_state]-top" if(check_state_in_icon(draw_state, icon)) - var/image/I = image(icon, draw_state) - I.pixel_z = 32 - I.layer = ABOVE_WINDOW_LAYER - add_overlay(I) + var/image/overlay_image = image(icon, draw_state) + overlay_image.pixel_z = 32 + overlay_image.layer = ABOVE_WINDOW_LAYER + add_overlay(overlay_image) // Append our off state if needed. if(stat & BROKEN) @@ -116,9 +116,9 @@ icon_state = "[icon_state]-off" /obj/machinery/smartfridge/dismantle() - for(var/datum/stored_items/I in item_records) - while(I.amount > 0) - I.get_product(get_turf(src)) // They'd get dumped anyway, but this makes things GC properly. + for(var/datum/stored_items/stored_item in item_records) + while(stored_item.amount > 0) + stored_item.get_product(get_turf(src)) // They'd get dumped anyway, but this makes things GC properly. ..() /******************* @@ -129,42 +129,42 @@ . = ..() update_icon() -/obj/machinery/smartfridge/attackby(var/obj/item/O, var/mob/user) - if(accept_check(O)) - if(!user.try_unequip(O)) +/obj/machinery/smartfridge/attackby(var/obj/item/used_item, var/mob/user) + if(accept_check(used_item)) + if(!user.try_unequip(used_item)) return TRUE - stock_item(O) - user.visible_message("\The [user] has added \the [O] to \the [src].", "You add \the [O] to \the [src].") + stock_item(used_item) + user.visible_message("\The [user] has added \the [used_item] to \the [src].", "You add \the [used_item] to \the [src].") update_icon() return TRUE - if(O.storage) + if(used_item.storage) var/plants_loaded = 0 - for(var/obj/G in O.storage.get_contents()) - if(accept_check(G) && O.storage.remove_from_storage(user, G, src, TRUE)) + for(var/obj/G in used_item.storage.get_contents()) + if(accept_check(G) && used_item.storage.remove_from_storage(user, G, src, TRUE)) plants_loaded++ stock_item(G) - O.storage.finish_bulk_removal() + used_item.storage.finish_bulk_removal() if(plants_loaded) - user.visible_message("\The [user] loads \the [src] with the contents of \the [O].", "You load \the [src] with the contents of \the [O].") - if(length(O.storage.get_contents()) > 0) + user.visible_message("\The [user] loads \the [src] with the contents of \the [used_item].", "You load \the [src] with the contents of \the [used_item].") + if(length(used_item.storage.get_contents()) > 0) to_chat(user, "Some items were refused.") return TRUE return ..() -/obj/machinery/smartfridge/proc/stock_item(var/obj/item/O) - for(var/datum/stored_items/I in item_records) - if(istype(O, I.item_path) && O.name == I.item_name) - stock(I, O) +/obj/machinery/smartfridge/proc/stock_item(var/obj/item/stocking_item) + for(var/datum/stored_items/stored_item in item_records) + if(istype(stocking_item, stored_item.item_path) && stocking_item.name == stored_item.item_name) + stock(stored_item, stocking_item) return - var/datum/stored_items/I = new/datum/stored_items(src, O.type, O.name) - dd_insertObjectList(item_records, I) - stock(I, O) + var/datum/stored_items/stored_item = new/datum/stored_items(src, stocking_item.type, stocking_item.name) + dd_insertObjectList(item_records, stored_item) + stock(stored_item, stocking_item) -/obj/machinery/smartfridge/proc/stock(var/datum/stored_items/I, var/obj/item/O) - I.add_product(O) +/obj/machinery/smartfridge/proc/stock(var/datum/stored_items/stored_item, var/obj/item/stocking_item) + stored_item.add_product(stocking_item) SSnano.update_uis(src) /obj/machinery/smartfridge/interface_interact(mob/user) @@ -187,10 +187,10 @@ var/list/items[0] for (var/i=1 to length(item_records)) - var/datum/stored_items/I = item_records[i] - var/count = I.get_amount() + var/datum/stored_items/stored_item = item_records[i] + var/count = stored_item.get_amount() if(count > 0) - items.Add(list(list("display_name" = html_encode(capitalize(I.item_name)), "vend" = i, "quantity" = count))) + items.Add(list(list("display_name" = html_encode(capitalize(stored_item.item_name)), "vend" = i, "quantity" = count))) if(items.len > 0) data["contents"] = items @@ -210,15 +210,15 @@ if(href_list["vend"]) var/index = text2num(href_list["vend"]) - var/datum/stored_items/I = item_records[index] - var/count = I.get_amount() + var/datum/stored_items/stored_item = item_records[index] + var/count = stored_item.get_amount() var/amount = clamp(text2num(href_list["amount"]), 0, count) // Sanity check, there are probably ways to press the button when it shouldn't be possible. if(amount <= 0) return TOPIC_REFRESH // you must be confused, we have none of that here! for(var/i = 1 to amount) - I.get_product(get_turf(src)) + stored_item.get_product(get_turf(src)) update_icon() var/vend_state = "[icon_state]-vend" if (check_state_in_icon(vend_state, icon)) //Show the vending animation if needed @@ -232,8 +232,8 @@ if(!target) return 0 - for(var/datum/stored_items/I in src.item_records) - throw_item = I.get_product(loc) + for(var/datum/stored_items/stored_item in src.item_records) + throw_item = stored_item.get_product(loc) if(!QDELETED(throw_item)) break diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm index fd147aef4247..8c9b8eb407d9 100644 --- a/code/game/machinery/suit_cycler.dm +++ b/code/game/machinery/suit_cycler.dm @@ -195,33 +195,33 @@ return TRUE return ..() -/obj/machinery/suit_cycler/attackby(obj/item/I, mob/user) +/obj/machinery/suit_cycler/attackby(obj/item/used_item, mob/user) if(electrified != 0 && shock(user, 100)) return TRUE //Hacking init. - if(IS_MULTITOOL(I) || IS_WIRECUTTER(I)) + if(IS_MULTITOOL(used_item) || IS_WIRECUTTER(used_item)) if(panel_open) physical_attack_hand(user) return TRUE - if(istype(I, /obj/item/clothing/shoes/magboots)) + if(istype(used_item, /obj/item/clothing/shoes/magboots)) if(locked) to_chat(user, SPAN_WARNING("The suit cycler is locked.")) return TRUE if(boots) to_chat(user, SPAN_WARNING("The cycler already contains some boots.")) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, "You fit \the [I] into the suit cycler.") - set_boots(I) + to_chat(user, "You fit \the [used_item] into the suit cycler.") + set_boots(used_item) update_icon() updateUsrDialog() return TRUE - if(istype(I,/obj/item/clothing/head/helmet/space) && !istype(I, /obj/item/clothing/head/helmet/space/rig)) + if(istype(used_item,/obj/item/clothing/head/helmet/space) && !istype(used_item, /obj/item/clothing/head/helmet/space/rig)) if(locked) to_chat(user, SPAN_WARNING("The suit cycler is locked.")) @@ -231,14 +231,14 @@ to_chat(user, SPAN_WARNING("The cycler already contains a helmet.")) return TRUE - if(user.try_unequip(I, src)) - to_chat(user, "You fit \the [I] into the suit cycler.") - set_helmet(I) + if(user.try_unequip(used_item, src)) + to_chat(user, "You fit \the [used_item] into the suit cycler.") + set_helmet(used_item) update_icon() updateUsrDialog() return TRUE - if(istype(I,/obj/item/clothing/suit/space/void)) + if(istype(used_item,/obj/item/clothing/suit/space/void)) if(locked) to_chat(user, SPAN_WARNING("The suit cycler is locked.")) @@ -248,9 +248,9 @@ to_chat(user, SPAN_WARNING("The cycler already contains a voidsuit.")) return TRUE - if(user.try_unequip(I, src)) - to_chat(user, "You fit \the [I] into the suit cycler.") - set_suit(I) + if(user.try_unequip(used_item, src)) + to_chat(user, "You fit \the [used_item] into the suit cycler.") + set_suit(used_item) update_icon() updateUsrDialog() return TRUE diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index 6c442f851c18..bb8fda1746f7 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -48,9 +48,9 @@ var/turf/T = get_turf(locked) . += SPAN_NOTICE("The console is locked on to \[[T.loc.name]\].") -/obj/machinery/computer/teleporter/attackby(var/obj/I, var/mob/user) +/obj/machinery/computer/teleporter/attackby(var/obj/used_item, var/mob/user) - var/obj/item/card/data/C = I + var/obj/item/card/data/C = used_item if(!istype(C) || (stat & (NOPOWER|BROKEN)) || C.function != "teleporter") return ..() @@ -64,10 +64,10 @@ if(!L) L = locate("landmark*[C.data]") // use old stype - if(istype(L, /obj/abstract/landmark) && isturf(L.loc) && user.try_unequip(I)) + if(istype(L, /obj/abstract/landmark) && isturf(L.loc) && user.try_unequip(used_item)) to_chat(user, "You insert the coordinates into the machine.") to_chat(user, "A message flashes across the screen reminding the traveller that the nuclear authentication disk is to remain on the [station_name()] at all times.") - qdel(I) + qdel(used_item) audible_message(SPAN_NOTICE("Locked in.")) src.locked = L one_time_use = 1 @@ -98,11 +98,11 @@ areaindex[tmpname] = 1 L[tmpname] = radio - for (var/obj/item/implant/tracking/I in global.tracking_implants) - if (!I.implanted || !ismob(I.loc)) + for (var/obj/item/implant/tracking/used_item in global.tracking_implants) + if (!used_item.implanted || !ismob(used_item.loc)) continue else - var/mob/M = I.loc + var/mob/M = used_item.loc if (M.stat == DEAD) if (M.timeofdeath + 6000 < world.time) continue @@ -116,7 +116,7 @@ tmpname = "[tmpname] ([++areaindex[tmpname]])" else areaindex[tmpname] = 1 - L[tmpname] = I + L[tmpname] = used_item var/desc = input("Please select a location to lock in.", "Locking Computer") in L|null if(!desc) @@ -150,8 +150,8 @@ if(station && station.engaged) station.disengage() -/obj/machinery/computer/teleporter/proc/set_target(var/obj/O) - src.locked = O +/obj/machinery/computer/teleporter/proc/set_target(var/obj/target) + src.locked = target events_repository.register(/decl/observ/destroyed, locked, src, PROC_REF(target_lost)) /obj/machinery/computer/teleporter/Destroy() diff --git a/code/game/machinery/turrets/_turrets.dm b/code/game/machinery/turrets/_turrets.dm index d61ef7495687..8a3633cc0c65 100644 --- a/code/game/machinery/turrets/_turrets.dm +++ b/code/game/machinery/turrets/_turrets.dm @@ -132,19 +132,19 @@ return update_use_power(POWER_USE_IDLE) -/obj/machinery/turret/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/gun) && !installed_gun) - if(!user.try_unequip(I, src)) +/obj/machinery/turret/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/gun) && !installed_gun) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, SPAN_NOTICE("You install \the [I] into \the [src]!")) - installed_gun = I + to_chat(user, SPAN_NOTICE("You install \the [used_item] into \the [src]!")) + installed_gun = used_item setup_gun() return TRUE - if(istype(I, /obj/item/ammo_magazine) || istype(I, /obj/item/ammo_casing)) + if(istype(used_item, /obj/item/ammo_magazine) || istype(used_item, /obj/item/ammo_casing)) var/obj/item/stock_parts/ammo_box/ammo_box = get_component_of_type(/obj/item/stock_parts/ammo_box) if(istype(ammo_box)) - return ammo_box.attackby(I, user) + return ammo_box.attackby(used_item, user) . = ..() // This is called after the gun gets instantiated or slotted in. diff --git a/code/game/machinery/turrets/network_turret.dm b/code/game/machinery/turrets/network_turret.dm index ede8a175eef7..110daa4e9487 100644 --- a/code/game/machinery/turrets/network_turret.dm +++ b/code/game/machinery/turrets/network_turret.dm @@ -34,13 +34,13 @@ . = ..() set_extension(src, /datum/extension/network_device/sentry_turret) -/obj/machinery/turret/network/attackby(obj/item/I, mob/user) +/obj/machinery/turret/network/attackby(obj/item/used_item, mob/user) . = ..() - if(istype(I, /obj/item/stock_parts/computer/hard_drive/portable)) + if(istype(used_item, /obj/item/stock_parts/computer/hard_drive/portable)) if(!check_access(user)) to_chat(user, SPAN_WARNING("\The [src] flashes a red light: you lack access to download its logfile.")) return - var/obj/item/stock_parts/computer/hard_drive/portable/drive = I + var/obj/item/stock_parts/computer/hard_drive/portable/drive = used_item var/datum/computer_file/data/logfile/turret_log = prepare_log_file() if(drive.store_file(turret_log) == OS_FILE_SUCCESS) to_chat(user, SPAN_NOTICE("\The [src] flashes a blue light as it downloads its log file onto \the [drive]!")) diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm index 6211ee65c261..d6773a58c0d0 100644 --- a/code/game/objects/effects/chem/foam.dm +++ b/code/game/objects/effects/chem/foam.dm @@ -170,11 +170,11 @@ physically_destroyed() return TRUE -/obj/structure/foamedmetal/attackby(var/obj/item/I, var/mob/user) - if(prob(I.expend_attack_force(user) * 20 - metal * 25)) +/obj/structure/foamedmetal/attackby(var/obj/item/used_item, var/mob/user) + if(prob(used_item.expend_attack_force(user) * 20 - metal * 25)) user.visible_message( SPAN_WARNING("\The [user] smashes through the foamed metal."), - SPAN_NOTICE("You smash through the foamed metal with \the [I].") + SPAN_NOTICE("You smash through the foamed metal with \the [used_item].") ) physically_destroyed() else diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index 6fe6ea7441a4..3da636a2c505 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -16,13 +16,13 @@ sweepable = TRUE burnable = FALSE -/obj/effect/decal/cleanable/ash/attackby(obj/item/I, mob/user) - if(ATOM_IS_OPEN_CONTAINER(I)) - if(REAGENTS_FREE_SPACE(I.reagents) <= 0) - to_chat(user, SPAN_WARNING("\The [I] is full.")) +/obj/effect/decal/cleanable/ash/attackby(obj/item/used_item, mob/user) + if(ATOM_IS_OPEN_CONTAINER(used_item)) + if(REAGENTS_FREE_SPACE(used_item.reagents) <= 0) + to_chat(user, SPAN_WARNING("\The [used_item] is full.")) else - I.add_to_reagents(/decl/material/solid/carbon/ashes, 20) - user.visible_message(SPAN_NOTICE("\The [user] carefully scoops \the [src] into \the [I].")) + used_item.add_to_reagents(/decl/material/solid/carbon/ashes, 20) + user.visible_message(SPAN_NOTICE("\The [user] carefully scoops \the [src] into \the [used_item].")) qdel(src) return TRUE return ..() diff --git a/code/game/objects/items/books/skill/_skill_custom.dm b/code/game/objects/items/books/skill/_skill_custom.dm index 2d9bfa2a3595..736cd80fe022 100644 --- a/code/game/objects/items/books/skill/_skill_custom.dm +++ b/code/game/objects/items/books/skill/_skill_custom.dm @@ -53,8 +53,8 @@ /obj/item/book/skill/custom/question icon = 'icons/obj/items/books/book_white_question.dmi' -/obj/item/book/skill/custom/attackby(obj/item/pen, mob/user) - if(!IS_PEN(pen)) +/obj/item/book/skill/custom/attackby(obj/item/used_item, mob/user) + if(!IS_PEN(used_item)) return ..() if(!user.skill_check(SKILL_LITERACY, SKILL_BASIC)) to_chat(user, SPAN_WARNING("You can't even read, yet you want to write a whole educational textbook?")) @@ -64,26 +64,26 @@ return TRUE var/state_check = skill_option_string // the state skill_option_string is in just before opening the input var/choice = input(user, "What would you like to change?","Textbook editing") as null|anything in list("Title", "Author", skill_option_string) - if(!can_write(pen,user)) + if(!can_write(used_item,user)) return TRUE switch(choice) if("Title") - edit_title(pen, user) + edit_title(used_item, user) if("Skill") if(state_check != "Skill") // make sure someone hasn't already started the book while we were staring at menus woops to_chat(user, SPAN_WARNING("The skill has already been selected and the writing started.")) return TRUE - edit_skill(pen, user) + edit_skill(used_item, user) if("Continue writing content") if(state_check != "Continue writing content") return TRUE - continue_skill(pen, user) + continue_skill(used_item, user) if("Author") - edit_author(pen, user) + edit_author(used_item, user) else return TRUE diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 890fb77b269c..104617710a6e 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -67,8 +67,8 @@ STOP_PROCESSING_POWER_OBJECT(src) . = ..() -/obj/item/powersink/attackby(var/obj/item/I, var/mob/user) - if(IS_SCREWDRIVER(I)) +/obj/item/powersink/attackby(var/obj/item/used_item, var/mob/user) + if(IS_SCREWDRIVER(used_item)) if(mode == DISCONNECTED) var/turf/T = loc if(isturf(T) && !!T.is_plating()) diff --git a/code/game/objects/items/devices/radio/beacon.dm b/code/game/objects/items/devices/radio/beacon.dm index 3aa24d6dacaf..1cda309212b5 100644 --- a/code/game/objects/items/devices/radio/beacon.dm +++ b/code/game/objects/items/devices/radio/beacon.dm @@ -74,8 +74,8 @@ var/global/list/radio_beacons = list() var/turf/T = get_turf(src) hide(hides_under_flooring() && !T.is_plating()) -/obj/item/radio/beacon/anchored/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/stack/nanopaste)) +/obj/item/radio/beacon/anchored/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/stack/nanopaste)) if(functioning) to_chat(user, SPAN_WARNING("\The [src] does not need any repairs.")) return TRUE @@ -83,7 +83,7 @@ var/global/list/radio_beacons = list() to_chat(user, SPAN_WARNING("\The [src] is completely irrepairable.")) return TRUE - var/obj/item/stack/nanopaste/S = I + var/obj/item/stack/nanopaste/S = used_item if(!panel_open) to_chat(user, SPAN_WARNING("You can't work on \the [src] until its been opened up.")) return TRUE diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 54ecd2dfd4ef..32287bf5e738 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -38,20 +38,20 @@ mytape = null return ..() -/obj/item/taperecorder/attackby(obj/item/I, mob/user, params) - if(IS_SCREWDRIVER(I)) +/obj/item/taperecorder/attackby(obj/item/used_item, mob/user, params) + if(IS_SCREWDRIVER(used_item)) maintenance = !maintenance to_chat(user, "You [maintenance ? "open" : "secure"] the lid.") return TRUE - if(istype(I, /obj/item/magnetic_tape)) + if(istype(used_item, /obj/item/magnetic_tape)) if(mytape) to_chat(user, "There's already a tape inside.") return TRUE - if(!user.try_unequip(I)) + if(!user.try_unequip(used_item)) return TRUE - I.forceMove(src) - mytape = I - to_chat(user, "You insert [I] into [src].") + used_item.forceMove(src) + mytape = used_item + to_chat(user, "You insert [used_item] into [src].") update_icon() return TRUE return ..() @@ -421,10 +421,10 @@ storedinfo += "*\[[time2text(used_capacity*10,"mm:ss")]\] [text]" -/obj/item/magnetic_tape/attackby(obj/item/I, mob/user, params) +/obj/item/magnetic_tape/attackby(obj/item/used_item, mob/user, params) if(user.incapacitated()) // TODO: this may not be necessary since OnClick checks before starting the attack chain return TRUE - if(ruined && IS_SCREWDRIVER(I)) + if(ruined && IS_SCREWDRIVER(used_item)) if(!max_capacity) to_chat(user, "There is no tape left inside.") return TRUE @@ -433,7 +433,7 @@ to_chat(user, "You wound the tape back in.") fix() return TRUE - else if(IS_PEN(I)) + else if(IS_PEN(used_item)) if(loc == user) var/new_name = input(user, "What would you like to label the tape?", "Tape labeling") as null|text if(isnull(new_name)) return TRUE @@ -445,11 +445,11 @@ SetName("tape") to_chat(user, "You scratch off the label.") return TRUE - else if(IS_WIRECUTTER(I)) + else if(IS_WIRECUTTER(used_item)) cut(user) return TRUE - else if(istype(I, /obj/item/magnetic_tape/loose)) - join(user, I) + else if(istype(used_item, /obj/item/magnetic_tape/loose)) + join(user, used_item) return TRUE return ..() diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 2f2506b6aa05..40f7cc830eff 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -28,21 +28,21 @@ attacher_ref = null return ..() -/obj/item/transfer_valve/attackby(obj/item/item, mob/user) +/obj/item/transfer_valve/attackby(obj/item/used_item, mob/user) var/turf/location = get_turf(src) // For admin logs - if(istype(item, /obj/item/tank)) + if(istype(used_item, /obj/item/tank)) var/T1_weight = 0 var/T2_weight = 0 if(tank_one && tank_two) to_chat(user, "There are already two tanks attached, remove one first.") return TRUE - if(!user.try_unequip(item, src)) + if(!user.try_unequip(used_item, src)) return TRUE if(!tank_one) - tank_one = item + tank_one = used_item else - tank_two = item + tank_two = used_item message_admins("[key_name_admin(user)] attached both tanks to a transfer valve. (JMP)") log_game("[key_name_admin(user)] attached both tanks to a transfer valve.") to_chat(user, "You attach the tank to the transfer valve.") @@ -54,24 +54,24 @@ src.w_class = max(initial(src.w_class),T1_weight,T2_weight) //gets w_class of biggest object, because you shouldn't be able to just shove tanks in and have them be tiny. . = TRUE //TODO: Have this take an assemblyholder - else if(isassembly(item)) - var/obj/item/assembly/A = item + else if(isassembly(used_item)) + var/obj/item/assembly/A = used_item if(A.secured) to_chat(user, "The device is secured.") return TRUE if(attached_device) to_chat(user, "There is already an device attached to the valve, remove it first.") return TRUE - if(!user.try_unequip(item, src)) + if(!user.try_unequip(used_item, src)) return TRUE attached_device = A - to_chat(user, "You attach \the [item] to the valve controls and secure it.") + to_chat(user, "You attach \the [used_item] to the valve controls and secure it.") A.holder = src A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb). - global.bombers += "[key_name(user)] attached a [item] to a transfer valve." - message_admins("[key_name_admin(user)] attached a [item] to a transfer valve. (JMP)") - log_game("[key_name_admin(user)] attached a [item] to a transfer valve.") + global.bombers += "[key_name(user)] attached a [used_item] to a transfer valve." + message_admins("[key_name_admin(user)] attached a [used_item] to a transfer valve. (JMP)") + log_game("[key_name_admin(user)] attached a [used_item] to a transfer valve.") attacher_ref = weakref(user) . = TRUE if(.) diff --git a/code/game/objects/items/devices/tvcamera.dm b/code/game/objects/items/devices/tvcamera.dm index 753ead692e42..4450994afe0c 100644 --- a/code/game/objects/items/devices/tvcamera.dm +++ b/code/game/objects/items/devices/tvcamera.dm @@ -97,12 +97,13 @@ /* Assembly by a roboticist */ // TODO: Make this slapcrafting or remove tvcamera/tvassembly entirely -/obj/item/robot_parts/head/attackby(var/obj/item/assembly/S, mob/user) - if (!istype(S, /obj/item/assembly/infra)) +/obj/item/robot_parts/head/attackby(obj/item/used_item, mob/user) + var/obj/item/assembly/infra/assembly = used_item + if(!istype(assembly)) return ..() - var/obj/item/TVAssembly/A = new(user) - qdel(S) - user.put_in_hands(A) + var/obj/item/TVAssembly/tv_assembly = new(user) + qdel(assembly) + user.put_in_hands(tv_assembly) to_chat(user, "You add the infrared sensor to the robot head.") qdel(src) return TRUE diff --git a/code/game/objects/items/paintkit.dm b/code/game/objects/items/paintkit.dm index 9e99fdea07d2..5d8602efb267 100644 --- a/code/game/objects/items/paintkit.dm +++ b/code/game/objects/items/paintkit.dm @@ -38,10 +38,10 @@ desc = "A kit for modifying a voidsuit." uses = 2 -/obj/item/clothing/head/helmet/space/void/attackby(var/obj/item/O, var/mob/user) +/obj/item/clothing/head/helmet/space/void/attackby(var/obj/item/used_item, var/mob/user) - if(istype(O,/obj/item/kit/suit)) - var/obj/item/kit/suit/kit = O + if(istype(used_item,/obj/item/kit/suit)) + var/obj/item/kit/suit/kit = used_item to_chat(user, SPAN_NOTICE("You set about modifying \the [src] into \a [kit.new_name] void helmet.")) SetName("[kit.new_name] void helmet") desc = kit.new_desc @@ -53,10 +53,10 @@ return ..() -/obj/item/clothing/suit/space/void/attackby(var/obj/item/O, var/mob/user) +/obj/item/clothing/suit/space/void/attackby(var/obj/item/used_item, var/mob/user) - if(istype(O, /obj/item/kit/suit)) - var/obj/item/kit/suit/kit = O + if(istype(used_item, /obj/item/kit/suit)) + var/obj/item/kit/suit/kit = used_item to_chat(user, SPAN_NOTICE("You set about modifying \the [src] into \a [kit.new_name] voidsuit.")) SetName("[kit.new_name] voidsuit") desc = kit.new_desc diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 37ebe84e2db5..2dadd2bbf4d5 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -35,8 +35,8 @@ else . += "It has a blank space for a signature." -/obj/item/card/union/attackby(var/obj/item/thing, var/mob/user) - if(IS_PEN(thing)) +/obj/item/card/union/attackby(var/obj/item/used_item, var/mob/user) + if(IS_PEN(used_item)) if(signed_by) to_chat(user, SPAN_WARNING("\The [src] has already been signed.")) else @@ -63,9 +63,9 @@ . = ..() add_overlay(overlay_image(icon, "[icon_state]-color", detail_color)) -/obj/item/card/data/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/integrated_electronics/detailer)) - var/obj/item/integrated_electronics/detailer/D = I +/obj/item/card/data/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/integrated_electronics/detailer)) + var/obj/item/integrated_electronics/detailer/D = used_item detail_color = D.detail_color update_icon() return ..() diff --git a/code/game/objects/items/weapons/ecigs.dm b/code/game/objects/items/weapons/ecigs.dm index 55789ad967b9..353404026db9 100644 --- a/code/game/objects/items/weapons/ecigs.dm +++ b/code/game/objects/items/weapons/ecigs.dm @@ -131,14 +131,14 @@ M.update_equipment_overlay(slot_wear_mask_str, redraw_mob = FALSE) M.update_inhand_overlays() -/obj/item/clothing/mask/smokable/ecig/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/chems/ecig_cartridge)) +/obj/item/clothing/mask/smokable/ecig/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/chems/ecig_cartridge)) if (ec_cartridge)//can't add second one to_chat(user, SPAN_NOTICE("A cartridge has already been installed.")) - else if(user.try_unequip(I, src))//fits in new one - ec_cartridge = I + else if(user.try_unequip(used_item, src))//fits in new one + ec_cartridge = used_item update_icon() - to_chat(user, SPAN_NOTICE("You insert \the [I] into \the [src].")) + to_chat(user, SPAN_NOTICE("You insert \the [used_item] into \the [src].")) return TRUE return ..() diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 289c8d6fcd57..296e348430d4 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -28,12 +28,12 @@ wires = null return ..() -/obj/item/plastique/attackby(var/obj/item/I, var/mob/user) - if(IS_SCREWDRIVER(I)) +/obj/item/plastique/attackby(var/obj/item/used_item, var/mob/user) + if(IS_SCREWDRIVER(used_item)) open_panel = !open_panel to_chat(user, "You [open_panel ? "open" : "close"] the wire panel.") return TRUE - else if(IS_WIRECUTTER(I) || IS_MULTITOOL(I) || istype(I, /obj/item/assembly/signaler )) + else if(IS_WIRECUTTER(used_item) || IS_MULTITOOL(used_item) || istype(used_item, /obj/item/assembly/signaler )) return wires.Interact(user) else return ..() diff --git a/code/game/objects/items/weapons/mop.dm b/code/game/objects/items/weapons/mop.dm index 87d93544aebe..2efa8c00554f 100644 --- a/code/game/objects/items/weapons/mop.dm +++ b/code/game/objects/items/weapons/mop.dm @@ -68,8 +68,8 @@ to_chat(user, SPAN_NOTICE("You have finished mopping!")) return TRUE -/obj/effect/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/mop) || istype(I, /obj/item/soap)) +/obj/effect/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/mop) || istype(used_item, /obj/item/soap)) return FALSE return ..() diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm index 99614d0fe16e..bd0956bad5b2 100644 --- a/code/game/objects/items/weapons/soap.dm +++ b/code/game/objects/items/weapons/soap.dm @@ -111,13 +111,13 @@ return TRUE return ..() -/obj/item/soap/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/key)) +/obj/item/soap/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/key)) if(key_data) to_chat(user, SPAN_WARNING("\The [src] already has a key imprint.")) else - to_chat(user, SPAN_NOTICE("You imprint \the [I] into \the [src].")) - var/obj/item/key/K = I + to_chat(user, SPAN_NOTICE("You imprint \the [used_item] into \the [src].")) + var/obj/item/key/K = used_item key_data = K.key_data update_icon() return TRUE diff --git a/code/game/objects/structures/barsign.dm b/code/game/objects/structures/barsign.dm index d47f2eef2fd7..f3f0467e1a62 100644 --- a/code/game/objects/structures/barsign.dm +++ b/code/game/objects/structures/barsign.dm @@ -33,11 +33,11 @@ . = ..() icon_state = pick(get_valid_states()) -/obj/structure/sign/double/barsign/attackby(obj/item/I, mob/user) +/obj/structure/sign/double/barsign/attackby(obj/item/used_item, mob/user) if(cult) return ..() - var/obj/item/card/id/card = I.GetIdCard() + var/obj/item/card/id/card = used_item.GetIdCard() if(istype(card)) if(access_bar in card.GetAccess()) var/sign_type = input(user, "What would you like to change the barsign to?") as null|anything in get_valid_states(0) diff --git a/code/game/objects/structures/beds/rollerbed.dm b/code/game/objects/structures/beds/rollerbed.dm index a919d9f30bc9..a3f332b4b044 100644 --- a/code/game/objects/structures/beds/rollerbed.dm +++ b/code/game/objects/structures/beds/rollerbed.dm @@ -34,12 +34,12 @@ iv.pixel_y = 6 add_overlay(iv) -/obj/structure/bed/roller/attackby(obj/item/I, mob/user) - if(iv_stand && !beaker && istype(I, /obj/item/chems)) - if(!user.try_unequip(I, src)) +/obj/structure/bed/roller/attackby(obj/item/used_item, mob/user) + if(iv_stand && !beaker && istype(used_item, /obj/item/chems)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, "You attach \the [I] to \the [src].") - beaker = I + to_chat(user, "You attach \the [used_item] to \the [src].") + beaker = used_item queue_icon_update() return TRUE return ..() diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm index ccfe1f59c914..8fa15bf53cdc 100644 --- a/code/game/objects/structures/bedsheet_bin.dm +++ b/code/game/objects/structures/bedsheet_bin.dm @@ -18,9 +18,9 @@ LINEN BINS w_class = ITEM_SIZE_SMALL material = /decl/material/solid/organic/cloth -/obj/item/bedsheet/attackby(obj/item/I, mob/user) - if(I.is_sharp() || I.has_edge()) - user.visible_message("\The [user] begins cutting up \the [src] with \a [I].", "You begin cutting up \the [src] with \the [I].") +/obj/item/bedsheet/attackby(obj/item/used_item, mob/user) + if(used_item.is_sharp() || used_item.has_edge()) + user.visible_message("\The [user] begins cutting up \the [src] with \a [used_item].", "You begin cutting up \the [src] with \the [used_item].") if(do_after(user, 50, src)) to_chat(user, "You cut \the [src] into pieces!") for(var/i in 1 to rand(2,5)) @@ -137,33 +137,33 @@ LINEN BINS else icon_state = "linenbin-full" -/obj/structure/bedsheetbin/attackby(obj/item/I, mob/user) +/obj/structure/bedsheetbin/attackby(obj/item/used_item, mob/user) var/curamount = get_amount() - if(istype(I, /obj/item/bedsheet)) + if(istype(used_item, /obj/item/bedsheet)) if(curamount >= max_stored) to_chat(user, SPAN_WARNING("\The [src] is full!")) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - LAZYDISTINCTADD(sheets, I) + LAZYDISTINCTADD(sheets, used_item) update_icon() - to_chat(user, SPAN_NOTICE("You put [I] in [src].")) + to_chat(user, SPAN_NOTICE("You put [used_item] in [src].")) return TRUE //Let the parent attackby run to handle tool interactions . = ..() if(!.) - if(curamount && !hidden && I.w_class < w_class) //make sure there's sheets to hide it among, make sure nothing else is hidden in there. - if(!user.try_unequip(I, src)) + if(curamount && !hidden && used_item.w_class < w_class) //make sure there's sheets to hide it among, make sure nothing else is hidden in there. + if(!user.try_unequip(used_item, src)) return TRUE - hidden = I - to_chat(user, SPAN_NOTICE("You hide [I] among the sheets.")) + hidden = used_item + to_chat(user, SPAN_NOTICE("You hide [used_item] among the sheets.")) return TRUE else if(hidden) - to_chat(user, SPAN_WARNING("There's not enough space to hide \the [I]!")) - else if(I.w_class >= w_class) - to_chat(user, SPAN_WARNING("\The [I] is too big to hide in \the [src]!")) + to_chat(user, SPAN_WARNING("There's not enough space to hide \the [used_item]!")) + else if(used_item.w_class >= w_class) + to_chat(user, SPAN_WARNING("\The [used_item] is too big to hide in \the [src]!")) else if(curamount < 1) to_chat(user, SPAN_WARNING("You can't hide anything if there's no sheets to cover it!")) diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index b7186e1926d5..a8a883a64c3f 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -76,9 +76,9 @@ for(var/i = 1 to 4) add_overlay(image(icon, "catwalk[connections ? connections[i] : "0"]", dir = BITFLAG(i-1))) if(plated_tile) - var/image/I = image(icon, "plated") - I.color = plated_tile.color - add_overlay(I) + var/image/overlay_image = image(icon, "plated") + overlay_image.color = plated_tile.color + add_overlay(overlay_image) /obj/structure/catwalk/create_dismantled_products(var/turf/T) . = ..() @@ -109,25 +109,25 @@ /obj/structure/catwalk/attack_robot(var/mob/user) return attack_hand_with_interaction_checks(user) -/obj/structure/catwalk/attackby(obj/item/C, mob/user) +/obj/structure/catwalk/attackby(obj/item/used_item, mob/user) if((. = ..())) return - if(istype(C, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = C + if(istype(used_item, /obj/item/gun/energy/plasmacutter)) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(cutter.slice(user)) dismantle_structure(user) return TRUE - if(istype(C, /obj/item/stack/tile/mono) && !plated_tile) + if(istype(used_item, /obj/item/stack/tile/mono) && !plated_tile) var/ladder = (locate(/obj/structure/ladder) in loc) if(ladder) to_chat(user, SPAN_WARNING("\The [ladder] is in the way.")) return TRUE - var/obj/item/stack/tile/ST = C + var/obj/item/stack/tile/ST = used_item if(ST.in_use) return TRUE @@ -148,7 +148,7 @@ var/decl/flooring/F = decls[flooring_type] if(!F.build_type) continue - if(istype(C, F.build_type) && (!F.build_material || C.material?.type == F.build_material)) + if(istype(used_item, F.build_type) && (!F.build_material || used_item.material?.type == F.build_material)) plated_tile = F break update_icon() @@ -217,10 +217,10 @@ if(locate(/obj/structure/catwalk) in loc) warning("Frame Spawner: A catwalk already exists at [loc.x]-[loc.y]-[loc.z]") else - var/obj/structure/catwalk/C = new /obj/structure/catwalk(loc) - C.plated_tile += GET_DECL(plating_type) - C.name = "plated catwalk" - C.update_icon() + var/obj/structure/catwalk/catwalk = new /obj/structure/catwalk(loc) + catwalk.plated_tile += GET_DECL(plating_type) + catwalk.name = "plated catwalk" + catwalk.update_icon() activated = 1 for(var/turf/T in orange(src, 1)) for(var/obj/effect/wallframe_spawn/other in T) diff --git a/code/game/objects/structures/charge_pylon.dm b/code/game/objects/structures/charge_pylon.dm index fd12329b714f..8c504e466205 100644 --- a/code/game/objects/structures/charge_pylon.dm +++ b/code/game/objects/structures/charge_pylon.dm @@ -45,10 +45,10 @@ visible_message("\The [user] has been shocked by \the [src]!") user.throw_at(get_step(user,get_dir(src,user)), 5, 10) -/obj/structure/charge_pylon/attackby(var/obj/item/item, mob/user) - if(!istype(item, /obj/item/grab)) +/obj/structure/charge_pylon/attackby(var/obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/grab)) return FALSE - var/obj/item/grab/grab = item + var/obj/item/grab/grab = used_item var/mob/M = grab.get_affecting_mob() if(M) charge_user(M) diff --git a/code/game/objects/structures/chemistry/heater.dm b/code/game/objects/structures/chemistry/heater.dm index 7050d2f9ee86..bf0c3a573feb 100644 --- a/code/game/objects/structures/chemistry/heater.dm +++ b/code/game/objects/structures/chemistry/heater.dm @@ -75,18 +75,18 @@ if(ismob(new_loc)) visible_message(SPAN_NOTICE("\The [new_loc] removes \the [am] from \the [src].")) -/obj/structure/fire_source/heater/attackby(obj/item/thing, mob/user) +/obj/structure/fire_source/heater/attackby(obj/item/used_item, mob/user) - if(istype(thing, /obj/item/chems/glass) && ATOM_IS_OPEN_CONTAINER(thing)) + if(istype(used_item, /obj/item/chems/glass) && ATOM_IS_OPEN_CONTAINER(used_item)) if(retort && vessel) to_chat(user, SPAN_WARNING("\The [src] is already holding \a [retort] and \a [vessel].")) return TRUE - if(user.try_unequip(thing, src)) + if(user.try_unequip(used_item, src)) if(!retort) - set_retort(thing) + set_retort(used_item) visible_message(SPAN_NOTICE("\The [user] places \the [retort] onto \the [src].")) else if(!vessel) - set_vessel(thing) + set_vessel(used_item) visible_message(SPAN_NOTICE("\The [user] places \the [vessel] under \the [src].")) return TRUE diff --git a/code/game/objects/structures/crates_lockers/closets/statue.dm b/code/game/objects/structures/crates_lockers/closets/statue.dm index 27a6d55f4fce..946821ceff5a 100644 --- a/code/game/objects/structures/crates_lockers/closets/statue.dm +++ b/code/game/objects/structures/crates_lockers/closets/statue.dm @@ -98,10 +98,10 @@ current_health -= 60 / severity check_health() -/obj/structure/closet/statue/attackby(obj/item/I, mob/user) - current_health -= I.expend_attack_force(user) +/obj/structure/closet/statue/attackby(obj/item/used_item, mob/user) + current_health -= used_item.expend_attack_force(user) user.do_attack_animation(src) - visible_message("[user] strikes [src] with [I].") + visible_message("[user] strikes [src] with [used_item].") check_health() return TRUE diff --git a/code/game/objects/structures/drain.dm b/code/game/objects/structures/drain.dm index 7863c0f7c171..66cdf42b45e0 100644 --- a/code/game/objects/structures/drain.dm +++ b/code/game/objects/structures/drain.dm @@ -16,17 +16,17 @@ if(welded) . += "It is welded shut." -/obj/structure/hygiene/drain/attackby(var/obj/item/thing, var/mob/user) - if(IS_WELDER(thing)) - var/obj/item/weldingtool/welder = thing +/obj/structure/hygiene/drain/attackby(var/obj/item/used_item, var/mob/user) + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(welder.isOn()) welded = !welded to_chat(user, "You weld \the [src] [welded ? "closed" : "open"].") else - to_chat(user, "Turn \the [thing] on, first.") + to_chat(user, "Turn \the [used_item] on, first.") update_icon() return TRUE - if(IS_WRENCH(thing)) + if(IS_WRENCH(used_item)) new /obj/item/drain(src.loc) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) to_chat(user, "[user] unwrenches \the [src].") @@ -52,8 +52,8 @@ material = /decl/material/solid/metal/brass var/constructed_type = /obj/structure/hygiene/drain -/obj/item/drain/attackby(var/obj/item/thing, var/mob/user) - if(IS_WRENCH(thing)) +/obj/item/drain/attackby(var/obj/item/used_item, var/mob/user) + if(IS_WRENCH(used_item)) new constructed_type(get_turf(src)) playsound(src, 'sound/items/Ratchet.ogg', 50, 1) to_chat(user, SPAN_NOTICE("\The [user] wrenches \the [src] down.")) diff --git a/code/game/objects/structures/extinguisher.dm b/code/game/objects/structures/extinguisher.dm index 768fe81af7f1..79cd15f429fc 100644 --- a/code/game/objects/structures/extinguisher.dm +++ b/code/game/objects/structures/extinguisher.dm @@ -16,13 +16,13 @@ // TODO: I wanted to make it so you had to actually use your hand to open it if it's closed, but // that'd be out of scope for just an attackby audit. Someone fix this so it can call parent please. -/obj/structure/extinguisher_cabinet/attackby(obj/item/O, mob/user) +/obj/structure/extinguisher_cabinet/attackby(obj/item/used_item, mob/user) if(isrobot(user)) return FALSE - if(istype(O, /obj/item/chems/spray/extinguisher)) - if(!has_extinguisher && opened && user.try_unequip(O, src)) - has_extinguisher = O - to_chat(user, "You place [O] in [src].") + if(istype(used_item, /obj/item/chems/spray/extinguisher)) + if(!has_extinguisher && opened && user.try_unequip(used_item, src)) + has_extinguisher = used_item + to_chat(user, "You place [used_item] in [src].") playsound(src.loc, 'sound/effects/extin.ogg', 50, 0) else opened = !opened diff --git a/code/game/objects/structures/fences.dm b/code/game/objects/structures/fences.dm index 8a127ce484fe..05eb791fb898 100644 --- a/code/game/objects/structures/fences.dm +++ b/code/game/objects/structures/fences.dm @@ -77,8 +77,8 @@ return TRUE return ..() -/obj/structure/fence/handle_repair(mob/user, obj/item/tool) - var/obj/item/stack/stack = tool +/obj/structure/fence/handle_repair(mob/user, obj/item/used_item) + var/obj/item/stack/stack = used_item if(hole_size > NO_HOLE && istype(stack)) to_chat(user, SPAN_NOTICE("You fit [stack.get_string_for_amount(1)] to damaged areas of \the [src].")) stack.use(1) @@ -88,8 +88,8 @@ return ..() -/obj/structure/fence/attackby(obj/item/tool, mob/user) - if(IS_WIRECUTTER(tool)) +/obj/structure/fence/attackby(obj/item/used_item, mob/user) + if(IS_WIRECUTTER(used_item)) if(!cuttable) to_chat(user, SPAN_WARNING("This section of the fence can't be cut.")) return TRUE @@ -98,7 +98,7 @@ to_chat(user, SPAN_NOTICE("This fence has too much cut out of it already.")) return TRUE - if(tool.do_tool_interaction(TOOL_WIRECUTTERS, user, src, CUT_TIME, "cutting through", "cutting through", check_skill = FALSE) && current_stage == hole_size) // do_tool_interaction sleeps, so make sure it hasn't been cut more while we waited + if(used_item.do_tool_interaction(TOOL_WIRECUTTERS, user, src, CUT_TIME, "cutting through", "cutting through", check_skill = FALSE) && current_stage == hole_size) // do_tool_interaction sleeps, so make sure it hasn't been cut more while we waited switch(++hole_size) if(MEDIUM_HOLE) user.visible_message( diff --git a/code/game/objects/structures/fireaxe_cabinet.dm b/code/game/objects/structures/fireaxe_cabinet.dm index ec563ffce7e7..d1b9ada07538 100644 --- a/code/game/objects/structures/fireaxe_cabinet.dm +++ b/code/game/objects/structures/fireaxe_cabinet.dm @@ -64,29 +64,29 @@ fireaxe = null . = ..() -/obj/structure/fireaxecabinet/attackby(var/obj/item/O, var/mob/user) +/obj/structure/fireaxecabinet/attackby(var/obj/item/used_item, var/mob/user) - if(IS_MULTITOOL(O)) + if(IS_MULTITOOL(used_item)) toggle_lock(user) return TRUE - if(istype(O, /obj/item/bladed/axe/fire)) + if(istype(used_item, /obj/item/bladed/axe/fire)) if(open) if(fireaxe) to_chat(user, "There is already \a [fireaxe] inside \the [src].") - else if(user.try_unequip(O)) - O.forceMove(src) - fireaxe = O + else if(user.try_unequip(used_item)) + used_item.forceMove(src) + fireaxe = used_item to_chat(user, "You place \the [fireaxe] into \the [src].") update_icon() return TRUE - var/force = O.expend_attack_force(user) + var/force = used_item.expend_attack_force(user) if(force) user.setClickCooldown(10) attack_animation(user) playsound(user, 'sound/effects/Glasshit.ogg', 50, 1) - visible_message("[user] [pick(O.attack_verb)] \the [src]!") + visible_message("[user] [pick(used_item.attack_verb)] \the [src]!") if(damage_threshold > force) to_chat(user, "Your strike is deflected by the reinforced glass!") return TRUE diff --git a/code/game/objects/structures/fires.dm b/code/game/objects/structures/fires.dm index 2c7dbb75097f..4e6c92a6daaa 100644 --- a/code/game/objects/structures/fires.dm +++ b/code/game/objects/structures/fires.dm @@ -277,36 +277,36 @@ environment.adjust_gas(w, waste[w], FALSE) environment.update_values() -/obj/structure/fire_source/attackby(var/obj/item/thing, var/mob/user) +/obj/structure/fire_source/attackby(var/obj/item/used_item, var/mob/user) // Gate a few interactions behind intent so they can be bypassed if needed. if(!user.check_intent(I_FLAG_HARM)) // Put cooking items onto the fire source. - if(istype(thing, /obj/item/chems/cooking_vessel) && user.try_unequip(thing, get_turf(src))) - thing.reset_offsets() + if(istype(used_item, /obj/item/chems/cooking_vessel) && user.try_unequip(used_item, get_turf(src))) + used_item.reset_offsets() return TRUE // Pour fuel or water into a fire. - if(istype(thing, /obj/item/chems)) - var/obj/item/chems/chems = thing + if(istype(used_item, /obj/item/chems)) + var/obj/item/chems/chems = used_item if(chems.standard_pour_into(user, src)) return TRUE - if(lit == FIRE_LIT && istype(thing, /obj/item/flame)) - thing.fire_act(return_air(), get_effective_burn_temperature(), 500) + if(lit == FIRE_LIT && istype(used_item, /obj/item/flame)) + used_item.fire_act(return_air(), get_effective_burn_temperature(), 500) return TRUE - if(thing.isflamesource()) - visible_message(SPAN_NOTICE("\The [user] attempts to light \the [src] with \the [thing].")) - try_light(thing.get_heat()) + if(used_item.isflamesource()) + visible_message(SPAN_NOTICE("\The [user] attempts to light \the [src] with \the [used_item].")) + try_light(used_item.get_heat()) return TRUE if((lit != FIRE_LIT || user.check_intent(I_FLAG_HARM))) // Only drop in one log at a time. - if(istype(thing, /obj/item/stack)) - var/obj/item/stack/stack = thing - thing = stack.split(1) - if(!QDELETED(thing) && user.try_unequip(thing, src)) - user.visible_message(SPAN_NOTICE("\The [user] drops \the [thing] into \the [src].")) + if(istype(used_item, /obj/item/stack)) + var/obj/item/stack/stack = used_item + used_item = stack.split(1) + if(!QDELETED(used_item) && user.try_unequip(used_item, src)) + user.visible_message(SPAN_NOTICE("\The [user] drops \the [used_item] into \the [src].")) update_icon() return TRUE diff --git a/code/game/objects/structures/flora/_flora.dm b/code/game/objects/structures/flora/_flora.dm index c38361f4a845..6d50acaf27e6 100644 --- a/code/game/objects/structures/flora/_flora.dm +++ b/code/game/objects/structures/flora/_flora.dm @@ -25,16 +25,16 @@ clear_materials() return ..() -/obj/structure/flora/attackby(obj/item/O, mob/user) - if(!user.check_intent(I_FLAG_HARM) && can_cut_down(O, user)) +/obj/structure/flora/attackby(obj/item/used_item, mob/user) + if(!user.check_intent(I_FLAG_HARM) && can_cut_down(used_item, user)) play_cut_sound(user) - cut_down(O, user) + cut_down(used_item, user) return TRUE . = ..() /**Whether the item used by user can cause cut_down to be called. Used to bypass default attack proc for some specific items/tools. */ -/obj/structure/flora/proc/can_cut_down(var/obj/item/I, var/mob/user) - return (I.expend_attack_force(user) >= 5) && I.is_sharp() //Anything sharp and relatively strong can cut us instantly +/obj/structure/flora/proc/can_cut_down(var/obj/item/used_item, var/mob/user) + return (used_item.expend_attack_force(user) >= 5) && used_item.is_sharp() //Anything sharp and relatively strong can cut us instantly /**What to do when the can_cut_down check returns true. Normally simply calls dismantle. */ /obj/structure/flora/proc/play_cut_sound(mob/user) @@ -42,7 +42,7 @@ if(snd_cut) playsound(src, snd_cut, 40, TRUE) -/obj/structure/flora/proc/cut_down(var/obj/item/I, var/mob/user) +/obj/structure/flora/proc/cut_down(var/obj/item/used_item, var/mob/user) dismantle_structure(user) return TRUE diff --git a/code/game/objects/structures/flora/plant.dm b/code/game/objects/structures/flora/plant.dm index 02ccd36a6567..9e44f55a2f3a 100644 --- a/code/game/objects/structures/flora/plant.dm +++ b/code/game/objects/structures/flora/plant.dm @@ -73,15 +73,15 @@ reset_color() set_overlays(plant.get_appearance(dead = dead, growth_stage = growth_stage, can_harvest = !!harvestable)) -/obj/structure/flora/plant/attackby(obj/item/O, mob/user) +/obj/structure/flora/plant/attackby(obj/item/used_item, mob/user) - if(IS_SHOVEL(O) || IS_HATCHET(O)) - user.visible_message(SPAN_NOTICE("\The [user] uproots \the [src] with \the [O]!")) + if(IS_SHOVEL(used_item) || IS_HATCHET(used_item)) + user.visible_message(SPAN_NOTICE("\The [user] uproots \the [src] with \the [used_item]!")) physically_destroyed() return TRUE // Hydrotray boilerplate for taking samples. - if(O.has_edge() && O.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) + if(used_item.has_edge() && used_item.w_class < ITEM_SIZE_NORMAL && !user.check_intent(I_FLAG_HARM)) if(sampled) to_chat(user, SPAN_WARNING("There's no bits that can be used for a sampling left.")) return TRUE diff --git a/code/game/objects/structures/ironing_board.dm b/code/game/objects/structures/ironing_board.dm index 4853908a3654..a6c821cadf72 100644 --- a/code/game/objects/structures/ironing_board.dm +++ b/code/game/objects/structures/ironing_board.dm @@ -24,14 +24,14 @@ . = ..() -/obj/structure/bed/roller/ironingboard/proc/remove_item(var/obj/item/I) - if(I == cloth) +/obj/structure/bed/roller/ironingboard/proc/remove_item(var/obj/item/used_item) + if(used_item == cloth) cloth = null - else if(I == holding) + else if(used_item == holding) holding = null update_icon() - events_repository.unregister(/decl/observ/destroyed, I, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) + events_repository.unregister(/decl/observ/destroyed, used_item, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) // make a screeching noise to drive people mad /obj/structure/bed/roller/ironingboard/Move() @@ -60,14 +60,14 @@ if(cloth) add_overlay(image(cloth.icon, cloth.icon_state)) -/obj/structure/bed/roller/ironingboard/attackby(var/obj/item/I, var/mob/user) +/obj/structure/bed/roller/ironingboard/attackby(var/obj/item/used_item, var/mob/user) if(!density) - if(istype(I,/obj/item/clothing) || istype(I,/obj/item/ironingiron)) + if(istype(used_item,/obj/item/clothing) || istype(used_item,/obj/item/ironingiron)) to_chat(user, "[src] isn't deployed!") return TRUE return ..() - if(istype(I,/obj/item/clothing)) + if(istype(used_item,/obj/item/clothing)) if(cloth) to_chat(user, "[cloth] is already on the ironing table!") return TRUE @@ -75,13 +75,13 @@ to_chat(user, "[buckled_mob] is already on the ironing table!") return TRUE - if(user.try_unequip(I, src)) - cloth = I - events_repository.register(/decl/observ/destroyed, I, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) + if(user.try_unequip(used_item, src)) + cloth = used_item + events_repository.register(/decl/observ/destroyed, used_item, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) update_icon() return TRUE - else if(istype(I,/obj/item/ironingiron)) - var/obj/item/ironingiron/iron = I + else if(istype(used_item,/obj/item/ironingiron)) + var/obj/item/ironingiron/iron = used_item // anti-wrinkle "massage" if(buckled_mob && ishuman(buckled_mob)) @@ -100,9 +100,9 @@ return TRUE if(!cloth) - if(!holding && !iron.enabled && user.try_unequip(I, src)) + if(!holding && !iron.enabled && user.try_unequip(used_item, src)) holding = iron - events_repository.register(/decl/observ/destroyed, I, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) + events_repository.register(/decl/observ/destroyed, used_item, src, TYPE_PROC_REF(/obj/structure/bed/roller/ironingboard, remove_item)) update_icon() return TRUE to_chat(user, "There isn't anything on the ironing board.") diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 4d58c9790cbf..5d67e910f7cb 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -24,69 +24,69 @@ . += "\The [src] [html_icon(src)] contains [reagents.total_volume] unit\s of liquid!" -/obj/structure/janitorialcart/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/bag/trash) && !mybag) - if(!user.try_unequip(I, src)) +/obj/structure/janitorialcart/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/bag/trash) && !mybag) + if(!user.try_unequip(used_item, src)) return TRUE - mybag = I + mybag = used_item update_icon() updateUsrDialog() - to_chat(user, "You put [I] into [src].") + to_chat(user, "You put [used_item] into [src].") return TRUE - else if(istype(I, /obj/item/mop)) - if(I.reagents.total_volume < I.reagents.maximum_volume) //if it's not completely soaked we assume they want to wet it, otherwise store it + else if(istype(used_item, /obj/item/mop)) + if(used_item.reagents.total_volume < used_item.reagents.maximum_volume) //if it's not completely soaked we assume they want to wet it, otherwise store it if(reagents.total_volume < 1) to_chat(user, "[src] is out of water!") else - reagents.trans_to_obj(I, I.reagents.maximum_volume) - to_chat(user, "You wet [I] in [src].") + reagents.trans_to_obj(used_item, used_item.reagents.maximum_volume) + to_chat(user, "You wet [used_item] in [src].") playsound(loc, 'sound/effects/slosh.ogg', 25, 1) return TRUE if(!mymop) - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - mymop = I + mymop = used_item update_icon() updateUsrDialog() - to_chat(user, "You put [I] into [src].") + to_chat(user, "You put [used_item] into [src].") return TRUE - else if(istype(I, /obj/item/chems/spray) && !myspray) - if(!user.try_unequip(I, src)) + else if(istype(used_item, /obj/item/chems/spray) && !myspray) + if(!user.try_unequip(used_item, src)) return TRUE - myspray = I + myspray = used_item update_icon() updateUsrDialog() - to_chat(user, "You put [I] into [src].") + to_chat(user, "You put [used_item] into [src].") return TRUE - else if(istype(I, /obj/item/lightreplacer) && !myreplacer) - if(!user.try_unequip(I, src)) + else if(istype(used_item, /obj/item/lightreplacer) && !myreplacer) + if(!user.try_unequip(used_item, src)) return TRUE - myreplacer = I + myreplacer = used_item update_icon() updateUsrDialog() - to_chat(user, "You put [I] into [src].") + to_chat(user, "You put [used_item] into [src].") return TRUE - else if(istype(I, /obj/item/caution)) + else if(istype(used_item, /obj/item/caution)) if(signs < 4) - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE signs++ update_icon() updateUsrDialog() - to_chat(user, "You put [I] into [src].") + to_chat(user, "You put [used_item] into [src].") else to_chat(user, "[src] can't hold any more signs.") return TRUE - else if(istype(I, /obj/item/chems/glass)) + else if(istype(used_item, /obj/item/chems/glass)) return FALSE // So we do not put them in the trash bag as we mean to fill the mop bucket; FALSE means run afterattack else if(mybag) - return mybag.attackby(I, user) + return mybag.attackby(used_item, user) return ..() @@ -217,26 +217,26 @@ if(mybag) . += "\A [mybag] is hanging on the [callme]." -/obj/structure/janicart/attackby(obj/item/I, mob/user) +/obj/structure/janicart/attackby(obj/item/used_item, mob/user) - if(istype(I, /obj/item/mop)) + if(istype(used_item, /obj/item/mop)) if(reagents.total_volume > 1) - reagents.trans_to_obj(I, 2) - to_chat(user, SPAN_NOTICE("You wet [I] in the [callme].")) + reagents.trans_to_obj(used_item, 2) + to_chat(user, SPAN_NOTICE("You wet [used_item] in the [callme].")) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else to_chat(user, SPAN_NOTICE("This [callme] is out of water!")) return TRUE - if(istype(I, /obj/item/janicart_key)) - to_chat(user, SPAN_NOTICE("Hold \the [I] in one of your hands while you drive this [callme].")) + if(istype(used_item, /obj/item/janicart_key)) + to_chat(user, SPAN_NOTICE("Hold \the [used_item] in one of your hands while you drive this [callme].")) return TRUE - if(istype(I, /obj/item/bag/trash)) - if(!user.try_unequip(I, src)) + if(istype(used_item, /obj/item/bag/trash)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, SPAN_NOTICE("You hook \the [I] onto the [callme].")) - mybag = I + to_chat(user, SPAN_NOTICE("You hook \the [used_item] onto the [callme].")) + mybag = used_item return TRUE . = ..() diff --git a/code/game/objects/structures/lattice.dm b/code/game/objects/structures/lattice.dm index 6681b61e3e99..0dd3a86c453d 100644 --- a/code/game/objects/structures/lattice.dm +++ b/code/game/objects/structures/lattice.dm @@ -64,30 +64,30 @@ to_chat(user, SPAN_NOTICE("Slicing lattice joints...")) physically_destroyed() -/obj/structure/lattice/attackby(obj/item/C, mob/user) - if (istype(C, /obj/item/stack/tile)) +/obj/structure/lattice/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/stack/tile)) var/turf/T = get_turf(src) - T.attackby(C, user) //BubbleWrap - hand this off to the underlying turf instead + T.attackby(used_item, user) //BubbleWrap - hand this off to the underlying turf instead return TRUE - if(IS_WELDER(C)) - var/obj/item/weldingtool/welder = C + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(welder.weld(0, user)) deconstruct(user) return TRUE - if(istype(C, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = C + if(istype(used_item, /obj/item/gun/energy/plasmacutter)) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(!cutter.slice(user)) return TRUE deconstruct(user) return TRUE - if (istype(C, /obj/item/stack/material/rods)) + if (istype(used_item, /obj/item/stack/material/rods)) var/ladder = (locate(/obj/structure/ladder) in loc) if(ladder) to_chat(user, SPAN_WARNING("\The [ladder] is in the way.")) return TRUE - var/obj/item/stack/material/rods/rods = C + var/obj/item/stack/material/rods/rods = used_item var/turf/my_turf = get_turf(src) if(my_turf?.get_supporting_platform()) to_chat(user, SPAN_WARNING("There is already a platform here.")) diff --git a/code/game/objects/structures/memorial.dm b/code/game/objects/structures/memorial.dm index 5a99c067a93d..38b509028309 100644 --- a/code/game/objects/structures/memorial.dm +++ b/code/game/objects/structures/memorial.dm @@ -12,12 +12,12 @@ var/list/fallen = list() -/obj/structure/memorial/attackby(var/obj/D, var/mob/user) - if(istype(D, /obj/item/clothing/dog_tags)) - var/obj/item/clothing/dog_tags/T = D - to_chat(user, "You add \the [T.owner_name]'s \the [T] to \the [src].") - fallen += "[T.owner_rank] [T.owner_name] | [T.owner_branch]" - qdel(T) +/obj/structure/memorial/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/clothing/dog_tags)) + var/obj/item/clothing/dog_tags/dogtags = used_item + to_chat(user, "You add \the [dogtags.owner_name]'s [dogtags.name] to \the [src].") + fallen += "[dogtags.owner_rank] [dogtags.owner_name] | [dogtags.owner_branch]" + qdel(dogtags) return TRUE return ..() diff --git a/code/game/objects/structures/mop_bucket.dm b/code/game/objects/structures/mop_bucket.dm index 4a4adca8fb22..22eec93ece55 100644 --- a/code/game/objects/structures/mop_bucket.dm +++ b/code/game/objects/structures/mop_bucket.dm @@ -17,15 +17,15 @@ if(distance <= 1) . += "\The [src] [html_icon(src)] contains [reagents.total_volume] unit\s of water!" -/obj/structure/mopbucket/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/mop)) +/obj/structure/mopbucket/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/mop)) if(reagents.total_volume < 1) to_chat(user, SPAN_WARNING("\The [src] is out of water!")) - else if(REAGENTS_FREE_SPACE(I.reagents) >= 5) - reagents.trans_to_obj(I, 5) - to_chat(user, SPAN_NOTICE("You wet \the [I] in \the [src].")) + else if(REAGENTS_FREE_SPACE(used_item.reagents) >= 5) + reagents.trans_to_obj(used_item, 5) + to_chat(user, SPAN_NOTICE("You wet \the [used_item] in \the [src].")) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else - to_chat(user, SPAN_WARNING("\The [I] is saturated.")) + to_chat(user, SPAN_WARNING("\The [used_item] is saturated.")) return TRUE return ..() diff --git a/code/game/objects/structures/produce_bin.dm b/code/game/objects/structures/produce_bin.dm index 5c4b23434322..86ed462f5050 100644 --- a/code/game/objects/structures/produce_bin.dm +++ b/code/game/objects/structures/produce_bin.dm @@ -23,27 +23,27 @@ if(storage.can_be_inserted(produce, null)) storage.handle_item_insertion(null, produce) -/obj/structure/produce_bin/attackby(obj/item/bag, mob/user) +/obj/structure/produce_bin/attackby(obj/item/used_item, mob/user) if(user.check_intent(I_FLAG_HARM)) return ..() - if(bag.storage) + if(used_item.storage) var/emptied = FALSE - for(var/obj/item/food/grown/produce in bag.get_stored_inventory()) + for(var/obj/item/food/grown/produce in used_item.get_stored_inventory()) if(storage.can_be_inserted(produce)) - bag.storage.remove_from_storage(null, produce, loc, skip_update = TRUE) + used_item.storage.remove_from_storage(null, produce, loc, skip_update = TRUE) storage.handle_item_insertion(null, produce, skip_update = TRUE) emptied = TRUE if(emptied) - bag.storage.finish_bulk_removal() + used_item.storage.finish_bulk_removal() storage.finish_bulk_insertion() - if(length(bag.get_stored_inventory())) - to_chat(user, SPAN_NOTICE("You partially empty \the [bag] into \the [src]'s hopper.")) + if(length(used_item.get_stored_inventory())) + to_chat(user, SPAN_NOTICE("You partially empty \the [used_item] into \the [src]'s hopper.")) else - to_chat(user, SPAN_NOTICE("You empty \the [bag] into \the [src]'s hopper.")) + to_chat(user, SPAN_NOTICE("You empty \the [used_item] into \the [src]'s hopper.")) return TRUE return ..() diff --git a/code/game/objects/structures/racks.dm b/code/game/objects/structures/racks.dm index 2cbeb5bb7f58..cda6216899a8 100644 --- a/code/game/objects/structures/racks.dm +++ b/code/game/objects/structures/racks.dm @@ -35,10 +35,10 @@ return DEXTERITY_HOLD_ITEM return ..() -/obj/structure/rack/attackby(obj/item/O, mob/user, click_params) +/obj/structure/rack/attackby(obj/item/used_item, mob/user, click_params) . = ..() - if(!. && !isrobot(user) && O.loc == user && user.try_unequip(O, loc)) - auto_align(O, click_params) + if(!. && !isrobot(user) && used_item.loc == user && user.try_unequip(used_item, loc)) + auto_align(used_item, click_params) return TRUE /obj/structure/rack/holorack/dismantle_structure(mob/user) diff --git a/code/game/objects/structures/rubble.dm b/code/game/objects/structures/rubble.dm index 69a418337921..221b9ebd9ea0 100644 --- a/code/game/objects/structures/rubble.dm +++ b/code/game/objects/structures/rubble.dm @@ -26,21 +26,21 @@ /obj/structure/rubble/on_update_icon() ..() for(var/i = 1 to 7) - var/image/I = image(icon,"rubble[rand(1,76)]") + var/image/overlay_image = image(icon,"rubble[rand(1,76)]") if(prob(10)) var/atom/A = pick(loot) if(initial(A.icon) && initial(A.icon_state)) - I.icon = initial(A.icon) - I.icon_state = initial(A.icon_state) - I.color = initial(A.color) + overlay_image.icon = initial(A.icon) + overlay_image.icon_state = initial(A.icon_state) + overlay_image.color = initial(A.color) if(!lootleft) - I.color = "#54362e" - I.pixel_x = rand(-16,16) - I.pixel_y = rand(-16,16) + overlay_image.color = "#54362e" + overlay_image.pixel_x = rand(-16,16) + overlay_image.pixel_y = rand(-16,16) var/matrix/M = matrix() M.Turn(rand(0,360)) - I.transform = M - add_overlay(I) + overlay_image.transform = M + add_overlay(overlay_image) if(lootleft) add_overlay("twinkle[rand(1,3)]") @@ -65,8 +65,8 @@ to_chat(user, SPAN_WARNING("Someone is already rummaging here!")) return TRUE -/obj/structure/rubble/attackby(var/obj/item/I, var/mob/user) - if(I.do_tool_interaction(TOOL_PICK, user, I, 3 SECONDS, set_cooldown = TRUE)) +/obj/structure/rubble/attackby(var/obj/item/used_item, var/mob/user) + if(used_item.do_tool_interaction(TOOL_PICK, user, used_item, 3 SECONDS, set_cooldown = TRUE)) if(lootleft && prob(1)) var/obj/item/booty = pickweight(loot) booty = new booty(loc) diff --git a/code/game/objects/structures/safe.dm b/code/game/objects/structures/safe.dm index 5257b0607a9f..bd2bfd5e8d37 100644 --- a/code/game/objects/structures/safe.dm +++ b/code/game/objects/structures/safe.dm @@ -23,12 +23,12 @@ FLOOR SAFES // TODO: make this use a storage datum? /obj/structure/safe/Initialize() - for(var/obj/item/I in loc) + for(var/obj/item/thing in loc) if(space >= maxspace) break - if(I.w_class + space <= maxspace) //todo replace with internal storage or something - space += I.w_class - I.forceMove(src) + if(thing.w_class + space <= maxspace) //todo replace with internal storage or something + space += thing.w_class + thing.forceMove(src) . = ..() tumbler_1_pos = rand(0, 72) tumbler_1_open = rand(0, 72) @@ -134,21 +134,21 @@ FLOOR SAFES return TOPIC_REFRESH -/obj/structure/safe/attackby(obj/item/I, mob/user) +/obj/structure/safe/attackby(obj/item/used_item, mob/user) if(open) - if(I.w_class + space <= maxspace) - if(!user.try_unequip(I, src)) + if(used_item.w_class + space <= maxspace) + if(!user.try_unequip(used_item, src)) return TRUE - space += I.w_class - to_chat(user, "You put [I] in [src].") + space += used_item.w_class + to_chat(user, "You put [used_item] in [src].") updateUsrDialog() return TRUE else - to_chat(user, "[I] won't fit in [src].") + to_chat(user, "[used_item] won't fit in [src].") return TRUE else - if(istype(I, /obj/item/clothing/neck/stethoscope)) - to_chat(user, "Hold [I] in one of your hands while you manipulate the dial.") + if(istype(used_item, /obj/item/clothing/neck/stethoscope)) + to_chat(user, "Hold [used_item] in one of your hands while you manipulate the dial.") return TRUE return FALSE diff --git a/code/game/objects/structures/seaweed.dm b/code/game/objects/structures/seaweed.dm index bfa52f88a189..45762a60d942 100644 --- a/code/game/objects/structures/seaweed.dm +++ b/code/game/objects/structures/seaweed.dm @@ -30,8 +30,8 @@ icon_state = "lichen" icon = 'icons/obj/structures/plants.dmi' -/obj/effect/decal/cleanable/lichen/attackby(obj/item/I, mob/user) - if(I.is_sharp() && I.expend_attack_force(user) > 1) +/obj/effect/decal/cleanable/lichen/attackby(obj/item/used_item, mob/user) + if(used_item.is_sharp() && used_item.expend_attack_force(user) > 1) qdel(src) return TRUE . = ..() \ No newline at end of file diff --git a/code/game/objects/structures/stasis_cage.dm b/code/game/objects/structures/stasis_cage.dm index 2ac55e2afe1d..5474cb223cf5 100644 --- a/code/game/objects/structures/stasis_cage.dm +++ b/code/game/objects/structures/stasis_cage.dm @@ -15,9 +15,9 @@ if(A) contain(A) -/obj/structure/stasis_cage/attackby(obj/item/O, mob/user) - if(contained && istype(O, /obj/item/scanner/xenobio)) - return contained.attackby(O, user) +/obj/structure/stasis_cage/attackby(obj/item/used_item, mob/user) + if(contained && istype(used_item, /obj/item/scanner/xenobio)) + return contained.attackby(used_item, user) . = ..() /obj/structure/stasis_cage/attack_hand(var/mob/user) diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index 9f3fe1060a3c..25154a8f0036 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -78,14 +78,14 @@ popup.open() return TRUE -/obj/structure/tank_rack/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/tank)) +/obj/structure/tank_rack/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/tank)) var/list/adding_to_list - if(istype(I, /obj/item/tank/oxygen) || istype(I, /obj/item/tank/air)) + if(istype(used_item, /obj/item/tank/oxygen) || istype(used_item, /obj/item/tank/air)) LAZYINITLIST(oxygen_tanks) adding_to_list = oxygen_tanks - else if(istype(I, /obj/item/tank/hydrogen)) + else if(istype(used_item, /obj/item/tank/hydrogen)) LAZYINITLIST(hydrogen_tanks) adding_to_list = hydrogen_tanks else @@ -96,11 +96,11 @@ UNSETEMPTY(adding_to_list) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - LAZYADD(adding_to_list, weakref(I)) - to_chat(user, SPAN_NOTICE("You put [I] in [src].")) + LAZYADD(adding_to_list, weakref(used_item)) + to_chat(user, SPAN_NOTICE("You put [used_item] in [src].")) update_icon() attack_hand_with_interaction_checks(user) return TRUE diff --git a/code/game/objects/structures/under_wardrobe.dm b/code/game/objects/structures/under_wardrobe.dm index 815a1405394a..a440ae1b8806 100644 --- a/code/game/objects/structures/under_wardrobe.dm +++ b/code/game/objects/structures/under_wardrobe.dm @@ -8,9 +8,9 @@ density = TRUE var/static/list/amount_of_underwear_by_id_card -/obj/structure/undies_wardrobe/attackby(var/obj/item/item, var/mob/user) - if(istype(item, /obj/item/underwear)) - var/obj/item/underwear/underwear = item +/obj/structure/undies_wardrobe/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/underwear)) + var/obj/item/underwear/underwear = used_item if(!user.try_unequip(underwear)) return TRUE qdel(underwear) diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index 93cf5851a2da..1778979d9b52 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -29,9 +29,9 @@ var/global/list/hygiene_props = list() clogged = 0 tool_interaction_flags = initial(tool_interaction_flags) -/obj/structure/hygiene/attackby(var/obj/item/thing, var/mob/user) - if(clogged > 0 && isplunger(thing)) - user.visible_message(SPAN_NOTICE("\The [user] strives valiantly to unclog \the [src] with \the [thing]!")) +/obj/structure/hygiene/attackby(var/obj/item/used_item, var/mob/user) + if(clogged > 0 && isplunger(used_item)) + user.visible_message(SPAN_NOTICE("\The [user] strives valiantly to unclog \the [src] with \the [used_item]!")) spawn playsound(loc, 'sound/effects/plunger.ogg', 75, 1) sleep(5) @@ -50,9 +50,9 @@ var/global/list/hygiene_props = list() unclog() return TRUE //toilet paper interaction for clogging toilets and other facilities - if (istype(thing, /obj/item/stack/tape_roll/barricade_tape/toilet)) + if (istype(used_item, /obj/item/stack/tape_roll/barricade_tape/toilet)) if (clogged == -1) - to_chat(user, SPAN_WARNING("Try as you might, you can not clog \the [src] with \the [thing].")) + to_chat(user, SPAN_WARNING("Try as you might, you can not clog \the [src] with \the [used_item].")) return TRUE if (clogged) to_chat(user, SPAN_WARNING("\The [src] is already clogged.")) @@ -60,11 +60,11 @@ var/global/list/hygiene_props = list() if (!do_after(user, 3 SECONDS, src)) to_chat(user, SPAN_WARNING("You must stay still to clog \the [src].")) return TRUE - if (clogged || QDELETED(thing) || !user.try_unequip(thing)) + if (clogged || QDELETED(used_item) || !user.try_unequip(used_item)) return TRUE - to_chat(user, SPAN_NOTICE("You unceremoniously jam \the [src] with \the [thing]. What a rebel.")) + to_chat(user, SPAN_NOTICE("You unceremoniously jam \the [src] with \the [used_item]. What a rebel.")) clog(1) - qdel(thing) + qdel(used_item) return TRUE . = ..() @@ -141,17 +141,18 @@ var/global/list/hygiene_props = list() swirlie.take_damage(8) return TRUE + // TODO: storage datum if(cistern && !open) if(!contents.len) to_chat(user, SPAN_NOTICE("The cistern is empty.")) else - var/obj/item/I = pick(contents) + var/obj/item/thing = pick(contents) if(ishuman(user)) - user.put_in_hands(I) + user.put_in_hands(thing) else - I.dropInto(loc) - to_chat(user, SPAN_NOTICE("You find \a [I] in the cistern.")) - w_items -= I.w_class + thing.dropInto(loc) + to_chat(user, SPAN_NOTICE("You find \a [thing] in the cistern.")) + w_items -= thing.w_class return TRUE if(user.check_dexterity(DEXTERITY_SIMPLE_MACHINES, TRUE)) @@ -188,8 +189,8 @@ var/global/list/hygiene_props = list() return TRUE return ..() -/obj/structure/hygiene/toilet/attackby(obj/item/I, var/mob/user) - if(IS_CROWBAR(I)) +/obj/structure/hygiene/toilet/attackby(obj/item/used_item, var/mob/user) + if(IS_CROWBAR(used_item)) to_chat(user, SPAN_NOTICE("You start to [cistern ? "replace the lid on the cistern" : "lift the lid off the cistern"].")) playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1) if(do_after(user, 30, src)) @@ -202,16 +203,16 @@ var/global/list/hygiene_props = list() return TRUE if(cistern && !isrobot(user)) //STOP PUTTING YOUR MODULES IN THE TOILET. - if(I.w_class > ITEM_SIZE_NORMAL) - to_chat(user, SPAN_WARNING("\The [I] does not fit.")) + if(used_item.w_class > ITEM_SIZE_NORMAL) + to_chat(user, SPAN_WARNING("\The [used_item] does not fit.")) return TRUE - if(w_items + I.w_class > ITEM_SIZE_HUGE) + if(w_items + used_item.w_class > ITEM_SIZE_HUGE) to_chat(user, SPAN_WARNING("The cistern is full.")) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - w_items += I.w_class - to_chat(user, SPAN_NOTICE("You carefully place \the [I] into the cistern.")) + w_items += used_item.w_class + to_chat(user, SPAN_NOTICE("You carefully place \the [used_item] into the cistern.")) return TRUE . = ..() @@ -300,21 +301,21 @@ var/global/list/hygiene_props = list() if(. != INITIALIZE_HINT_QDEL) addtimer(CALLBACK(src, TYPE_PROC_REF(/datum, qdel_self)), 25 SECONDS) -/obj/structure/hygiene/shower/attackby(obj/item/I, var/mob/user) - if(istype(I, /obj/item/scanner/gas)) +/obj/structure/hygiene/shower/attackby(obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/scanner/gas)) to_chat(user, SPAN_NOTICE("The water temperature seems to be [watertemp].")) return TRUE - if(IS_WRENCH(I)) + if(IS_WRENCH(used_item)) var/newtemp = input(user, "What setting would you like to set the temperature valve to?", "Water Temperature Valve") in temperature_settings - if(newtemp != watertemp && !QDELETED(I) && !QDELETED(user) && !QDELETED(src) && user.Adjacent(src) && I.loc == src) - to_chat(user, SPAN_NOTICE("You begin to adjust the temperature valve with \the [I].")) + if(newtemp != watertemp && !QDELETED(used_item) && !QDELETED(user) && !QDELETED(src) && user.Adjacent(src) && used_item.loc == src) + to_chat(user, SPAN_NOTICE("You begin to adjust the temperature valve with \the [used_item].")) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) if(do_after(user, (5 SECONDS), src) && newtemp != watertemp) watertemp = newtemp user.visible_message( - SPAN_NOTICE("\The [user] adjusts \the [src] with \the [I]."), - SPAN_NOTICE("You adjust the shower with \the [I].")) + SPAN_NOTICE("\The [user] adjusts \the [src] with \the [used_item]."), + SPAN_NOTICE("You adjust the shower with \the [used_item].")) add_fingerprint(user) return TRUE . = ..() @@ -405,15 +406,15 @@ var/global/list/hygiene_props = list() SPAN_NOTICE("You wash your hands using \the [src].")) return TRUE -/obj/structure/hygiene/sink/attackby(obj/item/hit_with, var/mob/user) - if(isplunger(hit_with) && clogged > 0) +/obj/structure/hygiene/sink/attackby(obj/item/used_item, var/mob/user) + if(isplunger(used_item) && clogged > 0) return ..() if(busy) to_chat(user, SPAN_WARNING("Someone's already washing here.")) return TRUE - var/obj/item/chems/chem_container = hit_with + var/obj/item/chems/chem_container = used_item if (istype(chem_container) && ATOM_IS_OPEN_CONTAINER(chem_container) && chem_container.reagents) user.visible_message( SPAN_NOTICE("\The [user] fills \the [chem_container] using \the [src]."), @@ -422,8 +423,8 @@ var/global/list/hygiene_props = list() chem_container.add_to_reagents(/decl/material/liquid/water, min(REAGENTS_FREE_SPACE(chem_container.reagents), chem_container.amount_per_transfer_from_this)) return TRUE - else if (istype(hit_with, /obj/item/baton)) - var/obj/item/baton/baton = hit_with + else if (istype(used_item, /obj/item/baton)) + var/obj/item/baton/baton = used_item var/obj/item/cell/cell = baton.get_cell() if(cell?.check_charge(0) && baton.status) if(isliving(user)) @@ -434,25 +435,25 @@ var/global/list/hygiene_props = list() // robot users used to be handled separately, but deductcharge handles that for us baton.deductcharge(baton.hitcost) var/decl/pronouns/user_pronouns = user.get_pronouns() - user.visible_message(SPAN_DANGER("\The [user] was stunned by [user_pronouns.his] wet [hit_with]!")) + user.visible_message(SPAN_DANGER("\The [user] was stunned by [user_pronouns.his] wet [used_item]!")) return TRUE - else if(istype(hit_with, /obj/item/mop)) - if(REAGENTS_FREE_SPACE(hit_with.reagents) >= 5) - hit_with.add_to_reagents(/decl/material/liquid/water, 5) - to_chat(user, SPAN_NOTICE("You wet \the [hit_with] in \the [src].")) + else if(istype(used_item, /obj/item/mop)) + if(REAGENTS_FREE_SPACE(used_item.reagents) >= 5) + used_item.add_to_reagents(/decl/material/liquid/water, 5) + to_chat(user, SPAN_NOTICE("You wet \the [used_item] in \the [src].")) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else - to_chat(user, SPAN_WARNING("\The [hit_with] is saturated.")) + to_chat(user, SPAN_WARNING("\The [used_item] is saturated.")) return TRUE var/turf/location = user.loc if(!isturf(location)) return FALSE - if(!istype(hit_with)) + if(!istype(used_item)) return FALSE - to_chat(usr, SPAN_NOTICE("You start washing \the [hit_with].")) + to_chat(usr, SPAN_NOTICE("You start washing \the [used_item].")) playsound(loc, 'sound/effects/sink_long.ogg', 75, 1) busy = TRUE @@ -461,13 +462,13 @@ var/global/list/hygiene_props = list() return TRUE busy = FALSE - if(istype(hit_with, /obj/item/chems/spray/extinguisher)) + if(istype(used_item, /obj/item/chems/spray/extinguisher)) return TRUE // We're washing, not filling. - hit_with.clean() + used_item.clean() user.visible_message( \ - SPAN_NOTICE("\The [user] washes \a [hit_with] using \the [src]."), - SPAN_NOTICE("You wash \a [hit_with] using \the [src].")) + SPAN_NOTICE("\The [user] washes \a [used_item] using \the [src]."), + SPAN_NOTICE("You wash \a [used_item] using \the [src].")) return TRUE @@ -486,10 +487,10 @@ var/global/list/hygiene_props = list() flick("puddle-splash", src) return ..() -/obj/structure/hygiene/sink/puddle/attackby(obj/item/O, var/mob/user) - icon_state = "puddle-splash" +/obj/structure/hygiene/sink/puddle/attackby(obj/item/used_item, var/mob/user) . = ..() - icon_state = "puddle" + if(.) + flick("puddle-splash", src) //////////////////////////////////////////////////// // Toilet Paper Roll diff --git a/code/game/turfs/floors/subtypes/floor_static.dm b/code/game/turfs/floors/subtypes/floor_static.dm index e990493c61a4..0a345025524a 100644 --- a/code/game/turfs/floors/subtypes/floor_static.dm +++ b/code/game/turfs/floors/subtypes/floor_static.dm @@ -9,8 +9,8 @@ footstep_type = /decl/footsteps/plating is_outside = OUTSIDE_AREA -/turf/floor/fixed/attackby(var/obj/item/C, var/mob/user) - if(istype(C, /obj/item/stack) && !IS_COIL(C)) +/turf/floor/fixed/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/stack) && !IS_COIL(used_item)) return TRUE return ..() @@ -29,8 +29,8 @@ icon = 'icons/turf/flooring/alium.dmi' icon_state = "jaggy" -/turf/floor/fixed/alium/attackby(var/obj/item/C, var/mob/user) - if(IS_CROWBAR(C)) +/turf/floor/fixed/alium/attackby(var/obj/item/used_item, var/mob/user) + if(IS_CROWBAR(used_item)) to_chat(user, "There aren't any openings big enough to pry it away...") return TRUE return ..() diff --git a/code/game/turfs/open/_open.dm b/code/game/turfs/open/_open.dm index e763a49a8384..3836af3e8072 100644 --- a/code/game/turfs/open/_open.dm +++ b/code/game/turfs/open/_open.dm @@ -48,35 +48,35 @@ /turf/open/is_open() return TRUE -/turf/open/attackby(obj/item/C, mob/user) +/turf/open/attackby(obj/item/used_item, mob/user) - if(istype(C, /obj/item/stack/material/rods)) + if(istype(used_item, /obj/item/stack/material/rods)) var/ladder = (locate(/obj/structure/ladder) in src) if(ladder) to_chat(user, SPAN_WARNING("\The [ladder] is in the way.")) return TRUE var/obj/structure/lattice/lattice = locate(/obj/structure/lattice, src) if(lattice) - return lattice.attackby(C, user) - var/obj/item/stack/material/rods/rods = C + return lattice.attackby(used_item, user) + var/obj/item/stack/material/rods/rods = used_item if (rods.use(1)) to_chat(user, SPAN_NOTICE("You lay down the support lattice.")) playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) new /obj/structure/lattice(src, rods.material.type) return TRUE - if (istype(C, /obj/item/stack/tile)) - var/obj/item/stack/tile/tile = C + if (istype(used_item, /obj/item/stack/tile)) + var/obj/item/stack/tile/tile = used_item tile.try_build_turf(user, src) return TRUE //To lay cable. - if(IS_COIL(C) && try_build_cable(C, user)) + if(IS_COIL(used_item) && try_build_cable(used_item, user)) return TRUE for(var/atom/movable/M in below) if(M.movable_flags & MOVABLE_FLAG_Z_INTERACT) - return M.attackby(C, user) + return M.attackby(used_item, user) return FALSE diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index a5b145bc5abd..0c4d7107c015 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -92,23 +92,23 @@ return ..() -/turf/space/attackby(obj/item/C, mob/user) +/turf/space/attackby(obj/item/used_item, mob/user) - if (istype(C, /obj/item/stack/material/rods)) + if (istype(used_item, /obj/item/stack/material/rods)) var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) - return L.attackby(C, user) - var/obj/item/stack/material/rods/rods = C + return L.attackby(used_item, user) + var/obj/item/stack/material/rods/rods = used_item if (rods.use(1)) to_chat(user, "Constructing support lattice ...") playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) new /obj/structure/lattice(src, rods.material.type) return TRUE - if (istype(C, /obj/item/stack/tile/floor)) + if (istype(used_item, /obj/item/stack/tile/floor)) var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) if(L) - var/obj/item/stack/tile/floor/S = C + var/obj/item/stack/tile/floor/S = used_item if (!S.use(1)) return TRUE playsound(src, 'sound/weapons/Genhit.ogg', 50, 1) diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 9a6aff50393d..37b63eb82cde 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -2,7 +2,7 @@ var/push_direction // push things that get caught in the transit tile this direction //Overwrite because we dont want people building rods in space. -/turf/space/transit/attackby(obj/O, mob/user) +/turf/space/transit/attackby(obj/item/used_item, mob/user) return TRUE /turf/space/transit/Initialize() diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 785f34bb3799..ad3ddc0fd4df 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -83,15 +83,15 @@ //Not sure what goes here quite yet send signal? return 1 -/obj/item/assembly/attackby(obj/item/component, mob/user) - if(!user_can_attack_with(user) || !component.user_can_attack_with(user)) +/obj/item/assembly/attackby(obj/item/used_item, mob/user) + if(!user_can_attack_with(user) || !used_item.user_can_attack_with(user)) return TRUE - if(isassembly(component)) - var/obj/item/assembly/assembly = component + if(isassembly(used_item)) + var/obj/item/assembly/assembly = used_item if(!assembly.secured && !secured) attach_assembly(assembly, user) return TRUE - if(IS_SCREWDRIVER(component)) + if(IS_SCREWDRIVER(used_item)) if(toggle_secure()) to_chat(user, SPAN_NOTICE("\The [src] is ready!")) else diff --git a/code/modules/atmospherics/components/unary/outlet_injector.dm b/code/modules/atmospherics/components/unary/outlet_injector.dm index 80bd794da66e..20a9ee0a3b24 100644 --- a/code/modules/atmospherics/components/unary/outlet_injector.dm +++ b/code/modules/atmospherics/components/unary/outlet_injector.dm @@ -127,8 +127,8 @@ /obj/machinery/atmospherics/unary/outlet_injector/hide(var/i) update_icon() -/obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/O, var/mob/user) - if(IS_MULTITOOL(O)) +/obj/machinery/atmospherics/unary/outlet_injector/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/browser/written_digital/popup = new (user, "Vent Configuration Utility", "[src] Configuration Panel", 600, 200) popup.set_content(jointext(get_console_data(),"
    ")) popup.open() diff --git a/code/modules/banners/_banner_frame.dm b/code/modules/banners/_banner_frame.dm index 39090a1ada7d..745de870f6ba 100644 --- a/code/modules/banners/_banner_frame.dm +++ b/code/modules/banners/_banner_frame.dm @@ -59,20 +59,20 @@ return TRUE return ..() -/obj/structure/banner_frame/attackby(obj/item/O, mob/user) - if(istype(O, /obj/item/banner)) +/obj/structure/banner_frame/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/banner)) if(banner) to_chat(user, SPAN_WARNING("There is already a banner hung on \the [src].")) return TRUE - var/obj/item/banner/other_banner = O + var/obj/item/banner/other_banner = used_item if(other_banner.banner_type != accepts_banner_type) - to_chat(user, SPAN_WARNING("\The [src] is not suitable for hanging \the [O].")) + to_chat(user, SPAN_WARNING("\The [src] is not suitable for hanging \the [used_item].")) return TRUE - if(user.try_unequip(O, src)) - user.visible_message(SPAN_NOTICE("\The [user] hangs \the [O] from \the [src]."), SPAN_NOTICE("You hang \the [O] from \the [src]."), SPAN_NOTICE("You hear the rustling of fabric.")) - set_banner(O) + if(user.try_unequip(used_item, src)) + user.visible_message(SPAN_NOTICE("\The [user] hangs \the [used_item] from \the [src]."), SPAN_NOTICE("You hang \the [used_item] from \the [src]."), SPAN_NOTICE("You hear the rustling of fabric.")) + set_banner(used_item) return TRUE return ..() diff --git a/code/modules/brain_interface/_brain_interface.dm b/code/modules/brain_interface/_brain_interface.dm index 2bca80610c73..ff8fd7e858ac 100644 --- a/code/modules/brain_interface/_brain_interface.dm +++ b/code/modules/brain_interface/_brain_interface.dm @@ -59,26 +59,26 @@ else . += SPAN_NOTICE("It is undamaged.") -/obj/item/organ/internal/brain_interface/attackby(var/obj/item/O, var/mob/user) +/obj/item/organ/internal/brain_interface/attackby(var/obj/item/used_item, var/mob/user) - if(istype(O, /obj/item/stack/nanopaste)) + if(istype(used_item, /obj/item/stack/nanopaste)) var/mob/living/brain/brainmob = get_brainmob() if(!istype(brainmob) || !brainmob.emp_damage) to_chat(user, SPAN_WARNING("\The [src] has no damage to repair.")) return TRUE - var/obj/item/stack/nanopaste/pasta = O + var/obj/item/stack/nanopaste/pasta = used_item pasta.use(1) to_chat(user, SPAN_NOTICE("You repair some of the damage to \the [src]'s electronics with the nanopaste.")) brainmob.emp_damage = max(brainmob.emp_damage - rand(5,10), 0) return TRUE - if(istype(O, /obj/item/organ/internal/brain)) + if(istype(used_item, /obj/item/organ/internal/brain)) if(holding_brain) to_chat(user, SPAN_WARNING("\The [src] already has a brain in it.")) return TRUE - var/obj/item/organ/internal/brain/inserting_brain = O + var/obj/item/organ/internal/brain/inserting_brain = used_item if(BP_IS_PROSTHETIC(inserting_brain)) to_chat(user, SPAN_WARNING("You don't need to put a robotic brain into an interface.")) return TRUE @@ -91,7 +91,7 @@ to_chat(user, SPAN_WARNING("\The [inserting_brain] is completely useless.")) return TRUE - if(user.try_unequip(O, src)) + if(user.try_unequip(used_item, src)) user.visible_message(SPAN_NOTICE("\The [user] sticks \the [inserting_brain] into \the [src].")) SetName("[initial(name)] (\the [inserting_brain])") holding_brain = inserting_brain @@ -100,7 +100,7 @@ SSstatistics.add_field("cyborg_mmis_filled",1) return TRUE - if(istype(O,/obj/item/card/id) || istype(O,/obj/item/modular_computer)) + if(istype(used_item,/obj/item/card/id) || istype(used_item,/obj/item/modular_computer)) if(allowed(user)) locked = !locked to_chat(user, SPAN_NOTICE("You [locked ? "lock" : "unlock"] \the [src].")) @@ -109,7 +109,7 @@ return TRUE if(holding_brain) - return holding_brain.attackby(O, user) + return holding_brain.attackby(used_item, user) . = ..() diff --git a/code/modules/butchery/butchery_hook.dm b/code/modules/butchery/butchery_hook.dm index 47c7161471dd..c69c4f8ce2cd 100644 --- a/code/modules/butchery/butchery_hook.dm +++ b/code/modules/butchery/butchery_hook.dm @@ -221,9 +221,9 @@ return FALSE -/obj/structure/meat_hook/attackby(var/obj/item/thing, var/mob/user) +/obj/structure/meat_hook/attackby(var/obj/item/used_item, var/mob/user) - if(!IS_KNIFE(thing)) + if(!IS_KNIFE(used_item)) return ..() if(!occupant) @@ -237,22 +237,22 @@ busy = TRUE if(occupant_state == CARCASS_FRESH) if(occupant.currently_has_skin()) - do_butchery_step(user, thing, CARCASS_SKINNED, "skinning") + do_butchery_step(user, used_item, CARCASS_SKINNED, "skinning") else set_carcass_state(CARCASS_SKINNED, apply_damage = FALSE) if(occupant_state == CARCASS_SKINNED) if(occupant.currently_has_innards()) - do_butchery_step(user, thing, CARCASS_GUTTED, "gutting") + do_butchery_step(user, used_item, CARCASS_GUTTED, "gutting") else set_carcass_state(CARCASS_GUTTED, apply_damage = FALSE) if(occupant_state == CARCASS_GUTTED) if(occupant.currently_has_bones()) - do_butchery_step(user, thing, CARCASS_JOINTED, "deboning") + do_butchery_step(user, used_item, CARCASS_JOINTED, "deboning") else set_carcass_state(CARCASS_JOINTED, apply_damage = FALSE) if(occupant_state == CARCASS_JOINTED) if(occupant.currently_has_meat()) - do_butchery_step(user, thing, CARCASS_EMPTY, "butchering") + do_butchery_step(user, used_item, CARCASS_EMPTY, "butchering") else set_carcass_state(CARCASS_EMPTY, apply_damage = FALSE) busy = FALSE diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index 588c193fbd94..ab1d3bca1ff9 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -98,9 +98,9 @@ // Sort of a placeholder for proper tailoring. #define RAG_COUNT(X) ceil((LAZYACCESS(X.matter, /decl/material/solid/organic/cloth) * 0.65) / SHEET_MATERIAL_AMOUNT) -/obj/item/clothing/attackby(obj/item/I, mob/user) +/obj/item/clothing/attackby(obj/item/used_item, mob/user) var/rags = RAG_COUNT(src) - if(istype(material) && material.default_solid_form && rags && (I.is_sharp() || I.has_edge()) && user.check_intent(I_FLAG_HARM)) + if(istype(material) && material.default_solid_form && rags && (used_item.is_sharp() || used_item.has_edge()) && user.check_intent(I_FLAG_HARM)) if(length(accessories)) to_chat(user, SPAN_WARNING("You should remove the accessories attached to \the [src] first.")) return TRUE @@ -109,9 +109,9 @@ to_chat(user, SPAN_WARNING("You must either be holding \the [src], or [it] must be on the ground, before you can shred [it].")) return TRUE playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1) - user.visible_message(SPAN_DANGER("\The [user] begins ripping apart \the [src] with \the [I].")) + user.visible_message(SPAN_DANGER("\The [user] begins ripping apart \the [src] with \the [used_item].")) if(do_after(user, 5 SECONDS, src)) - user.visible_message(SPAN_DANGER("\The [user] tears \the [src] apart with \the [I].")) + user.visible_message(SPAN_DANGER("\The [user] tears \the [src] apart with \the [used_item].")) material.create_object(get_turf(src), rags) if(loc == user) user.drop_from_inventory(src) @@ -219,14 +219,14 @@ // Clothing does not generally align with each other's world icons, so we just use the mob overlay in this case. if(should_use_combined_accessory_appearance()) - var/image/I = get_mob_overlay(ismob(loc) ? loc : null, get_fallback_slot()) - if(I?.icon) // Null or invisible overlay, we don't want to make our clothing invisible just because it has an accessory. - I.plane = plane - I.layer = layer - I.color = color - I.alpha = alpha - I.name = name - appearance = I + var/image/overlay_image = get_mob_overlay(ismob(loc) ? loc : null, get_fallback_slot()) + if(overlay_image?.icon) // Null or invisible overlay, we don't want to make our clothing invisible just because it has an accessory. + overlay_image.plane = plane + overlay_image.layer = layer + overlay_image.color = color + overlay_image.alpha = alpha + overlay_image.name = name + appearance = overlay_image set_dir(SOUTH) update_clothing_icon() return diff --git a/code/modules/clothing/_clothing_accessories.dm b/code/modules/clothing/_clothing_accessories.dm index d958fc571e7a..fcee791c31a7 100644 --- a/code/modules/clothing/_clothing_accessories.dm +++ b/code/modules/clothing/_clothing_accessories.dm @@ -49,22 +49,22 @@ return TRUE return ..() -/obj/item/clothing/attackby(var/obj/item/I, var/mob/user) +/obj/item/clothing/attackby(var/obj/item/used_item, var/mob/user) - if(istype(I, /obj/item/clothing)) + if(istype(used_item, /obj/item/clothing)) - var/obj/item/clothing/accessory = I + var/obj/item/clothing/accessory = used_item if(!isnull(accessory.accessory_slot)) if(can_attach_accessory(accessory, user)) if(user.try_unequip(accessory)) attach_accessory(user, accessory) else - to_chat(user, SPAN_WARNING("You cannot attach \the [I] to \the [src].")) + to_chat(user, SPAN_WARNING("You cannot attach \the [used_item] to \the [src].")) return TRUE if(length(accessories)) for(var/obj/item/clothing/accessory in accessories) - accessory.attackby(I, user) + accessory.attackby(used_item, user) return TRUE . = ..() diff --git a/code/modules/clothing/badges/holobadge.dm b/code/modules/clothing/badges/holobadge.dm index 90a5cd0e0411..b4f8888574fe 100644 --- a/code/modules/clothing/badges/holobadge.dm +++ b/code/modules/clothing/badges/holobadge.dm @@ -40,10 +40,10 @@ to_chat(user, "You crack the holobadge security checks.") return 1 -/obj/item/clothing/badge/holo/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/card/id) || istype(O, /obj/item/modular_computer)) +/obj/item/clothing/badge/holo/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/card/id) || istype(used_item, /obj/item/modular_computer)) - var/obj/item/card/id/id_card = O.GetIdCard() + var/obj/item/card/id/id_card = used_item.GetIdCard() if(!id_card) return TRUE diff --git a/code/modules/clothing/gloves/jewelry/rings/_ring.dm b/code/modules/clothing/gloves/jewelry/rings/_ring.dm index ea58b6662b83..27fdb3cc815a 100644 --- a/code/modules/clothing/gloves/jewelry/rings/_ring.dm +++ b/code/modules/clothing/gloves/jewelry/rings/_ring.dm @@ -53,10 +53,10 @@ if(base_desc) desc = "[base_desc] [desc]" -/obj/item/clothing/gloves/ring/attackby(var/obj/item/tool, var/mob/user) - if(can_inscribe && tool.is_sharp() && user.check_intent(I_FLAG_HELP)) +/obj/item/clothing/gloves/ring/attackby(var/obj/item/used_item, var/mob/user) + if(can_inscribe && used_item.is_sharp() && user.check_intent(I_FLAG_HELP)) var/new_inscription = sanitize(input("Enter an inscription to engrave.", "Inscription") as null|text) - if(user.stat || !user.incapacitated() || !user.Adjacent(src) || tool.loc != user) + if(user.stat || !user.incapacitated() || !user.Adjacent(src) || used_item.loc != user) return TRUE if(!new_inscription) return TRUE diff --git a/code/modules/clothing/masks/cig_crafting.dm b/code/modules/clothing/masks/cig_crafting.dm index 1fbe74668f2b..4ffe22101d57 100644 --- a/code/modules/clothing/masks/cig_crafting.dm +++ b/code/modules/clothing/masks/cig_crafting.dm @@ -57,8 +57,8 @@ /obj/item/food/grown/dried_tobacco/fine seed = "finetobacco" -/obj/item/clothing/mask/smokable/cigarette/rolled/attackby(obj/item/I, mob/user) - if(!istype(I, /obj/item/cigarette_filter)) +/obj/item/clothing/mask/smokable/cigarette/rolled/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/cigarette_filter)) return ..() if(filter) to_chat(user, "[src] already has a filter!") @@ -66,12 +66,12 @@ if(lit) to_chat(user, "[src] is lit already!") return TRUE - if(!user.try_unequip(I)) + if(!user.try_unequip(used_item)) return TRUE - to_chat(user, "You stick [I] into \the [src]") + to_chat(user, "You stick [used_item] into \the [src]") filter = 1 SetName("filtered [name]") brand = "[brand] with a filter" update_icon() - qdel(I) + qdel(used_item) return TRUE diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm index ee2399b9cd40..589a7f0d79e1 100644 --- a/code/modules/clothing/shoes/_shoes.dm +++ b/code/modules/clothing/shoes/_shoes.dm @@ -58,11 +58,11 @@ try_remove_cuffs(user) ..() -/obj/item/clothing/shoes/attackby(var/obj/item/I, var/mob/user) - if (istype(I, /obj/item/handcuffs)) - add_cuffs(I, user) +/obj/item/clothing/shoes/attackby(var/obj/item/used_item, var/mob/user) + if (istype(used_item, /obj/item/handcuffs)) + add_cuffs(used_item, user) return TRUE - . = add_hidden(I, user) + . = add_hidden(used_item, user) if(!.) . = ..() @@ -109,8 +109,8 @@ verbs -= /obj/item/clothing/shoes/proc/try_remove_cuffs attached_cuffs = null -/obj/item/clothing/shoes/proc/add_hidden(var/obj/item/I, var/mob/user) - if (!(I.item_flags & ITEM_FLAG_CAN_HIDE_IN_SHOES)) // fail silently +/obj/item/clothing/shoes/proc/add_hidden(var/obj/item/used_item, var/mob/user) + if (!(used_item.item_flags & ITEM_FLAG_CAN_HIDE_IN_SHOES)) // fail silently return FALSE if (!can_add_hidden_item) to_chat(user, SPAN_WARNING("\The [src] can't hold anything.")) @@ -118,15 +118,15 @@ if (hidden_item) to_chat(user, SPAN_WARNING("\The [src] already holds \an [hidden_item].")) return TRUE - if (I.w_class > hidden_item_max_w_class) - to_chat(user, SPAN_WARNING("\The [I] is too large to fit in \the [src].")) + if (used_item.w_class > hidden_item_max_w_class) + to_chat(user, SPAN_WARNING("\The [used_item] is too large to fit in \the [src].")) return TRUE if (do_after(user, 1 SECONDS)) - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - user.visible_message(SPAN_ITALIC("\The [user] shoves \the [I] into \the [src]."), range = 1) + user.visible_message(SPAN_ITALIC("\The [user] shoves \the [used_item] into \the [src]."), range = 1) verbs |= /obj/item/clothing/shoes/proc/remove_hidden - hidden_item = I + hidden_item = used_item return TRUE /obj/item/clothing/shoes/proc/remove_hidden(var/mob/user) diff --git a/code/modules/detectivework/tools/sample_kits/_sample.dm b/code/modules/detectivework/tools/sample_kits/_sample.dm index d56d685faaa9..657e77ecb843 100644 --- a/code/modules/detectivework/tools/sample_kits/_sample.dm +++ b/code/modules/detectivework/tools/sample_kits/_sample.dm @@ -49,9 +49,9 @@ /obj/item/forensics/sample/proc/merge_evidence_list(var/list/new_evidence) LAZYDISTINCTADD(evidence, new_evidence) -/obj/item/forensics/sample/attackby(var/obj/O, var/mob/user) - if(O.type == src.type) - if(user.try_unequip(O) && merge_evidence(O, user)) - qdel(O) +/obj/item/forensics/sample/attackby(var/obj/used_item, var/mob/user) + if(used_item.type == src.type) + if(user.try_unequip(used_item) && merge_evidence(used_item, user)) + qdel(used_item) return 1 return ..() \ No newline at end of file diff --git a/code/modules/economy/cael/ATM.dm b/code/modules/economy/cael/ATM.dm index c2e50a639305..dd440576bc61 100644 --- a/code/modules/economy/cael/ATM.dm +++ b/code/modules/economy/cael/ATM.dm @@ -75,8 +75,8 @@ to_chat(user, "[html_icon(src)] [src] beeps: \"[response]\"") return 1 -/obj/machinery/atm/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/card/id)) +/obj/machinery/atm/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/card/id)) if(emagged > 0) //prevent inserting id into an emagged ATM to_chat(user, "[html_icon(src)] CARD READER ERROR. This system has been compromised!") @@ -85,7 +85,7 @@ to_chat(user, "You try to insert your card into [src], but nothing happens.") return TRUE - var/obj/item/card/id/idcard = I + var/obj/item/card/id/idcard = used_item if(!held_card) if(!user.try_unequip(idcard, src)) return TRUE @@ -96,30 +96,30 @@ return TRUE else if(authenticated_account) - if(istype(I,/obj/item/cash)) - var/obj/item/cash/dolla = I + if(istype(used_item,/obj/item/cash)) + var/obj/item/cash/dolla = used_item //deposit the cash if(authenticated_account.deposit(dolla.absolute_worth, "Credit deposit", machine_id)) playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, 1) - to_chat(user, "You insert [I] into [src].") + to_chat(user, "You insert [used_item] into [src].") attack_hand_with_interaction_checks(user) - qdel(I) + qdel(used_item) return TRUE - if(istype(I,/obj/item/charge_stick)) - var/obj/item/charge_stick/stick = I - var/datum/extension/lockable/lock = get_extension(I, /datum/extension/lockable) + if(istype(used_item,/obj/item/charge_stick)) + var/obj/item/charge_stick/stick = used_item + var/datum/extension/lockable/lock = get_extension(used_item, /datum/extension/lockable) if(lock.locked) to_chat(user, SPAN_WARNING("Cannot transfer funds from a locked [stick.name].")) else if(authenticated_account.deposit(stick.loaded_worth, "Credit deposit", machine_id)) playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 50, 1) - to_chat(user, "You insert [I] into [src].") + to_chat(user, "You insert [used_item] into [src].") attack_hand_with_interaction_checks(user) - qdel(I) + qdel(used_item) return TRUE return ..() @@ -430,11 +430,11 @@ if(emagged > 0) to_chat(user, "[html_icon(src)] The ATM card reader rejected your ID because this machine has been sabotaged!") else - var/obj/item/I = user.get_active_held_item() - if (istype(I, /obj/item/card/id)) - if(!user.try_unequip(I, src)) + var/obj/item/thing = user.get_active_held_item() + if (istype(thing, /obj/item/card/id)) + if(!user.try_unequip(thing, src)) return - held_card = I + held_card = thing else release_held_id(user) if("logout") @@ -445,9 +445,9 @@ /obj/machinery/atm/proc/scan_user(mob/living/human/human_user) if(!authenticated_account) - var/obj/item/card/id/I = human_user.GetIdCard() - if(istype(I)) - return I + var/obj/item/card/id/thing = human_user.GetIdCard() + if(istype(thing)) + return thing // put the currently held id on the ground or in the hand of the user /obj/machinery/atm/proc/release_held_id(mob/living/human/human_user) diff --git a/code/modules/economy/cael/Accounts_DB.dm b/code/modules/economy/cael/Accounts_DB.dm index 8d8b7f4c8a5b..64cea625b356 100644 --- a/code/modules/economy/cael/Accounts_DB.dm +++ b/code/modules/economy/cael/Accounts_DB.dm @@ -21,10 +21,10 @@ . = ..() machine_id = "[station_name()] Acc. DB #[num_financial_terminals++]" -/obj/machinery/computer/account_database/attackby(obj/O, mob/user) - if(istype(O, /obj/item/card/id) && !held_card) - if(user.try_unequip(O, src)) - held_card = O +/obj/machinery/computer/account_database/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/card/id) && !held_card) + if(user.try_unequip(used_item, src)) + held_card = used_item SSnano.update_uis(src) return TRUE return ..() diff --git a/code/modules/economy/cael/EFTPOS.dm b/code/modules/economy/cael/EFTPOS.dm index 551e88a70c01..519938245c6d 100644 --- a/code/modules/economy/cael/EFTPOS.dm +++ b/code/modules/economy/cael/EFTPOS.dm @@ -79,18 +79,18 @@ else close_browser(user, "window=eftpos") -/obj/item/eftpos/attackby(obj/item/O, user) +/obj/item/eftpos/attackby(obj/item/used_item, user) - var/obj/item/card/id/I = O.GetIdCard() + var/obj/item/card/id/I = used_item.GetIdCard() if(I) if(linked_account) - scan_card(I, O) + scan_card(I, used_item) else to_chat(user, "[html_icon(src)]Unable to connect to linked account.") return TRUE - else if (istype(O, /obj/item/charge_stick)) - var/obj/item/charge_stick/E = O + else if (istype(used_item, /obj/item/charge_stick)) + var/obj/item/charge_stick/E = used_item if (linked_account) if(transaction_locked && !transaction_paid) if(!E.is_locked() && transaction_amount <= E.loaded_worth) @@ -105,7 +105,7 @@ else to_chat(user, "[html_icon(src)]Transaction failed! Please try again.") else - to_chat(user, "[html_icon(src)]\The [O] doesn't have that much money!") + to_chat(user, "[html_icon(src)]\The [used_item] doesn't have that much money!") else to_chat(user, "[html_icon(src)]EFTPOS is not connected to an account.") return TRUE diff --git a/code/modules/fabrication/fabricator_intake.dm b/code/modules/fabrication/fabricator_intake.dm index 433bd25913ba..ddd0afb010a0 100644 --- a/code/modules/fabrication/fabricator_intake.dm +++ b/code/modules/fabrication/fabricator_intake.dm @@ -91,13 +91,13 @@ else to_chat(user, SPAN_WARNING("\The [src] cannot process \the [thing].")) -/obj/machinery/fabricator/attackby(var/obj/item/O, var/mob/user) - if((. = component_attackby(O, user))) +/obj/machinery/fabricator/attackby(var/obj/item/used_item, var/mob/user) + if((. = component_attackby(used_item, user))) return - if(panel_open && (IS_MULTITOOL(O) || IS_WIRECUTTER(O))) + if(panel_open && (IS_MULTITOOL(used_item) || IS_WIRECUTTER(used_item))) attack_hand_with_interaction_checks(user) return TRUE - if((obj_flags & OBJ_FLAG_ANCHORABLE) && (IS_WRENCH(O) || IS_HAMMER(O))) + if((obj_flags & OBJ_FLAG_ANCHORABLE) && (IS_WRENCH(used_item) || IS_HAMMER(used_item))) return ..() if(stat & (NOPOWER | BROKEN)) return TRUE @@ -106,57 +106,57 @@ if(!user.check_intent(I_FLAG_HARM)) // Set or update our local network. - if(IS_MULTITOOL(O)) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/fabnet = get_extension(src, /datum/extension/local_network_member) fabnet.get_new_tag(user) return TRUE // Install new designs. - if(istype(O, /obj/item/disk/design_disk)) - var/obj/item/disk/design_disk/disk = O + if(istype(used_item, /obj/item/disk/design_disk)) + var/obj/item/disk/design_disk/disk = used_item if(!disk.blueprint) - to_chat(user, SPAN_WARNING("\The [O] is blank.")) + to_chat(user, SPAN_WARNING("\The [used_item] is blank.")) return TRUE if(disk.blueprint in installed_designs) - to_chat(user, SPAN_WARNING("\The [src] is already loaded with the blueprint stored on \the [O].")) + to_chat(user, SPAN_WARNING("\The [src] is already loaded with the blueprint stored on \the [used_item].")) return TRUE installed_designs += disk.blueprint design_cache |= disk.blueprint - visible_message(SPAN_NOTICE("\The [user] inserts \the [O] into \the [src], and after a second or so of loud clicking, the fabricator beeps and spits it out again.")) + visible_message(SPAN_NOTICE("\The [user] inserts \the [used_item] into \the [src], and after a second or so of loud clicking, the fabricator beeps and spits it out again.")) return TRUE // TEMP HACK FIX: // Autolathes currently do not process atom contents. As a workaround, refuse all atoms with contents. - if(length(O.contents) && !ignore_input_contents_length) + if(length(used_item.contents) && !ignore_input_contents_length) to_chat(user, SPAN_WARNING("\The [src] cannot process an object containing other objects. Empty it out first.")) return TRUE // REMOVE FIX WHEN LATHES TAKE CONTENTS PLS. // Take reagents, if any are applicable. - var/atom_name = O.name - var/reagents_taken = take_reagents(O, user) + var/atom_name = used_item.name + var/reagents_taken = take_reagents(used_item, user) if(reagents_taken != SUBSTANCE_TAKEN_NONE) show_intake_message(user, reagents_taken, atom_name, took_reagents = TRUE) updateUsrDialog() return TRUE - if(!can_ingest(O)) - to_chat(user, SPAN_WARNING("\The [src] cannot process \the [O].")) + if(!can_ingest(used_item)) + to_chat(user, SPAN_WARNING("\The [src] cannot process \the [used_item].")) return TRUE // Take everything if we have a recycler. - if(!is_robot_module(O) && user.try_unequip(O)) - var/result = max(take_materials(O, user), max(reagents_taken, take_reagents(O, user, TRUE))) + if(!is_robot_module(used_item) && user.try_unequip(used_item)) + var/result = max(take_materials(used_item, user), max(reagents_taken, take_reagents(used_item, user, TRUE))) show_intake_message(user, result, atom_name) if(result == SUBSTANCE_TAKEN_NONE) - user.put_in_active_hand(O) + user.put_in_active_hand(used_item) return TRUE - if(istype(O, /obj/item/stack)) - var/obj/item/stack/stack = O + if(istype(used_item, /obj/item/stack)) + var/obj/item/stack/stack = used_item if(!QDELETED(stack) && stack.amount > 0) user.put_in_active_hand(stack) else - qdel(O) + qdel(used_item) updateUsrDialog() return TRUE . = ..() diff --git a/code/modules/games/boardgame.dm b/code/modules/games/boardgame.dm index 263020f25f41..266a7030ea99 100644 --- a/code/modules/games/boardgame.dm +++ b/code/modules/games/boardgame.dm @@ -23,14 +23,14 @@ M.examine_verb(src) return TRUE -/obj/item/board/attackby(obj/item/I, mob/user) - if(addPiece(I,user)) +/obj/item/board/attackby(obj/item/used_item, mob/user) + if(addPiece(used_item,user)) return TRUE return ..() -/obj/item/board/proc/addPiece(obj/item/I, mob/user, var/tile = 0) - if(I.w_class != ITEM_SIZE_TINY) //only small stuff - user.show_message("\The [I] is too big to be used as a board piece.") +/obj/item/board/proc/addPiece(obj/item/used_item, mob/user, var/tile = 0) + if(used_item.w_class != ITEM_SIZE_TINY) //only small stuff + user.show_message("\The [used_item] is too big to be used as a board piece.") return 0 if(num == 64) user.show_message("\The [src] is already full!") @@ -40,22 +40,22 @@ return 0 if(!user.Adjacent(src)) return 0 - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return 0 num++ - if(!board_icons["[I.icon] [I.icon_state]"]) - board_icons["[I.icon] [I.icon_state]"] = new /icon(I.icon,I.icon_state) + if(!board_icons["[used_item.icon] [used_item.icon_state]"]) + board_icons["[used_item.icon] [used_item.icon_state]"] = new /icon(used_item.icon,used_item.icon_state) if(tile == 0) var i; for(i=0;i<64;i++) if(!board["[i]"]) - board["[i]"] = I + board["[i]"] = used_item break else - board["[tile]"] = I + board["[tile]"] = used_item src.updateDialog() @@ -87,9 +87,9 @@ dat += "
    = 0) //check to see if clicked on tile is currently selected one if(text2num(s) == selected) selected = -1 //deselect it else - if(I) //cant put items on other items. + if(thing) //cant put items on other items. return //put item in new spot. - I = board["[selected]"] + thing = board["[selected]"] board["[selected]"] = null board -= "[selected]" board -= null - board["[s]"] = I + board["[s]"] = thing selected = -1 else - if(I) + if(thing) selected = text2num(s) else var/mob/living/human/H = locate(href_list["person"]) @@ -141,25 +141,25 @@ return addPiece(O,H,text2num(s)) if(href_list["remove"]) - var/obj/item/I = board["[selected]"] - if(!I) + var/obj/item/thing = board["[selected]"] + if(!thing) return board["[selected]"] = null board -= "[selected]" board -= null - I.forceMove(src.loc) + thing.forceMove(src.loc) num-- selected = -1 var j for(j=0;j<64;j++) if(board["[j]"]) var/obj/item/K = board["[j]"] - if(K.icon == I.icon && cmptext(K.icon_state,I.icon_state)) + if(K.icon == thing.icon && cmptext(K.icon_state,thing.icon_state)) src.updateDialog() return //Didn't find it in use, remove it and allow GC to delete it. - board_icons["[I.icon] [I.icon_state]"] = null - board_icons -= "[I.icon] [I.icon_state]" + board_icons["[thing.icon] [thing.icon_state]"] = null + board_icons -= "[thing.icon] [thing.icon_state]" board_icons -= null src.updateDialog() diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 069c27f6b493..8d55baee65a0 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -145,13 +145,13 @@ var/global/list/card_decks = list() . += "
    There [cards.len == 1 ? "is" : "are"] still [cards.len] card\s." . += SPAN_NOTICE("You can deal cards at a table by clicking on it with grab intent.") -/obj/item/deck/attackby(obj/O, mob/user) - if(istype(O,/obj/item/hand)) - var/obj/item/hand/H = O +/obj/item/deck/attackby(obj/item/used_item, mob/user) + if(istype(used_item,/obj/item/hand)) + var/obj/item/hand/H = used_item for(var/datum/playingcard/P in H.cards) cards += P - qdel(O) + qdel(used_item) to_chat(user, "You place your cards on the bottom of \the [src].") return TRUE return ..() @@ -227,10 +227,10 @@ var/global/list/card_decks = list() H.throw_at(get_step(target, ismob(target) ? target.dir : target), 10, 1,user) -/obj/item/hand/attackby(obj/item/O, mob/user) +/obj/item/hand/attackby(obj/item/used_item, mob/user) - if(istype(O,/obj/item/hand)) - var/obj/item/hand/H = O + if(istype(used_item,/obj/item/hand)) + var/obj/item/hand/H = used_item for(var/datum/playingcard/P in cards) H.cards += P H.concealed = src.concealed @@ -239,7 +239,7 @@ var/global/list/card_decks = list() H.name = "hand of [(H.cards.len)] card\s" return TRUE - if(length(cards) == 1 && IS_PEN(O)) + if(length(cards) == 1 && IS_PEN(used_item)) var/datum/playingcard/P = cards[1] if(lowertext(P.name) != "blank card") to_chat(user, SPAN_WARNING("You cannot write on that card.")) diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 254a5efd3ffc..407b1b196dad 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -132,11 +132,11 @@ dir = NORTHEAST icon_state = "rwindow_full" -/obj/structure/window/reinforced/holowindow/attackby(obj/item/weapon, mob/user) - if(IS_SCREWDRIVER(weapon) || IS_CROWBAR(weapon) || IS_WRENCH(weapon)) +/obj/structure/window/reinforced/holowindow/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item) || IS_CROWBAR(used_item) || IS_WRENCH(used_item)) to_chat(user, SPAN_NOTICE("It's a holowindow, you can't dismantle it!")) return TRUE - return bash(weapon, user) + return bash(used_item, user) /obj/structure/window/reinforced/holowindow/shatter(var/display_message = 1) playsound(src, "shatter", 70, 1) @@ -148,16 +148,16 @@ // This subtype is deleted when a ready button in the same area is pressed. /obj/structure/window/reinforced/holowindow/disappearing -/obj/machinery/door/window/holowindoor/attackby(obj/item/I, mob/user) +/obj/machinery/door/window/holowindoor/attackby(obj/item/used_item, mob/user) if (src.operating == 1) return TRUE - if(src.density && istype(I, /obj/item) && !istype(I, /obj/item/card)) + if(src.density && istype(used_item, /obj/item) && !istype(used_item, /obj/item/card)) playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) - visible_message("\The [src] was hit by \the [I].") - if(I.atom_damage_type == BRUTE || I.atom_damage_type == BURN) - take_damage(I.expend_attack_force(user)) + visible_message("\The [src] was hit by \the [used_item].") + if(used_item.atom_damage_type == BRUTE || used_item.atom_damage_type == BURN) + take_damage(used_item.expend_attack_force(user)) return TRUE src.add_fingerprint(user) @@ -261,14 +261,14 @@ /obj/structure/holohoop/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if (istype(mover,/obj/item) && mover.throwing) - var/obj/item/I = mover - if(istype(I, /obj/item/projectile)) + var/obj/item/thing = mover + if(istype(thing, /obj/item/projectile)) return if(prob(50)) - I.dropInto(loc) - visible_message("Swish! \the [I] lands in \the [src].", range = 3) + thing.dropInto(loc) + visible_message("Swish! \the [thing] lands in \the [src].", range = 3) else - visible_message("\The [I] bounces off of \the [src]'s rim!", range = 3) + visible_message("\The [thing] bounces off of \the [src]'s rim!", range = 3) return 0 else return ..(mover, target, height, air_group) @@ -290,12 +290,12 @@ /obj/structure/holonet/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if (istype(mover,/obj/item) && mover.throwing) - var/obj/item/I = mover - if(istype(I, /obj/item/projectile)) + var/obj/item/thing = mover + if(istype(thing, /obj/item/projectile)) return if(prob(10)) - I.dropInto(loc) - visible_message("Swish! \the [I] gets caught in \the [src].", range = 3) + thing.dropInto(loc) + visible_message("Swish! \the [thing] gets caught in \the [src].", range = 3) return 0 else return 1 diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm index 6aa7d2372d15..98efab116283 100644 --- a/code/modules/hydroponics/seed_storage.dm +++ b/code/modules/hydroponics/seed_storage.dm @@ -4,14 +4,14 @@ var/datum/seed/seed_type // Keeps track of what our seed is var/list/obj/item/seeds/seeds = list() // Tracks actual objects contained in the pile -/datum/seed_pile/New(var/obj/item/seeds/O) - name = O.name +/datum/seed_pile/New(var/obj/item/seeds/seeds) + name = seeds.name amount = 1 - seed_type = O.seed - seeds += O + seed_type = seeds.seed + seeds += seeds -/datum/seed_pile/proc/matches(var/obj/item/seeds/O) - if (O.seed == seed_type) +/datum/seed_pile/proc/matches(var/obj/item/seeds/seeds) + if (seeds.seed == seed_type) return 1 return 0 @@ -45,8 +45,7 @@ if(isnull(amount)) amount = 1 for (var/i = 1 to amount) - var/O = new typepath - add(O) + add(new typepath) /obj/machinery/seed_storage/Destroy() QDEL_NULL_LIST(piles) @@ -295,15 +294,15 @@ switch(task) if ("vend") - var/obj/O = pick(our_pile.seeds) - if (O) + var/obj/seeds = pick(our_pile.seeds) + if (seeds) --our_pile.amount - our_pile.seeds -= O + our_pile.seeds -= seeds if (our_pile.amount <= 0 || our_pile.seeds.len <= 0) piles -= our_pile qdel(our_pile) flick("[initial(icon_state)]-vend", src) - O.dropInto(loc) + seeds.dropInto(loc) . = TOPIC_REFRESH if ("purge") QDEL_LIST(our_pile.seeds) @@ -313,45 +312,45 @@ piles -= our_pile QDEL_NULL(our_pile) -/obj/machinery/seed_storage/attackby(var/obj/item/O, var/mob/user) +/obj/machinery/seed_storage/attackby(var/obj/item/used_item, var/mob/user) - if(istype(O, /obj/item/seeds)) - add(O) - user.visible_message(SPAN_NOTICE("\The [user] puts \the [O] into \the [src].")) + if(istype(used_item, /obj/item/seeds)) + add(used_item) + user.visible_message(SPAN_NOTICE("\The [user] puts \the [used_item] into \the [src].")) return TRUE - if(istype(O, /obj/item/plants) && O.storage) + if(istype(used_item, /obj/item/plants) && used_item.storage) var/loaded = 0 for(var/obj/item/seeds/G in storage.get_contents()) ++loaded - O.storage.remove_from_storage(user, G, src, TRUE) + used_item.storage.remove_from_storage(user, G, src, TRUE) add(G, 1) - O.storage.finish_bulk_removal() + used_item.storage.finish_bulk_removal() if (loaded) - user.visible_message(SPAN_NOTICE("\The [user] puts the seeds from \the [O] into \the [src].")) + user.visible_message(SPAN_NOTICE("\The [user] puts the seeds from \the [used_item] into \the [src].")) else - to_chat(user, SPAN_WARNING("There are no seeds in \the [O].")) + to_chat(user, SPAN_WARNING("There are no seeds in \the [used_item].")) return TRUE return ..() -/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/O, bypass_removal = 0) +/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/seeds, bypass_removal = 0) if(!bypass_removal) - if (ismob(O.loc)) - var/mob/user = O.loc - if(!user.try_unequip(O, src)) + if (ismob(seeds.loc)) + var/mob/user = seeds.loc + if(!user.try_unequip(seeds, src)) return - else if(isobj(O.loc)) - O.loc?.storage?.remove_from_storage(null, O, src) + else if(isobj(seeds.loc)) + seeds.loc?.storage?.remove_from_storage(null, seeds, src) - O.forceMove(src) + seeds.forceMove(src) for (var/datum/seed_pile/N in piles) - if (N.matches(O)) + if (N.matches(seeds)) ++N.amount - N.seeds += (O) + N.seeds += (seeds) return - piles += new /datum/seed_pile(O) + piles += new /datum/seed_pile(seeds) flick("[initial(icon_state)]-vend", src) return diff --git a/code/modules/hydroponics/trays/tray_soil.dm b/code/modules/hydroponics/trays/tray_soil.dm index 279cc704d58d..e0c42fa58163 100644 --- a/code/modules/hydroponics/trays/tray_soil.dm +++ b/code/modules/hydroponics/trays/tray_soil.dm @@ -91,13 +91,13 @@ break return ..() -/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/O, var/mob/user) +/obj/machinery/portable_atmospherics/hydroponics/soil/attackby(var/obj/item/used_item, var/mob/user) - if(istype(O, /obj/item/stack/material/brick)) + if(istype(used_item, /obj/item/stack/material/brick)) if(reinforced_with) to_chat(user, SPAN_WARNING("\The [src] has already been fenced with bricks.")) return TRUE - var/obj/item/stack/material/brick/bricks = O + var/obj/item/stack/material/brick/bricks = used_item if(bricks.get_amount() < 4) to_chat(user, SPAN_WARNING("You need at least four bricks to fence off \the [src].")) return TRUE @@ -111,13 +111,13 @@ neighbor.update_icon() return TRUE - if(!seed && user.check_intent(I_FLAG_HARM) && (IS_SHOVEL(O) || IS_HOE(O))) - var/use_tool = O.get_tool_quality(TOOL_SHOVEL) > O.get_tool_quality(TOOL_HOE) ? TOOL_SHOVEL : TOOL_HOE + if(!seed && user.check_intent(I_FLAG_HARM) && (IS_SHOVEL(used_item) || IS_HOE(used_item))) + var/use_tool = used_item.get_tool_quality(TOOL_SHOVEL) > used_item.get_tool_quality(TOOL_HOE) ? TOOL_SHOVEL : TOOL_HOE if(use_tool) - if(O.do_tool_interaction(use_tool, user, src, 3 SECONDS, "filling in", "filling in", check_skill = SKILL_BOTANY)) + if(used_item.do_tool_interaction(use_tool, user, src, 3 SECONDS, "filling in", "filling in", check_skill = SKILL_BOTANY)) qdel(src) return TRUE - if(istype(O, /obj/item/tank)) + if(istype(used_item, /obj/item/tank)) return TRUE return ..() diff --git a/code/modules/implants/implant_types/chem.dm b/code/modules/implants/implant_types/chem.dm index ccb8f8467b1f..a98016b2d583 100644 --- a/code/modules/implants/implant_types/chem.dm +++ b/code/modules/implants/implant_types/chem.dm @@ -40,14 +40,14 @@ var/global/list/chem_implants = list() reagents.trans_to_mob(R, amount, CHEM_INJECT) to_chat(R, "You hear a faint *beep*.") -/obj/item/implant/chem/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/chems/syringe)) +/obj/item/implant/chem/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/chems/syringe)) if(reagents.total_volume >= reagents.maximum_volume) to_chat(user, "\The [src] is full.") else if(do_after(user,5,src)) - I.reagents.trans_to_obj(src, 5) - to_chat(user, "You inject 5 units of the solution. The syringe now contains [I.reagents.total_volume] units.") + used_item.reagents.trans_to_obj(src, 5) + to_chat(user, "You inject 5 units of the solution. The syringe now contains [used_item.reagents.total_volume] units.") return TRUE else return ..() diff --git a/code/modules/implants/implantcase.dm b/code/modules/implants/implantcase.dm index 36bb284a2c51..9f754b9c8685 100644 --- a/code/modules/implants/implantcase.dm +++ b/code/modules/implants/implantcase.dm @@ -40,10 +40,10 @@ icon_state = "implantcase-0" // TODO: the name stuff here probably doesn't work, this needs an update_name override -/obj/item/implantcase/attackby(obj/item/I, mob/user) - if (IS_PEN(I)) +/obj/item/implantcase/attackby(obj/item/used_item, mob/user) + if (IS_PEN(used_item)) var/t = input(user, "What would you like the label to be?", src.name, null) - if (user.get_active_held_item() != I) + if (user.get_active_held_item() != used_item) return TRUE if((!in_range(src, usr) && loc != user)) return TRUE @@ -55,10 +55,10 @@ SetName(initial(name)) desc = "A case containing an implant." return TRUE - else if(istype(I, /obj/item/chems/syringe) && istype(imp,/obj/item/implant/chem)) - return imp.attackby(I,user) - else if (istype(I, /obj/item/implanter)) - var/obj/item/implanter/M = I + else if(istype(used_item, /obj/item/chems/syringe) && istype(imp,/obj/item/implant/chem)) + return imp.attackby(used_item,user) + else if (istype(used_item, /obj/item/implanter)) + var/obj/item/implanter/M = used_item if (M.imp && !imp && !M.imp.implanted) M.imp.forceMove(src) imp = M.imp @@ -71,9 +71,9 @@ update_icon() M.update_icon() return TRUE - else if (istype(I, /obj/item/implant) && user.try_unequip(I, src)) - to_chat(usr, "You slide \the [I] into \the [src].") - imp = I + else if (istype(used_item, /obj/item/implant) && user.try_unequip(used_item, src)) + to_chat(usr, "You slide \the [used_item] into \the [src].") + imp = used_item update_description() update_icon() return TRUE diff --git a/code/modules/implants/implanter.dm b/code/modules/implants/implanter.dm index ccc430483419..409c2cb362a3 100644 --- a/code/modules/implants/implanter.dm +++ b/code/modules/implants/implanter.dm @@ -59,10 +59,10 @@ return 1 return 0 -/obj/item/implanter/attackby(obj/item/I, mob/user) - if(!imp && istype(I, /obj/item/implant) && user.try_unequip(I,src)) - to_chat(usr, SPAN_NOTICE("You slide \the [I] into \the [src].")) - imp = I +/obj/item/implanter/attackby(obj/item/used_item, mob/user) + if(!imp && istype(used_item, /obj/item/implant) && user.try_unequip(used_item,src)) + to_chat(usr, SPAN_NOTICE("You slide \the [used_item] into \the [src].")) + imp = used_item update_icon() return TRUE return ..() diff --git a/code/modules/implants/implantpad.dm b/code/modules/implants/implantpad.dm index a2b1afb11fb4..4e6f78b10013 100644 --- a/code/modules/implants/implantpad.dm +++ b/code/modules/implants/implantpad.dm @@ -22,9 +22,9 @@ update_icon() return TRUE -/obj/item/implantpad/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/implantcase)) - var/obj/item/implantcase/C = I +/obj/item/implantpad/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/implantcase)) + var/obj/item/implantcase/C = used_item if(!imp && C.imp) C.imp.forceMove(src) imp = C.imp @@ -35,8 +35,8 @@ imp = null C.update_icon() . = TRUE - else if(istype(I, /obj/item/implanter)) - var/obj/item/implanter/C = I + else if(istype(used_item, /obj/item/implanter)) + var/obj/item/implanter/C = used_item if(!imp && C.imp) C.imp.forceMove(src) imp = C.imp @@ -47,8 +47,8 @@ imp = null C.update_icon() . = TRUE - else if(istype(I, /obj/item/implant) && user.try_unequip(I, src)) - imp = I + else if(istype(used_item, /obj/item/implant) && user.try_unequip(used_item, src)) + imp = used_item . = TRUE if(.) update_icon() diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index e8637643e086..e317edea3f55 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -64,11 +64,10 @@ /obj/item/electronic_assembly/examined_by(mob/user, distance, infix, suffix) . = ..() - for(var/I in assembly_components) - var/obj/item/integrated_circuit/IC = I - IC.external_examine(user) + for(var/obj/item/integrated_circuit/component as anything in assembly_components) + component.external_examine(user) if(opened) - IC.internal_examine(user) + component.internal_examine(user) if(opened) interact(user) @@ -123,11 +122,10 @@ visible_message(SPAN_WARNING("\The [src] shudders and sparks.")) power_failure = TRUE // Now spend it. - for(var/I in assembly_components) - var/obj/item/integrated_circuit/IC = I - if(IC.power_draw_idle) - if(power_failure || !draw_power(IC.power_draw_idle)) - IC.power_fail() + for(var/obj/item/integrated_circuit/component as anything in assembly_components) + if(component.power_draw_idle) + if(power_failure || !draw_power(component.power_draw_idle)) + component.power_fail() /obj/item/electronic_assembly/receive_mouse_drop(atom/dropping, mob/user, params) . = ..() @@ -306,9 +304,8 @@ //This only happens when this EA is loaded via the printer /obj/item/electronic_assembly/proc/post_load() - for(var/I in assembly_components) - var/obj/item/integrated_circuit/IC = I - IC.on_data_written() + for(var/obj/item/integrated_circuit/component as anything in assembly_components) + component.on_data_written() /obj/item/electronic_assembly/proc/return_total_complexity() . = 0 @@ -325,36 +322,36 @@ . += part.size // Returns true if the circuit made it inside. -/obj/item/electronic_assembly/proc/try_add_component(obj/item/integrated_circuit/IC, mob/user) +/obj/item/electronic_assembly/proc/try_add_component(obj/item/integrated_circuit/component, mob/user) if(!opened) to_chat(user, "\The [src]'s hatch is closed, you can't put anything inside.") return FALSE - if(IC.w_class > w_class) - to_chat(user, "\The [IC] is way too big to fit into \the [src].") + if(component.w_class > w_class) + to_chat(user, "\The [component] is way too big to fit into \the [src].") return FALSE var/total_part_size = return_total_size() var/total_complexity = return_total_complexity() - if((total_part_size + IC.size) > max_components) - to_chat(user, "You can't seem to add the '[IC]', as there's insufficient space.") + if((total_part_size + component.size) > max_components) + to_chat(user, "You can't seem to add the '[component]', as there's insufficient space.") return FALSE - if((total_complexity + IC.complexity) > max_complexity) - to_chat(user, "You can't seem to add the '[IC]', since this setup's too complicated for the case.") + if((total_complexity + component.complexity) > max_complexity) + to_chat(user, "You can't seem to add the '[component]', since this setup's too complicated for the case.") return FALSE - if((allowed_circuit_action_flags & IC.action_flags) != IC.action_flags) - to_chat(user, "You can't seem to add the '[IC]', since the case doesn't support the circuit type.") + if((allowed_circuit_action_flags & component.action_flags) != component.action_flags) + to_chat(user, "You can't seem to add the '[component]', since the case doesn't support the circuit type.") return FALSE - if(!user.try_unequip(IC,src)) + if(!user.try_unequip(component,src)) return FALSE - to_chat(user, "You slide [IC] inside [src].") + to_chat(user, "You slide [component] inside [src].") playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) add_allowed_scanner(user.ckey) - add_component(IC) + add_component(component) return TRUE @@ -365,22 +362,22 @@ assembly_components |= component -/obj/item/electronic_assembly/proc/try_remove_component(obj/item/integrated_circuit/IC, mob/user, silent) +/obj/item/electronic_assembly/proc/try_remove_component(obj/item/integrated_circuit/component, mob/user, silent) if(!opened) if(!silent) to_chat(user, "[src]'s hatch is closed, so you can't fiddle with the internal components.") return FALSE - if(!IC.removable) + if(!component.removable) if(!silent) to_chat(user, "[src] is permanently attached to the case.") return FALSE - remove_component(IC) + remove_component(component) if(!silent) - to_chat(user, "You pop \the [IC] out of the case, and slide it out.") + to_chat(user, "You pop \the [component] out of the case, and slide it out.") playsound(src, 'sound/items/crowbar.ogg', 50, 1) - user.put_in_hands(IC) + user.put_in_hands(component) add_allowed_scanner(user.ckey) // Make sure we're not on an invalid page @@ -406,50 +403,50 @@ visible_message("\The [user] points \the [src] towards \the [target].") -/obj/item/electronic_assembly/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/integrated_circuit)) - if(!user.canUnEquip(I)) +/obj/item/electronic_assembly/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/integrated_circuit)) + if(!user.canUnEquip(used_item)) return FALSE - if(try_add_component(I, user)) + if(try_add_component(used_item, user)) return TRUE else for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I, user, user.get_intent()) + S.attackby_react(used_item, user, user.get_intent()) return ..() - else if(IS_MULTITOOL(I) || istype(I, /obj/item/integrated_electronics/wirer) || istype(I, /obj/item/integrated_electronics/debugger)) + else if(IS_MULTITOOL(used_item) || istype(used_item, /obj/item/integrated_electronics/wirer) || istype(used_item, /obj/item/integrated_electronics/debugger)) if(opened) interact(user) return TRUE else to_chat(user, "[src]'s hatch is closed, so you can't fiddle with the internal components.") for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I, user, user.get_intent()) + S.attackby_react(used_item, user, user.get_intent()) return ..() - else if(istype(I, /obj/item/cell)) + else if(istype(used_item, /obj/item/cell)) if(!opened) to_chat(user, "[src]'s hatch is closed, so you can't access \the [src]'s power supplier.") for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I, user, user.get_intent()) + S.attackby_react(used_item, user, user.get_intent()) return ..() if(battery) to_chat(user, "[src] already has \a [battery] installed. Remove it first if you want to replace it.") for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I, user, user.get_intent()) + S.attackby_react(used_item, user, user.get_intent()) return ..() - var/obj/item/cell/cell = I - if(user.try_unequip(I,loc)) - user.drop_from_inventory(I, loc) + var/obj/item/cell/cell = used_item + if(user.try_unequip(used_item,loc)) + user.drop_from_inventory(used_item, loc) cell.forceMove(src) battery = cell playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) to_chat(user, "You slot \the [cell] inside \the [src]'s power supplier.") return TRUE return FALSE - else if(istype(I, /obj/item/integrated_electronics/detailer)) - var/obj/item/integrated_electronics/detailer/D = I + else if(istype(used_item, /obj/item/integrated_electronics/detailer)) + var/obj/item/integrated_electronics/detailer/D = used_item detail_color = D.detail_color update_icon() - else if(IS_SCREWDRIVER(I)) + else if(IS_SCREWDRIVER(used_item)) var/hatch_locked = FALSE for(var/obj/item/integrated_circuit/manipulation/hatchlock/H in assembly_components) // If there's more than one hatch lock, only one needs to be enabled for the assembly to be locked @@ -467,8 +464,8 @@ update_icon() return TRUE - else if(IS_COIL(I)) - var/obj/item/stack/cable_coil/C = I + else if(IS_COIL(used_item)) + var/obj/item/stack/cable_coil/C = used_item if(is_damaged() && do_after(user, 10, src) && C.use(1)) user.visible_message("\The [user] patches up \the [src].") current_health = min(get_max_health(), current_health + 5) @@ -476,7 +473,7 @@ else if(!user.check_intent(I_FLAG_HARM)) for(var/obj/item/integrated_circuit/input/S in assembly_components) - S.attackby_react(I, user, user.get_intent()) + S.attackby_react(used_item, user, user.get_intent()) return TRUE return ..() //Handle weapon attacks and etc @@ -489,9 +486,8 @@ /obj/item/electronic_assembly/emp_act(severity) . = ..() - for(var/I in src) - var/atom/movable/AM = I - AM.emp_act(severity) + for(var/atom/movable/thing as anything in get_contained_external_atoms()) + thing.emp_act(severity) // Returns true if power was successfully drawn. /obj/item/electronic_assembly/proc/draw_power(amount) diff --git a/code/modules/integrated_electronics/core/printer.dm b/code/modules/integrated_electronics/core/printer.dm index 52bd8428adde..a27fd59fe930 100644 --- a/code/modules/integrated_electronics/core/printer.dm +++ b/code/modules/integrated_electronics/core/printer.dm @@ -46,59 +46,59 @@ assembly.creator = key_name(user) cloning = FALSE -/obj/item/integrated_circuit_printer/proc/recycle(obj/item/O, mob/user, obj/item/electronic_assembly/assembly) - if(!O.canremove) //in case we have an augment circuit +/obj/item/integrated_circuit_printer/proc/recycle(obj/item/used_item, mob/user, obj/item/electronic_assembly/assembly) + if(!used_item.canremove) //in case we have an augment circuit return - for(var/material in O.matter) - if(materials[material] + O.matter[material] > metal_max) + for(var/material in used_item.matter) + if(materials[material] + used_item.matter[material] > metal_max) var/decl/material/material_datum = GET_DECL(material) if(material_datum) to_chat(user, "[src] can't hold any more [material_datum.name]!") return - for(var/material in O.matter) - materials[material] += O.matter[material] + for(var/material in used_item.matter) + materials[material] += used_item.matter[material] if(assembly) - assembly.remove_component(O) + assembly.remove_component(used_item) if(user) - to_chat(user, "You recycle [O]!") - qdel(O) + to_chat(user, "You recycle [used_item]!") + qdel(used_item) return TRUE -/obj/item/integrated_circuit_printer/attackby(obj/item/O, mob/user) - if(istype(O, /obj/item/stack/material)) - var/obj/item/stack/material/M = O - var/amt = M.amount - if(amt * SHEET_MATERIAL_AMOUNT + materials[M.material.type] > metal_max) - amt = ceil((metal_max - materials[M.material.type]) / SHEET_MATERIAL_AMOUNT) - if(!M.use(amt)) +/obj/item/integrated_circuit_printer/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/stack/material)) + var/obj/item/stack/material/stack = used_item + var/amt = stack.amount + if(amt * SHEET_MATERIAL_AMOUNT + materials[stack.material.type] > metal_max) + amt = ceil((metal_max - materials[stack.material.type]) / SHEET_MATERIAL_AMOUNT) + if(!stack.use(amt)) return FALSE - materials[M.material.type] = min(metal_max, materials[M.material.type] + amt * SHEET_MATERIAL_AMOUNT) - to_chat(user, "You insert [M.material.solid_name] into \the [src].") + materials[stack.material.type] = min(metal_max, materials[stack.material.type] + amt * SHEET_MATERIAL_AMOUNT) + to_chat(user, "You insert [stack.material.solid_name] into \the [src].") if(user) attack_self(user) // We're really bad at refreshing the UI, so this is the best we've got. return TRUE - if(istype(O, /obj/item/disk/integrated_circuit/upgrade/advanced)) + if(istype(used_item, /obj/item/disk/integrated_circuit/upgrade/advanced)) if(upgraded) to_chat(user, "[src] already has this upgrade. ") return TRUE - to_chat(user, "You install [O] into [src]. ") + to_chat(user, "You install [used_item] into [src]. ") upgraded = TRUE if(user) attack_self(user) return TRUE - if(istype(O, /obj/item/disk/integrated_circuit/upgrade/clone)) + if(istype(used_item, /obj/item/disk/integrated_circuit/upgrade/clone)) if(fast_clone) to_chat(user, "[src] already has this upgrade. ") return TRUE - to_chat(user, "You install [O] into [src]. Circuit cloning will now be instant. ") + to_chat(user, "You install [used_item] into [src]. Circuit cloning will now be instant. ") fast_clone = TRUE if(user) attack_self(user) return TRUE - if(istype(O, /obj/item/electronic_assembly)) - var/obj/item/electronic_assembly/EA = O //microtransactions not included + if(istype(used_item, /obj/item/electronic_assembly)) + var/obj/item/electronic_assembly/EA = used_item //microtransactions not included if(EA.battery) to_chat(user, "Remove [EA]'s power cell first!") return TRUE @@ -127,8 +127,8 @@ else return recycle(EA, user) - if(istype(O, /obj/item/integrated_circuit)) - return recycle(O, user) + if(istype(used_item, /obj/item/integrated_circuit)) + return recycle(used_item, user) return ..() @@ -191,16 +191,16 @@ var/list/current_list = SScircuit.circuit_fabricator_recipe_list[current_category] for(var/path in current_list) - var/obj/O = path + var/obj/building = path var/can_build = TRUE if(ispath(path, /obj/item/integrated_circuit)) var/obj/item/integrated_circuit/IC = path if((initial(IC.spawn_flags) & IC_SPAWN_RESEARCH) && (!(initial(IC.spawn_flags) & IC_SPAWN_DEFAULT)) && !upgraded) can_build = FALSE if(can_build) - HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
    " + HTML += "\[[initial(building.name)]\]: [initial(building.desc)]
    " else - HTML += "\[[initial(O.name)]\]: [initial(O.desc)]
    " + HTML += "\[[initial(building.name)]\]: [initial(building.desc)]
    " popup.set_content(JOINTEXT(HTML)) popup.open() diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 82449cc6ab6f..4148ac842ee5 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -34,9 +34,9 @@ QDEL_NULL(installed_gun) return ..() -/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/O, var/mob/user) - if(istype(O, /obj/item/gun/energy)) - var/obj/item/gun/energy/gun = O +/obj/item/integrated_circuit/manipulation/weapon_firing/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/gun/energy)) + var/obj/item/gun/energy/gun = used_item if(installed_gun) to_chat(user, "There's already a weapon installed.") return TRUE @@ -181,15 +181,18 @@ detach_grenade() return ..() -/obj/item/integrated_circuit/manipulation/grenade/attackby(var/obj/item/grenade/G, var/mob/user) - if(istype(G)) +/obj/item/integrated_circuit/manipulation/grenade/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/grenade)) if(attached_grenade) to_chat(user, "There is already a grenade attached!") return TRUE - if(user.try_unequip(G,src)) - user.visible_message("\The [user] attaches \a [G] to \the [src]!", "You attach \the [G] to \the [src].") - attach_grenade(G) - G.forceMove(src) + if(user.try_unequip(used_item,src)) + user.visible_message( + SPAN_WARNING("\The [user] attaches \a [used_item] to \the [src]!"), + SPAN_NOTICE("You attach \the [used_item] to \the [src].") + ) + attach_grenade(used_item) + used_item.forceMove(src) return TRUE else return ..() @@ -215,9 +218,9 @@ log_and_message_admins("activated a grenade assembly. Last touches: Assembly: [holder.fingerprintslast] Circuit: [fingerprintslast] Grenade: [attached_grenade.fingerprintslast]") // These procs do not relocate the grenade, that's the callers responsibility -/obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/grenade/G) - attached_grenade = G - G.forceMove(src) +/obj/item/integrated_circuit/manipulation/grenade/proc/attach_grenade(var/obj/item/grenade/grenade) + attached_grenade = grenade + grenade.forceMove(src) desc += " \An [attached_grenade] is attached to it!" /obj/item/integrated_circuit/manipulation/grenade/proc/detach_grenade() @@ -245,25 +248,25 @@ /obj/item/integrated_circuit/manipulation/plant_module/do_work() ..() var/obj/acting_object = get_object() - var/obj/OM = get_pin_data_as_type(IC_INPUT, 1, /obj) - var/obj/O = get_pin_data_as_type(IC_INPUT, 3, /obj/item) + var/obj/input_obj = get_pin_data_as_type(IC_INPUT, 1, /obj) + var/obj/input_item = get_pin_data_as_type(IC_INPUT, 3, /obj/item) - if(!check_target(OM)) + if(!check_target(input_obj)) push_data() activate_pin(2) return - if(istype(OM,/obj/effect/vine) && check_target(OM) && get_pin_data(IC_INPUT, 2) == 2) - qdel(OM) + if(istype(input_obj,/obj/effect/vine) && check_target(input_obj) && get_pin_data(IC_INPUT, 2) == 2) + qdel(input_obj) push_data() activate_pin(2) return - var/obj/machinery/portable_atmospherics/hydroponics/TR = OM - if(istype(TR)) + var/obj/machinery/portable_atmospherics/hydroponics/hydrotray = input_obj + if(istype(hydrotray)) switch(get_pin_data(IC_INPUT, 2)) if(0) - var/list/harvest_output = TR.harvest() + var/list/harvest_output = hydrotray.harvest() if(harvest_output && !islist(harvest_output)) harvest_output = list(harvest_output) for(var/i in 1 to length(harvest_output)) @@ -273,30 +276,30 @@ set_pin_data(IC_OUTPUT, 1, harvest_output) push_data() if(1) - TR.weedlevel = 0 - TR.update_icon() + hydrotray.weedlevel = 0 + hydrotray.update_icon() if(2) - if(TR.seed) //Could be that they're just using it as a de-weeder - TR.age = 0 - TR.plant_health = 0 - if(TR.harvest) - TR.harvest = FALSE //To make sure they can't just put in another seed and insta-harvest it - qdel(TR.seed) - TR.seed = null - TR.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds - TR.dead = 0 - TR.update_icon() + if(hydrotray.seed) //Could be that they're just using it as a de-weeder + hydrotray.age = 0 + hydrotray.plant_health = 0 + if(hydrotray.harvest) + hydrotray.harvest = FALSE //To make sure they can't just put in another seed and insta-harvest it + qdel(hydrotray.seed) + hydrotray.seed = null + hydrotray.weedlevel = 0 //Has a side effect of cleaning up those nasty weeds + hydrotray.dead = 0 + hydrotray.update_icon() if(3) - if(!check_target(O)) + if(!check_target(input_item)) activate_pin(2) return FALSE - else if(istype(O, /obj/item/seeds) && !istype(O, /obj/item/seeds/extracted/cutting)) - if(!TR.seed) - var/obj/item/seeds/seed = O - acting_object.visible_message("[acting_object] plants [O].") - TR.set_seed(seed.seed) - QDEL_NULL(O) + else if(istype(input_item, /obj/item/seeds) && !istype(input_item, /obj/item/seeds/extracted/cutting)) + if(!hydrotray.seed) + var/obj/item/seeds/seed = input_item + acting_object.visible_message("[acting_object] plants [input_item].") + hydrotray.set_seed(seed.seed) + QDEL_NULL(input_item) activate_pin(2) /obj/item/integrated_circuit/manipulation/seed_extractor @@ -313,15 +316,15 @@ /obj/item/integrated_circuit/manipulation/seed_extractor/do_work() ..() - var/obj/item/food/grown/O = get_pin_data_as_type(IC_INPUT, 1, /obj/item/food/grown) - if(!check_target(O)) + var/obj/item/food/grown/grown = get_pin_data_as_type(IC_INPUT, 1, /obj/item/food/grown) + if(!check_target(grown)) push_data() activate_pin(2) return var/list/seed_output = list() for(var/i in 1 to rand(1,4)) - seed_output += weakref(new /obj/item/seeds(get_turf(O), null, O.seed)) - qdel(O) + seed_output += weakref(new /obj/item/seeds(get_turf(grown), null, grown.seed)) + qdel(grown) if(seed_output.len) set_pin_data(IC_OUTPUT, 1, seed_output) @@ -437,8 +440,8 @@ step_towards(pulling, F) activate_pin(2) -/obj/item/integrated_circuit/manipulation/claw/proc/can_pull(var/obj/item/I) - return assembly && I && I.w_class <= assembly.w_class && !I.anchored +/obj/item/integrated_circuit/manipulation/claw/proc/can_pull(var/obj/item/used_item) + return assembly && used_item && used_item.w_class <= assembly.w_class && !used_item.anchored /obj/item/integrated_circuit/manipulation/claw/proc/pull() var/obj/acting_object = get_object() @@ -519,7 +522,7 @@ return // If the item is in a grabber circuit we'll update the grabber's outputs after we've thrown it. - var/obj/item/integrated_circuit/manipulation/grabber/G = A.loc + var/obj/item/integrated_circuit/manipulation/grabber/grabber = A.loc var/x_abs = clamp(T.x + target_x_rel, 0, world.maxx) var/y_abs = clamp(T.y + target_y_rel, 0, world.maxy) @@ -531,8 +534,8 @@ A.throw_at(locate(x_abs, y_abs, T.z), range, 3) // If the item came from a grabber now we can update the outputs since we've thrown it. - if(istype(G)) - G.update_outputs() + if(istype(grabber)) + grabber.update_outputs() /obj/item/integrated_circuit/manipulation/wormhole name = "wormhole generator" @@ -650,9 +653,9 @@ controlling = null -/obj/item/integrated_circuit/manipulation/ai/attackby(var/obj/item/I, var/mob/user) - if(is_type_in_list(I, list(/obj/item/aicard, /obj/item/paicard, /obj/item/organ/internal/brain_interface))) - load_ai(user, I) +/obj/item/integrated_circuit/manipulation/ai/attackby(var/obj/item/used_item, var/mob/user) + if(is_type_in_list(used_item, list(/obj/item/aicard, /obj/item/paicard, /obj/item/organ/internal/brain_interface))) + load_ai(user, used_item) return TRUE else return ..() diff --git a/code/modules/locks/lock_construct.dm b/code/modules/locks/lock_construct.dm index e36d93797a60..e8561f9b5b69 100644 --- a/code/modules/locks/lock_construct.dm +++ b/code/modules/locks/lock_construct.dm @@ -19,17 +19,17 @@ else . += SPAN_NOTICE("\The [src] is blank. Use a key on the lock to pair the two items.") -/obj/item/lock_construct/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/key)) - var/obj/item/key/K = I +/obj/item/lock_construct/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/key)) + var/obj/item/key/K = used_item if(!K.key_data) - to_chat(user, SPAN_NOTICE("You fashion \the [I] to unlock \the [src].")) + to_chat(user, SPAN_NOTICE("You fashion \the [used_item] to unlock \the [src].")) K.key_data = lock_data else - to_chat(user, SPAN_WARNING("\The [I] already unlocks something...")) + to_chat(user, SPAN_WARNING("\The [used_item] already unlocks something...")) return TRUE - if(istype(I,/obj/item/lock_construct)) - var/obj/item/lock_construct/L = I + if(istype(used_item,/obj/item/lock_construct)) + var/obj/item/lock_construct/L = used_item src.lock_data = L.lock_data to_chat(user, SPAN_NOTICE("You copy the lock from \the [L] to \the [src], making them identical.")) return TRUE diff --git a/code/modules/mechs/components/_components.dm b/code/modules/mechs/components/_components.dm index 281d3c4ade7b..7d516d493146 100644 --- a/code/modules/mechs/components/_components.dm +++ b/code/modules/mechs/components/_components.dm @@ -96,9 +96,9 @@ qdel(RC) update_components() -/obj/item/mech_component/attackby(var/obj/item/thing, var/mob/user) +/obj/item/mech_component/attackby(var/obj/item/used_item, var/mob/user) - if(IS_SCREWDRIVER(thing)) + if(IS_SCREWDRIVER(used_item)) if(contents.len) //Filter non movables var/list/valid_contents = list() @@ -118,15 +118,15 @@ to_chat(user, SPAN_WARNING("There is nothing to remove.")) return TRUE - if(IS_WELDER(thing)) - repair_brute_generic(thing, user) + if(IS_WELDER(used_item)) + repair_brute_generic(used_item, user) return TRUE - if(IS_COIL(thing)) - repair_burn_generic(thing, user) + if(IS_COIL(used_item)) + repair_burn_generic(used_item, user) return TRUE - if(istype(thing, /obj/item/robotanalyzer)) + if(istype(used_item, /obj/item/robotanalyzer)) to_chat(user, SPAN_NOTICE("Diagnostic Report for \the [src]:")) return_diagnostics(user) return TRUE diff --git a/code/modules/mechs/components/arms.dm b/code/modules/mechs/components/arms.dm index 9d5fe7a3a7d5..f420a8b3d853 100644 --- a/code/modules/mechs/components/arms.dm +++ b/code/modules/mechs/components/arms.dm @@ -24,13 +24,13 @@ /obj/item/mech_component/manipulators/prebuild() motivator = new(src) -/obj/item/mech_component/manipulators/attackby(var/obj/item/thing, var/mob/user) - if(istype(thing,/obj/item/robot_parts/robot_component/actuator)) +/obj/item/mech_component/manipulators/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item,/obj/item/robot_parts/robot_component/actuator)) if(motivator) to_chat(user, SPAN_WARNING("\The [src] already has an actuator installed.")) return TRUE - if(install_component(thing, user)) - motivator = thing + if(install_component(used_item, user)) + motivator = used_item return TRUE return FALSE else diff --git a/code/modules/mechs/components/body.dm b/code/modules/mechs/components/body.dm index ca4a65fadc05..16fe9e6f62f0 100644 --- a/code/modules/mechs/components/body.dm +++ b/code/modules/mechs/components/body.dm @@ -138,29 +138,29 @@ cell = new /obj/item/cell/exosuit(src) cell.charge = cell.maxcharge -/obj/item/mech_component/chassis/attackby(var/obj/item/thing, var/mob/user) - if(istype(thing,/obj/item/robot_parts/robot_component/diagnosis_unit)) +/obj/item/mech_component/chassis/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item,/obj/item/robot_parts/robot_component/diagnosis_unit)) if(diagnostics) to_chat(user, SPAN_WARNING("\The [src] already has a diagnostic system installed.")) return TRUE - if(install_component(thing, user)) - diagnostics = thing + if(install_component(used_item, user)) + diagnostics = used_item return TRUE return FALSE - else if(istype(thing, /obj/item/cell)) + else if(istype(used_item, /obj/item/cell)) if(cell) to_chat(user, SPAN_WARNING("\The [src] already has a cell installed.")) return TRUE - if(install_component(thing,user)) - cell = thing + if(install_component(used_item,user)) + cell = used_item return TRUE return FALSE - else if(istype(thing, /obj/item/robot_parts/robot_component/armour/exosuit)) + else if(istype(used_item, /obj/item/robot_parts/robot_component/armour/exosuit)) if(m_armour) to_chat(user, SPAN_WARNING("\The [src] already has armour installed.")) return TRUE - if(install_component(thing, user)) - m_armour = thing + if(install_component(used_item, user)) + m_armour = used_item return TRUE return FALSE else diff --git a/code/modules/mechs/components/frame.dm b/code/modules/mechs/components/frame.dm index e92325c92105..9cf6393faaf2 100644 --- a/code/modules/mechs/components/frame.dm +++ b/code/modules/mechs/components/frame.dm @@ -71,9 +71,9 @@ /obj/structure/heavy_vehicle_frame/set_dir() return ..(SOUTH) -/obj/structure/heavy_vehicle_frame/attackby(var/obj/item/thing, var/mob/user) +/obj/structure/heavy_vehicle_frame/attackby(var/obj/item/used_item, var/mob/user) // Removing components. - if(IS_CROWBAR(thing)) + if(IS_CROWBAR(used_item)) if(is_reinforced == FRAME_REINFORCED) if(!user.do_skilled(0.5 SECONDS, SKILL_DEVICES, src) || !material) return TRUE @@ -103,7 +103,7 @@ return TRUE // Final construction step. - else if(IS_SCREWDRIVER(thing)) + else if(IS_SCREWDRIVER(used_item)) // Check for basic components. if(!(arms && legs && head && body)) @@ -149,13 +149,13 @@ return TRUE // Installing wiring. - else if(IS_COIL(thing)) + else if(IS_COIL(used_item)) if(is_wired) to_chat(user, SPAN_WARNING("\The [src] has already been wired.")) return TRUE - var/obj/item/stack/cable_coil/CC = thing + var/obj/item/stack/cable_coil/CC = used_item if(CC.get_amount() < 10) to_chat(user, SPAN_WARNING("You need at least ten units of cable to complete the exosuit.")) return TRUE @@ -173,7 +173,7 @@ playsound(user.loc, 'sound/items/Deconstruct.ogg', 50, 1) is_wired = FRAME_WIRED // Securing wiring. - else if(IS_WIRECUTTER(thing)) + else if(IS_WIRECUTTER(used_item)) if(!is_wired) to_chat(user, "There is no wiring in \the [src] to neaten.") return TRUE @@ -187,8 +187,8 @@ playsound(user.loc, 'sound/items/Wirecutter.ogg', 100, 1) is_wired = (is_wired == FRAME_WIRED_ADJUSTED) ? FRAME_WIRED : FRAME_WIRED_ADJUSTED // Installing metal. - else if(istype(thing, /obj/item/stack/material)) - var/obj/item/stack/material/M = thing + else if(istype(used_item, /obj/item/stack/material)) + var/obj/item/stack/material/M = used_item if(M.material) if(is_reinforced) to_chat(user, SPAN_WARNING("There is already a material reinforcement installed in \the [src].")) @@ -210,7 +210,7 @@ else return ..() // Securing metal. - else if(IS_WRENCH(thing)) + else if(IS_WRENCH(used_item)) if(!is_reinforced) to_chat(user, SPAN_WARNING("There is no metal to secure inside \the [src].")) return TRUE @@ -228,8 +228,8 @@ playsound(user.loc, 'sound/items/Ratchet.ogg', 100, 1) is_reinforced = (is_reinforced == FRAME_REINFORCED_SECURE) ? FRAME_REINFORCED : FRAME_REINFORCED_SECURE // Welding metal. - else if(IS_WELDER(thing)) - var/obj/item/weldingtool/welder = thing + else if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(!is_reinforced) to_chat(user, SPAN_WARNING("There is no metal to secure inside \the [src].")) return TRUE @@ -253,42 +253,42 @@ to_chat(user, SPAN_WARNING("Not enough fuel!")) return TRUE // Installing basic components. - else if(istype(thing,/obj/item/mech_component/manipulators)) + else if(istype(used_item,/obj/item/mech_component/manipulators)) if(arms) to_chat(user, SPAN_WARNING("\The [src] already has manipulators installed.")) return TRUE - if(install_component(thing, user)) + if(install_component(used_item, user)) if(arms) - thing.dropInto(loc) + used_item.dropInto(loc) return TRUE - arms = thing - else if(istype(thing,/obj/item/mech_component/propulsion)) + arms = used_item + else if(istype(used_item,/obj/item/mech_component/propulsion)) if(legs) to_chat(user, SPAN_WARNING("\The [src] already has a propulsion system installed.")) return TRUE - if(install_component(thing, user)) + if(install_component(used_item, user)) if(legs) - thing.dropInto(loc) + used_item.dropInto(loc) return TRUE - legs = thing - else if(istype(thing,/obj/item/mech_component/sensors)) + legs = used_item + else if(istype(used_item,/obj/item/mech_component/sensors)) if(head) to_chat(user, SPAN_WARNING("\The [src] already has a sensor array installed.")) return TRUE - if(install_component(thing, user)) + if(install_component(used_item, user)) if(head) - thing.dropInto(loc) + used_item.dropInto(loc) return TRUE - head = thing - else if(istype(thing,/obj/item/mech_component/chassis)) + head = used_item + else if(istype(used_item,/obj/item/mech_component/chassis)) if(body) to_chat(user, SPAN_WARNING("\The [src] already has an outer chassis installed.")) return TRUE - if(install_component(thing, user)) + if(install_component(used_item, user)) if(body) - thing.dropInto(loc) + used_item.dropInto(loc) return TRUE - body = thing + body = used_item else return ..() update_icon() diff --git a/code/modules/mechs/components/head.dm b/code/modules/mechs/components/head.dm index 84791a488886..8c4869494e1d 100644 --- a/code/modules/mechs/components/head.dm +++ b/code/modules/mechs/components/head.dm @@ -56,29 +56,29 @@ /obj/item/mech_component/sensors/ready_to_install() return (radio && camera) -/obj/item/mech_component/sensors/attackby(var/obj/item/thing, var/mob/user) - if(istype(thing, /obj/item/mech_component/control_module)) +/obj/item/mech_component/sensors/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/mech_component/control_module)) if(software) to_chat(user, SPAN_WARNING("\The [src] already has a control modules installed.")) return TRUE - if(install_component(thing, user)) - software = thing + if(install_component(used_item, user)) + software = used_item return TRUE return FALSE - else if(istype(thing,/obj/item/robot_parts/robot_component/radio)) + else if(istype(used_item,/obj/item/robot_parts/robot_component/radio)) if(radio) to_chat(user, SPAN_WARNING("\The [src] already has a radio installed.")) return TRUE - if(install_component(thing, user)) - radio = thing + if(install_component(used_item, user)) + radio = used_item return TRUE return FALSE - else if(istype(thing,/obj/item/robot_parts/robot_component/camera)) + else if(istype(used_item,/obj/item/robot_parts/robot_component/camera)) if(camera) to_chat(user, SPAN_WARNING("\The [src] already has a camera installed.")) return TRUE - if(install_component(thing, user)) - camera = thing + if(install_component(used_item, user)) + camera = used_item return TRUE return FALSE else @@ -116,12 +116,12 @@ . = ..() . += SPAN_NOTICE("It has [max_installed_software - LAZYLEN(installed_software)] empty slot\s remaining out of [max_installed_software].") -/obj/item/mech_component/control_module/attackby(var/obj/item/thing, var/mob/user) - if(istype(thing, /obj/item/stock_parts/circuitboard/exosystem)) - install_software(thing, user) +/obj/item/mech_component/control_module/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/stock_parts/circuitboard/exosystem)) + install_software(used_item, user) return TRUE - if(IS_SCREWDRIVER(thing)) + if(IS_SCREWDRIVER(used_item)) . = ..() update_software() return diff --git a/code/modules/mechs/components/legs.dm b/code/modules/mechs/components/legs.dm index 40bf191e02f6..1270dbfda92f 100644 --- a/code/modules/mechs/components/legs.dm +++ b/code/modules/mechs/components/legs.dm @@ -22,13 +22,13 @@ /obj/item/mech_component/propulsion/update_components() motivator = locate() in src -/obj/item/mech_component/propulsion/attackby(var/obj/item/thing, var/mob/user) - if(istype(thing,/obj/item/robot_parts/robot_component/actuator)) +/obj/item/mech_component/propulsion/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item,/obj/item/robot_parts/robot_component/actuator)) if(motivator) to_chat(user, SPAN_WARNING("\The [src] already has an actuator installed.")) return TRUE - if(install_component(thing, user)) - motivator = thing + if(install_component(used_item, user)) + motivator = used_item return TRUE return FALSE else diff --git a/code/modules/mechs/equipment/combat_projectile.dm b/code/modules/mechs/equipment/combat_projectile.dm index 16756e060d6a..f71d5a2a5e59 100644 --- a/code/modules/mechs/equipment/combat_projectile.dm +++ b/code/modules/mechs/equipment/combat_projectile.dm @@ -1,12 +1,12 @@ -/obj/item/mech_equipment/mounted_system/projectile/attackby(var/obj/item/O, var/mob/user) +/obj/item/mech_equipment/mounted_system/projectile/attackby(var/obj/item/used_item, var/mob/user) var/obj/item/gun/projectile/automatic/A = holding if(!istype(A)) return FALSE - if(istype(O, /obj/item/crowbar)) + if(istype(used_item, /obj/item/crowbar)) A.unload_ammo(user) to_chat(user, SPAN_NOTICE("You remove the ammo magazine from \the [src].")) - else if(istype(O, A.magazine_type)) - A.load_ammo(O, user) + else if(istype(used_item, A.magazine_type)) + A.load_ammo(used_item, user) to_chat(user, SPAN_NOTICE("You load the ammo magazine into \the [src].")) return TRUE diff --git a/code/modules/mechs/equipment/medical.dm b/code/modules/mechs/equipment/medical.dm index b9f6b5da59b6..373af3a552e2 100644 --- a/code/modules/mechs/equipment/medical.dm +++ b/code/modules/mechs/equipment/medical.dm @@ -29,9 +29,9 @@ if(.) sleeper.ui_interact(user) -/obj/item/mech_equipment/sleeper/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/chems/glass)) - return sleeper.attackby(I, user) +/obj/item/mech_equipment/sleeper/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/chems/glass)) + return sleeper.attackby(used_item, user) else return ..() @@ -78,14 +78,14 @@ return null //You cannot modify these, it'd probably end with something in nullspace. In any case basic meds are plenty for an ambulance -/obj/machinery/sleeper/mounted/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/chems/glass)) - if(!user.try_unequip(I, src)) +/obj/machinery/sleeper/mounted/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/chems/glass)) + if(!user.try_unequip(used_item, src)) return TRUE if(beaker) user.put_in_hands(beaker) user.visible_message("\The [user] removes \the [beaker] from \the [src].", "You remove \the [beaker] from \the [src].") - beaker = I - user.visible_message("\The [user] adds \a [I] to \the [src].", "You add \a [I] to \the [src].") + beaker = used_item + user.visible_message("\The [user] adds \a [used_item] to \the [src].", "You add \a [used_item] to \the [src].") return TRUE return FALSE diff --git a/code/modules/mechs/equipment/utility.dm b/code/modules/mechs/equipment/utility.dm index 7d7d057c652d..37b955a8ddfe 100644 --- a/code/modules/mechs/equipment/utility.dm +++ b/code/modules/mechs/equipment/utility.dm @@ -423,9 +423,9 @@ DH.forceMove(src) drill_head = DH -/obj/item/mech_equipment/drill/attackby(obj/item/I, mob/user) - if (istype(I, /obj/item/drill_head)) - attach_head(I, user) +/obj/item/mech_equipment/drill/attackby(obj/item/used_item, mob/user) + if (istype(used_item, /obj/item/drill_head)) + attach_head(used_item, user) return TRUE . = ..() diff --git a/code/modules/mechs/mech_interaction.dm b/code/modules/mechs/mech_interaction.dm index 50188cb87fc2..8a8e9b671675 100644 --- a/code/modules/mechs/mech_interaction.dm +++ b/code/modules/mechs/mech_interaction.dm @@ -332,14 +332,14 @@ update_pilots() return 1 -/mob/living/exosuit/attackby(var/obj/item/thing, var/mob/user) +/mob/living/exosuit/attackby(var/obj/item/used_item, var/mob/user) // Install equipment. - if(!user.check_intent(I_FLAG_HARM) && istype(thing, /obj/item/mech_equipment)) + if(!user.check_intent(I_FLAG_HARM) && istype(used_item, /obj/item/mech_equipment)) if(hardpoints_locked) to_chat(user, SPAN_WARNING("Hardpoint system access is disabled.")) return TRUE - var/obj/item/mech_equipment/realThing = thing + var/obj/item/mech_equipment/realThing = used_item if(realThing.owner) return TRUE var/free_hardpoints = list() @@ -348,16 +348,16 @@ free_hardpoints += hardpoint var/to_place = input("Where would you like to install it?") as null|anything in (realThing.restricted_hardpoints & free_hardpoints) if(!to_place) - to_chat(user, SPAN_WARNING("There is no room to install \the [thing].")) - else if(!install_system(thing, to_place, user)) - to_chat(user, SPAN_WARNING("\The [thing] could not be installed in that hardpoint.")) + to_chat(user, SPAN_WARNING("There is no room to install \the [used_item].")) + else if(!install_system(used_item, to_place, user)) + to_chat(user, SPAN_WARNING("\The [used_item] could not be installed in that hardpoint.")) return TRUE // Apply customisation. - if(istype(thing, /obj/item/kit/paint)) - user.visible_message(SPAN_NOTICE("\The [user] opens \the [thing] and spends some quality time customising \the [src].")) + if(istype(used_item, /obj/item/kit/paint)) + user.visible_message(SPAN_NOTICE("\The [user] opens \the [used_item] and spends some quality time customising \the [src].")) - var/obj/item/kit/paint/P = thing + var/obj/item/kit/paint/P = used_item SetName(P.new_name) desc = P.new_desc @@ -381,7 +381,7 @@ if(!user.check_intent(I_FLAG_HARM)) // Removing systems from hardpoints. - if(IS_MULTITOOL(thing)) + if(IS_MULTITOOL(used_item)) if(hardpoints_locked) to_chat(user, SPAN_WARNING("Hardpoint system access is disabled.")) return TRUE @@ -395,7 +395,7 @@ return TRUE // Dismantling an exosuit entirely. - if(IS_WRENCH(thing)) + if(IS_WRENCH(used_item)) if(!maintenance_protocols) to_chat(user, SPAN_WARNING("The securing bolts are not visible while maintenance protocols are disabled.")) return TRUE @@ -406,7 +406,7 @@ return TRUE // Brute damage repair. - if(IS_WELDER(thing)) + if(IS_WELDER(used_item)) if(!get_damage(BRUTE)) return TRUE var/list/damaged_parts = list() @@ -415,11 +415,11 @@ damaged_parts += MC var/obj/item/mech_component/to_fix = input(user,"Which component would you like to fix") as null|anything in damaged_parts if(CanPhysicallyInteract(user) && !QDELETED(to_fix) && (to_fix in src) && to_fix.brute_damage) - to_fix.repair_brute_generic(thing, user) + to_fix.repair_brute_generic(used_item, user) return TRUE // Burn damage repair. - if(IS_COIL(thing)) + if(IS_COIL(used_item)) if(!get_damage(BURN)) return TRUE var/list/damaged_parts = list() @@ -428,11 +428,11 @@ damaged_parts += MC var/obj/item/mech_component/to_fix = input(user,"Which component would you like to fix") as null|anything in damaged_parts if(CanPhysicallyInteract(user) && !QDELETED(to_fix) && (to_fix in src) && to_fix.burn_damage) - to_fix.repair_burn_generic(thing, user) + to_fix.repair_burn_generic(used_item, user) return TRUE // Cell removal. - if(IS_SCREWDRIVER(thing)) + if(IS_SCREWDRIVER(used_item)) if(!maintenance_protocols) to_chat(user, SPAN_WARNING("The cell compartment remains locked while maintenance protocols are disabled.")) return TRUE @@ -444,23 +444,23 @@ user.put_in_hands(body.cell) to_chat(user, SPAN_NOTICE("You remove \the [body.cell] from \the [src].")) playsound(user.loc, 'sound/items/Crowbar.ogg', 50, 1) - visible_message(SPAN_NOTICE("\The [user] pries out \the [body.cell] using \the [thing].")) + visible_message(SPAN_NOTICE("\The [user] pries out \the [body.cell] using \the [used_item].")) power = MECH_POWER_OFF hud_power_control.queue_icon_update() body.cell = null return TRUE // Force-opening the cockpit. - if(IS_CROWBAR(thing)) + if(IS_CROWBAR(used_item)) if(!hatch_locked) to_chat(user, SPAN_NOTICE("The cockpit isn't locked. There is no need for this.")) return TRUE if(!body) //Error return TRUE var/delay = min(5 SECONDS * user.skill_delay_mult(SKILL_DEVICES), 5 SECONDS * user.skill_delay_mult(SKILL_EVA)) - visible_message(SPAN_NOTICE("\The [user] starts forcing \the [src]'s emergency [body.hatch_descriptor] release using \the [thing].")) + visible_message(SPAN_NOTICE("\The [user] starts forcing \the [src]'s emergency [body.hatch_descriptor] release using \the [used_item].")) if(do_after(user, delay, src)) - visible_message(SPAN_NOTICE("\The [user] forces \the [src]'s [body.hatch_descriptor] open using \the [thing].")) + visible_message(SPAN_NOTICE("\The [user] forces \the [src]'s [body.hatch_descriptor] open using \the [used_item].")) playsound(user.loc, 'sound/machines/bolts_up.ogg', 25, 1) hatch_locked = FALSE hatch_closed = FALSE @@ -471,23 +471,23 @@ return TRUE // Cell replacement. - if(istype(thing, /obj/item/cell)) + if(istype(used_item, /obj/item/cell)) if(!maintenance_protocols) to_chat(user, SPAN_WARNING("The cell compartment remains locked while maintenance protocols are disabled.")) return TRUE if(body?.cell) to_chat(user, SPAN_WARNING("There is already a cell in there!")) return TRUE - if(user.try_unequip(thing)) - thing.forceMove(body) - body.cell = thing + if(user.try_unequip(used_item)) + used_item.forceMove(body) + body.cell = used_item to_chat(user, SPAN_NOTICE("You install \the [body.cell] into \the [src].")) playsound(user.loc, 'sound/items/Screwdriver.ogg', 50, 1) visible_message(SPAN_NOTICE("\The [user] installs \the [body.cell] into \the [src].")) return TRUE // Diagnostic scan. - if(istype(thing, /obj/item/robotanalyzer)) + if(istype(used_item, /obj/item/robotanalyzer)) to_chat(user, SPAN_NOTICE("Diagnostic Report for \the [src]:")) for(var/obj/item/mech_component/MC in list(arms, legs, body, head)) if(MC) diff --git a/code/modules/mining/machinery/material_extractor.dm b/code/modules/mining/machinery/material_extractor.dm index 863f9fc59b21..39ca8096ae5e 100644 --- a/code/modules/mining/machinery/material_extractor.dm +++ b/code/modules/mining/machinery/material_extractor.dm @@ -149,8 +149,8 @@ return adjusted_reagents -/obj/machinery/material_processing/extractor/attackby(obj/item/I, mob/user) - if(IS_WRENCH(I) && !panel_open) +/obj/machinery/material_processing/extractor/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item) && !panel_open) var/datum/extension/atmospherics_connection/connection = get_extension(src, /datum/extension/atmospherics_connection) if(connection.disconnect()) to_chat(user, SPAN_NOTICE("You disconnect \the [src] from the port.")) @@ -165,13 +165,13 @@ to_chat(user, SPAN_WARNING("\The [src] failed to connect to the port.")) return TRUE - if(istype(I, /obj/item/chems/glass)) + if(istype(used_item, /obj/item/chems/glass)) if(isnull(output_container)) - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - output_container = I + output_container = used_item events_repository.register(/decl/observ/destroyed, output_container, src, TYPE_PROC_REF(/obj/machinery/material_processing/extractor, remove_container)) - user.visible_message(SPAN_NOTICE("\The [user] places \a [I] in \the [src]."), SPAN_NOTICE("You place \a [I] in \the [src].")) + user.visible_message(SPAN_NOTICE("\The [user] places \a [used_item] in \the [src]."), SPAN_NOTICE("You place \a [used_item] in \the [src].")) return TRUE to_chat(user, SPAN_WARNING("\The [src] already has an output container!")) diff --git a/code/modules/mob/living/bot/bot.dm b/code/modules/mob/living/bot/bot.dm index cf61d2ef7576..fca88bfd2e25 100644 --- a/code/modules/mob/living/bot/bot.dm +++ b/code/modules/mob/living/bot/bot.dm @@ -91,8 +91,8 @@ /mob/living/bot/try_awaken(mob/user) return FALSE -/mob/living/bot/attackby(var/obj/item/O, var/mob/user) - if(O.GetIdCard()) +/mob/living/bot/attackby(var/obj/item/used_item, var/mob/user) + if(used_item.GetIdCard()) if(access_scanner.allowed(user) && !open) locked = !locked to_chat(user, "Controls are now [locked ? "locked." : "unlocked."]") @@ -102,7 +102,7 @@ else to_chat(user, "Access denied.") return TRUE - else if(IS_SCREWDRIVER(O)) + else if(IS_SCREWDRIVER(used_item)) if(!locked) open = !open to_chat(user, "Maintenance panel is now [open ? "opened" : "closed"].") @@ -110,7 +110,7 @@ else to_chat(user, "You need to unlock the controls first.") return TRUE - else if(IS_WELDER(O)) + else if(IS_WELDER(used_item)) if(current_health < get_max_health()) if(open) heal_overall_damage(10) diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm index 037c13b9ffa2..ff482b50f311 100644 --- a/code/modules/mob/living/bot/medibot.dm +++ b/code/modules/mob/living/bot/medibot.dm @@ -155,8 +155,8 @@ else icon_state = "medibot[on]" -/mob/living/bot/medbot/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/chems/glass)) +/mob/living/bot/medbot/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/chems/glass)) if(locked) to_chat(user, "You cannot insert a beaker because the panel is locked.") return TRUE @@ -164,10 +164,10 @@ to_chat(user, "There is already a beaker loaded.") return TRUE - if(!user.try_unequip(O, src)) + if(!user.try_unequip(used_item, src)) return TRUE - reagent_glass = O - to_chat(user, "You insert [O].") + reagent_glass = used_item + to_chat(user, "You insert [used_item].") return TRUE else return ..() diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm index 078dee2a3827..39306c864512 100644 --- a/code/modules/mob/living/bot/mulebot.dm +++ b/code/modules/mob/living/bot/mulebot.dm @@ -115,7 +115,7 @@ if("safety") safety = !safety -/mob/living/bot/mulebot/attackby(var/obj/item/O, var/mob/user) +/mob/living/bot/mulebot/attackby(var/obj/item/used_item, var/mob/user) . = ..() update_icon() diff --git a/code/modules/mob/living/bot/remotebot.dm b/code/modules/mob/living/bot/remotebot.dm index fa28520aa3e5..ffdf2de4119d 100644 --- a/code/modules/mob/living/bot/remotebot.dm +++ b/code/modules/mob/living/bot/remotebot.dm @@ -34,11 +34,11 @@ if(prob(50)) C.forceMove(get_step(src, pick(global.alldirs))) -/mob/living/bot/remotebot/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/bot_controller) && !controller) - user.visible_message("\The [user] waves \the [I] over \the [src].") - to_chat(user, "You link \the [src] to \the [I].") - var/obj/item/bot_controller/B = I +/mob/living/bot/remotebot/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/bot_controller) && !controller) + user.visible_message("\The [user] waves \the [used_item] over \the [src].") + to_chat(user, "You link \the [src] to \the [used_item].") + var/obj/item/bot_controller/B = used_item B.bot = src controller = B return ..() @@ -53,16 +53,16 @@ holding = null return ..() -/mob/living/bot/remotebot/proc/pickup(var/obj/item/I) - if(holding || get_dist(src,I) > 1) +/mob/living/bot/remotebot/proc/pickup(var/obj/item/used_item) + if(holding || get_dist(src,used_item) > 1) return - src.visible_message("\The [src] picks up \the [I].") + src.visible_message("\The [src] picks up \the [used_item].") flick("fetchbot-c", src) working = 1 sleep(10) working = 0 - I.forceMove(src) - holding = I + used_item.forceMove(src) + holding = used_item /mob/living/bot/remotebot/proc/drop() if(working || !holding) diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index e612a4e3d72c..d4e5fbe2104e 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -103,7 +103,7 @@ if(emagged < 2) emagged = !emagged -/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user) +/mob/living/bot/secbot/attackby(var/obj/item/used_item, var/mob/user) var/curhealth = current_health . = ..() if(current_health < curhealth) diff --git a/code/modules/mob/living/simple_animal/_simple_animal.dm b/code/modules/mob/living/simple_animal/_simple_animal.dm index 0b7d78e11bf0..b6646ad21f93 100644 --- a/code/modules/mob/living/simple_animal/_simple_animal.dm +++ b/code/modules/mob/living/simple_animal/_simple_animal.dm @@ -348,11 +348,11 @@ var/global/list/simplemob_icon_bitflag_cache = list() user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) return TRUE -/mob/living/simple_animal/attackby(var/obj/item/O, var/mob/user) +/mob/living/simple_animal/attackby(var/obj/item/used_item, var/mob/user) - if(istype(O, /obj/item/stack/medical)) + if(istype(used_item, /obj/item/stack/medical)) if(stat != DEAD) - var/obj/item/stack/medical/MED = O + var/obj/item/stack/medical/MED = used_item if(!MED.animal_heal) to_chat(user, SPAN_WARNING("\The [MED] won't help \the [src] at all!")) else if(current_health < get_max_health() && MED.can_use(1)) diff --git a/code/modules/mob/living/simple_animal/crow/crow.dm b/code/modules/mob/living/simple_animal/crow/crow.dm index 1c780c3299aa..860fbb9b8b50 100644 --- a/code/modules/mob/living/simple_animal/crow/crow.dm +++ b/code/modules/mob/living/simple_animal/crow/crow.dm @@ -63,11 +63,11 @@ return backpack.attack_hand(user) return ..() -/mob/living/simple_animal/crow/attackby(obj/item/I, mob/user) +/mob/living/simple_animal/crow/attackby(obj/item/used_item, mob/user) if(user.check_intent(I_FLAG_HELP)) var/obj/item/backpack = get_equipped_item(slot_back_str) if(backpack) - return backpack.attackby(I, user) + return backpack.attackby(used_item, user) return ..() /mob/living/simple_animal/crow/on_update_icon() diff --git a/code/modules/mob/living/simple_animal/friendly/corgi.dm b/code/modules/mob/living/simple_animal/friendly/corgi.dm index ab52e19b77ca..9264cd3be0f4 100644 --- a/code/modules/mob/living/simple_animal/friendly/corgi.dm +++ b/code/modules/mob/living/simple_animal/friendly/corgi.dm @@ -126,9 +126,9 @@ if(prob(1)) dance() -/mob/living/simple_animal/corgi/attackby(var/obj/item/O, var/mob/user) //Marker -Agouri - if(istype(O, /obj/item/newspaper) && !stat) - visible_message(SPAN_NOTICE("\The [user] baps \the [src] on the nose with the rolled-up [O.name]!")) +/mob/living/simple_animal/corgi/attackby(var/obj/item/used_item, var/mob/user) //Marker -Agouri + if(istype(used_item, /obj/item/newspaper) && !stat) + visible_message(SPAN_NOTICE("\The [user] baps \the [src] on the nose with the rolled-up [used_item.name]!")) var/datum/mob_controller/corgi/corgi_ai = ai if(istype(corgi_ai)) corgi_ai.dance() diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 7a00faca3d58..3669fd32622f 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -244,14 +244,14 @@ var/global/chicken_count = 0 if(.) global.chicken_count -= 1 -/mob/living/simple_animal/fowl/chicken/attackby(var/obj/item/O, var/mob/user) - if(!istype(O, /obj/item/food)) +/mob/living/simple_animal/fowl/chicken/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/food)) return ..() - var/obj/item/food/G = O //feedin' dem chickens + var/obj/item/food/G = used_item //feedin' dem chickens if(findtext(G.get_grown_tag(), "wheat")) // includes chopped, crushed, dried etc. if(!stat && eggsleft < 4) - user.visible_message(SPAN_NOTICE("[user] feeds \the [O] to \the [src]! It clucks happily."), SPAN_NOTICE("You feed \the [O] to \the [src]! It clucks happily."), SPAN_NOTICE("You hear clucking.")) - qdel(O) + user.visible_message(SPAN_NOTICE("[user] feeds \the [used_item] to \the [src]! It clucks happily."), SPAN_NOTICE("You feed \the [used_item] to \the [src]! It clucks happily."), SPAN_NOTICE("You hear clucking.")) + qdel(used_item) eggsleft += rand(1, 2) else to_chat(user, SPAN_NOTICE("\The [src] doesn't seem hungry!")) diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 2f79162b6c92..95e133c9d35e 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -99,7 +99,7 @@ body.stop_automove() return -/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/O, var/mob/user) +/mob/living/simple_animal/hostile/bear/attackby(var/obj/item/used_item, var/mob/user) if(istype(ai)) var/stance = ai.get_stance() if(stance != STANCE_ATTACK && stance != STANCE_ATTACKING) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm index 3b185823bcb5..06b5079874ef 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/parrot.dm @@ -331,9 +331,9 @@ update_icon() //Mobs with objects -/mob/living/simple_animal/hostile/parrot/attackby(var/obj/item/O, var/mob/user) +/mob/living/simple_animal/hostile/parrot/attackby(var/obj/item/used_item, var/mob/user) . = ..() - if(!stat && !client && !istype(O, /obj/item/stack/medical) && O.expend_attack_force(user)) + if(!stat && !client && !istype(used_item, /obj/item/stack/medical) && used_item.expend_attack_force(user)) if(parrot_state == PARROT_PERCH) parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched parrot_interest = user @@ -371,10 +371,10 @@ return M /mob/living/simple_animal/hostile/parrot/proc/search_for_perch() - for(var/obj/O in view(src)) + for(var/obj/thing in view(src)) for(var/path in desired_perches) - if(istype(O, path)) - return O + if(istype(thing, path)) + return thing return null //This proc was made to save on doing two 'in view' loops seperatly diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index 2d9c574d3a08..62ad6a78a842 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -102,10 +102,10 @@ loc.verbs |= /obj/item/stock_parts/computer/card_slot/proc/verb_eject_id return TRUE -/obj/item/stock_parts/computer/card_slot/attackby(obj/item/card/id/I, mob/user) - if(!istype(I)) +/obj/item/stock_parts/computer/card_slot/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/card/id)) return ..() - insert_id(I, user) + insert_id(used_item, user) return TRUE /obj/item/stock_parts/computer/card_slot/broadcaster // read only diff --git a/code/modules/modular_computers/hardware/charge_stick_slot.dm b/code/modules/modular_computers/hardware/charge_stick_slot.dm index d7988d6298b4..4e3087c7db54 100644 --- a/code/modules/modular_computers/hardware/charge_stick_slot.dm +++ b/code/modules/modular_computers/hardware/charge_stick_slot.dm @@ -82,10 +82,10 @@ loc.verbs |= /obj/item/stock_parts/computer/charge_stick_slot/proc/verb_eject_stick return TRUE -/obj/item/stock_parts/computer/charge_stick_slot/attackby(obj/item/charge_stick/I, mob/user) - if(!istype(I)) +/obj/item/stock_parts/computer/charge_stick_slot/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/charge_stick)) return ..() - insert_stick(I, user) + insert_stick(used_item, user) return TRUE /obj/item/stock_parts/computer/charge_stick_slot/broadcaster // read only diff --git a/code/modules/modular_computers/hardware/disk_slot.dm b/code/modules/modular_computers/hardware/disk_slot.dm index 1cb1a6f7d93b..47831abe7613 100644 --- a/code/modules/modular_computers/hardware/disk_slot.dm +++ b/code/modules/modular_computers/hardware/disk_slot.dm @@ -97,10 +97,10 @@ os.unmount_storage(mount_name) -/obj/item/stock_parts/computer/data_disk_drive/attackby(obj/item/disk/new_disk, mob/user) - if(!istype(new_disk)) +/obj/item/stock_parts/computer/data_disk_drive/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/disk)) return ..() - insert_disk(new_disk, user) + insert_disk(used_item, user) return TRUE /obj/item/stock_parts/computer/data_disk_drive/Destroy() diff --git a/code/modules/modular_computers/hardware/drive_slot.dm b/code/modules/modular_computers/hardware/drive_slot.dm index 0dec813de9e6..c584eb9c284a 100644 --- a/code/modules/modular_computers/hardware/drive_slot.dm +++ b/code/modules/modular_computers/hardware/drive_slot.dm @@ -94,10 +94,10 @@ os.unmount_storage(mount_name) -/obj/item/stock_parts/computer/drive_slot/attackby(obj/item/stock_parts/computer/hard_drive/portable/I, mob/user) - if(!istype(I)) +/obj/item/stock_parts/computer/drive_slot/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/stock_parts/computer/hard_drive/portable)) return ..() - insert_drive(I, user) + insert_drive(used_item, user) return TRUE /obj/item/stock_parts/computer/drive_slot/Destroy() diff --git a/code/modules/modular_computers/hardware/lan_port.dm b/code/modules/modular_computers/hardware/lan_port.dm index c55d9da47a32..3074458d21e9 100644 --- a/code/modules/modular_computers/hardware/lan_port.dm +++ b/code/modules/modular_computers/hardware/lan_port.dm @@ -57,13 +57,13 @@ /obj/item/stock_parts/computer/lan_port/proc/check_terminal_block(var/turf/T) return locate(/obj/structure/network_cable) in T -/obj/item/stock_parts/computer/lan_port/attackby(obj/item/I, mob/user) +/obj/item/stock_parts/computer/lan_port/attackby(obj/item/used_item, mob/user) var/obj/machinery/parent = loc if(!istype(parent)) return ..() // Interactions inside machine only - if (istype(I, /obj/item/stack/net_cable_coil) && !terminal) + if (istype(used_item, /obj/item/stack/net_cable_coil) && !terminal) var/turf/T = get_turf(parent) if(check_terminal_block(T)) to_chat(user, SPAN_WARNING("There's already a network cable there!")) @@ -72,7 +72,7 @@ to_chat(user, SPAN_WARNING("You must remove the floor plating beneath \the [parent] first.")) return TRUE - var/obj/item/stack/net_cable_coil/C = I + var/obj/item/stack/net_cable_coil/C = used_item if(!C.can_use(5)) to_chat(user, SPAN_WARNING("You need five lengths of network cable for \the [parent].")) return TRUE @@ -83,7 +83,7 @@ user.visible_message(SPAN_NOTICE("\The [user] has added cables to \the [parent]!"), "You add cables to \the [parent].") set_terminal() return TRUE - if(IS_WIRECUTTER(I) && terminal) + if(IS_WIRECUTTER(used_item) && terminal) var/turf/T = get_turf(parent) if(istype(T) && !T.is_plating()) to_chat(user, SPAN_WARNING("You must remove the floor plating beneath \the [parent] first.")) diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index 00f823ff9fba..1a939ceb8f3a 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -291,9 +291,8 @@ ui.open() ui.set_auto_update(1) - -/obj/machinery/lapvend/attackby(obj/item/held_item as obj, mob/user as mob) - if(state == STATE_PAYMENT && process_payment(held_item)) +/obj/machinery/lapvend/attackby(obj/item/used_item, mob/user) + if(state == STATE_PAYMENT && process_payment(used_item)) fabricate_and_recalc_price(TRUE) flick("world-vend", src) if((devtype == DEVICE_TYPE_LAPTOP) && fabricated_laptop) diff --git a/code/modules/multiz/ladder.dm b/code/modules/multiz/ladder.dm index b86299bcf5f4..1cb9c5892dc4 100644 --- a/code/modules/multiz/ladder.dm +++ b/code/modules/multiz/ladder.dm @@ -120,12 +120,12 @@ /obj/structure/ladder/grab_attack(obj/item/grab/grab, mob/user) return FALSE -/obj/structure/ladder/attackby(obj/item/I, mob/user) - . = !istype(I, /obj/item/grab) && ..() +/obj/structure/ladder/attackby(obj/item/used_item, mob/user) + . = !istype(used_item, /obj/item/grab) && ..() if(!.) - climb(user, I) + climb(user, used_item) -/obj/structure/ladder/hitby(obj/item/I) +/obj/structure/ladder/hitby(obj/item/thing) . = ..() if(!target_down) return @@ -136,13 +136,13 @@ if(!istype(landing)) return for(var/atom/A in landing) - if(!A.CanPass(I, I.loc, 1.5, 0)) + if(!A.CanPass(thing, thing.loc, 1.5, 0)) blocker = A break if(!blocker) - visible_message(SPAN_DANGER("\The [I] goes down \the [src]!")) - I.forceMove(landing) - landing.visible_message(SPAN_DANGER("\The [I] falls from the top of \the [target_down]!")) + visible_message(SPAN_DANGER("\The [thing] goes down \the [src]!")) + thing.forceMove(landing) + landing.visible_message(SPAN_DANGER("\The [thing] falls from the top of \the [target_down]!")) /obj/structure/ladder/attack_hand(var/mob/user) if(user.check_intent(I_FLAG_HARM) || !user.check_dexterity(DEXTERITY_SIMPLE_MACHINES)) @@ -168,7 +168,7 @@ if(target_ladder) M.dropInto(target_ladder.loc) -/obj/structure/ladder/proc/climb(mob/M, obj/item/I) +/obj/structure/ladder/proc/climb(mob/M, obj/item/thing) if(!M.may_climb_ladders(src)) return @@ -186,7 +186,7 @@ M.visible_message(SPAN_NOTICE("\The [M] begins climbing [direction] \the [src].")) target_ladder.audible_message(SPAN_NOTICE("You hear something coming [direction] \the [src].")) if(do_after(M, climb_time, src)) - climbLadder(M, target_ladder, I) + climbLadder(M, target_ladder, thing) /obj/structure/ladder/attack_ghost(var/mob/M) instant_climb(M) @@ -250,7 +250,7 @@ /mob/observer/ghost/may_climb_ladders(var/ladder) return TRUE -/obj/structure/ladder/proc/climbLadder(mob/user, target_ladder, obj/item/I = null) +/obj/structure/ladder/proc/climbLadder(mob/user, target_ladder, obj/item/thing = null) var/turf/T = get_turf(target_ladder) for(var/atom/A in T) if(!A.CanPass(user, user.loc, 1.5, 0)) @@ -258,10 +258,10 @@ //We cannot use the ladder, but we probably can remove the obstruction var/atom/movable/M = A if(istype(M) && M.movable_flags & MOVABLE_FLAG_Z_INTERACT) - if(isnull(I) || istype(I, /obj/item/grab)) + if(isnull(thing) || istype(thing, /obj/item/grab)) M.attack_hand_with_interaction_checks(user) else - M.attackby(I, user) + M.attackby(thing, user) return FALSE playsound(src, pick(climbsounds), 50) playsound(target_ladder, pick(climbsounds), 50) @@ -277,8 +277,8 @@ else icon_state = "[base_icon][!!target_up][!!target_down]" if(target_down && draw_shadow) - var/image/I = image(icon, "downward_shadow") - I.appearance_flags |= RESET_COLOR - underlays = list(I) + var/image/overlay_image = image(icon, "downward_shadow") + overlay_image.appearance_flags |= RESET_COLOR + underlays = list(overlay_image) else underlays.Cut() diff --git a/code/modules/overmap/contacts/contact_sensors.dm b/code/modules/overmap/contacts/contact_sensors.dm index fcdd349fb077..7ebe9b07788e 100644 --- a/code/modules/overmap/contacts/contact_sensors.dm +++ b/code/modules/overmap/contacts/contact_sensors.dm @@ -150,9 +150,9 @@ if(!record.pinged) addtimer(CALLBACK(record, PROC_REF(ping)), time_delay) -/obj/machinery/computer/ship/sensors/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/computer/ship/sensors/attackby(var/obj/item/used_item, var/mob/user) . = ..() - var/obj/item/multitool/P = I + var/obj/item/multitool/P = used_item if(!istype(P)) return var/obj/item/ship_tracker/tracker = P.get_buffer() diff --git a/code/modules/overmap/disperser/disperser.dm b/code/modules/overmap/disperser/disperser.dm index 4b8660f0c0ee..5059a21e44a9 100644 --- a/code/modules/overmap/disperser/disperser.dm +++ b/code/modules/overmap/disperser/disperser.dm @@ -12,10 +12,10 @@ if(panel_open) . += "The maintenance panel is open." -/obj/machinery/disperser/attackby(obj/item/I, mob/user) - if(IS_WRENCH(I)) +/obj/machinery/disperser/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item)) if(panel_open) - user.visible_message("\The [user] rotates \the [src] with \the [I].", "You rotate \the [src] with \the [I].") + user.visible_message("\The [user] rotates \the [src] with \the [used_item].", "You rotate \the [src] with \the [used_item].") set_dir(turn(dir, 90)) playsound(src, 'sound/items/jaws_pry.ogg', 50, 1) else diff --git a/code/modules/overmap/ftl_shunt/core.dm b/code/modules/overmap/ftl_shunt/core.dm index f01dcb55a319..fe8407d230e7 100644 --- a/code/modules/overmap/ftl_shunt/core.dm +++ b/code/modules/overmap/ftl_shunt/core.dm @@ -112,9 +112,9 @@ else . += SPAN_WARNING("It looks like it's been tampered with, but you're not sure to what extent.") -/obj/machinery/ftl_shunt/core/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/stack/telecrystal)) - var/obj/item/stack/telecrystal/TC = O +/obj/machinery/ftl_shunt/core/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/stack/telecrystal)) + var/obj/item/stack/telecrystal/TC = used_item if(TC.amount < 10) to_chat(user, SPAN_WARNING("You don't have enough telecrystals to sabotage [src].")) @@ -238,11 +238,11 @@ return FTL_START_CONFIRMED /obj/machinery/ftl_shunt/core/proc/calculate_jump_requirements() - var/obj/effect/overmap/visitable/O = global.overmap_sectors[num2text(z)] - if(O) + var/obj/effect/overmap/visitable/site = global.overmap_sectors[num2text(z)] + if(site) var/shunt_distance var/vessel_mass = ftl_computer.linked.get_vessel_mass() - var/shunt_turf = locate(shunt_x, shunt_y, O.z) + var/shunt_turf = locate(shunt_x, shunt_y, site.z) shunt_distance = get_dist(get_turf(ftl_computer.linked), shunt_turf) required_fuel_joules = (vessel_mass * JOULES_PER_TON) * shunt_distance required_charge = required_fuel_joules * REQUIRED_CHARGE_MULTIPLIER @@ -275,9 +275,9 @@ cancel_shunt() return //If for some reason we don't have fuel now, just return. - var/obj/effect/overmap/visitable/O = global.overmap_sectors[num2text(z)] - if(O) - var/destination = locate(shunt_x, shunt_y, O.z) + var/obj/effect/overmap/visitable/site = global.overmap_sectors[num2text(z)] + if(site) + var/destination = locate(shunt_x, shunt_y, site.z) var/jumpdist = get_dist(get_turf(ftl_computer.linked), destination) var/obj/effect/portal/wormhole/wormhole = new(destination) //Generate a wormhole effect on overmap to give some indication that something is about to happen. QDEL_IN(wormhole, 6 SECONDS) @@ -584,13 +584,13 @@ master = null QDEL_NULL(fuel) -/obj/machinery/ftl_shunt/fuel_port/attackby(var/obj/item/O, var/mob/user) - if(istype(O, /obj/item/fuel_assembly) && !fuel) +/obj/machinery/ftl_shunt/fuel_port/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/fuel_assembly) && !fuel) if(!do_after(user, 2 SECONDS, src) || fuel) return TRUE - if(!user || !user.try_unequip(O, src)) + if(!user || !user.try_unequip(used_item, src)) return TRUE - fuel = O + fuel = used_item max_fuel = get_fuel_joules(TRUE) update_icon() return TRUE diff --git a/code/modules/overmap/ships/machines/fusion_thruster.dm b/code/modules/overmap/ships/machines/fusion_thruster.dm index 0f4b673554c1..3e4ac6748728 100644 --- a/code/modules/overmap/ships/machines/fusion_thruster.dm +++ b/code/modules/overmap/ships/machines/fusion_thruster.dm @@ -35,8 +35,8 @@ harvest_from = fusion_cores[1] return harvest_from -/obj/machinery/atmospherics/unary/engine/fusion/attackby(var/obj/item/thing, var/mob/user) - if(IS_MULTITOOL(thing)) +/obj/machinery/atmospherics/unary/engine/fusion/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/lanm = get_extension(src, /datum/extension/local_network_member) if(lanm.get_new_tag(user)) find_core() diff --git a/code/modules/overmap/ships/machines/gas_thruster.dm b/code/modules/overmap/ships/machines/gas_thruster.dm index 4d744491d3a2..67ea291ac16e 100644 --- a/code/modules/overmap/ships/machines/gas_thruster.dm +++ b/code/modules/overmap/ships/machines/gas_thruster.dm @@ -32,8 +32,8 @@ else z_flags &= ~ZMM_MANGLE_PLANES -/obj/machinery/atmospherics/unary/engine/attackby(obj/item/I, mob/user) - if(IS_MULTITOOL(I) && !panel_open) +/obj/machinery/atmospherics/unary/engine/attackby(obj/item/used_item, mob/user) + if(IS_MULTITOOL(used_item) && !panel_open) var/datum/extension/ship_engine/engine = get_extension(src, /datum/extension/ship_engine) if(engine.sync_to_ship()) to_chat(user, SPAN_NOTICE("\The [src] emits a ping as it syncs its controls to a nearby ship.")) diff --git a/code/modules/overmap/ships/machines/ion_thruster.dm b/code/modules/overmap/ships/machines/ion_thruster.dm index 63d983050364..a44269746651 100644 --- a/code/modules/overmap/ships/machines/ion_thruster.dm +++ b/code/modules/overmap/ships/machines/ion_thruster.dm @@ -46,8 +46,8 @@ var/thrust_cost = 750 var/thrust_effectiveness = 1 -/obj/machinery/ion_thruster/attackby(obj/item/I, mob/user) - if(IS_MULTITOOL(I) && !panel_open) +/obj/machinery/ion_thruster/attackby(obj/item/used_item, mob/user) + if(IS_MULTITOOL(used_item) && !panel_open) var/datum/extension/ship_engine/engine = get_extension(src, /datum/extension/ship_engine) if(engine.sync_to_ship()) to_chat(user, SPAN_NOTICE("\The [src] emits a ping as it syncs its controls to a nearby ship.")) diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index 7aad7aace238..cabe90556973 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -135,10 +135,10 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to ui_interact(user) return TRUE -/obj/machinery/faxmachine/attackby(obj/item/I, mob/user) +/obj/machinery/faxmachine/attackby(obj/item/used_item, mob/user) if(istype(construct_state, /decl/machine_construction/default/panel_closed)) - if(istype(I, /obj/item/paper) || istype(I, /obj/item/photo) || istype(I, /obj/item/paper_bundle)) - insert_scanner_item(I, user) + if(istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo) || istype(used_item, /obj/item/paper_bundle)) + insert_scanner_item(used_item, user) return TRUE . = ..() @@ -263,9 +263,9 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to to_chat(user, SPAN_WARNING("There's already a [scanner_item] in \the [src]!")) return TOPIC_NOACTION else - var/obj/item/I = user.get_active_held_item() - if(I) - insert_scanner_item(I, user) + var/obj/item/thing = user.get_active_held_item() + if(thing) + insert_scanner_item(thing, user) else to_chat(user, SPAN_WARNING("You're not holding anything!")) return TOPIC_NOACTION @@ -349,19 +349,19 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to return return D -/obj/machinery/faxmachine/proc/insert_scanner_item(var/obj/item/I, var/mob/user) +/obj/machinery/faxmachine/proc/insert_scanner_item(var/obj/item/thing, var/mob/user) if(!QDELETED(scanner_item)) if(user) to_chat(user, SPAN_WARNING("\The [src] already has something being scanned!")) return FALSE if(user) - to_chat(user, SPAN_NOTICE("You place \the [I] into \the [src]'s scanner.")) - if(!user.try_unequip(I, src)) + to_chat(user, SPAN_NOTICE("You place \the [thing] into \the [src]'s scanner.")) + if(!user.try_unequip(thing, src)) return FALSE else - I.dropInto(src) - scanner_item = I + thing.dropInto(src) + scanner_item = thing update_ui() return TRUE diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm index 077717829360..185771010d86 100644 --- a/code/modules/paperwork/filingcabinet.dm +++ b/code/modules/paperwork/filingcabinet.dm @@ -27,13 +27,13 @@ I.forceMove(src) . = ..() -/obj/structure/filing_cabinet/attackby(obj/item/P, mob/user) - if(!is_type_in_list(P, can_hold)) +/obj/structure/filing_cabinet/attackby(obj/item/used_item, mob/user) + if(!is_type_in_list(used_item, can_hold)) return ..() - if(!user.try_unequip(P, src)) + if(!user.try_unequip(used_item, src)) return TRUE add_fingerprint(user) - to_chat(user, SPAN_NOTICE("You put [P] in [src].")) + to_chat(user, SPAN_NOTICE("You put [used_item] in [src].")) flick("[initial(icon_state)]-open",src) updateUsrDialog() return TRUE @@ -41,8 +41,8 @@ /obj/structure/filing_cabinet/interact(mob/user) user.set_machine(src) var/dat = "
    " - for(var/obj/item/P in src) - dat += "" + for(var/obj/item/paper in src) + dat += "" dat += "
    [P.name]
    [paper.name]
    " show_browser(user, "[name][dat]", "window=filingcabinet;size=350x300") @@ -53,9 +53,9 @@ /obj/structure/filing_cabinet/OnTopic(mob/user, href_list, datum/topic_state/state) if(href_list["retrieve"]) close_browser(user, "window=filingcabinet") - var/obj/item/P = locate(href_list["retrieve"]) - if(istype(P) && CanPhysicallyInteractWith(user, src)) - user.put_in_hands(P) + var/obj/item/paper = locate(href_list["retrieve"]) + if(istype(paper) && CanPhysicallyInteractWith(user, src)) + user.put_in_hands(paper) flick("[initial(icon_state)]-open", src) updateUsrDialog() . = TOPIC_REFRESH diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index c0dd0d858629..3df8a1af0511 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -238,18 +238,18 @@ updateinfolinks() update_icon() -/obj/item/paper/proc/get_signature(var/obj/item/pen/P, mob/user) - if(P && IS_PEN(P)) +/obj/item/paper/proc/get_signature(var/obj/item/pen/pen, mob/user) + if(pen && IS_PEN(pen)) var/decl/tool_archetype/pen/parch = GET_DECL(TOOL_PEN) - return parch.get_signature(user, P) + return parch.get_signature(user, pen) return (user && user.real_name) ? user.real_name : "Anonymous" -/obj/item/paper/proc/parsepencode(t, obj/item/pen/P, mob/user, iscrayon, isfancy) +/obj/item/paper/proc/parsepencode(t, obj/item/pen/pen, mob/user, iscrayon, isfancy) if(length(t) == 0) return "" if(findtext(t, "\[sign\]")) - t = replacetext(t, "\[sign\]", "[get_signature(P, user)]") + t = replacetext(t, "\[sign\]", "[get_signature(pen, user)]") if(iscrayon) // If it is a crayon, and he still tries to use these, make them empty! t = replacetext(t, "\[*\]", "") @@ -264,7 +264,7 @@ t = replacetext(t, "\[cell\]", "") t = replacetext(t, "\[logo\]", "") - var/pen_color = P? P.get_tool_property(TOOL_PEN, TOOL_PROP_COLOR) : "black" + var/pen_color = pen ? pen.get_tool_property(TOOL_PEN, TOOL_PROP_COLOR) : "black" if(iscrayon) t = "[t]" else if(isfancy) @@ -285,19 +285,19 @@ return t -/obj/item/paper/proc/burnpaper(obj/item/P, mob/user) +/obj/item/paper/proc/burnpaper(obj/item/paper, mob/user) var/class = "warning" - if(P.isflamesource() && !user.restrained()) - if(istype(P, /obj/item/flame/fuelled/lighter/zippo)) + if(paper.isflamesource() && !user.restrained()) + if(istype(paper, /obj/item/flame/fuelled/lighter/zippo)) class = "rose" var/decl/pronouns/pronouns = user.get_pronouns() - user.visible_message("[user] holds \the [P] up to \the [src], it looks like [pronouns.he] [pronouns.is] trying to burn it!", \ - "You hold \the [P] up to \the [src], burning it slowly.") + user.visible_message("[user] holds \the [paper] up to \the [src], it looks like [pronouns.he] [pronouns.is] trying to burn it!", \ + "You hold \the [paper] up to \the [src], burning it slowly.") spawn(20) - if(get_dist(src, user) < 2 && user.get_active_held_item() == P && P.isflamesource()) + if(get_dist(src, user) < 2 && user.get_active_held_item() == paper && paper.isflamesource()) user.visible_message("[user] burns right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.", \ "You burn right through \the [src], turning it to ash. It flutters through the air before settling on the floor in a heap.") @@ -305,7 +305,7 @@ qdel(src) else - to_chat(user, SPAN_WARNING("You must hold \the [P] steady to burn \the [src].")) + to_chat(user, SPAN_WARNING("You must hold \the [paper] steady to burn \the [src].")) /obj/item/paper/CouldNotUseTopic(mob/user) to_chat(user, SPAN_WARNING("You can't reach!")) @@ -378,43 +378,43 @@ return ..() -/obj/item/paper/attackby(obj/item/P, mob/user) - if(istype(P, /obj/item/stack/tape_roll/duct_tape)) - var/obj/item/stack/tape_roll/duct_tape/tape = P +/obj/item/paper/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/stack/tape_roll/duct_tape)) + var/obj/item/stack/tape_roll/duct_tape/tape = used_item return tape.stick(src, user) - else if(istype(P, /obj/item/paper) || istype(P, /obj/item/photo)) - var/obj/item/paper_bundle/B = try_bundle_with(P, user) + else if(istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo)) + var/obj/item/paper_bundle/B = try_bundle_with(used_item, user) if(!B) return TRUE user.put_in_hands(B) - to_chat(user, SPAN_NOTICE("You clip \the [P] and \the [name] together.")) + to_chat(user, SPAN_NOTICE("You clip \the [used_item] and \the [name] together.")) return TRUE - else if(IS_PEN(P)) + else if(IS_PEN(used_item)) if(is_crumpled) to_chat(user, SPAN_WARNING("\The [src] is too crumpled to write on.")) return TRUE - var/obj/item/pen/robopen/RP = P + var/obj/item/pen/robopen/RP = used_item if ( istype(RP) && RP.mode == 2 ) RP.RenamePaper(user,src) else interact(user, readonly = FALSE) return TRUE - else if(P.get_tool_quality(TOOL_STAMP)) - apply_custom_stamp(P.icon, "with \the [P]") + else if(used_item.get_tool_quality(TOOL_STAMP)) + apply_custom_stamp(used_item.icon, "with \the [used_item]") playsound(src, 'sound/effects/stamp.ogg', 50, TRUE) - to_chat(user, SPAN_NOTICE("You stamp the paper with your [P.name].")) + to_chat(user, SPAN_NOTICE("You stamp the paper with your [used_item.name].")) return TRUE - else if(P.isflamesource()) - burnpaper(P, user) + else if(used_item.isflamesource()) + burnpaper(used_item, user) return TRUE - else if(istype(P, /obj/item/paper_bundle)) - var/obj/item/paper_bundle/B = P + else if(istype(used_item, /obj/item/paper_bundle)) + var/obj/item/paper_bundle/B = used_item B.merge(src, user) return TRUE return ..() @@ -450,8 +450,8 @@ /obj/item/paper/proc/can_bundle_with(var/obj/item/other) if(istype(other, /obj/item/paper)) - var/obj/item/paper/P = other - return can_bundle() && P.can_bundle() + var/obj/item/paper/paper = other + return can_bundle() && paper.can_bundle() else if(istype(other, /obj/item/photo)) return can_bundle() else if(istype(other, /obj/item/paper_bundle)) diff --git a/code/modules/paperwork/paper_sticky.dm b/code/modules/paperwork/paper_sticky.dm index aaa0ad746036..05e989afe20f 100644 --- a/code/modules/paperwork/paper_sticky.dm +++ b/code/modules/paperwork/paper_sticky.dm @@ -43,9 +43,9 @@ if(top?.info) icon_state = "[icon_state]_writing" -/obj/item/sticky_pad/attackby(var/obj/item/thing, var/mob/user) - if(IS_PEN(thing) || istype(thing, /obj/item/stamp)) - . = top?.attackby(thing, user) +/obj/item/sticky_pad/attackby(var/obj/item/used_item, var/mob/user) + if(IS_PEN(used_item) || istype(used_item, /obj/item/stamp)) + . = top?.attackby(used_item, user) update_icon() return . return ..() diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm index 0dfa1d4f831b..4bc17502521d 100644 --- a/code/modules/paperwork/paperbin.dm +++ b/code/modules/paperwork/paperbin.dm @@ -72,23 +72,23 @@ add_fingerprint(user) return TRUE -/obj/item/paper_bin/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/paper)) +/obj/item/paper_bin/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/paper)) if(amount >= max_amount) to_chat(user, SPAN_WARNING("\The [src] is full!")) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - add_paper(I) - to_chat(user, SPAN_NOTICE("You put [I] in [src].")) + add_paper(used_item) + to_chat(user, SPAN_NOTICE("You put [used_item] in [src].")) return TRUE - else if(istype(I, /obj/item/paper_bundle)) + else if(istype(used_item, /obj/item/paper_bundle)) if(amount >= max_amount) to_chat(user, SPAN_WARNING("\The [src] is full!")) return TRUE - var/obj/item/paper_bundle/B = I + var/obj/item/paper_bundle/B = used_item var/was_there_a_photo = FALSE - for(var/obj/item/bundleitem in I) //loop through items in bundle + for(var/obj/item/bundleitem in used_item) //loop through items in bundle if(istype(bundleitem, /obj/item/paper)) //if item is paper, add into the bin LAZYREMOVE(B.pages, bundleitem) add_paper(bundleitem) @@ -96,7 +96,7 @@ was_there_a_photo = TRUE bundleitem.dropInto(user.loc) bundleitem.reset_plane_and_layer() - to_chat(user, SPAN_NOTICE("You loosen \the [I] and add its papers into \the [src].")) + to_chat(user, SPAN_NOTICE("You loosen \the [used_item] and add its papers into \the [src].")) B.reevaluate_existence() if(was_there_a_photo) to_chat(user, SPAN_NOTICE("The photo cannot go into \the [src].")) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 5d816b92448e..b0fbf90ee7a9 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -243,9 +243,9 @@ update_icon() return TRUE -/obj/machinery/photocopier/attackby(obj/item/O, mob/user) - if(istype(construct_state, /decl/machine_construction/default/panel_closed) && (istype(O, /obj/item/paper) || istype(O, /obj/item/photo) || istype(O, /obj/item/paper_bundle))) - insert_item(O, user) +/obj/machinery/photocopier/attackby(obj/item/used_item, mob/user) + if(istype(construct_state, /decl/machine_construction/default/panel_closed) && (istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo) || istype(used_item, /obj/item/paper_bundle))) + insert_item(used_item, user) return TRUE return..() //Components attackby will handle refilling with paper and toner diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index b6b39467524d..c23a21c46fb9 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -108,8 +108,8 @@ tiny.pixel_x = -WORLD_ICON_SIZE * (photo_size-1)/2 - 3 tiny.pixel_y = -WORLD_ICON_SIZE * (photo_size-1)/2 + 3 -/obj/item/photo/attackby(obj/item/P, mob/user) - if(IS_PEN(P)) +/obj/item/photo/attackby(obj/item/used_item, mob/user) + if(IS_PEN(used_item)) if(!CanPhysicallyInteractWith(user, src)) to_chat(user, SPAN_WARNING("You can't interact with this!")) return TRUE @@ -260,18 +260,18 @@ to_chat(user, SPAN_WARNING("There is no cartridge in \the [src] to eject!")) -/obj/item/camera/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/camera_film)) +/obj/item/camera/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/camera_film)) if(film) //Skilled people don't have to remove the film first! if(user.get_skill_value(SKILL_DEVICES) >= SKILL_EXPERT) if(user.do_skilled(1 SECONDS, SKILL_DEVICES, src)) user.visible_message( - SPAN_NOTICE("In a swift flick of the finger, [user] ejects \the [film], and slides in \the [I]!"), - SPAN_NOTICE("From habit you instinctively pop the old [film] from \the [src] and insert a new [I] deftly!")) - user.try_unequip(I, src) + SPAN_NOTICE("In a swift flick of the finger, [user] ejects \the [film], and slides in \the [used_item]!"), + SPAN_NOTICE("From habit you instinctively pop the old [film] from \the [src] and insert a new [used_item] deftly!")) + user.try_unequip(used_item, src) user.put_in_active_hand(film) - film = I + film = used_item return TRUE return TRUE //Unskilled losers have to remove it first @@ -281,14 +281,14 @@ if(user.do_skilled(1 SECONDS, SKILL_DEVICES, src)) if(user.get_skill_value(SKILL_DEVICES) >= SKILL_EXPERT) user.visible_message( - SPAN_NOTICE("[user] swiftly slides \the [I] into \the [src]!"), - SPAN_NOTICE("You insert \a [I] swiftly into \the [src]!")) + SPAN_NOTICE("[user] swiftly slides \the [used_item] into \the [src]!"), + SPAN_NOTICE("You insert \a [used_item] swiftly into \the [src]!")) else user.visible_message( - SPAN_NOTICE("[user] inserts \a [I] into his [src]."), - SPAN_NOTICE("You insert \the [I] into \the [src].")) - user.try_unequip(I, src) - film = I + SPAN_NOTICE("[user] inserts \a [used_item] into his [src]."), + SPAN_NOTICE("You insert \the [used_item] into \the [src].")) + user.try_unequip(used_item, src) + film = used_item return TRUE return TRUE return ..() diff --git a/code/modules/persistence/graffiti.dm b/code/modules/persistence/graffiti.dm index 050fa7ffc267..cb65ce6ca0c3 100644 --- a/code/modules/persistence/graffiti.dm +++ b/code/modules/persistence/graffiti.dm @@ -37,18 +37,18 @@ if(processed_message) . += "It reads \"[processed_message]\"." -/obj/effect/decal/writing/attackby(var/obj/item/thing, var/mob/user) - if(IS_WELDER(thing) && thing.do_tool_interaction(TOOL_WELDER, user, src, 3 SECONDS)) +/obj/effect/decal/writing/attackby(var/obj/item/used_item, var/mob/user) + if(IS_WELDER(used_item) && used_item.do_tool_interaction(TOOL_WELDER, user, src, 3 SECONDS)) playsound(src, 'sound/items/Welder2.ogg', 50, TRUE) user.visible_message(SPAN_NOTICE("\The [user] clears away some graffiti.")) qdel(src) return TRUE - else if(thing.is_sharp() && !user.check_intent(I_FLAG_HELP)) //Check intent so you don't go insane trying to unscrew a light fixture over a graffiti + else if(used_item.is_sharp() && !user.check_intent(I_FLAG_HELP)) //Check intent so you don't go insane trying to unscrew a light fixture over a graffiti if(jobban_isbanned(user, "Graffiti")) to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) return TRUE var/turf/T = get_turf(src) if(T) - T.try_graffiti(user, thing) + T.try_graffiti(user, used_item) return TRUE return ..() diff --git a/code/modules/persistence/noticeboards.dm b/code/modules/persistence/noticeboards.dm index 28a2f6479136..9ec2db2954f9 100644 --- a/code/modules/persistence/noticeboards.dm +++ b/code/modules/persistence/noticeboards.dm @@ -64,16 +64,16 @@ var/nb_notices = LAZYLEN(notices) icon_state = "[bis.base_icon_state][nb_notices > 0? "0[nb_notices]" : ""]" -/obj/structure/noticeboard/attackby(var/obj/item/thing, var/mob/user) - if(!istype(thing, /obj/item/paper/sticky) && (istype(thing, /obj/item/paper) || istype(thing, /obj/item/photo))) +/obj/structure/noticeboard/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/paper/sticky) && (istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo))) if(jobban_isbanned(user, "Graffiti")) to_chat(user, SPAN_WARNING("You are banned from leaving persistent information across rounds.")) - else if(LAZYLEN(notices) < max_notices && user.try_unequip(thing, src)) + else if(LAZYLEN(notices) < max_notices && user.try_unequip(used_item, src)) add_fingerprint(user) - add_paper(thing) - to_chat(user, SPAN_NOTICE("You pin \the [thing] to \the [src].")) + add_paper(used_item) + to_chat(user, SPAN_NOTICE("You pin \the [used_item] to \the [src].")) else - to_chat(user, SPAN_WARNING("You hesitate, certain \the [thing] will not be seen among the many others already attached to \the [src].")) + to_chat(user, SPAN_WARNING("You hesitate, certain \the [used_item] will not be seen among the many others already attached to \the [src].")) return TRUE return ..() diff --git a/code/modules/pointdefense/pointdefense.dm b/code/modules/pointdefense/pointdefense.dm index dfec4c84562a..ce55afe2f299 100644 --- a/code/modules/pointdefense/pointdefense.dm +++ b/code/modules/pointdefense/pointdefense.dm @@ -85,8 +85,8 @@ data["turrets"] = turrets return data -/obj/machinery/pointdefense_control/attackby(var/obj/item/thing, var/mob/user) - if(IS_MULTITOOL(thing)) +/obj/machinery/pointdefense_control/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/pointdefense = get_extension(src, /datum/extension/local_network_member) pointdefense.get_new_tag(user) //Check if there is more than 1 controller @@ -137,8 +137,8 @@ new_dir = SOUTH . = ..() -/obj/machinery/pointdefense/attackby(var/obj/item/thing, var/mob/user) - if(IS_MULTITOOL(thing)) +/obj/machinery/pointdefense/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/pointdefense = get_extension(src, /datum/extension/local_network_member) pointdefense.get_new_tag(user) return TRUE diff --git a/code/modules/power/floorlamp.dm b/code/modules/power/floorlamp.dm index 62d4208e5905..067ee2b484be 100644 --- a/code/modules/power/floorlamp.dm +++ b/code/modules/power/floorlamp.dm @@ -18,15 +18,15 @@ base_state = "flamp" . = ..() -/obj/machinery/light/flamp/attackby(obj/item/held_item, mob/user) +/obj/machinery/light/flamp/attackby(obj/item/used_item, mob/user) if(!lampshade) - if(istype(held_item, /obj/item/lampshade)) - lampshade = held_item - user.drop_from_inventory(held_item, src) + if(istype(used_item, /obj/item/lampshade)) + lampshade = used_item + user.drop_from_inventory(used_item, src) update_light_status(FALSE) update_icon() return TRUE - else if(held_item.do_tool_interaction(TOOL_SCREWDRIVER, user, src, 1 SECOND, "unscrewing", "unscrewing")) + else if(used_item.do_tool_interaction(TOOL_SCREWDRIVER, user, src, 1 SECOND, "unscrewing", "unscrewing")) lampshade.dropInto(loc) lampshade = null update_light_status(FALSE) diff --git a/code/modules/power/fuel_assembly/fuel_compressor.dm b/code/modules/power/fuel_assembly/fuel_compressor.dm index 0488d360f935..ea91578156ca 100644 --- a/code/modules/power/fuel_assembly/fuel_compressor.dm +++ b/code/modules/power/fuel_assembly/fuel_compressor.dm @@ -116,8 +116,8 @@ return return !add_material(dropping, user) -/obj/machinery/fuel_compressor/attackby(var/obj/item/thing, var/mob/user) - return add_material(thing, user) || ..() +/obj/machinery/fuel_compressor/attackby(var/obj/item/used_item, var/mob/user) + return add_material(used_item, user) || ..() /obj/machinery/fuel_compressor/proc/add_material(var/obj/item/thing, var/mob/user) if(istype(thing) && thing.reagents && thing.reagents.total_volume && ATOM_IS_OPEN_CONTAINER(thing)) diff --git a/code/modules/power/fusion/consoles/_consoles.dm b/code/modules/power/fusion/consoles/_consoles.dm index f6e16cfae341..c5bae885e06c 100644 --- a/code/modules/power/fusion/consoles/_consoles.dm +++ b/code/modules/power/fusion/consoles/_consoles.dm @@ -22,8 +22,8 @@ var/datum/extension/local_network_member/fusion = get_extension(src, /datum/extension/local_network_member) return fusion.get_local_network() -/obj/machinery/computer/fusion/attackby(var/obj/item/thing, var/mob/user) - if(IS_MULTITOOL(thing)) +/obj/machinery/computer/fusion/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/fusion = get_extension(src, /datum/extension/local_network_member) fusion.get_new_tag(user) return TRUE diff --git a/code/modules/power/fusion/kinetic_harvester.dm b/code/modules/power/fusion/kinetic_harvester.dm index d866bf68034a..51d150e0c8d0 100644 --- a/code/modules/power/fusion/kinetic_harvester.dm +++ b/code/modules/power/fusion/kinetic_harvester.dm @@ -32,8 +32,8 @@ ui_interact(user) return TRUE -/obj/machinery/kinetic_harvester/attackby(var/obj/item/thing, var/mob/user) - if(IS_MULTITOOL(thing)) +/obj/machinery/kinetic_harvester/attackby(var/obj/item/used_item, var/mob/user) + if(IS_MULTITOOL(used_item)) var/datum/extension/local_network_member/lanm = get_extension(src, /datum/extension/local_network_member) if(lanm.get_new_tag(user)) find_core() diff --git a/code/modules/power/heavycable.dm b/code/modules/power/heavycable.dm index b0a37913ceb3..ed452d7e1fb8 100644 --- a/code/modules/power/heavycable.dm +++ b/code/modules/power/heavycable.dm @@ -16,16 +16,16 @@ can_have_color = FALSE #define IS_TOOL_WITH_QUALITY(A, T, Q) (isatom(A) && A.get_tool_quality(T) >= Q) -/obj/structure/cable/heavyduty/attackby(obj/item/item, mob/user) - if(IS_WIRECUTTER(item)) +/obj/structure/cable/heavyduty/attackby(obj/item/used_item, mob/user) + if(IS_WIRECUTTER(used_item)) // Must be cut with power tools like the hydraulic clamp. - if(IS_TOOL_WITH_QUALITY(item, TOOL_WIRECUTTERS, TOOL_QUALITY_GOOD)) - cut_wire(item, user) + if(IS_TOOL_WITH_QUALITY(used_item, TOOL_WIRECUTTERS, TOOL_QUALITY_GOOD)) + cut_wire(used_item, user) else - to_chat(user, SPAN_WARNING("\The [item] isn't strong enough to cut \the [src].")) + to_chat(user, SPAN_WARNING("\The [used_item] isn't strong enough to cut \the [src].")) return TRUE - if(istype(item, /obj/item/stack/cable_coil) && !istype(item, /obj/item/stack/cable_coil/heavyduty)) - to_chat(user, SPAN_WARNING("\The [item] isn't heavy enough to connect to \the [src].")) + if(istype(used_item, /obj/item/stack/cable_coil) && !istype(used_item, /obj/item/stack/cable_coil/heavyduty)) + to_chat(user, SPAN_WARNING("\The [used_item] isn't heavy enough to connect to \the [src].")) return TRUE return ..() diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 419650f03819..f826967278a5 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -164,9 +164,9 @@ _state = "[base_state]_broken" if(istype(lightbulb, /obj/item/light)) - var/image/I = image(icon, _state) - I.color = get_mode_color() - add_overlay(I) + var/image/overlay_image = image(icon, _state) + overlay_image.color = get_mode_color() + add_overlay(overlay_image) if(on) compile_overlays() // force a compile so that we update prior to the light being set @@ -591,10 +591,10 @@ // attack bulb/tube with object // if a syringe, can inject flammable liquids to make it explode -/obj/item/light/attackby(var/obj/item/I, var/mob/user) +/obj/item/light/attackby(var/obj/item/used_item, var/mob/user) ..() - if(istype(I, /obj/item/chems/syringe) && I.reagents?.total_volume) - var/obj/item/chems/syringe/S = I + if(istype(used_item, /obj/item/chems/syringe) && used_item.reagents?.total_volume) + var/obj/item/chems/syringe/S = used_item to_chat(user, "You inject the solution into \the [src].") for(var/rtype in S.reagents?.reagent_volumes) var/decl/material/R = GET_DECL(rtype) diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index e10a4f9c6d13..058d9aef597a 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -300,9 +300,9 @@ return SPAN_WARNING("You cannot do this while \the [src] is running!") return ..() -/obj/machinery/port_gen/pacman/attackby(var/obj/item/O, var/mob/user) - if(istype(O, sheet_path) && (isnull(sheet_material) || sheet_material == O.get_material_type())) - var/obj/item/stack/addstack = O +/obj/machinery/port_gen/pacman/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, sheet_path) && (isnull(sheet_material) || sheet_material == used_item.get_material_type())) + var/obj/item/stack/addstack = used_item var/amount = min((max_sheets - sheets), addstack.amount) if(amount < 1) to_chat(user, "\The [src] is full!") @@ -312,7 +312,7 @@ addstack.use(amount) updateUsrDialog() return TRUE - if(IS_WRENCH(O) && !active) + if(IS_WRENCH(used_item) && !active) if(!anchored) to_chat(user, "You secure \the [src] to the floor.") else @@ -321,7 +321,7 @@ playsound(src.loc, 'sound/items/Deconstruct.ogg', 50, 1) anchored = !anchored return TRUE - return component_attackby(O, user) + return component_attackby(used_item, user) /obj/machinery/port_gen/pacman/dismantle() while (sheets > 0) @@ -485,9 +485,9 @@ if(power_output > max_safe_output) icon_state = "potatodanger" -/obj/machinery/port_gen/pacman/super/potato/attackby(var/obj/item/hit_with, var/mob/user) - if(istype(hit_with, /obj/item/chems)) - var/obj/item/chems/chem_container = hit_with +/obj/machinery/port_gen/pacman/super/potato/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/chems)) + var/obj/item/chems/chem_container = used_item var/old_vodka_amount = REAGENT_VOLUME(reagents, /decl/material/liquid/alcohol/vodka) if(chem_container.standard_pour_into(src,user)) if(REAGENT_VOLUME(reagents, /decl/material/liquid/alcohol/vodka) > old_vodka_amount) // yay, booze! diff --git a/code/modules/projectiles/guns/launcher/foam_gun.dm b/code/modules/projectiles/guns/launcher/foam_gun.dm index d0933d5b31de..6a351feeda82 100644 --- a/code/modules/projectiles/guns/launcher/foam_gun.dm +++ b/code/modules/projectiles/guns/launcher/foam_gun.dm @@ -18,14 +18,14 @@ var/max_darts = 1 var/list/darts = new/list() -/obj/item/gun/launcher/foam/attackby(obj/item/I, mob/user) - if(!istype(I, /obj/item/foam_dart)) +/obj/item/gun/launcher/foam/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/foam_dart)) return ..() if(darts.len < max_darts) - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - darts += I - to_chat(user, SPAN_NOTICE("You slot \the [I] into \the [src].")) + darts += used_item + to_chat(user, SPAN_NOTICE("You slot \the [used_item] into \the [src].")) return TRUE else to_chat(user, SPAN_WARNING("\The [src] can hold no more darts.")) @@ -33,9 +33,9 @@ /obj/item/gun/launcher/foam/consume_next_projectile() if(darts.len) - var/obj/item/I = darts[1] - darts -= I - return I + var/obj/item/thing = darts[1] + darts -= thing + return thing return null /obj/item/gun/launcher/foam/CtrlAltClick(mob/user) diff --git a/code/modules/projectiles/guns/launcher/grenade_launcher.dm b/code/modules/projectiles/guns/launcher/grenade_launcher.dm index f2d830571f6d..1e1e7f0cda25 100644 --- a/code/modules/projectiles/guns/launcher/grenade_launcher.dm +++ b/code/modules/projectiles/guns/launcher/grenade_launcher.dm @@ -78,12 +78,11 @@ /obj/item/gun/launcher/grenade/attack_self(mob/user) pump(user) -/obj/item/gun/launcher/grenade/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/grenade)) - load(I, user) +/obj/item/gun/launcher/grenade/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/grenade)) + load(used_item, user) return TRUE - else - return ..() + return ..() /obj/item/gun/launcher/grenade/attack_hand(mob/user) if(!user.is_holding_offhand(src) || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) diff --git a/code/modules/projectiles/guns/launcher/rocket.dm b/code/modules/projectiles/guns/launcher/rocket.dm index 57b101eface7..5300df1294a4 100644 --- a/code/modules/projectiles/guns/launcher/rocket.dm +++ b/code/modules/projectiles/guns/launcher/rocket.dm @@ -22,12 +22,12 @@ if(distance <= 2) . += SPAN_NOTICE("[rockets.len]/[max_rockets] rocket\s.") -/obj/item/gun/launcher/rocket/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/ammo_casing/rocket)) +/obj/item/gun/launcher/rocket/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/ammo_casing/rocket)) if(rockets.len < max_rockets) - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - rockets += I + rockets += used_item to_chat(user, "You put the rocket in [src].") to_chat(user, "[rockets.len] / [max_rockets] rockets.") return TRUE @@ -38,10 +38,10 @@ /obj/item/gun/launcher/rocket/consume_next_projectile() if(rockets.len) - var/obj/item/ammo_casing/rocket/I = rockets[1] + var/obj/item/ammo_casing/rocket/rocket = rockets[1] var/obj/item/missile/M = new (src) M.primed = 1 - rockets -= I + rockets -= rocket return M return null diff --git a/code/modules/projectiles/guns/launcher/syringe_gun.dm b/code/modules/projectiles/guns/launcher/syringe_gun.dm index 02693dc1c5ff..3d1d65ad2847 100644 --- a/code/modules/projectiles/guns/launcher/syringe_gun.dm +++ b/code/modules/projectiles/guns/launcher/syringe_gun.dm @@ -24,11 +24,11 @@ MA.plane = FLOAT_PLANE underlays += MA -/obj/item/syringe_cartridge/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/chems/syringe)) - if(!user.try_unequip(I, src)) +/obj/item/syringe_cartridge/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/chems/syringe)) + if(!user.try_unequip(used_item, src)) return TRUE - syringe = I + syringe = used_item to_chat(user, "You carefully insert [syringe] into [src].") set_sharp(TRUE) name = "syringe dart" @@ -128,9 +128,9 @@ ) return TRUE -/obj/item/gun/launcher/syringe/attackby(var/obj/item/A, mob/user) - if(istype(A, /obj/item/syringe_cartridge)) - var/obj/item/syringe_cartridge/C = A +/obj/item/gun/launcher/syringe/attackby(var/obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/syringe_cartridge)) + var/obj/item/syringe_cartridge/C = used_item if(darts.len >= max_darts) to_chat(user, "[src] is full!") return TRUE diff --git a/code/modules/projectiles/guns/magnetic/magnetic.dm b/code/modules/projectiles/guns/magnetic/magnetic.dm index 7ebf59d143bd..43478d115947 100644 --- a/code/modules/projectiles/guns/magnetic/magnetic.dm +++ b/code/modules/projectiles/guns/magnetic/magnetic.dm @@ -98,10 +98,10 @@ else . += SPAN_NOTICE("The capacitor charge indicator is [SPAN_GREEN("green")].") -/obj/item/gun/magnetic/attackby(var/obj/item/thing, var/mob/user) +/obj/item/gun/magnetic/attackby(var/obj/item/used_item, var/mob/user) if(removable_components) - if(IS_SCREWDRIVER(thing)) + if(IS_SCREWDRIVER(used_item)) if(!capacitor) to_chat(user, "\The [src] has no capacitor installed.") return TRUE @@ -111,39 +111,39 @@ capacitor = null update_icon() return TRUE - if(istype(thing, /obj/item/stock_parts/capacitor)) + if(istype(used_item, /obj/item/stock_parts/capacitor)) if(capacitor) to_chat(user, "\The [src] already has \a [capacitor] installed.") return TRUE - if(!user.try_unequip(thing, src)) + if(!user.try_unequip(used_item, src)) return TRUE - capacitor = thing + capacitor = used_item playsound(loc, 'sound/machines/click.ogg', 10, 1) power_per_tick = (power_cost*0.15) * capacitor.rating user.visible_message("\The [user] slots \the [capacitor] into \the [src].") update_icon() return TRUE - if(!istype(thing, load_type)) + if(!istype(used_item, load_type)) return ..() // This is not strictly necessary for the magnetic gun but something using // specific ammo types may exist down the track. - var/obj/item/stack/ammo = thing + var/obj/item/stack/ammo = used_item if(!istype(ammo)) if(loaded) to_chat(user, "\The [src] already has \a [loaded] loaded.") return TRUE - var/obj/item/magnetic_ammo/mag = thing + var/obj/item/magnetic_ammo/mag = used_item if(istype(mag)) if(!(load_type == mag.basetype)) to_chat(user, "\The [src] doesn't seem to accept \a [mag].") return TRUE projectile_type = mag.projectile_type - if(!user.try_unequip(thing, src)) + if(!user.try_unequip(used_item, src)) return TRUE - loaded = thing + loaded = used_item else if(load_sheet_max > 1) var ammo_count = 0 var/obj/item/stack/loaded_ammo = loaded diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 86e54de2533c..1614d25961e8 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -96,10 +96,10 @@ . = ..() launcher = new(src) -/obj/item/gun/projectile/automatic/assault_rifle/grenade/attackby(obj/item/I, mob/user) - if(!istype(I, /obj/item/grenade)) +/obj/item/gun/projectile/automatic/assault_rifle/grenade/attackby(obj/item/used_item, mob/user) + if(!istype(used_item, /obj/item/grenade)) return ..() - launcher.load(I, user) + launcher.load(used_item, user) return TRUE /obj/item/gun/projectile/automatic/assault_rifle/grenade/attack_hand(mob/user) diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index 56ba8fb6d614..4888de9e105b 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -65,9 +65,9 @@ var/decl/material/R = GET_DECL(stype) . += SPAN_NOTICE("[SOLID_VOLUME(B.reagents, stype)] units of [R.get_reagent_name(B.reagents, MAT_PHASE_SOLID)]") -/obj/item/gun/projectile/dartgun/attackby(obj/item/I, mob/user) - if(istype(I, /obj/item/chems/glass)) - add_beaker(I, user) +/obj/item/gun/projectile/dartgun/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/chems/glass)) + add_beaker(used_item, user) return TRUE return ..() diff --git a/code/modules/projectiles/guns/projectile/shotgun.dm b/code/modules/projectiles/guns/projectile/shotgun.dm index 217d232ba35b..f0960ad6f4fc 100644 --- a/code/modules/projectiles/guns/projectile/shotgun.dm +++ b/code/modules/projectiles/guns/projectile/shotgun.dm @@ -80,10 +80,10 @@ return ..(user, allow_dump=1) //this is largely hacky and bad :( -Pete -/obj/item/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/A, mob/user) - if(w_class > ITEM_SIZE_NORMAL && A.get_tool_quality(TOOL_SAW) > 0) - if(istype(A, /obj/item/gun/energy/plasmacutter)) - var/obj/item/gun/energy/plasmacutter/cutter = A +/obj/item/gun/projectile/shotgun/doublebarrel/attackby(var/obj/item/used_item, mob/user) + if(w_class > ITEM_SIZE_NORMAL && used_item.get_tool_quality(TOOL_SAW) > 0) + if(istype(used_item, /obj/item/gun/energy/plasmacutter)) + var/obj/item/gun/energy/plasmacutter/cutter = used_item if(!cutter.slice(user)) return ..() to_chat(user, "You begin to shorten the barrel of \the [src].") diff --git a/code/modules/reagents/Chemistry-Grinder.dm b/code/modules/reagents/Chemistry-Grinder.dm index b798bf9e4e6d..e0f84a5350a6 100644 --- a/code/modules/reagents/Chemistry-Grinder.dm +++ b/code/modules/reagents/Chemistry-Grinder.dm @@ -41,23 +41,23 @@ else icon_state = "[initial(icon_state)]" -/obj/machinery/reagentgrinder/attackby(var/obj/item/O, var/mob/user) +/obj/machinery/reagentgrinder/attackby(var/obj/item/used_item, var/mob/user) if((. = ..())) return - if(!istype(O)) + if(!istype(used_item)) return FALSE - if (istype(O,/obj/item/chems/glass) || \ - istype(O,/obj/item/chems/drinks/glass2) || \ - istype(O,/obj/item/chems/drinks/shaker)) + if (istype(used_item,/obj/item/chems/glass) || \ + istype(used_item,/obj/item/chems/drinks/glass2) || \ + istype(used_item,/obj/item/chems/drinks/shaker)) if(beaker) return TRUE else - if(!user.try_unequip(O, src)) + if(!user.try_unequip(used_item, src)) return FALSE - beaker = O + beaker = used_item update_icon() SSnano.update_uis(src) return FALSE @@ -66,52 +66,52 @@ to_chat(user, SPAN_NOTICE("\The [src] cannot hold any additional items.")) return TRUE - if(is_type_in_list(O, blacklisted_types)) - to_chat(user, SPAN_NOTICE("\The [src] cannot grind \the [O].")) + if(is_type_in_list(used_item, blacklisted_types)) + to_chat(user, SPAN_NOTICE("\The [src] cannot grind \the [used_item].")) return FALSE - if(is_type_in_list(O, bag_whitelist)) - if(O.storage) + if(is_type_in_list(used_item, bag_whitelist)) + if(used_item.storage) var/failed = TRUE - for(var/obj/item/G in O) + for(var/obj/item/G in used_item) if(!G.reagents || !G.reagents.total_volume) continue failed = FALSE - O.storage.remove_from_storage(user, G, src) + used_item.storage.remove_from_storage(user, G, src) holdingitems += G if(LAZYLEN(holdingitems) >= limit) break if(failed) - to_chat(user, SPAN_NOTICE("Nothing in \the [O] is usable.")) + to_chat(user, SPAN_NOTICE("Nothing in \the [used_item] is usable.")) return TRUE - O.storage.finish_bulk_removal() + used_item.storage.finish_bulk_removal() - if(!length(O.contents)) - to_chat(user, "You empty \the [O] into \the [src].") + if(!length(used_item.contents)) + to_chat(user, "You empty \the [used_item] into \the [src].") else - to_chat(user, "You fill \the [src] from \the [O].") + to_chat(user, "You fill \the [src] from \the [used_item].") SSnano.update_uis(src) return FALSE - if(O.w_class > item_size_limit) - to_chat(user, SPAN_NOTICE("\The [src] cannot fit \the [O].")) + if(used_item.w_class > item_size_limit) + to_chat(user, SPAN_NOTICE("\The [src] cannot fit \the [used_item].")) return - if(istype(O,/obj/item/stack/material)) - var/decl/material/material = O.get_material() + if(istype(used_item,/obj/item/stack/material)) + var/decl/material/material = used_item.get_material() if(!material) to_chat(user, SPAN_NOTICE("\The [material.solid_name] cannot be ground down to any usable reagents.")) return TRUE - else if(!O.reagents?.total_volume) - to_chat(user, SPAN_NOTICE("\The [O] is not suitable for grinding.")) + else if(!used_item.reagents?.total_volume) + to_chat(user, SPAN_NOTICE("\The [used_item] is not suitable for grinding.")) return TRUE - if(!user.try_unequip(O, src)) + if(!user.try_unequip(used_item, src)) return FALSE - holdingitems += O + holdingitems += used_item SSnano.update_uis(src) return FALSE @@ -128,8 +128,8 @@ data["beaker"] = !!beaker data["contents"] = list() - for(var/obj/item/O in holdingitems) - data["contents"] += "[capitalize(O.name)]" + for(var/obj/item/thing in holdingitems) + data["contents"] += "[capitalize(thing.name)]" data["beakercontents"] = list() if(beaker?.reagents) @@ -171,9 +171,9 @@ if (!LAZYLEN(holdingitems)) return FALSE - for(var/obj/item/O in holdingitems) - O.dropInto(loc) - holdingitems -= O + for(var/obj/item/thing in holdingitems) + thing.dropInto(loc) + holdingitems -= thing holdingitems.Cut() /obj/machinery/reagentgrinder/proc/grind(mob/user) @@ -196,13 +196,13 @@ var/skill_factor = CLAMP01(1 + 0.3*(user.get_skill_value(skill_to_check) - SKILL_EXPERT)/(SKILL_EXPERT - SKILL_MIN)) // Process. - for (var/obj/item/O in holdingitems) + for (var/obj/item/thing in holdingitems) var/remaining_volume = beaker.reagents.maximum_volume - beaker.reagents.total_volume if(remaining_volume <= 0) break - var/obj/item/stack/material/stack = O + var/obj/item/stack/material/stack = thing if(istype(stack)) var/decl/material/material = stack.get_material() if(!material) @@ -216,10 +216,10 @@ beaker.add_to_reagents(material.type, (amount_to_take * REAGENT_UNITS_PER_MATERIAL_SHEET * skill_factor)) continue - else if(O.reagents) - O.reagents.trans_to(beaker, O.reagents.total_volume, skill_factor) - holdingitems -= O - qdel(O) + else if(thing.reagents) + thing.reagents.trans_to(beaker, thing.reagents.total_volume, skill_factor) + holdingitems -= thing + qdel(thing) /obj/machinery/reagentgrinder/proc/end_grind(mob/user) inuse = FALSE diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index d7c1f8cc4081..d603217b54df 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -38,33 +38,33 @@ /obj/machinery/chem_master/proc/get_remaining_volume() return clamp(reagent_limit - reagents.total_volume, 0, reagent_limit) -/obj/machinery/chem_master/attackby(var/obj/item/B, var/mob/user) +/obj/machinery/chem_master/attackby(var/obj/item/used_item, var/mob/user) - if(istype(B, /obj/item/chems/glass)) + if(istype(used_item, /obj/item/chems/glass)) if(beaker) to_chat(user, SPAN_WARNING("A beaker is already loaded into the machine.")) return TRUE - if(!user.try_unequip(B, src)) + if(!user.try_unequip(used_item, src)) return TRUE - beaker = B + beaker = used_item to_chat(user, SPAN_NOTICE("You add the beaker to the machine!")) updateUsrDialog() icon_state = "mixer1" return TRUE - if(istype(B, /obj/item/chems)) + if(istype(used_item, /obj/item/chems)) to_chat(user, SPAN_WARNING("\The [src] will only accept beakers.")) return TRUE - if(istype(B, /obj/item/pill_bottle)) + if(istype(used_item, /obj/item/pill_bottle)) if(loaded_pill_bottle) to_chat(user, SPAN_WARNING("A pill bottle is already loaded into the machine.")) return TRUE - if(!user.try_unequip(B, src)) + if(!user.try_unequip(used_item, src)) return TRUE - loaded_pill_bottle = B + loaded_pill_bottle = used_item to_chat(user, SPAN_NOTICE("You add the pill bottle into the dispenser slot!")) updateUsrDialog() return TRUE diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/dispenser/dispenser2.dm index 696dab904873..0b3c8f7e0d56 100644 --- a/code/modules/reagents/dispenser/dispenser2.dm +++ b/code/modules/reagents/dispenser/dispenser2.dm @@ -86,12 +86,12 @@ cartridges -= label SSnano.update_uis(src) -/obj/machinery/chemical_dispenser/attackby(obj/item/hit_with, mob/user) - if(istype(hit_with, /obj/item/chems/chem_disp_cartridge)) - add_cartridge(hit_with, user) +/obj/machinery/chemical_dispenser/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/chems/chem_disp_cartridge)) + add_cartridge(used_item, user) return TRUE - if(IS_CROWBAR(hit_with) && !panel_open && length(cartridges)) + if(IS_CROWBAR(used_item) && !panel_open && length(cartridges)) var/label = input(user, "Which cartridge would you like to remove?", "Chemical Dispenser") as null|anything in cartridges if(!label) return TRUE var/obj/item/chems/chem_disp_cartridge/C = remove_cartridge(label) @@ -100,12 +100,12 @@ C.dropInto(loc) return TRUE - if(is_type_in_list(hit_with, acceptable_containers)) + if(is_type_in_list(used_item, acceptable_containers)) if(container) to_chat(user, SPAN_WARNING("There is already \a [container] on \the [src]!")) return TRUE - var/obj/item/chems/new_container = hit_with + var/obj/item/chems/new_container = used_item if(!accept_drinking && (istype(new_container,/obj/item/chems/condiment) || istype(new_container,/obj/item/chems/drinks))) to_chat(user, SPAN_WARNING("This machine only accepts beakers!")) diff --git a/code/modules/reagents/heat_sources/_heat_source.dm b/code/modules/reagents/heat_sources/_heat_source.dm index eb5b3cebf445..c732465fab3f 100644 --- a/code/modules/reagents/heat_sources/_heat_source.dm +++ b/code/modules/reagents/heat_sources/_heat_source.dm @@ -90,16 +90,16 @@ return TRUE // Don't kill this processing loop unless we're not powered. . = ..() -/obj/machinery/reagent_temperature/attackby(var/obj/item/thing, var/mob/user) +/obj/machinery/reagent_temperature/attackby(var/obj/item/used_item, var/mob/user) - if(istype(thing, /obj/item/chems/cooking_vessel)) - if(!user.try_unequip(thing, get_turf(src))) + if(istype(used_item, /obj/item/chems/cooking_vessel)) + if(!user.try_unequip(used_item, get_turf(src))) return TRUE - thing.reset_offsets(anim_time = 0) - user.visible_message(SPAN_NOTICE("\The [user] places \the [thing] onto \the [src].")) + used_item.reset_offsets(anim_time = 0) + user.visible_message(SPAN_NOTICE("\The [user] places \the [used_item] onto \the [src].")) return TRUE - if(IS_WRENCH(thing)) + if(IS_WRENCH(used_item)) if(use_power == POWER_USE_ACTIVE) to_chat(user, SPAN_WARNING("Turn \the [src] off first!")) else @@ -108,18 +108,18 @@ playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) return TRUE - if(thing.reagents) + if(used_item.reagents) for(var/checktype in permitted_types) - if(istype(thing, checktype)) + if(istype(used_item, checktype)) if(container) to_chat(user, SPAN_WARNING("\The [src] is already holding \the [container].")) - else if(user.try_unequip(thing)) - thing.forceMove(src) - container = thing + else if(user.try_unequip(used_item)) + used_item.forceMove(src) + container = used_item visible_message(SPAN_NOTICE("\The [user] places \the [container] on \the [src].")) update_icon() return TRUE - to_chat(user, SPAN_WARNING("\The [src] cannot accept \the [thing].")) + to_chat(user, SPAN_WARNING("\The [src] cannot accept \the [used_item].")) return FALSE . = ..() diff --git a/code/modules/reagents/reagent_containers/bucket.dm b/code/modules/reagents/reagent_containers/bucket.dm index 8ff3971d56fc..2a3dd2a016eb 100644 --- a/code/modules/reagents/reagent_containers/bucket.dm +++ b/code/modules/reagents/reagent_containers/bucket.dm @@ -28,16 +28,16 @@ /obj/item/chems/glass/bucket/get_utensil_food_type() return null -/obj/item/chems/glass/bucket/attackby(var/obj/D, mob/user) - if(istype(D, /obj/item/mop)) +/obj/item/chems/glass/bucket/attackby(var/obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/mop)) if(reagents.total_volume < 1) to_chat(user, SPAN_WARNING("\The [src] is empty!")) - else if(REAGENTS_FREE_SPACE(D.reagents) >= 5) - reagents.trans_to_obj(D, 5) - to_chat(user, SPAN_NOTICE("You wet \the [D] in \the [src].")) + else if(REAGENTS_FREE_SPACE(used_item.reagents) >= 5) + reagents.trans_to_obj(used_item, 5) + to_chat(user, SPAN_NOTICE("You wet \the [used_item] in \the [src].")) playsound(loc, 'sound/effects/slosh.ogg', 25, 1) else - to_chat(user, SPAN_WARNING("\The [D] is saturated.")) + to_chat(user, SPAN_WARNING("\The [used_item] is saturated.")) return TRUE return ..() diff --git a/code/modules/reagents/reagent_containers/drinkingglass/extras.dm b/code/modules/reagents/reagent_containers/drinkingglass/extras.dm index 0372bc390fba..28a956f1f11d 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/extras.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/extras.dm @@ -1,8 +1,8 @@ -/obj/item/chems/drinks/glass2/attackby(obj/item/I, mob/user) +/obj/item/chems/drinks/glass2/attackby(obj/item/used_item, mob/user) if(extras.len >= 2) return ..() // max 2 extras, one on each side of the drink - if(istype(I, /obj/item/glass_extra)) - var/obj/item/glass_extra/GE = I + if(istype(used_item, /obj/item/glass_extra)) + var/obj/item/glass_extra/GE = used_item if(!can_add_extra(GE)) to_chat(user, "There's no space to put \the [GE] on \the [src]!") return TRUE @@ -12,11 +12,11 @@ to_chat(user, "You add \the [GE] to \the [src].") update_icon() return TRUE - else if(istype(I, /obj/item/food/processed_grown/slice)) + else if(istype(used_item, /obj/item/food/processed_grown/slice)) if(!rim_pos) - to_chat(user, "There's no space to put \the [I] on \the [src]!") + to_chat(user, "There's no space to put \the [used_item] on \the [src]!") return TRUE - var/obj/item/food/processed_grown/slice/FS = I + var/obj/item/food/processed_grown/slice/FS = used_item extras += FS if(!user.try_unequip(FS, src)) return TRUE diff --git a/code/modules/reagents/reagent_containers/food/fish.dm b/code/modules/reagents/reagent_containers/food/fish.dm index fd8ec91188e0..5b6534e4e54c 100644 --- a/code/modules/reagents/reagent_containers/food/fish.dm +++ b/code/modules/reagents/reagent_containers/food/fish.dm @@ -69,9 +69,9 @@ user.put_in_hands(shell) qdel(src) -/obj/item/mollusc/attackby(var/obj/item/thing, var/mob/user) - if(thing.is_sharp() || thing.has_edge()) - user.visible_message(SPAN_NOTICE("\The [user] cracks open \the [src] with \the [thing].")) +/obj/item/mollusc/attackby(var/obj/item/used_item, var/mob/user) + if(used_item.is_sharp() || used_item.has_edge()) + user.visible_message(SPAN_NOTICE("\The [user] cracks open \the [src] with \the [used_item].")) crack_shell(user) return TRUE . = ..() diff --git a/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_box.dm b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_box.dm index 6c6cf548fe68..759e2fd3b7c6 100644 --- a/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_box.dm +++ b/code/modules/reagents/reagent_containers/food/sliceable/pizza/pizza_box.dm @@ -35,11 +35,11 @@ if(overlay && length(stacked_boxes)) var/i = 1 for(var/obj/item/pizzabox/box in stacked_boxes) - var/image/I = box.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) - if(I) - I.pixel_y = i * 3 - I.pixel_x = pick(-1,0,1) - overlay.overlays += I + var/image/overlay_image = box.get_mob_overlay(user_mob, slot, bodypart, use_fallback_if_icon_missing, TRUE) + if(overlay_image) + overlay_image.pixel_y = i * 3 + overlay_image.pixel_x = pick(-1,0,1) + overlay.overlays += overlay_image i++ . = ..() @@ -220,11 +220,11 @@ return TRUE return ..() -/obj/item/pizzabox/attackby(obj/item/I, mob/user) +/obj/item/pizzabox/attackby(obj/item/used_item, mob/user) // Stacking pizza boxes. - if(istype(I, /obj/item/pizzabox)) - var/obj/item/pizzabox/box = I + if(istype(used_item, /obj/item/pizzabox)) + var/obj/item/pizzabox/box = used_item if(box.open) to_chat(user, SPAN_WARNING("You need to close \the [box] first!")) return TRUE @@ -257,7 +257,7 @@ return TRUE // Putting a pizza back in the box. - if(istype(I, /obj/item/food/sliceable/pizza)) + if(istype(used_item, /obj/item/food/sliceable/pizza)) if(!open) to_chat(user, SPAN_WARNING("Open \the [src] first!")) @@ -267,17 +267,17 @@ to_chat(user, SPAN_WARNING("\The [src] already has \the [pizza] inside!")) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - pizza = I + pizza = used_item update_strings() update_icon() - user.visible_message(SPAN_NOTICE("\The [user] slides \the [I] into \the [src].")) + user.visible_message(SPAN_NOTICE("\The [user] slides \the [used_item] into \the [src].")) return TRUE // Appending to the tag. - if(IS_PEN(I)) + if(IS_PEN(used_item)) if(open) to_chat(user, SPAN_WARNING("Close \the [src] first!")) @@ -290,7 +290,7 @@ var/box_count = LAZYLEN(stacked_boxes) var/obj/item/pizzabox/tagging_box = (box_count > 0) ? stacked_boxes[box_count] : src tagging_box.box_tag = copytext("[tagging_box.box_tag][tag_string]", 1, 30) - tagging_box.box_tag_color = I.get_tool_property(TOOL_PEN, TOOL_PROP_COLOR) || COLOR_BLACK + tagging_box.box_tag_color = used_item.get_tool_property(TOOL_PEN, TOOL_PROP_COLOR) || COLOR_BLACK user.visible_message(SPAN_NOTICE("\The [user] writes something on \the [src].")) update_strings() update_icon() diff --git a/code/modules/reagents/reagent_containers/food/sushi.dm b/code/modules/reagents/reagent_containers/food/sushi.dm index 4941b2aabedc..afb648168a04 100644 --- a/code/modules/reagents/reagent_containers/food/sushi.dm +++ b/code/modules/reagents/reagent_containers/food/sushi.dm @@ -82,34 +82,34 @@ adding += image(icon = icon, icon_state = "sashimi", pixel_x = offset, pixel_y = offset) add_overlay(adding) -/obj/item/food/sashimi/attackby(var/obj/item/I, var/mob/user) +/obj/item/food/sashimi/attackby(var/obj/item/used_item, var/mob/user) if(!(locate(/obj/structure/table) in loc)) return ..() // Add more slices. - if(istype(I, /obj/item/food/sashimi)) - var/obj/item/food/sashimi/other_sashimi = I + if(istype(used_item, /obj/item/food/sashimi)) + var/obj/item/food/sashimi/other_sashimi = used_item if(slices + other_sashimi.slices > 5) to_chat(user, "Show some restraint, would you?") return TRUE - if(!user.try_unequip(I)) + if(!user.try_unequip(used_item)) return TRUE slices += other_sashimi.slices bitesize = slices update_icon() - if(I.reagents) - I.reagents.trans_to(src, I.reagents.total_volume) - qdel(I) + if(used_item.reagents) + used_item.reagents.trans_to(src, used_item.reagents.total_volume) + qdel(used_item) return TRUE // Make sushi. - if(istype(I, /obj/item/food/boiledrice)) + if(istype(used_item, /obj/item/food/boiledrice)) if(slices > 1) to_chat(user, "Putting more than one slice of fish on your sushi is just greedy.") else - if(!user.try_unequip(I)) + if(!user.try_unequip(used_item)) return TRUE - new /obj/item/food/sushi(get_turf(src), null, TRUE, I, src) + new /obj/item/food/sushi(get_turf(src), null, TRUE, used_item, src) return TRUE . = ..() @@ -125,14 +125,14 @@ meat.set_meat_name(fish_type) // Used for turning rice into sushi. -/obj/item/food/boiledrice/attackby(var/obj/item/I, var/mob/user) +/obj/item/food/boiledrice/attackby(var/obj/item/used_item, var/mob/user) if((locate(/obj/structure/table) in loc)) - if(istype(I, /obj/item/food/sashimi)) - var/obj/item/food/sashimi/sashimi = I + if(istype(used_item, /obj/item/food/sashimi)) + var/obj/item/food/sashimi/sashimi = used_item if(sashimi.slices > 1) to_chat(user, "Putting more than one slice of fish on your sushi is just greedy.") else - new /obj/item/food/sushi(get_turf(src), null, TRUE, src, I) + new /obj/item/food/sushi(get_turf(src), null, TRUE, src, used_item) return TRUE var/static/list/sushi_types = list( /obj/item/food/friedegg, @@ -142,30 +142,30 @@ /obj/item/food/spider, /obj/item/food/butchery/meat/chicken ) - if(is_type_in_list(I, sushi_types)) - new /obj/item/food/sushi(get_turf(src), null, TRUE, src, I) + if(is_type_in_list(used_item, sushi_types)) + new /obj/item/food/sushi(get_turf(src), null, TRUE, src, used_item) return TRUE . = ..() // Used for turning other food into sushi. // TODO: maybe make these resolve_attackby overrides on boiledrice instead? -/obj/item/food/friedegg/attackby(var/obj/item/I, var/mob/user) - if((locate(/obj/structure/table) in loc) && istype(I, /obj/item/food/boiledrice)) - new /obj/item/food/sushi(get_turf(src), null, TRUE, I, src) +/obj/item/food/friedegg/attackby(var/obj/item/used_item, var/mob/user) + if((locate(/obj/structure/table) in loc) && istype(used_item, /obj/item/food/boiledrice)) + new /obj/item/food/sushi(get_turf(src), null, TRUE, used_item, src) return TRUE . = ..() -/obj/item/food/tofu/attackby(var/obj/item/I, var/mob/user) - if((locate(/obj/structure/table) in loc) && istype(I, /obj/item/food/boiledrice)) - new /obj/item/food/sushi(get_turf(src), null, TRUE, I, src) +/obj/item/food/tofu/attackby(var/obj/item/used_item, var/mob/user) + if((locate(/obj/structure/table) in loc) && istype(used_item, /obj/item/food/boiledrice)) + new /obj/item/food/sushi(get_turf(src), null, TRUE, used_item, src) return TRUE . = ..() -/obj/item/food/butchery/cutlet/raw/attackby(var/obj/item/I, var/mob/user) - if((locate(/obj/structure/table) in loc) && istype(I, /obj/item/food/boiledrice)) - new /obj/item/food/sushi(get_turf(src), null, TRUE, I, src) +/obj/item/food/butchery/cutlet/raw/attackby(var/obj/item/used_item, var/mob/user) + if((locate(/obj/structure/table) in loc) && istype(used_item, /obj/item/food/boiledrice)) + new /obj/item/food/sushi(get_turf(src), null, TRUE, used_item, src) return TRUE . = ..() -/obj/item/food/butchery/cutlet/attackby(var/obj/item/I, var/mob/user) - if((locate(/obj/structure/table) in loc) && istype(I, /obj/item/food/boiledrice)) - new /obj/item/food/sushi(get_turf(src), null, TRUE, I, src) +/obj/item/food/butchery/cutlet/attackby(var/obj/item/used_item, var/mob/user) + if((locate(/obj/structure/table) in loc) && istype(used_item, /obj/item/food/boiledrice)) + new /obj/item/food/sushi(get_turf(src), null, TRUE, used_item, src) return TRUE . = ..() // End non-fish sushi. diff --git a/code/modules/reagents/reagent_containers/inhaler.dm b/code/modules/reagents/reagent_containers/inhaler.dm index 69bd0710eaec..7408e7545d33 100644 --- a/code/modules/reagents/reagent_containers/inhaler.dm +++ b/code/modules/reagents/reagent_containers/inhaler.dm @@ -101,9 +101,9 @@ to_chat(user, SPAN_NOTICE("The reagents inside \the [src] are already secured.")) return TRUE -/obj/item/chems/inhaler/attackby(obj/item/tool, mob/user) - if(IS_SCREWDRIVER(tool) && !ATOM_IS_OPEN_CONTAINER(src)) - to_chat(user, SPAN_NOTICE("Using \the [tool], you unsecure the inhaler's lid.")) // it locks shut after being secured +/obj/item/chems/inhaler/attackby(obj/item/used_item, mob/user) + if(IS_SCREWDRIVER(used_item) && !ATOM_IS_OPEN_CONTAINER(src)) + to_chat(user, SPAN_NOTICE("Using \the [used_item], you unsecure the inhaler's lid.")) // it locks shut after being secured atom_flags |= ATOM_FLAG_OPEN_CONTAINER update_icon() return TRUE diff --git a/code/modules/reagents/reagent_containers/mortar.dm b/code/modules/reagents/reagent_containers/mortar.dm index edff209c0810..5df6aa94e4c8 100644 --- a/code/modules/reagents/reagent_containers/mortar.dm +++ b/code/modules/reagents/reagent_containers/mortar.dm @@ -10,16 +10,16 @@ var/grinding = FALSE // todo: generalize to use TOOL_PESTLE -/obj/item/chems/glass/mortar/attackby(obj/item/using_item, mob/living/user) +/obj/item/chems/glass/mortar/attackby(obj/item/used_item, mob/living/user) if((. = ..())) return - return try_grind(using_item, user) + return try_grind(used_item, user) /obj/item/chems/glass/mortar/can_lid() return FALSE -/obj/item/chems/glass/mortar/proc/try_grind(obj/item/using_item, mob/living/user) - if(!istype(using_item)) +/obj/item/chems/glass/mortar/proc/try_grind(obj/item/used_item, mob/living/user) + if(!istype(used_item)) return FALSE if(!CanPhysicallyInteract(user) || !user.check_dexterity(DEXTERITY_HOLD_ITEM)) return TRUE @@ -28,13 +28,13 @@ return TRUE var/list/contained_atoms = get_stored_inventory() var/obj/item/crushing_item = LAZYACCESS(contained_atoms, 1) - var/decl/material/attacking_material = using_item.get_material() + var/decl/material/attacking_material = used_item.get_material() var/decl/material/crushing_material = crushing_item?.get_material() var/skill_factor = CLAMP01(1 + 0.3*(user.get_skill_value(SKILL_CHEMISTRY) - SKILL_EXPERT)/(SKILL_EXPERT - SKILL_MIN)) - if(using_item.expend_attack_force(user) <= 0 || !attacking_material || !crushing_material) + if(used_item.expend_attack_force(user) <= 0 || !attacking_material || !crushing_material) return TRUE if(attacking_material.hardness <= crushing_material.hardness) - to_chat(user, SPAN_NOTICE("\The [using_item] is not hard enough to crush \the [crushing_item].")) + to_chat(user, SPAN_NOTICE("\The [used_item] is not hard enough to crush \the [crushing_item].")) return TRUE if(REAGENTS_FREE_SPACE(reagents) < crushing_item.reagents.total_volume) to_chat(user, SPAN_WARNING("\The [src] is too full to grind \the [crushing_item], it'd spill everywhere!")) @@ -47,7 +47,7 @@ if(user.get_stamina() < stamina_to_consume) to_chat(user, SPAN_WARNING("You are too tired to crush \the [crushing_item], take a break!")) return TRUE - to_chat(user, SPAN_NOTICE("You start grinding \the [crushing_item] with \the [using_item].")) + to_chat(user, SPAN_NOTICE("You start grinding \the [crushing_item] with \the [used_item].")) grinding = TRUE if(!do_after(user, stamina_to_consume SECONDS)) to_chat(user, SPAN_NOTICE("You stop grinding \the [crushing_item].")) @@ -58,9 +58,9 @@ return TRUE // already been ground! user.adjust_stamina(-stamina_to_consume) crushing_item.reagents.trans_to(src, crushing_item.reagents.total_volume, skill_factor) - to_chat(user, SPAN_NOTICE("You finish grinding \the [crushing_item] with \the [using_item].")) + to_chat(user, SPAN_NOTICE("You finish grinding \the [crushing_item] with \the [used_item].")) QDEL_NULL(crushing_item) // If there's more to crush, try looping if(length(get_stored_inventory()) > 0) - try_grind(using_item, user) + try_grind(used_item, user) return TRUE \ No newline at end of file diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 6af31c901452..42b9fd1a260a 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -64,7 +64,7 @@ . = ..() update_icon() -/obj/item/chems/syringe/attackby(obj/item/I, mob/user) +/obj/item/chems/syringe/attackby(obj/item/used_item, mob/user) return FALSE // allow afterattack to proceed /obj/item/chems/syringe/afterattack(obj/target, mob/user, proximity) diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm index da96a75e031b..ccfd214b9623 100644 --- a/code/modules/recycling/conveyor2.dm +++ b/code/modules/recycling/conveyor2.dm @@ -86,8 +86,8 @@ var/global/list/all_conveyor_switches = list() return TRUE // attack with item, place item on conveyor -/obj/machinery/conveyor/attackby(var/obj/item/I, mob/user) - if(IS_CROWBAR(I)) +/obj/machinery/conveyor/attackby(var/obj/item/used_item, mob/user) + if(IS_CROWBAR(used_item)) if(!(stat & BROKEN)) var/obj/item/conveyor_construct/C = new/obj/item/conveyor_construct(src.loc) C.id_tag = id_tag @@ -95,7 +95,7 @@ var/global/list/all_conveyor_switches = list() to_chat(user, "You remove the conveyor belt.") qdel(src) else - user.try_unequip(I, get_turf(src)) + user.try_unequip(used_item, get_turf(src)) return TRUE // make the conveyor broken @@ -207,8 +207,8 @@ var/global/list/all_conveyor_switches = list() last_pos = position position = 0 -/obj/machinery/conveyor_switch/attackby(obj/item/I, mob/user, params) - if(!IS_CROWBAR(I)) +/obj/machinery/conveyor_switch/attackby(obj/item/used_item, mob/user, params) + if(!IS_CROWBAR(used_item)) return ..() var/obj/item/conveyor_switch_construct/C = new/obj/item/conveyor_switch_construct(src.loc) C.id_tag = id_tag @@ -241,11 +241,11 @@ var/global/list/all_conveyor_switches = list() matter = list(/decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT) var/id_tag -/obj/item/conveyor_construct/attackby(obj/item/I, mob/user, params) - if(!istype(I, /obj/item/conveyor_switch_construct)) +/obj/item/conveyor_construct/attackby(obj/item/used_item, mob/user, params) + if(!istype(used_item, /obj/item/conveyor_switch_construct)) return ..() to_chat(user, "You link the switch to the conveyor belt assembly.") - var/obj/item/conveyor_switch_construct/C = I + var/obj/item/conveyor_switch_construct/C = used_item id_tag = C.id_tag return TRUE diff --git a/code/modules/recycling/disposal-construction.dm b/code/modules/recycling/disposal-construction.dm index d9db75c58358..7724f726e4a1 100644 --- a/code/modules/recycling/disposal-construction.dm +++ b/code/modules/recycling/disposal-construction.dm @@ -120,7 +120,7 @@ // attackby item // wrench: (un)anchor // weldingtool: convert to real pipe -/obj/structure/disposalconstruct/attackby(var/obj/item/I, var/mob/user) +/obj/structure/disposalconstruct/attackby(var/obj/item/used_item, var/mob/user) var/turf/T = loc if(!istype(T)) return TRUE @@ -130,7 +130,7 @@ var/obj/structure/disposalpipe/CP = locate() in T - if(IS_WRENCH(I)) + if(IS_WRENCH(used_item)) if(anchored) anchored = FALSE wrench_down(FALSE) @@ -144,9 +144,9 @@ update() update_verbs() return TRUE - else if(istype(I, /obj/item/weldingtool)) + else if(istype(used_item, /obj/item/weldingtool)) if(anchored) - var/obj/item/weldingtool/welder = I + var/obj/item/weldingtool/welder = used_item if(welder.weld(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) to_chat(user, "Welding \the [src] in place.") diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index a330ae36e09b..18cbae82610c 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -90,25 +90,25 @@ var/global/list/diversion_junctions = list() return ..() // attack by item places it in to disposal -/obj/machinery/disposal/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/disposal/attackby(var/obj/item/used_item, var/mob/user) if((. = ..())) return - if(stat & BROKEN || !I || !user) + if(stat & BROKEN || !used_item || !user) return - if(istype(I, /obj/item/bag/trash)) - if(I.storage) + if(istype(used_item, /obj/item/bag/trash)) + if(used_item.storage) to_chat(user, "You empty the bag.") - for(var/obj/item/O in I.storage.get_contents()) - I.storage.remove_from_storage(user, O, src, TRUE) - I.storage.finish_bulk_removal() + for(var/obj/item/O in used_item.storage.get_contents()) + used_item.storage.remove_from_storage(user, O, src, TRUE) + used_item.storage.finish_bulk_removal() update_icon() return - if(!user.try_unequip(I, src) || QDELETED(I)) + if(!user.try_unequip(used_item, src) || QDELETED(used_item)) return - user.visible_message("\The [user] places \the [I] into \the [src].", "You place \the [I] into \the [src].") + user.visible_message("\The [user] places \the [used_item] into \the [src].", "You place \the [used_item] into \the [src].") update_icon() @@ -438,14 +438,14 @@ var/global/list/diversion_junctions = list() /obj/machinery/disposal/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) if (istype(mover,/obj/item) && mover.throwing) - var/obj/item/I = mover - if(istype(I, /obj/item/projectile)) + var/obj/item/thing = mover + if(istype(thing, /obj/item/projectile)) return if(prob(75)) - I.forceMove(src) - visible_message("\The [I] lands in \the [src].") + thing.forceMove(src) + visible_message("\The [thing] lands in \the [src].") else - visible_message("\The [I] bounces off of \the [src]'s rim!") + visible_message("\The [thing] bounces off of \the [src]'s rim!") return 0 else return ..(mover, target, height, air_group) @@ -472,8 +472,8 @@ var/global/list/diversion_junctions = list() junctions.Cut() return ..() -/obj/machinery/disposal_switch/attackby(obj/item/I, mob/user, params) - if(IS_CROWBAR(I)) +/obj/machinery/disposal_switch/attackby(obj/item/used_item, mob/user, params) + if(IS_CROWBAR(used_item)) var/obj/item/disposal_switch_construct/C = new/obj/item/disposal_switch_construct(src.loc, id_tag) transfer_fingerprints_to(C) user.visible_message("\The [user] deattaches \the [src]") @@ -571,9 +571,9 @@ var/global/list/diversion_junctions = list() sleep(20) //wait until correct animation frame playsound(src, 'sound/machines/hiss.ogg', 50, 0, 0) -/obj/structure/disposaloutlet/attackby(var/obj/item/I, var/mob/user) - src.add_fingerprint(user, 0, I) - if(IS_SCREWDRIVER(I)) +/obj/structure/disposaloutlet/attackby(var/obj/item/used_item, var/mob/user) + src.add_fingerprint(user, 0, used_item) + if(IS_SCREWDRIVER(used_item)) switch(mode) if(0) mode=1 @@ -587,8 +587,8 @@ var/global/list/diversion_junctions = list() return TRUE else // This should be invalid? return FALSE - else if(istype(I,/obj/item/weldingtool) && mode==1) - var/obj/item/weldingtool/welder = I + else if(istype(used_item,/obj/item/weldingtool) && mode==1) + var/obj/item/weldingtool/welder = used_item if(welder.weld(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) to_chat(user, "You start slicing the floorweld off the disposal outlet.") diff --git a/code/modules/recycling/disposalpipe.dm b/code/modules/recycling/disposalpipe.dm index 3755fda1b1dd..0ed921518169 100644 --- a/code/modules/recycling/disposalpipe.dm +++ b/code/modules/recycling/disposalpipe.dm @@ -201,13 +201,13 @@ //attack by item //weldingtool: unfasten and convert to obj/disposalconstruct -/obj/structure/disposalpipe/attackby(var/obj/item/I, var/mob/user) - if(!istype(I, /obj/item/weldingtool)) +/obj/structure/disposalpipe/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/weldingtool)) return ..() if(!can_deconstruct()) return TRUE - src.add_fingerprint(user, 0, I) - var/obj/item/weldingtool/welder = I + src.add_fingerprint(user, 0, used_item) + var/obj/item/weldingtool/welder = used_item if(welder.weld(0,user)) playsound(src.loc, 'sound/items/Welder2.ogg', 100, 1) to_chat(user, "You begin slicing \the [src].") @@ -440,10 +440,10 @@ updatedesc() update() -/obj/structure/disposalpipe/tagger/attackby(var/obj/item/item, var/mob/user) - if(!istype(item, /obj/item/destTagger)) +/obj/structure/disposalpipe/tagger/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/destTagger)) return ..() - var/obj/item/destTagger/tagger = item + var/obj/item/destTagger/tagger = used_item if(tagger.current_tag)// Tag set sort_tag = tagger.current_tag playsound(src.loc, 'sound/machines/twobeep.ogg', 100, 1) @@ -515,10 +515,10 @@ linked = null return ..() -/obj/structure/disposalpipe/diversion_junction/attackby(var/obj/item/item, var/mob/user) - if(!istype(item, /obj/item/disposal_switch_construct)) +/obj/structure/disposalpipe/diversion_junction/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/disposal_switch_construct)) return ..() - var/obj/item/disposal_switch_construct/switchcon = item + var/obj/item/disposal_switch_construct/switchcon = used_item if(switchcon.id_tag) id_tag = switchcon.id_tag playsound(src.loc, 'sound/machines/twobeep.ogg', 100, TRUE) @@ -607,10 +607,10 @@ updatedesc() updatename() -/obj/structure/disposalpipe/sortjunction/attackby(var/obj/item/item, var/mob/user) - if(!istype(item, /obj/item/destTagger)) +/obj/structure/disposalpipe/sortjunction/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/destTagger)) return ..() - var/obj/item/destTagger/tagger = item + var/obj/item/destTagger/tagger = used_item if(tagger.current_tag)// Tag set sort_type = tagger.current_tag playsound(src.loc, 'sound/machines/twobeep.ogg', 100, TRUE) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index bf275817f0bf..dcca3724725b 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -79,8 +79,8 @@ update_icon() return -/obj/machinery/disposal/deliveryChute/attackby(var/obj/item/I, var/mob/user) - if(IS_SCREWDRIVER(I)) +/obj/machinery/disposal/deliveryChute/attackby(var/obj/item/used_item, var/mob/user) + if(IS_SCREWDRIVER(used_item)) if(c_mode==0) c_mode=1 playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, TRUE) @@ -91,8 +91,8 @@ playsound(src.loc, 'sound/items/Screwdriver.ogg', 50, TRUE) to_chat(user, "You attach the screws around the power connection.") return TRUE - else if(IS_WELDER(I) && c_mode==1) - var/obj/item/weldingtool/welder = I + else if(IS_WELDER(used_item) && c_mode==1) + var/obj/item/weldingtool/welder = used_item if(!welder.weld(1,user)) // 'you need more welding fuel' messages are already handled return TRUE to_chat(user, "You start slicing the floorweld off the delivery chute.") diff --git a/code/modules/research/design_database_analyzer.dm b/code/modules/research/design_database_analyzer.dm index 6750ea55a043..e4d6d06669d5 100644 --- a/code/modules/research/design_database_analyzer.dm +++ b/code/modules/research/design_database_analyzer.dm @@ -79,9 +79,9 @@ D.ui_interact(user) return TRUE -/obj/machinery/destructive_analyzer/attackby(var/obj/item/O, var/mob/user) +/obj/machinery/destructive_analyzer/attackby(var/obj/item/used_item, var/mob/user) - if(IS_MULTITOOL(O) && !user.check_intent(I_FLAG_HARM)) + if(IS_MULTITOOL(used_item) && !user.check_intent(I_FLAG_HARM)) var/datum/extension/local_network_member/fabnet = get_extension(src, /datum/extension/local_network_member) fabnet.get_new_tag(user) return TRUE @@ -89,7 +89,7 @@ if(busy) to_chat(user, SPAN_WARNING("\The [src] is busy right now.")) return TRUE - if((. = component_attackby(O, user))) + if((. = component_attackby(used_item, user))) return if(isrobot(user)) return TRUE @@ -99,21 +99,21 @@ if(panel_open) to_chat(user, SPAN_WARNING("You can't load \the [src] while it's opened.")) return TRUE - var/tech = O.get_origin_tech() + var/tech = used_item.get_origin_tech() if(!tech) - to_chat(user, SPAN_WARNING("Nothing can be learned from \the [O].")) + to_chat(user, SPAN_WARNING("Nothing can be learned from \the [used_item].")) return TRUE var/list/techlvls = cached_json_decode(tech) - if(!length(techlvls) || O.holographic) + if(!length(techlvls) || used_item.holographic) to_chat(user, SPAN_WARNING("You cannot deconstruct this item.")) return TRUE - if(!user.try_unequip(O, src)) + if(!user.try_unequip(used_item, src)) return TRUE busy = TRUE - loaded_item = O - to_chat(user, SPAN_NOTICE("You add \the [O] to \the [src].")) + loaded_item = used_item + to_chat(user, SPAN_NOTICE("You add \the [used_item] to \the [src].")) flick("d_analyzer_la", src) addtimer(CALLBACK(src, PROC_REF(refresh_busy)), 1 SECOND) return TRUE diff --git a/code/modules/sealant_gun/sealant_injector.dm b/code/modules/sealant_gun/sealant_injector.dm index 99f8553586d8..9bd7735bbd74 100644 --- a/code/modules/sealant_gun/sealant_injector.dm +++ b/code/modules/sealant_gun/sealant_injector.dm @@ -35,23 +35,23 @@ new /obj/item/chems/chem_disp_cartridge/polyacid(src) = 1 ) -/obj/structure/sealant_injector/attackby(obj/item/O, mob/user) +/obj/structure/sealant_injector/attackby(obj/item/used_item, mob/user) - if(istype(O, /obj/item/sealant_tank)) + if(istype(used_item, /obj/item/sealant_tank)) if(loaded_tank) to_chat(user, SPAN_WARNING("\The [src] already has a sealant tank inserted.")) return TRUE - if(user.try_unequip(O, src)) - loaded_tank = O + if(user.try_unequip(used_item, src)) + loaded_tank = used_item update_icon() return TRUE - if(istype(O, /obj/item/chems/chem_disp_cartridge)) + if(istype(used_item, /obj/item/chems/chem_disp_cartridge)) if(length(cartridges) >= max_cartridges) to_chat(user, SPAN_WARNING("\The [src] is loaded to capacity with cartridges.")) return TRUE - if(user.try_unequip(O, src)) - LAZYSET(cartridges, O, 1) + if(user.try_unequip(used_item, src)) + LAZYSET(cartridges, used_item, 1) update_icon() return TRUE diff --git a/code/modules/sealant_gun/sealant_rack.dm b/code/modules/sealant_gun/sealant_rack.dm index d952957c995d..4f053d436bd0 100644 --- a/code/modules/sealant_gun/sealant_rack.dm +++ b/code/modules/sealant_gun/sealant_rack.dm @@ -44,23 +44,23 @@ return TRUE return ..() -/obj/structure/sealant_rack/attackby(obj/item/O, mob/user) +/obj/structure/sealant_rack/attackby(obj/item/used_item, mob/user) - if(istype(O, /obj/item/gun/launcher/sealant)) + if(istype(used_item, /obj/item/gun/launcher/sealant)) if(loaded_gun) to_chat(user, SPAN_WARNING("There is already a sealant gun hung up on \the [src].")) return TRUE - if(user.try_unequip(O, src)) - loaded_gun = O + if(user.try_unequip(used_item, src)) + loaded_gun = used_item update_icon() return TRUE - if(istype(O, /obj/item/sealant_tank)) + if(istype(used_item, /obj/item/sealant_tank)) if(length(tanks) >= max_tanks) to_chat(user, SPAN_WARNING("\The [src] is filled to capacity with sealant tanks.")) return TRUE - if(user.try_unequip(O, src)) - LAZYADD(tanks, O) + if(user.try_unequip(used_item, src)) + LAZYADD(tanks, used_item) update_icon() return TRUE diff --git a/code/modules/shield_generators/shield.dm b/code/modules/shield_generators/shield.dm index 4a48e64409d5..7e9128219bb9 100644 --- a/code/modules/shield_generators/shield.dm +++ b/code/modules/shield_generators/shield.dm @@ -215,8 +215,8 @@ take_damage(proj.get_structure_damage(), SHIELD_DAMTYPE_EM) // Attacks with hand tools. Blocked by Hyperkinetic flag. -/obj/effect/shield/attackby(var/obj/item/I, var/mob/user) - return bash(I, user) +/obj/effect/shield/attackby(var/obj/item/used_item, var/mob/user) + return bash(used_item, user) /obj/effect/shield/bash(obj/item/weapon, mob/user) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) diff --git a/code/modules/shieldgen/emergency_shield.dm b/code/modules/shieldgen/emergency_shield.dm index 467db3a92f6c..50d21d7c3571 100644 --- a/code/modules/shieldgen/emergency_shield.dm +++ b/code/modules/shieldgen/emergency_shield.dm @@ -42,8 +42,8 @@ // Circumvent base machinery attackby // TODO: MAKE SHIELDS NOT MACHINERY??? -/obj/machinery/shield/attackby(obj/item/I, mob/user) - return bash(I, user) +/obj/machinery/shield/attackby(obj/item/used_item, mob/user) + return bash(used_item, user) /obj/machinery/shield/bash(obj/item/used_item, mob/user) if(isliving(user) && user.check_intent(I_FLAG_HELP)) diff --git a/code/modules/shieldgen/shieldwallgen.dm b/code/modules/shieldgen/shieldwallgen.dm index 5f85f83f107f..afd8d097a76c 100644 --- a/code/modules/shieldgen/shieldwallgen.dm +++ b/code/modules/shieldgen/shieldwallgen.dm @@ -287,10 +287,10 @@ update_nearby_tiles() . = ..() -/obj/machinery/shieldwall/attackby(var/obj/item/I, var/mob/user) +/obj/machinery/shieldwall/attackby(var/obj/item/used_item, var/mob/user) var/obj/machinery/shieldwallgen/G = prob(50) ? gen_primary : gen_secondary - G.storedpower -= I.expend_attack_force(user)*2500 - user.visible_message("\The [user] hits \the [src] with \the [I]!") + G.storedpower -= used_item.expend_attack_force(user)*2500 + user.visible_message("\The [user] hits \the [src] with \the [used_item]!") user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) user.do_attack_animation(src) playsound(loc, 'sound/weapons/smash.ogg', 75, 1) diff --git a/code/modules/shuttles/docking_beacon.dm b/code/modules/shuttles/docking_beacon.dm index bac4e5fe16a1..1df49863710e 100644 --- a/code/modules/shuttles/docking_beacon.dm +++ b/code/modules/shuttles/docking_beacon.dm @@ -45,8 +45,8 @@ SSshuttle.docking_beacons -= src permitted_shuttles.Cut() -/obj/machinery/docking_beacon/attackby(obj/item/I, mob/user) - if(IS_WRENCH(I)) +/obj/machinery/docking_beacon/attackby(obj/item/used_item, mob/user) + if(IS_WRENCH(used_item)) if(!allowed(user)) to_chat(user, SPAN_WARNING("The bolts on \the [src] are locked!")) return TRUE diff --git a/code/modules/synthesized_instruments/real_instruments/Synthesizer/synthesizer.dm b/code/modules/synthesized_instruments/real_instruments/Synthesizer/synthesizer.dm index b9537a30da81..4706caad9d8e 100644 --- a/code/modules/synthesized_instruments/real_instruments/Synthesizer/synthesizer.dm +++ b/code/modules/synthesized_instruments/real_instruments/Synthesizer/synthesizer.dm @@ -12,8 +12,8 @@ path = /datum/instrument sound_player = /datum/sound_player/synthesizer -/obj/structure/synthesized_instrument/synthesizer/attackby(obj/item/O, mob/user, params) - if (IS_WRENCH(O)) +/obj/structure/synthesized_instrument/synthesizer/attackby(obj/item/used_item, mob/user, params) + if (IS_WRENCH(used_item)) if (!anchored && !isspaceturf(get_turf(src))) playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1) to_chat(user, "You begin to tighten \the [src] to the floor...") diff --git a/code/modules/vehicles/engine.dm b/code/modules/vehicles/engine.dm index cffe87ade48a..90baf9d3dbe6 100644 --- a/code/modules/vehicles/engine.dm +++ b/code/modules/vehicles/engine.dm @@ -33,23 +33,23 @@ cost_per_move = 200 // W var/obj/item/cell/cell -/obj/item/engine/electric/attackby(var/obj/item/I, var/mob/user) - if(istype(I,/obj/item/cell)) +/obj/item/engine/electric/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item,/obj/item/cell)) if(cell) to_chat(user, "There is already a cell in \the [src].") else - cell = I - user.drop_from_inventory(I) - I.forceMove(src) + cell = used_item + user.drop_from_inventory(used_item) + used_item.forceMove(src) return TRUE - else if(IS_CROWBAR(I)) + else if(IS_CROWBAR(used_item)) if(cell) - to_chat(user, "You pry out \the [cell] with \the [I].") + to_chat(user, "You pry out \the [cell] with \the [used_item].") cell.dropInto(loc) cell = null return TRUE if(!user.check_intent(I_FLAG_HARM)) - to_chat(user, SPAN_WARNING("There is no cell in \the [src] to remove with \the [I]!")) + to_chat(user, SPAN_WARNING("There is no cell in \the [src] to remove with \the [used_item]!")) return TRUE return ..() @@ -92,8 +92,8 @@ temp_reagents_holder.create_reagents(15) temp_reagents_holder.atom_flags |= ATOM_FLAG_OPEN_CONTAINER -/obj/item/engine/thermal/attackby(var/obj/item/I, var/mob/user) - if(I.standard_pour_into(user, src)) +/obj/item/engine/thermal/attackby(var/obj/item/used_item, var/mob/user) + if(used_item.standard_pour_into(user, src)) return TRUE return ..() diff --git a/code/modules/xenoarcheaology/boulder.dm b/code/modules/xenoarcheaology/boulder.dm index 75b6df14520b..3d94afd97379 100644 --- a/code/modules/xenoarcheaology/boulder.dm +++ b/code/modules/xenoarcheaology/boulder.dm @@ -39,15 +39,15 @@ QDEL_NULL(artifact_find) return ..() -/obj/structure/boulder/attackby(var/obj/item/I, var/mob/user) +/obj/structure/boulder/attackby(var/obj/item/used_item, var/mob/user) - if(istype(I, /obj/item/depth_scanner)) - var/obj/item/depth_scanner/C = I + if(istype(used_item, /obj/item/depth_scanner)) + var/obj/item/depth_scanner/C = used_item C.scan_atom(user, src) return TRUE - if(istype(I, /obj/item/measuring_tape)) - var/obj/item/measuring_tape/P = I + if(istype(used_item, /obj/item/measuring_tape)) + var/obj/item/measuring_tape/P = used_item user.visible_message( SPAN_NOTICE("\The [user] extends \the [P] towards \the [src]."), SPAN_NOTICE("You extend \the [P] towards \the [src].") @@ -56,8 +56,8 @@ to_chat(user, SPAN_NOTICE("\The [src] has been excavated to a depth of [src.excavation_level]cm.")) return TRUE - if(I.do_tool_interaction(TOOL_PICK, user, src, 3 SECONDS, set_cooldown = TRUE)) - excavation_level += I.get_tool_property(TOOL_PICK, TOOL_PROP_EXCAVATION_DEPTH) + if(used_item.do_tool_interaction(TOOL_PICK, user, src, 3 SECONDS, set_cooldown = TRUE)) + excavation_level += used_item.get_tool_property(TOOL_PICK, TOOL_PROP_EXCAVATION_DEPTH) if(excavation_level > 200) user.visible_message( SPAN_DANGER("\The [src] suddenly crumbles away."), diff --git a/code/modules/xenoarcheaology/finds/strange_rock.dm b/code/modules/xenoarcheaology/finds/strange_rock.dm index 813caba8184c..4ceacb3a7204 100644 --- a/code/modules/xenoarcheaology/finds/strange_rock.dm +++ b/code/modules/xenoarcheaology/finds/strange_rock.dm @@ -18,8 +18,8 @@ QDEL_NULL(inside) . = ..() -/obj/item/strangerock/attackby(var/obj/item/I, var/mob/user) - if(istype(I, /obj/item/tool/xeno/brush)) +/obj/item/strangerock/attackby(var/obj/item/used_item, var/mob/user) + if(istype(used_item, /obj/item/tool/xeno/brush)) if(inside) inside.dropInto(loc) visible_message(SPAN_NOTICE("\The [src] is brushed away, revealing \the [inside].")) @@ -29,8 +29,8 @@ physically_destroyed() return TRUE - if(IS_WELDER(I)) - var/obj/item/weldingtool/welder = I + if(IS_WELDER(used_item)) + var/obj/item/weldingtool/welder = used_item if(welder.isOn()) if(welder.weld(2)) if(inside) @@ -44,8 +44,8 @@ visible_message(SPAN_NOTICE("A few sparks fly off \the [src], but nothing else happens.")) return TRUE - else if(istype(I, /obj/item/core_sampler)) - var/obj/item/core_sampler/S = I + else if(istype(used_item, /obj/item/core_sampler)) + var/obj/item/core_sampler/S = used_item S.sample_item(src, user) return TRUE diff --git a/code/modules/xenoarcheaology/machinery/artifact_harvester.dm b/code/modules/xenoarcheaology/machinery/artifact_harvester.dm index 15c69a09bbeb..c2c3043a700d 100644 --- a/code/modules/xenoarcheaology/machinery/artifact_harvester.dm +++ b/code/modules/xenoarcheaology/machinery/artifact_harvester.dm @@ -56,16 +56,16 @@ events_repository.register(/decl/observ/destroyed, new_artifact, src, TYPE_PROC_REF(/obj/machinery/artifact_harvester, clear_artifact)) cur_artifact = new_artifact -/obj/machinery/artifact_harvester/attackby(var/obj/I, var/mob/user) - if(!istype(I, /obj/item/anobattery)) +/obj/machinery/artifact_harvester/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/anobattery)) return ..() if(inserted_battery) to_chat(user, SPAN_WARNING("There is already a battery in [src].")) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, SPAN_NOTICE("You insert [I] into [src].")) - inserted_battery = I + to_chat(user, SPAN_NOTICE("You insert [used_item] into [src].")) + inserted_battery = used_item updateDialog() return TRUE diff --git a/code/modules/xenoarcheaology/machinery/geosample_scanner.dm b/code/modules/xenoarcheaology/machinery/geosample_scanner.dm index eba847f98f2c..1915abfab92c 100644 --- a/code/modules/xenoarcheaology/machinery/geosample_scanner.dm +++ b/code/modules/xenoarcheaology/machinery/geosample_scanner.dm @@ -60,34 +60,34 @@ ui_interact(user) return TRUE -/obj/machinery/radiocarbon_spectrometer/attackby(var/obj/I, var/mob/user) - if(istype(I, /obj/item/stack/nanopaste)) +/obj/machinery/radiocarbon_spectrometer/attackby(var/obj/used_item, var/mob/user) + if(istype(used_item, /obj/item/stack/nanopaste)) if(scanning) to_chat(user, SPAN_WARNING("You can't do that while [src] is scanning!")) return TRUE var/choice = alert("What do you want to do with the nanopaste?","Radiometric Scanner","Scan nanopaste","Fix seal integrity") - if(CanPhysicallyInteract(user) && !QDELETED(I) && I.loc == user && choice == "Fix seal integrity") - var/obj/item/stack/nanopaste/N = I + if(CanPhysicallyInteract(user) && !QDELETED(used_item) && used_item.loc == user && choice == "Fix seal integrity") + var/obj/item/stack/nanopaste/N = used_item var/amount_used = min(N.get_amount(), 10 - scanner_seal_integrity / 10) N.use(amount_used) scanner_seal_integrity = round(scanner_seal_integrity + amount_used * 10) return TRUE - if(istype(I, /obj/item/chems/glass)) + if(istype(used_item, /obj/item/chems/glass)) if(scanning) to_chat(user, SPAN_WARNING("You can't do that while [src] is scanning!")) return TRUE var/choice = alert("What do you want to do with the container?","Radiometric Scanner","Add coolant","Empty coolant","Scan container") - if(CanPhysicallyInteract(user) && !QDELETED(I) && I.loc == user) + if(CanPhysicallyInteract(user) && !QDELETED(used_item) && used_item.loc == user) //#TODO: The add coolant stuff could probably be handled by the default reagent handling code. And the emptying could be done with an alt interaction. if(choice == "Add coolant") - var/obj/item/chems/glass/G = I + var/obj/item/chems/glass/G = used_item var/amount_transferred = min(src.reagents.maximum_volume - src.reagents.total_volume, G.reagents.total_volume) G.reagents.trans_to(src, amount_transferred) to_chat(user, SPAN_INFO("You empty [amount_transferred]u of coolant into [src].")) update_coolant() return TRUE else if(choice == "Empty coolant") - var/obj/item/chems/glass/G = I + var/obj/item/chems/glass/G = used_item var/amount_transferred = min(G.reagents.maximum_volume - G.reagents.total_volume, src.reagents.total_volume) src.reagents.trans_to(G, amount_transferred) to_chat(user, SPAN_INFO("You remove [amount_transferred]u of coolant from [src].")) @@ -99,14 +99,14 @@ return TRUE //Now let people insert whatever into the scanner - if(istype(I)) + if(istype(used_item)) if(scanned_item) to_chat(user, SPAN_WARNING("\The [src] already has \a [scanned_item] inside!")) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - scanned_item = I - to_chat(user, SPAN_NOTICE("You put \the [I] into \the [src].")) + scanned_item = used_item + to_chat(user, SPAN_NOTICE("You put \the [used_item] into \the [src].")) return TRUE return FALSE diff --git a/code/modules/xenoarcheaology/tools/ano_device_battery.dm b/code/modules/xenoarcheaology/tools/ano_device_battery.dm index fcc690b4642f..d9ed40ae0473 100644 --- a/code/modules/xenoarcheaology/tools/ano_device_battery.dm +++ b/code/modules/xenoarcheaology/tools/ano_device_battery.dm @@ -60,15 +60,15 @@ STOP_PROCESSING(SSobj, src) . = ..() -/obj/item/anodevice/attackby(var/obj/I, var/mob/user) - if(!istype(I, /obj/item/anobattery)) +/obj/item/anodevice/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/anobattery)) return ..() if(inserted_battery) return TRUE - if(!user.try_unequip(I, src)) + if(!user.try_unequip(used_item, src)) return TRUE - to_chat(user, SPAN_NOTICE("You insert \the [I] into \the [src].")) - inserted_battery = I + to_chat(user, SPAN_NOTICE("You insert \the [used_item] into \the [src].")) + inserted_battery = used_item update_icon() return TRUE diff --git a/mods/content/beekeeping/hives/_hive.dm b/mods/content/beekeeping/hives/_hive.dm index 515fe39f8dc0..1ace43bbe1cf 100644 --- a/mods/content/beekeeping/hives/_hive.dm +++ b/mods/content/beekeeping/hives/_hive.dm @@ -45,17 +45,17 @@ if(!closed) . += "The lid is open." -/obj/machinery/beehive/attackby(var/obj/item/I, var/mob/user) - if(IS_CROWBAR(I)) +/obj/machinery/beehive/attackby(var/obj/item/used_item, var/mob/user) + if(IS_CROWBAR(used_item)) closed = !closed user.visible_message("\The [user] [closed ? "closes" : "opens"] \the [src].", "You [closed ? "close" : "open"] \the [src].") update_icon() return TRUE - else if(IS_WRENCH(I)) + else if(IS_WRENCH(used_item)) anchored = !anchored user.visible_message("\The [user] [anchored ? "wrenches" : "unwrenches"] \the [src].", "You [anchored ? "wrench" : "unwrench"] \the [src].") return TRUE - else if(istype(I, /obj/item/bee_smoker)) + else if(istype(used_item, /obj/item/bee_smoker)) if(closed) to_chat(user, "You need to open \the [src] with a crowbar before smoking the bees.") return TRUE @@ -63,24 +63,24 @@ smoked = 30 update_icon() return TRUE - else if(istype(I, /obj/item/hive_frame/crafted)) + else if(istype(used_item, /obj/item/hive_frame/crafted)) if(closed) - to_chat(user, "You need to open \the [src] with a crowbar before inserting \the [I].") + to_chat(user, "You need to open \the [src] with a crowbar before inserting \the [used_item].") return TRUE if(frames >= maxFrames) to_chat(user, "There is no place for an another frame.") return TRUE - var/obj/item/hive_frame/crafted/H = I + var/obj/item/hive_frame/crafted/H = used_item if(H.reagents?.total_volume) - to_chat(user, "\The [I] is full with beeswax and honey, empty it in the extractor first.") + to_chat(user, "\The [used_item] is full with beeswax and honey, empty it in the extractor first.") return TRUE ++frames - user.visible_message("\The [user] loads \the [I] into \the [src].", "You load \the [I] into \the [src].") + user.visible_message("\The [user] loads \the [used_item] into \the [src].", "You load \the [used_item] into \the [src].") update_icon() - qdel(I) + qdel(used_item) return TRUE - else if(istype(I, /obj/item/bee_pack)) - var/obj/item/bee_pack/B = I + else if(istype(used_item, /obj/item/bee_pack)) + var/obj/item/bee_pack/B = used_item if(B.full && bee_count) to_chat(user, "\The [src] already has bees inside.") return TRUE @@ -94,16 +94,16 @@ to_chat(user, "You need to open \the [src] with a crowbar before moving the bees.") return TRUE if(B.full) - user.visible_message("\The [user] puts the queen and the bees from \the [I] into \the [src].", "You put the queen and the bees from \the [I] into \the [src].") + user.visible_message("\The [user] puts the queen and the bees from \the [used_item] into \the [src].", "You put the queen and the bees from \the [used_item] into \the [src].") bee_count = 20 B.empty() else - user.visible_message("\The [user] puts bees and larvae from \the [src] into \the [I].", "You put bees and larvae from \the [src] into \the [I].") + user.visible_message("\The [user] puts bees and larvae from \the [src] into \the [used_item].", "You put bees and larvae from \the [src] into \the [used_item].") bee_count /= 2 B.fill() update_icon() return TRUE - else if(istype(I, /obj/item/scanner/plant)) + else if(istype(used_item, /obj/item/scanner/plant)) to_chat(user, "Scan result of \the [src]...") to_chat(user, "Beehive is [bee_count ? "[round(bee_count)]% full" : "empty"].[bee_count > 90 ? " Colony is ready to split." : ""]") if(frames) @@ -115,7 +115,7 @@ if(smoked) to_chat(user, "The hive is smoked.") return TRUE - else if(IS_SCREWDRIVER(I)) + else if(IS_SCREWDRIVER(used_item)) if(bee_count) to_chat(user, "You can't dismantle \the [src] with these bees inside.") return TRUE diff --git a/mods/content/xenobiology/slime/items.dm b/mods/content/xenobiology/slime/items.dm index da4a21eff12c..9689cd8b129f 100644 --- a/mods/content/xenobiology/slime/items.dm +++ b/mods/content/xenobiology/slime/items.dm @@ -17,8 +17,8 @@ /obj/item/slime_extract/get_base_value() . = ..() * Uses -/obj/item/slime_extract/attackby(obj/item/O, mob/user) - if(istype(O, /obj/item/slime_extract_enhancer)) +/obj/item/slime_extract/attackby(obj/item/used_item, mob/user) + if(istype(used_item, /obj/item/slime_extract_enhancer)) if(enhanced == 1) to_chat(user, " This extract has already been enhanced!") return ..() @@ -28,7 +28,7 @@ to_chat(user, "You apply the enhancer. It now has triple the amount of uses.") Uses = 3 enhanced = 1 - qdel(O) + qdel(used_item) return TRUE . = ..() @@ -73,10 +73,10 @@ /obj/effect/golemrune/Process() var/mob/observer/ghost/ghost - for(var/mob/observer/ghost/O in src.loc) - if(!O.client || (O.mind && O.mind.current && O.mind.current.stat != DEAD)) + for(var/mob/observer/ghost/observer in src.loc) + if(!observer.client || (observer.mind && observer.mind.current && observer.mind.current.stat != DEAD)) continue - ghost = O + ghost = observer break if(ghost) icon_state = "golem2" @@ -86,12 +86,12 @@ /obj/effect/golemrune/attack_hand(mob/user) SHOULD_CALL_PARENT(FALSE) var/mob/observer/ghost/ghost - for(var/mob/observer/ghost/O in src.loc) - if(!O.client) + for(var/mob/observer/ghost/observer in src.loc) + if(!observer.client) continue - if(O.mind && O.mind.current && O.mind.current.stat != DEAD) + if(observer.mind && observer.mind.current && observer.mind.current.stat != DEAD) continue - ghost = O + ghost = observer break if(!ghost) to_chat(user, SPAN_WARNING("The rune fizzles uselessly.")) diff --git a/mods/gamemodes/cult/mobs/constructs/soulstone.dm b/mods/gamemodes/cult/mobs/constructs/soulstone.dm index 19e1c55448e9..bf006ad412d0 100644 --- a/mods/gamemodes/cult/mobs/constructs/soulstone.dm +++ b/mods/gamemodes/cult/mobs/constructs/soulstone.dm @@ -46,21 +46,21 @@ if(full == SOULSTONE_CRACKED) . += "This one is cracked and useless." -/obj/item/soulstone/attackby(var/obj/item/I, var/mob/user) - if(is_evil && istype(I, /obj/item/nullrod)) +/obj/item/soulstone/attackby(var/obj/item/used_item, var/mob/user) + if(is_evil && istype(used_item, /obj/item/nullrod)) to_chat(user, SPAN_NOTICE("You cleanse \the [src] of taint, purging its shackles to its creator.")) is_evil = FALSE return TRUE - else if(I.expend_attack_force(user) >= 5) + else if(used_item.expend_attack_force(user) >= 5) if(full != SOULSTONE_CRACKED) user.visible_message( - SPAN_WARNING("\The [user] hits \the [src] with \the [I], and it breaks.[shade.client ? " You hear a terrible scream!" : ""]"), - SPAN_WARNING("You hit \the [src] with \the [I], and it cracks.[shade.client ? " You hear a terrible scream!" : ""]"), + SPAN_WARNING("\The [user] hits \the [src] with \the [used_item], and it breaks.[shade.client ? " You hear a terrible scream!" : ""]"), + SPAN_WARNING("You hit \the [src] with \the [used_item], and it cracks.[shade.client ? " You hear a terrible scream!" : ""]"), shade.client ? SPAN_NOTICE("You hear a scream.") : null) playsound(loc, 'sound/effects/Glasshit.ogg', 75) set_full(SOULSTONE_CRACKED) else - user.visible_message(SPAN_DANGER("\The [user] shatters \the [src] with \the [I]!")) + user.visible_message(SPAN_DANGER("\The [user] shatters \the [src] with \the [used_item]!")) shatter() return TRUE return ..() @@ -144,15 +144,15 @@ icon_state = "construct-cult" desc = "This eerie contraption looks like it would come alive if supplied with a missing ingredient." -/obj/structure/constructshell/attackby(var/obj/item/I, var/mob/user) - if(!istype(I, /obj/item/soulstone)) +/obj/structure/constructshell/attackby(var/obj/item/used_item, var/mob/user) + if(!istype(used_item, /obj/item/soulstone)) return ..() - var/obj/item/soulstone/S = I + var/obj/item/soulstone/S = used_item if(!S.shade.client) - to_chat(user, SPAN_NOTICE("\The [I] has essence, but no soul. Activate it in your hand to find a soul for it first.")) + to_chat(user, SPAN_NOTICE("\The [used_item] has essence, but no soul. Activate it in your hand to find a soul for it first.")) return TRUE if(S.shade.loc != S) - to_chat(user, SPAN_NOTICE("Recapture the shade back into \the [I] first.")) + to_chat(user, SPAN_NOTICE("Recapture the shade back into \the [used_item] first.")) return TRUE var/construct = alert(user, "Please choose which type of construct you wish to create.",,"Artificer", "Wraith", "Juggernaut") var/ctype diff --git a/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm b/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm index 05aeb1f74bb7..4ec0c9cf890a 100644 --- a/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm +++ b/mods/mobs/dionaea/mob/gestalt/gestalt_attacks.dm @@ -1,6 +1,6 @@ -/obj/structure/diona_gestalt/attackby(var/obj/item/thing, var/mob/user) +/obj/structure/diona_gestalt/attackby(var/obj/item/used_item, var/mob/user) . = ..() - if(thing.get_attack_force(user)) + if(used_item.get_attack_force(user)) shed_atom(forcefully = TRUE) /obj/structure/diona_gestalt/hitby() diff --git a/mods/species/ascent/effects/razorweb.dm b/mods/species/ascent/effects/razorweb.dm index 0647ffe0c91f..ec7b461524a6 100644 --- a/mods/species/ascent/effects/razorweb.dm +++ b/mods/species/ascent/effects/razorweb.dm @@ -78,16 +78,16 @@ qdel_self() return TRUE -/obj/effect/razorweb/attackby(var/obj/item/thing, var/mob/user) +/obj/effect/razorweb/attackby(var/obj/item/used_item, var/mob/user) var/destroy_self - if(thing.expend_attack_force(user)) - visible_message(SPAN_DANGER("\The [user] breaks \the [src] with \the [thing]!")) + if(used_item.expend_attack_force(user)) + visible_message(SPAN_DANGER("\The [user] breaks \the [src] with \the [used_item]!")) destroy_self = TRUE - if(prob(15) && user.try_unequip(thing)) - visible_message(SPAN_DANGER("\The [thing] is sliced apart!")) - qdel(thing) + if(prob(15) && user.try_unequip(used_item)) + visible_message(SPAN_DANGER("\The [used_item] is sliced apart!")) + qdel(used_item) if(destroy_self) qdel(src) From 6cbe41dc84db0f2f2792e33cb464be9516b198d6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 18 Feb 2025 20:04:01 +1100 Subject: [PATCH 025/512] Fixing seed storage var shadowing. --- code/modules/hydroponics/seed_storage.dm | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/code/modules/hydroponics/seed_storage.dm b/code/modules/hydroponics/seed_storage.dm index 98efab116283..d854110a206f 100644 --- a/code/modules/hydroponics/seed_storage.dm +++ b/code/modules/hydroponics/seed_storage.dm @@ -4,14 +4,14 @@ var/datum/seed/seed_type // Keeps track of what our seed is var/list/obj/item/seeds/seeds = list() // Tracks actual objects contained in the pile -/datum/seed_pile/New(var/obj/item/seeds/seeds) - name = seeds.name +/datum/seed_pile/New(var/obj/item/seeds/new_seeds) + name = new_seeds.name amount = 1 - seed_type = seeds.seed - seeds += seeds + seed_type = new_seeds.seed + seeds += new_seeds -/datum/seed_pile/proc/matches(var/obj/item/seeds/seeds) - if (seeds.seed == seed_type) +/datum/seed_pile/proc/matches(var/obj/item/seeds/check_seeds) + if (check_seeds.seed == seed_type) return 1 return 0 @@ -294,15 +294,15 @@ switch(task) if ("vend") - var/obj/seeds = pick(our_pile.seeds) - if (seeds) + var/obj/vending_seeds = pick(our_pile.seeds) + if (vending_seeds) --our_pile.amount - our_pile.seeds -= seeds + our_pile.seeds -= vending_seeds if (our_pile.amount <= 0 || our_pile.seeds.len <= 0) piles -= our_pile qdel(our_pile) flick("[initial(icon_state)]-vend", src) - seeds.dropInto(loc) + vending_seeds.dropInto(loc) . = TOPIC_REFRESH if ("purge") QDEL_LIST(our_pile.seeds) @@ -334,23 +334,23 @@ return ..() -/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/seeds, bypass_removal = 0) +/obj/machinery/seed_storage/proc/add(var/obj/item/seeds/adding_seeds, bypass_removal = 0) if(!bypass_removal) - if (ismob(seeds.loc)) - var/mob/user = seeds.loc - if(!user.try_unequip(seeds, src)) + if (ismob(adding_seeds.loc)) + var/mob/user = adding_seeds.loc + if(!user.try_unequip(adding_seeds, src)) return - else if(isobj(seeds.loc)) - seeds.loc?.storage?.remove_from_storage(null, seeds, src) + else if(isobj(adding_seeds.loc)) + adding_seeds.loc?.storage?.remove_from_storage(null, adding_seeds, src) - seeds.forceMove(src) + adding_seeds.forceMove(src) for (var/datum/seed_pile/N in piles) - if (N.matches(seeds)) + if (N.matches(adding_seeds)) ++N.amount - N.seeds += (seeds) + N.seeds += adding_seeds return - piles += new /datum/seed_pile(seeds) + piles += new /datum/seed_pile(adding_seeds) flick("[initial(icon_state)]-vend", src) return From 18f6e0018cdc9f3e46235c22c9f73589af48f09f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 02:45:32 -0500 Subject: [PATCH 026/512] Fix uses of initial(reagent.name) --- code/game/objects/items/weapons/autopsy.dm | 8 ++--- .../codex/categories/category_substances.dm | 8 ++--- .../integrated_electronics/subtypes/input.dm | 13 ++++--- .../reagents/chems/random/random_effects.dm | 2 +- .../reagents/dispenser/cartridge_spawn.dm | 19 +++++----- .../reagents/reagent_containers/borghydro.dm | 14 ++++---- .../reagents/reagent_containers/food/lunch.dm | 8 ++--- code/modules/scanners/health.dm | 36 +++++++++---------- code/modules/scanners/mass_spectrometer.dm | 26 +++++++------- 9 files changed, 67 insertions(+), 67 deletions(-) diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index 61aa021a7dc8..eead1d77e88f 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -35,8 +35,8 @@ return add_autopsy_data(S) - for(var/decl/material/dose as anything in M.chem_doses) - chemtraces |= initial(dose.name) + for(var/decl/material/dose in decls_repository.get_decls_unassociated(M.chem_doses)) + chemtraces |= dose.use_name else if(istype(A, /obj/item/organ/external)) set_target(A, user) @@ -65,11 +65,11 @@ if(timeofdeath) scan_data += "Time of death: [worldtime2stationtime(timeofdeath)]
    " - var/n = 1 + var/weapon_count = 1 for(var/weapon in weapon_data) var/list/organs = weapon_data[weapon]["organs"] var/datum/autopsy_data/data = weapon_data[weapon]["data"] - scan_data += "Weapon #[n++]: [data.weapon]" + scan_data += "Weapon #[weapon_count++]: [data.weapon]" if(data.hits) var/damage_desc switch(data.damage) diff --git a/code/modules/codex/categories/category_substances.dm b/code/modules/codex/categories/category_substances.dm index e8c96d49b729..6566d6694c06 100644 --- a/code/modules/codex/categories/category_substances.dm +++ b/code/modules/codex/categories/category_substances.dm @@ -3,8 +3,8 @@ desc = "Various natural and artificial substances." /decl/codex_category/substances/Populate() - - for(var/decl/material/mat as anything in SSmaterials.materials) + var/list/decl/material/alphabetized_materials = sortTim(decls_repository.get_decls_of_subtype_unassociated(/decl/material), /proc/cmp_name_asc) + for(var/decl/material/mat as anything in alphabetized_materials) if(mat.hidden_from_codex) continue @@ -67,8 +67,8 @@ if(mat.dissolves_in != MAT_SOLVENT_IMMUNE && LAZYLEN(mat.dissolves_into)) var/chems = list() for(var/chemical in mat.dissolves_into) - var/decl/material/R = chemical - chems += "[initial(R.name)] ([mat.dissolves_into[chemical]*100]%)" + var/decl/material/material = GET_DECL(chemical) + chems += "[material.name] ([mat.dissolves_into[chemical]*100]%)" var/solvent_needed if(mat.dissolves_in <= MAT_SOLVENT_NONE) solvent_needed = "any liquid" diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index d94349734ba9..0e0492966ced 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -292,16 +292,15 @@ /obj/item/integrated_circuit/input/gene_scanner/do_work() var/list/greagents = list() - var/obj/machinery/portable_atmospherics/hydroponics/H = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/portable_atmospherics/hydroponics) - if(!istype(H)) //Invalid input + var/obj/machinery/portable_atmospherics/hydroponics/plant = get_pin_data_as_type(IC_INPUT, 1, /obj/machinery/portable_atmospherics/hydroponics) + if(!istype(plant)) //Invalid input return for(var/i=1, i<=outputs.len, i++) set_pin_data(IC_OUTPUT, i, null) - if(H in view(get_turf(src))) // Like the medbot's analyzer it can be used at range. - if(H.seed) - for(var/chem_path in H.seed.chems) - var/decl/material/R = chem_path - greagents.Add(initial(R.name)) + if(plant.seed && (plant in view(get_turf(src)))) // Like the medbot's analyzer it can be used at range. + for(var/chem_path in plant.seed.chems) + var/decl/material/material = GET_DECL(chem_path) + greagents.Add(material.use_name) set_pin_data(IC_OUTPUT, 1, greagents) push_data() diff --git a/code/modules/reagents/chems/random/random_effects.dm b/code/modules/reagents/chems/random/random_effects.dm index 0ef001eb16ad..9136a9577f31 100644 --- a/code/modules/reagents/chems/random/random_effects.dm +++ b/code/modules/reagents/chems/random/random_effects.dm @@ -45,7 +45,7 @@ mode = RANDOM_CHEM_EFFECT_INT /decl/random_chem_effect/general_properties/name/on_property_recompute(var/decl/material/liquid/random/reagent, var/value) - reagent.name = "[initial(reagent.name)]-[value]" + reagent.name = "[initial(reagent.name)]-[value]" // this is a valid use of initial(reagent.name) since we're resetting it to the base value /decl/random_chem_effect/general_properties/color/get_random_value() return color_matrix_rotate_hue(round(rand(0,360),20)) diff --git a/code/modules/reagents/dispenser/cartridge_spawn.dm b/code/modules/reagents/dispenser/cartridge_spawn.dm index e88e3515f5cf..2d81ee8be767 100644 --- a/code/modules/reagents/dispenser/cartridge_spawn.dm +++ b/code/modules/reagents/dispenser/cartridge_spawn.dm @@ -1,13 +1,14 @@ -/client/proc/spawn_chemdisp_cartridge(size in list("small", "medium", "large"), reagent in decls_repository.get_decl_paths_of_subtype(/decl/material)) +/client/proc/spawn_chemdisp_cartridge(size in list("small", "medium", "large"), reagent_type in decls_repository.get_decl_paths_of_subtype(/decl/material)) set name = "Spawn Chemical Dispenser Cartridge" set category = "Admin" - var/obj/item/chems/chem_disp_cartridge/C + var/cartridge_type switch(size) - if("small") C = new /obj/item/chems/chem_disp_cartridge/small(usr.loc) - if("medium") C = new /obj/item/chems/chem_disp_cartridge/medium(usr.loc) - if("large") C = new /obj/item/chems/chem_disp_cartridge(usr.loc) - C.add_to_reagents(reagent, C.volume) - var/decl/material/R = reagent - C.setLabel(initial(R.name)) - log_and_message_admins("spawned a [size] reagent container containing [reagent]") + if("small") cartridge_type = /obj/item/chems/chem_disp_cartridge/small + if("medium") cartridge_type = /obj/item/chems/chem_disp_cartridge/medium + if("large") cartridge_type = /obj/item/chems/chem_disp_cartridge + var/obj/item/chems/chem_disp_cartridge/cartridge = new cartridge_type(usr.loc) + cartridge.add_to_reagents(reagent_type, cartridge.volume) + var/reagent_name = cartridge.reagents.get_primary_reagent_name() + cartridge.setLabel(reagent_name) + log_and_message_admins("spawned a [size] reagent container containing [reagent_name] ([reagent_type])") diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index a04958de0005..35110bc10b99 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -32,9 +32,9 @@ /obj/item/chems/borghypo/Initialize() . = ..() - for(var/decl/material/reagent as anything in reagent_ids) - reagent_volumes[reagent] = volume - reagent_names += initial(reagent.name) + for(var/decl/material/reagent in decls_repository.get_decls_unassociated(reagent_ids)) + reagent_volumes[reagent.type] = volume + reagent_names += reagent.use_name // TODO: should we even bother precaching this? all of this code sucks anyway START_PROCESSING(SSobj, src) /obj/item/chems/borghypo/Destroy() @@ -101,16 +101,16 @@ if(index > 0 && index <= reagent_ids.len) playsound(loc, 'sound/effects/pop.ogg', 50, 0) mode = index - var/decl/material/reagent = reagent_ids[mode] - to_chat(user, "Synthesizer is now producing '[initial(reagent.name)]'.") + var/decl/material/reagent = GET_DECL(reagent_ids[mode]) + to_chat(user, SPAN_NOTICE("Synthesizer is now producing '[reagent.use_name]'.")) return TOPIC_REFRESH /obj/item/chems/borghypo/get_examine_strings(mob/user, distance, infix, suffix) . = ..() if(distance > 2) return - var/decl/material/reagent = reagent_ids[mode] - . += SPAN_NOTICE("It is currently producing [initial(reagent.name)] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left.") + var/decl/material/reagent = GET_DECL(reagent_ids[mode]) + . += SPAN_NOTICE("It is currently producing [reagent.use_name] and has [reagent_volumes[reagent_ids[mode]]] out of [volume] units left.") /obj/item/chems/borghypo/service name = "cyborg drink synthesizer" diff --git a/code/modules/reagents/reagent_containers/food/lunch.dm b/code/modules/reagents/reagent_containers/food/lunch.dm index fc4f92672c18..0a1b7aa8daaa 100644 --- a/code/modules/reagents/reagent_containers/food/lunch.dm +++ b/code/modules/reagents/reagent_containers/food/lunch.dm @@ -103,8 +103,8 @@ var/global/list/lunchables_ethanol_reagents_ = list( /proc/init_lunchable_list(var/list/lunches) . = list() for(var/lunch in lunches) - var/obj/O = lunch - .[initial(O.name)] = lunch + var/object_name = atom_info_repository.get_name_for(lunch) + .[object_name] = lunch return sortTim(., /proc/cmp_text_asc) /proc/init_lunchable_reagent_list(var/list/banned_reagents, var/reagent_type) @@ -112,6 +112,6 @@ var/global/list/lunchables_ethanol_reagents_ = list( for(var/reagent_subtype in decls_repository.get_decls_of_type(reagent_type)) if(reagent_subtype in banned_reagents) continue - var/decl/material/reagent = reagent_subtype - .[initial(reagent.name)] = reagent_subtype + var/decl/material/reagent = GET_DECL(reagent_subtype) + .[reagent.liquid_name] = reagent_subtype return sortTim(., /proc/cmp_text_asc) diff --git a/code/modules/scanners/health.dm b/code/modules/scanners/health.dm index 20db2e1f9cda..2ad64584cdcb 100644 --- a/code/modules/scanners/health.dm +++ b/code/modules/scanners/health.dm @@ -244,11 +244,11 @@ if(H.reagents.total_volume) var/unknown = 0 var/reagentdata[0] - for(var/A in H.reagents.reagent_volumes) - var/decl/material/R = GET_DECL(A) - if(R.scannable) + for(var/rtype in H.reagents.reagent_volumes) + var/decl/material/injected_reagent = GET_DECL(rtype) + if(injected_reagent.scannable) print_reagent_default_message = FALSE - reagentdata[A] = "[round(REAGENT_VOLUME(H.reagents, A), 1)]u [R.use_name]" + reagentdata[rtype] = "[round(REAGENT_VOLUME(H.reagents, rtype), 1)]u [injected_reagent.use_name]" else unknown++ if(reagentdata.len) @@ -264,11 +264,11 @@ if(touching_reagents && touching_reagents.total_volume) var/unknown = 0 var/reagentdata[0] - for(var/A in touching_reagents.reagent_volumes) - var/decl/material/R = GET_DECL(A) - if(R.scannable) + for(var/rtype in touching_reagents.reagent_volumes) + var/decl/material/touched_reagent = GET_DECL(rtype) + if(touched_reagent.scannable) print_reagent_default_message = FALSE - reagentdata[R.type] = "[round(REAGENT_VOLUME(H.reagents, R.type), 1)]u [R.name]" + reagentdata[rtype] = "[round(REAGENT_VOLUME(H.reagents, rtype), 1)]u [touched_reagent.use_name]" else unknown++ if(reagentdata.len) @@ -284,10 +284,10 @@ if(ingested && ingested.total_volume) var/unknown = 0 for(var/rtype in ingested.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - if(R.scannable) + var/decl/material/ingested_reagent = GET_DECL(rtype) + if(ingested_reagent.scannable) print_reagent_default_message = FALSE - . += "[capitalize(R.use_name)] found in subject's stomach." + . += "[capitalize(ingested_reagent.use_name)] found in subject's stomach." else ++unknown if(unknown) @@ -298,10 +298,10 @@ if(inhaled && inhaled.total_volume) var/unknown = 0 for(var/rtype in inhaled.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - if(R.scannable) + var/decl/material/inhaled_reagent = GET_DECL(rtype) + if(inhaled_reagent.scannable) print_reagent_default_message = FALSE - . += "[capitalize(R.use_name)] found in subject's lungs." + . += "[capitalize(inhaled_reagent.use_name)] found in subject's lungs." else ++unknown if(unknown) @@ -310,10 +310,10 @@ if(length(H.chem_doses)) var/list/chemtraces = list() - for(var/T in H.chem_doses) - var/decl/material/R = T - if(initial(R.scannable)) - chemtraces += "[initial(R.name)] ([LAZYACCESS(H.chem_doses, T)])" + for(var/dose_type in H.chem_doses) + var/decl/material/dose_material = GET_DECL(dose_type) + if(dose_material.scannable) + chemtraces += "[dose_material.use_name] ([LAZYACCESS(H.chem_doses, dose_type)])" if(chemtraces.len) . += "Metabolism products of [english_list(chemtraces)] found in subject's system." diff --git a/code/modules/scanners/mass_spectrometer.dm b/code/modules/scanners/mass_spectrometer.dm index e04924c6d7ec..ff7b3e0df2c7 100644 --- a/code/modules/scanners/mass_spectrometer.dm +++ b/code/modules/scanners/mass_spectrometer.dm @@ -47,8 +47,8 @@ ..() /proc/mass_spectrometer_scan(var/datum/reagents/reagents, mob/user, var/details) - if(!reagents || !reagents.total_volume) - return "No sample to scan." + if(!reagents?.total_volume) + return SPAN_WARNING("No sample to scan.") var/list/blood_traces = list() var/list/blood_doses = list() @@ -57,27 +57,27 @@ if(istype(random)) return random.get_scan_data(user) - for(var/R in reagents.reagent_volumes) - if(!ispath(R, /decl/material/liquid/blood)) - return "The sample was contaminated! Please insert another sample" - var/data = REAGENT_DATA(reagents, R) + for(var/reagent_type in reagents.reagent_volumes) + if(!ispath(reagent_type, /decl/material/liquid/blood)) + return SPAN_WARNING("The sample was contaminated! Please insert another sample.") + var/data = REAGENT_DATA(reagents, reagent_type) if(islist(data)) blood_traces = data[DATA_BLOOD_TRACE_CHEM] blood_doses = data[DATA_BLOOD_DOSE_CHEM] break var/list/dat = list("Trace Chemicals Found: ") - for(var/T in blood_traces) - var/decl/material/R = T + for(var/trace_type in blood_traces) + var/decl/material/trace_material = GET_DECL(trace_type) if(details) - dat += "[initial(R.name)] ([blood_traces[T]] units) " + dat += "[trace_material.use_name] ([blood_traces[trace_type]] units) " else - dat += "[initial(R.name)] " + dat += "[trace_material.use_name] " if(details) dat += "Metabolism Products of Chemicals Found:" - for(var/T in blood_doses) - var/decl/material/R = T - dat += "[initial(R.name)] ([blood_doses[T]] units) " + for(var/dose_type in blood_doses) + var/decl/material/dose_material = GET_DECL(dose_type) + dat += "[dose_material.use_name] ([blood_doses[dose_type]] units) " return jointext(dat, "
    ") From 9509557bcd0308cc280e8d528e20b667a2b85876 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 02:45:47 -0500 Subject: [PATCH 027/512] Remove unused SSmaterials.materials var --- .../subsystems/initialization/materials.dm | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/code/controllers/subsystems/initialization/materials.dm b/code/controllers/subsystems/initialization/materials.dm index d82b3df641bb..9ce2feb2c266 100644 --- a/code/controllers/subsystems/initialization/materials.dm +++ b/code/controllers/subsystems/initialization/materials.dm @@ -6,8 +6,6 @@ SUBSYSTEM_DEF(materials) priority = SS_PRIORITY_MATERIALS // Material vars. - var/list/materials - var/list/strata var/list/fusion_reactions var/list/weighted_minerals_sparse = list() var/list/weighted_minerals_rich = list() @@ -54,9 +52,8 @@ SUBSYSTEM_DEF(materials) sortTim(cocktails_by_primary_ingredient[reagent], /proc/cmp_cocktail_des) // Various other material functions. - build_material_lists() // Build core material lists. + build_mineral_weight_lists() build_fusion_reaction_list() // Build fusion reaction tree. - materials = sortTim(SSmaterials.materials, /proc/cmp_name_asc) var/alpha_inc = 256 / DAMAGE_OVERLAY_COUNT for(var/i = 1; i <= DAMAGE_OVERLAY_COUNT; i++) @@ -65,18 +62,11 @@ SUBSYSTEM_DEF(materials) img.alpha = (i * alpha_inc) - 1 LAZYADD(wall_damage_overlays, img) - strata = decls_repository.get_decls_of_subtype(/decl/strata) // for debug VV purposes - . = ..() -/datum/controller/subsystem/materials/proc/build_material_lists() - if(LAZYLEN(materials)) - return - materials = list() - var/list/material_decls = decls_repository.get_decls_of_subtype(/decl/material) - for(var/mtype in material_decls) - var/decl/material/new_mineral = material_decls[mtype] - materials += new_mineral +/datum/controller/subsystem/materials/proc/build_mineral_weight_lists() + var/list/material_decls = decls_repository.get_decls_of_subtype_unassociated(/decl/material) + for(var/decl/material/new_mineral as anything in material_decls) if(new_mineral.sparse_material_weight) weighted_minerals_sparse[new_mineral.type] = new_mineral.sparse_material_weight if(new_mineral.rich_material_weight) From 4bb27b63fd847c0d46c3b305123dad42c145bec8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 02:46:57 -0500 Subject: [PATCH 028/512] Make category datums not use initial(name) --- code/_helpers/global_lists.dm | 3 --- code/datums/category.dm | 25 +++++++++++-------- code/datums/underwear/bottom.dm | 1 + code/datums/underwear/socks.dm | 1 + code/datums/underwear/top.dm | 1 + code/datums/underwear/undershirt.dm | 1 + code/datums/underwear/underwear.dm | 4 +++ .../antagonism/01_candidacy.dm | 3 +++ .../preference_setup/background/01_species.dm | 3 +++ .../controls/01_keybindings.dm | 3 +++ .../preference_setup/general/01_basic.dm | 3 +++ .../client/preference_setup/global/01_ui.dm | 3 +++ .../preference_setup/loadout/loadout.dm | 9 +++---- .../preference_setup/preference_setup.dm | 4 +++ .../preference_setup/records/00_records.dm | 1 + 15 files changed, 46 insertions(+), 19 deletions(-) diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 7b98b5f58af5..baa48fe542cd 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -9,9 +9,6 @@ var/global/list/mannequins_ // Uplinks var/global/list/obj/item/uplink/world_uplinks = list() -//Preferences stuff -var/global/datum/category_collection/underwear/underwear = new() - // Visual nets var/global/list/datum/visualnet/visual_nets = list() var/global/datum/visualnet/camera/cameranet = new() diff --git a/code/datums/category.dm b/code/datums/category.dm index 1c2688ff57d3..d345573374c9 100644 --- a/code/datums/category.dm +++ b/code/datums/category.dm @@ -12,16 +12,16 @@ categories_by_name = new() for(var/category_type in typesof(category_group_type)) var/datum/category_group/category = category_type - if(initial(category.name)) - category = new category(src) - categories += category - categories_by_name[category.name] = category + if(TYPE_IS_ABSTRACT(category)) + continue + category = new category(src) + categories += category + ASSERT(category.name) + categories_by_name[category.name] = category categories = sortTim(categories, /proc/cmp_category_groups) /datum/category_collection/Destroy() - for(var/category in categories) - qdel(category) - categories.Cut() + QDEL_LIST(categories) return ..() /****************** @@ -43,10 +43,12 @@ for(var/item_type in typesof(category_item_type)) var/datum/category_item/item = item_type - if(initial(item.name)) - item = new item(src) - items += item - items_by_name[item.name] = item + if(TYPE_IS_ABSTRACT(item)) + continue + item = new item(src) + items += item + ASSERT(item.name) + items_by_name[item.name] = item // For whatever reason dd_insertObjectList(items, item) doesn't insert in the correct order // If you change this, confirm that character setup doesn't become completely unordered. @@ -67,6 +69,7 @@ * Category Items * *****************/ /datum/category_item + abstract_type = /datum/category_item var/name = "" var/datum/category_group/category // The group this item belongs to diff --git a/code/datums/underwear/bottom.dm b/code/datums/underwear/bottom.dm index a2ed61658161..fc8bd4a2ee30 100644 --- a/code/datums/underwear/bottom.dm +++ b/code/datums/underwear/bottom.dm @@ -1,4 +1,5 @@ /datum/category_item/underwear/bottom + abstract_type = /datum/category_item/underwear/bottom underwear_gender = PLURAL underwear_name = "underwear" underwear_type = /obj/item/underwear/bottom diff --git a/code/datums/underwear/socks.dm b/code/datums/underwear/socks.dm index 4b2689521937..70dc7454dce7 100644 --- a/code/datums/underwear/socks.dm +++ b/code/datums/underwear/socks.dm @@ -1,4 +1,5 @@ /datum/category_item/underwear/socks + abstract_type = /datum/category_item/underwear/socks underwear_name = "socks" underwear_gender = PLURAL underwear_type = /obj/item/underwear/socks diff --git a/code/datums/underwear/top.dm b/code/datums/underwear/top.dm index 6b559214f65e..816df62549df 100644 --- a/code/datums/underwear/top.dm +++ b/code/datums/underwear/top.dm @@ -1,4 +1,5 @@ /datum/category_item/underwear/top + abstract_type = /datum/category_item/underwear/top underwear_name = "bra" underwear_type = /obj/item/underwear/top diff --git a/code/datums/underwear/undershirt.dm b/code/datums/underwear/undershirt.dm index ad2f3c3691f7..ae4ac6a5d603 100644 --- a/code/datums/underwear/undershirt.dm +++ b/code/datums/underwear/undershirt.dm @@ -1,4 +1,5 @@ /datum/category_item/underwear/undershirt + abstract_type = /datum/category_item/underwear/undershirt underwear_name = "undershirt" underwear_type = /obj/item/underwear/undershirt diff --git a/code/datums/underwear/underwear.dm b/code/datums/underwear/underwear.dm index a42fcf1a66f1..637bfe749ce5 100644 --- a/code/datums/underwear/underwear.dm +++ b/code/datums/underwear/underwear.dm @@ -1,6 +1,7 @@ /**************************** * Category Collection Setup * ****************************/ +var/global/datum/category_collection/underwear/underwear = new() /datum/category_collection/underwear category_group_type = /datum/category_group/underwear @@ -8,6 +9,9 @@ * Categories * *************/ // Lower sort order is applied as icons first +/datum/category_group/underwear + abstract_type = /datum/category_group/underwear + /datum/category_group/underwear/top name = "Underwear, top" sort_order = 1 diff --git a/code/modules/client/preference_setup/antagonism/01_candidacy.dm b/code/modules/client/preference_setup/antagonism/01_candidacy.dm index 40ad53d76f03..da9e0f65cb9b 100644 --- a/code/modules/client/preference_setup/antagonism/01_candidacy.dm +++ b/code/modules/client/preference_setup/antagonism/01_candidacy.dm @@ -2,6 +2,9 @@ var/list/may_be_special_role var/list/be_special_role +/datum/category_item/player_setup_item/antagonism + abstract_type = /datum/category_item/player_setup_item/antagonism + /datum/category_item/player_setup_item/antagonism/candidacy name = "Candidacy" sort_order = 1 diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index 3f8e52d19e78..6e0e9c68b734 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -1,3 +1,6 @@ +/datum/category_item/player_setup_item/background + abstract_type = /datum/category_item/player_setup_item/background + /datum/category_item/player_setup_item/background/species name = "Species" sort_order = 1 diff --git a/code/modules/client/preference_setup/controls/01_keybindings.dm b/code/modules/client/preference_setup/controls/01_keybindings.dm index eccfd9ecccf3..444274f1b5c8 100644 --- a/code/modules/client/preference_setup/controls/01_keybindings.dm +++ b/code/modules/client/preference_setup/controls/01_keybindings.dm @@ -47,6 +47,9 @@ to_chat(client, SPAN_DANGER("[conflicted.category]: [conflicted.full_name] needs updating.")) LAZYADD(key_bindings["Unbound"], conflicted.name) // set it to unbound to prevent this from opening up again in the future +/datum/category_item/player_setup_item/controls + abstract_type = /datum/category_item/player_setup_item/controls + /datum/category_item/player_setup_item/controls/keybindings name = "Keybindings" sort_order = 1 diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index b33b09d48bf7..88fda089b841 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -15,6 +15,9 @@ var/decl/species/species_decl = get_species_decl() return species_decl.get_bodytype_by_name(bodytype) || species_decl.default_bodytype +/datum/category_item/player_setup_item/physical + abstract_type = /datum/category_item/player_setup_item/physical + /datum/category_item/player_setup_item/physical/basic name = "Basic" sort_order = 1 diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index f48998316cc7..444ab4ec5a35 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -13,6 +13,9 @@ var/global/list/valid_icon_sizes = list(32, 48, 64, 96, 128) //Style for popup tooltips var/tooltip_style = "Midnight" +/datum/category_item/player_setup_item/player_global + abstract_type = /datum/category_item/player_setup_item/player_global + /datum/category_item/player_setup_item/player_global/ui name = "UI" sort_order = 1 diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 1555f26fd222..03f7ff92721f 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -263,14 +263,13 @@ entry += "
    " var/list/skill_checks = list() - for(var/R in skills_required) - var/decl/skill/S = R + for(var/decl/skill/required_skill in skills_required) var/skill_entry - skill_entry += "[S.levels[skills_required[R]]]" + skill_entry += "[required_skill.levels[skills_required[required_skill]]]" if(allowed) - skill_entry = "[skill_entry] [R]" + skill_entry = "[skill_entry] [required_skill]" else - skill_entry = "[skill_entry] [R]" + skill_entry = "[skill_entry] [required_skill]" skill_checks += skill_entry entry += "[english_list(skill_checks)]" diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index 06bdf434ba50..338e90db217f 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -1,5 +1,8 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" +/datum/category_group/player_setup_category + abstract_type = /datum/category_group/player_setup_category + /datum/category_group/player_setup_category/background_preferences name = "Background" sort_order = 1 // must go first because species @@ -181,6 +184,7 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" * Category Item Setup * **********************/ /datum/category_item/player_setup_item + abstract_type = /datum/category_item/player_setup_item var/sort_order = 0 var/datum/preferences/pref diff --git a/code/modules/client/preference_setup/records/00_records.dm b/code/modules/client/preference_setup/records/00_records.dm index 17146b1067dd..85a40a1a8f81 100644 --- a/code/modules/client/preference_setup/records/00_records.dm +++ b/code/modules/client/preference_setup/records/00_records.dm @@ -2,6 +2,7 @@ var/list/records = list() /datum/category_item/player_setup_item/records + abstract_type = /datum/category_item/player_setup_item/records var/record_key /datum/category_item/player_setup_item/records/content(var/mob/user) From 7e4acf4039eca83af840f7d1b6c1d8e7b172d7c8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 02:47:14 -0500 Subject: [PATCH 029/512] Remove a number of uses of initial(name) --- .../objects/items/weapons/material/stick.dm | 2 +- .../items/weapons/storage/fancy/_fancy.dm | 2 +- .../codex/categories/category_recipes.dm | 36 ++++++++++++++----- .../codex/categories/category_substances.dm | 5 ++- code/modules/codex/entries/_codex_entry.dm | 8 +++-- .../goals/definitions/department_clerical.dm | 6 ++-- .../personal_achievement_specific_object.dm | 2 +- code/unit_tests/unit_test.dm | 2 +- 8 files changed, 40 insertions(+), 23 deletions(-) diff --git a/code/game/objects/items/weapons/material/stick.dm b/code/game/objects/items/weapons/material/stick.dm index d752ca73f46d..8cddca3effdc 100644 --- a/code/game/objects/items/weapons/material/stick.dm +++ b/code/game/objects/items/weapons/material/stick.dm @@ -43,7 +43,7 @@ return TRUE if(cloth.get_amount() < cloth_cost) - to_chat(user, SPAN_WARNING("You need at least [cloth_cost] unit\s of material to create \a [initial(product_type.name)].")) + to_chat(user, SPAN_WARNING("You need at least [cloth_cost] unit\s of material to create \a [atom_info_repository.get_name_for(product_type)].")) return TRUE // Ugly way to check for dried grass vs regular grass. diff --git a/code/game/objects/items/weapons/storage/fancy/_fancy.dm b/code/game/objects/items/weapons/storage/fancy/_fancy.dm index 7dbc2d00ee76..44f9cd602a65 100644 --- a/code/game/objects/items/weapons/storage/fancy/_fancy.dm +++ b/code/game/objects/items/weapons/storage/fancy/_fancy.dm @@ -49,4 +49,4 @@ if(distance > 1 || !key_type) return var/key_count = count_by_type(contents, key_type) - . += "There [key_count == 1? "is" : "are"] [key_count] [initial(key_type.name)]\s in the box." + . += "There [key_count == 1? "is" : "are"] [key_count] [atom_info_repository.get_name_for(key_type)]\s in the box." diff --git a/code/modules/codex/categories/category_recipes.dm b/code/modules/codex/categories/category_recipes.dm index caf8064f577f..a73c524b228c 100644 --- a/code/modules/codex/categories/category_recipes.dm +++ b/code/modules/codex/categories/category_recipes.dm @@ -34,12 +34,13 @@ continue category_name = "mix recipe" lore_text = initial(product.desc) - mechanics_text = "This recipe produces \a [initial(product.name)].
    It should be performed in a mixing bowl or beaker, and requires the following ingredients:" + var/product_name = (ispath(product, /atom/movable) && TYPE_IS_SPAWNABLE(product)) ? atom_info_repository.get_name_for(product) : initial(product.name) + mechanics_text = "This recipe produces \a [product_name].
    It should be performed in a mixing bowl or beaker, and requires the following ingredients:" else var/decl/material/product = GET_DECL(food.result) if(!product) continue - lore_text = initial(product.lore_text) + lore_text = product.lore_text if(ispath(food.result, /decl/material/liquid/drink) || ispath(food.result, /decl/material/liquid/alcohol)) category_name = "drink recipe" mechanics_text = "This recipe produces [food.result_amount]u [product.name].
    It should be performed in a glass or shaker, and requires the following ingredients:" @@ -84,13 +85,18 @@ for(var/thing in recipe.reagents) var/decl/material/thing_reagent = GET_DECL(thing) ingredients += "[recipe.reagents[thing]]u [thing_reagent.name]" - for(var/thing in recipe.items) - var/atom/thing_atom = thing + for(var/atom/thing as anything in recipe.items) var/count = recipe.items[thing] - var/thing_name = initial(thing_atom.name) + var/thing_name = initial(thing.name) + if(ispath(thing, /atom/movable) && TYPE_IS_SPAWNABLE(thing)) + thing_name = atom_info_repository.get_name_for(thing) if(SScodex.get_entry_by_string(thing_name)) thing_name = "[thing_name]" - ingredients += (count > 1) ? "[count]x [thing_name]" : "\a [initial(thing_atom.name)]" + else + var/datum/codex_entry/result_entry = SScodex.get_codex_entry(thing) + if(result_entry) + thing_name = "[thing_name]" + ingredients += (count > 1) ? "[count]x [thing_name]" : "\a [thing_name]" for(var/thing in recipe.fruit) ingredients += "[recipe.fruit[thing]] [thing]\s" mechanics_text += "
    • [jointext(ingredients, "
    • ")]
    " @@ -100,13 +106,25 @@ cooking_methods += "\a [cooking_method]" var/atom/recipe_product = recipe.result - mechanics_text += "
    This recipe takes [ceil(recipe.cooking_time/10)] second\s to cook in [english_list(cooking_methods, and_text = " or ")] and creates \a [initial(recipe_product.name)]." + var/product_name + var/product_link var/lore_text = recipe.lore_text + if(ispath(recipe_product, /atom/movable) && TYPE_IS_SPAWNABLE(recipe_product)) + product_name = atom_info_repository.get_name_for(recipe_product) + else if(ispath(recipe.result, /decl/material)) + var/decl/material/result_reagent = GET_DECL(recipe.result) + product_name = result_reagent.use_name + product_link = "some [product_name]" + lore_text ||= result_reagent.lore_text + else // some things can't be spawned by the atom info repository because they need extra args we can't pass + product_name = initial(recipe_product.name) + product_link ||= "\a [product_name]" + mechanics_text += "
    This recipe takes [ceil(recipe.cooking_time/(1 SECOND))] second\s to cook in [english_list(cooking_methods, and_text = " or ")] and creates [product_link]." if(!lore_text) lore_text = initial(recipe_product.desc) - var/recipe_name = recipe.display_name || sanitize(initial(recipe_product.name)) - guide_html += "

    [capitalize(recipe_name)]

    Cook [english_list(ingredients)] for [ceil(recipe.cooking_time/10)] second\s." + var/recipe_name = recipe.display_name || sanitize(product_name) + guide_html += "

    [capitalize(recipe_name)]

    Cook [english_list(ingredients)] for [ceil(recipe.cooking_time/(1 SECOND))] second\s." entries_to_register += new /datum/codex_entry( \ _display_name = "[recipe_name] (cooking recipe)", \ diff --git a/code/modules/codex/categories/category_substances.dm b/code/modules/codex/categories/category_substances.dm index 6566d6694c06..9771477402fe 100644 --- a/code/modules/codex/categories/category_substances.dm +++ b/code/modules/codex/categories/category_substances.dm @@ -35,16 +35,15 @@ var/decl/material/catalyst = GET_DECL(catalyst_id) catalysts += "[reaction.catalysts[catalyst_id]]u [catalyst.name]" - var/decl/material/result = reaction.result var/mix_link = "Mixing" if(istype(reaction, /decl/chemical_reaction/alloy)) mix_link = "Alloying" mix_link = "[mix_link]" if(catalysts.len) - production_strings += "[mix_link] [english_list(reactant_values)], catalyzed by [english_list(catalysts)], producing [reaction.result_amount]u [lowertext(initial(result.name))]." + production_strings += "[mix_link] [english_list(reactant_values)], catalyzed by [english_list(catalysts)], producing [reaction.result_amount]u [mat.name]." else - production_strings += "[mix_link] [english_list(reactant_values)], producing [reaction.result_amount]u [lowertext(initial(result.name))]." + production_strings += "[mix_link] [english_list(reactant_values)], producing [reaction.result_amount]u [mat.name]." // Todo: smelting and compressing if(length(production_strings)) diff --git a/code/modules/codex/entries/_codex_entry.dm b/code/modules/codex/entries/_codex_entry.dm index 3aad339753be..62f5b134b64e 100644 --- a/code/modules/codex/entries/_codex_entry.dm +++ b/code/modules/codex/entries/_codex_entry.dm @@ -46,9 +46,11 @@ if(_antag_text) antag_text = _antag_text if(store_codex_entry && length(associated_paths)) - for(var/tpath in associated_paths) - var/atom/thing = tpath - var/thing_name = codex_sanitize(initial(thing.name)) + for(var/atom/thing as anything in associated_paths) + var/thing_name = initial(thing.name) + if(ispath(thing, /atom/movable) && TYPE_IS_SPAWNABLE(thing)) + thing_name = atom_info_repository.get_name_for(thing) + thing_name = codex_sanitize(thing_name) if(disambiguator) thing_name = "[thing_name] ([disambiguator])" LAZYDISTINCTADD(associated_strings, thing_name) diff --git a/code/modules/goals/definitions/department_clerical.dm b/code/modules/goals/definitions/department_clerical.dm index 75ac548eb873..c3afb787efe7 100644 --- a/code/modules/goals/definitions/department_clerical.dm +++ b/code/modules/goals/definitions/department_clerical.dm @@ -20,8 +20,7 @@ SSgoals.pending_goals -= src return paperwork_type = pick(paperwork_types) - var/obj/item/paperwork/paperwork_type_obj = paperwork_type - waiting_for_signatories_description = replacetext(waiting_for_signatories_description, "%PAPERWORK%", "\the [initial(paperwork_type_obj.name)]") + waiting_for_signatories_description = replacetext(waiting_for_signatories_description, "%PAPERWORK%", "\the [atom_info_repository.get_name_for(paperwork_type)]") ..() @@ -74,8 +73,7 @@ if(!generated_paperwork) description = waiting_for_signatories_description else if(QDELETED(paperwork_instance)) - var/obj/item/paperwork/paperwork_type_obj = paperwork_type - description = "\The [initial(paperwork_type_obj.name)] has been destroyed." + description = "\The [atom_info_repository.get_name_for(paperwork_type)] has been destroyed." else if(length(paperwork_instance.needs_signed)) description = "Have \the [paperwork_instance] signed by [english_list(paperwork_instance.all_signatories)]." else diff --git a/code/modules/goals/definitions/personal_achievement_specific_object.dm b/code/modules/goals/definitions/personal_achievement_specific_object.dm index 722a4dbb199b..93c4883eedf9 100644 --- a/code/modules/goals/definitions/personal_achievement_specific_object.dm +++ b/code/modules/goals/definitions/personal_achievement_specific_object.dm @@ -65,4 +65,4 @@ /datum/goal/achievement/specific_object/pet/update_strings() ..() var/mob/animal = object_path - description = "Pet \a [initial(animal.name)]." + description = "Pet \a [initial(animal.name)]." // probably best not to use the atom info repository for this, lest we get 'Pet a monkey (666).' diff --git a/code/unit_tests/unit_test.dm b/code/unit_tests/unit_test.dm index 24fd800c8544..47b103f626ea 100644 --- a/code/unit_tests/unit_test.dm +++ b/code/unit_tests/unit_test.dm @@ -211,8 +211,8 @@ var/global/ascii_reset = "[ascii_esc]\[0m" if(!check_rights(R_DEBUG)) return - log_and_message_admins("has started the unit test '[initial(unit_test_type.name)]'") var/datum/unit_test/test = new unit_test_type + log_and_message_admins("has started the unit test '[test.name]'") var/end_unit_tests = world.time + MAX_UNIT_TEST_RUN_TIME do_unit_test(test, end_unit_tests, FALSE) if(test.async) From 8fa99559785da125a52f5c20736b366a3633fe19 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 21:21:06 -0500 Subject: [PATCH 030/512] Replace several instances of initial(desc) --- code/datums/repositories/atom_info.dm | 9 +++++++++ code/modules/codex/categories/category_recipes.dm | 12 ++++++++---- code/modules/codex/categories/category_substances.dm | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/code/datums/repositories/atom_info.dm b/code/datums/repositories/atom_info.dm index 4bfb7a4b8233..c8c18c2e83da 100644 --- a/code/datums/repositories/atom_info.dm +++ b/code/datums/repositories/atom_info.dm @@ -5,6 +5,7 @@ var/global/repository/atom_info/atom_info_repository = new() var/list/combined_worth_cache = list() var/list/single_worth_cache = list() var/list/name_cache = list() + var/list/description_cache = list() var/list/matter_mult_cache = list() var/list/origin_tech_cache = list() @@ -37,6 +38,9 @@ var/global/repository/atom_info/atom_info_repository = new() if(!name_cache[key]) instance = instance || get_instance_of(path, material, amount) name_cache[key] = instance.name + if(!description_cache[key]) + instance = instance || get_instance_of(path, material, amount) + description_cache[key] = instance.desc if(!matter_mult_cache[key] && ispath(path, /obj)) var/obj/obj_instance = instance || get_instance_of(path, material, amount) matter_mult_cache[key] = obj_instance.get_matter_amount_modifier() @@ -67,6 +71,11 @@ var/global/repository/atom_info/atom_info_repository = new() update_cached_info_for(path, material, amount, key) . = name_cache[key] +/repository/atom_info/proc/get_description_for(var/path, var/material, var/amount) + var/key = create_key_for(path, material, amount) + update_cached_info_for(path, material, amount, key) + . = description_cache[key] + /repository/atom_info/proc/get_matter_multiplier_for(var/path, var/material, var/amount) var/key = create_key_for(path, material, amount) update_cached_info_for(path, material, amount, key) diff --git a/code/modules/codex/categories/category_recipes.dm b/code/modules/codex/categories/category_recipes.dm index a73c524b228c..46403278f40d 100644 --- a/code/modules/codex/categories/category_recipes.dm +++ b/code/modules/codex/categories/category_recipes.dm @@ -33,8 +33,12 @@ if(!product) continue category_name = "mix recipe" - lore_text = initial(product.desc) - var/product_name = (ispath(product, /atom/movable) && TYPE_IS_SPAWNABLE(product)) ? atom_info_repository.get_name_for(product) : initial(product.name) + var/product_name = initial(product.name) + if(ispath(product, /atom/movable) && TYPE_IS_SPAWNABLE(product)) + product_name = atom_info_repository.get_name_for(product) + lore_text = atom_info_repository.get_description_for(product) + else + lore_text = initial(product.desc) mechanics_text = "This recipe produces \a [product_name].
    It should be performed in a mixing bowl or beaker, and requires the following ingredients:" else var/decl/material/product = GET_DECL(food.result) @@ -111,6 +115,7 @@ var/lore_text = recipe.lore_text if(ispath(recipe_product, /atom/movable) && TYPE_IS_SPAWNABLE(recipe_product)) product_name = atom_info_repository.get_name_for(recipe_product) + lore_text ||= atom_info_repository.get_description_for(recipe_product) else if(ispath(recipe.result, /decl/material)) var/decl/material/result_reagent = GET_DECL(recipe.result) product_name = result_reagent.use_name @@ -118,10 +123,9 @@ lore_text ||= result_reagent.lore_text else // some things can't be spawned by the atom info repository because they need extra args we can't pass product_name = initial(recipe_product.name) + lore_text ||= initial(recipe_product.desc) product_link ||= "\a [product_name]" mechanics_text += "
    This recipe takes [ceil(recipe.cooking_time/(1 SECOND))] second\s to cook in [english_list(cooking_methods, and_text = " or ")] and creates [product_link]." - if(!lore_text) - lore_text = initial(recipe_product.desc) var/recipe_name = recipe.display_name || sanitize(product_name) guide_html += "

    [capitalize(recipe_name)]

    Cook [english_list(ingredients)] for [ceil(recipe.cooking_time/(1 SECOND))] second\s." diff --git a/code/modules/codex/categories/category_substances.dm b/code/modules/codex/categories/category_substances.dm index 9771477402fe..1ad0efa52120 100644 --- a/code/modules/codex/categories/category_substances.dm +++ b/code/modules/codex/categories/category_substances.dm @@ -9,7 +9,7 @@ if(mat.hidden_from_codex) continue - var/new_lore_text = initial(mat.lore_text) + var/new_lore_text = mat.lore_text if(mat.taste_description) if(new_lore_text) new_lore_text = "[new_lore_text]

    " From d3a9ee4a7e93334d0ab1f98ef195c9a83f99e106 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 22:46:58 -0500 Subject: [PATCH 031/512] Allow slag to show up in the codex --- code/modules/codex/categories/category_substances.dm | 5 ++++- .../materials/definitions/solids/materials_solid_mundane.dm | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/codex/categories/category_substances.dm b/code/modules/codex/categories/category_substances.dm index 1ad0efa52120..acd97e206bcb 100644 --- a/code/modules/codex/categories/category_substances.dm +++ b/code/modules/codex/categories/category_substances.dm @@ -67,7 +67,10 @@ var/chems = list() for(var/chemical in mat.dissolves_into) var/decl/material/material = GET_DECL(chemical) - chems += "[material.name] ([mat.dissolves_into[chemical]*100]%)" + var/material_link = "[material.name]" + if(material.hidden_from_codex) + material_link = material.name + chems += "[material_link] ([mat.dissolves_into[chemical]*100]%)" var/solvent_needed if(mat.dissolves_in <= MAT_SOLVENT_NONE) solvent_needed = "any liquid" diff --git a/code/modules/materials/definitions/solids/materials_solid_mundane.dm b/code/modules/materials/definitions/solids/materials_solid_mundane.dm index 8579088f2f26..039405d95068 100644 --- a/code/modules/materials/definitions/solids/materials_solid_mundane.dm +++ b/code/modules/materials/definitions/solids/materials_solid_mundane.dm @@ -5,7 +5,6 @@ ore_name = "slag" ore_desc = "Someone messed up..." ore_icon_overlay = "lump" - hidden_from_codex = TRUE reflectiveness = MAT_VALUE_DULL wall_support_value = MAT_VALUE_LIGHT value = 0.1 From 0e4f73c0a8cf4b9e832f03162f24cc275d08fb1c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 00:10:49 -0500 Subject: [PATCH 032/512] Add a test to check for missing stat_immune flags on machines --- code/unit_tests/machine_tests.dm | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/code/unit_tests/machine_tests.dm b/code/unit_tests/machine_tests.dm index bcb10b27b2fe..3c9258787e65 100644 --- a/code/unit_tests/machine_tests.dm +++ b/code/unit_tests/machine_tests.dm @@ -86,3 +86,36 @@ else pass("All machines had valid basetypes.") return 1 + +/datum/unit_test/machines_shall_have_sane_stat_immune + name = "MACHINE: All machines that do not require screens/keyboards must have NOSCREEN/NOINPUT stat immunity." + +/datum/unit_test/machines_shall_have_sane_stat_immune/start_test() + var/failed = list() + var/passed = list() + for(var/obj/machinery/machine as anything in SSmachines.machinery) + var/candidate_type = machine.base_type || machine.type + if(isnull(machine.construct_state)) + continue + if(passed[candidate_type] || failed[candidate_type]) + continue + var/obj/item/stock_parts/circuitboard/board = machine.get_component_of_type(/obj/item/stock_parts/circuitboard) + var/has_screen = machine.get_component_of_type(/obj/item/stock_parts/console_screen) + var/has_keyboard = machine.get_component_of_type(/obj/item/stock_parts/keyboard) + if(board) + has_screen ||= (/obj/item/stock_parts/console_screen in board.req_components) || (/obj/item/stock_parts/console_screen in board.additional_spawn_components) + has_keyboard ||= (/obj/item/stock_parts/keyboard in board.req_components) || (/obj/item/stock_parts/keyboard in board.additional_spawn_components) + if(!has_screen && !(machine.stat_immune & NOSCREEN)) + failed[candidate_type] = TRUE + log_bad("[log_info_line(machine)] doesn't start with or require a screen, but did not have NOSCREEN in stat_immune.") + if(!has_keyboard && !(machine.stat_immune & NOINPUT)) + failed[candidate_type] = TRUE + log_bad("[log_info_line(machine)] doesn't start with or require a keyboard, but did not have NOINPUT in stat_immune.") + if(!failed[candidate_type]) + passed[candidate_type] = TRUE + + if(length(failed)) + fail("One or more machines had incorrect stat_immune settings.") + else + pass("All machines had correct stat_immune settings.") + return TRUE \ No newline at end of file From 6fc525a1b3fc088069311244a284b587fa9f6550 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 16:33:57 -0500 Subject: [PATCH 033/512] Fix alien whitelist not filtering displayed species --- code/modules/client/preference_setup/background/01_species.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index 7383f2786800..ac308fb50108 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -47,7 +47,7 @@ . += "" . += "" . += "

    Species

    " - for(var/s in get_playable_species()) + for(var/s in playables) var/decl/species/list_species = get_species_by_key(s) if(pref.species == list_species.name) . += "[list_species.name] " From 9ea82af85a56684d80874a0369e1af475e1680d7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 16:37:12 -0500 Subject: [PATCH 034/512] Prevent href hacking of non-whitelisted species in character setup --- .../client/preference_setup/background/01_species.dm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index ac308fb50108..5ce542a3bc5c 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -89,6 +89,14 @@ var/choice = href_list["set_species"] if(choice != pref.species) + if(!check_rights(R_ADMIN, 0) && get_config_value(/decl/config/toggle/use_alien_whitelist)) + var/decl/species/new_species = get_species_by_key(choice) + if(!new_species) + return TOPIC_REFRESH + if(!(new_species.spawn_flags & SPECIES_CAN_JOIN)) + return TOPIC_REFRESH + else if((new_species.spawn_flags & SPECIES_IS_WHITELISTED) && !is_alien_whitelisted(preference_mob(), new_species)) + return TOPIC_REFRESH pref.species = choice pref.sanitize_preferences() From d2a78f6299878f5deed44c4ccf91c4d4ff5eab8f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 17:44:54 -0500 Subject: [PATCH 035/512] Fix arguments to change_appearance --- code/game/antagonist/antagonist.dm | 1 + code/game/antagonist/antagonist_update.dm | 6 +----- code/modules/acting/acting_items.dm | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm index 6aabe004cbe4..6e1c6c9ce547 100644 --- a/code/game/antagonist/antagonist.dm +++ b/code/game/antagonist/antagonist.dm @@ -50,6 +50,7 @@ var/decl/language/required_language // Used for setting appearance. + /// Species that are valid when changing appearance while spawning as this role. Null allows all species. var/list/valid_species var/min_player_age = 14 diff --git a/code/game/antagonist/antagonist_update.dm b/code/game/antagonist/antagonist_update.dm index 454d1c1b2f14..82053c6a128f 100644 --- a/code/game/antagonist/antagonist_update.dm +++ b/code/game/antagonist/antagonist_update.dm @@ -3,10 +3,6 @@ leader = current_antagonists[1] /decl/special_role/proc/update_antag_mob(var/datum/mind/player, var/preserve_appearance) - - if(!valid_species) - valid_species = list(global.using_map.default_species) - // Get the mob. if((flags & ANTAG_OVERRIDE_MOB) && (!player.current || (mob_path && !istype(player.current, mob_path)))) var/mob/holder = player.current @@ -17,7 +13,7 @@ if(!preserve_appearance && (flags & ANTAG_SET_APPEARANCE)) spawn(3) var/mob/living/carbon/human/H = player.current - if(istype(H)) H.change_appearance(APPEARANCE_ALL, H.loc, H, valid_species, state = global.z_topic_state) + if(istype(H)) H.change_appearance(APPEARANCE_ALL, H.loc, H, species_whitelist = valid_species, state = global.z_topic_state) return player.current /decl/special_role/proc/update_access(var/mob/living/player) diff --git a/code/modules/acting/acting_items.dm b/code/modules/acting/acting_items.dm index 672e773675af..675d28921869 100644 --- a/code/modules/acting/acting_items.dm +++ b/code/modules/acting/acting_items.dm @@ -33,7 +33,7 @@ if(!ishuman(user)) return ..() var/mob/living/carbon/human/H = user - H.change_appearance(APPEARANCE_ALL, H.loc, H, H.generate_valid_species(), state = global.z_topic_state) + H.change_appearance(APPEARANCE_ALL, H.loc, H, state = global.z_topic_state) var/getName = sanitize(input(H, "Would you like to change your name to something else?", "Name change") as null|text, MAX_NAME_LEN) if(getName) H.real_name = getName From 2b563c7e5a32cd1933184621d23505d11cb9baec Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sat, 22 Feb 2025 00:48:13 +0000 Subject: [PATCH 036/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 5f133c463f78..8230683f9a86 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -128,12 +128,6 @@

    ophelia v0.8 updated:

  • added new wooden chest sprites, by Doe
  • mud and soil plots are now properly greyscaled to soil material color
  • - -

    21 December 2024

    -

    Penelope Haze updated:

    -
      -
    • Makes weather effects slightly more transparent.
    • -
    From 8bf491a9137a10b581b7dd0e08558a83aebb3c82 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 19:40:11 -0500 Subject: [PATCH 037/512] Fix plural name for kobaloi species --- mods/content/fantasy/datum/kobaloi/species.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/content/fantasy/datum/kobaloi/species.dm b/mods/content/fantasy/datum/kobaloi/species.dm index 055513ab9816..9f2dd07bc4fc 100644 --- a/mods/content/fantasy/datum/kobaloi/species.dm +++ b/mods/content/fantasy/datum/kobaloi/species.dm @@ -1,5 +1,6 @@ /decl/species/kobaloi name = SPECIES_KOBALOI + name_plural = SPECIES_KOBALOI spawn_flags = SPECIES_CAN_JOIN preview_outfit = null description = "Kobaloi are small, scaled and furred creatures that usually dwell in the quiet places of the world, \ From e74fde06b608955502a2921331a01fe1d924d6cc Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 23 Feb 2025 20:05:52 +1100 Subject: [PATCH 038/512] Automatic changelog generation for PR #4886 [ci skip] --- html/changelogs/AutoChangeLog-pr-4886.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4886.yml diff --git a/html/changelogs/AutoChangeLog-pr-4886.yml b/html/changelogs/AutoChangeLog-pr-4886.yml new file mode 100644 index 000000000000..90df8c6c61e5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4886.yml @@ -0,0 +1,4 @@ +author: Penelope Haze +changes: + - {tweak: Human and unathi sprites should be slightly brighter now.} +delete-after: true From 5b458919a09ece983e9d22d9dd14cbcddb0c4389 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 22:14:47 -0500 Subject: [PATCH 039/512] Revert "Force update_icon calls prior to first SSicon_update flush to queue" This reverts commit c899a7419cf7cb53f4e3525229651e82f55c8655. --- code/game/atoms.dm | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 311d01d6a95c..c706714a0012 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -398,18 +398,13 @@ /** Update this atom's icon. - If prior to the first SSicon_update flush (i.e. it's during init), icon updates are forced to queue instead. - This saves a lot of init time. - Events: `updated_icon` */ /atom/proc/update_icon() SHOULD_CALL_PARENT(TRUE) - if(SSicon_update.init_state == SS_INITSTATE_NONE) - queue_icon_update() - else - on_update_icon() - RAISE_EVENT(/decl/observ/updated_icon, src) + on_update_icon() + RAISE_EVENT(/decl/observ/updated_icon, src) /** Update this atom's icon. From a8ca18ba12d7cf6beab1f238af47523fc7563edc Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 19:11:24 -0500 Subject: [PATCH 040/512] Fix ammo magazine lazyloaded matter values --- code/modules/projectiles/ammunition.dm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index a10c5770ff88..dfdce36903e3 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -177,6 +177,16 @@ stored_ammo += new ammo_type(src) contents_initialized = TRUE +/obj/item/ammo_magazine/get_contained_matter() + . = ..() + if(!lazyload_contents || contents_initialized || !ammo_type || !initial_ammo) + return + // Add our expected matter from lazyloaded stuff. + var/list/ammo_matter = atom_info_repository.get_matter_for(ammo_type).Copy() + for(var/matter_entry in ammo_matter) + ammo_matter[matter_entry] *= initial_ammo + . = MERGE_ASSOCS_WITH_NUM_VALUES(., ammo_matter) + /obj/item/ammo_magazine/proc/get_stored_ammo_count() . = length(stored_ammo) if(!contents_initialized) From a5a46629fa1c8cf0bae037643d2cc22994936c96 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 19:48:06 -0500 Subject: [PATCH 041/512] Fix unnecessary cache misses in the atom info repository --- code/datums/repositories/atom_info.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/datums/repositories/atom_info.dm b/code/datums/repositories/atom_info.dm index 4bfb7a4b8233..bb05ee4a2c6f 100644 --- a/code/datums/repositories/atom_info.dm +++ b/code/datums/repositories/atom_info.dm @@ -10,9 +10,9 @@ var/global/repository/atom_info/atom_info_repository = new() /repository/atom_info/proc/create_key_for(var/path, var/material, var/amount) . = "[path]" - if(material) + if(ispath(path, /obj) && material) // only objects take material as an arg . = "[.]-[material]" - if(!isnull(amount)) + if(ispath(path, /obj/item/stack) && !isnull(amount)) // similarly for stacks and amount . = "[.]-[amount]" /repository/atom_info/proc/get_instance_of(var/path, var/material, var/amount) From 333a652e58c21f86a91949bf93eac25b0831820e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 19:50:26 -0500 Subject: [PATCH 042/512] Remove remaining uses of modified types in code --- code/datums/supplypacks/galley.dm | 4 ++-- code/datums/supplypacks/science.dm | 2 +- code/modules/reagents/dispenser/dispenser_presets.dm | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/code/datums/supplypacks/galley.dm b/code/datums/supplypacks/galley.dm index 45c2c05ea161..2244e737d4e9 100644 --- a/code/datums/supplypacks/galley.dm +++ b/code/datums/supplypacks/galley.dm @@ -143,7 +143,7 @@ /decl/hierarchy/supply_pack/galley/beer_dispenser name = "Equipment - Booze dispenser" contains = list( - /obj/machinery/chemical_dispenser/bar_alc{anchored = FALSE} + /obj/machinery/chemical_dispenser/bar_alc/unanchored ) containertype = /obj/structure/largecrate containername = "booze dispenser crate" @@ -151,7 +151,7 @@ /decl/hierarchy/supply_pack/galley/soda_dispenser name = "Equipment - Soda dispenser" contains = list( - /obj/machinery/chemical_dispenser/bar_soft{anchored = FALSE} + /obj/machinery/chemical_dispenser/bar_soft/unanchored ) containertype = /obj/structure/largecrate containername = "soda dispenser crate" diff --git a/code/datums/supplypacks/science.dm b/code/datums/supplypacks/science.dm index f7d7f9991091..8458268f05a5 100644 --- a/code/datums/supplypacks/science.dm +++ b/code/datums/supplypacks/science.dm @@ -4,7 +4,7 @@ /decl/hierarchy/supply_pack/science/chemistry_dispenser name = "Equipment - Chemical Reagent dispenser" contains = list( - /obj/machinery/chemical_dispenser{anchored = FALSE} + /obj/machinery/chemical_dispenser/unanchored ) containertype = /obj/structure/largecrate containername = "reagent dispenser crate" diff --git a/code/modules/reagents/dispenser/dispenser_presets.dm b/code/modules/reagents/dispenser/dispenser_presets.dm index 0336edaecb5a..e6d1634b8447 100644 --- a/code/modules/reagents/dispenser/dispenser_presets.dm +++ b/code/modules/reagents/dispenser/dispenser_presets.dm @@ -1,3 +1,6 @@ +/obj/machinery/chemical_dispenser/unanchored + anchored = FALSE + /obj/machinery/chemical_dispenser/full spawn_cartridges = list( /obj/item/chems/chem_disp_cartridge/hydrazine, @@ -60,6 +63,9 @@ beaker_offset = -2 beaker_positions = list(-1,3,7,11,15) +/obj/machinery/chemical_dispenser/bar_soft/unanchored + anchored = FALSE + /obj/machinery/chemical_dispenser/bar_soft/full spawn_cartridges = list( /obj/item/chems/chem_disp_cartridge/water, @@ -98,6 +104,8 @@ beaker_offset = -2 beaker_positions = list(-3,2,7,12,17) +/obj/machinery/chemical_dispenser/bar_alc/unanchored + anchored = FALSE /obj/machinery/chemical_dispenser/bar_alc/full spawn_cartridges = list( From 6f920adbb7ea8627fe8cdb18726262dc84896f4d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 00:11:21 -0500 Subject: [PATCH 043/512] Add NOSCREEN and NOINPUT immunity to various machines --- code/game/machinery/OpTable.dm | 1 - code/game/machinery/bodyscanner.dm | 3 +-- code/game/machinery/kitchen/gibber.dm | 2 +- code/game/machinery/mech_recharger.dm | 1 - code/game/machinery/recharger.dm | 1 - code/game/machinery/rechargestation.dm | 1 - code/game/machinery/seed_extractor.dm | 1 - code/game/machinery/washing_machine.dm | 1 - .../circuitboards/machinery/medical.dm | 3 +-- .../modules/hydroponics/beekeeping/beehive.dm | 1 - code/modules/mining/drilling/drill.dm | 4 ++-- code/modules/power/fusion/core/_core.dm | 22 +++++-------------- .../fusion/fuel_injector/fuel_injector.dm | 1 - 13 files changed, 11 insertions(+), 31 deletions(-) diff --git a/code/game/machinery/OpTable.dm b/code/game/machinery/OpTable.dm index de556eb9486f..0e1be9fb40e4 100644 --- a/code/game/machinery/OpTable.dm +++ b/code/game/machinery/OpTable.dm @@ -10,7 +10,6 @@ active_power_usage = 5 construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 var/suppressing = FALSE var/mob/living/victim diff --git a/code/game/machinery/bodyscanner.dm b/code/game/machinery/bodyscanner.dm index 2e815dae25af..1ffe63761610 100644 --- a/code/game/machinery/bodyscanner.dm +++ b/code/game/machinery/bodyscanner.dm @@ -2,7 +2,7 @@ /obj/machinery/bodyscanner var/mob/living/carbon/human/occupant var/locked - name = "Body Scanner" + name = "body scanner" icon = 'icons/obj/Cryogenic2.dmi' icon_state = "body_scanner_0" density = TRUE @@ -11,7 +11,6 @@ active_power_usage = 10000 //10 kW. It's a big all-body scanner. construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 var/open_sound = 'sound/machines/podopen.ogg' var/close_sound = 'sound/machines/podclose.ogg' diff --git a/code/game/machinery/kitchen/gibber.dm b/code/game/machinery/kitchen/gibber.dm index 6857a5ea9df4..2ab6c6cff981 100644 --- a/code/game/machinery/kitchen/gibber.dm +++ b/code/game/machinery/kitchen/gibber.dm @@ -9,7 +9,7 @@ initial_access = list(list(access_kitchen, access_morgue)) construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 + stat_immune = NOSCREEN var/operating = 0 //Is it on? var/dirty = 0 // Does it need cleaning? diff --git a/code/game/machinery/mech_recharger.dm b/code/game/machinery/mech_recharger.dm index bd9e8be69364..faebaf4ae1e0 100644 --- a/code/game/machinery/mech_recharger.dm +++ b/code/game/machinery/mech_recharger.dm @@ -11,7 +11,6 @@ base_type = /obj/machinery/mech_recharger construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 var/mob/living/exosuit/charging var/base_charge_rate = 60 KILOWATTS diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 1326de26f89b..ae404b40f92b 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -15,7 +15,6 @@ var/icon_state_idle = "recharger0" //also when unpowered var/portable = 1 - stat_immune = 0 uncreated_component_parts = null construct_state = /decl/machine_construction/default/panel_closed diff --git a/code/game/machinery/rechargestation.dm b/code/game/machinery/rechargestation.dm index df55809d8f97..c2202c81daed 100644 --- a/code/game/machinery/rechargestation.dm +++ b/code/game/machinery/rechargestation.dm @@ -8,7 +8,6 @@ idle_power_usage = 50 base_type = /obj/machinery/recharge_station uncreated_component_parts = null - stat_immune = 0 construct_state = /decl/machine_construction/default/panel_closed var/overlay_icon = 'icons/obj/objects.dmi' diff --git a/code/game/machinery/seed_extractor.dm b/code/game/machinery/seed_extractor.dm index 0d9db5ebc3bc..4b7e91fae97f 100644 --- a/code/game/machinery/seed_extractor.dm +++ b/code/game/machinery/seed_extractor.dm @@ -10,7 +10,6 @@ active_power_usage = 2000 construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 /obj/machinery/seed_extractor/attackby(var/obj/item/O, var/mob/user) if((. = component_attackby(O, user))) diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 2f00796334ae..8fd05ec444fc 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -16,7 +16,6 @@ anchored = TRUE construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = NOSCREEN var/state = 0 var/gibs_ready = FALSE obj_flags = OBJ_FLAG_ANCHORABLE diff --git a/code/game/objects/items/weapons/circuitboards/machinery/medical.dm b/code/game/objects/items/weapons/circuitboards/machinery/medical.dm index a1ad9088df20..0f5e011f6878 100644 --- a/code/game/objects/items/weapons/circuitboards/machinery/medical.dm +++ b/code/game/objects/items/weapons/circuitboards/machinery/medical.dm @@ -18,8 +18,7 @@ origin_tech = @'{"engineering":2,"biotech":4,"programming":4}' req_components = list( /obj/item/stock_parts/scanning_module = 2, - /obj/item/stock_parts/manipulator = 2, - /obj/item/stock_parts/console_screen = 1) + /obj/item/stock_parts/manipulator = 2) additional_spawn_components = list( /obj/item/stock_parts/power/apc/buildable = 1 ) diff --git a/code/modules/hydroponics/beekeeping/beehive.dm b/code/modules/hydroponics/beekeeping/beehive.dm index 59f474001174..f6908d3e4cbc 100644 --- a/code/modules/hydroponics/beekeeping/beehive.dm +++ b/code/modules/hydroponics/beekeeping/beehive.dm @@ -172,7 +172,6 @@ density = TRUE construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 var/processing = 0 var/honey = 0 diff --git a/code/modules/mining/drilling/drill.dm b/code/modules/mining/drilling/drill.dm index fea0961004fa..5294aee6a657 100644 --- a/code/modules/mining/drilling/drill.dm +++ b/code/modules/mining/drilling/drill.dm @@ -6,7 +6,6 @@ layer = ABOVE_HUMAN_LAYER //So it draws over mobs in the tile north of it. construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 /obj/machinery/mining/drill name = "mining drill head" @@ -183,7 +182,7 @@ . = (length(supports) <= 0) /obj/machinery/mining/drill/proc/system_error(var/error) - + // TODO: suppress the message if no screen is installed? if(error) src.visible_message("\The [src] flashes a '[error]' warning.") need_player_check = 1 @@ -232,6 +231,7 @@ icon_state = "mining_brace" obj_flags = OBJ_FLAG_ROTATABLE interact_offline = 1 + stat_immune = NOSCREEN | NOINPUT var/obj/machinery/mining/drill/connected diff --git a/code/modules/power/fusion/core/_core.dm b/code/modules/power/fusion/core/_core.dm index 39bfe1b5f08b..9856433cd312 100644 --- a/code/modules/power/fusion/core/_core.dm +++ b/code/modules/power/fusion/core/_core.dm @@ -14,7 +14,7 @@ anchored = FALSE construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 + stat_immune = NOINPUT base_type = /obj/machinery/fusion_core stock_part_presets = list(/decl/stock_part_preset/terminal_setup) @@ -43,16 +43,6 @@ else owned_field.handle_tick() -/obj/machinery/fusion_core/Topic(href, href_list) - if(..()) - return 1 - if(href_list["str"]) - var/dif = text2num(href_list["str"]) - field_strength = min(max(field_strength + dif, MIN_FIELD_STR), MAX_FIELD_STR) - change_power_consumption(500 * field_strength, POWER_USE_ACTIVE) - if(owned_field) - owned_field.ChangeFieldStrength(field_strength) - /obj/machinery/fusion_core/update_use_power(new_use_power) . = ..() if(use_power == POWER_USE_IDLE && owned_field) @@ -101,7 +91,7 @@ /obj/machinery/fusion_core/attackby(var/obj/item/W, var/mob/user) if(owned_field) - to_chat(user,"Shut \the [src] off first!") + to_chat(user, SPAN_WARNING("Shut \the [src] off first!")) return if(IS_MULTITOOL(W)) @@ -113,12 +103,12 @@ anchored = !anchored playsound(src.loc, 'sound/items/Ratchet.ogg', 75, 1) if(anchored) - user.visible_message("[user.name] secures [src.name] to the floor.", \ - "You secure the [src.name] to the floor.", \ + user.visible_message("\The [user] secures \the [src] to the floor.", \ + "You secure \the [src] to the floor.", \ "You hear a ratchet.") else - user.visible_message("[user.name] unsecures [src.name] from the floor.", \ - "You unsecure the [src.name] from the floor.", \ + user.visible_message("\The [user] unsecures \the [src] from the floor.", \ + "You unsecure \the [src] from the floor.", \ "You hear a ratchet.") return diff --git a/code/modules/power/fusion/fuel_injector/fuel_injector.dm b/code/modules/power/fusion/fuel_injector/fuel_injector.dm index db6569659add..8d906b0f5e47 100644 --- a/code/modules/power/fusion/fuel_injector/fuel_injector.dm +++ b/code/modules/power/fusion/fuel_injector/fuel_injector.dm @@ -9,7 +9,6 @@ active_power_usage = 500 construct_state = /decl/machine_construction/default/panel_closed uncreated_component_parts = null - stat_immune = 0 base_type = /obj/machinery/fusion_fuel_injector var/fuel_usage = 0.001 From c8a98eb47711f7ff2967d57e69f0d3e27b0f6beb Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Mon, 24 Feb 2025 00:52:45 +0000 Subject: [PATCH 044/512] Automatic changelog generation [ci skip] --- html/changelog.html | 14 ++++++-------- html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-4886.yml | 4 ---- 3 files changed, 9 insertions(+), 12 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4886.yml diff --git a/html/changelog.html b/html/changelog.html index 8230683f9a86..372d34a4aa41 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
    +

    24 February 2025

    +

    Penelope Haze updated:

    +
      +
    • Human and unathi sprites should be slightly brighter now.
    • +
    +

    18 February 2025

    MistakeNot4892 updated:

      @@ -120,14 +126,6 @@

      MistakeNot4892 updated:

      • Raw plant oil no longer works as lantern fuel; it must be mixed with powdered graphite first.
      - -

      23 December 2024

      -

      ophelia v0.8 updated:

      -
        -
      • added new dirt and mud tile sprites
      • -
      • added new wooden chest sprites, by Doe
      • -
      • mud and soil plots are now properly greyscaled to soil material color
      • -
    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 4e9e0fdd738c..e11ef8f70b00 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14986,3 +14986,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. MistakeNot4892: - tweak: Modifiers like regeneration or personal shielding will now show at the top of the screen. +2025-02-24: + Penelope Haze: + - tweak: Human and unathi sprites should be slightly brighter now. diff --git a/html/changelogs/AutoChangeLog-pr-4886.yml b/html/changelogs/AutoChangeLog-pr-4886.yml deleted file mode 100644 index 90df8c6c61e5..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4886.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Penelope Haze -changes: - - {tweak: Human and unathi sprites should be slightly brighter now.} -delete-after: true From c7203b7e89f8b612cdbcf63c185b09659b429b3d Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 12:29:31 +1100 Subject: [PATCH 045/512] Partially merging mob examine with atom examine. --- code/game/atoms.dm | 2 ++ code/modules/mob/examine.dm | 21 ++++++++++----------- code/modules/mob/living/human/examine.dm | 19 ++++++++++--------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c706714a0012..347a07af1a83 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -284,11 +284,13 @@ */ /atom/proc/examined_by(mob/user, distance, infix, suffix) var/list/examine_lines + // to_chat(user, "
    ") // these don't work in BYOND's native output panel. If we switch to browser output instead, you can readd this for(var/add_lines in list(get_examine_header(user, distance, infix, suffix), get_examine_strings(user, distance, infix, suffix), get_examine_hints(user, distance, infix, suffix))) if(islist(add_lines) && LAZYLEN(add_lines)) LAZYADD(examine_lines, add_lines) if(LAZYLEN(examine_lines)) to_chat(user, jointext(examine_lines, "
    ")) + // to_chat(user, "
    ") // see above RAISE_EVENT(/decl/observ/atom_examined, src, user, distance) return TRUE diff --git a/code/modules/mob/examine.dm b/code/modules/mob/examine.dm index c9e19f366257..164b4d8b96b4 100644 --- a/code/modules/mob/examine.dm +++ b/code/modules/mob/examine.dm @@ -10,12 +10,6 @@ . |= thing.flags_inv return . & EQUIPMENT_VISIBILITY_FLAGS -/mob/proc/get_examined_short_description(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) - . = list() - . += "[html_icon(src)] That's \a [src][infix]. [suffix]" - if(desc) - . += desc - /mob/proc/get_examined_worn_held_items(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) . = list() var/slot_datums = get_inventory_slots() @@ -36,6 +30,10 @@ /mob/proc/get_other_examine_strings(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) return +// We add a default parameter here for hidden inventory flags. +/mob/get_examine_header(mob/user, distance, infix, suffix, hideflags) + return ..(user, distance, infix, suffix) + /mob/get_examine_strings(mob/user, distance, infix, suffix) SHOULD_CALL_PARENT(FALSE) @@ -49,8 +47,9 @@ // Show our equipment, held items, desc, etc. var/decl/pronouns/pronouns = get_visible_pronouns(hideflags) - // to_chat(user, "
    ") // these don't work in BYOND's native output panel. If we switch to browser output instead, you can readd this - . += get_examined_short_description(user, distance, infix, suffix, hideflags, pronouns) - . += get_examined_worn_held_items(user, distance, infix, suffix, hideflags, pronouns) - . += get_other_examine_strings(user, distance, infix, suffix, hideflags, pronouns) - // to_chat(user, "
    ") // see above + var/list/examine_items = get_examined_worn_held_items(user, distance, infix, suffix, hideflags, pronouns) + if(length(examine_items)) + . += examine_items + var/list/other_items = get_other_examine_strings(user, distance, infix, suffix, hideflags, pronouns) + if(length(other_items)) + . += other_items diff --git a/code/modules/mob/living/human/examine.dm b/code/modules/mob/living/human/examine.dm index 1c3dabe29148..49d8728fbf58 100644 --- a/code/modules/mob/living/human/examine.dm +++ b/code/modules/mob/living/human/examine.dm @@ -1,24 +1,25 @@ -/mob/living/human/get_examined_short_description(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) - var/msg = list("*---------*
    [user == src ? "You are" : "This is"] [name]") +/mob/living/human/get_examine_header(mob/user, distance, infix, suffix, hideflags) + SHOULD_CALL_PARENT(FALSE) + . = list("*---------*
    [user == src ? "You are" : "This is"] [name]") if(!(hideflags & HIDEJUMPSUIT) || !(hideflags & HIDEFACE)) var/species_name = "\improper " if(isSynthetic() && species.cyborg_noun) species_name += "[species.cyborg_noun] [species.get_root_species_name(src)]" else species_name += "[species.name]" - msg += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user))) ? SPAN_NOTICE(" \[?\]") : ""]" + . += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user))) ? SPAN_NOTICE(" \[?\]") : ""]" var/extra_species_text = species.get_additional_examine_text(src) if(extra_species_text) - msg += "
    [extra_species_text]" + . += "
    [extra_species_text]" var/show_descs = show_descriptors_to(user) if(show_descs) - msg += "
    [jointext(show_descs, "
    ")]
    " + . += "
    [jointext(show_descs, "
    ")]
    " var/print_flavour = print_flavor_text() if(print_flavour) - msg += "
    *---------*" - msg += "
    [print_flavour]" - msg += "
    *---------*" - return list(jointext(msg, null)) + . += "
    *---------*" + . += "
    [print_flavour]" + . += "
    *---------*" + . = list(jointext(., null)) /mob/living/human/get_other_examine_strings(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) From 0b111a2b5c6c43256511bf4daf74d1b33924f99a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 13:09:57 +1100 Subject: [PATCH 046/512] Fixes unarmed attack defaults being wonky. --- .../mob/living/human/human_attackhand.dm | 8 +++-- .../mob/living/human/unarmed_attack.dm | 29 +++++++++---------- code/modules/mob/mob.dm | 2 +- code/modules/species/species_attack.dm | 4 +-- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm index 747a1d5439cb..93d436e3a882 100644 --- a/code/modules/mob/living/human/human_attackhand.dm +++ b/code/modules/mob/living/human/human_attackhand.dm @@ -3,11 +3,12 @@ hit_zone = get_target_zone() var/list/available_attacks = get_mob_natural_attacks() var/decl/natural_attack/use_attack = default_attack - if(!use_attack || !use_attack.is_usable(src, target, hit_zone) || !(use_attack.type in available_attacks)) + if(!use_attack || !use_attack.attack_is_usable(src, target, hit_zone) || !(use_attack in available_attacks)) + var/alert_non_default_attack = use_attack?.name use_attack = null var/list/other_attacks = list() for(var/decl/natural_attack/u_attack as anything in available_attacks) - if(!u_attack.is_usable(src, target, hit_zone)) + if(!u_attack.attack_is_usable(src, target, hit_zone)) continue if(u_attack.is_starting_default) use_attack = u_attack @@ -15,6 +16,9 @@ other_attacks += u_attack if(!use_attack && length(other_attacks)) use_attack = pick(other_attacks) + if(use_attack && alert_non_default_attack) + to_chat(src, SPAN_WARNING("You cannot [alert_non_default_attack] \the [target] currently, so you switch attacks.")) + . = use_attack?.resolve_to_soft_variant(src) /obj/item/organ/external/proc/get_natural_attacks() diff --git a/code/modules/mob/living/human/unarmed_attack.dm b/code/modules/mob/living/human/unarmed_attack.dm index ce18cfa97bfb..33728d7201cd 100644 --- a/code/modules/mob/living/human/unarmed_attack.dm +++ b/code/modules/mob/living/human/unarmed_attack.dm @@ -63,7 +63,7 @@ /decl/natural_attack/proc/get_sparring_variant() return GET_DECL(sparring_variant_type) -/decl/natural_attack/proc/is_usable(var/mob/living/human/user, var/mob/target, var/zone) +/decl/natural_attack/proc/attack_is_usable(var/mob/living/human/user, var/mob/target, var/zone) if(!user.restrained() && !user.incapacitated()) for(var/etype in usable_with_limbs) var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(user, etype) @@ -127,9 +127,9 @@ target.visible_message("[target] has been weakened!") target.apply_effect(3, WEAKEN, armour * 100) - var/obj/item/clothing/C = target.get_covering_equipped_item_by_zone(zone) - if(istype(C) && prob(10)) - C.leave_evidence(user) + var/obj/item/clothing/gear = target.get_covering_equipped_item_by_zone(zone) + if(istype(gear) && prob(10)) + gear.leave_evidence(user) return TRUE @@ -178,17 +178,16 @@ sharp = TRUE edge = TRUE -/decl/natural_attack/bite/is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) - +/decl/natural_attack/bite/attack_is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) if(user.get_item_blocking_speech()) - return 0 + return FALSE for(var/slot in list(slot_wear_mask_str, slot_head_str, slot_wear_suit_str)) - var/obj/item/clothing/C = user.get_equipped_item(slot) - if(istype(C) && (C.body_parts_covered & SLOT_FACE) && (C.item_flags & ITEM_FLAG_THICKMATERIAL)) - return 0 //prevent biting through a space helmet or similar + var/obj/item/clothing/gear = user.get_equipped_item(slot) + if(istype(gear) && (gear.body_parts_covered & SLOT_FACE) && (gear.item_flags & ITEM_FLAG_THICKMATERIAL)) + return FALSE //prevent biting through a space helmet or similar if (user == target && (zone == BP_HEAD || zone == BP_EYES || zone == BP_MOUTH)) - return 0 //how do you bite yourself in the head? - return 1 + return FALSE //how do you bite yourself in the head? + return TRUE /decl/natural_attack/punch name = "punch" @@ -264,7 +263,7 @@ usable_with_limbs = list(BP_L_FOOT, BP_R_FOOT) sparring_variant_type = /decl/natural_attack/light_strike/kick -/decl/natural_attack/kick/is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) +/decl/natural_attack/kick/attack_is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) if(zone == BP_HEAD || zone == BP_EYES || zone == BP_MOUTH) zone = BP_CHEST . = ..() @@ -296,7 +295,7 @@ damage = 0 usable_with_limbs = list(BP_L_FOOT, BP_R_FOOT) -/decl/natural_attack/stomp/is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) +/decl/natural_attack/stomp/attack_is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) if(!istype(target)) return FALSE if (!user.current_posture.prone && (target.current_posture.prone || (zone in list(BP_L_FOOT, BP_R_FOOT)))) @@ -359,7 +358,7 @@ attack_noun = list("foot") usable_with_limbs = list(BP_L_FOOT, BP_R_FOOT) -/decl/natural_attack/light_strike/kick/is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) +/decl/natural_attack/light_strike/kick/attack_is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) if(zone == BP_HEAD || zone == BP_EYES || zone == BP_MOUTH) zone = BP_CHEST . = ..() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index aaef91f9a84d..6a4822997668 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1462,7 +1462,7 @@ if(get_equipped_item(slot_handcuffed_str) || buckled) return FALSE for(var/decl/natural_attack/attack as anything in get_mob_natural_attacks()) - if(attack.is_usable(src) && attack.shredding) + if(attack.attack_is_usable(src) && attack.shredding) return TRUE return FALSE diff --git a/code/modules/species/species_attack.dm b/code/modules/species/species_attack.dm index 0fffa9846431..a391a8994bf7 100644 --- a/code/modules/species/species_attack.dm +++ b/code/modules/species/species_attack.dm @@ -20,7 +20,7 @@ usable_with_limbs = list(BP_L_HAND, BP_R_HAND) var/blocked_by_gloves = TRUE -/decl/natural_attack/claws/is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) +/decl/natural_attack/claws/attack_is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) return (!user.get_equipped_item(slot_gloves_str) || !blocked_by_gloves) /decl/natural_attack/claws/show_attack(var/mob/living/human/user, var/mob/living/human/target, var/zone, var/attack_damage) @@ -124,7 +124,7 @@ BP_GROIN ) -/decl/natural_attack/tail/is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) //ensures that you can't tail someone in the skull +/decl/natural_attack/tail/attack_is_usable(var/mob/living/human/user, var/mob/living/human/target, var/zone) //ensures that you can't tail someone in the skull if(!(zone in can_hit_zones)) return FALSE for(var/foot_tag in list(BP_L_FOOT, BP_R_FOOT)) From 5087870e5b52a4fc10cec998ca38e77339abcbef Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 10:08:10 +1100 Subject: [PATCH 047/512] Supply shuttle ignores non-dense obstacles. --- code/controllers/subsystems/supply.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm index bf2d38aa0cb3..c717bd372ec0 100644 --- a/code/controllers/subsystems/supply.dm +++ b/code/controllers/subsystems/supply.dm @@ -117,7 +117,7 @@ SUBSYSTEM_DEF(supply) continue var/occupied = 0 for(var/atom/A in T.contents) - if(!A.simulated) + if(!A.simulated || !A.density) continue occupied = 1 break From b4dce679959dde8e0aa87cb7db7c57654b2621ab Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 22:58:57 +1100 Subject: [PATCH 048/512] Centrifuge needs input devices. --- code/game/objects/items/circuitboards/machinery/household.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/circuitboards/machinery/household.dm b/code/game/objects/items/circuitboards/machinery/household.dm index 7035bedba94e..b3e8803a255d 100644 --- a/code/game/objects/items/circuitboards/machinery/household.dm +++ b/code/game/objects/items/circuitboards/machinery/household.dm @@ -53,7 +53,9 @@ origin_tech = @'{"biotech":2,"engineering":1}' req_components = list( /obj/item/stock_parts/manipulator = 2, - /obj/item/stock_parts/matter_bin = 2 + /obj/item/stock_parts/matter_bin = 2, + /obj/item/stock_parts/console_screen = 1, + /obj/item/stock_parts/keyboard = 1 ) /obj/item/stock_parts/circuitboard/seed_extractor From e9a3221aa6812905f031cc6777f254a2ecfe2b72 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Feb 2025 23:24:29 -0500 Subject: [PATCH 049/512] Improve hotplate heating for cooking vessels --- code/modules/reagents/heat_sources/_heat_source.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/modules/reagents/heat_sources/_heat_source.dm b/code/modules/reagents/heat_sources/_heat_source.dm index eb5b3cebf445..085114944ece 100644 --- a/code/modules/reagents/heat_sources/_heat_source.dm +++ b/code/modules/reagents/heat_sources/_heat_source.dm @@ -83,9 +83,8 @@ // Hackery to heat pots placed onto a hotplate without also grilling/baking stuff. if(isturf(loc)) - var/datum/gas_mixture/environment = loc.return_air() for(var/obj/item/chems/cooking_vessel/pot in loc.get_contained_external_atoms()) - pot.fire_act(environment, temperature, 500) + pot.handle_external_heating(temperature, src) return TRUE // Don't kill this processing loop unless we're not powered. . = ..() From 7ecef3667e2c123db1f177f147e2071a27b5e193 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Feb 2025 23:24:50 -0500 Subject: [PATCH 050/512] Make sub-tick cooling and reheating not break pot boiling overlay --- code/modules/food/cooking/cooking_vessels/pot.dm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/modules/food/cooking/cooking_vessels/pot.dm b/code/modules/food/cooking/cooking_vessels/pot.dm index d2920d1db937..8ced7d1c4e84 100644 --- a/code/modules/food/cooking/cooking_vessels/pot.dm +++ b/code/modules/food/cooking/cooking_vessels/pot.dm @@ -25,16 +25,20 @@ . = ..() /obj/item/chems/cooking_vessel/pot/ProcessAtomTemperature() + var/prior_temperature = temperature . = ..() + // to avoid issues with it cooling down in ..() and reheating the same tick, we use the highest of the two + // todo: just prevent the cooling instead, for a less-hacky solution + var/use_temperature = max(temperature, prior_temperature) // Largely ignore return value so we don't skip this update on the final time we temperature process. - if(temperature != last_boil_temp) + if(use_temperature != last_boil_temp) - last_boil_temp = temperature + last_boil_temp = use_temperature var/next_boil_status = FALSE for(var/reagent_type in reagents?.reagent_volumes) var/decl/material/reagent = GET_DECL(reagent_type) - if(!isnull(reagent.boiling_point) && temperature >= reagent.boiling_point) + if(!isnull(reagent.boiling_point) && use_temperature >= reagent.boiling_point) next_boil_status = TRUE break From 16629e3380e80f4ac0e601a5f3806a969d54a057 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Feb 2025 23:56:40 -0500 Subject: [PATCH 051/512] Fix the skybox becoming blank after a full HUD reset --- code/_onclick/hud/hud.dm | 1 - code/modules/mob/login.dm | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 4fcc575748d0..51fd1d3cc5aa 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -15,7 +15,6 @@ hud_used = new hud_type(src) else hud_used = new /datum/hud(src) - refresh_lighting_master() /datum/hud var/mob/mymob diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 9f367883a5e9..51ca7c038f5a 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -90,8 +90,6 @@ hud_reset(TRUE) - client.update_skybox(1) - if(istype(machine)) machine.on_user_login(src) @@ -103,9 +101,9 @@ client.screen = list() //remove hud items just in case client.set_right_click_menu_mode(shift_to_open_context_menu) InitializeHud() - else - refresh_lighting_master() + refresh_lighting_master() + client.update_skybox(full_reset) // readd to client.screen if we cleared it refresh_client_images() reload_fullscreen() // Reload any fullscreen overlays this mob has. add_click_catcher() From 30c3a0f023a4e0c5d7c1d4cd4f36443b74627673 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 01:08:26 -0500 Subject: [PATCH 052/512] Rename single and double-letter loadout option variables --- code/controllers/subsystems/jobs.dm | 14 +-- .../preference_setup/loadout/loadout.dm | 118 +++++++++--------- .../mob/new_player/preferences_setup.dm | 12 +- code/modules/submaps/submap_join.dm | 12 +- code/unit_tests/loadout_tests.dm | 54 ++++---- 5 files changed, 105 insertions(+), 105 deletions(-) diff --git a/code/controllers/subsystems/jobs.dm b/code/controllers/subsystems/jobs.dm index 311b9f487c0f..5ecd6a466643 100644 --- a/code/controllers/subsystems/jobs.dm +++ b/code/controllers/subsystems/jobs.dm @@ -438,14 +438,14 @@ SUBSYSTEM_DEF(jobs) var/list/spawn_in_storage = list() if(H.client.prefs.Gear() && job.loadout_allowed) for(var/thing in H.client.prefs.Gear()) - var/decl/loadout_option/G = decls_repository.get_decl_by_id_or_var(thing, /decl/loadout_option) - if(!istype(G)) + var/decl/loadout_option/gear = decls_repository.get_decl_by_id_or_var(thing, /decl/loadout_option) + if(!istype(gear)) continue - if(!G.is_permitted(H, job)) + if(!gear.is_permitted(H, job)) to_chat(H, SPAN_WARNING("Your current species, job, branch, skills or whitelist status does not permit you to spawn with [thing]!")) continue - if(!G.slot || !G.spawn_on_mob(H, H.client.prefs.Gear()[G.uid])) - spawn_in_storage.Add(G) + if(!gear.slot || !gear.spawn_on_mob(H, H.client.prefs.Gear()[gear.uid])) + spawn_in_storage.Add(gear) // do accessories last so they don't attach to a suit that will be replaced if(H.char_rank && H.char_rank.accessory) @@ -537,8 +537,8 @@ SUBSYSTEM_DEF(jobs) return other_mob if(spawn_in_storage) - for(var/decl/loadout_option/G in spawn_in_storage) - G.spawn_in_storage_or_drop(H, H.client.prefs.Gear()[G.uid]) + for(var/decl/loadout_option/gear in spawn_in_storage) + gear.spawn_in_storage_or_drop(H, H.client.prefs.Gear()[gear.uid]) var/article = job.total_positions == 1 ? "the" : "a" to_chat(H, "You are [article] [alt_title || job_title].") diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 76aaf4d0bb55..22ddf68cddd3 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -89,25 +89,25 @@ pref.total_loadout_cost = 0 pref.total_loadout_selections = list() - var/list/gears = pref.gear_list[index] - if(istype(gears)) - for(var/gear_id in gears) + var/list/loadout = pref.gear_list[index] + if(istype(loadout)) + for(var/gear_id in loadout) var/mob/user = preference_mob() - var/decl/loadout_option/LO = decls_repository.get_decl_by_id_or_var(gear_id, /decl/loadout_option) + var/decl/loadout_option/gear = decls_repository.get_decl_by_id_or_var(gear_id, /decl/loadout_option) - if(!istype(LO)) - gears -= gear_id + if(!istype(gear)) + loadout -= gear_id continue // Swap names for UIDs to grandfather in old saves. - if(LO.uid != gear_id) - gears[LO.uid] = gears[gear_id] - gears -= gear_id - gear_id = LO.uid - - if(LO && (GET_DECL(LO.category) in global.using_map.loadout_categories) && LO.can_be_taken_by(user, pref) && LO.can_afford(user, pref)) - pref.total_loadout_cost += LO.cost - pref.total_loadout_selections[LO.category] = (pref.total_loadout_selections[LO.category] + 1) + if(gear.uid != gear_id) + loadout[gear.uid] = loadout[gear_id] + loadout -= gear_id + gear_id = gear.uid + + if(gear && (GET_DECL(gear.category) in global.using_map.loadout_categories) && gear.can_be_taken_by(user, pref) && gear.can_afford(user, pref)) + pref.total_loadout_cost += gear.cost + pref.total_loadout_selections[gear.category] = (pref.total_loadout_selections[gear.category] + 1) else pref.gear_list[index] = list() @@ -116,12 +116,12 @@ pref.total_loadout_cost = 0 pref.total_loadout_selections = list() - var/list/gears = pref.gear_list[pref.gear_slot] - for(var/i = 1; i <= gears.len; i++) - var/decl/loadout_option/G = decls_repository.get_decl_by_id_or_var(gears[i], /decl/loadout_option) - if(G) - pref.total_loadout_cost += G.cost - pref.total_loadout_selections[G.category] = (pref.total_loadout_selections[G.category] + 1) + var/list/loadout = pref.gear_list[pref.gear_slot] + for(var/i = 1; i <= loadout.len; i++) + var/decl/loadout_option/gear = decls_repository.get_decl_by_id_or_var(loadout[i], /decl/loadout_option) + if(gear) + pref.total_loadout_cost += gear.cost + pref.total_loadout_selections[gear.category] = (pref.total_loadout_selections[gear.category] + 1) /datum/category_item/player_setup_item/loadout/content() . = list() @@ -154,9 +154,9 @@ var/category_cost = 0 for(var/gear in LC.gear) - var/decl/loadout_option/G = LC.gear[gear] + var/decl/loadout_option/gear = LC.gear[gear] if(gear in pref.gear_list[pref.gear_slot]) - category_cost += G.cost + category_cost += gear.cost if(category == current_category_decl.type) . += " [LC.name] - [category_cost] " @@ -180,13 +180,13 @@ var/list/other_gear = list() var/i = 0 for(var/gear in current_loadout) - var/decl/loadout_option/G = decls_repository.get_decl_by_id(gear, validate_decl_type = FALSE) - if(istype(G)) - if(G.slot) + var/decl/loadout_option/gear = decls_repository.get_decl_by_id(gear, validate_decl_type = FALSE) + if(istype(gear)) + if(gear.slot) i++ - . += "
    Layer [i]: [G.name]
    Layer underLayer overRemove" + . += "
    Layer [i]: [gear.name]
    Layer underLayer overRemove" else - other_gear += "
    [G.name]
    Remove" + other_gear += "
    [gear.name]
    Remove" if(length(other_gear)) . += "
    Other gear
    " @@ -207,24 +207,24 @@ var/mob/user = preference_mob() for(var/gear_id in current_category_decl.gear) - var/decl/loadout_option/G = current_category_decl.gear[gear_id] - if(!G.can_be_taken_by(user, pref)) + var/decl/loadout_option/gear = current_category_decl.gear[gear_id] + if(!gear.can_be_taken_by(user, pref)) continue - var/ticked = (G.uid in pref.gear_list[pref.gear_slot]) + var/ticked = (gear.uid in pref.gear_list[pref.gear_slot]) var/list/entry = list() - entry += "[G.name]" - entry += "[G.cost]" - entry += "[G.get_description(get_gear_metadata(G, TRUE))]" + entry += "[gear.name]" + entry += "[gear.cost]" + entry += "[gear.get_description(get_gear_metadata(gear, TRUE))]" var/allowed = 1 - if(allowed && G.allowed_roles) + if(allowed && gear.allowed_roles) var/good_job = 0 var/bad_job = 0 entry += "
    " var/list/jobchecks = list() for(var/datum/job/J in jobs) - if(J.type in G.allowed_roles) + if(J.type in gear.allowed_roles) jobchecks += "[J.title]" good_job = 1 else @@ -233,7 +233,7 @@ allowed = good_job || !bad_job entry += "[english_list(jobchecks)]" - if(allowed && G.allowed_branches) + if(allowed && gear.allowed_branches) var/list/branches = list() for(var/datum/job/J in jobs) if(pref.branches[J.title]) @@ -244,7 +244,7 @@ entry += "
    " for(var/branch in branches) var/datum/mil_branch/player_branch = mil_branches.get_branch(branch) - if(player_branch.type in G.allowed_branches) + if(player_branch.type in gear.allowed_branches) branch_checks += "[player_branch.name]" good_branch = 1 else @@ -253,11 +253,11 @@ entry += "[english_list(branch_checks)]" - if(allowed && G.allowed_skills) + if(allowed && gear.allowed_skills) var/list/skills_required = list()//make it into instances? instead of path - for(var/skill in G.allowed_skills) + for(var/skill in gear.allowed_skills) var/decl/skill/instance = GET_DECL(skill) - skills_required[instance] = G.allowed_skills[skill] + skills_required[instance] = gear.allowed_skills[skill] allowed = skill_check(jobs, skills_required)//Checks if a single job has all the skills required @@ -277,44 +277,44 @@ entry += "" if(ticked) entry += "" - for(var/datum/gear_tweak/tweak in G.gear_tweaks) - var/contents = tweak.get_contents(get_tweak_metadata(G, tweak)) + for(var/datum/gear_tweak/tweak in gear.gear_tweaks) + var/contents = tweak.get_contents(get_tweak_metadata(gear, tweak)) if(contents) - entry += " [contents]" + entry += " [contents]" entry += "" if(!hide_unavailable_gear || allowed || ticked) . += entry . += "" . = jointext(.,null) -/datum/category_item/player_setup_item/loadout/proc/get_gear_metadata(var/decl/loadout_option/G, var/readonly) - var/list/gear = pref.gear_list[pref.gear_slot] - . = gear[G.uid] +/datum/category_item/player_setup_item/loadout/proc/get_gear_metadata(var/decl/loadout_option/gear, var/readonly) + var/list/gears = pref.gear_list[pref.gear_slot] + . = gears[gear.uid] if(!.) . = list() if(!readonly) - gear[G.uid] = . + gears[gear.uid] = . -/datum/category_item/player_setup_item/loadout/proc/get_tweak_metadata(var/decl/loadout_option/G, var/datum/gear_tweak/tweak) - var/list/metadata = get_gear_metadata(G) +/datum/category_item/player_setup_item/loadout/proc/get_tweak_metadata(var/decl/loadout_option/gear, var/datum/gear_tweak/tweak) + var/list/metadata = get_gear_metadata(gear) . = metadata["[tweak]"] if(!.) . = tweak.get_default() metadata["[tweak]"] = . -/datum/category_item/player_setup_item/loadout/proc/set_tweak_metadata(var/decl/loadout_option/G, var/datum/gear_tweak/tweak, var/new_metadata) - var/list/metadata = get_gear_metadata(G) +/datum/category_item/player_setup_item/loadout/proc/set_tweak_metadata(var/decl/loadout_option/gear, var/datum/gear_tweak/tweak, var/new_metadata) + var/list/metadata = get_gear_metadata(gear) metadata["[tweak]"] = new_metadata /datum/category_item/player_setup_item/loadout/OnTopic(href, href_list, user) if(href_list["toggle_gear"]) - var/decl/loadout_option/TG = locate(href_list["toggle_gear"]) - if(!istype(TG)) + var/decl/loadout_option/gear_to_toggle = locate(href_list["toggle_gear"]) + if(!istype(gear_to_toggle)) return TOPIC_REFRESH - if(TG.uid in pref.gear_list[pref.gear_slot]) - pref.gear_list[pref.gear_slot] -= TG.uid - else if(TG.can_afford(preference_mob(), pref)) - pref.gear_list[pref.gear_slot] += TG.uid + if(gear_to_toggle.uid in pref.gear_list[pref.gear_slot]) + pref.gear_list[pref.gear_slot] -= gear_to_toggle.uid + else if(gear_to_toggle.can_afford(preference_mob(), pref)) + pref.gear_list[pref.gear_slot] += gear_to_toggle.uid return TOPIC_REFRESH_UPDATE_PREVIEW if(href_list["gear"]) @@ -373,8 +373,8 @@ current_tab = global.using_map.loadout_categories[1].type return TOPIC_REFRESH if(href_list["clear_loadout"]) - var/list/gear = pref.gear_list[pref.gear_slot] - gear.Cut() + var/list/current_gear = pref.gear_list[pref.gear_slot] + current_gear.Cut() return TOPIC_REFRESH_UPDATE_PREVIEW if(href_list["toggle_hiding"]) hide_unavailable_gear = !hide_unavailable_gear diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 388f9e21797b..18915226f3dc 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -85,24 +85,24 @@ if((equip_preview_mob & EQUIP_PREVIEW_LOADOUT) && !(previewJob && (equip_preview_mob & EQUIP_PREVIEW_JOB) && previewJob.skip_loadout_preview)) // Equip custom gear loadout, replacing any job items for(var/thing in Gear()) - var/decl/loadout_option/G = decls_repository.get_decl_by_id_or_var(thing, /decl/loadout_option) - if(G) + var/decl/loadout_option/gear = decls_repository.get_decl_by_id_or_var(thing, /decl/loadout_option) + if(gear) var/permitted = FALSE - if(G.allowed_roles && G.allowed_roles.len) + if(LAZYLEN(gear.allowed_roles)) if(previewJob) - for(var/job_type in G.allowed_roles) + for(var/job_type in gear.allowed_roles) if(previewJob.type == job_type) permitted = TRUE else permitted = TRUE - if(G.whitelisted && !(mannequin.species.name in G.whitelisted)) + if(gear.whitelisted && !(mannequin.species.name in gear.whitelisted)) permitted = FALSE if(!permitted) continue - if(G.slot && G.spawn_on_mob(mannequin, gear_list[gear_slot][G.uid])) + if(gear.slot && gear.spawn_on_mob(mannequin, gear_list[gear_slot][gear.uid])) update_icon = TRUE if(update_icon) diff --git a/code/modules/submaps/submap_join.dm b/code/modules/submaps/submap_join.dm index 216dbaeb1e06..e4af7814f2fb 100644 --- a/code/modules/submaps/submap_join.dm +++ b/code/modules/submaps/submap_join.dm @@ -78,8 +78,8 @@ job.apply_fingerprints(character) var/list/spawn_in_storage = SSjobs.equip_custom_loadout(character, job) if(spawn_in_storage) - for(var/decl/loadout_option/G in spawn_in_storage) - G.spawn_in_storage_or_drop(user_human, user_human.client.prefs.Gear()[G.uid]) + for(var/decl/loadout_option/gear in spawn_in_storage) + gear.spawn_in_storage_or_drop(user_human, user_human.client.prefs.Gear()[gear.uid]) SScustomitems.equip_custom_items(user_human) character.job = job.title @@ -97,12 +97,12 @@ if(istype(ojob) && ojob.info) to_chat(character, ojob.info) - if(user_human && user_human.has_genetic_condition(GENE_COND_NEARSIGHTED)) + if(user_human && user_human.has_genetic_condition(GENE_COND_NEARSIGHTED)) // is this even necessary with the new aspects system? var/equipped = user_human.equip_to_slot_or_del(new /obj/item/clothing/glasses/prescription(user_human), slot_glasses_str) if(equipped) - var/obj/item/clothing/glasses/G = user_human.get_equipped_item(slot_glasses_str) - if(istype(G)) - G.prescription = 7 + var/obj/item/clothing/glasses/glasses = user_human.get_equipped_item(slot_glasses_str) + if(istype(glasses)) + glasses.prescription = 7 BITSET(character.hud_updateflag, ID_HUD) BITSET(character.hud_updateflag, IMPLOYAL_HUD) diff --git a/code/unit_tests/loadout_tests.dm b/code/unit_tests/loadout_tests.dm index 563a1863a204..53699f1c1c0c 100644 --- a/code/unit_tests/loadout_tests.dm +++ b/code/unit_tests/loadout_tests.dm @@ -4,9 +4,9 @@ /datum/unit_test/loadout_test_shall_have_valid_icon_states/start_test() var/list/failed = list() - for(var/decl/loadout_option/G in decls_repository.get_decls_unassociated(/decl/loadout_option)) + for(var/decl/loadout_option/gear in decls_repository.get_decls_unassociated(/decl/loadout_option)) var/list/path_tweaks = list() - for(var/datum/gear_tweak/path/p in G.gear_tweaks) + for(var/datum/gear_tweak/path/p in gear.gear_tweaks) path_tweaks += p if(path_tweaks.len) @@ -15,17 +15,17 @@ var/path_type = p.valid_paths[path_name] if(!type_has_valid_icon_state(path_type)) var/atom/A = path_type - failed += "[G] - [path_type] ('[path_name]'): Did not find a gear_tweak's icon_state '[initial(A.icon_state)]' in the icon '[initial(A.icon)]'." + failed += "[gear] - [path_type] ('[path_name]'): Did not find a gear_tweak's icon_state '[initial(A.icon_state)]' in the icon '[initial(A.icon)]'." else - if(!type_has_valid_icon_state(G.path)) - var/obj/O = G.path - if(ispath(G.path, /obj)) - O = new G.path() + if(!type_has_valid_icon_state(gear.path)) + var/obj/O = gear.path + if(ispath(gear.path, /obj)) + O = new gear.path() if(!is_string_in_list(O.icon_state, icon_states(O.icon))) - failed += "[G] - [G.path]: Did not find the icon state '[O.icon_state]' in the icon '[O.icon]'." + failed += "[gear] - [gear.path]: Did not find the icon state '[O.icon_state]' in the icon '[O.icon]'." qdel(O) else - failed += "[G] - [G.path]: Did not find the icon state '[initial(O.icon_state)]' in the icon '[initial(O.icon)]'." + failed += "[gear] - [gear.path]: Did not find the icon state '[initial(O.icon_state)]' in the icon '[initial(O.icon)]'." if(length(failed)) fail("[length(failed)] /decl/loadout definition\s had paths with invalid icon states:\n[jointext(failed, "\n")]") @@ -38,12 +38,12 @@ /datum/unit_test/loadout_test_gear_path_tweaks_shall_be_of_gear_path/start_test() var/list/failed = list() - for(var/decl/loadout_option/G in decls_repository.get_decls_unassociated(/decl/loadout_option)) - for(var/datum/gear_tweak/path/p in G.gear_tweaks) + for(var/decl/loadout_option/gear in decls_repository.get_decls_unassociated(/decl/loadout_option)) + for(var/datum/gear_tweak/path/p in gear.gear_tweaks) for(var/path_name in p.valid_paths) var/path_type = p.valid_paths[path_name] - if(!ispath(path_type, G.path)) - failed += "[G] - [path_type] ('[path_name]'): Was not a path of [G.path]." + if(!ispath(path_type, gear.path)) + failed += "[gear] - [path_type] ('[path_name]'): Was not a path of [gear.path]." if(length(failed)) fail("[length(failed)] /datum/gear_tweak/path definition\s had invalid paths:\n[jointext(failed, "\n")]") @@ -56,10 +56,10 @@ /datum/unit_test/loadout_test_gear_path_tweaks_shall_have_unique_keys/start_test() var/path_entries_by_gear_path_and_name = list() - for(var/decl/loadout_option/G in decls_repository.get_decls_unassociated(/decl/loadout_option)) - for(var/datum/gear_tweak/path/p in G.gear_tweaks) + for(var/decl/loadout_option/gear in decls_repository.get_decls_unassociated(/decl/loadout_option)) + for(var/datum/gear_tweak/path/p in gear.gear_tweaks) for(var/path_name in p.valid_paths) - group_by(path_entries_by_gear_path_and_name, "[G] - [p] - [path_name]", path_name) + group_by(path_entries_by_gear_path_and_name, "[gear] - [p] - [path_name]", path_name) var/number_of_issues = number_of_issues(path_entries_by_gear_path_and_name, "Path Tweak Names") if(number_of_issues) @@ -79,15 +79,15 @@ /datum/unit_test/loadout_custom_setup_tweaks_shall_have_valid_procs/start_test() var/list/failures = list() - for(var/decl/loadout_option/G in decls_repository.get_decls_unassociated(/decl/loadout_option)) + for(var/decl/loadout_option/gear in decls_repository.get_decls_unassociated(/decl/loadout_option)) var/datum/instance var/mob/user - for(var/datum/gear_tweak/custom_setup/cs in G.gear_tweaks) - instance = instance || new G.path() + for(var/datum/gear_tweak/custom_setup/custom_tweak in gear.gear_tweaks) + instance = instance || new gear.path() user = user || new() - var/res = cs.tweak_item(user, instance) - if(res != GEAR_TWEAK_SUCCESS && res != GEAR_TWEAK_SKIPPED) - failures += "[G.type] - [cs.type]" + var/result = custom_tweak.tweak_item(user, instance) + if(result != GEAR_TWEAK_SUCCESS && result != GEAR_TWEAK_SKIPPED) + failures += "[gear.type] - [custom_tweak.type]" QDEL_NULL(instance) QDEL_NULL(user) @@ -102,13 +102,13 @@ name = "LOADOUT: Custom setup tweak shall be applied as expected" /datum/unit_test/loadout_custom_setup_tweak_shall_be_applied_as_expected/start_test() - var/decl/loadout_option/G = GET_DECL(/decl/loadout_option/loadout_test) - var/obj/unit_test/loadout/instance = new G.path() + var/decl/loadout_option/gear = GET_DECL(/decl/loadout_option/loadout_test) + var/obj/unit_test/loadout/instance = new gear.path() var/mob/user = new() - for(var/datum/gear_tweak/custom_setup/cs in G.gear_tweaks) - cs.tweak_item(user, instance) + for(var/datum/gear_tweak/custom_setup/custom_tweak in gear.gear_tweaks) + custom_tweak.tweak_item(user, instance) - if(instance.loadout_mob == user && instance.loadout_var == G.custom_setup_proc_arguments[1]) + if(instance.loadout_mob == user && instance.loadout_var == gear.custom_setup_proc_arguments[1]) pass("Succesfully applied custom tweak") else fail("Failed to apply custom tweak") From 78fa03a1cda44ceeb94726482317ec21b4a84eec Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 01:22:31 -0500 Subject: [PATCH 053/512] Improve variable names and code quality in supply code --- code/controllers/subsystems/supply.dm | 148 +++++++++--------- code/datums/supplypacks/engineering.dm | 2 +- code/datums/supplypacks/supplypack.dm | 7 +- .../preference_setup/loadout/loadout.dm | 10 +- 4 files changed, 82 insertions(+), 85 deletions(-) diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm index 00e90000aabe..c581a872ec7b 100644 --- a/code/controllers/subsystems/supply.dm +++ b/code/controllers/subsystems/supply.dm @@ -40,13 +40,11 @@ SUBSYSTEM_DEF(supply) ordernum = rand(1,9000) //Build master supply list - var/decl/hierarchy/supply_pack/root = GET_DECL(/decl/hierarchy/supply_pack) - for(var/decl/hierarchy/supply_pack/sp in root.children) - if(sp.is_category()) - for(var/decl/hierarchy/supply_pack/spc in sp.get_descendants()) - spc.setup() - master_supply_list += spc - CHECK_TICK + var/decl/hierarchy/supply_pack/root = IMPLIED_DECL + for(var/decl/hierarchy/supply_pack/sp in root.get_descendants()) + if(!sp.is_category()) + master_supply_list += sp + CHECK_TICK // Just add points over time. /datum/controller/subsystem/supply/fire() @@ -62,68 +60,63 @@ SUBSYSTEM_DEF(supply) point_sources[source] += amount point_sources["total"] += amount - //To stop things being sent to centcomm which should not be sent to centcomm. Recursively checks for these types. -/datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/A) - if(isliving(A)) - return 1 - if(istype(A,/obj/item/disk/nuclear)) - return 1 - if(istype(A,/obj/machinery/nuclearbomb)) - return 1 - if(istype(A,/obj/item/radio/beacon)) - return 1 - - for(var/i=1, i<=A.contents.len, i++) - var/atom/B = A.contents[i] - if(.(B)) - return 1 +/// To stop things being sent to centcomm which should not be sent to centcomm. Recursively checks for these types. +/datum/controller/subsystem/supply/proc/forbidden_atoms_check(atom/checking) + if(isliving(checking)) // You can't send a mob to the admin level. + return TRUE + if(istype(checking, /obj/item/disk/nuclear)) // Keep it somewhere nuclear operatives can reach it. + return TRUE + if(istype(checking, /obj/machinery/nuclearbomb)) // Don't nuke the admin level. + return TRUE + if(istype(checking, /obj/item/radio/beacon)) // Because these can be used for teleportation, I guess? + return TRUE + + for(var/atom/child in checking.contents) + if(forbidden_atoms_check(child)) + return TRUE + return FALSE /datum/controller/subsystem/supply/proc/sell() - for(var/area/subarea in shuttle.shuttle_area) - for(var/atom/movable/AM in subarea) - if(AM.anchored) + for(var/obj/structure/closet/crate/sold_crate in subarea) + if(sold_crate.anchored) continue - if(istype(AM, /obj/structure/closet/crate)) - var/obj/structure/closet/crate/CR = AM - RAISE_EVENT(/decl/observ/crate_sold, subarea, CR) - add_points_from_source(CR.get_single_monetary_worth() * crate_return_rebate * 0.1, "crate") - var/find_slip = 1 - - for(var/atom/atom as anything in CR) - // Sell manifests - if(find_slip && istype(atom, /obj/item/paper/manifest)) - var/obj/item/paper/manifest/slip = atom - if(!LAZYACCESS(slip.metadata, "is_copy") && LAZYLEN(slip.applied_stamps)) - add_points_from_source(LAZYACCESS(slip.metadata, "order_total") * slip_return_rebate, "manifest") - find_slip = 0 - continue - - // Sell materials - if(is_type_in_list(atom, saleable_materials)) - add_points_from_source(atom.get_combined_monetary_worth() * goods_sale_modifier * 0.1, "goods") - // Must sell ore detector disks in crates - else if(istype(atom, /obj/item/disk/survey)) - add_points_from_source(atom.get_combined_monetary_worth() * 0.005, "data") - - qdel(AM) + RAISE_EVENT(/decl/observ/crate_sold, subarea, sold_crate) + add_points_from_source(sold_crate.get_single_monetary_worth() * crate_return_rebate * 0.1, "crate") + var/find_slip = TRUE + + for(var/atom/movable/subcontent as anything in sold_crate) + // Sell manifests + if(find_slip && istype(subcontent, /obj/item/paper/manifest)) + var/obj/item/paper/manifest/slip = subcontent + if(!LAZYACCESS(slip.metadata, "is_copy") && LAZYLEN(slip.applied_stamps)) + add_points_from_source(LAZYACCESS(slip.metadata, "order_total") * slip_return_rebate, "manifest") + find_slip = FALSE + continue + + // Sell materials + if(is_type_in_list(subcontent, saleable_materials)) + add_points_from_source(subcontent.get_combined_monetary_worth() * goods_sale_modifier * 0.1, "goods") + // Must sell ore detector disks in crates + else if(istype(subcontent, /obj/item/disk/survey)) + add_points_from_source(subcontent.get_combined_monetary_worth() * 0.005, "data") + + qdel(sold_crate) /datum/controller/subsystem/supply/proc/get_clear_turfs() var/list/clear_turfs = list() - for(var/area/subarea in shuttle.shuttle_area) - for(var/turf/T in subarea) - if(T.density) + for(var/turf/candidate_turf in subarea) + if(candidate_turf.density) continue - var/occupied = 0 - for(var/atom/A in T.contents) - if(!A.simulated || !A.density) + var/occupied = FALSE + for(var/atom/movable/child as anything in candidate_turf.contents) + if(!child.simulated || !child.density) continue - occupied = 1 + occupied = TRUE break if(!occupied) - clear_turfs += T - + clear_turfs += candidate_turf return clear_turfs //Buyin @@ -133,56 +126,55 @@ SUBSYSTEM_DEF(supply) var/list/clear_turfs = get_clear_turfs() - for(var/S in shoppinglist) + for(var/datum/supply_order/order in shoppinglist) if(!clear_turfs.len) break var/turf/pickedloc = pick_n_take(clear_turfs) - shoppinglist -= S - donelist += S + shoppinglist -= order + donelist += order - var/datum/supply_order/SO = S - var/decl/hierarchy/supply_pack/SP = SO.object + var/decl/hierarchy/supply_pack/supplypack = order.object - var/obj/A = new SP.containertype(pickedloc) - A.SetName("[SP.containername][SO.comment ? " ([SO.comment])":"" ]") + var/obj/result = new supplypack.containertype(pickedloc) + result.SetName("[supplypack.containername][order.comment ? " ([order.comment])":"" ]") //supply manifest generation begin var/obj/item/paper/manifest/slip - if(!SP.contraband) + if(!supplypack.contraband) var/info = list() info +="

    [global.using_map.boss_name] Shipping Manifest



    " - info +="Order #[SO.ordernum]
    " + info +="Order #[order.ordernum]
    " info +="Destination: [global.using_map.station_name]
    " info +="[shoppinglist.len] PACKAGES IN THIS SHIPMENT
    " info +="CONTENTS:
      " - slip = new /obj/item/paper/manifest(A, null, JOINTEXT(info)) - LAZYSET(slip.metadata, "order_total", SP.cost) + slip = new /obj/item/paper/manifest(result, null, JOINTEXT(info)) + LAZYSET(slip.metadata, "order_total", supplypack.cost) LAZYSET(slip.metadata, "is_copy", FALSE) //spawn the stuff, finish generating the manifest while you're at it - if(SP.access) - if(!islist(SP.access)) - A.req_access = list(SP.access) - else if(islist(SP.access)) - var/list/L = SP.access // access var is a plain var, we need a list - A.req_access = L.Copy() - - var/list/spawned = SP.spawn_contents(A) + if(supplypack.access) + if(!islist(supplypack.access)) + result.req_access = list(supplypack.access) + else if(islist(supplypack.access)) + var/list/supplypack_access = supplypack.access // access var is a plain var, we need a list + result.req_access = supplypack_access.Copy() + + var/list/spawned = supplypack.spawn_contents(result) if(slip) for(var/atom/content in spawned) slip.info += "
    • [content.name]
    • " //add the item to the manifest slip.info += "

    CHECK CONTENTS AND STAMP BELOW THE LINE TO CONFIRM RECEIPT OF GOODS
    " // Adds any given item to the supply shuttle -/datum/controller/subsystem/supply/proc/addAtom(var/atom/movable/A) +/datum/controller/subsystem/supply/proc/addAtom(var/atom/movable/added) var/list/clear_turfs = get_clear_turfs() if(!clear_turfs.len) return FALSE var/turf/pickedloc = pick(clear_turfs) - A.forceMove(pickedloc) + added.forceMove(pickedloc) return TRUE diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm index e7ec3c1645be..727e55a1432c 100644 --- a/code/datums/supplypacks/engineering.dm +++ b/code/datums/supplypacks/engineering.dm @@ -87,7 +87,7 @@ containername = "collector crate" access = access_engine_equip -/decl/hierarchy/supply_pack/engineering/PA +/decl/hierarchy/supply_pack/engineering/particle_accelerator name = "Equipment - Particle accelerator" contains = list(/obj/structure/particle_accelerator/fuel_chamber, /obj/machinery/particle_accelerator/control_box, diff --git a/code/datums/supplypacks/supplypack.dm b/code/datums/supplypacks/supplypack.dm index 1be6469edc51..c9e824cbeedd 100644 --- a/code/datums/supplypacks/supplypack.dm +++ b/code/datums/supplypacks/supplypack.dm @@ -14,8 +14,13 @@ var/supply_method = /decl/supply_method var/decl/security_level/security_level -//Is run once on init for non-base-category supplypacks. var/global/list/cargoprices = list() +/decl/hierarchy/supply_pack/Initialize() + . = ..() + if(!is_category()) + setup() + +//Is run once on init for non-category supplypacks. /decl/hierarchy/supply_pack/proc/setup() if(!num_contained) for(var/entry in contains) diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 22ddf68cddd3..d376a8bfc4fe 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -153,9 +153,9 @@ . += " |" var/category_cost = 0 - for(var/gear in LC.gear) - var/decl/loadout_option/gear = LC.gear[gear] - if(gear in pref.gear_list[pref.gear_slot]) + for(var/gear_id in LC.gear) + if(gear_id in pref.gear_list[pref.gear_slot]) + var/decl/loadout_option/gear = LC.gear[gear_id] category_cost += gear.cost if(category == current_category_decl.type) @@ -179,8 +179,8 @@ var/list/other_gear = list() var/i = 0 - for(var/gear in current_loadout) - var/decl/loadout_option/gear = decls_repository.get_decl_by_id(gear, validate_decl_type = FALSE) + for(var/gear_id in current_loadout) + var/decl/loadout_option/gear = decls_repository.get_decl_by_id(gear_id, validate_decl_type = FALSE) if(istype(gear)) if(gear.slot) i++ From a73bf4c747b5bc176967610c439dfb66ea012005 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 01:53:00 -0500 Subject: [PATCH 054/512] Clean up vehicle engine code --- code/modules/vehicles/engine.dm | 105 ++++++++++++++++---------------- 1 file changed, 51 insertions(+), 54 deletions(-) diff --git a/code/modules/vehicles/engine.dm b/code/modules/vehicles/engine.dm index 90baf9d3dbe6..d11185796a74 100644 --- a/code/modules/vehicles/engine.dm +++ b/code/modules/vehicles/engine.dm @@ -4,7 +4,7 @@ icon = 'icons/obj/objects.dmi' w_class = ITEM_SIZE_HUGE material = /decl/material/solid/metal/steel - var/stat = 0 + var/broken = FALSE var/trail_type var/cost_per_move = 5 @@ -19,10 +19,10 @@ /obj/item/engine/proc/use_power() return 0 -/obj/item/engine/proc/rev_engine(var/atom/movable/M) +/obj/item/engine/proc/rev_engine(var/obj/vehicle/vehicle) return -/obj/item/engine/proc/putter(var/atom/movable/M) +/obj/item/engine/proc/putter(var/obj/vehicle/vehicle) return /obj/item/engine/electric @@ -34,9 +34,10 @@ var/obj/item/cell/cell /obj/item/engine/electric/attackby(var/obj/item/used_item, var/mob/user) - if(istype(used_item,/obj/item/cell)) + // TODO: use cell extension for this? + if(istype(used_item, /obj/item/cell)) if(cell) - to_chat(user, "There is already a cell in \the [src].") + to_chat(user, SPAN_WARNING("There is already a cell in \the [src].")) else cell = used_item user.drop_from_inventory(used_item) @@ -44,7 +45,7 @@ return TRUE else if(IS_CROWBAR(used_item)) if(cell) - to_chat(user, "You pry out \the [cell] with \the [used_item].") + to_chat(user, SPAN_NOTICE("You pry out \the [cell] with \the [used_item].")) cell.dropInto(loc) cell = null return TRUE @@ -58,14 +59,14 @@ /obj/item/engine/electric/use_power() if(!cell) - return 0 + return FALSE return cell.use(cost_per_move * CELLRATE) -/obj/item/engine/electric/rev_engine(var/atom/movable/M) - M.audible_message("\The [M] beeps, spinning up.") +/obj/item/engine/electric/rev_engine(var/obj/vehicle/vehicle) + vehicle.audible_message("\The [vehicle] beeps, spinning up.") -/obj/item/engine/electric/putter(var/atom/movable/M) - M.audible_message("\The [M] makes one depressed beep before winding down.") +/obj/item/engine/electric/putter(var/obj/vehicle/vehicle) + vehicle.audible_message("\The [vehicle] makes one depressed beep before winding down.") /obj/item/engine/electric/emp_act(var/severity) if(cell) @@ -78,7 +79,7 @@ icon_state = "engine_fuel" trail_type = /datum/effect/effect/system/trail/thermal atom_flags = ATOM_FLAG_OPEN_CONTAINER - var/obj/temp_reagents_holder + var/datum/reagents/combustion_chamber var/fuel_points = 0 //fuel points are determined by differing reagents @@ -88,54 +89,50 @@ /obj/item/engine/thermal/Initialize() . = ..() create_reagents(500) - temp_reagents_holder = new() - temp_reagents_holder.create_reagents(15) - temp_reagents_holder.atom_flags |= ATOM_FLAG_OPEN_CONTAINER + combustion_chamber = new(15, global.temp_reagents_holder) /obj/item/engine/thermal/attackby(var/obj/item/used_item, var/mob/user) if(used_item.standard_pour_into(user, src)) return TRUE return ..() -/obj/item/engine/thermal/use_power() - if(fuel_points >= cost_per_move) - fuel_points -= cost_per_move - return 1 - if(!reagents || reagents.total_volume <= 0 || stat) - return 0 - - reagents.trans_to(temp_reagents_holder,min(reagents.total_volume,15)) - var/multiplier = 1 - var/actually_flameable = 0 - for(var/rtype in temp_reagents_holder.reagents.reagent_volumes) +/// Attempts to burn a sample of the fuel in our reagent holder. Returns TRUE if enough fuel points are produced to move, otherwise returns FALSE. +/obj/item/engine/thermal/proc/burn_fuel() + if(!reagents || reagents.total_volume <= 0 || broken) + return FALSE + reagents.trans_to_holder(combustion_chamber, min(reagents.total_volume, 15)) + var/multiplier = 0 + var/actually_flammable = FALSE + for(var/rtype in combustion_chamber.reagent_volumes) var/new_multiplier = 1 - var/decl/material/R = GET_DECL(rtype) - if(istype(R, /decl/material/liquid/alcohol)) - var/decl/material/liquid/alcohol/E = R - new_multiplier = (10/E.strength) - actually_flameable = 1 - else if(istype(R,/decl/material/liquid/fuel/hydrazine)) - new_multiplier = 1.25 - actually_flameable = 1 - else if(istype(R,/decl/material/liquid/fuel)) - actually_flameable = 1 - else if(istype(R,/decl/material/liquid/frostoil)) - new_multiplier = 0.1 - else if(istype(R,/decl/material/liquid/water)) - new_multiplier = 0.4 - else if(istype(R,/decl/material/liquid/nutriment/sugar) && REAGENT_VOLUME(reagents, rtype) > 1) - stat = DEAD + var/reagent_volume = combustion_chamber.reagent_volumes[rtype] + var/decl/material/reagent = GET_DECL(rtype) + if(reagent.accelerant_value < FUEL_VALUE_NONE) // suppresses fires rather than starts them + // this means that FUEL_VALUE_SUPPRESSANT is on par with water in the old code + new_multiplier = -(FUEL_VALUE_SUPPRESSANT + reagent.accelerant_value) / 2 * 0.4 + if(reagent.accelerant_value > FUEL_VALUE_NONE) + // averaging these means that FUEL_VALUE_ACCELERANT is 1x, hydrazine is 1.25x, and exotic matter is 1.5x + new_multiplier = (FUEL_VALUE_ACCELERANT + reagent.accelerant_value) / 2 + actually_flammable = TRUE + if(ispath(rtype, /decl/material/liquid/nutriment/sugar) && REAGENT_VOLUME(reagents, rtype) > 1) + broken = TRUE explosion(get_turf(src),-1,0,2,3,0) return 0 - multiplier = (multiplier + new_multiplier)/2 - if(!actually_flameable) - return 0 - fuel_points += 20 * multiplier * temp_reagents_holder.reagents.total_volume - temp_reagents_holder.reagents.clear_reagents() - return use_power() - -/obj/item/engine/thermal/rev_engine(var/atom/movable/M) - M.audible_message("\The [M] rumbles to life.") - -/obj/item/engine/thermal/putter(var/atom/movable/M) - M.audible_message("\The [M] putters before turning off.") \ No newline at end of file + multiplier += new_multiplier * reagent_volume + if(!actually_flammable) + return FALSE + fuel_points += 20 * multiplier + combustion_chamber.clear_reagents() + return fuel_points >= cost_per_move + +/obj/item/engine/thermal/use_power() + if(fuel_points >= cost_per_move || burn_fuel()) + fuel_points -= cost_per_move + return TRUE + return FALSE + +/obj/item/engine/thermal/rev_engine(var/obj/vehicle/vehicle) + vehicle.audible_message("\The [vehicle] rumbles to life.") + +/obj/item/engine/thermal/putter(var/obj/vehicle/vehicle) + vehicle.audible_message("\The [vehicle] putters before turning off.") \ No newline at end of file From 68cd764f3b8c2bb6fe5204e0f52e159e38efc0e8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 02:47:42 -0500 Subject: [PATCH 055/512] Clean up variable names in memory code --- code/datums/mind/memory.dm | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/code/datums/mind/memory.dm b/code/datums/mind/memory.dm index 34dacf9ef8a3..0089d7d8dfc9 100644 --- a/code/datums/mind/memory.dm +++ b/code/datums/mind/memory.dm @@ -7,8 +7,8 @@ . = mind.StoreMemory(memory, options) /datum/mind/proc/StoreMemory(var/memory, var/options) - var/decl/memory_options/MO = GET_DECL(options || /decl/memory_options/default) - return MO.Create(src, memory) + var/decl/memory_options/memory_option = GET_DECL(options || /decl/memory_options/default) + return memory_option.Create(src, memory) /datum/mind/proc/RemoveMemory(var/datum/memory/memory, var/mob/remover) if(!memory) @@ -20,20 +20,18 @@ ShowMemory(remover) /datum/mind/proc/ClearMemories(var/list/tags) - for(var/mem in memories) - var/datum/memory/M = mem + for(var/datum/memory/mem as anything in memories) // If no tags were supplied OR if there is any union between the given tags and memory tags // then remove the memory - if(!length(tags) || length(tags & M.tags)) - LAZYREMOVE(memories, M) + if(!length(tags) || length(tags & mem.tags)) + LAZYREMOVE(memories, mem) /datum/mind/proc/CopyMemories(var/datum/mind/target) if(!istype(target)) return - for(var/mem in memories) - var/datum/memory/M = mem - M.Copy(target) + for(var/datum/memory/mem in memories) + mem.Copy(target) /datum/mind/proc/MemoryTags() . = list() @@ -50,13 +48,12 @@ var/list/output = list() var/last_owner_name // We pretend that memories are stored in some semblance of an order - for(var/mem in memories) - var/datum/memory/M = mem - var/owner_name = M.OwnerName() + for(var/datum/memory/mem in memories) + var/owner_name = mem.OwnerName() if(owner_name != last_owner_name) output += "[current.real_name]'s Memories
    " last_owner_name = owner_name - output += "[M.memory] \[Remove\]" + output += "[mem.memory] \[Remove\]" if(objectives.len > 0) output += "
    Objectives:" @@ -161,9 +158,8 @@ return var/relevant_memories = 0 - for(var/mem in target.memories) - var/datum/memory/M = mem - if(M.type == memory_type) + for(var/datum/memory/mem in target.memories) + if(mem.type == memory_type) relevant_memories++ if(relevant_memories > memory_limit) From aeb7c18069d87dfeb35489078d679e5ff4573edb Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 03:28:02 -0500 Subject: [PATCH 056/512] Fix two-letter decl variable names --- code/controllers/subsystems/supply.dm | 7 ++-- code/datums/appearances/automatic/cardborg.dm | 12 +++--- code/datums/hierarchy.dm | 9 +++- code/datums/outfits/equipment/backpacks.dm | 6 +-- code/datums/outfits/outfit.dm | 10 ++--- code/datums/supplypacks/supplypack.dm | 41 +++++++++---------- code/datums/uplink/uplink_sources.dm | 4 +- code/game/machinery/alarm.dm | 16 ++++---- code/game/machinery/status_display.dm | 22 +++++----- code/game/turfs/initialization/init.dm | 7 ++-- code/game/turfs/turf_footsteps.dm | 4 +- code/modules/admin/verbs/modifyvariables.dm | 6 +-- code/modules/bodytype/bodytype_random.dm | 4 +- .../preference_setup/antagonism/02_setup.dm | 28 ++++++------- .../preference_setup/general/02_body.dm | 8 ++-- .../preference_setup/general/04_equipment.dm | 12 +++--- .../preference_setup/global/02_prefixes.dm | 4 +- .../preference_setup/loadout/loadout.dm | 32 +++++++-------- code/modules/client/ui_styles/_helpers.dm | 6 +-- code/modules/economy/_worth.dm | 6 +-- code/modules/events/shipping_error.dm | 10 ++--- code/modules/genetics/plants/gene_special.dm | 2 +- code/modules/genetics/plants/gene_vigour.dm | 2 +- code/modules/hydroponics/seed.dm | 16 ++++---- code/modules/hydroponics/seed_gene_mut.dm | 12 +++--- code/modules/hydroponics/trays/tray.dm | 4 +- .../subtypes/reagents.dm | 4 +- code/modules/mob/living/human/examine.dm | 4 +- .../retaliate/giant_parrot/giant_parrot.dm | 10 ++--- code/modules/mob/new_player/login.dm | 6 +-- .../file_system/programs/generic/supply.dm | 39 +++++++++--------- .../device_types/_network_device.dm | 12 +++--- .../drinkingglass/drinkingglass.dm | 16 ++++---- .../reagents/reagent_containers/spray.dm | 6 +-- code/modules/scent/_scent.dm | 10 ++--- code/unit_tests/alt_appearances_test.dm | 16 ++++---- code/unit_tests/view_variables_test.dm | 22 +++++----- .../byond_membership/_byond_membership.dm | 4 +- 38 files changed, 220 insertions(+), 219 deletions(-) diff --git a/code/controllers/subsystems/supply.dm b/code/controllers/subsystems/supply.dm index c581a872ec7b..69bde2c28c2d 100644 --- a/code/controllers/subsystems/supply.dm +++ b/code/controllers/subsystems/supply.dm @@ -41,10 +41,9 @@ SUBSYSTEM_DEF(supply) //Build master supply list var/decl/hierarchy/supply_pack/root = IMPLIED_DECL - for(var/decl/hierarchy/supply_pack/sp in root.get_descendants()) - if(!sp.is_category()) - master_supply_list += sp - CHECK_TICK + for(var/decl/hierarchy/supply_pack/pack in root.get_descendants()) + if(!pack.is_category()) + master_supply_list += pack // Just add points over time. /datum/controller/subsystem/supply/fire() diff --git a/code/datums/appearances/automatic/cardborg.dm b/code/datums/appearances/automatic/cardborg.dm index 52ad0031f3bb..dcc909286344 100644 --- a/code/datums/appearances/automatic/cardborg.dm +++ b/code/datums/appearances/automatic/cardborg.dm @@ -34,19 +34,19 @@ var/obj/item/back = H.get_equipped_item(slot_back_str) if(!istype(back)) return - var/decl/cardborg_appearance/ca = appearances[back.type] - if(!ca) ca = appearances[/obj/item/backpack] + var/decl/cardborg_appearance/disguise = appearances[back.type] + if(!disguise) disguise = appearances[/obj/item/backpack] - var/image/I = image(icon = ca.icon, icon_state = ca.icon_state, loc = H) + var/image/I = image(icon = disguise.icon, icon_state = disguise.icon_state, loc = H) I.override = 1 - I.overlays += image(icon = ca.icon, icon_state = "[ca.icon_state]-eyes") //gotta look realistic + I.overlays += image(icon = disguise.icon, icon_state = "[disguise.icon_state]-eyes") //gotta look realistic return I /decl/appearance_handler/cardborg/proc/init_appearances() if(!appearances) appearances = list() - for(var/decl/cardborg_appearance/ca in init_subtypes(/decl/cardborg_appearance)) - appearances[ca.backpack_type] = ca + for(var/decl/cardborg_appearance/disguise in init_subtypes(/decl/cardborg_appearance)) + appearances[disguise.backpack_type] = disguise /decl/cardborg_appearance var/backpack_type diff --git a/code/datums/hierarchy.dm b/code/datums/hierarchy.dm index 1186dcebc939..361295e09ae3 100644 --- a/code/datums/hierarchy.dm +++ b/code/datums/hierarchy.dm @@ -4,6 +4,8 @@ var/name = "Hierarchy" var/decl/hierarchy/parent var/list/decl/hierarchy/children + /// The cached result of get_descendants(). Should not be mutated. + VAR_PRIVATE/list/decl/hierarchy/_descendants var/expected_type /decl/hierarchy/Initialize() @@ -22,10 +24,13 @@ /decl/hierarchy/proc/get_descendants() if(!children) return - . = children.Copy() + if(_descendants) + return _descendants + _descendants = children.Copy() for(var/decl/hierarchy/child in children) if(child.children) - . |= child.get_descendants() + _descendants |= child.get_descendants() + return _descendants /decl/hierarchy/dd_SortValue() return name diff --git a/code/datums/outfits/equipment/backpacks.dm b/code/datums/outfits/equipment/backpacks.dm index 2a4aed715eab..8e6c68468285 100644 --- a/code/datums/outfits/equipment/backpacks.dm +++ b/code/datums/outfits/equipment/backpacks.dm @@ -190,9 +190,9 @@ /proc/get_default_outfit_backpack() var backpacks = global.using_map.get_available_backpacks() for(var/backpack in backpacks) - var/decl/backpack_outfit/bo = backpacks[backpack] - if(bo.is_default) - return bo + var/decl/backpack_outfit/backpack_option = backpacks[backpack] + if(backpack_option.is_default) + return backpack_option #undef BACKPACK_HAS_TYPE_SELECTION #undef BACKPACK_HAS_SUBTYPE_SELECTION diff --git a/code/datums/outfits/outfit.dm b/code/datums/outfits/outfit.dm index 0aa0c9ea9923..fa1c3f9627b9 100644 --- a/code/datums/outfits/outfit.dm +++ b/code/datums/outfits/outfit.dm @@ -205,17 +205,17 @@ wearer.put_in_hands(new hand(wearer)) if((outfit_flags & OUTFIT_HAS_BACKPACK) && !(OUTFIT_ADJUSTMENT_SKIP_BACKPACK & equip_adjustments)) - var/decl/backpack_outfit/bo + var/decl/backpack_outfit/backpack_option var/metadata if(wearer.backpack_setup) - bo = wearer.backpack_setup.backpack + backpack_option = wearer.backpack_setup.backpack metadata = wearer.backpack_setup.metadata else - bo = get_default_outfit_backpack() + backpack_option = get_default_outfit_backpack() - var/override_type = backpack_overrides[bo.type] - var/backpack = bo.spawn_backpack(wearer, metadata, override_type) + var/override_type = backpack_overrides[backpack_option.type] + var/backpack = backpack_option.spawn_backpack(wearer, metadata, override_type) if(backpack) if(back) diff --git a/code/datums/supplypacks/supplypack.dm b/code/datums/supplypacks/supplypack.dm index c9e824cbeedd..319d1dee4089 100644 --- a/code/datums/supplypacks/supplypack.dm +++ b/code/datums/supplypacks/supplypack.dm @@ -16,12 +16,9 @@ var/global/list/cargoprices = list() /decl/hierarchy/supply_pack/Initialize() - . = ..() - if(!is_category()) - setup() - -//Is run once on init for non-category supplypacks. -/decl/hierarchy/supply_pack/proc/setup() + . = ..() // make sure children are set up + if(is_category()) + return // don't do any of this for categories if(!num_contained) for(var/entry in contains) num_contained += max(1, contains[entry]) @@ -33,8 +30,8 @@ var/global/list/cargoprices = list() cost = max(1, NONUNIT_CEILING((cost * WORTH_TO_SUPPLY_POINTS_CONSTANT * SSsupply.price_markup), WORTH_TO_SUPPLY_POINTS_ROUND_CONSTANT)) global.cargoprices[name] = cost - var/decl/supply_method/sm = GET_DECL(supply_method) - manifest = sm.setup_manifest(src) + var/decl/supply_method/method = GET_DECL(supply_method) + manifest = method.setup_manifest(src) /client/proc/print_cargo_prices() set name = "Print Cargo Prices" @@ -64,8 +61,8 @@ var/global/list/cargoprices = list() return security_state.current_security_level_is_same_or_higher_than(security_level) /decl/hierarchy/supply_pack/proc/spawn_contents(var/location) - var/decl/supply_method/sm = GET_DECL(supply_method) - . = sm.spawn_contents(src, location) + var/decl/supply_method/method = GET_DECL(supply_method) + . = method.spawn_contents(src, location) for(var/obj/O in .) O.anchored = FALSE @@ -78,18 +75,18 @@ var/global/list/cargoprices = list() //NEW NOTE: Do NOT set the price of any crates below 7 points. Doing so allows infinite points. */ -/decl/supply_method/proc/spawn_contents(var/decl/hierarchy/supply_pack/sp, var/location) - if(!sp || !location) +/decl/supply_method/proc/spawn_contents(var/decl/hierarchy/supply_pack/pack, var/location) + if(!pack || !location) return . = list() - for(var/entry in sp.contains) - for(var/i = 1 to max(1, sp.contains[entry])) + for(var/entry in pack.contains) + for(var/i = 1 to max(1, pack.contains[entry])) dd_insertObjectList(.,new entry(location)) -/decl/supply_method/proc/setup_manifest(var/decl/hierarchy/supply_pack/sp) +/decl/supply_method/proc/setup_manifest(var/decl/hierarchy/supply_pack/pack) . = list() . += "
      " - for(var/path in sp.contains) + for(var/path in pack.contains) var/atom/A = path if(!ispath(A)) continue @@ -97,13 +94,13 @@ var/global/list/cargoprices = list() . += "
    " . = jointext(.,null) -/decl/supply_method/randomized/spawn_contents(var/decl/hierarchy/supply_pack/sp, var/location) - if(!sp || !location) +/decl/supply_method/randomized/spawn_contents(var/decl/hierarchy/supply_pack/pack, var/location) + if(!pack || !location) return . = list() - for(var/j = 1 to sp.num_contained) - var/picked = pick(sp.contains) + for(var/j = 1 to pack.num_contained) + var/picked = pick(pack.contains) . += new picked(location) -/decl/supply_method/randomized/setup_manifest(var/decl/hierarchy/supply_pack/sp) - return "Contains any [sp.num_contained] of:" + ..() +/decl/supply_method/randomized/setup_manifest(var/decl/hierarchy/supply_pack/pack) + return "Contains any [pack.num_contained] of:" + ..() diff --git a/code/datums/uplink/uplink_sources.dm b/code/datums/uplink/uplink_sources.dm index cb3f5f775ace..a37027741bf1 100644 --- a/code/datums/uplink/uplink_sources.dm +++ b/code/datums/uplink/uplink_sources.dm @@ -133,8 +133,8 @@ var/global/list/default_uplink_source_priority = list( priority_order |= GET_DECL(entry) for(var/entry in priority_order) - var/decl/uplink_source/US = entry - if(US.setup_uplink_source(M, amount) != SETUP_FAILED) + var/decl/uplink_source/uplink = entry + if(uplink.setup_uplink_source(M, amount) != SETUP_FAILED) return TRUE to_chat(M, "Either by choice or circumstance you will be without an uplink.") diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 928b331c9292..ea3a147ad7ea 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -884,18 +884,18 @@ FIRE ALARM set_light(2, 0.25, COLOR_RED) else if(isContactLevel(z)) var/decl/security_state/security_state = GET_DECL(global.using_map.security_state) - var/decl/security_level/sl = security_state.current_security_level + var/decl/security_level/sec_level = security_state.current_security_level - set_light(sl.light_power, sl.light_range, sl.light_color_alarm) + set_light(sec_level.light_power, sec_level.light_range, sec_level.light_color_alarm) - if(sl.alarm_appearance.alarm_icon) - var/image/alert1 = image(sl.icon, sl.alarm_appearance.alarm_icon) - alert1.color = sl.alarm_appearance.alarm_icon_color + if(sec_level.alarm_appearance.alarm_icon) + var/image/alert1 = image(sec_level.icon, sec_level.alarm_appearance.alarm_icon) + alert1.color = sec_level.alarm_appearance.alarm_icon_color add_overlay(alert1) - if(sl.alarm_appearance.alarm_icon_twotone) - var/image/alert2 = image(sl.icon, sl.alarm_appearance.alarm_icon_twotone) - alert2.color = sl.alarm_appearance.alarm_icon_twotone_color + if(sec_level.alarm_appearance.alarm_icon_twotone) + var/image/alert2 = image(sec_level.icon, sec_level.alarm_appearance.alarm_icon_twotone) + alert2.color = sec_level.alarm_appearance.alarm_icon_twotone_color add_overlay(alert2) else add_overlay("fire0") diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index f42cb1070087..4059128a7d11 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -168,23 +168,23 @@ remove_display() var/decl/security_state/security_state = GET_DECL(global.using_map.security_state) - var/decl/security_level/sl = security_state.current_security_level + var/decl/security_level/sec_level = security_state.current_security_level - set_light(sl.light_range, sl.light_power, sl.light_color_status_display) + set_light(sec_level.light_range, sec_level.light_power, sec_level.light_color_status_display) - if(sl.alarm_appearance.display_icon) - var/image/alert1 = image(sl.icon, sl.alarm_appearance.display_icon) - alert1.color = sl.alarm_appearance.display_icon_color + if(sec_level.alarm_appearance.display_icon) + var/image/alert1 = image(sec_level.icon, sec_level.alarm_appearance.display_icon) + alert1.color = sec_level.alarm_appearance.display_icon_color overlays |= alert1 - if(sl.alarm_appearance.display_icon_twotone) - var/image/alert2 = image(sl.icon, sl.alarm_appearance.display_icon_twotone) - alert2.color = sl.alarm_appearance.display_icon_twotone_color + if(sec_level.alarm_appearance.display_icon_twotone) + var/image/alert2 = image(sec_level.icon, sec_level.alarm_appearance.display_icon_twotone) + alert2.color = sec_level.alarm_appearance.display_icon_twotone_color overlays |= alert2 - if(sl.alarm_appearance.display_emblem) - var/image/alert3 = image(sl.icon, sl.alarm_appearance.display_emblem) - alert3.color = sl.alarm_appearance.display_emblem_color + if(sec_level.alarm_appearance.display_emblem) + var/image/alert3 = image(sec_level.icon, sec_level.alarm_appearance.display_emblem) + alert3.color = sec_level.alarm_appearance.display_emblem_color overlays |= alert3 /obj/machinery/status_display/proc/set_picture(state) diff --git a/code/game/turfs/initialization/init.dm b/code/game/turfs/initialization/init.dm index 4229a04db9a7..1553584fcd6e 100644 --- a/code/game/turfs/initialization/init.dm +++ b/code/game/turfs/initialization/init.dm @@ -7,6 +7,7 @@ /area/Initialize(mapload) . = ..() if(ispath(turf_initializer)) - var/decl/turf_initializer/ti = GET_DECL(turf_initializer) - for(var/turf/T in src) - ti.InitializeTurf(T) + var/decl/turf_initializer/initializer = GET_DECL(turf_initializer) + // TODO: It may be worth doing a post-mapload loop over turfs instead, to limit the number of in-area (in-world) loops? + for(var/turf/initialized_turf in src) + initializer.InitializeTurf(initialized_turf) diff --git a/code/game/turfs/turf_footsteps.dm b/code/game/turfs/turf_footsteps.dm index bfa1f9171569..afa6623a4985 100644 --- a/code/game/turfs/turf_footsteps.dm +++ b/code/game/turfs/turf_footsteps.dm @@ -1,8 +1,8 @@ /proc/get_footstep_for_mob(var/footstep_type, var/mob/living/caller) . = istype(caller) && caller.get_mob_footstep(footstep_type) if(!.) - var/decl/footsteps/FS = GET_DECL(footstep_type) - . = pick(FS.footstep_sounds) + var/decl/footsteps/footsteps = GET_DECL(footstep_type) + . = pick(footsteps.footstep_sounds) /turf/proc/get_footstep_sound(var/mob/caller) for(var/obj/structure/S in contents) diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm index 06c04257babc..94fc9afc0221 100644 --- a/code/modules/admin/verbs/modifyvariables.dm +++ b/code/modules/admin/verbs/modifyvariables.dm @@ -526,8 +526,8 @@ /client/proc/special_set_vv_var(var/datum/O, variable, var_value, client) var/list/vv_set_handlers = decls_repository.get_decls_of_subtype(/decl/vv_set_handler) for(var/vv_handler in vv_set_handlers) - var/decl/vv_set_handler/sh = vv_set_handlers[vv_handler] - if(sh.can_handle_set_var(O, variable, var_value, client)) - sh.handle_set_var(O, variable, var_value, client) + var/decl/vv_set_handler/set_handler = vv_set_handlers[vv_handler] + if(set_handler.can_handle_set_var(O, variable, var_value, client)) + set_handler.handle_set_var(O, variable, var_value, client) return TRUE return FALSE diff --git a/code/modules/bodytype/bodytype_random.dm b/code/modules/bodytype/bodytype_random.dm index 2e79046a92fd..fac34e32ebce 100644 --- a/code/modules/bodytype/bodytype_random.dm +++ b/code/modules/bodytype/bodytype_random.dm @@ -4,8 +4,8 @@ if((Z && !(appearance_flags & Z)) || !random_##Y.len){\ return;\ }\ - var/decl/color_generator/CG = GET_DECL(pickweight(random_##Y));\ - return CG && CG.generate_random_colour();\ + var/decl/color_generator/color_gen = GET_DECL(pickweight(random_##Y));\ + return color_gen?.generate_random_colour();\ } #define SETUP_RANDOM_COLOR_SETTER(X, Y)\ diff --git a/code/modules/client/preference_setup/antagonism/02_setup.dm b/code/modules/client/preference_setup/antagonism/02_setup.dm index ca6da3330fc5..ca04f308db91 100644 --- a/code/modules/client/preference_setup/antagonism/02_setup.dm +++ b/code/modules/client/preference_setup/antagonism/02_setup.dm @@ -27,8 +27,8 @@ /datum/category_item/player_setup_item/antagonism/basic/save_character(datum/pref_record_writer/writer) var/uplink_order = list() for(var/entry in pref.uplink_sources) - var/decl/uplink_source/UL = entry - uplink_order += UL.name + var/decl/uplink_source/uplink = entry + uplink_order += uplink.name writer.write("uplink_sources", uplink_order) writer.write("exploit_record", pref.exploit_record) @@ -43,10 +43,10 @@ . +="Antag Setup:
    " . +="Uplink Source Priority: Add
    " for(var/entry in pref.uplink_sources) - var/decl/uplink_source/US = entry - . +="[US.name] Move Up Move Down Remove
    " - if(US.desc) - . += "[US.desc]
    " + var/decl/uplink_source/uplink = entry + . +="[uplink.name] Move Up Move Down Remove
    " + if(uplink.desc) + . += "[uplink.desc]
    " if(!pref.uplink_sources.len) . += "You will not receive an uplink unless you add an uplink source!" . +="
    " @@ -64,25 +64,25 @@ return TOPIC_REFRESH if(href_list["remove_source"]) - var/decl/uplink_source/US = locate(href_list["remove_source"]) in pref.uplink_sources - if(US && pref.uplink_sources.Remove(US)) + var/decl/uplink_source/uplink = locate(href_list["remove_source"]) in pref.uplink_sources + if(uplink && pref.uplink_sources.Remove(uplink)) return TOPIC_REFRESH if(href_list["move_source_up"]) - var/decl/uplink_source/US = locate(href_list["move_source_up"]) in pref.uplink_sources - if(!US) + var/decl/uplink_source/uplink = locate(href_list["move_source_up"]) in pref.uplink_sources + if(!uplink) return TOPIC_NOACTION - var/index = pref.uplink_sources.Find(US) + var/index = pref.uplink_sources.Find(uplink) if(index <= 1) return TOPIC_NOACTION pref.uplink_sources.Swap(index, index - 1) return TOPIC_REFRESH if(href_list["move_source_down"]) - var/decl/uplink_source/US = locate(href_list["move_source_down"]) in pref.uplink_sources - if(!US) + var/decl/uplink_source/uplink = locate(href_list["move_source_down"]) in pref.uplink_sources + if(!uplink) return TOPIC_NOACTION - var/index = pref.uplink_sources.Find(US) + var/index = pref.uplink_sources.Find(uplink) if(index >= pref.uplink_sources.len) return TOPIC_NOACTION pref.uplink_sources.Swap(index, index + 1) diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index 38ea82db935b..044ee78d3d7c 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -261,8 +261,8 @@ var/list/accessory_metadata = length(current_accessories) ? current_accessories[current_accessory] : accessory_decl.get_default_accessory_metadata() var/list/metadata_strings = list() for(var/metadata_type in accessory_decl.accessory_metadata_types) - var/decl/sprite_accessory_metadata/sam = GET_DECL(metadata_type) - metadata_strings += sam.get_metadata_options_string(src, accessory_cat_decl, accessory_decl, LAZYACCESS(accessory_metadata, metadata_type)) + var/decl/sprite_accessory_metadata/metadata = GET_DECL(metadata_type) + metadata_strings += metadata.get_metadata_options_string(src, accessory_cat_decl, accessory_decl, LAZYACCESS(accessory_metadata, metadata_type)) var/acc_decl_ref = "\ref[accessory_decl]" . += "" . += "[accessory_cat_decl.name]" @@ -284,8 +284,8 @@ var/list/accessory_metadata = current_accessories[accessory] var/list/metadata_strings = list() for(var/metadata_type in accessory_decl.accessory_metadata_types) - var/decl/sprite_accessory_metadata/sam = GET_DECL(metadata_type) - metadata_strings += sam.get_metadata_options_string(src, accessory_cat_decl, accessory_decl, LAZYACCESS(accessory_metadata, metadata_type)) + var/decl/sprite_accessory_metadata/metadata = GET_DECL(metadata_type) + metadata_strings += metadata.get_metadata_options_string(src, accessory_cat_decl, accessory_decl, LAZYACCESS(accessory_metadata, metadata_type)) var/acc_decl_ref = "\ref[accessory_decl]" . += "" . += "Remove" diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index 79a4edfe91e0..d1678ce103cf 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -18,8 +18,8 @@ if(!backpacks_by_name) backpacks_by_name = list() var/bos = global.using_map.get_available_backpacks() - for(var/bo in bos) - var/decl/backpack_outfit/backpack_outfit = bos[bo] + for(var/backpack_option in bos) + var/decl/backpack_outfit/backpack_outfit = bos[backpack_option] backpacks_by_name[backpack_outfit.name] = backpack_outfit /datum/category_item/player_setup_item/physical/equipment/load_character(datum/pref_record_reader/R) @@ -210,13 +210,13 @@ var/backpack_name = href_list["backpack"] if(!(backpack_name in backpacks_by_name)) return TOPIC_NOACTION - var/decl/backpack_outfit/bo = backpacks_by_name[backpack_name] - var/datum/backpack_tweak/bt = locate(href_list["tweak"]) in bo.tweaks + var/decl/backpack_outfit/backpack_option = backpacks_by_name[backpack_name] + var/datum/backpack_tweak/bt = locate(href_list["tweak"]) in backpack_option.tweaks if(!bt) return TOPIC_NOACTION - var/new_metadata = bt.get_metadata(user, get_backpack_metadata(bo, bt)) + var/new_metadata = bt.get_metadata(user, get_backpack_metadata(backpack_option, bt)) if(new_metadata) - set_backpack_metadata(bo, bt, new_metadata) + set_backpack_metadata(backpack_option, bt, new_metadata) return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["change_cash_choice"]) var/list/display_choices = list() diff --git a/code/modules/client/preference_setup/global/02_prefixes.dm b/code/modules/client/preference_setup/global/02_prefixes.dm index 2e249179f8be..974dfbf03650 100644 --- a/code/modules/client/preference_setup/global/02_prefixes.dm +++ b/code/modules/client/preference_setup/global/02_prefixes.dm @@ -100,8 +100,8 @@ continue var/prefix_key = pref.prefix_keys_by_type[prefix_type] if(prefix_key == new_key) - var/decl/prefix/pi = GET_DECL(prefix_type) - pref.prefix_keys_by_type[pi.type] = pi.default_key + var/decl/prefix/prefix = GET_DECL(prefix_type) + pref.prefix_keys_by_type[prefix.type] = prefix.default_key // Then we reset any and all duplicates reset_duplicate_keys() // Then, if the new key was reset it means it matched a default key. diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index d376a8bfc4fe..0e6fe8ed2887 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -38,8 +38,8 @@ /decl/loadout_option/proc/can_afford(var/mob/user, var/datum/preferences/pref) if(cost > 0 && (pref.total_loadout_cost + cost) > get_config_value(/decl/config/num/max_gear_cost)) return FALSE - var/decl/loadout_category/LC = GET_DECL(category) - if(!LC || pref.total_loadout_selections[category] >= LC.max_selections) + var/decl/loadout_category/loadout_cat = GET_DECL(category) + if(!loadout_cat || pref.total_loadout_selections[category] >= loadout_cat.max_selections) return FALSE return TRUE @@ -145,7 +145,7 @@ var/firstcat = 1 current_tab = current_tab || global.using_map.loadout_categories[1].type var/decl/loadout_category/current_category_decl = GET_DECL(current_tab) - for(var/decl/loadout_category/LC as anything in global.using_map.loadout_categories) + for(var/decl/loadout_category/loadout_cat as anything in global.using_map.loadout_categories) if(firstcat) firstcat = FALSE @@ -153,21 +153,21 @@ . += " |" var/category_cost = 0 - for(var/gear_id in LC.gear) + for(var/gear_id in loadout_cat.gear) if(gear_id in pref.gear_list[pref.gear_slot]) - var/decl/loadout_option/gear = LC.gear[gear_id] + var/decl/loadout_option/gear = loadout_cat.gear[gear_id] category_cost += gear.cost if(category == current_category_decl.type) - . += " [LC.name] - [category_cost] " + . += " [loadout_cat.name] - [category_cost] " else var/category_selections - if(LC.max_selections < INFINITY) - category_selections = " - [LC.max_selections - pref.total_loadout_selections[category]] remaining" + if(loadout_cat.max_selections < INFINITY) + category_selections = " - [loadout_cat.max_selections - pref.total_loadout_selections[category]] remaining" if(category_cost) - . += " [LC.name] - [category_cost][category_selections] " + . += " [loadout_cat.name] - [category_cost][category_selections] " else - . += " [LC.name] - 0[category_selections] " + . += " [loadout_cat.name] - 0[category_selections] " . += "
    " . += "
    " @@ -366,9 +366,9 @@ recalculate_loadout_cost() return TOPIC_REFRESH_UPDATE_PREVIEW if(href_list["select_category"]) - var/decl/loadout_category/LC = locate(href_list["select_category"]) - if(istype(LC) && (LC in global.using_map.loadout_categories)) - current_tab = LC.type + var/decl/loadout_category/loadout_cat = locate(href_list["select_category"]) + if(istype(loadout_cat) && (loadout_cat in global.using_map.loadout_categories)) + current_tab = loadout_cat.type else current_tab = global.using_map.loadout_categories[1].type return TOPIC_REFRESH @@ -435,9 +435,9 @@ . = ..() if(!global.using_map.loadout_blacklist || !(type in global.using_map.loadout_blacklist)) - var/decl/loadout_category/LC = GET_DECL(category) - ADD_SORTED(LC.gear, uid, /proc/cmp_text_asc) - LC.gear[uid] = src + var/decl/loadout_category/loadout_cat = GET_DECL(category) + ADD_SORTED(loadout_cat.gear, uid, /proc/cmp_text_asc) + loadout_cat.gear[uid] = src if(FLAGS_EQUALS(loadout_flags, GEAR_HAS_TYPE_SELECTION|GEAR_HAS_SUBTYPE_SELECTION)) CRASH("May not have both type and subtype selection tweaks") diff --git a/code/modules/client/ui_styles/_helpers.dm b/code/modules/client/ui_styles/_helpers.dm index c7c7cc06da71..d0ea5baffa33 100644 --- a/code/modules/client/ui_styles/_helpers.dm +++ b/code/modules/client/ui_styles/_helpers.dm @@ -1,9 +1,9 @@ /proc/get_ui_styles(var/filter_available = TRUE) var/list/all_ui_styles = decls_repository.get_decls_of_subtype(/decl/ui_style) for(var/ui_type in all_ui_styles) - var/decl/ui_style/ui = all_ui_styles[ui_type] - if(!ui.restricted || !filter_available) - LAZYADD(., ui) + var/decl/ui_style/style = all_ui_styles[ui_type] + if(!style.restricted || !filter_available) + LAZYADD(., style) /proc/get_ui_icon(decl/ui_style/ui_style, ui_key) diff --git a/code/modules/economy/_worth.dm b/code/modules/economy/_worth.dm index 9642a67019ef..6e79ca19b6a1 100644 --- a/code/modules/economy/_worth.dm +++ b/code/modules/economy/_worth.dm @@ -10,9 +10,9 @@ /atom/proc/get_single_monetary_worth() . = get_base_value() * get_value_multiplier() if(reagents) - for(var/a in reagents.reagent_volumes) - var/decl/material/reg = GET_DECL(a) - . += reg.get_value() * REAGENT_VOLUME(reagents, a) * REAGENT_WORTH_MULTIPLIER + for(var/reagent_type in reagents.reagent_volumes) + var/decl/material/reagent = GET_DECL(reagent_type) + . += reagent.get_value() * REAGENT_VOLUME(reagents, reagent_type) * REAGENT_WORTH_MULTIPLIER . = max(0, round(.)) /atom/proc/get_contents_monetary_worth() diff --git a/code/modules/events/shipping_error.dm b/code/modules/events/shipping_error.dm index bd2d81fe75b0..772381d7a37d 100644 --- a/code/modules/events/shipping_error.dm +++ b/code/modules/events/shipping_error.dm @@ -1,6 +1,6 @@ /datum/event/shipping_error/start() - var/datum/supply_order/O = new /datum/supply_order() - O.ordernum = SSsupply.ordernum - O.object = pick(SSsupply.master_supply_list) - O.orderedby = random_name(pick(MALE,FEMALE), species = global.using_map.default_species) - SSsupply.shoppinglist += O + var/datum/supply_order/order = new /datum/supply_order() + order.ordernum = SSsupply.ordernum + order.object = pick(SSsupply.master_supply_list) + order.orderedby = random_name(pick(MALE,FEMALE), species = global.using_map.default_species) + SSsupply.shoppinglist += order diff --git a/code/modules/genetics/plants/gene_special.dm b/code/modules/genetics/plants/gene_special.dm index 4d45d5cf599c..2e864d759695 100644 --- a/code/modules/genetics/plants/gene_special.dm +++ b/code/modules/genetics/plants/gene_special.dm @@ -4,6 +4,6 @@ TRAIT_TELEPORTING ) -/decl/plant_gene/special/mutate(datum/seed/seed, turf/location) +/decl/plant_gene/special/mutate(datum/seed/seed, atom/location) if(prob(65)) seed.set_trait(TRAIT_TELEPORTING, !seed.get_trait(TRAIT_TELEPORTING)) diff --git a/code/modules/genetics/plants/gene_vigour.dm b/code/modules/genetics/plants/gene_vigour.dm index 1d98a5480a2c..335556230cd6 100644 --- a/code/modules/genetics/plants/gene_vigour.dm +++ b/code/modules/genetics/plants/gene_vigour.dm @@ -7,7 +7,7 @@ TRAIT_SPREAD ) -/decl/plant_gene/vigour/mutate(datum/seed/seed, turf/location) +/decl/plant_gene/vigour/mutate(datum/seed/seed, atom/location) if(prob(65)) seed.set_trait(TRAIT_PRODUCTION, seed.get_trait(TRAIT_PRODUCTION)+rand(-1,1),10,0) if(prob(65)) diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index d61f42d51ba0..bf56a5e39f18 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -511,11 +511,11 @@ return pick(mutants) //Mutates the plant overall (randomly). -/datum/seed/proc/mutate(var/degree,var/turf/source_turf) +/datum/seed/proc/mutate(var/degree, var/atom/location) if(!degree || get_trait(TRAIT_IMMUTABLE) > 0) return - source_turf.visible_message("\The [display_name] quivers!") + location.visible_message("\The [display_name] quivers!") //This looks like shit, but it's a lot easier to read/change this way. var/total_mutations = rand(1,1+degree) @@ -523,7 +523,7 @@ switch(rand(0,11)) if(0) //Plant cancer! set_trait(TRAIT_ENDURANCE,get_trait(TRAIT_ENDURANCE)-rand(10,20),null,0) - source_turf.visible_message("\The [display_name] withers rapidly!") + location.visible_message("\The [display_name] withers rapidly!") if(1) set_trait(TRAIT_NUTRIENT_CONSUMPTION,get_trait(TRAIT_NUTRIENT_CONSUMPTION)+rand(-(degree*0.1),(degree*0.1)),5,0) set_trait(TRAIT_WATER_CONSUMPTION, get_trait(TRAIT_WATER_CONSUMPTION) +rand(-degree,degree),50,0) @@ -545,7 +545,7 @@ if(prob(degree*5)) set_trait(TRAIT_CARNIVOROUS, get_trait(TRAIT_CARNIVOROUS)+rand(-degree,degree),2, 0) if(get_trait(TRAIT_CARNIVOROUS)) - source_turf.visible_message("\The [display_name] shudders hungrily.") + location.visible_message("\The [display_name] shudders hungrily.") if(6) set_trait(TRAIT_WEED_TOLERANCE, get_trait(TRAIT_WEED_TOLERANCE)+(rand(-2,2)*degree),10, 0) if(prob(degree*5)) @@ -559,7 +559,7 @@ set_trait(TRAIT_POTENCY, get_trait(TRAIT_POTENCY)+(rand(-20,20)*degree),200, 0) if(prob(degree*5)) set_trait(TRAIT_SPREAD, get_trait(TRAIT_SPREAD)+rand(-1,1),2, 0) - source_turf.visible_message("\The [display_name] spasms visibly, shifting in the tray.") + location.visible_message("\The [display_name] spasms visibly, shifting in the tray.") if(9) set_trait(TRAIT_MATURATION, get_trait(TRAIT_MATURATION)+(rand(-1,1)*degree),30, 0) if(prob(degree*5)) @@ -568,12 +568,12 @@ if(prob(degree*2)) set_trait(TRAIT_BIOLUM, !get_trait(TRAIT_BIOLUM)) if(get_trait(TRAIT_BIOLUM)) - source_turf.visible_message("\The [display_name] begins to glow!") + location.visible_message("\The [display_name] begins to glow!") if(prob(degree*2)) set_trait(TRAIT_BIOLUM_COLOUR,get_random_colour(0,75,190)) - source_turf.visible_message("\The [display_name]'s glow changes colour!") + location.visible_message("\The [display_name]'s glow changes colour!") else - source_turf.visible_message("\The [display_name]'s glow dims...") + location.visible_message("\The [display_name]'s glow dims...") if(11) set_trait(TRAIT_TELEPORTING,1) diff --git a/code/modules/hydroponics/seed_gene_mut.dm b/code/modules/hydroponics/seed_gene_mut.dm index a80cf2fd106f..1dbb3b1baf87 100644 --- a/code/modules/hydroponics/seed_gene_mut.dm +++ b/code/modules/hydroponics/seed_gene_mut.dm @@ -1,11 +1,11 @@ -/datum/seed/proc/diverge_mutate_gene(var/decl/plant_gene/G, var/turf/T) - if(!istype(G)) +/datum/seed/proc/diverge_mutate_gene(var/decl/plant_gene/gene, var/atom/location) + if(!istype(gene)) log_debug("Attempted to mutate [src] with a non-plantgene var.") return src - var/datum/seed/S = diverge() //Let's not modify all of the seeds. - T.visible_message("\The [S.display_name] quivers!") //Mimicks the normal mutation. - G.mutate(S, T) + var/datum/seed/seed = diverge() //Let's not modify all of the seeds. + location.visible_message("\The [seed.display_name] quivers!") //Mimicks the normal mutation. + gene.mutate(seed, location) - return S + return seed diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 6745fdaf11c9..965c40430eda 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -194,7 +194,7 @@ if(istype(Proj, /obj/item/projectile/energy/floramut/gene)) var/obj/item/projectile/energy/floramut/gene/G = Proj if(seed) - set_seed(seed.diverge_mutate_gene(G.gene, get_turf(loc)), reset_values = FALSE) //get_turf just in case it's not in a turf. + set_seed(seed.diverge_mutate_gene(G.gene, src), reset_values = FALSE) else mutate(1) return @@ -354,7 +354,7 @@ // harvested yet and it's safe to assume it's restricted to this tray. if(!isnull(SSplants.seeds[seed.name])) set_seed(seed.diverge(), reset_values = FALSE) - seed.mutate(severity,get_turf(src)) + seed.mutate(severity, src) return diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 777bc82a7b46..593941f651df 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -418,8 +418,8 @@ if(1) var/cont[0] for(var/rtype in reagents.reagent_volumes) - var/decl/material/RE = GET_DECL(rtype) - cont += RE.name + var/decl/material/reagent = GET_DECL(rtype) + cont += reagent.name set_pin_data(IC_OUTPUT, 3, cont) push_data() if(2) diff --git a/code/modules/mob/living/human/examine.dm b/code/modules/mob/living/human/examine.dm index 1c3dabe29148..52c619c459cc 100644 --- a/code/modules/mob/living/human/examine.dm +++ b/code/modules/mob/living/human/examine.dm @@ -249,8 +249,8 @@ var/list/human_examines = decls_repository.get_decls_of_subtype(/decl/human_examination) for(var/exam in human_examines) - var/decl/human_examination/HE = human_examines[exam] - var/adding_text = HE.do_examine(user, distance, src) + var/decl/human_examination/examiner = human_examines[exam] + var/adding_text = examiner.do_examine(user, distance, src) if(adding_text) . += adding_text diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm index 2ae451ec6364..86a1eacd47f0 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm @@ -32,12 +32,12 @@ /mob/living/simple_animal/hostile/parrot/space/Initialize() . = ..() - var/decl/parrot_subspecies/ps = get_parrot_species() - if(ps) - icon_set = ps.icon_set - butchery_data = ps.butchery_data + var/decl/parrot_subspecies/parrot_species = get_parrot_species() + if(parrot_species) + icon_set = parrot_species.icon_set + butchery_data = parrot_species.butchery_data if(get_subspecies_name) - SetName(ps.name) + SetName(parrot_species.name) set_scale(2) update_icon() diff --git a/code/modules/mob/new_player/login.dm b/code/modules/mob/new_player/login.dm index 6c3a0d04adaf..57c2e4070177 100644 --- a/code/modules/mob/new_player/login.dm +++ b/code/modules/mob/new_player/login.dm @@ -37,10 +37,10 @@ var/decl/security_state/security_state = GET_DECL(global.using_map.security_state) if(security_state?.show_on_login) - var/decl/security_level/SL = security_state.current_security_level - // todo: allow maps to oevrride this string for things like the fantasy map being on high alert? + var/decl/security_level/sec_level = security_state.current_security_level + // todo: allow maps to override this string for things like the fantasy map being on high alert? // eg "The alert level *in* Karzerfeste Keep is currently high alert." or "Karzerfeste Keep is currently on high alert." - to_chat(src, SPAN_NOTICE("The alert level on the [station_name()] is currently: [SL.name]. [SL?.up_description]")) + to_chat(src, SPAN_NOTICE("The alert level on the [station_name()] is currently: [sec_level.name]. [sec_level?.up_description]")) // bolds the changelog button on the interface so we know there are updates. if(client.prefs?.lastchangelog != global.changelog_hash) diff --git a/code/modules/modular_computers/file_system/programs/generic/supply.dm b/code/modules/modular_computers/file_system/programs/generic/supply.dm index b0f425734159..bae0aa67c9dd 100644 --- a/code/modules/modular_computers/file_system/programs/generic/supply.dm +++ b/code/modules/modular_computers/file_system/programs/generic/supply.dm @@ -166,11 +166,11 @@ if(href_list["order"]) clear_order_contents() - var/decl/hierarchy/supply_pack/P = locate(href_list["order"]) in SSsupply.master_supply_list - if(!istype(P)) + var/decl/hierarchy/supply_pack/pack = locate(href_list["order"]) in SSsupply.master_supply_list + if(!istype(pack)) return 1 - if(P.hidden && !emagged) + if(pack.hidden && !emagged) return 1 var/reason = sanitize(input(user,"Reason:","Why do you require this item?","") as null|text,,0) @@ -190,7 +190,7 @@ var/datum/supply_order/O = new /datum/supply_order() O.ordernum = SSsupply.ordernum - O.object = P + O.object = pack O.orderedby = idname O.reason = reason O.orderedrank = idrank @@ -315,31 +315,32 @@ category_contents.Cut() var/decl/hierarchy/supply_pack/root = GET_DECL(/decl/hierarchy/supply_pack) var/decl/currency/cur = GET_DECL(global.using_map.default_currency) - for(var/decl/hierarchy/supply_pack/sp in root.children) - if(!sp.is_category()) + // FIXME: This probably doesn't even work properly? It assumes there aren't any nested categories... + for(var/decl/hierarchy/supply_pack/pack in root.children) + if(!pack.is_category()) continue // No children - category_names.Add(sp.name) + category_names.Add(pack.name) var/list/category[0] - for(var/decl/hierarchy/supply_pack/spc in sp.get_descendants()) - if((spc.hidden || spc.contraband || !spc.sec_available()) && !emagged) + for(var/decl/hierarchy/supply_pack/child_pack in pack.get_descendants()) + if((child_pack.hidden || child_pack.contraband || !child_pack.sec_available()) && !emagged) continue category.Add(list(list( - "name" = spc.name, - "cost" = cur.format_value(spc.cost), - "ref" = "\ref[spc]" + "name" = child_pack.name, + "cost" = cur.format_value(child_pack.cost), + "ref" = "\ref[child_pack]" ))) - category_contents[sp.name] = category + category_contents[pack.name] = category /datum/nano_module/supply/proc/generate_order_contents(var/order_ref) - var/decl/hierarchy/supply_pack/sp = locate(order_ref) in SSsupply.master_supply_list - if(!istype(sp)) + var/decl/hierarchy/supply_pack/pack = locate(order_ref) in SSsupply.master_supply_list + if(!istype(pack)) return FALSE contents_of_order.Cut() showing_contents_of_ref = order_ref - for(var/item_path in sp.contains) // Thanks to Lohikar for helping me with type paths - CarlenWhite + for(var/item_path in pack.contains) // Thanks to Lohikar for helping me with type paths - CarlenWhite var/obj/item/stack/OB = item_path // Not always a stack, but will always have a name we can fetch. var/name = initial(OB.name) - var/amount = sp.contains[item_path] || 1 // If it's just one item (has no number associated), fallback to 1. + var/amount = pack.contains[item_path] || 1 // If it's just one item (has no number associated), fallback to 1. if(ispath(item_path, /obj/item/stack)) // And if it is a stack, consider the amount amount *= initial(OB.amount) @@ -349,9 +350,9 @@ "amount" = amount ))) - if(sp.contains.len == 0) // Handles the case where sp.contains is empty, e.g. for livecargo + if(!length(pack.contains)) // Handles the case where pack.contains is empty, e.g. for livecargo contents_of_order.Add(list(list( - "name" = sp.containername, + "name" = pack.containername, "amount" = 1 ))) diff --git a/code/modules/modular_computers/networking/device_types/_network_device.dm b/code/modules/modular_computers/networking/device_types/_network_device.dm index 7401c1ac7669..71a3eb7c1e78 100644 --- a/code/modules/modular_computers/networking/device_types/_network_device.dm +++ b/code/modules/modular_computers/networking/device_types/_network_device.dm @@ -447,16 +447,16 @@ var/list/pub_vars = get_public_variables() for(var/path in pub_methods) - var/decl/public_access/pub = pub_methods[path] - var/alias = pub.name + var/decl/public_access/pub_method = pub_methods[path] + var/alias = pub_method.name alias = replacetext(alias, " ", "_") - LAZYSET(command_and_call, alias, pub) + LAZYSET(command_and_call, alias, pub_method) for(var/path in pub_vars) - var/decl/public_access/pub = pub_vars[path] - var/alias = pub.name + var/decl/public_access/pub_var = pub_vars[path] + var/alias = pub_var.name alias = replacetext(alias, " ", "_") - LAZYSET(command_and_write, alias, pub) + LAZYSET(command_and_write, alias, pub_var) /**Returns the outward facing URI for this network device.*/ /datum/extension/network_device/proc/get_network_URI() diff --git a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm index e4fc8df99e23..8eb7a37a87ad 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm @@ -56,13 +56,13 @@ var/global/const/DRINK_ICON_NOISY = "noise" /obj/item/chems/drinks/glass2/proc/has_fizz() if(LAZYLEN(reagents.reagent_volumes)) - var/decl/material/R = reagents.get_primary_reagent_decl() - if(("fizz" in R.glass_special)) + var/decl/material/primary = reagents.get_primary_reagent_decl() + if(("fizz" in primary.glass_special)) return 1 var/totalfizzy = 0 for(var/rtype in reagents.reagent_volumes) - var/decl/material/re = GET_DECL(rtype) - if("fizz" in re.glass_special) + var/decl/material/reagent = GET_DECL(rtype) + if("fizz" in reagent.glass_special) totalfizzy += REAGENT_VOLUME(reagents, rtype) if(totalfizzy >= reagents.total_volume / 5) // 20% fizzy by volume return 1 @@ -72,12 +72,12 @@ var/global/const/DRINK_ICON_NOISY = "noise" if(LAZYLEN(reagents.reagent_volumes) > 0) if(temperature > T0C + 40) return 1 - var/decl/material/R = reagents.get_primary_reagent_decl() - if(!("vapor" in R.glass_special)) + var/decl/material/primary = reagents.get_primary_reagent_decl() + if(!("vapor" in primary.glass_special)) var/totalvape = 0 for(var/rtype in reagents.reagent_volumes) - var/decl/material/re = GET_DECL(rtype) - if("vapor" in re.glass_special) + var/decl/material/reagent = GET_DECL(rtype) + if("vapor" in reagent.glass_special) totalvape += REAGENT_VOLUME(reagents, type) if(totalvape >= volume * 0.6) // 60% vapor by container volume return 1 diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 400f96445fd3..ce3b69427c96 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -86,9 +86,9 @@ return TRUE else //If no safety, we just toggle the nozzle - var/decl/interaction_handler/IH = GET_DECL(/decl/interaction_handler/next_spray_amount) - if(IH.is_possible(src, user)) - IH.invoked(src, user, user.get_active_held_item()) + var/decl/interaction_handler/handler = GET_DECL(/decl/interaction_handler/next_spray_amount) + if(handler.is_possible(src, user)) + handler.invoked(src, user, user.get_active_held_item()) return TRUE ///Whether the spray has a safety toggle diff --git a/code/modules/scent/_scent.dm b/code/modules/scent/_scent.dm index 2298b57494d2..dac52b069a8e 100644 --- a/code/modules/scent/_scent.dm +++ b/code/modules/scent/_scent.dm @@ -132,13 +132,13 @@ To add a scent extension to an atom using a reagent's info, where R. is the reag if(!holder || !holder.total_volume) return for(var/reagent_type in holder.reagent_volumes) - var/decl/material/R = GET_DECL(reagent_type) - if(!R.scent) + var/decl/material/scented_reagent = GET_DECL(reagent_type) + if(!scented_reagent.scent) continue - var/decl/scent_intensity/SI = GET_DECL(R.scent_intensity) - var/r_scent_intensity = REAGENT_VOLUME(holder, reagent_type) * SI.intensity + var/decl/scent_intensity/scent = GET_DECL(scented_reagent.scent_intensity) + var/r_scent_intensity = REAGENT_VOLUME(holder, reagent_type) * scent.intensity if(r_scent_intensity > scent_intensity) - smelliest = R + smelliest = scented_reagent scent_intensity = r_scent_intensity return smelliest \ No newline at end of file diff --git a/code/unit_tests/alt_appearances_test.dm b/code/unit_tests/alt_appearances_test.dm index d1c4b22a8e80..afb67f655d49 100644 --- a/code/unit_tests/alt_appearances_test.dm +++ b/code/unit_tests/alt_appearances_test.dm @@ -2,9 +2,8 @@ name = "ALT APPEARANCE: Cardborg shall have base backpack variant" /datum/unit_test/alt_appearance_cardborg_shall_have_base_backpack_variant/start_test() - for(var/ca_type in decls_repository.get_decl_paths_of_subtype(/decl/cardborg_appearance)) - var/decl/cardborg_appearance/ca = ca_type - var/obj/item/backpack/backpack_type = initial(ca.backpack_type) + for(var/decl/cardborg_appearance/disguise in decls_repository.get_decls_of_subtype_unassociated(/decl/cardborg_appearance)) + var/obj/item/backpack/backpack_type = disguise.backpack_type if(backpack_type == /obj/item/backpack) pass("Found a cardborg appearance using the base /obj/item/backpack backpack.") return 1 @@ -18,10 +17,9 @@ /datum/unit_test/alt_appearance_cardborg_all_icon_states_shall_exist/start_test() var/failed = FALSE - for(var/ca_type in decls_repository.get_decl_paths_of_subtype(/decl/cardborg_appearance)) - var/decl/cardborg_appearance/ca = ca_type - var/icon_state = initial(ca.icon_state) - if(!check_state_in_icon(icon_state, initial(ca.icon))) + for(var/decl/cardborg_appearance/disguise in decls_repository.get_decls_of_subtype_unassociated(/decl/cardborg_appearance)) + var/icon_state = disguise.icon_state + if(!check_state_in_icon(icon_state, disguise.icon)) log_unit_test("Icon state [icon_state] is missing.") failed = TRUE if(failed) @@ -36,8 +34,8 @@ /datum/unit_test/alt_appearance_cardborg_shall_have_unique_backpack_types/start_test() var/list/backpack_types = list() for(var/ca_type in decls_repository.get_decl_paths_of_subtype(/decl/cardborg_appearance)) - var/decl/cardborg_appearance/ca = ca_type - group_by(backpack_types, initial(ca.backpack_type), ca) + var/decl/cardborg_appearance/disguise = ca_type + group_by(backpack_types, initial(disguise.backpack_type), disguise) var/number_of_issues = number_of_issues(backpack_types, "Backpack Types") if(number_of_issues) diff --git a/code/unit_tests/view_variables_test.dm b/code/unit_tests/view_variables_test.dm index 8bd641566b9d..ed92a6cceb63 100644 --- a/code/unit_tests/view_variables_test.dm +++ b/code/unit_tests/view_variables_test.dm @@ -5,20 +5,20 @@ var/list/faulty_handlers = list() var/list/vv_set_handlers = decls_repository.get_decls_of_subtype(/decl/vv_set_handler) for(var/vv_handler in vv_set_handlers) - var/decl/vv_set_handler/sh = vv_set_handlers[vv_handler] - if(!ispath(sh.handled_type)) - log_bad("[sh] does not have a valid handled type. Expected a path, was [log_info_line(sh.handled_type)]") - faulty_handlers |= sh - if(!islist(sh.handled_vars)) - log_bad("[sh] does not have a handled variables list. Expected a list, was [log_info_line(sh.handled_vars)]") - faulty_handlers |= sh - else if(!sh.handled_vars.len) - log_bad("[sh] as an empty handled variables list.") - faulty_handlers |= sh + var/decl/vv_set_handler/set_handler = vv_set_handlers[vv_handler] + if(!ispath(set_handler.handled_type)) + log_bad("[set_handler] does not have a valid handled type. Expected a path, was [log_info_line(set_handler.handled_type)]") + faulty_handlers |= set_handler + if(!islist(set_handler.handled_vars)) + log_bad("[set_handler] does not have a handled variables list. Expected a list, was [log_info_line(set_handler.handled_vars)]") + faulty_handlers |= set_handler + else if(!set_handler.handled_vars.len) + log_bad("[set_handler] as an empty handled variables list.") + faulty_handlers |= set_handler else continue // Somehow check for missing vars here without creating instances. - // I.e.: for(var/handled_var in sh.handled_vars) check handled_var in handled_type.vars + // I.e.: for(var/handled_var in set_handler.handled_vars) check handled_var in handled_type.vars if(faulty_handlers.len) fail("The following special VV handlers are invalid: [english_list(faulty_handlers)]") diff --git a/mods/content/byond_membership/_byond_membership.dm b/mods/content/byond_membership/_byond_membership.dm index c1944de09b37..5dbc59c09d02 100644 --- a/mods/content/byond_membership/_byond_membership.dm +++ b/mods/content/byond_membership/_byond_membership.dm @@ -7,8 +7,8 @@ /decl/communication_channel/ooc/get_emblem(client/C) if(C && C.get_byond_membership() && C.get_preference_value(/datum/client_preference/byond_membership/emblem) == PREF_SHOW) - var/decl/modpack/byond_membership/bm = GET_DECL(/decl/modpack/byond_membership) - return "[html_icon(bm.emblem)] " + var/decl/modpack/byond_membership/membership = GET_DECL(/decl/modpack/byond_membership) + return "[html_icon(membership.emblem)] " /datum/client_preference/byond_membership/emblem description = "BYOND Membership Emblem" From 3974d5fefb22ec0fb1eded7c6ee9581927657b5b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 05:15:18 -0500 Subject: [PATCH 057/512] Optimize global event cleanup --- code/datums/observation/~cleanup.dm | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm index 9685f39741a3..301d146a129b 100644 --- a/code/datums/observation/~cleanup.dm +++ b/code/datums/observation/~cleanup.dm @@ -1,18 +1,18 @@ -var/global/list/global_listen_count = list() - /datum /// Tracks how many event registrations are listening to us. Used in cleanup to prevent dangling references. var/event_source_count = 0 /// Tracks how many event registrations we are listening to. Used in cleanup to prevent dangling references. var/event_listen_count = 0 + /// Tracks how many global event registrations we are listening to. Used in cleanup to prevent dangling references. + var/global_listen_count = 0 /proc/cleanup_events(var/datum/source) - if(global.global_listen_count && global.global_listen_count[source]) - cleanup_global_listener(source, global.global_listen_count[source]) + if(source?.global_listen_count > 0) + cleanup_global_listener(source, source.global_listen_count) if(source?.event_source_count > 0) - cleanup_source_listeners(source, source?.event_source_count) + cleanup_source_listeners(source, source.event_source_count) if(source?.event_listen_count > 0) - cleanup_event_listener(source, source?.event_listen_count) + cleanup_event_listener(source, source.event_listen_count) /decl/observ/register(var/datum/event_source, var/datum/listener, var/proc_call) . = ..() @@ -29,22 +29,19 @@ var/global/list/global_listen_count = list() /decl/observ/register_global(var/datum/listener, var/proc_call) . = ..() if(.) - global.global_listen_count[listener] += 1 + listener.global_listen_count += 1 /decl/observ/unregister_global(var/datum/listener, var/proc_call) . = ..() if(.) - global.global_listen_count[listener] -= . - if(global.global_listen_count[listener] <= 0) - global.global_listen_count -= listener + listener.global_listen_count -= . /proc/cleanup_global_listener(listener, listen_count) - global.global_listen_count -= listener var/events_removed for(var/entry in global.all_observable_events) var/decl/observ/event = entry if((events_removed = event.unregister_global(listener))) - log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still registered to global events.") + log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still globally registered to an event.") listen_count -= events_removed if(!listen_count) return From 2f438f9f07438189559a072ff34695723b6c3bea Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 05:41:16 -0500 Subject: [PATCH 058/512] Remove RAISE_EVENT_REPEAT macro --- code/__defines/observ.dm | 5 +---- code/game/objects/items/__item.dm | 4 ++-- code/modules/shuttles/shuttle.dm | 4 ++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/code/__defines/observ.dm b/code/__defines/observ.dm index cada27347b25..1eeb9bf65d31 100644 --- a/code/__defines/observ.dm +++ b/code/__defines/observ.dm @@ -1,4 +1 @@ -// This also works, and removes the need for the _REPEAT variant, but the linter hates it: -// #define RAISE_EVENT(OBS, args...) (GET_DECL(OBS))?.raise_event(args); -#define RAISE_EVENT(OBS, args...) var/decl/observ/__event = GET_DECL(OBS); __event?.raise_event(args); -#define RAISE_EVENT_REPEAT(OBS, args...) __event = GET_DECL(OBS); __event?.raise_event(args); +#define RAISE_EVENT(OBS, args...) UNLINT((GET_DECL(OBS))?.raise_event(args)); diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 539765bd32ec..818bacab2a3c 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -649,7 +649,7 @@ addtimer(CALLBACK(user, TYPE_PROC_REF(/mob, check_emissive_equipment)), 0, TIMER_UNIQUE) RAISE_EVENT(/decl/observ/mob_unequipped, user, src) - RAISE_EVENT_REPEAT(/decl/observ/item_unequipped, src, user) + RAISE_EVENT(/decl/observ/item_unequipped, src, user) // called just after an item is picked up, after it has been equipped to the mob. /obj/item/proc/on_picked_up(mob/user) @@ -709,7 +709,7 @@ addtimer(CALLBACK(user, TYPE_PROC_REF(/mob, check_emissive_equipment)), 0, TIMER_UNIQUE) RAISE_EVENT(/decl/observ/mob_equipped, user, src, slot) - RAISE_EVENT_REPEAT(/decl/observ/item_equipped, src, user, slot) + RAISE_EVENT(/decl/observ/item_equipped, src, user, slot) // As above but for items being equipped to an active module on a robot. /obj/item/proc/equipped_robot(var/mob/user) diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index d11e0cb97a83..bd5e77eba2cd 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -184,7 +184,7 @@ var/obj/effect/shuttle_landmark/old_location = current_location RAISE_EVENT(/decl/observ/shuttle_pre_move, src, old_location, destination) shuttle_moved(destination, translation, angle_offset) - RAISE_EVENT_REPEAT(/decl/observ/shuttle_moved, src, old_location, destination) + RAISE_EVENT(/decl/observ/shuttle_moved, src, old_location, destination) if(istype(old_location)) old_location.shuttle_departed(src) destination.shuttle_arrived(src) @@ -208,7 +208,7 @@ var/obj/effect/shuttle_landmark/old_location = current_location RAISE_EVENT(/decl/observ/shuttle_pre_move, src, old_location, destination) shuttle_moved(destination, translation, angle_offset) - RAISE_EVENT_REPEAT(/decl/observ/shuttle_moved, src, old_location, destination) + RAISE_EVENT(/decl/observ/shuttle_moved, src, old_location, destination) if(istype(old_location)) old_location.shuttle_departed(src) destination.shuttle_arrived(src) From 993f76639e84a9832d6b2a8243e6e6ca638cdadf Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 13:42:58 -0500 Subject: [PATCH 059/512] Fix manuals not initializing properly --- code/game/objects/items/books/_book.dm | 23 ++++++++++----- .../objects/items/books/manuals/_manual.dm | 28 ++++++++++++++++++- code/modules/materials/_materials.dm | 3 +- code/modules/mob/living/living.dm | 4 +-- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/code/game/objects/items/books/_book.dm b/code/game/objects/items/books/_book.dm index 437c18ebf6be..f9db9deefc36 100644 --- a/code/game/objects/items/books/_book.dm +++ b/code/game/objects/items/books/_book.dm @@ -41,6 +41,13 @@ if(SSpersistence.is_tracking(src, /decl/persistence_handler/book)) . = QDEL_HINT_LETMELIVE +/// Clears the text written in the book. Used for acetone removing ink. Returns TRUE if successful, FALSE if it can't be dissolved. +/obj/item/book/proc/clear_text() + if(can_dissolve_text) + dat = null + return TRUE + return FALSE + /obj/item/book/on_update_icon() . = ..() icon_state = get_world_inventory_state() @@ -77,13 +84,17 @@ if(dat) user.visible_message("\The [user] opens a book titled \"[title]\" and begins reading intently.") - var/processed_dat = user.handle_reading_literacy(user, dat) - if(processed_dat) - show_browser(user, processed_dat, "window=book;size=1000x550") - onclose(user, "book") + show_text_to(user) else to_chat(user, SPAN_WARNING("This book is completely blank!")) +/// Reader is the mob doing the reading, whose skill will be used for skillchecks. User is the mob who is holding the book, and do_afters will use them. +/obj/item/book/proc/show_text_to(mob/reader, mob/user) + var/processed_dat = reader.handle_reading_literacy(reader, dat) + if(processed_dat) + show_browser(reader, processed_dat, "window=book;size=1000x550") + onclose(reader, "book") + /obj/item/book/attackby(obj/item/used_item, mob/user) if(IS_PEN(used_item)) @@ -148,9 +159,7 @@ SPAN_NOTICE("\The [user] opens up a book and shows it to \the [target].") ) user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //to prevent spam - var/processed_dat = target.handle_reading_literacy(user, "Author: [author].

    " + "[dat]") - if(processed_dat) - show_browser(target, processed_dat, "window=book;size=1000x550") + show_text_to(target) return TRUE return ..() diff --git a/code/game/objects/items/books/manuals/_manual.dm b/code/game/objects/items/books/manuals/_manual.dm index 7cee55d5709e..8d09360270e9 100644 --- a/code/game/objects/items/books/manuals/_manual.dm +++ b/code/game/objects/items/books/manuals/_manual.dm @@ -2,13 +2,38 @@ unique = TRUE // Unable to be copied, unable to be modified abstract_type = /obj/item/book/manual var/guide_decl + var/tmp/has_initialized = FALSE /obj/item/book/manual/Initialize() . = ..() + // try to initialize the text! if it's prior to sscodex init it'll initialize on being read + // if the guide is invalid the manual will need to be deleted + if(initialize_data(in_init = TRUE) == INITIALIZE_HINT_QDEL) + return INITIALIZE_HINT_QDEL + +/obj/item/book/manual/try_to_read() + initialize_data() + . = ..() + +/obj/item/book/manual/show_text_to() + initialize_data() + . = ..() + +/obj/item/book/manual/clear_text() + if((. = ..())) + has_initialized = TRUE // prevent data from being added later if it hasn't already been + +/obj/item/book/manual/proc/initialize_data(in_init = FALSE) + if(has_initialized || !SScodex.initialized) + return + // Has yet to initialize. var/guide_text = guide_decl && SScodex.get_manual_text(guide_decl) if(!guide_text) log_debug("Manual [type] spawned with invalid guide decl type ([guide_decl || null]).") - return INITIALIZE_HINT_QDEL + if(in_init) + return INITIALIZE_HINT_QDEL + qdel(src) + return dat = {" @@ -19,3 +44,4 @@ "} + has_initialized = TRUE diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index 8a54511cbb3f..1b8c388205a9 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -743,8 +743,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) O.visible_message(SPAN_NOTICE("The solution dissolves the ink on the paper."), range = 1) else if(istype(O, /obj/item/book) && amount >= FLUID_PUDDLE) var/obj/item/book/affectedbook = O - if(affectedbook.can_dissolve_text) - affectedbook.dat = null + if(affectedbook.clear_text()) O.visible_message(SPAN_NOTICE("The solution dissolves the ink on the book."), range = 1) else O.visible_message(SPAN_WARNING("The solution does nothing. Whatever this is, it isn't normal ink."), range = 1) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 03966f65b00d..dfa536ca3859 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -947,9 +947,9 @@ default behaviour is: if(user != src) to_chat(user, SPAN_NOTICE("\The [src] scans the writing...")) if(skill_check(SKILL_LITERACY, SKILL_BASIC)) - if(skip_delays || do_after(src, 1 SECOND, user)) + if(skip_delays || do_mob(user, src, 1 SECOND)) . = stars(text_content, 85) - else if(skip_delays || do_after(src, 3 SECONDS, user)) + else if(skip_delays || do_mob(user, src, 3 SECONDS)) . = ..() /mob/living/handle_writing_literacy(var/mob/user, var/text_content, var/skip_delays) From c6d2d192d897a8aae6237981a1bc7fb9b156cbf6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 13:40:19 -0500 Subject: [PATCH 060/512] Add CHECK_TICK to various procs that can block init --- code/controllers/subsystems/holomap.dm | 1 + code/game/machinery/cryopod.dm | 2 +- code/modules/random_map/noise/noise.dm | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/controllers/subsystems/holomap.dm b/code/controllers/subsystems/holomap.dm index ac6662184f62..0d2cc7371e49 100644 --- a/code/controllers/subsystems/holomap.dm +++ b/code/controllers/subsystems/holomap.dm @@ -104,4 +104,5 @@ SUBSYSTEM_DEF(minimap) if(!areas[areaToPaint]) areas[areaToPaint] = icon(HOLOMAP_ICON, "blank") areas[areaToPaint].DrawBox(HOLOMAP_AREACOLOR_BASE, x + offset_x, y + offset_y) //We draw white because we want a generic version to use later. However if there is no colour we ignore it + CHECK_TICK return areas \ No newline at end of file diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 2557a9767f3c..438184b0cd55 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -248,7 +248,7 @@ /obj/machinery/cryopod/lifepod/Process() if(SSevac.evacuation_controller && SSevac.evacuation_controller.state >= EVAC_LAUNCHING) if(occupant && !launched) - launch() + INVOKE_ASYNC(src, PROC_REF(launch)) ..() /obj/machinery/cryopod/Destroy() diff --git a/code/modules/random_map/noise/noise.dm b/code/modules/random_map/noise/noise.dm index 4cb74b70fe55..9abb4a1177ff 100644 --- a/code/modules/random_map/noise/noise.dm +++ b/code/modules/random_map/noise/noise.dm @@ -152,6 +152,7 @@ total += map[TRANSLATE_COORD(x, y+1)] next_map[TRANSLATE_COORD(x, y)] = round(total / 3) map = next_map + CHECK_TICK if(smooth_single_tiles) for(var/x in 1 to limit_x - 1) From c6deefa8f183cc2765fe1fd10e3f535c8ef8ebbd Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 13:40:59 -0500 Subject: [PATCH 061/512] Reduce unnecessary turf initialization on new levels --- code/modules/multiz/level_data.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/multiz/level_data.dm b/code/modules/multiz/level_data.dm index 00b82e3b5ac3..4c99de420b47 100644 --- a/code/modules/multiz/level_data.dm +++ b/code/modules/multiz/level_data.dm @@ -223,7 +223,8 @@ if(!change_turf && !change_area) return var/area/A = change_area ? get_base_area_instance() : null - for(var/turf/T as anything in Z_ALL_TURFS(level_z)) + // We don't have to worry about the edge turfs because those are handled in build_border(). + for(var/turf/T as anything in block(level_inner_min_x, level_inner_min_y, level_z, level_inner_max_x, level_inner_max_y, level_z)) if(change_turf) T = T.ChangeTurf(picked_turf) if(change_area) From b04cefdfbc166bf8b8b9bb2b379f45e08ffa8199 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 13:42:20 -0500 Subject: [PATCH 062/512] Improve profiling --- code/_helpers/cmp.dm | 2 ++ code/_helpers/logging.dm | 2 +- code/_helpers/mobs.dm | 2 +- code/_helpers/profiling.dm | 5 +++-- code/controllers/master.dm | 1 - code/modules/admin/verbs/debug.dm | 2 ++ 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/code/_helpers/cmp.dm b/code/_helpers/cmp.dm index 3a04928449ee..902bc95518be 100644 --- a/code/_helpers/cmp.dm +++ b/code/_helpers/cmp.dm @@ -57,6 +57,8 @@ /proc/cmp_qdel_item_time(datum/qdel_item/A, datum/qdel_item/B) . = B.hard_delete_time - A.hard_delete_time + if (!. && B.qdels && A.qdels) // sort by time per call + . = (B.destroy_time / B.qdels) - (A.destroy_time / A.qdels) if (!.) . = B.destroy_time - A.destroy_time if (!.) diff --git a/code/_helpers/logging.dm b/code/_helpers/logging.dm index 5c1744b0178f..7e476912b248 100644 --- a/code/_helpers/logging.dm +++ b/code/_helpers/logging.dm @@ -214,4 +214,4 @@ var/global/log_end= world.system_type == UNIX ? ascii2text(13) : "" /proc/report_progress(var/progress_message) admin_notice("[progress_message]", R_DEBUG) - to_world_log(progress_message) + log_world(progress_message) diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 5684048f9301..33b16c3b788e 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -34,7 +34,7 @@ /proc/get_exposed_defense_zone(var/atom/movable/target) return pick(BP_HEAD, BP_L_HAND, BP_R_HAND, BP_L_FOOT, BP_R_FOOT, BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG, BP_CHEST, BP_GROIN) -/proc/do_mob(mob/user , mob/target, time = 30, target_zone = 0, uninterruptible = 0, progress = 1, incapacitation_flags = INCAPACITATION_DEFAULT, check_holding = TRUE) +/proc/do_mob(mob/user, mob/target, time = 30, target_zone = 0, uninterruptible = 0, progress = 1, incapacitation_flags = INCAPACITATION_DEFAULT, check_holding = TRUE) if(!user || !target) return 0 var/user_loc = user.loc diff --git a/code/_helpers/profiling.dm b/code/_helpers/profiling.dm index 0c4785568368..f02138db049f 100644 --- a/code/_helpers/profiling.dm +++ b/code/_helpers/profiling.dm @@ -110,7 +110,8 @@ var/init = call_ext(lib, "init")() if("0" != init) CRASH("[lib] init error: [init]") -/world/New() +var/global/datum/profiler/_profiler = new +/datum/profiler/New() prof_init() - . = ..() + ..() #endif diff --git a/code/controllers/master.dm b/code/controllers/master.dm index f5f59fe940ca..7c24faa29d7e 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -187,7 +187,6 @@ var/global/datum/controller/master/Master = new var/msg = "Initializations complete within [time] second\s!" report_progress(msg) - log_world(msg) initializing = FALSE diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 96c051a8b9a4..e43cf8d96caa 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -511,6 +511,8 @@ . += "
  • qdel() Count: [I.qdels]
  • " if(I.early_destroy) . += "
  • Early destroy count: [I.early_destroy]
  • " + if(I.qdels) + . += "
  • Average Destroy() Cost: [I.destroy_time / I.qdels]ms/call
  • " . += "
  • Destroy() Cost: [I.destroy_time]ms
  • " if(I.hard_deletes) . += "
  • Total Hard Deletes [I.hard_deletes]
  • " From 66b27b3bcb45ce11a8bcb237bbd84e3072b18eb6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 13:42:42 -0500 Subject: [PATCH 063/512] Move event bookkeeping onto datums --- code/_global_vars/misc.dm | 1 - code/datums/datum.dm | 6 +- code/datums/observation/density_set.dm | 1 + code/datums/observation/entered.dm | 4 +- code/datums/observation/exited.dm | 4 +- code/datums/observation/helpers.dm | 3 +- code/datums/observation/moved.dm | 7 ++- code/datums/observation/name_set.dm | 4 +- code/datums/observation/observation.dm | 84 ++++++++++++++++--------- code/datums/observation/updated_icon.dm | 1 + code/datums/observation/~cleanup.dm | 32 +++++----- code/game/atoms.dm | 9 ++- code/game/atoms_movable.dm | 8 +-- code/game/turfs/turf_changing.dm | 4 +- nebula.dme | 1 - 15 files changed, 101 insertions(+), 68 deletions(-) delete mode 100644 code/_global_vars/misc.dm diff --git a/code/_global_vars/misc.dm b/code/_global_vars/misc.dm deleted file mode 100644 index 2ade2236e1a0..000000000000 --- a/code/_global_vars/misc.dm +++ /dev/null @@ -1 +0,0 @@ -var/global/list/all_observable_events = list() \ No newline at end of file diff --git a/code/datums/datum.dm b/code/datums/datum.dm index d4d9d3f5a1b5..881b69bb4e36 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -50,10 +50,8 @@ qdel(extension) extensions = null - var/decl/observ/destroyed/destroyed_event = GET_DECL(/decl/observ/destroyed) - // Typecheck is needed (rather than nullchecking) due to oddness with new() ordering during world creation. - if(istype(events_repository) && destroyed_event.event_sources[src]) - RAISE_EVENT(/decl/observ/destroyed, src) + if(event_listeners?[/decl/observ/destroyed]) + raise_event_non_global(/decl/observ/destroyed) if (!isturf(src)) // Not great, but the 'correct' way to do it would add overhead for little benefit. cleanup_events(src) diff --git a/code/datums/observation/density_set.dm b/code/datums/observation/density_set.dm index 9a022b893257..0eaeb65e56e3 100644 --- a/code/datums/observation/density_set.dm +++ b/code/datums/observation/density_set.dm @@ -11,3 +11,4 @@ /decl/observ/density_set name = "Density Set" expected_type = /atom + flags = OBSERVATION_NO_GLOBAL_REGISTRATIONS diff --git a/code/datums/observation/entered.dm b/code/datums/observation/entered.dm index d52829d6c7df..3512ed616173 100644 --- a/code/datums/observation/entered.dm +++ b/code/datums/observation/entered.dm @@ -12,6 +12,7 @@ /decl/observ/entered name = "Entered" expected_type = /atom + flags = OBSERVATION_NO_GLOBAL_REGISTRATIONS /******************* * Entered Handling * @@ -19,4 +20,5 @@ /atom/Entered(atom/movable/enterer, atom/old_loc) ..() - RAISE_EVENT(/decl/observ/entered, src, enterer, old_loc) + if(event_listeners?[/decl/observ/entered]) + raise_event_non_global(/decl/observ/entered, enterer, old_loc) diff --git a/code/datums/observation/exited.dm b/code/datums/observation/exited.dm index b00e30c79f68..6e8bc2ac80fc 100644 --- a/code/datums/observation/exited.dm +++ b/code/datums/observation/exited.dm @@ -12,6 +12,7 @@ /decl/observ/exited name = "Exited" expected_type = /atom + flags = OBSERVATION_NO_GLOBAL_REGISTRATIONS /****************** * Exited Handling * @@ -19,4 +20,5 @@ /atom/Exited(atom/movable/exitee, atom/new_loc) . = ..() - RAISE_EVENT(/decl/observ/exited, src, exitee, new_loc) + if(event_listeners?[/decl/observ/exited]) + raise_event_non_global(/decl/observ/exited, exitee, new_loc) diff --git a/code/datums/observation/helpers.dm b/code/datums/observation/helpers.dm index 89330ecc50b0..b404f2372635 100644 --- a/code/datums/observation/helpers.dm +++ b/code/datums/observation/helpers.dm @@ -1,5 +1,6 @@ /atom/movable/proc/recursive_move(var/atom/movable/am, var/old_loc, var/new_loc) - RAISE_EVENT(/decl/observ/moved, src, old_loc, new_loc) + if(event_listeners?[/decl/observ/moved]) + raise_event_non_global(/decl/observ/moved, old_loc, new_loc) /atom/movable/proc/move_to_turf(var/atom/movable/am, var/old_loc, var/new_loc) var/turf/T = get_turf(new_loc) diff --git a/code/datums/observation/moved.dm b/code/datums/observation/moved.dm index 101dd5b756fa..340779227b99 100644 --- a/code/datums/observation/moved.dm +++ b/code/datums/observation/moved.dm @@ -33,12 +33,13 @@ /atom/Entered(var/atom/movable/am, var/atom/old_loc) . = ..() - RAISE_EVENT(/decl/observ/moved, am, old_loc, am.loc) + if(am.event_listeners?[/decl/observ/moved]) + am.raise_event_non_global(/decl/observ/moved, old_loc, am.loc) /atom/movable/Entered(var/atom/movable/am, atom/old_loc) . = ..() - var/decl/observ/moved/moved_event = GET_DECL(/decl/observ/moved) - if(moved_event.has_listeners(am)) + // We inline and simplify has_listeners here since we know this event can never have global registrations. + if(am.event_listeners?[/decl/observ/moved]) events_repository.register(/decl/observ/moved, src, am, TYPE_PROC_REF(/atom/movable, recursive_move)) /atom/movable/Exited(var/atom/movable/am, atom/new_loc) diff --git a/code/datums/observation/name_set.dm b/code/datums/observation/name_set.dm index b3d216e6686a..f0f75e0c684c 100644 --- a/code/datums/observation/name_set.dm +++ b/code/datums/observation/name_set.dm @@ -11,6 +11,7 @@ /decl/observ/name_set name = "Name Set" expected_type = /atom + flags = OBSERVATION_NO_GLOBAL_REGISTRATIONS /********************* * Name Set Handling * @@ -23,5 +24,6 @@ if(has_extension(src, /datum/extension/labels)) var/datum/extension/labels/L = get_extension(src, /datum/extension/labels) name = L.AppendLabelsToName(name) - RAISE_EVENT(/decl/observ/name_set, src, old_name, new_name) + if(event_listeners?[/decl/observ/name_set]) + raise_event_non_global(/decl/observ/name_set, old_name, new_name) update_above() \ No newline at end of file diff --git a/code/datums/observation/observation.dm b/code/datums/observation/observation.dm index 892e97ce7c93..9c5055d561e4 100644 --- a/code/datums/observation/observation.dm +++ b/code/datums/observation/observation.dm @@ -59,7 +59,6 @@ /decl/observ var/name = "Unnamed Event" // The name of this event, used mainly for debug/VV purposes. The list of event managers can be reached through the "Debug Controller" verb, selecting the "Observation" entry. var/expected_type = /datum // The expected event source for this event. register() will CRASH() if it receives an unexpected type. - var/list/list/list/event_sources = list() // Associative list of event sources, each with their own associative list. This associative list contains an instance/list of procs to call when the event is raised. var/list/global_listeners = list() // Associative list of instances that listen to all events of this type (as opposed to events belonging to a specific source) and the proc to call. VAR_PROTECTED/flags // See _defines.dm for available flags and what they do @@ -67,21 +66,27 @@ . = ..() global.all_observable_events += src -/decl/observ/proc/is_listening(var/event_source, var/datum/listener, var/proc_call) +/datum + /// Associative list of observ type -> associative list of listeners -> an instance/list of procs to call on the listener when the event is raised. + var/list/list/list/event_listeners + /// Associative list of observ type -> datums we're listening to; contains no information about callbacks as that's already stored on their event_listeners list. + var/list/_listening_to + +/decl/observ/proc/is_listening(var/datum/event_source, var/datum/listener, var/proc_call) // Return whether there are global listeners unless the event source is given. if (!event_source) return !!global_listeners.len + var/list/listeners = event_source.event_listeners?[type] // Return whether anything is listening to a source, if no listener is given. if (!listener) - return global_listeners.len || !!event_sources[event_source] + return length(global_listeners) || !!listeners // Return false if nothing is associated with that source. - if (!event_sources[event_source]) + if (!listeners) return FALSE - // Get and check the listeners for the reuqested event. - var/listeners = event_sources[event_source] + // Get and check the listeners for the requested event. if (!listeners[listener]) return FALSE @@ -96,7 +101,7 @@ return (proc_call in callback) -/decl/observ/proc/has_listeners(var/event_source) +/decl/observ/proc/has_listeners(var/datum/event_source) return is_listening(event_source) /decl/observ/proc/register(var/datum/event_source, var/datum/listener, var/proc_call) @@ -111,16 +116,16 @@ CRASH("Unexpected type. Expected [expected_type], was [event_source.type]") // Setup the listeners for this source if needed. - var/list/listeners = event_sources[event_source] - if (!listeners) - listeners = list() - event_sources[event_source] = listeners - + LAZYINITLIST(event_source.event_listeners) + LAZYINITLIST(event_source.event_listeners[type]) + var/list/listeners = event_source.event_listeners[type] // Make sure the callbacks are a list. var/list/callbacks = listeners[listener] if (!callbacks) callbacks = list() listeners[listener] = callbacks + LAZYINITLIST(listener._listening_to) + LAZYADD(listener._listening_to[type], event_source) // If the proc_call is already registered skip if(proc_call in callbacks) @@ -130,25 +135,24 @@ callbacks += proc_call return TRUE -/decl/observ/proc/unregister(var/event_source, var/datum/listener, var/proc_call) +/decl/observ/proc/unregister(var/datum/event_source, var/datum/listener, var/proc_call) // Sanity. - if (!event_source || !listener || !event_sources[event_source]) - return 0 - - // Return zero if nothing is listening for this event. - var/list/listeners = event_sources[event_source] - if (!length(listeners)) - event_sources -= event_source + if (!event_source || !listener || !event_source.event_listeners?[type]) return 0 + var/list/list/listeners = event_source.event_listeners[type] // Remove all callbacks if no specific one is given. if (!proc_call) // Return the number of callbacks removed. . = length(listeners[listener]) if(listeners.Remove(listener)) + LAZYREMOVE(listener._listening_to?[type], event_source) + UNSETEMPTY(listener._listening_to) // Perform some cleanup and return true. - if (!listeners.len) - event_sources -= event_source + if (!length(listeners)) // No one is listening to us on this source anymore. + LAZYREMOVE(event_source.event_listeners, type) + UNSETEMPTY(event_source.event_listeners?[type]) + UNSETEMPTY(event_source.event_listeners) return . return 0 @@ -161,10 +165,13 @@ if(!callbacks.Remove(proc_call)) return 0 - if (!callbacks.len) - listeners -= listener - if (!listeners.len) - event_sources -= event_source + if(!LAZYLEN(callbacks)) // the above Remove() took our last callback away, so remove our callbacks list for this listener + LAZYREMOVE(event_source.event_listeners[type], listener) // note that UNSETEMPTY would just give it a null value + LAZYREMOVE(listener._listening_to[type], event_source) + if(!LAZYLEN(listener._listening_to[type])) + LAZYREMOVE(listener._listening_to, type) + if(!LAZYLEN(event_source.event_listeners[type])) + LAZYREMOVE(event_source.event_listeners, type) return 1 /decl/observ/proc/register_global(var/datum/listener, var/proc_call) @@ -210,9 +217,27 @@ global_listeners -= listener return 1 -/decl/observ/proc/raise_event() +/// A variant of raise_event for extra-fast processing, for observs that are certain to never have any global registrations. +/datum/proc/raise_event_non_global(event_type) + // Call the listeners for this specific event source, if they exist. + var/list/listeners = event_listeners?[event_type] + if(length(listeners)) + args[1] = src // replace event_type with src for the call + for (var/listener in listeners) + var/list/callbacks = listeners[listener] + for (var/proc_call in callbacks) + // If the callback crashes, record the error and remove it. + try + call(listener, proc_call)(arglist(args)) + catch (var/exception/e) + error(EXCEPTION_TEXT(e)) + var/decl/observ/event = GET_DECL(event_type) + event.unregister(src, listener, proc_call) + return TRUE + +/decl/observ/proc/raise_event(datum/source) // Sanity - if(!length(args)) + if(!source) return FALSE if(length(global_listeners)) @@ -229,8 +254,7 @@ unregister_global(listener, proc_call) // Call the listeners for this specific event source, if they exist. - var/source = args[1] - var/list/listeners = event_sources[source] + var/list/listeners = source.event_listeners?[type] if(length(listeners)) for (var/listener in listeners) var/list/callbacks = listeners[listener] diff --git a/code/datums/observation/updated_icon.dm b/code/datums/observation/updated_icon.dm index 19e43b88cb50..021b8bca092e 100644 --- a/code/datums/observation/updated_icon.dm +++ b/code/datums/observation/updated_icon.dm @@ -11,3 +11,4 @@ /decl/observ/updated_icon name = "Updated Icon" expected_type = /atom + flags = OBSERVATION_NO_GLOBAL_REGISTRATIONS \ No newline at end of file diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm index 301d146a129b..637e724942fb 100644 --- a/code/datums/observation/~cleanup.dm +++ b/code/datums/observation/~cleanup.dm @@ -38,8 +38,7 @@ /proc/cleanup_global_listener(listener, listen_count) var/events_removed - for(var/entry in global.all_observable_events) - var/decl/observ/event = entry + for(var/decl/observ/event in decls_repository.get_decls_of_subtype_unassociated(/decl/observ)) if((events_removed = event.unregister_global(listener))) log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still globally registered to an event.") listen_count -= events_removed @@ -48,13 +47,14 @@ if(listen_count > 0) CRASH("Failed to clean up all global listener entries!") +// This might actually be fast enough now that there's no point in logging it? /proc/cleanup_source_listeners(datum/event_source, source_listener_count) event_source.event_source_count = 0 var/events_removed - for(var/entry in global.all_observable_events) - var/decl/observ/event = entry - var/list/list/proc_owners = event.event_sources[event_source] + for(var/event_type in event_source.event_listeners) + var/list/list/proc_owners = event_source.event_listeners[event_type] if(proc_owners) + var/decl/observ/event = GET_DECL(event_type) for(var/proc_owner in proc_owners) var/list/callbacks_cached = proc_owners[proc_owner]?.Copy() if((events_removed = event.unregister(event_source, proc_owner))) @@ -68,16 +68,16 @@ /proc/cleanup_event_listener(datum/listener, listener_count) listener.event_listen_count = 0 var/events_removed - for(var/entry in global.all_observable_events) - var/decl/observ/event = entry - for(var/event_source in event.event_sources) - if(isnull(event.event_sources[event_source])) - log_debug("[event] ([event.type]) - [log_info_line(event_source)] had null listeners list!") - var/list/callbacks_cached = event.event_sources[event_source]?[listener]?.Copy() - if((events_removed = event.unregister(event_source, listener))) - log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still listening to [log_info_line(event_source)]. Callbacks: [json_encode(callbacks_cached)]") - listener_count -= events_removed - if(!listener_count) - return + for(var/event_type in listener._listening_to) + var/list/listened_sources = listener._listening_to[event_type] + if(listened_sources) + for(var/datum/event_source in listened_sources) + var/list/callbacks_cached = event_source.event_listeners[event_type]?[listener]?.Copy() + var/decl/observ/event = GET_DECL(event_type) + if((events_removed = event.unregister(event_source, listener))) + log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still listening to [log_info_line(event_source)]. Callbacks: [json_encode(callbacks_cached)]") + listener_count -= events_removed + if(!listener_count) + return if(listener_count > 0) CRASH("Failed to clean up all listener entries!") diff --git a/code/game/atoms.dm b/code/game/atoms.dm index c706714a0012..51a49b53ea1e 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -216,7 +216,8 @@ SHOULD_CALL_PARENT(TRUE) if(density != new_density) density = !!new_density - RAISE_EVENT(/decl/observ/density_set, src, !density, density) + if(event_listeners?[/decl/observ/density_set]) + raise_event_non_global(/decl/observ/density_set, !density, density) /** Handle a projectile `P` hitting this atom @@ -376,7 +377,8 @@ if(L.light_angle) L.source_atom.update_light() - RAISE_EVENT(/decl/observ/dir_set, src, old_dir, new_dir) + if(event_listeners?[/decl/observ/dir_set]) + raise_event_non_global(/decl/observ/dir_set, old_dir, new_dir) /// Set the icon to `new_icon` @@ -404,7 +406,8 @@ /atom/proc/update_icon() SHOULD_CALL_PARENT(TRUE) on_update_icon() - RAISE_EVENT(/decl/observ/updated_icon, src) + if(event_listeners?[/decl/observ/updated_icon]) + raise_event_non_global(/decl/observ/updated_icon) /** Update this atom's icon. diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 4ba136ff11ac..ce899f938418 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -185,8 +185,8 @@ . = TRUE // observ - if(!loc) - RAISE_EVENT(/decl/observ/moved, src, origin, null) + if(!loc && event_listeners?[/decl/observ/moved]) + raise_event_non_global(/decl/observ/moved, origin, null) // freelook if(simulated && opacity) @@ -237,8 +237,8 @@ else unbuckle_mob() - if(!loc) - RAISE_EVENT(/decl/observ/moved, src, old_loc, null) + if(!loc && event_listeners?[/decl/observ/moved]) + raise_event_non_global(/decl/observ/moved, old_loc, null) // freelook if(simulated && opacity) diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index c320bdf00c46..4d81c03ca318 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -121,8 +121,8 @@ if(tell_universe) global.universe.OnTurfChange(changed_turf) - if(changed_turf.density != old_density) - RAISE_EVENT(/decl/observ/density_set, changed_turf, old_density, changed_turf.density) + if(changed_turf.density != old_density && changed_turf.event_listeners?[/decl/observ/density_set]) + changed_turf.raise_event_non_global(/decl/observ/density_set, old_density, changed_turf.density) // lighting stuff diff --git a/nebula.dme b/nebula.dme index da54dd18fb41..5c8541c4f63a 100644 --- a/nebula.dme +++ b/nebula.dme @@ -115,7 +115,6 @@ #include "code\_global_vars\client.dm" #include "code\_global_vars\configuration.dm" #include "code\_global_vars\logging.dm" -#include "code\_global_vars\misc.dm" #include "code\_global_vars\mobs.dm" #include "code\_global_vars\sensitive.dm" #include "code\_global_vars\sound.dm" From 8eb902bebc6aaff18e4a4a21a379e4ddf2688a5b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 15:06:04 -0500 Subject: [PATCH 064/512] Fix observation unit tests for datum-based registration --- code/datums/observation/observation.dm | 4 - code/datums/observation/~cleanup.dm | 10 ++ code/unit_tests/observation_tests.dm | 154 +++++++++++-------------- 3 files changed, 75 insertions(+), 93 deletions(-) diff --git a/code/datums/observation/observation.dm b/code/datums/observation/observation.dm index 9c5055d561e4..ee87ba09d524 100644 --- a/code/datums/observation/observation.dm +++ b/code/datums/observation/observation.dm @@ -62,10 +62,6 @@ var/list/global_listeners = list() // Associative list of instances that listen to all events of this type (as opposed to events belonging to a specific source) and the proc to call. VAR_PROTECTED/flags // See _defines.dm for available flags and what they do -/decl/observ/Initialize() - . = ..() - global.all_observable_events += src - /datum /// Associative list of observ type -> associative list of listeners -> an instance/list of procs to call on the listener when the event is raised. var/list/list/list/event_listeners diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm index 637e724942fb..910e1e178459 100644 --- a/code/datums/observation/~cleanup.dm +++ b/code/datums/observation/~cleanup.dm @@ -1,3 +1,5 @@ +/// This variable is used only for sanity checks during unit tests. It contains a list of all datums with global event registrations. +var/global/list/_all_global_event_listeners = list() /datum /// Tracks how many event registrations are listening to us. Used in cleanup to prevent dangling references. var/event_source_count = 0 @@ -30,11 +32,19 @@ . = ..() if(.) listener.global_listen_count += 1 +// This variable is used only for sanity checks during unit tests. +#ifdef UNIT_TEST + global._all_global_event_listeners += listener +#endif /decl/observ/unregister_global(var/datum/listener, var/proc_call) . = ..() if(.) listener.global_listen_count -= . +#ifdef UNIT_TEST + if(!listener.global_listen_count) + global._all_global_event_listeners -= listener +#endif /proc/cleanup_global_listener(listener, listen_count) var/events_removed diff --git a/code/unit_tests/observation_tests.dm b/code/unit_tests/observation_tests.dm index 829bc7435764..fdc7c3e21a6d 100644 --- a/code/unit_tests/observation_tests.dm +++ b/code/unit_tests/observation_tests.dm @@ -7,29 +7,26 @@ abstract_type = /datum/unit_test/observation async = 0 var/list/received_moves - var/list/received_name_set_events - - var/list/stored_global_listen_count + var/list/received_opacity_events + /// A list of datums to check for event sanity pre- and post-test. + var/list/datums_of_interest + var/list/stored_global_registrations /datum/unit_test/observation/start_test() received_moves = received_moves || list() - received_name_set_events = received_name_set_events || list() + received_opacity_events = received_opacity_events || list() received_moves.Cut() - received_name_set_events.Cut() - - var/decl/observ/moved/moved_event = GET_DECL(/decl/observ/moved) - for(var/global_listener in moved_event.global_listeners) - events_repository.unregister_global(/decl/observ/moved, global_listener) + received_opacity_events.Cut() - stored_global_listen_count = global.global_listen_count.Copy() + stored_global_registrations = global._all_global_event_listeners.Copy() sanity_check_events("Pre-Test") . = conduct_test() sanity_check_events("Post-Test") + LAZYCLEARLIST(datums_of_interest) /datum/unit_test/observation/proc/sanity_check_events(var/phase) - for(var/entry in global.all_observable_events) - var/decl/observ/event = entry + for(var/decl/observ/event in decls_repository.get_decls_of_subtype_unassociated(/decl/observ)) var/null_count = 0 for(var/null_candidate in event.global_listeners) if(isnull(event.global_listeners[null_candidate])) @@ -37,27 +34,21 @@ if(null_count > 0) fail("[phase]: [event] - The global listeners list contains a null entry.") - for(var/event_source in event.event_sources) - for(var/list/list_of_listeners in event.event_sources[event_source]) - if(isnull(list_of_listeners)) - fail("[phase]: [event] - The event source list contains a null entry.") - else if(!istype(list_of_listeners)) - fail("[phase]: [event] - The list of listeners was not of the expected type. Was [list_of_listeners.type].") - else - for(var/listener in list_of_listeners) - if(isnull(listener)) - fail("[phase]: [event] - The event source listener list contains a null entry.") - else - var/proc_calls = list_of_listeners[listener] - if(isnull(proc_calls)) - fail("[phase]: [event] - [listener] - The proc call list was null.") - else - for(var/proc_call in proc_calls) - if(isnull(proc_call)) - fail("[phase]: [event] - [listener]- The proc call list contains a null entry.") - - for(var/entry in (global.global_listen_count - stored_global_listen_count)) - fail("[phase]: global_listen_count - Contained [log_info_line(entry)].") + for(var/datum/datum_of_interest in datums_of_interest) + for(var/registered_event_type in datum_of_interest.event_listeners) + if(datum_of_interest.event_listeners[registered_event_type] && (null in datum_of_interest.event_listeners[registered_event_type])) + fail("[phase]: [registered_event_type] - [datum_of_interest]'s event_listeners list contains a null key.") + for(var/datum/listener in datum_of_interest.event_listeners[registered_event_type]) + var/proc_calls = datum_of_interest.event_listeners[registered_event_type][listener] + if(isnull(proc_calls)) + fail("[phase]: [registered_event_type] - [listener] - The proc call list was null.") + else if(null in proc_calls) + fail("[phase]: [registered_event_type] - [listener]- The proc call list contains a null entry.") + if(datum_of_interest._listening_to?[registered_event_type] && (null in datum_of_interest._listening_to[registered_event_type])) + fail("[phase]: [registered_event_type] - [datum_of_interest]'s _listening_to list contains a null value.") + + for(var/entry in (global._all_global_event_listeners - stored_global_registrations)) + fail("[phase]: _all_global_event_listeners - Contained [log_info_line(entry)].") /datum/unit_test/observation/proc/conduct_test() return 0 @@ -70,40 +61,39 @@ var/list/l = entry log_unit_test("[l[1]] - [l[2]] - [l[3]]") -/datum/unit_test/observation/proc/receive_name_change(source, old_name, new_name) - received_name_set_events[++received_name_set_events.len] = list(source, old_name, new_name) +/datum/unit_test/observation/proc/receive_opacity_change(source, old_opacity, new_opacity) + received_opacity_events[++received_opacity_events.len] = list(source, old_opacity, new_opacity) -/datum/unit_test/observation/proc/dump_received_names() - for(var/entry in received_name_set_events) +/datum/unit_test/observation/proc/dump_received_opacities() + for(var/entry in received_opacity_events) var/list/l = entry log_unit_test("[l[1]] - [l[2]] - [l[3]]") /datum/unit_test/observation/global_listeners_shall_receive_events name = "OBSERVATION: Global listeners shall receive events" - var/old_name - var/new_name + var/old_opacity + var/new_opacity /datum/unit_test/observation/global_listeners_shall_receive_events/conduct_test() var/turf/start = get_safe_turf() var/obj/O = get_named_instance(/obj, start) - old_name = O.name - new_name = O.name + " (New)" - - events_repository.register_global(/decl/observ/name_set, src, TYPE_PROC_REF(/datum/unit_test/observation, receive_name_change)) - O.SetName(new_name) - - if(received_name_set_events.len != 1) - fail("Expected 1 raised name set event, were [received_name_set_events.len].") - dump_received_names() + old_opacity = O.opacity + new_opacity = !old_opacity + + events_repository.register_global(/decl/observ/opacity_set, src, TYPE_PROC_REF(/datum/unit_test/observation, receive_opacity_change)) + O.set_opacity(new_opacity) + if(length(received_opacity_events) != 1) + fail("Expected 1 raised opacity set event, were [received_opacity_events].") + dump_received_opacities() return 1 - var/list/event = received_name_set_events[1] - if(event[1] != O || event[2] != old_name || event[3] != new_name) - fail("Unepected name set event received. Expected [O], was [event[1]]. Expected [old_name], was [event[2]]. Expected [new_name], was [event[3]]") + var/list/event = received_opacity_events[1] + if(event[1] != O || event[2] != old_opacity || event[3] != new_opacity) + fail("Unexpected opacity set event received. Expected [O], was [event[1]]. Expected [old_opacity], was [event[2]]. Expected [new_opacity], was [event[3]]") else - pass("Received the expected name set event.") + pass("Received the expected opacity set event.") - events_repository.unregister_global(/decl/observ/name_set, src) + events_repository.unregister_global(/decl/observ/opacity_set, src) qdel(O) return 1 @@ -115,6 +105,8 @@ var/mob/living/human/H = get_named_instance(/mob/living/human, T, global.using_map.default_species) var/mob/observer/ghost/O = get_named_instance(/mob/observer/ghost, T, "Ghost") + datums_of_interest = list(T, H, O) + O.ManualFollow(H) if(is_listening_to_movement(H, O)) pass("The observer is now following the mob.") @@ -132,6 +124,7 @@ var/turf/T = get_safe_turf() var/mob/living/human/H = get_named_instance(/mob/living/human, T, global.using_map.default_species) var/mob/observer/ghost/O = get_named_instance(/mob/observer/ghost, T, "Ghost") + datums_of_interest = list(T, H, O) O.ManualFollow(H) O.stop_following() @@ -150,6 +143,7 @@ /datum/unit_test/observation/moved_shall_not_register_on_enter_without_listeners/conduct_test() var/turf/T = get_safe_turf() var/mob/living/human/H = get_named_instance(/mob/living/human, T, global.using_map.default_species) + datums_of_interest = list(T, H) qdel(H.virtual_mob) H.virtual_mob = null @@ -173,6 +167,7 @@ var/mob/living/human/H = get_named_instance(/mob/living/human, T, global.using_map.default_species) var/obj/structure/closet/C = get_named_instance(/obj/structure/closet, T, "Closet") var/mob/observer/ghost/O = get_named_instance(/mob/observer/ghost, T, "Ghost") + datums_of_interest = list(T, H, C, O) H.forceMove(C) O.ManualFollow(H) @@ -196,6 +191,7 @@ var/mob/living/human/H = get_named_instance(/mob/living/human, T, global.using_map.default_species) var/obj/structure/closet/C = get_named_instance(/obj/structure/closet, T, "Closet") var/mob/observer/ghost/O = get_named_instance(/mob/observer/ghost, T, "Ghost") + datums_of_interest = list(T, H, C, O) O.ManualFollow(H) H.forceMove(C) @@ -220,6 +216,7 @@ var/mob/observer/ghost/one = get_named_instance(/mob/observer/ghost, T, "Ghost One") var/mob/observer/ghost/two = get_named_instance(/mob/observer/ghost, T, "Ghost Two") var/mob/observer/ghost/three = get_named_instance(/mob/observer/ghost, T, "Ghost Three") + datums_of_interest = list(T, one, two, three) two.ManualFollow(one) three.ManualFollow(two) @@ -244,6 +241,7 @@ var/mob/observer/ghost/one = get_named_instance(/mob/observer/ghost, T, "Ghost One") var/mob/observer/ghost/two = get_named_instance(/mob/observer/ghost, T, "Ghost Two") var/mob/observer/ghost/three = get_named_instance(/mob/observer/ghost, T, "Ghost Three") + datums_of_interest = list(T, one, two, three) two.ManualFollow(one) three.ManualFollow(two) @@ -266,20 +264,21 @@ /datum/unit_test/observation/sanity_global_listeners_shall_not_leave_null_entries_when_destroyed/conduct_test() var/turf/T = get_safe_turf() var/obj/O = get_named_instance(/obj, T) + datums_of_interest = list(T, O) - events_repository.register_global(/decl/observ/name_set, O, TYPE_PROC_REF(/atom/movable, move_to_turf)) + events_repository.register_global(/decl/observ/atom_examined, O, TYPE_PROC_REF(/atom/movable, move_to_turf)) qdel(O) - var/decl/observ/name_set/name_set_event = GET_DECL(/decl/observ/name_set) + var/decl/observ/atom_examined/examined_event = IMPLIED_DECL var/null_count = 0 - for(var/null_candidate in name_set_event.global_listeners) - if (isnull(name_set_event.event_sources[null_candidate])) + for(var/datum/null_candidate in examined_event.global_listeners) // skip null keys + if (isnull(examined_event.global_listeners[null_candidate])) null_count++ - if(null_count > 0) + if(null_count) fail("The global listener list contains a null value.") else pass("The global listener list does not contain a null value.") - if(name_set_event.global_listeners && (null in name_set_event.global_listeners)) + if(examined_event.global_listeners && (null in examined_event.global_listeners)) fail("The global listener list contains a null key.") else pass("The global listener list does not contain a null key.") @@ -296,21 +295,7 @@ events_repository.register(/decl/observ/moved, event_source, listener, TYPE_PROC_REF(/atom/movable, recursive_move)) qdel(event_source) - - var/decl/observ/moved/moved_event = GET_DECL(/decl/observ/moved) - var/null_count = 0 - for(var/null_candidate in moved_event.event_sources) - if (isnull(moved_event.event_sources[null_candidate])) - null_count++ - if(null_count > 0) - fail("The event source list contains a null value.") - else - pass("The event source list does not contain a null value.") - if(moved_event.event_sources && (null in moved_event.event_sources)) - fail("The event source list contains a null key.") - else - pass("The event source list does not contain a null key.") - + sanity_check_events("Post-Event Source Deletion") qdel(listener) return 1 @@ -321,24 +306,11 @@ var/turf/T = get_safe_turf() var/mob/event_source = get_named_instance(/mob, T, "Event Source") var/mob/listener = get_named_instance(/mob, T, "Event Listener") + datums_of_interest = list(T, event_source, listener) events_repository.register(/decl/observ/moved, event_source, listener, TYPE_PROC_REF(/atom/movable, recursive_move)) qdel(listener) - - var/decl/observ/moved/moved_event = GET_DECL(/decl/observ/moved) - var/listeners = moved_event.event_sources[event_source] - var/null_count = 0 - for(var/null_candidate in listeners) - if (isnull(listeners[null_candidate])) - null_count++ - if(null_count > 0) - fail("The event source listener list contains a null value.") - else - pass("The event source listener list does not contain a null value.") - if(listeners && (null in listeners)) - fail("The event source listener list contains a null key.") - else - pass("The event source listener list does not contain a null key.") + sanity_check_events("Post-Listener Deletion") qdel(event_source) return 1 @@ -349,6 +321,7 @@ var/turf/T = get_safe_turf() var/mob/event_source = get_named_instance(/mob, T, "Event Source") var/mob/listener = get_named_instance(/mob, T, "Event Listener") + datums_of_interest = list(T, event_source, listener) var/initial_event_source_count = event_source.event_source_count var/initial_event_listen_count = listener.event_listen_count @@ -373,6 +346,7 @@ var/turf/T = get_safe_turf() var/mob/event_source = get_named_instance(/mob, T, "Event Source") var/mob/listener = get_named_instance(/mob, T, "Event Listener") + datums_of_interest = list(T, event_source, listener) var/initial_event_source_count = event_source.event_source_count var/initial_event_listen_count = listener.event_listen_count @@ -399,6 +373,7 @@ var/mob/event_source_A = get_named_instance(/mob, T, "Event Source A") var/mob/event_source_B = get_named_instance(/mob, T, "Event Source B") var/mob/listener = get_named_instance(/mob, T, "Event Listener") + datums_of_interest = list(T, event_source_A, event_source_B, listener) var/initial_event_listen_count = listener.event_listen_count events_repository.register(/decl/observ/moved, event_source_A, listener, TYPE_PROC_REF(/atom/movable, recursive_move)) @@ -424,6 +399,7 @@ var/mob/event_source = get_named_instance(/mob, T, "Event Source") var/mob/listener_A = get_named_instance(/mob, T, "Event Listener A") var/mob/listener_B = get_named_instance(/mob, T, "Event Listener B") + datums_of_interest = list(T, event_source, listener_A, listener_B) var/initial_event_source_count = event_source.event_source_count var/initial_event_listen_count = listener_B.event_listen_count From b72ac84f9753a5be4cce8a75b6348daa5387c9a5 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 18:25:42 -0500 Subject: [PATCH 065/512] Simplify event registration cleanup --- code/datums/observation/~cleanup.dm | 38 ++++++++++++----------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm index 910e1e178459..5ac8158aeec5 100644 --- a/code/datums/observation/~cleanup.dm +++ b/code/datums/observation/~cleanup.dm @@ -10,11 +10,11 @@ var/global/list/_all_global_event_listeners = list() /proc/cleanup_events(var/datum/source) if(source?.global_listen_count > 0) - cleanup_global_listener(source, source.global_listen_count) + cleanup_global_listener(source) if(source?.event_source_count > 0) - cleanup_source_listeners(source, source.event_source_count) + cleanup_source_listeners(source) if(source?.event_listen_count > 0) - cleanup_event_listener(source, source.event_listen_count) + cleanup_event_listener(source) /decl/observ/register(var/datum/event_source, var/datum/listener, var/proc_call) . = ..() @@ -46,48 +46,40 @@ var/global/list/_all_global_event_listeners = list() global._all_global_event_listeners -= listener #endif -/proc/cleanup_global_listener(listener, listen_count) - var/events_removed +/proc/cleanup_global_listener(datum/listener) for(var/decl/observ/event in decls_repository.get_decls_of_subtype_unassociated(/decl/observ)) - if((events_removed = event.unregister_global(listener))) + if(event.unregister_global(listener)) log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still globally registered to an event.") - listen_count -= events_removed - if(!listen_count) + if(!listener.global_listen_count) return - if(listen_count > 0) + if(listener.global_listen_count > 0) CRASH("Failed to clean up all global listener entries!") // This might actually be fast enough now that there's no point in logging it? -/proc/cleanup_source_listeners(datum/event_source, source_listener_count) - event_source.event_source_count = 0 - var/events_removed +/proc/cleanup_source_listeners(datum/event_source) for(var/event_type in event_source.event_listeners) var/list/list/proc_owners = event_source.event_listeners[event_type] if(proc_owners) var/decl/observ/event = GET_DECL(event_type) for(var/proc_owner in proc_owners) var/list/callbacks_cached = proc_owners[proc_owner]?.Copy() - if((events_removed = event.unregister(event_source, proc_owner))) + if(event.unregister(event_source, proc_owner)) log_debug("[event] ([event.type]) - [log_info_line(event_source)] was deleted while still being listened to by [log_info_line(proc_owner)]. Callbacks: [json_encode(callbacks_cached)]") - source_listener_count -= events_removed - if(!source_listener_count) + if(!event_source.event_source_count) return - if(source_listener_count > 0) + if(event_source.event_source_count > 0) CRASH("Failed to clean up all event source entries!") -/proc/cleanup_event_listener(datum/listener, listener_count) - listener.event_listen_count = 0 - var/events_removed +/proc/cleanup_event_listener(datum/listener) for(var/event_type in listener._listening_to) var/list/listened_sources = listener._listening_to[event_type] if(listened_sources) for(var/datum/event_source in listened_sources) var/list/callbacks_cached = event_source.event_listeners[event_type]?[listener]?.Copy() var/decl/observ/event = GET_DECL(event_type) - if((events_removed = event.unregister(event_source, listener))) + if(event.unregister(event_source, listener)) log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still listening to [log_info_line(event_source)]. Callbacks: [json_encode(callbacks_cached)]") - listener_count -= events_removed - if(!listener_count) + if(!listener.event_listen_count) return - if(listener_count > 0) + if(listener.event_listen_count > 0) CRASH("Failed to clean up all listener entries!") From c02467efca249bc769257c305f62088dd5492f73 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 22 Feb 2025 13:06:45 -0500 Subject: [PATCH 066/512] Preserve event bookkeeping vars through ChangeTurf --- code/game/turfs/turf_changing.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index 4d81c03ca318..ac2e306ea590 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -71,6 +71,8 @@ var/old_affecting_heat_sources = affecting_heat_sources var/old_height = get_physical_height() var/old_alpha_mask_state = get_movable_alpha_mask_state(null) + var/old_event_listeners = event_listeners + var/old_listening_to = _listening_to var/old_ambience = ambient_light var/old_ambience_mult = ambient_light_multiplier @@ -98,6 +100,9 @@ var/turf/changed_turf = . changed_turf.above = old_above // Multiz ref tracking. changed_turf.prev_type = old_prev_type // Shuttle transition turf tracking. + // Set our observation bookkeeping lists back. + changed_turf.event_listeners = old_event_listeners + changed_turf._listening_to = old_listening_to changed_turf.affecting_heat_sources = old_affecting_heat_sources From 02861e86bc8597695010546219227af8e833c7e3 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 20 Feb 2025 10:47:00 +1100 Subject: [PATCH 067/512] Reagent datum now uses material instances instead of types as keys. --- code/__defines/chemistry.dm | 10 +- code/__defines/mobs.dm | 3 + code/__defines/reagent_data_fields.dm | 3 + code/__globals.dm | 1 + code/_helpers/medical_scans.dm | 18 +- code/game/atoms.dm | 5 +- code/game/machinery/Sleeper.dm | 3 +- code/game/machinery/kitchen/icecream.dm | 10 +- code/game/machinery/kitchen/microwave.dm | 28 +- .../{_obj_edibility.dm => _objs_edibility.dm} | 2 +- code/game/objects/effects/chem/foam.dm | 4 +- code/game/objects/items/__item.dm | 10 +- code/game/objects/items/contraband.dm | 10 +- .../items/stacks/medical/medical_bandage.dm | 5 +- code/game/objects/items/toys.dm | 7 +- code/game/objects/items/weapons/autopsy.dm | 4 +- code/game/objects/structures/compost.dm | 13 +- code/game/objects/structures/fires.dm | 5 +- code/game/turfs/turf_fluids.dm | 21 +- .../spacesuits/rig/modules/utility.dm | 8 +- .../crafting/pottery/pottery_moulds.dm | 9 +- code/modules/detectivework/tools/rag.dm | 5 +- code/modules/economy/_worth.dm | 5 +- code/modules/fabrication/fabricator_intake.dm | 12 +- code/modules/food/cooking/_recipe.dm | 24 +- .../cooking_vessels/_cooking_vessel.dm | 13 +- .../food/cooking/cooking_vessels/pot.dm | 3 +- code/modules/hydroponics/grown.dm | 17 +- code/modules/hydroponics/trays/tray.dm | 36 +- .../subtypes/reagents.dm | 14 +- code/modules/materials/_materials.dm | 40 +-- .../gasses/material_gas_mundane.dm | 6 +- .../liquids/materials_liquid_toxins.dm | 8 +- .../liquids/materials_liquid_water.dm | 6 +- .../solids/materials_solid_elements.dm | 8 +- .../solids/materials_solid_mineral.dm | 2 +- .../mining/machinery/material_compressor.dm | 4 +- .../mining/machinery/material_extractor.dm | 15 +- .../mining/machinery/material_smelter.dm | 4 +- code/modules/mob/living/bot/medibot.dm | 4 +- code/modules/mob/living/life.dm | 15 +- code/modules/mob/living/living_blood.dm | 6 +- code/modules/mob/living/living_defines.dm | 2 +- code/modules/organs/organ.dm | 6 +- .../power/fuel_assembly/fuel_compressor.dm | 8 +- code/modules/power/lighting.dm | 5 +- .../projectiles/guns/projectile/dartgun.dm | 15 +- code/modules/reagents/Chemistry-Colours.dm | 13 +- code/modules/reagents/Chemistry-Grinder.dm | 5 +- code/modules/reagents/Chemistry-Holder.dm | 337 +++++++++--------- code/modules/reagents/Chemistry-Machinery.dm | 37 +- code/modules/reagents/Chemistry-Metabolism.dm | 13 +- code/modules/reagents/Chemistry-Taste.dm | 5 +- code/modules/reagents/chems/chems_alcohol.dm | 4 +- code/modules/reagents/chems/chems_blood.dm | 12 +- .../modules/reagents/chems/chems_compounds.dm | 16 +- code/modules/reagents/chems/chems_drinks.dm | 2 +- code/modules/reagents/chems/chems_drugs.dm | 21 +- .../modules/reagents/chems/chems_medicines.dm | 79 ++-- .../reagents/chems/chems_painkillers.dm | 10 +- code/modules/reagents/chems/chems_pigments.dm | 2 +- code/modules/reagents/chems/chems_poisons.dm | 2 +- .../reagents/chems/random/chems_random.dm | 2 +- code/modules/reagents/dispenser/dispenser2.dm | 5 +- .../reagents/reactions/reaction_synthesis.dm | 40 +-- code/modules/reagents/reagent_containers.dm | 7 +- .../drinkingglass/drinkingglass.dm | 18 +- .../reagent_containers/drinks/juicebox.dm | 4 +- .../reagents/reagent_containers/food.dm | 5 +- .../reagents/reagent_containers/retort.dm | 5 +- code/modules/reagents/reagent_dispenser.dm | 10 +- code/modules/scanners/breath.dm | 7 +- code/modules/scanners/health.dm | 37 +- code/modules/scanners/mass_spectrometer.dm | 6 +- code/modules/scanners/plant.dm | 10 +- code/modules/scanners/reagents.dm | 5 +- code/modules/scent/_scent.dm | 13 +- code/modules/surgery/other.dm | 2 +- code/modules/vehicles/engine.dm | 7 +- .../machinery/geosample_scanner.dm | 8 +- mods/content/xenobiology/colours/_colour.dm | 8 +- .../xenobiology/slime/slime_reagents.dm | 2 +- mods/species/skrell/datum/species.dm | 2 +- mods/species/vox/organs_vox.dm | 5 +- nebula.dme | 2 +- 85 files changed, 595 insertions(+), 635 deletions(-) rename code/game/objects/{_obj_edibility.dm => _objs_edibility.dm} (98%) diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 670021178c35..5e70c1e79047 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -81,12 +81,12 @@ #define REAGENT_LIST(R) (R.reagents?.get_reagents() || "No reagent holder") #define REAGENTS_FREE_SPACE(R) (R?.maximum_volume - R?.total_volume) -#define REAGENT_VOLUME(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.reagent_volumes && REAGENT_HOLDER.reagent_volumes[REAGENT_TYPE]) +#define REAGENT_VOLUME(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.reagent_volumes && REAGENT_HOLDER.reagent_volumes[RESOLVE_TO_DECL(REAGENT_TYPE)]) +#define LIQUID_VOLUME(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.liquid_volumes && REAGENT_HOLDER.liquid_volumes[RESOLVE_TO_DECL(REAGENT_TYPE)]) +#define SOLID_VOLUME(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.solid_volumes && REAGENT_HOLDER.solid_volumes[RESOLVE_TO_DECL(REAGENT_TYPE)]) +#define REAGENT_DATA(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.reagent_data && REAGENT_HOLDER.reagent_data[RESOLVE_TO_DECL(REAGENT_TYPE)]) -#define LIQUID_VOLUME(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.liquid_volumes && REAGENT_HOLDER.liquid_volumes[REAGENT_TYPE]) -#define SOLID_VOLUME(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.solid_volumes && REAGENT_HOLDER.solid_volumes[REAGENT_TYPE]) - -#define REAGENT_DATA(REAGENT_HOLDER, REAGENT_TYPE) (REAGENT_HOLDER?.reagent_data && REAGENT_HOLDER.reagent_data[REAGENT_TYPE]) +#define CHEM_DOSE(M, R) LAZYACCESS(M._chem_doses, RESOLVE_TO_DECL(R)) #define MAT_SOLVENT_NONE 0 #define MAT_SOLVENT_MILD 1 diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 3ea4d3cde8da..c6deed9da3a6 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -246,6 +246,9 @@ #define DATA_BLOOD_DOSE_CHEM /decl/reagent_data_field/blood_dose_chem #define DATA_BLOOD_HAS_OXY /decl/reagent_data_field/blood_has_oxy +// Misc general data. +#define DATA_COOLDOWN_TIME /decl/reagent_data_field/cooldown_time + //Used by show_message() and emotes #define VISIBLE_MESSAGE 1 #define AUDIBLE_MESSAGE 2 diff --git a/code/__defines/reagent_data_fields.dm b/code/__defines/reagent_data_fields.dm index 0caef07d2252..db7b27ed7168 100644 --- a/code/__defines/reagent_data_fields.dm +++ b/code/__defines/reagent_data_fields.dm @@ -62,3 +62,6 @@ /decl/reagent_data_field/blood_has_oxy uid = "rdf_blood_has_oxy" + +/decl/reagent_data_field/cooldown_time + uid = "rdf_cooldown_time" diff --git a/code/__globals.dm b/code/__globals.dm index 7c9e5ed5dbea..ecb9b3eb1fc1 100644 --- a/code/__globals.dm +++ b/code/__globals.dm @@ -1,6 +1,7 @@ // Defined here due to being used immediately below. #define GET_DECL(D) (ispath(D, /decl) ? (decls_repository.fetched_decls[D] || decls_repository.get_decl(D)) : null) #define IMPLIED_DECL GET_DECL(__IMPLIED_TYPE__) +#define RESOLVE_TO_DECL(D) (istype(D, /decl) ? D : GET_DECL(D)) // Defined here due to compile order; overrides in macros make the compiler complain. /decl/global_vars diff --git a/code/_helpers/medical_scans.dm b/code/_helpers/medical_scans.dm index fcb3fa78e88e..5d4b84e8df90 100644 --- a/code/_helpers/medical_scans.dm +++ b/code/_helpers/medical_scans.dm @@ -43,19 +43,17 @@ .["reagents"] = list() if(reagents?.total_volume) - for(var/liquid_type in reagents.liquid_volumes) - var/decl/material/reagent = GET_DECL(liquid_type) - var/list/reagent_data = list() - reagent_data["name"]= reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID) - reagent_data["quantity"] = round(REAGENT_VOLUME(reagents, reagent.type),1) + for(var/decl/material/reagent as anything in reagents.liquid_volumes) + var/list/reagent_data = list() + reagent_data["name"] = reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID) + reagent_data["quantity"] = round(REAGENT_VOLUME(reagents, reagent),1) reagent_data["scannable"] = reagent.scannable .["reagents"] += list(reagent_data) - for(var/solid_type in reagents.solid_volumes) - var/decl/material/reagent = GET_DECL(solid_type) - var/list/reagent_data = list() - reagent_data["name"]= reagent.get_reagent_name(reagents, MAT_PHASE_SOLID) - reagent_data["quantity"] = round(REAGENT_VOLUME(reagents, reagent.type),1) + for(var/decl/material/reagent as anything in reagents.solid_volumes) + var/list/reagent_data = list() + reagent_data["name"] = reagent.get_reagent_name(reagents, MAT_PHASE_SOLID) + reagent_data["quantity"] = round(REAGENT_VOLUME(reagents, reagent),1) reagent_data["scannable"] = reagent.scannable .["reagents"] += list(reagent_data) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 51a49b53ea1e..22f4bce9273c 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -426,7 +426,7 @@ /atom/proc/get_contained_matter() if(length(reagents?.reagent_volumes)) LAZYINITLIST(.) - for(var/reagent in reagents.reagent_volumes) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) .[reagent] += floor(REAGENT_VOLUME(reagents, reagent) / REAGENT_UNITS_PER_MATERIAL_UNIT) for(var/atom/contained_obj as anything in get_contained_external_atoms()) // machines handle component parts separately . = MERGE_ASSOCS_WITH_NUM_VALUES(., contained_obj.get_contained_matter()) @@ -483,8 +483,7 @@ */ /atom/proc/try_detonate_reagents(var/severity = 3) if(reagents) - for(var/r_type in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(r_type) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) reagent.explosion_act(src, severity) /** diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index edfca51d3e53..47bc17acc0dd 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -59,8 +59,7 @@ to_chat(user, SPAN_WARNING("\The [src] cannot accept any more chemical canisters.")) return FALSE if(!emagged) - for(var/rid in canister.reagents?.reagent_volumes) - var/decl/material/reagent = GET_DECL(rid) + for(var/decl/material/reagent as anything in canister.reagents?.reagent_volumes) for(var/banned_type in banned_chem_types) if(istype(reagent, banned_type)) to_chat(user, SPAN_WARNING("Automatic safety checking indicates the presence of a prohibited substance in this canister.")) diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm index 43e6c98cbb29..9671e16e3614 100644 --- a/code/game/machinery/kitchen/icecream.dm +++ b/code/game/machinery/kitchen/icecream.dm @@ -100,14 +100,12 @@ dat += "Chocolate cones: Dispense Make x5 [product_types[CONE_CHOC]] cones left. (Ingredients: flour, sugar, coco powder)
" dat += "
" dat += "VAT CONTENT
" - for(var/liquid_type in reagents?.liquid_volumes) - var/decl/material/reagent = GET_DECL(liquid_type) - dat += "[reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID)]: [LIQUID_VOLUME(reagents, liquid_type)]" + for(var/decl/material/reagent as anything in reagents?.liquid_volumes) + dat += "[reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID)]: [LIQUID_VOLUME(reagents, reagent)]" dat += "Purge
" - for(var/solid_type in reagents?.solid_volumes) - var/decl/material/reagent = GET_DECL(solid_type) - dat += "[reagent.get_reagent_name(reagents, MAT_PHASE_SOLID)]: [SOLID_VOLUME(reagents, solid_type)]" + for(var/decl/material/reagent as anything in reagents?.solid_volumes) + dat += "[reagent.get_reagent_name(reagents, MAT_PHASE_SOLID)]: [SOLID_VOLUME(reagents, reagent)]" dat += "Purge
" dat += "Refresh Close" diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index f7de6783e2bb..f1b754a8920e 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -179,9 +179,8 @@ for(var/obj/used_item in get_contained_external_atoms()) data["cooking_items"][used_item.name]++ data["cooking_reagents"] = list() - for(var/material_type in reagents.reagent_volumes) - var/decl/material/mat = GET_DECL(material_type) - data["cooking_reagents"][mat.name] = reagents.reagent_volumes[material_type] + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + data["cooking_reagents"][reagent.name] = reagents.reagent_volumes[reagent] data["on"] = !!operating data["broken"] = broken > 0 data["dirty"] = dirty >= 100 @@ -366,23 +365,22 @@ to_chat(user, SPAN_NOTICE("You remove [thing] from [src].")) SSnano.update_uis(src) -/obj/machinery/microwave/proc/eject_reagent(var/mob/user, var/material_type) - if(!reagents.reagent_volumes[material_type]) +/obj/machinery/microwave/proc/eject_reagent(var/mob/user, var/decl/material/reagent) + if(!reagents.reagent_volumes[reagent]) SSnano.update_uis(src) return // should not happen, must be a UI glitch or href hacking var/obj/item/chems/held_container = user.get_active_held_item() - var/decl/material/M = GET_DECL(material_type) if(istype(held_container)) - var/amount_to_move = min(REAGENTS_FREE_SPACE(held_container.reagents), REAGENT_VOLUME(reagents, material_type)) + var/amount_to_move = min(REAGENTS_FREE_SPACE(held_container.reagents), REAGENT_VOLUME(reagents, reagent)) if(amount_to_move <= 0) to_chat(user, SPAN_WARNING("[held_container] is full!")) return - to_chat(user, SPAN_NOTICE("You empty [amount_to_move] units of [M.name] into [held_container].")) - reagents.trans_type_to(held_container, material_type, amount_to_move) + to_chat(user, SPAN_NOTICE("You empty [amount_to_move] units of [reagent.name] into [held_container].")) + reagents.trans_type_to(held_container, reagent, amount_to_move) else - to_chat(user, SPAN_NOTICE("You try to dump out the [M.name], but it gets all over [src] because you have nothing to put it in.")) + to_chat(user, SPAN_NOTICE("You try to dump out the [reagent.name], but it gets all over [src] because you have nothing to put it in.")) dirty++ - reagents.clear_reagent(material_type) + reagents.clear_reagent(reagent) SSnano.update_uis(src) /obj/machinery/microwave/on_update_icon() @@ -433,11 +431,9 @@ return TOPIC_REFRESH if ("ejectreagent") - var/decl/material/mat - for(var/material_type in reagents.reagent_volumes) - mat = GET_DECL(material_type) - if(mat.name == href_list["target"]) - eject_reagent(user, material_type) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(reagent.name == href_list["target"]) + eject_reagent(user, reagent) break return TOPIC_REFRESH diff --git a/code/game/objects/_obj_edibility.dm b/code/game/objects/_objs_edibility.dm similarity index 98% rename from code/game/objects/_obj_edibility.dm rename to code/game/objects/_objs_edibility.dm index b95791a80684..65fc62ced6a4 100644 --- a/code/game/objects/_obj_edibility.dm +++ b/code/game/objects/_objs_edibility.dm @@ -156,7 +156,7 @@ show_feed_message_end(user, target, consumption_method) if(consumption_method == EATING_METHOD_DRINK && target?.has_personal_goal(/datum/goal/achievement/specific_object/drink)) - for(var/reagent in reagents.reagent_volumes) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) target.update_personal_goal(/datum/goal/achievement/specific_object/drink, reagent) handle_consumed(user, target, consumption_method) diff --git a/code/game/objects/effects/chem/foam.dm b/code/game/objects/effects/chem/foam.dm index d6773a58c0d0..06a1a7d81f79 100644 --- a/code/game/objects/effects/chem/foam.dm +++ b/code/game/objects/effects/chem/foam.dm @@ -59,7 +59,7 @@ if(!metal) F.create_reagents(10) if(reagents) - for(var/reagent in reagents.reagent_volumes) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) F.add_to_reagents(reagent, 1, safety = 1) //added safety check since reagents in the foam have already had a chance to react /obj/effect/effect/foam/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) // foam disolves when heated, except metal foams @@ -93,7 +93,7 @@ // bit of a hack here. Foam carries along any reagent also present in the glass it is mixed with (defaults to water if none is present). Rather than actually transfer the reagents, this makes a list of the reagent ids and spawns 1 unit of that reagent when the foam disolves. if(carry && !metal) - for(var/reagent in carry.reagent_volumes) + for(var/decl/material/reagent as anything in carry.reagent_volumes) carried_reagents += reagent /datum/effect/effect/system/foam_spread/start() diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 818bacab2a3c..8a62f95af5cf 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -1210,10 +1210,9 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. var/decl/material/bait_mat = GET_DECL(mat) if(bait_mat.fishing_bait_value) . += MATERIAL_UNITS_TO_REAGENTS_UNITS(matter[mat]) * bait_mat.fishing_bait_value * BAIT_VALUE_CONSTANT - for(var/mat in reagents?.reagent_volumes) - var/decl/material/bait_mat = GET_DECL(mat) - if(bait_mat.fishing_bait_value) - . += reagents.reagent_volumes[mat] * bait_mat.fishing_bait_value * BAIT_VALUE_CONSTANT + for(var/decl/material/reagent as anything in reagents?.reagent_volumes) + if(reagent.fishing_bait_value) + . += reagents.reagent_volumes[reagent] * reagent.fishing_bait_value * BAIT_VALUE_CONSTANT #undef BAIT_VALUE_CONSTANT /obj/item/proc/get_storage_cost() @@ -1292,8 +1291,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. if(!reagents_state || !check_state_in_icon(reagents_state, icon)) return var/image/reagent_overlay = overlay_image(icon, reagents_state, reagents.get_color(), RESET_COLOR | RESET_ALPHA) - for(var/reagent_type in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(reagent_type) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) if(!reagent.reagent_overlay) continue var/modified_reagent_overlay = state_prefix ? "[state_prefix]_[reagent.reagent_overlay]" : reagent.reagent_overlay diff --git a/code/game/objects/items/contraband.dm b/code/game/objects/items/contraband.dm index 601f8a9f3e83..8b62f298f8f7 100644 --- a/code/game/objects/items/contraband.dm +++ b/code/game/objects/items/contraband.dm @@ -48,12 +48,10 @@ add_to_reagents(reagent, picked_reagents[reagent]) var/list/names = new - for(var/liquid_type in reagents.liquid_volumes) - var/decl/material/liquid = GET_DECL(liquid_type) - names += liquid.get_reagent_name(reagents, MAT_PHASE_LIQUID) + for(var/decl/material/reagent as anything in reagents.liquid_volumes) + names += reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID) - for(var/solid_type in reagents.solid_volumes) - var/decl/material/solid = GET_DECL(solid_type) - names += solid.get_reagent_name(reagents, MAT_PHASE_SOLID) + for(var/decl/material/reagent as anything in reagents.solid_volumes) + names += reagent.get_reagent_name(reagents, MAT_PHASE_SOLID) desc = "Contains [english_list(names)]." \ No newline at end of file diff --git a/code/game/objects/items/stacks/medical/medical_bandage.dm b/code/game/objects/items/stacks/medical/medical_bandage.dm index 23d81504abf9..5a5727b290bd 100644 --- a/code/game/objects/items/stacks/medical/medical_bandage.dm +++ b/code/game/objects/items/stacks/medical/medical_bandage.dm @@ -25,9 +25,8 @@ /obj/item/stack/medical/bandage/proc/get_poultice_requirement_string() . = list() - for(var/reagent in poultice_reagent_requirements) - var/decl/material/reagent_decl = GET_DECL(reagent) - . += "[poultice_reagent_requirements[reagent]] unit\s of [reagent_decl.liquid_name]" + for(var/decl/material/reagent as anything in poultice_reagent_requirements) + . += "[poultice_reagent_requirements[reagent.type]] unit\s of [reagent.liquid_name]" . = english_list(.) /obj/item/stack/medical/bandage/get_examine_strings(mob/user, distance, infix, suffix) diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 15e634163ec3..2776a6d679c8 100644 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -66,10 +66,9 @@ return w_class = (reagents?.total_volume > 0)? ITEM_SIZE_SMALL : ITEM_SIZE_TINY //#TODO: Maybe acids should handle eating their own containers themselves? - for(var/reagent in reagents?.reagent_volumes) - var/decl/material/M = GET_DECL(reagent) - if(M.solvent_power >= MAT_SOLVENT_STRONG) - visible_message(SPAN_DANGER("\The [M] chews through \the [src]!")) + for(var/decl/material/reagent as anything in reagents?.reagent_volumes) + if(reagent.solvent_power >= MAT_SOLVENT_STRONG) + visible_message(SPAN_DANGER("\The [reagent] chews through \the [src]!")) physically_destroyed() /obj/item/chems/water_balloon/throw_impact(atom/hit_atom, datum/thrownthing/TT) diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index f234b0b6b641..b71582135b02 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -35,8 +35,8 @@ return add_autopsy_data(S) - for(var/decl/material/dose in decls_repository.get_decls_unassociated(M.chem_doses)) - chemtraces |= dose.use_name + for(var/decl/material/reagent as anything in M._chem_doses) + chemtraces |= reagent.use_name else if(istype(A, /obj/item/organ/external)) set_target(A, user) diff --git a/code/game/objects/structures/compost.dm b/code/game/objects/structures/compost.dm index a8149da99c96..e8f3c18ec831 100644 --- a/code/game/objects/structures/compost.dm +++ b/code/game/objects/structures/compost.dm @@ -174,15 +174,14 @@ var/global/const/COMPOST_WORM_HUNGER_FACTOR = MINIMUM_CHEMICAL_VOLUME remains.update_primary_material() // Digest reagents. - for(var/mat in reagents.reagent_volumes) - if(ispath(mat, /decl/material/liquid/fertilizer)) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(istype(reagent, /decl/material/liquid/fertilizer)) continue - var/decl/material/material_data = GET_DECL(mat) - if(!material_data.compost_value) + if(!reagent.compost_value) continue - var/clamped_worm_drink_amount = min(round(worm_eat_amount * REAGENT_UNITS_PER_MATERIAL_UNIT), reagents.reagent_volumes[mat]) - reagents.add_reagent(/decl/material/liquid/fertilizer/compost, max(1, round(clamped_worm_drink_amount * material_data.compost_value))) - reagents.remove_reagent(mat, clamped_worm_drink_amount) + var/clamped_worm_drink_amount = min(round(worm_eat_amount * REAGENT_UNITS_PER_MATERIAL_UNIT), reagents.reagent_volumes[reagent]) + reagents.add_reagent(/decl/material/liquid/fertilizer/compost, max(1, round(clamped_worm_drink_amount * reagent.compost_value))) + reagents.remove_reagent(reagent, clamped_worm_drink_amount) break // Grow more worms. diff --git a/code/game/objects/structures/fires.dm b/code/game/objects/structures/fires.dm index 4e6c92a6daaa..6f4821ea174c 100644 --- a/code/game/objects/structures/fires.dm +++ b/code/game/objects/structures/fires.dm @@ -366,13 +366,12 @@ var/do_steam = FALSE var/list/waste = list() - for(var/rtype in reagents?.reagent_volumes) + for(var/decl/material/reagent as anything in reagents?.reagent_volumes) - var/decl/material/reagent = GET_DECL(rtype) if(reagent.accelerant_value <= FUEL_VALUE_SUPPRESSANT && !isnull(reagent.boiling_point) && reagent.boiling_point < get_effective_burn_temperature()) do_steam = TRUE - var/volume = NONUNIT_CEILING(REAGENT_VOLUME(reagents, rtype) / REAGENT_UNITS_PER_GAS_MOLE, 0.1) + var/volume = NONUNIT_CEILING(REAGENT_VOLUME(reagents, reagent) / REAGENT_UNITS_PER_GAS_MOLE, 0.1) var/list/waste_products = burn_material(reagent, volume) if(!isnull(waste_products)) for(var/product in waste_products) diff --git a/code/game/turfs/turf_fluids.dm b/code/game/turfs/turf_fluids.dm index f0dd37d11c1a..b7b1f4fe95e7 100644 --- a/code/game/turfs/turf_fluids.dm +++ b/code/game/turfs/turf_fluids.dm @@ -166,13 +166,12 @@ if(!length(reagents?.reagent_volumes) || !istype(air)) return var/update_air = FALSE - for(var/rtype in reagents.reagent_volumes) - var/decl/material/mat = GET_DECL(rtype) - if(mat.gas_flags & XGM_GAS_FUEL) - var/moles = round(reagents.reagent_volumes[rtype] / REAGENT_UNITS_PER_GAS_MOLE) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(reagent.gas_flags & XGM_GAS_FUEL) + var/moles = round(reagents.reagent_volumes[reagent] / REAGENT_UNITS_PER_GAS_MOLE) if(moles > 0) - air.adjust_gas(rtype, moles, FALSE) - remove_from_reagents(rtype, round(moles * REAGENT_UNITS_PER_GAS_MOLE)) + air.adjust_gas(reagent.type, moles, FALSE) + remove_from_reagents(reagent, round(moles * REAGENT_UNITS_PER_GAS_MOLE)) update_air = TRUE if(update_air) air.update_values() @@ -190,7 +189,7 @@ if(reagents?.total_volume > FLUID_QDEL_POINT) ADD_ACTIVE_FLUID(src) var/decl/material/primary_reagent = reagents.get_primary_reagent_decl() - if(primary_reagent && (REAGENT_VOLUME(reagents, primary_reagent.type) >= primary_reagent.slippery_amount)) + if(primary_reagent && (REAGENT_VOLUME(reagents, primary_reagent) >= primary_reagent.slippery_amount)) last_slipperiness = primary_reagent.slipperiness else last_slipperiness = 0 @@ -217,10 +216,10 @@ solids = reagents if(LAZYLEN(solids?.solid_volumes)) var/list/matter_list = list() - for(var/reagent_type in solids.solid_volumes) - var/reagent_amount = solids.solid_volumes[reagent_type] - matter_list[reagent_type] = round(reagent_amount/REAGENT_UNITS_PER_MATERIAL_UNIT) - solids.remove_reagent(reagent_type, reagent_amount, defer_update = TRUE, removed_phases = MAT_PHASE_SOLID) + for(var/decl/material/reagent as anything in solids.solid_volumes) + var/reagent_amount = solids.solid_volumes[reagent] + matter_list[reagent] = round(reagent_amount/REAGENT_UNITS_PER_MATERIAL_UNIT) + solids.remove_reagent(reagent, reagent_amount, defer_update = TRUE, removed_phases = MAT_PHASE_SOLID) var/obj/item/debris/scraps/chemical/scraps = locate() in contents if(!istype(scraps) || scraps.get_total_matter() >= MAX_SCRAP_MATTER) diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index 62062d712350..f46dd0447280 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -198,15 +198,15 @@ // Magical chemical filtration system, do not question it. var/total_transferred = 0 - for(var/rtype in input_item.reagents.reagent_volumes) + for(var/decl/material/reagent as anything in input_item.reagents.reagent_volumes) for(var/chargetype in charges) var/datum/rig_charge/charge = charges[chargetype] - if(charge.product_type == rtype) - var/chems_to_transfer = REAGENT_VOLUME(input_item.reagents, rtype) + if(charge.product_type == reagent.type) + var/chems_to_transfer = REAGENT_VOLUME(input_item.reagents, reagent) if((charge.charges + chems_to_transfer) > max_reagent_volume) chems_to_transfer = max_reagent_volume - charge.charges charge.charges += chems_to_transfer - input_item.remove_from_reagents(rtype, chems_to_transfer) + input_item.remove_from_reagents(reagent, chems_to_transfer) total_transferred += chems_to_transfer break diff --git a/code/modules/crafting/pottery/pottery_moulds.dm b/code/modules/crafting/pottery/pottery_moulds.dm index c099b58d0dcc..6057a7a626a3 100644 --- a/code/modules/crafting/pottery/pottery_moulds.dm +++ b/code/modules/crafting/pottery/pottery_moulds.dm @@ -96,8 +96,7 @@ to_chat(user, SPAN_WARNING("\The [src] is not full yet!")) return TRUE - for(var/reagent_type in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(reagent_type) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) if(reagent.melting_point && temperature >= reagent.melting_point) to_chat(user, SPAN_WARNING("The contents of \the [src] are still molten! Wait for it to cool down.")) return TRUE @@ -116,11 +115,11 @@ product.dropInto(loc) reagents.remove_reagent(product_mat.type, REAGENT_VOLUME(reagents, product_mat.type)) - for(var/reagent_type in reagents.reagent_volumes) - if(reagent_type == product_mat.type) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(reagent.type == product_mat.type) continue LAZYINITLIST(product.matter) - product.matter[reagent_type] += max(1, round(reagents.reagent_volumes[reagent_type] / REAGENT_UNITS_PER_MATERIAL_UNIT)) + product.matter[reagent.type] += max(1, round(reagents.reagent_volumes[reagent] / REAGENT_UNITS_PER_MATERIAL_UNIT)) reagents.clear_reagents() if(length(product_metadata)) product.take_mould_metadata(product_metadata) diff --git a/code/modules/detectivework/tools/rag.dm b/code/modules/detectivework/tools/rag.dm index e286697b3ac4..60717340915e 100644 --- a/code/modules/detectivework/tools/rag.dm +++ b/code/modules/detectivework/tools/rag.dm @@ -185,9 +185,8 @@ var/total_volume = 0 if(reagents) total_volume += reagents.total_volume - for(var/rtype in reagents.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - total_fuel += REAGENT_VOLUME(reagents, rtype) * R.accelerant_value + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + total_fuel += REAGENT_VOLUME(reagents, reagent) * reagent.accelerant_value . = (total_fuel >= 2 && total_fuel >= total_volume*0.5) /obj/item/chems/rag/ignite_fire() diff --git a/code/modules/economy/_worth.dm b/code/modules/economy/_worth.dm index 6e79ca19b6a1..7e623d2907d0 100644 --- a/code/modules/economy/_worth.dm +++ b/code/modules/economy/_worth.dm @@ -10,9 +10,8 @@ /atom/proc/get_single_monetary_worth() . = get_base_value() * get_value_multiplier() if(reagents) - for(var/reagent_type in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(reagent_type) - . += reagent.get_value() * REAGENT_VOLUME(reagents, reagent_type) * REAGENT_WORTH_MULTIPLIER + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + . += reagent.get_value() * REAGENT_VOLUME(reagents, reagent) * REAGENT_WORTH_MULTIPLIER . = max(0, round(.)) /atom/proc/get_contents_monetary_worth() diff --git a/code/modules/fabrication/fabricator_intake.dm b/code/modules/fabrication/fabricator_intake.dm index ddd0afb010a0..482cddfea8ea 100644 --- a/code/modules/fabrication/fabricator_intake.dm +++ b/code/modules/fabrication/fabricator_intake.dm @@ -6,23 +6,23 @@ /obj/machinery/fabricator/proc/take_reagents(var/obj/item/thing, var/mob/user, var/destructive = FALSE) if(!thing.reagents || (!destructive && !ATOM_IS_OPEN_CONTAINER(thing))) return SUBSTANCE_TAKEN_NONE - for(var/R in thing.reagents.reagent_volumes) - if(!base_storage_capacity[R]) + for(var/decl/material/reagent as anything in thing.reagents.reagent_volumes) + if(!base_storage_capacity[reagent.type]) continue - var/taking_reagent = min(REAGENT_VOLUME(thing.reagents, R), floor((storage_capacity[R] - stored_material[R]) * REAGENT_UNITS_PER_MATERIAL_UNIT)) + var/taking_reagent = min(REAGENT_VOLUME(thing.reagents, reagent), floor((storage_capacity[reagent.type] - stored_material[reagent.type]) * REAGENT_UNITS_PER_MATERIAL_UNIT)) if(taking_reagent <= 0) continue var/reagent_matter = round(taking_reagent / REAGENT_UNITS_PER_MATERIAL_UNIT) if(reagent_matter <= 0) continue - thing.remove_from_reagents(R, taking_reagent) - stored_material[R] += reagent_matter + thing.remove_from_reagents(reagent, taking_reagent) + stored_material[reagent.type] += reagent_matter // If we're destroying this, take everything. if(destructive) . = SUBSTANCE_TAKEN_ALL continue // Otherwise take the first applicable and useful reagent. - if(stored_material[R] == storage_capacity[R]) + if(stored_material[reagent.type] == storage_capacity[reagent.type]) return SUBSTANCE_TAKEN_FULL else if(thing.reagents.total_volume > 0) return SUBSTANCE_TAKEN_SOME diff --git a/code/modules/food/cooking/_recipe.dm b/code/modules/food/cooking/_recipe.dm index 1cbafb646903..aaba7b53fca2 100644 --- a/code/modules/food/cooking/_recipe.dm +++ b/code/modules/food/cooking/_recipe.dm @@ -121,11 +121,11 @@ var/global/list/_cooking_recipe_cache = list() return TRUE /decl/recipe/proc/check_reagents(datum/reagents/avail_reagents) - SHOULD_BE_PURE(TRUE) + // SHOULD_BE_PURE(TRUE) Due to use of GET_DECL() in REAGENT_VOLUME, this cannot be pure. if(length(avail_reagents?.reagent_volumes) < length(reagents)) return FALSE - for(var/rtype in reagents) - if(REAGENT_VOLUME(avail_reagents, rtype) < reagents[rtype]) + for(var/reagent in reagents) + if(REAGENT_VOLUME(avail_reagents, reagent) < reagents[reagent]) return FALSE return TRUE @@ -351,27 +351,27 @@ var/global/list/_cooking_recipe_cache = list() if(REAGENT_MAX) //We want the highest of each. //Iterate through everything in buffer. If the target has less than the buffer, then top it up - for (var/reagent_type in buffer.reagent_volumes) - var/rvol = REAGENT_VOLUME(holder, reagent_type) - var/bvol = REAGENT_VOLUME(buffer, reagent_type) + for (var/decl/material/reagent as anything in buffer.reagent_volumes) + var/rvol = REAGENT_VOLUME(holder, reagent) + var/bvol = REAGENT_VOLUME(buffer, reagent) if (rvol < bvol) //Transfer the difference - buffer.trans_type_to_holder(holder, reagent_type, bvol-rvol) + buffer.trans_type_to_holder(holder, reagent, bvol-rvol) if(REAGENT_MIN) //Min is slightly more complex. We want the result to have the lowest from each side //But zero will not count. Where a side has zero its ignored and the side with a nonzero value is used - for (var/reagent_type in buffer.reagent_volumes) - var/rvol = REAGENT_VOLUME(holder, reagent_type) - var/bvol = REAGENT_VOLUME(buffer, reagent_type) + for (var/decl/material/reagent as anything in buffer.reagent_volumes) + var/rvol = REAGENT_VOLUME(holder, reagent) + var/bvol = REAGENT_VOLUME(buffer, reagent) if (rvol == 0) //If the target has zero of this reagent - buffer.trans_type_to_holder(holder, reagent_type, bvol) + buffer.trans_type_to_holder(holder, reagent, bvol) //Then transfer all of ours else if (rvol > bvol) //if the target has more than ours //Remove the difference - holder.remove_reagent(reagent_type, rvol-bvol) + holder.remove_reagent(reagent, rvol-bvol) if(length(.) > 1) // If we're here, then holder is a buffer containing the total reagents diff --git a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm index 189106c5b238..12dfbf6378a3 100644 --- a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm +++ b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm @@ -74,18 +74,15 @@ . += "\the [thing]" if(reagents?.total_volume) - for(var/solid_type in reagents.solid_volumes) - var/decl/material/reagent = GET_DECL(solid_type) - var/reagent_name = reagent.get_reagent_name(reagents, MAT_PHASE_SOLID) - . += "[reagents.solid_volumes[solid_type]]u of [reagent_name]" + for(var/decl/material/reagent as anything in reagents.solid_volumes) + . += "[reagents.solid_volumes[reagent]]u of [reagent.get_reagent_name(reagents, MAT_PHASE_SOLID)]" - for(var/liquid_type in reagents.liquid_volumes) - var/decl/material/reagent = GET_DECL(liquid_type) + for(var/decl/material/reagent as anything in reagents.liquid_volumes) var/reagent_name = reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID) if(!isnull(reagent.boiling_point) && temperature >= reagent.boiling_point && reagent.soup_hot_desc) - . += "[reagents.liquid_volumes[liquid_type]]u of [reagent.soup_hot_desc] [reagent_name]" + . += "[reagents.liquid_volumes[reagent]]u of [reagent.soup_hot_desc] [reagent_name]" else - . += "[reagents.liquid_volumes[liquid_type]]u of [reagent_name]" + . += "[reagents.liquid_volumes[reagent]]u of [reagent_name]" /obj/item/chems/cooking_vessel/get_examine_strings(mob/user, distance, infix, suffix) . = ..() diff --git a/code/modules/food/cooking/cooking_vessels/pot.dm b/code/modules/food/cooking/cooking_vessels/pot.dm index b463944f3ed4..a2c943db0f9d 100644 --- a/code/modules/food/cooking/cooking_vessels/pot.dm +++ b/code/modules/food/cooking/cooking_vessels/pot.dm @@ -32,8 +32,7 @@ last_boil_temp = temperature var/next_boil_status = FALSE - for(var/reagent_type in reagents?.reagent_volumes) - var/decl/material/reagent = GET_DECL(reagent_type) + for(var/decl/material/reagent as anything in reagents?.reagent_volumes) if(!isnull(reagent.boiling_point) && temperature >= reagent.boiling_point) next_boil_status = TRUE break diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 9da7ffda83e3..f2f7ea3ca9e8 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -138,19 +138,18 @@ var/list/descriptors = list() - for(var/rtype in reagents.reagent_volumes) - var/decl/material/chem = GET_DECL(rtype) - if(chem.fruit_descriptor) - descriptors |= chem.fruit_descriptor - if(chem.reflectiveness >= MAT_VALUE_SHINY) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(reagent.fruit_descriptor) + descriptors |= reagent.fruit_descriptor + if(reagent.reflectiveness >= MAT_VALUE_SHINY) descriptors |= "shiny" - if(chem.slipperiness >= 10) + if(reagent.slipperiness >= 10) descriptors |= "slippery" - if(chem.toxicity >= 3) + if(reagent.toxicity >= 3) descriptors |= "poisonous" - if(chem.radioactivity) + if(reagent.radioactivity) descriptors |= "radioactive" - if(chem.solvent_power >= MAT_SOLVENT_STRONG) + if(reagent.solvent_power >= MAT_SOLVENT_STRONG) descriptors |= "acidic" if(seed.get_trait(TRAIT_JUICY)) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 965c40430eda..a95e204e4e81 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -236,37 +236,37 @@ reagents.trans_to_obj(temp_chem_holder, min(reagents.total_volume,rand(1,3))) - for(var/R in temp_chem_holder.reagents.reagent_volumes) + for(var/decl/material/reagent as anything in temp_chem_holder.reagents.reagent_volumes) - var/reagent_total = REAGENT_VOLUME(temp_chem_holder.reagents, R) + var/reagent_total = REAGENT_VOLUME(temp_chem_holder.reagents, reagent) if(seed && !dead) //Handle some general level adjustments. - if(toxic_reagents[R]) - toxins += toxic_reagents[R] * reagent_total - if(weedkiller_reagents[R]) - weedlevel += weedkiller_reagents[R] * reagent_total - if(pestkiller_reagents[R]) - pestlevel += pestkiller_reagents[R] * reagent_total + if(toxic_reagents[reagent.type]) + toxins += toxic_reagents[reagent.type] * reagent_total + if(weedkiller_reagents[reagent.type]) + weedlevel += weedkiller_reagents[reagent.type] * reagent_total + if(pestkiller_reagents[reagent.type]) + pestlevel += pestkiller_reagents[reagent.type] * reagent_total // Beneficial reagents have a few impacts along with health buffs. - if(beneficial_reagents[R]) - plant_health += beneficial_reagents[R][1] * reagent_total - yield_mod += beneficial_reagents[R][2] * reagent_total - mutation_mod += beneficial_reagents[R][3] * reagent_total + if(beneficial_reagents[reagent.type]) + plant_health += beneficial_reagents[reagent.type][1] * reagent_total + yield_mod += beneficial_reagents[reagent.type][2] * reagent_total + mutation_mod += beneficial_reagents[reagent.type][3] * reagent_total // Mutagen is distinct from the previous types and mostly has a chance of proccing a mutation. - if(mutagenic_reagents[R]) - mutation_level += reagent_total*mutagenic_reagents[R]+mutation_mod + if(mutagenic_reagents[reagent.type]) + mutation_level += reagent_total*mutagenic_reagents[reagent.type]+mutation_mod // Handle nutrient refilling. - if(nutrient_reagents[R]) - nutrilevel += nutrient_reagents[R] * reagent_total + if(nutrient_reagents[reagent.type]) + nutrilevel += nutrient_reagents[reagent.type] * reagent_total // Handle water and water refilling. var/water_added = 0 - if(water_reagents[R]) - var/water_input = water_reagents[R] * reagent_total + if(water_reagents[reagent.type]) + var/water_input = water_reagents[reagent.type] * reagent_total water_added += water_input waterlevel += water_input diff --git a/code/modules/integrated_electronics/subtypes/reagents.dm b/code/modules/integrated_electronics/subtypes/reagents.dm index 593941f651df..b29a7e1c21c3 100644 --- a/code/modules/integrated_electronics/subtypes/reagents.dm +++ b/code/modules/integrated_electronics/subtypes/reagents.dm @@ -417,8 +417,7 @@ switch(ord) if(1) var/cont[0] - for(var/rtype in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(rtype) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) cont += reagent.name set_pin_data(IC_OUTPUT, 3, cont) push_data() @@ -484,14 +483,13 @@ if(target.reagents.maximum_volume - target.reagents.total_volume <= 0) return - for(var/rtype in source.reagents.reagent_volumes) - var/decl/material/mat = GET_DECL(rtype) + for(var/decl/material/reagent as anything in source.reagents.reagent_volumes) if(!direction_mode) - if(mat.name in demand) - source.reagents.trans_type_to(target, rtype, transfer_amount) + if(reagent.name in demand) + source.reagents.trans_type_to(target, reagent, transfer_amount) else - if(!(mat.name in demand)) - source.reagents.trans_type_to(target, rtype, transfer_amount) + if(!(reagent.name in demand)) + source.reagents.trans_type_to(target, reagent, transfer_amount) activate_pin(2) push_data() diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index 1b8c388205a9..95bbc6c7d647 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -751,7 +751,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) if(solvent_power >= MAT_SOLVENT_STRONG && O.solvent_can_melt(solvent_power) && (istype(O, /obj/item) || istype(O, /obj/effect/vine)) && (amount > solvent_melt_dose)) O.visible_message(SPAN_DANGER("\The [O] dissolves!")) O.handle_melting() - holder?.remove_reagent(type, solvent_melt_dose) + holder?.remove_reagent(src, solvent_melt_dose) else if(defoliant && istype(O, /obj/effect/vine)) qdel(O) else @@ -775,7 +775,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) /decl/material/proc/touch_turf(var/turf/touching_turf, var/amount, var/datum/reagents/holder) // Cleaner cleaning, lube lubbing, etc, all go here - if(REAGENT_VOLUME(holder, type) < turf_touch_threshold) + if(REAGENT_VOLUME(holder, src) < turf_touch_threshold) return if(istype(touching_turf) && touching_turf.simulated) @@ -786,15 +786,15 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) if(slipperiness != 0 && !touching_turf.check_fluid_depth()) // Don't make floors slippery if they have an active fluid on top of them please. if(slipperiness < 0) touching_turf.unwet_floor(TRUE) - else if (REAGENT_VOLUME(holder, type) >= slippery_amount) + else if (REAGENT_VOLUME(holder, src) >= slippery_amount) touching_turf.wet_floor(slipperiness) if(length(vapor_products)) - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) var/temperature = holder?.my_atom?.temperature || T20C for(var/vapor in vapor_products) touching_turf.assume_gas(vapor, (volume * vapor_products[vapor]), temperature) - holder.remove_reagent(type, volume) + holder.remove_reagent(src, volume) /decl/material/proc/on_mob_life(var/mob/living/M, var/metabolism_class, var/datum/reagents/holder, var/list/life_dose_tracker) @@ -807,7 +807,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) // Keep track of dosage of chems across holders for overdosing purposes if(overdose && metabolism_class != CHEM_TOUCH && islist(life_dose_tracker)) - life_dose_tracker[src] += REAGENT_VOLUME(holder, type) + life_dose_tracker[src] += REAGENT_VOLUME(holder, src) //determine the metabolism rate var/removed @@ -829,8 +829,8 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) if(!(flags & IGNORE_MOB_SIZE)) effective *= (MOB_SIZE_MEDIUM/M.mob_size) if(metabolism_class != CHEM_TOUCH) - var/dose = LAZYACCESS(M.chem_doses, type) + effective - LAZYSET(M.chem_doses, type, dose) + var/dose = CHEM_DOSE(M, src) + effective + LAZYSET(M._chem_doses, src, dose) var/remove_dose = TRUE if(effective >= (metabolism * 0.1) || effective >= 0.1) // If there's too little chemical, don't affect the mob, just remove it @@ -844,7 +844,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) if(CHEM_INHALE) affect_inhale(M, effective, holder) if(remove_dose) - holder.remove_reagent(type, removed) + holder.remove_reagent(src, removed) /decl/material/proc/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) @@ -856,9 +856,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) if(antibiotic_strength) M.adjust_immunity(-0.1 * antibiotic_strength) M.add_chemical_effect(CE_ANTIBIOTIC, antibiotic_strength) - if(REAGENT_VOLUME(holder, type) > 10) + if(REAGENT_VOLUME(holder, src) > 10) M.adjust_immunity(-0.3 * antibiotic_strength) - if(LAZYACCESS(M.chem_doses, type) > 15) + if(CHEM_DOSE(M, src) > 15) M.adjust_immunity(-0.25 * antibiotic_strength) if(nutriment_factor || hydration_factor) @@ -943,7 +943,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) /decl/material/proc/apply_intolerances(mob/living/subject, removed, datum/reagents/holder, ingestion_method) - var/list/data = REAGENT_DATA(holder, type) + var/list/data = REAGENT_DATA(holder, src) var/check_flags = LAZYACCESS(data, DATA_INGREDIENT_FLAGS) | allergen_flags if(!check_flags) return 1 @@ -1025,7 +1025,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) victim.clean() if(solvent_power > MAT_SOLVENT_NONE && removed >= solvent_melt_dose && victim.solvent_act(min(removed * solvent_power * ((removed < solvent_melt_dose) ? 0.1 : 0.2), solvent_max_damage), solvent_melt_dose, solvent_power)) - holder.remove_reagent(type, REAGENT_VOLUME(holder, type)) + holder.remove_reagent(src, REAGENT_VOLUME(holder, src)) . = TRUE /decl/material/proc/affect_overdose(mob/living/victim, total_dose) // Overdose effect. Doesn't happen instantly. @@ -1040,7 +1040,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) /decl/material/proc/mix_data(var/datum/reagents/reagents, var/list/newdata, var/amount) reagents.cached_color = null // colour masking may change - . = REAGENT_DATA(reagents, type) + . = REAGENT_DATA(reagents, src) if(!length(newdata) || !islist(newdata)) return @@ -1052,7 +1052,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) // Sum our existing taste data with the incoming taste data. var/total_taste = 0 - var/new_fraction = amount / REAGENT_VOLUME(reagents, type) // the fraction of the total reagent volume that the new data is associated with + var/new_fraction = amount / REAGENT_VOLUME(reagents, src) // the fraction of the total reagent volume that the new data is associated with var/list/tastes = list() var/list/newtastes = LAZYACCESS(newdata, DATA_TASTE) for(var/taste in newtastes) @@ -1098,7 +1098,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) /decl/material/proc/get_presentation_name(var/obj/item/prop) if(islist(prop?.reagents?.reagent_data)) - . = LAZYACCESS(prop.reagents.reagent_data[type], DATA_MASK_NAME) + . = LAZYACCESS(prop.reagents.reagent_data[src], DATA_MASK_NAME) . ||= glass_name || liquid_name if(prop?.reagents?.total_volume) . = build_presentation_name_from_reagents(prop, .) @@ -1170,12 +1170,12 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) // If it's not ignitable but can be boiled, consider vaporizing it. if(!isnull(boiling_point) && burn_temperature >= boiling_point) - LAZYSET(., type, amount) + LAZYSET(., src, amount) /decl/material/proc/get_reagent_name(datum/reagents/holder, phase = MAT_PHASE_LIQUID) if(istype(holder) && holder.reagent_data) - var/list/rdata = holder.reagent_data[type] + var/list/rdata = holder.reagent_data[src] if(rdata) var/data_name = rdata[DATA_MASK_NAME] if(data_name) @@ -1200,7 +1200,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) /decl/material/proc/get_reagent_color(datum/reagents/holder) if(istype(holder) && holder.reagent_data) - var/list/rdata = holder.reagent_data[type] + var/list/rdata = holder.reagent_data[src] if(rdata) var/data_color = rdata[DATA_MASK_COLOR] if(data_color) @@ -1208,7 +1208,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) return color /decl/material/proc/get_reagent_overlay_color(datum/reagents/holder) - var/list/rdata = REAGENT_DATA(holder, type) + var/list/rdata = REAGENT_DATA(holder, src) return LAZYACCESS(rdata, DATA_EXTRA_COLOR) || get_reagent_color(holder) + num2hex(opacity * 255) /decl/material/proc/can_hold_sharpness() diff --git a/code/modules/materials/definitions/gasses/material_gas_mundane.dm b/code/modules/materials/definitions/gasses/material_gas_mundane.dm index 9ed5c8ded417..4d21232b7ff2 100644 --- a/code/modules/materials/definitions/gasses/material_gas_mundane.dm +++ b/code/modules/materials/definitions/gasses/material_gas_mundane.dm @@ -65,7 +65,7 @@ . = ..() var/warning_message var/warning_prob = 10 - var/dosage = LAZYACCESS(M.chem_doses, type) + var/dosage = CHEM_DOSE(M, src) var/mob/living/human/H = M if(dosage >= 3) warning_message = pick("extremely dizzy","short of breath","faint","confused") @@ -133,7 +133,7 @@ /decl/material/gas/nitrous_oxide/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() - var/dosage = LAZYACCESS(M.chem_doses, type) + var/dosage = CHEM_DOSE(M, src) if(dosage >= 1) if(prob(5)) SET_STATUS_MAX(M, STAT_ASLEEP, 3) SET_STATUS_MAX(M, STAT_DIZZY, 3) @@ -257,7 +257,7 @@ /decl/material/gas/xenon/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() - var/dosage = LAZYACCESS(M.chem_doses, type) + var/dosage = CHEM_DOSE(M, src) if(dosage >= 1) if(prob(5)) SET_STATUS_MAX(M, STAT_ASLEEP, 3) SET_STATUS_MAX(M, STAT_DIZZY, 3) diff --git a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm index ad32f11030a8..d28aeeb98edc 100644 --- a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm +++ b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm @@ -88,7 +88,7 @@ /decl/material/liquid/venom/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) if(M.has_trait(/decl/trait/metabolically_inert)) return - if(prob(REAGENT_VOLUME(holder, type)*2)) + if(prob(REAGENT_VOLUME(holder, src)*2)) SET_STATUS_MAX(M, STAT_CONFUSE, 3) ..() @@ -163,7 +163,7 @@ M.take_damage(3 * removed, OXY) SET_STATUS_MAX(M, STAT_WEAK, 10) SET_STATUS_MAX(M, STAT_SILENCE, 10) - if(LAZYACCESS(M.chem_doses, type) <= removed) //half-assed attempt to make timeofdeath update only at the onset + if(CHEM_DOSE(M, src) <= removed) //half-assed attempt to make timeofdeath update only at the onset M.timeofdeath = world.time M.add_chemical_effect(CE_NOPULSE, 1) @@ -243,7 +243,7 @@ /decl/material/liquid/hair_remover/affect_touch(var/mob/M, var/removed, var/datum/reagents/holder) . = ..() M.lose_hair() - holder.remove_reagent(type, REAGENT_VOLUME(holder, type)) + holder.remove_reagent(type, REAGENT_VOLUME(holder, src)) return TRUE /decl/material/liquid/zombie @@ -270,7 +270,7 @@ ..() if (ishuman(M)) var/mob/living/human/H = M - var/true_dose = LAZYACCESS(H.chem_doses, type) + REAGENT_VOLUME(holder, type) + var/true_dose = CHEM_DOSE(H, src) + REAGENT_VOLUME(holder, src) if (true_dose >= amount_to_zombify) H.zombify() else if (true_dose > 1 && prob(20)) diff --git a/code/modules/materials/definitions/liquids/materials_liquid_water.dm b/code/modules/materials/definitions/liquids/materials_liquid_water.dm index 099b762761fb..c02b25369e93 100644 --- a/code/modules/materials/definitions/liquids/materials_liquid_water.dm +++ b/code/modules/materials/definitions/liquids/materials_liquid_water.dm @@ -57,7 +57,7 @@ /decl/material/liquid/water/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) ..() if(ishuman(M)) - var/list/data = REAGENT_DATA(holder, type) + var/list/data = REAGENT_DATA(holder, src) if(data?["holy"]) affect_holy(M, removed, holder) @@ -89,14 +89,14 @@ touching_turf.assume_air(lowertemp) qdel(hotspot) - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) if (environment && environment.temperature > min_temperature) // Abstracted as steam or something var/removed_heat = clamp(volume * WATER_LATENT_HEAT, 0, -environment.get_thermal_energy_change(min_temperature)) environment.add_thermal_energy(-removed_heat) if (prob(5) && environment && environment.temperature > T100C) touching_turf.visible_message(SPAN_NOTICE("The water sizzles as it lands on \the [touching_turf]!")) - var/list/data = REAGENT_DATA(holder, type) + var/list/data = REAGENT_DATA(holder, src) if(LAZYACCESS(data, "holy")) touching_turf.turf_flags |= TURF_FLAG_HOLY diff --git a/code/modules/materials/definitions/solids/materials_solid_elements.dm b/code/modules/materials/definitions/solids/materials_solid_elements.dm index 9375b255330f..330c11ada5ab 100644 --- a/code/modules/materials/definitions/solids/materials_solid_elements.dm +++ b/code/modules/materials/definitions/solids/materials_solid_elements.dm @@ -45,9 +45,9 @@ var/datum/reagents/ingested = M.get_ingested_reagents() if(ingested && LAZYLEN(ingested.reagent_volumes) > 1) var/effect = 1 / (LAZYLEN(ingested.reagent_volumes) - 1) - for(var/R in ingested.reagent_volumes) - if(R != type) - ingested.remove_reagent(R, removed * effect) + for(var/decl/material/reagent as anything in ingested.reagent_volumes) + if(reagent.type != type) + ingested.remove_reagent(reagent, removed * effect) /decl/material/solid/carbon/ashes name = "ashes" @@ -109,7 +109,7 @@ /decl/material/solid/potassium/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) if(volume > 3) M.add_chemical_effect(CE_PULSE, 1) if(volume > 10) diff --git a/code/modules/materials/definitions/solids/materials_solid_mineral.dm b/code/modules/materials/definitions/solids/materials_solid_mineral.dm index 9b619de94902..805cff68e0ef 100644 --- a/code/modules/materials/definitions/solids/materials_solid_mineral.dm +++ b/code/modules/materials/definitions/solids/materials_solid_mineral.dm @@ -184,7 +184,7 @@ /decl/material/solid/potash/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) if(volume > 3) M.add_chemical_effect(CE_PULSE, 1) if(volume > 10) diff --git a/code/modules/mining/machinery/material_compressor.dm b/code/modules/mining/machinery/material_compressor.dm index a899178e234c..5814e0edc7a9 100644 --- a/code/modules/mining/machinery/material_compressor.dm +++ b/code/modules/mining/machinery/material_compressor.dm @@ -16,8 +16,8 @@ for(var/obj/item/O in input_turf) if(!O.simulated || O.anchored) continue - for(var/mat in O.reagents?.reagent_volumes) - stored[mat] = stored[mat] + floor((O.reagents.reagent_volumes[mat] / REAGENT_UNITS_PER_MATERIAL_UNIT) * 0.75) // liquid reagents, lossy + for(var/decl/material/reagent as anything in O.reagents?.reagent_volumes) + stored[reagent.type] = stored[reagent.type] + floor((O.reagents.reagent_volumes[reagent] / REAGENT_UNITS_PER_MATERIAL_UNIT) * 0.75) // liquid reagents, lossy for(var/mat in O.matter) stored[mat] = stored[mat] + O.matter[mat] qdel(O) diff --git a/code/modules/mining/machinery/material_extractor.dm b/code/modules/mining/machinery/material_extractor.dm index 39ca8096ae5e..809c4af4ac04 100644 --- a/code/modules/mining/machinery/material_extractor.dm +++ b/code/modules/mining/machinery/material_extractor.dm @@ -97,8 +97,8 @@ return var/adjusted_reagents = FALSE - for(var/mtype in reagents.reagent_volumes) - adjusted_reagents = max(adjusted_reagents, process_non_liquid(mtype)) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + adjusted_reagents = max(adjusted_reagents, process_non_liquid(reagent)) if(adjusted_reagents) if(gas_contents) @@ -108,7 +108,7 @@ /obj/machinery/material_processing/extractor/proc/process_non_liquid(var/mtype) var/adjusted_reagents = FALSE var/flashed_warning = FALSE - var/decl/material/mat = GET_DECL(mtype) + var/decl/material/mat = RESOLVE_TO_DECL(mtype) // TODO: Change this to ambient/tank pressure when phase changes are properly implemented. switch(mat.phase_at_temperature(temperature, ONE_ATMOSPHERE)) if(MAT_PHASE_GAS) @@ -239,14 +239,11 @@ data["reagents"] = list() var/index = 0 - for(var/mtype in reagents.reagent_volumes) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) index += 1 - var/decl/material/mat = GET_DECL(mtype) - // TODO: Must be revised once state changes are in. Reagent names might be a litle odd in the meantime. - var/is_liquid = mat.phase_at_temperature(temperature, ONE_ATMOSPHERE) == MAT_PHASE_LIQUID - - data["reagents"] += list(list("label" = "[mat.liquid_name] ([reagents.reagent_volumes[mtype]] U)", "index" = index, "liquid" = is_liquid)) + var/is_liquid = reagent.phase_at_temperature(temperature, ONE_ATMOSPHERE) == MAT_PHASE_LIQUID + data["reagents"] += list(list("label" = "[reagent.liquid_name] ([reagents.reagent_volumes[reagent]] U)", "index" = index, "liquid" = is_liquid)) data["full"] = reagents.total_volume >= max_liquid data["gas_pressure"] = gas_contents?.return_pressure() diff --git a/code/modules/mining/machinery/material_smelter.dm b/code/modules/mining/machinery/material_smelter.dm index 3d54d262330b..43cd4b1cf63a 100644 --- a/code/modules/mining/machinery/material_smelter.dm +++ b/code/modules/mining/machinery/material_smelter.dm @@ -30,8 +30,8 @@ if(!(. = ..()) || !reagents) return - for(var/mtype in reagents.reagent_volumes) - show_materials |= mtype + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + show_materials |= reagent.type /obj/machinery/material_processing/smeltery/ProcessAtomTemperature() if(use_power) diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm index ff482b50f311..14b7f96c82e2 100644 --- a/code/modules/mob/living/bot/medibot.dm +++ b/code/modules/mob/living/bot/medibot.dm @@ -310,8 +310,8 @@ // If they're injured, we're using a beaker, and they don't have on of the chems in the beaker if(reagent_glass && use_beaker && ((patient.get_damage(BRUTE) >= heal_threshold) || (patient.get_damage(TOX) >= heal_threshold) || (patient.get_damage(TOX) >= heal_threshold) || (patient.get_damage(OXY) >= (heal_threshold + 15)))) - for(var/R in reagent_glass.reagents.reagent_volumes) - if(!patient.reagents.has_reagent(R)) + for(var/decl/material/reagent as anything in reagent_glass.reagents.reagent_volumes) + if(!patient.reagents.has_reagent(reagent)) return 1 continue diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 0715ea9f3dd4..171ad74570a9 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -234,21 +234,20 @@ // Update chem dosage. // TODO: refactor chem dosage above isSynthetic() and GODMODE checks. - if(length(chem_doses)) - for(var/T in chem_doses) + if(length(_chem_doses)) + for(var/decl/material/reagent as anything in _chem_doses) var/still_processing_reagent = FALSE for(var/datum/reagents/holder as anything in metabolizing_holders) - if(holder.has_reagent(T)) + if(holder.has_reagent(reagent)) still_processing_reagent = TRUE break if(still_processing_reagent) continue - var/decl/material/R = GET_DECL(T) - var/dose = LAZYACCESS(chem_doses, T) - R.metabolism*2 - LAZYSET(chem_doses, T, dose) - if(LAZYACCESS(chem_doses, T) <= 0) - LAZYREMOVE(chem_doses, T) + var/dose = CHEM_DOSE(src, reagent) - reagent.metabolism*2 + LAZYSET(_chem_doses, reagent, dose) + if(CHEM_DOSE(src, reagent) <= 0) + LAZYREMOVE(_chem_doses, reagent) if(apply_chemical_effects()) update_health() diff --git a/code/modules/mob/living/living_blood.dm b/code/modules/mob/living/living_blood.dm index 7226b46c66c8..dffee4ed0dcc 100644 --- a/code/modules/mob/living/living_blood.dm +++ b/code/modules/mob/living/living_blood.dm @@ -18,10 +18,10 @@ data[DATA_BLOOD_SPECIES] = species_name var/list/temp_chem = list() - for(var/R in reagents?.reagent_volumes) - temp_chem[R] = REAGENT_VOLUME(reagents, R) + for(var/decl/material/reagent as anything in reagents?.reagent_volumes) + temp_chem[reagent.type] = REAGENT_VOLUME(reagents, reagent) data[DATA_BLOOD_TRACE_CHEM] = temp_chem - data[DATA_BLOOD_DOSE_CHEM] = chem_doses?.Copy() || list() + data[DATA_BLOOD_DOSE_CHEM] = _chem_doses?.Copy() || list() if(isSynthetic()) data[DATA_BLOOD_HAS_OXY] = FALSE diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index f7be925f7e9c..aadc7cf7edf0 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -46,7 +46,7 @@ var/jumping = FALSE var/list/chem_effects - var/list/chem_doses + var/list/_chem_doses var/last_pain_message var/next_pain_time = 0 diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 87196b4663d6..c10b44a3b122 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -245,9 +245,9 @@ /obj/item/organ/proc/handle_ailment(var/datum/ailment/ailment) if(ailment.treated_by_reagent_type) for(var/datum/reagents/source as anything in owner.get_metabolizing_reagent_holders()) - for(var/reagent_type in source.reagent_volumes) - if(ailment.treated_by_medication(reagent_type, source.reagent_volumes[reagent_type])) - ailment.was_treated_by_medication(source, reagent_type) + for(var/decl/material/reagent as anything in source.reagent_volumes) + if(ailment.treated_by_medication(reagent.type, source.reagent_volumes[reagent])) + ailment.was_treated_by_medication(source, reagent.type) return if(ailment.treated_by_chem_effect && owner.has_chemical_effect(ailment.treated_by_chem_effect, ailment.treated_by_chem_effect_strength)) ailment.was_treated_by_chem_effect() diff --git a/code/modules/power/fuel_assembly/fuel_compressor.dm b/code/modules/power/fuel_assembly/fuel_compressor.dm index ea91578156ca..d07651603a4a 100644 --- a/code/modules/power/fuel_assembly/fuel_compressor.dm +++ b/code/modules/power/fuel_assembly/fuel_compressor.dm @@ -121,10 +121,10 @@ /obj/machinery/fuel_compressor/proc/add_material(var/obj/item/thing, var/mob/user) if(istype(thing) && thing.reagents && thing.reagents.total_volume && ATOM_IS_OPEN_CONTAINER(thing)) - for(var/R in thing.reagents.reagent_volumes) - var/taking_reagent = REAGENT_VOLUME(thing.reagents, R) - thing.remove_from_reagents(R, taking_reagent) - stored_material[R] += taking_reagent + for(var/decl/material/reagent as anything in thing.reagents.reagent_volumes) + var/taking_reagent = REAGENT_VOLUME(thing.reagents, reagent) + thing.remove_from_reagents(reagent, taking_reagent) + stored_material[reagent.type] += taking_reagent to_chat(user, SPAN_NOTICE("You add the contents of \the [thing] to \the [src]'s material buffer.")) return TRUE diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index f826967278a5..9564d1220823 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -596,9 +596,8 @@ if(istype(used_item, /obj/item/chems/syringe) && used_item.reagents?.total_volume) var/obj/item/chems/syringe/S = used_item to_chat(user, "You inject the solution into \the [src].") - for(var/rtype in S.reagents?.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - if(R.accelerant_value > FUEL_VALUE_ACCELERANT) + for(var/decl/material/reagent as anything in S.reagents?.reagent_volumes) + if(reagent.accelerant_value > FUEL_VALUE_ACCELERANT) rigged = TRUE log_and_message_admins("injected a light with flammable reagents, rigging it to explode.", user) break diff --git a/code/modules/projectiles/guns/projectile/dartgun.dm b/code/modules/projectiles/guns/projectile/dartgun.dm index 4888de9e105b..b5a33cfa8745 100644 --- a/code/modules/projectiles/guns/projectile/dartgun.dm +++ b/code/modules/projectiles/guns/projectile/dartgun.dm @@ -58,12 +58,10 @@ . += SPAN_NOTICE("\The [src] contains:") for(var/obj/item/chems/glass/beaker/B in beakers) if(B.reagents && LAZYLEN(B.reagents?.reagent_volumes)) - for(var/ltype in B.reagents.liquid_volumes) - var/decl/material/R = GET_DECL(ltype) - . += SPAN_NOTICE("[LIQUID_VOLUME(B.reagents, ltype)] units of [R.get_reagent_name(B.reagents, MAT_PHASE_LIQUID)]") - for(var/stype in B.reagents.solid_volumes) - var/decl/material/R = GET_DECL(stype) - . += SPAN_NOTICE("[SOLID_VOLUME(B.reagents, stype)] units of [R.get_reagent_name(B.reagents, MAT_PHASE_SOLID)]") + for(var/decl/material/reagent as anything in B.reagents.liquid_volumes) + . += SPAN_NOTICE("[LIQUID_VOLUME(B.reagents, reagent)] units of [reagent.get_reagent_name(B.reagents, MAT_PHASE_LIQUID)]") + for(var/decl/material/reagent as anything in B.reagents.solid_volumes) + . += SPAN_NOTICE("[SOLID_VOLUME(B.reagents, reagent)] units of [reagent.get_reagent_name(B.reagents, MAT_PHASE_SOLID)]") /obj/item/gun/projectile/dartgun/attackby(obj/item/used_item, mob/user) if(istype(used_item, /obj/item/chems/glass)) @@ -112,9 +110,8 @@ dat += "Beaker [i] contains: " if(B.reagents && LAZYLEN(B.reagents.reagent_volumes)) - for(var/rtype in B.reagents.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - dat += "
[REAGENT_VOLUME(B.reagents, rtype)] units of [R.get_reagent_name(B.reagents)], " + for(var/decl/material/reagent as anything in B.reagents.reagent_volumes) + dat += "
[REAGENT_VOLUME(B.reagents, reagent)] unit\s of [reagent.get_reagent_name(B.reagents)], " if(B in mixing) dat += "Mixing " else diff --git a/code/modules/reagents/Chemistry-Colours.dm b/code/modules/reagents/Chemistry-Colours.dm index 8a8da512b0a4..16d5d8ad9d62 100644 --- a/code/modules/reagents/Chemistry-Colours.dm +++ b/code/modules/reagents/Chemistry-Colours.dm @@ -3,17 +3,16 @@ if(!LAZYLEN(reagent_volumes)) cached_color = "#ffffffff" else if(LAZYLEN(reagent_volumes) == 1) // It's pretty common and saves a lot of work - var/decl/material/R = GET_DECL(reagent_volumes[1]) - cached_color = R.get_reagent_color(src) + num2hex(R.opacity * 255) + var/decl/material/reagent = reagent_volumes[1] + cached_color = reagent.get_reagent_color(src) + num2hex(reagent.opacity * 255) else var/list/colors = list(0, 0, 0, 0) var/tot_w = 0 - for(var/rtype in reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - if(R.color_weight <= 0) + for(var/decl/material/reagent as anything in reagent_volumes) + if(reagent.color_weight <= 0) continue - var/hex = uppertext(R.get_reagent_color(src)) + num2hex(R.opacity * 255) - var/mod = REAGENT_VOLUME(src, rtype) * R.color_weight + var/hex = uppertext(reagent.get_reagent_color(src)) + num2hex(reagent.opacity * 255) + var/mod = REAGENT_VOLUME(src, reagent) * reagent.color_weight colors[1] += HEX_RED(hex) * mod colors[2] += HEX_GREEN(hex) * mod colors[3] += HEX_BLUE(hex) * mod diff --git a/code/modules/reagents/Chemistry-Grinder.dm b/code/modules/reagents/Chemistry-Grinder.dm index e0f84a5350a6..40611e701161 100644 --- a/code/modules/reagents/Chemistry-Grinder.dm +++ b/code/modules/reagents/Chemistry-Grinder.dm @@ -133,9 +133,8 @@ data["beakercontents"] = list() if(beaker?.reagents) - for(var/rtype in beaker.reagents.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - data["beakercontents"] += "[capitalize(R.name)] ([REAGENT_VOLUME(beaker.reagents, rtype)]u)" + for(var/decl/material/reagent as anything in beaker.reagents.reagent_volumes) + data["beakercontents"] += "[capitalize(reagent.name)] ([REAGENT_VOLUME(beaker.reagents, reagent)]u)" ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 9c2063ed6cb3..20945f4c36da 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -1,11 +1,11 @@ var/global/obj/temp_reagents_holder = new var/global/datum/reagents/sink/infinite_reagent_sink = new -/atom/proc/add_to_reagents(reagent_type, amount, data, safety = FALSE, defer_update = FALSE, phase = null) - return reagents?.add_reagent(reagent_type, amount, data, safety, defer_update, phase) +/atom/proc/add_to_reagents(decl/material/reagent, amount, data, safety = FALSE, defer_update = FALSE, phase = null) + return reagents?.add_reagent(reagent, amount, data, safety, defer_update, phase) -/atom/proc/remove_from_reagents(reagent_type, amount, safety = FALSE, defer_update = FALSE) - return reagents?.remove_reagent(reagent_type, amount, safety, defer_update) +/atom/proc/remove_from_reagents(decl/material/reagent, amount, safety = FALSE, defer_update = FALSE) + return reagents?.remove_reagent(reagent, amount, safety, defer_update) /atom/proc/remove_any_reagents(amount = 1, defer_update = FALSE, removed_phases = (MAT_PHASE_LIQUID | MAT_PHASE_SOLID), skip_reagents = null) return reagents?.remove_any(amount, defer_update, removed_phases, skip_reagents) @@ -131,7 +131,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new return primary_reagent /datum/reagents/proc/get_primary_reagent_decl() - return GET_DECL(primary_reagent) + return RESOLVE_TO_DECL(primary_reagent) /datum/reagents/proc/update_total() // Updates volume. total_volume = 0 @@ -140,32 +140,32 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new reagent_volumes = list() primary_liquid = null - for(var/R in liquid_volumes) - var/vol = CHEMS_QUANTIZE(liquid_volumes[R]) + for(var/decl/material/reagent as anything in liquid_volumes) + var/vol = CHEMS_QUANTIZE(liquid_volumes[reagent]) if(vol < MINIMUM_CHEMICAL_VOLUME) - clear_reagent(R, defer_update = TRUE, force = TRUE) // defer_update is important to avoid infinite recursion + clear_reagent(reagent, defer_update = TRUE, force = TRUE) // defer_update is important to avoid infinite recursion else - LAZYSET(liquid_volumes, R, vol) - LAZYSET(reagent_volumes, R, vol) + LAZYSET(liquid_volumes, reagent, vol) + LAZYSET(reagent_volumes, reagent, vol) total_volume += vol total_liquid_volume += vol if(!primary_liquid || liquid_volumes[primary_liquid] < vol) - primary_liquid = R + primary_liquid = reagent primary_solid = null - for(var/R in solid_volumes) - var/vol = CHEMS_QUANTIZE(solid_volumes[R]) + for(var/decl/material/reagent as anything in solid_volumes) + var/vol = CHEMS_QUANTIZE(solid_volumes[reagent]) if(vol < MINIMUM_CHEMICAL_VOLUME) - clear_reagent(R, defer_update = TRUE, force = TRUE) + clear_reagent(reagent, defer_update = TRUE, force = TRUE) else - LAZYSET(solid_volumes, R, vol) - if(!reagent_volumes?[R]) - LAZYSET(reagent_volumes, R, vol) + LAZYSET(solid_volumes, reagent, vol) + if(!reagent_volumes?[reagent]) + LAZYSET(reagent_volumes, reagent, vol) else - reagent_volumes[R] += vol + reagent_volumes[reagent] += vol total_volume += vol if(!primary_solid || (solid_volumes[primary_solid] < vol)) - primary_solid = R + primary_solid = reagent if(solid_volumes?[primary_solid] > liquid_volumes?[primary_liquid]) primary_reagent = primary_solid @@ -190,8 +190,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new var/list/eligible_reactions = list() var/temperature = location?.temperature || T20C - for(var/thing in reagent_volumes) - var/decl/material/R = GET_DECL(thing) + for(var/decl/material/reagent as anything in reagent_volumes) // Check if the reagent is decaying or not. var/list/replace_self_with @@ -199,33 +198,32 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new var/replace_sound if(!(check_flags & ATOM_FLAG_NO_PHASE_CHANGE)) - if(!isnull(R.chilling_point) && LAZYLEN(R.chilling_products) && temperature <= R.chilling_point) - replace_self_with = R.chilling_products - if(R.chilling_message) - replace_message = "\The [R.get_reagent_name(src)] [R.chilling_message]" - replace_sound = R.chilling_sound - else if(!isnull(R.heating_point) && LAZYLEN(R.heating_products) && temperature >= R.heating_point) - replace_self_with = R.heating_products - if(R.heating_message) - replace_message = "\The [R.get_reagent_name(src)] [R.heating_message]" - replace_sound = R.heating_sound - - if(isnull(replace_self_with) && !isnull(R.dissolves_in) && !(check_flags & ATOM_FLAG_NO_DISSOLVE) && LAZYLEN(R.dissolves_into)) - for(var/other in reagent_volumes) - if(other == thing) + if(!isnull(reagent.chilling_point) && LAZYLEN(reagent.chilling_products) && temperature <= reagent.chilling_point) + replace_self_with = reagent.chilling_products + if(reagent.chilling_message) + replace_message = "\The [reagent.get_reagent_name(src)] [reagent.chilling_message]" + replace_sound = reagent.chilling_sound + else if(!isnull(reagent.heating_point) && LAZYLEN(reagent.heating_products) && temperature >= reagent.heating_point) + replace_self_with = reagent.heating_products + if(reagent.heating_message) + replace_message = "\The [reagent.get_reagent_name(src)] [reagent.heating_message]" + replace_sound = reagent.heating_sound + + if(isnull(replace_self_with) && !isnull(reagent.dissolves_in) && !(check_flags & ATOM_FLAG_NO_DISSOLVE) && LAZYLEN(reagent.dissolves_into)) + for(var/decl/material/solvent as anything in reagent_volumes) + if(solvent == reagent) continue - var/decl/material/solvent = GET_DECL(other) - if(solvent.solvent_power >= R.dissolves_in) - replace_self_with = R.dissolves_into - if(R.dissolve_message) - replace_message = "\The [R.get_reagent_name(src)] [R.dissolve_message] \the [solvent.get_reagent_name(src)]." - replace_sound = R.dissolve_sound + if(solvent.solvent_power >= reagent.dissolves_in) + replace_self_with = reagent.dissolves_into + if(reagent.dissolve_message) + replace_message = "\The [reagent.get_reagent_name(src)] [reagent.dissolve_message] \the [solvent.get_reagent_name(src)]." + replace_sound = reagent.dissolve_sound break // If it is, handle replacing it with the decay product. if(replace_self_with) - var/replace_amount = REAGENT_VOLUME(src, R.type) - clear_reagent(R.type) + var/replace_amount = REAGENT_VOLUME(src, reagent) + clear_reagent(reagent) for(var/product in replace_self_with) add_reagent(product, replace_self_with[product] * replace_amount) reaction_occurred = TRUE @@ -237,7 +235,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new playsound(location, replace_sound, 80, 1) else if(!(check_flags & ATOM_FLAG_NO_REACT)) // Otherwise, collect all possible reactions. - eligible_reactions |= SSmaterials.chemical_reactions_by_id[R.type] + eligible_reactions |= SSmaterials.chemical_reactions_by_id[reagent.type] if(!(check_flags & ATOM_FLAG_NO_REACT)) var/list/active_reactions = list() @@ -251,14 +249,14 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new // if two reactions share a reagent, each is allocated half of it, so we compute this here for(var/decl/chemical_reaction/reaction in active_reactions) var/list/adding = reaction.get_used_reagents() - for(var/R in adding) - LAZYADD(used_reagents[R], reaction) + for(var/reagent in adding) + LAZYADD(used_reagents[reagent], reaction) - for(var/R in used_reagents) - var/counter = length(used_reagents[R]) + for(var/reagent in used_reagents) + var/counter = length(used_reagents[reagent]) if(counter <= 1) continue // Only used by one reaction, so nothing we need to do. - for(var/decl/chemical_reaction/reaction in used_reagents[R]) + for(var/decl/chemical_reaction/reaction in used_reagents[reagent]) active_reactions[reaction] = max(counter, active_reactions[reaction]) counter-- //so the next reaction we execute uses more of the remaining reagents // Note: this is not guaranteed to maximize the size of the reactions we do (if one reaction is limited by reagent A, we may be over-allocating reagent B to it) @@ -296,19 +294,19 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new my_atom?.try_on_reagent_change() handle_update() -/datum/reagents/proc/add_reagent(var/reagent_type, var/amount, var/data = null, var/safety = 0, var/defer_update = FALSE, var/phase) +/datum/reagents/proc/add_reagent(var/decl/material/reagent, var/amount, var/data = null, var/safety = 0, var/defer_update = FALSE, var/phase) amount = CHEMS_QUANTIZE(min(amount, REAGENTS_FREE_SPACE(src))) if(amount <= 0) return FALSE - var/decl/material/newreagent = GET_DECL(reagent_type) - if(!istype(newreagent)) + reagent = RESOLVE_TO_DECL(reagent) + if(!istype(reagent)) return FALSE if(!phase) // By default, assume the reagent phase at STP. - phase = newreagent.phase_at_temperature() + phase = reagent.phase_at_temperature() // Assume it's in solution, somehow. if(phase == MAT_PHASE_GAS) phase = MAT_PHASE_LIQUID @@ -321,23 +319,23 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new LAZYINITLIST(solid_volumes) phase_volumes = solid_volumes - if(!phase_volumes[reagent_type]) - phase_volumes[reagent_type] = amount + if(!phase_volumes[reagent]) + phase_volumes[reagent] = amount else - phase_volumes[reagent_type] += amount + phase_volumes[reagent] += amount LAZYINITLIST(reagent_volumes) - if(!reagent_volumes[reagent_type]) - reagent_volumes[reagent_type] = amount - var/tmp_data = newreagent.initialize_data(data) + if(!reagent_volumes[reagent]) + reagent_volumes[reagent] = amount + var/tmp_data = reagent.initialize_data(data) if(tmp_data) - LAZYSET(reagent_data, reagent_type, tmp_data) + LAZYSET(reagent_data, reagent, tmp_data) if(reagent_volumes.len == 1) // if this is the first reagent, uncache color cached_color = null else - reagent_volumes[reagent_type] += amount + reagent_volumes[reagent] += amount if(!isnull(data)) - LAZYSET(reagent_data, reagent_type, newreagent.mix_data(src, data, amount)) + LAZYSET(reagent_data, reagent, reagent.mix_data(src, data, amount)) if(reagent_volumes.len > 1) // otherwise if we have a mix of reagents, uncache as well cached_color = null @@ -350,22 +348,26 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new handle_update(safety) return TRUE -/datum/reagents/proc/remove_reagent(var/reagent_type, var/amount, var/safety = 0, var/defer_update = FALSE, var/removed_phases = (MAT_PHASE_LIQUID | MAT_PHASE_SOLID)) +/datum/reagents/proc/remove_reagent(var/decl/material/reagent, var/amount, var/safety = 0, var/defer_update = FALSE, var/removed_phases = (MAT_PHASE_LIQUID | MAT_PHASE_SOLID)) amount = CHEMS_QUANTIZE(amount) - if(!isnum(amount) || amount <= 0 || REAGENT_VOLUME(src, reagent_type) <= 0) + if(!isnum(amount) || amount <= 0 || REAGENT_VOLUME(src, reagent) <= 0) + return FALSE + + reagent = RESOLVE_TO_DECL(reagent) + if(!istype(reagent)) return FALSE var/removed = 0 - if((removed_phases & MAT_PHASE_LIQUID) && LIQUID_VOLUME(src, reagent_type) > 0) + if((removed_phases & MAT_PHASE_LIQUID) && LIQUID_VOLUME(src, reagent) > 0) - removed += min(liquid_volumes[reagent_type], amount) - liquid_volumes[reagent_type] -= removed + removed += min(liquid_volumes[reagent], amount) + liquid_volumes[reagent] -= removed // If both liquid and solid reagents are being removed, we prioritize the liquid reagents. - if((removed < amount) && (removed_phases & MAT_PHASE_SOLID) && SOLID_VOLUME(src, reagent_type) > 0) + if((removed < amount) && (removed_phases & MAT_PHASE_SOLID) && SOLID_VOLUME(src, reagent) > 0) - var/solid_removed = min(solid_volumes[reagent_type], amount - removed) - solid_volumes[reagent_type] -= solid_removed + var/solid_removed = min(solid_volumes[reagent], amount - removed) + solid_volumes[reagent] -= solid_removed removed += solid_removed @@ -381,21 +383,26 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new handle_update(safety) return TRUE -/datum/reagents/proc/clear_reagent(var/reagent_type, var/defer_update = FALSE, var/force = FALSE) - . = force || !!REAGENT_DATA(src, reagent_type) || !!REAGENT_VOLUME(src, reagent_type) +/datum/reagents/proc/clear_reagent(var/decl/material/reagent, var/defer_update = FALSE, var/force = FALSE) + + reagent = RESOLVE_TO_DECL(reagent) + if(!istype(reagent)) + return FALSE + + . = force || !!REAGENT_DATA(src, reagent) || !!REAGENT_VOLUME(src, reagent) if(.) - var/amount = LAZYACCESS(reagent_volumes, reagent_type) - LAZYREMOVE(liquid_volumes, reagent_type) - LAZYREMOVE(solid_volumes, reagent_type) + var/amount = LAZYACCESS(reagent_volumes, reagent) + LAZYREMOVE(liquid_volumes, reagent) + LAZYREMOVE(solid_volumes, reagent) - LAZYREMOVE(reagent_volumes, reagent_type) - LAZYREMOVE(reagent_data, reagent_type) - if(primary_reagent == reagent_type) + LAZYREMOVE(reagent_volumes, reagent) + LAZYREMOVE(reagent_data, reagent) + if(primary_reagent == reagent) primary_reagent = null - if(primary_liquid == reagent_type) + if(primary_liquid == reagent) primary_liquid = null - if(primary_solid == reagent_type) + if(primary_solid == reagent) primary_solid = null cached_color = null @@ -404,15 +411,18 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new else handle_update() -/datum/reagents/proc/has_reagent(var/reagent_type, var/amount, var/phases) +/datum/reagents/proc/has_reagent(var/decl/material/reagent, var/amount, var/phases) . = 0 + reagent = RESOLVE_TO_DECL(reagent) + if(!istype(reagent)) + return if(phases) if(phases & MAT_PHASE_SOLID) - . += SOLID_VOLUME(src, reagent_type) + . += SOLID_VOLUME(src, reagent) if(phases & MAT_PHASE_LIQUID) - . += LIQUID_VOLUME(src, reagent_type) + . += LIQUID_VOLUME(src, reagent) else - . = REAGENT_VOLUME(src, reagent_type) + . = REAGENT_VOLUME(src, reagent) if(. && amount) . = (. >= amount) @@ -425,12 +435,12 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new /datum/reagents/proc/has_all_reagents(var/list/check_reagents, var/phases) . = TRUE for(var/check in check_reagents) - . = min(., has_reagent(check, check_reagents[check], phases)) + . = min(., has_reagent(RESOLVE_TO_DECL(check), check_reagents[check], phases)) if(!.) return /datum/reagents/proc/clear_reagents() - for(var/reagent in reagent_volumes) + for(var/decl/material/reagent as anything in reagent_volumes) clear_reagent(reagent, defer_update = TRUE) LAZYCLEARLIST(liquid_volumes) @@ -440,43 +450,39 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new total_volume = 0 my_atom?.try_on_reagent_change() -/datum/reagents/proc/get_overdose(var/decl/material/current) - if(current) - return initial(current.overdose) +/datum/reagents/proc/get_overdose(var/decl/material/reagent) + if(reagent) + return initial(reagent.overdose) return 0 /datum/reagents/proc/get_reagents(scannable_only = 0, precision) . = list() - for(var/rtype in liquid_volumes) - var/decl/material/current= GET_DECL(rtype) - if(scannable_only && !current.scannable) + for(var/decl/material/reagent as anything in liquid_volumes) + if(scannable_only && !reagent.scannable) continue - var/volume = REAGENT_VOLUME(src, rtype) + var/volume = REAGENT_VOLUME(src, reagent) if(precision) volume = round(volume, precision) if(volume) - . += "[current.get_reagent_name(src, MAT_PHASE_LIQUID)] ([volume])" - for(var/rtype in solid_volumes) - var/decl/material/current= GET_DECL(rtype) - if(scannable_only && !current.scannable) + . += "[reagent.get_reagent_name(src, MAT_PHASE_LIQUID)] ([volume])" + for(var/decl/material/reagent as anything in solid_volumes) + if(scannable_only && !reagent.scannable) continue - var/volume = REAGENT_VOLUME(src, rtype) + var/volume = REAGENT_VOLUME(src, reagent) if(precision) volume = round(volume, precision) if(volume) - . += "[current.get_reagent_name(src, MAT_PHASE_SOLID)] ([volume])" + . += "[reagent.get_reagent_name(src, MAT_PHASE_SOLID)] ([volume])" return english_list(., "EMPTY", "", ", ", ", ") /datum/reagents/proc/get_dirtiness() - for(var/rtype in reagent_volumes) - var/decl/material/current = GET_DECL(rtype) - . += current.dirtiness + for(var/decl/material/reagent as anything in reagent_volumes) + . += reagent.dirtiness return . / length(reagent_volumes) /datum/reagents/proc/get_accelerant_value() - for(var/rtype in reagent_volumes) - var/decl/material/current = GET_DECL(rtype) - . += current.accelerant_value + for(var/decl/material/reagent as anything in reagent_volumes) + . += reagent.accelerant_value return . / length(reagent_volumes) /* Holder-to-holder and similar procs */ @@ -530,14 +536,14 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new var/failed_remove = FALSE while(removing >= MINIMUM_CHEMICAL_VOLUME && total_volume >= MINIMUM_CHEMICAL_VOLUME && !failed_remove) failed_remove = TRUE - for(var/current in removing_volumes) - var/removing_amt = min(CHEMS_QUANTIZE(removing_volumes[current] * part), removing) + for(var/decl/material/reagent as anything in removing_volumes) + var/removing_amt = min(CHEMS_QUANTIZE(removing_volumes[reagent] * part), removing) if(removing_amt <= 0) continue failed_remove = FALSE removing -= removing_amt . += removing_amt - remove_reagent(current, removing_amt, TRUE, TRUE, removed_phases = removed_phases) + remove_reagent(reagent, removing_amt, TRUE, TRUE, removed_phases = removed_phases) if(!defer_update) handle_update() @@ -558,8 +564,8 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new var/part = amount if(skip_reagents) var/using_volume = total_volume - for(var/rtype in skip_reagents) - using_volume -= LAZYACCESS(reagent_volumes, rtype) + for(var/reagent in skip_reagents) + using_volume -= LAZYACCESS(reagent_volumes, reagent) if(using_volume <= 0) return 0 part /= using_volume @@ -572,28 +578,28 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new part /= using_volume . = 0 - for(var/rtype in reagent_volumes - skip_reagents) - var/amount_to_transfer = CHEMS_QUANTIZE(REAGENT_VOLUME(src, rtype) * part) + for(var/decl/material/reagent as anything in reagent_volumes - skip_reagents) + var/amount_to_transfer = CHEMS_QUANTIZE(REAGENT_VOLUME(src, reagent) * part) // Prioritize liquid transfers if(transferred_phases & MAT_PHASE_LIQUID) - var/liquid_transferred = min(amount_to_transfer, CHEMS_QUANTIZE(LIQUID_VOLUME(src, rtype))) - target.add_reagent(rtype, liquid_transferred * multiplier, REAGENT_DATA(src, rtype), TRUE, TRUE, MAT_PHASE_LIQUID) // We don't react until everything is in place + var/liquid_transferred = min(amount_to_transfer, CHEMS_QUANTIZE(LIQUID_VOLUME(src, reagent))) + target.add_reagent(reagent, liquid_transferred * multiplier, REAGENT_DATA(src, reagent), TRUE, TRUE, MAT_PHASE_LIQUID) // We don't react until everything is in place . += liquid_transferred amount_to_transfer -= liquid_transferred if(!copy) - remove_reagent(rtype, liquid_transferred, TRUE, TRUE, MAT_PHASE_LIQUID) + remove_reagent(reagent, liquid_transferred, TRUE, TRUE, MAT_PHASE_LIQUID) if(transferred_phases & MAT_PHASE_SOLID) - var/solid_transferred = (min(amount_to_transfer, CHEMS_QUANTIZE(SOLID_VOLUME(src, rtype)))) - target.add_reagent(rtype, solid_transferred * multiplier, REAGENT_DATA(src, rtype), TRUE, TRUE, MAT_PHASE_SOLID) // Ditto + var/solid_transferred = (min(amount_to_transfer, CHEMS_QUANTIZE(SOLID_VOLUME(src, reagent)))) + target.add_reagent(reagent, solid_transferred * multiplier, REAGENT_DATA(src, reagent), TRUE, TRUE, MAT_PHASE_SOLID) // Ditto . += solid_transferred amount_to_transfer -= solid_transferred if(!copy) - remove_reagent(rtype, solid_transferred, TRUE, TRUE, MAT_PHASE_SOLID) + remove_reagent(reagent, solid_transferred, TRUE, TRUE, MAT_PHASE_SOLID) // Due to rounding, we may have taken less than we wanted. @@ -681,14 +687,14 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new return//Nowhere to splash to, somehow //Create a temporary holder to hold all the amount that will be spread - var/datum/reagents/R = new /datum/reagents(total_volume * portion * multiplier, global.temp_reagents_holder) - trans_to_holder(R, total_volume * portion, multiplier, copy) + var/datum/reagents/reagent = new /datum/reagents(total_volume * portion * multiplier, global.temp_reagents_holder) + trans_to_holder(reagent, total_volume * portion, multiplier, copy) //The exact amount that will be given to each turf - var/turfportion = R.total_volume / turfs.len + var/turfportion = reagent.total_volume / turfs.len for (var/turf/T in turfs) - R.splash_turf(T, amount = turfportion, multiplier = 1, copy = FALSE) - qdel(R) + reagent.splash_turf(T, amount = turfportion, multiplier = 1, copy = FALSE) + qdel(reagent) //Spreads the contents of this reagent holder all over the target turf, dividing among things in it. //50% is divided between mobs, 20% between objects, and whatever's left on the turf itself @@ -810,18 +816,16 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new /datum/reagents/proc/touch_mob(mob/target) if(!target || !istype(target) || !target.simulated) return - for(var/rtype in reagent_volumes) - var/decl/material/current = GET_DECL(rtype) - current.touch_mob(target, REAGENT_VOLUME(src, rtype), src) + for(var/decl/material/reagent as anything in reagent_volumes) + reagent.touch_mob(target, REAGENT_VOLUME(src, reagent), src) /datum/reagents/proc/touch_turf(turf/touching_turf, touch_atoms = TRUE) if(!istype(touching_turf) || !touching_turf.simulated) return - for(var/rtype in reagent_volumes) - var/decl/material/current = GET_DECL(rtype) - current.touch_turf(touching_turf, REAGENT_VOLUME(src, rtype), src) + for(var/decl/material/reagent as anything in reagent_volumes) + reagent.touch_turf(touching_turf, REAGENT_VOLUME(src, reagent), src) var/dirtiness = get_dirtiness() if(dirtiness <= DIRTINESS_CLEAN) @@ -848,9 +852,8 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new /datum/reagents/proc/touch_obj(obj/target) if(!target || !istype(target) || !target.simulated) return - for(var/rtype in reagent_volumes) - var/decl/material/current = GET_DECL(rtype) - current.touch_obj(target, REAGENT_VOLUME(src, rtype), src) + for(var/decl/material/reagent as anything in reagent_volumes) + reagent.touch_obj(target, REAGENT_VOLUME(src, reagent), src) // Attempts to place a reagent on the mob's skin. // Reagents are not guaranteed to transfer to the target. @@ -868,25 +871,25 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new if(isliving(target)) var/mob/living/L = target if(type == CHEM_INJECT) - var/datum/reagents/R = L.get_injected_reagents() - if(R) - return trans_to_holder(R, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases) + var/datum/reagents/reagent = L.get_injected_reagents() + if(reagent) + return trans_to_holder(reagent, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases) if(type == CHEM_INGEST) - var/datum/reagents/R = L.get_ingested_reagents() - if(R) - return L.ingest(src, R, amount, multiplier, copy) //perhaps this is a bit of a hack, but currently there's no common proc for eating reagents + var/datum/reagents/reagent = L.get_ingested_reagents() + if(reagent) + return L.ingest(src, reagent, amount, multiplier, copy) //perhaps this is a bit of a hack, but currently there's no common proc for eating reagents if(type == CHEM_TOUCH) - var/datum/reagents/R = L.get_contact_reagents() - if(R) - return trans_to_holder(R, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases) + var/datum/reagents/reagent = L.get_contact_reagents() + if(reagent) + return trans_to_holder(reagent, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases) if(type == CHEM_INHALE) - var/datum/reagents/R = L.get_inhaled_reagents() - if(R) - return trans_to_holder(R, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases) - var/datum/reagents/R = new /datum/reagents(amount, global.temp_reagents_holder) - . = trans_to_holder(R, amount, multiplier, copy, TRUE, defer_update = defer_update, transferred_phases = transferred_phases) - R.touch_mob(target) - qdel(R) + var/datum/reagents/reagent = L.get_inhaled_reagents() + if(reagent) + return trans_to_holder(reagent, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases) + var/datum/reagents/reagent = new /datum/reagents(amount, global.temp_reagents_holder) + . = trans_to_holder(reagent, amount, multiplier, copy, TRUE, defer_update = defer_update, transferred_phases = transferred_phases) + reagent.touch_mob(target) + qdel(reagent) /datum/reagents/proc/trans_to_turf(var/turf/target, var/amount = 1, var/multiplier = 1, var/copy = 0, var/defer_update = FALSE, var/transferred_phases = (MAT_PHASE_LIQUID | MAT_PHASE_SOLID)) if(!target?.simulated) @@ -895,11 +898,11 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new // If we're only dumping solids, and there's not enough liquid present on the turf to make a slurry, we dump the solids directly. // This avoids creating an unnecessary reagent holder that won't be immediately deleted. if((!(transferred_phases & MAT_PHASE_LIQUID) || !total_liquid_volume) && (target.reagents?.total_liquid_volume < FLUID_SLURRY)) - var/datum/reagents/R = new /datum/reagents(amount, global.temp_reagents_holder) - . = trans_to_holder(R, amount, multiplier, copy, TRUE, defer_update = defer_update, transferred_phases = MAT_PHASE_SOLID) - R.touch_turf(target) - target.dump_solid_reagents(R) - qdel(R) + var/datum/reagents/reagent = new /datum/reagents(amount, global.temp_reagents_holder) + . = trans_to_holder(reagent, amount, multiplier, copy, TRUE, defer_update = defer_update, transferred_phases = MAT_PHASE_SOLID) + reagent.touch_turf(target) + target.dump_solid_reagents(reagent) + qdel(reagent) return if(!target.reagents) @@ -917,19 +920,18 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new return 0 if(!target.reagents) - var/datum/reagents/R = new /datum/reagents(amount * multiplier, global.temp_reagents_holder) - . = trans_to_holder(R, amount, multiplier, copy, TRUE, defer_update = defer_update, transferred_phases = transferred_phases) - R.touch_obj(target) - qdel(R) + var/datum/reagents/reagent = new /datum/reagents(amount * multiplier, global.temp_reagents_holder) + . = trans_to_holder(reagent, amount, multiplier, copy, TRUE, defer_update = defer_update, transferred_phases = transferred_phases) + reagent.touch_obj(target) + qdel(reagent) return return trans_to_holder(target.reagents, amount, multiplier, copy, defer_update = defer_update, transferred_phases = transferred_phases) /datum/reagents/proc/get_skimmable_reagents() - for(var/mat in reagent_volumes) - var/decl/material/reagent = GET_DECL(mat) + for(var/decl/material/reagent as anything in reagent_volumes) if(reagent.skimmable) - LAZYADD(., mat) + LAZYADD(., reagent) /// Used to return strings like "dilute blood" for use in phrases like "It's covered in dilute oily slimy bloody mud!" /// This is explicitly inspired by Caves of Qud, by the way. @@ -942,10 +944,9 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new var/list/volumes_temp = sortTim(reagent_volumes.Copy(), /proc/cmp_numeric_asc, associative = TRUE) var/list/accumulator = list() var/decl/material/primary_reagent_decl = get_primary_reagent_decl() // this also sets src.primary_reagent to the typepath - for(var/reagent_type in volumes_temp) - if(reagent_type == primary_reagent) + for(var/decl/material/reagent as anything in volumes_temp) + if(reagent == primary_reagent) continue // added later - var/decl/material/reagent = GET_DECL(reagent_type) reagent.build_coated_name(src, accumulator) if(length(accumulator) >= MAX_COATING_NAMES) break @@ -968,8 +969,7 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new // todo: maybe at some point we could make staining have some kind of priority to sort by? var/list/volumes_temp = sortTim(reagent_volumes.Copy(), /proc/cmp_numeric_asc, associative = TRUE) var/list/accumulator = list() - for(var/reagent_type in volumes_temp) - var/decl/material/reagent = GET_DECL(reagent_type) + for(var/decl/material/reagent in volumes_temp) var/coated_name = reagent.get_coated_adjective(src) accumulator |= coated_name if(length(accumulator) >= MAX_COATING_ADJECTIVES) @@ -990,12 +990,11 @@ var/global/datum/reagents/sink/infinite_reagent_sink = new /// Infinite reagent sink: nothing is ever actually added to it, useful for complex, filtered deletion of reagents without holder churn. /datum/reagents/sink -/datum/reagents/sink/add_reagent(reagent_type, amount, data, safety, defer_update, phase) +/datum/reagents/sink/add_reagent(var/decl/material/reagent, amount, data, safety, defer_update, phase) amount = CHEMS_QUANTIZE(min(amount, REAGENTS_FREE_SPACE(src))) if(amount <= 0) return FALSE - - var/decl/material/newreagent = GET_DECL(reagent_type) - if(!istype(newreagent)) + reagent = RESOLVE_TO_DECL(reagent) + if(!istype(reagent)) return FALSE return TRUE diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index d603217b54df..e2cf9e4abe10 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -223,8 +223,7 @@ /obj/machinery/chem_master/proc/fetch_contaminants(mob/user, datum/reagents/reagents, decl/material/main_reagent) . = list() - for(var/rtype in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(rtype) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) if(reagent != main_reagent && prob(user.skill_fail_chance(core_skill, 100))) . += reagent @@ -291,27 +290,25 @@ dat += "Beaker is empty." else dat += "Add to buffer:
" - for(var/rtype in R.reagent_volumes) - var/decl/material/G = GET_DECL(rtype) - dat += "[G.use_name], [REAGENT_VOLUME(R, rtype)] Units - " - dat += "(Analyze) " - dat += "(1) " - dat += "(5) " - dat += "(10) " - dat += "(All) " - dat += "(Custom)
" + for(var/decl/material/reagent as anything in R.reagent_volumes) + dat += "[reagent.use_name], [REAGENT_VOLUME(R, reagent)] Units - " + dat += "(Analyze) " + dat += "(1) " + dat += "(5) " + dat += "(10) " + dat += "(All) " + dat += "(Custom)
" dat += "
Transfer to [(!mode ? "disposal" : "beaker")]:
" if(reagents.total_volume) - for(var/rtype in reagents.reagent_volumes) - var/decl/material/N = GET_DECL(rtype) - dat += "[N.use_name], [REAGENT_VOLUME(reagents, rtype)] Units - " - dat += "(Analyze) " - dat += "(1) " - dat += "(5) " - dat += "(10) " - dat += "(All) " - dat += "(Custom)
" + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + dat += "[reagent.use_name], [REAGENT_VOLUME(reagents, reagent)] Units - " + dat += "(Analyze) " + dat += "(1) " + dat += "(5) " + dat += "(10) " + dat += "(All) " + dat += "(Custom)
" else dat += "Empty
" dat += extra_options() diff --git a/code/modules/reagents/Chemistry-Metabolism.dm b/code/modules/reagents/Chemistry-Metabolism.dm index 9c78f190ca2f..f15b50662785 100644 --- a/code/modules/reagents/Chemistry-Metabolism.dm +++ b/code/modules/reagents/Chemistry-Metabolism.dm @@ -2,11 +2,11 @@ var/metabolism_class //CHEM_TOUCH, CHEM_INGEST, or CHEM_INJECT var/mob/living/parent -/datum/reagents/metabolism/clear_reagent(var/reagent_type, var/defer_update = FALSE, var/force = FALSE) +/datum/reagents/metabolism/clear_reagent(var/decl/material/reagent, var/defer_update = FALSE, var/force = FALSE) // Duplicated check so that reagent data is accessible in on_leaving_metabolism. - if(force || !!(REAGENT_VOLUME(src, reagent_type) || REAGENT_DATA(src, reagent_type))) - var/decl/material/current = GET_DECL(reagent_type) - current.on_leaving_metabolism(src) + reagent = RESOLVE_TO_DECL(reagent) + if(force || !!(REAGENT_VOLUME(src, reagent) || REAGENT_DATA(src, reagent))) + reagent.on_leaving_metabolism(src) . = ..() /datum/reagents/metabolism/New(var/max = 100, mob/living/parent_mob, var/met_class) @@ -23,7 +23,6 @@ /datum/reagents/metabolism/proc/metabolize(list/dosage_tracker) if(!parent || total_volume < MINIMUM_CHEMICAL_VOLUME || !length(reagent_volumes)) return - for(var/rtype in reagent_volumes) - var/decl/material/current = GET_DECL(rtype) - current.on_mob_life(parent, metabolism_class, src, dosage_tracker) + for(var/decl/material/reagent as anything in reagent_volumes) + reagent.on_mob_life(parent, metabolism_class, src, dosage_tracker) update_total() diff --git a/code/modules/reagents/Chemistry-Taste.dm b/code/modules/reagents/Chemistry-Taste.dm index 73b25e51cd5c..959f790b398c 100644 --- a/code/modules/reagents/Chemistry-Taste.dm +++ b/code/modules/reagents/Chemistry-Taste.dm @@ -48,9 +48,8 @@ calculate text size per text. /datum/reagents/proc/get_taste_list(datum/reagents/source_holder) var/list/tastes = list() //descriptor = strength - for(var/reagent_type in reagent_volumes) - var/decl/material/reagent = GET_DECL(reagent_type) - var/list/nutriment_data = LAZYACCESS(reagent_data, reagent_type) + for(var/decl/material/reagent as anything in reagent_volumes) + var/list/nutriment_data = LAZYACCESS(reagent_data, reagent) var/list/taste_data = LAZYACCESS(nutriment_data, DATA_TASTE) if(length(taste_data)) for(var/taste in taste_data) diff --git a/code/modules/reagents/chems/chems_alcohol.dm b/code/modules/reagents/chems/chems_alcohol.dm index b218183a818c..8ac51f3bf450 100644 --- a/code/modules/reagents/chems/chems_alcohol.dm +++ b/code/modules/reagents/chems/chems_alcohol.dm @@ -53,7 +53,7 @@ M.add_chemical_effect(CE_ALCOHOL, 1) var/strength_mod = (M.GetTraitLevel(/decl/trait/malus/ethanol) * 2.5) || 1 - var/effective_dose = LAZYACCESS(M.chem_doses, type) * strength_mod * (1 + REAGENT_VOLUME(holder, type)/60) //drinking a LOT will make you go down faster + var/effective_dose = CHEM_DOSE(M, src) * strength_mod * (1 + REAGENT_VOLUME(holder, src)/60) //drinking a LOT will make you go down faster if(effective_dose >= strength) // Early warning ADJ_STATUS(M, STAT_DIZZY, 6) // It is decreased at the speed of 3 per tick if(effective_dose >= strength * 2) // Slurring @@ -471,7 +471,7 @@ if(M.has_trait(/decl/trait/metabolically_inert)) return - var/dose = LAZYACCESS(M.chem_doses, type) + var/dose = CHEM_DOSE(M, src) if(dose > 30) M.take_damage(2 * removed, TOX) if(dose > 60 && ishuman(M) && prob(5)) diff --git a/code/modules/reagents/chems/chems_blood.dm b/code/modules/reagents/chems/chems_blood.dm index 3af88ab10719..4642d9af3883 100644 --- a/code/modules/reagents/chems/chems_blood.dm +++ b/code/modules/reagents/chems/chems_blood.dm @@ -48,8 +48,8 @@ my_chems[chem] = my_chems[chem] + other_chems[chem] /decl/material/liquid/blood/touch_turf(var/turf/touching_turf, var/amount, var/datum/reagents/holder) - var/data = REAGENT_DATA(holder, type) - if(!istype(touching_turf) || REAGENT_VOLUME(holder, type) < 3) + var/data = REAGENT_DATA(holder, src) + if(!istype(touching_turf) || REAGENT_VOLUME(holder, src) < 3) return var/weakref/donor = LAZYACCESS(data, DATA_BLOOD_DONOR) blood_splatter(touching_turf, donor?.resolve() || holder.my_atom, 1) @@ -58,21 +58,21 @@ . = ..() if(M.has_trait(/decl/trait/metabolically_inert)) return - if(LAZYACCESS(M.chem_doses, type) > 5) + if(CHEM_DOSE(M, src) > 5) M.take_damage(removed, TOX) - if(LAZYACCESS(M.chem_doses, type) > 15) + if(CHEM_DOSE(M, src) > 15) M.take_damage(removed, TOX) /decl/material/liquid/blood/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) if(ishuman(M)) - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) var/mob/living/human/H = M H.inject_blood(volume, holder) holder.remove_reagent(type, volume) . = ..() /decl/material/liquid/blood/get_reagent_color(datum/reagents/holder) - var/list/blood_data = REAGENT_DATA(holder, type) + var/list/blood_data = REAGENT_DATA(holder, src) return blood_data?[DATA_BLOOD_COLOR] || ..() /decl/material/liquid/coagulated_blood diff --git a/code/modules/reagents/chems/chems_compounds.dm b/code/modules/reagents/chems/chems_compounds.dm index 154c6eb59ca4..bb54882996bf 100644 --- a/code/modules/reagents/chems/chems_compounds.dm +++ b/code/modules/reagents/chems/chems_compounds.dm @@ -140,7 +140,7 @@ if(M.has_trait(/decl/trait/metabolically_inert) || !M.can_feel_pain()) return - var/dose = LAZYACCESS(M.chem_doses, type) + var/dose = CHEM_DOSE(M, src) if(dose < agony_dose) if(prob(5) || dose == metabolism) //dose == metabolism is a very hacky way of forcing the message the first time this procs to_chat(M, discomfort_message) @@ -226,7 +226,7 @@ holder.remove_reagent(/decl/material/liquid/frostoil, 5) if(M.has_trait(/decl/trait/metabolically_inert) || !M.can_feel_pain()) return - if(LAZYACCESS(M.chem_doses, type) == metabolism) + if(CHEM_DOSE(M, src) == metabolism) to_chat(M, "You feel like your insides are burning!") else M.apply_effect(6, PAIN, 0) @@ -283,12 +283,12 @@ /decl/material/liquid/lactate/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) M.add_chemical_effect(CE_PULSE, 1) if(volume >= 10) M.add_chemical_effect(CE_PULSE, 1) M.add_chemical_effect(CE_SLOWDOWN, (volume/15) ** 2) - else if(LAZYACCESS(M.chem_doses, type) > 30) //after prolonged exertion + else if(CHEM_DOSE(M, src) > 30) //after prolonged exertion ADJ_STATUS(M, STAT_JITTER, 5) M.add_chemical_effect(CE_BREATHLOSS, 0.02 * volume) @@ -313,7 +313,7 @@ return if(H.regenerate_blood(4 * removed)) H.adjust_immunity(-0.1) - if(LAZYACCESS(H.chem_doses, type) > H.species.blood_volume/8) //half of blood was replaced with us, rip white bodies + if(CHEM_DOSE(H, src) > H.species.blood_volume/8) //half of blood was replaced with us, rip white bodies H.adjust_immunity(-0.5) /decl/material/solid/tobacco @@ -379,8 +379,10 @@ /decl/material/liquid/menthol/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() - if(world.time > REAGENT_DATA(holder, type) + 3 MINUTES) - LAZYSET(holder.reagent_data, type, world.time) + var/list/data = REAGENT_DATA(holder, src) + if(world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 3 MINUTES) + LAZYSET(data, DATA_COOLDOWN_TIME, world.time) + LAZYSET(holder.reagent_data, type, data) to_chat(M, SPAN_NOTICE("You feel faintly sore in the throat.")) /decl/material/liquid/nanitefluid diff --git a/code/modules/reagents/chems/chems_drinks.dm b/code/modules/reagents/chems/chems_drinks.dm index 899ecf64a652..b02703e26e11 100644 --- a/code/modules/reagents/chems/chems_drinks.dm +++ b/code/modules/reagents/chems/chems_drinks.dm @@ -369,7 +369,7 @@ if(M.has_trait(/decl/trait/metabolically_inert)) return - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) if(volume > 15) M.add_chemical_effect(CE_PULSE, 1) if(volume > 45) diff --git a/code/modules/reagents/chems/chems_drugs.dm b/code/modules/reagents/chems/chems_drugs.dm index e93452002971..c00540af2334 100644 --- a/code/modules/reagents/chems/chems_drugs.dm +++ b/code/modules/reagents/chems/chems_drugs.dm @@ -50,17 +50,24 @@ uid = "chem_nicotine" /decl/material/liquid/nicotine/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) . = ..() if(prob(volume*20)) M.add_chemical_effect(CE_PULSE, 1) - if(volume <= 0.02 && LAZYACCESS(M.chem_doses, type) >= 0.05 && world.time > REAGENT_DATA(holder, type) + 3 MINUTES) - LAZYSET(holder.reagent_data, type, world.time) + + var/update_data = FALSE + var/list/data = REAGENT_DATA(holder, src) + if(volume <= 0.02 && CHEM_DOSE(M, src) >= 0.05 && world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 3 MINUTES) + update_data = TRUE to_chat(M, "You feel antsy, your concentration wavers...") - else if(world.time > REAGENT_DATA(holder, type) + 3 MINUTES) - LAZYSET(holder.reagent_data, type, world.time) + else if(world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 3 MINUTES) + update_data = TRUE to_chat(M, "You feel invigorated and calm.") + if(update_data) + LAZYSET(data, DATA_COOLDOWN_TIME, world.time) + LAZYSET(holder.reagent_data, type, data) + /decl/material/liquid/nicotine/affect_overdose(mob/living/victim, total_dose) ..() victim.add_chemical_effect(CE_PULSE, 2) @@ -86,7 +93,7 @@ ADJ_STATUS(M, STAT_JITTER, -50) var/threshold = 1 - var/dose = LAZYACCESS(M.chem_doses, type) * sedative_strength + var/dose = CHEM_DOSE(M, src) * sedative_strength if(dose < 0.5 * threshold) if(dose == metabolism * 2 || prob(5)) M.emote(/decl/emote/audible/yawn) @@ -166,7 +173,7 @@ if(M.has_trait(/decl/trait/metabolically_inert)) return var/threshold = 1 - var/dose = LAZYACCESS(M.chem_doses, type) + var/dose = CHEM_DOSE(M, src) if(dose < 1 * threshold) M.apply_effect(3, STUTTER) ADJ_STATUS(M, STAT_DIZZY, 1) diff --git a/code/modules/reagents/chems/chems_medicines.dm b/code/modules/reagents/chems/chems_medicines.dm index 954942cd8781..02e3484df2c4 100644 --- a/code/modules/reagents/chems/chems_medicines.dm +++ b/code/modules/reagents/chems/chems_medicines.dm @@ -133,16 +133,14 @@ var/removing = (4 * removed * antitoxin_strength) var/datum/reagents/ingested = M.get_ingested_reagents() - for(var/R in ingested?.reagent_volumes) - var/decl/material/chem = GET_DECL(R) - if((remove_generic && chem.toxicity) || (R in remove_toxins)) - ingested.remove_reagent(R, removing) + for(var/decl/material/reagent as anything in ingested?.reagent_volumes) + if((remove_generic && reagent.toxicity) || (reagent.type in remove_toxins)) + ingested.remove_reagent(reagent, removing) return - for(var/R in M.reagents?.reagent_volumes) - var/decl/material/chem = GET_DECL(R) - if((remove_generic && chem.toxicity) || (R in remove_toxins)) - M.remove_from_reagents(R, removing) + for(var/decl/material/reagent as anything in M.reagents?.reagent_volumes) + if((remove_generic && reagent.toxicity) || (reagent.type in remove_toxins)) + M.remove_from_reagents(reagent, removing) return /decl/material/liquid/immunobooster @@ -159,7 +157,7 @@ /decl/material/liquid/immunobooster/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() - if(REAGENT_VOLUME(holder, type) >= REAGENTS_OVERDOSE) + if(REAGENT_VOLUME(holder, src) >= REAGENTS_OVERDOSE) return var/immunity_to_add = clamp((M.immunity_norm / 2) - M.get_immunity(), 0, removed) if(immunity_to_add > 0) @@ -183,20 +181,26 @@ allergen_flags = ALLERGEN_STIMULANT /decl/material/liquid/stimulants/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) . = ..() - if(volume <= 0.1 && LAZYACCESS(M.chem_doses, type) >= 0.5 && world.time > REAGENT_DATA(holder, type) + 5 MINUTES) - LAZYSET(holder.reagent_data, type, world.time) + var/update_data = FALSE + var/list/data = REAGENT_DATA(holder, src) + if(volume <= 0.1 && CHEM_DOSE(M, src) >= 0.5 && world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) + update_data = TRUE to_chat(M, "You lose focus...") else ADJ_STATUS(M, STAT_DROWSY, -5) ADJ_STATUS(M, STAT_PARA, -1) ADJ_STATUS(M, STAT_STUN, -1) ADJ_STATUS(M, STAT_WEAK, -1) - if(world.time > REAGENT_DATA(holder, type) + 5 MINUTES) - LAZYSET(holder.reagent_data, type, world.time) + if(world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) + update_data = TRUE to_chat(M, "Your mind feels focused and undivided.") + if(update_data) + LAZYSET(data, DATA_COOLDOWN_TIME, world.time) + LAZYSET(holder.reagent_data, type, data) + /decl/material/liquid/antidepressants name = "antidepressants" lore_text = "Stabilizes the mind a little." @@ -209,18 +213,25 @@ uid = "chem_antidepressants" /decl/material/liquid/antidepressants/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) - var/volume = REAGENT_VOLUME(holder, type) + var/volume = REAGENT_VOLUME(holder, src) . = ..() - if(volume <= 0.1 && LAZYACCESS(M.chem_doses, type) >= 0.5 && world.time > REAGENT_DATA(holder, type) + 5 MINUTES) - LAZYSET(holder.reagent_data, type, world.time) + + var/update_data = FALSE + var/list/data = REAGENT_DATA(holder, src) + if(volume <= 0.1 && CHEM_DOSE(M, src) >= 0.5 && world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) + update_data = TRUE to_chat(M, "Your mind feels a little less stable...") else M.add_chemical_effect(CE_MIND, 1) M.adjust_hallucination(-10) - if(world.time > REAGENT_DATA(holder, type) + 5 MINUTES) - LAZYSET(holder.reagent_data, type, world.time) + if(world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) + update_data = TRUE to_chat(M, "Your mind feels stable... a little stable.") + if(update_data) + LAZYSET(data, DATA_COOLDOWN_TIME, world.time) + LAZYSET(holder.reagent_data, type, data) + /decl/material/liquid/antibiotics name = "antibiotics" lore_text = "An all-purpose antibiotic agent." @@ -262,7 +273,7 @@ /decl/material/liquid/retrovirals/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() M.heal_damage(CLONE, 20 * removed) - if(LAZYACCESS(M.chem_doses, type) > 10) + if(CHEM_DOSE(M, src) > 10) ADJ_STATUS(M, STAT_DIZZY, 5) ADJ_STATUS(M, STAT_JITTER, 5) M.reset_genetic_conditions() @@ -279,8 +290,8 @@ uid = "chem_adrenaline" /decl/material/liquid/adrenaline/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) - var/volume = REAGENT_VOLUME(holder, type) - var/dose = LAZYACCESS(M.chem_doses, type) + var/volume = REAGENT_VOLUME(holder, src) + var/dose = CHEM_DOSE(M, src) . = ..() if(dose < 0.2) //not that effective after initial rush M.add_chemical_effect(CE_PAINKILLER, min(30*volume, 80)) @@ -378,9 +389,9 @@ /decl/material/liquid/clotting_agent/affect_blood(mob/living/M, removed, datum/reagents/holder) SET_STATUS_MAX(M, STAT_BLURRY, 30) - M.add_chemical_effect(CE_BLOCKAGE, (15 + REAGENT_VOLUME(holder, type))/100) + M.add_chemical_effect(CE_BLOCKAGE, (15 + REAGENT_VOLUME(holder, src))/100) for(var/obj/item/organ/external/limb in M.get_external_organs()) - if(!(limb.status & (ORGAN_ARTERY_CUT|ORGAN_BLEEDING)) || !prob(2 + REAGENT_VOLUME(holder, type))) + if(!(limb.status & (ORGAN_ARTERY_CUT|ORGAN_BLEEDING)) || !prob(2 + REAGENT_VOLUME(holder, src))) continue if(limb.status & ORGAN_ARTERY_CUT) limb.status &= ~ORGAN_ARTERY_CUT @@ -419,22 +430,22 @@ /decl/material/liquid/detoxifier/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() var/charges = removed * DETOXIFIER_EFFECTIVENESS - var/dosecharges = LAZYACCESS(M.chem_doses, type) * DETOXIFIER_DOSE_EFFECTIVENESS + var/dosecharges = CHEM_DOSE(M, src) * DETOXIFIER_DOSE_EFFECTIVENESS for(var/datum/reagents/container as anything in M.get_metabolizing_reagent_holders()) - for(var/reagent_type in container.reagent_volumes) - var/decl/material/liquid/painkillers/painkiller = GET_DECL(reagent_type) + for(var/decl/material/reagent as anything in container.reagent_volumes) + var/decl/material/liquid/painkillers/painkiller = reagent if(!istype(painkiller) || !painkiller.narcotic) continue - var/amount = min(charges, REAGENT_VOLUME(container, reagent_type)) + var/amount = min(charges, REAGENT_VOLUME(container, reagent)) if(amount) charges -= amount - container.remove_reagent(reagent_type, amount) - var/dose_amount = min(dosecharges, LAZYACCESS(M.chem_doses, reagent_type)) + container.remove_reagent(reagent, amount) + var/dose_amount = min(dosecharges, CHEM_DOSE(M, reagent)) if(dose_amount) - var/dose = LAZYACCESS(M.chem_doses, reagent_type) - dose_amount - LAZYSET(M.chem_doses, reagent_type, dose) - if(M.chem_doses[reagent_type] <= 0) - LAZYREMOVE(M.chem_doses, reagent_type) + var/dose = CHEM_DOSE(M, reagent) - dose_amount + LAZYSET(M._chem_doses, reagent, dose) + if(CHEM_DOSE(M, reagent) <= 0) + LAZYREMOVE(M._chem_doses, reagent) dosecharges -= dose_amount if(charges <= 0 && dosecharges <= 0) break diff --git a/code/modules/reagents/chems/chems_painkillers.dm b/code/modules/reagents/chems/chems_painkillers.dm index 8ab62f4048fa..9a976f06e2de 100644 --- a/code/modules/reagents/chems/chems_painkillers.dm +++ b/code/modules/reagents/chems/chems_painkillers.dm @@ -43,8 +43,8 @@ narcotic = TRUE /decl/material/liquid/painkillers/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) - var/volume = REAGENT_VOLUME(holder, type) - var/dose = LAZYACCESS(M.chem_doses, type) + var/volume = REAGENT_VOLUME(holder, src) + var/dose = CHEM_DOSE(M, src) . = ..() var/effectiveness = 1 if(dose < effective_dose) //some ease-in ease-out for the effect @@ -131,9 +131,9 @@ var/datum/reagents/ingested = M.get_ingested_reagents() if(ingested) var/list/pool = M.reagents.reagent_volumes | ingested.reagent_volumes - for(var/rtype in pool) - var/decl/material/liquid/alcohol/booze = GET_DECL(rtype) - if(!istype(booze) ||LAZYACCESS(M.chem_doses, rtype) < 2) //let them experience false security at first + for(var/reagent in pool) + var/decl/material/liquid/alcohol/booze = reagent + if(!istype(booze) ||CHEM_DOSE(M, reagent) < 2) //let them experience false security at first continue . = 1 if(booze.strength < 40) //liquor stuff hits harder diff --git a/code/modules/reagents/chems/chems_pigments.dm b/code/modules/reagents/chems/chems_pigments.dm index 55c6be4c47cb..5d23dc4e5230 100644 --- a/code/modules/reagents/chems/chems_pigments.dm +++ b/code/modules/reagents/chems/chems_pigments.dm @@ -108,7 +108,7 @@ exoplanet_rarity_gas = MAT_RARITY_NOWHERE /decl/material/liquid/paint/proc/apply_paint(var/atom/painting, var/datum/reagents/holder, var/threshold = 1) - if(istype(painting) && istype(holder) && REAGENT_VOLUME(holder, type) >= threshold) + if(istype(painting) && istype(holder) && REAGENT_VOLUME(holder, src) >= threshold) var/keep_alpha = painting.alpha painting.set_color(holder.get_color()) painting.set_alpha(keep_alpha) diff --git a/code/modules/reagents/chems/chems_poisons.dm b/code/modules/reagents/chems/chems_poisons.dm index b08e4b4197bb..09bf18e6d357 100644 --- a/code/modules/reagents/chems/chems_poisons.dm +++ b/code/modules/reagents/chems/chems_poisons.dm @@ -11,7 +11,7 @@ /decl/material/liquid/paralytics/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) var/threshold = 2 - var/dose = LAZYACCESS(M.chem_doses, type) + var/dose = CHEM_DOSE(M, src) . = ..() if(dose >= metabolism * threshold * 0.5) SET_STATUS_MAX(M, STAT_CONFUSE, 2) diff --git a/code/modules/reagents/chems/random/chems_random.dm b/code/modules/reagents/chems/random/chems_random.dm index 2f67984c0097..a38b74bc572c 100644 --- a/code/modules/reagents/chems/random/chems_random.dm +++ b/code/modules/reagents/chems/random/chems_random.dm @@ -69,7 +69,7 @@ var/global/list/random_chem_interaction_blacklist = list( /decl/material/liquid/random/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() FOR_ALL_EFFECTS - var/data = REAGENT_DATA(holder, type) + var/data = REAGENT_DATA(holder, src) effect.affect_blood(M, removed, LAZYACCESS(data, effect.type)) /decl/material/liquid/random/proc/on_chemicals_analyze(mob/user) diff --git a/code/modules/reagents/dispenser/dispenser2.dm b/code/modules/reagents/dispenser/dispenser2.dm index 0b3c8f7e0d56..2c6882d9e60f 100644 --- a/code/modules/reagents/dispenser/dispenser2.dm +++ b/code/modules/reagents/dispenser/dispenser2.dm @@ -147,9 +147,8 @@ data["glass"] = accept_drinking var beakerD[0] if(LAZYLEN(container?.reagents?.reagent_volumes)) - for(var/rtype in container.reagents.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - beakerD[++beakerD.len] = list("name" = R.use_name, "volume" = REAGENT_VOLUME(container.reagents, rtype)) + for(var/decl/material/reagent as anything in container.reagents.reagent_volumes) + beakerD[++beakerD.len] = list("name" = reagent.use_name, "volume" = REAGENT_VOLUME(container.reagents, reagent)) data["beakerContents"] = beakerD if(container) // Container has had null reagents in the past; may be due to qdel without clearing reference. diff --git a/code/modules/reagents/reactions/reaction_synthesis.dm b/code/modules/reagents/reactions/reaction_synthesis.dm index 79695861328a..fcbe27b4dfb5 100644 --- a/code/modules/reagents/reactions/reaction_synthesis.dm +++ b/code/modules/reagents/reactions/reaction_synthesis.dm @@ -40,22 +40,22 @@ . = ..() && length(holder.reagent_volumes) > 1 if(.) . = FALSE - for(var/rtype in holder.reagent_volumes) - if(rtype != /decl/material/liquid/crystal_agent && REAGENT_VOLUME(holder, rtype) >= REAGENT_UNITS_PER_MATERIAL_SHEET) + for(var/decl/material/reagent as anything in holder.reagent_volumes) + if(reagent.type != /decl/material/liquid/crystal_agent && REAGENT_VOLUME(holder, reagent) >= REAGENT_UNITS_PER_MATERIAL_SHEET) return TRUE /decl/chemical_reaction/synthesis/crystalization/on_reaction(datum/reagents/holder, created_volume, list/reaction_data) var/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) var/list/removing_reagents = list() - for(var/rtype in holder.reagent_volumes) - if(rtype != /decl/material/liquid/crystal_agent) - var/solidifying = floor(REAGENT_VOLUME(holder, rtype) / REAGENT_UNITS_PER_MATERIAL_SHEET) + for(var/decl/material/reagent as anything in holder.reagent_volumes) + if(reagent.type != /decl/material/liquid/crystal_agent) + var/solidifying = floor(REAGENT_VOLUME(holder, reagent) / REAGENT_UNITS_PER_MATERIAL_SHEET) if(solidifying) - SSmaterials.create_object(rtype, location, solidifying, /obj/item/stack/material/cubes) - removing_reagents[rtype] = solidifying * REAGENT_UNITS_PER_MATERIAL_SHEET - for(var/rtype in removing_reagents) - holder.remove_reagent(rtype, removing_reagents[rtype]) + SSmaterials.create_object(reagent.type, location, solidifying, /obj/item/stack/material/cubes) + removing_reagents[reagent] = solidifying * REAGENT_UNITS_PER_MATERIAL_SHEET + for(var/reagent in removing_reagents) + holder.remove_reagent(reagent, removing_reagents[reagent]) // Turns gas into a "solid" form for use in PACMAN etc. /decl/chemical_reaction/synthesis/aerogel @@ -70,11 +70,10 @@ . = ..() && length(holder.reagent_volumes) > 1 if(.) . = FALSE - for(var/rtype in holder.reagent_volumes) - if(REAGENT_VOLUME(holder, rtype) < REAGENT_UNITS_PER_MATERIAL_SHEET) + for(var/decl/material/reagent as anything in holder.reagent_volumes) + if(REAGENT_VOLUME(holder, reagent) < REAGENT_UNITS_PER_MATERIAL_SHEET) continue - var/decl/material/mat = GET_DECL(rtype) - if(!mat || mat.default_solid_form != /obj/item/stack/material/aerogel) + if(reagent.default_solid_form != /obj/item/stack/material/aerogel) continue return TRUE @@ -82,15 +81,14 @@ var/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) var/list/removing_reagents = list() - for(var/rtype in holder.reagent_volumes) - var/decl/material/mat = GET_DECL(rtype) - if(mat.default_solid_form == /obj/item/stack/material/aerogel) - var/solidifying = floor(REAGENT_VOLUME(holder, rtype) / REAGENT_UNITS_PER_MATERIAL_SHEET) + for(var/decl/material/reagent as anything in holder.reagent_volumes) + if(reagent.default_solid_form == /obj/item/stack/material/aerogel) + var/solidifying = floor(REAGENT_VOLUME(holder, reagent) / REAGENT_UNITS_PER_MATERIAL_SHEET) if(solidifying) - SSmaterials.create_object(rtype, location, solidifying) - removing_reagents[rtype] = solidifying * REAGENT_UNITS_PER_MATERIAL_SHEET - for(var/rtype in removing_reagents) - holder.remove_reagent(rtype, removing_reagents[rtype]) + SSmaterials.create_object(reagent.type, location, solidifying) + removing_reagents[reagent] = solidifying * REAGENT_UNITS_PER_MATERIAL_SHEET + for(var/reagent in removing_reagents) + holder.remove_reagent(reagent, removing_reagents[reagent]) /decl/chemical_reaction/synthesis/plastication name = "Plastic" diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 7b669a97daea..27af9a279d6c 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -176,11 +176,10 @@ // Vaporize anything over its boiling point. var/update_reagents = FALSE - for(var/reagent in reagents.reagent_volumes) - var/decl/material/mat = GET_DECL(reagent) - if(mat.can_boil_to_gas && !isnull(mat.boiling_point) && temperature >= mat.boiling_point) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(reagent.can_boil_to_gas && !isnull(reagent.boiling_point) && temperature >= reagent.boiling_point) // TODO: reduce atom temperature? - var/removing = min(mat.boil_evaporation_per_run, reagents.reagent_volumes[reagent]) + var/removing = min(reagent.boil_evaporation_per_run, reagents.reagent_volumes[reagent]) reagents.remove_reagent(reagent, removing, defer_update = TRUE, removed_phases = MAT_PHASE_LIQUID) update_reagents = TRUE loc.take_vaporized_reagent(reagent, removing) diff --git a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm index 8eb7a37a87ad..4937cbe44298 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/drinkingglass.dm @@ -56,14 +56,13 @@ var/global/const/DRINK_ICON_NOISY = "noise" /obj/item/chems/drinks/glass2/proc/has_fizz() if(LAZYLEN(reagents.reagent_volumes)) - var/decl/material/primary = reagents.get_primary_reagent_decl() - if(("fizz" in primary.glass_special)) + var/decl/material/primary_reagent = reagents.get_primary_reagent_decl() + if(("fizz" in primary_reagent.glass_special)) return 1 var/totalfizzy = 0 - for(var/rtype in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(rtype) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) if("fizz" in reagent.glass_special) - totalfizzy += REAGENT_VOLUME(reagents, rtype) + totalfizzy += REAGENT_VOLUME(reagents, reagent) if(totalfizzy >= reagents.total_volume / 5) // 20% fizzy by volume return 1 return 0 @@ -72,13 +71,12 @@ var/global/const/DRINK_ICON_NOISY = "noise" if(LAZYLEN(reagents.reagent_volumes) > 0) if(temperature > T0C + 40) return 1 - var/decl/material/primary = reagents.get_primary_reagent_decl() - if(!("vapor" in primary.glass_special)) + var/decl/material/primary_reagent = reagents.get_primary_reagent_decl() + if(!("vapor" in primary_reagent.glass_special)) var/totalvape = 0 - for(var/rtype in reagents.reagent_volumes) - var/decl/material/reagent = GET_DECL(rtype) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) if("vapor" in reagent.glass_special) - totalvape += REAGENT_VOLUME(reagents, type) + totalvape += REAGENT_VOLUME(reagents, reagent) if(totalvape >= volume * 0.6) // 60% vapor by container volume return 1 return 0 diff --git a/code/modules/reagents/reagent_containers/drinks/juicebox.dm b/code/modules/reagents/reagent_containers/drinks/juicebox.dm index fc558edf2991..1ffae8ceb750 100644 --- a/code/modules/reagents/reagent_containers/drinks/juicebox.dm +++ b/code/modules/reagents/reagent_containers/drinks/juicebox.dm @@ -118,8 +118,8 @@ /obj/item/chems/drinks/juicebox/sensible_random/populate_reagents() var/list/chosen_reagents = juice_it() - var/decl/material/J = GET_DECL(chosen_reagents[1]) - var/decl/material/K = GET_DECL(chosen_reagents[2]) + var/decl/material/J = chosen_reagents[1] + var/decl/material/K = chosen_reagents[2] var/splash = pick("teasing", "splash", "hint", "measure", "nip", "slug", "depth", "dash", "sensation", "surge", "squirt", "spritz", "efflux", "gush", "swell") desc = "[J.liquid_name]; [J.lore_text] This one comes with \an [splash] of [K.liquid_name] in a neat box." name = "\improper [J.liquid_name] and [K.liquid_name] juicebox" diff --git a/code/modules/reagents/reagent_containers/food.dm b/code/modules/reagents/reagent_containers/food.dm index 0d8435d02954..1e3f4cdb26dd 100644 --- a/code/modules/reagents/reagent_containers/food.dm +++ b/code/modules/reagents/reagent_containers/food.dm @@ -215,9 +215,8 @@ /obj/item/food/proc/add_allergen_flags(new_flags) - for(var/reagent in reagents.reagent_volumes) - var/decl/material/mat = GET_DECL(reagent) - var/list/newdata = mat.mix_data(reagents, list(DATA_INGREDIENT_FLAGS = new_flags)) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + var/list/newdata = reagent.mix_data(reagents, list(DATA_INGREDIENT_FLAGS = new_flags)) if(newdata) LAZYSET(reagents.reagent_data, reagent, newdata) diff --git a/code/modules/reagents/reagent_containers/retort.dm b/code/modules/reagents/reagent_containers/retort.dm index a8d69a6ce6a5..5292cd7ee9a7 100644 --- a/code/modules/reagents/reagent_containers/retort.dm +++ b/code/modules/reagents/reagent_containers/retort.dm @@ -19,9 +19,8 @@ /obj/item/chems/glass/retort/update_overlays() if(reagents?.total_volume && (!material || material.opacity < 1)) - for(var/reagent in reagents.reagent_volumes) - var/decl/material/mat = GET_DECL(reagent) - if(!isnull(mat.boiling_point) && temperature >= mat.boiling_point) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(!isnull(reagent.boiling_point) && temperature >= reagent.boiling_point) add_overlay(overlay_image(icon, "[icon_state]-fill-boil", reagents.get_color(), (RESET_ALPHA|RESET_COLOR))) return add_overlay(overlay_image(icon, "[icon_state]-fill", reagents.get_color(), (RESET_ALPHA|RESET_COLOR))) diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm index cd4493277c46..ecb39c854f4a 100644 --- a/code/modules/reagents/reagent_dispenser.dm +++ b/code/modules/reagents/reagent_dispenser.dm @@ -71,12 +71,10 @@ . += "Its refilling cap is closed." . += SPAN_NOTICE("It contains:") if(LAZYLEN(reagents?.reagent_volumes)) - for(var/rtype in reagents.liquid_volumes) - var/decl/material/R = GET_DECL(rtype) - . += SPAN_NOTICE("[LIQUID_VOLUME(reagents, rtype)] unit\s of [R.get_reagent_name(reagents, MAT_PHASE_LIQUID)].") - for(var/rtype in reagents.solid_volumes) - var/decl/material/R = GET_DECL(rtype) - . += SPAN_NOTICE("[SOLID_VOLUME(reagents, rtype)] unit\s of [R.get_reagent_name(reagents, MAT_PHASE_SOLID)].") + for(var/decl/material/reagent as anything in reagents.liquid_volumes) + . += SPAN_NOTICE("[LIQUID_VOLUME(reagents, reagent)] unit\s of [reagent.get_reagent_name(reagents, MAT_PHASE_LIQUID)].") + for(var/decl/material/reagent as anything in reagents.solid_volumes) + . += SPAN_NOTICE("[SOLID_VOLUME(reagents, reagent)] unit\s of [reagent.get_reagent_name(reagents, MAT_PHASE_SOLID)].") else . += SPAN_NOTICE("Nothing.") if(reagents?.maximum_volume) diff --git a/code/modules/scanners/breath.dm b/code/modules/scanners/breath.dm index bc80d7c7b9f0..3854377aa344 100644 --- a/code/modules/scanners/breath.dm +++ b/code/modules/scanners/breath.dm @@ -100,11 +100,10 @@ var/datum/reagents/inhaled = target.get_inhaled_reagents() if(inhaled && inhaled.total_volume) var/unknown = 0 - for(var/rtype in inhaled.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - if(R.scannable) + for(var/decl/material/reagent as anything in inhaled.reagent_volumes) + if(reagent.scannable) print_reagent_default_message = FALSE - . += "[capitalize(R.gas_name)] found in subject's breath." + . += "[capitalize(reagent.gas_name)] found in subject's breath." else ++unknown if(unknown) diff --git a/code/modules/scanners/health.dm b/code/modules/scanners/health.dm index 2ad64584cdcb..487327777b42 100644 --- a/code/modules/scanners/health.dm +++ b/code/modules/scanners/health.dm @@ -244,11 +244,10 @@ if(H.reagents.total_volume) var/unknown = 0 var/reagentdata[0] - for(var/rtype in H.reagents.reagent_volumes) - var/decl/material/injected_reagent = GET_DECL(rtype) - if(injected_reagent.scannable) + for(var/decl/material/reagent as anything in H.reagents.reagent_volumes) + if(reagent.scannable) print_reagent_default_message = FALSE - reagentdata[rtype] = "[round(REAGENT_VOLUME(H.reagents, rtype), 1)]u [injected_reagent.use_name]" + reagentdata[reagent.type] = "[round(REAGENT_VOLUME(H.reagents, reagent), 1)]u [reagent.use_name]" else unknown++ if(reagentdata.len) @@ -264,11 +263,10 @@ if(touching_reagents && touching_reagents.total_volume) var/unknown = 0 var/reagentdata[0] - for(var/rtype in touching_reagents.reagent_volumes) - var/decl/material/touched_reagent = GET_DECL(rtype) - if(touched_reagent.scannable) + for(var/decl/material/reagent as anything in touching_reagents.reagent_volumes) + if(reagent.scannable) print_reagent_default_message = FALSE - reagentdata[rtype] = "[round(REAGENT_VOLUME(H.reagents, rtype), 1)]u [touched_reagent.use_name]" + reagentdata[reagent.type] = "[round(REAGENT_VOLUME(H.reagents, reagent), 1)]u [reagent.name]" else unknown++ if(reagentdata.len) @@ -283,11 +281,10 @@ var/datum/reagents/ingested = H.get_ingested_reagents() if(ingested && ingested.total_volume) var/unknown = 0 - for(var/rtype in ingested.reagent_volumes) - var/decl/material/ingested_reagent = GET_DECL(rtype) - if(ingested_reagent.scannable) + for(var/decl/material/reagent as anything in ingested.reagent_volumes) + if(reagent.scannable) print_reagent_default_message = FALSE - . += "[capitalize(ingested_reagent.use_name)] found in subject's stomach." + . += "[capitalize(reagent.use_name)] found in subject's stomach." else ++unknown if(unknown) @@ -297,23 +294,21 @@ var/datum/reagents/inhaled = H.get_inhaled_reagents() if(inhaled && inhaled.total_volume) var/unknown = 0 - for(var/rtype in inhaled.reagent_volumes) - var/decl/material/inhaled_reagent = GET_DECL(rtype) - if(inhaled_reagent.scannable) + for(var/decl/material/reagent as anything in inhaled.reagent_volumes) + if(reagent.scannable) print_reagent_default_message = FALSE - . += "[capitalize(inhaled_reagent.use_name)] found in subject's lungs." + . += "[capitalize(reagent.use_name)] found in subject's lungs." else ++unknown if(unknown) print_reagent_default_message = FALSE . += "Non-medical reagent[(unknown > 1)?"s":""] found in subject's lungs." - if(length(H.chem_doses)) + if(length(H._chem_doses)) var/list/chemtraces = list() - for(var/dose_type in H.chem_doses) - var/decl/material/dose_material = GET_DECL(dose_type) - if(dose_material.scannable) - chemtraces += "[dose_material.use_name] ([LAZYACCESS(H.chem_doses, dose_type)])" + for(var/decl/material/reagent in H._chem_doses) + if(reagent.scannable) + chemtraces += "[reagent.use_name] ([CHEM_DOSE(H, reagent)])" if(chemtraces.len) . += "Metabolism products of [english_list(chemtraces)] found in subject's system." diff --git a/code/modules/scanners/mass_spectrometer.dm b/code/modules/scanners/mass_spectrometer.dm index ff7b3e0df2c7..510ea189fe03 100644 --- a/code/modules/scanners/mass_spectrometer.dm +++ b/code/modules/scanners/mass_spectrometer.dm @@ -57,10 +57,10 @@ if(istype(random)) return random.get_scan_data(user) - for(var/reagent_type in reagents.reagent_volumes) - if(!ispath(reagent_type, /decl/material/liquid/blood)) + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + if(!istype(reagent, /decl/material/liquid/blood)) return SPAN_WARNING("The sample was contaminated! Please insert another sample.") - var/data = REAGENT_DATA(reagents, reagent_type) + var/data = REAGENT_DATA(reagents, reagent) if(islist(data)) blood_traces = data[DATA_BLOOD_TRACE_CHEM] blood_doses = data[DATA_BLOOD_DOSE_CHEM] diff --git a/code/modules/scanners/plant.dm b/code/modules/scanners/plant.dm index dea3d5bd12dc..e2768e691db6 100644 --- a/code/modules/scanners/plant.dm +++ b/code/modules/scanners/plant.dm @@ -81,12 +81,10 @@ if(LAZYLEN(grown_reagents?.reagent_volumes)) dat += "

Reagent Data

" dat += "
This sample contains: " - for(var/ltype in grown_reagents.liquid_volumes) - var/decl/material/R = GET_DECL(ltype) - dat += "
- [R.get_reagent_name(grown_reagents, MAT_PHASE_LIQUID)], [LIQUID_VOLUME(grown_reagents, ltype)] unit(s)" - for(var/stype in grown_reagents.solid_volumes) - var/decl/material/R = GET_DECL(stype) - dat += "
- [R.get_reagent_name(grown_reagents, MAT_PHASE_SOLID)], [SOLID_VOLUME(grown_reagents, stype)] unit(s)" + for(var/decl/material/reagent as anything in grown_reagents.liquid_volumes) + dat += "
- [reagent.get_reagent_name(grown_reagents, MAT_PHASE_LIQUID)], [LIQUID_VOLUME(grown_reagents, reagent)] unit(s)" + for(var/decl/material/reagent as anything in grown_reagents.solid_volumes) + dat += "
- [reagent.get_reagent_name(grown_reagents, MAT_PHASE_SOLID)], [SOLID_VOLUME(grown_reagents, reagent)] unit(s)" dat += "

Other Data

" if(length(extended_trait_data)) diff --git a/code/modules/scanners/reagents.dm b/code/modules/scanners/reagents.dm index 2087c8027ba6..079117f25885 100644 --- a/code/modules/scanners/reagents.dm +++ b/code/modules/scanners/reagents.dm @@ -21,9 +21,8 @@ return list("No active chemical agents found in [O].") . = list("Chemicals found in [O]:") var/one_percent = O.reagents.total_volume / 100 - for (var/rtype in O.reagents.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - . += "[R.name][details ? ": [REAGENT_VOLUME(O.reagents, rtype) / one_percent]%" : ""]" + for (var/decl/material/reagent as anything in O.reagents.reagent_volumes) + . += "[reagent.name][details ? ": [REAGENT_VOLUME(O.reagents, reagent) / one_percent]%" : ""]" /obj/item/scanner/reagent/adv name = "advanced reagent scanner" diff --git a/code/modules/scent/_scent.dm b/code/modules/scent/_scent.dm index dac52b069a8e..b002b8a43c63 100644 --- a/code/modules/scent/_scent.dm +++ b/code/modules/scent/_scent.dm @@ -117,7 +117,7 @@ Reagents have the following vars, which coorelate to the vars on the standard sc scent_intensity, scent_descriptor, scent_range -To add a scent extension to an atom using a reagent's info, where R. is the reagent, use set_scent_by_reagents(). +To add a scent extension to an atom using a reagent's info, where reagent. is the reagent, use set_scent_by_reagents(). *****/ /proc/set_scent_by_reagents(var/atom/smelly_atom) @@ -131,14 +131,13 @@ To add a scent extension to an atom using a reagent's info, where R. is the reag var/scent_intensity if(!holder || !holder.total_volume) return - for(var/reagent_type in holder.reagent_volumes) - var/decl/material/scented_reagent = GET_DECL(reagent_type) - if(!scented_reagent.scent) + for(var/decl/material/reagent as anything in holder.reagent_volumes) + if(!reagent.scent) continue - var/decl/scent_intensity/scent = GET_DECL(scented_reagent.scent_intensity) - var/r_scent_intensity = REAGENT_VOLUME(holder, reagent_type) * scent.intensity + var/decl/scent_intensity/scent = GET_DECL(reagent.scent_intensity) + var/r_scent_intensity = REAGENT_VOLUME(holder, reagent) * scent.intensity if(r_scent_intensity > scent_intensity) - smelliest = scented_reagent + smelliest = reagent scent_intensity = r_scent_intensity return smelliest \ No newline at end of file diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm index 5b9c16d99cf3..684694d1406d 100644 --- a/code/modules/surgery/other.dm +++ b/code/modules/surgery/other.dm @@ -248,7 +248,7 @@ return FALSE // Check if we have sterilizing reagents and -only- sterilizing reagents. - for(var/reagent in container.reagents.reagent_volumes) + for(var/decl/material/reagent as anything in container.reagents.reagent_volumes) if(!(reagent in sterilizing_reagents)) return FALSE . = TRUE diff --git a/code/modules/vehicles/engine.dm b/code/modules/vehicles/engine.dm index d11185796a74..db7e0dfb8e42 100644 --- a/code/modules/vehicles/engine.dm +++ b/code/modules/vehicles/engine.dm @@ -103,10 +103,9 @@ reagents.trans_to_holder(combustion_chamber, min(reagents.total_volume, 15)) var/multiplier = 0 var/actually_flammable = FALSE - for(var/rtype in combustion_chamber.reagent_volumes) + for(var/decl/material/reagent as anything in temp_reagents_holder.reagents.reagent_volumes) var/new_multiplier = 1 - var/reagent_volume = combustion_chamber.reagent_volumes[rtype] - var/decl/material/reagent = GET_DECL(rtype) + var/reagent_volume = combustion_chamber.reagent_volumes[reagent] if(reagent.accelerant_value < FUEL_VALUE_NONE) // suppresses fires rather than starts them // this means that FUEL_VALUE_SUPPRESSANT is on par with water in the old code new_multiplier = -(FUEL_VALUE_SUPPRESSANT + reagent.accelerant_value) / 2 * 0.4 @@ -114,7 +113,7 @@ // averaging these means that FUEL_VALUE_ACCELERANT is 1x, hydrazine is 1.25x, and exotic matter is 1.5x new_multiplier = (FUEL_VALUE_ACCELERANT + reagent.accelerant_value) / 2 actually_flammable = TRUE - if(ispath(rtype, /decl/material/liquid/nutriment/sugar) && REAGENT_VOLUME(reagents, rtype) > 1) + if(ispath(reagent, /decl/material/liquid/nutriment/sugar) && REAGENT_VOLUME(reagents, reagent) > 1) broken = TRUE explosion(get_turf(src),-1,0,2,3,0) return 0 diff --git a/code/modules/xenoarcheaology/machinery/geosample_scanner.dm b/code/modules/xenoarcheaology/machinery/geosample_scanner.dm index 1915abfab92c..486a5eb5ea83 100644 --- a/code/modules/xenoarcheaology/machinery/geosample_scanner.dm +++ b/code/modules/xenoarcheaology/machinery/geosample_scanner.dm @@ -115,14 +115,14 @@ fresh_coolant = 0 coolant_purity = 0 var/num_reagent_types = 0 - for(var/rtype in reagents.reagent_volumes) - var/cur_purity = coolant_reagents_purity[rtype] + for(var/decl/material/reagent as anything in reagents.reagent_volumes) + var/cur_purity = coolant_reagents_purity[reagent.type] if(!cur_purity) cur_purity = 0.1 else if(cur_purity > 1) cur_purity = 1 - total_purity += cur_purity * REAGENT_VOLUME(reagents, rtype) - fresh_coolant += REAGENT_VOLUME(reagents, rtype) + total_purity += cur_purity * REAGENT_VOLUME(reagents, reagent) + fresh_coolant += REAGENT_VOLUME(reagents, reagent) num_reagent_types += 1 if(total_purity && fresh_coolant) coolant_purity = total_purity / fresh_coolant diff --git a/mods/content/xenobiology/colours/_colour.dm b/mods/content/xenobiology/colours/_colour.dm index 3b1248c353df..24a08bb42159 100644 --- a/mods/content/xenobiology/colours/_colour.dm +++ b/mods/content/xenobiology/colours/_colour.dm @@ -25,12 +25,12 @@ if(!istype(core) || core.Uses <= 0) return - for(var/rtype in holder.reagent_volumes) - if(holder.reagent_volumes[rtype] < 1) + for(var/decl/material/reagent as anything in holder.reagent_volumes) + if(holder.reagent_volumes[reagent] < 1) continue - var/call_proc = reaction_procs[rtype] + var/call_proc = reaction_procs[reagent] if(call_proc && call(src, call_proc)(holder)) - holder.remove_reagent(rtype, holder.reagent_volumes[rtype]) + holder.remove_reagent(reagent, holder.reagent_volumes[reagent]) . = TRUE break diff --git a/mods/content/xenobiology/slime/slime_reagents.dm b/mods/content/xenobiology/slime/slime_reagents.dm index 882797de7599..a88694656b6c 100644 --- a/mods/content/xenobiology/slime/slime_reagents.dm +++ b/mods/content/xenobiology/slime/slime_reagents.dm @@ -24,7 +24,7 @@ if(slime_ai.current_target) // don't bother resolving it, we're just clearing it slime_ai.current_target = null slime_victim.set_feeding_on() - if(LAZYACCESS(victim.chem_doses, type) == removed) + if(CHEM_DOSE(victim, src) == removed) var/reagent_name = get_reagent_name(holder) // mostly to check masked name, but handles phase too victim.visible_message( \ SPAN_DANGER("\The [slime_victim]'s flesh sizzles where \the [reagent_name] touches it!"), \ diff --git a/mods/species/skrell/datum/species.dm b/mods/species/skrell/datum/species.dm index ac49a3c8a8b9..c3ae5d8da757 100644 --- a/mods/species/skrell/datum/species.dm +++ b/mods/species/skrell/datum/species.dm @@ -133,7 +133,7 @@ // TODO: There's not currently a way to check this, which might be a little annoying for forensics. // But this is just a stopgap to stop Skrell from literally leaking blood everywhere they go. /decl/material/liquid/mucus/skrell/get_reagent_color(datum/reagents/holder) - var/list/goo_data = REAGENT_DATA(holder, type) + var/list/goo_data = REAGENT_DATA(holder, src) return goo_data?[DATA_BLOOD_COLOR] || ..() /obj/effect/decal/cleanable/blood/tracks/footprints/skrellprints diff --git a/mods/species/vox/organs_vox.dm b/mods/species/vox/organs_vox.dm index e2e43ad49331..4ccb8d14cf63 100644 --- a/mods/species/vox/organs_vox.dm +++ b/mods/species/vox/organs_vox.dm @@ -98,9 +98,8 @@ // Handle some post-metabolism reagent processing for generally inedible foods. if(ingested.total_volume > 0) - for(var/rtype in ingested.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - var/inedible_nutriment_amount = gains_nutriment_from_inedible_reagents[R] + for(var/decl/material/reagent as anything in ingested.reagent_volumes) + var/inedible_nutriment_amount = gains_nutriment_from_inedible_reagents[reagent.type] if(inedible_nutriment_amount > 0) owner.adjust_nutrition(inedible_nutriment_amount) diff --git a/nebula.dme b/nebula.dme index 5c8541c4f63a..a89bc4d9b9c5 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1013,8 +1013,8 @@ #include "code\game\machinery\vending\security.dm" #include "code\game\machinery\vending\toxins.dm" #include "code\game\objects\__objs.dm" -#include "code\game\objects\_obj_edibility.dm" #include "code\game\objects\_objs_damage.dm" +#include "code\game\objects\_objs_edibility.dm" #include "code\game\objects\_objs_interactions.dm" #include "code\game\objects\alien_props.dm" #include "code\game\objects\empulse.dm" From 6a4e655b11e4958eb9824dadc148a1ab015386df Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 03:57:03 -0500 Subject: [PATCH 068/512] Replace the global uplink singleton with a decl --- code/datums/uplink/uplink_items.dm | 7 ++--- code/game/objects/items/devices/uplink.dm | 2 ++ .../items/devices/uplink_random_lists.dm | 30 ++++++++++--------- .../preference_setup/antagonism/02_setup.dm | 4 +-- .../overmap/internet/internet_uplink.dm | 4 +-- .../overmap/internet/sector_internet.dm | 24 +++++++-------- code/unit_tests/uplink_tests.dm | 1 + 7 files changed, 38 insertions(+), 34 deletions(-) diff --git a/code/datums/uplink/uplink_items.dm b/code/datums/uplink/uplink_items.dm index 97db7fad4614..26ed3c2e370c 100644 --- a/code/datums/uplink/uplink_items.dm +++ b/code/datums/uplink/uplink_items.dm @@ -1,11 +1,10 @@ -var/global/datum/uplink/uplink = new() - -/datum/uplink +/decl/uplink var/list/items_assoc var/list/datum/uplink_item/items var/list/datum/uplink_category/categories -/datum/uplink/New() +/decl/uplink/Initialize() + . = ..() items_assoc = list() items = init_subtypes(/datum/uplink_item) categories = init_subtypes(/datum/uplink_category) diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index 02f4eb078b7c..91c1c3b66c1a 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -152,6 +152,7 @@ // The purchasing code. /obj/item/uplink/OnTopic(user, href_list) + var/decl/uplink/uplink = IMPLIED_DECL if(href_list["buy_item"]) var/datum/uplink_item/UI = (locate(href_list["buy_item"]) in uplink.items) UI.buy(src, usr) @@ -175,6 +176,7 @@ update_nano_data() /obj/item/uplink/proc/update_nano_data() + var/decl/uplink/uplink = IMPLIED_DECL if(nanoui_menu == 0) var/categories[0] for(var/datum/uplink_category/category in uplink.categories) diff --git a/code/game/objects/items/devices/uplink_random_lists.dm b/code/game/objects/items/devices/uplink_random_lists.dm index b0acc8d88f6a..9caf549fe317 100644 --- a/code/game/objects/items/devices/uplink_random_lists.dm +++ b/code/game/objects/items/devices/uplink_random_lists.dm @@ -19,19 +19,20 @@ /datum/uplink_random_selection/proc/get_random_item(var/telecrystals, obj/item/uplink/U, var/list/bought_items) var/const/attempts = 50 + var/decl/uplink/uplink = IMPLIED_DECL for(var/i = 0; i < attempts; i++) - var/datum/uplink_random_item/RI = pick(items) - if(!prob(RI.keep_probability)) + var/datum/uplink_random_item/random_item = pick(items) + if(!prob(random_item.keep_probability)) continue - var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item] - if(I.cost(telecrystals, U) > telecrystals) + var/datum/uplink_item/uplink_item = uplink.items_assoc[random_item.uplink_item] + if(uplink_item.cost(telecrystals, uplink) > telecrystals) continue - if(bought_items && (I in bought_items) && !prob(RI.reselect_probability)) + if(bought_items && (uplink_item in bought_items) && !prob(random_item.reselect_probability)) continue - if(U && !I.can_buy(U)) + if(uplink && !uplink_item.can_buy(uplink)) continue - return I + return uplink_item return uplink.items_assoc[/datum/uplink_item/item/stealthy_weapons/soap] var/global/list/uplink_random_selections_ @@ -121,16 +122,17 @@ var/global/list/uplink_random_selections_ var/new_thing = new/datum/uplink_random_item(uplink_item_type) items += new_thing -/datum/uplink_random_selection/blacklist/get_random_item(var/telecrystals, obj/item/uplink/U, var/list/bought_items) +/datum/uplink_random_selection/blacklist/get_random_item(var/telecrystals, obj/item/uplink/uplink_access, var/list/bought_items) var/const/attempts = 50 + var/decl/uplink/uplink = IMPLIED_DECL for(var/i = 0; i < attempts; i++) - var/datum/uplink_random_item/RI = pick(items) - if(!prob(RI.keep_probability)) + var/datum/uplink_random_item/random_item = pick(items) + if(!prob(random_item.keep_probability)) continue - var/datum/uplink_item/I = uplink.items_assoc[RI.uplink_item] - if(I.cost(telecrystals, U) > telecrystals) + var/datum/uplink_item/uplink_item = uplink.items_assoc[random_item.uplink_item] + if(uplink_item.cost(telecrystals, uplink_access) > telecrystals) continue - if(bought_items && (I in bought_items) && !prob(RI.reselect_probability)) + if(bought_items && (uplink_item in bought_items) && !prob(random_item.reselect_probability)) continue - return I + return uplink_item return uplink.items_assoc[/datum/uplink_item/item/stealthy_weapons/soap] diff --git a/code/modules/client/preference_setup/antagonism/02_setup.dm b/code/modules/client/preference_setup/antagonism/02_setup.dm index ca04f308db91..83488006cfcb 100644 --- a/code/modules/client/preference_setup/antagonism/02_setup.dm +++ b/code/modules/client/preference_setup/antagonism/02_setup.dm @@ -27,8 +27,8 @@ /datum/category_item/player_setup_item/antagonism/basic/save_character(datum/pref_record_writer/writer) var/uplink_order = list() for(var/entry in pref.uplink_sources) - var/decl/uplink_source/uplink = entry - uplink_order += uplink.name + var/decl/uplink_source/uplink_source = entry + uplink_order += uplink_source.name writer.write("uplink_sources", uplink_order) writer.write("exploit_record", pref.exploit_record) diff --git a/code/modules/overmap/internet/internet_uplink.dm b/code/modules/overmap/internet/internet_uplink.dm index c79bec98fc93..53e7e4eb923b 100644 --- a/code/modules/overmap/internet/internet_uplink.dm +++ b/code/modules/overmap/internet/internet_uplink.dm @@ -41,8 +41,8 @@ var/global/list/internet_uplinks = list() /obj/machinery/internet_uplink/attackby(var/obj/item/used_item, var/mob/user) if(IS_MULTITOOL(used_item)) - var/datum/extension/local_network_member/uplink = get_extension(src, /datum/extension/local_network_member) - uplink.get_new_tag(user) + var/datum/extension/local_network_member/uplink_comp = get_extension(src, /datum/extension/local_network_member) + uplink_comp.get_new_tag(user) return TRUE return ..() diff --git a/code/modules/overmap/internet/sector_internet.dm b/code/modules/overmap/internet/sector_internet.dm index ec63ebf3b848..62472321dfe4 100644 --- a/code/modules/overmap/internet/sector_internet.dm +++ b/code/modules/overmap/internet/sector_internet.dm @@ -11,30 +11,30 @@ if(!found_repeater) return - // Must have an operable internet uplink in range on the overmap. - for(var/obj/machinery/internet_uplink/uplink in global.internet_uplinks) - if(uplink.use_power != POWER_USE_ACTIVE || !uplink.operable()) + // Must have an operable internet uplink in range on the overmap. + for(var/obj/machinery/internet_uplink/inet_uplink in global.internet_uplinks) + if(inet_uplink.use_power != POWER_USE_ACTIVE || !inet_uplink.operable()) continue - if(uplink.restrict_networks && !(connecting_network in uplink.permitted_networks)) + if(inet_uplink.restrict_networks && !(connecting_network in inet_uplink.permitted_networks)) continue // Ensure the sectors are within range. - var/obj/effect/overmap/sector = uplink.get_owning_overmap_object() - if(sector == src || (get_dist(get_turf(sector), get_turf(src)) <= uplink.overmap_range)) + var/obj/effect/overmap/sector = inet_uplink.get_owning_overmap_object() + if(sector == src || (get_dist(get_turf(sector), get_turf(src)) <= inet_uplink.overmap_range)) return TRUE // Helper to get nearby connections. Returns list(list(x, y) = allowed networks). /obj/effect/overmap/visitable/proc/get_internet_connections() var/found = list() - for(var/obj/machinery/internet_uplink/uplink in global.internet_uplinks) - if(uplink.use_power != POWER_USE_ACTIVE || !uplink.operable()) + for(var/obj/machinery/internet_uplink/inet_uplink in global.internet_uplinks) + if(inet_uplink.use_power != POWER_USE_ACTIVE || !inet_uplink.operable()) continue // Range check. - var/obj/effect/overmap/sector = uplink.get_owning_overmap_object() - if(sector == src || (get_dist(get_turf(sector), get_turf(src)) <= uplink.overmap_range)) + var/obj/effect/overmap/sector = inet_uplink.get_owning_overmap_object() + if(sector == src || (get_dist(get_turf(sector), get_turf(src)) <= inet_uplink.overmap_range)) var/list/location = list(sector.x, sector.y) - var/allowed = uplink.restrict_networks ? english_list(uplink.permitted_networks, nothing_text = "NO NETWORKS") : "ALL NETWORKS" + var/allowed = inet_uplink.restrict_networks ? english_list(inet_uplink.permitted_networks, nothing_text = "NO NETWORKS") : "ALL NETWORKS" found[location] = allowed - + return found \ No newline at end of file diff --git a/code/unit_tests/uplink_tests.dm b/code/unit_tests/uplink_tests.dm index c21cedc86174..7599f1ccd115 100644 --- a/code/unit_tests/uplink_tests.dm +++ b/code/unit_tests/uplink_tests.dm @@ -2,6 +2,7 @@ name = "UPLINK: All uplink items shall be valid." /datum/unit_test/uplink_setup_test/start_test() + var/decl/uplink/uplink = IMPLIED_DECL var/success = TRUE for(var/item in uplink.items) From 2db73f051bcef18be40f55186ccb6f1a231854d3 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 04:43:58 -0500 Subject: [PATCH 069/512] Break up global_lists.dm --- code/_global_vars/client.dm | 3 - code/_helpers/global_lists.dm | 95 +++++++------------ code/controllers/subsystems/jobs.dm | 2 +- code/controllers/subsystems/machines.dm | 2 +- code/datums/underwear/underwear.dm | 2 + code/game/antagonist/antagonist_place.dm | 2 +- code/game/jobs/job/_job.dm | 2 +- code/game/machinery/teleporter.dm | 2 +- code/game/objects/effects/landmarks.dm | 5 +- code/game/objects/items/devices/uplink.dm | 2 - .../secrets/fun_secrets/break_some_lights.dm | 2 +- code/modules/chatter/_chatter.dm | 6 +- .../preference_setup/general/02_body.dm | 6 +- code/modules/events/apc_damage.dm | 2 +- code/modules/events/rogue_drones.dm | 2 +- code/modules/keybindings/_keybindings.dm | 2 + code/modules/keybindings/admin.dm | 1 + code/modules/keybindings/client.dm | 1 + code/modules/keybindings/communication.dm | 1 + code/modules/keybindings/human.dm | 1 + code/modules/keybindings/living.dm | 1 + code/modules/keybindings/mob.dm | 1 + code/modules/keybindings/movement.dm | 1 + code/modules/keybindings/robot.dm | 1 + .../{human_species.dm => human_presets.dm} | 9 ++ .../mob/observer/eye/freelook/ai/cameranet.dm | 2 +- .../observer/eye/freelook/update_triggers.dm | 2 +- .../mob/observer/eye/freelook/visualnet.dm | 6 +- code/modules/mob/transform_procs.dm | 6 +- code/modules/power/cable.dm | 6 +- code/modules/shuttles/shuttle_specops.dm | 4 +- code/unit_tests/map_tests.dm | 6 +- code/unit_tests/mob_tests.dm | 15 ++- code/unit_tests/organ_tests.dm | 28 ++++-- code/unit_tests/power_tests.dm | 2 +- code/unit_tests/unit_test.dm | 4 +- maps/~mapsystem/maps.dm | 7 ++ nebula.dme | 2 +- 38 files changed, 132 insertions(+), 112 deletions(-) rename code/modules/mob/living/human/{human_species.dm => human_presets.dm} (89%) diff --git a/code/_global_vars/client.dm b/code/_global_vars/client.dm index 1a3545fed8d0..5a8b7f1b1c5c 100644 --- a/code/_global_vars/client.dm +++ b/code/_global_vars/client.dm @@ -1,6 +1,3 @@ -var/global/list/hotkey_keybinding_list_by_key = list() -var/global/list/keybindings_by_name = list() - // This is a mapping from JS keys to Byond - ref: https://keycode.info/ var/global/list/_kbMap = list( "UP" = "North", diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index baa48fe542cd..d4216ae41905 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -1,19 +1,9 @@ -//Since it didn't really belong in any other category, I'm putting this here -//This is for procs to replace all the goddamn 'in world's that are chilling around the code -//Nine years later, we can report we've killed most of them! +// I really don't like having miscellaneous 'collection of definitions' files floating around in the codebase. +// I've already found a lot of the lists that used to be here a new forever home (or taken them out back and shot them), +// but hopefully we can do the same for the rest eventually. +// Either find a better spot for them that's related to their uses/function/etc., or delete them. -var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time -var/global/list/landmarks_list = list() //list of all landmarks created -var/global/list/mannequins_ - -// Uplinks -var/global/list/obj/item/uplink/world_uplinks = list() - -// Visual nets -var/global/list/datum/visualnet/visual_nets = list() -var/global/datum/visualnet/camera/cameranet = new() - -// Strings which corraspond to bodypart covering flags, useful for outputting what something covers. +// Strings which correspond to bodypart covering flags, useful for outputting what something covers. var/global/list/string_part_flags = list( "head" = SLOT_HEAD, "face" = SLOT_FACE, @@ -28,7 +18,8 @@ var/global/list/string_part_flags = list( "hands" = SLOT_HANDS ) -// Strings which corraspond to slot flags, useful for outputting what slot something is. +// TODO: These should probably be able to be generated automatically from inventory slot subtype definitions, maybe? +/// Strings which correspond to slot flags, useful for outputting what slot something is. var/global/list/string_slot_flags = list( "back" = SLOT_BACK, "face" = SLOT_FACE, @@ -45,72 +36,56 @@ var/global/list/string_slot_flags = list( "holster" = SLOT_HOLSTER ) -////////////////////////// -/////Initial Building///// -////////////////////////// - -/proc/get_mannequin(var/ckey) - if(SSatoms.atom_init_stage < INITIALIZATION_INNEW_REGULAR) - return - if(!mannequins_) - mannequins_ = new() - . = mannequins_[ckey] - if(!.) - . = new /mob/living/human/dummy/mannequin() - mannequins_[ckey] = . +// Used to avoid constantly generating new lists during movement. +var/global/list/all_stance_limbs = list( + ORGAN_CATEGORY_STANCE, + ORGAN_CATEGORY_STANCE_ROOT +) +var/global/list/child_stance_limbs = list( + ORGAN_CATEGORY_STANCE +) +// TODO: Replace keybinding datums with keybinding decls to make this unnecessary. +var/global/list/hotkey_keybinding_list_by_key = list() // Replace this with just looping over all keybinding decls (as below) in a 'reset hotkeys' proc. +var/global/list/keybindings_by_name = list() // Replace this with just decl lookups. /proc/makeDatumRefLists() // Keybindings for(var/KB in subtypesof(/datum/keybinding)) var/datum/keybinding/keybinding = KB - if(!initial(keybinding.name)) + if(TYPE_IS_ABSTRACT(keybinding)) continue + ASSERT(keybinding.name) var/datum/keybinding/instance = new keybinding global.keybindings_by_name[instance.name] = instance if(length(instance.hotkey_keys)) for(var/bound_key in instance.hotkey_keys) global.hotkey_keybinding_list_by_key[bound_key] += list(instance.name) - return 1 // This is all placeholder procs for an eventual PR to change them to use decls. var/global/list/all_species -var/global/list/playable_species // A list of ALL playable species, whitelisted, latejoin or otherwise. -var/global/list/bodytype_species_pairs = list() // A list of bodytypes -> species, used for mainly unit testing. /proc/build_species_lists() if(global.all_species) return - global.all_species = list() - global.playable_species = list() - var/list/species_decls = decls_repository.get_decls_of_subtype(/decl/species) - for(var/species_type in species_decls) - var/decl/species/species = species_decls[species_type] - if(species.name) - global.all_species[species.name] = species - for(var/decl/bodytype/bodytype in species.available_bodytypes) - global.bodytype_species_pairs[GET_DECL(bodytype)] = species - if(!(species.spawn_flags & SPECIES_IS_RESTRICTED)) - global.playable_species += species.name - if(global.using_map.default_species) - global.playable_species |= global.using_map.default_species + global.all_species = list() + for(var/decl/species/species in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) + ASSERT(species.name) // all non-abstract species should have names + global.all_species[species.name] = species +// TODO: Change species code to use decls instead of name keys. In that event, replace this with GET_DECL(species) I guess, or make it use UID instead of name? /proc/get_species_by_key(var/species_key) build_species_lists() . = global.all_species[species_key] +// In the event of the above, this would be replaced with decls_repository.get_decls_of_subtype(/decl/species) or similar helpers. /proc/get_all_species() build_species_lists() . = global.all_species +// In the event of the above, just make it add the typepath or UID instead of the name. /proc/get_playable_species() - build_species_lists() - . = global.playable_species -/proc/get_bodytype_species_pairs() - build_species_lists() - . = global.bodytype_species_pairs - -// Used to avoid constantly generating new lists during movement. -var/global/list/all_stance_limbs = list( - ORGAN_CATEGORY_STANCE, - ORGAN_CATEGORY_STANCE_ROOT -) -var/global/list/child_stance_limbs = list( - ORGAN_CATEGORY_STANCE -) + var/static/list/_playable_species // A list of ALL playable species, whitelisted, latejoin or otherwise. (read: non-restricted) + if(!_playable_species) + _playable_species = list() + for(var/decl/species/species in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) + if(species.spawn_flags & SPECIES_IS_RESTRICTED) + continue + _playable_species += species.name + return _playable_species diff --git a/code/controllers/subsystems/jobs.dm b/code/controllers/subsystems/jobs.dm index 5ecd6a466643..722dd50bee4c 100644 --- a/code/controllers/subsystems/jobs.dm +++ b/code/controllers/subsystems/jobs.dm @@ -573,7 +573,7 @@ SUBSYSTEM_DEF(jobs) return positions_by_department[dept] || list() /datum/controller/subsystem/jobs/proc/spawn_empty_ai() - for(var/obj/abstract/landmark/start/S in global.landmarks_list) + for(var/obj/abstract/landmark/start/S in global.all_landmarks) if(S.name != "AI") continue if(locate(/mob/living) in S.loc) diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm index 19a5202daa38..ca54acb3d7d3 100644 --- a/code/controllers/subsystems/machines.dm +++ b/code/controllers/subsystems/machines.dm @@ -94,7 +94,7 @@ if(current_step == this_step || (check_resumed && !resumed)) {\ for(var/datum/powernet/PN in powernets) qdel(PN) powernets.Cut() - setup_powernets_for_cables(global.cable_list) + setup_powernets_for_cables(global.all_cables) /datum/controller/subsystem/machines/proc/setup_powernets_for_cables(list/cables) for(var/obj/structure/cable/PC in cables) diff --git a/code/datums/underwear/underwear.dm b/code/datums/underwear/underwear.dm index 637bfe749ce5..ff0813a3e9f5 100644 --- a/code/datums/underwear/underwear.dm +++ b/code/datums/underwear/underwear.dm @@ -1,6 +1,8 @@ /**************************** * Category Collection Setup * ****************************/ +// TODO: replace underwear category stuff with decls or something? unlike player_setup_collection they're all singletons +// i hate to say it but the way this works may actually be perfect for /decl/hierarchy var/global/datum/category_collection/underwear/underwear = new() /datum/category_collection/underwear category_group_type = /datum/category_group/underwear diff --git a/code/game/antagonist/antagonist_place.dm b/code/game/antagonist/antagonist_place.dm index 1a69b0a7f26f..a81a4cb0dfb4 100644 --- a/code/game/antagonist/antagonist_place.dm +++ b/code/game/antagonist/antagonist_place.dm @@ -1,7 +1,7 @@ /decl/special_role/proc/get_starting_locations() if(landmark_id) starting_locations = list() - for(var/obj/abstract/landmark/L in global.landmarks_list) + for(var/obj/abstract/landmark/L in global.all_landmarks) if(L.name == landmark_id) starting_locations |= get_turf(L) diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index 9e085a1c4415..2c52112cbc66 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -445,7 +445,7 @@ /datum/job/proc/get_roundstart_spawnpoint() var/list/loc_list = list() - for(var/obj/abstract/landmark/start/sloc in global.landmarks_list) + for(var/obj/abstract/landmark/start/sloc in global.all_landmarks) if(sloc.name != title) continue if(locate(/mob/living) in sloc.loc) continue loc_list += sloc diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index bb8fda1746f7..6053e343fad9 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -55,7 +55,7 @@ return ..() var/obj/L = null - for(var/obj/abstract/landmark/sloc in global.landmarks_list) + for(var/obj/abstract/landmark/sloc in global.all_landmarks) if(sloc.name != C.data || (locate(/mob/living) in sloc.loc)) continue L = sloc diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 827773adb4cc..157e64b348f6 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -1,3 +1,4 @@ +var/global/list/obj/abstract/landmark/all_landmarks = list() /obj/abstract/landmark name = "landmark" var/delete_me = 0 @@ -7,13 +8,13 @@ tag = "landmark*[name]" if(delete_me) return INITIALIZE_HINT_QDEL - global.landmarks_list += src + global.all_landmarks += src /obj/abstract/landmark/proc/delete() delete_me = TRUE /obj/abstract/landmark/Destroy() - global.landmarks_list -= src + global.all_landmarks -= src return ..() /obj/abstract/landmark/start diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index 91c1c3b66c1a..2d54bf5b1bfa 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -50,13 +50,11 @@ update_nano_data() src.uplink_owner = owner - world_uplinks += src uses = telecrystals START_PROCESSING(SSobj, src) /obj/item/uplink/Destroy() uplink_owner = null - world_uplinks -= src STOP_PROCESSING(SSobj, src) return ..() diff --git a/code/modules/admin/secrets/fun_secrets/break_some_lights.dm b/code/modules/admin/secrets/fun_secrets/break_some_lights.dm index 702b8d3427a5..f3784b1c16d2 100644 --- a/code/modules/admin/secrets/fun_secrets/break_some_lights.dm +++ b/code/modules/admin/secrets/fun_secrets/break_some_lights.dm @@ -11,7 +11,7 @@ var/list/epicentreList = list() for(var/i in 1 to 2) var/list/possibleEpicentres = list() - for(var/obj/abstract/landmark/newEpicentre in global.landmarks_list) + for(var/obj/abstract/landmark/newEpicentre in global.all_landmarks) if(newEpicentre.name == "lightsout" && !(newEpicentre in epicentreList)) possibleEpicentres += newEpicentre if(length(possibleEpicentres)) diff --git a/code/modules/chatter/_chatter.dm b/code/modules/chatter/_chatter.dm index 9dbbc5b0c963..06fd5c76bac1 100644 --- a/code/modules/chatter/_chatter.dm +++ b/code/modules/chatter/_chatter.dm @@ -14,7 +14,7 @@ calls_and_responses = list( new /datum/chatter_conversation/debug_one ) - + /datum/chatter_conversation/debug_one/create_lines() chatter_lines = list( new /datum/chatter_line("Sir One", "Dame Two", "This is $NAME$ to $TARGET$, what's our vector, Victor?"), @@ -48,7 +48,7 @@ create_conversations() next_chatter_time = world.time + rand(min_chatter_time_elapsed, max_chatter_time_elapsed) if(listener_landmark && ispath(listener_instance)) - for(var/obj/abstract/landmark/landmark in global.landmarks_list) + for(var/obj/abstract/landmark/landmark in global.all_landmarks) if(landmark.name != listener_landmark) continue var/turf/T = get_turf(landmark) @@ -94,7 +94,7 @@ next_chatter_time = world.time + rand(min_chatter_time_elapsed, max_chatter_time_elapsed) else next_chatter_time = world.time + rand(min_line_time, max_line_time) - + /decl/radio_chatter/proc/hear_chat() if(current_dialogue_sequence) interrupted = TRUE diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index 044ee78d3d7c..b2f5a88a05e9 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -110,6 +110,9 @@ /datum/category_item/player_setup_item/physical/body/sanitize_character() var/decl/species/mob_species = get_species_by_key(pref.species) + if(!mob_species || (mob_species.spawn_flags & SPECIES_IS_RESTRICTED)) + pref.species = global.using_map.default_species + mob_species = get_species_by_key(pref.species) var/decl/bodytype/mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype if(mob_bodytype.appearance_flags & HAS_SKIN_COLOR) pref.skin_colour = pref.skin_colour || mob_bodytype.base_color || COLOR_BLACK @@ -122,9 +125,6 @@ pref.blood_type = sanitize_text(pref.blood_type, initial(pref.blood_type)) - if(!pref.species || !(pref.species in get_playable_species())) - pref.species = global.using_map.default_species - if(!pref.blood_type || !(pref.blood_type in mob_species.blood_types)) pref.blood_type = pickweight(mob_species.blood_types) diff --git a/code/modules/events/apc_damage.dm b/code/modules/events/apc_damage.dm index a3af950e8e23..4855cc37b22d 100644 --- a/code/modules/events/apc_damage.dm +++ b/code/modules/events/apc_damage.dm @@ -22,7 +22,7 @@ var/list/possibleEpicentres = list() var/list/apcs = list() - for(var/obj/abstract/landmark/newEpicentre in global.landmarks_list) + for(var/obj/abstract/landmark/newEpicentre in global.all_landmarks) if(newEpicentre.name == "lightsout") possibleEpicentres += newEpicentre diff --git a/code/modules/events/rogue_drones.dm b/code/modules/events/rogue_drones.dm index c5d0df69341e..2ea63e27e717 100644 --- a/code/modules/events/rogue_drones.dm +++ b/code/modules/events/rogue_drones.dm @@ -5,7 +5,7 @@ /datum/event/rogue_drone/start() //spawn them at the same place as carp var/list/possible_spawns = list() - for(var/obj/abstract/landmark/C in global.landmarks_list) + for(var/obj/abstract/landmark/C in global.all_landmarks) if(C.name == "carpspawn") possible_spawns.Add(C) diff --git a/code/modules/keybindings/_keybindings.dm b/code/modules/keybindings/_keybindings.dm index d23b116879ed..67710245b909 100644 --- a/code/modules/keybindings/_keybindings.dm +++ b/code/modules/keybindings/_keybindings.dm @@ -1,9 +1,11 @@ /datum/keybinding + abstract_type = /datum/keybinding /// A default hotkey keys. var/list/hotkey_keys /// A classic hotkey keys when client don't use hotkey mode. Uses `hotkey_keys` if not defined. var/list/classic_keys + // TODO: convert to /decl/keybinding, replace name with uid and full_name with name /// A unique keybind id for preference storing. var/name /// A full keybind name for displaying. diff --git a/code/modules/keybindings/admin.dm b/code/modules/keybindings/admin.dm index 9b433212567e..23a6d425f974 100644 --- a/code/modules/keybindings/admin.dm +++ b/code/modules/keybindings/admin.dm @@ -1,4 +1,5 @@ /datum/keybinding/admin + abstract_type = /datum/keybinding/admin category = CATEGORY_ADMIN /datum/keybinding/admin/can_use(client/user) diff --git a/code/modules/keybindings/client.dm b/code/modules/keybindings/client.dm index e6f5ea8ec35b..8e1cc489b6e6 100644 --- a/code/modules/keybindings/client.dm +++ b/code/modules/keybindings/client.dm @@ -1,4 +1,5 @@ /datum/keybinding/client + abstract_type = /datum/keybinding/client category = CATEGORY_CLIENT /datum/keybinding/client/hotkey_mode diff --git a/code/modules/keybindings/communication.dm b/code/modules/keybindings/communication.dm index 9d6fadf4a1cb..7f1b6f76ac72 100644 --- a/code/modules/keybindings/communication.dm +++ b/code/modules/keybindings/communication.dm @@ -1,4 +1,5 @@ /datum/keybinding/client/communication + abstract_type = /datum/keybinding/client/communication category = CATEGORY_COMMUNICATION /datum/keybinding/client/communication/ooc diff --git a/code/modules/keybindings/human.dm b/code/modules/keybindings/human.dm index c93ddcc13cfd..cc283c2f1580 100644 --- a/code/modules/keybindings/human.dm +++ b/code/modules/keybindings/human.dm @@ -1,4 +1,5 @@ /datum/keybinding/human + abstract_type = /datum/keybinding/human category = CATEGORY_HUMAN /datum/keybinding/human/can_use(client/user) diff --git a/code/modules/keybindings/living.dm b/code/modules/keybindings/living.dm index 334811f9524c..7f9ba3530a2c 100644 --- a/code/modules/keybindings/living.dm +++ b/code/modules/keybindings/living.dm @@ -1,4 +1,5 @@ /datum/keybinding/living + abstract_type = /datum/keybinding/living category = CATEGORY_LIVING /datum/keybinding/living/can_use(client/user) diff --git a/code/modules/keybindings/mob.dm b/code/modules/keybindings/mob.dm index 4ab7f0f14f96..73a6bc128a75 100644 --- a/code/modules/keybindings/mob.dm +++ b/code/modules/keybindings/mob.dm @@ -1,4 +1,5 @@ /datum/keybinding/mob + abstract_type = /datum/keybinding/mob category = CATEGORY_MOB /datum/keybinding/mob/can_use(client/user) diff --git a/code/modules/keybindings/movement.dm b/code/modules/keybindings/movement.dm index df313a4fd83d..78e1b4417c86 100644 --- a/code/modules/keybindings/movement.dm +++ b/code/modules/keybindings/movement.dm @@ -1,4 +1,5 @@ /datum/keybinding/movement + abstract_type = /datum/keybinding/movement category = CATEGORY_MOVEMENT /datum/keybinding/movement/north diff --git a/code/modules/keybindings/robot.dm b/code/modules/keybindings/robot.dm index 37ecc1772d3d..c598ffb77849 100644 --- a/code/modules/keybindings/robot.dm +++ b/code/modules/keybindings/robot.dm @@ -1,4 +1,5 @@ /datum/keybinding/robot + abstract_type = /datum/keybinding/robot category = CATEGORY_ROBOT /datum/keybinding/robot/can_use(client/user) diff --git a/code/modules/mob/living/human/human_species.dm b/code/modules/mob/living/human/human_presets.dm similarity index 89% rename from code/modules/mob/living/human/human_species.dm rename to code/modules/mob/living/human/human_presets.dm index 90977e6035a7..5490d841c7c4 100644 --- a/code/modules/mob/living/human/human_species.dm +++ b/code/modules/mob/living/human/human_presets.dm @@ -3,6 +3,15 @@ status_flags = GODMODE|CANPUSH virtual_mob = null +/proc/get_mannequin(var/ckey) + var/static/list/mob/living/human/dummy/mannequin/mannequins = list() + if(SSatoms.atom_init_stage < INITIALIZATION_INNEW_REGULAR) + return + . = mannequins[ckey] + if(!.) + . = new /mob/living/human/dummy/mannequin() + mannequins[ckey] = . + /mob/living/human/dummy/mannequin/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) . = ..() STOP_PROCESSING(SSmobs, src) diff --git a/code/modules/mob/observer/eye/freelook/ai/cameranet.dm b/code/modules/mob/observer/eye/freelook/ai/cameranet.dm index d6653c5dfd85..90e270c35ddf 100644 --- a/code/modules/mob/observer/eye/freelook/ai/cameranet.dm +++ b/code/modules/mob/observer/eye/freelook/ai/cameranet.dm @@ -1,7 +1,7 @@ // CAMERA NET // // The datum containing all the chunks. - +var/global/datum/visualnet/camera/cameranet = new() /datum/visualnet/camera // The security cameras on the map, no matter if they work or not. This list only contains cameras of type /obj/machinery/camera. var/list/cameras diff --git a/code/modules/mob/observer/eye/freelook/update_triggers.dm b/code/modules/mob/observer/eye/freelook/update_triggers.dm index 674973f5e4a7..197fb081c4b3 100644 --- a/code/modules/mob/observer/eye/freelook/update_triggers.dm +++ b/code/modules/mob/observer/eye/freelook/update_triggers.dm @@ -4,7 +4,7 @@ /proc/updateVisibility(atom/A, var/opacity_check = 1) if(GAME_STATE >= RUNLEVEL_GAME) - for(var/datum/visualnet/VN in visual_nets) + for(var/datum/visualnet/VN in all_visual_nets) VN.update_visibility(A, opacity_check) /turf/drain_power() diff --git a/code/modules/mob/observer/eye/freelook/visualnet.dm b/code/modules/mob/observer/eye/freelook/visualnet.dm index 59d409d2224e..c71be4a09622 100644 --- a/code/modules/mob/observer/eye/freelook/visualnet.dm +++ b/code/modules/mob/observer/eye/freelook/visualnet.dm @@ -1,7 +1,7 @@ // VISUAL NET // // The datum containing all the chunks. - +var/global/list/datum/visualnet/all_visual_nets = list() /datum/visualnet // The chunks of the map, mapping the areas that an object can see. var/list/chunks = list() @@ -11,12 +11,12 @@ /datum/visualnet/New() ..() - visual_nets += src + all_visual_nets += src if(!valid_source_types) valid_source_types = list() /datum/visualnet/Destroy() - visual_nets -= src + all_visual_nets -= src for(var/source in sources) remove_source(source, FALSE) sources.Cut() diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index fa65282b349a..43b674835701 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -75,21 +75,21 @@ if(move) var/obj/loc_landmark - for(var/obj/abstract/landmark/start/sloc in global.landmarks_list) + for(var/obj/abstract/landmark/start/sloc in global.all_landmarks) if (sloc.name != "AI") continue if (locate(/mob/living) in sloc.loc) continue loc_landmark = sloc if (!loc_landmark) - for(var/obj/abstract/landmark/tripai in global.landmarks_list) + for(var/obj/abstract/landmark/tripai in global.all_landmarks) if (tripai.name == "tripai") if((locate(/mob/living) in tripai.loc) || (locate(/obj/structure/aicore) in tripai.loc)) continue loc_landmark = tripai if (!loc_landmark) to_chat(O, "Oh god sorry we can't find an unoccupied AI spawn location, so we're spawning you on top of someone.") - for(var/obj/abstract/landmark/start/sloc in global.landmarks_list) + for(var/obj/abstract/landmark/start/sloc in global.all_landmarks) if (sloc.name == "AI") loc_landmark = sloc O.forceMove(loc_landmark ? loc_landmark.loc : get_turf(src)) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index 0eb0729530dd..56ef6ac56bf9 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -22,6 +22,8 @@ If d1 = dir1 and d2 = dir2, it's a full X-X cable, getting from dir1 to dir2 By design, d1 is the smallest direction and d2 is the highest */ +/// Tracks all cable instances, so that powernets don't have to look through the entire world all the time +var/global/list/obj/structure/cable/all_cables = list() /obj/structure/cable name = "power cable" desc = "A flexible superconducting cable for heavy-duty power transfer." @@ -100,12 +102,12 @@ By design, d1 is the smallest direction and d2 is the highest var/turf/T = src.loc // hide if turf is not intact if(level == LEVEL_BELOW_PLATING && T) hide(!T.is_plating()) - global.cable_list += src //add it to the global cable list + global.all_cables += src //add it to the global cable list /obj/structure/cable/Destroy() // called when a cable is deleted if(powernet) cut_cable_from_powernet() // update the powernets - global.cable_list -= src // remove it from global cable list + global.all_cables -= src // remove it from global cable list . = ..() // then go ahead and delete the cable // Ghost examining the cable -> tells him the power diff --git a/code/modules/shuttles/shuttle_specops.dm b/code/modules/shuttles/shuttle_specops.dm index 90a54b1eab08..5ffe256bd8d1 100644 --- a/code/modules/shuttles/shuttle_specops.dm +++ b/code/modules/shuttles/shuttle_specops.dm @@ -146,10 +146,10 @@ sleep(10) var/spawn_marauder[] = new() - for(var/obj/abstract/landmark/L in global.landmarks_list) + for(var/obj/abstract/landmark/L in global.all_landmarks) if(L.name == "Marauder Entry") spawn_marauder.Add(L) - for(var/obj/abstract/landmark/L in global.landmarks_list) + for(var/obj/abstract/landmark/L in global.all_landmarks) if(L.name == "Marauder Exit") var/obj/effect/portal/P = new(L.loc) P.set_invisibility(INVISIBILITY_ABSTRACT)//So it is not seen by anyone. diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index 89238fa88d21..20ba36dac7da 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -184,7 +184,7 @@ /datum/unit_test/wire_dir_and_icon_stat/start_test() var/list/bad_cables = list() - for(var/obj/structure/cable/C in global.cable_list) + for(var/obj/structure/cable/C in global.all_cables) var/expected_icon_state = "[C.d1]-[C.d2]" if(C.icon_state != expected_icon_state) bad_cables |= C @@ -411,7 +411,7 @@ var/safe_landmarks = 0 var/space_landmarks = 0 - for(var/lm in global.landmarks_list) + for(var/lm in global.all_landmarks) var/obj/abstract/landmark/landmark = lm if(istype(landmark, /obj/abstract/landmark/test/safe_turf)) log_debug("Safe landmark found: [log_info_line(landmark)]") @@ -706,7 +706,7 @@ var/global/_unit_test_sort_junctions = list() exceptions_by_turf[T] += exception[4] exceptions = exceptions_by_turf - for(var/obj/structure/cable/C in global.cable_list) + for(var/obj/structure/cable/C in global.all_cables) if(!QDELETED(C) && !all_ends_connected(C)) failures++ diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index a131d1ee7bdc..9c25e0806105 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -22,16 +22,23 @@ if(!isspaceturf(T)) //If the above isn't a space turf then we force it to find one will most likely pick 1,1,1 T = locate(/turf/space) - var/list/bodytype_pairings = get_bodytype_species_pairs() - for(var/decl/bodytype/bodytype in bodytype_pairings) - var/decl/species/species = bodytype_pairings[bodytype] - var/mob/living/human/test_subject = new(null, species.name, null, bodytype) + var/datum/mob_snapshot/dummy_appearance = new + for(var/decl/bodytype/bodytype in decls_repository.get_decls_of_subtype_unassociated(/decl/bodytype)) + if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here + continue + var/decl/species/species = bodytype.get_user_species_for_validation() + ASSERT(species) + dummy_appearance.root_species = species + dummy_appearance.root_bodytype = bodytype + var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) if(test_subject.need_breathe()) test_subject.apply_effect(20, STUN, 0) var/obj/item/organ/internal/lungs/L = test_subject.get_organ(test_subject.get_bodytype().breathing_organ, /obj/item/organ/internal/lungs) if(L) L.last_successful_breath = -INFINITY test_subjects["[bodytype.type]"] = list(test_subject, damage_check(test_subject, OXY)) + QDEL_NULL(dummy_appearance) + return 1 /datum/unit_test/human_breath/check_result() diff --git a/code/unit_tests/organ_tests.dm b/code/unit_tests/organ_tests.dm index 86d3406a5f30..ec3df05f5d19 100644 --- a/code/unit_tests/organ_tests.dm +++ b/code/unit_tests/organ_tests.dm @@ -116,10 +116,15 @@ /datum/unit_test/bodytype_organ_creation/start_test() var/failcount = 0 - var/list/bodytype_pairings = get_bodytype_species_pairs() - for(var/decl/bodytype/bodytype in bodytype_pairings) - var/decl/species/species = bodytype_pairings[bodytype] - var/mob/living/human/test_subject = new(null, species.name, null, bodytype) + var/datum/mob_snapshot/dummy_appearance = new + for(var/decl/bodytype/bodytype in decls_repository.get_decls_of_subtype_unassociated(/decl/bodytype)) + if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here + continue + var/decl/species/species = bodytype.get_user_species_for_validation() + ASSERT(species) + dummy_appearance.root_species = species + dummy_appearance.root_bodytype = bodytype + var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) var/fail = 0 fail |= !check_internal_organs(test_subject, bodytype) @@ -127,6 +132,7 @@ fail |= !check_organ_parents(test_subject, bodytype) if(fail) failcount++ + QDEL_NULL(dummy_appearance) if(failcount) fail("[failcount] bodytypes were created with invalid organ configuration.") @@ -249,10 +255,15 @@ /datum/unit_test/bodytype_organ_lists_update/start_test() var/failcount = 0 - var/list/bodytype_pairings = get_bodytype_species_pairs() - for(var/decl/bodytype/bodytype in bodytype_pairings) - var/decl/species/species = bodytype_pairings[bodytype] - var/mob/living/human/test_subject = new(null, species.name, null, bodytype) + var/datum/mob_snapshot/dummy_appearance = new + for(var/decl/bodytype/bodytype in decls_repository.get_decls_of_subtype_unassociated(/decl/bodytype)) + if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here + continue + var/decl/species/species = bodytype.get_user_species_for_validation() + ASSERT(species) + dummy_appearance.root_species = species + dummy_appearance.root_bodytype = bodytype + var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) for(var/O in test_subject.get_internal_organs()) if(!test_internal_organ(test_subject, O)) @@ -261,6 +272,7 @@ for(var/O in test_subject.get_external_organs()) if(!test_external_organ(test_subject, O)) failcount++ + QDEL_NULL(dummy_appearance) if(failcount) fail("[failcount] organs failed to be removed and replaced correctly.") diff --git a/code/unit_tests/power_tests.dm b/code/unit_tests/power_tests.dm index 8715e17efd54..16df5f3e9d90 100644 --- a/code/unit_tests/power_tests.dm +++ b/code/unit_tests/power_tests.dm @@ -21,7 +21,7 @@ var/failed = 0 var/list/found_cables = list() - for(var/obj/structure/cable/C in global.cable_list) + for(var/obj/structure/cable/C in global.all_cables) if(C in found_cables) continue var/list/to_search = list(C) diff --git a/code/unit_tests/unit_test.dm b/code/unit_tests/unit_test.dm index 47b103f626ea..82a186cb0d1c 100644 --- a/code/unit_tests/unit_test.dm +++ b/code/unit_tests/unit_test.dm @@ -136,7 +136,7 @@ var/global/ascii_reset = "[ascii_esc]\[0m" /datum/unit_test/proc/get_safe_turf() check_cleanup = TRUE if(!safe_landmark) - for(var/landmark in global.landmarks_list) + for(var/landmark in global.all_landmarks) if(istype(landmark, /obj/abstract/landmark/test/safe_turf)) safe_landmark = landmark break @@ -145,7 +145,7 @@ var/global/ascii_reset = "[ascii_esc]\[0m" /datum/unit_test/proc/get_space_turf() check_cleanup = TRUE if(!space_landmark) - for(var/landmark in global.landmarks_list) + for(var/landmark in global.all_landmarks) if(istype(landmark, /obj/abstract/landmark/test/space_turf)) space_landmark = landmark break diff --git a/maps/~mapsystem/maps.dm b/maps/~mapsystem/maps.dm index 84a5e81f276c..394aa2eceaca 100644 --- a/maps/~mapsystem/maps.dm +++ b/maps/~mapsystem/maps.dm @@ -564,6 +564,13 @@ var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable if(!length(SSmapping.contact_levels)) log_error("[name] has no contact levels!") . = FALSE + var/decl/species/default_species_decl = get_species_by_key(default_species) + if(default_species_decl.species_flags & SPECIES_IS_RESTRICTED) + log_error("[name]'s default species [default_species_decl.type] is set to restricted!") + if(default_species_decl.species_flags & SPECIES_IS_WHITELISTED) + log_error("[name]'s default species [default_species_decl.type] is set to whitelisted!") + if(default_species_decl.species_flags & SPECIES_CAN_JOIN) + log_error("[name]'s default species [default_species_decl.type] is not allowed to join the game!") /datum/map/proc/get_available_submap_archetypes() return decls_repository.get_decls_of_subtype_unassociated(/decl/submap_archetype) diff --git a/nebula.dme b/nebula.dme index 5c8541c4f63a..5287d0c8535b 100644 --- a/nebula.dme +++ b/nebula.dme @@ -2941,8 +2941,8 @@ #include "code\modules\mob\living\human\human_movement.dm" #include "code\modules\mob\living\human\human_organs.dm" #include "code\modules\mob\living\human\human_powers.dm" +#include "code\modules\mob\living\human\human_presets.dm" #include "code\modules\mob\living\human\human_skin.dm" -#include "code\modules\mob\living\human\human_species.dm" #include "code\modules\mob\living\human\human_verbs.dm" #include "code\modules\mob\living\human\life.dm" #include "code\modules\mob\living\human\login.dm" From 8ec5fd12d5480661c4b41689f7b3ef5fe5e7a064 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 18 Feb 2025 05:00:12 -0500 Subject: [PATCH 070/512] Consolidate or remove old global variables --- code/_global_vars/configuration.dm | 4 ---- code/_global_vars/lists/flavor.dm | 2 ++ code/_global_vars/lists/logs.dm | 1 - code/_global_vars/lists/names.dm | 18 +----------------- code/_global_vars/lists/objects.dm | 1 - code/_global_vars/sound.dm | 1 + code/datums/observation/~cleanup.dm | 2 +- code/game/objects/explosion.dm | 3 +-- code/modules/admin/admin_verbs.dm | 2 -- .../secrets/admin_secrets/show_signalers.dm | 15 --------------- code/modules/admin/verbs/debug.dm | 16 ---------------- code/modules/events/gravity.dm | 14 +++++--------- code/modules/mob/mob.dm | 5 ++++- code/unit_tests/observation_tests.dm | 2 +- nebula.dme | 1 - 15 files changed, 16 insertions(+), 71 deletions(-) delete mode 100644 code/modules/admin/secrets/admin_secrets/show_signalers.dm diff --git a/code/_global_vars/configuration.dm b/code/_global_vars/configuration.dm index c9347417bba6..377c65a2aa30 100644 --- a/code/_global_vars/configuration.dm +++ b/code/_global_vars/configuration.dm @@ -6,10 +6,6 @@ var/global/join_motd = null var/global/secret_force_mode = "secret" // if this is anything but "secret", the secret rotation will forceably choose this mode. -var/global/Debug2 = 0 - -var/global/gravity_is_on = 1 - // Database connections. A connection is established on world creation. // Ideally, the connection dies when the server restarts (After feedback logging.). var/global/DBConnection/dbcon // General-purpose record database. diff --git a/code/_global_vars/lists/flavor.dm b/code/_global_vars/lists/flavor.dm index b2096edc0a4f..80c11924a919 100644 --- a/code/_global_vars/lists/flavor.dm +++ b/code/_global_vars/lists/flavor.dm @@ -71,6 +71,8 @@ var/global/list/numbers_as_words = list("One", "Two", "Three", "Four", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen") +// This is, for some reason, used exclusively for headphones, jukeboxes, and boomboxes. +// It also seems to exist mostly for the purpose of allowing admins to upload their own songs to those at runtime? var/global/list/music_tracks = list( "Beyond" = /decl/music_track/ambispace, "Clouds of Fire" = /decl/music_track/clouds_of_fire, diff --git a/code/_global_vars/lists/logs.dm b/code/_global_vars/lists/logs.dm index 44b16a6dbacb..8face994fe93 100644 --- a/code/_global_vars/lists/logs.dm +++ b/code/_global_vars/lists/logs.dm @@ -1,4 +1,3 @@ var/global/list/bombers = list() var/global/list/admin_log = list() -var/global/list/lastsignalers = list() // Keeps last 100 signals here in format: "[src] used \ref[src] @ location [src.loc]: [freq]/[code]" var/global/list/lawchanges = list() // Stores who uploaded laws to which silicon-based lifeform, and what the law was. diff --git a/code/_global_vars/lists/names.dm b/code/_global_vars/lists/names.dm index efb1b85ba2b3..2bd23f308908 100644 --- a/code/_global_vars/lists/names.dm +++ b/code/_global_vars/lists/names.dm @@ -7,22 +7,6 @@ var/global/list/wizard_second = file2list("config/names/wizardsecond.txt") var/global/list/verbs = file2list("config/names/verbs.txt") var/global/list/adjectives = file2list("config/names/adjectives.txt") -var/global/list/descriptive_slot_names = list( - slot_back_str = "Back", - slot_w_uniform_str = "Uniform", - slot_head_str = "Head", - slot_wear_suit_str = "Suit", - slot_l_ear_str = "Left Ear", - slot_r_ear_str = "Right Ear", - slot_belt_str = "Belt", - slot_shoes_str = "Shoes", - slot_wear_mask_str = "Mask", - slot_handcuffed_str = "Handcuffs", - slot_wear_id_str = "ID", - slot_gloves_str = "Gloves", - slot_glasses_str = "Glasses", - slot_l_store_str = "Left Pocket", - slot_r_store_str = "Right Pocket", - slot_s_store_str = "Suit Storage", +var/global/list/abstract_slot_names = list( slot_in_backpack_str = "In Backpack" ) diff --git a/code/_global_vars/lists/objects.dm b/code/_global_vars/lists/objects.dm index f6e27d7c419b..97d7e3490ce3 100644 --- a/code/_global_vars/lists/objects.dm +++ b/code/_global_vars/lists/objects.dm @@ -3,7 +3,6 @@ var/global/list/sec_hud_users = list() // List of all entities using a var/global/list/jani_hud_users = list() var/global/list/hud_icon_reference = list() var/global/list/listening_objects = list() // List of objects that need to be able to hear, used to avoid recursive searching through contents. -var/global/list/global_map = list() var/global/datum/universal_state/universe = new diff --git a/code/_global_vars/sound.dm b/code/_global_vars/sound.dm index 9525f1b0b2b3..bab80ae12bee 100644 --- a/code/_global_vars/sound.dm +++ b/code/_global_vars/sound.dm @@ -1,3 +1,4 @@ +// TODO: make a code/game/sound folder to store these and playsound code? var/global/list/shatter_sound = list( 'sound/effects/Glassbr1.ogg', 'sound/effects/Glassbr2.ogg', diff --git a/code/datums/observation/~cleanup.dm b/code/datums/observation/~cleanup.dm index 5ac8158aeec5..39c9dc8152c2 100644 --- a/code/datums/observation/~cleanup.dm +++ b/code/datums/observation/~cleanup.dm @@ -47,7 +47,7 @@ var/global/list/_all_global_event_listeners = list() #endif /proc/cleanup_global_listener(datum/listener) - for(var/decl/observ/event in decls_repository.get_decls_of_subtype_unassociated(/decl/observ)) + for(var/decl/observ/event as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/observ)) if(event.unregister_global(listener)) log_debug("[event] ([event.type]) - [log_info_line(listener)] was deleted while still globally registered to an event.") if(!listener.global_listen_count) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 638b704a188d..f037c65998aa 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -89,8 +89,7 @@ addtimer(CALLBACK(AM, TYPE_PROC_REF(/atom/movable, throw_at), throw_target, throw_dist, throw_dist), 0) var/took = (REALTIMEOFDAY-start_time)/10 - if(Debug2) - to_world_log("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.") + testing("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.") return 1 #define EXPLFX_NONE 0 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index aba99df3baf1..9c203d83c176 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -164,7 +164,6 @@ var/global/list/admin_verbs_debug = list( /datum/admins/proc/jump_to_fluid_source, /datum/admins/proc/jump_to_fluid_active, /client/proc/cmd_admin_list_open_jobs, - /client/proc/Debug2, /client/proc/ZASSettings, /client/proc/cmd_debug_make_powernets, /client/proc/debug_controller, @@ -288,7 +287,6 @@ var/global/list/admin_verbs_hideable = list( /client/proc/cmd_admin_list_open_jobs, /client/proc/callproc, /client/proc/callproc_target, - /client/proc/Debug2, /client/proc/reload_admins, /client/proc/cmd_debug_make_powernets, /client/proc/debug_controller, diff --git a/code/modules/admin/secrets/admin_secrets/show_signalers.dm b/code/modules/admin/secrets/admin_secrets/show_signalers.dm deleted file mode 100644 index 3ddf2a4e2ffd..000000000000 --- a/code/modules/admin/secrets/admin_secrets/show_signalers.dm +++ /dev/null @@ -1,15 +0,0 @@ -/datum/admin_secret_item/admin_secret/show_signalers - name = "Show Last Signalers" - -/datum/admin_secret_item/admin_secret/show_signalers/name() - return "Show Last [length(global.lastsignalers)] Signaler\s" - -/datum/admin_secret_item/admin_secret/show_signalers/execute(var/mob/user) - . = ..() - if(!.) - return - - var/dat = "Showing last [length(global.lastsignalers)] signalers.
" - for(var/sig in global.lastsignalers) - dat += "[sig]
" - show_browser(user, dat, "window=lastsignalers;size=800x500") diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index e43cf8d96caa..edc6df1696af 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -1,19 +1,3 @@ -/client/proc/Debug2() - set category = "Debug" - set name = "Debug-Game" - if(!check_rights(R_DEBUG)) return - - if(Debug2) - Debug2 = 0 - message_admins("[key_name(src)] toggled debugging off.") - log_admin("[key_name(src)] toggled debugging off.") - else - Debug2 = 1 - message_admins("[key_name(src)] toggled debugging on.") - log_admin("[key_name(src)] toggled debugging on.") - - SSstatistics.add_field_details("admin_verb","DG2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - // callproc moved to code/modules/admin/callproc diff --git a/code/modules/events/gravity.dm b/code/modules/events/gravity.dm index 60e8c51bc91c..4bbc5e3a50ba 100644 --- a/code/modules/events/gravity.dm +++ b/code/modules/events/gravity.dm @@ -8,17 +8,13 @@ command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system reinitializes.", "[location_name()] Gravity Subsystem", zlevels = affecting_z) /datum/event/gravity/start() - gravity_is_on = 0 for(var/area/A in global.areas) if(A.z in affecting_z) - A.gravitychange(gravity_is_on) + A.gravitychange(FALSE) /datum/event/gravity/end() - if(!gravity_is_on) - gravity_is_on = 1 - - for(var/area/A in global.areas) - if((A.z in affecting_z) && initial(A.has_gravity)) - A.gravitychange(gravity_is_on) + for(var/area/A in global.areas) + if((A.z in affecting_z) && initial(A.has_gravity)) + A.gravitychange(TRUE) - command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.", "[location_name()] Gravity Subsystem", zlevels = affecting_z) + command_announcement.Announce("Gravity generators are again functioning within normal parameters. Sorry for any inconvenience.", "[location_name()] Gravity Subsystem", zlevels = affecting_z) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index aaef91f9a84d..cbe88a39215b 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -309,7 +309,10 @@ client.eye = loc /mob/proc/get_descriptive_slot_name(var/slot) - return global.descriptive_slot_names[slot] || slot + if(global.abstract_slot_names[slot]) // this is an abstract slot like "in backpack" + return global.abstract_slot_names[slot] + var/datum/inventory_slot/slot_datum = get_inventory_slot_datum(slot) + return slot_datum?.slot_name || slot /mob/proc/show_stripping_window(mob/user) diff --git a/code/unit_tests/observation_tests.dm b/code/unit_tests/observation_tests.dm index fdc7c3e21a6d..b68e9fe6a0ae 100644 --- a/code/unit_tests/observation_tests.dm +++ b/code/unit_tests/observation_tests.dm @@ -26,7 +26,7 @@ LAZYCLEARLIST(datums_of_interest) /datum/unit_test/observation/proc/sanity_check_events(var/phase) - for(var/decl/observ/event in decls_repository.get_decls_of_subtype_unassociated(/decl/observ)) + for(var/decl/observ/event as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/observ)) var/null_count = 0 for(var/null_candidate in event.global_listeners) if(isnull(event.global_listeners[null_candidate])) diff --git a/nebula.dme b/nebula.dme index 5287d0c8535b..74979c73c72b 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1690,7 +1690,6 @@ #include "code\modules\admin\secrets\admin_secrets\show_crew_manifest.dm" #include "code\modules\admin\secrets\admin_secrets\show_game_mode.dm" #include "code\modules\admin\secrets\admin_secrets\show_law_changes.dm" -#include "code\modules\admin\secrets\admin_secrets\show_signalers.dm" #include "code\modules\admin\secrets\admin_secrets\toggle_circuits.dm" #include "code\modules\admin\secrets\admin_secrets\toggle_overmap_movement.dm" #include "code\modules\admin\secrets\admin_secrets\traitors_and_objectives.dm" From b36f610d6d52846c61881405acfe687056c5ec87 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 21:04:58 -0500 Subject: [PATCH 071/512] Fix setup_human breaking when passed supplied_appearance --- code/modules/mob/living/human/human.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index 0472a5074e30..481ebd65ebbf 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -975,7 +975,7 @@ //Human mob specific init code. Meant to be used only on init. /mob/living/human/proc/setup_human(species_name, datum/mob_snapshot/supplied_appearance) if(supplied_appearance) - species_name = supplied_appearance.root_species + species_name = supplied_appearance.root_species.name else if(!species_name) species_name = global.using_map.default_species //Humans cannot exist without a species! From 5b92c93c45a786b401692a9babfd3a967f2aca6f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 19 Feb 2025 22:13:53 -0500 Subject: [PATCH 072/512] Fix mob test bodytype validation --- code/unit_tests/mob_tests.dm | 5 ++--- code/unit_tests/organ_tests.dm | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 9c25e0806105..9cbaf2c509c4 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -24,10 +24,9 @@ T = locate(/turf/space) var/datum/mob_snapshot/dummy_appearance = new for(var/decl/bodytype/bodytype in decls_repository.get_decls_of_subtype_unassociated(/decl/bodytype)) - if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here - continue var/decl/species/species = bodytype.get_user_species_for_validation() - ASSERT(species) + if(!species) + continue dummy_appearance.root_species = species dummy_appearance.root_bodytype = bodytype var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) diff --git a/code/unit_tests/organ_tests.dm b/code/unit_tests/organ_tests.dm index ec3df05f5d19..298f8825d996 100644 --- a/code/unit_tests/organ_tests.dm +++ b/code/unit_tests/organ_tests.dm @@ -121,7 +121,8 @@ if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here continue var/decl/species/species = bodytype.get_user_species_for_validation() - ASSERT(species) + if(!species) + continue dummy_appearance.root_species = species dummy_appearance.root_bodytype = bodytype var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) @@ -260,7 +261,8 @@ if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here continue var/decl/species/species = bodytype.get_user_species_for_validation() - ASSERT(species) + if(!species) + continue dummy_appearance.root_species = species dummy_appearance.root_bodytype = bodytype var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) From c0cc10e99124adedeec849f7d75c05986b1aec57 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 20:59:51 -0500 Subject: [PATCH 073/512] Fix parent_organ_data's has_children list increasing indefinitely --- code/modules/bodytype/_bodytype.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/bodytype/_bodytype.dm b/code/modules/bodytype/_bodytype.dm index 7bb3afd74473..0e2ef18ae68e 100644 --- a/code/modules/bodytype/_bodytype.dm +++ b/code/modules/bodytype/_bodytype.dm @@ -410,7 +410,7 @@ var/global/list/bodytypes_by_category = list() for(var/ltag in override_limb_types) has_limbs[ltag] = list("path" = override_limb_types[ltag]) - //Build organ descriptors + //Build organ descriptors and children lists for(var/organ_tag in has_limbs) var/list/organ_data = has_limbs[organ_tag] var/obj/item/organ/organ = organ_data["path"] @@ -421,6 +421,9 @@ var/global/list/bodytypes_by_category = list() LAZYADD(_organs_by_category[organ_cat], organ) LAZYINITLIST(_organ_tags_by_category) LAZYADD(_organ_tags_by_category[organ_cat], organ_tag) + var/list/parent_organ_data = has_limbs[organ::parent_organ] + if(parent_organ_data) + parent_organ_data["has_children"]++ for(var/organ_tag in has_organ) var/obj/item/organ/organ = has_organ[organ_tag] @@ -664,9 +667,6 @@ var/global/list/bodytypes_by_category = list() var/list/organ_data = has_limbs[limb_type] var/limb_path = organ_data["path"] var/obj/item/organ/external/E = new limb_path(H, null, supplied_data) //explicitly specify the dna and bodytype - if(E.parent_organ) - var/list/parent_organ_data = has_limbs[E.parent_organ] - parent_organ_data["has_children"]++ H.add_organ(E, GET_EXTERNAL_ORGAN(H, E.parent_organ), FALSE, FALSE, skip_health_update = TRUE) //Create missing internal organs From 1b2284b0553710bcce4f874d64fc6a483c2b310c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 20 Feb 2025 21:00:10 -0500 Subject: [PATCH 074/512] Fix mob and organ unit tests --- code/modules/mob/living/human/human.dm | 1 + code/modules/mob/mob_snapshot.dm | 9 +- code/modules/organs/external/_external.dm | 2 +- code/modules/organs/organ.dm | 7 +- code/unit_tests/mob_tests.dm | 2 +- code/unit_tests/organ_tests.dm | 101 +++++++++++----------- mods/species/drakes/species_bodytypes.dm | 4 +- 7 files changed, 65 insertions(+), 61 deletions(-) diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index 481ebd65ebbf..e4c18624c6f8 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -981,6 +981,7 @@ set_species(species_name, supplied_appearance?.root_bodytype) var/decl/bodytype/root_bodytype = get_bodytype() // root bodytype is set in set_species + ASSERT((!supplied_appearance?.root_bodytype) || (root_bodytype == supplied_appearance.root_bodytype)) if(!get_skin_colour()) set_skin_colour(root_bodytype.base_color, skip_update = TRUE) if(!get_eye_colour()) diff --git a/code/modules/mob/mob_snapshot.dm b/code/modules/mob/mob_snapshot.dm index 4f5441a8933e..7dea014aa94a 100644 --- a/code/modules/mob/mob_snapshot.dm +++ b/code/modules/mob/mob_snapshot.dm @@ -39,8 +39,8 @@ if(!condition.is_heritable) LAZYREMOVE(genetic_conditions, condition) -/datum/mob_snapshot/Clone() - var/datum/mob_snapshot/clone = ..() +/datum/mob_snapshot/PopulateClone(datum/mob_snapshot/clone) + clone = ..() if(clone) clone.real_name = real_name clone.eye_color = eye_color @@ -59,13 +59,12 @@ // Replaces UpdateAppearance(). /datum/mob_snapshot/proc/apply_appearance_to(mob/living/target) - if(istype(root_species)) + if(istype(root_species) && root_species != target.get_species()) if(istype(root_bodytype)) target.set_species(root_species.name, root_bodytype) else target.set_species(root_species.name) - - else if(istype(root_bodytype)) + else if(istype(root_bodytype) && target.get_bodytype() != root_bodytype) target.set_bodytype(root_bodytype) target.set_fingerprint(fingerprint) diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 1a68409f94da..24ea4429fcfc 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -112,7 +112,7 @@ fingerprint.completeness = rand(10,90) forensics.add_data(/datum/forensics/fingerprints, fingerprint) -/obj/item/organ/external/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance, decl/bodytype/new_bodytype) +/obj/item/organ/external/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance) . = ..() if(. != INITIALIZE_HINT_QDEL && isnull(pain_disability_threshold)) pain_disability_threshold = (max_damage * 0.75) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 87196b4663d6..d9835817d5a1 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -123,8 +123,11 @@ QDEL_NULL(organ_appearance) organ_appearance = supplied_appearance.Clone() blood_DNA = list(organ_appearance.unique_enzymes = organ_appearance.blood_type) - set_species(organ_appearance.root_species?.name || global.using_map.default_species) - if(organ_appearance.root_bodytype) + if(species != organ_appearance.root_species) + if(organ_appearance.root_bodytype && organ_appearance.root_bodytype != bodytype) + bodytype = organ_appearance.root_bodytype // this lets us take advantage of set_bodytype being called in set_species + set_species(organ_appearance.root_species?.name || global.using_map.default_species) + else if(organ_appearance.root_bodytype && organ_appearance.root_bodytype != bodytype) set_bodytype(organ_appearance.root_bodytype) /obj/item/organ/proc/set_bodytype(decl/bodytype/new_bodytype, override_material = null, apply_to_internal_organs = TRUE) diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 9cbaf2c509c4..578242d58e04 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -29,7 +29,7 @@ continue dummy_appearance.root_species = species dummy_appearance.root_bodytype = bodytype - var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) + var/mob/living/human/test_subject = new(T, species.name, dummy_appearance) if(test_subject.need_breathe()) test_subject.apply_effect(20, STUN, 0) var/obj/item/organ/internal/lungs/L = test_subject.get_organ(test_subject.get_bodytype().breathing_organ, /obj/item/organ/internal/lungs) diff --git a/code/unit_tests/organ_tests.dm b/code/unit_tests/organ_tests.dm index 298f8825d996..7aa38550be82 100644 --- a/code/unit_tests/organ_tests.dm +++ b/code/unit_tests/organ_tests.dm @@ -27,23 +27,23 @@ for(var/organ_tag in bodytype.has_organ) var/obj/item/organ/I = GET_INTERNAL_ORGAN(H, organ_tag) if(!istype(I)) - fail("[bodytype.name] failed to register internal organ for tag \"[organ_tag]\" to organ list.") + fail("[bodytype.type] failed to register internal organ for tag \"[organ_tag]\" to organ list.") . = 0 continue if(!(I in H.get_internal_organs())) - fail("[bodytype.name] failed to register internal organ for tag \"[organ_tag]\" to internal_organs.") + fail("[bodytype.type] failed to register internal organ for tag \"[organ_tag]\" to internal_organs.") . = 0 continue var/req_type = bodytype.has_organ[organ_tag] if(!istype(I, req_type)) - fail("[bodytype.name] incorrect type of internal organ created for tag \"[organ_tag]\". Expected [req_type], found [I.type].") + fail("[bodytype.type] incorrect type of internal organ created for tag \"[organ_tag]\". Expected [req_type], found [I.type].") . = 0 continue if(I.organ_tag != organ_tag) - fail("[bodytype.name] internal organ tag mismatch. Registered as \"[organ_tag]\", actual tag was \"[I.organ_tag]\".") + fail("[bodytype.type] internal organ tag mismatch. Registered as \"[organ_tag]\", actual tag was \"[I.organ_tag]\".") . = 0 if(!isnum(I.absolute_max_damage) || I.absolute_max_damage <= 0) - fail("[bodytype.name] internal organ has invalid absolute_max_damage value ([I.absolute_max_damage]).") + fail("[bodytype.type] internal organ has invalid absolute_max_damage value ([I.absolute_max_damage]).") . = 0 /datum/unit_test/bodytype_organ_creation/proc/check_external_organs(var/mob/living/human/H, var/decl/bodytype/bodytype) @@ -51,24 +51,24 @@ for(var/organ_tag in bodytype.has_limbs) var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(H, organ_tag) if(!istype(E)) - fail("[bodytype.name] failed to register external organ for tag \"[organ_tag]\" to organs_by_name.") + fail("[bodytype.type] failed to register external organ for tag \"[organ_tag]\" to organs_by_name.") . = 0 continue if(!(E in H.get_external_organs())) - fail("[bodytype.name] failed to register external organ for tag \"[organ_tag]\" to organs.") + fail("[bodytype.type] failed to register external organ for tag \"[organ_tag]\" to organs.") . = 0 continue var/list/organ_data = bodytype.has_limbs[organ_tag] var/req_type = organ_data["path"] if(!istype(E, req_type)) - fail("[bodytype.name] incorrect type of external organ created for tag \"[organ_tag]\". Expected [req_type], found [E.type].") + fail("[bodytype.type] incorrect type of external organ created for tag \"[organ_tag]\". Expected [req_type], found [E.type].") . = 0 continue if(E.organ_tag != organ_tag) - fail("[bodytype.name] external organ tag mismatch. Registered as \"[organ_tag]\", actual tag was \"[E.organ_tag]\".") + fail("[bodytype.type] external organ tag mismatch. Registered as \"[organ_tag]\", actual tag was \"[E.organ_tag]\".") . = 0 if(!isnum(E.absolute_max_damage) || E.absolute_max_damage <= 0) - fail("[bodytype.name] external organ has invalid absolute_max_damage value ([E.absolute_max_damage]).") + fail("[bodytype.type] external organ has invalid absolute_max_damage value ([E.absolute_max_damage]).") . = 0 /datum/unit_test/bodytype_organ_creation/proc/check_organ_parents(var/mob/living/human/H, var/decl/bodytype/bodytype) @@ -79,38 +79,38 @@ continue var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(H, E.parent_organ) if(!istype(parent)) - fail("[bodytype.name] external organ [E] could not find its parent in organs_by_name. Parent tag was \"[E.parent_organ]\".") + fail("[bodytype.type] external organ [E] could not find its parent in organs_by_name. Parent tag was \"[E.parent_organ]\".") . = 0 continue if(!(parent in external_organs)) - fail("[bodytype.name] external organ [E] could not find its parent in organs. Parent was [parent](parent.type). Parent tag was \"[E.parent_organ]\".") + fail("[bodytype.type] external organ [E] could not find its parent in organs. Parent was [parent](parent.type). Parent tag was \"[E.parent_organ]\".") . = 0 continue if(E.parent != parent) - fail("[bodytype.name] external organ [E] parent mismatch. Parent reference was [E.parent] with tag \"[E.parent? E.parent.organ_tag : "N/A"]\". Parent was [parent](parent.type). Parent tag was \"[E.parent_organ]\".") + fail("[bodytype.type] external organ [E] parent mismatch. Parent reference was [E.parent] with tag \"[E.parent? E.parent.organ_tag : "N/A"]\". Parent was [parent](parent.type). Parent tag was \"[E.parent_organ]\".") . = 0 continue if(!(E in parent.children)) - fail("[bodytype.name] external organ [E] was not found in parent's children. Parent was [parent]. Parent tag was \"[E.parent_organ]\".") + fail("[bodytype.type] external organ [E] was not found in parent's children. Parent was [parent]. Parent tag was \"[E.parent_organ]\".") . = 0 continue for(var/obj/item/organ/internal/I in H.get_internal_organs()) if(!I.parent_organ) - fail("[bodytype.name] internal organ [I] did not have a parent_organ tag.") + fail("[bodytype.type] internal organ [I] did not have a parent_organ tag.") . = 0 continue var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(H, I.parent_organ) if(!istype(parent)) - fail("[bodytype.name] internal organ [I] could not find its parent in organs_by_name. Parent tag was \"[I.parent_organ]\".") + fail("[bodytype.type] internal organ [I] could not find its parent in organs_by_name. Parent tag was \"[I.parent_organ]\".") . = 0 continue if(!(parent in external_organs)) - fail("[bodytype.name] internal organ [I] could not find its parent in organs. Parent was [parent]. Parent tag was \"[I.parent_organ]\".") + fail("[bodytype.type] internal organ [I] could not find its parent in organs. Parent was [parent]. Parent tag was \"[I.parent_organ]\".") . = 0 continue if(!(I in parent.internal_organs)) - fail("[bodytype.name] internal organ [I] was not found in parent's internal_organs. Parent was [parent]. Parent tag was \"[I.parent_organ]\".") + fail("[bodytype.type] internal organ [I] was not found in parent's internal_organs. Parent was [parent]. Parent tag was \"[I.parent_organ]\".") . = 0 continue @@ -118,8 +118,6 @@ var/failcount = 0 var/datum/mob_snapshot/dummy_appearance = new for(var/decl/bodytype/bodytype in decls_repository.get_decls_of_subtype_unassociated(/decl/bodytype)) - if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here - continue var/decl/species/species = bodytype.get_user_species_for_validation() if(!species) continue @@ -148,88 +146,87 @@ /datum/unit_test/bodytype_organ_lists_update/proc/check_internal_organ_present(var/mob/living/human/H, var/obj/item/organ/internal/I) var/decl/bodytype/root_bodytype = H.get_bodytype() if(!(I in H.get_internal_organs())) - fail("[root_bodytype.name] internal organ [I] not in internal_organs.") + fail("[root_bodytype.type] internal organ [I] not in internal_organs.") return 0 var/found = GET_INTERNAL_ORGAN(H, I.organ_tag) if(I != found) - fail("[root_bodytype.name] internal organ [I] not in organ list. Organ tag was \"[I.organ_tag]\", found [found? found : "nothing"] instead.") + fail("[root_bodytype.type] internal organ [I] not in organ list. Organ tag was \"[I.organ_tag]\", found [found? found : "nothing"] instead.") return 0 var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(H, I.parent_organ) if(!istype(parent)) - fail("[root_bodytype.name] internal organ [I] could not find its parent in organs_by_name. Parent tag was \"[I.parent_organ]\".") + fail("[root_bodytype.type] internal organ [I] could not find its parent in organs_by_name. Parent tag was \"[I.parent_organ]\".") return 0 if(!(I in parent.internal_organs)) - fail("[root_bodytype.name] internal organ [I] was not in parent's internal_organs. Parent was [parent]. Parent tag was \"[I.parent_organ]\".") + fail("[root_bodytype.type] internal organ [I] was not in parent's internal_organs. Parent was [parent]. Parent tag was \"[I.parent_organ]\".") return 0 return 1 /datum/unit_test/bodytype_organ_lists_update/proc/check_internal_organ_removed(var/mob/living/human/H, var/obj/item/organ/internal/I, var/obj/item/organ/external/old_parent) var/decl/bodytype/root_bodytype = H.get_bodytype() if(I in H.get_internal_organs()) - fail("[root_bodytype.name] internal organ [I] was not removed from internal_organs.") + fail("[root_bodytype.type] internal organ [I] was not removed from internal_organs.") return 0 var/found = GET_INTERNAL_ORGAN(H, I.organ_tag) if(found) - fail("[root_bodytype.name] internal organ [I] was not removed from organ list. Organ tag was \"[I.organ_tag]\".") + fail("[root_bodytype.type] internal organ [I] was not removed from organ list. Organ tag was \"[I.organ_tag]\".") return 0 if(I in old_parent.internal_organs) - fail("[root_bodytype.name] internal organ [I] was not removed from parent's internal_organs. Parent was [old_parent].") + fail("[root_bodytype.type] internal organ [I] was not removed from parent's internal_organs. Parent was [old_parent].") return 0 return 1 /datum/unit_test/bodytype_organ_lists_update/proc/check_external_organ_present(var/mob/living/human/H, var/obj/item/organ/external/E) var/decl/bodytype/root_bodytype = H.get_bodytype() if(!(E in H.get_external_organs())) - fail("[root_bodytype.name] external organ [E] not in organs.") + fail("[root_bodytype.type] external organ [E] not in organs.") return 0 var/found = GET_EXTERNAL_ORGAN(H, E.organ_tag) if(E != found) - fail("[root_bodytype.name] external organ [E] not in organ list. Organ tag was \"[E.organ_tag]\", found [found? found : "nothing"] instead.") + fail("[root_bodytype.type] external organ [E] not in organ list. Organ tag was \"[E.organ_tag]\", found [found? found : "nothing"] instead.") return 0 if(E.parent_organ) var/obj/item/organ/external/parent = E.parent if(!istype(parent)) - fail("[root_bodytype.name] external organ [E] had no parent. Parent tag was \"[E.parent_organ]\".") + fail("[root_bodytype.type] external organ [E] had no parent. Parent tag was \"[E.parent_organ]\".") return 0 if(parent.organ_tag != E.parent_organ) - fail("[root_bodytype.name] external organ [E] parent tag mismatch. Parent tag was \"[E.parent_organ]\", actual tag was \"[parent.organ_tag]\".") + fail("[root_bodytype.type] external organ [E] parent tag mismatch. Parent tag was \"[E.parent_organ]\", actual tag was \"[parent.organ_tag]\".") return 0 if(!(E in parent.children)) - fail("[root_bodytype.name] external organ [E] was not in parent's children. Parent was [parent]. Parent tag was \"[E.parent_organ]\".") + fail("[root_bodytype.type] external organ [E] was not in parent's children. Parent was [parent]. Parent tag was \"[E.parent_organ]\".") return 0 return 1 /datum/unit_test/bodytype_organ_lists_update/proc/check_external_organ_removed(var/mob/living/human/H, var/obj/item/organ/external/E, var/obj/item/organ/external/old_parent = null) var/decl/bodytype/root_bodytype = H.get_bodytype() if(E in H.get_external_organs()) - fail("[root_bodytype.name] external organ [E] was not removed from organs.") + fail("[root_bodytype.type] external organ [E] was not removed from organs.") return 0 var/found = GET_EXTERNAL_ORGAN(H, E.organ_tag) if(found) - fail("[root_bodytype.name] external organ [E] was not removed from organs_by_name. Organ tag was \"[E.organ_tag]\".") + fail("[root_bodytype.type] external organ [E] was not removed from organs_by_name. Organ tag was \"[E.organ_tag]\".") + return 0 + if(old_parent && (E in old_parent.children)) + fail("[root_bodytype.type] external organ [E] was not removed from parent's children. Parent was [old_parent].") return 0 - if(old_parent) - if(!(E in old_parent.children)) - fail("[root_bodytype.name] external organ [E] was not removed from parent's children. Parent was [old_parent].") - return 0 return 1 /datum/unit_test/bodytype_organ_lists_update/proc/test_internal_organ(var/mob/living/human/H, var/obj/item/organ/internal/I) var/decl/bodytype/root_bodytype = H.get_bodytype() if(!check_internal_organ_present(H, I)) - fail("[root_bodytype.name] internal organ [I] failed initial presence check.") + fail("[root_bodytype.type] internal organ [I] failed initial presence check.") return 0 var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(H, I.parent_organ) H.remove_organ(I) if(!check_internal_organ_removed(H, I, parent)) - fail("[root_bodytype.name] internal organ [I] was not removed correctly.") + fail("[root_bodytype.type] internal organ [I] was not removed correctly.") return 0 H.add_organ(I, parent) if(!check_internal_organ_present(H, I)) - fail("[root_bodytype.name] internal organ [I] was not replaced correctly.") + fail("[root_bodytype.type] internal organ [I] was not replaced correctly.") return 0 return 1 @@ -237,19 +234,19 @@ /datum/unit_test/bodytype_organ_lists_update/proc/test_external_organ(var/mob/living/human/H, var/obj/item/organ/external/E) var/decl/bodytype/root_bodytype = H.get_bodytype() if(!check_external_organ_present(H, E)) - fail("[root_bodytype.name] external organ [E] failed initial presence check.") + fail("[root_bodytype.type] external organ [E] failed initial presence check.") return 0 var/obj/item/organ/external/parent = E.parent - H.remove_organ(E) + H.remove_organ(E, drop_organ = FALSE, ignore_children = TRUE) if(!check_external_organ_removed(H, E, parent)) - fail("[root_bodytype.name] external organ [E] was not removed correctly.") + fail("[root_bodytype.type] external organ [E] was not removed correctly.") return 0 H.add_organ(E) - if(!check_external_organ_removed(H, E)) - fail("[root_bodytype.name] external organ [E] was not replaced correctly.") + if(!check_external_organ_present(H, E)) + fail("[root_bodytype.type] external organ [E] was not replaced correctly.") return 0 return 1 @@ -258,8 +255,6 @@ var/failcount = 0 var/datum/mob_snapshot/dummy_appearance = new for(var/decl/bodytype/bodytype in decls_repository.get_decls_of_subtype_unassociated(/decl/bodytype)) - if(!bodytype.bodytype_flag) // no equip flag, currently, implies no organs. todo: a better way to exclude simple animal bodytypes here - continue var/decl/species/species = bodytype.get_user_species_for_validation() if(!species) continue @@ -271,8 +266,14 @@ if(!test_internal_organ(test_subject, O)) failcount++ - for(var/O in test_subject.get_external_organs()) - if(!test_external_organ(test_subject, O)) + var/list/external_organs_by_depth = list() + for(var/obj/item/organ/external/external_organ in test_subject.get_external_organs()) + external_organs_by_depth[external_organ] = bodytype.has_limbs?[external_organ.organ_tag]?["has_children"] || 0 + // sort from least to most children, so 0-child organs are first, then 1, then 2, etc. + external_organs_by_depth = sortTim(external_organs_by_depth, /proc/cmp_numeric_asc, TRUE) + // test from leaf nodes towards root nodes, because this can be destructive if we remove an organ with children + for(var/obj/item/organ/external/external_organ in external_organs_by_depth) + if(!test_external_organ(test_subject, external_organ)) failcount++ QDEL_NULL(dummy_appearance) diff --git a/mods/species/drakes/species_bodytypes.dm b/mods/species/drakes/species_bodytypes.dm index aae52bd678ac..c5cbabe65312 100644 --- a/mods/species/drakes/species_bodytypes.dm +++ b/mods/species/drakes/species_bodytypes.dm @@ -317,7 +317,7 @@ var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws/strong/drake) return unarmed_attack -/obj/item/organ/external/hand/quadruped/grafadreka/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance, decl/bodytype/new_bodytype) +/obj/item/organ/external/hand/quadruped/grafadreka/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance) . = ..() item_flags |= ITEM_FLAG_NO_BLUDGEON set_extension(src, /datum/extension/tool, list( @@ -337,7 +337,7 @@ var/static/unarmed_attack = GET_DECL(/decl/natural_attack/claws/strong/drake) return unarmed_attack -/obj/item/organ/external/hand/right/quadruped/grafadreka/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance, decl/bodytype/new_bodytype) +/obj/item/organ/external/hand/right/quadruped/grafadreka/Initialize(mapload, material_key, datum/mob_snapshot/supplied_appearance) . = ..() item_flags |= ITEM_FLAG_NO_BLUDGEON set_extension(src, /datum/extension/tool, list( From 6da620fc8011e0228a1640eb9683049a0cef539d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 16:49:26 -0500 Subject: [PATCH 075/512] Add UIDs to species decls --- code/modules/species/species.dm | 1 + code/modules/species/station/human.dm | 1 + code/modules/species/station/monkey.dm | 1 + mods/content/fantasy/datum/hnoll/species.dm | 1 + mods/content/fantasy/datum/kobaloi/species.dm | 1 + mods/content/xenobiology/species/golem.dm | 1 + mods/species/adherent/datum/species.dm | 1 + mods/species/ascent/datum/species.dm | 3 ++- mods/species/drakes/species.dm | 1 + mods/species/neoavians/datum/species.dm | 1 + mods/species/random_species/random_species_species.dm | 1 + mods/species/serpentid/datum/species.dm | 1 + mods/species/skrell/datum/species.dm | 1 + mods/species/tajaran/datum/species.dm | 1 + mods/species/tritonian/datum/species.dm | 1 + mods/species/unathi/datum/species.dm | 1 + mods/species/utility_frames/species.dm | 1 + mods/species/vox/datum/species.dm | 1 + 18 files changed, 19 insertions(+), 1 deletion(-) diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 2e8495de0a87..64ba850a5653 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -5,6 +5,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 /decl/species abstract_type = /decl/species + decl_flags = DECL_FLAG_MANDATORY_UID // Descriptors and strings. var/name diff --git a/code/modules/species/station/human.dm b/code/modules/species/station/human.dm index 2ee92427f41f..eb83f82cee08 100644 --- a/code/modules/species/station/human.dm +++ b/code/modules/species/station/human.dm @@ -1,4 +1,5 @@ /decl/species/human + uid = "species_human" name = SPECIES_HUMAN name_plural = "Humans" primitive_form = SPECIES_MONKEY diff --git a/code/modules/species/station/monkey.dm b/code/modules/species/station/monkey.dm index 1871219744e5..51bd1624812d 100644 --- a/code/modules/species/station/monkey.dm +++ b/code/modules/species/station/monkey.dm @@ -1,4 +1,5 @@ /decl/species/monkey + uid = "species_monkey" name = SPECIES_MONKEY name_plural = "Monkeys" description = "Ook." diff --git a/mods/content/fantasy/datum/hnoll/species.dm b/mods/content/fantasy/datum/hnoll/species.dm index 8bb1cd7496e7..6d678e469c47 100644 --- a/mods/content/fantasy/datum/hnoll/species.dm +++ b/mods/content/fantasy/datum/hnoll/species.dm @@ -12,6 +12,7 @@ ) /decl/species/hnoll + uid = "species_hnoll" name = SPECIES_HNOLL name_plural = "Hnoll" description = "The hnoll are thickly-furred, powerfully built bipeds with a notable resemblance to the steppe \ diff --git a/mods/content/fantasy/datum/kobaloi/species.dm b/mods/content/fantasy/datum/kobaloi/species.dm index 9f2dd07bc4fc..4a1979f8f76b 100644 --- a/mods/content/fantasy/datum/kobaloi/species.dm +++ b/mods/content/fantasy/datum/kobaloi/species.dm @@ -1,4 +1,5 @@ /decl/species/kobaloi + uid = "species_kobaloi" name = SPECIES_KOBALOI name_plural = SPECIES_KOBALOI spawn_flags = SPECIES_CAN_JOIN diff --git a/mods/content/xenobiology/species/golem.dm b/mods/content/xenobiology/species/golem.dm index 93dc4786eaeb..26edb43ce686 100644 --- a/mods/content/xenobiology/species/golem.dm +++ b/mods/content/xenobiology/species/golem.dm @@ -10,6 +10,7 @@ uid = "bodytype_crystalline_golem" /decl/species/golem + uid = "species_golem" name = SPECIES_GOLEM name_plural = "Golems" hidden_from_codex = TRUE diff --git a/mods/species/adherent/datum/species.dm b/mods/species/adherent/datum/species.dm index f209e12168b7..435c0f2ad81b 100644 --- a/mods/species/adherent/datum/species.dm +++ b/mods/species/adherent/datum/species.dm @@ -11,6 +11,7 @@ ) /decl/species/adherent + uid = "species_adherent" name = SPECIES_ADHERENT name_plural = "Adherents" base_external_prosthetics_model = null diff --git a/mods/species/ascent/datum/species.dm b/mods/species/ascent/datum/species.dm index f6bc5dddb055..fa9f6607d9ba 100644 --- a/mods/species/ascent/datum/species.dm +++ b/mods/species/ascent/datum/species.dm @@ -24,7 +24,7 @@ splatter_colour = "#660066" /decl/species/mantid - + uid = "species_mantid_alate" name = SPECIES_MANTID_ALATE name_plural = "Kharmaan Alates" show_ssd = "quiescent" @@ -91,6 +91,7 @@ return /decl/species/mantid/gyne + uid = "species_mantid_gyne" name = SPECIES_MANTID_GYNE name_plural = "Kharmaan Gynes" diff --git a/mods/species/drakes/species.dm b/mods/species/drakes/species.dm index e5b53bae100c..f8a494ed89de 100644 --- a/mods/species/drakes/species.dm +++ b/mods/species/drakes/species.dm @@ -1,4 +1,5 @@ /decl/species/grafadreka + uid = "species_grafadreka" name = SPECIES_GRAFADREKA name_plural = SPECIES_GRAFADREKA description = "The reclusive grafadreka (Icelandic, lit. 'digging dragon'), also known as the snow drake, is a large reptillian pack predator similar in size and morphology to old Earth hyenas. \ diff --git a/mods/species/neoavians/datum/species.dm b/mods/species/neoavians/datum/species.dm index 065b6c6d932d..9d62eaf06420 100644 --- a/mods/species/neoavians/datum/species.dm +++ b/mods/species/neoavians/datum/species.dm @@ -16,6 +16,7 @@ meat_type = /obj/item/food/butchery/meat/chicken /decl/species/neoavian + uid = "species_avian" name = SPECIES_AVIAN name_plural = "Neo-Avians" description = "Avian species, largely crows, magpies and other corvids, were among the first sophonts uplifted to aid in colonizing Mars. \ diff --git a/mods/species/random_species/random_species_species.dm b/mods/species/random_species/random_species_species.dm index 06f431624ac4..33dc877d8f76 100644 --- a/mods/species/random_species/random_species_species.dm +++ b/mods/species/random_species/random_species_species.dm @@ -1,4 +1,5 @@ /decl/species/alium + uid = "species_random_alien" name = SPECIES_ALIEN name_plural = "Humanoids" description = "Some alien humanoid species, unknown to humanity. How exciting." diff --git a/mods/species/serpentid/datum/species.dm b/mods/species/serpentid/datum/species.dm index 4fb33bdc6833..d6b22eabb9c7 100644 --- a/mods/species/serpentid/datum/species.dm +++ b/mods/species/serpentid/datum/species.dm @@ -19,6 +19,7 @@ bone_type = null /decl/species/serpentid + uid = "species_serpentid" name = SPECIES_SERPENTID name_plural = "Serpentids" spawn_flags = SPECIES_IS_RESTRICTED diff --git a/mods/species/skrell/datum/species.dm b/mods/species/skrell/datum/species.dm index ac49a3c8a8b9..a84431f303c1 100644 --- a/mods/species/skrell/datum/species.dm +++ b/mods/species/skrell/datum/species.dm @@ -4,6 +4,7 @@ bone_material = /decl/material/solid/organic/bone/cartilage /decl/species/skrell + uid = "species_skrell" name = SPECIES_SKRELL name_plural = SPECIES_SKRELL diff --git a/mods/species/tajaran/datum/species.dm b/mods/species/tajaran/datum/species.dm index 4feacd90c5b7..47e47c8fea62 100644 --- a/mods/species/tajaran/datum/species.dm +++ b/mods/species/tajaran/datum/species.dm @@ -12,6 +12,7 @@ ) /decl/species/tajaran + uid = "species_tajaran" name = SPECIES_TAJARAN name_plural = "Tajaran" base_external_prosthetics_model = null diff --git a/mods/species/tritonian/datum/species.dm b/mods/species/tritonian/datum/species.dm index 84491dd46cf6..6d1090472cd1 100644 --- a/mods/species/tritonian/datum/species.dm +++ b/mods/species/tritonian/datum/species.dm @@ -1,4 +1,5 @@ /decl/species/human/tritonian + uid = "species_tritonian" name = SPECIES_TRITONIAN name_plural = "Tritonians" description = "A human-derived genotype designed for colonizing aquatic worlds." diff --git a/mods/species/unathi/datum/species.dm b/mods/species/unathi/datum/species.dm index aa7e32e0efb3..3eabb2ef0399 100644 --- a/mods/species/unathi/datum/species.dm +++ b/mods/species/unathi/datum/species.dm @@ -16,6 +16,7 @@ skin_material = /decl/material/solid/organic/skin/lizard /decl/species/unathi + uid = "species_unathi" name = SPECIES_UNATHI name_plural = SPECIES_UNATHI butchery_data = /decl/butchery_data/humanoid/unathi diff --git a/mods/species/utility_frames/species.dm b/mods/species/utility_frames/species.dm index 2fa4f50fe438..ff4d7292c911 100644 --- a/mods/species/utility_frames/species.dm +++ b/mods/species/utility_frames/species.dm @@ -10,6 +10,7 @@ ) /decl/species/utility_frame + uid = "species_frame" name = SPECIES_FRAME name_plural = "Utility Frames" description = "Simple AI-driven robots are used for many menial or repetitive tasks in human space." diff --git a/mods/species/vox/datum/species.dm b/mods/species/vox/datum/species.dm index eac1ad157862..98cb432bf540 100644 --- a/mods/species/vox/datum/species.dm +++ b/mods/species/vox/datum/species.dm @@ -20,6 +20,7 @@ transfusion_fail_reagent = /decl/material/gas/ammonia /decl/species/vox + uid = "species_vox" name = SPECIES_VOX name_plural = SPECIES_VOX base_external_prosthetics_model = /decl/bodytype/prosthetic/vox/crap From 07a64586f9e4926f7c65cd0fde5497d46344bc9e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 21 Feb 2025 19:39:03 -0500 Subject: [PATCH 076/512] Make species procs use UID instead of name --- code/__defines/mobs.dm | 3 -- code/_helpers/global_lists.dm | 21 +-------- code/_helpers/mobs.dm | 2 +- .../hud/screen/screen_warning_oxygen.dm | 2 +- code/datums/trading/_trader.dm | 2 +- .../traits/prosthetics/prosthetic_limbs.dm | 10 ++--- .../gamemodes/endgame/ftl_jump/ftl_jump.dm | 2 +- code/game/jobs/job/_job.dm | 14 +++--- code/game/jobs/server_whitelist.dm | 6 +-- code/game/movietitles.dm | 11 +++-- code/modules/admin/topic.dm | 2 + code/modules/admin/view_variables/topic.dm | 4 +- code/modules/awaymissions/corpse.dm | 2 +- code/modules/blood/blood_types.dm | 2 +- code/modules/bodytype/_bodytype.dm | 3 +- code/modules/bodytype/bodytype_helpers.dm | 2 +- code/modules/bodytype/bodytype_prosthetic.dm | 3 +- .../preference_setup/background/01_species.dm | 28 ++++++++---- .../background/02_background.dm | 2 +- .../preference_setup/general/01_basic.dm | 12 ++--- .../preference_setup/general/02_body.dm | 18 ++++---- .../preference_setup/occupation/occupation.dm | 6 +-- .../occupation/skill_selection.dm | 2 +- code/modules/client/preferences.dm | 5 ++- code/modules/clothing/masks/miscellaneous.dm | 4 +- .../codex/categories/category_species.dm | 4 +- .../crafting/stack_recipes/recipes_planks.dm | 2 +- code/modules/events/ion_storm.dm | 12 ++--- .../designs/robotics/designs_organs.dm | 2 +- .../designs/robotics/designs_prosthetics.dm | 4 +- .../fabrication/fabricator_bioprinter.dm | 2 +- .../random_exoplanet/planetoid_data.dm | 6 +-- code/modules/mob/living/human/examine.dm | 2 +- code/modules/mob/living/human/human.dm | 30 ++++++------- .../mob/living/human/human_appearance.dm | 15 +++---- .../modules/mob/living/human/human_presets.dm | 16 +++---- code/modules/mob/living/human/npcs.dm | 6 +-- code/modules/mob/living/living.dm | 2 +- code/modules/mob/living/living_attackhand.dm | 3 +- code/modules/mob/mob_helpers.dm | 2 +- code/modules/mob/mob_snapshot.dm | 6 +-- code/modules/mob/new_player/new_player.dm | 12 ++--- .../mob/new_player/preferences_setup.dm | 2 +- .../file_system/reports/crew_record.dm | 3 +- code/modules/nano/modules/human_appearance.dm | 8 ++-- code/modules/organs/external/_external.dm | 2 +- .../organs/external/_external_icons.dm | 2 +- code/modules/organs/internal/_internal.dm | 2 +- code/modules/organs/internal/brain.dm | 2 +- code/modules/organs/internal/lungs.dm | 2 +- code/modules/organs/internal/stomach.dm | 2 +- code/modules/organs/organ.dm | 14 +++--- code/modules/projectiles/projectile/change.dm | 8 ++-- code/modules/species/species.dm | 14 +++--- code/modules/species/species_getters.dm | 3 -- code/modules/species/station/human.dm | 7 +-- code/modules/species/station/monkey.dm | 2 +- code/modules/sprite_accessories/_accessory.dm | 10 ++--- .../cosmetics/_accessory_cosmetics.dm | 1 - .../ears/_accessory_ears.dm | 1 - .../facial/_accessory_facial.dm | 1 - .../frills/_accessory_frills.dm | 1 - .../hair/_accessory_hair.dm | 1 - .../horns/_accessory_horns.dm | 1 - .../tails/_accessory_tail.dm | 1 - code/modules/submaps/submap_job.dm | 6 +-- code/modules/surgery/_surgery.dm | 8 ++-- code/unit_tests/backgrounds.dm | 45 +++++++++---------- code/unit_tests/clothing.dm | 3 +- code/unit_tests/equipment_tests.dm | 4 +- code/unit_tests/mob_tests.dm | 33 +++++++++----- code/unit_tests/organ_tests.dm | 4 +- code/unit_tests/traders.dm | 2 +- maps/shaded_hills/shaded_hills_map.dm | 2 +- maps/~mapsystem/maps.dm | 4 +- .../away_sites/lar_maria/lar_maria.dm | 18 ++++---- mods/content/fantasy/_fantasy.dm | 4 -- mods/content/fantasy/datum/hnoll/markings.dm | 6 +-- mods/content/fantasy/datum/hnoll/species.dm | 2 +- .../content/fantasy/datum/kobaloi/markings.dm | 2 +- mods/content/fantasy/datum/kobaloi/species.dm | 4 +- mods/content/xenobiology/_xenobiology.dm | 3 +- mods/content/xenobiology/slime/items.dm | 2 +- mods/content/xenobiology/species/golem.dm | 2 +- mods/gamemodes/heist/special_role.dm | 2 +- mods/species/adherent/_adherent.dm | 7 ++- mods/species/adherent/datum/species.dm | 2 +- mods/species/ascent/ascent.dm | 6 --- mods/species/ascent/datum/antagonist.dm | 13 +++--- mods/species/ascent/datum/languages.dm | 8 ++-- mods/species/ascent/datum/species.dm | 5 +-- mods/species/ascent/datum/traits.dm | 10 ++--- mods/species/ascent/effects/razorweb.dm | 6 +-- mods/species/ascent/items/id_control.dm | 2 +- mods/species/ascent/items/rig.dm | 6 +-- mods/species/ascent/machines/magnetotron.dm | 6 +-- mods/species/ascent/machines/ship_machines.dm | 2 +- mods/species/ascent/mobs/insectoid_egg.dm | 2 +- mods/species/ascent/mobs/nymph/nymph_life.dm | 2 +- mods/species/drakes/_drakes.dm | 8 ++-- mods/species/drakes/species.dm | 4 +- mods/species/drakes/species_bodytypes.dm | 2 +- mods/species/neoavians/_neoavians.dm | 3 +- mods/species/neoavians/datum/accessory.dm | 4 +- mods/species/neoavians/datum/loadout.dm | 2 +- mods/species/neoavians/datum/species.dm | 2 +- .../species/random_species/_random_species.dm | 4 +- mods/species/random_species/aliumizer.dm | 10 ++--- .../random_species/random_species_species.dm | 2 +- mods/species/serpentid/datum/species.dm | 2 +- mods/species/serpentid/serpentid.dm | 1 - mods/species/skrell/_skrell.dm | 8 ++-- mods/species/skrell/datum/accessory.dm | 2 +- mods/species/skrell/datum/species.dm | 4 +- mods/species/skrell/gear/gear_ears.dm | 4 +- mods/species/skrell/gear/gear_head.dm | 4 +- mods/species/skrell/gear/gear_mask.dm | 4 +- mods/species/tajaran/_tajaran.dm | 7 ++- mods/species/tajaran/datum/accessory.dm | 6 +-- mods/species/tajaran/datum/species.dm | 2 +- mods/species/tritonian/_tritonian.dm | 2 - mods/species/tritonian/datum/species.dm | 2 +- mods/species/unathi/_unathi.dm | 7 ++- mods/species/unathi/datum/species.dm | 4 +- mods/species/unathi/datum/sprite_accessory.dm | 4 +- .../species/utility_frames/_utility_frames.dm | 2 - mods/species/utility_frames/markings.dm | 2 +- mods/species/utility_frames/species.dm | 2 +- mods/species/utility_frames/traits.dm | 4 +- mods/species/vox/_vox.dm | 5 +-- mods/species/vox/datum/accessories.dm | 4 +- mods/species/vox/datum/species.dm | 4 +- mods/species/vox/datum/species_bodytypes.dm | 1 + mods/species/vox/datum/trader.dm | 12 ++--- mods/species/vox/datum/traits.dm | 4 +- mods/species/vox/gear/gun_slugsling.dm | 5 ++- mods/species/vox/organs_vox.dm | 2 +- mods/~compatibility/patches/heist_vox.dm | 6 +-- nano/templates/appearance_changer.tmpl | 2 +- 139 files changed, 359 insertions(+), 417 deletions(-) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 3ea4d3cde8da..b23ee3650e6d 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -270,9 +270,6 @@ #define CORPSE_CAN_REENTER BITFLAG(0) #define CORPSE_CAN_RESPAWN BITFLAG(1) -#define SPECIES_HUMAN "Human" -#define SPECIES_MONKEY "Monkey" - #define SURGERY_CLOSED 0 #define SURGERY_OPEN 1 #define SURGERY_RETRACTED 2 diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index d4216ae41905..7bb01c2778df 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -61,25 +61,6 @@ var/global/list/keybindings_by_name = list() // Replace this with just decl look for(var/bound_key in instance.hotkey_keys) global.hotkey_keybinding_list_by_key[bound_key] += list(instance.name) -// This is all placeholder procs for an eventual PR to change them to use decls. -var/global/list/all_species -/proc/build_species_lists() - if(global.all_species) - return - global.all_species = list() - for(var/decl/species/species in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) - ASSERT(species.name) // all non-abstract species should have names - global.all_species[species.name] = species - -// TODO: Change species code to use decls instead of name keys. In that event, replace this with GET_DECL(species) I guess, or make it use UID instead of name? -/proc/get_species_by_key(var/species_key) - build_species_lists() - . = global.all_species[species_key] -// In the event of the above, this would be replaced with decls_repository.get_decls_of_subtype(/decl/species) or similar helpers. -/proc/get_all_species() - build_species_lists() - . = global.all_species -// In the event of the above, just make it add the typepath or UID instead of the name. /proc/get_playable_species() var/static/list/_playable_species // A list of ALL playable species, whitelisted, latejoin or otherwise. (read: non-restricted) if(!_playable_species) @@ -87,5 +68,5 @@ var/global/list/all_species for(var/decl/species/species in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) if(species.spawn_flags & SPECIES_IS_RESTRICTED) continue - _playable_species += species.name + _playable_species += species.uid return _playable_species diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 33b16c3b788e..269e7b986da1 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -9,7 +9,7 @@ /proc/random_name(gender, species) if(species) - var/decl/species/current_species = get_species_by_key(species) + var/decl/species/current_species = decls_repository.get_decl_by_id(species) if(current_species) var/decl/background_detail/background = current_species.get_default_background_datum_by_flag(BACKGROUND_FLAG_NAMING) if(background) diff --git a/code/_onclick/hud/screen/screen_warning_oxygen.dm b/code/_onclick/hud/screen/screen_warning_oxygen.dm index f964f7017a6c..507e80dea53d 100644 --- a/code/_onclick/hud/screen/screen_warning_oxygen.dm +++ b/code/_onclick/hud/screen/screen_warning_oxygen.dm @@ -23,7 +23,7 @@ var/datum/gas_mixture/environment = owner.loc?.return_air() if(!environment) return - var/decl/species/species = get_species_by_key(global.using_map.default_species) + var/decl/species/species = decls_repository.get_decl_by_id(global.using_map.default_species) if(!species.breath_type || environment.gas[species.breath_type] > species.breath_pressure) for(var/gas in species.poison_types) if(environment.gas[gas]) diff --git a/code/datums/trading/_trader.dm b/code/datums/trading/_trader.dm index 267e2c67c776..097965789bd6 100644 --- a/code/datums/trading/_trader.dm +++ b/code/datums/trading/_trader.dm @@ -199,7 +199,7 @@ if(ishuman(user)) var/mob/living/human/H = user if(H.species) - specific = H.species.name + specific = H.species.uid else if(issilicon(user)) specific = TRADER_HAIL_SILICON_END if(!speech["[TRADER_HAIL_START][specific]"]) diff --git a/code/datums/traits/prosthetics/prosthetic_limbs.dm b/code/datums/traits/prosthetics/prosthetic_limbs.dm index 245e4db88063..a620ebef2942 100644 --- a/code/datums/traits/prosthetics/prosthetic_limbs.dm +++ b/code/datums/traits/prosthetics/prosthetic_limbs.dm @@ -14,10 +14,8 @@ var/list/incompatible_with_limbs = list(BP_L_HAND) var/model -/decl/trait/prosthetic_limb/proc/get_base_model(var/species_name) - if(!species_name) - return /decl/bodytype/prosthetic/basic_human - var/decl/species/species = species_name ? get_species_by_key(species_name) : global.using_map.default_species +/decl/trait/prosthetic_limb/proc/get_base_model(var/species_uid) + var/decl/species/species = decls_repository.get_decl_by_id(species_uid || global.using_map.default_species) return species?.base_external_prosthetics_model /decl/trait/prosthetic_limb/get_chargen_name(datum/preferences/pref) @@ -87,7 +85,7 @@ var/decl/bodytype/prosthetic/robot_model = GET_DECL(model) if(!istype(robot_model)) return FALSE - var/decl/species/S = get_species_by_key(pref.species) || get_species_by_key(global.using_map.default_species) + var/decl/species/S = pref.get_species_decl() var/decl/bodytype/B = S.get_bodytype_by_name(pref.bodytype) if(!robot_model.check_can_install(apply_to_limb, target_bodytype = (check_bodytype || B.bodytype_category))) return FALSE @@ -114,7 +112,7 @@ // Robotize the selected limb. if(. && apply_to_limb) - var/use_model = model || get_base_model(holder.get_species_name()) + var/use_model = model || get_base_model(holder.get_species()?.uid) var/obj/item/organ/external/E = GET_EXTERNAL_ORGAN(holder, apply_to_limb) if(!istype(E)) var/list/organ_data = holder.should_have_limb(apply_to_limb) diff --git a/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm b/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm index 8f8d2f43e3cd..634ee0779fb6 100644 --- a/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm +++ b/code/game/gamemodes/endgame/ftl_jump/ftl_jump.dm @@ -121,7 +121,7 @@ /obj/effect/bluegoast/proc/blueswitch() var/mob/living/human/H if(ishuman(daddy)) - H = new(get_turf(src), daddy.species.name, daddy.get_mob_snapshot(), daddy.get_bodytype()) + H = new(get_turf(src), daddy.species.uid, daddy.get_mob_snapshot(), daddy.get_bodytype()) for(var/obj/item/entry in daddy.get_equipped_items(TRUE)) daddy.remove_from_mob(entry) //steals instead of copies so we don't end up with duplicates H.equip_to_appropriate_slot(entry) diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index 2c52112cbc66..2dcadfe65666 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -235,13 +235,13 @@ to_chat(feedback, "Wrong rank for [title]. Valid ranks in [prefs.branches[title]] are: [get_ranks(prefs.branches[title])].") return TRUE - var/decl/species/S = get_species_by_key(prefs.species) + var/decl/species/S = prefs.get_species_decl() if(!is_species_allowed(S)) to_chat(feedback, "Restricted species, [S], for [title].") return TRUE - if(LAZYACCESS(minimum_character_age, S.get_root_species_name()) && (prefs.get_character_age() < minimum_character_age[S.get_root_species_name()])) - to_chat(feedback, "Not old enough. Minimum character age is [minimum_character_age[S.get_root_species_name()]].") + if(LAZYACCESS(minimum_character_age, S.uid) && (prefs.get_character_age() < minimum_character_age[S.uid])) + to_chat(feedback, "Not old enough. Minimum character age is [minimum_character_age[S.uid]].") return TRUE if(!S.check_background(src, prefs)) @@ -379,17 +379,17 @@ if(!SSjobs.job_icons[title]) var/mob/living/human/dummy/mannequin/mannequin = get_mannequin("#job_icon") if(mannequin) - var/decl/species/mannequin_species = get_species_by_key(global.using_map.default_species) + var/decl/species/mannequin_species = decls_repository.get_decl_by_id(global.using_map.default_species) if(!is_species_allowed(mannequin_species)) // Don't just default to the first species allowed, pick one at random. for(var/other_species in shuffle(get_playable_species())) - var/decl/species/other_species_decl = get_species_by_key(other_species) + var/decl/species/other_species_decl = decls_repository.get_decl_by_id(other_species) if(is_species_allowed(other_species_decl)) mannequin_species = other_species_decl break if(!is_species_allowed(mannequin_species)) PRINT_STACK_TRACE("No allowed species allowed for job [title] ([type]), falling back to default!") - mannequin.change_species(mannequin_species.name) + mannequin.change_species(mannequin_species.uid) dress_mannequin(mannequin) mannequin.set_dir(SOUTH) var/icon/preview_icon = getFlatIcon(mannequin) @@ -411,7 +411,7 @@ reasons["Your branch of service does not allow it."] = TRUE else if(!isnull(allowed_ranks) && (!caller.prefs.ranks[title] || !is_rank_allowed(caller.prefs.branches[title], caller.prefs.ranks[title]))) reasons["Your rank choice does not allow it."] = TRUE - var/decl/species/S = get_species_by_key(caller.prefs.species) + var/decl/species/S = caller.prefs.get_species_decl() if(S) if(!is_species_allowed(S)) reasons["Your species choice does not allow it."] = TRUE diff --git a/code/game/jobs/server_whitelist.dm b/code/game/jobs/server_whitelist.dm index 9c8b84f46b57..0c39c017cb9b 100644 --- a/code/game/jobs/server_whitelist.dm +++ b/code/game/jobs/server_whitelist.dm @@ -63,8 +63,8 @@ var/global/list/alien_whitelist = list() alien_whitelist[row["ckey"]] = list(row["race"]) return TRUE -/proc/is_species_whitelisted(mob/M, var/species_name) - var/decl/species/S = get_species_by_key(species_name) +/proc/is_species_whitelisted(mob/M, var/species_uid) + var/decl/species/S = decls_repository.get_decl_by_id(species_uid) return is_alien_whitelisted(M, S) /proc/is_alien_whitelisted(mob/M, var/species) @@ -95,7 +95,7 @@ var/global/list/alien_whitelist = list() return FALSE if(!get_config_value(/decl/config/toggle/use_alien_whitelist) || !(S.spawn_flags & SPECIES_IS_WHITELISTED)) return TRUE - return whitelist_lookup(S.get_root_species_name(M), M.ckey) + return whitelist_lookup(S.uid, M.ckey) // Check for arbitrary text whitelisting. return istext(species) ? whitelist_lookup(species, M.ckey) : FALSE diff --git a/code/game/movietitles.dm b/code/game/movietitles.dm index 38b4dcf87ccf..e193fae03d2a 100644 --- a/code/game/movietitles.dm +++ b/code/game/movietitles.dm @@ -102,17 +102,16 @@ var/global/list/end_titles if(H.timeofdeath < 5 MINUTES) //no prespawned corpses continue if(H.isMonkey() && findtext(H.real_name,"[lowertext(H.species.name)]")) - monkies[H.species.name] += 1 + monkies[H.species] += 1 else if(H.real_name) corpses += H.real_name - for(var/spec in monkies) - var/decl/species/S = get_species_by_key(spec) - corpses += "[monkies[spec]] [lowertext(monkies[spec] > 1 ? S.name_plural : S.name)]" + for(var/decl/species/monkey_species in monkies) + corpses += "[monkies[monkey_species]] [lowertext(monkies[monkey_species] > 1 ? monkey_species.name_plural : monkey_species.name)]" if(corpses.len) titles += "
BASED ON REAL EVENTS
In memory of [english_list(corpses)].
" var/list/staff = list("PRODUCTION STAFF:") - var/list/staffjobs = list("Coffe Fetcher", "Cameraman", "Angry Yeller", "Chair Operator", "Choreographer", "Historical Consultant", "Costume Designer", "Chief Editor", "Executive Assistant") + var/list/staffjobs = list("Coffee Fetcher", "Cameraman", "Angry Yeller", "Chair Operator", "Choreographer", "Historical Consultant", "Costume Designer", "Chief Editor", "Executive Assistant") var/list/goodboys = list() for(var/client/C) if(!C.holder) @@ -120,7 +119,7 @@ var/global/list/end_titles if(C.holder.rights & (R_DEBUG|R_ADMIN)) var/list/all_backgrounds = decls_repository.get_decls_of_subtype(/decl/background_detail/heritage) var/decl/background_detail/cult = all_backgrounds[pick(all_backgrounds)] - staff += "[uppertext(pick(staffjobs))] - [cult.get_random_name(pick(MALE, FEMALE))] a.k.a. '[C.key]'" + staff += "[uppertext(pick(staffjobs))] - [cult.get_random_name(C.gender)] a.k.a. '[C.key]'" else if(C.holder.rights & R_MOD) goodboys += "[C.key]" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 45976fa23812..6cad22d7cde8 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -233,6 +233,8 @@ delmob = TRUE var/transform_key = replacetext(href_list["simplemake"], "_", " ") + // Nothing ever seems to pass species to any simplemake href links... + // TODO: Remove subspecies argument if it actually is defunct? if(M.try_rudimentary_transform(transform_key, delmob, href_list["species"])) log_and_message_admins("has used rudimentary transformation on [key_name_admin(M)]. Transforming to [transform_key]; deletemob=[delmob]") diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 114f3bd55106..5051805d0212 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -332,7 +332,7 @@ to_chat(usr, SPAN_WARNING("This can only be done to instances of type /mob/living/human")) return - var/new_species = input("Please choose a new species.","Species",null) as null|anything in get_all_species() + var/decl/species/new_species = input("Please choose a new species.","Species",null) as null|anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species) if(!victim) to_chat(usr, SPAN_WARNING("Mob doesn't exist anymore")) @@ -341,7 +341,7 @@ if(!new_species) return - if(victim.change_species(new_species)) + if(victim.change_species(new_species.uid)) to_chat(usr, SPAN_NOTICE("Set species of \the [victim] to [victim.species].")) else to_chat(usr, SPAN_WARNING("Failed! Something went wrong.")) diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 0974e8d543e6..62eb69dc0a6e 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -63,7 +63,7 @@ else M.randomize_skin_color() - var/decl/species/species_decl = get_species_by_key(species_choice) + var/decl/species/species_decl = decls_repository.get_decl_by_id(species_choice) var/decl/bodytype/root_bodytype = M.get_bodytype() var/update_hair = FALSE if((spawn_flags & CORPSE_SPAWNER_RANDOM_HAIR_COLOR)) diff --git a/code/modules/blood/blood_types.dm b/code/modules/blood/blood_types.dm index 3bf5fc6f4678..af4508282e7e 100644 --- a/code/modules/blood/blood_types.dm +++ b/code/modules/blood/blood_types.dm @@ -20,7 +20,7 @@ var/global/list/blood_types_by_name var/name var/list/antigens var/random_weighting = 1 - var/antigen_category = SPECIES_MONKEY // Rhesus factor oh no + var/antigen_category = "Primate" // Rhesus factor oh no var/splatter_name = "blood" var/splatter_desc = "It's some blood. That's not supposed to be there." diff --git a/code/modules/bodytype/_bodytype.dm b/code/modules/bodytype/_bodytype.dm index 0e2ef18ae68e..a805373f1b1b 100644 --- a/code/modules/bodytype/_bodytype.dm +++ b/code/modules/bodytype/_bodytype.dm @@ -825,8 +825,7 @@ var/global/list/bodytypes_by_category = list() to_chat(victim, SPAN_DANGER(pick(heat_discomfort_strings))) /decl/bodytype/proc/get_user_species_for_validation() - for(var/species_name in get_all_species()) - var/decl/species/species = get_species_by_key(species_name) + for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) if(src in species.available_bodytypes) return species diff --git a/code/modules/bodytype/bodytype_helpers.dm b/code/modules/bodytype/bodytype_helpers.dm index 53e30984d13b..e5d4488ef346 100644 --- a/code/modules/bodytype/bodytype_helpers.dm +++ b/code/modules/bodytype/bodytype_helpers.dm @@ -38,7 +38,7 @@ // Markings used to be cleared outside of here, but it was always done before every call, so it was moved in here. // remove invalid accessories for our new bodytype. don't clear the list directly as we did before, to preserve in the case of no default - var/decl/species/mob_species = get_species_by_key(pref.species) + var/decl/species/mob_species = pref.get_species_decl() var/decl/bodytype/mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype for(var/acc_cat in pref.sprite_accessories) if(!(acc_cat in mob_species.available_accessory_categories)) diff --git a/code/modules/bodytype/bodytype_prosthetic.dm b/code/modules/bodytype/bodytype_prosthetic.dm index c01812a75787..7423faf51b70 100644 --- a/code/modules/bodytype/bodytype_prosthetic.dm +++ b/code/modules/bodytype/bodytype_prosthetic.dm @@ -60,8 +60,7 @@ /decl/bodytype/prosthetic/get_user_species_for_validation() if(bodytype_category) - for(var/species_name in get_all_species()) - var/decl/species/species = get_species_by_key(species_name) + for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) for(var/decl/bodytype/bodytype_data in species.available_bodytypes) if(bodytype_data.bodytype_category == bodytype_category) return species diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index fec5d7948050..dcd727964a11 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -6,11 +6,21 @@ sort_order = 1 var/hide_species = TRUE +// This must always return a decl, NEVER null. +/datum/preferences/proc/get_species_decl() + RETURN_TYPE(/decl/species) + species ||= global.using_map.default_species + . = decls_repository.get_decl_by_id(species, validate_decl_type = FALSE) + if(!.) + species = global.using_map.default_species + return decls_repository.get_decl_by_id(species) + /datum/category_item/player_setup_item/background/species/save_character(datum/pref_record_writer/writer) writer.write("species", pref.species) /datum/category_item/player_setup_item/background/species/preload_character(datum/pref_record_reader/R) - pref.species = R.read("species") + var/decl/species/loaded_species = decls_repository.get_decl_by_id_or_var(R.read("species"), /decl/spawnpoint) + pref.species = loaded_species?.uid || decls_repository.get_decl_by_id(global.using_map.default_species) /datum/category_item/player_setup_item/background/species/sanitize_character() . = ..() @@ -18,9 +28,9 @@ /datum/category_item/player_setup_item/background/species/proc/sanitize_species() - if(!pref.species || !get_species_by_key(pref.species)) + if(!pref.species || !pref.get_species_decl()) pref.set_species(global.using_map.default_species) - var/decl/species/mob_species = get_species_by_key(pref.species) + var/decl/species/mob_species = pref.get_species_decl() var/decl/bodytype/mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype var/decl/pronouns/pronouns = get_pronouns_by_gender(pref.gender) if(!istype(pronouns) || !(pronouns in mob_species.available_pronouns)) @@ -33,13 +43,13 @@ pref.all_underwear.Cut() /datum/category_item/player_setup_item/background/species/content(var/mob/user) - var/decl/species/current_species = get_species_by_key(pref.species) + var/decl/species/current_species = pref.get_species_decl() var/list/prefilter = get_playable_species() var/list/playables = list() for(var/s in prefilter) if(!check_rights(R_ADMIN, 0) && get_config_value(/decl/config/toggle/use_alien_whitelist)) - var/decl/species/checking_species = get_species_by_key(s) + var/decl/species/checking_species = decls_repository.get_decl_by_id(s) if(!(checking_species.spawn_flags & SPECIES_CAN_JOIN)) continue else if((checking_species.spawn_flags & SPECIES_IS_WHITELISTED) && !is_alien_whitelisted(preference_mob(),checking_species)) @@ -51,11 +61,11 @@ . += "

Species

" . += "
" for(var/s in playables) - var/decl/species/list_species = get_species_by_key(s) - if(pref.species == list_species.name) + var/decl/species/list_species = decls_repository.get_decl_by_id(s) + if(pref.species == list_species.uid) . += "[list_species.name] " else - . += "[list_species.name] " + . += "[list_species.name] " . += "

" . += "" @@ -94,7 +104,7 @@ if(choice != pref.species) if(!check_rights(R_ADMIN, 0) && get_config_value(/decl/config/toggle/use_alien_whitelist)) - var/decl/species/new_species = get_species_by_key(choice) + var/decl/species/new_species = decls_repository.get_decl_by_id(choice) if(!new_species) return TOPIC_REFRESH if(!(new_species.spawn_flags & SPECIES_CAN_JOIN)) diff --git a/code/modules/client/preference_setup/background/02_background.dm b/code/modules/client/preference_setup/background/02_background.dm index 762520d1c435..ab98dce04256 100644 --- a/code/modules/client/preference_setup/background/02_background.dm +++ b/code/modules/client/preference_setup/background/02_background.dm @@ -1,5 +1,5 @@ #define GET_ALLOWED_VALUES(write_to, check_key) \ - var/decl/species/S = get_species_by_key(pref.species); \ + var/decl/species/S = pref.get_species_decl(); \ if(!S) { \ write_to = list(); \ } else if(S.force_background_info[check_key]) { \ diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index e7792fceeab9..96a439422849 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -5,11 +5,7 @@ var/real_name //our character's name var/be_random_name = 0 //whether we are a random name every round -// These two should always return a decl, NEVER null. -/datum/preferences/proc/get_species_decl() - RETURN_TYPE(/decl/species) - return get_species_by_key(species || global.using_map.default_species) - +// This must always return a decl, NEVER null. /datum/preferences/proc/get_bodytype_decl() RETURN_TYPE(/decl/bodytype) var/decl/species/species_decl = get_species_decl() @@ -54,7 +50,7 @@ if(!valid_spawn) pref.spawnpoint = global.using_map.default_spawn - var/decl/species/S = get_species_by_key(pref.species) || get_species_by_key(global.using_map.default_species) + var/decl/species/S = pref.get_species_decl() pref.be_random_name = sanitize_integer(pref.be_random_name, 0, 1, initial(pref.be_random_name)) var/decl/pronouns/pronouns @@ -81,7 +77,7 @@ . += "
" . += "Bodytype: " - var/decl/species/S = get_species_by_key(pref.species) + var/decl/species/S = pref.get_species_decl() for(var/decl/bodytype/B in S.available_bodytypes) if(B.name == pref.bodytype) . += "[capitalize(B.pref_name)]" @@ -105,7 +101,7 @@ . = jointext(.,null) /datum/category_item/player_setup_item/physical/basic/OnTopic(var/href,var/list/href_list, var/mob/user) - var/decl/species/S = get_species_by_key(pref.species) + var/decl/species/S = pref.get_species_decl() if(href_list["rename"]) var/raw_name = input(user, "Choose your character's name:", "Character Name") as text|null diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index b2f5a88a05e9..65dcf28fbc78 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -84,7 +84,7 @@ /datum/category_item/player_setup_item/physical/body/save_character(datum/pref_record_writer/writer) - var/decl/species/mob_species = get_species_by_key(pref.species) + var/decl/species/mob_species = pref.get_species_decl() var/list/save_accessories = list() for(var/acc_cat in mob_species.available_accessory_categories) if(!(acc_cat in pref.sprite_accessories)) @@ -109,10 +109,10 @@ /datum/category_item/player_setup_item/physical/body/sanitize_character() - var/decl/species/mob_species = get_species_by_key(pref.species) + var/decl/species/mob_species = pref.get_species_decl() if(!mob_species || (mob_species.spawn_flags & SPECIES_IS_RESTRICTED)) pref.species = global.using_map.default_species - mob_species = get_species_by_key(pref.species) + mob_species = pref.get_species_decl() var/decl/bodytype/mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype if(mob_bodytype.appearance_flags & HAS_SKIN_COLOR) pref.skin_colour = pref.skin_colour || mob_bodytype.base_color || COLOR_BLACK @@ -186,7 +186,7 @@ /datum/category_item/player_setup_item/physical/body/content(var/mob/user) . = list() - var/decl/species/mob_species = get_species_by_key(pref.species) + var/decl/species/mob_species = pref.get_species_decl() var/decl/bodytype/mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype . += "Blood Type: [pref.blood_type]
" . += "Randomize Appearance
" @@ -303,7 +303,7 @@ /datum/category_item/player_setup_item/physical/body/OnTopic(var/href,var/list/href_list, var/mob/user) - var/decl/species/mob_species = get_species_by_key(pref.species) + var/decl/species/mob_species = pref.get_species_decl() var/decl/bodytype/mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype if(href_list["set_descriptor"]) @@ -327,7 +327,7 @@ else if(href_list["blood_type"]) var/new_b_type = input(user, "Choose your character's blood type:", CHARACTER_PREFERENCE_INPUT_TITLE) as null|anything in mob_species.blood_types if(new_b_type && CanUseTopic(user)) - mob_species = get_species_by_key(pref.species) + mob_species = pref.get_species_decl() if(new_b_type in mob_species.blood_types) pref.blood_type = new_b_type return TOPIC_REFRESH @@ -436,7 +436,7 @@ if(!(mob_bodytype.appearance_flags & HAS_EYE_COLOR)) return TOPIC_NOACTION var/new_eyes = input(user, "Choose your character's eye colour:", CHARACTER_PREFERENCE_INPUT_TITLE, pref.eye_colour) as color|null - mob_species = get_species_by_key(pref.species) + mob_species = pref.get_species_decl() mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype if(new_eyes && (mob_bodytype.appearance_flags & HAS_EYE_COLOR) && CanUseTopic(user)) pref.eye_colour = new_eyes @@ -446,7 +446,7 @@ if(!(mob_bodytype.appearance_flags & HAS_A_SKIN_TONE)) return TOPIC_NOACTION var/new_s_tone = input(user, "Choose your character's skin-tone. Lower numbers are lighter, higher are darker. Range: 1 to [mob_bodytype.max_skin_tone()]", CHARACTER_PREFERENCE_INPUT_TITLE, (-pref.skin_tone) + 35) as num|null - mob_species = get_species_by_key(pref.species) + mob_species = pref.get_species_decl() mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype if(new_s_tone && (mob_bodytype.appearance_flags & HAS_A_SKIN_TONE) && CanUseTopic(user)) pref.skin_tone = 35 - max(min(round(new_s_tone), mob_bodytype.max_skin_tone()), 1) @@ -456,7 +456,7 @@ if(!(mob_bodytype.appearance_flags & HAS_SKIN_COLOR)) return TOPIC_NOACTION var/new_skin = input(user, "Choose your character's skin colour: ", CHARACTER_PREFERENCE_INPUT_TITLE, pref.skin_colour) as color|null - mob_species = get_species_by_key(pref.species) + mob_species = pref.get_species_decl() mob_bodytype = mob_species.get_bodytype_by_name(pref.bodytype) || mob_species.default_bodytype if(new_skin && (mob_bodytype.appearance_flags & HAS_SKIN_COLOR) && CanUseTopic(user)) pref.skin_colour = new_skin diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm index ed49536a4ddf..3d1b29c1a54f 100644 --- a/code/modules/client/preference_setup/occupation/occupation.dm +++ b/code/modules/client/preference_setup/occupation/occupation.dm @@ -150,7 +150,7 @@ var/help_link = "?" lastJob = job - var/species_name = S.get_root_species_name() + var/species_uid = S.uid var/bad_message = "" if(job.total_positions == 0 && job.spawn_positions == 0) bad_message = "\[UNAVAILABLE]" @@ -159,8 +159,8 @@ else if(!job.player_old_enough(user.client)) var/available_in_days = job.available_in_days(user.client) bad_message = "\[IN [(available_in_days)] DAYS]" - else if(LAZYACCESS(job.minimum_character_age, species_name) && user.client && (user.client.prefs.get_character_age() < job.minimum_character_age[species_name])) - bad_message = "\[MIN CHAR AGE: [job.minimum_character_age[species_name]]]" + else if(LAZYACCESS(job.minimum_character_age, species_uid) && user.client && (user.client.prefs.get_character_age() < job.minimum_character_age[species_uid])) + bad_message = "\[MIN CHAR AGE: [job.minimum_character_age[species_uid]]]" else if(!job.is_species_allowed(S)) bad_message = "\[SPECIES RESTRICTED]" else if(!S.check_background(job, user.client.prefs)) diff --git a/code/modules/client/preference_setup/occupation/skill_selection.dm b/code/modules/client/preference_setup/occupation/skill_selection.dm index 0399006bab6c..ec4b0ba348db 100644 --- a/code/modules/client/preference_setup/occupation/skill_selection.dm +++ b/code/modules/client/preference_setup/occupation/skill_selection.dm @@ -87,7 +87,7 @@ //Sets up skills_allocated /datum/preferences/proc/sanitize_skills(var/list/input) . = list() - var/decl/species/S = get_species_by_key(species) + var/decl/species/S = get_species_decl() for(var/job_name in SSjobs.titles_to_datums) var/datum/job/job = SSjobs.get_by_title(job_name) var/input_skills = list() diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 838fede2cd9b..d24d40d0256e 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -77,7 +77,7 @@ var/global/list/time_prefs_fixed = list() gender = pick(MALE, FEMALE) real_name = get_random_name() - var/decl/species/species = get_species_by_key(global.using_map.default_species) + var/decl/species/species = decls_repository.get_decl_by_id(global.using_map.default_species) blood_type = pickweight(species.blood_types) if(client) @@ -358,7 +358,8 @@ var/global/list/time_prefs_fixed = list() character.traits = null var/decl/bodytype/new_bodytype = get_bodytype_decl() - if(species == character.get_species_name()) + var/decl/species/character_species = character.get_species() + if(species == character_species.uid) character.set_bodytype(new_bodytype) else character.change_species(species, new_bodytype) diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index afabff1f337f..df8cce8d806f 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -166,12 +166,12 @@ name = "human mask" desc = "A rubber human mask." icon = 'icons/clothing/mask/human.dmi' - var/species = SPECIES_HUMAN + var/species = /decl/species/human::uid /obj/item/clothing/mask/rubber/species/Initialize() . = ..() visible_name = species - var/decl/species/S = get_species_by_key(species) + var/decl/species/S = decls_repository.get_decl_by_id(species) if(istype(S)) var/decl/background_detail/C = GET_DECL(S.default_background_info[/decl/background_category/heritage]) if(istype(C)) diff --git a/code/modules/codex/categories/category_species.dm b/code/modules/codex/categories/category_species.dm index c35f3bce307b..d0ca4089cb5f 100644 --- a/code/modules/codex/categories/category_species.dm +++ b/code/modules/codex/categories/category_species.dm @@ -4,10 +4,8 @@ /decl/codex_category/species/Populate() - for(var/thing in get_all_species()) - var/decl/species/species = get_species_by_key(thing) + for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) if(!species.hidden_from_codex) - var/entry_type = (species.secret_codex_info) ? /datum/codex_entry/scannable : /datum/codex_entry var/datum/codex_entry/entry = new entry_type( _display_name = "[species.name] (species)", diff --git a/code/modules/crafting/stack_recipes/recipes_planks.dm b/code/modules/crafting/stack_recipes/recipes_planks.dm index e1e762675cfb..d643a2e51b8f 100644 --- a/code/modules/crafting/stack_recipes/recipes_planks.dm +++ b/code/modules/crafting/stack_recipes/recipes_planks.dm @@ -104,7 +104,7 @@ abstract_type = /decl/stack_recipe/planks/prosthetic difficulty = MAT_VALUE_EASY_DIY category = "prosthetics" - var/prosthetic_species = SPECIES_HUMAN + var/prosthetic_species = /decl/species/human::uid var/prosthetic_model = /decl/bodytype/prosthetic/wooden /decl/stack_recipe/planks/prosthetic/spawn_result(mob/user, location, amount, decl/material/mat, decl/material/reinf_mat, paint_color, spent_type, spent_amount = 1) diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm index b75e55818938..48702089f434 100644 --- a/code/modules/events/ion_storm.dm +++ b/code/modules/events/ion_storm.dm @@ -142,14 +142,10 @@ return pick(players) return default_if_none -/datum/event/ionstorm/proc/get_random_species_name(var/default_if_none) - if(!default_if_none) - default_if_none = global.using_map.default_species - . = length(global.all_species) ? pick(global.all_species) : default_if_none - if(.) - var/decl/species/species = all_species[.] - if(species) - . = species.name_plural +/datum/event/ionstorm/proc/get_random_species_name() + var/list/decl/species/all_species = decls_repository.get_decls_of_subtype_unassociated(/decl/species) + var/decl/species/species = pick(all_species) // this should never fail. + return species.name_plural /datum/event/ionstorm/proc/get_random_language(var/mob/living/silicon/S) var/list/languages = S.speech_synthesizer_langs.Copy() diff --git a/code/modules/fabrication/designs/robotics/designs_organs.dm b/code/modules/fabrication/designs/robotics/designs_organs.dm index baaad0b945e5..bce2a16e8e93 100644 --- a/code/modules/fabrication/designs/robotics/designs_organs.dm +++ b/code/modules/fabrication/designs/robotics/designs_organs.dm @@ -20,7 +20,7 @@ /datum/fabricator_recipe/robotics/organ/build(turf/location, datum/fabricator_build_order/order) . = ..() - var/decl/species/species = get_species_by_key(order.get_data("species", global.using_map.default_species)) + var/decl/species/species = decls_repository.get_decl_by_id(order.get_data("species", global.using_map.default_species)) for(var/obj/item/organ/internal/I in .) I.set_species(species) I.set_bodytype(species.base_internal_prosthetics_model) diff --git a/code/modules/fabrication/designs/robotics/designs_prosthetics.dm b/code/modules/fabrication/designs/robotics/designs_prosthetics.dm index d8d93cc9feae..fcec37a7beef 100644 --- a/code/modules/fabrication/designs/robotics/designs_prosthetics.dm +++ b/code/modules/fabrication/designs/robotics/designs_prosthetics.dm @@ -62,7 +62,7 @@ var/decl/bodytype/prosthetic/company = GET_DECL(model) if(!istype(company)) return FALSE - var/decl/species/species = get_species_by_key(robofab.picked_prosthetic_species) + var/decl/species/species = decls_repository.get_decl_by_id(robofab.picked_prosthetic_species) if(!istype(species)) return FALSE var/obj/item/organ/target_limb = path @@ -92,7 +92,7 @@ /datum/fabricator_recipe/robotics/prosthetic/build(var/turf/location, var/datum/fabricator_build_order/order) . = ..() var/species_name = order.get_data("species", global.using_map.default_species) - var/decl/species/species = get_species_by_key(species_name) + var/decl/species/species = decls_repository.get_decl_by_id(species_name) if(species) for(var/obj/item/organ/external/E in .) E.set_species(species_name) diff --git a/code/modules/fabrication/fabricator_bioprinter.dm b/code/modules/fabrication/fabricator_bioprinter.dm index ca0b5905513f..26e548f8d627 100644 --- a/code/modules/fabrication/fabricator_bioprinter.dm +++ b/code/modules/fabrication/fabricator_bioprinter.dm @@ -67,7 +67,7 @@ return list( "real_name" = loaded_dna.real_name, "UE" = loaded_dna.unique_enzymes, - "species" = loaded_dna.root_species.name, + "species" = loaded_dna.root_species.uid, "btype" = loaded_dna.blood_type, ) diff --git a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm index 741bc5d94a5f..c113ec46b77b 100644 --- a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm +++ b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm @@ -489,7 +489,7 @@ //Adjust for species habitability if(habitability_class == HABITABILITY_OKAY || habitability_class == HABITABILITY_IDEAL) - var/decl/species/S = global.get_species_by_key(global.using_map.default_species) + var/decl/species/S = decls_repository.get_decl_by_id(global.using_map.default_species) if(habitability_class == HABITABILITY_IDEAL) . = clamp(., S.default_bodytype.cold_discomfort_level + rand(1,5), S.default_bodytype.heat_discomfort_level - rand(1,5)) //Clamp between comfortable levels since we're ideal else @@ -501,7 +501,7 @@ //Adjust for species habitability if(habitability_class == HABITABILITY_OKAY || habitability_class == HABITABILITY_IDEAL) - var/decl/species/S = global.get_species_by_key(global.using_map.default_species) + var/decl/species/S = decls_repository.get_decl_by_id(global.using_map.default_species) var/breathed_min_pressure = S.breath_pressure var/safe_max_pressure = S.get_hazard_high_pressure() var/safe_min_pressure = S.get_hazard_low_pressure() @@ -550,7 +550,7 @@ blacklisted_flags |= XGM_GAS_CONTAMINANT //Make sure temperature can't damage people on casual planets (Only when not forcing an atmosphere) - var/decl/species/S = global.get_species_by_key(global.using_map.default_species) + var/decl/species/S = decls_repository.get_decl_by_id(global.using_map.default_species) var/lower_temp = max(S.default_bodytype.cold_level_1, atmosphere_gen_temperature_min) var/higher_temp = min(S.default_bodytype.heat_level_1, atmosphere_gen_temperature_max) var/breathed_gas = S.breath_type diff --git a/code/modules/mob/living/human/examine.dm b/code/modules/mob/living/human/examine.dm index 52c619c459cc..401bd21b915e 100644 --- a/code/modules/mob/living/human/examine.dm +++ b/code/modules/mob/living/human/examine.dm @@ -3,7 +3,7 @@ if(!(hideflags & HIDEJUMPSUIT) || !(hideflags & HIDEFACE)) var/species_name = "\improper " if(isSynthetic() && species.cyborg_noun) - species_name += "[species.cyborg_noun] [species.get_root_species_name(src)]" + species_name += "[species.cyborg_noun] [species.name]" else species_name += "[species.name]" msg += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user))) ? SPAN_NOTICE(" \[?\]") : ""]" diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index e4c18624c6f8..b0b6ac4559c1 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -7,7 +7,7 @@ max_health = 150 var/embedded_flag //To check if we've need to roll for damage on movement while an item is imbedded in us. -/mob/living/human/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) current_health = max_health reset_hud_overlays() @@ -479,20 +479,20 @@ update_eyes() return TRUE -/mob/proc/set_species(var/new_species_name, var/new_bodytype = null) +/mob/proc/set_species(var/new_species_uid, var/new_bodytype = null) return //set_species should not handle the entirety of initing the mob, and should not trigger deep updates //It focuses on setting up species-related data, without force applying them uppon organs and the mob's appearance. // For transforming an existing mob, look at change_species() -/mob/living/human/set_species(var/new_species_name, var/new_bodytype = null) - if(!new_species_name) - CRASH("set_species on mob '[src]' was passed a null species name '[new_species_name]'!") - var/new_species = get_species_by_key(new_species_name) - if(species?.name == new_species_name) +/mob/living/human/set_species(var/new_species_uid, var/new_bodytype = null) + if(!new_species_uid) + CRASH("set_species on mob '[src]' was passed a null species uid!") + var/decl/species/new_species = decls_repository.get_decl_by_id(new_species_uid) + if(species?.uid == new_species_uid) return if(!new_species) - CRASH("set_species on mob '[src]' was passed a bad species name '[new_species_name]'!") + CRASH("set_species on mob '[src]' was passed a bad species uid '[new_species_uid]'!") //Handle old species transition if(species) @@ -586,7 +586,7 @@ // Triggers deep update of limbs and hud /mob/living/human/proc/apply_species_appearance() if(!species) - icon_state = lowertext(SPECIES_HUMAN) + icon_state = null // this used to set it to "human" but that's not even an icon state that exists, so else species.apply_appearance(src) @@ -973,13 +973,13 @@ mind.name = newname //Human mob specific init code. Meant to be used only on init. -/mob/living/human/proc/setup_human(species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/proc/setup_human(species_uid, datum/mob_snapshot/supplied_appearance) if(supplied_appearance) - species_name = supplied_appearance.root_species.name - else if(!species_name) - species_name = global.using_map.default_species //Humans cannot exist without a species! + species_uid = supplied_appearance.root_species.uid + else if(!species_uid) + species_uid = global.using_map.default_species //Humans cannot exist without a species! - set_species(species_name, supplied_appearance?.root_bodytype) + set_species(species_uid, supplied_appearance?.root_bodytype) var/decl/bodytype/root_bodytype = get_bodytype() // root bodytype is set in set_species ASSERT((!supplied_appearance?.root_bodytype) || (root_bodytype == supplied_appearance.root_bodytype)) if(!get_skin_colour()) @@ -1016,7 +1016,7 @@ SetName(initial(name)) //Runs last after setup and after the parent init has been executed. -/mob/living/human/proc/post_setup(species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/proc/post_setup(species_uid, datum/mob_snapshot/supplied_appearance) try_refresh_visible_overlays() //Do this exactly once per setup /mob/living/human/handle_flashed(var/flash_strength) diff --git a/code/modules/mob/living/human/human_appearance.dm b/code/modules/mob/living/human/human_appearance.dm index 272f2165b4a4..d3196fbab25e 100644 --- a/code/modules/mob/living/human/human_appearance.dm +++ b/code/modules/mob/living/human/human_appearance.dm @@ -21,10 +21,7 @@ if(!new_species) return - if(species?.name == new_species) - return - - if(!(new_species in get_all_species())) + if(species?.uid == new_species) return set_species(new_species, new_bodytype) @@ -90,19 +87,17 @@ /mob/living/human/proc/generate_valid_species(var/check_whitelist = 1, var/list/whitelist = list(), var/list/blacklist = list()) var/list/valid_species = new() - for(var/current_species_name in get_all_species()) - var/decl/species/current_species = get_species_by_key(current_species_name) - + for(var/decl/species/current_species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) if(check_whitelist) //If we're using the whitelist, make sure to check it! if((current_species.spawn_flags & SPECIES_IS_RESTRICTED) && !check_rights(R_ADMIN, 0, src)) continue if(!is_alien_whitelisted(src, current_species)) continue - if(whitelist.len && !(current_species_name in whitelist)) + if(whitelist.len && !(current_species.uid in whitelist)) continue - if(blacklist.len && (current_species_name in blacklist)) + if(blacklist.len && (current_species.uid in blacklist)) continue - valid_species += current_species_name + valid_species += current_species.uid return valid_species diff --git a/code/modules/mob/living/human/human_presets.dm b/code/modules/mob/living/human/human_presets.dm index 5490d841c7c4..7a4d8bb44cba 100644 --- a/code/modules/mob/living/human/human_presets.dm +++ b/code/modules/mob/living/human/human_presets.dm @@ -12,12 +12,12 @@ . = new /mob/living/human/dummy/mannequin() mannequins[ckey] = . -/mob/living/human/dummy/mannequin/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/dummy/mannequin/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) . = ..() STOP_PROCESSING(SSmobs, src) global.human_mob_list -= src -/mob/living/human/dummy/selfdress/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/dummy/selfdress/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) ..() return INITIALIZE_HINT_LATELOAD @@ -31,18 +31,18 @@ /mob/living/human/corpse/get_death_message(gibbed) return SKIP_DEATH_MESSAGE -/mob/living/human/corpse/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance, obj/abstract/landmark/corpse/corpse) - . = ..(mapload, species_name, supplied_appearance) // do not pass the corpse landmark +/mob/living/human/corpse/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance, obj/abstract/landmark/corpse/corpse) + . = ..(mapload, species_uid, supplied_appearance) // do not pass the corpse landmark var/decl/background_detail/background = get_background_datum_by_flag(BACKGROUND_FLAG_NAMING) if(background) - var/newname = background.get_random_name(src, gender, species.name) + var/newname = background.get_random_name(src, gender, species.uid) if(newname && newname != name) real_name = newname SetName(newname) if(mind) mind.name = real_name if(corpse) - corpse.randomize_appearance(src, get_species_name()) + corpse.randomize_appearance(src, get_species()?.uid) corpse.equip_corpse_outfit(src) return INITIALIZE_HINT_LATELOAD @@ -71,8 +71,8 @@ /mob/living/human/monkey gender = PLURAL -/mob/living/human/monkey/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/monkey/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) if(gender == PLURAL) gender = pick(MALE, FEMALE) - species_name = SPECIES_MONKEY + species_uid = /decl/species/monkey::uid . = ..() diff --git a/code/modules/mob/living/human/npcs.dm b/code/modules/mob/living/human/npcs.dm index dbe4b30ea876..1f75d60c9c86 100644 --- a/code/modules/mob/living/human/npcs.dm +++ b/code/modules/mob/living/human/npcs.dm @@ -2,7 +2,7 @@ real_name = "Pun Pun" gender = MALE -/mob/living/human/monkey/punpun/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/monkey/punpun/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) ..() return INITIALIZE_HINT_LATELOAD @@ -35,8 +35,8 @@ sensor.set_sensor_mode(VITALS_SENSOR_OFF) attach_accessory(null, sensor) -/mob/living/human/blank/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) - species_name = SPECIES_HUMAN +/mob/living/human/blank/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) + species_uid = /decl/species/human::uid ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index dfa536ca3859..639e2ad7812b 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -427,7 +427,7 @@ default behaviour is: continue var/icon/DI var/use_colour = (BP_IS_PROSTHETIC(O) ? SYNTH_BLOOD_COLOR : O.species.get_species_blood_color(src)) - var/cache_index = "[O.damage_state]/[O.bodytype.uid]/[O.icon_state]/[use_colour]/[O.species.name]" + var/cache_index = "[O.damage_state]/[O.bodytype.uid]/[O.icon_state]/[use_colour]/[O.species.uid]" if(!(cache_index in damage_icon_parts)) var/damage_overlay_icon = O.bodytype.get_damage_overlays(src) if(check_state_in_icon(O.damage_state, damage_overlay_icon)) diff --git a/code/modules/mob/living/living_attackhand.dm b/code/modules/mob/living/living_attackhand.dm index 52a96d71282c..52cce7e49af7 100644 --- a/code/modules/mob/living/living_attackhand.dm +++ b/code/modules/mob/living/living_attackhand.dm @@ -103,8 +103,7 @@ uniform.add_fingerprint(user) // They're SSD, so permanently asleep. - var/show_ssd = get_species_name() - if(show_ssd && ssd_check()) + if(ssd_check() && get_species()?.get_ssd(src)) user.visible_message( SPAN_NOTICE("\The [user] shakes \the [src] trying to wake [pronouns.him] up!"), SPAN_NOTICE("You shake \the [src], but they do not respond...") diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 988521933f5b..b4bded7cf315 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -352,7 +352,7 @@ var/global/list/global/organ_rel_size = list( if(istype(belt, /obj/item/gun) || istype(belt, /obj/item/energy_blade) || istype(belt, /obj/item/baton)) threatcount += 2 - if(get_species_name() != global.using_map.default_species) + if(get_species()?.uid != global.using_map.default_species) threatcount += 2 if(check_records || check_arrest) diff --git a/code/modules/mob/mob_snapshot.dm b/code/modules/mob/mob_snapshot.dm index 7dea014aa94a..9b6a485a0e23 100644 --- a/code/modules/mob/mob_snapshot.dm +++ b/code/modules/mob/mob_snapshot.dm @@ -23,7 +23,7 @@ unique_enzymes = donor?.get_unique_enzymes() fingerprint = donor?.get_full_print(ignore_blockers = TRUE) - root_species = donor?.get_species() || get_species_by_key(global.using_map.default_species) + root_species = donor?.get_species() || decls_repository.get_decl_by_id(global.using_map.default_species) root_bodytype = donor?.get_bodytype() || root_species.default_bodytype for(var/obj/item/organ/external/limb in donor?.get_external_organs()) @@ -61,9 +61,9 @@ if(istype(root_species) && root_species != target.get_species()) if(istype(root_bodytype)) - target.set_species(root_species.name, root_bodytype) + target.set_species(root_species.uid, root_bodytype) else - target.set_species(root_species.name) + target.set_species(root_species.uid) else if(istype(root_bodytype) && target.get_bodytype() != root_bodytype) target.set_bodytype(root_bodytype) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 76e3dc995a59..5eaca24a6515 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -164,7 +164,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) if(!SSjobs.check_general_join_blockers(src, job)) return FALSE - var/decl/species/S = get_species_by_key(client.prefs.species) + var/decl/species/S = client.prefs.get_species_decl() if(!check_species_allowed(S)) return 0 @@ -361,7 +361,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) var/decl/species/chosen_species if(client.prefs.species) - chosen_species = get_species_by_key(client.prefs.species) + chosen_species = client.prefs.get_species_decl() if(!spawn_turf) var/datum/job/job = SSjobs.get_by_title(mind.assigned_role) @@ -374,7 +374,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) if(!check_species_allowed(chosen_species)) spawning = 0 //abort return null - new_character = new(spawn_turf, chosen_species.name) + new_character = new(spawn_turf, chosen_species.uid) if(!new_character) new_character = new(spawn_turf) @@ -427,11 +427,11 @@ INITIALIZE_IMMEDIATE(/mob/new_player) /mob/new_player/proc/check_species_allowed(var/decl/species/S, var/show_alert=1) if(!S.is_available_for_join() && !has_admin_rights()) if(show_alert) - to_chat(src, alert("Your current species, [client.prefs.species], is not available for play.")) + to_chat(src, alert("Your current species, [S.name], is not available for play.")) return 0 if(!is_alien_whitelisted(src, S)) if(show_alert) - to_chat(src, alert("You are currently not whitelisted to play [client.prefs.species].")) + to_chat(src, alert("You are currently not whitelisted to play [S.name_plural].")) return 0 return 1 @@ -439,7 +439,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) SHOULD_CALL_PARENT(FALSE) var/decl/species/chosen_species if(client.prefs.species) - chosen_species = get_species_by_key(client.prefs.species) + chosen_species = client.prefs.get_species_decl() if(!chosen_species || !check_species_allowed(chosen_species, 0)) return global.using_map.default_species return chosen_species.name diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 18915226f3dc..02545d440181 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -96,7 +96,7 @@ else permitted = TRUE - if(gear.whitelisted && !(mannequin.species.name in gear.whitelisted)) + if(gear.whitelisted && !(mannequin.species.uid in gear.whitelisted)) permitted = FALSE if(!permitted) diff --git a/code/modules/modular_computers/file_system/reports/crew_record.dm b/code/modules/modular_computers/file_system/reports/crew_record.dm index 420acdb719e7..fb6a7c6a233a 100644 --- a/code/modules/modular_computers/file_system/reports/crew_record.dm +++ b/code/modules/modular_computers/file_system/reports/crew_record.dm @@ -61,7 +61,8 @@ var/global/arrest_security_status = "Arrest" set_gender(gender_term) set_age(crewmember?.get_age() || 30) set_status(global.default_physical_status) - set_species_name(crewmember ? crewmember.get_species_name() : global.using_map.default_species) + var/decl/species/default_species = decls_repository.get_decl_by_id(global.using_map.default_species) + set_species_name(crewmember ? crewmember.get_species_name() : default_species.name) set_branch(crewmember ? (crewmember.char_branch && crewmember.char_branch.name) : "None") set_rank(crewmember ? (crewmember.char_rank && crewmember.char_rank.name) : "None") diff --git a/code/modules/nano/modules/human_appearance.dm b/code/modules/nano/modules/human_appearance.dm index 6e22447ab9ca..9ba722beb8c3 100644 --- a/code/modules/nano/modules/human_appearance.dm +++ b/code/modules/nano/modules/human_appearance.dm @@ -14,6 +14,7 @@ src.whitelist = species_whitelist src.blacklist = species_blacklist +// FIXME: This doesn't currently handle arbitrary sprite accessory categories, so you can't select ears/tail/etc. /datum/nano_module/appearance_changer/Topic(ref, href_list, var/datum/topic_state/state = global.default_topic_state) if(..()) return 1 @@ -80,13 +81,14 @@ return var/list/data = host.initial_data() - data["specimen"] = owner.species.name + data["current_species_uid"] = owner.species.uid data["gender"] = owner.gender data["change_race"] = can_change(APPEARANCE_RACE) if(data["change_race"]) var/species[0] - for(var/specimen in owner.generate_valid_species(check_whitelist, whitelist, blacklist)) - species[++species.len] = list("specimen" = specimen) + for(var/species_uid in owner.generate_valid_species(check_whitelist, whitelist, blacklist)) + var/decl/species/candidate_species = decls_repository.get_decl_by_id(species_uid) + species[++species.len] = list("uid" = species_uid, "name" = candidate_species.name) data["species"] = species data["change_gender"] = can_change(APPEARANCE_GENDER) diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 24ea4429fcfc..7c6d37a1fa0c 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -135,7 +135,7 @@ if(owner) LAZYREMOVE(owner.bad_external_organs, src) -/obj/item/organ/external/set_species(specie_name) +/obj/item/organ/external/set_species(species_uid) _icon_cache_key = null . = ..() skin_blend = bodytype.limb_blend diff --git a/code/modules/organs/external/_external_icons.dm b/code/modules/organs/external/_external_icons.dm index e10a803445c8..0e447204cec7 100644 --- a/code/modules/organs/external/_external_icons.dm +++ b/code/modules/organs/external/_external_icons.dm @@ -127,7 +127,7 @@ var/global/list/organ_icon_cache = list() /obj/item/organ/external/proc/get_icon_cache_key_components() - . = list("[icon_state]_[species.name]_[get_organ_appearance_bodytype()?.uid || "BAD_BODYTYPE"]_[render_alpha]_[icon]") + . = list("[icon_state]_[species.uid]_[get_organ_appearance_bodytype()?.uid || "BAD_BODYTYPE"]_[render_alpha]_[icon]") // Skeletons don't care about most icon appearance stuff. if(limb_flags & ORGAN_FLAG_SKELETAL) diff --git a/code/modules/organs/internal/_internal.dm b/code/modules/organs/internal/_internal.dm index 8c7939f7ed43..a200ebacfc41 100644 --- a/code/modules/organs/internal/_internal.dm +++ b/code/modules/organs/internal/_internal.dm @@ -36,7 +36,7 @@ . = ..() set_max_damage(absolute_max_damage) -/obj/item/organ/internal/set_species(species_name) +/obj/item/organ/internal/set_species(species_uid) . = ..() if(species.organs_icon) icon = species.organs_icon diff --git a/code/modules/organs/internal/brain.dm b/code/modules/organs/internal/brain.dm index 008ef91f52f4..b3afab56119a 100644 --- a/code/modules/organs/internal/brain.dm +++ b/code/modules/organs/internal/brain.dm @@ -45,7 +45,7 @@ /obj/item/organ/internal/brain/getToxLoss() return 0 -/obj/item/organ/internal/brain/set_species(species_name) +/obj/item/organ/internal/brain/set_species(species_uid) . = ..() icon_state = "brain-prosthetic" if(species) diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm index dc919a92490c..9c6e8070cb68 100644 --- a/code/modules/organs/internal/lungs.dm +++ b/code/modules/organs/internal/lungs.dm @@ -59,7 +59,7 @@ /obj/item/organ/internal/lungs/proc/adjust_oxygen_deprivation(var/amount) oxygen_deprivation = clamp(oxygen_deprivation + amount, 0, species.total_health) -/obj/item/organ/internal/lungs/set_species(species_name) +/obj/item/organ/internal/lungs/set_species(species_uid) . = ..() sync_breath_types() diff --git a/code/modules/organs/internal/stomach.dm b/code/modules/organs/internal/stomach.dm index d8abe4894167..4cbde4e21255 100644 --- a/code/modules/organs/internal/stomach.dm +++ b/code/modules/organs/internal/stomach.dm @@ -12,7 +12,7 @@ QDEL_NULL(ingested) . = ..() -/obj/item/organ/internal/stomach/set_species(species_name) +/obj/item/organ/internal/stomach/set_species(species_uid) if(species?.gluttonous) verbs -= /obj/item/organ/internal/stomach/proc/throw_up . = ..() diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index d9835817d5a1..fa386ca13797 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -126,7 +126,7 @@ if(species != organ_appearance.root_species) if(organ_appearance.root_bodytype && organ_appearance.root_bodytype != bodytype) bodytype = organ_appearance.root_bodytype // this lets us take advantage of set_bodytype being called in set_species - set_species(organ_appearance.root_species?.name || global.using_map.default_species) + set_species(organ_appearance.root_species?.uid || global.using_map.default_species) else if(organ_appearance.root_bodytype && organ_appearance.root_bodytype != bodytype) set_bodytype(organ_appearance.root_bodytype) @@ -170,15 +170,15 @@ absolute_max_damage = floor(ndamage) max_damage = absolute_max_damage -/obj/item/organ/proc/set_species(specie_name) +/obj/item/organ/proc/set_species(species_uid) vital_to_owner = null // This generally indicates the owner mob is having species set, and this value may be invalidated. - if(istext(specie_name)) - species = get_species_by_key(specie_name) + if(istext(species_uid)) + species = decls_repository.get_decl_by_id(species_uid) else - species = specie_name + species = species_uid if(!species) - species = get_species_by_key(global.using_map.default_species) - PRINT_STACK_TRACE("Invalid species. Expected a valid species name as string, was: [log_info_line(specie_name)]") + species = decls_repository.get_decl_by_id(global.using_map.default_species) + PRINT_STACK_TRACE("Invalid species. Expected a valid species UID as string, was: [log_info_line(species_uid)]") set_bodytype(bodytype || species.default_bodytype, override_material = material?.type) diff --git a/code/modules/projectiles/projectile/change.dm b/code/modules/projectiles/projectile/change.dm index 1c3821119369..7e498de80efc 100644 --- a/code/modules/projectiles/projectile/change.dm +++ b/code/modules/projectiles/projectile/change.dm @@ -13,11 +13,11 @@ . = list() if(!isrobot(M)) . += "robot" - for(var/t in get_all_species()) - . += t + for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) + . += species.uid if(ishuman(M)) var/mob/living/human/H = M - . -= H.species.name + . -= H.species.uid /obj/item/projectile/change/proc/apply_transformation(var/mob/M, var/choice) @@ -29,7 +29,7 @@ transfer_key_from_mob_to_mob(M, robot) return robot - if(get_species_by_key(choice)) + if(decls_repository.get_decl_by_id(choice)) var/mob/living/human/H = M if(!istype(H)) H = new(get_turf(M)) diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 64ba850a5653..4123ad590039 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -303,7 +303,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/decl/sprite_accessory/accessory = GET_DECL(accessory_type) // If this accessory is species restricted, add us to the list. if(accessory.species_allowed) - accessory.species_allowed |= name + accessory.species_allowed |= uid if(!isnull(accessory.body_flags_allowed)) for(var/decl/bodytype/bodytype in available_bodytypes) accessory.body_flags_allowed |= bodytype.body_flags @@ -320,7 +320,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 for(var/accessory_type in disallow_specific_sprite_accessories) var/decl/sprite_accessory/accessory = GET_DECL(accessory_type) if(accessory.species_allowed) - accessory.species_allowed -= name + accessory.species_allowed -= uid if(!isnull(accessory.body_flags_allowed)) for(var/decl/bodytype/bodytype in available_bodytypes) accessory.body_flags_allowed &= ~bodytype.body_flags @@ -386,9 +386,9 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/decl/trait/trait = GET_DECL(trait_type) if(!trait.validate_level(trait_level)) . += "invalid levels for species trait [trait_type]" - if(name in trait.blocked_species) + if(uid in trait.blocked_species) . += "trait [trait.name] prevents this species from taking it" - if(trait.permitted_species && !(name in trait.permitted_species)) + if(trait.permitted_species && !(uid in trait.permitted_species)) . += "trait [trait.name] does not permit this species to take it" if(!length(blood_types)) @@ -707,10 +707,10 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 // TODO: generate an icon based on all available bodytypes. - var/mob/living/human/dummy/mannequin/mannequin = get_mannequin("#species_[ckey(name)]") + var/mob/living/human/dummy/mannequin/mannequin = get_mannequin("#species_[ckey(uid)]") if(mannequin) - mannequin.change_species(name) // handles species/bodytype init + mannequin.change_species(uid) // handles species/bodytype init default_bodytype.customize_preview_mannequin(mannequin) // handles body colors/styles setup customize_preview_mannequin(mannequin) // handles 'cultural' things like default outfit @@ -724,7 +724,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) preview_icon_width = preview_icon.Width() preview_icon_height = preview_icon.Height() - preview_icon_path = "species_preview_[ckey(name)].png" + preview_icon_path = "species_preview_[ckey(uid)].png" return preview_icon diff --git a/code/modules/species/species_getters.dm b/code/modules/species/species_getters.dm index 4bf80fd91e74..cf8f78ca0e91 100644 --- a/code/modules/species/species_getters.dm +++ b/code/modules/species/species_getters.dm @@ -28,9 +28,6 @@ /decl/species/proc/get_radiation_mod(var/mob/living/human/H) . = (H && H.isSynthetic() ? 0.5 : radiation_mod) -/decl/species/proc/get_root_species_name(var/mob/living/human/H) - return name - /decl/species/proc/get_bodytype_by_name(var/bodytype_name) bodytype_name = trim(lowertext(bodytype_name)) if(!bodytype_name) diff --git a/code/modules/species/station/human.dm b/code/modules/species/station/human.dm index eb83f82cee08..d1f3e5323c30 100644 --- a/code/modules/species/station/human.dm +++ b/code/modules/species/station/human.dm @@ -1,8 +1,8 @@ /decl/species/human uid = "species_human" - name = SPECIES_HUMAN + name = "Human" name_plural = "Humans" - primitive_form = SPECIES_MONKEY + primitive_form = /decl/species/monkey::uid description = "A medium-sized creature prone to great ambition. If you are reading this, you are probably a human." hidden_from_codex = FALSE spawn_flags = SPECIES_CAN_JOIN @@ -30,9 +30,6 @@ /decl/emote/exertion/synthetic/creak ) -/decl/species/human/get_root_species_name(var/mob/living/human/H) - return SPECIES_HUMAN - /decl/species/human/get_ssd(var/mob/living/human/H) if(H.stat == CONSCIOUS) return "staring blankly, not reacting to your presence" diff --git a/code/modules/species/station/monkey.dm b/code/modules/species/station/monkey.dm index 51bd1624812d..d50c96b24823 100644 --- a/code/modules/species/station/monkey.dm +++ b/code/modules/species/station/monkey.dm @@ -1,6 +1,6 @@ /decl/species/monkey uid = "species_monkey" - name = SPECIES_MONKEY + name = "Monkey" name_plural = "Monkeys" description = "Ook." codex_description = "Monkeys and other similar creatures tend to be found on science stations and vessels as \ diff --git a/code/modules/sprite_accessories/_accessory.dm b/code/modules/sprite_accessories/_accessory.dm index 2f659cfc98e8..f7f9c46c2110 100644 --- a/code/modules/sprite_accessories/_accessory.dm +++ b/code/modules/sprite_accessories/_accessory.dm @@ -29,10 +29,8 @@ var/list/decl/bodytype/bodytypes_allowed /// Restricted from specific bodytypes. null matches none var/list/decl/bodytype/bodytypes_denied - /// Restrict some styles to specific root species names - var/list/species_allowed = list(SPECIES_HUMAN) - /// Restrict some styles to specific species names, irrespective of root species name - var/list/subspecies_allowed + /// Restrict some styles to specific species UIDs. + var/list/species_allowed = list(/decl/species/human::uid) /// Restrict some styles to specific bodytype flags. var/body_flags_allowed /// Restrict some styles to specific bodytype flags. @@ -90,9 +88,7 @@ if(species) var/species_is_permitted = TRUE if(species_allowed) - species_is_permitted = (species.get_root_species_name(owner) in species_allowed) - if(subspecies_allowed) - species_is_permitted = (species.name in subspecies_allowed) + species_is_permitted = (species.uid in species_allowed) if(!species_is_permitted) return FALSE if(bodytype) diff --git a/code/modules/sprite_accessories/cosmetics/_accessory_cosmetics.dm b/code/modules/sprite_accessories/cosmetics/_accessory_cosmetics.dm index aa47401eb2b6..91df82be7f3d 100644 --- a/code/modules/sprite_accessories/cosmetics/_accessory_cosmetics.dm +++ b/code/modules/sprite_accessories/cosmetics/_accessory_cosmetics.dm @@ -12,7 +12,6 @@ bodytypes_allowed = null bodytypes_denied = null species_allowed = null - subspecies_allowed = null bodytype_categories_allowed = null bodytype_categories_denied = null body_flags_allowed = null diff --git a/code/modules/sprite_accessories/ears/_accessory_ears.dm b/code/modules/sprite_accessories/ears/_accessory_ears.dm index ac8757346f89..bc64873f19a0 100644 --- a/code/modules/sprite_accessories/ears/_accessory_ears.dm +++ b/code/modules/sprite_accessories/ears/_accessory_ears.dm @@ -22,7 +22,6 @@ bodytypes_allowed = null bodytypes_denied = null species_allowed = null - subspecies_allowed = null bodytype_categories_allowed = null bodytype_categories_denied = null body_flags_allowed = null diff --git a/code/modules/sprite_accessories/facial/_accessory_facial.dm b/code/modules/sprite_accessories/facial/_accessory_facial.dm index 9fe557fb225a..106c91852d53 100644 --- a/code/modules/sprite_accessories/facial/_accessory_facial.dm +++ b/code/modules/sprite_accessories/facial/_accessory_facial.dm @@ -39,7 +39,6 @@ bodytypes_allowed = null bodytypes_denied = null species_allowed = null - subspecies_allowed = null bodytype_categories_allowed = null bodytype_categories_denied = null body_flags_allowed = null diff --git a/code/modules/sprite_accessories/frills/_accessory_frills.dm b/code/modules/sprite_accessories/frills/_accessory_frills.dm index b03ec96eeafd..9d6e187d93a7 100644 --- a/code/modules/sprite_accessories/frills/_accessory_frills.dm +++ b/code/modules/sprite_accessories/frills/_accessory_frills.dm @@ -21,7 +21,6 @@ bodytypes_allowed = null bodytypes_denied = null species_allowed = null - subspecies_allowed = null bodytype_categories_allowed = null bodytype_categories_denied = null body_flags_allowed = null diff --git a/code/modules/sprite_accessories/hair/_accessory_hair.dm b/code/modules/sprite_accessories/hair/_accessory_hair.dm index cd06c2f0e4fb..328397907dac 100644 --- a/code/modules/sprite_accessories/hair/_accessory_hair.dm +++ b/code/modules/sprite_accessories/hair/_accessory_hair.dm @@ -43,7 +43,6 @@ bodytypes_allowed = null bodytypes_denied = null species_allowed = null - subspecies_allowed = null bodytype_categories_allowed = null bodytype_categories_denied = null body_flags_allowed = null diff --git a/code/modules/sprite_accessories/horns/_accessory_horns.dm b/code/modules/sprite_accessories/horns/_accessory_horns.dm index 59e7b0ff6a27..4526113a70f8 100644 --- a/code/modules/sprite_accessories/horns/_accessory_horns.dm +++ b/code/modules/sprite_accessories/horns/_accessory_horns.dm @@ -25,7 +25,6 @@ bodytypes_allowed = null bodytypes_denied = null species_allowed = null - subspecies_allowed = null bodytype_categories_allowed = null bodytype_categories_denied = null body_flags_allowed = null diff --git a/code/modules/sprite_accessories/tails/_accessory_tail.dm b/code/modules/sprite_accessories/tails/_accessory_tail.dm index 0c6d8a543464..bef3c6677821 100644 --- a/code/modules/sprite_accessories/tails/_accessory_tail.dm +++ b/code/modules/sprite_accessories/tails/_accessory_tail.dm @@ -37,7 +37,6 @@ bodytypes_allowed = null bodytypes_denied = null species_allowed = null - subspecies_allowed = null bodytype_categories_allowed = null bodytype_categories_denied = null body_flags_allowed = null diff --git a/code/modules/submaps/submap_job.dm b/code/modules/submaps/submap_job.dm index 89d8b2f38718..f7d72268f72a 100644 --- a/code/modules/submaps/submap_job.dm +++ b/code/modules/submaps/submap_job.dm @@ -79,9 +79,9 @@ return TRUE /datum/job/submap/is_restricted(var/datum/preferences/prefs, var/feedback) - var/decl/species/S = get_species_by_key(prefs.species) - if(LAZYACCESS(minimum_character_age, S.get_root_species_name()) && (prefs.get_character_age() < minimum_character_age[S.get_root_species_name()])) - to_chat(feedback, "Not old enough. Minimum character age is [minimum_character_age[S.get_root_species_name()]].") + var/decl/species/S = prefs.get_species_decl() + if(LAZYACCESS(minimum_character_age, S.uid) && (prefs.get_character_age() < minimum_character_age[S.uid])) + to_chat(feedback, "Not old enough. Minimum character age is [minimum_character_age[S.uid]].") return TRUE if(LAZYLEN(whitelisted_species) && !(prefs.species in whitelisted_species)) to_chat(feedback, "Your current species, [prefs.species], is not permitted as [title] on \a [owner.archetype.name].") diff --git a/code/modules/surgery/_surgery.dm b/code/modules/surgery/_surgery.dm index fe4eb699d91c..8c0f853e9647 100644 --- a/code/modules/surgery/_surgery.dm +++ b/code/modules/surgery/_surgery.dm @@ -103,12 +103,12 @@ var/global/list/surgery_tool_exception_cache = list() if(allowed_species) . = FALSE if(species) - for(var/species_name in allowed_species) - if(species.get_root_species_name(target) == species_name) + for(var/species_uid in allowed_species) + if(species.uid == species_uid) return TRUE if(species && disallowed_species) - for(var/species_name in disallowed_species) - if(species.get_root_species_name(target) == species_name) + for(var/species_uid in disallowed_species) + if(species.uid == species_uid) return FALSE /decl/surgery_step/proc/get_skill_reqs(mob/living/user, mob/living/target, obj/item/tool, target_zone) diff --git a/code/unit_tests/backgrounds.dm b/code/unit_tests/backgrounds.dm index e08b1ec37512..6710868f07c6 100644 --- a/code/unit_tests/backgrounds.dm +++ b/code/unit_tests/backgrounds.dm @@ -6,90 +6,89 @@ var/list/all_background_tokens = global.using_map.get_background_categories() var/fails = 0 - for(var/species_name in get_all_species()) - var/decl/species/species = get_species_by_key(species_name) + for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) if(!islist(species.default_background_info)) fails++ - log_bad("Default background info for [species_name] is not a list.") + log_bad("Default background info for [species.type] is not a list.") else for(var/cat_type in species.default_background_info) if(!(cat_type in all_background_tokens)) fails++ - log_bad("Default background info for [species_name] contains invalid tag '[cat_type]'.") + log_bad("Default background info for [species.type] contains invalid tag '[cat_type]'.") else var/val = species.default_background_info[cat_type] if(!val) fails++ - log_bad("Default background value '[val]' for [species_name] tag '[cat_type]' is null, must be a type.") + log_bad("Default background value '[val]' for [species.type] tag '[cat_type]' is null, must be a type.") else if(istext(val)) fails++ - log_bad("Default background value '[val]' for [species_name] tag '[cat_type]' is text, must be a type.") + log_bad("Default background value '[val]' for [species.type] tag '[cat_type]' is text, must be a type.") else var/decl/background_detail/background = GET_DECL(val) if(!istype(background)) fails++ - log_bad("Default background value '[val]' for [species_name] tag '[cat_type]' is not a valid background label.") + log_bad("Default background value '[val]' for [species.type] tag '[cat_type]' is not a valid background label.") else if(background.category != cat_type) fails++ - log_bad("Default background value '[val]' for [species_name] tag '[cat_type]' does not match background datum category ([background.category] must equal [cat_type]).") + log_bad("Default background value '[val]' for [species.type] tag '[cat_type]' does not match background datum category ([background.category] must equal [cat_type]).") else if(!background.description) fails++ - log_bad("Default background value '[val]' for [species_name] tag '[cat_type]' does not have a description set.") + log_bad("Default background value '[val]' for [species.type] tag '[cat_type]' does not have a description set.") if(!islist(species.force_background_info)) fails++ - log_bad("Forced background info for [species_name] is not a list.") + log_bad("Forced background info for [species.type] is not a list.") else for(var/cat_type in species.force_background_info) if(!(cat_type in all_background_tokens)) fails++ - log_bad("Forced background info for [species_name] contains invalid tag '[cat_type]'.") + log_bad("Forced background info for [species.type] contains invalid tag '[cat_type]'.") else var/val = species.force_background_info[cat_type] if(!val) fails++ - log_bad("Forced background value for [species_name] tag '[cat_type]' is null, must be a type.") + log_bad("Forced background value for [species.type] tag '[cat_type]' is null, must be a type.") else if(istext(val)) fails++ - log_bad("Forced background value for [species_name] tag '[cat_type]' is text, must be a type.") + log_bad("Forced background value for [species.type] tag '[cat_type]' is text, must be a type.") else var/decl/background_detail/background = GET_DECL(val) if(!istype(background)) fails++ - log_bad("Forced background value '[val]' for [species_name] tag '[cat_type]' is not a valid background label.") + log_bad("Forced background value '[val]' for [species.type] tag '[cat_type]' is not a valid background label.") else if(background.category != cat_type) fails++ - log_bad("Forced background value '[val]' for [species_name] tag '[cat_type]' does not match background datum category ([background.category] must equal [cat_type]).") + log_bad("Forced background value '[val]' for [species.type] tag '[cat_type]' does not match background datum category ([background.category] must equal [cat_type]).") else if(!background.description) fails++ - log_bad("Forced background value '[val]' for [species_name] tag '[cat_type]' does not have a description set.") + log_bad("Forced background value '[val]' for [species.type] tag '[cat_type]' does not have a description set.") if(!islist(species.available_background_info)) fails++ - log_bad("Available background info for [species_name] is not a list.") + log_bad("Available background info for [species.type] is not a list.") else for(var/cat_type in all_background_tokens) if(!islist(species.available_background_info[cat_type])) fails++ - log_bad("Available background info for [species_name] tag '[cat_type]' is invalid type, must be a list.") + log_bad("Available background info for [species.type] tag '[cat_type]' is invalid type, must be a list.") else if(!LAZYLEN(species.available_background_info[cat_type])) fails++ - log_bad("Available background info for [species_name] tag '[cat_type]' is empty, must have at least one entry.") + log_bad("Available background info for [species.type] tag '[cat_type]' is empty, must have at least one entry.") else for(var/val in species.available_background_info[cat_type]) if(istext(val)) - log_bad("Available background value '[val]' for [species_name] tag '[cat_type]' is text, must be a type.") + log_bad("Available background value '[val]' for [species.type] tag '[cat_type]' is text, must be a type.") else var/decl/background_detail/background = GET_DECL(val) if(!istype(background)) fails++ - log_bad("Available background value '[val]' for [species_name] tag '[cat_type]' is not a valid background label.") + log_bad("Available background value '[val]' for [species.type] tag '[cat_type]' is not a valid background label.") else if(background.category != cat_type) fails++ - log_bad("Available background value '[val]' for [species_name] tag '[cat_type]' does not match background datum category ([background.category] must equal [cat_type]).") + log_bad("Available background value '[val]' for [species.type] tag '[cat_type]' does not match background datum category ([background.category] must equal [cat_type]).") else if(!background.description) fails++ - log_bad("Available background value '[val]' for [species_name] tag '[cat_type]' does not have a description set.") + log_bad("Available background value '[val]' for [species.type] tag '[cat_type]' does not have a description set.") if(fails > 0) fail("[fails] invalid background value(s)") diff --git a/code/unit_tests/clothing.dm b/code/unit_tests/clothing.dm index 8219e6d04188..c3be17e43c58 100644 --- a/code/unit_tests/clothing.dm +++ b/code/unit_tests/clothing.dm @@ -8,7 +8,8 @@ var/list/icon_states_checked = list() var/list/reported_failures = list() - var/decl/species/default_species = get_species_by_key(SPECIES_HUMAN) + // TODO: Make this not hardcoded to humans, and test more than just the default bodytype. + var/decl/species/default_species = decls_repository.get_decl_by_id(/decl/species/human::uid) var/decl/bodytype/default_bodytype = default_species.default_bodytype var/state_base = default_bodytype.bodytype_category diff --git a/code/unit_tests/equipment_tests.dm b/code/unit_tests/equipment_tests.dm index dac446856e8b..0779dfb8b5f0 100644 --- a/code/unit_tests/equipment_tests.dm +++ b/code/unit_tests/equipment_tests.dm @@ -7,7 +7,7 @@ async = 1 /datum/unit_test/vision_glasses/start_test() - subject = new(get_safe_turf(), SPECIES_HUMAN) // force human so default map species doesn't mess with anything + subject = new(get_safe_turf(), /decl/species/human::uid) // force human so default map species doesn't mess with anything subject.equip_to_slot(new glasses_type(subject), slot_glasses_str) return 1 @@ -150,7 +150,7 @@ failure_list += "[item] was equipped to [equipped_location] despite failing isEquipped (should not be equipped)." /datum/unit_test/equipment_slot_test/start_test() - var/mob/living/human/subject = new(get_safe_turf(), SPECIES_HUMAN) // force human so default map species doesn't mess with anything + var/mob/living/human/subject = new(get_safe_turf(), /decl/species/human::uid) // force human so default map species doesn't mess with anything created_atoms |= subject var/list/failures = list() diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 578242d58e04..f7613b917d75 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -29,7 +29,7 @@ continue dummy_appearance.root_species = species dummy_appearance.root_bodytype = bodytype - var/mob/living/human/test_subject = new(T, species.name, dummy_appearance) + var/mob/living/human/test_subject = new(T, species.uid, dummy_appearance) if(test_subject.need_breathe()) test_subject.apply_effect(20, STUN, 0) var/obj/item/organ/internal/lungs/L = test_subject.get_organ(test_subject.get_bodytype().breathing_organ, /obj/item/organ/internal/lungs) @@ -71,7 +71,7 @@ test_result["msg"] = "Unable to find a location to create test mob" return test_result - var/mob/living/human/H = new mobtype(mobloc, SPECIES_HUMAN) // force human for testing + var/mob/living/human/H = new mobtype(mobloc, global.using_map.default_species) // force default species for testing H.mind_initialize("TestKey[rand(0,10000)]") @@ -282,8 +282,8 @@ /datum/unit_test/mob_nullspace/start_test() // Simply create one of each species type in nullspace - for(var/species_name in get_all_species()) - var/test_subject = new/mob/living/human(null, species_name) + for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) + var/test_subject = new/mob/living/human(null, species.uid) test_subjects += test_subject return TRUE @@ -303,13 +303,24 @@ /datum/unit_test/mob_organ_size/start_test() var/failed = FALSE - for(var/species_name in get_all_species()) - var/mob/living/human/H = new(null, species_name) - for(var/obj/item/organ/external/E in H.get_external_organs()) - for(var/obj/item/organ/internal/I in E.internal_organs) - if(I.w_class > E.cavity_max_w_class) - failed = TRUE - log_bad("Internal organ [I] inside external organ [E] on species [species_name] was too large to fit.") + var/datum/mob_snapshot/dummy_appearance = new + for(var/decl/bodytype/bodytype in decls_repository.get_decls_of_subtype_unassociated(/decl/bodytype)) + var/decl/species/species = bodytype.get_user_species_for_validation() + if(!species) + continue + dummy_appearance.root_species = species + dummy_appearance.root_bodytype = bodytype + var/mob/living/human/test_subject = new(null, species.uid, dummy_appearance) + for(var/obj/item/organ/internal/organ in test_subject.get_internal_organs()) + var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(test_subject, organ.parent_organ) + if(!parent) + failed = TRUE + log_bad("Internal organ [organ] inside mob of species [species.type] lacked a parent organ (expected [organ.parent_organ])!") + continue + if(organ.w_class > parent.cavity_max_w_class) + failed = TRUE + log_bad("Internal organ [organ] inside external organ [parent] on species [species.type] was too large to fit.") + QDEL_NULL(dummy_appearance) if(failed) fail("A mob had an internal organ too large for its external organ.") else diff --git a/code/unit_tests/organ_tests.dm b/code/unit_tests/organ_tests.dm index 7aa38550be82..72d20645b58b 100644 --- a/code/unit_tests/organ_tests.dm +++ b/code/unit_tests/organ_tests.dm @@ -123,7 +123,7 @@ continue dummy_appearance.root_species = species dummy_appearance.root_bodytype = bodytype - var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) + var/mob/living/human/test_subject = new(null, species.uid, dummy_appearance) var/fail = 0 fail |= !check_internal_organs(test_subject, bodytype) @@ -260,7 +260,7 @@ continue dummy_appearance.root_species = species dummy_appearance.root_bodytype = bodytype - var/mob/living/human/test_subject = new(null, species.name, dummy_appearance) + var/mob/living/human/test_subject = new(null, species.uid, dummy_appearance) for(var/O in test_subject.get_internal_organs()) if(!test_internal_organ(test_subject, O)) diff --git a/code/unit_tests/traders.dm b/code/unit_tests/traders.dm index e05559885302..fda00e9c246b 100644 --- a/code/unit_tests/traders.dm +++ b/code/unit_tests/traders.dm @@ -45,7 +45,7 @@ var/list/all_species = decls_repository.get_decls_of_subtype(/decl/species) for(var/species_type in all_species) var/decl/species/species = all_species[species_type] - acceptable_additional_tokens |= "[TRADER_HAIL_START][species.name]" + acceptable_additional_tokens |= "[TRADER_HAIL_START][species.uid]" var/list/failures = list() for(var/trader_type in subtypesof(/datum/trader)) diff --git a/maps/shaded_hills/shaded_hills_map.dm b/maps/shaded_hills/shaded_hills_map.dm index 09bf988942e0..59f2a26ce09a 100644 --- a/maps/shaded_hills/shaded_hills_map.dm +++ b/maps/shaded_hills/shaded_hills_map.dm @@ -1,6 +1,6 @@ /datum/map/shaded_hills default_liquid_fuel_type = /decl/material/liquid/oil - default_species = SPECIES_KOBALOI + default_species = /decl/species/kobaloi::uid loadout_categories = list( /decl/loadout_category/fantasy/clothing, /decl/loadout_category/fantasy/utility diff --git a/maps/~mapsystem/maps.dm b/maps/~mapsystem/maps.dm index 394aa2eceaca..a5266629ce9e 100644 --- a/maps/~mapsystem/maps.dm +++ b/maps/~mapsystem/maps.dm @@ -136,7 +136,7 @@ var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable var/list/station_departments = list()//Gets filled automatically depending on jobs allowed - var/default_species = SPECIES_HUMAN + var/default_species = /decl/species/human::uid // Can this map be voted for by players? var/votable = TRUE @@ -564,7 +564,7 @@ var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable if(!length(SSmapping.contact_levels)) log_error("[name] has no contact levels!") . = FALSE - var/decl/species/default_species_decl = get_species_by_key(default_species) + var/decl/species/default_species_decl = decls_repository.get_decl_by_id(default_species) if(default_species_decl.species_flags & SPECIES_IS_RESTRICTED) log_error("[name]'s default species [default_species_decl.type] is set to restricted!") if(default_species_decl.species_flags & SPECIES_IS_WHITELISTED) diff --git a/mods/content/corporate/away_sites/lar_maria/lar_maria.dm b/mods/content/corporate/away_sites/lar_maria/lar_maria.dm index 68c947fe0a57..269d8ed89b83 100644 --- a/mods/content/corporate/away_sites/lar_maria/lar_maria.dm +++ b/mods/content/corporate/away_sites/lar_maria/lar_maria.dm @@ -24,10 +24,10 @@ ///////////////////////////////////crew and prisoners /obj/abstract/landmark/corpse/lar_maria - eye_colors_per_species = list(SPECIES_HUMAN = list(COLOR_RED))//red eyes - skin_tones_per_species = list(SPECIES_HUMAN = list(-15)) - facial_styles_per_species = list(SPECIES_HUMAN = list(/decl/sprite_accessory/facial_hair/shaved)) - genders_per_species = list(SPECIES_HUMAN = list(MALE)) + eye_colors_per_species = list(/decl/species/human::uid = list(COLOR_RED))//red eyes + skin_tones_per_species = list(/decl/species/human::uid = list(-15)) + facial_styles_per_species = list(/decl/species/human::uid = list(/decl/sprite_accessory/facial_hair/shaved)) + genders_per_species = list(/decl/species/human::uid = list(MALE)) /mob/living/simple_animal/hostile/lar_maria name = "Lar Maria hostile mob" @@ -83,10 +83,10 @@ /obj/abstract/landmark/corpse/lar_maria/zhp_guard name = "dead guard" corpse_outfits = list(/decl/outfit/corpse/zhp_guard) - skin_tones_per_species = list(SPECIES_HUMAN = list(-15)) + skin_tones_per_species = list(/decl/species/human::uid = list(-15)) /obj/abstract/landmark/corpse/lar_maria/zhp_guard/dark - skin_tones_per_species = list(SPECIES_HUMAN = list(-115)) + skin_tones_per_species = list(/decl/species/human::uid = list(-115)) /decl/outfit/corpse/zhp_guard name = "Dead ZHP guard" @@ -161,9 +161,9 @@ /obj/abstract/landmark/corpse/lar_maria/virologist_female name = "dead virologist" corpse_outfits = list(/decl/outfit/corpse/zhp_virologist_female) - hair_styles_per_species = list(SPECIES_HUMAN = list(/decl/sprite_accessory/hair/flair)) - hair_colors_per_species = list(SPECIES_HUMAN = list("#ae7b48")) - genders_per_species = list(SPECIES_HUMAN = list(FEMALE)) + hair_styles_per_species = list(/decl/species/human::uid = list(/decl/sprite_accessory/hair/flair)) + hair_colors_per_species = list(/decl/species/human::uid = list("#ae7b48")) + genders_per_species = list(/decl/species/human::uid = list(FEMALE)) /decl/outfit/corpse/zhp_virologist_female name = "Dead female ZHP virologist" diff --git a/mods/content/fantasy/_fantasy.dm b/mods/content/fantasy/_fantasy.dm index 41796ad41966..43b31de9fc4f 100644 --- a/mods/content/fantasy/_fantasy.dm +++ b/mods/content/fantasy/_fantasy.dm @@ -1,7 +1,3 @@ -#define SPECIES_KOBALOI "Kobaloi" -#define SPECIES_HNOLL "Hnoll" -#define SPECIES_DVERGR "Dvergr" - #define BODYTYPE_KOBALOI "reptomammalian body" #define BODYTYPE_HNOLL "hyenoid body" #define BODYTYPE_DVERGR "small humanoid body" diff --git a/mods/content/fantasy/datum/hnoll/markings.dm b/mods/content/fantasy/datum/hnoll/markings.dm index f9ad2750b7fc..e897347c5c81 100644 --- a/mods/content/fantasy/datum/hnoll/markings.dm +++ b/mods/content/fantasy/datum/hnoll/markings.dm @@ -2,7 +2,7 @@ /decl/sprite_accessory/hair/hnoll name = "Hnoll Rattail" icon_state = "hair_rattail" - species_allowed = list(SPECIES_HNOLL) + species_allowed = list(/decl/species/hnoll::uid) icon = 'mods/content/fantasy/icons/hnoll/hair.dmi' color_blend = ICON_MULTIPLY uid = "acc_hair_hnoll_rattail" @@ -135,7 +135,7 @@ /decl/sprite_accessory/facial_hair/hnoll name = "Hnoll Sideburns" icon_state = "facial_sideburns" - species_allowed = list(SPECIES_HNOLL) + species_allowed = list(/decl/species/hnoll::uid) icon = 'mods/content/fantasy/icons/hnoll/facial.dmi' color_blend = ICON_MULTIPLY uid = "acc_fhair_hnoll_sideburns" @@ -169,7 +169,7 @@ name = "Hnoll Nose" icon_state = "nose" icon = 'mods/content/fantasy/icons/hnoll/markings.dmi' - species_allowed = list(SPECIES_HNOLL) + species_allowed = list(/decl/species/hnoll::uid) body_parts = list(BP_HEAD) color_blend = ICON_MULTIPLY uid = "acc_marking_hnoll_nose" diff --git a/mods/content/fantasy/datum/hnoll/species.dm b/mods/content/fantasy/datum/hnoll/species.dm index 6d678e469c47..21785afa88a1 100644 --- a/mods/content/fantasy/datum/hnoll/species.dm +++ b/mods/content/fantasy/datum/hnoll/species.dm @@ -13,7 +13,7 @@ /decl/species/hnoll uid = "species_hnoll" - name = SPECIES_HNOLL + name = "Hnoll" name_plural = "Hnoll" description = "The hnoll are thickly-furred, powerfully built bipeds with a notable resemblance to the steppe \ hyenas that often decorate their coinage and art. The oldest hnoll cultures make their home on the Grass Ocean and the \ diff --git a/mods/content/fantasy/datum/kobaloi/markings.dm b/mods/content/fantasy/datum/kobaloi/markings.dm index fd2c99a3f102..96132b522a3a 100644 --- a/mods/content/fantasy/datum/kobaloi/markings.dm +++ b/mods/content/fantasy/datum/kobaloi/markings.dm @@ -6,7 +6,7 @@ abstract_type = /decl/sprite_accessory/marking/kobaloi icon = 'mods/content/fantasy/icons/kobaloi/markings.dmi' color_blend = ICON_MULTIPLY - species_allowed = list(SPECIES_KOBALOI) + species_allowed = list(/decl/species/kobaloi::uid) body_parts = list(BP_HEAD) mask_to_bodypart = FALSE diff --git a/mods/content/fantasy/datum/kobaloi/species.dm b/mods/content/fantasy/datum/kobaloi/species.dm index 4a1979f8f76b..e2eada0ede5f 100644 --- a/mods/content/fantasy/datum/kobaloi/species.dm +++ b/mods/content/fantasy/datum/kobaloi/species.dm @@ -1,7 +1,7 @@ /decl/species/kobaloi uid = "species_kobaloi" - name = SPECIES_KOBALOI - name_plural = SPECIES_KOBALOI + name = "Kobaloi" + name_plural = "Kobaloi" spawn_flags = SPECIES_CAN_JOIN preview_outfit = null description = "Kobaloi are small, scaled and furred creatures that usually dwell in the quiet places of the world, \ diff --git a/mods/content/xenobiology/_xenobiology.dm b/mods/content/xenobiology/_xenobiology.dm index ab4b0f9da7ae..d34306165c6b 100644 --- a/mods/content/xenobiology/_xenobiology.dm +++ b/mods/content/xenobiology/_xenobiology.dm @@ -1,9 +1,8 @@ #define isslime(X) istype(X, /mob/living/slime) -#define SPECIES_GOLEM "Golem" /decl/modpack/xenobiology name = "Xenobiology" /decl/modpack/xenobiology/initialize() . = ..() - SSmodpacks.default_submap_blacklisted_species += SPECIES_GOLEM + SSmodpacks.default_submap_blacklisted_species += /decl/species/golem::uid diff --git a/mods/content/xenobiology/slime/items.dm b/mods/content/xenobiology/slime/items.dm index 9689cd8b129f..6c175cc88f5d 100644 --- a/mods/content/xenobiology/slime/items.dm +++ b/mods/content/xenobiology/slime/items.dm @@ -99,7 +99,7 @@ visible_message(SPAN_WARNING("A craggy humanoid figure coalesces into being!")) var/mob/living/human/G = new(src.loc) - G.set_species(SPECIES_GOLEM) + G.set_species(/decl/species/golem::uid) G.key = ghost.key var/obj/item/implant/translator/natural/I = new() diff --git a/mods/content/xenobiology/species/golem.dm b/mods/content/xenobiology/species/golem.dm index 26edb43ce686..0c247f87bddd 100644 --- a/mods/content/xenobiology/species/golem.dm +++ b/mods/content/xenobiology/species/golem.dm @@ -11,7 +11,7 @@ /decl/species/golem uid = "species_golem" - name = SPECIES_GOLEM + name = "Golem" name_plural = "Golems" hidden_from_codex = TRUE diff --git a/mods/gamemodes/heist/special_role.dm b/mods/gamemodes/heist/special_role.dm index 81f043b491f9..d9f984dcf6c7 100644 --- a/mods/gamemodes/heist/special_role.dm +++ b/mods/gamemodes/heist/special_role.dm @@ -55,5 +55,5 @@ return 1 /decl/special_role/raider/equip_role(var/mob/living/human/player) - default_outfit = LAZYACCESS(outfits_per_species, player.species.name) || initial(default_outfit) + default_outfit = LAZYACCESS(outfits_per_species, player.species.uid) || initial(default_outfit) . = ..() diff --git a/mods/species/adherent/_adherent.dm b/mods/species/adherent/_adherent.dm index e71681dc4311..a3956328501e 100644 --- a/mods/species/adherent/_adherent.dm +++ b/mods/species/adherent/_adherent.dm @@ -3,7 +3,6 @@ #define BP_JETS "maneuvering jets" #define BP_COOLING_FINS "cooling fins" -#define SPECIES_ADHERENT "Adherent" #define BODYTYPE_ADHERENT "adherent body" /decl/modpack/adherent @@ -11,8 +10,8 @@ /decl/modpack/adherent/pre_initialize() ..() - SSmodpacks.default_submap_whitelisted_species |= SPECIES_ADHERENT + SSmodpacks.default_submap_whitelisted_species |= /decl/species/adherent::uid -/mob/living/human/adherent/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) - species_name = SPECIES_ADHERENT +/mob/living/human/adherent/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) + species_uid = /decl/species/adherent::uid . = ..() diff --git a/mods/species/adherent/datum/species.dm b/mods/species/adherent/datum/species.dm index 435c0f2ad81b..938102c15af1 100644 --- a/mods/species/adherent/datum/species.dm +++ b/mods/species/adherent/datum/species.dm @@ -12,7 +12,7 @@ /decl/species/adherent uid = "species_adherent" - name = SPECIES_ADHERENT + name = "Adherent" name_plural = "Adherents" base_external_prosthetics_model = null diff --git a/mods/species/ascent/ascent.dm b/mods/species/ascent/ascent.dm index b2240733cf15..611b84f81fc8 100644 --- a/mods/species/ascent/ascent.dm +++ b/mods/species/ascent/ascent.dm @@ -1,7 +1,3 @@ -#define SPECIES_MANTID_ALATE "Kharmaan Alate" -#define SPECIES_MANTID_GYNE "Kharmaan Gyne" -#define SPECIES_MANTID_NYMPH "Kharmaan Nymph" - #define BODYTYPE_MANTID_SMALL "small mantid body" #define BODYTYPE_MANTID_LARGE "large mantid body" @@ -15,7 +11,5 @@ ##_thing/ascent/desc = "Some kind of strange alien " + _desc + " technology."; \ ##_thing/ascent/color = COLOR_PURPLE; -#define ALL_ASCENT_SPECIES list(SPECIES_MANTID_ALATE, SPECIES_MANTID_GYNE) - /decl/modpack/ascent name = "The Ascent" diff --git a/mods/species/ascent/datum/antagonist.dm b/mods/species/ascent/datum/antagonist.dm index 2dd1000fac8f..fbf82caec228 100644 --- a/mods/species/ascent/datum/antagonist.dm +++ b/mods/species/ascent/datum/antagonist.dm @@ -21,21 +21,22 @@ if(ishuman(player.current)) var/mob/living/human/H = player.current H.set_gyne_lineage(lineage) // This makes all antag ascent have the same lineage on get_random_name. - if(!leader && is_species_whitelisted(player.current, SPECIES_MANTID_GYNE)) + var/species_uid = H.get_species()?.uid + if(!leader && is_species_whitelisted(player.current, /decl/species/mantid/gyne::uid)) leader = player - if(H.species.get_root_species_name() != SPECIES_MANTID_GYNE) - H.set_species(SPECIES_MANTID_GYNE) + if(species_uid != /decl/species/mantid/gyne::uid) + H.set_species(/decl/species/mantid/gyne::uid) H.set_gender(FEMALE) else - if(H.species.get_root_species_name() != SPECIES_MANTID_ALATE) - H.set_species(SPECIES_MANTID_ALATE) + if(species_uid != /decl/species/mantid::uid) + H.set_species(/decl/species/mantid::uid) H.set_gender(MALE) var/decl/background_detail/heritage/ascent/background = GET_DECL(/decl/background_detail/heritage/ascent) H.real_name = background.get_random_name(H, H.gender) H.name = H.real_name /decl/special_role/hunter/equip_role(var/mob/living/human/player) - if(player?.species.get_root_species_name(player) == SPECIES_MANTID_GYNE) + if(player?.get_species()?.uid == /decl/species/mantid::uid) rig_type = /obj/item/rig/mantid/gyne else rig_type = initial(rig_type) diff --git a/mods/species/ascent/datum/languages.dm b/mods/species/ascent/datum/languages.dm index d4af47ccc14e..6ea22b2a117d 100644 --- a/mods/species/ascent/datum/languages.dm +++ b/mods/species/ascent/datum/languages.dm @@ -12,8 +12,8 @@ shorthand = "KV" machine_understands = FALSE var/list/correct_mouthbits = list( - SPECIES_MANTID_ALATE, - SPECIES_MANTID_GYNE + /decl/species/mantid::uid, + /decl/species/mantid/gyne::uid ) /decl/language/mantid/can_be_spoken_properly_by(var/mob/speaker) @@ -24,7 +24,7 @@ return SPEECH_RESULT_GOOD if(ishuman(speaker)) var/mob/living/human/H = speaker - if(H.species.name in correct_mouthbits) + if(H.species.uid in correct_mouthbits) return SPEECH_RESULT_GOOD return SPEECH_RESULT_MUDDLED @@ -74,7 +74,7 @@ return TRUE else if(ishuman(speaker)) var/mob/living/human/H = speaker - return (H.species.name == SPECIES_MANTID_ALATE || H.species.name == SPECIES_MANTID_GYNE) + return istype(H.get_species(), /decl/species/mantid) return FALSE /decl/language/mantid/worldnet diff --git a/mods/species/ascent/datum/species.dm b/mods/species/ascent/datum/species.dm index fa9f6607d9ba..421eb27a89ed 100644 --- a/mods/species/ascent/datum/species.dm +++ b/mods/species/ascent/datum/species.dm @@ -25,7 +25,7 @@ /decl/species/mantid uid = "species_mantid_alate" - name = SPECIES_MANTID_ALATE + name = "Kharmaan Alate" name_plural = "Kharmaan Alates" show_ssd = "quiescent" hidden_from_codex = TRUE @@ -92,8 +92,7 @@ /decl/species/mantid/gyne uid = "species_mantid_gyne" - - name = SPECIES_MANTID_GYNE + name = "Kharmaan Gyne" name_plural = "Kharmaan Gynes" available_bodytypes = list(/decl/bodytype/crystalline/mantid/gyne) diff --git a/mods/species/ascent/datum/traits.dm b/mods/species/ascent/datum/traits.dm index 2e8e36b2bb56..9faaa45fd242 100644 --- a/mods/species/ascent/datum/traits.dm +++ b/mods/species/ascent/datum/traits.dm @@ -1,9 +1,8 @@ /decl/trait/build_references() . = ..() LAZYINITLIST(blocked_species) - blocked_species |= SPECIES_MANTID_ALATE - blocked_species |= SPECIES_MANTID_GYNE - blocked_species |= SPECIES_MANTID_NYMPH + blocked_species |= /decl/species/mantid::uid + blocked_species |= /decl/species/mantid/gyne::uid /decl/trait/ascent abstract_type = /decl/trait/ascent @@ -12,9 +11,8 @@ . = ..() blocked_species = null permitted_species = list( - SPECIES_MANTID_ALATE, - SPECIES_MANTID_GYNE, - SPECIES_MANTID_NYMPH + /decl/species/mantid::uid, + /decl/species/mantid/gyne::uid ) // Modifies the exosuit that you spawn with. diff --git a/mods/species/ascent/effects/razorweb.dm b/mods/species/ascent/effects/razorweb.dm index ec7b461524a6..fe859d155f99 100644 --- a/mods/species/ascent/effects/razorweb.dm +++ b/mods/species/ascent/effects/razorweb.dm @@ -32,8 +32,8 @@ var/image/gleam var/image/web var/static/species_immunity_list = list( - SPECIES_MANTID_ALATE = TRUE, - SPECIES_MANTID_GYNE = TRUE + /decl/species/mantid::uid = TRUE, + /decl/species/mantid/gyne::uid = TRUE ) /obj/effect/razorweb/Destroy() @@ -133,7 +133,7 @@ var/mob/living/human/H if(ishuman(L)) H = L - if(species_immunity_list[H.species.name]) + if(species_immunity_list[H.species.uid]) return if(!silent) diff --git a/mods/species/ascent/items/id_control.dm b/mods/species/ascent/items/id_control.dm index b5d09fe55e4a..5a7831346832 100644 --- a/mods/species/ascent/items/id_control.dm +++ b/mods/species/ascent/items/id_control.dm @@ -8,7 +8,7 @@ /obj/item/card/id/ascent/GetAccess() var/mob/living/human/H = loc - if(istype(H) && !(H.species.name in ALL_ASCENT_SPECIES)) + if(istype(H) && !istype(H.get_species(), /decl/species/mantid)) . = list() else . = ..() diff --git a/mods/species/ascent/items/rig.dm b/mods/species/ascent/items/rig.dm index 214f60caa99a..321d28d856af 100644 --- a/mods/species/ascent/items/rig.dm +++ b/mods/species/ascent/items/rig.dm @@ -41,7 +41,7 @@ /obj/item/rig_module/maneuvering_jets ) req_access = list(access_ascent) - var/mantid_caste = SPECIES_MANTID_ALATE + var/mantid_caste = /decl/species/mantid::uid // Renamed blade. /obj/item/rig_module/mounted/energy_blade/mantid @@ -209,7 +209,7 @@ ARMOR_BIO = ARMOR_BIO_SHIELDED, ARMOR_RAD = ARMOR_RAD_SHIELDED ) - mantid_caste = SPECIES_MANTID_GYNE + mantid_caste = /decl/species/mantid/gyne::uid initial_modules = list( /obj/item/rig_module/vision/thermal, /obj/item/rig_module/ai_container, @@ -231,7 +231,7 @@ if(!. || slot != slot_back_str || !mantid_caste) return var/decl/species/my_species = user?.get_species() - if(my_species?.get_root_species_name(user) != mantid_caste) + if(my_species?.uid != mantid_caste) to_chat(user, SPAN_WARNING("Your species cannot wear \the [src].")) return FALSE diff --git a/mods/species/ascent/machines/magnetotron.dm b/mods/species/ascent/machines/magnetotron.dm index ef49173254c6..878e9bc4c819 100644 --- a/mods/species/ascent/machines/magnetotron.dm +++ b/mods/species/ascent/machines/magnetotron.dm @@ -24,7 +24,7 @@ display_message("No biological signature detected in [src].") return TRUE - if(target.get_species_name() != SPECIES_MANTID_ALATE) + if(target.get_species()?.uid != /decl/species/mantid::uid) display_message("Invalid biological signature detected. Safety mechanisms engaged, only alates may undergo metamorphosis.") return TRUE @@ -46,7 +46,7 @@ target.visible_message(SPAN_NOTICE("[target] molts away their shell, emerging as a new gyne.")) spark_at(src, cardinal_only = TRUE) ADJ_STATUS(target, STAT_STUN, 6) - target.change_species(SPECIES_MANTID_GYNE) + target.change_species(/decl/species/mantid/gyne::uid) new /obj/effect/temp_visual/emp_burst(loc) for(var/obj/item/organ/external/E in target.get_external_organs()) if(prob(60)) @@ -59,7 +59,7 @@ /obj/machinery/ascent_magnetotron/proc/get_total_gynes() for(var/mob/living/human/H in global.living_mob_list_) - if(H.get_species_name() == SPECIES_MANTID_GYNE) + if(H.get_species()?.uid == /decl/species/mantid/gyne::uid) . += 1 /obj/item/stock_parts/circuitboard/ascent_magnetotron diff --git a/mods/species/ascent/machines/ship_machines.dm b/mods/species/ascent/machines/ship_machines.dm index 84d848e7d14d..9db2e97943ca 100644 --- a/mods/species/ascent/machines/ship_machines.dm +++ b/mods/species/ascent/machines/ship_machines.dm @@ -164,7 +164,7 @@ MANTIDIFY(/obj/item/chems/chem_disp_cartridge, "canister", "chemical storage") return ..() if(ishuman(user)) var/mob/living/human/H = user - if(!(H.species.name in ALL_ASCENT_SPECIES)) + if(!istype(H.get_species(), /decl/species/mantid)) to_chat(H, SPAN_WARNING("You have no idea how to use \the [src].")) return TRUE else if(!isascentdrone(user)) diff --git a/mods/species/ascent/mobs/insectoid_egg.dm b/mods/species/ascent/mobs/insectoid_egg.dm index 685b62a50aa4..bfc48cac0def 100644 --- a/mods/species/ascent/mobs/insectoid_egg.dm +++ b/mods/species/ascent/mobs/insectoid_egg.dm @@ -95,7 +95,7 @@ var/global/default_gyne if(!current_health || maturity != 100 || hatched || hatching) return - var/mob/living/simple_animal/alien/kharmaan/new_nymph = new(src, SPECIES_MANTID_NYMPH) // Spawn in the egg. + var/mob/living/simple_animal/alien/kharmaan/new_nymph = new(src) // Spawn in the egg. new_nymph.lastarea = get_area(src) new_nymph.key = C.ckey new_nymph.real_name = "[random_id(/decl/species/mantid, 10000, 99999)] [lineage]" diff --git a/mods/species/ascent/mobs/nymph/nymph_life.dm b/mods/species/ascent/mobs/nymph/nymph_life.dm index 0724b604a493..8879b71c576f 100644 --- a/mods/species/ascent/mobs/nymph/nymph_life.dm +++ b/mods/species/ascent/mobs/nymph/nymph_life.dm @@ -41,7 +41,7 @@ visible_message("\icon[src] [src] begins to shimmy and shake out of its old skin.") if(molt == 5) if(do_after(src, 10 SECONDS, src, FALSE)) - var/mob/living/human/H = new(get_turf(src), SPECIES_MANTID_ALATE) + var/mob/living/human/H = new(get_turf(src), /decl/species/mantid::uid) H.set_gyne_lineage(get_gyne_lineage()) H.real_name = "[random_id(/decl/species/mantid, 10000, 99999)] [H.get_gyne_name()]" H.nutrition = nutrition * 0.25 // Homgry after molt. diff --git a/mods/species/drakes/_drakes.dm b/mods/species/drakes/_drakes.dm index 47bf61c6a401..1843e9e473e9 100644 --- a/mods/species/drakes/_drakes.dm +++ b/mods/species/drakes/_drakes.dm @@ -1,4 +1,3 @@ -#define SPECIES_GRAFADREKA "Grafadreka" #define BODYTYPE_GRAFADREKA "drake body" #define BODYTYPE_GRAFADREKA_HATCHLING "hatchling drake body" #define BP_DRAKE_GIZZARD "drake gizzard" @@ -6,7 +5,6 @@ /decl/modpack/grafadreka name = "Grafadreka Species" -/mob/living/human/grafadreka/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) - // fantasy modpack overrides drake name, so can't use the #define - var/decl/species/grafadreka/drakes = GET_DECL(/decl/species/grafadreka) - . = ..(mapload, drakes.name) +/mob/living/human/grafadreka/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) + species_uid = /decl/species/grafadreka::uid + . = ..() diff --git a/mods/species/drakes/species.dm b/mods/species/drakes/species.dm index f8a494ed89de..40d272e983ce 100644 --- a/mods/species/drakes/species.dm +++ b/mods/species/drakes/species.dm @@ -1,7 +1,7 @@ /decl/species/grafadreka uid = "species_grafadreka" - name = SPECIES_GRAFADREKA - name_plural = SPECIES_GRAFADREKA + name = "Grafadreka" + name_plural = "Grafadreka" description = "The reclusive grafadreka (Icelandic, lit. 'digging dragon'), also known as the snow drake, is a large reptillian pack predator similar in size and morphology to old Earth hyenas. \ They commonly dig shallow dens in dirt, snow or foliage, sometimes using them for concealment prior to an ambush. \ Biological cousins to the elusive kururak, they have heavy, low-slung bodies and powerful jaws suited to hunting land prey rather than fishing. \ diff --git a/mods/species/drakes/species_bodytypes.dm b/mods/species/drakes/species_bodytypes.dm index c5cbabe65312..5d8bf5862b68 100644 --- a/mods/species/drakes/species_bodytypes.dm +++ b/mods/species/drakes/species_bodytypes.dm @@ -262,7 +262,7 @@ icon = 'mods/species/drakes/icons/markings.dmi' icon_state = "spines" uid = "acc_marking_drake_spines" - species_allowed = list(SPECIES_GRAFADREKA) + species_allowed = list(/decl/species/grafadreka::uid) color_blend = ICON_MULTIPLY body_parts = list( BP_CHEST, diff --git a/mods/species/neoavians/_neoavians.dm b/mods/species/neoavians/_neoavians.dm index 0f248d0cde0a..426648c86ce8 100644 --- a/mods/species/neoavians/_neoavians.dm +++ b/mods/species/neoavians/_neoavians.dm @@ -1,4 +1,3 @@ -#define SPECIES_AVIAN "Neo-Avian" #define BODYTYPE_AVIAN "avian body" #define BODY_EQUIP_FLAG_AVIAN BITFLAG(6) @@ -7,4 +6,4 @@ /decl/modpack/neoavians/pre_initialize() ..() - SSmodpacks.default_submap_whitelisted_species |= SPECIES_AVIAN + SSmodpacks.default_submap_whitelisted_species |= /decl/species/neoavian::uid diff --git a/mods/species/neoavians/datum/accessory.dm b/mods/species/neoavians/datum/accessory.dm index b8c260ced4b3..978711e67460 100644 --- a/mods/species/neoavians/datum/accessory.dm +++ b/mods/species/neoavians/datum/accessory.dm @@ -3,7 +3,7 @@ name = "Avian Plumage" icon_state = "avian_default" icon = 'mods/species/neoavians/icons/hair.dmi' - species_allowed = list(SPECIES_AVIAN) + species_allowed = list(/decl/species/neoavian::uid) color_blend = ICON_MULTIPLY uid = "acc_hair_avian_plumage" @@ -124,7 +124,7 @@ icon_state = "beak" body_parts = list(BP_HEAD) icon = 'mods/species/neoavians/icons/markings.dmi' - species_allowed = list(SPECIES_AVIAN) + species_allowed = list(/decl/species/neoavian::uid) color_blend = ICON_MULTIPLY uid = "acc_marking_avian_beak" diff --git a/mods/species/neoavians/datum/loadout.dm b/mods/species/neoavians/datum/loadout.dm index 080f69b56d22..608757094363 100644 --- a/mods/species/neoavians/datum/loadout.dm +++ b/mods/species/neoavians/datum/loadout.dm @@ -2,7 +2,7 @@ name = "Avian" /decl/loadout_option/avian - whitelisted = list(SPECIES_AVIAN) + whitelisted = list(/decl/species/neoavian::uid) category = /decl/loadout_category/avian abstract_type = /decl/loadout_option/avian diff --git a/mods/species/neoavians/datum/species.dm b/mods/species/neoavians/datum/species.dm index 9d62eaf06420..1b102057266b 100644 --- a/mods/species/neoavians/datum/species.dm +++ b/mods/species/neoavians/datum/species.dm @@ -17,7 +17,7 @@ /decl/species/neoavian uid = "species_avian" - name = SPECIES_AVIAN + name = "Neo-Avian" name_plural = "Neo-Avians" description = "Avian species, largely crows, magpies and other corvids, were among the first sophonts uplifted to aid in colonizing Mars. \ These days they are more commonly found pursuing their own careers and goals on the fringes of human space or around their adopted homeworld \ diff --git a/mods/species/random_species/_random_species.dm b/mods/species/random_species/_random_species.dm index 7f20e9a608f5..49640db2218c 100644 --- a/mods/species/random_species/_random_species.dm +++ b/mods/species/random_species/_random_species.dm @@ -1,8 +1,6 @@ -#define SPECIES_ALIEN "Humanoid" - /decl/modpack/random_species name = "Random Alien Species" /decl/modpack/random_species/initialize() . = ..() - SSmodpacks.default_submap_blacklisted_species += SPECIES_ALIEN + SSmodpacks.default_submap_blacklisted_species += /decl/species/alium::uid diff --git a/mods/species/random_species/aliumizer.dm b/mods/species/random_species/aliumizer.dm index 6d7ab1e57964..34e95893d565 100644 --- a/mods/species/random_species/aliumizer.dm +++ b/mods/species/random_species/aliumizer.dm @@ -13,19 +13,19 @@ var/decl/species/species = user.get_species() if(!species) return TRUE - if(species.name == SPECIES_ALIEN) - to_chat(user, SPAN_WARNING("You're already a [SPECIES_ALIEN].")) + if(species.uid == /decl/species/alium::uid) + to_chat(user, SPAN_WARNING("You're already an alien.")) return TRUE if(alert("Are you sure you want to be an alien?", "Mom Look I'm An Alien!", "Yes", "No") == "No") - to_chat(user, SPAN_NOTICE("You are now a [SPECIES_ALIEN]!")) + to_chat(user, SPAN_NOTICE("You are now an alien!")) return TRUE - if(species.name == SPECIES_ALIEN) //no spamming it to get free implants + if(species.uid == /decl/species/alium::uid) //no spamming it to get free implants return TRUE to_chat(user, "You're now an alien humanoid of some undiscovered species. Make up what lore you want, no one knows a thing about your species! You can check info about your traits with Check Species Info verb in IC tab.") to_chat(user, "You can't speak any other languages by default. You can use translator implant that spawns on top of this monolith - it will give you knowledge of any language if you hear it enough times.") var/mob/living/human/H = user new /obj/item/implanter/translator(get_turf(src)) - H.change_species(SPECIES_ALIEN) + H.change_species(/decl/species/alium::uid) var/decl/background_detail/background = H.get_background_datum_by_flag(BACKGROUND_FLAG_NAMING) H.fully_replace_character_name(background.get_random_name(H, H.gender)) H.rename_self("Humanoid Alien", 1) diff --git a/mods/species/random_species/random_species_species.dm b/mods/species/random_species/random_species_species.dm index 33dc877d8f76..3db442f8b108 100644 --- a/mods/species/random_species/random_species_species.dm +++ b/mods/species/random_species/random_species_species.dm @@ -1,6 +1,6 @@ /decl/species/alium uid = "species_random_alien" - name = SPECIES_ALIEN + name = "Humanoid" name_plural = "Humanoids" description = "Some alien humanoid species, unknown to humanity. How exciting." rarity_value = 5 diff --git a/mods/species/serpentid/datum/species.dm b/mods/species/serpentid/datum/species.dm index d6b22eabb9c7..f01a3f4c746f 100644 --- a/mods/species/serpentid/datum/species.dm +++ b/mods/species/serpentid/datum/species.dm @@ -20,7 +20,7 @@ /decl/species/serpentid uid = "species_serpentid" - name = SPECIES_SERPENTID + name = "Serpentid" name_plural = "Serpentids" spawn_flags = SPECIES_IS_RESTRICTED diff --git a/mods/species/serpentid/serpentid.dm b/mods/species/serpentid/serpentid.dm index fc9c6b085a4b..627bca7da6b1 100644 --- a/mods/species/serpentid/serpentid.dm +++ b/mods/species/serpentid/serpentid.dm @@ -1,3 +1,2 @@ -#define SPECIES_SERPENTID "Serpentid" #define BODYTYPE_SNAKE "snakelike body" #define BODY_EQUIP_FLAG_SNAKE BITFLAG(12) diff --git a/mods/species/skrell/_skrell.dm b/mods/species/skrell/_skrell.dm index c038ee1d7d22..b6ac75a5b89b 100644 --- a/mods/species/skrell/_skrell.dm +++ b/mods/species/skrell/_skrell.dm @@ -1,5 +1,3 @@ -#define SPECIES_SKRELL "Skrell" - /decl/modpack/skrell name = "Skrell Species" tabloid_headlines = list( @@ -9,8 +7,8 @@ /decl/modpack/skrell/pre_initialize() ..() - SSmodpacks.default_submap_whitelisted_species |= SPECIES_SKRELL + SSmodpacks.default_submap_whitelisted_species |= /decl/species/skrell::uid -/mob/living/human/skrell/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) - species_name = SPECIES_SKRELL +/mob/living/human/skrell/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) + species_uid = /decl/species/skrell::uid . = ..() diff --git a/mods/species/skrell/datum/accessory.dm b/mods/species/skrell/datum/accessory.dm index 86dc5b9755ab..6f142dccdb15 100644 --- a/mods/species/skrell/datum/accessory.dm +++ b/mods/species/skrell/datum/accessory.dm @@ -2,7 +2,7 @@ name = "Kanin - Very Short Headtails" icon = 'mods/species/skrell/icons/body/hair.dmi' icon_state = "very_short" - species_allowed = list(SPECIES_SKRELL) + species_allowed = list(/decl/species/skrell::uid) uid = "acc_hair_skrell_veryshort" /decl/sprite_accessory/hair/skrell/raskin diff --git a/mods/species/skrell/datum/species.dm b/mods/species/skrell/datum/species.dm index a84431f303c1..c327cc9bd342 100644 --- a/mods/species/skrell/datum/species.dm +++ b/mods/species/skrell/datum/species.dm @@ -5,8 +5,8 @@ /decl/species/skrell uid = "species_skrell" - name = SPECIES_SKRELL - name_plural = SPECIES_SKRELL + name = "Skrell" + name_plural = "Skrell" available_bodytypes = list( /decl/bodytype/skrell diff --git a/mods/species/skrell/gear/gear_ears.dm b/mods/species/skrell/gear/gear_ears.dm index 338e30307fe3..474bdf444521 100644 --- a/mods/species/skrell/gear/gear_ears.dm +++ b/mods/species/skrell/gear/gear_ears.dm @@ -4,7 +4,7 @@ /obj/item/clothing/ears/skrell/mob_can_equip(mob/user, slot, disable_warning = FALSE, force = FALSE, ignore_equipped = FALSE) . = ..() - if(. && user?.get_species_name() != SPECIES_SKRELL) + if(. && user?.get_species()?.uid != /decl/species/skrell::uid) return FALSE /obj/item/clothing/ears/skrell/band @@ -43,7 +43,7 @@ /decl/loadout_option/ears/skrell name = "skrell headtail accessory selection" category = /decl/loadout_category/ears - whitelisted = list(SPECIES_SKRELL) + whitelisted = list(/decl/species/skrell::uid) path = /obj/item/clothing/ears/skrell loadout_flags = GEAR_HAS_COLOR_SELECTION | GEAR_HAS_SUBTYPE_SELECTION uid = "gear_accessory_skrell" diff --git a/mods/species/skrell/gear/gear_head.dm b/mods/species/skrell/gear/gear_head.dm index 655c5b99824f..23cd1d2c7193 100644 --- a/mods/species/skrell/gear/gear_head.dm +++ b/mods/species/skrell/gear/gear_head.dm @@ -14,7 +14,7 @@ /obj/item/clothing/head/helmet/space/void/skrell/mob_can_equip(mob/user, slot, disable_warning = FALSE, force = FALSE, ignore_equipped = FALSE) . = ..() - if(. && user?.get_species_name() != SPECIES_SKRELL) + if(. && user?.get_species()?.uid != /decl/species/skrell::uid) return FALSE /obj/item/clothing/head/helmet/space/void/skrell/black @@ -27,5 +27,5 @@ /obj/item/clothing/head/helmet/skrell/mob_can_equip(mob/user, slot, disable_warning = FALSE, force = FALSE, ignore_equipped = FALSE) . = ..() - if(. && user?.get_species_name() != SPECIES_SKRELL) + if(. && user?.get_species()?.uid != /decl/species/skrell::uid) return FALSE diff --git a/mods/species/skrell/gear/gear_mask.dm b/mods/species/skrell/gear/gear_mask.dm index c28f99aa4871..b11dd2f833b1 100644 --- a/mods/species/skrell/gear/gear_mask.dm +++ b/mods/species/skrell/gear/gear_mask.dm @@ -1,7 +1,7 @@ /decl/loadout_option/mask/skrell name = "skrellian gill cover" path = /obj/item/clothing/mask/gas/skrell - whitelisted = list(SPECIES_SKRELL) + whitelisted = list(/decl/species/skrell::uid) uid = "gear_mask_skrell" /obj/item/clothing/mask/gas/skrell @@ -13,5 +13,5 @@ /obj/item/clothing/mask/gas/skrell/mob_can_equip(mob/user, slot, disable_warning = FALSE, force = FALSE, ignore_equipped = FALSE) . = ..() - if(. && user?.get_species_name() != SPECIES_SKRELL) + if(. && user?.get_species()?.uid != /decl/species/skrell::uid) return FALSE diff --git a/mods/species/tajaran/_tajaran.dm b/mods/species/tajaran/_tajaran.dm index cb92dbfae89c..2b07b2c74b82 100644 --- a/mods/species/tajaran/_tajaran.dm +++ b/mods/species/tajaran/_tajaran.dm @@ -1,5 +1,4 @@ #define LANGUAGE_TAJARAN "Siik'maas" -#define SPECIES_TAJARAN "Tajara" #define BODYTYPE_TAJARAN "felinoid body" /decl/modpack/tajaran @@ -10,10 +9,10 @@ /decl/modpack/tajaran/pre_initialize() ..() - SSmodpacks.default_submap_whitelisted_species |= SPECIES_TAJARAN + SSmodpacks.default_submap_whitelisted_species |= /decl/species/tajaran::uid -/mob/living/human/tajaran/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) - . = ..(species_name = SPECIES_TAJARAN) +/mob/living/human/tajaran/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) + . = ..(species_uid = /decl/species/tajaran::uid) /obj/item var/_tajaran_onmob_icon diff --git a/mods/species/tajaran/datum/accessory.dm b/mods/species/tajaran/datum/accessory.dm index 33d858efac46..9c893b7669ab 100644 --- a/mods/species/tajaran/datum/accessory.dm +++ b/mods/species/tajaran/datum/accessory.dm @@ -2,7 +2,7 @@ /decl/sprite_accessory/hair/taj name = "Tajaran Rattail" icon_state = "hair_rattail" - species_allowed = list(SPECIES_TAJARAN) + species_allowed = list(/decl/species/tajaran::uid) icon = 'mods/species/tajaran/icons/hair.dmi' color_blend = ICON_MULTIPLY uid = "acc_hair_taj_rattail" @@ -135,7 +135,7 @@ /decl/sprite_accessory/facial_hair/taj name = "Tajaran Sideburns" icon_state = "facial_sideburns" - species_allowed = list(SPECIES_TAJARAN) + species_allowed = list(/decl/species/tajaran::uid) icon = 'mods/species/tajaran/icons/facial.dmi' color_blend = ICON_MULTIPLY uid = "acc_fhair_taj_sideburns" @@ -169,7 +169,7 @@ name = "Tajaran Nose" icon_state = "nose" icon = 'mods/species/tajaran/icons/markings.dmi' - species_allowed = list(SPECIES_TAJARAN) + species_allowed = list(/decl/species/tajaran::uid) body_parts = list(BP_HEAD) color_blend = ICON_MULTIPLY uid = "acc_marking_taj_nose" diff --git a/mods/species/tajaran/datum/species.dm b/mods/species/tajaran/datum/species.dm index 47e47c8fea62..7282b912bc7a 100644 --- a/mods/species/tajaran/datum/species.dm +++ b/mods/species/tajaran/datum/species.dm @@ -13,7 +13,7 @@ /decl/species/tajaran uid = "species_tajaran" - name = SPECIES_TAJARAN + name = "Tajara" name_plural = "Tajaran" base_external_prosthetics_model = null diff --git a/mods/species/tritonian/_tritonian.dm b/mods/species/tritonian/_tritonian.dm index 5b8b6ad2a6c7..b0a904ef7146 100644 --- a/mods/species/tritonian/_tritonian.dm +++ b/mods/species/tritonian/_tritonian.dm @@ -1,4 +1,2 @@ -#define SPECIES_TRITONIAN "Tritonian" - /decl/modpack/tritonians name = "Tritonian Species" \ No newline at end of file diff --git a/mods/species/tritonian/datum/species.dm b/mods/species/tritonian/datum/species.dm index 6d1090472cd1..782588ca0e7e 100644 --- a/mods/species/tritonian/datum/species.dm +++ b/mods/species/tritonian/datum/species.dm @@ -1,6 +1,6 @@ /decl/species/human/tritonian uid = "species_tritonian" - name = SPECIES_TRITONIAN + name = "Tritonian" name_plural = "Tritonians" description = "A human-derived genotype designed for colonizing aquatic worlds." diff --git a/mods/species/unathi/_unathi.dm b/mods/species/unathi/_unathi.dm index 9815aeceb09c..ca5be894e5da 100644 --- a/mods/species/unathi/_unathi.dm +++ b/mods/species/unathi/_unathi.dm @@ -1,4 +1,3 @@ -#define SPECIES_UNATHI "Unathi" #define LANGUAGE_LIZARD "Sinta'unathi" /decl/modpack/unathi @@ -11,8 +10,8 @@ /decl/modpack/unathi/pre_initialize() ..() - SSmodpacks.default_submap_whitelisted_species |= SPECIES_UNATHI + SSmodpacks.default_submap_whitelisted_species |= /decl/species/unathi::uid -/mob/living/human/unathi/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) - species_name = SPECIES_UNATHI +/mob/living/human/unathi/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) + species_uid = /decl/species/unathi::uid . = ..() diff --git a/mods/species/unathi/datum/species.dm b/mods/species/unathi/datum/species.dm index 3eabb2ef0399..02b118b2e68a 100644 --- a/mods/species/unathi/datum/species.dm +++ b/mods/species/unathi/datum/species.dm @@ -17,8 +17,8 @@ /decl/species/unathi uid = "species_unathi" - name = SPECIES_UNATHI - name_plural = SPECIES_UNATHI + name = "Unathi" + name_plural = "Unathi" butchery_data = /decl/butchery_data/humanoid/unathi available_bodytypes = list( diff --git a/mods/species/unathi/datum/sprite_accessory.dm b/mods/species/unathi/datum/sprite_accessory.dm index bc102edebe41..1175142a4caf 100644 --- a/mods/species/unathi/datum/sprite_accessory.dm +++ b/mods/species/unathi/datum/sprite_accessory.dm @@ -2,7 +2,7 @@ name = "Lizard Horns" icon = 'mods/species/unathi/icons/horns.dmi' icon_state = "horns" - species_allowed = list(SPECIES_UNATHI) + species_allowed = list(/decl/species/unathi::uid) color_blend = ICON_MULTIPLY accessory_flags = HAIR_VERY_SHORT uid = "acc_hair_una_horns" @@ -71,7 +71,7 @@ name = "Lizard Frills Aqua" icon = 'mods/species/unathi/icons/frills.dmi' icon_state = "frills_aqua" - species_allowed = list(SPECIES_UNATHI) + species_allowed = list(/decl/species/unathi::uid) color_blend = ICON_MULTIPLY accessory_flags = HAIR_VERY_SHORT uid = "acc_hair_una_aqua" diff --git a/mods/species/utility_frames/_utility_frames.dm b/mods/species/utility_frames/_utility_frames.dm index c763243445bd..ef8f8957c518 100644 --- a/mods/species/utility_frames/_utility_frames.dm +++ b/mods/species/utility_frames/_utility_frames.dm @@ -1,5 +1,3 @@ -#define SPECIES_FRAME "Utility Frame" - /decl/modpack/utility_frames name = "Utility Frames" dreams = list("a utility frame", "rogue machine servitors") diff --git a/mods/species/utility_frames/markings.dm b/mods/species/utility_frames/markings.dm index ade0c186443c..a4700a242c56 100644 --- a/mods/species/utility_frames/markings.dm +++ b/mods/species/utility_frames/markings.dm @@ -2,7 +2,7 @@ name = "Frame Department Stripe" icon_state = "single_stripe" body_parts = list(BP_CHEST) - species_allowed = list(SPECIES_FRAME) + species_allowed = list(/decl/species/utility_frame::uid) icon = 'mods/species/utility_frames/icons/markings.dmi' color_blend = ICON_MULTIPLY uid = "acc_marking_frame_stripe" diff --git a/mods/species/utility_frames/species.dm b/mods/species/utility_frames/species.dm index ff4d7292c911..7201f13c3cb5 100644 --- a/mods/species/utility_frames/species.dm +++ b/mods/species/utility_frames/species.dm @@ -11,7 +11,7 @@ /decl/species/utility_frame uid = "species_frame" - name = SPECIES_FRAME + name = "Utility Frame" name_plural = "Utility Frames" description = "Simple AI-driven robots are used for many menial or repetitive tasks in human space." cyborg_noun = null diff --git a/mods/species/utility_frames/traits.dm b/mods/species/utility_frames/traits.dm index 66fc29e15eff..8e1150fce82e 100644 --- a/mods/species/utility_frames/traits.dm +++ b/mods/species/utility_frames/traits.dm @@ -1,6 +1,6 @@ /decl/trait/build_references() . = ..() - LAZYDISTINCTADD(blocked_species, SPECIES_FRAME) + LAZYDISTINCTADD(blocked_species, /decl/species/utility_frame::uid) /decl/trait/utility_frame abstract_type = /decl/trait/utility_frame @@ -8,7 +8,7 @@ /decl/trait/utility_frame/build_references() . = ..() blocked_species = null - permitted_species = list(SPECIES_FRAME) + permitted_species = list(/decl/species/utility_frame::uid) // Cosmetic/armour changes, different models of limb /decl/trait/utility_frame/customisation diff --git a/mods/species/vox/_vox.dm b/mods/species/vox/_vox.dm index 7f45da9bb350..70f65067b0b4 100644 --- a/mods/species/vox/_vox.dm +++ b/mods/species/vox/_vox.dm @@ -1,4 +1,3 @@ -#define SPECIES_VOX "Vox" #define BODYTYPE_VOX "reptoavian body" #define BODYTYPE_VOX_LARGE "large reptoavian body" #define BP_HINDTONGUE "hindtongue" @@ -10,10 +9,10 @@ credits_crew_names = list("THE VOX") credits_topics = list("VOX RITUAL DUELS", "NECK MARKINGS", "ANCIENT SUPERCOMPUTERS") -/mob/living/human/vox/Initialize(mapload, species_name, datum/mob_snapshot/supplied_appearance) +/mob/living/human/vox/Initialize(mapload, species_uid, datum/mob_snapshot/supplied_appearance) SET_HAIR_STYLE(src, /decl/sprite_accessory/hair/vox/short, TRUE) SET_HAIR_COLOR(src, COLOR_BEASTY_BROWN, TRUE) - species_name = SPECIES_VOX + species_uid = /decl/species/vox::uid . = ..() /datum/follow_holder/voxstack diff --git a/mods/species/vox/datum/accessories.dm b/mods/species/vox/datum/accessories.dm index 69256c54168b..f0889543cbb7 100644 --- a/mods/species/vox/datum/accessories.dm +++ b/mods/species/vox/datum/accessories.dm @@ -2,7 +2,7 @@ name = "Long Vox Quills" icon = 'mods/species/vox/icons/body/soldier/hair.dmi' icon_state = "vox_longquills" - species_allowed = list(SPECIES_VOX) + species_allowed = list(/decl/species/vox::uid) uid = "acc_hair_vox_longquills" /decl/sprite_accessory/hair/vox/get_accessory_icon(obj/item/organ/external/organ) @@ -30,7 +30,7 @@ name = "Vox Neck Markings" icon_state = "neck_markings" body_parts = list(BP_HEAD) - species_allowed = list(SPECIES_VOX) + species_allowed = list(/decl/species/vox::uid) icon = 'mods/species/vox/icons/body/soldier/markings.dmi' color_blend = ICON_MULTIPLY uid = "acc_markings_vox_neck" diff --git a/mods/species/vox/datum/species.dm b/mods/species/vox/datum/species.dm index 98cb432bf540..fb9a026c4404 100644 --- a/mods/species/vox/datum/species.dm +++ b/mods/species/vox/datum/species.dm @@ -21,8 +21,8 @@ /decl/species/vox uid = "species_vox" - name = SPECIES_VOX - name_plural = SPECIES_VOX + name = "Vox" + name_plural = "Vox" base_external_prosthetics_model = /decl/bodytype/prosthetic/vox/crap default_emotes = list( diff --git a/mods/species/vox/datum/species_bodytypes.dm b/mods/species/vox/datum/species_bodytypes.dm index 092cfeb50b96..6aca9f46c5cc 100644 --- a/mods/species/vox/datum/species_bodytypes.dm +++ b/mods/species/vox/datum/species_bodytypes.dm @@ -147,6 +147,7 @@ /decl/bodytype/vox/stanchion name = "stanchion voxform" bodytype_category = BODYTYPE_VOX_LARGE + // TODO: should the extra big guys really have the same bodytype equip flags as the little guys? blood_overlays = 'mods/species/vox/icons/body/stanchion/blood_overlays.dmi' damage_overlays = 'mods/species/vox/icons/body/stanchion/damage_overlays.dmi' icon_base = 'mods/species/vox/icons/body/stanchion/body.dmi' diff --git a/mods/species/vox/datum/trader.dm b/mods/species/vox/datum/trader.dm index 6211285cb6af..b73bf61ae6b6 100644 --- a/mods/species/vox/datum/trader.dm +++ b/mods/species/vox/datum/trader.dm @@ -61,17 +61,17 @@ /datum/trader/ship/vox/New() speech[TRADER_HAIL_SILICON] = "Hello metal thing! You trade metal for things?" - speech[TRADER_HAIL_START + SPECIES_HUMAN] = "Hello hueman! Kiikikikiki! " + TRADER_TOKEN_MOB + " trade with us, yes? Good!" - visited_vox_speech[TRADER_HAIL_START + SPECIES_HUMAN] = "Friend of it is friend of all Shoal! " + TRADER_TOKEN_MOB + " you trade now!" - visited_vox_speech[TRADER_HAIL_START + SPECIES_VOX] = "SKREEEE! May the Shoal make this trade good, " + TRADER_TOKEN_MOB + "!" + speech[TRADER_HAIL_START + /decl/species/human::uid] = "Hello hueman! Kiikikikiki! " + TRADER_TOKEN_MOB + " trade with us, yes? Good!" + visited_vox_speech[TRADER_HAIL_START + /decl/species/human::uid] = "Friend of it is friend of all Shoal! " + TRADER_TOKEN_MOB + " you trade now!" + visited_vox_speech[TRADER_HAIL_START + /decl/species/vox::uid] = "SKREEEE! May the Shoal make this trade good, " + TRADER_TOKEN_MOB + "!" ..() /datum/trader/ship/vox/hail(var/mob/user) if(ishuman(user)) var/mob/living/human/H = user if(H.species) - switch(H.species.name) - if(SPECIES_VOX) + switch(H.species.uid) + if(/decl/species/vox::uid) disposition = 1000 hailed_vox = TRUE speech = visited_vox_speech @@ -88,5 +88,5 @@ . *= 2 /datum/trader/ship/clothingshop/New() - speech[TRADER_HAIL_START + SPECIES_VOX] = "Well hello, sir! I don't believe we have any clothes that fit you... but you can still look!" + speech[TRADER_HAIL_START + /decl/species/vox::uid] = "Well hello, sir! I don't believe we have any clothes that fit you... but you can still look!" ..() diff --git a/mods/species/vox/datum/traits.dm b/mods/species/vox/datum/traits.dm index 337974e1d64b..0ce137e24e10 100644 --- a/mods/species/vox/datum/traits.dm +++ b/mods/species/vox/datum/traits.dm @@ -1,6 +1,6 @@ /decl/trait/build_references() . = ..() - LAZYDISTINCTADD(blocked_species, SPECIES_VOX) + LAZYDISTINCTADD(blocked_species, /decl/species/vox::uid) /decl/trait/vox abstract_type = /decl/trait/vox @@ -8,7 +8,7 @@ /decl/trait/vox/build_references() . = ..() blocked_species = null - permitted_species = list(SPECIES_VOX) + permitted_species = list(/decl/species/vox::uid) // Bonuses or maluses to skills/checks/actions. /decl/trait/vox/psyche diff --git a/mods/species/vox/gear/gun_slugsling.dm b/mods/species/vox/gear/gun_slugsling.dm index 38012b37a764..422da40b00d8 100644 --- a/mods/species/vox/gear/gun_slugsling.dm +++ b/mods/species/vox/gear/gun_slugsling.dm @@ -24,7 +24,7 @@ var/mob/living/L = AM if(L.get_bodytype()?.bodytype_flag & BODY_EQUIP_FLAG_VOX) return FALSE - if(L.faction == SPECIES_VOX) + if(L.faction == /mob/living/simple_animal/hostile/slug/vox::faction) return FALSE squish() @@ -34,6 +34,9 @@ playsound(src.loc,'sound/effects/attackblob.ogg',100, 1) qdel(src) +/mob/living/simple_animal/hostile/slug/vox + faction = "Vox" + //a slug sling basically launches a small egg that hatches (either on a person or on the floor), releasing a terrible blood thirsty monster. //Balanced due to the non-spammy nature of the gun, as well as the frailty of the creatures. /obj/item/gun/launcher/alien/slugsling diff --git a/mods/species/vox/organs_vox.dm b/mods/species/vox/organs_vox.dm index e2e43ad49331..b0941cb86df2 100644 --- a/mods/species/vox/organs_vox.dm +++ b/mods/species/vox/organs_vox.dm @@ -185,7 +185,7 @@ /obj/item/organ/internal/voxstack/get_examine_strings(mob/user, distance, infix, suffix) . = ..() - var/user_vox = user.get_species_name() == SPECIES_VOX // TODO use bodytype flags instead so subspecies are included + var/user_vox = istype(user.get_species(), /decl/species/vox) if (istype(backup)) var/owner_viable = find_dead_player(stored_ckey, TRUE) if (user_vox) diff --git a/mods/~compatibility/patches/heist_vox.dm b/mods/~compatibility/patches/heist_vox.dm index e37a3416faa6..c1007fdeb89b 100644 --- a/mods/~compatibility/patches/heist_vox.dm +++ b/mods/~compatibility/patches/heist_vox.dm @@ -1,6 +1,6 @@ /decl/special_role/raider/Initialize() . = ..() - LAZYSET(outfits_per_species, SPECIES_VOX, /decl/outfit/vox_raider) + LAZYSET(outfits_per_species, /decl/species/vox::uid, /decl/outfit/vox_raider) // The following mirror is ~special~. /obj/structure/mirror/raider @@ -15,7 +15,7 @@ var/decl/species/my_species = user?.get_species() var/decl/special_role/raider/raiders = GET_DECL(/decl/special_role/raider) - if(!istype(user) || !user.mind || !raiders.is_antagonist(user.mind) || !my_species || my_species.name == SPECIES_VOX || !is_alien_whitelisted(user, SPECIES_VOX)) + if(!istype(user) || !user.mind || !raiders.is_antagonist(user.mind) || !my_species || my_species.uid == /decl/species/vox::uid || !is_alien_whitelisted(user, /decl/species/vox::uid)) return ..() var/choice = input("Do you wish to become a vox of the Shoal? This is not reversible.") as null|anything in list("No","Yes") @@ -23,7 +23,7 @@ return TRUE var/decl/outfit/outfit = GET_DECL(/decl/outfit/vox_raider) - var/mob/living/human/vox/vox = new(get_turf(src), SPECIES_VOX) + var/mob/living/human/vox/vox = new(get_turf(src), /decl/species/vox::uid) outfit.equip_outfit(vox) if(user.mind) user.mind.transfer_to(vox) diff --git a/nano/templates/appearance_changer.tmpl b/nano/templates/appearance_changer.tmpl index fb54ad5e0944..00a1b62d1b5c 100644 --- a/nano/templates/appearance_changer.tmpl +++ b/nano/templates/appearance_changer.tmpl @@ -5,7 +5,7 @@
{{for data.species}} - {{:helper.link(value.specimen, null, { 'race' : value.specimen}, null, data.specimen == value.specimen ? 'selected' : null)}} + {{:helper.link(value.name, null, { 'race' : value.uid}, null, data.current_species_uid == value.uid ? 'selected' : null)}} {{/for}}
From 5a1c2b9e5e25e002fceef5f83235479a421b3505 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 25 Feb 2025 19:17:48 +1100 Subject: [PATCH 077/512] Fixing some overlooked uses of abstract wood. --- code/_global_vars/lists/jewellery.dm | 2 +- code/game/objects/items/weapons/material/folding.dm | 2 +- code/modules/banners/sign.dm | 2 +- code/modules/banners/sign_post.dm | 2 +- code/modules/mob/living/simple_animal/hostile/tree.dm | 2 +- code/modules/persistence/persistence_datum_paper.dm | 2 +- mods/content/beekeeping/hive_frame.dm | 2 +- mods/content/beekeeping/items.dm | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/code/_global_vars/lists/jewellery.dm b/code/_global_vars/lists/jewellery.dm index 7364bff8b607..9ec4cded16c0 100644 --- a/code/_global_vars/lists/jewellery.dm +++ b/code/_global_vars/lists/jewellery.dm @@ -5,7 +5,7 @@ var/global/list/random_jewellery_material_types = list( /decl/material/solid/metal/platinum, /decl/material/solid/metal/steel, /decl/material/solid/organic/bone, - /decl/material/solid/organic/wood + /decl/material/solid/organic/wood/oak ) var/global/list/random_jewellery_gem_types = list( /obj/item/gemstone/baguette/topaz, diff --git a/code/game/objects/items/weapons/material/folding.dm b/code/game/objects/items/weapons/material/folding.dm index 5d298afbd27b..acb1ff7c17a8 100644 --- a/code/game/objects/items/weapons/material/folding.dm +++ b/code/game/objects/items/weapons/material/folding.dm @@ -58,7 +58,7 @@ valid_handle_colors = list(WOOD_COLOR_GENERIC, WOOD_COLOR_RICH, WOOD_COLOR_BLACK, WOOD_COLOR_CHOCOLATE, WOOD_COLOR_PALE) /obj/item/knife/folding/wood/get_striking_material(mob/user, atom/target) - . = open ? ..() : GET_DECL(/decl/material/solid/organic/wood) // todo: different handle colors -> different material + . = open ? ..() : GET_DECL(/decl/material/solid/organic/wood/oak) // todo: different handle colors -> different material /obj/item/knife/folding/tacticool name = "folding knife" diff --git a/code/modules/banners/sign.dm b/code/modules/banners/sign.dm index 835a88424278..4d341f08f58f 100644 --- a/code/modules/banners/sign.dm +++ b/code/modules/banners/sign.dm @@ -21,5 +21,5 @@ . = ..() /obj/item/banner/sign/random/Initialize(ml, material_key) - material = pick(typesof(/decl/material/solid/organic/wood)) + material = pick(decls_repository.get_decls_of_subtype(/decl/material/solid/organic/wood)) . = ..() diff --git a/code/modules/banners/sign_post.dm b/code/modules/banners/sign_post.dm index d1d0f959023e..d4b4a0c45a18 100644 --- a/code/modules/banners/sign_post.dm +++ b/code/modules/banners/sign_post.dm @@ -16,7 +16,7 @@ density = FALSE /obj/structure/banner_frame/sign/random/Initialize(ml, _mat, _reinf_mat) - material = pick(typesof(/decl/material/solid/organic/wood)) + material = pick(decls_repository.get_decls_of_subtype(/decl/material/solid/organic/wood)) ..() return INITIALIZE_HINT_LATELOAD diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 325ca3f6f8a4..ae1de5c119f1 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -35,6 +35,6 @@ /mob/living/simple_animal/hostile/tree/death(gibbed) . = ..() if(. && !gibbed) - var/decl/material/mat = GET_DECL(/decl/material/solid/organic/wood) + var/decl/material/mat = GET_DECL(/decl/material/solid/organic/wood/oak) mat.place_shards(loc) qdel(src) diff --git a/code/modules/persistence/persistence_datum_paper.dm b/code/modules/persistence/persistence_datum_paper.dm index 4615ebe28e55..4aa5dd6df239 100644 --- a/code/modules/persistence/persistence_datum_paper.dm +++ b/code/modules/persistence/persistence_datum_paper.dm @@ -14,7 +14,7 @@ var/obj/structure/noticeboard/board = locate() in creating if(!board) var/decl/material/mat = decls_repository.get_decl_by_id_or_var(tokens["noticeboard_material"], /decl/material, "name") - board = new(creating, (mat?.type || /decl/material/solid/organic/wood)) + board = new(creating, (mat?.type || /decl/material/solid/organic/wood/oak)) if("noticeboard_direction" in tokens) board.set_dir(tokens["noticeboard_direction"]) if(LAZYLEN(board.notices) < board.max_notices) diff --git a/mods/content/beekeeping/hive_frame.dm b/mods/content/beekeeping/hive_frame.dm index 787210811ac4..0bfd7265f231 100644 --- a/mods/content/beekeeping/hive_frame.dm +++ b/mods/content/beekeeping/hive_frame.dm @@ -48,7 +48,7 @@ name = "hive frame" desc = "A wooden frame for insect hives that the workers will fill with products like honey." icon = 'mods/content/beekeeping/icons/frame.dmi' - material = /decl/material/solid/organic/wood + material = /decl/material/solid/organic/wood/oak material_alteration = MAT_FLAG_ALTERATION_ALL // TEMP until beewrite redoes hives. diff --git a/mods/content/beekeeping/items.dm b/mods/content/beekeeping/items.dm index c55a11d7d20f..2c15fa75cd04 100644 --- a/mods/content/beekeeping/items.dm +++ b/mods/content/beekeeping/items.dm @@ -3,7 +3,7 @@ desc = "Contains everything you need to build a beehive." icon = 'mods/content/beekeeping/icons/apiary_bees_etc.dmi' icon_state = "apiary" - material = /decl/material/solid/organic/wood + material = /decl/material/solid/organic/wood/oak /obj/item/beehive_assembly/attack_self(var/mob/user) to_chat(user, "You start assembling \the [src]...") From a1aad5807b6cf21dad92534c454fd66b26418a0f Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 17 Feb 2025 13:07:52 +1100 Subject: [PATCH 078/512] Swapping robot modules out for grippers. Removing browser module list, making robots use storage datum. --- code/_onclick/cyborg.dm | 5 - code/_onclick/hud/_defines.dm | 5 +- code/_onclick/hud/hud_elements/hud_robot.dm | 7 +- code/_onclick/hud/hud_types/_hud.dm | 35 ++- code/_onclick/hud/hud_types/robot.dm | 80 ----- .../screen/robot/screen_robot_inventory.dm | 6 +- .../hud/screen/robot/screen_robot_module.dm | 6 +- .../hud/screen/robot/screen_robot_modules.dm | 30 -- .../hud/screen/robot/screen_robot_panel.dm | 9 - .../hud/screen/robot/screen_robot_store.dm | 14 +- .../inventory_slots/inventory_gripper.dm | 20 +- .../inventory_gripper_robot.dm | 24 ++ code/datums/mind/mind.dm | 32 +- code/datums/storage/_storage.dm | 7 +- code/game/antagonist/antagonist_equip.dm | 2 +- .../machine_construction/frame.dm | 2 +- .../machine_construction/wall_frame.dm | 2 +- .../_machines_base/machinery_components.dm | 2 +- code/game/objects/items/__item.dm | 9 +- code/modules/food/assembled.dm | 2 +- .../integrated_electronics/core/assemblies.dm | 2 +- code/modules/keybindings/_defines.dm | 1 - code/modules/keybindings/robot.dm | 72 ----- code/modules/mechs/components/frame.dm | 2 +- code/modules/mob/inventory.dm | 14 +- code/modules/mob/living/human/examine.dm | 2 +- code/modules/mob/living/living.dm | 3 - .../living/silicon/robot/drone/drone_items.dm | 55 ---- .../mob/living/silicon/robot/inventory.dm | 281 ++---------------- code/modules/mob/living/silicon/robot/life.dm | 35 +-- .../living/silicon/robot/modules/_module.dm | 32 +- .../silicon/robot/modules/module_miner.dm | 1 - .../modules/mob/living/silicon/robot/robot.dm | 123 +------- .../mob/living/silicon/robot/robot_damage.dm | 10 +- .../mob/living/silicon/robot/robot_items.dm | 2 +- .../living/silicon/robot/robot_movement.dm | 3 +- code/modules/mob/living/silicon/silicon.dm | 3 +- .../retaliate/giant_parrot/giant_parrot.dm | 2 +- code/modules/mob/mob_movement.dm | 5 - code/modules/nano/interaction/hands.dm | 2 +- code/modules/paperwork/paper.dm | 4 +- code/modules/recycling/package_wrapper.dm | 2 +- code/modules/xenoarcheaology/boulder.dm | 15 +- code/unit_tests/mob_tests.dm | 3 +- nebula.dme | 3 +- 45 files changed, 180 insertions(+), 796 deletions(-) delete mode 100644 code/_onclick/hud/screen/robot/screen_robot_panel.dm create mode 100644 code/datums/inventory_slots/inventory_gripper_robot.dm delete mode 100644 code/modules/keybindings/robot.dm diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 2ad7f9d7c98f..9b621ba801ef 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -86,11 +86,6 @@ holding.afterattack(A, src, 0, params) return -//Middle click cycles through selected modules. -/mob/living/silicon/robot/MiddleClickOn(var/atom/A) - cycle_modules() - return - //Give cyborgs hotkey clicks without breaking existing uses of hotkey clicks // for non-doors/apcs /mob/living/silicon/robot/CtrlShiftClickOn(var/atom/A) diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 41016eea0b09..51398a81da00 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -52,12 +52,9 @@ #define ui_movi "RIGHT-2:24,BOTTOM:5" #define ui_attack_selector "RIGHT-2:27,BOTTOM+2:9" #define ui_zonesel "RIGHT-1:28,BOTTOM:5" -#define ui_acti_alt "RIGHT-1:28,BOTTOM:5" //alternative intent switcher for when the interface is hidden #define ui_stamina "RIGHT-2:24,BOTTOM:8" -#define ui_borg_pull "RIGHT-3:24,BOTTOM+1:7" -#define ui_borg_module "RIGHT-2:26,BOTTOM+1:7" -#define ui_borg_panel "RIGHT-1:28,BOTTOM+1:7" +#define ui_borg_module "RIGHT-1:28,BOTTOM+1:7" //Gun buttons #define ui_gun1 "RIGHT-1:28,BOTTOM+3:7" diff --git a/code/_onclick/hud/hud_elements/hud_robot.dm b/code/_onclick/hud/hud_elements/hud_robot.dm index a47c9c7866f0..687d673f3a27 100644 --- a/code/_onclick/hud/hud_elements/hud_robot.dm +++ b/code/_onclick/hud/hud_elements/hud_robot.dm @@ -1,4 +1,5 @@ /datum/hud/robot + offset_hands_vertically = FALSE gun_mode_toggle_type = /obj/screen/gun/mode omit_hud_elements = list( /decl/hud_element/health, @@ -23,7 +24,6 @@ /decl/hud_element/module_selection, /decl/hud_element/robot_inventory, /decl/hud_element/robot_radio, - /decl/hud_element/robot_panel, /decl/hud_element/robot_store, /decl/hud_element/robot_drop_grab ) @@ -45,15 +45,12 @@ elem_is_auxilliary = FALSE /decl/hud_element/module_selection - elem_type = /obj/screen/robot/module/select + elem_type = /obj/screen/robot/module elem_is_auxilliary = FALSE /decl/hud_element/robot_radio elem_type = /obj/screen/robot/radio -/decl/hud_element/robot_panel - elem_type = /obj/screen/robot/panel - /decl/hud_element/robot_store elem_type = /obj/screen/robot/store diff --git a/code/_onclick/hud/hud_types/_hud.dm b/code/_onclick/hud/hud_types/_hud.dm index f0d9c880d61d..5cab1935e444 100644 --- a/code/_onclick/hud/hud_types/_hud.dm +++ b/code/_onclick/hud/hud_types/_hud.dm @@ -100,6 +100,7 @@ VAR_PRIVATE/obj/screen/gun/item/gun_item_use_toggle VAR_PRIVATE/obj/screen/gun/radio/gun_radio_use_toggle + var/offset_hands_vertically = TRUE /datum/hud/New(mob/_owner) if(istype(_owner)) @@ -355,20 +356,28 @@ // Rebuild offsets for the hand elements. var/hand_y_offset = 21 var/list/elements = hud_elements_hands?.Copy() - while(length(elements)) - var/copy_index = min(length(elements), 2)+1 - var/list/sublist = elements.Copy(1, copy_index) - elements.Cut(1, copy_index) - var/obj/screen/inventory/inv_box - if(length(sublist) == 1) - inv_box = sublist[1] - inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]" + if(length(elements)) + if(offset_hands_vertically) + while(length(elements)) + var/copy_index = min(length(elements), 2)+1 + var/list/sublist = elements.Copy(1, copy_index) + elements.Cut(1, copy_index) + var/obj/screen/inventory/inv_box + if(length(sublist) == 1) + inv_box = sublist[1] + inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]" + else + inv_box = sublist[1] + inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]" + inv_box = sublist[2] + inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]" + hand_y_offset += world.icon_size else - inv_box = sublist[1] - inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]" - inv_box = sublist[2] - inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]" - hand_y_offset += world.icon_size + var/hand_x_offset = -((length(elements) * world.icon_size) / 2) + (world.icon_size/2) + for(var/obj/screen/inventory/inv_box in elements) + inv_box.screen_loc = "CENTER:[hand_x_offset],BOTTOM:[hand_y_offset]" + hand_x_offset += world.icon_size + hand_y_offset += world.icon_size if(mymob.client && islist(hud_elements_hands) && length(hud_elements_hands)) mymob.client.screen |= hud_elements_hands diff --git a/code/_onclick/hud/hud_types/robot.dm b/code/_onclick/hud/hud_types/robot.dm index 051484a4acd4..a84112549ad1 100644 --- a/code/_onclick/hud/hud_types/robot.dm +++ b/code/_onclick/hud/hud_types/robot.dm @@ -9,83 +9,3 @@ /datum/hud/robot/get_ui_alpha() return 255 - -// TODO: Convert robots to use inventory slots. -/datum/hud/robot/finalize_instantiation(mob/_owner) - var/mob/living/silicon/robot/robit = _owner - if(!istype(robit)) - return ..() - robit.inv1 = new(null, _owner) - robit.inv2 = new(null, _owner) - robit.inv3 = new(null, _owner) - LAZYINITLIST(hud_elements_auxilliary) - hud_elements_auxilliary += robit.inv1 - hud_elements_auxilliary += robit.inv2 - hud_elements_auxilliary += robit.inv3 - ..() - -/datum/hud/proc/toggle_show_robot_modules() - var/mob/living/silicon/robot/robit = owner?.resolve() - if(istype(robit)) - robit.shown_robot_modules = !robit.shown_robot_modules - update_robot_modules_display() -/datum/hud/proc/update_robot_modules_display() - var/mob/living/silicon/robot/robit = owner?.resolve() - if(!istype(robit) || !robit.client) - return - - if(robit.shown_robot_modules) - if(robit.active_storage) - robit.active_storage.close(robit) //Closes the inventory ui. - - if(!robit.module) - to_chat(robit, SPAN_WARNING("No module selected.")) - return - - if(!robit.module.equipment) - to_chat(robit, SPAN_WARNING("Selected module has no equipment available.")) - return - - if(!robit.robot_modules_background) - return - - var/display_rows = ceil(robit.module.equipment.len / 8) - robit.robot_modules_background.screen_loc = "CENTER-4:16,BOTTOM+1:7 to CENTER+3:16,BOTTOM+[display_rows]:7" - robit.client.screen += robit.robot_modules_background - - var/x = -4 //Start at CENTER-4,SOUTH+1 - var/y = 1 - - //Unfortunately adding the emag module to the list of modules has to be here. This is because a borg can - //be emagged before they actually select a module. - or some situation can cause them to get a new module - // - or some situation might cause them to get de-emagged or something. - if(robit.emagged) - if(!(robit.module.emag in robit.module.equipment)) - robit.module.equipment.Add(robit.module.emag) - else - if(robit.module.emag in robit.module.equipment) - robit.module.equipment.Remove(robit.module.emag) - - for(var/atom/movable/A in robit.module.equipment) - if( (A != robit.module_state_1) && (A != robit.module_state_2) && (A != robit.module_state_3) ) - //Module is not currently active - robit.client.screen += A - if(x < 0) - A.screen_loc = "CENTER[x]:[WORLD_ICON_SIZE/2],BOTTOM+[y]:7" - else - A.screen_loc = "CENTER+[x]:[WORLD_ICON_SIZE/2],BOTTOM+[y]:7" - A.hud_layerise() - - x++ - if(x == 4) - x = -4 - y++ - - else - //Modules display is hidden - for(var/atom/A in robit.module.equipment) - if( (A != robit.module_state_1) && (A != robit.module_state_2) && (A != robit.module_state_3) ) - //Module is not currently active - robit.client.screen -= A - robit.shown_robot_modules = 0 - robit.client.screen -= robit.robot_modules_background diff --git a/code/_onclick/hud/screen/robot/screen_robot_inventory.dm b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm index fa79e6cb1b48..ab8d4815f9f8 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_inventory.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm @@ -7,6 +7,6 @@ if(isrobot(user)) var/mob/living/silicon/robot/robot = user if(robot.module) - robot.hud_used.toggle_show_robot_modules() - return 1 - to_chat(robot, "You haven't selected a module yet.") + robot.module.storage?.open(user) + else + to_chat(robot, "You haven't selected a module yet.") diff --git a/code/_onclick/hud/screen/robot/screen_robot_module.dm b/code/_onclick/hud/screen/robot/screen_robot_module.dm index 188715d51dff..69c0fde190f3 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_module.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_module.dm @@ -1,17 +1,17 @@ -/obj/screen/robot/module/select +/obj/screen/robot/module name = "module" icon = 'icons/mob/screen/styles/robot/module.dmi' icon_state = "nomod" screen_loc = ui_borg_module -/obj/screen/robot/module/select/on_update_icon() +/obj/screen/robot/module/on_update_icon() . = ..() icon_state = initial(icon_state) var/mob/living/silicon/robot/owner = owner_ref?.resolve() if(istype(owner) && owner.modtype) icon_state = lowertext(owner.modtype) -/obj/screen/robot/module/select/handle_click(mob/user, params) +/obj/screen/robot/module/handle_click(mob/user, params) if(isrobot(user)) var/mob/living/silicon/robot/robot = user robot.pick_module() diff --git a/code/_onclick/hud/screen/robot/screen_robot_modules.dm b/code/_onclick/hud/screen/robot/screen_robot_modules.dm index 0e82b4fe44f6..09029a035fde 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_modules.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_modules.dm @@ -2,33 +2,3 @@ name = "module" icon_state = "block" icon = 'icons/mob/screen/styles/robot/modules_background.dmi' - -/obj/screen/robot/module - dir = SOUTHWEST - icon = 'icons/mob/screen/styles/robot/modules_inventory.dmi' - var/module_index - -/obj/screen/robot/module/handle_click(mob/user, params) - if(isrobot(user) && !isnull(module_index)) - var/mob/living/silicon/robot/robot = user - robot.toggle_module(module_index) - return TRUE - return ..() - -/obj/screen/robot/module/one - name = "module1" - icon_state = "inv1" - screen_loc = ui_inv1 - module_index = 1 - -/obj/screen/robot/module/two - name = "module2" - icon_state = "inv2" - screen_loc = ui_inv2 - module_index = 2 - -/obj/screen/robot/module/three - name = "module3" - icon_state = "inv3" - screen_loc = ui_inv3 - module_index = 3 diff --git a/code/_onclick/hud/screen/robot/screen_robot_panel.dm b/code/_onclick/hud/screen/robot/screen_robot_panel.dm deleted file mode 100644 index d092bffc3180..000000000000 --- a/code/_onclick/hud/screen/robot/screen_robot_panel.dm +++ /dev/null @@ -1,9 +0,0 @@ -/obj/screen/robot/panel - name = "panel" - icon_state = "panel" - screen_loc = ui_borg_panel - -/obj/screen/robot/panel/handle_click(mob/user, params) - if(isrobot(user)) - var/mob/living/silicon/robot/robot = user - robot.installed_modules() diff --git a/code/_onclick/hud/screen/robot/screen_robot_store.dm b/code/_onclick/hud/screen/robot/screen_robot_store.dm index 36db253a4af0..90b46cae00c5 100644 --- a/code/_onclick/hud/screen/robot/screen_robot_store.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_store.dm @@ -4,10 +4,10 @@ screen_loc = ui_borg_store /obj/screen/robot/store/handle_click(mob/user, params) - if(isrobot(user)) - var/mob/living/silicon/robot/robot = user - if(robot.module) - robot.uneq_active() - robot.hud_used.update_robot_modules_display() - else - to_chat(robot, "You haven't selected a module yet.") + var/mob/living/silicon/robot/robot = user + if(istype(robot) && robot.module) + var/obj/item/active_item = robot.get_active_held_item() + if(active_item) + user.try_unequip(active_item, robot.module, FALSE) + else + to_chat(robot, "You haven't selected a module yet.") diff --git a/code/datums/inventory_slots/inventory_gripper.dm b/code/datums/inventory_slots/inventory_gripper.dm index 08d90f5bd49e..2f87394ca74e 100644 --- a/code/datums/inventory_slots/inventory_gripper.dm +++ b/code/datums/inventory_slots/inventory_gripper.dm @@ -1,13 +1,12 @@ /datum/inventory_slot/gripper + // For reference, grippers do not use ui_loc, they have it set dynamically during /datum/hud/proc/rebuild_hands() + quick_equip_priority = null // you quick-equip stuff by holding it in a gripper, so this ought to be skipped + fluid_height = (FLUID_SHALLOW + FLUID_OVER_MOB_HEAD) / 2 // halfway between waist and top of head, so roughly chest level, reasoning that you can just hold it up out of the water var/hand_sort_priority = 1 var/dexterity = DEXTERITY_FULL var/covering_slot_flags /// If set, use this icon_state for the hand slot overlay; otherwise, use slot_id. var/hand_overlay - quick_equip_priority = null // you quick-equip stuff by holding it in a gripper, so this ought to be skipped - fluid_height = (FLUID_SHALLOW + FLUID_OVER_MOB_HEAD) / 2 // halfway between waist and top of head, so roughly chest level, reasoning that you can just hold it up out of the water - - // For reference, grippers do not use ui_loc, they have it set dynamically during /datum/hud/proc/rebuild_hands() /datum/inventory_slot/gripper/proc/get_dexterity(var/silent) return dexterity @@ -32,16 +31,3 @@ /datum/inventory_slot/gripper/can_equip_to_slot(var/mob/user, var/obj/item/prop, var/disable_warning) return ..() && user.check_dexterity(DEXTERITY_EQUIP_ITEM, silent = disable_warning) - -// Stub definitions for future work and to pass CI. -/datum/inventory_slot/gripper/robot - abstract_type = /datum/inventory_slot/gripper/robot - -/datum/inventory_slot/gripper/robot/one - ui_label = "1" - -/datum/inventory_slot/gripper/robot/two - ui_label = "2" - -/datum/inventory_slot/gripper/robot/three - ui_label = "3" diff --git a/code/datums/inventory_slots/inventory_gripper_robot.dm b/code/datums/inventory_slots/inventory_gripper_robot.dm new file mode 100644 index 000000000000..11e521a8612f --- /dev/null +++ b/code/datums/inventory_slots/inventory_gripper_robot.dm @@ -0,0 +1,24 @@ +// Stub definitions for future work and to pass CI. +/datum/inventory_slot/gripper/robot + abstract_type = /datum/inventory_slot/gripper/robot + +/datum/inventory_slot/gripper/robot/can_equip_to_slot(var/mob/user, var/obj/item/prop, var/disable_warning) + var/mob/living/silicon/robot/robot = user + if(!istype(robot) || !robot.module || !(prop in robot.module.equipment)) + return FALSE + return ..() + +/datum/inventory_slot/gripper/robot/one + slot_name = "Primary Hardpoint" + slot_id = "slot_robot_one" + ui_label = "1" + +/datum/inventory_slot/gripper/robot/two + slot_name = "Secondary Hardpoint" + slot_id = "slot_robot_two" + ui_label = "2" + +/datum/inventory_slot/gripper/robot/three + slot_name = "Tertiary Hardpoint" + slot_id = "slot_robot_three" + ui_label = "3" diff --git a/code/datums/mind/mind.dm b/code/datums/mind/mind.dm index 584ca62c3bb9..c4d6cb45958a 100644 --- a/code/datums/mind/mind.dm +++ b/code/datums/mind/mind.dm @@ -396,37 +396,21 @@ if("unemag") var/mob/living/silicon/robot/robot = current if (istype(robot)) - robot.emagged = 0 - if (robot.activated(robot.module.emag)) - robot.module_active = null - if(robot.module_state_1 == robot.module.emag) - robot.module_state_1 = null - robot.module.emag.forceMove(null) - else if(robot.module_state_2 == robot.module.emag) - robot.module_state_2 = null - robot.module.emag.forceMove(null) - else if(robot.module_state_3 == robot.module.emag) - robot.module_state_3 = null + if(robot.module?.emag) + robot.drop_from_inventory(robot.module.emag) robot.module.emag.forceMove(null) + robot.emagged = FALSE log_admin("[key_name_admin(usr)] has unemag'ed [robot].") if("unemagcyborgs") if (isAI(current)) var/mob/living/silicon/ai/ai = current for (var/mob/living/silicon/robot/robot in ai.connected_robots) - robot.emagged = 0 - if (robot.module) - if (robot.activated(robot.module.emag)) - robot.module_active = null - if(robot.module_state_1 == robot.module.emag) - robot.module_state_1 = null - robot.module.emag.forceMove(null) - else if(robot.module_state_2 == robot.module.emag) - robot.module_state_2 = null - robot.module.emag.forceMove(null) - else if(robot.module_state_3 == robot.module.emag) - robot.module_state_3 = null - robot.module.emag.forceMove(null) + robot.emagged = FALSE + if(robot.module?.emag) + robot.drop_from_inventory(robot.module.emag) + robot.module.emag.forceMove(null) + log_admin("[key_name_admin(usr)] has unemag'ed [ai]'s Cyborgs.") else if (href_list["common"]) diff --git a/code/datums/storage/_storage.dm b/code/datums/storage/_storage.dm index dcd00f9f16a0..eed463095919 100644 --- a/code/datums/storage/_storage.dm +++ b/code/datums/storage/_storage.dm @@ -90,11 +90,6 @@ var/global/list/_test_storage_items = list() play_open_sound() holder?.queue_icon_update() play_use_sound() - if (isrobot(user) && user.hud_used) - var/mob/living/silicon/robot/robot = user - if(robot.shown_robot_modules) //The robot's inventory is open, need to close it first. - robot.hud_used.toggle_show_robot_modules() - prepare_ui() if(storage_ui) storage_ui.on_open(user) @@ -124,7 +119,7 @@ var/global/list/_test_storage_items = list() /datum/storage/proc/can_be_inserted(obj/item/inserting, mob/user, stop_messages = 0, click_params = null) if(!istype(inserting)) return //Not an item - if(user && !user.canUnEquip(inserting)) + if(user && !user.can_unequip_item(inserting)) return 0 if(!holder || holder.loc == inserting) diff --git a/code/game/antagonist/antagonist_equip.dm b/code/game/antagonist/antagonist_equip.dm index 358f49da1a4f..022bb8c57d09 100644 --- a/code/game/antagonist/antagonist_equip.dm +++ b/code/game/antagonist/antagonist_equip.dm @@ -12,7 +12,7 @@ // This could use work. if(flags & ANTAG_CLEAR_EQUIPMENT) for(var/obj/item/thing in player.contents) - if(player.canUnEquip(thing)) + if(player.can_unequip_item(thing)) qdel(thing) //mainly for nonhuman antag compatibility. Should not effect item spawning. player.species.equip_survival_gear(player) diff --git a/code/game/machinery/_machines_base/machine_construction/frame.dm b/code/game/machinery/_machines_base/machine_construction/frame.dm index e12a6e5cc80b..5eeb7883bc92 100644 --- a/code/game/machinery/_machines_base/machine_construction/frame.dm +++ b/code/game/machinery/_machines_base/machine_construction/frame.dm @@ -89,7 +89,7 @@ if(istype(used_item, /obj/item/stock_parts/circuitboard)) var/obj/item/stock_parts/circuitboard/circuit = used_item if(circuit.board_type == machine.expected_machine_type) - if(user.canUnEquip(used_item)) + if(user.can_unequip_item(used_item)) TRANSFER_STATE(/decl/machine_construction/frame/awaiting_parts) user.try_unequip(used_item, machine) playsound(machine.loc, 'sound/items/Deconstruct.ogg', 50, 1) diff --git a/code/game/machinery/_machines_base/machine_construction/wall_frame.dm b/code/game/machinery/_machines_base/machine_construction/wall_frame.dm index 830c3da857e9..5c38cf0cd7c2 100644 --- a/code/game/machinery/_machines_base/machine_construction/wall_frame.dm +++ b/code/game/machinery/_machines_base/machine_construction/wall_frame.dm @@ -192,7 +192,7 @@ if(board.build_path != (machine.base_type || machine.type)) to_chat(user, SPAN_WARNING("This circuitboard does not fit inside \the [machine]!")) return TRUE - if(!user.canUnEquip(board)) + if(!user.can_unequip_item(board)) return TRUE machine.set_broken(TRUE, MACHINE_BROKEN_CONSTRUCT) TRANSFER_STATE(diconnected_state) diff --git a/code/game/machinery/_machines_base/machinery_components.dm b/code/game/machinery/_machines_base/machinery_components.dm index abf8e0d67dc5..d4fecb27c52d 100644 --- a/code/game/machinery/_machines_base/machinery_components.dm +++ b/code/game/machinery/_machines_base/machinery_components.dm @@ -301,7 +301,7 @@ Standard helpers for users interacting with machinery parts. return TRUE /obj/machinery/proc/part_insertion(mob/user, obj/item/stock_parts/part) // Second argument may actually be an arbitrary item. - if(!user.canUnEquip(part) && !isstack(part)) + if(!user.can_unequip_item(part) && !isstack(part)) return FALSE var/number = can_add_component(part, user) if(!number) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 818bacab2a3c..f22b9568f34f 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -581,15 +581,13 @@ return FALSE /obj/item/attack_ai(mob/living/silicon/ai/user) - if (!istype(src.loc, /obj/item/robot_module)) + if (!istype(loc, /obj/item/robot_module)) return //If the item is part of a cyborg module, equip it if(!isrobot(user)) return var/mob/living/silicon/robot/robot = user - robot.activate_module(src) - if(robot.hud_used) - robot.hud_used.update_robot_modules_display() + robot.put_in_hands(src) /obj/item/proc/try_slapcrafting(obj/item/used_item, mob/user) if(SSfabrication.try_craft_with(src, used_item, user)) @@ -727,7 +725,6 @@ var/obj/item/back = user.get_equipped_item(slot_back_str) return back?.storage?.can_be_inserted(src, user, TRUE) - var/datum/inventory_slot/inv_slot = user.get_inventory_slot_datum(slot) if(!inv_slot) return FALSE @@ -748,7 +745,7 @@ return inv_slot?.is_accessible(user, src, disable_warning) /obj/item/proc/can_be_dropped_by_client(mob/M) - return M.canUnEquip(src) + return M.can_unequip_item(src) /obj/item/verb/verb_pickup() set src in oview(1) diff --git a/code/modules/food/assembled.dm b/code/modules/food/assembled.dm index 4007ffbdeccf..861cb9494194 100644 --- a/code/modules/food/assembled.dm +++ b/code/modules/food/assembled.dm @@ -64,7 +64,7 @@ create_type = names[create_type] // TODO: move reagents/matter into produced food object. - if(ispath(create_type) && user.canUnEquip(src)) + if(ispath(create_type) && user.can_unequip_item(src)) var/obj/item/food/result if(ispath(create_type, /obj/item/food)) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index e317edea3f55..4e784c115474 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -405,7 +405,7 @@ /obj/item/electronic_assembly/attackby(obj/item/used_item, mob/user) if(istype(used_item, /obj/item/integrated_circuit)) - if(!user.canUnEquip(used_item)) + if(!user.can_unequip_item(used_item)) return FALSE if(try_add_component(used_item, user)) return TRUE diff --git a/code/modules/keybindings/_defines.dm b/code/modules/keybindings/_defines.dm index 469a4f57fc28..f80cbd168bd1 100644 --- a/code/modules/keybindings/_defines.dm +++ b/code/modules/keybindings/_defines.dm @@ -3,7 +3,6 @@ #define CATEGORY_MOB "MOB" #define CATEGORY_LIVING "LIVING" #define CATEGORY_HUMAN "HUMAN" -#define CATEGORY_ROBOT "ROBOT" #define CATEGORY_MISC "MISC" #define CATEGORY_MOVEMENT "MOVEMENT" #define CATEGORY_COMMUNICATION "COMMUNICATION" diff --git a/code/modules/keybindings/robot.dm b/code/modules/keybindings/robot.dm deleted file mode 100644 index c598ffb77849..000000000000 --- a/code/modules/keybindings/robot.dm +++ /dev/null @@ -1,72 +0,0 @@ -/datum/keybinding/robot - abstract_type = /datum/keybinding/robot - category = CATEGORY_ROBOT - -/datum/keybinding/robot/can_use(client/user) - return isrobot(user.mob) - -/datum/keybinding/robot/moduleone - hotkey_keys = list("1") - name = "module_one" - full_name = "Toggle Module 1" - description = "Equips or unequips the first module" - -/datum/keybinding/robot/moduleone/down(client/user) - var/mob/living/silicon/robot/robot = user.mob - robot.toggle_module(1) - return TRUE - -/datum/keybinding/robot/moduletwo - hotkey_keys = list("2") - name = "module_two" - full_name = "Toggle Module 2" - description = "Equips or unequips the second module" - -/datum/keybinding/robot/moduletwo/down(client/user) - var/mob/living/silicon/robot/robot = user.mob - robot.toggle_module(2) - return TRUE - -/datum/keybinding/robot/modulethree - hotkey_keys = list("3") - name = "module_three" - full_name = "Toggle Module 3" - description = "Equips or unequips the third module" - -/datum/keybinding/robot/modulethree/down(client/user) - var/mob/living/silicon/robot/robot = user.mob - robot.toggle_module(3) - return TRUE - -/datum/keybinding/robot/intent_cycle - hotkey_keys = list("4") - name = "cycle_intent" - full_name = "Cycle Intent Left" - description = "Cycles the intent left" - -/datum/keybinding/robot/intent_cycle/down(client/user) - user.mob.cycle_intent(INTENT_HOTKEY_LEFT) - return TRUE - -/datum/keybinding/robot/module_cycle - hotkey_keys = list("X") - name = "cycle_modules" - full_name = "Cycle Modules" - description = "Cycles your modules" - -/datum/keybinding/robot/module_cycle/down(client/user) - var/mob/living/silicon/robot/robot = user.mob - robot.cycle_modules() - return TRUE - -/datum/keybinding/robot/unequip_module - hotkey_keys = list("Q") - name = "unequip_module" - full_name = "Unequip Module" - description = "Unequips the active module" - -/datum/keybinding/robot/unequip_module/down(client/user) - var/mob/living/silicon/robot/robot = user.mob - if(robot.module) - robot.uneq_active() - return TRUE diff --git a/code/modules/mechs/components/frame.dm b/code/modules/mechs/components/frame.dm index 9cf6393faaf2..6ad92e633602 100644 --- a/code/modules/mechs/components/frame.dm +++ b/code/modules/mechs/components/frame.dm @@ -301,7 +301,7 @@ return 0 if(user) visible_message(SPAN_NOTICE("\The [user] begins installing \the [thing] into \the [src].")) - if(!user.canUnEquip(thing) || !user.do_skilled(3 SECONDS, SKILL_DEVICES, src) || user.get_active_held_item() != thing) + if(!user.can_unequip_item(thing) || !user.do_skilled(3 SECONDS, SKILL_DEVICES, src) || user.get_active_held_item() != thing) return if(!user.try_unequip(thing)) return diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index ced4a913ece7..b306780544b9 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -18,7 +18,7 @@ /mob/proc/equip_to_slot_if_possible(obj/item/prop, slot, del_on_fail = 0, disable_warning = 0, redraw_mob = 1, force = FALSE, delete_old_item = TRUE, ignore_equipped = FALSE) if(!istype(prop) || !slot) return FALSE - . = (canUnEquip(prop) && can_equip_anything_to_slot(slot) && has_organ_for_slot(slot) && prop.mob_can_equip(src, slot, disable_warning, force, ignore_equipped = ignore_equipped)) + . = (can_unequip_item(prop) && can_equip_anything_to_slot(slot) && has_organ_for_slot(slot) && prop.mob_can_equip(src, slot, disable_warning, force, ignore_equipped = ignore_equipped)) if(.) equip_to_slot(prop, slot, redraw_mob, delete_old_item = delete_old_item) //This proc should not ever fail. else if(del_on_fail) @@ -263,12 +263,14 @@ return FALSE return !!get_equipped_slot_for_item(I) -/mob/proc/canUnEquip(obj/item/I) +/mob/proc/can_unequip_item(obj/item/I) if(!I) //If there's nothing to drop, the drop is automatically successful. return TRUE + if(I in get_organs()) + return FALSE var/slot = get_equipped_slot_for_item(I) if(!slot && !istype(I.loc, /obj/item/rig_module)) - return 1 //already unequipped, so success + return TRUE //already unequipped, so success return I.mob_can_unequip(src, slot) /// Gets the inventory slot string ID for the mob whose contents we're in, if any. @@ -343,7 +345,7 @@ //This differs from remove_from_mob() in that it checks if the item can be unequipped first. Use drop_from_inventory if you don't want to check. /mob/proc/try_unequip(obj/item/I, var/atom/target, var/play_dropsound = TRUE) - if(!canUnEquip(I)) + if(!can_unequip_item(I)) return FALSE drop_from_inventory(I, target, play_dropsound) return TRUE @@ -369,9 +371,9 @@ object.compile_overlays() // avoid world overlays on inventory state and vice versa return TRUE -/mob/proc/drop_held_items() +/mob/proc/drop_held_items(drop_loc = loc) for(var/thing in get_held_items()) - try_unequip(thing) + try_unequip(thing, drop_loc) //Returns the item equipped to the specified slot, if any. /mob/proc/get_equipped_item(var/slot) diff --git a/code/modules/mob/living/human/examine.dm b/code/modules/mob/living/human/examine.dm index 105a41f7e80d..def57af24f3d 100644 --- a/code/modules/mob/living/human/examine.dm +++ b/code/modules/mob/living/human/examine.dm @@ -282,7 +282,7 @@ return glasses.hud /mob/living/silicon/robot/getHUDsource(hudtype) - for(var/obj/item/borg/sight/sight in list(module_state_1, module_state_2, module_state_3)) + for(var/obj/item/borg/sight/sight in get_held_items()) if(istype(sight) && (sight.glasses_hud_type & hudtype)) return sight diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index dfa536ca3859..187c00b5ec77 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -708,9 +708,6 @@ default behaviour is: return TRUE return FALSE -/mob/living/human/canUnEquip(obj/item/I) - . = ..() && !(I in get_organs()) - /mob/proc/can_be_possessed_by(var/mob/observer/ghost/possessor) return istype(possessor) && possessor.client diff --git a/code/modules/mob/living/silicon/robot/drone/drone_items.dm b/code/modules/mob/living/silicon/robot/drone/drone_items.dm index bf450cb99a61..b56da846f44a 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone_items.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone_items.dm @@ -404,58 +404,3 @@ to_chat(user, "You deploy your decompiler and clear out the contents of \the [T].") else to_chat(user, "Nothing on \the [T] is useful to you.") - return - -//PRETTIER TOOL LIST. -/mob/living/silicon/robot/drone/installed_modules() - - if(weapon_lock) - to_chat(src, "Weapon lock active, unable to use modules! Count:[weaponlock_time]") - return - - if(!module) - module = new /obj/item/robot_module/drone(src) - - var/dat = "Drone modules\n" - dat += {" - Activated Modules -
- Module 1: [module_state_1 ? "[module_state_1]" : "No Module"]
- Module 2: [module_state_2 ? "
[module_state_2]" : "No Module"]
- Module 3: [module_state_3 ? "
[module_state_3]" : "No Module"]
-
- Installed Modules

"} - - - var/tools = "Tools and devices
" - var/resources = "
Resources
" - - for (var/O in module.equipment) - - var/module_string = "" - - if (!O) - module_string += text("Resource depleted
") - else if(activated(O)) - module_string += text("[O]: Activated
") - else - module_string += text("[O]:
Activate
") - - if((istype(O,/obj/item) || istype(O,/obj/item)) && !(istype(O,/obj/item/stack/cable_coil))) - tools += module_string - else - resources += module_string - - dat += tools - - if (emagged) - if (!module.emag) - dat += text("Resource depleted
") - else if(activated(module.emag)) - dat += text("[module.emag]: Activated
") - else - dat += text("[module.emag]: Activate
") - - dat += resources - - show_browser(src, dat, "window=robotmod") diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index a867511c8a42..a7e2e6ff9d65 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -1,260 +1,21 @@ -//These procs handle putting s tuff in your hand. It's probably best to use these rather than setting stuff manually -//as they handle all relevant stuff like adding it to the player's screen and such - -//Returns the thing in our active hand (whatever is in our active module-slot, in this case) or any active grab -/mob/living/silicon/robot/get_active_held_item() - return module_active || (locate(/obj/item/grab) in contents) - -/*-------TODOOOOOOOOOO--------*/ - -//Verbs used by hotkeys. -/mob/living/silicon/robot/verb/cmd_unequip_module() - set name = "unequip-module" - set hidden = 1 - uneq_active() - -/mob/living/silicon/robot/verb/cmd_toggle_module(module as num) - set name = "toggle-module" - set hidden = 1 - toggle_module(module) - -/mob/living/silicon/robot/proc/uneq_active() - if(isnull(module_active)) - return - var/obj/item/borg/sight/borg_sight - if(module_state_1 == module_active) - if(istype(module_state_1,/obj/item/borg/sight)) - borg_sight = module_state_1 - sight_mode &= ~borg_sight.sight_mode - if (client) - client.screen -= module_state_1 - module_state_1.forceMove(module) - module_active = null - module_state_1 = null - inv1.icon_state = "inv1" - else if(module_state_2 == module_active) - if(istype(module_state_2,/obj/item/borg/sight)) - borg_sight = module_state_2 - sight_mode &= ~borg_sight.sight_mode - if (client) - client.screen -= module_state_2 - module_state_2.forceMove(module) - module_active = null - module_state_2 = null - inv2.icon_state = "inv2" - else if(module_state_3 == module_active) - if(istype(module_state_3,/obj/item/borg/sight)) - borg_sight = module_state_3 - sight_mode &= ~borg_sight.sight_mode - if (client) - client.screen -= module_state_3 - module_state_3.forceMove(module) - module_active = null - module_state_3 = null - inv3.icon_state = "inv3" - update_icon() - if(istype(hud_used)) - hud_used.update_robot_modules_display() - -/mob/living/silicon/robot/proc/uneq_all() - module_active = null - - if(module_state_1) - if(istype(module_state_1,/obj/item/borg/sight)) - sight_mode &= ~module_state_1:sight_mode - if (client) - client.screen -= module_state_1 - module_state_1.forceMove(module) - module_state_1 = null - inv1.icon_state = "inv1" - if(module_state_2) - if(istype(module_state_2,/obj/item/borg/sight)) - sight_mode &= ~module_state_2:sight_mode - if (client) - client.screen -= module_state_2 - module_state_2.forceMove(module) - module_state_2 = null - inv2.icon_state = "inv2" - if(module_state_3) - if(istype(module_state_3,/obj/item/borg/sight)) - sight_mode &= ~module_state_3:sight_mode - if (client) - client.screen -= module_state_3 - module_state_3.forceMove(module) - module_state_3 = null - inv3.icon_state = "inv3" - update_icon() - if(istype(hud_used)) - hud_used.update_robot_modules_display() - -/mob/living/silicon/robot/proc/activated(obj/item/O) - if(module_state_1 == O) - return 1 - else if(module_state_2 == O) - return 1 - else if(module_state_3 == O) - return 1 - else - return 0 - -//Helper procs for cyborg modules on the UI. -//These are hackish but they help clean up code elsewhere. - -//module_selected(module) - Checks whether the module slot specified by "module" is currently selected. -/mob/living/silicon/robot/proc/module_selected(var/module) //Module is 1-3 - return module == get_selected_module() - -//module_active(module) - Checks whether there is a module active in the slot specified by "module". -/mob/living/silicon/robot/proc/module_active(var/module) //Module is 1-3 - if(module < 1 || module > 3) return 0 - - switch(module) - if(1) - if(module_state_1) - return 1 - if(2) - if(module_state_2) - return 1 - if(3) - if(module_state_3) - return 1 - return 0 - -//get_selected_module() - Returns the slot number of the currently selected module. Returns 0 if no modules are selected. -/mob/living/silicon/robot/proc/get_selected_module() - if(module_state_1 && module_active == module_state_1) - return 1 - else if(module_state_2 && module_active == module_state_2) - return 2 - else if(module_state_3 && module_active == module_state_3) - return 3 - - return 0 - -//select_module(module) - Selects the module slot specified by "module" -/mob/living/silicon/robot/proc/select_module(var/module) //Module is 1-3 - if(module < 1 || module > 3) return - - if(!module_active(module)) return - - switch(module) - if(1) - if(module_active != module_state_1) - inv1.icon_state = "inv1 +a" - inv2.icon_state = "inv2" - inv3.icon_state = "inv3" - module_active = module_state_1 - return - if(2) - if(module_active != module_state_2) - inv1.icon_state = "inv1" - inv2.icon_state = "inv2 +a" - inv3.icon_state = "inv3" - module_active = module_state_2 - return - if(3) - if(module_active != module_state_3) - inv1.icon_state = "inv1" - inv2.icon_state = "inv2" - inv3.icon_state = "inv3 +a" - module_active = module_state_3 - return - return - -//deselect_module(module) - Deselects the module slot specified by "module" -/mob/living/silicon/robot/proc/deselect_module(var/module) //Module is 1-3 - if(module < 1 || module > 3) return - - switch(module) - if(1) - if(module_active == module_state_1) - inv1.icon_state = "inv1" - module_active = null - return - if(2) - if(module_active == module_state_2) - inv2.icon_state = "inv2" - module_active = null - return - if(3) - if(module_active == module_state_3) - inv3.icon_state = "inv3" - module_active = null - return - return - -//toggle_module(module) - Toggles the selection of the module slot specified by "module". -/mob/living/silicon/robot/proc/toggle_module(var/module) //Module is 1-3 - if(module < 1 || module > 3) return - - if(module_selected(module)) - deselect_module(module) - else - if(module_active(module)) - select_module(module) - else - deselect_module(get_selected_module()) //If we can't do select anything, at least deselect the current module. - return - -//cycle_modules() - Cycles through the list of selected modules. -/mob/living/silicon/robot/proc/cycle_modules() - var/slot_start = get_selected_module() - if(slot_start) deselect_module(slot_start) //Only deselect if we have a selected slot. - - var/slot_num - if(slot_start == 0) - slot_num = 1 - slot_start = 2 - else - slot_num = slot_start + 1 - - while(slot_start != slot_num) //If we wrap around without finding any free slots, just give up. - if(module_active(slot_num)) - select_module(slot_num) - return - slot_num++ - if(slot_num > 3) slot_num = 1 //Wrap around. - - return - -/mob/living/silicon/robot/proc/activate_module(var/obj/item/O) - if(!(locate(O) in module.equipment) && O != src.module.emag) - return - if(activated(O)) - to_chat(src, SPAN_NOTICE("\The [O] is already active.")) - return - if(!module_state_1) - module_state_1 = O - O.hud_layerise() - O.screen_loc = inv1.screen_loc - O.forceMove(src) - if(istype(module_state_1,/obj/item/borg/sight)) - sight_mode |= module_state_1:sight_mode - else if(!module_state_2) - module_state_2 = O - O.hud_layerise() - O.screen_loc = inv2.screen_loc - O.forceMove(src) - if(istype(module_state_2,/obj/item/borg/sight)) - sight_mode |= module_state_2:sight_mode - else if(!module_state_3) - module_state_3 = O - O.hud_layerise() - O.screen_loc = inv3.screen_loc - O.forceMove(src) - if(istype(module_state_3,/obj/item/borg/sight)) - sight_mode |= module_state_3:sight_mode - else - to_chat(src, SPAN_NOTICE("You need to disable a module first!")) - -/mob/living/silicon/robot/put_in_hands(var/obj/item/prop) // No hands. - prop.forceMove(get_turf(src)) - return 1 - -//Robots don't use inventory slots, so we need to override this. -/mob/living/silicon/robot/canUnEquip(obj/item/I) - if(!I) - return 1 - if((I in module) || (I in src)) //Includes all modules and installed components. - return I.canremove //Will be 0 for modules, but items held by grippers will also be checked here. - return 1 \ No newline at end of file +// Would be nice to use can_unequip_item() but it doesn't have a target param. +/mob/living/silicon/robot/try_unequip(obj/item/I, atom/target, play_dropsound) + if(!module || (target != module && (I in module.equipment))) + return FALSE + return ..() + +/mob/living/silicon/robot/drop_from_inventory(obj/item/dropping_item, atom/target, play_dropsound) + if(module && (dropping_item in module.equipment) && target != module) + return FALSE + . = ..() + if(!QDELETED(dropping_item) && module?.storage && (dropping_item in module.equipment)) + module.storage.handle_item_insertion(src, dropping_item) + +// Always try to redirect drops into our module. +/mob/living/silicon/robot/drop_item(var/atom/Target) + Target = module + return ..() + +// Overriding default drop arg. +/mob/living/silicon/robot/drop_held_items(drop_loc = module) + return ..() diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 765cf2b43f60..6dac7f4072c6 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -15,12 +15,10 @@ C.update_power_state() if ( cell && is_component_functioning("power cell") && src.cell.charge > 0 ) - if(src.module_state_1) - cell_use_power(50) // 50W load for every enabled tool TODO: tool-specific loads - if(src.module_state_2) - cell_use_power(50) - if(src.module_state_3) - cell_use_power(50) + // 50W load for every enabled tool TODO: tool-specific loads + var/use_power = 50 * length(get_held_items()) + if(use_power) + cell_use_power(use_power) if(lights_on) if(intenselight) @@ -72,7 +70,7 @@ //update the state of modules and components here if (stat != CONSCIOUS) - uneq_all() + drop_held_items() if(silicon_radio) if(!is_component_functioning("radio")) @@ -91,7 +89,7 @@ if(!.) return var/obj/item/borg/sight/hud/hud = (locate(/obj/item/borg/sight/hud) in src) - if(hud && hud.hud) + if(hud?.hud) hud.hud.process_hud(src) else switch(src.sensor_mode) @@ -109,9 +107,6 @@ set_fullscreen(GET_STATUS(src, STAT_BLURRY), "blurry", /obj/screen/fullscreen/blurry) set_fullscreen(GET_STATUS(src, STAT_DRUGGY), "high", /obj/screen/fullscreen/high) - update_items() - return 1 - /mob/living/silicon/robot/handle_vision() ..() @@ -140,21 +135,6 @@ set_see_invisible(SEE_INVISIBLE_LIVING) // This is normal vision (25), setting it lower for normal vision means you don't "see" things like darkness since darkness // has a "invisible" value of 15 - -/mob/living/silicon/robot/proc/update_items() - if (src.client) - src.client.screen -= src.contents - for(var/obj/I in src.contents) - if(I && !(istype(I,/obj/item/cell) || istype(I,/obj/item/radio) || istype(I,/obj/machinery/camera) || istype(I,/obj/item/organ/internal/brain_interface))) - src.client.screen += I - if(src.module_state_1) - src.module_state_1:screen_loc = ui_inv1 - if(src.module_state_2) - src.module_state_2:screen_loc = ui_inv2 - if(src.module_state_3) - src.module_state_3:screen_loc = ui_inv3 - update_icon() - /mob/living/silicon/robot/proc/process_killswitch() if(killswitch) killswitch_time -- @@ -163,10 +143,9 @@ killswitch = 0 spawn(5) gib() - /mob/living/silicon/robot/proc/process_locks() if(weapon_lock) - uneq_all() + drop_held_items() weaponlock_time -- if(weaponlock_time <= 0) to_chat(src, SPAN_DANGER("Weapon lock timed out!")) diff --git a/code/modules/mob/living/silicon/robot/modules/_module.dm b/code/modules/mob/living/silicon/robot/modules/_module.dm index 3647dd37935a..418ce907e21b 100644 --- a/code/modules/mob/living/silicon/robot/modules/_module.dm +++ b/code/modules/mob/living/silicon/robot/modules/_module.dm @@ -1,9 +1,25 @@ +/datum/storage/robot_module + storage_slots = 24 + // No real limits since mobs generally won't be able to freely interact with this storage. + max_w_class = ITEM_SIZE_GARGANTUAN + +/datum/storage/robot_module/can_be_inserted(obj/item/W, mob/user, stop_messages, click_params) + var/mob/living/silicon/robot/robot = user + return istype(robot) && (W in robot.module?.equipment) + +/obj/item/robot_module/get_stored_inventory() + . = ..() + var/mob/living/silicon/robot/robot = loc + if(LAZYLEN(.) && emag && (!istype(robot) || !robot.emagged)) + LAZYREMOVE(., emag) + /obj/item/robot_module name = "robot module" icon = 'icons/obj/modules/module_standard.dmi' icon_state = ICON_STATE_WORLD obj_flags = OBJ_FLAG_CONDUCTIBLE | OBJ_FLAG_NO_STORAGE is_spawnable_type = FALSE + storage = /datum/storage/robot_module var/associated_department var/hide_on_manifest = 0 @@ -13,7 +29,7 @@ /decl/language/human/common = TRUE, /decl/language/legal = TRUE, /decl/language/sign = FALSE - ) + ) var/list/module_sprites = list() var/can_be_pushed = 1 // Equivalent to shoes with ITEM_FLAG_NOSLIP @@ -42,12 +58,19 @@ var/list/skills = list() // Skills that this module grants. Other skills will remain at minimum levels. var/list/software = list() // Apps to preinstall on robot's inbiult computer -/obj/item/robot_module/Initialize() +/obj/item/robot_module/Initialize(ml, material_key, reference_only = FALSE) . = ..() + if(reference_only) + return var/mob/living/silicon/robot/robot = loc if(!istype(robot)) + // Clear refs to avoid attempting to qdel a type in module Destroy(). + equipment = null + synths = null + emag = null + jetpack = null return INITIALIZE_HINT_QDEL robot.module = src @@ -84,8 +107,7 @@ equipment = created_equipment /obj/item/robot_module/proc/finalize_equipment() - for(var/obj/item/I in equipment) - I.canremove = FALSE + return /obj/item/robot_module/proc/build_synths() var/list/created_synths = list() @@ -136,10 +158,10 @@ QDEL_NULL_LIST(synths) QDEL_NULL(emag) QDEL_NULL(jetpack) + . = ..() var/mob/living/silicon/robot/robot = loc if(istype(robot) && robot.module == src) robot.module = null - . = ..() /obj/item/robot_module/emp_act(severity) if(equipment) diff --git a/code/modules/mob/living/silicon/robot/modules/module_miner.dm b/code/modules/mob/living/silicon/robot/modules/module_miner.dm index 9ce6b5d42e5d..d1e76232d72f 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_miner.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_miner.dm @@ -45,5 +45,4 @@ equipment -= D qdel(D) D = new /obj/item/tool/drill/diamond(src) - D.canremove = FALSE equipment += D diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 323d3d876e4b..bcc2945bf461 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -34,20 +34,8 @@ var/dismantle_type = /obj/item/robot_parts/robot_suit /// If icon selection has been completed yet var/icon_selected = TRUE - /// Hud stuff - var/obj/screen/robot/module/one/inv1 - var/obj/screen/robot/module/two/inv2 - var/obj/screen/robot/module/three/inv3 - - /// Used to determine whether they have the module menu shown or not - var/shown_robot_modules = 0 - var/obj/screen/robot/modules_background/robot_modules_background - /// 3 Modules can be activated at any one time. + var/obj/item/robot_module/module = null - var/obj/item/module_active - var/obj/item/module_state_1 - var/obj/item/module_state_2 - var/obj/item/module_state_3 var/mob/living/silicon/ai/connected_ai = null var/obj/item/cell/cell = /obj/item/cell/high var/cell_emp_mult = 2.5 @@ -89,6 +77,10 @@ /mob/living/silicon/robot/Initialize() + add_held_item_slot(new /datum/inventory_slot/gripper/robot/one) + add_held_item_slot(new /datum/inventory_slot/gripper/robot/two) + add_held_item_slot(new /datum/inventory_slot/gripper/robot/three) + reset_hud_overlays() . = ..() @@ -99,7 +91,6 @@ wires = new(src) - robot_modules_background = new(null, src) ident = random_id(/mob/living/silicon/robot, 1, 999) updatename(modtype) @@ -195,9 +186,7 @@ /mob/living/silicon/robot/proc/reset_module(var/suppress_alert = null) // Clear hands and module icon. - uneq_all() - if(shown_robot_modules) - hud_used.toggle_show_robot_modules() + drop_held_items() modtype = initial(modtype) refresh_hud_element(HUD_ROBOT_MODULE) // If the robot had a module and this wasn't an uncertified change, let the AI know. @@ -205,6 +194,7 @@ if (!suppress_alert) notify_ai(ROBOT_NOTIFICATION_MODULE_RESET, module.name) // Delete the module. + module.storage?.close(src) module.Reset(src) QDEL_NULL(module) updatename("Default") @@ -688,49 +678,9 @@ else add_overlay(image(panel_icon, "ov-openpanel -c")) - if(module_active && istype(module_active, /obj/item/borg/combat/shield)) + if(istype(get_active_held_item(), /obj/item/borg/combat/shield)) add_overlay("[icon_state]-shield") -/mob/living/silicon/robot/proc/installed_modules() - if(weapon_lock) - to_chat(src, "Weapon lock active, unable to use modules! Count:[weaponlock_time]") - return - - if(!module) - pick_module() - return - var/dat = "Modules\n" - dat += {" - Activated Modules -
- Module 1: [module_state_1 ? "[module_state_1]" : "No Module"]
- Module 2: [module_state_2 ? "
[module_state_2]" : "No Module"]
- Module 3: [module_state_3 ? "
[module_state_3]" : "No Module"]
-
- Installed Modules

"} - - - for (var/obj in module.equipment) - if (!obj) - dat += text("Resource depleted
") - else if(activated(obj)) - dat += text("[obj]: Activated
") - else - dat += text("[obj]:
Activate
") - if (emagged && module.emag) - if(activated(module.emag)) - dat += text("[module.emag]: Activated
") - else - dat += text("[module.emag]: Activate
") -/* - if(activated(obj)) - dat += text("[obj]: \[Activated | Deactivate\]
") - else - dat += text("[obj]: \[Activate | Deactivated\]
") -*/ - show_browser(src, dat, "window=robotmod") - - /mob/living/silicon/robot/OnSelfTopic(href_list) if (href_list["showalerts"]) open_subsystem(/datum/nano_module/alarm_monitor/all) @@ -742,61 +692,6 @@ O.attack_self(src) return TOPIC_HANDLED - if (href_list["act"]) - var/obj/item/O = locate(href_list["act"]) - if (!istype(O)) - return TOPIC_HANDLED - - if(!((O in module.equipment) || (O == src.module.emag))) - return TOPIC_HANDLED - - if(activated(O)) - to_chat(src, "Already activated.") - return TOPIC_HANDLED - if(!module_state_1) - module_state_1 = O - O.hud_layerise() - O.forceMove(src) - O.equipped_robot() - if(istype(module_state_1,/obj/item/borg/sight)) - sight_mode |= module_state_1:sight_mode - else if(!module_state_2) - module_state_2 = O - O.hud_layerise() - O.forceMove(src) - O.equipped_robot() - if(istype(module_state_2,/obj/item/borg/sight)) - sight_mode |= module_state_2:sight_mode - else if(!module_state_3) - module_state_3 = O - O.hud_layerise() - O.forceMove(src) - O.equipped_robot() - if(istype(module_state_3,/obj/item/borg/sight)) - sight_mode |= module_state_3:sight_mode - else - to_chat(src, "You need to disable a module first!") - installed_modules() - return TOPIC_HANDLED - - if (href_list["deact"]) - var/obj/item/O = locate(href_list["deact"]) - if(activated(O)) - if(module_state_1 == O) - module_state_1 = null - O.forceMove(null) - else if(module_state_2 == O) - module_state_2 = null - O.forceMove(null) - else if(module_state_3 == O) - module_state_3 = null - O.forceMove(null) - else - to_chat(src, "Module isn't activated.") - else - to_chat(src, "Module isn't activated.") - installed_modules() - return TOPIC_HANDLED return ..() /mob/living/silicon/robot/proc/radio_menu() @@ -805,7 +700,7 @@ /mob/living/silicon/robot/Move(a, b, flag) . = ..() if(. && module && isturf(loc)) - var/obj/item/ore/orebag = locate() in list(module_state_1, module_state_2, module_state_3) + var/obj/item/ore/orebag = locate() in get_held_items() if(orebag) loc.attackby(orebag, src) module.handle_turf(loc, src) diff --git a/code/modules/mob/living/silicon/robot/robot_damage.dm b/code/modules/mob/living/silicon/robot/robot_damage.dm index 6723fd88775f..7e43ee35c774 100644 --- a/code/modules/mob/living/silicon/robot/robot_damage.dm +++ b/code/modules/mob/living/silicon/robot/robot_damage.dm @@ -61,8 +61,8 @@ return //Combat shielding absorbs a percentage of damage directly into the cell. - if(module_active && istype(module_active,/obj/item/borg/combat/shield)) - var/obj/item/borg/combat/shield/shield = module_active + var/obj/item/borg/combat/shield/shield = get_active_held_item() + if(istype(shield)) //Shields absorb a certain percentage of damage based on their power setting. var/absorb_brute = brute*shield.shield_level var/absorb_burn = burn*shield.shield_level @@ -107,8 +107,8 @@ var/list/datum/robot_component/parts = get_damageable_components() //Combat shielding absorbs a percentage of damage directly into the cell. - if(module_active && istype(module_active,/obj/item/borg/combat/shield)) - var/obj/item/borg/combat/shield/shield = module_active + var/obj/item/borg/combat/shield/shield = get_active_held_item() + if(istype(shield)) //Shields absorb a certain percentage of damage based on their power setting. var/absorb_brute = brute*shield.shield_level var/absorb_burn = burn*shield.shield_level @@ -138,5 +138,5 @@ update_health() /mob/living/silicon/robot/emp_act(severity) - uneq_all() + drop_held_items() ..() //Damage is handled at /silicon/ level. diff --git a/code/modules/mob/living/silicon/robot/robot_items.dm b/code/modules/mob/living/silicon/robot/robot_items.dm index 0ed14bd60fe1..0f61b2f14bcd 100644 --- a/code/modules/mob/living/silicon/robot/robot_items.dm +++ b/code/modules/mob/living/silicon/robot/robot_items.dm @@ -80,7 +80,7 @@ //This is used to unlock other borg covers. /obj/item/card/robot //This is not a child of id cards, as to avoid dumb typechecks on computers. name = "access code transmission device" - icon_state = "robot_base" + icon_state = "emag" desc = "A circuit grafted onto the bottom of an ID card. It is used to transmit access codes into other robot chassis, \ allowing you to lock and unlock other robots' panels." diff --git a/code/modules/mob/living/silicon/robot/robot_movement.dm b/code/modules/mob/living/silicon/robot/robot_movement.dm index 55cfd8753368..e38f7b95deb8 100644 --- a/code/modules/mob/living/silicon/robot/robot_movement.dm +++ b/code/modules/mob/living/silicon/robot/robot_movement.dm @@ -13,7 +13,8 @@ tally += speed - if(module_active && istype(module_active,/obj/item/borg/combat/mobility)) + // Gross, todo slowdown for robots + if(istype(get_active_held_item(), /obj/item/borg/combat/mobility)) tally-=3 return tally+get_config_value(/decl/config/num/movement_robot) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index a8a18aa126fc..8d293f584fa5 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -85,7 +85,8 @@ /mob/living/silicon/drop_item(var/Target) for(var/obj/item/grab/grab as anything in get_active_grabs()) qdel(grab) - . = TRUE + return TRUE + return ..() /mob/living/silicon/emp_act(severity) switch(severity) diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm index 86a1eacd47f0..34ed830fc4b1 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/giant_parrot/giant_parrot.dm @@ -52,7 +52,7 @@ else if(H.get_equipped_item(slot_head_str)) var/obj/item/clothing/head/HAT = H.get_equipped_item(slot_head_str) - if(H.canUnEquip(HAT)) + if(H.can_unequip_item(HAT)) visible_message(SPAN_MFAUNA("\The [src] rips \the [H]'s [HAT] off!")) set_special_ability_cooldown(ability_cooldown) H.try_unequip(HAT, get_turf(src)) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 65a7437dfd92..dac76423f549 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -64,16 +64,11 @@ if(ismob(mob)) var/mob/M = mob M.swap_hand() - if(isrobot(mob)) - var/mob/living/silicon/robot/robot = mob - robot.cycle_modules() - return /client/verb/attack_self() set hidden = 1 if(mob) mob.mode() - return /client/verb/toggle_throw_mode_verb() set hidden = TRUE diff --git a/code/modules/nano/interaction/hands.dm b/code/modules/nano/interaction/hands.dm index 3122925e2cc0..819adeb820c4 100644 --- a/code/modules/nano/interaction/hands.dm +++ b/code/modules/nano/interaction/hands.dm @@ -18,7 +18,7 @@ var/global/datum/topic_state/hands/hands_topic_state = new return STATUS_CLOSE /mob/living/silicon/robot/hands_can_use_topic(src_object) - for(var/obj/item/gripper/active_gripper in list(module_state_1, module_state_2, module_state_3)) + for(var/obj/item/gripper/active_gripper in get_held_items()) if(active_gripper.contains(src_object)) return STATUS_INTERACTIVE return STATUS_CLOSE diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 3df8a1af0511..1b9b65b220da 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -427,10 +427,10 @@ var/obj/item/paper_bundle/B = new(loc) if(user) - if(!user.canUnEquip(src)) + if(!user.can_unequip_item(src)) to_chat(user, SPAN_WARNING("You can't unequip \the [src]!")) return - if(!user.canUnEquip(other)) + if(!user.can_unequip_item(other)) to_chat(user, SPAN_WARNING("You can't unequip \the [other]!")) return user.try_unequip(src, B) diff --git a/code/modules/recycling/package_wrapper.dm b/code/modules/recycling/package_wrapper.dm index 631ebef3e863..ba8b75246be9 100644 --- a/code/modules/recycling/package_wrapper.dm +++ b/code/modules/recycling/package_wrapper.dm @@ -108,7 +108,7 @@ to_chat(user, SPAN_WARNING("\The [target] moving around too much. Restrain or incapacitate them first.")) /obj/item/stack/package_wrap/afterattack(var/obj/target, mob/user, proximity_flag, click_parameters) - if(!proximity_flag || !can_wrap(target) || (user.isEquipped(target) && !user.canUnEquip(target))) + if(!proximity_flag || !can_wrap(target) || (user.isEquipped(target) && !user.can_unequip_item(target))) return user.setClickCooldown(attack_cooldown) return wrap(target, user) || ..() diff --git a/code/modules/xenoarcheaology/boulder.dm b/code/modules/xenoarcheaology/boulder.dm index 3d94afd97379..ed0737bc8a3d 100644 --- a/code/modules/xenoarcheaology/boulder.dm +++ b/code/modules/xenoarcheaology/boulder.dm @@ -88,13 +88,8 @@ /obj/structure/boulder/Bumped(AM) . = ..() - if(ishuman(AM)) - var/mob/living/human/H = AM - for(var/obj/item/P in H.get_inactive_held_items()) - if(IS_PICK(P)) - attackby(P, H) - return - else if(isrobot(AM)) - var/mob/living/silicon/robot/robot = AM - if(IS_PICK(robot.module_active)) - attackby(robot.module_active,robot) + if(isliving(AM)) + var/mob/living/user = AM + var/obj/item/equipped_item = user.get_active_held_item() + if(istype(equipped_item) && IS_PICK(equipped_item)) + attackby(equipped_item, user) diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 578242d58e04..9f0725d7b5ce 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -325,13 +325,14 @@ var/list/failures = list() for(var/moduletype in typesof(/obj/item/robot_module)) - var/obj/item/robot_module/mod = new + var/obj/item/robot_module/mod = new(null, null, TRUE) // Reference copy only; have to do this to access lists. for(var/sprite in mod.module_sprites) var/check_icon = mod.module_sprites[sprite] if(!check_state_in_icon("world", check_icon)) failures += "[moduletype] ([sprite]): [check_icon] missing world sprite" if(!check_state_in_icon("world-eyes", check_icon)) failures += "[moduletype] ([sprite]): [check_icon] missing eyes sprite" + qdel(mod) if(length(failures)) fail("Some robot modules had invalid or missing icon_states:\n[jointext(failures, "\n")]") diff --git a/nebula.dme b/nebula.dme index 74979c73c72b..df544ac6edef 100644 --- a/nebula.dme +++ b/nebula.dme @@ -246,7 +246,6 @@ #include "code\_onclick\hud\screen\robot\screen_robot_inventory.dm" #include "code\_onclick\hud\screen\robot\screen_robot_module.dm" #include "code\_onclick\hud\screen\robot\screen_robot_modules.dm" -#include "code\_onclick\hud\screen\robot\screen_robot_panel.dm" #include "code\_onclick\hud\screen\robot\screen_robot_radio.dm" #include "code\_onclick\hud\screen\robot\screen_robot_store.dm" #include "code\_onclick\hud\screen\robot\screen_robot_warnings.dm" @@ -497,6 +496,7 @@ #include "code\datums\hostility\hostility.dm" #include "code\datums\inventory_slots\_inventory_slot.dm" #include "code\datums\inventory_slots\inventory_gripper.dm" +#include "code\datums\inventory_slots\inventory_gripper_robot.dm" #include "code\datums\inventory_slots\inventory_gripper_subtypes.dm" #include "code\datums\inventory_slots\slots\slot_back.dm" #include "code\datums\inventory_slots\slots\slot_belt.dm" @@ -2675,7 +2675,6 @@ #include "code\modules\keybindings\living.dm" #include "code\modules\keybindings\mob.dm" #include "code\modules\keybindings\movement.dm" -#include "code\modules\keybindings\robot.dm" #include "code\modules\keybindings\setup.dm" #include "code\modules\lighting\_lighting_defs.dm" #include "code\modules\lighting\lighting_area.dm" From 66534bd7552a326262e6d901045b222bf32aeb11 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 2 Mar 2025 09:20:19 +1100 Subject: [PATCH 079/512] Automatic changelog generation for PR #4856 [ci skip] --- html/changelogs/AutoChangeLog-pr-4856.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4856.yml diff --git a/html/changelogs/AutoChangeLog-pr-4856.yml b/html/changelogs/AutoChangeLog-pr-4856.yml new file mode 100644 index 000000000000..212ddd8557d7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4856.yml @@ -0,0 +1,5 @@ +author: MistakeNot4892 +changes: + - {tweak: 'Old browser-based module selection for robots has been removed, use the + INV button to open storage like you would a belt/backpack.'} +delete-after: true From b0047ef59a5bd13f93c309e9d4df3aedf38858b4 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 1 Mar 2025 17:25:59 -0500 Subject: [PATCH 080/512] Add compatibility for name-based species whitelists --- code/game/jobs/server_whitelist.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/jobs/server_whitelist.dm b/code/game/jobs/server_whitelist.dm index 0c39c017cb9b..da26aaeea7cf 100644 --- a/code/game/jobs/server_whitelist.dm +++ b/code/game/jobs/server_whitelist.dm @@ -95,7 +95,7 @@ var/global/list/alien_whitelist = list() return FALSE if(!get_config_value(/decl/config/toggle/use_alien_whitelist) || !(S.spawn_flags & SPECIES_IS_WHITELISTED)) return TRUE - return whitelist_lookup(S.uid, M.ckey) + return whitelist_lookup(S.uid, M.ckey) || whitelist_lookup(S.name, M.ckey) // Check for arbitrary text whitelisting. return istext(species) ? whitelist_lookup(species, M.ckey) : FALSE From 205bcafcc5ef3ebdce929228ecbd33517a7c9427 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 2 Mar 2025 00:55:16 +0000 Subject: [PATCH 081/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 4 ++++ html/changelogs/AutoChangeLog-pr-4856.yml | 5 ----- 3 files changed, 10 insertions(+), 5 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4856.yml diff --git a/html/changelog.html b/html/changelog.html index 372d34a4aa41..9bd641f320f0 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
+

02 March 2025

+

MistakeNot4892 updated:

+
    +
  • Old browser-based module selection for robots has been removed, use the INV button to open storage like you would a belt/backpack.
  • +
+

24 February 2025

Penelope Haze updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index e11ef8f70b00..830056235331 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14989,3 +14989,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2025-02-24: Penelope Haze: - tweak: Human and unathi sprites should be slightly brighter now. +2025-03-02: + MistakeNot4892: + - tweak: Old browser-based module selection for robots has been removed, use the + INV button to open storage like you would a belt/backpack. diff --git a/html/changelogs/AutoChangeLog-pr-4856.yml b/html/changelogs/AutoChangeLog-pr-4856.yml deleted file mode 100644 index 212ddd8557d7..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4856.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: MistakeNot4892 -changes: - - {tweak: 'Old browser-based module selection for robots has been removed, use the - INV button to open storage like you would a belt/backpack.'} -delete-after: true From ace2725bd1df1574fe991b234c658aaf51d74d59 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Feb 2025 15:55:59 -0500 Subject: [PATCH 082/512] Fix missing clothing modifiers unit test --- code/unit_tests/clothing.dm | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/code/unit_tests/clothing.dm b/code/unit_tests/clothing.dm index 2b3889695c33..bf36a09222b1 100644 --- a/code/unit_tests/clothing.dm +++ b/code/unit_tests/clothing.dm @@ -103,31 +103,32 @@ // Validate against the list of generated tokens. for(var/gen_token in generated_tokens) - - // This logic is currently not working (false negatives). Uncomment when fixed. - /* if(ICON_STATE_WORLD in check_states) var/check_state = "[ICON_STATE_WORLD][gen_token]" if(!(check_state in reported_failures[clothes.icon]) && !(check_state in check_states)) LAZYADD(reported_failures[clothes.icon], check_state) clothing_fails += "missing token world state '[check_state]' in '[clothes.icon]'" + else + // Prune expected states from the file. + check_states -= check_state if(ICON_STATE_INV in check_states) var/check_state = "[ICON_STATE_INV][gen_token]" if(!(check_state in reported_failures[clothes.icon]) && !(check_state in check_states)) LAZYADD(reported_failures[clothes.icon], check_state) clothing_fails += "missing token inventory state '[check_state]' in '[clothes.icon]'" + else + // Prune expected states from the file. + check_states -= check_state if(fallback_slot) var/check_state = "[state_base]-[fallback_slot][gen_token]" if(!(check_state in reported_failures[clothes.icon]) && !(check_state in check_states)) LAZYADD(reported_failures[clothes.icon], check_state) clothing_fails += "missing token onmob state '[check_state]' in '[clothes.icon]'" - */ - // Prune expected states from the file. - for(var/related_state in check_states) - if(findtext(related_state, gen_token)) - check_states -= related_state + else + // Prune expected states from the file. + check_states -= check_state // Now we check for unrelated or invalid modifier states remaining. var/list/extraneous_states = list() @@ -135,7 +136,12 @@ for(var/modifier_type in all_modifiers) var/decl/clothing_state_modifier/modifier = all_modifiers[modifier_type] if(modifier.applies_icon_state_modifier) + // This is working on the assumption that bodytypes all end in " body". + // If that changes this will need a better method. + var/regex/is_alt_bodytype_state = regex("^\[A-Za-z \]+ body-[modifier.icon_state_modifier]$") for(var/check_state in check_states) + if(is_alt_bodytype_state.Find(check_state)) + continue if(findtext(check_state, modifier.icon_state_modifier)) extraneous_states |= check_state From 0e254b82c6c4e0c7d9ea680d46ac3f6e97db7351 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Feb 2025 15:56:26 -0500 Subject: [PATCH 083/512] Add missing open states to NT black jacket --- .../icons/clothing/suit/nt_black.dmi | Bin 1139 -> 2102 bytes .../icons/clothing/suit/nt_brown.dmi | Bin 1483 -> 2084 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/suit/nt_black.dmi b/mods/content/corporate/icons/clothing/suit/nt_black.dmi index 6fd8c4635a17b730be29f8b335acd314771c2b38..a28c0e9d590d54117a34aa76a727a51967e7424a 100644 GIT binary patch literal 2102 zcma);c~Fzd62QMeki($hV*v#gR0PBWC5Rj@0S!kY_d-A*ft6cs30Djx9*7D83o5z< zK~7m9h*3@vkQI!8+()=#M2HY$fRG?$lWeNq`{&hrRl8F?(^WlP(_QuJnd#fE&i0B5 z`xF2GP((Pu-6gt2GKq3KBx_dSMGc91g7fgk!h_=jFNeos!(*ZWAemG&(5~?2geG{^ zJmpSV(UCOlz=30VPg2wOAWW{B5D@N}F`OYA>}o{YbwS)AKHG*LW1LG zyq>F9piLH0+ev9T3jv-(Vh1tmL6~5Nlm3?0ze?hK^GSdg0LZ!`;5Ht~B=#IEdd5Lz z$Er&*OiV#P&r@z?j zzx;4$MD@*3IlS+4?7J!$y&mCci0fwP=aqh{nrMolTk9^uaR7E!-FnYkAkSb&F8m}> z_YO$c4We`V()rybwH@MZ%FcktK3J&$P{7(?hxk~K-8gADY(thvueLn~oCo^Wl3(51 zd%qp^NMpEcI7}W`SZnqSDLPWwW9l>pn_v^7AfA_0tz>fS%7U9_Y@22V&@mG~Jkr%* z@r;a&*47s6{VtYl1ktx7XfbECwgIt^)v&jP4*> zz==+Y#G3t4pxm>#4w?Oi%+uD39{J7>(QEdw7M@BIl~>X4%R&_kS|$>F$;W zJ~9}fq@*MObrp?PEi{iLT-fWwa#Zg##DXE+N)mv9dRrt3 zF}dbF3vqonj^xM}r}&|->AcJ8dL=NeT6|t>C6DNs=BANn8YX2i&Mi)_mjRSbOw-Jl z#5RP|%ZUll>^8z-UeS&l&DrD>6s{qw`<-JGpjcnwMzwe8>oI%1zv$O76m*f`x{A|dB*3@V0NNLoMxy` zd3asKPB_l;r@?Nl#Q-+wY1xu*V0Ejwjtp`d%){oG&Cs)qd}7*R0Y6F(zu71Bw;<|4 zxLcZ|%h)m(BzmeiCO=bz4{n(kPjIeT7CBcQvPIi>p}*`-eka_DY?&6LKoVS`p`idO zzwV`-68Pogo3!GXw+RF*jpLggo`BPEYuj1&SwiPI&R}TwqNqusgqecyH#?ZUFij>* z6?4*ABD|^JHv$XzZKF3XE4rz0HZM#{z-?ju+kad4^YZdxb4Wd%8<#SjQUfdL65;uh z;LWpQlzk^H@_`@IhNzEA#9_1nEGzKw63>!nc)BQ$Iad6-eh9h?0)} z?+f$y9R4}Iqg|UqM^2kSAXwZsHe`+iKfVuY+ehID`d-!Rx+2YM8aQ~m|2&;;G+7WO zINbs|Q%+4h83NUA#~5+_d?Ge*?d>GB$w(+gxihu+>&BGC8>JPGvvNGx&tkC_c|6`8 z?^C_A87b92f>fC9gejXL3 z>ItR9f$Y(u#AFx;OCQpzdrrE?LoBH;OH1_SpajWbUx(5{kli%+qtJZ0e zgI&^^W3!`Je17A7j9nr|NN(N;lCI(Y`Pwm2EAYckQy10+(?^WchkiAviRsf#+Hw8r zh7w$B_LL4=?Z3W@e-87RRAFM!J1~f?{03d9g;pDRc*Zu+`6$n=V literal 1139 zcmeAS@N?(olHy`uVBq!ia0vp^2|(!mRj0>QilWT>7rzNQ;@RM~b&1W7t|`xB78I&|J(b5}UBB9*KhNvU zN1r;|DT*f-pV8UB{^#$kEqfbZ>g0yU>2L+4x;Zj1FfZ|RaSW-L^LDm>-f9DZWBZqQ z_y-*A);ZDC+uwA>xPU=^Rrk80NnW;Gv-K{uio3MBzgEe=m@a_XEAkBQd%cAjtQmGcE!z3HcK&pBjiqH? zEBCtbE#*C`dV~Fg_<>~~)BnkDuYFVgjbZ5(KaP*dyL^Ma-cCFH^oY4~@&^5-EDU$< z+)1#StHi-1k-Xt<-o~3bRX5*1Vchn?HE_rM_{)q7G`Khv_brt_t$JhoRDOopXW4GQ z70b`hUwew3L38Q!zvp5vYJks)&0&g{%tO1{A< zk!`zo@4i+W`!f{i3O!GuHP>J7&5U2a_IkF8r%{CV9+uzRsxL=5XZPxyj#*t_Q&Zv| z{nIY)#!cp~MGe=ag1oMj-t}7j8pz048*6T8a^>4>8yg#i(?(~W7nh$6+h=&}b?jv4 z`HN@2ioU*`)n^jR`Sa)BaU57`KHoCU0cd!j2qVL(O)es?98LX|r)%tvpFYj~$RaOv z-`?|fpJ)H|lS|-E;=V33p`pL=xY)gW<|-T~5>5r{n)IEJ*l`#MJjhn}Q|9+kn;B|9V%fe?5r)TW|j`%~q*&h6}fwn$iQ z@sJYA`t5xAb#%bxx8HpE{du?6GE~&omL9)-`}V!}mKNMee*E=)YHh3vxX`m#kDD%; zsBS$k=fJ~_1@(M)%85VoSo6@q*y5^WrZFU)lhEV#=SY+``2uj)-wNU5u=B;+OKb_umBx~z0F?B1m zJ**kqw%MFlTv~GRz;l(ZMPVL~BK9tr&JdOTr1IS%#>Wq7-V2BI-XZUi- WzV4rzN;=bQMqhfiPybY_lUNTmC8;LVTVMbzv z;j$^OsT1iKk}($MN@yEuO*YN$?&scr`rP~1`Qv%{Jm2T@d7jVneLl}aLiiok)X>)e z06-J&$0IH>7`TA0ar@~ zlOiMf)<9QjM&A7SQzLR8`RT%_O;ul0$zJVp+}VOs00jVQFu12%KuW1_+A5Cgt*62> zJxjtgZP(Io3U^fx81qourPRKs>>sLob@YO5F(O3Dazx4jXN;9K{;+keN9b7iV&un~ z0gszI^>^x7o!{=`9zZ_Wl9gtA7^&+u^Qma*t3~{wGs%uH!#upKV{J=zSqmOSUIC^P zcJ3pE0q{M_J`eR=cfSP4hg9=Db*h|PTP7QYbl?dn&J0)sQu@W(C#q2cI+3YbU1+Wt z;62IkzrSD?8~{m4$(m2j+z<+SG8QV1ln%B;p}&b{dm}arr1{k>P7zNwMQ;lZ=^wxG zw{gp#)|A#=m3 z6$x3?q45V`1ffY>5BmcGIHyvsdtO{rW~RVVhhuazMm?+Rj27Zy=1t6p5M zI`(rv>@ZclB@rdd>olmOpg?4ck)^?oSjG}MyWkc9T<=eZs!;e_92gi2M$uy_(8+4>?1h_GO#r37*xNnT{1<|9loiG4*if>dW_3S=u~`!kzo;;B~91rDjy@| zi+yjl|K1q%5~0<=jzG4HI>@l|V`9s@!dV%tVEnR)k+)ONxW{S(RMeN?e(RyLR6gny z9c}6R5KyJb=C)10EB@*Al5cPQk?qm&%naT-@d9oFa&$Cl@wm$llhItclkWens}<2W zTge#t|2FwM=qKPJ25C$e+6hI|o*TRqTi3@SG}`{_yRHpTqq)%PER z@|S#Rt+dDI2^$;@25utOk&8+S%|3Q4FvN`4``MbVmW3d-Du@ohqONN;l^)hBYs))9 zp*LIQy)A0(cX^|q*oxbC&JNyIBPAk_kE;#F61t7?hVlo>dh8V4YW5;z`b1mj_+rVu zm3gWZx*_;BDo@aE;W>|~4PGL2w~iXhe^&}vMz@%kQqcM?qEi^NQ#6O{#|X@nf_P4? zu$P&z`D6X?g()xY%Sj2Q28JHT@0CBz0KJl?ONtH=kqlm1R(EqyzE~2!Odl?~HZ)I- zS^@b_F{Cidn` z-DKQzrtrD}c$yp;X->?6aeBKQ?#x#SFC{vkX_%Web+ETz1A#!!KosN54lAgMN`K8{ z+zsXlNC|>81JBX~s{99x;ux!Qa}}?Q21>k>sqC+6YAB@Xhb7)DINHYM7iB+)fCtNQ zJxXOitDZJ(9F0&EO5H24B`~p&TyJG|Op<^R!^rloY(|(?#YbCfJ1BpMZhE^eSzBuw ziLwO%8jTj-Scg^QirS5>EPNyTvhU_Wb)6_6;+)tyDnyNoGZ^-yvd_>It@U|gOC~2eq*y_C0mELwNCAom6gxmyg}}Nl1qNDL2JL7 zrMa_Flw-{?ks9d4g^a%-N8HFfO!CCYY0Sg#U*>>EgSGB;*zL2>Rs4WI!<6N9Pbs)%fG&b|<(ETkTPW?SDg{B`v0DT|OSE7NMs5k%VWP(1e2m zV^)Ase&ElDHUvP^glaA{T%$aC@KJg9av$|teho+I{XvWYU!@uxRA#XO-0QXBccc2V h&4>F&kf*nlS+OxmKV3X`PVx2uxR;+N-TnO4e*sa5@23C& literal 1483 zcmeAS@N?(olHy`uVBq!ia0vp^4M3d0!3HF+R#kZdsp(ZA5hX6E#mPmP1tppJc?=8{ zbEfw06hNhS+qw#x)W2v zel@FV*9@lq2`kF0g}gW1bbeH#@-VjI#~!CsYStbi+{f>UspNEU3b6})&tTjBZf)qt zC&%Wmn$K=rv|-1_+R&BHYkZ4O%wP9!^>3@Y$5dzeIc}YGPdCaZwVCxoKLZ2Hdrud~ zkcv5P=h){ zY^BG>P1l}Yd!1#^cvMVtV!#B3%*PiG863`Wyq6+jFfaX?{|DRsY_lcL?(MfMzCXLM z+UWZA>k36Dm(6AH6z6iV5NRmTV0ak7aA+Yzi!&pK`t&j;m;SWH^Vki(?w!i`fTO&KA+7NzqV(Fs-XSXkLw-H>t1Ls zxVd8YRxin`iys9k0rjkv6AfHF#aXpdKBVVWpx~>N>WIh{xrN94tN#F10g?VZn`5V! zAOG>Nl2w1c+~cE@j|bc?dE74KusN{YyG`&_gX-aqKh6Okxp&8>uX#56`nvz33|zZ+ zMm%m;T=!$E*UjJe=be3UCZ=b(*_@f&)n=c!z3fsbVYT?9$Di;|@%MVBrFEr6SLyqb@|L&b&VVGlbZqN5s>tC(dx9ahd!nXJIe<~CAZ@8n$V0z%< zSrFTZ{Kc=^I_fj`ac4HwU~3hZwBMoS`grBuE&ll_NeQzy#<2eT0ptd;cphb+B)@h9t{U%uT9 z%3;_bBi&zi=>DCxYZ<(1z5XUj-t|$M$t}76-8=D5Ksn~iEl+R!czw8<;lTa3@r9*@ zd<^$i14V4+9Vp6qBmQaOqxL9f9v|Vg-%`^OW^F%b==C>izs5wl|DP+GKyl^wPV36a z@ZYVi{!H6NR9)`6#!uKf`Dm?tmdjUzmXFuvpKtpar*5a+Q1I?+Y{ULHXT&|Kx|jHJ z>YXYP&zwE!+YiQyY{t8x^#W_(Go3ix9E_S;+L;9SSQTV2lM%Ya1^I;29#`cbcr$rB zK6=yne_Byx$3KQ!Y=Wx-KmNGT@N<4|{c+*-%5Lf(maT~4eN<=etkr9Ph+USN>#X`52!$H&6ap9N&2_ z*Ot-?9kcwlzyB-iF8V|459gyV>^s6)U-bHv?5cggM7>f~E9A_i#08h%=HF4N6klZ= z@snk(Qz^&svsaH=`bnj0i0yy&@H_j3#`BEV9O@fHzqmc~nkp;usPyO#?P*VMYz%E| zf5X2Zc6X?8(#aFLDwCg>Jm^og+-5HNa@zh}HNpCZ&_AD|s~^e*Po1eE-uQ2)S;cwj zr*k`4>Kl6XZ~xVQYH@P4|JlNnVx?%7S7)qmi)4#t{uXBF{>L!ep`PL42eSb5Y>X2A zN4~SpnKy6QT&GnVm^e^m;5mQsUj>g%_6M9@Rx_;#TM6`Om}a%_LeFh&?8TK~T8qLo zou5v1)4R>{m$AheXyXNW2a7N40(|+*t;k%cY{z%@2mMZ+8F15q Date: Sun, 23 Feb 2025 15:56:50 -0500 Subject: [PATCH 084/512] Add open state to letterman jacket --- .../clothing/suits/jackets/letterman.dm | 2 +- icons/clothing/suits/letterman.dmi | Bin 753 -> 1026 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/clothing/suits/jackets/letterman.dm b/code/modules/clothing/suits/jackets/letterman.dm index fad6634e1e13..5dde2a967eaa 100644 --- a/code/modules/clothing/suits/jackets/letterman.dm +++ b/code/modules/clothing/suits/jackets/letterman.dm @@ -3,7 +3,7 @@ desc = "A letter jacket often given to members of a varsity team." color = "#ee1511" icon = 'icons/clothing/suits/letterman.dmi' - markings_state_modifier = "_sleeves" + markings_state_modifier = "-sleeves" markings_color = "#ffffff" /obj/item/clothing/suit/jacket/letterman/red diff --git a/icons/clothing/suits/letterman.dmi b/icons/clothing/suits/letterman.dmi index 959af29a3e0228ec910dddccdb5fe85e5f6f60cc..f182b5464114468e7bee49954a8d9ef7140385fb 100644 GIT binary patch delta 943 zcmV;g15o_&1%e1=iBL{Q4GJ0x0000DNk~Le0001>0001h1Oos70Det>C;$KeCs0gO zMZmzo|NsAkgM&XmKgGqx=jZ3m&CTB4-lU|Y@9*#C=H~VF^>T7@Rq6Iq00001bW%=J z06^y0W&i*HrIBc2f9d8Iq~;N+v^Xa`8=`pL ztnor}ky7j{5YL`BJGMc5T8O;7yiQe+zMCiDZ@|0rq@aGXczac7?r+|6Z>uaZA48sk zJWKN9KD?(f(MRrydn-?r%uEcv-Y~y>$_&ci*?03ac}3< zhgnpBub-G-fA25xv0}cthn=_bq!xNw9QUiLy@#ucdE(y6Cuu%2MG`Y#ZnUZ2US|3`abMTmV}sV0OM-gLlM1v^1D>ie zRp1G{RZnS>#^7W0F3G%?mzS59*K5h*JC({3_z{xze?5G-SODK8ThTF%CQu)LMxGS; zAU6j1kfJFzOtz$XeJywr^G$su_%6t2+-|1Gvx(k7y_LU?knd=;gATzi!}?nAWF+}8 zLcXJs!3j-<_4)~UGLn240pF1s4Kits4gJ;XZgU>q-s@KLmL@St=5FnrkW-$BCx9t@xN(Yvole|$S(*ZiPC9t@Y%t{*O$C+6F|HZkEa z5B`CMd64Y=Lt7zC=;A?Z|FEZ_oN$l_t^Gq=6+UGb4|;idd3kyLzjE=QQ>BGd=c)No zz3rUjKQ|9z{&47kRC~$)k5A!2o~L%X@U}Z3`OnRRm_O8XE3|K$dw3QP^8BwAI(U)% zL3aWVLcUjj`;<%3{ser(2`hPCHpKsr`x*}BskF~qYl;e-&~-sxUS9uJKLILCrb94+ R^G*N&002ovPDHLkV1moA(`x_# delta 691 zcmV;k0!;ma2=N7fiBL{Q4GJ0x0000DNk~Le0001h0001B1Oos704G#udH?_bDo{*R zMZmzo|NsAkgM&XmKgGqx&CSi;-rncu=cJ^h@9*#C=H~VF^>T7@z`(%dR=A-60004W zQchCV=-0C=2JR&a8Wd`o}D7w4p=mZcUGRGm?p zo0ylMnWB)CpHit?oReP?UtF45g3xC|l0Hm(QS~b;xca$(Jr4kKz)w@f+qItn00GlU zL_t(oh3%KIPQx%1MQ^OS9bkx~4pFAWbYd(&kVKi7GPUZ~1yHvxu=5d=xr~_*U%;nf zcOdV%BvmAa3VeTuRLA$_`X!a>SHR2bd=%)LdDiPgWIc?ix|)??cR*C7%#W(7V)a3h zXGM#0jR|nq=^IvxGLXe8ZE3kPm+@=ep!fIhU7_aIs-*CcN+{Q^s0@n7r zsk?l`31f&VoRWoQZQsGN?(z*Mj5A%ts?7LPk@84bUqpX|6=6Wn^Dr#uBtT9i2}p(Y zp<6DReam*~Jq|zUrV^5(>kFk+#0r8?3A#{EQ1|$vX_`0om^#xbdgS_A_t$%Qd3pV7 z3GJ?&_|d#ybI$fof=(g~P=I9WCZZi6+<8GBw!dRH1Vv2oc}nLGcV0N2AAnKACY+$j z3AyuvVeo(X!2~GYfg%BNcPL%Fbg-2g6}*FKuG)Y{*mqz*z8QpJzr~sR4$47?-zAXq z4o1KyVKy)P9PrLNxNrh+G9cg`ggn5R7mk$*%>#5Qx@x_=yu7^5UJt;QvN;N$hTJbV zTX$))>pw}HfQQ5X^;TQRr$GUmqiQ*<0~~j7;xH@xeM#QI@a>)Re|SL6JLsP$yuALN Zz5wGEO3L2Y5oZ7Z002ovPDHLkV1gb;O5gwh From 20af0cdcaf37b96b065398bdb5a1b033654a2187 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Feb 2025 15:57:33 -0500 Subject: [PATCH 085/512] Fix misnamed labcoat icon states --- code/modules/clothing/suits/labcoat.dm | 3 +-- icons/clothing/suits/labcoat/default.dmi | Bin 1773 -> 3473 bytes icons/clothing/suits/labcoat/rd.dmi | Bin 1745 -> 1746 bytes 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index 24f7d5f0a72c..696d5a4f4d76 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -24,7 +24,7 @@ ) valid_accessory_slots = list(ACCESSORY_SLOT_ARMBAND) restricted_accessory_slots = list(ACCESSORY_SLOT_ARMBAND) - markings_state_modifier = "_marking" + markings_state_modifier = "-marking" matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_TRACE) origin_tech = @'{"materials":1,"engineering":1,"biotech":1}' @@ -73,4 +73,3 @@ icon = 'icons/clothing/suits/labcoat/rd.dmi' body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_ARMS markings_color = COLOR_BOTTLE_GREEN - markings_state_modifier = "_marking" diff --git a/icons/clothing/suits/labcoat/default.dmi b/icons/clothing/suits/labcoat/default.dmi index 1b57d582124a3642b5db371982c7ae9bfdb50d6d..abd5d8f0b820545cef9bc74a3218ecad01f53390 100644 GIT binary patch literal 3473 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 WWJP*^&MPCn&TB87241sq0bm7AQeHp+ delta 219 zcmV<103`p?4bcsdqkqMER9JLGWpiV4X>fFDZ*Bkpc$}q@%L;=q5JlI?R|MUvG}Uc4 zMJX=oFGxyK6RH_WVx@my`=TJVi0(itYc0L(d)s~+{1_~V~0*LIvduAcb4F63lE0I0Z*j?9f2XVLNBJvhM9}f zm7OyD7&f1gUBfgePENpYp{>D{wo~rQC9}7kP>rr%?fcv|rJS|T8i^?-(|ie8|0R8r V73uRm??#f)85Vj1TeETjU Date: Sun, 23 Feb 2025 15:58:06 -0500 Subject: [PATCH 086/512] Add open state to the brown suit jacket --- icons/clothing/suits/jackets/brown_suit.dmi | Bin 632 -> 657 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/suits/jackets/brown_suit.dmi b/icons/clothing/suits/jackets/brown_suit.dmi index e2938c1ef5cd2dd13ee31e393bf902454714a0a0..042714e11879a1b345f0a0db0cba9c9a47ccd44f 100644 GIT binary patch delta 573 zcmV-D0>b_H1d#< zEm}-vz+|jD0004nNklb>!3`HpvZC6nmI@<=i%Z$4hy+Dv$AV4nA-hZj2 z4E|DLD;^32C_j+liOM%E2jMr7O7%E0f0l^1F!voYIeYos%{{vw*bIS;bQ@T90!&Ym zHpn9T3)`8KfnZBw{kY6Nv$w!I0ggS%6fc6jKL;RAbsuK_+R3NKZ@70nlgOvT%qHZz z3BWyYK9vd2B=Y_YXU4g17+8RFQyn<+_ux;LS43f9*{w zl}e@h8#VI*@zuXP&YfmHh?AzAGieV@j%GfH)v+2BJiz#G=K~|Ybl@S#wtV1aLW84# zLCOa)FRbMQBd$N8!AswPLCASwH6O5(JsLbqH$Rw^2V!1W%Lim>C_5O*0AA&VIv>Q% z{EZ8*oJ?ocd7;h+cs1y1S(*=2TPl_6q1DI-O*Qht9R}<9;2wkGT|UZ(tp-xA$W{aQ zUalOvZ3gV7a^>7zKbSRHsynznu@^fadMj6c*2nt|gIisxRR2i7`G-77Fi5`{00000 LNkvXXu0mjf#UJ$z delta 548 zcmV+<0^9wO1^5J3iBL{Q4GJ0x0000DNk~Le0001B0001B1Oos701&on3jhEB7*I@9 zMZmzoPCgxPSSWj9Ep%NghHyMsNhe%TBhFe5`v3p{0d!JMQvg8b*k%9#0FIGaV1MDN zGD>q3^YSxO6q52&Ds_u<@=M~2OEXIl`bhJ z0004WNkl~1>n5ESc@8x-SfKMFO}3y7157TR7kM#^;Ue$Mpy0qcx-2qQ+DJ0000 Date: Sun, 23 Feb 2025 15:58:29 -0500 Subject: [PATCH 087/512] Add kitbashed rolled world states for prisoner jumpsuit --- .../clothing/jumpsuits/jumpsuit_prisoner.dmi | Bin 1920 -> 2103 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_prisoner.dmi b/icons/clothing/jumpsuits/jumpsuit_prisoner.dmi index 20848b0b82ece4648a5e2a043959f264b58268ca..26ea1aef0143644aef95b90f3eacc74f810549a2 100644 GIT binary patch delta 2036 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 Ip5d&21KGN`5C8xG delta 1869 zcmV-T2eSCL5P%OMiBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^GACVy`Foih< zpF;%7PyqAu^UP8J2SAW>0K-)#ZRQUP~02$5?ff52l0 z{C)yWO-)=V1ZFJ*u0;U$dI0Hp2ct#+q(J~gL_}L#TX1l2goK25GXT|Q0Ip5~xl972 zNdT@*0nKeKxnd}IHwk|@38q2-=x+d%L;%EE0Lone|BnDcK|#S<0BJA)c{l*1OaMPW zKfu7iL5oTV00001bW%=J06^y0e`Wvx0H}IYSad{Xb7OL8aCB*JZU6vyoTZV=3WG2Z zMc2t!1YKMDaNA8$#6|sukdmXs$h9fPzIY z&Z6G!IZIYYli_sa%z(X{xI&03LXJg3a=PG5TMC&EoQ)wepJC> zlu6Fsj!4r-u78&+LgzsL*AX1R0%1#ulScVX^Yqm$MLRUFhdcp8Fo3iKXOCTN*hO#%HiPB*SQzoz5<{K;m%Gi+zx9y zI{+}M*Qu=6BhZ0TN^4Ce93pP`F&Z)EW5OC=tb|dLM7z7Ye6jQG?L8#AhkJX7Fm5zx zcn4%-+5`YH+aFA61&o@_WU6acQuLZy|EXDa!nl#9X(N6Fe+e6prcD4~M*52j z8zA#BVclGB5-LNc|JIl=PSaLQ!|x-&ed3E-X^KL~i~N`u*d9Q`_QX(H0aben*j5mb z2wE*1!B&g-Az;A4d(4HMFXE~W7tu{ZVp3VR+chs`C#2xS8R&loki`^cP#-=u5wxCz z(X)tN&E`R~X@0r^fB26IRPVWdp`Z7Z`ON~@XvHsIr72$GG=23lZoyB1g#pht}-HT@PT@Rfy4W@qY zj^KN`^uZ>56CNHO*60-iz{?1N`tC%izH!kB0=%e$fcydGe*ysJ7XtnJ>P_T6eEjqo z0e=4U@x!d4jqvCwJPePH0ACRGCW1>`6vY>Mp(Wmr`6Qu(7y;5L&1VokC_Un{x(A*k z2Joxa|7!geK8yF`*u^&?jBm|HfIWJW^e|xi8$FA^wecSd`)f6`-g3LC}8DSptb1@QR94R~_AVZf8q@2(-fpPnoOST}(9pl%yL#~!2z zp2Aa*m7OjVLHbLfL(jYpJg7bO(-uxS-!2k~L?V$$bg$*}A2%(Z|F~)S{KrizY9=%P zF}aU~aWdyWCeHt?Hl%pYf4q-;K``e(0u8QR*DarWf93l==d{DayKprggWAdNA+Hb2S7VP{m|!px);%4)TF22(S2J z?;vj%x|?;iE%BA%w6tO z*2#xU0n+x(+h`ASe3TQAJ|%_wkfaR)KOg5V?d1w8PKr-0<%jnU={x{ zo0hk!pSEy1lpWXGMIw<%Bof_otvLU0X{|c{Z&|H8|8Hr&WS0Mzfb_bgTK?Z^%(FO| z%m1?v5!28W^8XT;|FhVZggA++h<<)x}*^v)$9r=IdXhei(RF=+rR={=S|COUGJAZPXWmf=i-m?O(CI7FacpXrz zO3%Gp0^ULXA4Tin{Mu1qyLUUlJIMble}7W6ewN;Q7QnUS|BdOeq+n%Z&pli3Ysvo` zm$cXDHTK-woW{S(|H@xu?>&)7Boc{4B9TZWx-OeDb$6X};kCHjU09r{J5xoA%iV{? znVM8^QE~EU6)IX>Za&~bEi!qu3RNvGHz07K7MVO+g{l^pyK}n>waDag+lm&KZ(DX3 zYLUr1+E%l;occX=p?+TyErB2E+&duC2x00000NkvXX Hu0mjfM7DWq From a67f70e4a7eae907afa43ca41fdb31f80bcb7f3f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Feb 2025 15:58:37 -0500 Subject: [PATCH 088/512] Add kitbashed rolled world states for quantum mechanic jumpsuit --- icons/clothing/jumpsuits/uniform_quantum.dmi | Bin 1466 -> 1658 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/uniform_quantum.dmi b/icons/clothing/jumpsuits/uniform_quantum.dmi index e43f27ee1ffed1b99d29fb756ab178bef5b12ad7..7728c659ecf01f57d216a5341641db5540d27771 100644 GIT binary patch delta 1594 zcmV-A2F3Zh3;GNpiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@Z;>HYf46#6 zSad{Xb7OL8aCB*JZU6vyoTZY@3WG2ZgwM%S1UtG6APZ*~?o73ZR?YLQWHrXK&DbCmk9kuBh&j!qALO?@Wu-z2NMB z_`AW9kk8Xs6j_mF8!g=;l75n@DC+$AY!9-)#%I-TP9^{V1uRKKK~#90?OcJD+b9e) z0$lgnroI3F*+YPxO~XjBNuLo^65*$g4mEDp#U#e~^DQO8Y`A z57a`9e>p;o+&;b@;_VHfSgsMzfDlqjHeS~H}EKDd_f)30v#W>G% zEI)@0%o~r|UxGtmaJX-Sb-l1D+9hjJSi~>wt}4C(&3uaI@+Z z<)+>(m0WU7V7!#_3N^=NCa};xn=c8}5x|SwmH^;+l5(948t`PkexhmN>izR{ed{!(adT#*gn`pQK-> zMi!RYx=?5Qf^YTrt@<26e14ArpT92CFo7R+75;($6tL+}?ZsR)?y~SgeuBSm)1PV| zqD8(}AnAqDe{9Yw1F%gZApmI!(32A|bYKlYviFr7)3HJ|7RE zGJ^0XX*Uo$M%ODucnj2^fRB&;VB3cDAeU59Kzv`izGRL1U@R#<2QZG z%lcY?fBM{Vxu5_OPhx4UEGtYpo`9-PJUa>R<7#}{A=3PP>6n#GzkQa7;718GzHd`% zdtCS|rd2<08xSCX!uJ}=2;draeTT#0a5x+ehr{7;I2`Yd!~T9p`}Un%=b-+EeDggJ z16lq3E)nlVdQSGQw2%WC{ry#=d0RIcIbI19e{%d+2xRp4SBZWY>x0Os>=2YdR)2rh zs7HbFO#)f`3cZJ+1v2{kU8Enz%1YTGXn}10{;F~RWox6dL(l@*{QX`h#d(=;&oYh5 z4nYZI^!GQ7yTe$cvO`b;+5G*h#vBJD@O#-ID1mJL{%xJCmL0-rfgBEp!{Kl^91e%W zf8jV0^_}V)zhA8m?im*JA#uJu=--e0|60P%^^3k1dXIlU^8Z`;Nfz`G?D6kM{(mpO zv!(wO_H-VudzuBkAA9_J+|j35&!Ej*s{cI3+3I5RCDCKL7v#07*qoM6N<$g6kgutpET3 delta 1400 zcmV-;1&8|j47v*;iBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^GACVzdf2Dd< zSad{Xb7OL8aCB*JZU6vyoTZVy3c@fHh3DicLOUz|bajyy>0n zf^LF!J0G0yET54OL zDHh&yHj?tNuH-mr zowMoY%-aCNCmG}B;vNp6P$(3dm5BIAl=cPzV!o95^Rk2~XW^40Xh4~de;M+plu9Xl zghSNgW0Zu0B_AN9#d=mAjs-);Q@sMNRqsT5B0gflpC_PGsckmMT4J)+&EvUpHwQ$SE|mJ%sB1L{kS zOfbIuM+|u6c_Pyk047P%aU!&kQE3^3SKtf?#+SQ;>SKtOX99OIT^Ww0+n@FroA98i5}QvhdZz5<|LBCB|r>kDOF z_drB|_9g7A1O_P8 zcfj6@3%K}y+W~$54+GMNzZJml|2+b@#{YW&u={_gL32OFelxBGuQwc7^*&i)_D z(A)PP^7;8@0Y2dW5!I4vQa2f9z&-sxs+|2=3~ORurXb+2=KuZrB>#`|C(j|nzuVdW zlLQvB47jKGe?A}_o|<(8o)b?4+-^`-@$Y2{elDPAuNjZ(1rVOSJD}{h;dORz|F8cn zOWS{<{cP1Ge*rHF7z%|#p-?Ck3Wfe}E%qGtzxLI5QJy?NypdyU@m#3C{dfJ%t^E)C zZUgW{-RS=f09(iHeR@!zhrMoc4iEi`W-vSMI-TC_Hxv_>=eFGh>SY%yb4Lzf=Xd#sMlj_QcnKb6dq9Y$f81 zxfa*D&Odgt&fl9k^k~*vTwd>gv?$m4dke^oKRC*7Y_AP`YLxc`kK3-axSZZqBX6z0 zHvmDRR$5$6_j;7~1P|M;w79(9)hO=?9=2U)PH{N`QQi|gY`f0l@_W~!yeD|v_8Arz zi1MD`pOPpn5am6=hZh(Mg+ifFC=?2XLZMJ76bgkxU!%WjeIT;EUm3Ol0000 From c59f991e70a042bb561710943c4ae23c49b0241f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Feb 2025 16:05:35 -0500 Subject: [PATCH 089/512] Repath colorable bowties to the base bowtie type --- code/datums/supplypacks/nonessent.dm | 2 +- code/game/objects/effects/landmarks.dm | 2 +- .../structures/crates_lockers/closets/job_closets.dm | 2 +- .../preference_setup/loadout/lists/accessories.dm | 2 +- code/modules/clothing/neck/bowties.dm | 12 ++++++------ code/modules/mob/living/human/npcs.dm | 2 +- tools/map_migrations/4898_color_bowtie.txt | 1 + 7 files changed, 12 insertions(+), 11 deletions(-) create mode 100644 tools/map_migrations/4898_color_bowtie.txt diff --git a/code/datums/supplypacks/nonessent.dm b/code/datums/supplypacks/nonessent.dm index e3e9d7dc889b..d219153c0fa7 100644 --- a/code/datums/supplypacks/nonessent.dm +++ b/code/datums/supplypacks/nonessent.dm @@ -103,7 +103,7 @@ /obj/item/clothing/costume/owl, /obj/item/clothing/pants/slacks/black, /obj/item/clothing/shirt/button, - /obj/item/clothing/neck/tie/bow/color/red, + /obj/item/clothing/neck/tie/bow/red, /obj/item/clothing/suit/jacket/vest/blue, /obj/item/clothing/costume/gladiator, /obj/item/clothing/costume/soviet, diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 7d695e1f75d0..6eb0db0a61dd 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -107,7 +107,7 @@ /obj/abstract/landmark/costume/waiter/make_costumes() new /obj/item/clothing/pants/slacks/black(loc) new /obj/item/clothing/shirt/button(loc) - new /obj/item/clothing/neck/tie/bow/color/red(loc) + new /obj/item/clothing/neck/tie/bow/red(loc) new /obj/item/clothing/suit/jacket/vest/blue(loc) var/CHOICE= pick( /obj/item/clothing/head/kitty, /obj/item/clothing/head/rabbitears) new CHOICE(loc) diff --git a/code/game/objects/structures/crates_lockers/closets/job_closets.dm b/code/game/objects/structures/crates_lockers/closets/job_closets.dm index ba9e023a08e3..7993621be7df 100644 --- a/code/game/objects/structures/crates_lockers/closets/job_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/job_closets.dm @@ -43,7 +43,7 @@ /obj/item/clothing/dress/sun, /obj/item/clothing/pants/slacks/black = 2, /obj/item/clothing/shirt/button = 2, - /obj/item/clothing/neck/tie/bow/color/red = 2, + /obj/item/clothing/neck/tie/bow/red = 2, /obj/item/clothing/suit/jacket/vest/blue = 2, /obj/item/radio/headset/headset_service = 2, /obj/item/box/mousetraps = 2, diff --git a/code/modules/client/preference_setup/loadout/lists/accessories.dm b/code/modules/client/preference_setup/loadout/lists/accessories.dm index 7f43717605be..eecae4505e49 100644 --- a/code/modules/client/preference_setup/loadout/lists/accessories.dm +++ b/code/modules/client/preference_setup/loadout/lists/accessories.dm @@ -59,7 +59,7 @@ /decl/loadout_option/accessory/bow/color name = "bowtie, color select" - path = /obj/item/clothing/neck/tie/bow/color + path = /obj/item/clothing/neck/tie/bow loadout_flags = GEAR_HAS_COLOR_SELECTION uid = "gear_accessory_bowtie_color" diff --git a/code/modules/clothing/neck/bowties.dm b/code/modules/clothing/neck/bowties.dm index 593be612f068..e70b3215857b 100644 --- a/code/modules/clothing/neck/bowties.dm +++ b/code/modules/clothing/neck/bowties.dm @@ -1,16 +1,16 @@ //Bowties +/obj/item/clothing/neck/tie/bow + name = "bowtie" + desc = "A neosilk hand-tied bowtie." + icon = 'icons/clothing/accessories/ties/bowtie.dmi' + /obj/item/clothing/neck/tie/bow/get_assumed_clothing_state_modifiers() var/static/list/expected_state_modifiers = list( GET_DECL(/decl/clothing_state_modifier/untied) ) return expected_state_modifiers -/obj/item/clothing/neck/tie/bow/color - name = "bowtie" - desc = "A neosilk hand-tied bowtie." - icon = 'icons/clothing/accessories/ties/bowtie.dmi' - -/obj/item/clothing/neck/tie/bow/color/red +/obj/item/clothing/neck/tie/bow/red paint_color = COLOR_RED /obj/item/clothing/neck/tie/bow/ugly diff --git a/code/modules/mob/living/human/npcs.dm b/code/modules/mob/living/human/npcs.dm index dbe4b30ea876..7cc6a33e7c53 100644 --- a/code/modules/mob/living/human/npcs.dm +++ b/code/modules/mob/living/human/npcs.dm @@ -11,7 +11,7 @@ if(prob(50)) equip_to_appropriate_slot(new /obj/item/clothing/pants/slacks/black(src)) equip_to_appropriate_slot(new /obj/item/clothing/shirt/button(src)) - equip_to_appropriate_slot(new /obj/item/clothing/neck/tie/bow/color/red(src)) + equip_to_appropriate_slot(new /obj/item/clothing/neck/tie/bow/red(src)) equip_to_appropriate_slot(new /obj/item/clothing/suit/jacket/vest/blue(src)) else var/obj/item/clothing/C = new /obj/item/clothing/pants/casual/mustangjeans(src) diff --git a/tools/map_migrations/4898_color_bowtie.txt b/tools/map_migrations/4898_color_bowtie.txt new file mode 100644 index 000000000000..50099e74e447 --- /dev/null +++ b/tools/map_migrations/4898_color_bowtie.txt @@ -0,0 +1 @@ +/obj/item/clothing/neck/tie/bow/color/@SUBTYPES : /obj/item/clothing/neck/tie/bow/@SUBTYPES{@OLD} \ No newline at end of file From 904460f71cab24d160f5bae605eb35f1124bb217 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 10:17:02 +1100 Subject: [PATCH 090/512] Fixes token ordering on letterman sleeve states. --- icons/clothing/suits/letterman.dmi | Bin 1026 -> 1027 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/suits/letterman.dmi b/icons/clothing/suits/letterman.dmi index f182b5464114468e7bee49954a8d9ef7140385fb..b8b0d2801d73deaed306b2ff6de8dee7b39d4ff5 100644 GIT binary patch delta 78 zcmV-U0I~mq2!jZaWC5m;WpO;ZO4P<8_3xf~%hkIC24729@n>l{c8P69Mo7ZvG?4 From fd4c42176e4b46ad088451b2da31608acea3f2c2 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 10:20:28 +1100 Subject: [PATCH 091/512] Corrects ordering of quantum jumpsuit state tokens. --- icons/clothing/jumpsuits/uniform_quantum.dmi | Bin 1658 -> 1656 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/uniform_quantum.dmi b/icons/clothing/jumpsuits/uniform_quantum.dmi index 7728c659ecf01f57d216a5341641db5540d27771..a120fe40f89595d4378b2b3385110448517509c7 100644 GIT binary patch delta 203 zcmV;+05t#l4EPL?c7L^cR9JLGWpiV4X>fFDZ*Bkpc$}q@%?iRW5QNXkQ-t=c_|vNw zX^|f6E0jpKCXi-fleYNw273?{q(8SAm~YsDO~tvml$FS@CGUZ}K_^Zk+wM3Uj0!rM z&Y63&z%AN`)QhGYw){!DGW1?a&~Og|G^3p1;yLb_|EL!-nE z)g!_f>Y?tOX^`4CoXv-SH!dmpUa{hk6%3sg+1hYiOXOpOjQL{Dy FLfFDZ*Bkpc$}q@%?g7s5QNXkQv^M?^v7#2 zMG+766(l8V6Np*ZM5S-vP!FXo6sxx#m~VC#HWlZhtZI>8Dn0;tgHD`8w%u_y8WnUD z#{*{?%uR<$_#gwsF&UApN;p%7eAIi+T9O@1^Sf)~Ex-VNra_y~T9_L>nP+d%eJ33n zC9bIMk;2f7P47&L)V<*BfB3t>l912SR}@*1Wg9KsB9eZRsVM6F`D_oez{Y3QZcZk% HGyy~f;TT Date: Mon, 24 Feb 2025 10:27:23 +1100 Subject: [PATCH 092/512] Adding sleeve and rolled states for jumpshorts. --- icons/clothing/jumpsuits/jumpsuit_shorts.dmi | Bin 1139 -> 1740 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_shorts.dmi b/icons/clothing/jumpsuits/jumpsuit_shorts.dmi index 00530b3f19d7a20e66f3edd79e1c76251709f673..8025567b7f851073585b05e8ef37cb5f105245f8 100644 GIT binary patch delta 1697 zcmV;S244B|2+R#3iBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@Z;>G*MSy^S zFfcH{z`!jnEi*GSH8nLaFE2MYH!CYEIyyQkDk^4XW=BUyUS3`&Cnqc{EFB#k8X6iO zA0Pk!{}&e*G&D3B85xm@A%BUIr*;4U00DGTPE!Ct=GbNc006amR9JLGWpiV4X>fFD zZ*Bkpc$}q@%?iRW5QNXkQ-t=c_|vNwX^|f6E0jpKCXi-fleYNw273?{q(8SAm~YsD zO~tvml$FS@CGUZ}K_^Zk+wM3Uj0!rM&Y5`WH=As_vovxZ~~ zqy9{7yanjNPfQb93p1;yLb_|EL!-nE)g!_f>Y?tOX^`4CoXv-SH!dmpUa{hk6%3sg+1hYiOXOpOjQ2+o1I7vi7RCt{2n~QeaHVlRpk_zRNop15n*}W)U zny&Bvf&(boa~lGX1b=mId+<3{jtvr*Ul%8!RaJ&z7>4n?aOd(b=O@~4jSsHAzrU{? zk)dSQBIy%jY?=nPgdOs8u3kWXCp8F6o2nH_h9;Emi;pBy<7KL=^C!y_f7ADzOKDb2@*`n z|Kd1(pv2 z$u8;_*V_zJz&3;}w+C1|Bnb5dt^n39>bH5^;p5K@T|mADvnMfU&-;H-Q-`={m-LIS zY4%Oy=sf^ePoJMt?K&j=;yc&G#=T<-xGmlVP$$p@EPwa#x6pq1Qx{Ni1;A%8R8js* z=x4z9M<`XmUqH7p48t%C!!QiPc*Wr;k2xMFi?+Y7jSv449gm#33voOW32OWM+W0u% zId?p~r>DO^i)hmewEuA-h+n^)cg-H-+M}7Vf`as_4la)KwUXLy$dk4Jc4p? z#QNw0gn#vqtNuO_AAa_7{5-Jiz}NMjTL8n((;gf7gt_nU6AMt)rN2+Pho>CBVhTV9 zADyG-!v)5D#nk2Bgh|h zWb;+s-&e-Z9)zz!WDm4a+uzs4&ko-5>o4p8eScpUzpA+A{D2Yq{=P20VHk#C7=~dO zhG7_nF^%xu?_Vyy;NW5=zrC$Q9Ulz&K{*KBY^eb94im;QPyB$r*+lm4@>Iv%LXx^s ziGNxp!&_*=W#IhrLkiw84eoxrBiDKG))KT*LgO7M*!`#Oa?-{R3FqgZi4HnDb%O?0 z=okfOh!0a!cEKk|AA)EkcR=0+-IyO0AD1VRbJSf%-3b)vmBMT#Pl0?AIQkq^$M5EH z4zj@9QfI;gh%F${3*q|s7Y9@XoGTO%Jb!nsOvwkXK4tuTn`R>Kl9C|k4Vr0nlsqP$iK-orgZDK`{wb2|MEMG%gZ{rz*0*D6WM4W@NS+f-W&e rJbLU6ThL>~yQR=HW5lywzj4jK7=CxZ`0pkr00000NkvXXu0mjfhm$3< delta 1091 zcmV-J1ibsq4f6;giBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`H>+bMH(6! zA0HopfPgSCFu=gTGcz;)|Nkv5Ej2YY7Z(>VFE2MYHzy}2D=RBHIyy8oG%6}8W@ctb zM@L>>UKtq~EG#S?9UYO0A%C7uVjKVf00DGTPE!Ct=GbNc005YJR9JLGWpiV4X>fFD zZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w z;*!LYR3KBSJijO>MTv_uC9|j)$T#HTOe;#vO@*-GsxnG*6Z7&jQ-2ha@>42xi*xcz z;>+Vp^D@)&i*gZ~O^DW<6Q7ZomqL!tBD^}46Wj%aetI?&P+iPsn1QV8 zx{3&hTY(5b{Xc#|19$Ys-1#dXJO3Jm<76fcy*6LpxeVbQy`!eA`tV_D=)A@F9KhJy306$DIq}n z6?)Mwm&1K`#_-h=Uqko8Bp@lJ>F#=r!a2Kp4wFu!tk^Xg-U!k9c(MCL@YXEjFsU;9Y3I%(> z&!KKR_%7&Ld=U<-?**vqNW(o4ERb)4y}%thzbOKTGlcEp2e5C*JunQzFbu=QAOrOE zsUX6S_@m{%@)3SCgNMqc=RrSQhf%xd2V)AjZZFz)7)C-?iAiZP&ln+qYe$?|K3j&NaMtk-jS$yxX~b-$nZv zhG7_nVVM7uQ1ZRp&Rs)C=uq;#T>XRy9ZJ6Y4_uR&|FKz2h|p-t&B_1RET%+gH09>x ze{2?$A~ce6bMikvHYq}fl5bxAC&s2kXe8z4usneC&V-os<8s^Q<68o}U#k48t%C!!QiPFbu=w@f#8_Q*m!83~K-Y002ov JPDHLkV1h-D>#qO+ From 2ae9035cdc6e065bdf053f6530093ac533967c9b Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 10:30:49 +1100 Subject: [PATCH 093/512] Adding (bad) world states for hazard jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_hazard.dmi | Bin 4958 -> 5446 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_hazard.dmi b/icons/clothing/jumpsuits/jumpsuit_hazard.dmi index 08c2522ff7c1520d06704ffa3028800efbcc8774..be1f5468a07790b0df9b941927baa27e7c4abd51 100644 GIT binary patch literal 5446 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 UlIENar7;Sa8(SHDfjB?=H!*BsdjJ3c literal 4958 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 xb@qkYAmWCp|FT^OH)o{8?QiV Date: Mon, 24 Feb 2025 10:38:17 +1100 Subject: [PATCH 094/512] Added world states for sterile jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_sterile.dmi | Bin 1670 -> 1891 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_sterile.dmi b/icons/clothing/jumpsuits/jumpsuit_sterile.dmi index 0d770cf251e4e9a5ca110f575a47545aa60a3e78..6eea5cbe755ca300a8b07cc32b66357d3b78f419 100644 GIT binary patch delta 1879 zcmV-d2dMal4dV_WiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@Z;>G*e=}zP z0Ga=bi;G&8yMTaz?Ck7QQ&TrLH~9GY>+9>lz`*J0>BYsxIyyRLW@bl6M_yiDdU|@u z#>Qh}Vt9CXyScfFh=|V2%yMyY#Kgqd*VklZWU;Zafq{X@$jD=3V_#oiVq#)(adC-> ziMzYIz`(#QiZ4k30004WQchC-$gd^u zfxJN{P9odxI2()#I-28wGY#gh!)Sbv0isL>B&!n6lp!Dep0kEz3#0x_e{H-4=)q4+ z6Iu&1tEWP`Yo$Y@#0}LW!WinI?wo0m+BcldhkrLNDfwQp;*b?xw${=uBIz%gilWM2 z&-MhfM8;>6sEJVk00qNIL_t(|ob6nJcH1@#6k!ggJTqPDy4&2ObrO52+wA{;ZvZ8G zPE1gdAkWDg&W-ZQqi_I7f2n<^Cs&ohU@#aA4IE79H~}}1zck!r;`}e3e+}X<4u?2( z-c1p+3BnN%=ScusA&GY`gg{4uM&t~q{3|zw3uyWC6wofMn+g>;?@>I@I=z)J;0mp)>OMIKUrs??!ee7NG)dOlob^&N7HKg{QIe<$yuh8Oa8Kn((M ziOW3Ho|2pXHudOzeX79xHGcFTG0$^+PS8<@OPeh5c^V>>=r~G#LYc2;b)fz({M?5+ zvjv#{gv8=imj5?FNxzea$oZu|{dw^9%wa&sD?F?H%N8d-cw&9X@lArul;Bb2Epyn%L`*<5PaHTvCF|rF0kQ;DNU{ZLwv{Un51HuZ*Ta zo*Hy|owPh(16jVE5v;lK+8bnuiQ-66d%>;TV@`ABS_pC}a2$@e?NbI7WisK06q-lKM;Tq z1Nr?5OC3J!0I7gWBewt2iUoY(CB!dpxBwp@c)0){;wpx>yaKd)pilr(?$M(aa4x+6 z0(>fF=xc>HHfQ{GkX6(9%c+Q;=U+M2_^*KWE{5FDkzS`ec>T`tq;`u4Uy?DOf-`DB0 z#67Nyf7WSS~DT0gxb66;!eKVeI!@?+k=gaDf+e~9#s5xjT^0#Q?N; zf7`9>K3COuYHzs!TBPr1)8_zC@bA;Pbl6G(sDSNG-a)*Fc3ZIky?(^USjERjIRI|U z1rWL0i7a8aJEwknNACwg;M4Xk{yVl~h-}vcy}rR` z0;&A{gNP@M7mtZ@V}sBUNayc2@K5P&u_xa#HV9pTbpHNc<8Q``0#3&Up(~Kif8XD0 zq;2}5fYY%-7%flngx9!jAlU(66eD!rE~s& z8X3!i9)Ld0%lZFld@Kuk2>LWH=l?h3BU#V`(5HFw+|exP{^--Z!raj;=>F)_JaO)5 z7W5GGX`VE9Gz)qF`ZQ0R`=2<+En-ryZ=O8&g3fWD=3TPUGWs;nEPBH+{sH8NdQ^&5 R0001>2m=5B0K5^GACVy=e|ma) zV`5@6X8!=0|BH)@T9&))?CeuhQ#Us^`1tti>+67kfWW}O>FMcsczCamdET#Kgqd*Vo9%$YNq*WMpKqv9W=HfpKwhV`F1qUtfud ziMzYIz`($BE;%*;0004WQchCyRf)t$?)jw+@^D00j0) zL_t(|ob8<9cH1@#g#{Xe=}2=nmtI=ATiwL9+S+^n*Bd}Po)ZzIR5#Th+?>d#1Py+G zDE0J8r&VP#nM|fwk38@ac8hP>gpK~O{f4WZ~@fE$pca)CH z`c3V@2Ym|w1fEbgN(CT*z#U9xs5v|LXN^nb6#W)U{4e4t-6!KRrEVS`h~9tD06)AZ zdU$B+ME6+$Eg710{XX-b6oad zG9K6GVQ~3V>|~C*2YHjO1E@DLX!#C;nC$R#95eAC0hjNfbRL3|KX7)>zd>1nJIsLG zVI@DuqqKNjm(Otq@U%5DfR2Auz)Odf{2%}RM}9ti)Yg~7e-^X`NsD27nV3qza&pkV zf9|l_q31K8#J3y>rHe%7Y_$mmh4bGOD&S|15q(xWv<+FlGvN>OF(7*9Q3pgH7Qw3> zWWvWRUnG3|VLkzLd`H#+iP-{@4j3M3qeo@Jh90vM-W>4BLAEgg(^pv-Nk6lcK2qOg2uhGfE)e4f0(`O|7rGG5pZh%&+)&y73X{oXGMP*!lgVTvNr017^C(WB zJ?enCr{XmxFT69%3zsrAmRg@rZrADVR#koH_T&M%$=~ymLnF%l7Q6Z0XcX$lzGW}8wvbZMHFpI00MGpNOV~S7tgK=b##Wg5- zugWpSr~JVa-!O}-ke$}4D#sL`@&`}j!z`{sa$2p|y(-5Pug@K5aTT)5f49-Aa!m1= zxx*~3Li%)-V~SVj4z##R>C;t?DPEg9PSE1YOQ~{9@#@^4VsR-|jwxQB`!g&qrOGkI zzp)pnR5_-2^8!sKlgVT Date: Mon, 24 Feb 2025 10:38:24 +1100 Subject: [PATCH 095/512] Added world states for captain jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_captain.dmi | Bin 1750 -> 1899 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_captain.dmi b/icons/clothing/jumpsuits/jumpsuit_captain.dmi index c21ff4d7bcbc55ed4d888c2abdbf907c3ab257e9..9b1c43034b475b89e90911bbbad30c28bc26430f 100644 GIT binary patch delta 1839 zcmV+~2hjM|4eJgeiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@Z;>G~R{$$g z|NjjOM1%l1YZ+38;l~MpfPflTjwo)g0ARQaElfH(I#W|q3`KbgHC*)A4-`_03rvI% zH(U)ZN*rOJ6-s#yDnu7Yb1W<@GFyQzQ+5q1MGq}Vk*XwrPy`2k00001bW%=J06^y0 zW&i*HwR%)obVOxyV{&P5bZKvH004NLrIO7G!Y~ko&&gAS_N@5Rs~2gJ9_%ZWNVX=B zW?_@I`1S^S5EZ09w;7mk*nv&Oxww>-$gd^ufxJN{P9odxI2()#I-28wGY#gh!)Sbv z0isL>B&!mC&Xge^{hqUiWDBGIOl`ac=)q4+6Iu&1tEWP`Yo$Y@#0}LW!WinI?wo0m z+BcldhkrLNDfwQp;*b?xw${=uBIz%gilWM2&-MhfM8;>6sEJVk00py2L_t(|ob6kI zQrkEbv_ruzB6idu2MPyvObaxSqg?O*f9)g%+)S%~eRBNFgwDOCPNuA~`<~?3Gb@}V z0)apv5Nwc6CI<%xlSw*|-#5|^AJW5vL-#g_-#gNyqe*(0PL7U10}-B$Ecb7D2KkT2 z$HyNLpDK%!>4|#_R#@9OT(fIx*CUKs^= z*FiVK;2iJxFl|(km6<(EcmU07wY9>*20U*N?+}~e2yc|DudeFsZ|KeM;mG<7ei0h)IO8v8>vK=Dbp!l1zOEYC7~AU-*}yi70B%gb&T5zUtL}K12wR3xO>$U-K89_tIGX*#|F)%V%eGn8CpSpo=A>RW z?Q$6s(5mh7{Wchnw_Uy;;+=on&%Y%au#?cXa0jVqTibrPfu`Nc_X8F$yg|J8Z~OSS zLH~`%vhn#O67a!g17@Jv%J+jEZsq&o3Yxa*VE<4${ z|I5IjKvrf=M$bUz2Zd>Fy4?60V*Uwkpmxf!8E}QvnC7g2m+j#XFSP#mu^Au)xGTW* zPyFTUtG$~b0ecVm+70|2+CL9=?Bo*{#uidQDwP*OJ)_`p(r*Y zc?mkO#Ks#KaQ(HRAEVNBp#Ew~#9GS;@*)0UNL+ z{tmMJwW$_{6sRgan^m}f0WVQhIQ^{(tUiK&CjfZ=S^F|W0=9;Qp2JN>_Z8O**Z|+( zRLUeqDJ-C7q=5Yv8~P@pwL#xuzW?SAebAr#_!aa#UPIRao?t)1;0Dk_}lHuk1gh|Y}H&)-R4skJH<@=P0J%66o-`VwVvXp>>A41EZ8@rIiWBW37=u!}d^WEd+$AA()H;n>kK^a0q# z8;>0=Lmz-$yz$tvGV~$X#T#xijFh1d!Y{uE45bWYA4abg_p%1_=-gxXjGxS}& dCF>V#<3H~U{>ygpo;Lsh002ovPDHLkV1g3>gn$45 delta 1689 zcmV;K24?x|4%Q7JiBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^GACVz4SO5PF z04q`pM1%`Wgb+7e061$IQicsJN*rOJ;l~MpfPflTjulFI4k|m_5Dn$=1Nc7kbk*Xwr@fcvP00001bW%=J06^y0 zW&i*HsCrabbVOxyV{&P5bZKvH004NLrIE`DgD?<9*U47|U0eEa+f7l#Mg4`4lCcTI z3{0Y-f8S7{-4$wg_rRQc7gLH$+x3HJu03CXf<-URqTcN}OIAmd;dJE8fW4czLWn9t zjzvOpy5LNITMC&EoQk8A({1uIEJK~#90?V15o+c*$~?NE@5h#jo6 zgWQr*uz}VzM{~XZ|JQD%5MQ8rl1*?zXZE#rX1rp5^=WM@^mU_%#bU8o8^x2!(b3Ul z5+51_DE{yvK0Z1&ABRS9D?T}y#K-aE(BFy3YG3jTO3NoUhD z^Wh{ENjlB4Y?^`;6rWLihT?XFIFE7+mq+IU{&=i1LbHc*0V;~9X*RW=&Ulha`InSw z;*3XsQIVHrnV)BnFwf5IkOBaTWS(B6^F+7+4OdrT2f;cnwFGekSe8{$=4YP};HR^^ zEUL0}14eOIL3aVSD(nQbagE|@Kq_KYWe6~iYjJgWC`L-(jJHaNNg17~&%EIPA zfHrwSWkw6wRLBju6?XzgT?HL+3z%2MXOO>t1NdB2;2DhKu0oDmEYkT_h3DzZDsSQ` zh+9CBibD7+DC{72_;T@u_JKrvSzO`;q6%-~+7r(Wb*O^$A;4>X8DCvpP3VXLpzj&o z#8Xe)&Ks&=H_!!0-yyL%0l==pApb%nLePQYc6<3sIS?Qv|Jn_75nf-%SMl{V;EU9M zMks!Bb7Kz#NY7SI+Z^7gX``fI0XNEk%w9Z2yReC?x;B4NoCpga-iHo$p-|yz4HU!-5wb5?*5x^if{LK zI|0)3?|H^Taa+NA{Oc@9-0xCB+GFQ`^er}r8+9OVzYx8AHb-Cti^XEGSS;3iRmgul zv_k&lp%wBU4=p9D&VQ`lBVkc(`H#?mJEV#&|M5NYMPc_WQZGLDt&n>b0_?)reA!Lm z3evx7%^w7)qK(7lp9lVLO#-L33Rh6kKBm*4E2q~~$8<-$}PSn8 z0p-jKNNT1OAEk9j(Q8C^*v9caHh{Q5c7*l-_VFLTN8jOyP@G2ig8%1u zpT97(SS%Kc#R_WV{=c0ycK_e58omE-XTGZI{{#M9QT6Np8^=6*^5?XF$DcEeb3OY1 zD%k(GBjHy6pL>R)D*E*Q6{FdYq3$&^Z@B;OY2X+Nb+4Iu!~K8Jc!0tFKXdBQ|L5C? zcGB4We@|*3?D_dMb9!hUqqjAB|KFPBhvoRuKD)LR!P-y%U%NDwdRVs4ubIj&LxB6} z|7({^B7C58>%Ha#+(-X^9~Eo4{F{KD0sel?3AmU3zn1FtNVRGM*Io(u2K|5SPl9>z z#?t+LT>cEb#e3@ivw$yPT-O|cd+GmMEgmoaxp-Wx0@qyG_tO8jYUx>{V->h|IIVuQ z|F*wY!D}oQi^XEGSS%Kc^~cF&oxNRha|(KJ{uB=DY;bP0$etd5oIkh2IvbiBFS4Hp z=jQ`9*^u0Dkv%=QKyIf^HYB%ik-a=Pe|EP`HY7J5+tY&!q<2_n19RiC{XDoHfQ}qP za)U+o_29gMHrbHeXlzdp&JPG|vLU(Q*f;UufK4_eHy%5t2R9@)dx0z#i^XEGSS%Kc j#bU8oEEbEkAN>au9v{)&j$_nz00000NkvXXu0mjf%?2hE From 2e989f606723622b12a2d9c1fee77ccc5a85d5f2 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 10:40:38 +1100 Subject: [PATCH 096/512] Added world states for QM jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_qm.dmi | Bin 1809 -> 1916 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_qm.dmi b/icons/clothing/jumpsuits/jumpsuit_qm.dmi index d8cc0d6eb6a5dfbce0eefb7d477d31b11719bc2a..1ff46f49e5f6ef7fe6821f4627295c4766d1549a 100644 GIT binary patch delta 1905 zcmV-%2afoW4*U)!iBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%Qw2>tu ze_~={p?o>Oz`*nK^N?>di;Ih=r>AOaYOstDQ&Ur}hCQl)Aeot&se(K_JUmoXRBLN% zfq{XIjg8;m-=w6ZIyyQ;L_~6Oa#2xHX=!P8c6PI~vxS9)larIg#KfJQonvETadB~} zsj2z-`HG5)T0{|}dL3F?T1G}jetv$Tf1#n4mX=*zU6O7azm`b5ySr;?X~4k1>;0Ra z00001bW%=J06^y0W&i*HwR%)obVOxyV{&P5bZKvH004NLrIO7G!Y~ko&&gAS_N@5R zs~2gJ9_%ZWNVX=BW?_@I`1S^S5EZ09w;7mk*nv&Oxww>-$gd^ufxJN{P9odxe>fYA z3ObtOfin%}uES`2kO87h1|+Kz&Xge^{hqUiWDBGIOl`ac=)q4+6Iu&1tEWP`Yo$Y@ z#0}LW!WinI?wo0m+BcldhkrLNDfwQp;*b?xw${=uBIz%gilWM2&-MhfM8;>6sEJVk z00p&4L_t(|ob8+qd)hV-$8AL@f3oa&W*N|?$=YosC5BRH^V0GCKiEz(ammn0wq+j3 zc0Ypigp==dC&^Fv8xchWK@bE{5i@pncE(uT(SB_BU?9%V&c$HBJK2v8AILEd{y`IPf7qc${2P^@%eaOdSexnaq0&aWs@zRXYTcJgtHJ)&n%>^t-obNHX|<69B4%f1N4k)9P@dy!{b?D{OVJGrcznobDPhS6I(w*kvaOf*=TjAl^2D z`P-nXMyS3Y96yT6`5ep+Ck#T&=cU~ks_%!!*XJ)53nspx9@rPbpo!f>u)ZG{UprVV zmZfCkE9T&1sSF1VZV4kLum39Z}f0e$!|E5X3()X=zs!Hg8 zgZN840WjqdV2wFgFQv?N7@JY;==)afct_v2zbP!2Ws~@&J-&7@UzYjAq zpyv+Gjy#UUho?XOwxQL5CY39El|%hZBcy}AJ3I{%@W+qv1WaX9R|Q}W>+_LG8mjLb zw+-S)*dj5nf5SX=I7oAcgHU}xG=5}G{I#wflu1Jpsdz8@B!AP9mW2!bF8f*}64h=2WlbMZY6YO~`;ZxF%p!5|`h8RI0-1#(A;Mp6o_2TDQw z(YBO_e~9nfMpZe;bJW4}3hX}wK83^&Xs|*m7#`oVjVcnUK0C*!AS58P7c7CX(vtv9 zAUM8f8`X9JiNDd^xY|0y3K;1{pk}T`8XCVJeczqHLGLg0r0+YfmFlqf7y8lnQKR9Y z_ZN<>@6-MPf*=TjAP9mW2!iwb8HDNkFHtO2@>Q-O8~u%i+?ha#zF!B~tCF{JP1*3xX5(PGK_88tB@G=95_Bip6c4*g(whX`g*L^* z?vnH;LAR$(@$k02Nzm r9^Uqd5_Fs5ou<~`rg)_F6TAEaX;;9Jy{aa700000NkvXXu0mjf(Q2AJ delta 1797 zcmV+g2m1K@4v`KeiBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^G9{>OV%#kG` zf1!Liz`(%s^Yf5zGh<_8adB~ri;JhHr?89=si~>?`T0{*Q?7 zg@u!olf=Ztot>Sbp`n(RmR((4s(>Jpe{LJUmPot1yDly+M@L6WN=jvAWl&I1MMXsz z7#JQN9%g1{sHmtQARsq4H^9KagBP;n00001bW%=J06^y0W&i*HsCrabbVOxyV{&P5 zbZKvH004NLrIE`DgD?<9*U47|U0eEa+f7l#Mg4`4lCcTI3{0Y-f8S7{-4$wgfA_$g zdlyrROWXB>Xs$h9fPzIY&Z6G!IZIYYli_sa%z(X{xI&03LXJg3a=PG5TMC&EoQk8A({1wTndK~#90f9;yMnYa)!bZl_j4f6nmH(Gkor z#WSMI@CxLe4xQcs8PXIwog4wit(N{xr`^~J$P*B@ArBrg%s8&nntiD zs2eRaOyAq$OF&z^0?b1_e;9NSU?)j*m_xuowMxL2ZI{wHqh*Gprvzm@O9(K@Z1EDX z-^()^;}ij&_O;G(N;3isTLjp$UZv463YHlzf3n9%AYKA?`gt~T0gm)2%lq&uQDGRK z#B>|6jBbp1kYWDG5?=y7jhBF|L=RAc0tzN&CwthudVTgLeRKBuf0b?Yz@6bL-X4uc zZFnOqGn2S7NPCz$!6r3Px7#gW5O9%U2v`XMazp#n0hnaVjyAwFjUsLU;M?PqD2+~z z--7Yqz5kOx{(6Vb&&`L^vyTYyC0NSbTyFw6q$gO}0Km%<(6I+8gE!7Cc6zf(1`XeVe+<42`QrR6L65Otq7Kgo z6p2J4kw_$JR6hT)Y5DxerseY=o0iXiY+Po=e{{ZaX-MXQ|M-983xWs!BkJ(z>%Qf3 zc&iSNzM`<>A0Zpb=ReY!2|~g1m&cXD9TviGI~{LGD?qpZ7^tZ-W(wces#`*%eXMU? zDW*O{Fn}2@f93{$-{(Iv-;g~*Z~}G9|6?F!jucO|R%nLC(EO&0rLf57KdPxo4S%`; zvkU^>4k-Rv;U!j|slx!RfX{zaoWQ6=1RWBl%itDdK*ggVz@gzy;sA8}k2Ewb0=rjm z2}}JApFfcm8epe}9g9iE;XW{tRx#|HF7Jm;dKG zf8+k2e|(WhBoc{4BA0et|F^MrUH`YKc3%ItG2hPX|2C6ZssFS7QOkvMHR}KRy8&c> zZdw0l|D!wa=XL7;a#;Vjss1akvy0E`um4+g+=c1@`s@FKT>^UQ|G249|A)%!HrB4| z{}w9lf68|C7&mu?rT0Vay#B9Z`BHLxDOQd>h+yrf{;!yErtW6N>M_pj%m=uS`oCf} zBf>js3+FK_;6CdAC|R@FdjeVke0t0ZxR?6Bg7S4wxhg!zY=HZz|0}){%%dxo*7tt) z)pr%|ss677d<0`VW&zww{onlC{r4Z=@4wAGf5$A^PyOG#puI+~x#w7On*S{RDSpnq z$3!BLNF)-8L?V&sv24!N_6Fz1YjL@UusBm&Q%#G@J%+`Zssh~9oIF~EniiLv54ce4 zOdhR5U5m>N2wbRjCXZI3uEpgZ-0niHGkM&%rp4tM-r`KHH+e_jdKOm=z^7xZGkM&% zSDwY?6m+51nY?`!YFk`xK;%NLGkMf^D;5`Uq1Kr^?z=;aYn{nA;{~oWdGP{8B9TZW n5{X12kw_#Gi9{liXg~TFBB|rr?Mth;00000NkvXXu0mjfsVron From 672a12f09a462638057643fb848a376fe91d172a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 10:46:35 +1100 Subject: [PATCH 097/512] Added world states for cargo jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_cargo.dmi | Bin 1787 -> 1904 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_cargo.dmi b/icons/clothing/jumpsuits/jumpsuit_cargo.dmi index 83e2d5c74095e85403f122dcb50b7d9b3f224259..278b871f3a1265d4dc9638f0b79f5117a2cfb30f 100644 GIT binary patch delta 1890 zcmV-o2c7u)4e$;niBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%Q*pVeA zf55=NVq#*de-FN$5Rz^iYHDh*j1Z@%r@NUFqIw>gnVF`25Uq(2z@QM9au3O-5tMHa zJUl#9R8(tgYk`4*jg5_%a}VF&-=w6ZmT?a{IyzHRQ$$2Wa&mG}QBi4WX?AvYv$L~> zg@u!olf=Ztot>R#OcH!u7Gq;$adB~}f2pbY`T2^9ir2IzT0{|}dL5a8AIz&LzMv>t zT3SX%Mt**NmX?-XU0tD}q1w7VySuw&Y z63&z%AN`)QhGYw){!DGW1?a&~OcPoQGpnaUx@)CFqr?r>Bf=Q!q3)b%klHt#&4+(C zE-Cq5vEq;wUAETJEh6bJnTn#ye_zk`1hYiOXOpOjQ2+o1g-Jv~RCt{2oB?~%NDzjz z>BeoE)Nnbdw$)mDRqu{g3IV|)RjbGU|4BEK%hb4hcMe7Hag;A+G@aK48`b7Fgy}Y_7|Jytl&mw@p1fRO(2n z!%(B=V?@8-hnF&+*g`g42-qJ&!Uol6Xw>nUaks*o&l7wkJkAq1e-1TzKIX;ClULEJ zlb0{_6}0K6Qubs7cX`@Mx9))O^}*56(ZM0{KH$YNP1F2NBw*2DcInw4XHel@E8VMB zm`dRA{QUg*_?%84iloE?m4I3A$-zLL;ekrPtb1?X<}38}4KcxYfBuEHzuyr$?ksqE z)34(-^!PMxujA?>f7HKJh8GtXmvA3a32Yl!+$e=RnZWzeXgC_Zf5Zvo&oMfItIOeV zczN}B6Tsag4O=LMxeu?>$D0699P|vO92N(LVHk#C7=~e(4aO7un8}z@9Q*su{+^dj zryv`GOu%9~&Ge#cf8W&~&!5d^lko>K!sNqv0z>o>ocsHZfBqO?Hk)UQ$@n7`;Ny6* z$mX+|E3j(?{2#{koLw)|uc@M)RNsXb`<1m|9VpYVsf-M<{D4S=i`rX^gg@_x z^UcW@D!`YMo6pt2OlNWi(j@8*vI z$Tz9~fC0uec4OQA48t%C!!QiPFbu;mtq?!``M>kG1gK>3Kp8swgOJ~-0HQeCmH_$f zbc523zX(Je2jth|MFOWPWw;8cuo1*XKwdm3y{YqE{o#D$WmE}%(2Jk*8cGC11T}*= z2LHgLe@g7`A6PD)de8&Jp1>OCH`7$bSz_Sy23xb2dC{zN27&if# zfV02lGOF?kB>o{UW<_;G70|;cK|G?LgYN#e{=Q8wMwk;Yo$l`638vRd%j+n^Fbu;m z48t%C!!QiAFJV8Cv=2;N$OYFocsHwiKa?r zPOcfi{1YWqLjI1NTYvw~Wur>)7@kIcue~M^#!v7X7b*d_{(fb$Q6*dDY9od33-VXW zT>JagWH+j0t6Y5q1o3HqxBh;Ku1c25)n_ddxUFe(r~ZD4u1c25)nzTy2yT+j!0VvD zf3K^Ot#UP4<1ZFUO9CC3Y*eXMKw` z#WRfUs0H1ICdH%2cGQAyMU&!DV>@d>G`FEi@u;!eY(Y0E9zAx8E$Al2dz`)gCdK1k cKXadd0gTSUYY@C!rvLx|07*qoM6N<$g4o`k8UO$Q delta 1772 zcmV0001>2m=5B0K5^G9{>OV@R21Y ze`ZV)d|ej6z`&}155AocV`F1+adDDv8?cNJsi~>?`T3`(r@NUFii(QYv?f|a5u$n? zrhO2jdL6Ba5Wt`inSmdfnVFYz56Pwx%&RD3Vq%nU55Ax%JUl#9R8(tgYk`4*m~#)7 zaSu8=I#W|qYHDgkL_~6Oa#2xHX=!O%e_C2bMn-;qes*?tv$L~>g@u!olf=Ztot>SQ zmX=*zU7?|&+PXcvySpwfE=Na4N=iy)Wo1xMP(?*W7#J8H9v)_9W~ivBARr(&H#fk* zz^f*qWB>pF0d!JMQvg8b*k%9#0H}IYSad{Xb7OL8aCB*JZU6vyoTZV=3WG2Ze?`~H zR|H*K`f%G#QN%_4g^-f53B(LcqM?7^P@&xwYIpa*oO>5jic8z|gJ`ZjUx0!|FV3Rg z?Kw+UN0Z@n51fspCRp?P%FL7UXtlVZepJC>lu6Fs zj!4r-u78&+LgzsL*AX1R0%1#uf0IV}P4o2CEJZssuZKJVLok4}1ZR(I000FANkl@#EkYnYPu$zOCp=Hqt)fSIzALtcf9q3%5MgNP z2nRv1v$F#&d5K17*9aSwU*!2<==#1FX$>*L+uPe@gr&E8AMEb$?ovAtH=A&IgJcLx zXf|U?&~3GR*Kf64tspL77GbjA_aFG=0>Q7{ZikJBq+$555yB9{P(}hKSBLHbGV07D z+|dlk`~AOsq8|m@?IiAoe~m|!;G;&^jgxkp3ZdwMf$#T(Hb5OYk1%|%>))FR?&onieO9k5WqF%Ji_v>0rm%vpMc<#$AP9_2`25h-|cqE2sWUz zA48Za!Jdkc_9>ME>C7Xne!ANq9QgjB?;ix3ekIsU;{H>!;M0Dbe~?d!==FN=DsgpN zoTllm2;)z8`-3ATcob;*l^`9gm@FQOO6&!6dLcgzt+g1`3;4-fYa zsP~|X%+MUcAugmz2+B^UqYhGV7GX;8;N;}w=;(wL#HK$q2@d=7fjYq`k`fz2@a3!5 zGLo-fy(H#;^Y$P7fB5$e(SM4~yVK+Ml;Hd0(|7ZMI>Qu#DE0Rbg3(2&KNO?0v$JzJ zMwB3IaT8v1M1Y_ZUX;)oQ-U@ixKRfVQt-ogJQ|NbP=a6>oBVRa_>cYYj|JYNwBW`0 zXf!&%AO)RMvtMrb$9}lQGH(dM4!DgjI<#Oj`FKg)K#KJ8e`8`?fmsm98$wXZQQpvk zpDv97I=%d~g5c^j$(QhNU_hOM48t%C!!S&Z*z%8cW6M9*jV=FJH@5s^?bz~<^|O$F ztXoFUP5zM@u=I7)m@>TifTgcgx2R|Zw)`Vp*-;;qpvdiPf@F5g&@&S>=N}#6i8S@d z^qXjb8r;L=e;%mQFlInZkPc>RBYxkOe?-3l<_L)kh!*}M1pg0W2r)C$uS*5^6o z7TNNT!b_tRKh1)kM+&L|p9Q_e;xkS_?SL)+C@_FhDN-vyyB2v1qM*Q8D8WIBH;F;e zoPUI=VG|?_Ah%HQg?x=-@0i*E2XDf3Y?e%|7g@U&FKWqxr|54?2D^qp--;C@^wTtJlxym%7 zZ&P{we_!tMRe5~P7S7%3q1jCRUpB!=T}`sZa~Ro)O>h(Sf7xULhF8#L#&cT1P1OHE zuqKnYAhaNO_ncO6BlUk7#OoSjm08Z|1UFOvmwf}7r6(5l_j>Zp_7vM$OZ}e`T$0h9 ztBdLP>mUF9xc)x1oU4s#2KO2qQ_H#fnEuTEf6snSt>+kqVHk#C7=~e%(PgIAH#s)e z6qk7lO=fCs6ijiM=g?%P@(yeYE}q(jf+;SuACZMBvv_J3il(^CfJq~A;m>zp~@^?zYFV0agkZ5GK;6i zKCUIjMP#AMES?@)VT!BF;_Jx;mRUUK0vU#37=~dOhG7_nVHk#CHp4HdRQR^XNc0H+ O0000 Date: Mon, 24 Feb 2025 10:49:08 +1100 Subject: [PATCH 098/512] Added world states for chaplain jumpsuit modifiers. --- .../clothing/jumpsuits/jumpsuit_chaplain.dmi | Bin 1378 -> 1872 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_chaplain.dmi b/icons/clothing/jumpsuits/jumpsuit_chaplain.dmi index d606563bc88c0242e2b30d617703e9410bb3c12c..3e8769c98df86b7b8d2431e2e05f193532896866 100644 GIT binary patch delta 1825 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 Date: Mon, 24 Feb 2025 10:51:17 +1100 Subject: [PATCH 099/512] Added world states for HOP jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_hop.dmi | Bin 1904 -> 2047 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_hop.dmi b/icons/clothing/jumpsuits/jumpsuit_hop.dmi index d6f1c360f5fe956d8f0d8e7bec752a9fc92198a2..61380b57b1488d145a61ce023b4c7fda8dc5e8ee 100644 GIT binary patch delta 1967 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 Date: Mon, 24 Feb 2025 10:57:08 +1100 Subject: [PATCH 100/512] Added world states for hydro jumpsuit modifiers. --- .../jumpsuits/jumpsuit_hydroponics.dmi | Bin 2032 -> 2218 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_hydroponics.dmi b/icons/clothing/jumpsuits/jumpsuit_hydroponics.dmi index cd06cdc3dbbd1fcffd50a34a8c7d8a02d8afa410..25f328ae0798d7a1594dcb27a06f6f62d3b399e9 100644 GIT binary patch delta 2148 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 Date: Mon, 24 Feb 2025 10:59:35 +1100 Subject: [PATCH 101/512] Added world states for janitor jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_janitor.dmi | Bin 2088 -> 2274 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_janitor.dmi b/icons/clothing/jumpsuits/jumpsuit_janitor.dmi index 596f8161bfc57dbb59602c2d4b193888ce733b8f..8d9257cc96ba963062d4b9223cbd178cfc71d49c 100644 GIT binary patch delta 2230 zcmXw4c|6ox8=uLTtR<4-W;d=i(lwBH{-Jm-79=X=g`{y67(K2M$4{1KJg7m-$?LefGY5J=R< z+T4LRQ+cCIfRBfv3_=(P1UAoAF#xjl`?KMFVOqEc9<@B%+}tdRtSv7uCy_{{rKLC= zuGWf5N}=+sy`1Xr?;oy)&o!(qORKFeswEPMNl8g*@PYu(psud2J9q8`1q3BV;DAJ2 zMMXtxYim?gl(W2VR#sMLXJ=z$qoK5yot@q2=xAnUCJ>Ly&CM+aii`dH{AOlms;a8Y z&CMetBkk?&0|NuCtgKKdRD67VT3Q-`KnPTePtv=0QP%UKVu+_|0tSPLh=|BHdcoy# zBXsiX>+9X!-7_*WZr;3ESy}1p>zkOEn4h2D(9m%I{(VnR&t#WU8wHHDysw8s@Kso> zrKP2hj}IP?_x2_@fyDqta;+WjS-{Z_NJo(I(zriw(HigM7Hxhd3KJO^9vv8l1%cv< zs_zX7J=YOS9eU-M%6P&WX^;xcm0i`yvu=as`1=srSPbY5G07?f`NYGpalBn$`?I|K zmrW|`_%0Jwq$2J6S(&>+289cFJ<+A7F9H&Bz!kPoip!@8 zGAdqs4>2Gl^Zu)Zy4&_35cH0XxrtL;(OOY9=Dp?70mqDYvILd8^Pj2*tFZg%ZL3Es z4}01Nk)Z*Au|v@4N4e^{O)i&@p$)EKOrL!9&WFtGF<)kGBuyQet$wE?kSs5t=mUH3 zsJM7=(f{%gy%HhscQGc7@YR($xznxrh$mg0!Ai{dU%~ zOPS925=flJA)R!X{Fo2kV@{*j^RgLKBnIz7anN_s&{hs_j5JJw4UdJ=NNd~9__t~W zWUL9Uz37rS+jaRauM~7^=M8L&aJnD*?ll7|9Wo&=VwwhqAn{trvNrYMbL4f8E)Q0F z_|AMW&6KJB*P&Am2P>{VDY1bkO^o9p`ufC?hcRQ!3q#&yvAwp5fHRTA0_y`p#pjsc zr#O=Oeo&{5xjJ#Trm=6W?k7t^fg9;MnbZCfT7^!&9%1iL~32qarTVZ$?H8wj1@5Q`~oFFY0=^hX~w8O7!dbf4ib-D0MBKbCK6 z-i;lGP^s9X7IFN>lYJr(xoxHeou7w&-a?Ox(Z6xQCDd!R?EuFKJG+b}r8M>cY|bsC zm35_kA4iUy$WiH8mOZ>zBz5X#_CW=3*8ewmYPP~=1^@eO_Kn8u=0dK;W7@utaFFX z+kXQX%$U6>;qp~hujwt>rm2~+ts$+K*(lAjfp1La_O1*aqFtt{i+mm-TtA6n`r(jRFG{?Y-VgTZn?vksv+nMuFQqcZ2$%>S zTnFCUr<4Hye#cK_%{({aaDWdxuE&qR3gBFl2<6K69^N7^5GtJoXG10WPT2-=TqiC2 zf^?|Rpj-IjUTb1nub}C?OgE)$(fhiL^B@UxK@&f$lQ4wok!jwCp-aA0?j?qDU(@Qu z`AX8IzitGh_08tfMUEprtt-aH1#n!aEf?vP!7TAq2>O1CnI_&0a5EJ_8PmE~^dEob z?T&`(=%;M2L@Ds7Nr{FOFc&I=e~Gz){+`&Lk~sri9qa96h+ zdm2nhW=R|T7=~=^oyWe@E%H4AM~_uOpLbFK`OefUtG}`KJvI3}x!Gi>lzfhcn7ZK! zg>FL=eN!3$=yZS-l9U{lQ;xiky*we1$c31Q{mOJgS16jiR^Njr_=4vqu(V@pH9X@ks2WPA;8g}C^StA1P zE{J`8UcStO-Slbyb-oVqZ8pbDE?K=^9j>;;qrB5jS-*<%XBGhRNVr6h2`W>twTzTo z6F2UBkH_@>Ww&`+&M)m%YuN~)CXO}ElYWwW&Agzi3U>4#zlfq8o!Fo(5&TOcHgjEs w-OUT<=P0001>2m=5B0K5^G9{>OWJCP+i z22dhwT_=2zUmJh3gTP~BV{vhDpP!$nN5H_qz`3Eol|IA&|NmxYW|2LopoOQUoTsp` zuyHVzsi~=2T3UX7erR24yu7@Ni;HS#YKn@AeQ|()eSo5(qP4ZPhK7c7b903^nU0Q* zySuxiqoY+IVy&&Mot>RM8eUCJP1V)ae|ms`fPj&akz_<xhNA!A4&Vo)Aka4CV4 zOaUQ(vBWhk00001bW%=J06^y0W&i*HsCrabbVOxyV{&P5bZKvH004NLrIE`DgD?<9 z*U47|U0eEa+f7l#Mg4`4lCcTI3{0Y-f8S7{-4$wg_rRQc7gLH$+x3HJu03CXf<-UR zqTcN}OIAmd;dJE8fW4czLWn9tjzvOpy5LNITMC&EoQk8A({1?Ndb zK~#90?V5dG+Ex^RBc`!lCL_oIhlZI^?MAdRwDl#G*bTMY?2A@v+fXBI*YE!gc5a}5 zDsa!e0R;NTd2FsV=a@XX7eYM0qiF;|5X3j8VzKGz=~!%P(jo}@)IDQndd9eSe|FL; zVrE%9X3Q9|IQv1IFqcTcm`MDH9AGY)G)*&^oI_8MnpbPgr;vc2W^pi##pCQJ;S^@F zIkvE{z;Zulga^oE^NY!3axtG3$GKmBcFEETxLiTAma>?ko}P-wEHBw$ z$a40t%OV4a!~Er7TN1{(U$K}iSPxLc!UL<2Efx{O*-&r=wyCsWjWf%u4{b2a+4gU% z0s|fgx!+-XD2j8zVzHER3f3AXxMmfcRH;}*rf`-Eu5&@rYcR8#d1NOx${PuP`w#fP zFy0n?B#O5LQw66|!Dp~iaSAC^P&3+shS)E&34#m+w=%s3Vf^tE5Pb4@QxFdYOU2Z- z<2d*XLU20;(~Jr3gn}`l;BH3S%-JBgk=qJ?62$jR(>2Y#O+h>qoG+!epUMTFZl_Av zyCiMw?0{e_W~6(A`}_OarfpY$S=F|;!k+~3awu5d6vRV8j^|V?Owg)0UYH~fA3R%G zkN+88UwL*QPWY=@1;J{yh8#b6=((=z?In?TfuGou&!7k2Qpk(+z&JWOios?ef;E-k z-tqBqxqOTY@?qPP33}Vti6TLGe;9l~1Q}yBy9Oh2{O5oF!@vH0j-8)>4<|2PzQP1w zy?k+Uohab->8WvKoSwc$;PaRe`I!JxxxR*1zi^tWEEbcHW}gvhK&EVS3!PXReyv9-sLN7 z3rqAo!R5y<<4XX4g0MjTB_?R4 z{y%?2g4(VAKQa8g>i)lW;wZT3{}aQ{tM32PMklE3|Kmf1{y*7`XedVA|JNqC3dhcU ze7Fj_Q@a>{dH-LCeiV8f=^gt*%Z_~l#?$|&H~CCmHTBMYd}f;}!EyBe>FFjIUNxI( zUAj*wIF9~5Jq;pzAk-n)yH6-Mmi|9IXf|218R&|A0}9?j|6lM4WV+t5u)eJMDG;Ui zDR>9{f1zNPjA&mkTeM#K`A{1}4DR7k*wh!>BoLc|i6)DNpd^>gvq zDnu=D$pw)rR6iGwtwPiim;B)3DpWrgkLN}#amf)?ruw^hNp7?fR|LV{WAt3 zmlU*73f0fWi&r6XiAxGvh3eA83+-qvk^lez07*qoM6N<$f>$5LivR!s From ed64ed333eb9c07c443a7269db8b15bca7e8e07e Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 24 Feb 2025 11:10:25 +1100 Subject: [PATCH 102/512] Added world states for miner jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_miner.dmi | Bin 1712 -> 1932 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_miner.dmi b/icons/clothing/jumpsuits/jumpsuit_miner.dmi index 3a9a06b40d12bb5ca50a37c1034252940c43a93f..c93ee14a40fd671cd07a81795c8b2550f57710fa 100644 GIT binary patch delta 1823 zcmV+)2jKXy4U7*ZiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%Qu8}1u z7?N%qdtDcBDS?qar-e6}qIw>uN5EAeVv$)Y31&?bcS{_cVI+}>Ie);wz%DN{f|^Uj z00001bW%=J06^y0W&i*HwR%)obVOxyV{&P5bZKvH004NLrIO7G!Y~ko&&gAS_N@5R zs~2gJ9_%ZWNVX=BW?_@I`1S^S5EZ09w;7mk*nv&Oxww>-$gd^ufxJN{P9odxI2()# zI-28wGY#gh!)Sbv0e_-Q1|+Kz&Xge^{hqUiWDBGIOl`ac=)q4+6Iu&1tEWP`Yo$Y@ z#0}LW!WinI?wo0m+BcldhkrLNDfwQp;*b?xw${=uBIz%gilWM2&-MhfM8;>6sEJVk z00qlQL_t(|ob8*7R@+7phWCPEXQg%GLT)Z0Ku~LJVr;P6lYjSrvCgb6HL$a5YwfDE z^93sh{j0fYMNWPlgkTtkVVDZ3^vTJIRV22%$Ypruq&y}fA{ssoEJ|IdctouWj z7}RCf-eGTrsDI~KmgR&F4Omkk#`+r&txnWutsRYu(P-2~m)X`1@Kjjot^u!(OQ1lQ zFBC{@kyfWBg(q1&-nRv7#FY>aaoH;|?*Wr^JFr_kUOC|iuj zW2FkKy!m6gwWp`2u*MYB1RC8Vot>R+-C_LBr(*}otGfa|eEjtJ%jZuYKllrX=>lDD`Yt;_DHYJwWHR{`KE#Tsj`JJi47=%~y~9+2F&%CYbm%r&C%wQ8Tm%~k>EitB z#kVitE`PqB69s~fkh-v!mujLeFUbxgdeP8Px04Do|JBvi1U{7BI~E^N_>c`uKr@DH zuy-u%Pz!rB@Q}h!0O}F^7hv(}vVjI7dhc)peFOX7R)=nS?_2}bp_|Sy48t%C!@O>^ zR>Sa$q0*Yt68-(;{CK@ai#~AqaPUS`5mNpA)PMYVeU_m`|D9U!9o_pZ^G8Vb_Y?DD z0F0jN0r@{3i|#!X;R|p8e?KXI9YC9aFXN0Gqx}K&6Mz5Z3jM_2_m-gZ-SYddZUPhq z={*XI?mZRYiN8J!Oxl`uk$H{2~}Y(G$WEsz88be?KvQ zbsjBxDge6ofdHxgerkSUZ-hX9p8kgfRUvMuJCNw_r{>29H~5rMGTdK~Z^-MD{r$xJ zE`kYKkLcb9`cL-v)AH8=g4U^xG?3^nr+?*74!{i@qJfC}4x2F0K(fD|mLK(~`3?)n z0O|gIT7HIM7=~dOhG7_n`QKun{r&3lM*=jbr94uH$@#4n?hh3}x~pZZ0ZG2drj^6w zw^=47d{Mu|RDx6jzlBCrmXdmr4MJJA3y+Y$zWn!+_$8;Zh6*sf6(WNoi0cIiAb$&S zJ3UT*2vCKf0?gdyv)PPn;1&ujsrs>l5*FOj4W#9_3NBSr8t<Mm+Up*3mQh)vZI*DgW z%ZDwcJ5WD#u!4g>P@=#8ca|4ZT2`m1$?eJ#i$BL6s0Nb!{ifEJQ(88sk~@G%7Z8OA zlj!f)Ik3{@(<%ARbz`}LJ3vQC^Y@z^Sn0DV`ObA=4Wqb#F|4TtN&bEVOlkRiO1^U) zSf5t}8c6Z?>m-{MvROyYb$?;~$7+RNRGdVAze%#${JGgYN#Z-#iFE~8UXs7x zHn~HQ=I=N7rWBbR!!QiPFbu;m48y!`4rD?1#(^y8j>++`<;Rrf~oO N002ovPDHLkV1jCPf=B=W delta 1601 zcmV-H2EO@>53mg-iBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^G9{>OVpOGaf z40lT$dtDcjZX2R{9+71#2Ap9eW=#{3m^ptgFEhZvz^&V}{r~^~0d!JMQvg8b*k%9# z0H}IYSad{Xb7OL8aCB*JZU6vyoTZV=3WG2ZMc2t!1YKMDaNA8$#6|sukdmXs$h9fPzIY&Z6G!IZIYYli_sa%z(X{xI&03LXLk$ zLUOv`Oj`<>51fspCRp?P%FL7UXtlVZepJC>lu6Fsj!4r-u78&+LgzsL*AX1R0%1#u zlScVX^Yqm$MLRUFhdcp8Fo3iKXOCPfOX&|l`9;2q?B^F zH4Y6)aVYQqZrzna$f1=Sf@6N{2bh1stE@grPG;CyAsB{Xm}jKYCnqOb$-YGhWcFb& z91aH`vUh4IKN>w44z&452*M7-mEK{9!vbR`ptTytC5B3CDt(@rTn}_^vOG9NYKI}7 zYprwo1R#njB6^TrQ-(5E#-oCQGF$C%&;a9kmSs5+N53q?6rU)+PnbQ+2t$9FTXTvS z8xoY++71T{eB22J<0yzhNMR{Ki`gLuwS^!E`v-!-4a((ehh<;|E}kRdxEIv;dRh>p zniLeaaDqiBfy}jB?Xc8420m^;%>?64Fb6?MKnr4ao#nJ(0V4_(6x33zcG&$Di2E&8 zp|}&&xppZiL6;o{5rWE|7Da!d)Tvdw!O>{6w!`>WD2|3I825r&7b(F)lW${t_W8@# zZ(qNBJ|oT`w!_P~QYsS1iHrCV7q}2=el;GCzrznT!)k}g{E0YTlnOrMegM3BH83Oy z=cAN+h=QE|xcK?)=f#h6B0t0tGVao13Q7>OM+Akvyi{X#c}d2{9x{J^b#*m{A2NO| z1iqgBpvI^W*W?x_z>g^v`5d!jh#5mJ01U4&1w8|1zkanJ2r6aa86XAK*jh_I!p;y= zL}q~OulGYii%%*kn23A9==_!i`xR79fc_v(#8EK%2)Yyp2;Knx^13+89}7O`c)cLQ zFbu;mOs}NskA3srE4+WH`eWau>W{snH|md60j^Ir>W_WPgn6kyQUkVrADdW(*ALkG zO@yWFXa%YIqpD0 z$`1`o7;sAprs|Ih)RdGaSfY1^?sJrSMx9_)RkEZ6O9|naV5i?Op9w7})YQ~vOt7rYlq>-!%Xce5B94M0Ay`LF z*qw2GkYJ^Rsw#h4(A-A_VfHC`fPO?Zg*8xuiTdIVJRLX7Yl!;^3f`N^8r?FpyddLVHk#C-Y*^Z{~b)%{eOqjdH>(Rex3LK9fscM{|ipx z+Ur{M|8-Q|+vxuzM(8&Ef4Z~s-b?>q7@RlV|F<021uuX7e_?!gU8?_2bSaqV|HDg* z{=d#Dpk4R>Et$>Tb@Lux=Ci=)bvp0=^Dcj#$KTn;y|oC4TS+kiv-%1!BrT=e+Cb)}hPh99;F#S=w*Jfw}KC{HV-UMO4V7IpRDs-7EOQRUNHMH`v028#p2&$@z^Bp1vpOsU-LMh<9Cy|*B^~1d5>WjhG7_nVHjqc zP-W`vlH(=$&v86OpfdGlv@CJOa|9|=K7f~&i>FSZWr-`{w^Nz&fjt&aokH6ZS2Q;! zI1f~z_E|i23NHCmy2KSv4%shut5Ewao;(FA`JQ=(bJ)S1CAO{aCB{PXr*w%cN(1RH zAoX^QqGf$AK9)+pm*BZ)Cr7*bUVLoxH>H?XbkP z&*J;31@5zWt_3m-!!QiPFbu;m48t%C!yJeItB Date: Mon, 24 Feb 2025 11:22:42 +1100 Subject: [PATCH 103/512] Added world states for CE jumpsuit modifiers. --- icons/clothing/jumpsuits/jumpsuit_ce.dmi | Bin 2180 -> 2307 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_ce.dmi b/icons/clothing/jumpsuits/jumpsuit_ce.dmi index d1b0c535638d39409eb2f9f301b0732f028d408e..d96512b52d3dbc389be53ac789f7638c9a7e0950 100644 GIT binary patch delta 2271 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 delta 2151 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 From 68ff2138b5af82a120cb6628df00b635179ef4df Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Feb 2025 16:41:11 -0500 Subject: [PATCH 104/512] Add missing modifier sprites for many jumpsuits --- icons/clothing/jumpsuits/jumpsuit_atmos.dmi | Bin 2009 -> 2200 bytes icons/clothing/jumpsuits/jumpsuit_captain.dmi | Bin 1899 -> 1903 bytes icons/clothing/jumpsuits/jumpsuit_ce.dmi | Bin 2307 -> 5131 bytes icons/clothing/jumpsuits/jumpsuit_chemist.dmi | Bin 1459 -> 1642 bytes icons/clothing/jumpsuits/jumpsuit_cmo.dmi | Bin 1763 -> 1928 bytes .../clothing/jumpsuits/jumpsuit_engineer.dmi | Bin 2026 -> 2207 bytes .../clothing/jumpsuits/jumpsuit_genetics.dmi | Bin 1652 -> 1837 bytes icons/clothing/jumpsuits/jumpsuit_hos.dmi | Bin 1945 -> 2135 bytes icons/clothing/jumpsuits/jumpsuit_hos_alt.dmi | Bin 973 -> 1566 bytes icons/clothing/jumpsuits/jumpsuit_medical.dmi | Bin 1756 -> 1928 bytes icons/clothing/jumpsuits/jumpsuit_psych.dmi | Bin 1750 -> 1913 bytes icons/clothing/jumpsuits/jumpsuit_rd.dmi | Bin 1713 -> 1873 bytes .../clothing/jumpsuits/jumpsuit_robotics.dmi | Bin 1704 -> 1825 bytes icons/clothing/jumpsuits/jumpsuit_sec.dmi | Bin 1701 -> 1883 bytes icons/clothing/jumpsuits/jumpsuit_sterile.dmi | Bin 1891 -> 1892 bytes .../clothing/jumpsuits/jumpsuit_virology.dmi | Bin 1713 -> 1873 bytes icons/clothing/jumpsuits/jumpsuit_warden.dmi | Bin 1731 -> 1913 bytes icons/clothing/uniform_rd_alt.dmi | Bin 1047 -> 1230 bytes 18 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_atmos.dmi b/icons/clothing/jumpsuits/jumpsuit_atmos.dmi index 3d5217e8b2e72cf5e35e3cb2fcb42633801c7d38..c875b073bd17392cdf9028bd04c5ee6d7b1aa272 100644 GIT binary patch delta 2146 zcmV-o2%Y!Y510`piBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%R4v{4& zV*qWD0F=SWrU1yO0^!pF0IC0sjEw*80MWYwR8&*|Zj%6luHDT7Yinx&rT>eIi&Ilm z%d`UI)&j$o0BC4vz@PwXYHG2S0qx%cd1L?sPG&qjJb{6Mz`($+kN~ol0>Y#Mkz)XH}g8%>k0d!JM zQvg8b*k%9#0JeHmSad{Xb7OL8aCB*ZZ*Bkpc$}q@%?g7s5QNXkQv^M?^v7#2MG+76 z6(l8V6Np*ZM5S-vP!FY)7PYq-m~VC$HWlZhtZI>8Dn0;tgHD`8w%u_y8WnUj#{*{? z%uR>M_#gvBnT$wQC7dZkKKeapEy)fh{hr!*3owA6nI^Or7FN%Nbl*vbMu{tbs(XYn zG-J~{(;{^*I9m>XEU>2I+cAH1ttqjMmTuK}`bnmusPpHuJpjU<#%G!Okoo`s26jnA zK~#90?VJr)+DH_JlUPZB*fyIrtf{RlD*aeoYj@YUttM2UHHOyD*8cxrvUdhdJ?`9m zFyO>~C9wrx9( z*g>}L`5ue?nd|!&{4CTb2822f&~cm<2hVVhZnLf%f0x%y*Yi9uunGp)Pj?3i*Pp)t z123M7^zjkac!mwsK(@Yr!~*;s;=|67R2OLGx~X~VuG@Cqb&o$2=o@}>v*~Y$bRM6* zwgv$j1~Ph-IY<(D1d z;q!Fa1V9hGfgX5ci3d37e{?rDH@h2{-m$m0w+*=2h=DolU|@ZJy=_^zfj@V4cHX|- z!41IMgbwp98o+#YZFjZ(?)AI&>Mj!C?q7eiuYWLI>+J36+xp%f^7?bvyV^uxnL4Q`lD5ClOG1VKD(!YIE@6wW`6X$hkU!pkrb zO`24cFzWSsQCLSEMDfquUi zfz7J+K-lkvLl`1>4}drfd;Q89i2C91Q?`Lm!?0i3b0B1Ye9jmlFvdRfMq)X*^LX#@ z%pPa=z_EtU7C8n|IhdD29@p?V%fRt4ZTNp6F#d%Z2>4x)X8@P;ob$lhWf-ghyE>CL z6umwWqw%#)K;josTgczDyCex(SO!`_lB5j<3_|u!2@@5fYcPwk_gG}22)rQhAx7U5 zAE4EWT@D(5;7HRzPVg>FK-RPo+7W~BOIG}22Vby>4h*;f`$h}|V*_yRx zhfo5q;QOrv4RGLP#?Kvi*eSx2&qk1oW-w;apM3p_yZ{)8lLYMm-UUe#XBmjR-f8BW ze0bXPFo)yw^DK6e9+)%;Vsvp9!b@EA6yPU;%i7?7@kQS0dA5P`Q`~^(#%EauJQzGD zCoyh78+q=o%FE3nglo4O#onL*+(6w(@=coZKHGt`C^ye737+rqH5C8pgbdh7= z^a`B?7=tUk2iOIQGwm#6eLucF$utmv#nF$f`r_IB2O4+w|Qt@?o~#;<9&>IV=#tsg*8y}tjm zegM;N>IV>1ukXv&4=7*Xm#rUAzP>M8KcIYneP6bIK>7N2kNpDm16gmh^F<%;GKlRpC|f^pa}+^; zmiV&;=?(UlYAkl6Cfejmldm5bBg)cvZ#i9dmqxY~9^0x9*$7Xzeqe$qOYl1uKbED?FLq;s5{u07*qoM6N<$f&u68ga7~l delta 1930 zcmV;52X*+E5!nwViBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^G9{>OW3y~!# z276!tlyv}+O&ehTn?I$^fMQ!Q&Y>d z0_4^LyQcudl>oq?0BUM#v6TVs-vajC0C{8p0GI0nPG&qjJb{6Mz`($+kN~ol0>Y#M z=+FR>uquB5TY9310oJb?!JQa#Spa!o003Kgcx3_M&;Ylo0Kc99igEz6lmNGv0Px-b zn}7hFf&lyI0E~11z`(%90BX_z0004WQchCV=- z0C=3Gk;@8$Fc3x8$yWqjTl#R@O;N-}{e_T{u?c^~3{0Y-f8S7{-4$wg_rRQc7gLH$ z+x3HJu03CXf<-URqTcN}OIAmd;dJE8fW4czLWn9tjzvOpy5LM(3Yia_jie@6^ZUxo zlk#Y_xS@Vj!C{n1&fbnl(?_mybf9KZr$ONo<4`Azfm)htCjG_Qv|0Yfl= zv;===k8A({1;|N6K~#90?VJ5y+DH(_H=#m+5N){}hO205i=egi<cPk8FQw zsZcBy@rCAFdiTiW5_SCf3jloaoQi9}M$K))6!Ieo!KPbluz(wS1Z@(qRZv08_uIbT z3iMAzd^0R>mBURct^q3zxA`(1@MV9~ZLpsbZ({=hZJV0n?d@$?W?|S4Ls($=6BRE5 zV3~|-K-4RK25}9%(v|3N=k@a1o40S)mS1=13PI}~jNm(mTwoagv%9sm)!pRcdSrIe zM{q~+yJg4Q-QBg}@>sxDtL->E;9q-td+*=xv4D7M?xX?kG;b1n|AmW-ue!LC zz(&jg!Y++_5Wi6xgxd`6g)HDFIEl;UPh1=bKd15a2|wSN4*(rFNgN)q`vuP8FI^T; ztp=%lnlQLC9|9KOR~jC$+%12pQn$4V zBoc{4B9UmWGWn15mdSsdw@m)yyk+tq=dOY?5~l#B`;Yzcy@-8g z1P2wOm|euseB!f9P%lCs>o8%Hdlm(Le31qiz~r8v$2_3w1^(q#$ODE~mwwRW!X`j< z1IWd3^%(#!dspAtu=;-0yPOEnxlk7={$G53o(dR27kWQ2pj!J*dt+^ zW_LYt|ClLmxLNZ5+$jO7q5MBu*seMM zZ%}a>`j!7j3)_D+=l`iG0-Eyw@RlL}FKr{5NYl>$8_3G(`|UEkXYs3UC(rf0*!&3Hih6?o=5GIE(y0oss`6UmXFg zLYWzGCi#Du@ZKItcc;qk2zU?qe_plP9!+1^#=$=X!e{M6Ce+8tw=NF)-8L?V$$Bod8^a;EO@;dnDzT zoT+sBt>a*Ue^erHXZ-#_2p)H>1Us4#>Gs<8+>@ zdoLCj<3f$odA{xxEv|7oKOZk}oX(3EC=!W8B9TZW5{X12kw_#GiA1x}f3ng8e=#QL Qb^rhX07*qoM6N<$f-GK{LI3~& diff --git a/icons/clothing/jumpsuits/jumpsuit_captain.dmi b/icons/clothing/jumpsuits/jumpsuit_captain.dmi index 9b1c43034b475b89e90911bbbad30c28bc26430f..c0099fba885b78fb0249c6d96b72b1be16740695 100644 GIT binary patch delta 1503 zcmYLIc{tPw7@jf4y$#k8Vumisk&G+H7|dW3B~rPPl@{Y@#W;UIN3qWsqo(8tqtQdD z8Lj(qj3czN2%BRvGg>l_X&fPpqt#Qp`~CAh@B6*qAMf`*pJ3nOzG^xYXmD}FdJ-QB zeNsKx7V>ot9fmrwqbNxk$yirebS~X@@e3flAQNr!ykv$*l`dvW=17*bM0(#97F6iE zh>NA#p)P7`l5=u$@bnlIaJ?L9Ti)x``x%{uu^6UO&m}y}adWeSDwL4*<0`Dvw|hrM zMkrbC%G2RV*W5XBBp}Bq_73AH>xQpVccZwPB1StUZNrl-H&xaO4_`vTcO>pz%^g#^ zL?OMfO5AMmoTqvOFU&px^-J^SX3>M&@I#uEPv=LmM_vy>;PFLq<}hnD1~FKPM}Yew z(k(g5DU+2t$4yRUv#|MNp+Om~a0?EKqw}^)fuma#fGY;FWu%twjr7QE*mRi&h;g)s zyNvzS`UaG6rZ{CrJR;=0NR8`bH%taI8=RZ9Ae1*!OxFu;bp>7$Q{7=4cS813?RFjF zZIU#RM0!2ATHaSP_(0WvbAKd%^U*c*=;VXIhl{2#SCHk*WH9hCE-2Ra;n`x zdul`mHtoTslHeGWZBt{L8*^9?2BbvW7Uhkw z_@K@H>6Uc8dyGbqBm%}BM@2RGGlz;J$x@c03|Oa4w!Kch)}eujaEY*KYW6GM$5 z*q^sqi_fF>Bq2k!XOKG*6uT+20Q)dvy(|lDP?+u;H*uRRV41E;yy|=QN2g706F#L- zU}$cbnV*s-TS=I?h!}Sab^R6JeoI(}K-MmNd7&jG&dY&#W1=Zc=BgPM%Gdl<7q(&5 zxNGZ;X`(lIjRds;cqrdsSaAY``0iPaJcuq6cq^zAZP?t9dA8K_9^kDd0i_kCjnEdS zLEX#`oF8<4$`u%{tonglnNeWo){aX1n>eVJ7VDN+Qex70B=kVCDsR{Lx_=0zLxCsS zvfg=Vz<26j?`QR~KIHG(x(9qc`PawUYiYn2gH@wBj2lLgMqgi>4X$syN%)A6p;7B# zn*DUJ>aTbrOx-6yz%zTQ-!Sm3^SDyCp0j_NOxDF;U{FSz*)+j3!Q;vA`pT;kLJ3O^ zt>!xXHg(quH;2--TcyO628X&X= z;YyBO;^U&rPW9(n4NzVkt#_4!p|U7NZhCk!;c0=iM5UfhfoCH`^-*Q@mXC6(-?gM2 zLkMrGZq*nI)y*s@>BQj^Ndh%}kQu2LtVmbdM?2C1iBTeH;73eI7veH!iuH@v78#$h>V_^!+T~8plAzeZl12^=cMUJ{qvW zWh7>##A=sdQ4AIZr!uG^2O~WeW>g&31Lqbc9r-})&$&?n`gx~ib{$K1?OXvQ>1D=N znkcYoyXb1F#W$Q7g!Nmtp8`9Vws$~h*G9lxg?r467uf!3-9ZNp_~&saHknr?-+vz; z^*0I__+kk(CBdynxV<{Y(``h*A$0jc&-N$)gHrr)fjovJ0jiiQ`%73z#owf4|4sI* z1q^S~E%DXm@T^!GcRg=vknoSVNkoq@0gt*x< zM2FdA)SW;lEfFf5PM%!&w*S92(HW7fL0A^Si#8D5jNL5D(3hi-y>h|1IWp|8r2PZL CvebS6 delta 1499 zcmV<11tj|K4(krEqXB=jNkl8)leRBNFgwDOCPNuA~`<~?3Gb@}V0)apv5Nwc6CI<%xlSw*|-#5|^AJW5vL-#g_ z-#gNyqe*(0PL7U10}-B$Ecb7D2KkT2$HyNLpDK%!>4|#_R#<;@d@)A3f%?j6Q54e> zRA~8`@9OT(fIx*CUKs^=*FiVK;2iJxFl|(km6<(EcmU07wY9>*20U*N z?+}~e2yc|Dud;uWj2a+#ThrDV@Oy=?deFuL_f&T5zUtL}K12wR3xO>$U z-K89_tIGX*#|F)%V%eGn8CpSpo=A>RW?Q$6s(5mh7{Wchnw_Uy;;+=on&%Y%au#?cX za0jVqTibrPfu`Nc_X8F$yg|J8Z~OSSLH~`%vhjcUBogq!WdmlQ*~<5W9d70O;R>3z z>Eqwv6{y?h3$=&mrtnMCqH~a&E<4${|I5IjKvrf=M$bUz2Zd>Fy4?60V*Uwkpmxf! z8E}QvnC7g2m+j#XFSP#mu^Au)xGTW*PyFTUtG$~b0ecVm+70|2+cD~Q_cMA09Hwy6c{CuD1pZEp5Mb{{g=GHGF zDv+Bl^ZdQQ?Hw&}cl)*taQwZ%-TgO8;M@J(+cv=Q_X4-~WO$w3lPkc@_j&$_-_VbQ z?^$@4|CM9r`#gVvKp+qZ1OkCTAP@-tx6psTy#I0j5rK|=t3O_5`@7V}{U8CIye80O z9R=L2&glox*#26Rk5Og0OJ)_`p(r*Yc?mkO#Ks#KaQ(HRAEVN$8sRskEZB>oPv{k5qUh7_nOJ)2dy0WVQhIQ^{(tUiK& zCjfZ=S^F|W0=9;Qp2JN>_Z8O**Z|+(RLUeqDJ-C7q=5Yv8~P@pwL#xuzW?SAebAr# z_!aa#UPIRao?t)1;0DN z;9u!MgY$jD#Q*OhV%$Ue(Mvo6A#T2pO;(Rv3k_}lHuk1gh|Y}H&%b&tqyT9 zVCDOii9LUw*5BFnZ?p*=UcOJ5#Eg65`TXhhpVO!FXTUS_eQXjl?u+M@Jq_(aH84Ei zCro0-z482G_3!Ejl;P$3lu5)`AP@)y0)apv5C{YU!Co;^hW_T>Xp>>A41EZ8@rIiW zBW37=u!}d^WEd+$AA()H;n-8rGV}r1#T$V#<3H~U{>ygpo;Lsh002ovPDHLkV1lFE B|6~9F diff --git a/icons/clothing/jumpsuits/jumpsuit_ce.dmi b/icons/clothing/jumpsuits/jumpsuit_ce.dmi index d96512b52d3dbc389be53ac789f7638c9a7e0950..66444d604cb0aae593521d6fb2cf032c53442312 100644 GIT binary patch literal 5131 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 delta 1345 zcmV-H1-|;~46_S=iBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`2YX_fly3T zMZmzokwE~#Qvj-}s>xRX+1c6uhybLdq-ttv|NsA|r>FDt^Nfs)-{0RYCS4ghJ1TfTx>1y29~1T{%SK~#90?VF2on=lYX zS%)AgsZwQ~7MebshjE?%|H0msU8k+JVkQ*mOm#Cr;>Fs79*ln%-&9pmQBl#WXtlby zxLB=dsr+?Kmlv0ESO}nLR&+_LrcnTZhP}>*xG^TjPjx20bH7MbG(ZVh zYt^{qZ<@N&qShIteuvE@0Z91hnuIXb2Dzqj&O13Mgf&jEq(lKAeQ+b!p8_D~(fHMS z6MMkeL_D5T zgU#pwmb(rBUB{^@fW^h!dFwmo_}6({F2KhNIFHA3@UnkpeF*HQo7?;K{q4;sWtJd6 z06?HMfH;)wK~WGY&h$XQyA8JRMga6+lok*1B$EZe0P6s_%Y-#nk#>cjzkHRSZ=aQT zOuRuOO1x?zmYot0UF;$K3V-&X65k*YGLvvn;keFKfCt2!dr+@%6Gr7103*vt?*S9q zVALJ}!Q+3J`~Z+!fY$*WatH5pfbi&^^yn-A&%7|eQy2r_BY@AWf^gXB0MB8>9EdA4 zvrLEL0BGA09Z*zMR8&+nmzH`w5k-|$@XHaPbVq@@AOUIy6!302fR7)XRPgE}mdVvh z)v+*uVQUs00=6jP6#)L@`1jQw$}UnqxefrF!u)?`!WJVSM-2c~f&6Fye8@fou+>Kx zwf`o9Xc>qokUBy=#|LTdUIEx18__4ZOhT#QH|YdH-fO8zKZFCo&P8dZ(-yBg6jsz| z00#mkKL8}Zw>A&p)!L1F2|CU#G7vl}`K9xm#VDzFO5VkXRO%EE0E|**4xsm++@n^# z0ib^-mg-lXg;8qp8c%Rrr2~%u{Hy~=`JDy8)%U$#Jy+Ft@A?6N@T3A%CjccLb7R+M z0Q!CYKHCPp2LP}`{lDAk0Itsh>=E4WbNRCsyxr|~wtB(-B^hU#;T1c53YG3MMXtLQ~L*o^G|>59~jI(wSQnR|K$FGy!bc&!1+fG{>?v- z{76F0I`1DCAo$fkkc|K0A4s-9$e;BO3?iKT18Keb2hxgPo{#zJ^wmG00G#{-IzY}p zFbpu(KM)(q^#E;00gUwzV3yLMdlin!{R7C4wG2oFV0!-maV+3_CByXo0oqD+odbWE z*grsi>oS$q^!@<=^v-`*-#)#6fNB)5lL8F+2ljiE_geirhkpS1b$~hi1Eqp5Dk>@} z`WICE1I0gZw_e&maJOF8KTuU~evC9)(Lb;xz|lXTeSJR%K-NDny$1XP(<|>En2lh; z{CWStEXw%@<^jm~2j&6D`3L4u);}FEi^_ih{D1lZB*0)pOZ5}$00000NkvXXu0mjf D+%9w# diff --git a/icons/clothing/jumpsuits/jumpsuit_cmo.dmi b/icons/clothing/jumpsuits/jumpsuit_cmo.dmi index 432273d5689dae29fed7b65aa4b662e773d8d62a..ade2910cecefd72206761dba367764e9ec61a7ac 100644 GIT binary patch delta 1880 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 z z^#9pIIB%~2n{(soa5w<{X6IBYl}e>jsZ=U|mFlW$SK=B^ElXTEFFZ7TbO}CI9}F|? zN?dK6H=^tke5^irnog=l^b_ z5oMR)6KmU*xH9hJQFaMlT-&n5m2)4DvPDwRs5QmIrbl}e>jsjj2{0TRSxWk{l8@&Et;07*qo IM6N<$g7}t6RsaA1 diff --git a/icons/clothing/jumpsuits/jumpsuit_engineer.dmi b/icons/clothing/jumpsuits/jumpsuit_engineer.dmi index a944a9746d3ada9dc6e425814f794107a6229593..02999b489c385e8e30b0335af2a8db70a1c7182f 100644 GIT binary patch delta 2135 zcmah~i8s{k7k_5P7Bhxkgk(!fc^M*%Z4@!DLQ(3q7G`Ww8M36WF?PzD62izD5|tP< zmPiPZCE1D)S+dU<^Hc91@H^+ZpXc7^e9n39z2|e!{ejLBl!>-5Ge+@>^8x@+coW0( zyElE;vUw1@cx^q|J5femF3}&nw*YPV;9Vhnq8Hv^3F6}7*b9ISfgT#%%F1e_6P_52 zfe3#ibaZscWHOyjFG~Owsqn@p@B#>w--neY!Ag=~SS&UqB!oa97#kbg+uPr^1JnpG z{vMti3#&?pQ=?%1F0dd+km3t=CP7mgxONdt`f|^716l!?=mu3qfc6N)+ywqA@X8d> z|4h8<0cgk+T^a@HA>bx-83Z_h%uv9b0dXX-n?#z0VBu~ZFw%K5OMv@6NZ1Wt1zKGq z8M^p5-E_N7a`W~Az&|4|sgsw25eVyQv*ggNT5a`EHWEay3CkVw_$%u2pkbc(m<2j7 zMdW3b*h6o>eJ6ycsU_}-4oCGs0L3iB@YTqT6XL=oHK-Lq6z@12*|sT-FieXxxp*i; z;glXjm-u%ZzdY;lXMa9SNLHHs3lWivUE!oLeB|lqW5q#XDr!!>+P$*A%9=L(kYaiM zw_z2CRI2d&ZmQQOe+E9ETDUS@sS6q(w-D192@C+Z0`Z0hR{j}3Gx)4~O@vwx%eWt( zMM$MXmj_~EEE*Vt6;U)(yK5h1Bdh|B-eD_O+{(|pN%E4+{MziZfIctD&Z%anyM6R& zI?%!sD$R2>^jnRoscG3T7Sh|GP z%-0a_Bvkg`NUcR%0y%R`bz^P3(roOWP3?c7b`6`gz&c-_>hPH=FAed#!&L$!MI+0> zY>mN%nS&$(mH_74&}z+R>V#u3uAgjRw?7&2U?gnL)DL}vg-jADsIiYgOg4-)9;u^vW*lWJnRF588JiId^Z z7;}g4tsEp(?BNe_Hy@wm<$^iL(UGO_o4qD4>RL8O!fyv_{Y%!&_mX-4>7Z%E@rhYESc0p6vMROb!PfyqI-l3p+OAngo zl6CH0W!U&1?(?iKEhmGrW|&v@2LC8u-Q0yCTje0NmwrRq` z(6`UPHl70s6_rq2WKIjl=jwXW?S)oc#U>V`*{JL4HdP zeYo^5SIy!QvM3=z0ImUKJ96IFbIG z$Dun@Ax_GIX}7f~C)Fs?aXaI^hbQ;YaY^|zFpEg(v&o7G6)8!=ATG0(0*9p$Nb5k>q^PFOsb}z{y5rkC@AeBB z&mYOH&&rT;7N4QKT^=Z5K?j<$h_%B)78K4# z$qk1H{y3rBE zHR=}(!MNu8H_q<&^e@bJ^n*3*ncu1Hp!Ip5YAcV&>vTZlMVqXJv;tqx2+Y zKp%79l999R77Njl4j7PY>G+dljotJt@Z9i}So%f?}AJ%P9)h(Ze=*@JkNJ+1zl0ISGHhV?a z(6;lZlJmZFT;R1!{iSOBrw`DdS$(6%chtbf$>7k;){$hLd8M|{f4Y6n$p;MDC57M5 zp3XV*tDGhmd(7ZL!I@u6&-wmyR9ln^Idsu3Ns;k(7JCAf-pir))5`a*>ZIT$PxKS^ t)cod(n0C7)S$F;mrA?kI&3fIzmJy1$Uz>`l-rcGIZ)C=4Sa#Ae^naj8_DTQ% delta 1925 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 AR{#J2 diff --git a/icons/clothing/jumpsuits/jumpsuit_hos.dmi b/icons/clothing/jumpsuits/jumpsuit_hos.dmi index e3e0f1e2f75227b260ecbbfe4a987b7147e2cba7..468cc979a85cd0937830f509124d17ba9634e91b 100644 GIT binary patch delta 2029 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 LNkvXXu0mjfoul4( delta 1838 zcmV+}2hsS~5Sb4liBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^GACVzMNMsQa zdKDGdI47naAFe4H(>EpT?Cf}QCAcshpd1`n5fPyt7^)~5y)zwXVjGq!9+V{%qaGig z9~hDw7RNOn$TlXB92UAaCy|dK7*SDCTow#j003S90CE5TOaK6X003qH0FmY-e_;s+ zfPjF&z`%0|1)K~AKR-Xfz`zNl>w^FQ00DGTPE!Ct=GbNc005|ZR9JLGWpiV4X>fFD zZ*Bkpc$}q?%L;=q5JlI?R|H*K`f%G#QN%_4g^-f53B(LcqM?7^P@&xwYIpa*oO>5j zic8z|gJ`ZjUx0!|FV3Rg?Kw+Ue@BzybmYu{y_>i~h$=#kMM84A;7nTznGc+eq$XJN z`^wCd@@TcVp?*}sVU$VE-i}DqN3MUDD?;Z$|JM;5zye`QiIYb8P4o2CEJZssuZKJV zLok4}1ZR(I000G@Nkls&Ha0i6wzf7mH_8S8gud-7$t2-4rVa;+} zzPr22T}L{Hh`(fvy+q=9e~RT9bsVm4cozC;vr-j^a8#v$+;`mu-{lS0^|>U@Y}d8z z-)-^2q$_yb53IWP3MH(+^6FOLa}NO&HOvnQVABUVoO4IKY0k&(On>Ar^Kk*#3|d~` zc&{~0Zy~t3Ux1Ase@Crh(^A^gC0q$oNtV#hx zZtzJ3dG^~3-~lt(p>20<`;cY7NdW6Duk$Vl@CpXOyN=hYqnCJpA1YX_$}VvYz9FU+ zgs+0xCr!lJQ3iO#er5{}=0__%Yj^YO#`V|fA(vkJ~t?^f*3 zcDLJYAIhI$cu2*!U{77a9=uq{V}5L&o}O0WFj2rTnqp;0;uyJc{uc~p+6j|0S^u^!0;>JUHc*KL5DshTzw4@K#l*%InV)L zg8fs-_5>Yzg)=~L8!7G~2&(|q{$q9v@@SAm$O=*Zge0hW0?UWV{2zJlR`7Wua*(jj z9ph0le~6TTNdg;8a6nih0YLmI2EYV&=d||S6cCALY%t&^v-q&;|4KD0S`JX{@5RYp ztOV@CEgq@;KX?#g%z@MSi~Tr;&*tM};yK_zX#n;I3cw=%V}CL}CO*kf18Or!Boc{4 zB0XEJy8mxkt-SwlS*^VPZ%M78|8F_5_PzeUfA(tn|CS`Y-~T7g@LHay@Bi~WyuEE% z#A*MZTw+~)|KB8W6}s#HlS{0t@BcGa2&n7-6GMUiKh+n}Qd)KY-$dz6HakI>2@G|D~f55Z=I;D$hyRUq}BR ze-vvp`Uij>0M4J2PQRA!wG`^*LakEGxzYfQ^gF=JJh5V85r3)+3f4+ z{~MpVKmPsUo{cr5kkeAA}ssI2007*qoM6N<$f+gQu9RL6T diff --git a/icons/clothing/jumpsuits/jumpsuit_hos_alt.dmi b/icons/clothing/jumpsuits/jumpsuit_hos_alt.dmi index 9057fbea3e384c71d7079692ea7c2e6e17100da7..a7ee171acbb5115a82b3ec28b3234c577f79803a 100644 GIT binary patch literal 1566 zcmV+(2I2XMP)^4FfckgI>5ld?+5+300001 zbW%=J06^y0W&i*HwR%)obVOxyV{&P5bZKvH004NLrIO7G!Y~ko&&gAS_N@5Rs~2gJ z9_%ZWNVX=BW?_@I`1S^S5EZ09w;7mk*nv&Oxww>-$gd^ufxJN{P9odxI2()#I-28w zGY#gh!)Sbv0isL>B&!n6lp!Dep0kEz3#0x_ZM+5O!B0#RS_?C)r$V}Gr9-2{4b>yU z80w+!oN18SH=NCfe>W~E`ChT&kQH6F*3vB^=`WdzqRL;-_5`y;#%GhLiBSLm1lvhO zK~#90?OcJP(l88Mm$v8_{{QEiblpVlrQ0$d?`aO0%7vu4cEG#7ISdYm!{KoJD+psK zM>@&B8x%v}F@_M^Bkb{3nDwI&M-Cce01b3_BX;Q*6#Y0LrW8_&?GVZvpW7*JiSg|Q zhp6(BzUtFV-{UzVQ78ip{I_Pn#)I*HXNG|~Pm+ zjWqH2CeVS-^Zal6v{r!dV~lcd@+C$hvP7Uow(?+rd|U3vd16&JeOT>3Lkb_WAh!6e zOUVG=WOV+z-)|RMz0@+IYfy;4H*4>YyBc2*rneBID@u{Y4i7u z^@nnr>(;3nVE6ZJ_00+F{{96GC?6x;0K29~WBs(eJW~bW~t=KB2&iUrCJ&$0lN0!3iWy|&fAW`ja+;FTLB z7un<57S?O+`H$M5IGg{YW&pB7XNv4I@If0CXY>075DtgK;cz${4u`|x_>V#AFMof2 zR9CL^A2Xcx_qQtL`1^A^>h4MXc*t+BKVIbT*Qka{wI^!_Wp^M(J|KJ8_+lzWdvNAr4zh7%KRO%{s6>R=~MN6fgat?>X;cz${4u`|xaC~W8WI?|T7g^9J zi_2kWX|zjnkp+DUN5n(BB$rvxXK+M3v`ccG1$`Vx#KXHJS6R>}a6~*M_96@V433Bg zW3RHHPvMAoDE2Z7`UH-M2V+0Xf^H4!fOt6ejTZC~@!lyk#u4${>vufkCk!|+m-?To Qz5oCK07*qoM6N<$f^rJ${{R30 literal 973 zcmV;;12X)HP)^4FfckgI>5ld$ww9@00001bW%=J06^y0W&i*H zn0i!LbVOxyV{&P5bZKvH004NLQ&wi?^C?`dUi!&v&s2IpM1ti$90=c~4ZP)W5cM&J!8-@&XFYd023YyH??O;RBaYBb-fE-OmaW|Ue z0wS76aj=H`73745OmvWd=;>Y|z&qV2?s$L?XL10}K$)wN03FM8mfs6qvqUEwu`IaK zI?Q>NQM|W-0)+Q8xPm1eDmkD_z-NFTj?k7^K+IpOT)=T@pp(#X3x05r^Gv|?umdX8 zT7jpf>3RhVPBY*KzBtd-I3f@Bj@=gf$78C?ggdBW`qK~kiORw_VqnZh{W57lsF4&MNP<@L9v@h_p z)d?tHgcUq{mO2Oi-*&)!#wvK0;FSUv78bt`)?~goe4aOh`lVYFeqnSgei zU4lr$w3&eHH#>qz0=JpKijZcPn4SpmJmZsAt@x<`%^JzEm(b}?QjI6x)YygYr>%!$ zv?Gg$IsqC;W0Og|n#cYzl5t#n2BFO>SbW|~A4eAn(8+zwjHpsTnS1d2m2XCuIB@uG zH!`A&95~<8H{Xn?3ZeNiI;oP05nYDtPs+6!Sy)(D{2$;KwRiff@fMlzBvrE=Ki7-N zxp@G3d@*h9aY@mO&&>nSBRy0v(a*30m(K&xBbEDSJG=+%z~%D*^hj9zxHQLsq63%D z11L-9kH#Tk2QHrnP`0yJgt*(G4qQGD!0huc>Z>6DI&k?sfU-TADx=?m4qQGDpsbUX vpL#5FQ2m=5B0B!b@Z;>G*MT?7z zT9&(jfPn1m>{C-yH#ax<`1tGV>%hRk>FMdk#l<>0I%Z~OM@L6qUS4{7ddSAcV`5@> zczCfFD zZ*Bkpc$}q@%?iRW5QNXkQ-t=c_|vNwX^|f6E0jpKCXi-fleYNw273?{q(8SAm~YsD zO~tvml$FS@CGUZ}K_^Zk+wM3Uj0!rM&Y5`WH=As_vovxZ~~ zqy9{7yanjNPfQb93p1;yLb_|EL!-nE)g!_f>Y?tOX^`4CoXv-SH!dmpUa{hk6%3sg+1hYiOXOpOjQ2+o1?ny*JRCt{2T#tL&HW0Ohrf4V~_2@R5v?PI1 z((M2L|8^%Ej|4p#`+v+w^6egt)9T6h?)1Zy=g(A?LZMJ76b+1>(Q#(YNdDR|vzc+f zIQ}(?zdDTfH^!M8@3RToBi>#n0qf}K@Cq;{gg{3?d(Ro(@UL7KE}-QvQ$U(wMV9*^|x96zXXwfFK;8~m;MarDJRQ|*rXXg%`ox75$i&ZZxURl z1edUYGS3;%5`Q;yG=m+Vhqt`EX^AZ( zx=0=PJk<`6qX9bICoRu=Aj==Z$2uCc3;TH6@%aM!cuJ72kj@oWfMZ}j5*z3zf&zMZ z+8=zW9m!WT!&CsxFi4R21USKzAnlG~0cD;p;PfgLP=Dg9ZiYaDU;g-$Uw?f8e6=E2 zK8)l)5iB1@@`o8lBiyY3RKT?n+jm-6z*n9^|MeXgK<{B8_cq+}F2q#~?|BAj_1HoI zo^p@QYXO(S$1lL80!mk**c{#|(iOVrGG5{p3WY+UP$(218>=&JT^RVEL7~4d)~ECD z4AG?yB!6MKE3)CE+Dzawmbqn0O&rW)Zb5G z&(N=suhIm-dxUpcDS*`9m+Ch&^I-6eUb@0PbRAD2_4lRv)dQUw`!*5xc>wW+{=QV7 zBYzanZzI6-#s0ofpCddL&rcB^;rViZU#8CzkA7XWPUG4?;w36}mu31Xz!P|vJan*6 zmn}e|p8~97IY3-rwg8EK3h)%mYcQ5(K>e7=Uk+ zLhsOS`5842^5Y6@>aYdR*ogJp$E4tcaCVn&RO2N`1<)*)_5jhi0I@zV!8yCfuz$h? zXx^p{9&UlO2|V6|Vtvc@cQF7>-gb-K=c@Wa!&@$ZCh5n;^f`bn`1k2tI&4t@Dqy=W zT`M=6{T3D=*N=V|tGL_Y0DfBxK-szd9lVgZF7a(#tDp-?Ck3WY+UP$(218>9XG7G{=? zuiN-A#Ww^N14;e;R$}(^M5L+dr@Vr4Afdm1(C{@^@an6~jAz*zet+88px}i-LVy1t z;TNuQi{o!|%e9RH2dZlrNa*h$G(vg|BD^Z#v~3icuT#WDd2wv9qhAep~^z{|^vp`YHiQJ5@{LZMJ76bgkxp-?Ck6Jjz8`bwD0f*vK#hcl&f z{(owj%7Pw&A%mCm|5N)^7G?Ap3>mzf|KGGvWI>O>kio-!C$pf3W60nY`c7s+566(f zgMBBnpvPdy;Gw>gSs*7&3Uc?-iZnA%l0#fyNjzcxurrj`1%Eg?i(( Sd5*0B00000001>2m=5B0K5^GACVy=MS6OA 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 UKH}*HM*si-07*qoM6N<$f{)*3S^xk5 delta 1686 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 D=qFd8 delta 1635 zcmV-p2AuiP4zUd(iBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^GACVy`A>ZHM zR8&+qH#dNQfNN`Ojg5`Kz`%HTc)Pi|iin7MdU}yx6$Wx~amdETk%ldQ^q8AK00001 zbW%=J06^y0W&i*HsCrabbVOxyV{&P5bZKvH004NLrIE`DgD?<9*U47|U0eEa+f7l# zMg4`4lCcTI3{0Y-f8S7{-4$wg_rRQc7gLH$+x3HJu03CXf<-URqTcN}OIAmd;dJE8 zfW4czLWn9tjzvOpy5LNITMC&EoQk8A({1tCd9K~#90?V90Q+d2$} z<1pJWbBx2*jGc2jpy|p+cmLNn$?0HiBs*zH!Vi5sNw-K!KJhKjP=J~;{wNB-y$~*@9c4I-8<`Q2FbANSpb;XV_ z8jLZC8NlSrA~8RzDEaX*Rs-5cI5Y{UkY8OX%zz4^Y*||CEWWTAK<A(rTlL0J}Z_YRcXM-ridK=`#oT`IAMDa}jh05bQ8JID*;`_7)J>bsA8ALz?Uqhq?y9x(?J5gm;Bd zJLBpQ;{UpKOwh#yyY|)x9`lf%;*i({%$Mt%yXx-d`U|s)fe!$Ikcn@=4kBj&hR)71HuC10bv*R73>n+2z~wcKm7UsD|df9 ztsw{p2(j0HFOF0IP{0%S{yL5@KSFRUE(SB?TH6`^yxL|$BbZq+<_9?P|gm3t5xRqc@L3DBoc{4 zqW7v?{c&mK>W@n+SASeux%%Vc3P<%v?yrg^byR;`8iv+u{gHDxd7WFY^+(R(2iP@{%eNKSU{zehl4RUAwFpKj)|~21mVA_Qf+PwXRiJjJjOPv zq`yRe0Klz{;#TnnuEQo4xG%hb54Jc6!~o{%kHI6KGbRn_*xE;E&}aic#UVO0%=>fo zN0=OIV1(K4DZ(}u$=M}{fUpWuYY@L;NdYG7k8$+`tWL2{NmOE=!bQ4aCIA85#wMPz zT=gtq`78+tqt`Tib*m`8!|kGf# z@_@EU0>a(hZpZV1#}3}kdF1MkX1m>*;t9@Aq#gGN2w?dL2&7zUlk_#wi^2|B=6vsjYYnS?tuRbaE|^z z_^5eyg?s+H8=AUC0?yI@7d!IZaX&tPb&Uj^rT-5b-rY&NJ9X_$z&GgsGx77vWUrkE zIKKbS?c;8{cbRKc^jZ4<-2NBp1h9LJiatyKpWDavb^_SFww(6+y@4ZpO(YVDL?V$$ zBoc{cRlgF~a_U*)%0EQch|`}QnxWuoiYgQ-se`zN39?N{Q;gr~C{l056%v&5APPiHwK zdCs?Ii7PE8%OT0LzHd_EVzL~PJn#D!B`zk*A<0i%3uLk!lDyOcMIw<%Boc{4B9TZW h5{X12k!T+M2HNF!1|Ry=oB#j{002ovPDHLkV1i9|BIW=9 diff --git a/icons/clothing/jumpsuits/jumpsuit_robotics.dmi b/icons/clothing/jumpsuits/jumpsuit_robotics.dmi index e1083edf339eccd503bcc22482ffb76d8c0dc52a..ff89c3e05de1c1a5d678e9331d99d1e89ef5b8a0 100644 GIT binary patch delta 1810 zcmV+t2krQ%4WSMtiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%QU6Cav ze~TmlFfcGZJv}ioF)uGKD=RB1Dk>Kj7aSZMIyyQmEG!)z9UmVbCnqN~G&C6*85$ZI zGcz+nLPEg6z+KDm>;M1&0d!JMQvg8b*k%9#0JVBlSad{Xb7OL8aCB*JZU6vyoTZY@ z3c@fDgwM%Sg!ZiX)2kP0ksj&Y63&z%AN`)QhGYw){!DGW1?a&~ zOcPoQGpnaUx@)CFqr?r>Bf=Q!q3)b%klHt#&4+(CE-Cq5vEq;wUAETJEh6bJf0>G+ z%3sg+1hYiOXOpOjQ2+o1u}MThRCt{2oC{mqIt+#rj8YW0F0kyBZRG#|%_Co0cvi_y ztMruZ=pAHhs;!%`V7}KkB`}mU1ftQi7M_#{C z0f0*I?UfCGYkP-fg~j{8fAemFDXsv|YyT491w!bB3EbEo6G$s8C*bKE@Go)#bPX8j zTb#gc?Q{s`6%rHJO>_yJgiBD2;OPQ@!3+LxZpX4hVghcO{4_Z+fqR2xg~SBD1B?LQ zzit9$g~SB>M4#j){)5Cif$0U6SZAs;^=L#wRnU-mjwXtKugI=m{0~v%=XTcX`>Oca zfrB>yFIT_=4RE}JfAN#P&&_ZAr0?^G5dAQ@B)@AG`< z`$ByBZpSYJ*$Mcl-$RfckdcN+$KZ#)&-0=03;V~pHRG3o9I0y%HG0v3ci}jWn}AZ^ zPi_~)7gr$NA>QPxRJ_i;od%wx)%UgW^UC~mUUuN!&(lC=e}AREuZ`c~FG`NR2A*aJ zNZJ3A5>V><+W1)-tL&dW$X7A7zORg*Jjl1XJirTgfo#<3`?~ni4)9)g@DBWMf+V9_ zUDm~qc6@JD;JvZ}YJFc9KiWb5piv_D+pd5nezMmStPjxZ`?~mDR}<$KjL_@*y7-1+ z7=~dOhG7_nfAPNsfBXB7i{Ef?GT%xUP{&80L9UbR>3zheuu;=p>N{%VC*@b}p<$G6 zW1Cje&oPHV(H@F#!LE+)^6nn^9uJ0)9tM>i(E9-bN-Zb=B(t~>`uHxkVAGRcyd9E* z5F~XnM}S(R8j=Gs0cHHScY4fAYT~7*kf3r7g;c>xe*+;NBhm!)@#BEhppY}f`UI0z zY%#^7*vsdjIzE;Ti`WB+?UQMen|NtNz#up2$mqr0_3_i=fE9Thy_>p50`e&wiKp=m z;}?BjJOs$za1dO*g%z7%avxb6pLWd-#H&PUU{pM~+WKT4@>Nh9A5RSm@hVZZFS$+E zM(E=ke}-WghG7_nVHn2W3(jeK?`d2OW>vEKtD_2i|2T@NQhGJ3D~H=HIiI&T()Y_K zrb_v#8*EgrNfNi`S^A&+wEF(h3sWV`Z%LI~3eNM^d%vB9wN&c+#R*fT_+ETVs@!5c zrst%j87lStGKQ&At8&Z1nf%CJbozdQt5TzKe~TG#-qIfISz{gV@>N{z}bWtg@; z`0Z3lK%?)MAWW5-m0QRV<~e>zew6xt3BpvVS-GVQ8F6|leg7DPsZy(QYoXKkk8o9L zRL(FA!!QiPFbu;m{%lr~pzp>?67-e9qo%*Gcv6>SB?{=4^6o-30FMY#t8x6HF$p8QV07*qoM6N<$g3;@9 ANdN!< delta 1688 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 diff --git a/icons/clothing/jumpsuits/jumpsuit_sterile.dmi b/icons/clothing/jumpsuits/jumpsuit_sterile.dmi index 6eea5cbe755ca300a8b07cc32b66357d3b78f419..9b06e63d337625845f58247c65282c0eb6dca402 100644 GIT binary patch delta 1516 zcmVc<=Gb&;T^UDg8=yp#&QKItesOYo>op2FAGw&VJ%tnlEP_ z=k_bi!OzMBZ%xZ{2?P^A>=d)SjrA#Fg;MeD9hKJ6Pwex{r|NDLzfmV1;v=Eb?jE229aVlyrwYU(QO8^Rww=WRhZnZX*H__q|lKz89%e4L-HDx6?daZiB`-qQBQEmj5YA$8=_ zR8t^_1vO^YK|0p~ zCCok3LF(^I^-)Bd>B-xul=KP$cQfnQ={0(K~8DTNXIeUUz)EN2f7 z0AIgx0ls|&czBqV$pajJ;_oNSW8zzXKWQ$@^a+0}4<&5`ehKHeJ4*1$4)(;~Pi~vI7ByfuE!-NmiH&+$ipp9x>kLUrjk9g{pc=Qh8D@eF`V zp!N4zzVY`Ned^PxU+@V;*VyJOKn38=8KwSy410lo!TBn60G|usa{;9OzErE74ynH{)h`}#WazqysLvx4U+C{k^(jJjd=r5kFZTC^`V`?QJ3dBuV#mw< zeVIN|fM=TzV4ts>fJ8qASciOou)b~r68#w9Ipp_X$gP0b z-VtpjyhYMiq z(On5_xHGt-+++ue_2WAvp)9%g6Sg>%j(PuL0&MCa+&f0}B2ul*IqWF&G%_o41^!;l36u@Tu`#2UaTP^@5u-)@Ji1yHa%O)V#53mbG*zNcL zu+1lchYWVmXgnyC1dD|ewK)?r*`TIu^6DNQB;*=uQ zHV9pTME-s&;!xw&F;S{*5IO?M{QVm45Z@L%xQ@0#=n5qB_m3KX6J8~7-Zltbfn@&v zQ6p~CR|%ZA4Z>)FayT3g27fx+MhmV`C=?2XLZMJ76bi+yF`5N^BaCK24-%)#h0-bi zKemizK@UKm;-&om*glp8Jp^QZikI^L>-Lc>=mF?cJihN}7Ic5~DPE@UXclyT^eGKL{>pPkSJpg@*$M*eCoMU!Umlu!kdqd~APw{S9XdZovrxv~96#oDlvwBMr S&^!7700000AwraUuU>bl$9q;(Q|soU)Te{TRK zdrnMHks!~>8_tdL%A;@qNU43NCs&ohU@#aA4IE79H~}}1zck!r;`}e3e+}X<4u?2( z-c1p+3BnN%=ScusA&GY`gg{4uM&t~q{3|zw3uyWC6wofMn+kswIPWKv{lxn`U(W*N z_AAaY%<2pe?!Ze0M3+8dibWn$f2!1>Tzt6V)_Oi%W%V6$i$Bcgb0_bih8Oa8Kn((M ziOW3Ho|2pXHudOzeX79xHGcFTG0$^+PS8<@OPeh5c^V>>=r~G#LYc2;b)fz({M?5+ zvjv#{gv8=imj8b@K}o-phsgP*KmB>|^~_;F$16Om{mT|7K6qk%$ni~r%aq_!ETGH- zH#j;s7gn&yLx74eGDkgj>2Epyn%L`*<5PaHTvCF|rF0kQ;DNU{ZLwv{Un51HuZ*Ta zo*Hy|owPh(16jVE5v;lK+8bnuiQ-66d%>;Qkykoib#pr0rd(8<&F!MECh zd_^lv1<(o$2@;aapWf}el?gFkyaKd)pilr(?$M(aa4x+6 z0(>fXX6^JGX@hd_GON$@}A4e_yH3{HzWxM0tswi!`C0E#6{_`#NFONxG-r1e zu#uj@RrRKLqFO(_BNFRcdOu-Hr}AUozk~prCW!Qo5xG*t%4`X~oU@?%^-)|)*KTkxOnttjlCE{ey@njTeuJa$|$g5lH9nH}FsCZLufcF*XQYfpq@ngx9!jAlU(66eD!rE~s& z8X3!i9)Ld0%lZFld@Kuk2>N3*FX#U^<0Dzn1JI{=^4!rZ=>F)_yu#ekEa?8|(>!tR zXcqJk^l6?ncQgxn0Qxjfoco_R$6`{iZ=O8&g3fWD=3TPUGWs;nEPBH+{sH8NdQ^&5 R2m=5B0B!b@Z;>G>Jb-|J z-{0RU?l>Ea3ObtOfin%}uES`2kO87h1|+Kzf6kO4AN`)QhGYw){!DGW1?a&~ zOcPoQGpnaUx@)CFqr?r>Bf=Q!q3)b%klHt#&4+(CE-Cq5vEq;wUAETJEh6bJnTn#y zU(fagvqZ*clcRx7{Vx3ZndGmcUMfj}S-bkI$6c6Qb@dSd+4fco^Ovrn3;uogc# zpfad1Z70R&C;+y_BfuC##;pUK+jIP7C&bynrM{aUS~6~(fztkfm&q4s`#4p< zZoKt{^(n?R_D5f6>`-osc1`14aQG`rVIB7Pe-iskbhwX`^og!akCR(a`875SQh|G zhb58%3URDILU|w$1Pm+0xHSQy!Pu-qEU--lwxob^95OiTttD5mk7r`qL={5>0kBok ze+&db98bcKPQhV3)fd|q3T)d*oC1|N2*3lRZGFrOQ2TgJ0G!(~w!wxr#`M2o92*!? z1BdZM|M~LjdU1Vq`I!(>6PYU=7 zG3UO%X8{J^t>_gn{>Gd4yaMXSJ=vBxD*!% z1OkCTAP{_P=%zl0cAuI4K0AMR3!_n`396y*Z*cv6ZvM2tb5`fw_cXz2i~f9ee*)Xz zXXZ}?&RF9~V@X--VS>vN%;4{{^6v<4Z=L)0og(=D&EbqJK|JvHho1`Lfxn;q)To=q zTk6a#xg;CJgxvvfBr=9;L8O5 z;kW`g`4hpTFCT-xv;u5@pO+sAZf+`f4@xum{ys0iKp+qZ1OkCTAP@)y|69aYzdv05 z3PB$x?_e;&&JTg~LlMMo@0x%meVcSy+>xC>My<7n7ZF~?bR*JT69mg034JGAcex22 z-2BmFZmS#OA*Z-ny9CO5e_O)13n5Z}FaY(3;D9JEfSo^j+#es4DiQ?JJB%v~x=0^F zF-=$z&)Bf@N8LRpMc##6r<-*2AqWCsl}qOUJ|ad6VCTmbjOZSd3KK~4HcfC#qJbzN zEFFCgvhzo@zl#K*ezl_AXQh5Xd&>e~k$xO4e@{Tf)4s4-Q3N1hf3+$9JF)lb;|%*OE=2yZivUPBZR$^rr{fSn(o zbOZuKo*Ge}Xa*)8F6ca0^s$@Ks>eVcG@%8v=p6K*aR-_bJ@(pu+E$-{zJZ zn*=0UEJz}zzrWA1d)Vqgz;J95y025DiFp40K8a1m9z02t8=Hh05zF82lceYMY;|lB zDnvYgzeCuj8$sJp8JmO(5!2t_=lB=#O2BYz5-LPIf4|R>e-6`E0)}IgP$A;^`+ID+ zTMMu1*d)wGBoGJ$0)apv5C{YU!Hk&Af<6&uv!Ev>$ITm4=luUPGM5EC0b`n%^Z(QM zTo&{cjA>rZ|L?|UvY;nmO!MfuvsuvNF{XKixwBc&<1war$;3fV8|0tYMGGUcb00000NkvXXu0mjf D=qFd8 delta 1635 zcmV-p2AuiP4zUd(iBL{Q4GJ0x0000DNk~Le0001>0001>2m=5B0K5^GACVy`A>ZHM zR8&+qH#dNQfNN`Ojg5`Kz`%HTc)Pi|iin7MdU}yx6$Wx~amdETk%ldQ^q8AK00001 zbW%=J06^y0W&i*HsCrabbVOxyV{&P5bZKvH004NLrIE`DgD?<9*U47|U0eEa+f7l# zMg4`4lCcTI3{0Y-f8S7{-4$wg_rRQc7gLH$+x3HJu03CXf<-URqTcN}OIAmd;dJE8 zfW4czLWn9tjzvOpy5LNITMC&EoQk8A({1tCd9K~#90?V90Q+d2$} z<1pJWbBx2*jGc2jpy|p+cmLNn$?0HiBs*zH!Vi5sNw-K!KJhKjP=J~;{wNB-y$~*@9c4I-8<`Q2FbANSpb;XV_ z8jLZC8NlSrA~8RzDEaX*Rs-5cI5Y{UkY8OX%zz4^Y*||CEWWTAK<A(rTlL0J}Z_YRcXM-ridK=`#oT`IAMDa}jh05bQ8JID*;`_7)J>bsA8ALz?Uqhq?y9x(?J5gm;Bd zJLBpQ;{UpKOwh#yyY|)x9`lf%;*i({%$Mt%yXx-d`U|s)fe!$Ikcn@=4kBj&hR)71HuC10bv*R73>n+2z~wcKm7UsD|df9 ztsw{p2(j0HFOF0IP{0%S{yL5@KSFRUE(SB?TH6`^yxL|$BbZq+<_9?P|gm3t5xRqc@L3DBoc{4 zqW7v?{c&mK>W@n+SASeux%%Vc3P<%v?yrg^byR;`8iv+u{gHDxd7WFY^+(R(2iP@{%eNKSU{zehl4RUAwFpKj)|~21mVA_Qf+PwXRiJjJjOPv zq`yRe0Klz{;#TnnuEQo4xG%hb54Jc6!~o{%kHI6KGbRn_*xE;E&}aic#UVO0%=>fo zN0=OIV1(K4DZ(}u$=M}{fUpWuYY@L;NdYG7k8$+`tWL2{NmOE=!bQ4aCIA85#wMPz zT=gtq`78+tqt`Tib*m`8!|kGf# z@_@EU0>a(hZpZV1#}3}kdF1MkX1m>*;t9@Aq#gGN2w?dL2&7zUlk_#wi^2|B=6vsjYYnS?tuRbaE|^z z_^5eyg?s+H8=AUC0?yI@7d!IZaX&tPb&Uj^rT-5b-rY&NJ9X_$z&GgsGx77vWUrkE zIKKbS?c;8{cbRKc^jZ4<-2NBp1h9LJiatyKpWDavb^_SFww(6+y@4ZpO(YVDL?V$$ zBoc{cRlgF~a_U*)%0EQch|`}QnxWuoiYgQ-se`zN39?N{Q;gr~C{l056%v&5APPiHwK zdCs?Ii7PE8%OT0LzHd_EVzL~PJn#D!B`zk*A<0i%3uLk!lDyOcMIw<%Boc{4B9TZW h5{X12k!T+M2HNF!1|Ry=oB#j{002ovPDHLkV1i9|BIW=9 diff --git a/icons/clothing/jumpsuits/jumpsuit_warden.dmi b/icons/clothing/jumpsuits/jumpsuit_warden.dmi index 8eea4464c55557eb29470466cf0f02a8849f8ddb..44d32edbfffcf932198c1d6a2cf16dfaf7fdc06b 100644 GIT binary patch delta 1828 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 N002ovPDHLkV1gE$5f1+zDql7X zCMG6V_Y;Q#=FT~iU1 zE`|C400P-bL_t(|ob8x_ZmTd1MM)rOX$vcK-T!~;Y-cbic0!4o0>^(y!18 z|2%=MkkERb0Iqk?!b5q-RaoJh9{?i|SSVp#Wjznztbq<5>Kp5r1}ppl0DO)B0HB5h zP?$*rc7s!Z#TLnj>W)sCKY|~CQUJiah#Ii;1~&cco5c|XpH6>(^+y1+6~N2@7Hi0N z1mHNI031A|&O`vl0vmnfQ1b5x-u`eai@y_aJ${D~fP_Ct@(TiR62Jj|Wsb)qj0b+f z=nDn>AjuDljzeCtAv*;gcYH|^5@XqJ+3I0WZ!IuDP@@vV54mCiE zc5xUaHGmDmDad~S&>Ix%5bd8-ji(zak@6K_Kfs9^M4p1UA0D(F0CaywZqk$=9s}9^ z2a3|ER4SE9^lkJ@FU3UXux=Umi=nn+YY|^b6rk+C(&n^vi!c&-hWB!N6f<@{vw)MTF*(Z!j|QzjTUgA~dDkPbTH& zdX<1(!Z%tepHWu9b?< z)_evn*5u@WX>E5WEsIar2q`xw|BGu^MQ9=A=HxejdF_q}os<8c_^x1DH3MGX6{u7y ll}e>jsZ=VJN~Kce=^I&nFT{a!Du)07002ovPDHLkV1k?6oWuYC From 251cb8d1400f3e3704cc937cb911b0e9aa862720 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Feb 2025 16:41:24 -0500 Subject: [PATCH 105/512] Repath RD alt suit to costume --- code/modules/clothing/costumes/rank.dm | 14 ++++++++++++++ code/modules/clothing/jumpsuits/job.dm | 8 -------- code/modules/fabrication/designs/textile/job.dm | 2 +- tools/map_migrations/4898_jumpsuits_costumes.txt | 4 ++++ 4 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 tools/map_migrations/4898_jumpsuits_costumes.txt diff --git a/code/modules/clothing/costumes/rank.dm b/code/modules/clothing/costumes/rank.dm index 3d4030b7b1e6..19c9cb2498c1 100644 --- a/code/modules/clothing/costumes/rank.dm +++ b/code/modules/clothing/costumes/rank.dm @@ -38,3 +38,17 @@ /decl/material/solid/metal/steel = MATTER_AMOUNT_TRACE ) +/obj/item/clothing/costume/research_director_suit + desc = "A dress suit and slacks stained with hard work and dedication to science. Perhaps other things as well, but mostly hard work and dedication." + name = "head researcher uniform" + icon = 'icons/clothing/uniform_rd_alt.dmi' + armor = list( + ARMOR_BIO = ARMOR_BIO_MINOR + ) + +// Copied from jumpsuits, with the rolled-down modifier removed. +/obj/item/clothing/costume/research_director_suit/get_assumed_clothing_state_modifiers() + var/static/list/expected_state_modifiers = list( + GET_DECL(/decl/clothing_state_modifier/rolled_sleeves) + ) + return expected_state_modifiers diff --git a/code/modules/clothing/jumpsuits/job.dm b/code/modules/clothing/jumpsuits/job.dm index 90eb1ae24bbe..2d3e59b8412a 100644 --- a/code/modules/clothing/jumpsuits/job.dm +++ b/code/modules/clothing/jumpsuits/job.dm @@ -97,14 +97,6 @@ ARMOR_BIO = ARMOR_BIO_MINOR ) -/obj/item/clothing/jumpsuit/research_director/rdalt - desc = "A dress suit and slacks stained with hard work and dedication to science. Perhaps other things as well, but mostly hard work and dedication." - name = "head researcher uniform" - icon = 'icons/clothing/uniform_rd_alt.dmi' - armor = list( - ARMOR_BIO = ARMOR_BIO_MINOR - ) - /obj/item/clothing/jumpsuit/chemist desc = "It's made of a special fiber that gives special protection against biohazards. It has a chemist rank stripe on it." name = "pharmacist's jumpsuit" diff --git a/code/modules/fabrication/designs/textile/job.dm b/code/modules/fabrication/designs/textile/job.dm index e0f376636b25..39ba3626a2ed 100644 --- a/code/modules/fabrication/designs/textile/job.dm +++ b/code/modules/fabrication/designs/textile/job.dm @@ -25,7 +25,7 @@ path = /obj/item/clothing/jumpsuit/research_director /datum/fabricator_recipe/textiles/job/medical/rdalt - path = /obj/item/clothing/jumpsuit/research_director/rdalt + path = /obj/item/clothing/costume/research_director_suit /datum/fabricator_recipe/textiles/job/medical/dress_rd path = /obj/item/clothing/skirt/research_director diff --git a/tools/map_migrations/4898_jumpsuits_costumes.txt b/tools/map_migrations/4898_jumpsuits_costumes.txt new file mode 100644 index 000000000000..15248ad7d2bd --- /dev/null +++ b/tools/map_migrations/4898_jumpsuits_costumes.txt @@ -0,0 +1,4 @@ +# Converts a number of jumpsuits to costumes +# because they shouldn't have the full suite of jumpsuit modifiers +# (e.g. can't be rolled down, no sleeves to roll up, etc) +/obj/item/clothing/jumpsuit/research_director/rdalt : /obj/item/clothing/costume/research_director_suit{@OLD} \ No newline at end of file From 3c8ddffd80cb81d1b2162f5b80fc78c3f41e8710 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Feb 2025 16:41:48 -0500 Subject: [PATCH 106/512] Fix clothing unit test marking state false positives --- code/modules/clothing/suits/labcoat.dm | 2 ++ code/unit_tests/clothing.dm | 10 ++++++---- maps/away/slavers/slavers_base.dm | 4 ++++ mods/content/psionics/items/foundation_labcoat.dm | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index 696d5a4f4d76..c135777a93b5 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -36,6 +36,7 @@ name = "chief medical officer labcoat" desc = "A labcoat with command blue highlights." icon = 'icons/clothing/suits/labcoat/cmo.dmi' + markings_state_modifier = null /obj/item/clothing/suit/toggle/labcoat/mad name = "The Mad's labcoat" @@ -57,6 +58,7 @@ /obj/item/clothing/suit/toggle/labcoat/blue name = "blue-edged labcoat" icon = 'icons/clothing/suits/labcoat/blue_edge.dmi' + markings_state_modifier = null /obj/item/clothing/suit/toggle/labcoat/coat name = "coat" diff --git a/code/unit_tests/clothing.dm b/code/unit_tests/clothing.dm index bf36a09222b1..4bf9ea0260d8 100644 --- a/code/unit_tests/clothing.dm +++ b/code/unit_tests/clothing.dm @@ -94,9 +94,11 @@ generated_tokens += "[gen_token][token]" // God help unit test time if people start putting markings on flannel shirts. - if(clothes.markings_state_modifier && clothes.markings_color) + if(clothes.markings_state_modifier) + // Check even if markings_color is null, because subtypes may use the icon and we don't want to mark it as extraneous. for(var/token in generated_tokens) generated_tokens += "[token][clothes.markings_state_modifier]" + generated_tokens += clothes.markings_state_modifier // Keep track of which states we've looked for or otherwise evaluated for later state checking. var/list/check_states = icon_states(clothes.icon) @@ -138,11 +140,11 @@ if(modifier.applies_icon_state_modifier) // This is working on the assumption that bodytypes all end in " body". // If that changes this will need a better method. - var/regex/is_alt_bodytype_state = regex("^\[A-Za-z \]+ body-[modifier.icon_state_modifier]$") + var/regex/is_alt_bodytype_state = regex("^\[A-Za-z \]+ body-") for(var/check_state in check_states) - if(is_alt_bodytype_state.Find(check_state)) - continue if(findtext(check_state, modifier.icon_state_modifier)) + if(is_alt_bodytype_state.Find(check_state)) + continue extraneous_states |= check_state for(var/extraneous_state in extraneous_states) diff --git a/maps/away/slavers/slavers_base.dm b/maps/away/slavers/slavers_base.dm index 697a24856d31..ea9e39a60cbd 100644 --- a/maps/away/slavers/slavers_base.dm +++ b/maps/away/slavers/slavers_base.dm @@ -183,3 +183,7 @@ ARMOR_LASER = ARMOR_LASER_MINOR, ARMOR_ENERGY = ARMOR_ENERGY_MINOR ) + +// Disable the modifiers we don't have rather than adding new sprites, this item and away site is removed on dev anyway. +/obj/item/clothing/jumpsuit/abolitionist/get_assumed_clothing_state_modifiers() + return null \ No newline at end of file diff --git a/mods/content/psionics/items/foundation_labcoat.dm b/mods/content/psionics/items/foundation_labcoat.dm index 363d4c81a2cd..c4d1772566cc 100644 --- a/mods/content/psionics/items/foundation_labcoat.dm +++ b/mods/content/psionics/items/foundation_labcoat.dm @@ -3,3 +3,4 @@ name = "\improper Foundation labcoat" desc = "A medical labcoat with a Cuchulain Foundation crest stencilled on the back." icon = 'mods/content/psionics/icons/foundation_labcoat.dmi' + markings_state_modifier = null From 464db40da7e54f224426867d11e955d9f0a42be2 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Feb 2025 16:42:21 -0500 Subject: [PATCH 107/512] Add kitbashed modifier world states for some corporate security jumpsuits --- .../icons/clothing/under/hos_corporate.dmi | Bin 1339 -> 1773 bytes .../icons/clothing/under/sec_corporate.dmi | Bin 1359 -> 1807 bytes .../icons/clothing/under/warden_corporate.dmi | Bin 1339 -> 1545 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/under/hos_corporate.dmi b/mods/content/corporate/icons/clothing/under/hos_corporate.dmi index 053afd3fa604981c770ccc5147784f3a05a9ae75..0c2ab5200ea674dff8c65f2d62c5228816c9201f 100644 GIT binary patch delta 1734 zcmV;%208h=3hfOgiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%Qgpnm5 z7%3?!R3RZFBO@UpAr=-EK0ZE0LlPMo8IffneHa09QEHN=LLPA0$BqYGV!1tYJcmMzZ0d!JMQvg8b*k%9#0JVBlSad{X zb7OL8aCB*JZU6vyoTZY@3c@fDgwM%Sg!ZiX)2kP0ksj&Y63&z% zAN`)QhGYw){!DGW1?a&~OcPoQGpnaUx@)CFqr?r>Bf=Q!q3)b%klHt#&4+(CE-Cq5 zvEq;wUAETJEh6bJnTn#yU(fagvqZ*cf0L+*Q2+o1R!KxbRCt{2Sq*ohNDxF!Xl3Gs z%f}|0Q^fs1@c;k7>lu)j-Av6Ot>^AumkD`VLv?pCnD>e#Q79A&h2jsvES=xn-pte4 zME=^y(m5>_3!10dBwh?Qh>t-7xjyEX#K`SoIf<7dZlE!DcX!4Bez~%}Q8vqHf92~i z#wXSy-eP~@Ef(aB84NN8@pt?JJU3{UG{*k z>&vI-r^l=C$zTv3Ajm&{e(UfVG;m=)83qImK0W_q0r|(pdcEH8?*cS%e_=iu1_TYp zc&@Nmmdgdwzc@b(7~t0d{_0q)H{0!Y6Br=OUmdo=Br-sVzdCe)Yh$}{4f4T{MbH1b z12DS7G+v=lC=?2XLh*Z}+RbB2=DP|}(tKZ9pU+RT-FzO!VZ}9;Q{TzF%L*6z*||0)u#jxVC++am;?MLfA#MGalY?lN7PS1 z{azsSEzo}f;sHeYzO;Vga`$hyFRw`8_2u^4u+Ve9FyEKfPd0B!V)J(x9BnPjYc_sb zn(s^NTZOmvdL0P9woJdl^TqkTu)b4R2Mll)tnvBsd|y_-7YHVg+t>iIbXitkEbxmA z@I55({qh4$ukQrje_{fGdq|$|%jzdx0v{F##q;ufUshkCP$(1%g+ifFC=`nSE$FAe zzg_)^z(CW5CKT7Fniuge5}@wv*Z`Q0ohYqO#|OQD-ZND*_92USO@sKR*M=Pm>(|}s zb?IL~`=)k)4f5wr-f$5=U)RJmyb$vG^-&@y&@|X#w}3$Ze>?$o0&oCfeWKDzAP2ZX zdv+bThnn1N0yKc@E@y=c)u%Eqc?XyHE^$mZ}7XG2!Dx) z>yx{`3Et&=e+Ahbs_`|n17L%@9s}Qk()!*1IQ*Y3#*g_o9aJ>xPu*d9zTdC%xYW-ioxp|LZ41LE zVZMJ<@wi0YN65Lcpq4cbtPh+J=KH;f$0a&`6proUf3V49iQ`LQzTdC$xD<14JgDUX zu!=0-A4ER76mf1e4%C+Xq5~{0$@d2lk4q8f#^Uf)Hf>Wr1qP7h`+X6QOHt=W;?T6M z{Xsgye7`T^aVhHDSR6XQ_C)#qv4+Q`m~-cXEZ;xE=TgKug+ifFC=?2XLZMJ7es7#9 zg1#Egd=x=XEN%}YOQWYGXNsUF;S}@GQD=|(B7s_Fb}W2Vg!APdDk==;}r8W c>sP$Tzm`(x#p4V1o&W#<07*qoM6N<$f+cY_;{X5v delta 1297 zcmV+s1@8Lo4Z8{@iBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`2YX_dyyp{ zAqol#e*gd}DJfJTAtNIrAt50a78XTA5*Zm83=9kp4-b)CA%9di?^D1RqKiHkEOv#1!zH{{|>D@x2wg|OkOGD>q3^YSxO6q52&Ds_u<@=M~& z<4f~0)AEaQ5t>a%*Q{HVpOcfCLYW!GIjN~-sl~VqQC4vEa{&hq0BMO^zJgf=PXGV| z!%0LzRCt{2nvHUzKoEox5(bpjkevB3@q!xU{on9r7JuaKlI>Z`9FWRwr$WkVWIktC z%OM>_K|w)5Ur4h!xw^he;@L#?(>S3l%P5Ic_X!NhM-0e5KVN$R`8-ho7Q`y#u(${? zjg46@m&TwM5an??PZGqiSV?V4XDO{*1jh7$#vp&mKfsszvpCO9ks|=PL~)be7#Dyo z-vM$7;D5IOE?)rB`6}lkB?2hbjl@fxi!0LJOFxW)OcbkPkEEd-zt z0C)Ye2P{8U=zI&{@09fteGQU0J697R$K|w)5<0zSf;dPwqNit94=?L<|kb%$9ewnyv#f+s@MI0A%=&*K4!~=-uCcucE!X6uWP7`2c#GE+#Cy z8*B)m<|6!y0I03*15oVe&GoDN1p_{vZhsU4`^Z+!I%+NAa~epnm+75n_?`Rtbz8nZ zxGzA*rnW)_guE#lhC~3-p2znss4oB=f(p20EgnhD|o=W&J0K?-Q(g7&rJ=y(DaF_E6aC4}}Yajrye}1)} zarl$Y=b!a4859&06cnUt==^|BL+1y48azMXt3P;tz@riJ10MaAA3**oKj6HAH$ULh z@B9GtyZnG#vi53z;2Z!Ha5(v-__O{*=Ns$L`2qgg-hF8X97E>^ zA|4uee8-I#JUAh-AScZa(3AjOegOUZem;14@&m)m zlOGsfdVXLO0xdr<3V@a$7>VG22T=0^;{Z&$2lf0w&^OgDchh@}cSwV600000NkvXX Hu0mjf5C1}8 diff --git a/mods/content/corporate/icons/clothing/under/sec_corporate.dmi b/mods/content/corporate/icons/clothing/under/sec_corporate.dmi index cc7cc944616395862c09c38fca881e7aea0cfb46..e0b9a156a3e48d12e728a8f74f56e5519a85f8bd 100644 GIT binary patch delta 1795 zcmV+e2mJWY3XcvYiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%QjgciH ze<>*`R3Rae001yBFcuaTEh-MYsvtf-J|iO|e{&UJU|<{^92prI6ciM{000*k7d$*X zR8&-ffq}rlz#1AFA|fJ5Nl7LqCJG7)e*gds3=9ts4{B;^2L}f>Ha09QEHN=LLPA0$ zBqTaII>5ldBL1a`00001bW%=J06^y0e`Wvx0JVBlSad{Xb7OL8aCB*JZU6vyoTZY@ z3c@fDgwM%Sg!ZiX)2kP0ksjU?l>Ea3ObtOfin%}uES`2kO87h1|+Kz&Xge^{hqUiWDBGIOl`acf9Sza zOcPoQGpnaUx@)CFqr?r>Bf=Q!q3)b%klHt#&4+(CE-Cq5vEq;wUAETJEh6bJnTn#y zU(fagvqZ*clc@Q<>7ONe<)HEMNyRBg{ydWeRDmFuSV*ZCP`){y-v+6Nk-{X z$R9dle?G)BCjNi|WQNH3kd4xX#OzPR{=`oGHklR7EV*?D$mS^*clYrwox3Uw>1-ig zVSnH&%&V7W?@w7m-9X(INNe)DPpH7G*WL9SGb^*}>`!!odG#_)dw!3cv4VLH%^Xp44yYnYaUuPhF*`9-P>C$Znydvin;2Q6Br&@A- z_C&kSuvcHEs}uiLuPS7H(KWDe=>Hao9S-Rk$7i_&&j6nuU&SZ>@NX~lq}5HUgZq3* z{^XPZH{jE=lE~?kffLy4e-16VPfq;d-(Kjq$w>qJo2!Cl*#a)1fSxf{Mg|;pAcy@s zHUM~de7gDk*XNt3$A>YxaJy}w3^iyx4Mq=N)-7K^1%6$)J&O7UL4A);PtVWKPf(8@ z(#>YGpic@a@aw|uQPejG>I>aC_7@I8whj>1MH7f2|gt2K@TP;R2&T z13vxYXakpKwXg-!!A;ufzitCWdl;uHilQirqA2g1?Jm4#w?&G0zAwyA`;&M#i)MHM ziMu!f5ybO-VSc+m*>1}mFUZTSUE~tw^L<%<*5loLOL^erYx(i6+|GBgE5HQveNld9 zZp`*8yNCkhpYF`pf2}cdS8(}!UzDHO&doPF0!IOsoc^1cJ019GzVFme=KF7u-v&rx zzEZIReEG%+3gCbL5uPq{*l_-Cp)){of1i|o2TES!X(04|B-DTjL5^K*ptX0!1OzE&i!;ePRaUzp!U*mw-E7Hsf-`FvlNzYE}?F8N*z&DZcA&8vr&S z%x_G=A&>)9An&d`_fVbNivTrXtIH|E8|61eUeFa>f8e{wf-b>!K?QFCdlOXn9u()N zID8V$_m5E=E}8Z#g5AxcjfOBVaFik=Kf6M_Um(2J3AP$!T&YjEQM^QI*@x#-A zWWL`eakvz8?o1AK)9`;3M>yZ_k~mxnI(III7FeEWzJJW&a4F>6RLJK0M_euioKqA< zQ4~c{6h%>#_sv8j=!-GY2zq34KAf2vy(O7w1U-r&=ApMFlZ~LqFvL9cmSnmS^l*ll zRfpe_Of`ZY!4UI2YbP2(k70;;aP3qh=ur$Y53QYS1U-Tw=E1f9)d<>I)ByAF+6#`L lhnROsqcKCw(^|`H<=6lK002ovPDHLkV1hvYR4o7i delta 1320 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 delta 1236 zcmV;_1S|WA47&;;iBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`H>+ee+mi; ze*gd}DJfJTAuup7-{0RB78V>F92prITU%QrBO@Lj9t;c&6ciK>4-biniN62<7Z(>i zJUmoXRDpqkz`(#78X6)ZB1uU}YHDgGCME|52R1e~EG#TBF)_fvz`fR+tN;K20d!JM zQvg8b*k%9#0H1nPSad{Xb7OL8k;Ybk;i@u9a})FOGgB0j@>42xi*xcz;>+Vp^D@)& zi*gZ~O-R?QTa=%ZlbS-A8O1rNsb#6fxC~KNaP@Nm2Mz#fiCeycSp`o300Y2DL_t(| zob8$cSE5i5g)s{z6a|DR%Qnl9|Njej=0R**@6Pks0-g5VbHq9qn9t$qaqtFzftQz; z*LTwFVt#pbIlq`qR6mU7bbWbE^C-0X%*R{I$G%A6j~6Pyl30msmXI&NeC)48$mjae zdNB{?uzs3x?R+!aWT}OqD0;r4upHj{1btIKisK@QAwbUONH*anw*VAn+4Gg<=L(%K zvibtBUZgQ|<`5ubfSg}|tpj;~S@wMVC-UX>TYXka6yHb}0YI=c732)I`qewW>QjX` zpMWolQ@WL1PzU%dT?NY?;VcY#KJ(uP|E~3^_3v!!FiyjntQ6P*K10D33L8MQjo$Ie ze|DdMZvevWHY$`3@Fn2l^02-QHNMV&1F)+QDy;+e54)?!UyoP2hkFEn(DFfm!n_9| zfZ5=8L2&=HZ}nsc==s3$54+v-^Yae+FS3zyK!EaaIAr`N?EpO=INs%F`ydd%LI6xq zE?3JE)DL<-aJb87f<4=~zDwmHtEwtf0CZmn4q5|F0SFubn%@GPU;n27yq*tGWu`!e zUPIaW8o>Tb0IYU%p5N|&@dW@cFE1}IuaUGs!|NF0;eEj)^kntpq=?NBKNUbe+Z1uS zSWgC!gd4hviPEV6avAMzDV?qZGFr~U=>TN-kG9(o0MLi$e=q3(KSlPNTrPm#rn3q2 z?gkqIsJRF~5CFB+T>y$L!@oSgpd-5*g}^?tRkMy-i+G;~5>zsOz4Hv8*^jT=^7YDo z0y;Le5h@_$P0}zV0thM|-}j)t0CWf{K+`~g#_T}2zO>+g>Pz!hf`B@}1*CcnuQAn4 zVlE;EU;+(bm8|#*uJ9@}LQA0Cp;nfF6M(NS1HhL^$0K+7hyl0+-g7L z@F$(iKj~xA%gf8l%S+YZ`2mLp&kr~>e15=DfB5`>t}*fhy8g-!K%bz0N`AnhKluUd zYrme$wb%0lCjfwa!^r@omDq}L-iXV=YlZG^Q`Ou0000 Date: Wed, 26 Feb 2025 16:41:28 -0500 Subject: [PATCH 108/512] Repath various bespoke jumpsuits to /costume --- code/datums/supplypacks/nonessent.dm | 4 +- .../crates_lockers/closets/secure/security.dm | 2 +- code/modules/clothing/costumes/misc.dm | 38 +++++++++++++++++++ code/modules/clothing/costumes/rank.dm | 5 +++ code/modules/clothing/jumpsuits/job.dm | 5 --- code/modules/clothing/jumpsuits/misc.dm | 38 ------------------- .../spells/artifacts/spellbound_servants.dm | 2 +- maps/antag_spawn/wizard/wizard_base.dmm | 2 +- maps/away/slavers/slavers_base.dm | 4 +- .../crashed_pod/crashed_pod.dmm | 2 +- .../exoplanet_ruins/playablecolony/colony.dmm | 4 +- .../psionics/datum/antagonists/paramount.dm | 2 +- mods/gamemodes/heist/heist_base.dmm | 10 ++--- .../4898_jumpsuits_costumes.txt | 9 ++++- 14 files changed, 67 insertions(+), 60 deletions(-) diff --git a/code/datums/supplypacks/nonessent.dm b/code/datums/supplypacks/nonessent.dm index d219153c0fa7..57d47f77cc6f 100644 --- a/code/datums/supplypacks/nonessent.dm +++ b/code/datums/supplypacks/nonessent.dm @@ -94,7 +94,7 @@ /obj/item/clothing/pants/slacks/purple, /obj/item/clothing/shirt/button, /obj/item/clothing/suit/jacket/vest/black, - /obj/item/clothing/jumpsuit/mailman, + /obj/item/clothing/costume/mailman, /obj/item/clothing/dress/saloon, /obj/item/clothing/suspenders, /obj/item/clothing/suit/toggle/labcoat/mad, @@ -115,7 +115,7 @@ /obj/item/clothing/costume/kilt, /obj/item/clothing/costume/savage_hunter, /obj/item/clothing/costume/savage_hunter/female, - /obj/item/clothing/jumpsuit/wetsuit) + /obj/item/clothing/costume/wetsuit) name = "Costume - Random" containername = "actor costumes crate" supply_method = /decl/supply_method/randomized diff --git a/code/game/objects/structures/crates_lockers/closets/secure/security.dm b/code/game/objects/structures/crates_lockers/closets/secure/security.dm index 08ba2e29d23b..860f376f6b1f 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/security.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/security.dm @@ -19,7 +19,7 @@ /obj/item/telebaton, /obj/item/clothing/dress/cap, /obj/item/clothing/head/caphat/formal, - /obj/item/clothing/jumpsuit/captainformal, + /obj/item/clothing/costume/captainformal, ) /obj/structure/closet/secure_closet/hop diff --git a/code/modules/clothing/costumes/misc.dm b/code/modules/clothing/costumes/misc.dm index 13495b75d2f8..fe650fcc9140 100644 --- a/code/modules/clothing/costumes/misc.dm +++ b/code/modules/clothing/costumes/misc.dm @@ -105,3 +105,41 @@ name = "rogue's uniform" desc = "For the man who doesn't care because he's still free." icon = 'icons/clothing/rogue_captain.dmi' + +/obj/item/clothing/costume/mailman + name = "mailman's jumpsuit" + desc = "'Special delivery!'" + icon = 'icons/clothing/jumpsuits/jumpsuit_mailman.dmi' + +/obj/item/clothing/costume/vice + name = "vice officer's jumpsuit" + desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." + icon = 'icons/clothing/uniform_vice.dmi' + +/obj/item/clothing/costume/johnny + name = "brown jumpsuit" + desc = "A label on the inside of the collar reads, 'johnny~~~'." + icon = 'icons/clothing/jumpsuits/jumpsuit_johnny.dmi' + +/obj/item/clothing/costume/psyche + name = "psychedelic jumpsuit" + desc = "Groovy!" + icon = 'icons/clothing/jumpsuits/jumpsuit_psychadelic.dmi' + +/obj/item/clothing/costume/wetsuit + name = "tactical wetsuit" + desc = "For when you want to scuba dive your way into an enemy base but still want to show off a little skin." + icon = 'icons/clothing/jumpsuits/wetsuit.dmi' + body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY + +/obj/item/clothing/costume/psysuit + name = "dark undersuit" + desc = "A thick, layered grey undersuit lined with power cables. Feels a little like wearing an electrical storm." + icon = 'icons/clothing/jumpsuits/jumpsuit_psionic.dmi' + body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_FEET|SLOT_ARMS|SLOT_HANDS + +/obj/item/clothing/costume/caretaker + name = "caretaker's jumpsuit" + desc = "A holy jumpsuit. Treat it well." + icon = 'icons/clothing/jumpsuits/caretaker.dmi' + bodytype_equip_flags = BODY_EQUIP_FLAG_HUMANOID diff --git a/code/modules/clothing/costumes/rank.dm b/code/modules/clothing/costumes/rank.dm index 19c9cb2498c1..b2bc5a1fc940 100644 --- a/code/modules/clothing/costumes/rank.dm +++ b/code/modules/clothing/costumes/rank.dm @@ -52,3 +52,8 @@ GET_DECL(/decl/clothing_state_modifier/rolled_sleeves) ) return expected_state_modifiers + +/obj/item/clothing/costume/captainformal + name = "captain's formal uniform" + desc = "A captain's formal-wear, for special occasions." + icon = 'icons/clothing/uniform_captain_formal.dmi' \ No newline at end of file diff --git a/code/modules/clothing/jumpsuits/job.dm b/code/modules/clothing/jumpsuits/job.dm index 2d3e59b8412a..29e7ec910f72 100644 --- a/code/modules/clothing/jumpsuits/job.dm +++ b/code/modules/clothing/jumpsuits/job.dm @@ -208,8 +208,3 @@ matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_TRACE ) - -/obj/item/clothing/jumpsuit/captainformal - name = "captain's formal uniform" - desc = "A captain's formal-wear, for special occasions." - icon = 'icons/clothing/uniform_captain_formal.dmi' diff --git a/code/modules/clothing/jumpsuits/misc.dm b/code/modules/clothing/jumpsuits/misc.dm index afb30f30c5a3..54fd1367f62d 100644 --- a/code/modules/clothing/jumpsuits/misc.dm +++ b/code/modules/clothing/jumpsuits/misc.dm @@ -1,41 +1,3 @@ -/obj/item/clothing/jumpsuit/mailman - name = "mailman's jumpsuit" - desc = "'Special delivery!'" - icon = 'icons/clothing/jumpsuits/jumpsuit_mailman.dmi' - -/obj/item/clothing/jumpsuit/vice - name = "vice officer's jumpsuit" - desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." - icon = 'icons/clothing/uniform_vice.dmi' - -/obj/item/clothing/jumpsuit/johnny - name = "brown jumpsuit" - desc = "A label on the inside of the collar reads, 'johnny~~~'." - icon = 'icons/clothing/jumpsuits/jumpsuit_johnny.dmi' - /obj/item/clothing/jumpsuit/rainbow name = "rainbow" icon = 'icons/clothing/jumpsuits/jumpsuit_rainbow.dmi' - -/obj/item/clothing/jumpsuit/psyche - name = "psychedelic jumpsuit" - desc = "Groovy!" - icon = 'icons/clothing/jumpsuits/jumpsuit_psychadelic.dmi' - -/obj/item/clothing/jumpsuit/wetsuit - name = "tactical wetsuit" - desc = "For when you want to scuba dive your way into an enemy base but still want to show off a little skin." - icon = 'icons/clothing/jumpsuits/wetsuit.dmi' - body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY - -/obj/item/clothing/jumpsuit/psysuit - name = "dark undersuit" - desc = "A thick, layered grey undersuit lined with power cables. Feels a little like wearing an electrical storm." - icon = 'icons/clothing/jumpsuits/jumpsuit_psionic.dmi' - body_parts_covered = SLOT_UPPER_BODY|SLOT_LOWER_BODY|SLOT_LEGS|SLOT_FEET|SLOT_ARMS|SLOT_HANDS - -/obj/item/clothing/jumpsuit/caretaker - name = "caretaker's jumpsuit" - desc = "A holy jumpsuit. Treat it well." - icon = 'icons/clothing/jumpsuits/caretaker.dmi' - bodytype_equip_flags = BODY_EQUIP_FLAG_HUMANOID diff --git a/code/modules/spells/artifacts/spellbound_servants.dm b/code/modules/spells/artifacts/spellbound_servants.dm index 6477080cfdf4..e7ce1bd18a6e 100644 --- a/code/modules/spells/artifacts/spellbound_servants.dm +++ b/code/modules/spells/artifacts/spellbound_servants.dm @@ -71,7 +71,7 @@ name = "Caretaker" desc = "A healer, a medic, a shoulder to cry on. This servant will heal you, even from near death." spiel = "'The last enemy that will be destroyed is death.' You can perceive any injuries with simple sight, and heal them with the Trance spell; potentially even reversing death itself! However, this comes at a price; Trance will become increasingly harder to use as you use it, until you can use it no longer. Be cautious, and aid your Master in any way possible!" - equipment = list(/obj/item/clothing/jumpsuit/caretaker = slot_w_uniform_str, + equipment = list(/obj/item/clothing/costume/caretaker = slot_w_uniform_str, /obj/item/clothing/shoes/dress/caretakershoes = slot_shoes_str) spells = list(/spell/toggle_armor/caretaker, /spell/targeted/heal_target/touch, diff --git a/maps/antag_spawn/wizard/wizard_base.dmm b/maps/antag_spawn/wizard/wizard_base.dmm index 965c15e71e67..602e41a4dfae 100644 --- a/maps/antag_spawn/wizard/wizard_base.dmm +++ b/maps/antag_spawn/wizard/wizard_base.dmm @@ -322,7 +322,7 @@ /area/map_template/wizard_station) "bh" = ( /obj/structure/closet, -/obj/item/clothing/jumpsuit/psysuit, +/obj/item/clothing/costume/psysuit, /obj/item/clothing/suit/wizrobe/psypurple, /turf/unsimulated/floor/lino, /area/map_template/wizard_station) diff --git a/maps/away/slavers/slavers_base.dm b/maps/away/slavers/slavers_base.dm index ea9e39a60cbd..ef7cfb1455b8 100644 --- a/maps/away/slavers/slavers_base.dm +++ b/maps/away/slavers/slavers_base.dm @@ -70,7 +70,7 @@ /decl/outfit/corpse/slavers_base/slaver1 name = "Dead Slaver 1" - uniform = /obj/item/clothing/jumpsuit/johnny + uniform = /obj/item/clothing/costume/johnny shoes = /obj/item/clothing/shoes/color/black glasses = /obj/item/clothing/glasses/sunglasses @@ -80,7 +80,7 @@ /decl/outfit/corpse/slavers_base/slaver2 name = "Dead Slaver 2" - uniform = /obj/item/clothing/jumpsuit/johnny + uniform = /obj/item/clothing/costume/johnny shoes = /obj/item/clothing/shoes/color/blue /obj/abstract/landmark/corpse/slavers_base/slaver3 diff --git a/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm b/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm index b944f2498005..44c3c76a9e02 100644 --- a/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm +++ b/maps/random_ruins/exoplanet_ruins/crashed_pod/crashed_pod.dmm @@ -284,7 +284,7 @@ /obj/item/stack/material/puck/mapped/uranium/ten, /obj/item/clothing/costume/savage_hunter, /obj/item/clothing/costume/savage_hunter/female, -/obj/item/clothing/jumpsuit/wetsuit, +/obj/item/clothing/costume/wetsuit, /obj/effect/decal/cleanable/dirt/visible, /obj/item/trash/candy/proteinbar, /obj/item/trash/liquidfood, diff --git a/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm b/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm index 782dcad53805..51089ce8d4b0 100644 --- a/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm +++ b/maps/random_ruins/exoplanet_ruins/playablecolony/colony.dmm @@ -1550,8 +1550,8 @@ pixel_y = 20 }, /obj/structure/closet, -/obj/item/clothing/jumpsuit/wetsuit, -/obj/item/clothing/jumpsuit/wetsuit, +/obj/item/clothing/costume/wetsuit, +/obj/item/clothing/costume/wetsuit, /obj/item/clothing/costume/savage_hunter, /obj/item/clothing/costume/savage_hunter/female, /obj/item/clothing/shirt/harness, diff --git a/mods/content/psionics/datum/antagonists/paramount.dm b/mods/content/psionics/datum/antagonists/paramount.dm index 5d4da1a87759..573a2920a33a 100644 --- a/mods/content/psionics/datum/antagonists/paramount.dm +++ b/mods/content/psionics/datum/antagonists/paramount.dm @@ -16,7 +16,7 @@ /decl/outfit/paramount name = "Special Role - Paramount Grandmaster" head = /obj/item/clothing/head/helmet/space/psi_amp - uniform = /obj/item/clothing/jumpsuit/psysuit + uniform = /obj/item/clothing/costume/psysuit suit = /obj/item/clothing/suit/wizrobe/psypurple shoes = /obj/item/clothing/shoes/jackboots back = /obj/item/backpack/satchel diff --git a/mods/gamemodes/heist/heist_base.dmm b/mods/gamemodes/heist/heist_base.dmm index 81cc7795bc75..03fe3d7afdb7 100644 --- a/mods/gamemodes/heist/heist_base.dmm +++ b/mods/gamemodes/heist/heist_base.dmm @@ -479,7 +479,7 @@ /obj/effect/floor_decal/carpet, /obj/item/clothing/costume/lawyer, /obj/item/clothing/costume/lawyer_bluesuit, -/obj/item/clothing/jumpsuit/mailman, +/obj/item/clothing/costume/mailman, /obj/item/clothing/webbing, /obj/item/clothing/costume/dispatch, /turf/unsimulated/floor/carpet, @@ -737,7 +737,7 @@ /obj/machinery/door/blast/regular/open{ id_tag = "SkipjackShuttersNorth"; name = "Blast Doors"; - + }, /obj/effect/wallframe_spawn/reinforced/titanium, /obj/effect/paint/brown, @@ -1104,7 +1104,7 @@ dir = 4; id_tag = "SkipjackShuttersWest"; name = "Skipjack Shutters"; - + }, /obj/effect/wallframe_spawn/reinforced/titanium, /obj/effect/paint/brown, @@ -1131,7 +1131,7 @@ dir = 8; id_tag = "SkipjackShuttersEast"; name = "Skipjack Shutters"; - + }, /obj/effect/wallframe_spawn/reinforced/titanium, /obj/effect/paint/brown, @@ -1203,7 +1203,7 @@ dir = 4; id_tag = "SkipjackShuttersWest"; name = "Skipjack Shutters"; - + }, /obj/effect/wallframe_spawn/reinforced/titanium, /turf/floor/plating, diff --git a/tools/map_migrations/4898_jumpsuits_costumes.txt b/tools/map_migrations/4898_jumpsuits_costumes.txt index 15248ad7d2bd..4a7af78fa802 100644 --- a/tools/map_migrations/4898_jumpsuits_costumes.txt +++ b/tools/map_migrations/4898_jumpsuits_costumes.txt @@ -1,4 +1,11 @@ # Converts a number of jumpsuits to costumes # because they shouldn't have the full suite of jumpsuit modifiers # (e.g. can't be rolled down, no sleeves to roll up, etc) -/obj/item/clothing/jumpsuit/research_director/rdalt : /obj/item/clothing/costume/research_director_suit{@OLD} \ No newline at end of file +/obj/item/clothing/jumpsuit/research_director/rdalt : /obj/item/clothing/costume/research_director_suit{@OLD} +/obj/item/clothing/jumpsuit/captainformal/@SUBTYPES : /obj/item/clothing/costume/captainformal/@SUBTYPES{@OLD} +/obj/item/clothing/jumpsuit/mailman/@SUBTYPES : /obj/item/clothing/costume/mailman/@SUBTYPES{@OLD} +/obj/item/clothing/jumpsuit/vice/@SUBTYPES : /obj/item/clothing/costume/vice/@SUBTYPES{@OLD} +/obj/item/clothing/jumpsuit/johnny/@SUBTYPES : /obj/item/clothing/costume/johnny/@SUBTYPES{@OLD} +/obj/item/clothing/jumpsuit/psyche/@SUBTYPES : /obj/item/clothing/costume/psyche/@SUBTYPES{@OLD} +/obj/item/clothing/jumpsuit/wetsuit/@SUBTYPES : /obj/item/clothing/costume/wetsuit/@SUBTYPES{@OLD} +/obj/item/clothing/jumpsuit/caretaker/@SUBTYPES : /obj/item/clothing/costume/caretaker/@SUBTYPES{@OLD} \ No newline at end of file From 98a0a613c1f2d8e00968b3e5ac84e604809a9d28 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 26 Feb 2025 16:41:54 -0500 Subject: [PATCH 109/512] Add kitbashed rolled states for rainbow jumpsuit --- icons/clothing/jumpsuits/jumpsuit_rainbow.dmi | Bin 2116 -> 2567 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/jumpsuits/jumpsuit_rainbow.dmi b/icons/clothing/jumpsuits/jumpsuit_rainbow.dmi index b64bae0a0dcd8d7da1ae93da6cdadea614d9900b..170534cbc62f92b792e00bc2d37bf3cd821959cb 100644 GIT binary patch delta 2441 zcmXw43pmu<7T?Ar86xF%I27TCO!UAI(RhU>QbLRf)1XnN!!Xm|;Ls$mGpLUDTjc!= zgV7{OMwF%$l~*ax>6pW4=1%wA`+aM#{jIgvZ|%MI?^}B_<&t*qrJg=zFC+Df6aYZR z(E;TqoO^|%P*PN=!`5l|jJ-OiGOU5%CKv?991dq1Xvaxvf7-FX25uA|AD?{<#Ky+r zaJVs`$2bG1R4Ppd2oQiN2PXH42qs`5At5wNAczM{SCE{XJQ*gEQKV`v3#-5xCPpU@agC0AYouEb<%8QA8c` z6&0>>kw|23Z*NdgkiEUVudgp25buIgK*NJlBKXuUS{(foOBR3#CJfgGv}oWr0WfC5 z^on-?+5sSt1xzbIqX5Baz{CUEDmJbp{-tV+RS1mT33$1XN%|z_rWagv*<+<^#}iqRV!W2Q2(Z%>Cmc^9(0k``p>#VjGRKLRh!CPJe%V3_+fiy z)_9eBsOQ+lWevrtpEg-M(`N^z}K> zbk2aaM%L>04R}{Uw9?T0m)n07WZi*$eff`Ve%9NW*9C{SXxi^wQIBw0P^&3!j8n5L znBz3qD_D>-SZ(ZiZ|0buQ?{XZ>jm#_|Hsg%_66wJd)uN-`R?KUcZV~os;V*e{>O-)S?EkLytuj>`^ z^>+uBX;JI?`stV$Z^_Y#$ON0BUl-H!ulD_F{^(>>usypl|0*(aamgJSxx8?=GB|f2 zAB&=*xG3ob6yeA+tQK~V*(uE46__Go(7V;R8UeQN9-h4Jl7iv9RvzYhhER@qgAc4qbL&JJrB@HjzkmG0 zKC?Uk+w9mpejE;oEu_rxhA@6C#XTz?=a+754!wyO*@_5e<(^W!Hut)T)H8|gX5}lf zo5UrzvN(joy~hqi#+_EIJAs@Z309$Kr9EpNh8Ns3vz)m3D5M<&e#w z@ehoV6Rz<|CuGHx_T();+ZdDR_-L*NR0rmH*ZBW3{8O*>lx?PP%;z!O{tX!%4MMI6 z1dR?nlS(O`$R{qdU%C~2qJ75;F1(LA%12IA-uk?xY|LKlwQT3mBx0`=e3w`wdqVUu zck$sZScikt;!(4ea%0Hmr9dM|Z!MUsyN_*W zi}6|e1%9-tk%VcnX*{bi%NvFG)HM63;BCz*`yY(Hc~fONm2{=BZ&ECdgn8R@^xl*x zRPOeSyZFJ^X;Wn93~!AeG{cikL_wE)3@=(BzSf-?QAn}t)Uhknlu!OL%WF6<_Lt$; zI**a8A+D{GoT|JJ@U)5&8Rc)nUzRvUHdfk9YW#dW|CMxs0hFfR6Fsl`YH9V z$`vD<+e22xu={eBAL*p!ca=LFv{)mYcg;_g<^&4+z|SUMOB9>C|B;qf>BbpjSjx;A znT>jFYHK$QF{jI}8mGb(+%_yji}AUdB_*rvifL(aVWn$i3bpoXl|>BSCT4X_rP67Z zr%4M&JdI#M7pL7X(#6TbG!$z7)myiZG?3j~0%8sC3HOigzi)h$KmU)Z8A{2|LU_c_ zDiuTQ>eZfp3?)p6$e^Yg{kL`hrB~%~sWf@vIR&pWG&mxYk!tq+K)j<$hta6fw(h`# z`X@|K$hp%smsL7;3Oyk%&qh+xQ*F)8hn!2ia+5GrgjaDM97z$vPXFKIHD*lEDh=2% l9(4Ew`ia`38#71v5`TF&w!LC2`UwAN;AndaRcqrH_a7%2g_-~W delta 1948 zcmX|BX;hQf7QKW)=ICN9GKeB15(x7okYcfbRR~0JfCnfTAXI`O1%gOIU=h(GNk2uI zEyjXXLeR*lkU*HqB%)<-iZZDTL9qe?`3lds-j8$7-e<3~&R+Mdds*7zt)@A6e;*B1 z162TkhM%u@&_=$o5e#MdjkD>|Z)lFGIgSQQ{sMN3i;Lr6H&c1{Tg^RHYPOk~nL_~0 z@dEG#AR>UAoE%64z*r#O3SODX(NutF8z8A6@+pAB(6OS~0#P71!~ql-#KgovWB?BX z0)fz14yJ_QRjnNDI1q7wpg@rnfZ*`;bx0)At^1&T0VL4C6@g;MM}<=)1gGCvG2yjx zf`~JNqMOhF>b0^V36TS!WUD-eO)=z93n0zS!D1x1hXj00z(Xnu%#~kb0c?#RsfEcC zVX)-p=Eh(!ghC;aNc8dX2@4BDkgUjnb{%lRhA}P;yseinPeqUdz&BU$-{3F=&ch&4 zj3Ct^a3tVE1IH6YU>5{XFt8IN(B%k262OWy0b~VWBoJ={A~%d!1<-H+$^bAPhy#J> zXN)+)f^Q3GWB@$_Fb9Y^K$L6250XCR4l!|V2!Znr;}VFe26GO)gb3Rvs%Q4^OQrQfU*JkS0y=uSOhYJQb3 z-m~Q%{;X0q{nVRX(OPI$oJ{a}_6kx->>*6lJL7BDGg^dZum05sQ@q5A9lS1e zJTY&&n7r%u@RO_{$DkW2Z6lYi1nCgkx9U8U=mb8c@43dU*-WeY+s zOa|fTrJ(`n?t#k;%suPc6ID{qgONt%)PglP^H;4!+;EldzNw{2qj~%uSa?fUU`j49 zk{jAxd&{Y4PX1p0SbkJz5=(5iYPS;WL+NB`npwCQU7qx3y=*{O*0;tcyIk9A=-q_Gr4Oa;s;PeU&HeXzn%&N6!Qn9N z{JP$DM(^|zXSZ_sj;^vad~@JdCzaM8QP*M?R<=8lw`Elw6IC(!rxP<@4};F^Bk5W<+V(H%bn&w z-BKc8&y*YQXYj|=S%pRH#iHie_}JK3nQkAFGne3!reK+3X6Sj)n8lXg=@SwX(z0tN zM!`5Hj!f3u>*hAbUVPpxot<@0x~oO+yEV6*16A;u75=3zvUr;!Uf25}&IQ3QBKg4+ zAA6C};xQB@{c~p-7l(^n8EyE1&rFOi+y99-Ki`Gr%*S(0h8N?qjWN=>x%FHO2A5pg z8~Sdhjl!#_mLgOJ%G#8)>-8_Sr(4YI%n#pr9FwHd)6lcNesp2j-Z}KWl-^PtiL>@( z`--)4GF*I#EJg$qb)~`>u8cu&9d7SGNztHhG;<9T&y(@LbY3}0l zy6pJ3)t0tt)AKgYX-oYHn^H0?`e955Y4W0l)xr~Z-5lH&AN6_AcSA~9i<(8xU95-< zFdnbA)HS@S_G`JK4uyVOa=&I;U|E{y(Q{K`lGU3Z;;;IowZWc(?TWC`S63RR_q(s+ zCY`58Vf2?GGF-vXTr)B9SjHKQt>CKlmgr&FXYe39w{$?Nw_bo`!;pf++z%dHGuaP! zBiL`@%BZ!lNW8k!)HICx8lcP2hAVstC_~-0H~27F9=#lnlIwaS3*gkUXW@Oc72HJ` zq$p|fx}t}jH1ZXEq}R(Jg&oh}(_eFYUUp<;8?4|C!+r?-D17Lk|Dl8zPba*SxN5Mo zt*f7bKgXl#ck8uqyMLnh9J#vloSo$m3;xNRfVRDQfVebt2`)PEgGpQ@>b~j92Jkh%9wI36`k#h^-k{>*M&@-lLZY0*odT%sX+fcy zaFn^%)ltvJ>)TE?Em3oR)Z|6POiEO<{||_pm8p$N@Ftk}AK=4!oe|%!$ Date: Wed, 26 Feb 2025 16:42:03 -0500 Subject: [PATCH 110/512] Add kitbashed rolled states for SWAT jumpsuit --- icons/clothing/uniform_swat.dmi | Bin 1143 -> 1653 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/clothing/uniform_swat.dmi b/icons/clothing/uniform_swat.dmi index 97bf8ed0dd8ddce81621b62bdc1c47ea2bde21fb..93fd89ab227c86d8d22d4194ea854471895fa65c 100644 GIT binary patch delta 1643 zcmV-x29){t2=xpliBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%QRFNeg ze}I61YHDggKtNJbQj3d=Q&UqlM>{PoEn{P292^`eDJeBIHAO{5a&mG|P*7%OW~ivB zH#axHz`(9?DV+cS00DGTPE!Ct=GbNc006amR9JLGWpiV4X>fFDZ*Bkpc$}q@%?iRW z5QNXkQ-t=c_|vNwX^|f6E0jpKCXi-ff0MTO_6BY?tOX^`4CoXv-SH!dmpUa{hk6f68Ca z_5`y;#%GhLiBSLm1rA9>K~#90?OcI&(=ZH-UE;B>;0*=^{{KUfWT!CdlaneT8|Vhz z+ob3uC2`hM(qV8o91e%0AjEh$9AXSN+V=+K7v3G-1(adWzB|G=QidUpBPgI_wWnMg5hFE`Nwd7yblqk zsM@(flAzYWF^#Z+VPuyFHsfQc*g<|l_~9qw>eMW-)0ysbUx7=P!8$U_|uU*8R5)~jP0zSx3f65`=u_x|K zloWx(WN*c$Gm~3<@KY#i7<@xg`e~=*AJ5oOhwJ zO70F`q4-3`dw>=|I+I^>0dg_G7gF86JG_9sA@2m>+kw7)cVu2+v$_ncc89~^a5x+e z$J>UYEMI`%k{b1WGk+0Y!k`3+)up|)QQx=n*8xBbnnQJI8m;=if04gXq(El)h9T4T zoS>4QN#D2d*8t?9yk%p}BW|bfoA`^pkl+p!_BO){eZOu0rSAj&Fo(abtxJF?x{?}z zr6+tAPx3g5Kgr|3KJXgWvdqjE3sAIm*3Ce z#|7|9Oj>|4UBLyIfAoDT{~#N(Mvnrpcz!9qVHSz z`9jgT6GGH^c%d=t`$m3_pj_sr2nlX)*Y|DwLeZIj@Rd^8!&Y_K#xDUnHv`c^vTXqt z{t_VT0rJ)b82D=dRlLq>0cL&Q#y^xlCbaE!54*l^<99e5e-4Mk;cz${4u|8vMf&6W zo8#{Un8bw5ZW}c7r!>eH3Xsdzy#lcA(NRRq{7HX|D)XK5GAc##dJTf4w~)##9}Ot1 z{1je&j4IbrFD`(xD|19(=K;aUMBDJEpg%@c15gquK$&9eLpmO{wvUk&_@x2(F)EpI zrcpTr#X&mA_P#P6AE=gg5ic3|CuzA>=Lj>i|O0_eWjd=Mh&=-^b^mnZLxw44F?L9yY@avU;n= z#DO+9^XJO|0tD#T=Uk>W4?DlZ;cz${4u`|xa5x^=fpf)?}?9l;_OwgJ?E=|H5+JCHkG*xNRUC~5c=~b1AB1Pr_orm9yVUF4d{7t8${qSPeSdOlbg9$1`REj2)Au!!9`Q`% zeE#q9B-OkNL&f!PEVQl*T5uGega9GLu9{{(e3~M002ovPDHLkV1n{(Ain?r delta 1129 zcmV-v1eW{t4EG2niBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`2YX_W|1Wy ze?UM$YHDgVM>|qdQj3d=Q&UqdEiGeXV;meDDJdy6H8n*=MJ_HbM@L6WN=jvAWpZ+I zP*6}97#JQN9%g1{sHmtQARsq4H^9Ka#aH<=00001bW%=J06^y0W&i*Hn0i!LbVOxy zV{&P5bZKvH004NLQ&wD@x2wg|OkOGD>q3^YSxO6q52& zDs_u<@=M~&<4f~0)AEaQ5t>bi)|?Zck(if4j?N;yI+Yb%{anD|004qrQxTLde}(!0 z00SFIL_t(|ob6bPa^oNjG^CJA$n_bgZron`|6h5M@U%_CVz86*+>EvpIzd=kBp_az zMxjtBzF@3ftyb2W<>H&0)s0zSPN3oBQj$@Hjbj%Zemv!1@V`Y7 zqJ1C$QphtP1|dy=N=Q%c`04ZnW$wQv4@m-I_sAXzP!e#3nok1h_(Jej2%bj}yZ1yu z7DC#Gk0enBq((cgQu1NL4&0U}DBluxD;cmUd-U&_BP3vGkrDw~sEMaTe+b_Q@VA8h zlfbz>29PxjOAzihyZhDsZgU4HGW~6)hBQM4Jjdh|$Ydb!^YXz2Xcy$SxwZHpm453p z1mgN~h`__+)Bbk<^!NZAkX`wWAW`33NQuL)V`6ab~*NDG+rJFA|4X9Wgji+h+TwGw^xw zMw9Kj7YcYn;Jj}t0XupOwKU%&&9xorn@S*e!7)VJQ?MT^p7MX}_VeR6CKM9*5iHd= z31OT-|9X7;^LBjge@FTzV*DWPTdFmE`jNitp?_~b+V_66PoYpK6bgkx@qZ$vd@tvm zo4kZhDc{S*FObkFs^6Dp-?Ck3WY+UP$(1%MIHVE;=DbgdwTQW00000NkvXXu0mjfD3|$= From 745f2eb1164fdeebce7f794cbe63fe463a6a735a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 26 Feb 2025 17:05:01 -0500 Subject: [PATCH 111/512] Add a few missing jumpsuit sprites in the corporate modpack --- .../corporate/icons/clothing/under/aether.dmi | Bin 1364 -> 1825 bytes .../corporate/icons/clothing/under/pcrc.dmi | Bin 1087 -> 1119 bytes .../corporate/icons/clothing/under/pilot.dmi | Bin 1102 -> 1215 bytes .../icons/clothing/under/pilot_heph.dmi | Bin 1111 -> 1223 bytes .../icons/clothing/under/pilot_nt.dmi | Bin 1013 -> 1123 bytes .../corporate/icons/clothing/under/work.dmi | Bin 1258 -> 1290 bytes .../icons/clothing/under/work_heph.dmi | Bin 1305 -> 1337 bytes .../icons/clothing/under/work_nt.dmi | Bin 1154 -> 1196 bytes .../icons/clothing/under/work_zeng.dmi | Bin 1154 -> 1196 bytes 9 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/under/aether.dmi b/mods/content/corporate/icons/clothing/under/aether.dmi index b44fb13c2bc6032068aa1cb456aa77404d423b62..6c87d6007164fed83dea458e8f9f441c8210f0ee 100644 GIT binary patch delta 1795 zcmV+e2mJWd3ZV`qiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%Qb&(}B ze`{-N0Hyzni;GiJQ)p;tYHDhgY%v2)W;{GRfq{X*z`!~>I)H$HW@ctbM@L>>UI1Hp z0GG-Dr2hby>i}DNU`8Ooz`)U~oXY?J00DGTPE!Ct=GbNc006amR9JLGWpiV4X>fFD zZ*Bkpc$}q@%?iRW5QNXkQ-t=c_|vNwe`%2(>?@Q=wkD8fVUxD__6BY?tOX^`4CoXv-SH!dmpUa{hke-&M} z*3vB^=`WdzqRL;-_5`y;#%GhLiBSLm1(``iK~#90?OY9G+BOii#8nu3aY8eoZMrR` z;s5`|-N}Y@sh(u}%xJcI1e)-~eMvU-ol#X83e^y@MD^;H_UqC_`;@64!H11S`Ff|p|V zej@??&hepR>0e{ceR&-1hYm1lrY z@03ZPz~3B}z^&2w7$ANhDDXGOvwT9}`}0iRU@#aA27|%yzTrkF{{+=%rM|EBFRv%2 zGe&3_k|veEVgyLF^{we_;WAU*$g<@IhL5V1lcD6>yExO`?D3`)U4F-%p!ojPQ@o0*-vq zK*K}OQS_?sBmS)K1M_?@Col|5@`CTjBc8(J@w>wnc-8k2f7bVbf4LX^S2%%K*`_c9 z6+T;Q_5EmegnxLVjn7k)Gtl^q0j<72#y@5J_cJ4H7-T@Ye>0bXKSQhUYyDTUwuv%V z5|Ete@te6;-yh?js2_(cyyRZrXYc~w%GLV*82|K=`7Bkru5cv>Tj=2H_4>Zfzwq5~ zm>`^*(7^$Eb-C!Da{i-%CVw%|$v4+cpx~c!{-Xh(|44pv{<;Yi{8P?q@6 z#eQD8$%@C<^&h)O9`f;dmuWHi!3b((yJmQ)zm9(wocy3JWaX&8Rsb}*dk?;8G7-2& zT0DT)`wxQ&XrS*>BL^~|iI)?k=_m{`P?uBh-^DKqe~O8m0q=7OWV*P$3x^X>`|sDF zhb;u><9A?k73TN~`hI2!YyCTsza>p*pvSfJeZBvSfee35eP8Wg-JqaujJ^*u(E67y zXly`$4n&EME2zoK_e2d`Lu&ueZfHQb=UIH;eJCY>N9g?<3vJc*d?c#G&$axV zJ^|V4ZihF*Q|kL?ABidzDmNarXFG5syale`e~(TQRVq|&EDlfcYer9KmoEMF`+`)J zN|hUlLmj(-Xqz;xzCSogRH<0Gu{b#CRc0nYqwk-6B&t-Z+)~i#`)8!8RH&T6U@#aA z27|$1Fc=K)8w*L$H^V{_^i1dSFtT{4OR|szJquHchq@$-NzijJrFf`IvYZ4x9aD;j zRmUzSK~Kk&;$^xd3rWy(Fr|2S>_QUsEKDgL8oQVTJqJ^YhsOR}5_AeviigMEP=cOP lyjvC;V@mN%>o@#}zX69#RVpAFJTd?P002ovPDHLkV1lO+b=Lp@ delta 1305 zcmV+!1?Kvp4%7-IiBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`2YX_a*-u8 z8vvKe0HptGYij_d|BH)@Q&UrFYHF2iF#wnAk!~G-dH`E_U`8Ooz`%ni?JWQR00DGT zPE!Ct=GbNc005qPR9JLGWpiV4X>fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5f zFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3KBSJijO>MTv_uC9|j)$T#HTOe;#v zO@*+3;i@u9a})FOGgB0j@>42xi*xcz;>+Vp^D@)&i*gZ~O-R=aiUm?SK@QdLENMMXvLazwk`j)=F*@6L8-ZZiVsy%0F^ z9sn@cvacbZbJB#DJx-B2wdP#jO)UBSc@xbqrK#(hQH5LxL9*)}=4W;lf@oSL_~P64 zyo~{{@zq8cYeUc8`(XPx0qY^`YCzDmjl?emposx=m;S9n{;~scZ{b*6bk+Cdga8$P zs8N8uY)z~H-OypA}@)5;Z zsRFLRZ6ni^WNRP*(Lpv0FbV?LE+hb?|D_i^0(iVWJUu)et{*`IkKexQ>j#QkVl6X> zSGUf|Ja-P{mq9iPRzUENi3;h!V1`%vyt-+g<1UcKy@y>O1kZEw3xHfiq>pfa1&&gm zBdmZBbaV160Lz5O0GYUSKa9orH<8eG~R&^9E$BUwa8Vk`Iq zR%Fj|SnP;3`~j-V!f8caF zL4e{96crT}75y*5{=gc^Q~tmj`A2_X&ObHgDdi8WqLe?dibj7RS!01vUKs_LsoeT4){Q;{#8A1wxC0001h2m=5B0K2`CDUl%~17`pK zkwhVXz`(#6gpLjX0004WQchCdQ@0+L}hbha%pgMX>V=-0C=3Okj)Ch zFc5^#$y0>(toYNb7ilRy*jFf#-I_p}g-zPv+Z!zCQABU^!OSpBsm@K?^{T#fazPH3 zygI3ByOSbWh$h4FAcaADGjW9wb;K--MC_n{kOC}+%zG(D))TJ!o zibEP^Z%5+k9j?9)XGB~u{8qx`9Kv6QeCR4w)7Q_VA2f+|d0^wO0RR94A4x<(RCt{2 zn+We)8Sx(39;etV6k-J74(UK2VjL!r<2e_kD>;ib$faTl3fu&>NSAZ-B|aQ`r$8!L z0sN!SZuZt%$pw!>3gSchgWN<1tfWW?skMrLwY44~a~52=R?YbW>0j zpvetPeSjw%PXZtS5(4r;7ZBTx2ouGBO9!wX@!GdvZ&(Jtx*1Btm(;$G8k|}=$$*XD zopFjSOEbIx4Kt`uoy>8p9KCw+FM$2#VSB)*u*@%xEnhsy#Ib*#t>ak-+J)};B%Y-xetT^dIzjUTZ&geDUMTr6gxm& zMXJ0^OiV^)$bcntIhz3!#*+ewgvv75CI;-!ATFRX;3NV*B*Z_?^W}P(&mThkeEGcH zZl9O45TE%l&sPcXiox~79w04bS_`(j#CYK@mL?&0oqn^wN98VB?j$l`#i%^Utsz2V zAS-i(Gh}5U=li@;LmYop0U5A=@|{K=V?58*-wVKtz*Ye@4k&=UL@Kj%QWu#8P#hsY z0f=ji-axq27HJN@09YAN>_WZ=gVshFJ5UG2K`;QA7*L)>l>wD8NHf3!%maYSBvO7+ zt8oG}9w~qbHv@)3p-?Ck`p@O<|Cv`h`+qjyxc`^Rfd6Onjr)JtfZP3lKMU|1{J+!^ zZ1?{RKFDAEzvm|h{@?2V^`9*Ga@+qao2SWN|4)do_F7+QqUSct|D(^XfUEzv9nkjw zh5!fsKRUeN|B3dR4e0FuS@QP(to-i&pOxR;|FiPD`+rt`cmL1I@9zKEfX@D(mEYa} zv+}$9e|GtyP$(1%g+ifzP$(1%?I&;l&&u!a|5^Fn{XaXuv;Sx2_xAtH{NDcG3xK}< zpPAp=|1+bkw+na zX8-@dz`*l4fBXOd00DGTPE!Ct=GbNc005qPR9JLGWpiV4X>fFDZ*Bkpc$`yKaB_9` z^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3KBSJijO> zMTv_uC9|j)$T#HTOe;#vO@*-GsxnG{a})FOGgB0j@>42xi*xcz;>+Vp^D@)&i*gZ~ zO-R=a_qynJbOprKU6o9(N zZ(n}BpbWg!8cM^<>YonKCkFro&N9#@0njs43b@LMza8e|={O(WjQHXBeme_-lIpCWtP`w-<1{=ogtPQJVO1NzQS ze(s#C1OVGs+rqf{14jIIJlB;b-WU4-wK%8Kzy84E0RGX05C2ntKSb&kJn0Yc#q$Sb z5s;g#3Rd<9rV|eD{5k94)%}6%>D^4iwfzCf!tAW1tNR0;U{ilUCZYqdx<7!aUW_>~ z#vi~cT5W&<{s3{Fn85-506%DKfba)Gp-?FFpJ>y^mFo|TsNeGkh5$JJz#stI9~c85 z{y^C-4aFbe&+PzV`mtm~0QY!40KoSL)>rrg;SYpA5dJ{;1EEkT6bgkxp-|`(e_()o ze_#ZF>ko_~*!1k=`U67%Jbz#afaebk0iBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`2YX_LXjmy zf55=N&Tt_u00001bW%=J06^y0W&i*Ho_bVRbVOxyV{&P5bZKvH004NLrI5`EgD?<; z&&g8+JzM(YwU?rZhx!VVvTGBFS;$61-@c(jdn~25`Cz^|OsOty*AJ?>_HxC*mb^Nv zdbgJ%S%@aX=_rLkdpB_djyhtFMWW!Ke~hqxkt*(y~#G_Q}I8DU;+95N*7000AlNklJg8R@9a65i`Q>j#{pBe^({rfPSf0Tc` zOtUfX^K_X{%D+t4>wLXV3n8#J_mH*Z43D^>akMZzznPYGS*Llrjq5U%8jhP2^pLns z%4hf98)L8^S^n{c1_Z)j02W;PWxQb!3XR4sIPb-K7m5Vd$A|{r#YhOO+(r>$J!H&0 z%qzBGEVu()MZH&SF-oSXoe}E8E8(+LiD=tWIuH1ppJS_`)VJgl5g8>M*_HDdj z5DEa!KLLCJ5K8%72o-?q3V`)mo`S}Rm59wsaTpQ*1R%qV{~Ko|Q~)jjxDbGR1?WP4 z1y2AHPh&4JPyjPy10cx?rBGEh2l2=Y#ab9e*hbgKPW2z z6K(_ZG;x4Diz@(Fg!nW7A_bUN+zX})7Gk-9-FJIWJ92^)+H3K&+jqH>I0%qB@5l+T zgt0lA0Mi3oq;W|dz*k{Y5^*nZ8|^~m_W8q3U$TY$p;3YJa@=od_`A zke*kUuLnT!?=THc1c=%GId2G3?ZpA)m+w~qJcgfSXaGFJ@?}EVf9e48mNy!fyl+k7 z3g2D!J$<{4RN*7=Z z5N93mG@&R!7WHUQm*EQ8;hzM&d<1!RNZ1uf@`#c}L~BQz(^qFm>H>BbkR+S;-GM?F@W#z2bzWbYyE-r6P1|$ILjYMD@x2wg|OkOGD>q3^YSxOe-x7PQz~_fbMi~#%i~M)GSl*lauJ$MNY|`e zl%JE6nu5y=Wd&D17qGtoF4sh|hU@JV0009VNkl(3`%fu_5YP@q00K0l@3&z^ zkP3id+ha@*KPV3qbT?!U~uLFy63G%LZ~B^6-W@aMe-Kg8xVve*rB~!(ND+ z@enzIFM_6s?wUVLZwkG>F@hb@5ll4GTM|E#PLDt>19*tu1&HFP7vUjl=$nEi1P98G zij?)|CmC;(@Y$TxUvkMMm;5gxFC2v7^l=aW!&*OWT^rB8P(;^3RcQs|Z!6X9JOM8& z&)n!6t3wBnUY`fJ|5(YMe>)vkxaZkz6W|f{#D^N7IEXMh3y|z%uK_HVXQ$_&%Q=1x zu*C{MfBP;QD9_xwpW!D4uL5{xrdu7LU4H2A^T>}wAI#vP$MG~Q04&#Vyn~`XfZ8Jb z)RKMR)3;-pSC%n0YOF*k$0#b>XZkDxD*%ytZmb(mZgGs{3P?G?e~Y9RfLBoJBDt*q ztOeL8AQvcFDNr2H%I-ag9MC9G^6wi*W!2z?0wlDu`$t9Ou za>?J8XL?`B%-#cJ$J#9NIKR;|FFoL%-;v~W$NZj%IDpEYh6TOfvAKWt*KMvJjAzfD zUK_6;9FT?Hk$7evZDS?<|5CFEsNcc(6%74vTJrB}1xiK;vyhzj1%APR%(_*em{im6 zB&quUf4e|2UZA{k!O$*H%qoCpexD=Ms2_}nNS+rA+#<_u;hyV=-0C=3Gkj)B%Fc5^#$x{S9Tl(X*m!gP=`U;Y=YZHiB$VNlozM(>UETy;kV7@s_ zsV;5T530HLa>c-wygI9Tx0fPWh$h47e<+1PdpB_djyhtFMWW!KkOFMr%m*o^pl96j zyJePHd$OQz1doax#W9VGw-bf=BiFynRUqdO{@Y-OxFUbqDpfl)uaBM?VP0(8$ z00V(`uzoh($ZSWsEa9!F}ilf4Ci= zPAZj3^;5%OuzwkbgYus*<7CXsG+w5I^3UV-I$f{hObD#aJ!CC8!+YG&I9eE<-;DEZ zzKzrP`gWVgQp5A&1U)2fk@DHS_r@6P&n*9aMFRq1FaR^I{qpvTK`1mjFTr^)-n&pF zus%jK@GeF|U}e3F2R1n0^f z2uCxZVJ8yOyV*F=8cRvr-&J#6JPZ zFysHmSqT+@3ji(zAYTExkYB+AfW*_-OAHjiOjv;v*5X9wsrU$h=yw6Qe@Fp_VcUkc zv?I4d@e2SJ4uBPajmO_9D*z*I1JgKifIN#U09b_hGyoz6m~OZij2A4#as#_S#uqlbS7r2FXA#(ftVJEPH{Pgg) z(h|-e7LT~kiqIaw39Q|bfB%FDXfY0S7EAOtJrZ~dyQ>3`AOr9r_yd5r2O#wz9{PL; z8u9eTP>VK&C1BGdjZeZH=aVoWyaOP=Oz<~~X8gTH<)uiaQmIs`zeHxo^KyUkRK4wa zV(%2*S45Tr2?Vu2Ui=OOxUWdhtIOvDp!j!~1_uJfZ2ufL1gZAoe*p5!_cH+Aho59< z06fC-WkOl%0CLJ34NKm)CUJ#tm2FGkYzSiZh*)uztOum$9!)-NOg7m*oQ&E30(`I4aX5%@sAd2P^eTYl}e>j{mXj3Kd=wrJN$uWVgFoz zApJxorazAI2U7VP5A_E=%6FEagFhg-g=GLe{DEj`dECbzaERQX=;9Ax5?27a_ydtU z6g~U_TXE~V_ye^HUi|@;N~Kb%R4Uc~psza%-;}@M4?G{B?hkY!sQCkZ2rB+SAA*WM w&BN)4{n-ExSF|MDF6Tf07*qoM6N<$g1=i9uK)l5 delta 1069 zcmV+|1k(G*3D*cEiBL{Q4GJ0x0000DNk~Le0001B0001B2m=5B0M$l^3IG5AMUf>s ze>ShMHmIm@aBzEjdm0)VeaN&z00001bW%=J06^y0W&i*Hm3mZIbVOxyV{&P5bZKvH z004NLQ&wi?^C?`dUi!&v&s2IpMq3^YSxO6q52&Ds_u<@=M~& z<4f~0)AEaQ5t>a%*Q{HVpOcfCg3AnL1y?^8u)hE<*F>_0>+KW(00SRML_t(&f$f=n zZ=)~_#vxmQnvFP^^8G*RJ7@@{R z%l=bJAq2FqMF0Xcq3@UXHw38wcwN?*lBN{bB0-WF3{o^BgfRBwjHky;6x4CG)uP7j zW^4S@ASCF3FtzOcO>ie-vjRAV4enzT7qhsQ`%S4oHO#WWaR>V7`{8I0O|n zJffu$y8a7L)Mvm2fC~Y1oyK*=C}MezUH=In`Y>XJj##TB>3}8!z|v7b-|u_>?hV<> znic>S4!{b+L-l<>U>l6XzyT2e?m&H!;zI%BjJ+^iuu#hevhT8aLmaqjf3N64fa}~4 z2N6qLW268~4<4g{mZ)Jb#Km}soWK`BQ$$zIAEq~jUY{7jis%R?n&~ZxA4!Ktpq2qV zM9%_5any_O5H<8o!4iT4^W#e_mFexzRUPhYldUJ`QmIv64M^dfVWhXSYp&N7xe|YJlP( z!ssYKvX8X}uw0%Uo`Wvu_%*;1D**lNyKJC5bL+msPYfOf@XSn?IzYSp(BJ2g@4Ify zVAFlS8x{bTYdGFPQ6E5U5q@aNKJe*VvCJ#W7#lTKB9vnkmF+XVe;0ujfJi+z)`cgx zI7V^>q#WQyQVYNyxGT7PC4b2Q%*VMZ_7QsuViM=0kUIl7I~cC=$V%uaL?~Za=K%FPedF* zWp~4Z-tXAlKl|%8f7cJjvu97Qjn@wj$U^T(JTs56lKy|HSp?MYVEhV({x>c8_q75g zBZOH35P;{r|sRpcpSu9=Tv>7bs>GKr_G35o**A#zQ3c3kGfx n+W=l3wDbG$Sb_47l?T57r-?UELCYo$00000NkvXXu0mjfq@d;_ diff --git a/mods/content/corporate/icons/clothing/under/pilot_nt.dmi b/mods/content/corporate/icons/clothing/under/pilot_nt.dmi index 3139942a091fdcd7792cfd824980a8c4a085f543..381c7ad5cb0c0be952c9539bbf0336daf4369710 100644 GIT binary patch delta 1088 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 O002ov22Mn-LSTY`Zz!4o diff --git a/mods/content/corporate/icons/clothing/under/work_heph.dmi b/mods/content/corporate/icons/clothing/under/work_heph.dmi index 22208b9cb283ff6de433d2743d6dae19ad330591..acd277e5f765117f4dad169900f7cc603f5bf0ec 100644 GIT binary patch delta 1261 zcmV0001h2m=5B0K2`CDUl&wf1r9) zSad{Xb7OL8aCB*JZU6vyoUM?}3c@fDgwM%Sg!ZiX)2kP0DLvR%D3RToK$?Y3+Thz8 zEa*{0Z}Y*-Fife=P22UVzI1Xy4wk$+scO5EB3Xzg!|@=6L3=ZCg%EYbEQ>_!ppXJA zhs=8^M%ELq`sFh7q&-jRm8fI@t;^`f(z7JDpk|h z&!ZnSiFJ8ky8`F!ea1jvljkGuNf%2Grt;p<(V*FyS^&xWU(lE$T+`(Mw z=$prDHGz~hZ#@~Lma_T(7(OSz8uaNUUi$Fv)>mWCLA>P|-ZDs4rHv}^d{>JHE zHO{j1aRTO_1}RLPK#9+WRv1HTjXA#t>Gb5otQ;b~{8fps24CaFe;|Ea4l`_!c6M-` zGN;?^^oJX;P=6bQaTbiH(zFexwPVfTM9ZL=CTx(7Jz8t9L0Tke6AU)b;;Ob-ErRUC4RqSgRXuN+}=T@QmIrbf0YWWGyfCSoBzrFdh6SrgQ_Cs(OdDwRs5QmIs` zUix~L+Vh_)ZMFHIIDh$^AH9Xgz6QT*?Q$2MMMTf{wK{p_yQ&z1eB!! zw#AU`vkNdN@IPt(4SKR4SE9rBbO>DwRss z+x+ivL+#{$$7?75J6=2a-|^bX|3097{O=Rm$NxT{ef;lu?c{&QYajpnfcEh})$i0l Xd^243y@d9a00000NkvXXu0mjfZ>)K- delta 1229 zcmV;;1Ty=%3YiKaiBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`H>-Bf1Y|& zSad{Xb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1D@x2wg|OkOGD>q3^YSxO z6q52&Ds_u<@=M~&<4f~0)AEaQe-WBZNY@PHrlyvq7E@+OQGQNNY6>nhloee4T)=?? z0CEOfzJ&7~J^%m%+et)0RCt{2T8na{FbpICLj1zcUH<=DZ{@UfdhyCPr8u2AZ-bkO zz*;0f&;QN`wLYf06PjoWK>?U#4p@0Jv*s90;IAH2&_yrRX*SEfGft2kVfoFRr zfS=_YMqoVMZl_<;kcH@j0JRIKJ?2IuFk=}Q=a~~g?lBiR0Zc+1e-#3B5RRuQFGLd~ zU~V__TN=`Vm~NU~8tH@B2P^=mM?*RYSO#1O)B&Q8KTqvWrXrt(Rp4S-h-eS+9rM9D zzy$Vt2*?!92k+nIgLh!e4*#+k8RUVEVl0M6)?4lZ`_(Q2J`><6s1w+gfgHiX7$pU| z9cQT4Dli31UQd~Qf4#$gU->=S)$bv&%2sae%AP3h_iVr4IRRTGvE%brmQN5RMu!TM_$TPnv0L3#t=>rA( zCw-vYeN7+8DnrbVo@Mi<4-orSo|j=VO|B0J0bFhAJgS!GfB!&0(+4tvM+yB!0z37A zOiw3ptUfRdQvAz*l7hqaf%od24Z;TcKrY{D@zg>ez&zE8&*Sw0tY>s9X`&BEh&X`; z`hWyUjo{Jx09N~z?v^d|0kwed`anlVM@Ps1f|qVrsy@&Fsy@&Hnm*8o0M`fF5YY62 zHUwhU7G9Tvf4AcPl?1f%e8{<>33{ikR2EeNHGLpgj;#OuyObWa+Jl>QeZaYB5*$S0 zAaiq~L@|cap!8D+s`>!>4{x7x|00!&L_^Bha^+>IK#>z<^f9XG18x&2h=;mBe*vgNpr#L`fUEZk6gmM_ANU@D zLSH3RePFjhVd?^fR=}H0pkV93yFkHw*nKZBteZelRw(Y9K*1CW+Xae_j*gCwj*gCw zACIpq3*Y45p>oMzUPVCaXE2~I2prEqs`o(OqG>?Dyp`}TBY;6r5fF|ipuE7)f`QQl riY5$dBO1=}1ibdX-|^@be0%%>9l1?^N%L7F00000NkvXXu0mjf{G&W8 diff --git a/mods/content/corporate/icons/clothing/under/work_nt.dmi b/mods/content/corporate/icons/clothing/under/work_nt.dmi index 161202531a51132867b464feaca9fb3a6fda5ddd..7861250dcecbb87fcab0969f0e76f0392e7f05ee 100644 GIT binary patch delta 1143 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 Date: Sun, 2 Mar 2025 08:02:24 +1100 Subject: [PATCH 112/512] Added rolled/sleeve states to Focal jumpsuit. --- .../corporate/icons/clothing/under/focal.dmi | Bin 927 -> 1802 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/under/focal.dmi b/mods/content/corporate/icons/clothing/under/focal.dmi index cec1cf34841544fc207f8b5a3b6f1f15469b9258..d2d9b45e50fdabc5084b2662425c2ebba7ee87f7 100644 GIT binary patch delta 1768 zcmV2m=5B0B!b@Z;>H5e{4+- zhhP%Hi5cj$O?y=rl4KjGcNU^=9)N&=z`(#fJUmoXRBLN%ieDP4aXmUZI#W|qYHDhp za22Pgr*BLvieeJLz`)rsO8fu-00DGTPE!Ct=GbNc006amR9JLGWpiV4X>fFDZ*Bkp zc$}q@%?iRW5QNXkQ-t=c_|vNwe`%2(>?@Q=wkD8fVUxD__6BY?tOX^`4CoXv-SH!dmpUa{hke-&M}*3vB^ z=`WdzqRL;-_5`y;#%GhLiBSLm1%gRLK~#90?VO8t+bR%6EfJ|0Bu9wE?kjyb>Hq)Y z9gwY?CLFLePLs5=Q@afZ%`gJVUWcWwR)Qc1g7BA6)#~c%O4Zdu{k3V@4|=^`>kn+%9gWW!V@7%{(M{X8zE?)|p8oZ` z%cO?_(t0T1W^)_Z+<*dRJv}}*I-|7FJvcnCtKL}a1J;^erS(3Lf7U|eB#sw^dW!?!W*`x^t%2<1ly)PQa`u zG^5PQ*)5%*t#$FYls?T+N3&TPSAFA@wb$2 zNw-NoP~F__cDuU1f4u>>v4ZaC2J`XLM|w{eP||6DBdwq@UE!o#8b8#V&tJZpPv+~F z&)|cspbr(zZk&Pijk2V#+;*fP+AS=gpf~m1-Q72O)u4ca9tJqLAzMIBUw!}alV<4W zkMCfBqz9nh(0#tH!y76fugA|Rm-!?s>25y(XW;(+eorr?f3KQ{hx)F5ctBruN;;P+ z++yejzfA7w7V7=}t$vxL0<3lPX$A`z_s+Tf_?8QB;bspDuu->Cz)SJ|3mD@7;TkXL zuTH$f7H-2iT@VC85ClPZ-*lZ_=X`lf``r9g ze^a%#GwWZdf5Wff-nUhgJO^xl|D^mK%pU>-^S$p3^j(5296b7D0Q1P-Pc0Jj$lp&d zq7(9WIR6wt+35bF06|qKz$1Sj=|_JblG?s_V{6P{_nq@QtOn;x7KQ7XW?h;6*`SrdU;qh#LpP4^Khz2Uwt*!9!e1D&p z{}3Rje^Z2f0Zez9m!BO#3V8Jb*#17hfTH=1_t`Ju@AL8tf*=TjAP9mW2*N*$d-C_Y z%U=jE%kG6LWalR#{-6MEI=WNA4qpal@ny0pK*%Fp)qhtvFh@SCnM*kN+pNRNEqApb-XQ`uh`F8Sg9a&7*CKRNEp- zfq4G@G0EVovGRj1v@N0(h~@7ep(Q#_f7e02Z4re)Jb!;;bQLYr%8iA#MHB)t{e7I{ zy%j*S{H%ayZHp)b;`#eW=qewcUg@c}MO-Y9AP9mW2!bF8f*=TQgLC}*l>eV={}Y_! z->3ZlT>Bs49REJ$|Nq~9fjxi)oa5i4z6I<4WjV*cM}0502e629{Cm{*VtW9KJ~+p} zM}0502e5#1>~GZfVix)m{)Pfh_U}>Oi|qj{;vCx@^%d*>-{e2C?w|rv9Z@X+0000< KMNUMnLSTXlQ*ti= delta 886 zcmV-+1Bv{K4xa}hiBL{Q4GJ0x0000DNk~Le0001B0000$2m=5B0MhD$Jdq(df9SML zdsP>bWE+QI5~z0;qHi9-i5WaRJXBOvYin!3z`%-M8me(UIyyR2Q&VbcYJh-%o^TbX zr>AdBD{M^;z`($YViK%6X8QmD00DGTPE!Ct=GbNc004}7R9JLGWpiV4X>fFDZ*Bkp zc$`yKaB_9`^iy#0_2eo`Eh^5;f6r5}RWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSoZ^zi zl2jm5sXV_ZCq;>iGbOXA7|1u|;!G<_%uR)`;i@u9a})FOGgB0j@>42xi*xcz;>+Vp z^D@)&i*gZ~O;9u|E4cc(fZYTDSIsUP6S;w}0006&Nkl>~8f9w#zK^W-n-(6UJ29$jUjQx?-k0k&Ehd8hhU4XJ5SY@9H z1Te}FptJy*d>kg$5NR2IPjU4J7u-d66!TNbNAj`gv($K;=UMCHD4evI675i;8Hzqqe}2(7506jo**!fz z2nQ`riBjMs0&e(5pH8P=bZG(b^7{7v{Qma(A|xQ6CHjWWfz~`oD_B;ED>$Fe3tf`m zn9D_<^yMPtZxnwbbV)x$wa_Oz3`_OTQqdWUblOBfT4Ib#+5(9Dv5NrAKK^7t$_d0h zzUAN42WcJZ{9U_tf9?7y@*cbE5gmG8pI;f^7T`*H>JGqE|L?s~7QO2}rGQWF4y-b@ zYw%p$2k*qXhRbH|0X6^tb9F2M*o6&%U_G}0GJv}SZ$mWzg3m306p*_EAD|lG!RHo0 z3dr371=Ru~znHFXQR0b+0k;4=Aa^KI09F5g0&4->0!RVeOdV_j(E7Rlmk%1dw2QR> zZnCHcKskWUflBrHnUD)u*{8~OOa2VF`hMI2-wwE0+*807z^;OR1LI08NG!6T6951J M07*qoM6N<$f_EL0$N&HU From 8dc7c0d9edc93884bf0da01353ccbf281f912681 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 2 Mar 2025 08:10:51 +1100 Subject: [PATCH 113/512] Added rolled/sleeve states to Hephaestus jumpsuit. --- .../corporate/icons/clothing/under/heph.dmi | Bin 772 -> 1671 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/under/heph.dmi b/mods/content/corporate/icons/clothing/under/heph.dmi index 1cca7673b4f295e8116f39ff989172c93aae777f..eae302368199aac60e2ddfafda83dae2e3a97c3e 100644 GIT binary patch delta 1655 zcmV--28j8D28RtLiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%QSCJ(p ze_C2vb8~ZTa&&ZgdK$mo8n)9Jvd$Q-$QP)?7Nx&uXJV=-0C=3GlFbUjFc5^# z$y0>(toYNb7ip0m>?@Q=wkD8fVUxD_fA$7@5EZ09w;7mk*nv&Oxww>-$gd^ufxJN{ zP9odxI2()#I-28wGY#gh!)Sbv0isL>B&!n6lp!Dep0kEz3#0x_ZM+5O!B0#RS_?C) zr$V}Gr9-2{4b>yU80w+!oN18SH=NCfe>W~E`ChT&kQH6F*3vB^=`WdzqRL;-fA$2k zM8;>6sEJVk00kXML_t(|ob6lza-%p91SbetQgZR`Ib=8g|L18W;Lfpn6g0TJuA5GU zRH;SJw7{gQiPCing+ifFDEtY_4Or$5>E!qEMU+jSa{H1T3>5}FFWA* zK9bSFU(~<#1p{%E98muyo(!x4z`)8Q12$M{5gK6lxWJYiyix!5dWkcie+(4)m|L?fXxPe zWCQlffW0tq#jg$is2E`Q)PG3FCO#SXnG7I)F#sB%27gk6pn(ccAF`0X%N1&TGVr&+ zfL#SZ12x`Lf1WkK@o_>%f3pE^;^NW)HNf+9i>K!#UZFbA{T`|E-q91tp=(&<#fZNl z2*syV=EK>a1LV^sH0&khc`0oEgkuBVpY8c}^~JFH5swX=6MueO0~P-6czgpsHOPGi zS^n-wPsqw+l;af&g+ifFC=`#4_daLz5W~>-?}(J<`_lS!zVQ^Hei zcpF`S0vGu{;MaWr2K85gsDK3G`JBMN`99+LY?EZ`_2-F2frzOlFwrd3;F9knzHXpi zzrzNS@WcyD>%>xnf3kdET7MS0BDmF|M_1abZ9HmW>XU%;V?uZyRa` zg8hB7`l|q{Fz5TM0p<=$_YgK9uRp(lz>nFQz-OHB$-iOwjOTyesJ`{{3kbBCbLEl3 zXQ*uvN{>QdKwRIhFCf5UtimrZf>{IHFDh|;g+ifFe<&0Rg+ifFC=`#4=6ruS|B#NC zV{|y|kS4G~(tLkbIh?MFWKSo#171j&?=Q0)IXGPWGrBlNWzj#V`#yLfVZOhVaPD|I z#-nA¬oE=KD(x@7&47qh-gMP!p2n`>RN*aWShj)`XgnDBoXajj_gPt7A>52+8vO zjM0qae`$=z%2*RBLc)B1sgbqV=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ> zRWQ*r;NmRLOex6#a*U0*I5Sc+(=$pSf1Kiy#FA7XQ>i?^C?`dUi!&v&s2IpMQe{sou zNtGX$rrES<)8A6N+jm{J-?g3}f<8ki_*tGGV+i|hA3}`w{6p9U(%->OfPXw5UB8L_ zEuc36ZA3soK(rFt$V1-1z^1SH{Vkxk2yK)eThRPoj0E+WhtugaFk3zV@fHwGfDj08 z$R{xX`Y#B`w|oE|0R})9NFcl;f1jS0IQto3`k5dx2k6_}Km))TfaZCLvws5^eii^{ z01U6C8E}~a^aP+UfG7U}xHtd^fNKVL{vBXT0Js9+5CHh70MH}A89_2@H9(>+9uE(2 zm%G9RUwWLN-u(u|c?0YQFpn~_>*r4pOP>HooC*Mukw$<1qG&$iK48rLfB1WV1^)#A zk^>6Iu7JZTH(C`+U>a>pagG#=GOsKX$g=pY9$~a&r}Aa$H3PG zh Date: Sun, 2 Mar 2025 08:19:50 +1100 Subject: [PATCH 114/512] Added rolled/sleeve states to Ward-Takahashi jumpsuit. --- .../corporate/icons/clothing/under/wardt.dmi | Bin 921 -> 1828 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/under/wardt.dmi b/mods/content/corporate/icons/clothing/under/wardt.dmi index bf6eb752378cde18511df83f54cdb16da54c7af0..7caceac5affe88747df6abacd67c93bf0c2af7c6 100644 GIT binary patch delta 1771 zcmV2m=5B0B!b@Z;>G{1~D-) zJv}{H#0Lcz`(%Eyb%om0004WQchCV=-0C=3GlFbUjFc5^#$y0>(toYNb7ip0m>?@Q=wkD8fVUxD_ z_6B zB&!n6lp!Dep0kEz3#0x_ZM+5O!B0#RS_?C)r$V}Gr9-2{4b>yU80w+!oN18SH=NCf ze>W~E`ChT&kQH6F*3vB^=`WdzqRL;-_5`y;#%GhLiBSLm1*l0xK~#90?OY3c+bRq- zaf*M61F`#Bx|?)c|No!75;)%4Aeb%pu}vqd*IGhH0&MynYB!BSp-?Ck31-u7x7&7O z7TP}==IY9}+tyxP2mEYPVRx*g;spw$0eP`#1vkUB*s$_!2w@@ZrltmcC~9 zaT-$r+%-_P<3*l2h+PNn`h!38cg%k}&^(y&E?}4fDt1f_Ab#aDsM*mWbr4^GKMV(d z&liA8l%WGxK-o?S2FkEdK*^p~0%jG61^5GA1Bd)75HoyyG&}S7n9r|n$2&Yuk-|Dq zv)_k+|M(GrxCj7Sz()fYFt`TpHwi4@E3RPs{nt-i0F6&>6-($2hpwZ;yJmki15`j$ zDgf8u2G?UP;H~iY7jP2`xcR&V&>gmLoBa=w4hn@rp-?CkioX#y3h=x=nzO1NL8$MG z`SJJJW$MDozn{{}h@8|5l>ihZd z_*Lg09rFdWt^HOG@Qr-9t9a7)^Z2RnGwtb6HB&7)c2Y8 zbg1!9ju{+J6re8!=qbR7nWR#EU&`Oa^H07Mz&}ln8M9E|m-45P`3`^ZgA4Ej;QQp5 zX)o0GrTmRM(VdEyx9MI__qY>RfKcC;@+WDm&^|>dY*0w`eIb90P;5U&;Ehs!U&fyT zJeLDJR|=4+%QF5L;F(>9lEdxu+ZG_!Jg*10v?HK1MZm0QU?J70?%E&^UjGdaeL5fAujcx_n$= zqr9OD4D!!-jRjcXuR$??{V^%59tvAXX%e;EB|sNJ%TAy*_@@AjJ+`F?TmUQpZzQEZ zm$8oD1C;aE^!=Kh@((qAzp#rbU-@*Q0B5c9ifgMtZAv5y{=5#T-K z{0fCap-?Ck3Wa|{p-?FPY%JFIN0=x)y?hH){ArE%(-i|r_5G0o+6$6YQ!B5a97w3| zpE+U$@Zv>WhKO6>-v9RdC^WeSabukYg~_bBj<3B-8g3u!CqH%RqnS+#*y03HALmM*>vNEkY%b zOyB>712P4?KDP*!Kr(&*jIood=N4hLKnjIIp-?Ck3WY+UP$)hJ=IHl1{l9enJupYV z&*}fA^Y4N=`h8CSFP(o6%+c>T-_`a2mSB#4&-t#l2e1fp^n1>CwLO4En4{lwzN_s4 zEWjN7p7S?dZ4Y1x=IHmF?`nGhOE5>j=X_V&16YJPvODLi(*3`Q{{bg=Yl9bQ;o|@R N002ovPDHLkV1ha1QM3R6 delta 857 zcmV-f1E&0>4w(lbiBL{Q4GJ0x0000DNk~Le0001B0000$2m=5B0MhD$Jdq(U20cAJ zF)=ZbRwRGGz`!3L9~v4OCnqN~G&C6*88V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRLOex6# za*U0*I5Sc+(=$pSoZ^zil2jm5sXV_ZCq;>iGbMkss2IpMY$^KxsR=E9kbq|3mI1aH}iT4inXWU5=`h%8oy~#K;uIrcImv zl`4OARaLrFzZHMCGrH1dxBDf6A|j&=Rspc5R3TX*fOE<2oE)D@Rgy%okzd6Oc!I0z zWUp(Ups4gQIQfzVSpTTda|GuP(6q1wMJhDd-2}w}kpF&8z;ZRXDSA6Gc!CNo_P0T? z1yHba0yeM!cRVzR-W-mO2NbGHfR2lAOt61;P5>9iJlmZMEh=c^#glykU^5{I3(%&p za{@N~dbYb$iwfG4W9%tD?g0P|`xog7fH?sGD$Us4IaP3Wj6Le|7CZv@@OI(q!)=%o z5c}ZN^uBLSLLU?tHJ=hC0;U9HfbZMhpJf0#OvOb4{5_@;!1uTZJ>Lb1aJ{NpU9W#a z{KB3?z(=ltQWKB}SP~kH_9Q(i0C-1-9S-j=0MG(#m(75_cP=ik0E!#{JzSulH-HQ{ zCctq$0GbwFf1qjEv}x0(|63*v__95j*{SenvcoWB10VsoNRR8~_#T4~UH}HkVZi$V z<|1)0S_D|K)(@jJ7ZsOr@X2W{09$_tYOGv=ZD@#uwE$!Ejaqp>#%sE1W7Y$-HXnJw zNAy__z!3_0K)^v-4H!l&cn`|}nt-oSyh%%dxZHdW;BODd6-t3WiM}L;;cM99XU3G3rWz&#JRzY4f_c|do65zyuLFFGYG0u~Zn jbXWu|ZGY_$ZQ}F|iLW9kVNQe(00000NkvXXu0mjfuK8-G From 9a9ca588f1689c355d68acca787c1468c474a919 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 2 Mar 2025 08:23:32 +1100 Subject: [PATCH 115/512] Added missing states to corpo work jumpsuits. --- .../corporate/icons/clothing/under/pcrc.dmi | Bin 1119 -> 1721 bytes .../corporate/icons/clothing/under/work.dmi | Bin 1290 -> 1690 bytes .../icons/clothing/under/work_heph.dmi | Bin 1337 -> 1740 bytes .../icons/clothing/under/work_nt.dmi | Bin 1196 -> 1568 bytes .../icons/clothing/under/work_zeng.dmi | Bin 1196 -> 1579 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/under/pcrc.dmi b/mods/content/corporate/icons/clothing/under/pcrc.dmi index b2d99d1aafc14ee5afcbb23774801a07ece33f06..f3bffe07d5d9934a910e3f1a38cce6c8e928a9d2 100644 GIT binary patch delta 1709 zcmV;e22%Oo2)PYMiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@ZvX%QNKi~v zMZmzoBPumAIYik204_B@G(1N$|Nk8$EImb2Izdj6M-$gd^ufxJN{P9odxI2()#I-28w zGY#gh!)SkekO87h1|+Kz&Xge^{hqUiWDBGIOl`ac=)q4+6Iu&1tEWP`Yo$Y@#0}LW z!WinI?wo0m+BcldhkrLNDfwQp;*b?xw${=uBIz%gilWM2&-MhfM8;>6sEJVk00mx2 zL_t(|ob6nRcH1}%BpAsiyWQq!(*OU|0+6i44F`XW2sOtpCO%#@5Dto@<)PV>0)apv z5cto41P=a#!O7*Eaf&_ufcV?%5YNfoujRN@SRJnjUwfH50tPV0P;KF~y0vIL3^V7mN%lrQCcO9mrLsb6N;x7ff z=HHTFw*VQUSzm{EPH<-bGngfnueD;{TfmvtX_neusK;}Hnf+&@0ImRj45al&!MIuI z@RA@&hDHGvpMKol-9Oyl-TnaaZ|{FTK0f}uzl8T6~K-Ev`=BL=F07>JLQGk9#%#i(t zm(%<4XE=;AU!bYl4(dd(iJtX+z;E(6h|kY{e0fI>v<(f}f=ZnYar0T1-xoi1Cb89lvBKk) z$9?gW&S7SOGS$y$4mh9yUwnUYz!%7Nz!w=8;MVtj@x{T^cQD}s-1@#RzB=fr?<5`! z(y8zJ;s*kOKp+qZ1OkCTAQ1Sn(CtZhkJ9D+ul;P$8((x;!W-Q#%hbJJe_Jcz=84|; zIm`MX(FtyZTekAGci^P8iDZ)#TnVRAHpAoNGhg-5-i0Nrj0<2BRnC9ER=fv?a;;ne zkmlU+`O?(Y1xP^3$LEVITC=skK(_%_)PnB#c~S3Wl>!(n`!6aSW$Rv1V+^b&eK+b(Ww9O?=#QU^M6YP8r1Ht&Re$akV2IQ1_<5DT9R(Dli>759;^hH% zd|H3+g9oY2FMZsW$E|-c;*C#vU1722;bi3~`$>BRpsl6{#HVcm0{x~}>1OkCTAP@)y0)ar_Yhzg7zp}bErMI8nac((s>if@D@^+<>)9D4{f$hkt?{8j& zr#}jybjbh7VLNi_`>Rc5gJ1bd#BCiLLdTI)-@n9=66HbWu_1r-9QpM9&56divT7Y0 zLeG&;-@jPp`bwZ}9UDT&kx$=Wu>OabSIaD|V?*dTa_ak+7|UXB?i?FJ$B|Fp-(oD? zG?_b+c_t+2)a})>!0)apv5C{YUfk5DMV2^&^(*LdF?}0t~eM|qhj=u}` z==UxC-#Y#t*rQ$FBiqB)07kG!zel!*tpN;SkA9DA4_gBm!XEt|*&enAFn~S!J+eJ) z4PXR&^m}A`*c!kH_UQM>_OLa8A?%Uek!?u#|4;k|1i39^;z+j-00000NkvXXu0mjf DEsI<< delta 1102 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 delta 1232 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 N002ovPDHLkV1l=$GyVVo delta 1261 zcmV*-iBL{Q4GJ0x0000DNk~Le0001>0001h2m=5B0K2`CDUl&wf1r9) zSad{Xb7OL8aCB*JZU6vyoUM?}3c@fDgwM%Sg!ZiX)2kP0DLvR%D3RToK$?Y3+Thz8 zEa*{0Z}Y*-Fife=P22UVzI1Xy4wk$+scO5EB3Xzg!|@=6L3=ZCg%EYbEQ>_!ppXJA zhs=8^M%ELq`sFh7q&-jRm8fI@t;^`f(z7JDpk|h z&!ZnSiFJ8ky8`F!ea1jvljkGuNf%2Grt;p<(V*FyS^&xWU(lE$T+`(Mw z=$prDHGz~hZ#@~Lma_T(7(OSz8uaNUUi$Fv)>mWCLA>P|-ZDs4rHv}^d{>JHE zHO{j1aRTO_1}RLPK#9+WRv1HTjXA#t>Gb5otQ;b~{8fps24CaFe;|Ea4l`_!c6M-` zGN;?^^oJX;P=6bQaTbiH(zFexwPVfTM9ZL=CTx(7Jz8t9L0Tke6AU)b;;Ob-ErRUC4RqSgRXuN+}=T@QmIrbf0YWWGyfCSoBzrFdh6SrgQ_Cs(OdDwRs5QmIs` zUix~L+Vh_)ZMFHIIDh$^AH9Xgz6QT*?Q$2MMMTf{wK{p_yQ&z1eB!! zw#AU`vkNdN@IPt(4SKR4SE9rBbO>DwRss z+x+ivL+#{$$7?75J6=2a-|^bX|3097{O=Rm$NxT{ef;lu?c{&QYajpnfcEh})$i0l Xd^243y@d9a00000NkvXXu0mjfdA51y diff --git a/mods/content/corporate/icons/clothing/under/work_nt.dmi b/mods/content/corporate/icons/clothing/under/work_nt.dmi index 7861250dcecbb87fcab0969f0e76f0392e7f05ee..31174887aa70c8adab7ce865883a977d4e763348 100644 GIT binary patch delta 1518 zcmV1Oos70H_9jZjm8If3U?l>Ea3ObtOfin%}uES`2kO87h1|+Kz z&Xge^{hqUiWDBGIOl`ac=)q4+e-l~@GpnaUx@)CFqr?r>Bf=Q!q3)b%klHt#&4+(C zE-Cq5vEq;wUAETJEh6bJnTn#yU(fagvqZ*clc7#3mm9>{bS8rQ=t$!6q)2lE3`ch!$OTFUGC7xNf8FIj$fUkM zD!VX;-dm)7!giCp{TlDL^FBSj6@$OeGGhh?25VS8D?Hcmd!zDg_o`ja=J$nt_Wj%G zclAt8f;s_v)Q^7{^)fjLb>b&e|EsA38pOl;Suf7yj0Hh}P7HH(V(a(ObT+&O^`X01 zxaDka1w7y^lUG+04>p3@e`5H0*n0D&BDp%wwxF?n9ioS!7^^o%h}w$IX%SHi76D5z9i6vY*k-I4GtKa;DU3;-hc}d{-4sX3g8{FQ>6jn|0%r~k=;In z1%KZ%wuAqt^vo*T5enLZ+OPrP|0%tQER`lMSk_Shq5MCg7X=(0p*TcrW-0$q=!Igc z7NGAk(*F~Be^Jm>3znz><^Ku2C{XRZ%h88`^8bWh{Cc=l3tkrC9aH|F(987i;{xA@ z1*HEc^ach71_lNOpA14~LvJZPjbd!>r?)5gEfW_`DpVTqOp-$%UccgF_fg$q8czbpW_LRP(xC04_qo>s11~W zLg;e@j5+$$T1Ptu6e?iw?SR2G^;>#Z1`PN)mH`9aqQ4z5U?3p%S2AF96aHQXjDKK* z?SKI{e@MN7fq{X6fx#yPo&T3O+!%I;?UUg|82%qI)%t(Abu29CdR1lx^4~sO#!5T* zf4LQPt@SGd@#B*G=b=Z=egrQ__JZir{f4|rJe+jSAaMV>cf2?-9g}C1T3+#EFj;E|NXmvWR3&08g zFE9H=$@i3%u7Q9295x{Qzr3tCc~4pC8i;3r8tDDM1m_?AIFPKeVR7{c3=9km3=9lD zex&>TLtx+!RWrX6(*1st2k`nX4O0Dnk_Yhm4oLU=a5qmP&^1W)`*1f;BG4e+@59|( zM2SFybiWUG^CW_7r2Boin=27$8l?JtxSJ~xXd0yYeYl$|5onO^_u+1yMDWq#KSUOW Uv<@&ysQ>@~07*qoM6N<$f`Jy_V*mgE delta 1143 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 delta 1143 zcmV--1c>{q46F$uiBL{Q4GJ0x0000DNk~Le0001>0001h1Oos70Det>D3KvXf1r9) zSad{Xb7OL8aCB*JZU6vyoUM?}3c@fDgwM%Sg!ZiX)2kP0DLvR%D3RToK$?Y3+Thz8 zEa*{0Z}Y*-Fife=P22UVzI1Xy4wk$+scO5EB3Xzg!|@=6L3=ZCg%EYbEQ>_!ppXJA zhs=8^M%ELq`sFh7q&-jRm8fI@t;^`f(z7JDpk|h z&!ZnSiFJ8kqH4#t00nW zrH205q86bJU8*E9*+5CDGa{!d9lNsi8&sY7P>qAY@4W|SnPWiJJ=<&ifBy2EL&Pr- z;^Oj9LM16Zy-#5EP4{4Tc`XWksOhEa2p0a>dWslce&hi@vI^oFBs8q6El zt{y5o41Nrwq>(*jR;>!~$O)2nEz{`uPKFHl)+oIa9H2hK}`e~eXNn~)<2+^f}g zATVtVf$=29zyty}F>o60o&q3E8xuIMsxu+yYY_PRoDg_q8hFBobJ`fr?MCAzoHy8( z^3k7-3<7c3tT8+i8;{2D$V5~-Dsb9_g|yJRUsoCjexNJ}o~Rp}+z4a?uMFQs*7lZ_ zPX>)KFgBf-ut)S>|o&32&BHJ90AXS;u8vPZWwwZg!50ejY=>t4Di2oW zlN;{W_C+d~u!7VD6AB{sL2dsc70f>ns0${%fPGNgO?Po|adB~Z&@uU7;pF*XabS)Q z76<0|U~yoM4;D|34;D|358eT2_QB%G@xkKB@xeO)%|7^F Date: Sun, 2 Mar 2025 08:45:33 +1100 Subject: [PATCH 116/512] Added missing states to corpo pilot jumpsuits. --- .../corporate/icons/clothing/under/pilot.dmi | Bin 1215 -> 1747 bytes .../icons/clothing/under/pilot_heph.dmi | Bin 1223 -> 1757 bytes .../icons/clothing/under/pilot_nt.dmi | Bin 1123 -> 1668 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/content/corporate/icons/clothing/under/pilot.dmi b/mods/content/corporate/icons/clothing/under/pilot.dmi index e7b54b38133de0de5d5f028a9b7e2e52ef0c8af0..956101e2af94be8bdfe12452005308948b692738 100644 GIT binary patch delta 1658 zcmV-=28H>*3DXTBiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@Z;>Hh0kx5U z6n~P<3c@fDgwM%Sg!ZiX)2kP0ksjU?l>Ea3ObtOfin%}uES`2kO87h1|+Kz&Xge^{hqUiWDBGIOl`ac z=)q4+6Iu&1tEWP`Yo$Y@#0}LW!WinI?th$VklHt#&4+(CE-Cq5vEq;wUAETJEh6bJ znTn#yU(fagvqZ*clc{Peoi3-#G*8#@a+*xVV&3?_lmEClPe<6h#aDS7LNLbAcC68c zCdi5Q?Qy))B&ii}*m#se@Z|$jWchK4E)W}BtX5z{N@NgRN}vKW5A%gS1I_emh>ZvN zQF6X~dwAnwiphC*9aD546EJ}|Dt{qmn*b7=PAA&S6H2hb)86qTr597Z0-iTCfgR>+yw%DG-(iw}8v(*#KYoyK<_uzz%pBq|_< z-U5ceY3Qz&_g{}qDkrv7>J|`G*hD-q*f3UZkeajn=V5V*iPZ?5bWz)xp2ReD{ zXo>gE!2(jb4klQ@SHmZ|7Js+}Tt>+p3V z1)Fb)zU>k4sT6>x(04Dudb-uO7EhrD|K*@1h!XVpRw5Ms`<}$~v|`pxAFog-6bgkx zq4?RbPu%DkcsnlB_vP{F_v4knTg|LP4-`Uu|JnH05${2N&FV4ULx1!%9T?)r{|o0W2W@-ZAR%fvTtQP+i^hedwPT zXX#4)^?&_#{Fu1-2fs$)3Rr_fd0eLNx8p}P{=)%QzWmZCK&J1vzk_oeX!*fWg@3-S8 zF8->X^4hOoSn*Y;?>`Yg@#3!KcffiG;P2)7emj0*;ui<0Re!+36d>03+woK43uvkD z`5?11K&J1@;ujv@>a`8z`o1jwVSQj=ABtE5xxO!puTUry3WY+UP$(1%#Xk%G$KM|p zzu{n`VT(ryaeN}m2RSH&$4$Q9Zgw-TiC_9t5xs;|S`YMd+#@QAQ_6il8`z>u8m2*EpJ`Aad08GmHz<6gK@t99gF+nt zs~Z&J_~HgdnL!PGKj99AG``&$6m<)`H7FPl?E+wjLVq0JYz+wTE@gwiTeKS#z(O8h zp-?Ck3WY+UP$(1%#m`2!zJJH6`@EMv>~BH_){#`-zk9JCgFJ@B74VLP`u-hbjKtgc zu7GtYqF4By2Jc9y@2{Zz%Rk}A|5aeOF<}J_M?!u75yO^7k$qRd$FVN79Le}O!@Qtx9G#ttF{Vm2i zO?_jm3k^pyegA>`PHK*I;bo2#3WY+UP$(1%g+ifFd=Ko=?`!%$H~tyequHpmLXJC(hU(^4&@lU}X{T|uAtOwAAJxlsMvVB<(pbLBSdu02v9zX~7==aF> zWj%l%?9uO$?aO)qJ=mk)Biont0J^Y8c1N}<-T#~T5Bipkpz1*=d;kCd07*qoM6N<$ Ef`~*cg8%>k delta 1122 zcmV-o1fBcS4ZjH?iBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`H>-B0iKb7 z6n~J-3WG2ZgwM%S1U*~&hkv*tf7vQkJ2bD4o*7|YZ5%Qr=>Px&fk{L` zRCt{2nvHUsFc5@;f&mMolZ4;@S-X-Gcc#@!oe+z5ddnDRa)SHN4{$qvdsC@Ys-GGL zgZ=w3oRojOOtUfX^K_X{%D+t4>wLXV3n8#J_mH*Z43D^>akMZzznPYGS*LlrjeqMh zl^Twl6ZDX{P0DBY-Wy}EA6fqKh6V(}U;q|e`(?ag5DJaPEjaJRdl!lX*2jnj-o;1= ztlUNsVLfEbJj^S$VJ<-$7h;G`+-;1({ocTM#DEY}8(+LiD=tWIuH1ppJS_`)VJgl5 zg8>M*_HDdj5DEa!KLLCJ5K8%72!9oT>k5GNTAqT&h?R)VN^uww{{$ezjQ<;FB~$<| z0JsoI0EUgqC7eGj9&w)) zp*?^TSbHG<8z!K|IM7)v(cAP$;3@2(4nTqoz=z-u0OApV)Ps2F^C4)&(;GuA+7y<6 zO^-A_33HrJ!hG-nfc!GS-+w5Y@kfiwOOZ;YQmIsbiOhlLu03=n4>@HC+)Ko<3AP?zBf+2NlAynFt<8 diff --git a/mods/content/corporate/icons/clothing/under/pilot_heph.dmi b/mods/content/corporate/icons/clothing/under/pilot_heph.dmi index 1bb0c8227764ce2712d2422ec12169b6fbe8672f..658f129b22c69f03c44528598d906161d6394b8b 100644 GIT binary patch delta 1717 zcmV;m21@zI3Ed4LiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@Z;>HBe>ShM zHmIm@aBzEjdm0)Vz`(#*cp^an0004WQchCV=- z0C=3GlFbUjFc5^#$y0>(toYNb7ip0m>?@Q=wkD8fVUxD__6BB&!n6lp!Dep0kEz3#0x_ zZM+5O!B0#RS_?C)r$V}Gr9-2{4b>yU80w+!oN18SH=NCfe>W~E`ChT&kQH6F*3vB^ z=`WdzqRL;-_5`y;#%GhLiBSLm1%gRLK~#90?OThIn=lLnH#}l`SlCJafB#b}n}jw! zOAc0g$xXFPxEZga2M7*UlcrH96bgl6McW$O|7hDv{?#~i{b0u951~)^Nx685^V{m`S z(FPl2#ADli{KO{770_%vf0aVlrj1OIde6|9+gn$N%3xTM>4DB%C)?%k; zLu@>eA12qPPYrLJ4?Z|>r*rV`a{^{T4oe8pW+4*n#}SWmPbFC3yRK^wnBGXV7|$DQ zAdkm>KA*6OG6lG0D`3eKm=ZirnBa6I3*h-RzX>y>3SfC-z(T;ye?qnckiQi`bO7W9*QT>YKSrz9$PP@ZE$* zKYr@?m>?EFCkXK-e~KTnfMLS_1$~D%$~wM_`E_go9N*Z>#h&7hNH9_thQ|yswY00_ zyBjKb>+lv2&XEP+<$+ru3wSjk;Qs^zH>%z(;*+=@u&RF9+U&FhQUnC6>g$fA2+%Z!2cq)$t02LZMJ7 z6pHT+`@n;qAs@$O`o26qe*b*ppH?I5s22*MzW-?a)0sYka5@73eT49B2w)~E5bOI7 z#y_8!SGJ^#k#9r|1_=1#N;rT`-_JXMP1_^_l;gW(Ko$_c?-+Hs!Rj$QsjhDNKIxwq zXYpmS5I?cZe>-RF@F>iX4gy$*MpOYeeZRH4CqigyRK5+3HSfg+Stih=k66*Wq_@0e_b3iL!Fc%7t>HFpQ`~h6g z%;f?n%E1XPm(4KqeWAWDjo-xE2Qatc8%y1XrTV@!e}43U7Mym9J%smR@*0xr`{nq7 zi@&O;y!Hz-E4~W#{RiR)Ufi|(0a#A~`F***UydJ`_{l*i6)-aei1qz){1Es8O6q$& z$!rJ6^nF?U#M6&@WdpgsFN@!-FAVHU5o;jV_hs=F3WY+UP$(1%g+ihDZvlV({dVyS z4mO$`fAI(*j*mpzCBZ(vowBb5RDEJ$QeZh!N57|RpEd)i!XDY3vQ_E+|HLnFo{P^0F!>h%3jhEB LNkvXXu0mjfdC@iq delta 1178 zcmV;L1ZDf(4aW%~iBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`H>+$e|vj- zaBy%oudp_#s2Um?z`(#TbY-Cc0004WQchCV=- z0C=3Gkj)B%Fc5^#$x{S9Tl(X*m!gP=`U;Y=YZHiB$VNlozM(>UETy;kV7@s_sV;5T z530HLa>c-wygI9Tx0fPWh$h47e<+1PdpB_djyhtFMWW!KkOFMr%m*o^pl96jyJePH zd$OQz1doax#W9VGw-bf=BiFynRUqdO{@Y-OxFUbqDpfl)uaBM?VP0(8$00V(`uzoh($ZSWsEa9!F}ilf4Ci=PAZj3 z^;5%OuzwkbgYus*<7CXsG+w5I^3UV-I$f{hObD#aJ!CC8!+YG&I9eE<-;DEZzKzrP z`gWVgQp5A&1U)2fk@DHS_r@6P&n*9aMFRq1FaR^I{qpvTK`1mjFTr^)-n&pFus%jK z@GeF|U}e3F2R1n0^f2uCxZVJ8yOyV*F=8cRvr-&J#6JPZFysHm zSqT+@3ji(zAYTExkYB+AfW*_-OAHjiOjv;v*5X9wsrU$h=yw6Qe@Fp_VcUkcv?I4d z@e2SJ4uBPajmO_9D*z*I1JgKifIN#U09b_hGyoz6m~OZij2A4#as#_S#uqlbS7r2FXA#(ftVJEPH{Pgg)(h|-e z7LT~kiqIaw39Q|bfB%FDXfY0S7EAOtJrZ~dyQ>3`AOr9r_yd5r2O#wz9{PL;8u9eT zP>VK&C1BGdjZeZH=aVoWyaOP=Oz<~~X8gTH<)uiaQmIs`zeHxo^KyUkRK4waV(%2* zS45Tr2?Vu2Ui=OOxUWdhtIOvDp!j!~1_uJfZ2ufL1gZAoe*p5!_cH+Aho59<06fC- zWkOl%0CLJ34NKm)CUJ#tm2FGkYzSiZh*)uztOum$9!)-NOg7m*oQ&E30(`I4aX5%@sAd2P^eTYl}e>j{mXj3Kd=wrJN$uWVgFozApJxo zrazAI2U7VP5A_E=%6FEagFhg-g=GLe{DEj`dECbzaERQX=;9Ax5?27a_ydtU6g~U_ zTXE~V_ye^HUi|@;N~Kb%R4Uc~psza%-;}@M4?G{B?hkY!sQCkZ2rB+SAA*WM&BN)4{n-ExSF|MDF6Tf07*qoM6N<$f_gO;ZU6uP diff --git a/mods/content/corporate/icons/clothing/under/pilot_nt.dmi b/mods/content/corporate/icons/clothing/under/pilot_nt.dmi index 381c7ad5cb0c0be952c9539bbf0336daf4369710..eb649c789c84488e6b0194690ab633763b9929fc 100644 GIT binary patch delta 1594 zcmV-A2F3Z~2!stGiBL{Q4GJ0x0000DNk~Le0002M0001>2m=5B0B!b@Z;>HS0kx5F z6n~P<3c@fDgwM%Sg!ZiX)2kP0ksjU?l>Ea3ObtOfin%}uES`2kO87h1|+Kz&Xge^{hqUiWDBGIOl`ac z=)q4+6Iu&1tEWP`Yo$Y@#0}LW!WinI?th$VklHt#&4+(CE-Cq5vEq;wUAETJEh6bJ znTn#yU(fagvqZ*clcxS92SS5B| zcU-IQF=!7!M4F8ce=LY##V_AKe=U>6EVTgYBfQkv(Pj!Tc8>GVirzb+>-(Mw=zJPLv4 zr+i?DEHAA9mvW{K$>$6*n1c(MK90tr>!R@>J_;_>?+7ogfI0ba&iQgVUxH5{Kp!KG zvWEfiJdI9RD7={a9e7?^0kcoxa(~X3e9j?tmv|YWOabPEN08;W_%cO^5@3001rSfs zpYz$H6+!{76yVAv!15GeEGs0UHPm=yUt9rn70^G#&onh;fTpUSpv0%LylIAVLYMK4 z2dumTgan+sUfoAI^tVZgua{`9$07cS72qiW4|(T2Z34l2m;ldHbTs1PNnfH$6jNUO(r{Bt5FS8j>kb_PPO3E(C4?g_X+ z8?%Rm&3ObsekhCdlA#q%Df%Mc!R-UFc=I5!_S6$;zn=AqJT=@*ZZgQ zmlJ=tT3C-BD3tpCv;I#DBdeT>dW=Vio`ynLK?Z7l|4IMLiFstJ${2hin#e(>2UjF) zHGLllTTS0b!j|aY*A6g&a=vHO;fb=R5TUv%RdAZVk9Z<@|ApQ9^?&)Y!X1{sry|~a z>Vy)IDmZt2AMy0%{YUbD>)3;d!|5vb^gTY`h7z_r3!C){L-UEB|`=0*KwSNcp==VMSpKJdX?9uOg`ajqH9oVDa z_w;|R{adg{zejx!s{ssQkA9E(9##Vw!XEt|^*yWxFn~S!J?eW{4PXR&^n29zuo}P! s_UQMh?_o87A?%UeQD2kp|4;k|i}^xOVytx!01E&B07*qoM6N<$f(XbBuK)l5 delta 1044 zcmV+v1nc{R4dVzQiBL{Q4GJ0x0000DNk~Le0001h0001h2m=5B0QBII`H>+{0iKa@ z6n~J-3WG2ZgwM%S1U*~&hkv*tf7vQkJ2bD4o*7|YZ5%Qr=>Px&G)Y83 zRCt{2T7hokFbFMP0yb^4|Nq+qck4-~JUlI{bEo5FO(#Lk3*a<7^>Rrh5{cg+Dt3M& zIw}6LvXt^Byvj-OE4L=CaRm%U8G6`DkiqT%P`GMU7QQZ8dCzf_A!@CaQtZ5-_M}{B)+l2NS5Ku@!)HSA!KjP05_>$9ODX%;aj-BkXj`}B6?8~Y&ac|~MBk%8FkZx4Pa5?HPl9#5CACty<A-@9y^zoQap*ND(? z<_|O)*dd+*bQcf@_4B?1_0g{c0)GV!1qxYLNT3T8 zG7u=*L4m?Yd`w`1KoJh`hXsmWf%rZj4e<07DE8N&r$B)j@`%8g9Huz3e|V%okw_#G zi9{mtFXQ$4z%c?pp$`lP``79N{u34Tf6meeeEii@^?{G^9R--64@mbQL|}$KpajR` zIr@NNfnth2U`-qlm}R05C{`$D=mQj}^;7hLXo63DAdyHU5{X12@ju}E%EAxDALs+G zClKocQy4`0z#ImFJ}`$tpbtzU5a Date: Sun, 2 Mar 2025 08:51:21 +1100 Subject: [PATCH 117/512] Adding missing states to Skrell jumpsuit. --- .../icons/clothing/under/skrell_uniform.dmi | Bin 1113 -> 1771 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/species/bayliens/skrell/icons/clothing/under/skrell_uniform.dmi b/mods/species/bayliens/skrell/icons/clothing/under/skrell_uniform.dmi index f36bd4edfbb0f29e682322cb47f381b69959c79f..3d51d61c7d5c7eb0022354698ec5dd6dc36ff943 100644 GIT binary patch delta 1756 zcmYjSeLT~P8sD&a*}O*H!jMJ@vHKC9v{htYGEJwCD|xBoHR7;yo4ou+QV!EZ$2lPj zp-UujU1l~qCF;zvLU9k7yyRuc%r^V|cGtQ6asPOp@8|nG&-ah#c|OnQd8e_WZC4l^ zNx#?(+%`ebogiV}#Wc6NY;g@vc5r@6Vgv$Hb>gK>0pw6e0& z)6>J@aF&*qSS;4w9?Riyy!OXNC?#+TIVc21SeT4elFqAVLMh%c=@-)yQYi^3mtin! z)q~rwwFX@D@_8>q^2IF@ezS2xspaZ{a$?s$Mr?Fhmqd)r)HABb|I753l*!yvzXAX5 zF26I>W+%*L9m59MOsyX_FV^zBE68=zUT7VR&tkx91Ce{14Sp}TwgT^U6nu}Wg94LT zh$Sv5a90@0t-0}d&!q<^>Yi!8wH+||bbq}nf$`qG>h%r4-N`{3(LTp8I^Q)ucF<L2c7|HD7Os6_$`c)!EKh3GY>8P_DBfT_{Bq~Y z3cm}@AWd|dd-!6dw#hu(!6+9KG;$C?s9&*fW0xt?j<~q24SpbaSnAxr7hN>bxXn9} zapCCmn^LY-UY*+c!!#8$mVra>P^!m|8`IqAJ-PyuVB<(CBM<+xdf@4KK7fl^tWD3j zn`mkvoSv6F7!HyA(R-U&2fRI(l;wr+Uk|;90ZK{fB_44kQpMse(*_4$U%Q3EfR?j_ zgk4rkny5*M=L&cz_^S290fy9Y(XjC)DI_qx#gM=f%spxTQj~|XzA<}bX%3|uv?w30 z0khK5{r}|KQ)|XnTiwC|iR<-$%J=K1Z^XnhN+oe<)HbMJY+M~W1l{7y+u}j~sUBaAH z_Q*2w51|~*!}?O^VE*Mx=Ejc zuEN^fh6BoaSw3k=pijh-;PW0txLgxQ-P*S9m+jCRF;!R$xSdq9=$vsZ0Ywi5gEevSfUcb;LOCQ%}THcC}r`zMJTaTC&VWA*JIXzr)EoFc6E*)cjS5X zBta-#5#9J$eOw2_<~4ndf9P9fm$7PT4gGEWIOw4TY-;nWavFHYj_$vyU)K-b+3^IU zrMNd57yvh_B-vl*t30f~;A&|r1pOeR!;EFk?6b{V@7!k9wHO6&cQa6oq@wXcPjJA8 zb?w=Z+EYZ?_*urxg#Z;Zu)C_nOs}%TgjTYtQ^q(}Y^swVfq&AxJ6g9DZZoYG!0OYt zQ{e9)?b%^9kGQ`)cAxZTNE?2v08-(Jpxsf!P;-t08#iPSDGRLDLQ2_;HF|J7oKJdbADXVTRg!G0}AOz-RYBx3R?{UKmPtW z$yi|-Vdo9GrSQq9KKB2$hc2k0Uj~5R+NTGWL2cmsVbbhEbT0-uCfjNDhU}k=*S8UL z>P6e`bj}s{i10GvALtBQ3PaTa1W(!IXTAFHh`1JNY?fONLCwgS;`JWd%Ej~Xh%xC- z9}yC&%nl4PJtkE zdbq=^>>EL{4=!%Ko=<$yliES}-&VdYXI(W@zH?XMY@yIu-4I@a`YG~rk6-k+Nfl!o zLXM@vva|1K1Uz>HVKc vx=i&X ze>yrk8yg!P9UU((FCZWwEG#S^A0H495HvJ29v&ViCnqQMTv_uC9|j)$T#HTOe;#vO@*-G zsxnG*6Z7&jQxuZ&Qz~_fbMi~#%i~M)GSl*lauJ$MNY@PHrlyvq7UMERS;5uM1?({Z zdvZl5Qkt^E0009aNklsk)wF_L6w2_eKXglqUf7S6# zIxDmY`Jt6_r=51%-?fRR`pb_7n2YH!`)LBlGA?Uc{$rA|3Pa;7~ z6pB%b;&KZw3HW81mc@%H#GDgRAWAt)5r7kADnB9)f`zFP5dQkQeoY~z#JDJ}Un9hv z0$~d&mo1142n*cf5(&Z@L(ZIYe~4=k2!K-|PbA`%fyw*iJ+Tm<))<+Q1#^rm{TiX+ z^@v3L&fp0IBvxQuT`cjz5Z(IajP5uHWc*H${E`-*B!U=m3Jd~9{^frXPNhO3-r|Fx z{u7R<1_{`H3d#Yyk^z+pYPfsiPzeG*DFMI`f*JrdV$`oo&`c$`7g^5$f8o0s;3i7A zjULTlWmJfj0yhTmV;6FK1Sso+8X(35Jjn$|Dmp+=jz9Kl5bC}B zI6A&PxYhwp&zvMC3OhF&Jk6OzN-X%{opFF_G_@dI|{JTe|@)gR*|~|ef{9# z&AH1)Z@R-9Z5QWmk7j^}{l>Rm?-~K$^xo9a57nioPb>#ZKU5d)H-23QOFy{wB=rfp z&!N%Yw>|W`d&rA1f~!rSxBr%YaP1VW8uVT@ef{9t+sGj3IGp<6w9`)eJ!Z`R$HN=* z|3Up=_xFSP!JPjOf9i+$Y5p(2()WEoq95QUg7*A>NI$gx{(b&0dSGiu^n;RtbD!q_ z3XaRx4^Hh}Kh6Jj0$V@y2#ooE>%MLM&>`s0|3~$MIsYHk59a)TR6p4B|3Uq5VE#X* z9}dj_$MnO2`Tv-HI57Vo(+>yc|6}^$!2EwqKOE@q$MnO07i!-D%jPShsg5wE00000 LNkvXXu0mjf9OVTw From eb2bedf0c03b451e2680bb456833c926225b09d0 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 15:58:15 +1100 Subject: [PATCH 118/512] Fixed robot module icon test. --- code/modules/mob/living/silicon/robot/modules/_module.dm | 7 +++++++ code/unit_tests/mob_tests.dm | 2 +- test/check-paths.sh | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/silicon/robot/modules/_module.dm b/code/modules/mob/living/silicon/robot/modules/_module.dm index 418ce907e21b..0688dfe61255 100644 --- a/code/modules/mob/living/silicon/robot/modules/_module.dm +++ b/code/modules/mob/living/silicon/robot/modules/_module.dm @@ -58,9 +58,16 @@ var/list/skills = list() // Skills that this module grants. Other skills will remain at minimum levels. var/list/software = list() // Apps to preinstall on robot's inbiult computer +// Override because storage is created very early. +/obj/item/robot_module/New(loc, material_key, reference_only = FALSE) + if(reference_only) + storage = null + ..(loc, material_key) + /obj/item/robot_module/Initialize(ml, material_key, reference_only = FALSE) . = ..() + if(reference_only) return diff --git a/code/unit_tests/mob_tests.dm b/code/unit_tests/mob_tests.dm index 9f0725d7b5ce..f0c9da65cd97 100644 --- a/code/unit_tests/mob_tests.dm +++ b/code/unit_tests/mob_tests.dm @@ -325,7 +325,7 @@ var/list/failures = list() for(var/moduletype in typesof(/obj/item/robot_module)) - var/obj/item/robot_module/mod = new(null, null, TRUE) // Reference copy only; have to do this to access lists. + var/obj/item/robot_module/mod = new moduletype(reference_only = TRUE) // Reference copy only; have to do this to access lists. for(var/sprite in mod.module_sprites) var/check_icon = mod.module_sprites[sprite] if(!check_state_in_icon("world", check_icon)) diff --git a/test/check-paths.sh b/test/check-paths.sh index 4e2cdcdf3f75..8984b116442e 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -41,7 +41,7 @@ exactly 0 "incorrect indentations" '^( {4,})' -P exactly 22 "text2path uses" 'text2path' exactly 4 "update_icon() overrides" '\/update_icon\(' -P exactly 0 "goto uses" '\bgoto\b' -exactly 9 "atom/New uses" '^/(obj|atom|area|mob|turf).*/New\(' +exactly 10 "atom/New uses" '^/(obj|atom|area|mob|turf).*/New\(' exactly 1 "decl/New uses" '^/decl.*/New\(' exactly 3 "tag uses" '(? Date: Wed, 5 Mar 2025 16:10:41 +1100 Subject: [PATCH 119/512] Backported citizenship from the Polaris Neb fork. --- .../backgrounds/background_categories.dm | 8 ++++++ .../backgrounds/citizenship/_citizenship.dm | 18 ++++++++++++ .../citizenship/citizenship_other.dm | 16 +++++++++++ code/modules/mob/living/human/human.dm | 2 +- code/modules/species/species.dm | 2 +- code/modules/species/station/monkey.dm | 7 +++-- code/unit_tests/backgrounds.dm | 9 +++--- maps/~mapsystem/maps.dm | 27 ++++++++++++------ mods/content/fantasy/datum/hnoll/species.dm | 3 ++ mods/content/fantasy/datum/kobaloi/species.dm | 3 ++ mods/content/fantasy/datum/overrides.dm | 12 +++++--- mods/content/fantasy/datum/species.dm | 3 ++ mods/content/xenobiology/species/golem.dm | 7 +++-- mods/species/adherent/datum/species.dm | 3 ++ mods/species/ascent/datum/species.dm | 18 ++++++------ mods/species/drakes/species.dm | 28 +++++++++++++------ mods/species/skrell/datum/species.dm | 3 ++ mods/species/vox/datum/species.dm | 3 ++ nebula.dme | 2 ++ 19 files changed, 132 insertions(+), 42 deletions(-) create mode 100644 code/modules/backgrounds/citizenship/_citizenship.dm create mode 100644 code/modules/backgrounds/citizenship/citizenship_other.dm diff --git a/code/modules/backgrounds/background_categories.dm b/code/modules/backgrounds/background_categories.dm index 61e5f76a0ad0..a9bc106d5f5d 100644 --- a/code/modules/backgrounds/background_categories.dm +++ b/code/modules/backgrounds/background_categories.dm @@ -31,8 +31,16 @@ old_tag = "home_system" uid = "heritage_cat_homeworld" item_type = /decl/background_detail/location + // When citizenship decls are better implemented, remove BACKGROUND_FLAG_CITIZENSHIP from flags. background_flags = BACKGROUND_FLAG_CITIZENSHIP | BACKGROUND_FLAG_LOCATION | BACKGROUND_FLAG_HOMEWORLD | BACKGROUND_FLAG_RESIDENCE +/decl/background_category/citizenship + name = "Citizenship" + old_tag = "citizenship" + uid = "heritage_cat_citizenship" + item_type = /decl/background_detail/citizenship + background_flags = BACKGROUND_FLAG_CITIZENSHIP + /decl/background_category/faction name = "Faction" old_tag = "faction" diff --git a/code/modules/backgrounds/citizenship/_citizenship.dm b/code/modules/backgrounds/citizenship/_citizenship.dm new file mode 100644 index 000000000000..e16cc9455ac7 --- /dev/null +++ b/code/modules/backgrounds/citizenship/_citizenship.dm @@ -0,0 +1,18 @@ +/decl/background_detail/citizenship + abstract_type = /decl/background_detail/citizenship + category = /decl/background_category/citizenship + var/ruling_body = "Other Faction" + var/capital + var/size_heading = "Systems" + var/size_value + var/founded + +/decl/background_detail/citizenship/get_text_details() + . = list() + if(!isnull(capital)) + . += "Capital: [capital]." + if(!isnull(size_value) && !isnull(size_heading)) + . += "Extent: [size_value] [size_heading]." + if(!isnull(founded)) + . += "Founded: [founded]" + . += ..() diff --git a/code/modules/backgrounds/citizenship/citizenship_other.dm b/code/modules/backgrounds/citizenship/citizenship_other.dm new file mode 100644 index 000000000000..d121a81af01a --- /dev/null +++ b/code/modules/backgrounds/citizenship/citizenship_other.dm @@ -0,0 +1,16 @@ +/decl/background_detail/citizenship/other + name = "Other Polity" + uid = "stateless_citizenship" + description = "You are from one of the many small, relatively unknown powers scattered across the galaxy." + language = /decl/language/human/common + secondary_langs = list( + /decl/language/human/common, + /decl/language/sign + ) + +/decl/background_detail/citizenship/stateless + name = "Stateless" + uid = "stateless" + description = "You do not possess any kind of official citizenship." + economic_power = 0 + capital = "None" diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index b0b6ac4559c1..5f1afb8faea7 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -545,7 +545,7 @@ //Syncs background categories/values to the currently set species, and may trigger a language update /mob/living/human/proc/apply_species_background_info() var/update_lang - for(var/cat_type in global.using_map.get_background_categories()) + for(var/cat_type in decls_repository.get_decls_of_subtype(/decl/background_category)) if(species.force_background_info && species.force_background_info[cat_type]) update_lang = TRUE set_background_value(cat_type, species.force_background_info[cat_type], defer_language_update = TRUE) diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 4123ad590039..e2720ffd1596 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -348,7 +348,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 else if(length(available_pronouns) && !default_pronouns) default_pronouns = available_pronouns[1] - for(var/cat_type in global.using_map.get_background_categories()) + for(var/cat_type in decls_repository.get_decls_of_subtype(/decl/background_category)) var/force_val = force_background_info[cat_type] if(force_val) diff --git a/code/modules/species/station/monkey.dm b/code/modules/species/station/monkey.dm index d50c96b24823..60c0c3d97c74 100644 --- a/code/modules/species/station/monkey.dm +++ b/code/modules/species/station/monkey.dm @@ -33,9 +33,10 @@ holder_type = /obj/item/holder force_background_info = list( - /decl/background_category/heritage = /decl/background_detail/heritage/hidden/monkey, - /decl/background_category/homeworld = /decl/background_detail/location/stateless, - /decl/background_category/faction = /decl/background_detail/faction/other + /decl/background_category/heritage = /decl/background_detail/heritage/hidden/monkey, + /decl/background_category/homeworld = /decl/background_detail/location/stateless, + /decl/background_category/citizenship = /decl/background_detail/citizenship/stateless, + /decl/background_category/faction = /decl/background_detail/faction/other ) ai = /datum/mob_controller/monkey diff --git a/code/unit_tests/backgrounds.dm b/code/unit_tests/backgrounds.dm index 6710868f07c6..3896baf0e9cd 100644 --- a/code/unit_tests/backgrounds.dm +++ b/code/unit_tests/backgrounds.dm @@ -3,8 +3,7 @@ /datum/unit_test/background/start_test() - var/list/all_background_tokens = global.using_map.get_background_categories() - + var/list/all_background_categories = decls_repository.get_decls_of_subtype(/decl/background_category) var/fails = 0 for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) if(!islist(species.default_background_info)) @@ -12,7 +11,7 @@ log_bad("Default background info for [species.type] is not a list.") else for(var/cat_type in species.default_background_info) - if(!(cat_type in all_background_tokens)) + if(!(cat_type in all_background_categories)) fails++ log_bad("Default background info for [species.type] contains invalid tag '[cat_type]'.") else @@ -40,7 +39,7 @@ log_bad("Forced background info for [species.type] is not a list.") else for(var/cat_type in species.force_background_info) - if(!(cat_type in all_background_tokens)) + if(!(cat_type in all_background_categories)) fails++ log_bad("Forced background info for [species.type] contains invalid tag '[cat_type]'.") else @@ -67,7 +66,7 @@ fails++ log_bad("Available background info for [species.type] is not a list.") else - for(var/cat_type in all_background_tokens) + for(var/cat_type in all_background_categories) if(!islist(species.available_background_info[cat_type])) fails++ log_bad("Available background info for [species.type] tag '[cat_type]' is invalid type, must be a list.") diff --git a/maps/~mapsystem/maps.dm b/maps/~mapsystem/maps.dm index a5266629ce9e..ff76e866b038 100644 --- a/maps/~mapsystem/maps.dm +++ b/maps/~mapsystem/maps.dm @@ -142,17 +142,19 @@ var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable var/votable = TRUE var/list/available_background_info = list( - /decl/background_category/homeworld = list(/decl/background_detail/location/other), - /decl/background_category/faction = list(/decl/background_detail/faction/other), - /decl/background_category/heritage = list(/decl/background_detail/heritage/other), - /decl/background_category/religion = list(/decl/background_detail/religion/other) + /decl/background_category/citizenship = list(/decl/background_detail/citizenship/other), + /decl/background_category/homeworld = list(/decl/background_detail/location/other), + /decl/background_category/faction = list(/decl/background_detail/faction/other), + /decl/background_category/heritage = list(/decl/background_detail/heritage/other), + /decl/background_category/religion = list(/decl/background_detail/religion/other) ) var/list/default_background_info = list( - /decl/background_category/homeworld = /decl/background_detail/location/other, - /decl/background_category/faction = /decl/background_detail/faction/other, - /decl/background_category/heritage = /decl/background_detail/heritage/other, - /decl/background_category/religion = /decl/background_detail/religion/other + /decl/background_category/citizenship = /decl/background_detail/citizenship/other, + /decl/background_category/homeworld = /decl/background_detail/location/other, + /decl/background_category/faction = /decl/background_detail/faction/other, + /decl/background_category/heritage = /decl/background_detail/heritage/other, + /decl/background_category/religion = /decl/background_detail/religion/other ) var/access_modify_region = list( @@ -194,7 +196,13 @@ var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable "reinforced" ) var/background_categories_generated = FALSE - var/list/_background_categories + // Hard defining this to avoid pulling in unimplemented citizenship decls for the time being. + var/list/_background_categories = list( + /decl/background_category/heritage, + /decl/background_category/homeworld, + /decl/background_category/faction, + /decl/background_category/religion + ) var/default_ui_style @@ -206,6 +214,7 @@ var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable if(!background_categories_generated) if(isnull(_background_categories)) _background_categories = decls_repository.get_decls_of_type(/decl/background_category) + _background_categories = _background_categories?.Copy() || list() // Avoid mutating the cache. else for(var/cat_type in _background_categories) _background_categories[cat_type] = GET_DECL(cat_type) diff --git a/mods/content/fantasy/datum/hnoll/species.dm b/mods/content/fantasy/datum/hnoll/species.dm index 21785afa88a1..e21059381009 100644 --- a/mods/content/fantasy/datum/hnoll/species.dm +++ b/mods/content/fantasy/datum/hnoll/species.dm @@ -32,6 +32,9 @@ base_external_prosthetics_model = null available_background_info = list( + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), /decl/background_category/homeworld = list( /decl/background_detail/location/fantasy, /decl/background_detail/location/fantasy/mountains, diff --git a/mods/content/fantasy/datum/kobaloi/species.dm b/mods/content/fantasy/datum/kobaloi/species.dm index e2eada0ede5f..c34156ee2a9a 100644 --- a/mods/content/fantasy/datum/kobaloi/species.dm +++ b/mods/content/fantasy/datum/kobaloi/species.dm @@ -17,6 +17,9 @@ base_external_prosthetics_model = null available_background_info = list( + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), /decl/background_category/homeworld = list( /decl/background_detail/location/fantasy, /decl/background_detail/location/fantasy/mountains, diff --git a/mods/content/fantasy/datum/overrides.dm b/mods/content/fantasy/datum/overrides.dm index 08b4b54f4de9..da96ea085c32 100644 --- a/mods/content/fantasy/datum/overrides.dm +++ b/mods/content/fantasy/datum/overrides.dm @@ -1,5 +1,8 @@ /decl/species available_background_info = list( + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), /decl/background_category/homeworld = list( /decl/background_detail/location/fantasy, /decl/background_detail/location/fantasy/mountains, @@ -25,10 +28,11 @@ ) ) default_background_info = list( - /decl/background_category/homeworld = /decl/background_detail/location/fantasy, - /decl/background_category/faction = /decl/background_detail/faction/fantasy, - /decl/background_category/heritage = /decl/background_detail/heritage/fantasy, - /decl/background_category/religion = /decl/background_detail/religion/other + /decl/background_category/citizenship = /decl/background_detail/citizenship/other, + /decl/background_category/homeworld = /decl/background_detail/location/fantasy, + /decl/background_category/faction = /decl/background_detail/faction/fantasy, + /decl/background_category/heritage = /decl/background_detail/heritage/fantasy, + /decl/background_category/religion = /decl/background_detail/religion/other ) // Rename wooden prostheses diff --git a/mods/content/fantasy/datum/species.dm b/mods/content/fantasy/datum/species.dm index 40c2c609ea74..6c8e041c8567 100644 --- a/mods/content/fantasy/datum/species.dm +++ b/mods/content/fantasy/datum/species.dm @@ -12,6 +12,9 @@ base_external_prosthetics_model = /decl/bodytype/prosthetic/wooden available_background_info = list( + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), /decl/background_category/homeworld = list( /decl/background_detail/location/fantasy, /decl/background_detail/location/fantasy/mountains, diff --git a/mods/content/xenobiology/species/golem.dm b/mods/content/xenobiology/species/golem.dm index 0c247f87bddd..51b9a2046e88 100644 --- a/mods/content/xenobiology/species/golem.dm +++ b/mods/content/xenobiology/species/golem.dm @@ -34,9 +34,10 @@ available_pronouns = list(/decl/pronouns/neuter) force_background_info = list( - /decl/background_category/heritage = /decl/background_detail/heritage/hidden/cultist, - /decl/background_category/homeworld = /decl/background_detail/location/stateless, - /decl/background_category/faction = /decl/background_detail/faction/other + /decl/background_category/heritage = /decl/background_detail/heritage/hidden/cultist, + /decl/background_category/homeworld = /decl/background_detail/location/stateless, + /decl/background_category/citizenship = /decl/background_detail/citizenship/other, + /decl/background_category/faction = /decl/background_detail/faction/other ) traits = list(/decl/trait/metabolically_inert = TRAIT_LEVEL_EXISTS) diff --git a/mods/species/adherent/datum/species.dm b/mods/species/adherent/datum/species.dm index 938102c15af1..a63f58ceaee3 100644 --- a/mods/species/adherent/datum/species.dm +++ b/mods/species/adherent/datum/species.dm @@ -55,6 +55,9 @@ species_hud = /datum/hud_data/adherent available_background_info = list( + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), /decl/background_category/heritage = list( /decl/background_detail/heritage/adherent ), diff --git a/mods/species/ascent/datum/species.dm b/mods/species/ascent/datum/species.dm index 421eb27a89ed..2a26f97bfba3 100644 --- a/mods/species/ascent/datum/species.dm +++ b/mods/species/ascent/datum/species.dm @@ -72,10 +72,11 @@ spawn_flags = SPECIES_IS_RESTRICTED force_background_info = list( - /decl/background_category/heritage = /decl/background_detail/heritage/ascent, - /decl/background_category/homeworld = /decl/background_detail/location/kharmaani, - /decl/background_category/faction = /decl/background_detail/faction/ascent_alate, - /decl/background_category/religion = /decl/background_detail/religion/kharmaani + /decl/background_category/citizenship = /decl/background_detail/citizenship/other, + /decl/background_category/heritage = /decl/background_detail/heritage/ascent, + /decl/background_category/homeworld = /decl/background_detail/location/kharmaani, + /decl/background_category/faction = /decl/background_detail/faction/ascent_alate, + /decl/background_category/religion = /decl/background_detail/religion/kharmaani ) pain_emotes_with_pain_level = list( @@ -108,8 +109,9 @@ swap_flags = ALLMOBS force_background_info = list( - /decl/background_category/heritage = /decl/background_detail/heritage/ascent, - /decl/background_category/homeworld = /decl/background_detail/location/kharmaani, - /decl/background_category/faction = /decl/background_detail/faction/ascent_gyne, - /decl/background_category/religion = /decl/background_detail/religion/kharmaani + /decl/background_category/citizenship = /decl/background_detail/citizenship/other, + /decl/background_category/heritage = /decl/background_detail/heritage/ascent, + /decl/background_category/homeworld = /decl/background_detail/location/kharmaani, + /decl/background_category/faction = /decl/background_detail/faction/ascent_gyne, + /decl/background_category/religion = /decl/background_detail/religion/kharmaani ) diff --git a/mods/species/drakes/species.dm b/mods/species/drakes/species.dm index 40d272e983ce..78ace9a7326b 100644 --- a/mods/species/drakes/species.dm +++ b/mods/species/drakes/species.dm @@ -23,16 +23,28 @@ ) available_background_info = list( - /decl/background_category/heritage = list(/decl/background_detail/heritage/grafadreka), - /decl/background_category/homeworld = list(/decl/background_detail/location/grafadreka), - /decl/background_category/faction = list(/decl/background_detail/faction/grafadreka), - /decl/background_category/religion = list(/decl/background_detail/religion/grafadreka) + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), + /decl/background_category/heritage = list( + /decl/background_detail/heritage/grafadreka + ), + /decl/background_category/homeworld = list( + /decl/background_detail/location/grafadreka + ), + /decl/background_category/faction = list( + /decl/background_detail/faction/grafadreka + ), + /decl/background_category/religion = list( + /decl/background_detail/religion/grafadreka + ) ) force_background_info = list( - /decl/background_category/heritage = /decl/background_detail/heritage/grafadreka, - /decl/background_category/homeworld = /decl/background_detail/location/grafadreka, - /decl/background_category/faction = /decl/background_detail/faction/grafadreka, - /decl/background_category/religion = /decl/background_detail/religion/grafadreka + /decl/background_category/citizenship = /decl/background_detail/citizenship/other, + /decl/background_category/heritage = /decl/background_detail/heritage/grafadreka, + /decl/background_category/homeworld = /decl/background_detail/location/grafadreka, + /decl/background_category/faction = /decl/background_detail/faction/grafadreka, + /decl/background_category/religion = /decl/background_detail/religion/grafadreka ) species_hud = /datum/hud_data/grafadreka inherent_verbs = list( diff --git a/mods/species/skrell/datum/species.dm b/mods/species/skrell/datum/species.dm index faf6149fd1cc..318bfaef9202 100644 --- a/mods/species/skrell/datum/species.dm +++ b/mods/species/skrell/datum/species.dm @@ -60,6 +60,9 @@ ) available_background_info = list( + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), /decl/background_category/heritage = list( /decl/background_detail/heritage/skrell, /decl/background_detail/heritage/skrell/caste_malish, diff --git a/mods/species/vox/datum/species.dm b/mods/species/vox/datum/species.dm index fb9a026c4404..ec9468a13420 100644 --- a/mods/species/vox/datum/species.dm +++ b/mods/species/vox/datum/species.dm @@ -91,6 +91,9 @@ ) available_background_info = list( + /decl/background_category/citizenship = list( + /decl/background_detail/citizenship/other + ), /decl/background_category/heritage = list( /decl/background_detail/heritage/vox, /decl/background_detail/heritage/vox/salvager, diff --git a/nebula.dme b/nebula.dme index 058ab7b1f380..d3b4a5f2ab33 100644 --- a/nebula.dme +++ b/nebula.dme @@ -1811,6 +1811,8 @@ #include "code\modules\awaymissions\trigger.dm" #include "code\modules\backgrounds\_background.dm" #include "code\modules\backgrounds\background_categories.dm" +#include "code\modules\backgrounds\citizenship\_citizenship.dm" +#include "code\modules\backgrounds\citizenship\citizenship_other.dm" #include "code\modules\backgrounds\faction\_faction.dm" #include "code\modules\backgrounds\faction\factions_human.dm" #include "code\modules\backgrounds\heritage\_heritage.dm" From 45d4f139e08d1aa10f17e750cc1f01ef41147ef6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 16:51:23 +1100 Subject: [PATCH 120/512] Added a background flag completeness unit test. --- code/__defines/backgrounds.dm | 12 ++++++++++++ code/unit_tests/backgrounds.dm | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/code/__defines/backgrounds.dm b/code/__defines/backgrounds.dm index f9fbe1bb6efc..c24f9fa371fa 100644 --- a/code/__defines/backgrounds.dm +++ b/code/__defines/backgrounds.dm @@ -5,3 +5,15 @@ #define BACKGROUND_FLAG_LOCATION BITFLAG(4) #define BACKGROUND_FLAG_RESIDENCE BITFLAG(5) #define BACKGROUND_FLAG_HOMEWORLD BITFLAG(6) + +#ifdef UNIT_TEST +var/global/list/all_background_flags = list( + "BACKGROUND_FLAG_NAMING" = (BACKGROUND_FLAG_NAMING), + "BACKGROUND_FLAG_CITIZENSHIP" = (BACKGROUND_FLAG_CITIZENSHIP), + "BACKGROUND_FLAG_IDEOLOGY" = (BACKGROUND_FLAG_IDEOLOGY), + "BACKGROUND_FLAG_RELIGION" = (BACKGROUND_FLAG_RELIGION), + "BACKGROUND_FLAG_LOCATION" = (BACKGROUND_FLAG_LOCATION), + "BACKGROUND_FLAG_RESIDENCE" = (BACKGROUND_FLAG_RESIDENCE), + "BACKGROUND_FLAG_HOMEWORLD" = (BACKGROUND_FLAG_HOMEWORLD) +) +#endif \ No newline at end of file diff --git a/code/unit_tests/backgrounds.dm b/code/unit_tests/backgrounds.dm index 3896baf0e9cd..7ae0d11df6e6 100644 --- a/code/unit_tests/backgrounds.dm +++ b/code/unit_tests/backgrounds.dm @@ -5,6 +5,18 @@ var/list/all_background_categories = decls_repository.get_decls_of_subtype(/decl/background_category) var/fails = 0 +#ifdef UNIT_TEST + var/list/check_flags = global.all_background_flags.Copy() + for(var/cat_type in all_background_categories) + var/decl/background_category/background_cat = all_background_categories[cat_type] + for(var/background_flag in check_flags) + if(background_cat.background_flags & check_flags[background_flag]) + check_flags -= background_flag + if(length(check_flags)) + fails++ + log_bad("Set of map background categories missing background flags: [english_list(check_flags)]") +#endif + for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species)) if(!islist(species.default_background_info)) fails++ From 8527309104660512b7001efd2c337a73d414bf45 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 17:49:33 +1100 Subject: [PATCH 121/512] Fixed bad dels on reference robot modules. --- .../mob/living/silicon/robot/modules/_module.dm | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/silicon/robot/modules/_module.dm b/code/modules/mob/living/silicon/robot/modules/_module.dm index 0688dfe61255..5de1f45f8dec 100644 --- a/code/modules/mob/living/silicon/robot/modules/_module.dm +++ b/code/modules/mob/living/silicon/robot/modules/_module.dm @@ -161,10 +161,15 @@ .[state] = cicon.ids_to_icons[state] /obj/item/robot_module/Destroy() - QDEL_NULL_LIST(equipment) + for(var/datum/thing in (equipment|synths)) + qdel(thing) + equipment = null + synths = null QDEL_NULL_LIST(synths) - QDEL_NULL(emag) - QDEL_NULL(jetpack) + if(istype(emag)) + QDEL_NULL(emag) + if(istype(jetpack)) + QDEL_NULL(jetpack) . = ..() var/mob/living/silicon/robot/robot = loc if(istype(robot) && robot.module == src) From d8ddaf5a5e6b07de1b453a0d1eebc4a89afc3f65 Mon Sep 17 00:00:00 2001 From: Typhin Date: Sun, 23 Feb 2025 23:38:59 -0600 Subject: [PATCH 122/512] Fix surgery checking surgeon's clothing for blockage instead of patient's Fixes an issue where if the surgeon was wearing a thick material on a body part, they would be unable to perform surgery on a patient even if the patient wasn't wearing anything. Also added to the failure message a section that explains what item is blocking the surgery, removing guesswork. --- code/modules/surgery/_surgery.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/surgery/_surgery.dm b/code/modules/surgery/_surgery.dm index 11b61a35b24a..677e81cd2f10 100644 --- a/code/modules/surgery/_surgery.dm +++ b/code/modules/surgery/_surgery.dm @@ -148,9 +148,9 @@ var/global/list/surgery_tool_exception_cache = list() affected.how_open() < open_threshold)) return FALSE // Check if clothing is blocking access - var/obj/item/I = user.get_covering_equipped_item_by_zone(target_zone) + var/obj/item/I = target.get_covering_equipped_item_by_zone(target_zone) if(I && (I.item_flags & ITEM_FLAG_THICKMATERIAL)) - to_chat(user,SPAN_NOTICE("The material covering this area is too thick for you to do surgery through!")) + to_chat(user,SPAN_NOTICE("The material covering this area (\the [I.name]) is too thick for you to do surgery through!")) return FALSE return affected return FALSE From 2d6a1eb2e026b5c829d3a5cb48fb1959c796aa29 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 23:40:21 +1100 Subject: [PATCH 123/512] Tweaking Typhin's surgery wording slightly. --- code/modules/surgery/_surgery.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/surgery/_surgery.dm b/code/modules/surgery/_surgery.dm index 677e81cd2f10..22235bd3ec31 100644 --- a/code/modules/surgery/_surgery.dm +++ b/code/modules/surgery/_surgery.dm @@ -150,7 +150,7 @@ var/global/list/surgery_tool_exception_cache = list() // Check if clothing is blocking access var/obj/item/I = target.get_covering_equipped_item_by_zone(target_zone) if(I && (I.item_flags & ITEM_FLAG_THICKMATERIAL)) - to_chat(user,SPAN_NOTICE("The material covering this area (\the [I.name]) is too thick for you to do surgery through!")) + to_chat(user,SPAN_NOTICE("\The [I] covering that area is too thick for you to do surgery through!")) return FALSE return affected return FALSE From 71f5846f4b4808d11df6b290c7ee67c8c30bdf49 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 26 Feb 2025 18:11:34 +1100 Subject: [PATCH 124/512] Organs squelch. --- code/modules/organs/organ.dm | 69 +++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm index 644368591096..700736d7bd6f 100644 --- a/code/modules/organs/organ.dm +++ b/code/modules/organs/organ.dm @@ -1,38 +1,59 @@ /obj/item/organ - name = "organ" - icon = 'icons/obj/surgery.dmi' - germ_level = 0 - w_class = ITEM_SIZE_SMALL + name = "organ" + icon = 'icons/obj/surgery.dmi' + germ_level = 0 + w_class = ITEM_SIZE_SMALL default_action_type = /datum/action/item_action/organ - origin_tech = @'{"materials":1,"biotech":1}' - abstract_type = /obj/item/organ + origin_tech = @'{"materials":1,"biotech":1}' + abstract_type = /obj/item/organ + pickup_sound = 'sound/foley/meat1.ogg' + drop_sound = 'sound/foley/meat2.ogg' + hitsound = 'sound/effects/squelch1.ogg' // Strings. - var/organ_tag = "organ" // Unique identifier. - var/organ_category // Identifier for use in organ collections, unused if unset. Would be nice to make this a list, but bodytypes rely on initial() with it. - var/parent_organ = BP_CHEST // Organ holding this object. + /// Unique identifier. + var/organ_tag = "organ" + /// Identifier for use in organ collections, unused if unset. Would be nice to make this a list, but bodytypes rely on initial() with it. + var/organ_category + /// Organ holding this object. + var/parent_organ = BP_CHEST // Status tracking. - var/status = 0 // Various status flags (such as robotic) - var/organ_properties = 0 // A flag for telling what capabilities this organ has. ORGAN_PROP_PROSTHETIC, ORGAN_PROP_CRYSTAL, etc.. - var/vital_to_owner // Cache var for vitality to current owner. + /// Various status flags (such as robotic) + var/status = 0 + /// A flag for telling what capabilities this organ has. ORGAN_PROP_PROSTHETIC, ORGAN_PROP_CRYSTAL, etc.. + var/organ_properties = 0 + /// Cache var for vitality to current owner. + var/vital_to_owner // Reference data. var/datum/mob_snapshot/organ_appearance - var/mob/living/human/owner // Current mob owning the organ. - var/decl/species/species // Original species. - var/decl/bodytype/bodytype // Original bodytype. - var/list/ailments // Current active ailments if any. - var/meat_name // Taken from first owner. + /// Current mob owning the organ. + var/mob/living/human/owner + /// Original species. + var/decl/species/species + /// Original bodytype. + var/decl/bodytype/bodytype + /// Current active ailments if any. + var/list/ailments + /// Taken from first owner. + var/meat_name // Damage vars. - var/damage = 0 // Current damage to the organ - var/min_broken_damage = 30 // Damage before becoming broken - var/max_damage = 30 // Damage cap, including scarring - var/absolute_max_damage = 0 // Lifetime damage cap, ignoring scarring. - var/rejecting // Is this organ already being rejected? - var/death_time // REALTIMEOFDAY at moment of death. - var/scale_max_damage_to_species_health // Whether or not we should scale the damage values of this organ to the owner species. + /// Current damage to the organ + var/damage = 0 + /// Damage before becoming broken + var/min_broken_damage = 30 + /// Damage cap, including scarring + var/max_damage = 30 + /// Lifetime damage cap, ignoring scarring. + var/absolute_max_damage = 0 + /// Is this organ already being rejected? + var/rejecting + /// REALTIMEOFDAY at moment of death. + var/death_time + /// Whether or not we should scale the damage values of this organ to the owner species. + var/scale_max_damage_to_species_health /// Set to true if this organ should return info to Stat(). See get_stat_info(). var/has_stat_info From 0fac5aa651ca22133b46b46068afdb982d01fcf5 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 26 Feb 2025 18:17:49 +1100 Subject: [PATCH 125/512] Corrects args in stun_effect_act() apply_damage(). --- code/modules/mob/living/living_defense.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 0b65799b7933..ab6e9ef1fb52 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -93,7 +93,7 @@ apply_effect(stun_amount, EYE_BLUR) if (agony_amount) - apply_damage(agony_amount, PAIN, def_zone, used_weapon) + apply_damage(agony_amount, PAIN, def_zone = def_zone, used_weapon = used_weapon) apply_effect(agony_amount/10, STUTTER) apply_effect(agony_amount/10, EYE_BLUR) From dddb542f7a4f2ac3c4645f38e45c734d905b2b27 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 23:45:44 +1100 Subject: [PATCH 126/512] Canisters should no longer complain about not receiving power. --- code/game/machinery/atmoalter/canister.dm | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 48e9178a8c70..0529877b38e7 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -1,20 +1,20 @@ /obj/machinery/portable_atmospherics/canister - name = "canister" - icon = 'icons/obj/atmos.dmi' - icon_state = "yellow" - density = TRUE - max_health = 100 - obj_flags = OBJ_FLAG_CONDUCTIBLE - w_class = ITEM_SIZE_GARGANTUAN - construct_state = /decl/machine_construction/pipe/welder - uncreated_component_parts = null - start_pressure = 45 ATM - volume = 1000 - interact_offline = TRUE - matter = list( + name = "canister" + icon = 'icons/obj/atmos.dmi' + icon_state = "yellow" + density = TRUE + max_health = 100 + obj_flags = OBJ_FLAG_CONDUCTIBLE + w_class = ITEM_SIZE_GARGANTUAN + construct_state = /decl/machine_construction/pipe/welder + stat_immune = NOSCREEN | NOINPUT | NOPOWER + start_pressure = 45 ATM + volume = 1000 + interact_offline = TRUE + matter = list( /decl/material/solid/metal/steel = 10 * SHEET_MATERIAL_AMOUNT ) - + uncreated_component_parts = null var/valve_open = FALSE var/release_pressure = ONE_ATMOSPHERE var/release_flow_rate = ATMOS_DEFAULT_VOLUME_PUMP //in L/s From 9cbb843d557a03652651d146f43c30a29d77ea2d Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 23:49:35 +1100 Subject: [PATCH 127/512] Player panel uses a language ref instead of language name. --- code/modules/admin/admin.dm | 4 ++-- code/modules/admin/topic.dm | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 79c44208bc00..a7e19bd44def 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -216,9 +216,9 @@ var/global/BSACooldown = 0 else f = 0 if(L in M.languages) - body += "[L.name]" + body += "[L.name]" else - body += "[L.name]" + body += "[L.name]" body += {"
    diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 8adc77ad2e73..287d40709ffb 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1469,13 +1469,16 @@ if(!istype(M)) to_chat(usr, "[M] is illegal type, must be /mob!") return - var/decl/language/L = SSlore.get_language_by_name(href_list["lang"]) - if(L in M.languages) - if(!M.remove_language(L.type)) - to_chat(usr, "Failed to remove language '[L.name]' from \the [M]!") + var/decl/language/L = locate(href_list["lang"]) + if(istype(L)) + if(L in M.languages) + if(!M.remove_language(L.type)) + to_chat(usr, "Failed to remove language '[L.name]' from \the [M]!") + else + if(!M.add_language(L.type)) + to_chat(usr, "Failed to add language '[L.name]' to \the [M]!") else - if(!M.add_language(L.type)) - to_chat(usr, "Failed to add language '[L.name]' from \the [M]!") + to_chat(usr, "Failed to toggle unknown language on \the [M]!") show_player_panel(M) From 0d99dd0d6de2f0e0b61ea0c20a9219f74bd3508c Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 23:53:01 +1100 Subject: [PATCH 128/512] Suit cyclers now handle space suits in general. --- code/game/machinery/suit_cycler.dm | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm index 7f899870a1cb..3a95a3ea24bb 100644 --- a/code/game/machinery/suit_cycler.dm +++ b/code/game/machinery/suit_cycler.dm @@ -49,7 +49,7 @@ var/target_bodytype var/mob/living/human/occupant - var/obj/item/clothing/suit/space/void/suit + var/obj/item/clothing/suit/space/suit var/obj/item/clothing/head/helmet/space/helmet var/obj/item/clothing/shoes/magboots/boots @@ -148,6 +148,21 @@ target_bodytype = available_bodytypes[1] update_icon() +#ifdef UNIT_TEST + // Pass this off to lateload to make sure any Initialize() overrides on subtypes or modpacks also run. + return INITIALIZE_HINT_LATELOAD + +/obj/machinery/suit_cycler/LateInitialize() + . = ..() + if(suit && !istype(suit)) + log_error("[type] has invalid suit instance: [suit]") + if(helmet && !istype(helmet)) + log_error("[type] has invalid helmet instance: [helmet]") + if(boots && !istype(boots)) + log_error("[type] has invalid suit instance: [boots]") +#endif + + /obj/machinery/suit_cycler/Destroy() if(occupant) occupant.dropInto(loc) @@ -238,14 +253,14 @@ updateUsrDialog() return TRUE - if(istype(I,/obj/item/clothing/suit/space/void)) + if(istype(I,/obj/item/clothing/suit/space)) if(locked) to_chat(user, SPAN_WARNING("The suit cycler is locked.")) return TRUE if(suit) - to_chat(user, SPAN_WARNING("The cycler already contains a voidsuit.")) + to_chat(user, SPAN_WARNING("The cycler already contains a spacesuit.")) return TRUE if(user.try_unequip(I, src)) From 7f4029b647a736d24e786da01fc0ec2388685584 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 5 Mar 2025 23:58:05 +1100 Subject: [PATCH 129/512] Vitals sensor alt interaction is more selective. Fix for accidental recursion in get_vitals_sensor() proc. --- code/modules/clothing/_clothing.dm | 19 +++++++++++++++---- .../modules/clothing/sensors/vitals_sensor.dm | 3 +++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index 31e8219e033a..9b25f567400c 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -401,7 +401,7 @@ /obj/item/clothing/proc/set_sensors(mob/user) if (isobserver(user) || user.incapacitated()) return - var/obj/item/clothing/sensor/vitals/sensor = locate() in accessories + var/obj/item/clothing/sensor/vitals/sensor = get_vitals_sensor() if(sensor) sensor.user_set_sensors(user) @@ -436,6 +436,12 @@ remove_hood(skip_update = TRUE) update_icon() +/obj/item/clothing/proc/get_vitals_sensor() + for(var/obj/item/clothing/accessory in accessories) + var/obj/item/sensor = accessory.get_vitals_sensor() + if(sensor) + return sensor + /obj/item/clothing/get_alt_interactions(var/mob/user) . = ..() var/list/all_clothing_state_modifiers = list() @@ -446,13 +452,18 @@ var/decl/clothing_state_modifier/modifier = GET_DECL(modifier_type) if(modifier.alt_interaction_type) LAZYADD(., modifier.alt_interaction_type) - LAZYADD(., /decl/interaction_handler/clothing_set_sensors) + if(get_vitals_sensor()) + LAZYADD(., /decl/interaction_handler/clothing_set_sensors) /decl/interaction_handler/clothing_set_sensors name = "Set Sensors Level" expected_target_type = /obj/item/clothing +/decl/interaction_handler/clothing_set_sensors/is_possible(atom/target, mob/user, obj/item/prop) + var/obj/item/clothing/clothing = target + return ..() && istype(clothing) && clothing.get_vitals_sensor() + /decl/interaction_handler/clothing_set_sensors/invoked(atom/target, mob/user, obj/item/prop) - var/obj/item/clothing/U = target - U.set_sensors(user) + var/obj/item/clothing/clothing = target + clothing.set_sensors(user) diff --git a/code/modules/clothing/sensors/vitals_sensor.dm b/code/modules/clothing/sensors/vitals_sensor.dm index 8ed94b74013e..236911481d65 100644 --- a/code/modules/clothing/sensors/vitals_sensor.dm +++ b/code/modules/clothing/sensors/vitals_sensor.dm @@ -11,6 +11,9 @@ "Tracking beacon" ) +/obj/item/clothing/sensor/vitals/get_vitals_sensor() + return src + /obj/item/clothing/sensor/vitals/Initialize() . = ..() if(isnull(sensor_mode) || sensor_mode < VITALS_SENSOR_OFF || sensor_mode > VITALS_SENSOR_TRACKING) From 8547dcff9c3d52ab98c2dae57f111ab74a1d1230 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 00:03:00 +1100 Subject: [PATCH 130/512] Slightly cleans up assembly Destroy() logic. Fixes runtime in assembly Destroy(). --- .../game/objects/items/weapons/tanks/tanks.dm | 15 ++++++---- code/modules/assembly/assembly.dm | 15 +++++----- code/modules/assembly/holder.dm | 28 +++++++++++-------- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 931fb10dddfa..7ab26cff0849 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -574,20 +574,23 @@ var/global/list/global/tank_gauge_cache = list() update_icon(TRUE) /obj/item/tank/proc/ignite() //This happens when a bomb is told to explode + var/obj/item/assembly_holder/assy = proxyassembly.assembly - var/ign = assy.a_right - var/obj/item/other = assy.a_left + var/obj/item/igniter = assy.a_right + var/obj/item/other = assy.a_left if (isigniter(assy.a_left)) - ign = assy.a_left - other = assy.a_right + igniter = assy.a_left + other = assy.a_right if(other) other.dropInto(get_turf(src)) - qdel(ign) + if(!QDELETED(igniter)) + qdel(igniter) assy.master = null proxyassembly.assembly = null - qdel(assy) + if(!QDELETED(assy)) + qdel(assy) update_icon(TRUE) air_contents.add_thermal_energy(15000) diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index e583f5664cec..12cae89c707c 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -23,13 +23,14 @@ var/const/WIRE_RADIO_PULSE = 16 //Allows Pulse(1) to send a radio message /obj/item/assembly/Destroy() - if(!QDELETED(holder)) - if(holder.a_left == src) - holder.a_left = null - if(holder.a_right == src) - holder.a_right = null - QDEL_NULL(holder) - else + if(holder) + if(istype(holder)) + if(holder.a_left == src) + holder.a_left = null + if(holder.a_right == src) + holder.a_right = null + if(istype(holder, /datum) && !QDELETED(holder)) + qdel(holder) holder = null return ..() diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index c4ef0fcdbfa7..b5a45ca6acb9 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -20,20 +20,26 @@ global.listening_objects += src /obj/item/assembly_holder/Destroy() - if(!QDELETED(a_left)) - a_left.holder = null - QDEL_NULL(a_left) - else + + if(a_left) + if(a_left.holder == src) + a_left.holder = null + if(!QDELETED(a_left)) + qdel(a_left) a_left = null - if(!QDELETED(a_right)) - a_right.holder = null - QDEL_NULL(a_right) - else + + if(a_right) + if(a_right.holder == src) + a_right.holder = null + if(!QDELETED(a_right)) + qdel(a_right) a_right = null - if(!QDELETED(special_assembly)) - QDEL_NULL(special_assembly) - else + + if(special_assembly) + if(!QDELETED(special_assembly)) + qdel(special_assembly) special_assembly = null + return ..() /obj/item/assembly_holder/proc/attach(var/obj/item/left, var/obj/item/right, var/mob/user) From e9663cfaa7d02a55faea04c88f92ab2823f859af Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 00:09:51 +1100 Subject: [PATCH 131/512] Updates damage overlays on organ dismemberment. --- code/modules/organs/external/_external.dm | 25 +++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index 5917819063cf..8917e89de859 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -1087,9 +1087,19 @@ Note that amputating the affected organ does in fact remove the infection from t if(!clean) owner.shock_stage += min_broken_damage - var/obj/item/organ/external/original_parent = parent var/mob/living/human/victim = owner //Keep a reference for post-removed(). + var/obj/item/organ/external/original_parent = parent owner.remove_organ(src, TRUE, FALSE, ignore_children, update_icon = FALSE) + if(original_parent) + // Traumatic amputation is messy. + if(!clean && disintegrate != DISMEMBER_METHOD_BURN) + original_parent.sever_artery() + // Leave a big ol hole. + var/datum/wound/lost_limb/stump = new(src, disintegrate, clean) + stump.parent_organ = original_parent + LAZYADD(original_parent.wounds, stump) + original_parent.update_damages() + var/remaining_organs = victim.get_external_organs() if(istype(victim) && !QDELETED(victim)) // If they are down to their last organ, just spawn the organ and delete them. @@ -1101,21 +1111,10 @@ Note that amputating the affected organ does in fact remove the infection from t victim.dump_contents() qdel(victim) else // We deliberately skip queuing this via remove_organ() above due to potentially immediately deleting the mob. + victim.update_damage_overlays(FALSE) victim.regenerate_body_icon = TRUE victim.queue_icon_update() - if(original_parent) - - // Traumatic amputation is messy. - if(!clean && disintegrate != DISMEMBER_METHOD_BURN) - original_parent.sever_artery() - - // Leave a big ol hole. - var/datum/wound/lost_limb/stump = new(src, disintegrate, clean) - stump.parent_organ = original_parent - LAZYADD(original_parent.wounds, stump) - original_parent.update_damages() - if(QDELETED(src)) return From 1a81c9f55ab84d702622a4c8ee942c3015e86bcf Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 00:38:08 +1100 Subject: [PATCH 132/512] Fix for moving in space while self-grabbed. More fixes around moving in space while selfgrabbed. --- code/game/atoms_movable.dm | 9 ++++++--- code/modules/mechs/mech_movement.dm | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index bb82fc706188..8ab907fda4f6 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -58,20 +58,23 @@ SSspacedrift.processing[src] = src return 1 -//return 0 to space drift, 1 to stop, -1 for mobs to handle space slips +//return SPACE_MOVE_FORBIDDEN to space drift, SPACE_MOVE_PERMITTED to stop, SPACE_MOVE_SUPPORTED for mobs to handle space slips /atom/movable/proc/is_space_movement_permitted(allow_movement = FALSE) if(!simulated) return SPACE_MOVE_PERMITTED if(has_gravity()) return SPACE_MOVE_PERMITTED - if(length(grabbed_by)) - return SPACE_MOVE_PERMITTED if(throwing) return SPACE_MOVE_PERMITTED if(anchored) return SPACE_MOVE_PERMITTED if(!isturf(loc)) return SPACE_MOVE_PERMITTED + if(length(grabbed_by)) + for(var/obj/item/grab/grab as anything in grabbed_by) + if(grab.assailant == src) + continue + return SPACE_MOVE_PERMITTED if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier return SPACE_MOVE_SUPPORTED return SPACE_MOVE_FORBIDDEN diff --git a/code/modules/mechs/mech_movement.dm b/code/modules/mechs/mech_movement.dm index 46d8c67a3e35..40f325d3c3a3 100644 --- a/code/modules/mechs/mech_movement.dm +++ b/code/modules/mechs/mech_movement.dm @@ -145,12 +145,22 @@ . = SPACE_MOVE_FORBIDDEN anchored = FALSE //Regardless of modules, emp prevents control - if(has_gravity() || throwing || !isturf(loc) || length(grabbed_by) || !can_slip(magboots_only = TRUE) || locate(/obj/structure/lattice) in range(1, get_turf(src))) - . = SPACE_MOVE_PERMITTED - else - var/obj/item/mech_equipment/ionjets/J = hardpoints[HARDPOINT_BACK] - if(istype(J) && ((allow_movement || J.stabilizers) && J.provides_thrust())) + + if(length(grabbed_by)) + for(var/obj/item/grab/grab as anything in grabbed_by) + if(grab.assailant == src) + continue . = SPACE_MOVE_PERMITTED + break + + if(. != SPACE_MOVE_PERMITTED) + if(has_gravity() || throwing || !isturf(loc) || length(grabbed_by) || !can_slip(magboots_only = TRUE) || locate(/obj/structure/lattice) in range(1, get_turf(src))) + . = SPACE_MOVE_PERMITTED + else + var/obj/item/mech_equipment/ionjets/J = hardpoints[HARDPOINT_BACK] + if(istype(J) && ((allow_movement || J.stabilizers) && J.provides_thrust())) + . = SPACE_MOVE_PERMITTED + if(. == SPACE_MOVE_PERMITTED) anchored = TRUE From f5553b5c1c8922ad9562682e571e3eb48488ae5f Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 00:38:17 +1100 Subject: [PATCH 133/512] Fix for runtimes in bottle overlays. --- code/modules/reagents/reagent_containers/glass/bottle.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 094887c87ac4..8dc73f68d50b 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -44,7 +44,7 @@ var/image/overglass = mutable_appearance(icon, "[icon_state]_over", color) overglass.alpha = alpha * ((alpha/255) ** 3) add_overlay(overglass) - if(material.reflectiveness >= MAT_VALUE_SHINY) + if(istype(material) && material.reflectiveness >= MAT_VALUE_SHINY) var/mutable_appearance/shine = mutable_appearance(icon, "[icon_state]_shine", adjust_brightness(color, 20 + material.reflectiveness)) shine.alpha = material.reflectiveness * 3 add_overlay(shine) From 70b8ece0e144ff4ec6113dc16955ee82a75c07ed Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 01:06:44 +1100 Subject: [PATCH 134/512] Fixes runtime with qdeleted items dropped into a recycler. --- code/modules/fabrication/recycler.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/fabrication/recycler.dm b/code/modules/fabrication/recycler.dm index 47056aba3e7b..ffbe9858f913 100644 --- a/code/modules/fabrication/recycler.dm +++ b/code/modules/fabrication/recycler.dm @@ -73,7 +73,9 @@ qdel(munching) for(var/obj/item/thing in fell_out) - if(storage?.can_be_inserted(thing)) + if(QDELETED(thing)) + fell_out -= thing + else if(storage?.can_be_inserted(thing)) fell_out -= thing storage.handle_item_insertion(null, thing) From 9390c07674cbfd27b56b33a90ec7d428f4effd18 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 01:24:22 +1100 Subject: [PATCH 135/512] Added relaymove() override for suit cyclers. --- code/game/machinery/suit_cycler.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm index 3a95a3ea24bb..6528dc3a5c54 100644 --- a/code/game/machinery/suit_cycler.dm +++ b/code/game/machinery/suit_cycler.dm @@ -481,6 +481,11 @@ return eject_occupant(usr) +/obj/machinery/suit_cycler/relaymove(var/mob/user) + ..() + if(occupant == user) + eject_occupant(user) + /obj/machinery/suit_cycler/proc/eject_occupant(mob/user) if(locked || active) From 2f1b14cfe70aaefad7c68e9a1e1d53292e0db7c5 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 01:35:57 +1100 Subject: [PATCH 136/512] Restricted ERT and Merc cameras from station camera monitoring. --- .../file_system/programs/generic/camera.dm | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/code/modules/modular_computers/file_system/programs/generic/camera.dm b/code/modules/modular_computers/file_system/programs/generic/camera.dm index 290bf6c7124d..6f167e4682b3 100644 --- a/code/modules/modular_computers/file_system/programs/generic/camera.dm +++ b/code/modules/modular_computers/file_system/programs/generic/camera.dm @@ -19,6 +19,30 @@ var/list/viewers = list() var/bypass_access = FALSE +/datum/nano_module/program/camera_monitor/proc/get_forbidden_channels() + var/static/list/forbidden_channels = list( + (CAMERA_CHANNEL_ERT), + (CAMERA_CHANNEL_MERCENARY) + ) + return forbidden_channels + +/datum/nano_module/program/camera_monitor/ert + name = "ERT Camera Monitoring program" + +/datum/nano_module/program/camera_monitor/ert/get_forbidden_channels() + var/static/list/forbidden_channels = list( + (CAMERA_CHANNEL_MERCENARY) + ) + +/datum/nano_module/program/camera_monitor/mercenary + name = "Mercenary Camera Monitoring program" + +/datum/nano_module/program/camera_monitor/mercenary/get_forbidden_channels() + var/static/list/forbidden_channels = list( + (CAMERA_CHANNEL_ERT) + ) + return forbidden_channels + /datum/nano_module/program/camera_monitor/Destroy() unlook_all() . = ..() @@ -34,6 +58,7 @@ var/list/cameras_by_channel = get_cameras_by_channel() for(var/channel in cameras_by_channel) all_channels += channel + all_channels -= get_forbidden_channels() data["channels"] = all_channels From 78746395d7c9e800de4a30fbf72d421febbf5901 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 6 Mar 2025 01:41:54 +1100 Subject: [PATCH 137/512] Disables client spinning verbs. --- code/modules/client/movement.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/client/movement.dm b/code/modules/client/movement.dm index efcf51c02ee2..47b5ff8c256f 100644 --- a/code/modules/client/movement.dm +++ b/code/modules/client/movement.dm @@ -2,7 +2,7 @@ /client/New() ..() dir = NORTH - +/* Commenting out due to being very broken. Consider removing and officially not supporting client dir changes. /client/verb/spinleft() set name = "Spin View CCW" set category = "OOC" @@ -12,4 +12,4 @@ set name = "Spin View CW" set category = "OOC" dir = turn(dir, -90) - +*/ \ No newline at end of file From 131a157f18e13a73889c6528b8224c18acfafd1b Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Fri, 7 Mar 2025 00:53:01 +0000 Subject: [PATCH 138/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 9bd641f320f0..6c9d76150a95 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -126,12 +126,6 @@

    MistakeNot4892 updated:

    • Mud and blood can now leave footprints.
    - -

    03 January 2025

    -

    MistakeNot4892 updated:

    -
      -
    • Raw plant oil no longer works as lantern fuel; it must be mixed with powdered graphite first.
    • -

From f3854a1f83c2b27e1fb428d66e2507cd377b89f0 Mon Sep 17 00:00:00 2001 From: Cerebulon Date: Wed, 5 Mar 2025 21:55:46 +0000 Subject: [PATCH 139/512] Various Polaris sprite ports --- icons/obj/items/grenades/clusterbang.dmi | Bin 730 -> 1854 bytes .../items/grenades/clusterbang_segment.dmi | Bin 686 -> 2265 bytes icons/obj/items/grenades/concussion.dmi | Bin 753 -> 1224 bytes icons/obj/items/grenades/delivery.dmi | Bin 670 -> 1679 bytes icons/obj/items/grenades/emp.dmi | Bin 676 -> 829 bytes icons/obj/items/grenades/emp_old.dmi | Bin 643 -> 777 bytes icons/obj/items/grenades/flashbang.dmi | Bin 629 -> 1466 bytes icons/obj/items/grenades/frag.dmi | Bin 671 -> 1323 bytes icons/obj/items/grenades/grenade.dmi | Bin 622 -> 1395 bytes icons/obj/items/grenades/grenade_chem.dmi | Bin 671 -> 1308 bytes icons/obj/items/storage/portafreezer.dmi | Bin 346 -> 362 bytes icons/obj/machines/fabricators/bioprinter.dmi | Bin 1145 -> 1724 bytes icons/obj/structures/displaycase.dmi | Bin 2210 -> 769 bytes icons/obj/structures/morgue.dmi | Bin 2511 -> 1648 bytes icons/obj/terminals.dmi | Bin 19958 -> 26173 bytes icons/obj/watercloset.dmi | Bin 20639 -> 18514 bytes 16 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/items/grenades/clusterbang.dmi b/icons/obj/items/grenades/clusterbang.dmi index c2558423c4af7c20ce38a5c1d43be8c8c5546edf..0c82ea4e6524fad807bd2732cc263d225a8201e8 100644 GIT binary patch literal 1854 zcmb_dc~BGf68?n<;R>gsPY@8VNI<{_i-M6$?!-hy&;)`~5acotKn@{*C1Nm8%ke~L z2vs1wG%;L4F-97A99mF{B;1HqBoX9LAVs8MrvLTNcIMmtW_D-4`DS)@HW!C=hpX>Y z2LQl5JzP&Kn7SFNDvB&ZUwEn@ZpxVeifd?mNL<7fNx@>sN)1;w37_qcxU%df7 z^A!9}Uw6w!1T&inz=2u-g3F+QbNxNDtRo4QW84Cy5q)iFM!>0^PZI?qv~*i!*9u)$}N zqKsqq`7Wh7{I=#g@xic%!HzQx z^Ip@r;)Ns`^4-Qa0Yj0L_ezy7YF_r&N!?6!s9c$~CbTNzSlCug6?#N*NeR7kN&eaU zAOsNUt{jb-hJNwcL{01O7zEhLL*CKlcME354i=8$gz!=o(Df!xG5z6@0FIqmGm|do z>mf#zM+KKA+eAuWD>5zY|Blu>u3y;EK`E_jv)0_~bQ9h2s=ykfe@!=^M;&lI2SMAh zd21)P&)0ZcdEswzWk^d$$dlzF?fG})Pa)5iw$nH=|FKzLLDy0!D{8yWEw`V7tyL=; zl>Z9>lGoXerT}!1+r|Z{q;N>>%!Yu2@S4mE(b#lc())>He;$l~ILLrf{cO&zZ8Tbf z=b5>b(J8x%Wb)Put2mKASGk$Og~3)zst$qh&Z4{ZwhzI*FNM3HARylUlD||@L5OXi z_4NtokN1z-sXzE4*8Y5ASe&ryj*kkI&$vCHOuPeeX6c|XE{95xy)a2Ke_MEvc@vQF zkqM|GWvcBGBNPxqjJa~PyM{&Dz&wRJSAT@no_bV>UM?R^0w<>94AE;QhIs@U3jT_e(N@mD zmi6`u*P`MU(*+l~#c+};`)x;lJ(P@ma99N=Sd4C3oa&SWk4pboVOH_dDssNg+RIlQ z1wQ&@%p3b#R3%lK)wk+21^okb>O*dK-`hs-Af7W&WX?B-hdz39qNM-f8NPY{Gst!Q z<*+6+U1-v%vYp;xA)L?_Sr>ThEi9-ATKL(o_lE|+!l{A+uls2P_#p%OIrfG+oPE#r?K^ffvNjaOCdG)I{Umfok>?vG-M>Sf*{z1-`KA)Q)# z_0+@$G)7)tKp*o&XIIw^Jq@f(mq&Q>ekjl}BSVP1RzZ*t&{H}IGP#4U>G$2Jg!CX^ z-qkTXZGV^sP2cGk7Wfx1gaa=Jr=fFmr*LX7mzAzmRswTwUs8NVme)Xilozi%x<`Hf zFsF|fI+nI?C;muK`6b^qXiWopg1)Y1&gu^W*r?0o8ZX(BK*FrhGoMwSY|qJdRA`P2 z?1|Y_yy*KdlgOM{jZaQ6p3^op!fsLfCky=h?4}{qo@#7)U2$>o^Wou}Y&N@!)HKdP zj41hFFmksw$kNh%H(DjCNAc>QA&&E+K{px;<)s0DJniv|-3a&!Ooy>(3D|ITQ=`A3 aYy%WIH1?yL%~^_v2s}?>UAfM|S$_fr5=Y|z delta 696 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 delta 673 zcmV;S0$%;u5v~Q08Gi!+008vhk@)}s06b7kR7JqRz#bkRNl8g$WMuzq+U|Fi&y zhll^<0KmY&|7J5hJUk&GAvZTSEiEl5C@2gJ3;+NCm1qD62nY$=KxO~{00DGTPE!Ct z=GbNc006FfR9JLGWpiV4X>fFDZ*Bkpc$}S(%?iRW5QNXkQ-6f^YQ>*ky-17nU|*r6 zW;F|GBFWm)w>R2Lg$m+rW|@y2CKbo>RMnz5SG)%w&{=U1`Fg|IfQoc9`yFQ*@TO@p zfh0kc$>6+E31l&Unvwd^N$XIF)~PWI z#!+J$E$ysbzJL64f%JcqEg1U7rJ}5h_smaoR&BZXhYJJ%00Cx6L_t(|obA}_a)K}r zhG7ycQ01WZ{_nK`bZpCJVI5+oRW)ItV4i$^7;T_i+@7^-}ui-ssKmrhfco*$+`J= z4~tNjF5#JvF2a5H!!amRE<*Ge+|U1b5ym@_A;4h@Fn$#{pCW*A1?B)hz6jTLAj$ez zEBN*&ZM|c3D}}dEud91>$4H%F?i5@oc{>*b<-@0_=4NH&+1w004kj zv-JN;m;dyu0aO1U@A8#0dRJ!a|D#>LRz~kjZT)|=%h$?`A5xiC;E6J8uLi7JU@o)v zYQT61?PYj1000000NBU*a?YIKT4fH9eFZLGnHmEC!0x^QgAEEdsd16}00000NkvXX Hu0mjfX4^7X diff --git a/icons/obj/items/grenades/concussion.dmi b/icons/obj/items/grenades/concussion.dmi index e66e3839cf8a84212b6857f451533f45f2847738..413769a7765f0a3c89a23a4932ee08e5d50b9a41 100644 GIT binary patch literal 1224 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSYpOybN?cNllZ!G7N;32F7#J$% z%ssP_ugQR+<>AiSF77o+OE#4m3LIuw@6fe&n`fqPwBnw<&E3t8k1I}okM9dE&a1u> z>zyvT=p&!Z)qf5rlTt1{urTu4Vq`uyPFZcDh=tML87-gPlD-t_F8Z3ep;^o?ZHkAm zl7*JnI!7O^rp0%34&Q&eBInmFUAr6GzZW@+mOrkW@@UeTHFn8vogras9wb=16`R!d z?#g~C98jLSd)71C)eH>G*F9YvLn`LHy?Z|Ua)Qk9kNHOe#X5@5crW4NdUR3#f5Si4 zy;V0CCbBbg-A-K0Q#E}dJ3F6|<1AG^U957@kz{8yG&2To&_@j;f z#f`e>KTk^AyfQV~Rih|Q_IPA9L$8~1pqJ;;powb^SI(Orq9qFCExu@=)U@c?)zUe| zJDGHJbUHdbR$tw;O!nO8Jxi`;MXGO4?*hse&Z*>Q(A&4MAV9KnQZ=bGRQCa%t_@nEGHhxqSAja|de3#Ca zaO+o%;NJ7<5=XbBGx8W4F$iCO{<_BQpoXj5?8*Pt?)vdQsE?RGKlSb(jZ~T0d%hj6 zW++(BmhkG=pO9;%pBGOl&G~fW{>*TO%h#SS@0xKNY{)fthU?F#?_Up8{hYbsv9E#! z8$%ysLo&ky2?mOo*74sME`O@EpE-NB@a=7>+1aO0sJ_{J;D)w?0L!(h(SU#CH`O{M_O_H(R;FQ0V#2sl)IioGs+dmFp`y4QS40uwK-XV`6h``WEz zX_|sR^v~@6)mzG6@aYNv_7SOtAv6-+PL%5cj@i7 W)0Fkz>x2P|CI(MeKbLh*2~7Zd%^T4G delta 740 zcmVN?arc763a-5j;FRAt50*H#aRUEhs1`z`($Hk5nN50004WQchCV=-0C=2JR&a84_w-Y6@%7{?OMfjY&dkqKuvIY8GvMMZ z&rB)F0CJ3txHvOXGt)ClAe`co#FA7XQ>i?^C?`dUi!&v&s2IpM$kv&Znp1*HpR$6hp9?s! z08rjt9F)@#D1QI|0m4Z{K~#90?U>P$gCGn=jSFH^YwQ32>=L2fZq*_q0ro8mg@rEaivs^7$+VOx6e3+NuIFzC(UAkbeMc$!G$$w18=ue+J_;3lUw~o6=3!TEeD5i zsRB-|!1Xq~8uY{MstI&r;1ycQUL&AZ;L1bw+n}!oRt4A_h=MpobOCh*HVAaVV05^n z2{Z|TnSYzAfb2qXh?k(Bf|S58xu;h^1UOVd3Xu{>H*kUA$9%$000000C*EhFF(`yC*R4KC9>Q`&2;`TKh=7zn&ly| z*ho$r@0g!zK3C21IReYQ{A}l+cqeO?fL?*zcU^L3xlg8T!t8f)W&r>I00000fDd5H zuYscZTe`B6`J4LE|0J-Yh28RNAcJHRzxNWP1$N$q8GjJ~00000000000002sO?(3n W{1x=PgAj!P00008yVWr3fH4Hhoo+Y8_VWlWt_r1Ki9hRP+09|&8#ccJQRh*DRNDD zm^{oXn=20y63SC#Nvx6N+|`3p1laxL3p-D$C4VFxJ~zWH(u zCrMwG2KI=oafP@JLd4S>{WoZAOWVFA${g$VA2Ou&br(8RGtbylZMFT%h^oqmN$r$R z7LuPrGh7^ucRg|G96_Z7MiJt%n$Z@qUIsfO9DcVaOc}nuu^H4BU?9&bIxe~Cck-yw z%s9#Ok>4GT+%PVbXd}R}j4N+I?Ck8!!%gAb zcJD@OsGjlFj^!F(%}TPy^tK61nh~eT{r0m99fxWz*n0{KpZgHO&RcW<76Thootrm? zVPXq@NK3y7z4ZZJ*;%08v8G{vgbFwEnq?O{vc1_zxYVqVX2zMVYX(#ZsYQ@yOSMS1^8gZw^rqVm zaNE4`8%~K3BqS4t|7LXm8TOZgPA72JGy`i~YlqtvF9jb(xPrT88Nx?$P=~u9jfp zf!-d++SwCE?#?S?IM8~{*K2iDZJI^`(z(~6!l<5>1+`d z96b1S$BO2QM%|K1N=n?v;=bKld9@&3luhrd3F46KuXuWQZB(K~{vR4>HSKCsR@4wP zCML#2?>n;0SooG>kwbFBN+mm(QTnv!JqLPy*jWnYp~U`vHNZA<3Vqp_EOYX+0aywk zn(u`rmIt=vOoWsN_W82+L4${C?dm;Sr1ucO=zIXQ$B(*IXG4&T@@kuKZ~$j@?0|$o z>+bVTnVAl2wVL(z*2~(jJ6nI!Rw6~WrG0-Y3)PUE;8Iu4k;|D1)LO_WoU_g*Zeefj zX}mQdUhw1d-u_0mbUnC9TT-dkBWV?%Qi)6(`B6JD?(el{wANk=gV$XGaFP=NdRbJm zlIdf%^lmqwJ^IdVk8LU4(Ar}MVDE%F?fJyvj@YG4x#jkg-F>Hzg!`rD>Fqu-(Ol?hym`WJEqsN)l^gnPb(v0OCUU( zgw@7jBiO;D;ek(kGok(dflSYH`1ddFkY21P;o!7rA1;2=XYSU`>HMl)u4AJ7{EOON zC_ThAcN6_$5B02wjl)#MY&VDlC_V^cu@2-k`%=|%x}IKYwp2RlT-=%R@*+_@zHDu1 zZbm$3)GqR2T$#&mD%MI?-O3CP2bD`hDU>ziu?E1U{c@UY@!pBWJ}U=~d8mBwW@}wU8J@@lR7t7ghleNTVY}EWQ6Y6MAnQjk!~d}V9IcU6+w(}UerJL{zNJC zN)Xe_FsN7da74K}8n#o>Ol|b0it{{h*Ya5Ku({mR{#T`(kN;kXt4e5iZVD2ezE1JO N04@X)zI<;m`yWyW<>CMU literal 670 zcmV;P0%84$P)004jp0{{R3ySD@x2wg|Jao=_V$ZWR|63S8M_lP0dNH1PSXH=>Rc8cSdP$VqSh`ib7I; zN~LabPJT&zPJBjU9+JH#*zLulvxsb+NvSy{xb!J2xca$(0}ucg(qcU-YH#8I00CM_ zL_t(|obA|wZh|lnfZ=wd0t!^$|7AykEo}6<_Jj$&-IOoO;t0xoGrCLYM)MIU46>zSgu7nriJl9n?|Fo>|T*1Fcuolk0Oj~5B;2D>ADPgGKSvN_wY?HG- zW={X0Hq&3-`~m;~0002cyLFpO-7SB5Vr(RGd3@6k{%4%d4}JE0d2A%IBEIQcZ@$Or zjBg7P6vu8OYvP;xBa-0bo}ZvNb{km}f4tAg#gaQrRIq$bG>qR|+i!_W=fuJckp%bJ zB*k+800000z>5*Pc&gUl{=_a`s*NXiHTEZU@se#kxi7Rosf(9v@&`^!kebq1d^npOa|u-tnX+O&H#Og*^aZTmz|pRyQv?Yv<^YE4#ssb zjvCWwY2icWKa>7%vQ>r_xqoTZ;-Y!Gyb$*4dpW)a%E<90R~b)5Sr^mIPnybYyLch% z+yDRp$4Nv%RCt{2o85APFc5`lM5RB1fIw+&Yy18WSsZIGAlZ|!DARhr3unwGo5Lm$ zjx$CPA%u_~cgD;uA(~wQ1yBGMu!!PbOWd{j1NuS%%T?S{(0yMmy?^INeX)SGMZh{h z0O$(^ERtj(AW8h!Af&IA<=WC1P=TPnb^-l8h|4;*uU){(B4ENzh_Nl_6hI{y=){@PiCKj`BJj zO}(1f+>ahBnRj4`0L9yvR)4h#O!}H;nY#oi-tOP_ z??T*1K`M?%@pk{Anm;;xb{rJ(FFB4dX}1fzk4wcd>I#53#2l|cybE-3$jw*4q#N)Y z(8WCzD4&EVjs>8zAkWJ}JdB#U)|>_KG%O4GFly>bbr>No|2_Z}%=|_~{v_Xf*A;}X TJzOsU0000a)uK38yayl9S#c2gdc)a(igYyl9cLQwrfD*PBtewP z;Ji@@X9|6Ye#_a_%MK>}nab{He@w~?VGqmU*hGPmrjc-sWA)2QDYh{ z?W|qC{Bwcye}9uL82ZMgqO6Pe%ujPxZMpb|3j_cF0ai&wK~#90?bzLJgD?z+VbW1( z$u@r0-T$qQYG);J;u>TLz0X-8bv`8^FiivCR6+=*^XB<4AFVV)>AX4Nwd=a8aK7vN zz7yv!CS1qdZifX3{|X73CZE74+%IigTmk|d8KCvP27iXQG6XQ+1?~adx4``(tPF6N zXMj&*fUm;&?@|EY6{vg`9GIZuX(%y2j@{n}tn6<@<^;~~ga7~lIFX?lUyh9HG0p$$ zE2m8J_%d$&Jx|s1=f`dut(h%b&K#cW!kRQ9PoHQ+ogNhZ%k4;ui z4cn&NZ+{DF0?dg3yIq7eQd_v!Z3qAW000@<{y)>;NM*zcbp3y}%a_W?U74=`&vyAz z8M!aj_5ax}Un=wblSs7!ZU%l92Fl3sC07|wMOhcq%}<)jZM%3O>)ZeU z0hUQbK~#90?V3?ngD?z*Spjv0!T{0fHmCppPm1U4_^`D}L&iFf_j}mO4asd`loYZI z006)ltCdM@AxrK62JX~AF33Q{#-zDV19?#vk>#hzV40{iegl8yLm6pciVPcwN#iw8 zhztZrDM)j9sNfV_Bh49k_`FJDC20Tv000000N~~bS{7fZzI{(@fNJVvLIwK={#ZfV z?Ct*r`v?AFG6RdpVH49tAFe&T=8JgJVK{c``8*`FtzPg~Pc~;9;9T2~i_y^cnzevk4cmrZjE25bEk+#6KM$}D5Nl8fn006+iz=wy2|KtGwv;ZWM{{Vph z0Dyo1x3>WQ{{a60fB*ph001N;Bme-JC@3f`EiE@UH^VD!9smFU0d!JMQvg8b*k%9# z0IqseSad{Xb7OL8aCB*JZU6vyoSl%(3c@fDgwM%Sg!XF1pMPGxNQ?AfU!kOCH4AAX z$=cGlH`+^u3gT^MnU5VN702>a)uK38yayl9S#c2gdc)a(igYyl9cLQwrfD*PBtewP z;Ji@@X9|6Ye#_a_%MK>}nab{He@w~?VGqmU*hGPmrjc-sWA)2QDYh{ z?W|qC{Bwcye}9uL82ZMgqO6Pe%ujPxZMpb|3j_cF0X0cPK~#90?by*$!ypia;Sy|Z zEm4!!_kUI6#EUwzEGuEQ9slnZ0;kJlQg*ikfLkF1=lzGlIl&OM03kf}+kU0a>y{ww z4>77G=ouh-SK#@$_}3LUy(}66oKs5Y!h>lX$8^^L+<%Y2{WYu%(9KtX*Tw*E%J{n$ zz_$XG--3<_4*J)yr1dpy{zK9pppjO=)(Tf7P%7yCmk$5{0A@GahcLX>yz_1R|Z&S$^oQh)a9cofLJVX8GU)v5!eUS4E=**fSNMq3urikzc&fK z<*xGE^bcqf0000003P4v`r(|w(52`jdRM^x2moMnpIqk*1bZ`7S^xk507*qoM6N<$ Eg8RT8?f?J) diff --git a/icons/obj/items/grenades/flashbang.dmi b/icons/obj/items/grenades/flashbang.dmi index 3ff439d54c6a9a45720fac37ebcfc9a915587a3b..53849faa0c0ce85383741ebbef83a1655f3c0ecf 100644 GIT binary patch literal 1466 zcmbtUc~BB~6#hY4X^Ch~TDq&7W!Y@nl%t_8UQnTlrIvX_VreldDpZO`sd!MDwqYrt zwH;)af|`*j#H5m@NY+LrNUjQ$ZV?_KTDt7c&g@Ko?d<;Xj`?QZyzjmF<~zL`yTiXTe7)oPi`2J(4c=90`v;Dzx8wPyOkj3jwU3=>0g2&VwYCH<4wQQQSR`EH? zbGAw;Ntlt@RRpsXzf;-btIY>+bjGjgRf`eU;Pf+I5kQD{@bH^z97jXNx5GsRqn6n}Jy?l$Wc0EaIcf@$TU*%O zGu5iu^;{p%r_)y~-tpLK<7yD1!7X@COxGj=4tVKwn+dN$cSv26e{)Rtt8q@rS>`qI3QgU?KSF;j^tD}AAwRGHnT%b{NVeSHM~h;HZ^T^ zV~N8@F72(DPMEL+KqiyztABI9j9y{bdKmC=nxB!1tLVrSl?%i&*eM+_YM>6apvxJM zOmnOMOWOeDB8q*^CQj;ox2TP|WTFZtRN2kDx%8>mr{O@B+DQtFJp?<&{IOT7Y0Z77r@T^4E}ZXpnB2Dg zE;!F*NhY#S4sh6-B@VUb`Tv9SU#EJI0Y=;w)R@48!SaQr+Z{(qEojaTOZQ3G&_Jo6 zH{r&24(}Q1)^|A^)^Dja|0}sf-dtCCUC7ojz3%%fv|w)L4CP1; zt(D;FRJ2nAjj4Hgu%ad)_WcL{fgW1C3dFGbL!KVqg2^&zcsB>>dQWxu*AI`&$UHPc z8c3uieq3awPCV^7{9`A0j}GQGD; zJ?`-xANh_t0c(bQrufwzl`{ML2>a^cYs!h!JzjbA@`9IRt*YU%bp?+u;kV706|&cB zC#gt-%2&wDkd#vr@98jm9Y{J=B_AJ9#efTeN}q*Jj`w8DuthevIi7gTvv2+rqW^}<5c-A zrcRNwQm6r!GG>;5i)jWxyea){8N2fqaOZvI2eRX&QfZ%N9`eo-P7Q+qAuGj7`@Cd9 z4iS8vmqf4P8<+OA0OZ`34!(WmLi3^|B3qXQsYF-{7d`;Xnx@M}MR=Nl!+biu8>NGg uQ#XRxSq*fm{c<@OLObv<mjJ&Hn=?oUZ5q delta 615 zcmV-t0+{`}3-tt$8Gi!+008vhk@)}s06b7kR7JqRz#bkRWMpJXNlAx?hyUaN|Fi)A zW;6c)Gr+*W|A0U|JUk&GAvZTSEiEl5C@2gJ3;+NCm1qD62nZ6XZ6W{w00DGTPE!Ct z=GbNc006FfR9JLGWpiV4X>fFDZ*Bkpc$}S(%?iRW5QNXkQ-6f^YQ>*ky-17nU|*r6 zW;F|GBFWm)w>R2Lg$m+rW|@y2CKbo>RMnz5SG)%w&{=U1`Fg|IfQoc9`yFQ*@TO@p zfh0kc$>6+E31l&Unvwd^N$XIF)~PWI z#!+J$E$ysbzJL64f%JcqEg1U7rJ}5h_smaoR&BZXhYJJ%00AvYL_t(|obB7uZo)7O zh2f^59gMbt?fu_%<&Le66GMZC^naJdF-J)x8BJptDM!#F+_U|p{+{5T%<#((ZRaPqzb?-HPye-YsG$pHE_ zFMRI41C_r800000@CxT?^JqHPFIQ@X&VqSKf9s~S%+&$%wL)jHET-;v-PEOM2#~Ga zb`}kz5MUhY17vHrokepL9vXHaUn_Q&%F^c9en(IfU=afBbqTAx00000z^hs2e`U&l z_|<@E{$S5f`AQpoDznZ1*(qOZqtB(b`9C}5Yi(|eRHhwxpiSx3fb|H>ZAz~OjF-^f zhF1ds0001heO#^==LBE+-&opn-+}A5a{vI?-4EF@2|{I6vbX>M002ovPDHLkV1jCE B6^;M^ diff --git a/icons/obj/items/grenades/frag.dmi b/icons/obj/items/grenades/frag.dmi index f932b34099df5792a35492f2f1ebca1e3ef0d61b..2555b05fa0abec6d0e3c76ef58a99ee8fe6b2c28 100644 GIT binary patch literal 1323 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSYpOybN?cNllZ!G7N;32F7#J$% z%ssP_ugQR+<>AiSF77o+OE#4m3LIuw@6fe&n`fqPwBnw<&E3t8k1I}okM9dE&a1u> z>zyvT=p&!Z)qf5rlTt1{urTu4Vq`uyPFZcDh=tML87-gPlD-t_F8Z3ep;^o?ZHkAm zl7*JnI!7O^rp0%34&Q&eBInmFUAr6GzZW@+mOrkW@@UeTHFn8vogras9wb=16`R!d z?#g~C98jLSd)71C)eH_=jXclp~<=o1qw)2h9o+`g(TFyXud9eSHdh-i6vStenQAu$Wrw-59FSm6?zx&hZ_b>E zz4z8kHH?e?oKwrnaadq&7`Nx7iUakfVmr@0eXi>HXls;iOJYXx4CCNy6}e}DHh=r} z&4%GciB;J9#_88fkFGhMojuQXul9`Db^H!~j1z(xo`^75vXaYux0!LrHhcLE)piF} z*3D%#ICq30=Fa^5&oxb+r{>J|->-f~2 zWkw#h=2h(vY-9x-&%G3NSVl~0040|MF8;7^`Ec8|Owp>~7ssB3ZF}*Xp&`Eh-qIT9 zv`;nK(Q#P`wWVKA+PAmAUnS=sxHG)LoV`A!dtZP1>G+4c`{h48db&;c|NI5MCqJ)! zBYpq)ub-Ot^i2C=;y8=gKjgf9dDZ{V@BIDj3`eYYPjwS`|0Yd(cJ$KTg`aQl`+i+K z{?YfRV*l3MZ$GW=@a{Xyw%czv3g7+nOR(-&;qFbh9rtXW{kOKR?fUv}-qMHlv$JpV zv$Ol%XDVjBkhgua0*64G;-CNX8QTsk_859x7WrGZ|I^8ek44tWwR)P1E;uiE|678u zonb+*WZ&t(JPUdy%DvYy{QA4kT!N>ds){R_=iIq-22#Dx(tb|=!*!QQs`uDcT?U3r zCR@!EG{e`4KKP{g;m403uaYxoDRDGO$IG6mIbF*Qv`1T8J6xW-$zeM~yXddz17AfG z;$EmG)U`70*vE8+`|soD<;%kuPOiV;oUr+3iy_j)=e1s_0Im7h5Z>;sbQMH(vQK@)z4*}Q$iB}TR~H* delta 658 zcmV;D0&V@P3ZDg#8Gi!+008vhk@)}s09sH?R7JqRz#bkRWMpJXNl6?W96dcfE-o%6 zFBKgo4ig&)I66UQ|7I!wDFDnf|FB8_q%G)!0RJ*F|1B;585u-XCp1JFBQXy=JUk&G zAvZTSEiEl5C@5tAG62XjL=9&_00001bW%=J06^y0W&i*HuYY<}Sad{Xb7OL8aCB*J zZU6vyoSl%(3c@fDgwM%Sg!XF1pI*I4i}YY$p`>Ot3uz+B+S0c-+DnBB;%&ZVh8-pq z$MRIwqBvK)2OrQ`aS-`>!`Xm}bcFqmGYxptG(jLq5M?qrZ&bpWLLVY;IlFqAy>rjc-sWA)2QDYh{?W|qC{Bt4c|4z1G=vyuo zWnH{yegbq3ZMqPFpG5!w0XRuSK~#90?b_RJ!Y~Yg;im0Qu=57A4ZQzrE^sxdb8uBt zA^z_&avdvfg&a{;0Pvr4ZsGmwdf^J{CRc!KTf_ZNa(^*)6}X4Tuz#Cxf>oQ`)ALKP zTmh@~>szpzT)_LsXApnx>-#52ZJ`gfzLU0c{J^X>wNs%9l`|hN}Sp0002M sJTxP$4aGHv4b9&eOf2340GQn$DZ~^u`9oE601E&B07*qoM6N<$f*J!HuK)l5 diff --git a/icons/obj/items/grenades/grenade.dmi b/icons/obj/items/grenades/grenade.dmi index a962ec066d7e6dddd3c66d73727d30630e3d85fd..de04fe934c85c9098d4eab642f516f75837c084a 100644 GIT binary patch literal 1395 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSYpOybN?cNllZ!G7N;32F7#J$% z%ssP_ugQR+<>AiSF77o+OE#4m3LIuw@6fe&n`fqPwBnw<&E3t8k1I}okM9dE&a1u> z>zyvT=p&!Z)qf5rlTt1{urTu4Vq`uyPFZcDh=tML87-gPlD-t_F8Z3ep;^o?ZHkAm zl7*JnI!7O^rp0%34&Q&eBInmFUAr6GzZW@+mOrkW@@UeTHFn8vogras9wb=16`R!d z?#g~C98jLSd)71C)eH ziYN12KX5$Uv~y;y@n-$|-?i7zs5Jk+-+c4*O8tAsj9d1KKUqbZhg(${ZRF%-(oR`I-$VPf$5!6FT#UN>gX zNeX?*>Pi~fd$z4BRy1~4eU*vf%kNtK_aOPdb@!`(RICF^nyuUXmBH`cjl*BNZ-@0) z{(WQyri zT5Gv7w%-nW*SM`Oc-p4p)~|nZaVA*EocsE*E9_cD?wsSlbRF(2vS*nX%DQi%Zv+~l2Qota9K*V`=l{n`J}%4E zZ#XRTQf$H3pI7IvUhz4jo}uWMvjF+dMfK(CP}_z*x881BdHwZ=+WVcUuRouq_(eE37vc9^F%92FxbkC#&A6*&O%PV9v7=hIMbF4f?m(GgvN9XP7ycP}+bdo(9P| z5wW$aUm2d!y6(L&{oJ~l$@};jcKo@idP>}=`uVjppMr#!hlk()_xjdW`PFj%aWm5! z&hP(sP3Cj$o-Kcj;{HD_pR<3%yC?rOO}g*xH2u8l{o^m+IO26p&12?q8nJ)4$o^jb z&$0jCZb>sVoLfF!tN+27n_Dj(yRfh7=hhNO`hT2< zZ*SiKWIlWwJ=Oigp-bIM-9Fqq{`#K&?)t^GU%M`EKj5R^y6^Mf_O$w+kv7G9`fC3l z{Jz(~Y)5@QKX>`Rqx{SFt@)D#bX8u&eD6;uz6$JkUmYP~|08vGy+5~c%rwo0XXU>$ zw)!3TUfXj#nZaR_3PXd*Uv`Vs`i7u2KIa*l4<3-_YnSMC^O(dE9UVQxN6q81Nb^C5 z%j=qp?lR3f`|KbO14HJlDCr4Pv@i1rv@PUpVwgR9HhaAHWf4aK1)jsF?76(kX67?y z&Pqy6efl8VQQ(ExgAFnN#Xh{?G0^`aXs|nm(Z-7T4ENs;o2yr)F`U%9?wqjts?#JD zpj|7jW&u$ZM@h)Dzl?I;99W7nc)I$z JtaD0e0ssSxd@=w4 delta 608 zcmV-m0-yc!3ho4u8Gi!+008vhk@)}s069=hR7JqRz#bkRWMpJXNlAx?hi3mX0L(MM zz`!^V=-0C=38kj)ChFc5^#$y0>(YJbI_UcE?*^k841q-He> zX(Gwm(ziF-ON9#JZN6oO9VQjW@>JELI9I#}AJAEG5czt;*?@|4g#C^)4S3TuK_E#G zWimK#RKl4;A0lr#yL#Edq(5ER9qo@!c_Hj!*&LfFFmimISFgpwK5OE3)} z#>HDuF+tdDoCCyZ0Q3P zw*UYD006$>+|Mrc=km8JwL)jXFs9eKK8-_hfPAgcSuBgGd9Lf56b%8gwe!xR%T)+) zy_5&Y*3LVNhA3P#+<|(pd`R31X$}KEbamT0002rX4(IhE&uJK0n`4U z-}03<`dLe+8UO$Q u006ARvclG3IL4^M@;8Pm+(!TatGfY7tO~j#7qWT)0000-i3Plq0Nid zy;xFXkjLU)XAxv1Eoo}u*CVv{jPG&t7L7$r?u+I(OU#}4VouDrgS&3r3hNG3o8s}9 z*`mm6T^x^AgL1U)-}|Y{bN<{sd+v6B^|qw9@@aQ6qORY+dTs5C#WSyz&kR(WD#~qf zqwk_fYVd*;+P|1|PgN_dQh4IQz`&yB>EaktG3V_a!wlg-nd2Y-cd9Bq3YelL(tNX& zd&kW_J->5@eA&LP=(cQGVBz^{(GkTL0tEswyLVjkeR1RDQ-w=mTtO#PUKH>xUD&00 zXLtGc)2jE+tMI*#i`&2RbnI;LoV+}#1w~%AjAzW5T0|I~x)>B)8zv|@cnB&i;SdO7 z;n2ho=HlFN`Q?&CiDh=jxDFe5h2r*;QlP`2Ky%k-|B8dU{bZ z#~arh?!KE>RZx&{H}CrG8LnE%`&@y>xbB;G=v`Cv+G*3ho7NYe3i?*lZ5Ma(vAEEK zbLY;5^oMWR^vs(3_{Tap@aM=)R$_Wk>>L4D@dy+58^40+FAG0EsVpUuBn z53XN%$6q0I^j>4=?Zq3kv^Ls5@J!3q-?u7bYgDF)Yv#Sx{ofh3=j+^9``r85`|r$~ z4{u)ZK3S&s=KJr>(dVb<{65z7-uchd``23zZ@pi)eZudv_FsQ9uj*fDb8pM%kI&X0 z`PXo{V9lzxfe~!-*@yl$On5}1XCCzI_@1zKQoOjr0m;I`mq9ND>vsH9{QmLBtnSkjjW^%D z8*6NQ`}Xa}#tW30N;d4;WwnoGwk#Wmc}$bBh1Ku1>(}@H&(F?2J?reVBfB3Pg}xQ+ zkvz|6+zqsM`|ZcO<2N7X*vYc{A?psj05EtvioNqGy0pq7PbcZ_ocV zi{shk;)cKN*)M-DJw4l{!)6ZC8~YgV_494B%fIiJ7F6P2&Jdj+$6o#X-0kDq;cuhg z_WZqZFVdQ&MBb@0PQDE9{>OV delta 658 zcmV;D0&V@A3ZDg#8Gi!+006tak|_WH06$PnR7JqRz#bkRWMpJXNlC!Kz=wy2I66Tr zEHGyOGXTspX8&gY|1&&1JRu<=H#aveEiEW0C}jUK0LU``nE=4Rz-ig)@c;k-0d!JM zQvg8b*k%9#0K9rsSad{Xb7OL8aCB*JZU6vyoSl))4uUWcgn!TNQ#5cD;}2Ia24XnK zE0Be*wxP79tq|VcDi=&JA>L*--|S|xF+1m%qGZ{%pgmeAjbj}vnJ(X4NZP-XH7frr7qh&~K0kZ`RmX|KUxKbb z0003-NklhJH)c1easqw-YDU=O0Y?J@HtgyRMY)n?{Ism|n zF{X8dBxCwsdBWbV1#J3^jmbIVb_wSL?sLw#SwgdOc7NDw4)~xtpmXk{0e=pM(yh-M zs}HFDh}FL&J39=6;-8W^pmTKrkH@+Qr&H?FZwRRSh%kUHto;(O;(Q{qeO6lS@q2cmL;%owtI3(Y4{^BG=nOz}q!@e|&8?`OW>FbA!n) zTogRP_E- zYc*v3UbMwajj8K}Wc^;W#Y>HOY^ox9f(2t%tG^Y}BNmUTt^R~BiF^#z9{>OV006+Z slT=7;2x`nWB!5$ELj4f~0F?O!zVr(q)@8o~01E&B07*qoM6N<$g0*!naR2}S diff --git a/icons/obj/items/storage/portafreezer.dmi b/icons/obj/items/storage/portafreezer.dmi index e80bc712afa000e636e4ef13d16c2cf154b8e449..20fed2ca55990fdc480df16dd486da9737b16784 100644 GIT binary patch delta 198 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 Ef(}Ii#{d8T diff --git a/icons/obj/structures/displaycase.dmi b/icons/obj/structures/displaycase.dmi index a6411b171ad3602914ed7dcf6a4a341262e32592..828acda9127fd085054b467880edc32439e8b52b 100644 GIT binary patch delta 614 zcmV-s0-61y5rGDfrhfuONklBjU6otP8VNye-1lwR*oKhiL=$;{KvnHzp zozua42mOQ$84DTGp;LzrUDT-%@YX_y5(MlSx(*SfApqps`x(m?FGyvTN=zqol*g4qu>|$x6!iTLU zFP}bJo2Y0E27p~G;W&=&TC{NIAAxBAx(m?FGyvTN=q3{Z?6#ZU@q*>)&^7=Z$Kgq# zIC=F`pQ!$y-uFpj0DSuL8KGwoBC5Yq7_4FEVBZ5$9hi)?PCPE`Vu|Ag%X@U{4}~BD zicYbkPMDbwz<+TZgb)buq&d~NI>pM-J}wOPuF6CclbI>_OeJv{_|WSCQT-3lJ$$#>-}g;9-t?J-^)2YC>s!!$ z^}0UOe+2I3MszS{r2a|Zvsg%9??*d44)lQYi}ZydIe+Z)3oz#_8p}0)f7~9Mp8dil zdRHwLAir7zVwzy*YHYf(%-zyD4WUsE%UFzvT0H7nQa9AfSF3QmUxFm ze=k|ua9@Y+z|02_MZJ<`(}La=ZUlbpp4<4Z0*FHz9@V(S0LbUytP>`fOSvmtU&C1^ z)RgGdHvsnDZnOM2U162IBjEWuy7e>t7MKKo0i-y_evA}`YybcN07*qoM6N<$f|C?D Ai~s-t delta 2067 zcmV+u2<-QP2BHy=rhf z6P-hpLMa6z7k`UMCa;V^ltM&EA@b(+E3fhZn7Q;sgxGa7$0u}6LkfZ59evYK#E6v& zPoO!Q<5nvYP?RIIHrUA|laFz|oKgy947xC+n1~?|oFfMR5z>5jyX1i29QEmGj%o;y z0c0R|oZBFTwC`RSw)kQ9{0!T3soPQ?6S~P_ngy6DWQr2N$G-|2ui87=w(>}>ZK0H+X4Ksxhe$z8iGH;r^nE__N&yK|T8e7CPH7QAltyWtzw@3LB7M`)oSo6tHQH#3 zaeuWL#`l;3@LfabdLUuPV;GMIBDqM2$RLVsKF2ANVxkz0u;U5F+I90IO3=n2DmOd{ z2;S43&FShI-*t$L2+nPa^Ic{D`liFREx!yC?d?prf=#>FmJh0^KT~`xpW!jnUFQeGQOVe(XHEzxE`j&V18;0kpVCF~=zoC!!&jR5 zt@_~T>&<-rmFRtW2mbe}YgeCptu(KwqWIHS7tIH9L~ezZ%9j~2&@PrN_7A9!kLg!6 z(Vq*K#*W8Ku3uw(WXhiaXu3oaZeLLSJ^bXOQqAV$@igGqXwA?Ma zfYSP#ci?}fK0f}{d*IJhQGdK3Na#7GE< z-UpiA(e#e4cYNx{Km9>Dn>{hz*|~8qz5xi%)6VBC_77N{oe_r-_u=d1&Gy#qU2QE^ zPbjrT`!l4`dD7Dw34%zT`h45sj*ro2b0$s0RG_+X#((zR@C`t_STMi6PjhyLA38!&dC0MoiqT|> z8JAfjl!EiAF~)rPBaz^G>ce9ehldaXN(5~ROkuH;3AP&3FKc4o}VZyI6eg z!@w`T@dEAPA$GtA^}hH9pguaHozLOlf8SL@W-4Q_vl->iV}F>@Xgw1ohIAJh+Tuiv zk#MNk=!G-!t8I~0^aA0Y;abK*)hh0wfq4cE9l3w{GTNHj6KN zdwab3i>K4dLx0ofm#oTFDn+Q>u*gughK$2&NG?B5D&K=f1>WU%Qi94rNZQXXi#Oy+t8rO9hn77myB@22qo3(3O;G80g_Gz|w< diff --git a/icons/obj/structures/morgue.dmi b/icons/obj/structures/morgue.dmi index 2d86bea7d1b286e611ade9ded8ed9ec40e73a264..b91eb2af3a51739bd0e75416082a57b444e6a042 100644 GIT binary patch delta 1561 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 From 1309022f524ff25fbb7e57fc1f069acc04fbd3d7 Mon Sep 17 00:00:00 2001 From: Cerebulon Date: Thu, 6 Mar 2025 10:30:22 +0000 Subject: [PATCH 140/512] Remove stray grenades from grenade lights --- icons/obj/items/grenades/clusterbang.dmi | Bin 1854 -> 1807 bytes .../items/grenades/clusterbang_segment.dmi | Bin 2265 -> 1728 bytes icons/obj/items/grenades/concussion.dmi | Bin 1224 -> 1198 bytes icons/obj/items/grenades/delivery.dmi | Bin 1679 -> 1578 bytes icons/obj/items/grenades/emp.dmi | Bin 829 -> 1478 bytes icons/obj/items/grenades/emp_old.dmi | Bin 777 -> 1453 bytes icons/obj/items/grenades/flashbang.dmi | Bin 1466 -> 1457 bytes icons/obj/items/grenades/frag.dmi | Bin 1323 -> 1322 bytes icons/obj/items/grenades/grenade.dmi | Bin 1395 -> 1383 bytes icons/obj/items/grenades/grenade_chem.dmi | Bin 1308 -> 1298 bytes 10 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/items/grenades/clusterbang.dmi b/icons/obj/items/grenades/clusterbang.dmi index 0c82ea4e6524fad807bd2732cc263d225a8201e8..2ea0b9c7f422ad83c1877e1521217fdd37cc3e3e 100644 GIT binary patch delta 1549 zcmb_ac~H^`6#fz51z}#9W@4AAlxCWEC8QRbS8b%Lrhuld7m`K3e-_E}I{&;WR`@T2x-p4`YAadVQb(|ef zxn?8m794qq9b=LUZRF(JtPjcDFhGh_&PQgl?VkhAfk2y%9UtZ}u!&>UZFN_dFlz}O!6gG6N)eos7)}R_;%*FL0l`wvxfUDIDryj@H1Wa1h59lf z%kkk1nG**5yQpdT$0F~Qlt}9Mp;rh+LHqNZglE@}_zEb?@9L61O`Id^8dl5mFLGo= z#Wk3aa8|D~Bq z%5&-=lgVcfsa}nY`5+Y5ZmxX^cXf9+YMW+iOFCZ-R3^dpXlqB$XnpWJ^@<^oc;3Kx zK%5S##`#r^eqAKuO+5Q)+A)`6kn$fu{U-;Zf$i9orm$z#)Ezq7fpP<*lw0dd6Sh^= zdtOD9Z43%6pioQ1`Vwj!O}OpD%=TI_{Fn$7F3%=hwL5K!w}x>u?^@7)WMU?>mK1N% zhrI!J9cu-ABsIAxtfyHZD+@lK%w1m!r<$~icuQ2-J2LgA&jbG_3S#ZBr-mmdqhwLj z*r=G5l@<3ivfKZH1^B43@!EYFFi%_bp)t%~D7gRtZxSphcI!Ymgcj@ufZ>m^%?{_a nE0y(hX3T&_xRRdEzfisn@*}Z&ZDz@FfGnKPxI4Dk6I1^JdlAdK delta 1527 zcmbW0eKZq#7{`Az%*(usZY1eV=Dk%bT0#^ya|_k9RU#ra4V7g>*U~h4!6llh#yV^B zPGz)~E9y|LY#2(nWQ)AyWmj_7IsJ9-fA=}x^ZfCA&+|FYIp6bS>o@7=3{w5~dhgnQ zu4t?X6J_DMJcFo_UfLorT+5HK36K|}FnbDFUTycHSJOSy<1(zga~v~8>)TiFa=C2f zDI(qQGL{ejWn)5)A|<9j0jx zl6o*Zvbp#?a+BNRO--Yt(Nx2Su`y(Dw-N{5{S&*}i};g}4x(ih^BbBma5&lU6;g%`JP-%#c`41M zZg#1EMi2M`^C9Id|yX`gxJIJ!g zde7iXCX*D1PfN!S^u~}stChYkf74YZ_pvsl@fFT+C?|S*q$ymJ5uKNx&uE=ie)Hc5 z0bvYpp6+N(mn0++?tG1jht1Usw#|N;w6Sux_mCt+6>5U#AL3QpUmAsa*wF#L7~3a&J{`f1H8;HK^WccHR!NP< z?+_q;pYCA|KnqDUC`=|sLGF)ImxMf9zqeW8x<78t@0j7a9Rh=2HZq~KV3&}ErCJB@ zDm9ZV8%C9!Cz+Nw#fwAv8VzJV3^td~aRgDVxwon}*Mqy?Z?1%b183b%gvwPDTgm2^ zot@1SJGx{jor>=ggKs0`*+u-JLubaS z%Rork<#dsCz@OxR(>vXyaEU;Fp+o=KgIT6zV$#=(Pqt`#A?`Vr$mVRw!xu~iM-)m) zoJg0)G+YwZsjtt?NIu?@8s7T4XE1Yel0-za=!-5GlY#&as_%5nmuD(VLP>IYj0^Ut z_c=XpR;{~-V8vHz-?GRx0KR>RA-UgQsQB0Fiv8Tz@#fLAMd_Si4m;fWuuQtt6I7J> zb(`78v9FhA=F7fRK8`UUEY4b`oVx?NAJ}-4fSxUuC4rqI@fPTXRTf!zI#TZ)kt!-? zVv9ODnipc@r&5H+_<4FnE$+vb>}n_pQQ@kI6Hc9~n;LGF9+Aoao?~$Yl#-0CX=^K0 zuMu==ciacJt28w&y3=nuH`wYMZd9mSP_MV$UB+k$J7}iryyLFDU;TNp@?QiNA3i?< znch!b;n0-kRkfPtj28RmAp@~<&Yrb5b4m!4kAgdH*8nz73*`9Squ})%%@_x{``bec zS$5qB!q)bO_w{VHh?9sr)Kk<48!I|%-J7lEHBoRGE5X4(kn7tRms_py7gLQhFV%*( z>aR7{mYC6*Sy=}M8n-LdF@XBt+g;u;m>273wqYasm zLf9ubH-It-h3V2wc0FZ-|0C+Z)_QT^P0t8)d^`}R{bp9}Olc{w<98;VrKb6HSI7DZ z+D^6WOt|to1rY<3bt{6l5QH+eB$fLqriD^giLu?7#@lBZ z=^iR(fA^ZWAH-w(>Qlp5L-S|PCs>UeXjoff)wO@7v0RmiLDCN(a!nbwxGFC%?^R#l z6)u;{A=VA@Z2Q#$Fc_uJ0%Usno)5hg*{%ZsG~8oC+~Y%MBmHy%P*R#+ueQ~jgBdcX i8~|5O$J+8gDp~@$?zLU$20J!T)!yA$Z@%Y|w0{6#@!awN diff --git a/icons/obj/items/grenades/clusterbang_segment.dmi b/icons/obj/items/grenades/clusterbang_segment.dmi index 2fd27755f2a9ee0f105e993917392d08b33b6e42..dc1d1b36c870675004a89d8752b7c7a631a9a349 100644 GIT binary patch literal 1728 zcmah~eKZql7=PI!iYedHNG|u%y-T&Iv7xb)uUp7T`D|&7hA|YTDBZGB&6tI*A_=QR zHY4Mjrddg?wuHLws5Hq}zPjt4bMLw5-qY!i_j%6yJHO|g=XuZX`Msxny>VKaCYk^M zEsyQkUCK=Ta+azoV;efGOPOj@{Q}8Yd_qJ#fkY-8js+l@b?NL)P5yd4H+fTSa$S{v z?*7}`Pm>R2T)tw(R3}(?5J&n^9WBqT*m3P8`Ew9UUrV^*?X}rv{X?^)hn0S1VV8cxmZs-_(!)o^klt# z4=?Q^=EC6N_=lTg;;ZOQR?G>Cowg^z)=;mLVj6#gt65c_X;@tu!;M%hIR(Iy2Od}# zzhu_v3!g)>gQguHaI#~Dq8jcwOhLiJJ6HQOGyCd;;yVc%&1cwJu6c;)z|fJfZL5BN zSr{yBHJANXKEeJu)z0gP#-`^#G~Teq9kuVPPtklIW8>Rq|aUDrvd1gPOT1M2DubQ~1Or6~pI2OkSt!|()|jGRwl;2_ z(*%(u=5-C72_OQbJU1%D!5%qEVOn+fFNoBIuqFZ%Py^SUz*?w;s#kbl;tv$Ao}XmH zjz=burp4Bz{SC-yAFnDC=L*8F83RUOpd{D7pj<=z(Iy1(c}~QLT`hRT?YQD6k^o+V ze9%#vI`Z+i@SEe#Ey+Ra4E$@?68w4bs~B z!a`%rC2!m3i{!1N;s*~7$rwm61Ptk-?jKm0JsRoXQZYR`4pF4Q0|Ej_b=E52`&4-P z{NSx?kq}vZn)u_`#K>;q;lpc-M4OuyM#$2$Sc~D|VJd;yd0>NZdML9Sx|MePzWAl< zrt#UG4dPKlYRAV*A9m9wN#61aD=wjviA`$w#2Pu z{1mJ+IROJ^>GLWa4re_odKEB1L!lUZ6e{}Y#rrcsK|!4d{Avi#Gy9iIoqA2BVqUB=DIxGMpr}NODmO1u9&61(HDa4 zs~0^A{v+!Mz_$Z~|5N){;N5WQ`%mwkpq zJLF(39_qWS$F%6n%69PP+`85{%a2a+-d7Z+%si=!N^jPld}sLGKyvDILd|NXec@?^mp+IuZZ)cv^WmSv&C^DJd;6 zd1Fb4#R$@p?+$iE~P$gsXn7>p9qw(Wopd&#Gt2F9~?Kd1Gr_Ly!Fl{!$o# literal 2265 zcmb_edpOkF8eZdmT#Do_l-Nct<5H#^Mw#3S8RJ@rj7wWHZc`f9TtYJHX&+N=L)(4Z z1~IN-P};_3q}(Qq%Rbc5C^CecU;TN`Kj%Ep`D3kbJ>OdES!=!D_rBlCyyRpnC9W(E z0Fbh`Lt`MD^u39RKz*;JKNB)_B&=sN8W(jfGBi9olz;~yrl2sVUOWY%n7Xv<9I-r= zJJuEicZgtlJeVkT)X>%{zekv5l$~Q>@U1C3NP`z;9qv;1+Mc?kF=9l?yWz)ADJh*q z4k;P^K4{&qCFz0|CI^0I45U6b^#}c#6BZf1`U%rhsBCuF2M@ynvqOcH^@KW0I{j@= zeApuD(Hx<{^%Opmc_Jb!2s@jD>nm*t5V56S&cyuUc;{*DveYb=z^gu6Mgc%{(H?yk z8&j}ac=jUOU9o?ErqZ}Wkru+jp~aeXrdf~aqcg)xt0vty>$deO#J05pEaL%AQ6Qo-QWcHdhQ*lD2yl)wZ~k zfC>DN)V0J<__V&X74;A9I4z}w88zGn8+?`~tZ_iXN>x4ysRtrF!F(O)tMUZBh}8Yh zP)!x1vKX8A)1)4dwZ># zCRlf($P96M{_h0#DLf6Ab)mc-X)HB}$7_(j>V>flIxmi54@Del9&bQ6x_S-7MC#%6 zT56d}R)P_wz&z3G6|_=j90oF54)h|>iGHHF#`2QA(uPEIaj5bxR%Q+Jij%ju9~2O9 z?)W2n_zv}=_KUtg^ws#=%S6!KUMHJv^N_vWzQT(x+7OwEP_3cS7RtzCK!b&rb0yMF1xOeKE>? z*WaHRVnnDS$*vtvthduCwI9_QKYq(s9tk-N5N2i-s(iZ#7q!z2bGn{uRN4Vllex|p zbDh;^YJ`$?ZyR?Nm3t}__i!zu+lN!M(%Si#WpY*Q4S4L)O6AS+yQg>lhA({oVsPVl zRWAy3?97>m5D5J%VcxLt6?pf4`{bn8Uny1a`lhC|D)8*Ysd`5J4-FceR!qE*?+k_(SlrAHZD+>d1IX89fE`b=j2G93zbw|c2xN4BBMD~ zCjCEC*&mkCDSN^{REx}B-aF^be!~wTYpu0#3x8&M-4Fpz5GZmqFjuGXQz7Km<9fd zH!MNKcYnT#le~h-*?V}tY44C-=mfUD$mg4;W8CZajS#A~X9^E=$k(ZTKYHi<*Td4$ z7O~G4-o_>dx`eh1o)&%JqwcIl)~gOR^bnOzHx&9mJQ?CU1d{6`@aLu;xTktKi8MAu z8S5~KJe>=MpWf^oxxS&2mPb9v3L6#(IXpx~8Ai6M_RJv+{5s=S8ouOZS?8~Mf$Y9Q z^`Xq+AwlLGxBnw0&q?5i*XFuB%Tj#2F*|S6s&*ui-coycbas6m3W`GV{}h-Xx76)J zNX~Wb5+&9(cknJJ;=5$#*N>b{U;B4idL9!yMWOQNf1~jlqV=_RvFTiMnFBi^Zz#&sdx}`$D zaUpZIy82H461-Rv+LB*=kKcF-Bz;#VQSt(?nk>V4Vdk5wb=%rvAp**V#L07jubN^^ zS8T9~;4L0!QC%hG+Hhg>c3kJgNGxSL&ez-g3=MbHVrHt@H|YCnHGKnv#D?v)cl?TD zEutJst~`<~$ZRN$@5u=WB4JvINx$mcOcY^z2DoqfZWVYW~mw$cL=UaaA_U*5+ z-YULsV5OFJD-K26-D41J@%cGGj#J?-TIL%&T5EPi;ivtH?(S*x<(bKsOhG~3xQQk3 z%xPxb)^{DDZ;NT%d2O=cciCH7WNoiX%yKd==Htlxe5A#Kpw&=9^5tNXk%`6a#XmIE zVY;QJZ*?6R4$NnJcRYD<=f841WKlIuZl+rxQ3)#pDbVw(w>`TVimGjuTf80auNA|` z+FS1sx>|MgC7puY;RKktODJ$E(vUl=eP2mk;8 diff --git a/icons/obj/items/grenades/concussion.dmi b/icons/obj/items/grenades/concussion.dmi index 413769a7765f0a3c89a23a4932ee08e5d50b9a41..2a72701e0922a2d2540cba58d5962c2c4fce781b 100644 GIT binary patch delta 992 zcmX@XxsG$fo%+3=E{-7;bKc(FpDmmybNple5h0$IsHk?27?#42KkT>mE7Uvp@v+Ig z335{0Eg~-4qA}&pgJ;wBE5ypUx(mkeq-&@wJLA*8Gzk!zWjUM;s0^j2+4hg)9nv3`YbTESTyA+|fjr3OTI4>eZy+ z5hJ6`(X`}hmZfEw*e03v-LK!+G^A~w=@OW7H0h$4Y>WVl=f;RF8eMB{=2QtfhCMDV zof{m<7#1FW_RN~gFGZe#RV=@(ImdpU{w67){xjJOg)3Pv1&0!ZM+tvOW>9($GxM0CKt|QlIOmDtlI(Ma13{Y ze1l(bw;99zZ_j7%+-rYOW#3)y2S&ooAL@(@}7oXS=tK z;ceOOg7+6S-X~U^zs>NV?K=A-SfH_rdm(@mkPuWp`Sv@_@L`}nuF zAFG$G4%xIPylKt(`YUhc^5)Cr|E#z8nP$9(;ql4!AzI>f<`O(P7BaWqT8mbH{p9*i z`@p$(ag)AUm}PDCy{~pZ=hR%s$!hoCyuUu{-!IDobEES=K)P*MW4_+qS}0>J&9mwF zZBP=)d&Qvl`_-k7pX6O9_PXU<`EoIYu_ZA=g0KC*&HdwrIe{W`egD0Dxw18JM&xg6 zhBIleL=|`rJMF)}-J;iaB)4lDF46VAM4(#n+p@! znYnH!F6OD4zL1@r&&Y9>v;L#pddIyLbKWU+ELhMgTe73wsYvrk^AevoyS7zM`ttE} z<-tDheQNoae155fEx#;ysC3;M#uYI<3^L3N#~BV7G8BNB^+;?a=5%j{vuVa3ZS*g0 z)II-sQrhN~snM<)MRBsnBdZyD-IN2pJeLMdTywZ`-t-VHQ6O*eMFXX#MbEC5&MDr> zq@$zL(c!WB>ZWC~=RWUQay2VbeS3NrP_}SRB|n4Sc7`T}4KDw#Se|{qyng@myyGIS z=VyPlcrMoP{&$oeb7}5!4WK}2{Z5tzQ)az<`*iJ!%F;K-A6-AR@uQjms`HVYOe8a% zE#cO$8o|Bi)g_K@NoTC*F*aflzW)4mjom>FSGn1f|Et~g<9$#cF@JvQ-9H+sGPC!5 zJ6z3Bu$(R7)vrGx*GfMxo>H3g>Bjw;;S86rJzw56<2KL~9^-574A-Ae-@hKH`Z;sM zV_yXeHikaNhGd2Z5)Am5^#oN|$A4qE{HfM{=Iq(Rx3{HcXP-Wy`eyTi8`=&6EZ3$+ z7v4;kIDdn|gMTsek2-_+Zyd)Se`Y)&S)pt{E51Sa(YyU|7 z?fdCtLi{6*Nq6Vwp2&aB)*mihUg#N?we`3C_iy*6*`8NX`{xz0H}3!Qqpnw9n?F6) zUR(J*uC4pQ%}+%|&mT>)`SC3@PFL^bsrAZ>m1ew9UJ$olz3;Kd)+pIO7JbTh_2)nN z{C2ld{_Rg6>Mv%k%$L-z`v3avwy*zwc*Mo;Rck-TYWVU=w~v5B)u-6&qPMrP+pl}g zrz9}((t3v7*0-_(T89?q9v7`~{z$@K4@%?aPnj3-_Jm*?ccgy8M%?+76~U z-`?HQ=-R^TeDv}BMqniD*vKsL?bW3(pVm*AWbw?&SGZTyL82|Jc>VR?uRq&$DFu4* z`qk~fKiz<*caNZx**8%I9_Q7!-+GC-HVZtmn74EC{%sp)+SLC_QA;yyoc5n{&eX~N mlOMlIDEOm|mZgvq;&w diff --git a/icons/obj/items/grenades/delivery.dmi b/icons/obj/items/grenades/delivery.dmi index 91b3594e74d4b89de8fded06eae5b26ee73411d8..69645514829c42751291723e40fe9668cf3950e5 100644 GIT binary patch delta 1379 zcmeC@UBxruM!l`4i(^Q|oVRlgGo-^Mj{jfvm`kUnc~Jn5(hFAUoff8@Wdprx}tg<$;w;z7capRecbKC0&^8$Nx zqA%U`)c^lKU(n;nUjO^QUsf;QeE+%2;)@Lro=#3=S7_^IQE+FfpPVN%l8-vh`Peq``32U9xVUfp{QMJr z)C@BU`X2u{nIhEQ-VPKsb86c0h*$gk#E^y|>pB`f0$o0~?NYcJFvBTe8oC<;LyX(l0+QQUh8t zLw%t=_j5P%CT#vB%Ku2gQoNL5+1&H&hu->M;JsYMSh8p}gWA0F{G06^%^#id{awv9 z+ne==#JT7EMS1(A51;T2`5d#_zQObP=fy98Iwk{kJi5e{@apHE4d>35E5Ex_A5-I> zSoG9&LFV(%%#S*5Z;4}=yW`q*hq>qF|HTBJUHp&X$qP3DToHrhFe0K6toq#6U(7v9 zPm6BK%gY}>a-^OmZcl~auZ@{vJ!=`JdZ{M9-F|MCddEJ)ZA=UYzWvdOS}V3su1tX~ zIfs?u%S^<-pQ&jycuq9`ctzIcocI=qaeCzDUR{ME& zUl|{qe3$oeLEQbCO}nF65^_Xecs4BfvU^>3&A&BFPd-=fSSS56OrYjhsFd`to2P}onD%6KoV;t>U-d*=c|KmRKWEOI*~xG=O_)I`_K)9;9S_7M zw=vk(bFa9X)j50nd9lAgen<#B#)1N%ZVwD4snbL!GH3f@&7yQA7zIi*btT~fY1 z=v$Go>ST3(&EI|ZT?K0Hf4}$VS@lVk_m?%qx)WYp5-el#*|CA4{zxKY$6+Rcc2)&G zZU-5$1`8dA!U%>(8yGMof>>tEpZ{I<_(#{Crxtzo_V)TII-)Digdefu7FU>k_Se=Z z-i;AFZ`Gb#^vQQ04Oo43!r8Q~6C6VKExH!z#pOB z`cyBv@!WjQvm6I}QkhreEHJvDopa`jd_9-6H>=hs(XHnWX&>l*$P%V@Y~tysJP$6M z3p>X7PjC8ZNp0cB6^3ivMFXa;Ur{>ko1VhtlN>jhU3(XEUH!RD+P{lIT3R~1%I4;Z zQ{gT$&HKgtr0WD+uz0VY2#;fi$T@e`3vX-e6t>wr8kf9gEfDi%z3{PS--&-LX9ISc z9e=JetC;nN$hqg+i}UtLCa&pSV?e^WpJHqV2z#1={6V1j%wLzF3{Z{k5Kb zM^}oGsDApj9&VZ|10Ip{1c+wZgVj(00VqQ*y@HjUb@2oL#+55q20SjtmAs(gKW7`uhFt3_|24$Y{v0f+ zy0k5~-eB%L9&L8PEjkUkx9jrr^EJd3BmOAtd(~|)!_VLD^-ImVT#1TnmxHfFHcbO+ zzFmLg20MdI&KvEi3K4(YqpcYlfP|O6lR*8txZ^XPC$5XT9@XT{op5`b{oc^yuXl?v zJop;RU4J>cR8>eO{!hjuwSBj4I+_#)zjUp*bUnQ1{oCY|CLhDY#i#iQf81MZ^YXR! zsXpE2X<7%`t37wD>;Ctz4oLEUpS0++)pReFCe_PFRy}|CJ$n0wSCtV)z9CA2FE_GZ zetGg?GjmSgJxjs*;xBw{{Co?NMR!bLaC})FD?Y6>g0Wubbkplym$o-Oc;|0sv!+VU zDoB&T!Ck90^t|(?hn{Phj;}s%dc8Gs76Zd&lftv5Tkmq|=^S`@DSmC3|DP#4Md#@K zO+Pw)uc(cLgoW1M_lpDf{QUntpJ7kGTmQBuc4lVRiyKpmR&s5yuKs`IuDn1<5EU?R5EYr+$;)oxhBZq7`|OD_oR7!m7&s+cz8gKHfif?nJ>bEpf300U8oZ zgE*(9%HAyn=J5j$V>2Sfyp{@awKh%J{HtGFym$KR*DpMlp6j_k(d*&UUsiJZdS0FK zXZAYcmwlm6YRRo?)# z<)d`_;#QQ#$HTMsXGGNr&Ddev^>VG1&~|r5 zhW&c~mc2>5a3hcTeW8h+z`H-Lmx}5e-tVigGI=<^?vLZnzdQ5y zecgZK^M~>^+%x0r!sOzw{5gEjiD^rofFUqNovJ#zzH0;Pg

o?&|*wb;xF%@eRFb a{LiQ@I;%%oyI+I>2s~Z=T-G@yGywqOX_)Q+ diff --git a/icons/obj/items/grenades/emp.dmi b/icons/obj/items/grenades/emp.dmi index fdbf8bbda41e9696c6b7166a8b0e71407cc298b1..cc7bc5a9616157845127a3fd7c256c288f405856 100644 GIT binary patch literal 1478 zcma)6do&Yz9RF=(UX4(5^4i5&S0trllyHa3^5}*NnLMsrOPWl~h?&%sXF}LoM+KPs)RaG2T}>%DE|Jfa>Ml7bIME}97@dHRPs9^W0YIWN3huzEb_SlJjwVv(!Q4Yb zwrWv^V+e1_LBY+InnvAKVWtN{KUdKH#EJ7n5_Yr#UVkqWn|=JDd*-`UaMIz*E=}jt z5uxR6{!=+vR5tXd*D#+RPOG+Ix$c3n4g7774>T(LCPiN}(C4yht7${ELRskUrK|6F zKP(E2ulQ98r?aa2s#v)2;_{ctS5+)x-ch0QeE0k_ha(3aW}y{Nj1t79Oq$E6K?=FPP*Uhm@jZO zh3!OIb?<`@Ju+v-r)G=8HOuyPxm!}FZ8v#M>Yn38G3HB&ktk^lYSfvh^Fnp5@7b^0 zKcPo`uVL}Y$p~uMmN{FuiA$0X`LUu@{Qb4iO z_NlYhD-XDvV#QxLYoYN56ZlV9zACb|5Sm7s{TTvyQs0WxRXnfp2bjy`!0jr>@{sDj zXLeE1rj@7eADMIJCAN)pTNjIo*F@zf9^_sR*dY)I>^mP}LkVB)acd7}evs7oT_$V2 zf}H>K@vTso?E~V`^CTUie4`Gq8Jx~V$6X$ZoyR=4(N)c?8$1z=!?A{LqtWQTc*k>E zfuOKKi1CNGE$O=n#=rM`LDsTjOC%EC0%h9EBdu1zF+}a`{4y?fW>`iVKw;an4cxkG z3j-;%g0)wmoNcYmeCe)JZ7$)s>b#Q52XaeZ52N*A?o_1RjehlUi6K5=Q6xF;(ivuZ zBcRT41D7sKhfII03^GC1zey{S%2Nojzll`%+_%gNvGU~xnO4NH(VG>}lcHH3r#daY zRI$#xlMv7Ztzj^ew=vC%JVzYv744%mBuG8EB2jx|kYx5>d)rZ^8Ypc*OkAV zMUO(~Lt9Jx5fWMn98P5id0CLg@60!}Juc&$uvxhsG_MADVa)rHjm|uKB9VCOP(6Qm zIN_dk?<8OmN+m=4%bFGE_dxpa12aiJ3p()T`wQO)t8be3Z)FcQthTf!%6FEQb#mKs zgSs~<>!oipHZ^^Z!<>lvg@b!0zC;qs!Gw4p@^2Kb)t?faYq{w;pV4;v(?(sTQxkUD z`1Jb4*X~ z`Fwbjd{%~l>kW;~FiYN?$I4Dpd^@~@p$H*aLV&S}3B*yOv6&8YHt*`?gcJ78khp#j zpToDS=I6AI2^AkNFo{2+QcY##sm3HD2e`{vFpSo*vXXAb@P}n}0j1HOYJ+2={51eL zy1aNHMUkMS?_vT`4P}%t`bZW>|DgPemm)i|oh}lgHn;~DZ>c!1Y<^B=P8qWu zxEj~t5r|qYq^g+R)8nbFmNgKAWU~xfasr{CU=&7s-o?}w)qt^1nGQWnJBm!kCfbYr zqGv^&3lNv3<<)L<7F{2y&C!#NxPe;OXS7zd6MCI`o8uXKZ~lJ~w+gA}FKoqG^dDC~ OW`Ond_qdITp#A}>sibHC delta 817 zcmV-11J3-$3%v%A8Gi!+008vhk@)}s0BKN6R7JqRz#bkREiEl1lK&_uC^j}WE-o%e zNJs#H|2H=`0RR600GUZiNrZ%iVq#)PM@J-yvw6(TipqX(z}40Dk}hbW%=J06^y0W&i*H zuX@&`^!kebq1d^npOa|u- ztnX+O&H#Og*?*3+tCyXc^}DGbowN=?v<}8~Fpe72Xlda?=0B7EZ?aW}7P)EF;-Y!G zyb$*4dpW)a%E<90R~b)5Sr^mIPnybYyLch%+yDRp$4Nv%RCt{2o85APFc5`lM5RB1 zfIw+&Yy18WSsZIGAlZ|!DARhr3unwGo5Lm$jx$CPA%BFB9(TsfEg_m+0R>P17O;ro zUQ67y`2+ew0n1g~Q_y{1ExqSQeX)SGMZh{h0O$(^ERtj(AW8h!Af&IA<=WC1P=TPn zb^-l8h|4;*uU){(B4ENzh_Nl_6hI{y=){@>(-G(+cq9vR~4U0FQRSe^fgpbEHSAdSuWp9o!ok!fts|7T?2CLEi_ zy+RZDfBrN;2qAPiCKj`BJjO}(1f+>ahBnRI#53#2l|cybE-3$jw*4q#N)Y(8WCzD4&EVjs>8zAkWJ}JdB#U)|>_K vG%73$`7mngN_7|^F8@9N70mobME)e-d)F0&uRUBZ00000NkvXXu0mjf(1CUq diff --git a/icons/obj/items/grenades/emp_old.dmi b/icons/obj/items/grenades/emp_old.dmi index c34925a671ada3ac8ef6eb10d49c76b462d5e0f9..97f03da5c6ff352008a8cebd20f908aba0b10942 100644 GIT binary patch literal 1453 zcmbVMeK-?%9RF=Ii86^$Ej#s)NG_gs6jE~$n@lvjXgE?9S(cgDX5`%ErRWM9mzP|R zJu)x4iIz68j-@*Q>e z#F2;vO}ObyFUxf3?fwFXVukl zapZ@=jrrIj$s2Y>SLvPLki3HD30Gm8BgRvq%Iy8w)FYuiyWTV3ahX68XMK|JkyzUWFyBk->7&KmSwJUG%A z)U5Mb&4+18TOm{P$slC_eX)?9Y~IbOJR=VLL~?{VK_J@29;Z}Vj;i_ocCoNFsTIp{ zrs(i7-F0fC6nJhw{yz(Sw%h-MGeeNRx&v{(ZpF>~l4;7Q&UKeUa!Gr6eM zI`YJKO z$n$A6^R}9{oLHMBF6<4Yyj(yQ&A>?ao{+;pkRs7HY~AgF_!KBfl}Jqi6qEN(Oim6I zRSEt%_?N&;=vEc(s{$VzaF+n-ix&YUqZaC^DwxM_%ye^IDpiy)3g_pk4rp`+{zjTc zGePu+6JhW}HHyuuPWpy=AMpc`DBHh@-qYIOm6VSOLqf^U$6IZCYJ!EAZC*-UzO|@D zK;&nO{@l$NYHwe8umUd$-%`33llyG?3pB8s$B*in$4BbSf6 z?2F+mU(Hu5wq4HZL1fowJ9E3>0R8jWv66tl8Hm-ddhVN-DV8P>!fn4jjT&n9zd^pa z2|0?Z;MHnIA3C>JuGg4E8*ct6vH&9uD{=r33@z)~bTk=>VUI2P=zWu9%NEyZeMrVK zdF1YaE53q8qu{d$8)a7hjSQ|xda{h=xanLg&lu&bHAi=GEW*yIlQjTyV{FjRpc|U910cYck1*(Fo99q7z=&Yn z9B8v4=Y^r7wGmcyhl%asZ`ET95Z8ev>-RNr`*My5PC}uaC;g&wln=wF5@}{~_ eUM2s2-;m%asqElXako(8zrf1_hq<+nl=>I=%#0}j delta 764 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 diff --git a/icons/obj/items/grenades/grenade.dmi b/icons/obj/items/grenades/grenade.dmi index de04fe934c85c9098d4eab642f516f75837c084a..11a48997b03d81ba146a84cc2918969d6bf10866 100644 GIT binary patch delta 1022 zcmVZEw=c z^yE#Jj0YR&p}mx0Ay_QJ61?a^SQShtUc`f#OYxT8dM|>kdXYdjSQdsUiMVvfLvbl3 zO?M`5X7c)dzvCWeUT6P(GufT@wlW+JA-vYg9)Off0gzJwHXcA2hDj7fsMqUQc5p!uB=ve7Q4}EzLn|UEYP_bdb1pN0 z=Xn5tUawclI=CPRl3uS@dGdI+C~CYWuCws~F5ElDotqP*$GmfMf(!SKjUF>kMU2; z@3QC1C4kXrw9?1RTT$aRaUSEh0I`dH5JZzt0xXko0t=IH0tkP(=LTTg`h39b{sfEI zwim!W3j?rmeZI;42^J~x+C2GhGVPfGya?;_msvNzNEz2Auk)Pg8NjCX`FZS5u!v22 z0nBrz#i2H>&(C9jf<il;Qo8HvWH1FBfAPU!aJTI7WR-db_~!c` zlXH%P^P8{Yoj?D;^&7iZ{!O7}G<<)1@a9{?oyi!tH=0A6XM)rLeEi`Dr~l)BfBRhk zKAg@hOn{`9=^@bbJVa51*=&YtwTf!Bs)s;J8T(y;9s=#84I;?t sjUaLgfSdv#rvS()0CEa|oB|;CAFpt`@5aGgs{jB107*qoM6N<$f~raG0ssI2 delta 1024 zcmV+b1poWz3iAq(+<$^eL_t(|obBB)h#XY_#_?~?UDpg5iz9L_E{8VPMbyepJF&Sm z+DVwPFbfG>nlKzJ25rJ(lR%0^!Ck~gEW|Xy?yO8B7QrH?rU;9BNA$R1!mfDao<;Bo z;j+1zeKWH!-}fu8n0Yt%zc;g&c`x3^#s-AfLe&G1YAFD63X>%R5|RTDe_SB}bUGaq zMUk;_tSE|1r_-@=tTL22UK`ihdH``8nwJ0ad8oGKpcCvj@j*Y&Cbpay4|j|V-~55@!Go1g?$QWx7$|kfwqoQ zma@k?>-h=^U^pDk_3?^U)_854$NDWm+@e1Ok&}P}Ad_AK9Dg|lK<+pTwiDm2a%Gnv9*XwyVzoM_hJ z*Gr*i&aRnbz7GJn{MjYS7czV2*39x!6Q@^K-~Q{`wI8b zUjO5FoWHQ{o(VDs@X-hFANgxto&k} zzp!ptpG)${^$@u4dsrAh_+`6)PYW|#mMMVdcl&6yPQdqneT>Ir06>x?0Dv_82RLPa zfKseX&j5qLz#9&S7>!0qk_1~@TbN8HNYfO9!9dflgL2&hn$70H3;+OWnpzu>lq=H= z5Qd=%f&iPFn+IP@(-c7vAPmFGKMG2AnQsAUnqp;T<=|^U5a<@*uw4HZ@aPOMFZ2;G zyIcW0Is?pC3;po3d#Yvt$u8GJV5`+ak|dZ+CaBeFsMTtE2y|5D{Q(~LgVsZ!o3ud$ uIlU1?P63cp0OS+^IR!vY0gzJwD-U_j*X26T zlJ)Cx9$*jz(Re(za=C127svCws9Y}Fcs#Zs2nrElUh{Ri&a>pP{+XNsx3;#-%&gz< zmy#}y=Xp`T-!I)9uPE}GuZwk_C9m~&9^ljOf9%`dh0`&=?OoW@?|+<*nWa4DTARf> z&ywZqDY^bmNDu_k`ue&BK~QovW~bAMuCA`E)9E-HGfR2QH;Z+iCCk^7*rMA za5YX|@}6(j$IE*BOaeSPIa%oOvX<9;m*F_hFTp?@Jcx#qP5~y9T>%$=2oO>P2&skN zA8?*!+ly}%E%g3?^W?dA;LXN-S?Z;>-9=z*JnZ3$C!-S>-9>z?>FuE*_!J^{Nwg(!u8r8e_l)d=3n^z z0oBJ)9&gdPc=H!xf51f$I9Ad2D9nS4HDP~1Nbw*VlTQLIe{e~>eD%7JUl$<2C2?=_ ze(n(-Y#*dP9)FU*WZt}e7k&Epp)lXxyQ`i+(fGdq-*j=37C&L*qf!k+5Bu9V=v|6p{zb7{&NQM9t;0)*v zp8;dI`J0e145yD_%y<-&6amJ>?}FVTKuGZ!5K;sPe<=cl6ahkt03k(ykRm`xt^D5u z*6Vfk6jmB%Ku8fFqzDjF1PCbtgcJcnDpi0RjmEaCiC{G)4sfH<*#5HlU`T{WBT;}G zjmGxi@sr_;i*qAFq>(7V%faBV@$*Oh>%&L(;^Mr1IT#$eo)}g`;!E)5U~u^S_b=i@ pDyeQl28a)7@fZe^PXaU+)L$9zop`>1!mt1U002ovPDHLkV1n^5%hCV< delta 923 zcmV;M17!S?3Y-d%;cF&IL_t(|obB8(XcJK!$MOG(B_iTblqwX1*>wxJ*^Vww&caOw z^{9(EgrGP{>Y~IU=n!xaT)Vi|P3YLkUHX4mAj^j#1Sk`=fuJa^itbZYAz~$v-Gcy|u27&A1 zgkhKt27}=EcvVr>e0{9*BxS9?_W-Yb`E8$`?Ry>b)3bfM_T{(NF^g2jd|8WF=Shlu zJ%R72E-o%w9LIsLF}vMvdT?-H-EP<0m_;gMzD2C_Bt^cS!tR1wt(KQdg0FGP zQucg{K3>t|7ZTvk&dyYiSG2O`I}6A0ehCJ$;6XH#aRMEaU;-w8P5u6WCz-Xq_~y}6 z?+62;zuRokPmDk`x*;7Mj}FTSd1wOVNuMQPrvkM{t#Z!FlY z=S$Y__XD%Tv!L%|9F5uU_k&x{mu&mSg6~88<=@wY!?oXjw~+hIKlS?qs*j;O-n8@a z=C8#5fYWfSs_jt=SOy=q@^XT!D^wrB3mHGDGY4rrECW@l}zUzCvUS)ph(}Vysh@vQMHk;OHG^}2) zo0-{gIJ6{5EQ+F(2(u$V2laa0hQpzmnI%ago=vrJ6OvJ*(NIrerf>$#px5gKN0(tU zv)$c)T{AP=+uP$apd$iwu)4ZBz66^c1_(D?f-^We`>n69kNGF9yn zj2X`XGmD}qZMWOwyI-@z2)P8i;SA{D-!mZG5uk&1yFLE*(G3aQ5TFCjfd23qFoWa2 z2}zP<{20cJM=`DlFe82!>=yw-iqC+MB0xxg5g?=p5K;sPDFTEP0YYl-{~mBfc=MS>HDS2n?#5_oC54WTuZN? zJ!^OOzZ(%E52pZIZ(av`=g!;5D_8AX?Tr1{*!b*wVwexkm*6{3p9Eij{j}Db*L)Wb x0?u;Xgxr7omiUkhk6|E_X#ypaU;+;o{Q(VmmU!P8ULODe002ovPDHLkV1i#$(gFYg From 85b589490d09d8d7d1f7c6df32fbffec16f3611b Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sat, 8 Mar 2025 21:50:08 +1100 Subject: [PATCH 141/512] Automatic changelog generation for PR #4930 [ci skip] --- html/changelogs/AutoChangeLog-pr-4930.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4930.yml diff --git a/html/changelogs/AutoChangeLog-pr-4930.yml b/html/changelogs/AutoChangeLog-pr-4930.yml new file mode 100644 index 000000000000..69d95d22c025 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4930.yml @@ -0,0 +1,4 @@ +author: Cerebulon +changes: + - {imageadd: 'New icons for a variety of objects, mostly machines and grenades.'} +delete-after: true From 24638629a83365fe1c10ffdc24c91644ad3734c8 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 9 Mar 2025 00:45:35 +0000 Subject: [PATCH 142/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-4930.yml | 4 ---- 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4930.yml diff --git a/html/changelog.html b/html/changelog.html index 6c9d76150a95..dd22d85f14bd 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->

+

09 March 2025

+

Cerebulon updated:

+
    +
  • New icons for a variety of objects, mostly machines and grenades.
  • +
+

02 March 2025

MistakeNot4892 updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 830056235331..a685bdd0d080 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14993,3 +14993,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. MistakeNot4892: - tweak: Old browser-based module selection for robots has been removed, use the INV button to open storage like you would a belt/backpack. +2025-03-09: + Cerebulon: + - imageadd: New icons for a variety of objects, mostly machines and grenades. diff --git a/html/changelogs/AutoChangeLog-pr-4930.yml b/html/changelogs/AutoChangeLog-pr-4930.yml deleted file mode 100644 index 69d95d22c025..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4930.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Cerebulon -changes: - - {imageadd: 'New icons for a variety of objects, mostly machines and grenades.'} -delete-after: true From 08bd524b0be0805c6a348f02e5a3d7b793aa6306 Mon Sep 17 00:00:00 2001 From: Cerebulon Date: Sun, 9 Mar 2025 03:28:31 +0000 Subject: [PATCH 143/512] Converting the Tajaran modpack back to old sprite style --- mods/species/tajaran/datum/accessory.dm | 282 +++++++++--------- mods/species/tajaran/datum/species.dm | 5 +- .../tajaran/datum/species_bodytypes.dm | 10 +- mods/species/tajaran/icons/body.dmi | Bin 1430 -> 1422 bytes mods/species/tajaran/icons/body_male.dmi | Bin 0 -> 1379 bytes mods/species/tajaran/icons/cosmetics.dmi | Bin 584 -> 313 bytes mods/species/tajaran/icons/deformed_body.dmi | Bin 1356 -> 1494 bytes .../tajaran/icons/deformed_body_male.dmi | Bin 0 -> 1490 bytes mods/species/tajaran/icons/eyes.dmi | Bin 400 -> 253 bytes mods/species/tajaran/icons/hair.dmi | Bin 8505 -> 31399 bytes mods/species/tajaran/icons/markings.dmi | Bin 6502 -> 6735 bytes mods/species/tajaran/icons/markings_old.dmi | Bin 22482 -> 0 bytes mods/species/tajaran/icons/skeleton.dmi | Bin 1575 -> 1613 bytes mods/species/tajaran/icons/tail.dmi | Bin 4472 -> 2149 bytes 14 files changed, 162 insertions(+), 135 deletions(-) create mode 100644 mods/species/tajaran/icons/body_male.dmi create mode 100644 mods/species/tajaran/icons/deformed_body_male.dmi delete mode 100644 mods/species/tajaran/icons/markings_old.dmi diff --git a/mods/species/tajaran/datum/accessory.dm b/mods/species/tajaran/datum/accessory.dm index 9c893b7669ab..7d40b46a502d 100644 --- a/mods/species/tajaran/datum/accessory.dm +++ b/mods/species/tajaran/datum/accessory.dm @@ -12,159 +12,163 @@ return src return GET_DECL(/decl/sprite_accessory/hair/bald) -/decl/sprite_accessory/hair/taj/straight - name = "Tajaran Straight Hair" - icon_state = "hair_straight" - uid = "acc_hair_taj_straight" /decl/sprite_accessory/hair/taj/clean name = "Tajaran Clean" - icon_state = "hair_clean" + icon_state = "hair_clean_s_noear" uid = "acc_hair_taj_clean" +/decl/sprite_accessory/hair/taj/bangs + name = "Tajara Bangs" + icon_state = "hair_bangs_s_noear" + uid = "acc_hair_taj_bangs" + +/decl/sprite_accessory/hair/taj/braid + name = "Tajara Braid" + icon_state = "hair_tbraid_s_noear" + uid = "acc_hair_taj_braid" + /decl/sprite_accessory/hair/taj/shaggy - name = "Tajaran Shaggy" - icon_state = "hair_shaggy" + name = "Tajara Shaggy" + icon_state = "hair_shaggy_s_noear" uid = "acc_hair_taj_shaggy" /decl/sprite_accessory/hair/taj/mohawk name = "Tajaran Mohawk" - icon_state = "hair_mohawk" + icon_state = "hair_mohawk_s_noear" uid = "acc_hair_taj_mohawk" /decl/sprite_accessory/hair/taj/plait - name = "Tajaran Plait" - icon_state = "hair_plait" + name = "Tajara Plait" + icon_state = "hair_plait_s_noear" uid = "acc_hair_taj_plait" +/decl/sprite_accessory/hair/taj/straight + name = "Tajara Straight" + icon_state = "hair_straight_s_noear" + uid = "acc_hair_taj_straight" + /decl/sprite_accessory/hair/taj/long - name = "Tajaran Long Hair" - icon_state = "hair_long" + name = "Tajara Long" + icon_state = "hair_long_s_noear" uid = "acc_hair_taj_long" /decl/sprite_accessory/hair/taj/spiky - name = "Tajaran Spiky" - icon_state = "hair_tajspiky" + name = "Tajara Spiky" + icon_state = "hair_tajspiky_s_noear" uid = "acc_hair_taj_spiky" -/decl/sprite_accessory/hair/taj/bangs - name = "Tajaran Bangs" - icon_state = "hair_bangs" - uid = "acc_hair_taj_bangs" - /decl/sprite_accessory/hair/taj/messy - name = "Tajaran Messy" - icon_state = "hair_messy" + name = "Tajara Messy" + icon_state = "hair_messy_s_noear" uid = "acc_hair_taj_messy" -/decl/sprite_accessory/hair/taj/braid - name = "Tajaran Braid" - icon_state = "hair_tbraid" - uid = "acc_hair_taj_braid" - /decl/sprite_accessory/hair/taj/bob - name = "Tajaran Bob" - icon_state = "hair_tbob" + name = "Tajara Bob" + icon_state = "hair_tbob_s_noear" uid = "acc_hair_taj_bob" -/decl/sprite_accessory/hair/taj/weave - name = "Tajaran Fingerweave" - icon_state = "hair_fingerwave" - uid = "acc_hair_taj_weave" - /decl/sprite_accessory/hair/taj/sidebraid - name = "Tajaran Sidebraid" - icon_state = "hair_sidebraid" + name = "Tajara Sidebraid" + icon_state = "hair_sidebraid_s_noear" uid = "acc_hair_taj_sidebraid" + /decl/sprite_accessory/hair/taj/ribbons - name = "Tajaran Ribbons" - icon_state = "hair_ribbons" + name = "Tajara Ribbons" + icon_state = "hair_ribbons_s_noear" uid = "acc_hair_taj_ribbons" -/decl/sprite_accessory/hair/taj/combed - name = "Tajaran Combed" - icon_state = "hair_combedback" - uid = "acc_hair_taj_combed" +/decl/sprite_accessory/hair/taj/combedback + name = "Tajara Combedback" + icon_state = "hair_combedback_s_noear" + uid = "acc_hair_taj_combedback" /decl/sprite_accessory/hair/taj/tailedbangs - name = "Tajaran Tailed Bangs" - icon_state = "hair_tailedbangs" + name = "Tajara Tailedbangs" + icon_state = "hair_tailedbangs_s_noear" uid = "acc_hair_taj_tailedbangs" -/decl/sprite_accessory/hair/taj/lynx - name = "Tajaran Lynx" - icon_state = "hair_lynx" - uid = "acc_hair_taj_lynx" - /decl/sprite_accessory/hair/taj/longtail - name = "Tajaran Long Tail" - icon_state = "hair_longtail" + name = "Tajara Longtail" + icon_state = "hair_longtail_s_noear" uid = "acc_hair_taj_longtail" /decl/sprite_accessory/hair/taj/shy - name = "Tajaran Shy" - icon_state = "hair_shy" + name = "Tajara Shy" + icon_state = "hair_shy_s_noear" uid = "acc_hair_taj_shy" /decl/sprite_accessory/hair/taj/ponytail - name = "Tajaran Ponytail" - icon_state = "hair_ponytail" + name = "Tajara Ponytail" + icon_state = "hair_ponytail_s_noear" uid = "acc_hair_taj_ponytail" /decl/sprite_accessory/hair/taj/overeye - name = "Tajaran Overeye" - icon_state = "hair_overeye" + name = "Tajara Overeye" + icon_state = "hair_overeye_s_noear" uid = "acc_hair_taj_overeye" /decl/sprite_accessory/hair/taj/tough - name = "Tajaran Tough" - icon_state = "hair_tough" + name = "Tajara Tough" + icon_state = "hair_tough_s_noear" uid = "acc_hair_taj_tough" /decl/sprite_accessory/hair/taj/cuttail - name = "Tajaran Cut Tail" - icon_state = "hair_cuttail" + name = "Tajara Cuttail" + icon_state = "hair_cuttail_s_noear" uid = "acc_hair_taj_cuttail" /decl/sprite_accessory/hair/taj/dreadlocks - name = "Tajaran Dreadlocks" - icon_state = "hair_dreadlocks" - uid = "acc_hair_taj_deadlocks" + name = "Tajara Dreadlocks" + icon_state = "hair_dreadlocks_s_noear" + uid = "acc_hair_taj_dreadlocks" + +/decl/sprite_accessory/hair/taj/fingerwave + name = "Tajaran Fingerwave" + icon_state = "hair_fingerwave_s_noear" + uid = "acc_hair_taj_fingerwave" + +/decl/sprite_accessory/hair/taj/lynx + name = "Tajaran Lynx" + icon_state = "hair_lynx_s_noear" + uid = "acc_hair_taj_lynx" + +//Facial hs /decl/sprite_accessory/facial_hair/taj - name = "Tajaran Sideburns" + name = "Tajara Sideburns" icon_state = "facial_sideburns" species_allowed = list(/decl/species/tajaran::uid) icon = 'mods/species/tajaran/icons/facial.dmi' - color_blend = ICON_MULTIPLY uid = "acc_fhair_taj_sideburns" /decl/sprite_accessory/facial_hair/taj/mutton - name = "Tajaran Mutton Chops" + name = "Tajara Mutton" icon_state = "facial_mutton" uid = "acc_fhair_taj_mutton" /decl/sprite_accessory/facial_hair/taj/pencilstache - name = "Tajaran Pencil Moustache" + name = "Tajara Pencilstache" icon_state = "facial_pencilstache" uid = "acc_fhair_taj_pencilstache" /decl/sprite_accessory/facial_hair/taj/moustache - name = "Tajaran Moustache" + name = "Tajara Moustache" icon_state = "facial_moustache" uid = "acc_fhair_taj_moustache" /decl/sprite_accessory/facial_hair/taj/goatee - name = "Tajaran Goatee" + name = "Tajara Goatee" icon_state = "facial_goatee" uid = "acc_fhair_taj_goatee" /decl/sprite_accessory/facial_hair/taj/smallstache - name = "Tajaran Small Moustache" + name = "Tajara Smallsatche" icon_state = "facial_smallstache" uid = "acc_fhair_taj_smallstache" +//Markings /decl/sprite_accessory/marking/tajaran name = "Tajaran Nose" icon_state = "nose" @@ -175,41 +179,26 @@ uid = "acc_marking_taj_nose" /decl/sprite_accessory/marking/tajaran/ears - name = "Tajaran Wide Ears" + name = "Tajaran Ears" icon_state = "ears_plain" mask_to_bodypart = FALSE uid = "acc_marking_taj_wideears" -/decl/sprite_accessory/marking/tajaran/ears/wide_inner - name = "Tajaran Wide Ears Interior" - icon_state = "ears_plain_inner" +/decl/sprite_accessory/marking/tajaran/ears/inner + name = "Tajaran Ears Interior" + icon_state = "earsin" uid = "acc_marking_taj_wideears_inner" +/decl/sprite_accessory/marking/tajaran/ears/outer + name = "Tajaran Ears Exterior" + icon_state = "earsout" + uid = "acc_marking_taj_wideears_outer" + /decl/sprite_accessory/marking/tajaran/ears/wide_tuft - name = "Tajaran Wide Ears Tuft" - icon_state = "ears_plain_tuft" + name = "Tajaran Ear Tufts" + icon_state = "earsout_tuft" uid = "acc_marking_taj_wideears_tuft" -/decl/sprite_accessory/marking/tajaran/ears/narrow - name = "Tajaran Narrow Ears" - icon_state = "ears_narrow" - uid = "acc_marking_taj_narrowears" - -/decl/sprite_accessory/marking/tajaran/ears/narrow_inner - name = "Tajaran Narrow Ears Interior" - icon_state = "ears_narrow_inner" - uid = "acc_marking_taj_narrowears_inner" - -/decl/sprite_accessory/marking/tajaran/ears/narrow_tuft - name = "Tajaran Narrow Ears Tuft" - icon_state = "ears_narrow_tuft" - uid = "acc_marking_taj_narrowears_tuft" - -/decl/sprite_accessory/marking/tajaran/ears/earrings - name = "Tajaran Earrings" - icon_state = "taj_earrings" - uid = "acc_marking_taj_earrings" - /decl/sprite_accessory/marking/tajaran/patches name = "Patches (Body)" icon_state = "patches" @@ -237,14 +226,17 @@ body_parts = list(BP_R_LEG, BP_R_FOOT) uid = "acc_marking_taj_patches_rightleg" +/decl/sprite_accessory/marking/tajaran/patches/head + name = "Patches (Head)" + icon_state = "patchesface" + body_parts = list(BP_HEAD) + uid = "acc_marking_taj_patches_head" + + /decl/sprite_accessory/marking/tajaran/tiger - name = "Tiger Stripes (Head)" + name = "Tiger Stripes (Body)" icon_state = "tiger" accessory_flags = HAIR_LOSS_VULNERABLE - uid = "acc_marking_taj_tiger_head" - -/decl/sprite_accessory/marking/tajaran/tiger/body - name = "Tiger Stripes (Body)" body_parts = list(BP_CHEST, BP_GROIN) uid = "acc_marking_taj_tiger_body" @@ -268,36 +260,11 @@ body_parts = list(BP_R_LEG, BP_R_FOOT) uid = "acc_marking_taj_tiger_rightleg" -/decl/sprite_accessory/marking/tajaran/spots - name = "Spots (Head)" - icon_state = "spots" - accessory_flags = HAIR_LOSS_VULNERABLE - uid = "acc_marking_taj_spots_head" - -/decl/sprite_accessory/marking/tajaran/spots/body - name = "Spots (Body)" - body_parts = list(BP_CHEST, BP_GROIN) - uid = "acc_marking_taj_spots_body" - -/decl/sprite_accessory/marking/tajaran/spots/left_arm - name = "Spots (Left Arm)" - body_parts = list(BP_L_ARM, BP_L_HAND) - uid = "acc_marking_taj_spots_leftarm" - -/decl/sprite_accessory/marking/tajaran/spots/right_arm - name = "Spots (Right Arm)" - body_parts = list(BP_R_ARM, BP_R_HAND) - uid = "acc_marking_taj_spots_rightarm" - -/decl/sprite_accessory/marking/tajaran/spots/left_leg - name = "Spots (Left Leg)" - body_parts = list(BP_L_LEG, BP_L_FOOT) - uid = "acc_marking_taj_spots_leftleg" - -/decl/sprite_accessory/marking/tajaran/spots/right_leg - name = "Spots (Right Leg)" - body_parts = list(BP_R_LEG, BP_R_FOOT) - uid = "acc_marking_taj_spots_rightleg" +/decl/sprite_accessory/marking/tajaran/tiger/head + name = "Tiger Stripes (Head)" + icon_state = "tigerface" + body_parts = list(BP_HEAD) + uid = "acc_marking_taj_tiger_head" /decl/sprite_accessory/marking/tajaran/pawsocks name = "Pawsocks (Left Arm)" @@ -321,9 +288,58 @@ body_parts = list(BP_R_LEG, BP_R_FOOT) uid = "acc_marking_taj_pawsocks_rightleg" +/decl/sprite_accessory/marking/tajaran/tuxedo + name = "Tuxedo (Body, Legs, Feet)" + icon_state = "tuxedo" + body_parts = list(BP_CHEST, BP_GROIN, BP_R_LEG, BP_R_FOOT, BP_L_LEG, BP_L_FOOT) + accessory_flags = HAIR_LOSS_VULNERABLE + uid = "acc_marking_taj_tuxedo_body" + +/decl/sprite_accessory/marking/tajaran/tuxedo/right_arm + name = "Tuxedo (Right Arm)" + body_parts = list(BP_R_ARM, BP_R_HAND) + uid = "acc_marking_taj_tuxedo_rightarm" + +/decl/sprite_accessory/marking/tajaran/tuxedo/left_arm + name = "Tuxedo (Left Arm)" + body_parts = list(BP_L_ARM, BP_L_HAND) + uid = "acc_marking_taj_pawsocks_leftarm" + /decl/sprite_accessory/marking/tajaran/belly - name = "Belly" - icon_state = "belly" + name = "Belly Full (Body)" + icon_state = "bellyfull" body_parts = list(BP_CHEST, BP_GROIN) accessory_flags = HAIR_LOSS_VULNERABLE uid = "acc_marking_taj_belly" + +/decl/sprite_accessory/marking/tajaran/belly/upper + name = "Belly Upper (Body)" + icon_state = "crest" + body_parts = list(BP_CHEST) + uid = "acc_marking_taj_bellyupper" + +/decl/sprite_accessory/marking/tajaran/belly/lower + name = "Belly Lower (Body)" + icon_state = "belly" + uid = "acc_marking_taj_bellylower" + +/decl/sprite_accessory/marking/tajaran/backstripe + name = "Back Stripe (Body)" + icon_state = "backstripe" + body_parts = list(BP_CHEST, BP_GROIN) + accessory_flags = HAIR_LOSS_VULNERABLE + uid = "acc_marking_taj_backstripe" + +/decl/sprite_accessory/marking/tajaran/muzzle + name = "Muzzle Coloration (Head)" + icon_state = "muzzle" + body_parts = list(BP_HEAD) + accessory_flags = HAIR_LOSS_VULNERABLE + uid = "acc_marking_taj_muzzle" + +/decl/sprite_accessory/marking/tajaran/chin + name = "Chin Coloration (Head)" + icon_state = "chin" + body_parts = list(BP_HEAD) + accessory_flags = HAIR_LOSS_VULNERABLE + uid = "acc_marking_taj_chin" \ No newline at end of file diff --git a/mods/species/tajaran/datum/species.dm b/mods/species/tajaran/datum/species.dm index 7282b912bc7a..ec391b696db5 100644 --- a/mods/species/tajaran/datum/species.dm +++ b/mods/species/tajaran/datum/species.dm @@ -19,7 +19,10 @@ description = "A small mammalian carnivore. If you are reading this, you are probably a Tajaran." hidden_from_codex = FALSE - available_bodytypes = list(/decl/bodytype/tajaran) + available_bodytypes = list( + /decl/bodytype/tajaran, + /decl/bodytype/tajaran/masculine + ) traits = list(/decl/trait/malus/intolerance/caffeine = TRAIT_LEVEL_MAJOR) diff --git a/mods/species/tajaran/datum/species_bodytypes.dm b/mods/species/tajaran/datum/species_bodytypes.dm index f2ae05c42dcf..cafd64384fba 100644 --- a/mods/species/tajaran/datum/species_bodytypes.dm +++ b/mods/species/tajaran/datum/species_bodytypes.dm @@ -1,5 +1,5 @@ /decl/bodytype/tajaran - name = "felinoid" + name = "feminine" bodytype_category = BODYTYPE_TAJARAN limb_blend = ICON_MULTIPLY icon_template = 'mods/species/tajaran/icons/template.dmi' @@ -78,6 +78,14 @@ ) . = ..() +/decl/bodytype/tajaran/masculine + name = "masculine" + icon_base = 'mods/species/tajaran/icons/body_male.dmi' + icon_deformed = 'mods/species/tajaran/icons/deformed_body_male.dmi' + associated_gender = MALE + onmob_state_modifiers = null + uid = "bodytype_tajaran_masc" + /decl/bodytype/tajaran/get_default_grooming_results(obj/item/organ/external/limb, obj/item/grooming/tool) if(tool?.grooming_flags & GROOMABLE_BRUSH) return list( diff --git a/mods/species/tajaran/icons/body.dmi b/mods/species/tajaran/icons/body.dmi index 5facaf8686da3e10f38988b10a5a3f14249e3213..7f3a5afd6b53d5525aba84e62874a36201183213 100644 GIT binary patch literal 1422 zcmV;91#$X`P)^{@K0do70aXfR@;{X5zU`a$lRCt{2oXu|2KoG~hP9@+FRIghk zBo2w4NJR$hkZMFTjO!Umy`LkUj(Mfn;WO z6DK(C7xU{SyWW}qj@Pk0yPG6~Pls*0_)iW-DZ`O#9uy^h)&{f|n$9RTr{< zDFl5kn0ZPI7Ze0R5ClOG1VIo4$1@VjG(p8xDx`b06;C*6d&6I9Puy*t8iHQ;6t{TX zAuaqa-z@HR(NDj-++S*s4U}i@HD`4m-8sODti8pbXOR$YHhheYF`qLoL=($%hwrxu z0V+l6sqpNqO3J{e7w0UvySGbbjI#w7=^(50kKl5H3MoB0Xb}e*GUnRU5uMCaYzA2c zY?ix3rzh_x32o2kPr07oZj*ao+Cy?{O3x9S)6O?rsKbLM?y{d=bwoi&2h`$oMhKHx zfO@M1>%+1Fhyc(@P6Moyb6RTV3UMK>AGD$!fxlQPfL0q@Y_`Du>#QkRhPO@p z40Si64IF_A_v=k;P;ai}8bq&l{Go~+gb}$@s6cOZu|c;}%@v{3X*Iu+as;@nLQTrf z1E}V^O!?+V7NHZEf@JgL+yz4q-sAE;@Nzv4RQf$6H(!W0$g)A;!xwDu4c2mvp-Lm9 zf}IW#+y{7v4SoTv#-uV(}2MQ2u!``U)12zj5)R4p|!AfdLu^FqQ8oM~7OOj6o|Ch`b7X!=3OL~24F#SOMO^E;%@c;k-07*qoM6N<$f&|2k>i_@% literal 1430 zcmV;H1!?+;P)s}0004WQchCV=-0C=2@k-G}RFbqX!`zuVcm%fHBT}nd8(ELI%wPFjL7-Z4@e&a5kinZMf zM;8ui&8;8C$#nNozko8P)m+Vax7X^8j>A??N38;&4_wMcXSNJmYyw!ohYE3_N-`9Tt zHaU=Y>`4D{000DeNkl%Zw!+q%yfxbbX zpjpd70{F4(4$?8t6+QAqSDqj_-)b(U;XS4(%R2m7EC?ar2&s;^FJTzJYIKQ9xr_QJLa+bkl^@a z0q!0uw5t?RfJ=E3nfK!OWc)5R5GRbSk0~p#$<=UtGPSFr57aA+k8QNeTcAaK(=nT| zKIP#)T0X~YS=}taP6UIsTX=@v%DW!oSVKG=`6G6CLX$^!b>_6M z#%fnc2qAc0!QIHz=4YAb}G*6yQV?cx9t-bsyo? z#&ro|>(D)4taSyL5L2GPbg_dbu?Yp4gfE*@S;laive@0FF60@v;SSyMyY3H70j9fy z1SW+53D>EEYp@PUT$8B+I%skmQ-ogVTtER`#9lj*V;>9k6Y)_1_6Zks1uR+zV?cHl zaX`X4yf53Nd>d}N4k~P;uvA=!cR^4V-~x2|p~vIoZKy1u758;p<77eI5^6KnjB6CJbs^Vkh+z`)uV?4{-vQ%XIP|jDw6-t31#tut|Qv<9&o7c5-zA zZYN7>aT}|Ca}V*qh=QtZ;CPY>mHGHu3fT5=+^G&V4|(0ok`_vgf8JgBZ2UlgZy=m| zpmQhy`@rnHxPWRE>5JCtcguFP#AN}C6sajeCOsV?3(5`hICCR$<;%75c$A)=d zOkD92WTjSj7P7>ovVc>w&n=*QfwN*e@5`|%zx&%vS39#kKnVE(um|yNdj$suQds$Q z-|HqTjKks+rb6>uy8)K1w0Z}_*L$?v|D0dI0*AA!Sp^V62qA(qaky} zimsW!-8RYsGFPnVnhCuAq>_^>R(8#hT6aR?L)!n}UCy{>lLRa;IQ!8RJL8%O0ohEb zuW-3auG{1JXX-=p8cn%1+FU@3xpbXZ6N_(J`SdR_A;WG|1uV+d<&(D$y>3QA2qAQ38>@P8PDa=;zz7v#%-JSCuD@rZr52A2MQce1$cMqB|5zf>qU49qug zbA_3~*aS}2S-I0(?QMbv*p!wtqU47PPBVAqX2B0E^T5VIorjZuU%?z$8%hm;l7#>x k1}91aiglJb9G)ou7xurG{N>jnmH+?%07*qoM6N<$g2wQlh5!Hn diff --git a/mods/species/tajaran/icons/body_male.dmi b/mods/species/tajaran/icons/body_male.dmi new file mode 100644 index 0000000000000000000000000000000000000000..a4577a11a6ecf3fad199733a9e501b2836cf9c0b GIT binary patch literal 1379 zcmV-p1)TbcP)^{@K0do70aXfR@;{X5zHAzH4RCt{2oV{|>KoG}$a*8x&EGglm zvri6_l4wH$9kEkUfq4S(jK(umBr|~$0^{)vRdD4xJOq!C7qEvHu%7{?z`ET%TNbkN z#r`VY>309OI$74re{{G z78hg@&f0T-#Qr}JwBDqplD!}EnF-GECkTQd2!bF8HxHig6%5b!3Wn!<1v4i}EKu;u zBfL&Q`wi$3SU_T4Uq<))o9j8O?#FvrV46%gs+ohU1w*Rk@vTa zYNw5sYwt(Zew5&{-zvY~w}OQ`A58B6EKp;Qm0fg#;Z9SP-5yZV6%cQJsA;}P*Hqsihl=|5fV`}GSdgq5 zD1JuGF(#_)T z(D>>1kot@5O#|ifz2>COMLncN(%$0FwMYmz8#=~p%vX#9;llFDq5EwDfLf7yDmXu{ zqcYIx#Z?Qw?_?CL;z3sQ|4|%jP(!8r-3S?YkTTb%K7PPuGJ~u%ndL6y>B;qeAGfFT zr&Q1Xbc~*TaSzd>DZWNzPCMUhp%-*JW|#f=u0sl5*u{dqln@rP276HiyNNr15Wtuq zRe`^EYFcb}cJhR{){F(i!=wV>$H4qxDeXt^OpC|Sj{VnJOR@>wj`E3>FbKiiI;gYpndpa8a#x2cPWby1_LD626$^4+y~goC8$r1upr$6`Qe^RI3*m z8C^f>7W_9E@q1zab5dOI_hfg7AP9G#$^@6k7uPCSv6!E1EBh{pNgZCa`*g6iQQ)dWNh-ywA0FiDPW1niR`07g?d|(BOI1(4{?|7D zdUBM^oi{I;H?1^0`m@Ex3h1OfPZ!6KiaBp@845KRaIhSxxi24|?lrf^ch-Wm?F&;I z7Vf$RRHde3xw`sB*rdmCJ1x#Q@d*KiAi&PkZ0iM!67PollPl{P_lv>A86r|ra{^t8 hR00eIyy1cm0@=&`O_?U#{iX;K^K|udS?83{1OTK4bdvx8 literal 584 zcmeAS@N?(olHy`uVBq!ia0vp^2|!%L!3HGPv|U*Nq&liXB1&9Ri<65o3raHc^B5Q^ z=Cq#L$k${b!1iG0cai!8b0r?VSe_##4doe^CdVz(eQ7Fm|K3E4pJ(H{Z*R zcDI+`1_{4(quni1i5KHfxJ)w*i}(_L>6P~3MU|(P@y=9mO*EWPDe^z5)wNvZ-v&4N zPyfo7#VlU(wc_siY(rgTpc&#@cN?CTF;?Bfz`$7T>EaktG3V{=gSkwG46X-NWtT{o zyYZGBy?A#?%M+m`G2$L-arf>xUbEAkHsRmPs=axI_r5U3#WHSSN?<*})ga2C%@D@0 zh9LqZz|Sg?Tx0iI!F}WRnRjFpdJ1P2&pReDy?X!SjJ)$H=hOZEN@ta_W9q{&h>$=k z^POpytMyB!@qDmlwaUM}?X2Z_ZTE~tEpMxsk4ebyFP#v+Rr|o4&$Uml|FwUm&Jq1d z$ZirA2NSXfRm+WFrjDy;0;gH=v;Wu`@yC1hdgc6C8i{uq!Ja40ET9(s{W^v#mU3-$ Q045CvPgg&ebxsLQ0J2roZU6uP diff --git a/mods/species/tajaran/icons/deformed_body.dmi b/mods/species/tajaran/icons/deformed_body.dmi index 09a348406db00e100a70b3046bd424d93a1f01f4..42c45ef556a520715f1464c85b41d40f57434415 100644 GIT binary patch delta 1299 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 literal 0 HcmV?d00001 diff --git a/mods/species/tajaran/icons/eyes.dmi b/mods/species/tajaran/icons/eyes.dmi index e7b1f1241a27ef98bdefffd42c9e4ab05716dac3..d9f4f5d9a86aaff53bc05c5455295266eab75ef8 100644 GIT binary patch delta 238 zcmbQh{FiZpc)bG$8v_Hws?5TBKq|W`B%;J6wK%ybv!En1KaYW-Vvg!@YrX~r0oDVv zY>#q(I~KpYw^4#?M|0=ufEAnqd-t_o_HDkYr+1*jz5mIicicTI-+JuLTrJpBs358; zyYZi9=~||?YfH9G;g%3yX}f;8h(T3WLUZHCKD$}}CHQ9Bq)(^@+Ux7-;uumf=j|;; zz5@n4EC=_f{{R1Ynn+9AlBq_{IcX=q=P@u; z%wavam#aZRgzdu3-y-tc-0k^v%Q;nLzQ{7^%4!9yy#9U;-|Cxd+RLWhi^!_WGYGMt z@S`Y$v!_yNVv=1jb8_5@ZF^k}mZ%68txV7ma=*Dg;-JLJ=8sahB7ZT?;gt|cxv}>n z(BgZZE{-7;bKc(C$a`2pgyEva;uOKKbiwzNj=4^`=DGsckwVd<_n*z_xBh&E zX%r9IgVJD*J7}rz+>vw&wf6K!J8tPTPX`8!$la;9%*Cc<9a8o|zjO5d?NAl=(8cxc~@ SJy(D}W$<+Mb6Mw<&;$S&&XbJ* diff --git a/mods/species/tajaran/icons/hair.dmi b/mods/species/tajaran/icons/hair.dmi index 88380247713eb7dff0aaf3b1936a14436ea1a2ec..ed61015bcff0221e5c528d48d0af918b352d1539 100644 GIT binary patch literal 31399 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 BbsPWy diff --git a/mods/species/tajaran/icons/markings.dmi b/mods/species/tajaran/icons/markings.dmi index e92348f285163ff107bec5227f5adae6af3ab4a8..1b4bc930b2c7139ecb9713a3efb447837c59a246 100644 GIT binary patch literal 6735 zcmb7}cTg0~w!mlMLzE~WQ8EaAOHx2`lBgg#2rLMaB(J0;EkOi9KoF6f6eTS|f-J6N zkg#OQIqZ`2q9BW9^t{&7(V!$_Ap-z_^5Fwj0|0<< zf)8-@3RprXQj7+Z$p9l$Z&iCQTTiFw-cE3L0PxFvGbl^da);u|JVrW#L>5==a9^#E z*a8wU?8ZHqAI&uj9SJsLETj1uA?Z= z)xeINu<<)#uO{raZ)_zwpqzua2g;3&Q+h)GVlh$dJbK}FW5RA+M$mC3@KNq}>#P03 zk$QY;_H?u{WZJo@-I*L}66(q{lt=qyqE%(q^M9^nRd}i#$meq(X)pC)5x*0L*tDs@^y9%iNlQyWU(0BHb0? zfgv0dEA1sJ3nuAcJxRF$$vYC&pBvHjOpwv5OkeG(xc}lwsJpkUbhDBNc9Wv#T6j|# z?bTv^$tK#oP9o;Y&|LM$Oan3X%rEY*7U%9d`aN8O-ePqqxsg!Fisj0#|G<8%nm~Io zEw2$hM{V6Hr~l`K(0M|@tYp`ca&rIE<^F~6(-i4Uhm{p}1qd~_G$Mv(b zv((HwJIyU?NG{5<0lBq&dW!5^`Smn7m|Y^Sou&?83!|=?rprBqRvc6&0_) zxc-?26U%f4*W!C0)nj$z*8&zDy=w7-`r4cbg zh;8EsOB{UUIOo>=@o#b%o=jEPb_@&+y*xM&k)+R&oINbsJt2k8QcW>%YLn|Yr5}s| z2Tw4f$0773UXA%qA;nJ3H zoXvM1*Vorm)4u*;1su9ZY@BAOauagW^UqT9NiOs}_$ZkgZ&=1}>hjXgUD@TchHG_R zKj{TU+`z&bX!3N0SQ>?B8ihfT(MJ;A6y}^~e3tP>)qT!6Rz)vKsoiCIhW9)Dzl@zE z(-Y9R{eZc_{mvuYQl4i?(wrh^9J_opIJrql^d)6wHlBO$Y%d?M!;@2uKXNWkS6WsU zety#M`@Kp7&VSVA9TxX(4avAYPAd*irK#S>_WbVrftjZ^{+L&|e*h0V^pBAoP70#1F zc)0JUXVflSE@OL(Ew5@Y-HIos`RjK>j`Ev$83*@3MMvgU(tYGMMLqh?4H1IaBt%=vGHNr<+mq!lF z6Rzl8p=aI~=V#j8po^)T5EMi%s z^?|-B1W1WAIT{p`x3#5<)I4){b;aEd#gFg}JR(r~Bk{vUF>&hOSZ!ThTRhf>)gtpr z8b8V)ggB(cioPEv?wy{$Xvt%8C_BUlwp$7gy))WU|;b`4U$G0|P?}Z@b@z!*{3?v5QCEGV*`TF9zrcee`R} znjqdq`GEag`n0eW<)jwlJ9eNuF)tPRbN@oI{`{8@ki&VQed?3A=RABkNDegAD)7!$ zv%{*t5U(Ei$<4tyQXSSgf0W*!zB9ZZm70c`6^&GR(PUltQ>MXqSzJD-SHD+C5^dl{ zzN#dXb(*M7H4^W#nfj3gy!?@Jz%{onLuB39fiFV89dnak4pw15G5R6o z^9}EbdCzubf{mlo7kLw3R7X`}^vGXbPi-2D)r#{hICc43lYU3)mB+m{weEyohpE{9 zDfcF8q0Kle9XMRXrXqFl+mY$r-v9X$Z-P1PPg zceS&#n8tV&tQ!)NW@+>t(@hSWx_`F6Lki~D9&jqv;#0VNiQ+q6p87mZfA8qCzpi`K|^&MX~)wG?Te_1p&qLsH1Y ztJB+Yl$gT3VyiQx$_v5?sj5Uq+vV0iH)mz6RfuEI6J!tw$h<(ux4BD;3*FwHt%t3l zoI%fl8wVS1i_l9VrDmUReo30)St+_)kfRXytnTo6z;QYcYg{zA>u5DbY{kKOZCShw zN~aIXW9l9<)BMAwkH5)M2{%xmWJa+!Z2h6W3J$NVtc=p@N&?H0aDcJT-I9C~HC
    UrIkN;riaoQ3A$_w~MctSl__)a-If5*fw^#}K74 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 literal 6502 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 diff --git a/mods/species/tajaran/icons/markings_old.dmi b/mods/species/tajaran/icons/markings_old.dmi deleted file mode 100644 index 4dcd2efaf88c0d0daf69d538f9afca25ac3b6461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22482 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%0Den5-u+)g=fgV-unE9l#d}L9t@j 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 diff --git a/mods/species/tajaran/icons/skeleton.dmi b/mods/species/tajaran/icons/skeleton.dmi index 286b75d741fe302286496c6bcf34f99f5f4dbf1c..4ab2d2bc53d615d3950508b3fdfb7024a5cf0b43 100644 GIT binary patch delta 1610 zcmV-Q2DSO849yIX7JmTX1Oos703L6pV*mgE6;Mo6MF0Q*rlWPw&#C6-##&i5y1Aac zx{@J+qrU(E00DGTPE!Ct=GbNc0060aR9JLGWpiV4X>fFDZ*Bkpc$|&WI|{=v3g6DDR{6n$%_=HV zei&oSucT6@X(~`ohy2NWQJ60aV~swGW`YG_{pV`c_RZ%--rm!k6ts9PY5)KQF-b&0 zRCt{2oxyJ7IDZU=B^l5;aWOqJ7RF~s#`?aq)1G&_ox9=|e*Z_lzW<2z zm+$|e`q`8l?Bdd4ZL6OyD$xFC6<7^0j}J)eeuocOZ+{-67VTZRW^G^TZ+~K4lTM~@ z?_&=1$N;E4QURN1H!Tf=&9yX zljcD^dVh5f^yK}B2W)Z^Tk{%F)DAc3JJKGmSDyK{Iuy8{2Tl5Y>H%H@TIcYLl|1GevA0K_V}U0L1$K@bE%5ClQ^=)kLr79?|6K`LAPB;T!=&T+{dgY-E$H|j z7PUwa1VIqqLL35k#oGS`A_nI{dM;j&41Z6VcSxXSv+;s}rR5!;9)aYaZ0#>x_NY0W z;sN=1K_I%}H{ivo`FH_oui#%?eToO<;{~L>D14FZo_IMV>ZdiJD$BdL-}-FOtcxZS zdwhi9-Q;6jcB>so6IKU?vR6L_pqR;s`V@MfCCp zOn3m&S8zv4VN@>f0lHF&MAdSy0A2&kh)P1`N4S^AHy6c)ljZINrp*0&B)`^--31rf zK)#&XDSU1wpI@Nq;{%xY!c9HDK!4r%xJg~PbYsvgrk-D*+~Zwrz~deBHkqmC7pVU0 zLv+qJUmuunh$f$3V9PJ}XZ8GpZbzI;^85nY3H$YPWYX>Zn){Y;>iGpVD$(l;%emjq zM1I1>v-7=oe!?LX`@dLgq?gXnXu=^sVLbnT$j*oM2MjoSU*QMN&!9hM=YNam{}0*u z(EflP&;43ebKcOvfB6aFtdIE#Pg)so@pQlOfpPxd7Do@n^Z$qJd}x1wp&kIn`F~R! z^ApDN|A+j9Xn#OQJ@CXh|8LCkjN|!#r1yZQ9&n6(z&h1Fxh9Se^nDf3`hnWT@c~Q1zU@0~@v4 zHY*J;x;pB3{lF@H{s8aba#xZ3f<&+AqKyG~4WM~RsRlzs9>6=a+yCqV(trn)tJDBq z4**%%1PwC4sMG-7@qMQZy4rcXyM6ytN$wGE8{WZfm*f{j8gd4(c0+=#(mo#FZ&Ch% z{rEm(0ILf&N<*xNI4-$?ya9aU`@{YMnm>T-FG%tS08`ul0>~Jcg*|yEx&QzG07*qo IM6N<$g8oMs*Z=?k delta 1572 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 From cc2f26d9e3a69072da0fd74bba9a0f8b102c9a4e Mon Sep 17 00:00:00 2001 From: Cerebulon Date: Sun, 9 Mar 2025 06:59:41 +0000 Subject: [PATCH 144/512] Readjust clothing, markings etc. to fit old sprite and multiplicative blending. --- .../tajaran/datum/species_bodytypes.dm | 23 ------------------ mods/species/tajaran/icons/body.dmi | Bin 1422 -> 1422 bytes mods/species/tajaran/icons/body_male.dmi | Bin 1379 -> 1379 bytes .../tajaran/icons/clothing/atmos/suit.dmi | Bin 925 -> 901 bytes .../tajaran/icons/clothing/atmos_alt/suit.dmi | Bin 850 -> 824 bytes .../icons/clothing/deathsquad/suit.dmi | Bin 1106 -> 1086 bytes .../icons/clothing/engineering_alt/suit.dmi | Bin 843 -> 824 bytes .../icons/clothing/excavation/suit.dmi | Bin 968 -> 936 bytes .../tajaran/icons/clothing/medical/suit.dmi | Bin 2506 -> 2217 bytes .../icons/clothing/medical_alt/suit.dmi | Bin 885 -> 863 bytes .../tajaran/icons/clothing/merc/suit.dmi | Bin 986 -> 956 bytes .../tajaran/icons/clothing/mining/suit.dmi | Bin 801 -> 779 bytes .../icons/clothing/mining_alt/suit.dmi | Bin 1160 -> 1143 bytes .../tajaran/icons/clothing/nasa/suit.dmi | Bin 1237 -> 1195 bytes .../tajaran/icons/clothing/pilot/suit.dmi | Bin 838 -> 813 bytes .../tajaran/icons/clothing/salvage/suit.dmi | Bin 1171 -> 1142 bytes .../tajaran/icons/clothing/sec/suit.dmi | Bin 989 -> 905 bytes .../tajaran/icons/clothing/sec_alt/suit.dmi | Bin 960 -> 941 bytes .../tajaran/icons/clothing/wizard/suit.dmi | Bin 998 -> 969 bytes mods/species/tajaran/icons/deformed_body.dmi | Bin 1494 -> 1494 bytes .../tajaran/icons/deformed_body_male.dmi | Bin 1490 -> 1490 bytes mods/species/tajaran/icons/hair.dmi | Bin 31399 -> 8327 bytes mods/species/tajaran/icons/markings.dmi | Bin 6735 -> 6419 bytes mods/species/tajaran/icons/tail.dmi | Bin 2149 -> 2149 bytes 24 files changed, 23 deletions(-) diff --git a/mods/species/tajaran/datum/species_bodytypes.dm b/mods/species/tajaran/datum/species_bodytypes.dm index cafd64384fba..8c006d8e241a 100644 --- a/mods/species/tajaran/datum/species_bodytypes.dm +++ b/mods/species/tajaran/datum/species_bodytypes.dm @@ -55,29 +55,6 @@ "Your overheated skin itches." ) -/decl/bodytype/tajaran/Initialize() - _equip_adjust = list( - (slot_glasses_str) = list( - "[NORTH]" = list(0, 2), - "[EAST]" = list(0, 2), - "[SOUTH]" = list( 0, 2), - "[WEST]" = list(0, 2) - ), - (slot_wear_mask_str) = list( - "[NORTH]" = list(0, 2), - "[EAST]" = list(0, 2), - "[SOUTH]" = list( 0, 2), - "[WEST]" = list(0, 2) - ), - (slot_head_str) = list( - "[NORTH]" = list(0, 2), - "[EAST]" = list(0, 2), - "[SOUTH]" = list( 0, 2), - "[WEST]" = list(0, 2) - ) - ) - . = ..() - /decl/bodytype/tajaran/masculine name = "masculine" icon_base = 'mods/species/tajaran/icons/body_male.dmi' diff --git a/mods/species/tajaran/icons/body.dmi b/mods/species/tajaran/icons/body.dmi index 7f3a5afd6b53d5525aba84e62874a36201183213..498c7147fc74b9e4f4643a90b20fa3ed98cf8985 100644 GIT binary patch delta 57 zcmV-90LK503yuqrEH1aV%GlWJ?(X{F;Pbh;%=-HO>+Ami|Nr9R^)s0Oo>55K+wQlu P%J}&I9t<|bv05|*d%q@V delta 57 zcmeC+Ami|Nr9R^)s0Oo>54^z`(b) P%J}&Itrv6Rv04cQpvNb6 delta 57 zcmV-90LK603gZfpEG|h&Txx24fPj;7a)nDvUYnb(eSMIVlcscZhclS~o>54^z`#jI PT#AaH4I%Qcv04cQ-u4-0 diff --git a/mods/species/tajaran/icons/clothing/atmos/suit.dmi b/mods/species/tajaran/icons/clothing/atmos/suit.dmi index 6b175ec87d6dff02d8e4de1900b0b5e9826a220e..856901b8e11ee415dd21a4439074284deba956a2 100644 GIT binary patch delta 755 zcmV&LZ00001bW%=J06^y0W&i*HdXaHI0wA1`v^jrZ(I8?fTKG)>00MeR zL_t(oh3!_+cH|%k6%b8gH1q#o+lxut-40~>uxFo!o_OZ;!W999l-}}||1LyK6vHAc z^9ymwoaF{rR>c=+7*6ov2G?SuzJ}paYn2W&D4!ho@WtsJT$E2i5H2#=tI~L@5y$cu*L>^yvt|ZRc#BICw&A+Ls3n z(Q@(20|&<$chpc>H^fk6cVb}p6$1xPZAWC0#|>G;kG;7#%`AGj$S>hv>dp0xXB&eMEeWf}VdO{E1hR)|?vnL&5HQsE}($ zDkUa>Im$G4(aO1Li;n>Rq}dYTNMLKIqsV;Pz92}phf5)CA9Nh)IB4vy{XU?O4uk>c z@bJv*=&6sDv&XOxC;;yb;%&g(%TW@(?v@Hqg*4%?l-}}|e(sk4WQrfODfZyp z5Qxd$2tt1}Rl@ye^K}~Mw>_Qx*+t885#*R4Uj$3>2v+p0+5Lkj3+-u+2xxJuNAOte z(X=#SH;G zSm~O7)F;quP@>iMU|Z0A)uxz`00WMqJuf~%(vE*2hVSbDS(YAbfX-9c(iGX-Re+S| z3G0)fu{Qz!#bA{X_P)j##_K&ng$hTdYEu};5tsy~z)_kl!1WbDwN&{G=$SUkhgWIp zObx%e%BH_1(Cx_uJTunxk1_UOI+y}*j04xY{dkw~AGK#-^gMQVIymh!hJ-#$|L2f# l4GkY>^N$Ix8R1JG@&TeB5UBYv0000pP)t-sz`($CRVO<;JEnOz&ZuuVa%o18 zg==0?kwF_3@rEQ;00001bW%=J06^y0W&i*He35ZK1V9`Mu931ie_~xAXk72S761SO zkV!;AR9J=WSM6@(FbFi*#z~ww`~FXR1DmdNUGP@wN%tpI^;R7iWAMjpO1Is1+y5{k z`c*vVl6gJ>Pp1IP6TH@%Ib#fQuJ#+^g87Lh@K9VtX1LT+ihg(=iZ`_hPFamy4~t*a zd0JPdEEe_Hc!Z7^4+j351c>xJR1$|e{cJmmrhQ3e!=sbm+|6q<{tDwLEt z>r9E{Z3)1M8!~9v3GaA9?fNT&j%vF2m4Sm}jeC97pzcl$6mRQ>8hUu@J1T2^B>iLW zF5Z?6UG#A6lh%NlwFYjVfwx1B=HqIJ?zLldQQ%rd)G$1cf7$@;QFPwu$}l{S=ymPg z>G2m%8jecG1R1TWF+s8WBE)UGcIojFFg;F6eC1$vECKr@!aHiL!;B!Qk4tgIP6+lf z=u9WdfOR@uLmN5c&5@VAn|Ej4op7IE8cxBV;o zi3XecaQ?_Ze^Z&pP;pZVg3y~1&{W3R+Y&!art@l@t&zxF!ud@iP1G!)r;2jXwp;{p zApt!JmgW(xP!6WiqK74Q6LJt5t4Huy^l8(V%R`@YTn@B6JorI)osr^f391m`=EkRu zikKXq6j5O*wD}3H)ry3{kFS;ibDz%`@N>>OhcG?*E{F-{!o z{_S4EHGf2}fpO%q`x?yRGo;)x)c?B_yrkVzqQwN4l6(2X{s8@+6bk-q6;l8J002ov JPDHLkV1g(JZJYoA diff --git a/mods/species/tajaran/icons/clothing/atmos_alt/suit.dmi b/mods/species/tajaran/icons/clothing/atmos_alt/suit.dmi index f9ce4604f3a6be02ab116f92b716abf73448b54c..fa7e1d8bed0f51e83d848f0f2f3f14223bb192bb 100644 GIT binary patch delta 700 zcmV;t0z>`M2Dk>07fwI~0{{R3SVwH_0000dP)t-s0000ZA|@OnD>y(>M_FrBQ&1~3 zKt4S`Mv#RV7a28WYQ};9f?GhJ@$I z05bsQ(?m!i7Kp1fMNBRPO&74VQ-3ZbNI^U9@3ux5uiK6lz@uf-FUMxanDLHPB_1u4 z;#zB9x(Tz6mF}3_$20nC&!$mk*<{d`%?w}ff9qbC!GFtOned=huYcNRnpvJ{J+*AM z-6|=2cvmel)S9FqklA;)PV28 zToz_B6pgA-fQtBw!~zu~kd6@LuE1JNv2b3Lm2O0&~!=1zA)8_eQi#d)RHbq`e zs&k7c;XG5~n^R=1v_jhsa)a0d5t6^ff&+}T*1PM~tx;uK}3B#)6kMZxr18@W2 zyf|Y1{)H3pDk^D*r{?D#Qh#TL=@96?z42xZse8T4&C>u0bh&ed)ml8^HwaAOSL{iq zK%pgBc;mhxp&vploJBYEI~MlhVLrhEpJ`Xn4aY(+SgD^_cxAib5(!>9IxaHDyCOX* zjs+@khF(6>xM;$3K5_&AU|2AX6tHljXysnkLa-~ueMO}!NWn5E16>>o;ADuk)~;Xz z1>)$d+YShM**?$F3Z~&Ct}qmBY}W{**x!j7fA{ICF6QC;{M#b)A$8Bebc}v{`<{by i;%n&&renOt3Hb{bvbSmz`U*h+0000S3L^= delta 726 zcmV;{0xA8t2GRzQ7fwtB0{{R3FNLg@0000dP)t-sz`(#OG(aOFCOAM+93m@6S!+~N zP(D3BMv#RV7a28WYQ};9f8nu5P&J!K%h?gK?ZfQE`b?(imG_X7Q0$J21Z^$ zgS-|TL>qko8=fRusKKC1I%V!+bnTY6DqFZ%6fTihjB|vc6v9sT5VYF^KmH>~2i4%`> zj}Z$xmKA?AOrjg5fT=d~JC>?ra-PoU_XC@ZeZx9~GOT-e>hMGLyA0m%42DUNH}d6Y z(@uQDGo>bm^|Bi&cq5MscSSQ5e6r`qNxD_51NoO@z~k)g*lqVo8VI0~5YZS%8MHFKuto@iP6kxl1i^;pq z)AJT{np&(Uc{i;t4ED0QFZm~HlC>1c^%2kS)7qMoTS6^|g<&TMYe@?v2vw_Y>xs)X z%Z}gLztwuze~CEJsgU{>x&Zcncd+ga(KT#g1>A}X+ToclQA29=&~*--T6eTrLy1!8 zL%Q628z6x$_qMQFb0iQ3Oyaxf3MN6KAz5~7-vh3885S4tzJCVj-9*TTpF) zg?_%0U$OAQ_W2zW+%h?xWQbQq`jnpvl;aHjFj08YgsCvG1OQ-I(9Z#NV4)`|E^>N| z1!wp`IFbrm5S-xy(UWj0fR!OtO4))A;6pZkZx=N}p0`hPG=eUhg)IzulbSKIaq8`P zjlX+zRY&vewf{rpdr;c@pzEHKKD_4854op=E$F&O{ygx%0P=#i(^b07*qo IM6N<$g1Ny#vH$=8 diff --git a/mods/species/tajaran/icons/clothing/deathsquad/suit.dmi b/mods/species/tajaran/icons/clothing/deathsquad/suit.dmi index 34b9cedc5abbbb9d56d7c62e3b34bf6206520e5d..e55e927d5ec975a0838b2ec2a07da40eee6343a9 100644 GIT binary patch delta 911 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 FV1gdTi?sj% diff --git a/mods/species/tajaran/icons/clothing/engineering_alt/suit.dmi b/mods/species/tajaran/icons/clothing/engineering_alt/suit.dmi index 1565d9f8e8916c6432f19680a2df324acc74015a..a2b5977c671e764775b04891880d329fdd19db3d 100644 GIT binary patch delta 674 zcmV;T0$u&f2Dk>07ZpGR0{{R3SVwH_0000XP)t-s0001yEFKlW3-Sj50004WQchC< zK<3zH0001bkzYRoAe@n+Ie%c$AYv+7_)P!+0zXMaK~zYI?UX@l+b|Tz?lp zw@HM7Z!y9w*{KP>^cX}&mQ%OVWj&68bB!_EoSm#VD}EoK-*d`HMVAnqI;rH}^ zPtud$Bjnls$CwZon3D;mli{DaH{*hHg?NxcyolXNi#7QtvfJaGaVv}N)}ZCCmFzFZDZ{LN%|uxuiH5Ha+- z48FUtYzsx@ zm_{rhf})=R?eq!$gj%N)9oHEoSmV73Fe+IchMI^ZfnC9P{Vt17^}! z+j4<<1`ZSNa$8Z%VO(G)A>R~(uv@3QT5~L5yw-wUop8U8YhdW7^fFrOaAMiKRjt_s z2?W&8m7aLqu)D{z{iAsofA?^iT)FEn0?9f$o2DvcPQ)ZtgMXJ@I==csGxvF4=jgq? zS2Aa=fUo2S7FZy+AW$p%0$Pa$ z{VLXg1rY734H9@+@br)gz7^>+{#3v?&d^T+a5{-X5;%fUs%k9oQ&l==s7hxXke-A)2vk;ct?4Y-$ohj7^2J!lmB zJMLbS#q~}fOXFWpYoBHj7HBgu{K5Vh1YllAxB@dV4t_#@0cM=1;m^U~TmS$707*qo IM6N<$f}O57U;qFB delta 693 zcmV;m0!sb32FnJJ7Zpqd0{{R3FNLg@0000XP)t-sz`($fEFKl-u6Hs30004WQchC< zK<3zH0001dkzYRqKpYFMk)Sz$VqG9;T<^RV0006|NklK0I-vl~$I~8@XNO>xXhVJn=VE;nA|m z@HCHgzpLPx3LPU+HKtXiS51?V`_eXb=S&tq1*Woa_BG;qpA`^$UzGk{g6eu+&~T+$mlYE|1pRB zdHM($_2sr)K%Qxb5gu$Sc*k%M7tWmv*rter?m5}jia~+0T5)=P!u>w3H3gRvXQWoa z#IiZ7TG0s*xUO~AdW4x__Z`pcA6oeOJo4ho6{2%tdM2EYJwhCRfr-S;z>zO#hZoaS z2Gq%zq%wNh`E2!tWbP$>or7D8Ux}Q$0$Yg>AmGp6DmZ&F5AWv*f`WAa2TZ4qFj&4@ zt#3QNT<1TZ3Mh!J=3tnH z@f~55${Gq@DobZ{4^`<5HPkb65AFe%>60rg<;W3MYuKklr`9r93Vlc zd{;<91xL`0h7;*`3e$W04id)Rj=7&n<9er#t?_QAwMViL3d+nqFWMiIv^J;1UBS$~ bLmZ)B#8s)B+k{LM00000NkvXXu0mjfUR*q- diff --git a/mods/species/tajaran/icons/clothing/excavation/suit.dmi b/mods/species/tajaran/icons/clothing/excavation/suit.dmi index 9265508d9b1395386f7ce993e79fb844d00c1cf0..dc261cdcbfccf5bfa220e785b876a3ab37abb749 100644 GIT binary patch delta 813 zcmV+|1JeA+2dD>-7g|6F0{{R3owtGP0000pP)t-s00020V*nf?D=RcWii)21!%WmUq7K?ox*w)6jA+Y!#`NrU9R z^fBsMv70T1tF1{0pZLTdN2Gb7=<>wO$>$jv2|U{w`2GryZ#fp=67yzdD9_tAKP}F2 zi)AJh-0{NY2bWc#wphxRbKXjct*#w_$H{SRYX><;?tjSGz&ppBZ9c}ZdD!8##u@JG#H&^DG2C z1ATp3L+HIXrl5z!>)=~p7z${O1sGGn9s-UprhkAlqBjO7J!C52DWGSa9u}gS2}7}t z5DD%oeBu*-5ygEKyaY;*-yUy8A3wW5j+3ILHKPD;Hwl1w^AZZ7@NZhdory#(?nsH` z2yknBRd`2W7XO)L3-p}(?*cQ+7C6)dsDbg<0L5Rk?1b4?3d*A=plEs}yRu1v3GiNM zGk@k=58l8NAT119oSn*{_F>iqvIR7u>Kjp#&DB246t6U?fJ}?vaV1oxpK<2!|$O{{3-g_NI_{nuC5P(5HuB zTOpAaPQUtVs1cQ64*?!-8pL~n=_mWDfI^=-jJ1)=Be?P8u#0H$3W$5swY|)Ns~}Gg r0fhv&@k4>8_qxo%jlkt0zVi`ZyMG#-sY;++00000NkvXXu0mjfW6^0} delta 845 zcmV-T1G4<62gnDI7g|gR0{{R3>UBYv0000pP)t-sz`(#OG(d`qo~mO293m@8M_l*A zOx&OwV<`X_7a2Z1Kf=MuBO)e(3Km-c5I8_mR8vsfTQh$E0004WQchC5ZNCO17`>{2(W<%Bqo+QiNb`g771I+Qj5DvW=mt|^g zAU$#mqZ6Zly%QQRG?WZ|++78NNJt4BmX!1#1IISVq?^IQHL%v`zOlxy;N!>{U+mym zsvQFRb&0+S&`RL(sGPZ8i{!TehM(sUoJffTpXBX#G)E6G3!XslW8^U|HSh<|ofmk( z`Uw_t3=hvpzrbfL1g(L5-K`1<_s1dy}aMmJI z0Z##$b$FPFW)g#1vY3~5CE3VBUFa{+SErmCreU`1xjK^fO@CXXE_4Xf=!k!kW0y*1t!ZD*wu=u zjr8Y#02WMHHet4v3X|dqC^Q|b?JuOlih0M%jCuCJp?LzV$Fo`_r`FWO&C{7}0VOm& zm&AFeP!l&PUNNhHOrz%Edi<{hqQIi1#b&`qNFuJsIW5{+;B;~xoEa9)b4W7)@1Xet zuxR^AU_YIlgGMG=Y-SB?Xd-V2k)}mkKTxJ%lXKo3BddM!J(z~R4#=>(04F_d`dVPR z`g~Qu3nyM#PmAW%sm2S3X-9+a08@@Sx2HvO73AgQpb+8tekkyKTAvneA#ggmFFxWI XU6vf@4oHB{00000NkvXXu0mjfXbE$A diff --git a/mods/species/tajaran/icons/clothing/medical/suit.dmi b/mods/species/tajaran/icons/clothing/medical/suit.dmi index 235d2810121bd6c0f88a23d17e9f089851b1481c..d269def02a5046442bc2465e5c90428faee21f8b 100644 GIT binary patch literal 2217 zcmV;a2v+xrP)V=-0C=1w$2|_hFboFJIX=awb_Vg&H493GGPGAfMRAFx(nzse#O)b)+iP*_ z?{P#JBJEsN$_kI}cp~?aWEmdU3%Shl%Jz@iWDJjH=0#S(I8?Bu%$@=00-qsL_t(|ob6k2XdBlV|H&&OqebPW-ZZQ< zS1XQPG%r=D)hdKRE90y}S4O-ly+< z@7?=80S+8EaNxj!0|)=7aDCqbSi$(%5V^9j$nLv3f;e_^%2Hnpzm!g=34ebkm0;Jg zcvAE1?%lg>QLJ8uO0b1HolX-%2+3qJ?3_-g*}<0+LWmJTt;nD#3L%6LMN!thHp|^$ zuTdLf-o6G@WL+}w;@E{9U7gi@)5=YGDO zUFUK+G&eUxk|aZxLQz!#y*=HeSS$hn>%1PPuHMts7mG#o_H@_93TQjDlciD#05CWZ z#f883V{jmfO7%wh4OzgMR0681qF5}#?RIPGXy;E|y@z742vt=z{-GW?lS;6*>5l;b zKW*H@uK9X1{Euu@$(s^wG!{=nk|Y3Stsj5kDZKg5n>f_s(mYc>gIIM+$)7#p>i)yb zD!u>X_!}UEAQn$DC46!B0{~$6R`{!0KqL|YP@ZaN!>Xz>ZL6w^LoF@{f`C{&iLQ>I z<~^%O{QE1yx6}FDGl<2L8oxs=fR5}+DrJI78=xq25CHRGCE!12-Fu(Asue&kB;=_Bj;D?K(e4>|;R)1unv zeF1em{P?5RQp>!o<6n)%lMR%Aa3G40KRJu%pB=#T+4nU3KLBvVApeGyyeIAI2x4|_ z9zfXwe%SCM_T0Ct510k??cWQ2m3HC7k1Q*I=kI*}SzP`26HWb{{0e-cS5wy25j4eL zbqLT#{oA(U#Odj(7Vy>QR{=mHgcZE}%u@~jnKi5|HT%5hVii> zGBcSX0I+XYknGzPWUD_#QP`@G)&aoGWQvTB4b^2G!1MR^bd&ZrKjRx88)EnEZGJ*6 z#tgqH^K5VPvqq^k6pKY19Uf%QWIkKA?E|a5%}<)1^y0>US0H-aI2euM_ka2`0DzX8 zvwN_*1px41bqh|Mo(8RJc-)IC3yY}NI-tGHPYy<-I2etxUw(FO zUc=AJAj@*yccUQ7GF$Y7!(kE*he;-rApoE+Qxt{NTZr~HKj9BWQAi*VAOH{u1lU#> zU7(raH)Jm1aF{hHiXs4DX=w@9u3d8l0s+#}(gFa;=kx5H%atp>y9a`*Om@{4`1!Y6t) zAu@g|EE0*}(xpqbrpQDh5%f=`aj2zC!OL+bmB5|+3jX$wx6rs%HY9^#3;6WY|FCPi z4aLU-1wmLhfuf%1pGpG&-d-XV<?-J6M|&004of?;CEz)0th;qiD7izm^4 zc$n2w*=)0bYoBW!9vySQ+K90o7#VySfHoRUeG=~&ckbM7xJ}c$!u&8O6bkToJOH4H z+V0q~!xkr~C<@^t!Fm~h^47SSongZkK*5jwu8ts1u9Guh2P#=W-~PRLr-o3tDFx_L zV=CngytrqVWnrq}`b`xVKls<0d;mTdpi=tIMz9nZ>D#{-{%u?F#M7Ou^YK?-!HrvA z;`)udwl0fXn;J>ewx1yNRyizAl|bVKfVtp^X$AO1FLQh}CJzAjzy8Md&Qr8DHIm03 z-LggoDw}OSfbYEMapUkvdG0L~3OI1!z@~i=UB7YHb?)3bLY*It7t)-e43-VIWhp#P za{?quf+R^AFT7dscsz`s<||l%DFs}=Sq?#eyZXQqnVq0AQ5lWGumXB}y21zr$mX zZqa<70BdEe21Aakx2K!@s_#WC-@1*n@BJ0j15<3~3_!up1iTyr(U;)gwiWNrUaToe z6TLm%gdQ`KDbm~1O*WN9qKNb7 r&)Yf_WLYM9PT*m_0xjQ2ejeWe_7(WK6hI4B00000NkvXXu0mjfH)J*3 literal 2506 zcmZ`*XHb*f5`L3VLQ6ma5fDO%GzF2WKnh%{(wp=mC`fNg5hQf!p?rX$NDo_)?H8XM|xu=2A40KlQAt7%HNIQr3t zGST(7N^&{f;KR(Vf;8_1x&%D%3wq$|0{|ffj2-H*Xjx9ik%!CN*xHF#wSMvfW_Kz0 zD}4IQ(+uuo7Zqn`4{T=QALq^W;Dlcj`(fIVY8fX>?kp*r8ZvrMERyTk2dF`PPZHlN-d1XT<*Az4SjVLs!{U z<(vEYe6cLQ2J#CJXsyHH--BECW-DIWHu}t$rJ%J{ofKFZ_%`sP5}ZzT5bZJ?eiX)+ z3I_eJ!=+{vw$gDDd5pH64rw2{os{gieaI$;j`)Ri`uyF9Bqg{W{vedmKITHu&0=Ox z0eEd4wbWfT#Lm%CtbPrYiQ+ms`a(#*^q2{p^nLSNv+_097smvcjdvvymx=ljq{79{ zWa8kE<|O+xL~W=#P_XA~e}BLK-qK(}7DDgbe5g=)c{wyr10d{MacdbgSX@?5`^m`~ z_XY7lfCg!25@wCFvaKel9BLw?=(61E7keo|LnJ#VCwe*5B10o118)+EEiuZ6VR%G? zg`}!`e)^{zpIE47^kD#{UQHwja95qiJN_kcdAkV^HYqkIB&3s9FS7|ZS9*`LQa;b* z%AC%onx>jif<#i%UjkbS$C1_d-Pgg}?<&5K|5A8QR9hKQdPs$iQA0EYw5c3*(Ro^1D{|inj^(sLg$FkN-A11I{u1H>TzAlhG5y1)4eLKr4jaO6tEv@eRMo&&jaj zy<^wGi)IH$mSDg#IkbPPl)Nw_(4=-R6O}l!ULfs`755yQ?FS4zcIN(o9x%0v^PhbJwnKyA7Czmr~XDQ$I(537+Qd(%GUwwBbM75XYWx$ah2 zPYqkK%sNoDS9(6enOYctu<)+A8?gKDE+%S%cR~caqJ)6}laY z2U&g!(aD{tcnJE?V{tFfmKsIB9aFt)ZM|3csl|OyK0*n>8eP=k>3F&Wk6MeERq94F zr?)wco%p}aqS4d461-OS8ah0#m%VuZ^eFIOsbQLj+OhV%5>A%JwalGPkB7YkoTI*xv?as_eWa=T71=)P|WNgXM_ zi5`*8DnnhBuHi&9qj6{g*1si&IjD-+tD>!MIbIh-8&P0f8RPEp_fskKlJEQ#q>+g# z)hc*#;WLZ}_u@E{5}w0CVj%?EIXF}wD)X`5e*+x_OHJKgzD=rmRvgBf{m*GkIL*_Z z4n6`K&w>EbutNSCzdGyjf`H>=fj9T`&Ie#W#)m_7L=P8hbjbY2*;2yhI_;`kf1h0% zAA~j`lYhSVz8BP_`P0)E0=%@;v%#813^EvSZEv>F*6n<1$z5#8-JL^w(*G3NT=ugT z`tfNE+$@&65PrJCe3T3v+4-(-cgl0(yYD*RdK2!Gy{iUK`#EBNq;Qp&O$`E4coZ`A za5X;%YHZJ3aKoQrYt~FmO=TG<_j%>H9qqwfSKPc|3uF^f#H@wHoeznkRu+<`<5Xqc zU>6XAH<>(=>lxfR@8|Fm|IJ4{0BuZy;{syL`%jCPZW&_^=)->K%)j`>M;jM0_`t4D zgHWD`H;-~vS+v@Cec_>M7R$k;)>Z1CX=##d6Y^@|(?D@|B%&`2{713E#MCa#Vzl@9OuX1gIJx@9_kGJni}Ter7AelEa$`&QeO_h%$;nQ8M>d4D z>qrNrePDo{R9Q*?lz+|5?;Rna8nd|{7}OD%=jj|6KK4=yg}ceJy}DZHy!h@ zYkWU`+_1r|+oCS?qp+|LRVdZ(QNLs^lnaYS5X|#|S_&nJKHm2qi=QnX!dEdv`}xX^ RV)W$<(9<&1tk!Uf{tt`-tZx7S diff --git a/mods/species/tajaran/icons/clothing/medical_alt/suit.dmi b/mods/species/tajaran/icons/clothing/medical_alt/suit.dmi index e2e0245516acd32babae5fb2e44e3ad96b1901c5..7b9f801e353411fb7faa90dcf669c94fdc65c1f8 100644 GIT binary patch delta 719 zcmV;=0xljA6o74$1XX0H4RKYx!~rS+LIRYcbPLTL(UlBNbT?Qq^dg!i3zb|YdnOp+ zB5^YyK_-mAOBO&G`5XKXE>i7#R~8U!-}XI!es_L%ewK9}{}ZUdDV zM`-t`4R|Vl-<$w0HK}|@n}C&&Xtr7>Wby(}?-rcM#YdspI(WYp7H!Q4A;6cO?WrZ= z=J=E=iW!ZYqg<%)ZALnKZl0(Nx3QQLuMnK4CG`fa{>Yo~v&0al)$hfo5kpd7igIQQ z34s~Sg^l?`^+q4dobkTm0VahY1}^6wEd)C7)6AoPv2L6_%z0KE-V_i-WnWSg>2cQdk?t5uFnl2+cB1~Q{PVwfrp_{fv0zj3MD*X2(rs{ zo7S-*A}YrP+HST<2^7dYV)D_a9D|fcEN+8}6BN;I0xDdIC`y1JSsTYf^PIJRG0o@k z_hI{ge`Gcd6#FCd`RKZFnisptss|IRUN?CT3$$h{@lA8}px2tg66iyZOxl`DQ?Ysp zuUH2)&k8C9g#LI76DYi<$5{;suYxT~Bh6*Jdz{{cdypi?@GIzCNVtbN#YEIKJ48?% z0|9pvia_gZw9Wv*q4Kc{E4W`Iu0x@Qo*2D;x4)u36e?jDm_q7#hp>XTm{~@&7NJq$ z+U?X7g3tF4|3w&ke$5p6Jj?*{8bzj{<|epgmE{d`=2sv0{{R3FNLg@0000jP)t-sz`(#OG(b8*P8=dDFHUYFA|@3T z6_Gv|6&}6%i~s-t0d!JMQvg8b*k%9#0DO^aKLkJ=3$Br@Ie%hZAZT3gycPfe0&Yn} zK~zYI?Ug@o(?Ar!?U)2r%~0Ers(9%oqDz*#0VF_3{86fO3p97pl?;xeJIR894sP-R zvcL)#aXTQ$R2#wK1%$HkIrto0q}YC!0f`aRxBZ@fes_L%c`=NO`0vB4qdzB1+t%1> z*=`H+72I>7K!5h|;a(T;M7})(Ty8V@p0xohAu8DDoYC=1GP$2~B+%m!+pO8!~I zay-YafL5A`e-IaFSiWt;voS8sTX)`R>|KMbPW!<_q_OR2=Wiwl+7f2$II$)m-`6Uj z_?}jwOhz0-wo%chWo(Fm$!3nGooq1*1v(43d~%+l7o&iO@J5Ys!1@uWa5Z2!0)pgS z5{iOnynp+P7km-_R+#7OnawR-Xs!#%n&71R^AzcVIIinL{ib#&FZZLx045fLe)Iws z=u8*lTfxy}NE#CO6>KIX+{26!D)tMus9+=n0_jH#gMZeUc$oo$#pF{PRhsHC-4YKLLnp4C{iL{tj3n zy+zjs4i%#`U!&f1E1?MB^NN~#ezLlTX6o%%@K`@AHTSGIUG=8bQvX6y7u4Ka<_+UF YAQPFeH$gF6N&o-=07*qoM6N<$f=p{udH?_b diff --git a/mods/species/tajaran/icons/clothing/merc/suit.dmi b/mods/species/tajaran/icons/clothing/merc/suit.dmi index d7828714306cc1b5981271e7416ee0232363f2d2..37bef8119e7a20e6be66694eb6eadfdcb884fcde 100644 GIT binary patch delta 792 zcmV+z1LyqO2fPQ67Z^YY0{{R3owtGP0000;P)t-s0000xJ3EmwEhC>k6Foe-1&0004WQchCII@cT|$Ln@MlLhW!eG7;QiLbfIOD4dE59 z`0o)lTuPJ}oD-4DHC#SrDd00L7b}Bu=EO74lC!C>tQRTsJa2MY7n^fB;fYo_*buU; zluXWP@NDsrl8Al*e1C+JAuu@Z2N#12N|dCb4+p>+K3`@Ib4?rvr+z{#qvG zl!t?C@jy!sa8QSXke7pi@}~oX2ZBe*!$Btecn|=G11w)r~y{cWSid|7+kjr z9AF8?4|LorBpcI{^JX}>=swfEs@Htji-hVaiQ~F$$GylLcz@GJgsc8y^Vqt>?=C7F zRP#-^f6W?8ulAep_!=puqy0}Vv3GHK(E2p3l7-GS5JT|416mtM?yuF zt1qAiPI%DcW?W)3C=RO<`#s6Ie_Ex7F6(3|#8!IiHPrfjvK4q*7Fhy5iNH3k-Ut41si`tA$7kA&o%>Jg3ar1xszK~?UqKuy^mv_Azd zOHS1nsDC0*Jpqg_Da&?J0u%wGcIw4eh@%E)HPkAO8khoOdf?NCFdhSQZ$}G{>7lP; z_x49%1VNA$X-NLr1$ufzYsW^3>xlyHU!!ic-kOdAUlsZ|Y!%?&E>}QDh;id1AMpdx Wp&Ox35))_u0000UBYv0000;P)t-sz`(#eJ3CNNP?0Y!Cn_o`N?m$& zCopVYQeqw>C>k90thxID0004WQchCsPF$9Ujk;DQomo|nB=&M1>uc;@Tv3fRB{ zZ4y5eP?YU^nG~ne6%-2(w3Yw`wJQi^JrOAWp}@ccL8Fwepb#!k1i+yH6WDmrKQRMp zfEhH|#_tLYT$c$HU<$?sotFy9&h&xvZYa3uI@7hP=W<$$gz71O68m}I&ufu6@UD*t zXZ>O0F*OIjtEf;=%{SqGn>Eg@+Hb<+Hge2o`Cqui*2Kkw)+cGDTm^AXO?(Ahmp$!E z^$55^z>nF*kx)_P>JzAd0Uos7^ixa*ie@#(c29D~Pn)#RWScC8nC6yR4YmH9YzCgz zRn~xGH8UDQKp-`L+6>xo6BHz;^8$TqZvjUdbmmvQ;uZfUn$=0Z1>V>Jf!T|m$HyT- zi(?A3f;J$)o=MGZnHt>4*jPVNnzruL+ytIskS1~xcvk|N7oT96NeOnRt1>otAvGD^ z_|FuF02YCSXJ-OPoZ;XEM#WCJ(cOs+6?BV6HyfvEmE(7R3JzJlD&DB5#XLp|4hX>Z z>?o)ZcZgJ9K@~ZWJh+1<|6x`1SkSN zcygO=9bP99v-f3Vmquyz=+9)G$cQ(fU`>4u0`TD zV8Hk->OyPyLVj-V>fyp2z{jskphm6_eB>j30Svkw)JhBU-v9sr07*qoM6N<$g8yc5 Ag8%>k diff --git a/mods/species/tajaran/icons/clothing/mining/suit.dmi b/mods/species/tajaran/icons/clothing/mining/suit.dmi index 963ade3c684fd4a68ba7f43631015fa0e55ba961..0b6cc99dbfcabbb3cbf9083f7665a8db1e656f02 100644 GIT binary patch delta 655 zcmV;A0&xAI28#xe7ezn>0{{R3SVwH_0000UP)t-s0000SA}ex5DxYsXTL2J3CL^*e zAc6`OD>OhjKvGYqucrV200DGTPE!Ct=GbNc004TCTt5OJoROb7e_+udVk%nrO#lD_ z6-h)vR7i>Kl`(7FKoEsjN<^+aDPGv?>`?};47*;EGDVDAX_Nt#DGuDHaN5%afmF(1 zIQ`qm$yu6pf(fMccHi*k?d;BKq}0p$pB1HPz_CrUOTn)#la&JR0WZHUyz|cc_rk!V z^Y3nEezQYB6c!p8f3Uv(^vKs&6Em)7L04-)b2bOg%9gpQ_wx>@A1pI>;#XEbIA~CF z;NZ&2wlF9BK<5157C{2z9Y)=WS53mH=6DvwNOrulJUj4P9PV>Xivxqnkd_)+9`0Fg zk$I!7C^EyQg_)J&q)byz3c*J5)SJ$jMhR~EfK_BtBik3He|^9zhMGV!8ZCJ$t0X7+ zzB(B_(i=_|WM6=ZNX>#yDm~VG71)cRSXm53Ub0r0Y2vPv_<+~JI zbQy;NzWA)Ae?#sectHr2l|@l*9ZCVY+{z*oLa5~_S|FLAVt3)T(&6ATcP<^=mbW4h zAExOb9TF&^lnxp+1cFktWR-BKWng9cF=$RS9-F-sq}?$T^j#_iQ47I1Pzs=y87q_9 zP>|bTi@u?!?*YwGV54&%3MyMJ<3O#(zX`^9kFFV#IiTCWzxRzf4ew|e*9laCMdhK0 p#?9#<(;qJ3uu7UHg!=X8`w0PTdSTDlo{0be002ovPDHLkV1gFeBCh}d delta 677 zcmV;W0$Tlx2B8L!7e!120{{R3FNLg@0000UP)t-sz`(#9A}cF2KypPYpKm=|01!eZ zBeE9%tYMatH@7v7ApYcaA=bxh*$W|ot>GnA2B zrAqm4$-y;wK2Ud1y?rmAe|GW`M~LU~-;XHQPZy#z4LCMwcE$LmA#b?g9N^X0nfJ~* z_nrkfwC>&Q#IN=Uh%A3XApy2GpC0+6ElowOsqA7@UyPj4+b&SmHiC-9X zOi&=E!p1h8DPWrL7Ky5jorMI3dyMiEFLXkwqIeQw^k%p>G$qg*>>n!S=L7O2z!0%QLUgz1 zQ_vb`xnR4y+iQO=ctqd=_%GkNu+1|H1=@aAJfU*nxq#3a{_Xk7Smc7YmEoIAJVMJ@ z6yW&;5!?KdIJKC{Aycy3po{&HT4Np*@AP^eGALQ{-Hi{P(vK)fuM8iR^ zxsc{zd!sT>xeyf)9BM)Uw0y=wRwfiG6D(0`fBrt8JTOhvs&b*wnPxuJ#A5iHFidOY zx=(^`|30-=^7IRe`eB(s7esUp>S$P00S6FL_t(oh3%GWSKBZQhV8^wBLyg- zu#ptzd9c(0{{QdW>u}jbPw><|TK;8_Bj|a!cO%9s6s(!spua&UXt=nInSCX~7X;N9_$#!2YJi^Kpzb z_ko*hj4rKPWgUsDt?9}yI|A@3Lw5MJLBJ5R?P zJ0M4}%@O41MGl;;@a}(GdyC)7xk${Y)s6|jg) zp7()i+3$8c-?yf;4;U-q*|Nt96nM6N7`*qx&=+aul;c#n+3))SpZ#9v5YV}~yO-Yf za{o=?_jdtP=;qia$g&9&n*>>@{v49t9VMJU*xqAOL^662Z^$5I7vhQR5aV z2!~$dhWZ#xhyl4SP`n%yFfqo(E_@%4V|FlyeCP@a*gV)i;3*#lZG227#jH@^H~<_F zVMwv85JDU$I80-NUxAMS%)kdv$|O#9vf0u%bH$98qbT;{caumM&yO+%Oc)7 zmoOepf+moAhencf+agBYrH-4OSCfFs)o=&5^1XcKobM<%37SCe9jNopohkZg0$gqq zG=bbZz{M*uZV{Wy5s)$m&bOaG2{Ou3>1#km8 UBtl0SpWb4 delta 911 zcmV;A191HJ2#5)g7Zpqh0{{R3>UBYv0001oP)t-sz`($fEQA#sR$__(0004WQchC< zK<3zH0001dk;Oj*KpYFMlLi4fe_~xAXk72S761SPCrLy>R9J=Wmr+yOFc5?#Te|qp zKrn_DJEW=#H8SM?|Gut5DFy4yOJ6#Z%Md*Coz^Q^wl~I{>QtxtAInx%WmQ@`Z*66* zceTPTS&Ki7Z^-$E8}DdS>d4$Ovt8lRdiJdpJHR)Nlq3 zz9n{^K631U>|mQ6hv=+_&}?-<5TXHK@P^Ghh+$YOw}vD>%SOh~c2JAFos9 zxR6-^7jen+J}@o&zVH3en$kXCTnW#XJ+453=NiV*dq0jtk!DWWr^?N4H;nk~b~=ZE z&duFk20O_9o5J^Z0aF<6_L_jm_gKXrA{q~Ppl}>CZtfoh4-9#@e^(vAfL(F$b9xLM z9;Zp;cwm7K8aFh=U_uO7>jK5eF#!`}Tcoa$7k`d5|a&wJ*yCJ;VVn8T_76jmi> zjMoKR{p9EwQABG%e=>O{_f!`W((my|YFv14zA0F|VKkYF0QFiO`$ptI^<@!nol6*xsHO?z1lLG%Zd=4iKh$y4dwmgo-*AVv^4syu zIp0x^YMMY!aMXF{&J=w_F_)v7CXf>xTD;rWbq#V=~9C|`T8%JH>h^g1!ts#YB*r_2d z7w~{Kg{EKwlG>VpAgNjPi4c+vBI^zWQB89IYe7DDAVHf$m@$WGT6Zu_n892Wzywl= z$Y^TC0001oP)t-s0000|Qc@uxARHVVVgm!Xpq(Tn zB%O$cd=?fqHa2f>Z;?u76+`V~Bme*a0d!JMQvg8b*k%9#0E3amKLQ|}lL!Gfe}EyE zvVyCh3)o%&v!x_Z4ZMQY0009+Nkl*+bRxpyH+BqSsx-c>A=Qi~Z}>+^HW&71tn1SjaorIg6)-jTl%N7N5-4Z_1rn&i(E6?2GO6pL_*4|WPL^&>;NKKb z1Ri7Q+#36+c>=MuwR6-GgzXkPT&+H@R@mWo8&2?D_^v?Mo!~J{Oggs<;#g`4kiafX z9byheU}q=X?q~uKlL9J4e}Qq12*t6~5+D%pB#a%VCjLU96U@! zq5;=#RhaV&&iR{#az709&?D8T(3fqRr7Xl@O_KR^u+yaG`GUZK3z zr~u3p08~J?41wX0jOS@a{n^ztja#Szr|av3j^N`QfyY<_6G;ZguIu}x@4N0uFi_56 z|6S7c&GC3zJNe;x-v@%5j^8v4-UfRi~Ehpa;aU3OSd1o4bgeI(E~i6?efot&x#2*lUK>Pvm2gDx`e?a^JbO{LwiMJf$4~Rc-p+8X3 z^)GpUpnA>s2i}W6Any-|KOp{q_ygh(h(93yfcOIv5)u+`I>a9kf8ekDf59Jke_+O- zIOh*kZ@?dr_Xoru5Pv}Y0r3aK9}s`wfAa^v0@Q!SNq3{XcmMzZ07*qoM6N<$f*MY} AA^-pY delta 1021 zcmZ3@d6jd5xbX}QW(EcZ=~O{}Ak`k=6XJT{zyUKev!I}${QP_w85tE76-5PwBxdFv z3+B%4XsZzuo9LA$%8<$&3e><@666=m;PC858j#aE@u)qEgADh&$!v_~^$v>DH#M!E z&kdCN*RHaqBu6QNfq^;O)5S5QV$R#>?x5QS0$X$=H>u2NS#t1#mTyc!2lM~`wXrwf zC7o86VB;m zN!5zdoa&{xP$5zwLsEQ!cIdRF^{YyH%uhwF_USoql)WmYF(WWFr$^+R#`8HweeaC+ z$yfArpH*lnJazPQvx$VufUjN!!EV_|v zm(z<2j6M$QCv7WZtBccr@u$10@4-yb6q9A<+v0Ryd1q_%J~(=XQE(-r^8!V^1kQTK zYp<>@ms}ecu{}=bdUm`2x0NR*%3C{pygXwgbNH5q)gkN)_FXKit=+rt=N*&fs!4Yb z_RC)IeWT^bF2%7TlhKsLB<%9v=+4M%CZ&Iuu8W;~_DI)*`Vt4hngc!^qOUR@F*#*w zE3Q!eFq>Cv&iVc4p06m_{89bSwf}D#?$7(cXjRW+wVm5ZXDf@qhOfb`63(1AW_6lJ zM>X&^+gQ0wOzd-LjmYA3sF>5T@Q_!#y+&M%(3Ax~8Xo>OP}5>Kc-Ted^~Ph?bG}-~ zDE}+zYCJyIL37smL#{7u&9Zgs0~%y|3^yK@xSg@Q?2Fj!A7Lvj^iAE4yewq@};H zQ#Uc|u4{B*uh}818kVr*vBc~DdzdpE_Apmm`H*oS*Xw|8)PvL<-Zi^7_wMa3S1?hy zw{Xwo7Y)AL8(uWLQDSOyHkz|s_3MqR+tzAaIdJ*s(>S(IcB&8R?VcQP2s*g%egE+{ z6>oksFLdB+{PlZ{{kHbQncr;Qe=Fjt>v&!-QGBAdy( zx&3G*)6G)LPyPpEb?VKZHZ<*dJ?|Z>WWkAF56uO2-JK@=`Epm{kA(0Ciwl3(e}tq> zn+@K_^dxtuWKPfdDKou3C-VNDncmwf`nNib6+)idQYrT*~uF)h6Ko>it7mw;kc*vdhriqH?{bdpHq$g o$E+v0AIW%GkW>E8_WmY&vFKdtmb-sAfjN}H)78&qol`;+0RLj&2><{9 diff --git a/mods/species/tajaran/icons/clothing/pilot/suit.dmi b/mods/species/tajaran/icons/clothing/pilot/suit.dmi index 1e95ce43f85d0fc30563be0404d427a1025396be..b11b61d8d69911d19de93cab69388f41745d958b 100644 GIT binary patch delta 689 zcmV;i0#5zL2CW8=7f3(^0{{R3SVwH_0000XP)t-s0000SA}b>zCMz^RR8vriF}prJ zKNuGoTp4>fKvESI6x^!#c zxQ-1T4sRt(A)m4iB-T?3rO@@>_EUcT=jqv&33;jiDUVWz{Sjq=Ia(x`$vC2PGPFF2 zAQ~g~KN-ru>?}X(RrXnbT49g_fY|jregY+h>{~(0w)E`6p_WR@Z71B;gOk9TGxu5s zuuNXvbJ13}aJ%P1<>Kx7BHT#N7*qPHQ0DC#u+U;ff%ng)jlXJC#*~?xA&%D;htdTTg=3Nt0{AZ@JdJ+O)xKb zg}EISvtv2&UG;#u-N(0`!W=#CVl4Qg-6-bJ7>$J+S!lJiEzqhEPC}dyg&O_1U>K%_ z*$h$Q3JN{WIu48(3P4YkuiAx;UGQ^VXoG~8`secce_si7v~Yi43

    +$!44}$5@A3GQ+Ttn8|m4;Rpg?XxRtQj$mLD$5@au2ZMyFd4DZ@Y*HjVtapdQPs^{T(|7A9 zr-$kBh=t?vpl}ag;h@l&MZ8!|;TKL=iE%cw+#6@@62VtUEpUPsF-|1jeDqu*CVV>| zIRc|g=WS*+O&phmNmyh5Qa5zYPsJRj_~H*6&~+c9D$Yb)r%HOj+>%fgDbSh zBKqcd75_7#OuH^=mfKvESI6-7>M=Kufz0d!JMQvg8b*k%9#0DO^OKLkJ=3$Br%Ie%hZAZT3g zycPfe0!v9mK~zYI?Ulc4+dve6PZo)Ar`(xx)n?gH;mz{1b;Yav4}=oP+$*P5(zU+0 zTQMOWV=X~jz(c`*Wn~)c-nr1dC2#v4pPt_R&=VoA@!y9xivFJPD0SGMQ3jZkQG}Vy z6G|6T%Zmh(Ib#2_q5SLC@_)TvWnZKf1~~wT?N!GQprnvjR?xByJv?!!rIK>f3H^F- z6j<}Zy_NwilZ#s}+UOGf9TzGW?`}@QrSyz3rLQ^;jzY)87a~hoL@c#JX+V^^6Oxi~M$1kh#;Z-W3ku5-D@fHpP2>oHPDZXU8h;4%<&pI~V~#P379VrOT4jb|Au@{}!Vv@jzQq9A5e%%;6bn-3 zV31HX@6Ux#O^k%Qo9%x8Z28S{`Qhfl>0x;|VBv7sE8N33*ef)7iI=J+{KOSjVxA2x z_vTrfBKQfZ1+Jh)iYpRtJbNk;6TTVG9D&h^Gm}_NozwElNpC&GLT^%YECgX#6DKCS zUEv6CZ(ZU3+7Vcpo{fuCa@-W<8eE|r?�yRs7EiW!!a1!#G$={7Mp}c~R|NYIsdm w1mNs!yZ2B8ar07xn|AOiS5T%P=D4}P00iilPy8&G(f|Me07*qoM6N<$f;%}!m;e9( diff --git a/mods/species/tajaran/icons/clothing/salvage/suit.dmi b/mods/species/tajaran/icons/clothing/salvage/suit.dmi index 902a9487ac6f966d17d77d19c57060142efbbc55..df273abc4f408163149609581ea9631e4d2146d3 100644 GIT binary patch delta 871 zcmV-t1DO1i3HAt(EDs}6IBR537BVANb75tMagjS<1fob~1CgJYe=12tK~z|U?N`xq z+c*pq0hwS4NQ%fNQcJpR+VuZ_u`4$>Hy4q)hkLskGxlh_z;Z!?5IhWbyW8FVNOOnv zVPZFqqhspfZoFJBqwC>b!UrtyA&T$djzb9SI=I?2FK}4q$+U$l@$xV|EKJ(Oy{swI zOgXLM&mNj&q3Pq}f5(XyNeu?&r_F2jS^c(igMcE<)2Gj$rWsES+-DX)PwO;$;e3*y zo};`fkjQ6=>e!V)vIvEO=M#bM8s(-yBA(9#33BP2`|b48-(6u3%Q zE!i5Ro+SdmZeRH8_LaYE*H#MOdpEd?N*S#Su>re-n=S>dq-tpLBn&*)l)x zntXkOU$c)pkvJjRqtDm31XuzJlc^6ug-Dx z+{RJMHmld!nw5Mz2z3|M#u5BQkf@YGsYhU1Kv1-U53DM|1ySWTZiWiu#jK4FBd&TG z3oiZG#V;K9e;z)V2$fJs#M(H@eLQZ2wsANlEknV#wU$7yxr_|l_XyNVkwHqqQfCIf zT#h0b^uXKk$!7uqW#8%-1H*2(wsDlAnIQ#yw_Db~;CH**-TqgGmhqpQ0(utnJ7XLg zBOFE-dISL!;E-OpAR6JJLoi995cd7Y%gaj($In0Ze?0^$GBpVvi_a1_Nm<(jnv-l% zvM-Nq1qD;eiuY@_Hi6;oIC%+X^tON~9#YbB+KKMR{UvD;Nsppq-U65nVm*9%*CkY|n6i5O zhsFc8+Ph3HL|T@DS(3XH1EMSN1{S*#7jF%GwX1Fj0l#;L3MQunZC957~1lKqJV38Hp$EZm0=qlZK x^pZ%J5)Tdk+=%eI(H#Sr_GhpgX!f^1>=*QwGCI7%LXH3c002ovPDHLkV1o8BngRd- delta 900 zcmV-~1AF}T2$KnrEDu(5VP%GKBT_hPWKb3|Bau5`1Ou)~Cy}3+e@96~K~z|U?N`x~ z+cpf8On_hrNIH?ZlTy-2F1h^wFLvc#r_&SZy!53r#*950FR)yYAOsJ?!yfjq|D%nU z%VoUl;GDbX;127<#BLl%$JE2!O@Zs-Ucx6V@F|M#;EqEG>^ivGG%s*i=E<~$EAjF) zJuOVy#J#L3(@Z(7f8x&`nq;Br^YiD47D){T<(JKC_F4V5bAx~)&C{1ZzDzTo8o19a zexBB8_QLrjK|M!#S0Itk64kLQfn*U11NHAhI8 zDCUYp&na+~uv)S;NIgpge%-$Ex9uB$-L9<^zWWsRwfeg5e9|^Do6ed$k(AcPy>kr`SMpocI&hfBa$#Tj@ zy0_qAXJ4J;>bZ@hmTgwAvo$OEb`a_=tc@f1n;=msg;I~ew1A*!2On5ff(xR`ZQKkM z#*0}SN4ptae;ErdeY>X|_=V%%!v_y~31k9k{PYw}#$INn;>+cuTjQ&7va84jsOP%(TEE!q(P z3AzxOEuB3YTqUYCYHtC|2C*JKz3URHRZLku{zKydTkTyY7a}c7U%(+@Sty2{0uZEH z>pcR%sY~E+Q!%1hXAV7Vx693`&47zu=6GihVsE<`=MvfyFoOl`kljz=z{7YsF<^!Z zV?ZhSYTbr}QnKn%MsWS`4;EQreT<3}kFL^@#kPy>XNP0000Bl~6vyR~!NV0I$3!M~g~+J2hAtTb9dp7Y zOO_G>Sq(=!+nCs+t>&-@cUy)G{Qw*3 zv|;vYKx;-CKY49CgHu{@d_+BuDZdhs|cai_2LDX5Bedz&4 zy26%%O!G?)1*tuj6gXPJ>~jpR8_8wcT0_Y(pInpNCj$Ulqm9ZW%jk&M6&GAmTe z0n0?D-KL4@{Y7g7Qan+7{Jz53_ac#ha7MMLbjW<*FiDhbxI6}xD5d_&5An~T{o&LU zyexfRZnZxz@%;qg%H{!s8;~Z3d*BCxtTzWc9u%yG!xt&gNAXDbP(auu0~4b~_OYN) zV6b;K6xci#CY+!?%cKn!l#ERe6tTM6&p2pZvmDd+K@o(IevpC`v7#;mMHs?=HB<%! zRAM2v8o?4{m>Zx5H=}~BH~dI2BX&VootqJ1uub7l#utDeKe_$TKB(^Px3ACvM;t!h z@-0TVHLq-8tf92`8qUBYv0000mP)t-sz`(#}|7Ig1CNC~AE;TJhv=A?? zc)I7v4HHcODOYt2A35==qLi{qxF*Hz=PF2I@*6T!P(D3g(f^#)Hi5^oB-ls zf5X0>5I|dar5Mbr000^hn}6b?@A#0b6j@<^0LCLa+17coRWa(HxC$MpM#&h?6^dC% zh%T{Wf-b;>0VFj*2qImFMg6C#LtTZ&9t;Iiic!;;fS(J90EJFGKwLPLS^_f!h!mXN znaV2s;@NWr!!qvtD9RRelP*#YmaBAmc#-P7((8D1c2j-u(=3gElR1@vBv4M|EP_`0 z7$5FQ(&tK2#kRL>p?wi>$-*$~PZ`S`jtK4uVx41o4r_J#Mc1<<20v%j}Cz)uG%$AV{Q z;dH)GWowl#=hGG!k$+v;ec{H}7Kc^A#aH$>y_z6`fnE7NewQ5#Z19P0H@abR75B}4 zYz@G~p?sBt`1dQp+;mo|_v^h9zS}@rGq0Y7vfAuJp$PEXRhxa70MR-`h+efeC>LYW5L$0DsRGVr5!1z%9&{Yl0Ag zeH&!^3m#geEk<#&n`dIahA38osy4+G5`3~1B3r8*SJlYbB@M)j+qshNyh-FiX z+!d#4l>rA!?Y$BQ81Bh^Ryq-3~DIT;Xid6B@AZ={wRfQ#A&@?h!;qG?{fHLn_v9xN`# z5?DtOT%B}=lweqUoxlrtLVzSQb&ytn?_&~z5`~~m-_||vps^8G54M}e1jscF7_4@i zdU(S?T{T0PSkk{ZKKXzJ?Zt}+Bcdt0{{R3>UBYv0000*P)t-sz`(#lLP8oE8Zc-33=~14qK_nw3G4qqwF}T{CLuugp)Z{gJ+|aoXmL{9WjWTd zj`bg|M7mOJK$LSP3h|Qo7pD?Fo@j-G6<7c9LR9gg;!_Z(n(#1w*<%27O6642$@frt zeyQg<`T#$jsay(vT@TlPw|A;ZSEcv2>xeV+TGkJIaW~@d%J`&Pvg=SuA~;yf=jF4k za4=Sy?svK)xr*;y|BMdc;#@w;neF~3L2if`pPgu9jIp1-8eu7&OZQtkS`R~r>Mb=>m z81!irNQWh0(DJ8$K22^P5P@_DK@8NlIk~%i$9eJJ2FE(qvHtPO;T!w!Y_L^dGGyJ; z(bAXEbhDcZnx6}hI5Pv)P~pLWLk(wJ<%y6?T)S1s5B>0%MF5b)7$Kt|&(aM#(SII7 z@|Lb@Zz+oIDI5-I7)R-+VDhQp*qA+nv091jYc5({gzXob5}jBpdwJR#^JFMu_Mt^^|j zVrdhRwsalWBoW;6f* diff --git a/mods/species/tajaran/icons/clothing/wizard/suit.dmi b/mods/species/tajaran/icons/clothing/wizard/suit.dmi index 17f0769a4d2660096c43a08f3efac0370aa5832b..b8b7ed3ebd0b2ad97efee68680b224ce11a1e4f7 100644 GIT binary patch delta 802 zcmV+-1Ks@Q2gwJJ7aKqb0{{R3owtGP0000;P)t-s0000gDk?iWJCQXoBv4RLY*J`b zCv`|3Vj>zS000OB= zL_t(oh3%Hna^oNjMFAlrn_xr8rvLw^dm)+ab|Sfb*x9FO#-27uzP^?*l5_8P$A1qW zLhvRfii`w~L?$0$@+HX%zEQqt8I%%7-guLgG|stPWZkxHmrKd4a*iiFQh@{9V3%BA zR^uFZgd~MK7o&d&9^k+s6r;iSZ3h>H3rZAu<;smC$|M?(e8dA-;q_XCh1bZjF|m|u zedUz6#>z?It{yqTCAWPTa48>E4j%t2 z{ORC@IHE1wU50fLI9egxfU>IPVV|CzL zs`wZ~S12~CTj%kd<_(r2p1qWX6$S3&`sP~uwde}GlS|A`T=nAkHx_7>h zKUCgt{^oyhbd|s39se%8-TZ%)LquBJ{42(AV2lTY(o*J(U?%X2*1V9Bz&lAvgcffK zY%8TAWbDiMT2m72iIxHY)5tMAqUoSxp+#F8KkqBHD?y9Y6ApUJ0H+S-a6pI3YrST= zf9K#%`C6;Wk9v&Z=6>ej4g-Qj-9bZpzKb;5K@)!@Bx#0&IJ!O@G-IVugM%>|MBM@Q zY+Na*q9uSD$`}o-)-v9XV4AbLF9tk$w4!tWYXqhECeKWlJS!%@Xq1N9lg+WqLj z-v~}1e1ElohP*=87twqBGcW>3K^l_3cIcsr*6u_?IZ?p%C5Vjt;rEMzpPQ}kV>++} g#t1PleC8v51NRpkgle~lBLDyZ07*qoM6N<$f+?nO&;S4c delta 831 zcmV-F1Hk;r2j&Nm7amLq0{{R3>UBYv0000;P)t-sz`(#eJ3CNNP%0`akuoqLY*J`b zCv`|3Vj>zSYn5Dn00001bW%=J06^y0W&i*He36Df1V9`Mu93$%e_~xAXk72S761SO z#7RU!R9J=Wm)nlpFbqU>p=i-oWJ^i2|No~QDT}t-kWPX2r9cQI*v+BG6I!+=&b{kh z@A@ChhYqhz?`z7GQ~m!qlt;ozA&Dnd@O;4%p=5=o(F{=>mD z$0s!A#OuSs<9~&JI(XvvWDIILNOPHJd@LpAtnyiDt~9)BfAGP5IN^@>LGf;Le`A|F zx^!6V>YXro?jBsd6FvoU3MtzH7l8vYxx?wn6W&b+p2NJ%mO#f!-?whgpu<2rOpb97VSsIp)q#7d;b!zfp?Fx`0*~)$o?xjGIZ9nvQQ$C+@2>Z6i>|;+DN-1(qIQf^ z3k0NlT>%z-e~2!I@rTO8E#4enLFMmy*Sr2@sZWyM>P3ipsSr+576hPhDuECePXvfa z3opOah-gMg8E#Vf1S#;HI*Oj7!mV+=HLzkf=1mz zM@YJhblX7}G-T<9gEX=i9CTx)P=|vN(30)|J1345Owkg+3}pl~Yl9zGN06!Q41}01 zk3O|LPL4(LVIA+>$81Q}4ecZMlLRz9V1gVifryl<|J?a0a49*lbwhh(z&{Y^Y&h_1 zOj-7mX%S!u_`#Fnsw>1fgR>cqDb5+F-@&gTjvVwt02RZt1;nBiy0MC$us#bxOe)&Y z{52;HO$00_;_Hb5j;~&1^bfyZ6yki?#xOFPEii)IJn*w0^&Ks;9(3uY7c>9>002ov JPDHLkV1ffxe@_4a diff --git a/mods/species/tajaran/icons/deformed_body.dmi b/mods/species/tajaran/icons/deformed_body.dmi index 42c45ef556a520715f1464c85b41d40f57434415..cf761e9bf07d2f5cd4393b7ec2f6f09e9a807673 100644 GIT binary patch delta 60 zcmV-C0K@;*3)TyeEHSsY%GlWJ?(X{F;Pbh;%=-HO>+Ami|Nr9R^)s0Oo>55K+wQ=? Sz_+!^`1t>H1+TfWU3mo~;wnG@ delta 60 zcmV-C0K@;*3)TyeEHOz*Txx24fPj;7a)nDvUYnb(eSMIVlcscZhclS~o>53`ZGgbQ Sz)443ii)2RlTv@NU3mp43>w4$ diff --git a/mods/species/tajaran/icons/deformed_body_male.dmi b/mods/species/tajaran/icons/deformed_body_male.dmi index f1fa36b7713c423f80a19143c9e7fcd0b1ba1d06..11d2cbbe55a31918af4e7592a7548b4532fd549b 100644 GIT binary patch delta 60 zcmV-C0K@;%3(^aaEHSsY%GlWJ?(X{F;Pbh;%=-HO>+Ami|Nr9R^)s0Oo>55K+wQ=? Sz_+!^`1t>H1+TfWU3CQ_0xC2B delta 60 zcmV-C0K@;%3(^aaEHOz*Txx24fPj;7a)nDvUYnb(eSMIVlcscZhclS~o>53`ZGgbQ Sz)443ii)2RlTv@NU3CQ}EE>1~ diff --git a/mods/species/tajaran/icons/hair.dmi b/mods/species/tajaran/icons/hair.dmi index ed61015bcff0221e5c528d48d0af918b352d1539..79684b445056a9399919a15cff6791864c290f56 100644 GIT binary patch literal 8327 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 S68M7w=!Ti4X~k8S$Nvjs%}=oa literal 31399 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 WUd7W9^t{&7(V!$_Ap-z_^5Fwj0|0<< zf)8-@3RprXQj7+Z$p9l$Z&iCQTTiFw-cE3L0PxFvGbl^da);u|JVrW#L>5==a9^#E z*a8wU?8ZHqAI&uj9SJsLETj1uA?Z= z)xeINu<<)#uO{raZ)_zwpqzua2g;3&Q+h)GVlh$dJbK}FW5RA+M$mC3@KNq}>#P03 zk$QY;_H?u{WZJo@-I*L}66(q{lt=qyqE%(q^M9^nRd}i#$meq(X)pC)5x*0L*tDs@^y9%iNlQyWU(0BHb0? zfgv0dEA1sJ3nuAcJxRF$$vYC&pBvHjOpwv5OkeG(xc}lwsJpkUbhDBNc9Wv#T6j|# z?bTv^$tK#oP9o;Y&|LM$Oan3X%rEY*7U%9d`aN8O-ePqqxsg!Fisj0#|G<8%nm~Io zEw2$hM{V6Hr~l`K(0M|@tYp`ca&rIE<^F~6(-i4Uhm{p}1qd~_G$Mv(b zv((HwJIyU?NG{5<0lBq&dW!5^`Smn7m|Y^Sou&?83!|=?rprBqRvc6&0_) zxc-?26U%f4*W!C0)nj$z*8&zDy=w7-`r4cbg zh;8EsOB{UUIOo>=@o#b%o=jEPb_@&+y*xM&k)+R&oINbsJt2k8QcW>%YLn|Yr5}s| z2Tw4f$0773UXA%qA;nJ3H zoXvM1*Vorm)4u*;1su9ZY@BAOauagW^UqT9NiOs}_$ZkgZ&=1}>hjXgUD@TchHG_R zKj{TU+`z&bX!3N0SQ>?B8ihfT(MJ;A6y}^~e3tP>)qT!6Rz)vKsoiCIhW9)Dzl@zE z(-Y9R{eZc_{mvuYQl4i?(wrh^9J_opIJrql^d)6wHlBO$Y%d?M!;@2uKXNWkS6WsU zety#M`@Kp7&VSVA9TxX(4avAYPAd*irK#S>_WbVrftjZ^{+L&|e*h0V^pBAoP70#1F zc)0JUXVflSE@OL(Ew5@Y-HIos`RjK>j`Ev$83*@3MMvgU(tYGMMLqh?4H1IaBt%=vGHNr<+mq!lF z6Rzl8p=aI~=V#j8po^)T5EMi%s z^?|-B1W1WAIT{p`x3#5<)I4){b;aEd#gFg}JR(r~Bk{vUF>&hOSZ!ThTRhf>)gtpr z8b8V)ggB(cioPEv?wy{$Xvt%8C_BUlwp$7gy))WU|;b`4U$G0|P?}Z@b@z!*{3?v5QCEGV*`TF9zrcee`R} znjqdq`GEag`n0eW<)jwlJ9eNuF)tPRbN@oI{`{8@ki&VQed?3A=RABkNDegAD)7!$ zv%{*t5U(Ei$<4tyQXSSgf0W*!zB9ZZm70c`6^&GR(PUltQ>MXqSzJD-SHD+C5^dl{ zzN#dXb(*M7H4^W#nfj3gy!?@Jz%{onLuB39fiFV89dnak4pw15G5R6o z^9}EbdCzubf{mlo7kLw3R7X`}^vGXbPi-2D)r#{hICc43lYU3)mB+m{weEyohpE{9 zDfcF8q0Kle9XMRXrXqFl+mY$r-v9X$Z-P1PPg zceS&#n8tV&tQ!)NW@+>t(@hSWx_`F6Lki~D9&jqv;#0VNiQ+q6p87mZfA8qCzpi`K|^&MX~)wG?Te_1p&qLsH1Y ztJB+Yl$gT3VyiQx$_v5?sj5Uq+vV0iH)mz6RfuEI6J!tw$h<(ux4BD;3*FwHt%t3l zoI%fl8wVS1i_l9VrDmUReo30)St+_)kfRXytnTo6z;QYcYg{zA>u5DbY{kKOZCShw zN~aIXW9l9<)BMAwkH5)M2{%xmWJa+!Z2h6W3J$NVtc=p@N&?H0aDcJT-I9C~HC

    UrIkN;riaoQ3A$_w~MctSl__)a-If5*fw^#}K74 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 diff --git a/mods/species/tajaran/icons/tail.dmi b/mods/species/tajaran/icons/tail.dmi index 34ea05358ccc6aa3c617d9f02751a478f4b78b54..fe0108c1eb6b899f3a252cc96c57cd856d70cb6a 100644 GIT binary patch delta 21 dcmaDV@Kj)e4%harr+)nS&wu)9^hPs%4gh`=3l0DP delta 21 ccmaDV@Kj)e4wt8UOjp Date: Sun, 9 Mar 2025 18:14:10 +1100 Subject: [PATCH 145/512] Converting Taj ears to Neb ears accessory. --- mods/species/tajaran/datum/accessory.dm | 10 ++++++---- .../tajaran/datum/species_bodytypes.dm | 4 ++-- mods/species/tajaran/icons/ears.dmi | Bin 0 -> 419 bytes mods/species/tajaran/icons/hair.dmi | Bin 8327 -> 8059 bytes mods/species/tajaran/icons/markings.dmi | Bin 6419 -> 6004 bytes 5 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 mods/species/tajaran/icons/ears.dmi diff --git a/mods/species/tajaran/datum/accessory.dm b/mods/species/tajaran/datum/accessory.dm index 7d40b46a502d..b88d66ed84d3 100644 --- a/mods/species/tajaran/datum/accessory.dm +++ b/mods/species/tajaran/datum/accessory.dm @@ -178,23 +178,25 @@ color_blend = ICON_MULTIPLY uid = "acc_marking_taj_nose" -/decl/sprite_accessory/marking/tajaran/ears +/decl/sprite_accessory/ears/tajaran name = "Tajaran Ears" icon_state = "ears_plain" + icon = 'mods/species/tajaran/icons/ears.dmi' mask_to_bodypart = FALSE uid = "acc_marking_taj_wideears" + species_allowed = list(/decl/species/tajaran::uid) -/decl/sprite_accessory/marking/tajaran/ears/inner +/decl/sprite_accessory/ears/tajaran/inner name = "Tajaran Ears Interior" icon_state = "earsin" uid = "acc_marking_taj_wideears_inner" -/decl/sprite_accessory/marking/tajaran/ears/outer +/decl/sprite_accessory/ears/tajaran/outer name = "Tajaran Ears Exterior" icon_state = "earsout" uid = "acc_marking_taj_wideears_outer" -/decl/sprite_accessory/marking/tajaran/ears/wide_tuft +/decl/sprite_accessory/ears/tajaran/wide_tuft name = "Tajaran Ear Tufts" icon_state = "earsout_tuft" uid = "acc_marking_taj_wideears_tuft" diff --git a/mods/species/tajaran/datum/species_bodytypes.dm b/mods/species/tajaran/datum/species_bodytypes.dm index 8c006d8e241a..60d933c5ab83 100644 --- a/mods/species/tajaran/datum/species_bodytypes.dm +++ b/mods/species/tajaran/datum/species_bodytypes.dm @@ -35,8 +35,8 @@ ) default_sprite_accessories = list( - SAC_HAIR = list(/decl/sprite_accessory/hair/taj/lynx = list(SAM_COLOR = "#46321c")), - SAC_MARKINGS = list(/decl/sprite_accessory/marking/tajaran/ears = list(SAM_COLOR = "#ae7d32")) + SAC_HAIR = list(/decl/sprite_accessory/hair/taj/lynx = list(SAM_COLOR = "#46321c")), + SAC_EARS = list(/decl/sprite_accessory/ears/tajaran = list(SAM_COLOR = "#ae7d32")) ) cold_level_1 = 200 diff --git a/mods/species/tajaran/icons/ears.dmi b/mods/species/tajaran/icons/ears.dmi new file mode 100644 index 0000000000000000000000000000000000000000..27418f2b560ea3459f43e84bbf3db9c2f8c9eb37 GIT binary patch literal 419 zcmV;U0bKrxP)A**wCkZd#XLW1Oug3_2RA%VvDHa7uE9lP8tO?0RRAan*p;t5V&6oK@9)^ N002ovPDHLkV1mvfvoQbw literal 0 HcmV?d00001 diff --git a/mods/species/tajaran/icons/hair.dmi b/mods/species/tajaran/icons/hair.dmi index 79684b445056a9399919a15cff6791864c290f56..2d1c659aa78e07d78ee1331b8d3a542d7b95170c 100644 GIT binary patch literal 8059 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 TyuS|~ssjdk_jHSO?8E;DQ*ji8 literal 8327 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 S68M7w=!Ti4X~k8S$Nvjs%}=oa diff --git a/mods/species/tajaran/icons/markings.dmi b/mods/species/tajaran/icons/markings.dmi index 80fe7cbeb5e9a0f2442882bcf447c0d51f70e017..20a0a07b9593aa53535fd491e7d66ebb0314a3fd 100644 GIT binary patch literal 6004 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 literal 6419 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 WUd7 Date: Sun, 9 Mar 2025 21:56:17 +0000 Subject: [PATCH 146/512] Resolve unit test failures --- mods/species/tajaran/datum/accessory.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/species/tajaran/datum/accessory.dm b/mods/species/tajaran/datum/accessory.dm index b88d66ed84d3..d71003eeaa0e 100644 --- a/mods/species/tajaran/datum/accessory.dm +++ b/mods/species/tajaran/datum/accessory.dm @@ -1,7 +1,7 @@ //Hairstyles /decl/sprite_accessory/hair/taj name = "Tajaran Rattail" - icon_state = "hair_rattail" + icon_state = "hair_rattail_s_noear" species_allowed = list(/decl/species/tajaran::uid) icon = 'mods/species/tajaran/icons/hair.dmi' color_blend = ICON_MULTIPLY @@ -305,7 +305,7 @@ /decl/sprite_accessory/marking/tajaran/tuxedo/left_arm name = "Tuxedo (Left Arm)" body_parts = list(BP_L_ARM, BP_L_HAND) - uid = "acc_marking_taj_pawsocks_leftarm" + uid = "acc_marking_taj_tuxedo_leftarm" /decl/sprite_accessory/marking/tajaran/belly name = "Belly Full (Body)" From 6893bfa27400a72bf95f9e8fa6b2b7fb3785db2c Mon Sep 17 00:00:00 2001 From: Cerebulon Date: Sun, 9 Mar 2025 21:56:17 +0000 Subject: [PATCH 147/512] Resolve unit test failures --- mods/species/tajaran/datum/accessory.dm | 4 ++-- mods/species/tajaran/icons/tail.dmi | Bin 2149 -> 2146 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/species/tajaran/datum/accessory.dm b/mods/species/tajaran/datum/accessory.dm index b88d66ed84d3..d71003eeaa0e 100644 --- a/mods/species/tajaran/datum/accessory.dm +++ b/mods/species/tajaran/datum/accessory.dm @@ -1,7 +1,7 @@ //Hairstyles /decl/sprite_accessory/hair/taj name = "Tajaran Rattail" - icon_state = "hair_rattail" + icon_state = "hair_rattail_s_noear" species_allowed = list(/decl/species/tajaran::uid) icon = 'mods/species/tajaran/icons/hair.dmi' color_blend = ICON_MULTIPLY @@ -305,7 +305,7 @@ /decl/sprite_accessory/marking/tajaran/tuxedo/left_arm name = "Tuxedo (Left Arm)" body_parts = list(BP_L_ARM, BP_L_HAND) - uid = "acc_marking_taj_pawsocks_leftarm" + uid = "acc_marking_taj_tuxedo_leftarm" /decl/sprite_accessory/marking/tajaran/belly name = "Belly Full (Body)" diff --git a/mods/species/tajaran/icons/tail.dmi b/mods/species/tajaran/icons/tail.dmi index fe0108c1eb6b899f3a252cc96c57cd856d70cb6a..2851b3f7e33b7afa35f89d3ccb779b7b6cfac635 100644 GIT binary patch delta 80 zcmV-W0I&b$5aJM!Mgg>uM}0pHaTsodFdT=WXoh8`S0@E;D?ld$t0AV!4bMo^G msOHk*ocwZXxKzj3fJ<4y)z1YSu>edEca(8p-wd+`0bd8jXC!6- delta 83 zcmV-Z0IdJw5ake%Mgg~xM}0zZm~DhG8;6-_W@V=2q#6=-sG*J_US}Gb8h|jG;W_#F p1-J|+*`>uf`Q_AbsgAJ$m$HJZp9?r%0p!GYV{kI^1G57GUk5m$CAt6r From 7d6a3ba8bd2ebd23b6dc955f7ee86d6ad6b6d20c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 9 Mar 2025 17:22:26 -0400 Subject: [PATCH 148/512] Fix scanner components blocking machinery interactions --- code/modules/modular_computers/hardware/scanners/scanner.dm | 6 +++--- .../modular_computers/hardware/scanners/scanner_paper.dm | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/code/modules/modular_computers/hardware/scanners/scanner.dm b/code/modules/modular_computers/hardware/scanners/scanner.dm index ea42566d7a0a..830f306d2337 100644 --- a/code/modules/modular_computers/hardware/scanners/scanner.dm +++ b/code/modules/modular_computers/hardware/scanners/scanner.dm @@ -54,12 +54,12 @@ /obj/item/stock_parts/computer/scanner/proc/do_on_afterattack(mob/user, atom/target, proximity) -// TODO: Revisit to see if we can make do_on_attackby return a bool so that normal afterattack can run. /obj/item/stock_parts/computer/scanner/attackby(obj/W, mob/user) - do_on_attackby(user, W) - return TRUE + return do_on_attackby(user, W) +/// Returns TRUE if the attackby chain should be stopped. /obj/item/stock_parts/computer/scanner/proc/do_on_attackby(mob/user, atom/target) + return FALSE /obj/item/stock_parts/computer/scanner/proc/can_use_scanner(mob/user, atom/target, proximity = TRUE) if(!check_functionality()) diff --git a/code/modules/modular_computers/hardware/scanners/scanner_paper.dm b/code/modules/modular_computers/hardware/scanners/scanner_paper.dm index 04bfb3ae3694..a0d0c430ab1f 100644 --- a/code/modules/modular_computers/hardware/scanners/scanner_paper.dm +++ b/code/modules/modular_computers/hardware/scanners/scanner_paper.dm @@ -27,7 +27,7 @@ driver.scan_file_type = target.scan_file_type if(target.type == /obj/item/paper/bodyscan) - driver.data_buffer = display_medical_data(target.metadata.Copy(),user.get_skill_value(SKILL_MEDICAL), TRUE) + driver.data_buffer = display_medical_data(target.metadata.Copy(),user.get_skill_value(SKILL_MEDICAL), TRUE) else driver.data_buffer = data @@ -35,4 +35,5 @@ SSnano.update_uis(driver.NM) /obj/item/stock_parts/computer/scanner/paper/do_on_attackby(mob/user, atom/target) - do_on_afterattack(user, target, TRUE) \ No newline at end of file + do_on_afterattack(user, target, TRUE) + return can_use_scanner(user, target, TRUE) \ No newline at end of file From a237bc4279dcdb860abe43ad79bd5a0d5231d497 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 13:48:19 -0400 Subject: [PATCH 149/512] Fix machinery components break naming #4933 --- .../machinery/_machines_base/stock_parts/_stock_parts.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm b/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm index 38cc9bbe24db..f3c2bd507167 100644 --- a/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm +++ b/code/game/machinery/_machines_base/stock_parts/_stock_parts.dm @@ -86,7 +86,12 @@ if(ELECTROCUTE) cause = "sparks" visible_message(SPAN_WARNING("Something [cause] inside \the [machine]."), range = 2) - SetName("broken [name]") + update_name() + +/obj/item/stock_parts/update_name() + . = ..() + if(!is_functional()) + SetName("broken [name]") // prepend 'broken' to the results /obj/item/stock_parts/proc/is_functional() return (!can_take_damage()) || (current_health > 0) From a0ed0d2a3cfc19e4c477a9ad813212a112d8be6c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 14:00:25 -0400 Subject: [PATCH 150/512] Fix attaching an assembly to a tank causes overlaying issue #4908 --- .../game/objects/items/weapons/tanks/tanks.dm | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 24c7dda61fba..eece9781bc04 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -177,9 +177,6 @@ var/global/list/global/tank_gauge_cache = list() if(wired) to_chat(user, "You begin attaching the assembly to \the [src].") if(do_after(user, 50, src)) - to_chat(user, "You finish attaching the assembly to \the [src].") - global.bombers += "[key_name(user)] attached an assembly to a wired [src]. Temp: [air_contents.temperature-T0C]" - log_and_message_admins("attached an assembly to a wired [src]. Temp: [air_contents.temperature-T0C]", user) assemble_bomb(used_item,user) else to_chat(user, "You stop attaching the assembly.") @@ -550,23 +547,26 @@ var/global/list/global/tank_gauge_cache = list() /obj/item/tankassemblyproxy/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. tank.cause_explosion() //boom (or not boom if you made shijwtty mix) -/obj/item/tank/proc/assemble_bomb(used_item,user) //Bomb assembly proc. This turns assembly+tank into a bomb +/obj/item/tank/proc/assemble_bomb(used_item,mob/user) //Bomb assembly proc. This turns assembly+tank into a bomb var/obj/item/assembly_holder/S = used_item - var/mob/M = user - if(!S.secured) //Check if the assembly is secured - return if(isigniter(S.a_left) == isigniter(S.a_right)) //Check if either part of the assembly has an igniter, but if both parts are igniters, then fuck it return + if(!S.secured) //Check if the assembly is secured + to_chat(user, SPAN_NOTICE("\The [S] must be secured before attaching it to \the [src]!")) + return - if(!M.try_unequip(src)) + if(!user.try_unequip(src)) return //Remove the tank from your character,in case you were holding it - M.put_in_hands(src) //Equips the bomb if possible, or puts it on the floor. + user.put_in_hands(src) //Equips the bomb if possible, or puts it on the floor. proxyassembly.assembly = S //Tell the bomb about its assembly part S.master = proxyassembly //Tell the assembly about its new owner - S.forceMove(src) //Move the assembly + user.remove_from_mob(S, src, FALSE) //Move the assembly and reset HUD layer/plane status update_icon() + to_chat(user, "You finish attaching the assembly to \the [src].") + global.bombers += "[key_name(user)] attached an assembly to a wired [src]. Temp: [air_contents.temperature-T0C]" + log_and_message_admins("attached an assembly to a wired [src]. Temp: [air_contents.temperature-T0C]", user) /obj/item/tank/proc/cause_explosion() //This happens when a bomb is told to explode var/obj/item/assembly_holder/assy = proxyassembly.assembly From 0b1bd2de8741bfc23fa066d5f7cce4a689e862bf Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 12:43:59 -0400 Subject: [PATCH 151/512] Add better null guards to NanoUI code --- code/modules/nano/nanoui.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index c1dff1b5bf27..9fc00cd5a649 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -520,7 +520,7 @@ nanoui is used to open and update nano browser uis set_map_z_level(map_z) map_update = 1 - if ((src_object && src_object.Topic(href, href_list, state)) || map_update) + if (src_object && (src_object.Topic(href, href_list, state) || map_update)) SSnano.update_uis(src_object) // update all UIs attached to src_object /** From b4b722d6b9b98984d3e15811cc0de3aa7c6e75de Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 28 Feb 2025 01:47:29 -0500 Subject: [PATCH 152/512] Fix runtime-generated Z levels --- code/modules/multiz/level_data.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/multiz/level_data.dm b/code/modules/multiz/level_data.dm index 4c99de420b47..ea5984672f15 100644 --- a/code/modules/multiz/level_data.dm +++ b/code/modules/multiz/level_data.dm @@ -224,7 +224,7 @@ return var/area/A = change_area ? get_base_area_instance() : null // We don't have to worry about the edge turfs because those are handled in build_border(). - for(var/turf/T as anything in block(level_inner_min_x, level_inner_min_y, level_z, level_inner_max_x, level_inner_max_y, level_z)) + for(var/turf/T as anything in Z_ALL_TURFS(level_z)) if(change_turf) T = T.ChangeTurf(picked_turf) if(change_area) From 670850bfa2bc555a2922092f2cd81c07af9f1a18 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 28 Feb 2025 01:47:39 -0500 Subject: [PATCH 153/512] Fix crates shaking excessively when opened --- code/game/objects/structures/crates_lockers/crates.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index edbdf78c3222..4eaac0b2cc2e 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -9,7 +9,7 @@ var/rigged = 0 /obj/structure/closet/crate/open(mob/user) - if((atom_flags & ATOM_FLAG_CLIMBABLE) && !opened && can_open(user)) + if((atom_flags & ATOM_FLAG_CLIMBABLE) && LAZYLEN(climbers) && !opened && can_open(user)) object_shaken() . = ..() if(.) From ead64cbdc4b30e1e9d68663001efdc37ef807a5f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 28 Feb 2025 01:47:44 -0500 Subject: [PATCH 154/512] Fix UI colors --- code/_onclick/hud/screen/screen_drop.dm | 2 ++ code/_onclick/hud/screen/screen_equip.dm | 2 ++ code/_onclick/hud/screen/screen_gun.dm | 2 ++ code/_onclick/hud/screen/screen_maneuver.dm | 2 ++ code/_onclick/hud/screen/screen_resist.dm | 2 ++ code/_onclick/hud/screen/screen_throw.dm | 2 ++ code/_onclick/hud/screen/screen_toggle.dm | 2 ++ code/_onclick/hud/screen/screen_zone_selector.dm | 2 ++ 8 files changed, 16 insertions(+) diff --git a/code/_onclick/hud/screen/screen_drop.dm b/code/_onclick/hud/screen/screen_drop.dm index 085922329c75..716c451252a9 100644 --- a/code/_onclick/hud/screen/screen_drop.dm +++ b/code/_onclick/hud/screen/screen_drop.dm @@ -2,6 +2,8 @@ name = "drop" icon_state = "act_drop" screen_loc = ui_drop_throw + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/drop/handle_click(mob/user, params) if(user.client) diff --git a/code/_onclick/hud/screen/screen_equip.dm b/code/_onclick/hud/screen/screen_equip.dm index 39ca9349ad81..589edc66a05d 100644 --- a/code/_onclick/hud/screen/screen_equip.dm +++ b/code/_onclick/hud/screen/screen_equip.dm @@ -1,6 +1,8 @@ /obj/screen/equip name = "equip" icon_state = "act_equip" + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/equip/handle_click(mob/user, params) if(ishuman(user)) diff --git a/code/_onclick/hud/screen/screen_gun.dm b/code/_onclick/hud/screen/screen_gun.dm index e0bc13fee624..4cb1eee5886f 100644 --- a/code/_onclick/hud/screen/screen_gun.dm +++ b/code/_onclick/hud/screen/screen_gun.dm @@ -2,6 +2,8 @@ icon = 'icons/mob/screen/styles/midnight/fire_intent.dmi' dir = SOUTH abstract_type = /obj/screen/gun + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE var/base_icon_state var/toggle_flag diff --git a/code/_onclick/hud/screen/screen_maneuver.dm b/code/_onclick/hud/screen/screen_maneuver.dm index ddfdf15d7d6c..4052a690a53c 100644 --- a/code/_onclick/hud/screen/screen_maneuver.dm +++ b/code/_onclick/hud/screen/screen_maneuver.dm @@ -2,6 +2,8 @@ name = "Prepare Maneuver" icon_state = "maneuver_off" screen_loc = ui_pull_resist + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/maneuver/handle_click(mob/user, params) if(isliving(user)) diff --git a/code/_onclick/hud/screen/screen_resist.dm b/code/_onclick/hud/screen/screen_resist.dm index 9bdb07a9a0b9..ff781aa09c7a 100644 --- a/code/_onclick/hud/screen/screen_resist.dm +++ b/code/_onclick/hud/screen/screen_resist.dm @@ -2,6 +2,8 @@ name = "resist" icon_state = "act_resist" screen_loc = ui_pull_resist + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/resist/handle_click(mob/user, params) if(isliving(user)) diff --git a/code/_onclick/hud/screen/screen_throw.dm b/code/_onclick/hud/screen/screen_throw.dm index 1b4de10e6e87..5d2d9888ec02 100644 --- a/code/_onclick/hud/screen/screen_throw.dm +++ b/code/_onclick/hud/screen/screen_throw.dm @@ -2,6 +2,8 @@ name = "throw" icon_state = "act_throw_off" screen_loc = ui_drop_throw + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/throw_toggle/handle_click(mob/user, params) if(!user.stat && isturf(user.loc) && !user.restrained()) diff --git a/code/_onclick/hud/screen/screen_toggle.dm b/code/_onclick/hud/screen/screen_toggle.dm index 4f534e230f33..ddcf626e8c26 100644 --- a/code/_onclick/hud/screen/screen_toggle.dm +++ b/code/_onclick/hud/screen/screen_toggle.dm @@ -2,6 +2,8 @@ name = "toggle" icon_state = "other" screen_loc = ui_inventory + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/toggle/handle_click(mob/user, params) if(!user.hud_used) diff --git a/code/_onclick/hud/screen/screen_zone_selector.dm b/code/_onclick/hud/screen/screen_zone_selector.dm index 51b36db21255..567b5645da3d 100644 --- a/code/_onclick/hud/screen/screen_zone_selector.dm +++ b/code/_onclick/hud/screen/screen_zone_selector.dm @@ -2,6 +2,8 @@ name = "damage zone" icon_state = "zone_sel_tail" screen_loc = ui_zonesel + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/zone_selector/handle_click(mob/user, params) var/list/PL = params2list(params) From cee8fb3ab68a401b7df54f0d2c9186e5ae9daa52 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 28 Feb 2025 03:01:32 -0500 Subject: [PATCH 155/512] Improve redundant icon updates during init --- code/game/atoms.dm | 10 ++++++++++ code/game/objects/effects/misc.dm | 4 ++-- code/game/objects/items/__item.dm | 2 +- code/game/turfs/floors/_floor.dm | 13 +++---------- code/game/turfs/floors/floor_layers.dm | 4 ++-- code/game/turfs/walls/wall_icon.dm | 4 ++-- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 20e343c6bb26..09b5980c5523 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -411,6 +411,16 @@ if(event_listeners?[/decl/observ/updated_icon]) raise_event_non_global(/decl/observ/updated_icon) +/** + * Update this atom's icon. + * If prior to SSicon_update's first flush, queues. + * Otherwise, updates instantly. + */ +/atom/proc/lazy_update_icon() + if(SSicon_update.init_state != SS_INITSTATE_NONE) + return update_icon() + queue_icon_update() + /** Update this atom's icon. diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 48f931aef161..805288d6b365 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -30,12 +30,12 @@ if(istype(wall)) wall.paint_color = color wall.stripe_color = color - wall.update_icon() + wall.lazy_update_icon() var/obj/structure/wall_frame/WF = locate() in loc if(WF) WF.paint_color = color WF.stripe_color = color - WF.update_icon() + WF.lazy_update_icon() qdel(src) /obj/effect/paint/pink diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index eb6278824848..ca88dfb2541d 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -1118,7 +1118,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. for(var/equipped_slot in get_associated_equipment_slots()) wearer.update_equipment_overlay(equipped_slot, FALSE) if(do_update_icon) - wearer.update_icon() + wearer.lazy_update_icon() return TRUE /obj/item/proc/reconsider_client_screen_presence(var/client/client, var/slot) diff --git a/code/game/turfs/floors/_floor.dm b/code/game/turfs/floors/_floor.dm index 7dc51d0f1746..a2a53460c0a8 100644 --- a/code/game/turfs/floors/_floor.dm +++ b/code/game/turfs/floors/_floor.dm @@ -46,16 +46,9 @@ fill_to_zero_height() // try to refill turfs that act as fluid sources if(floor_material || get_topmost_flooring()) - update_from_flooring() - if(!ml) - for(var/direction in global.alldirs) - var/turf/target_turf = get_step_resolving_mimic(src, direction) - if(istype(target_turf)) - if(TICK_CHECK) // not CHECK_TICK -- only queue if the server is overloaded - target_turf.queue_icon_update() - else - target_turf.update_icon() - update_icon() + update_from_flooring(skip_update = ml) + if(ml) // We skipped the update above to avoid updating our neighbors, but we need to update ourselves. + lazy_update_icon() /turf/floor/ChangeTurf(turf/N, tell_universe, force_lighting_update, keep_air, update_open_turfs_above, keep_height) diff --git a/code/game/turfs/floors/floor_layers.dm b/code/game/turfs/floors/floor_layers.dm index 7283ebaaf9c6..78302f336e8d 100644 --- a/code/game/turfs/floors/floor_layers.dm +++ b/code/game/turfs/floors/floor_layers.dm @@ -250,8 +250,8 @@ qdel(print) if(!skip_update) - update_icon() + lazy_update_icon() for(var/dir in global.alldirs) var/turf/neighbor = get_step_resolving_mimic(src, dir) if(istype(neighbor)) - neighbor.update_icon() + neighbor.lazy_update_icon() diff --git a/code/game/turfs/walls/wall_icon.dm b/code/game/turfs/walls/wall_icon.dm index fb2b4640b418..94ca6d9b6eca 100644 --- a/code/game/turfs/walls/wall_icon.dm +++ b/code/game/turfs/walls/wall_icon.dm @@ -30,11 +30,11 @@ wall.other_connections = null iterate_turfs += wall for(var/turf/wall/wall as anything in iterate_turfs) - wall.update_icon() + wall.lazy_update_icon() else wall_connections = null other_connections = null - update_icon() + lazy_update_icon() /turf/wall/proc/paint_wall(var/new_paint_color) paint_color = new_paint_color From 60aa77dc16521b68116bea079c7cffae86a1731b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 28 Feb 2025 03:01:42 -0500 Subject: [PATCH 156/512] Fix atmos grief fixer verb --- code/modules/admin/verbs/grief_fixers.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/verbs/grief_fixers.dm b/code/modules/admin/verbs/grief_fixers.dm index afea1d4a6feb..9288165c9b4a 100644 --- a/code/modules/admin/verbs/grief_fixers.dm +++ b/code/modules/admin/verbs/grief_fixers.dm @@ -13,9 +13,10 @@ sleep(10) var/current_time = world.timeofday - var/list/steps = sortTim(decls_repository.get_decls_of_subtype_unassociated(/decl/atmos_grief_fix_step), /proc/cmp_decl_sort_value_asc) + var/list/steps = decls_repository.get_decls_of_subtype_unassociated(/decl/atmos_grief_fix_step) + steps = sortTim(steps.Copy(), /proc/cmp_decl_sort_value_asc) var/step_count = length(steps) - for(var/step_index in 1 to length(step_count)) + for(var/step_index in 1 to step_count) var/decl/atmos_grief_fix_step/fix_step = steps[step_index] to_chat(usr, "\[[step_index]/[step_count]\] - [fix_step.name].") fix_step.act() From 7607021ad5f3a8a54a31784393cc8a92af74f341 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 26 Feb 2025 17:28:05 -0500 Subject: [PATCH 157/512] Move masks referencing Bay lore into SCG modpack --- code/modules/clothing/masks/miscellaneous.dm | 18 ------------------ mods/content/government/_government.dme | 1 + .../government/icons/masks}/admiral.dmi | Bin .../government/icons/masks}/barros.dmi | Bin .../government/icons/masks}/turner.dmi | Bin mods/content/government/items/masks.dm | 17 +++++++++++++++++ 6 files changed, 18 insertions(+), 18 deletions(-) rename {icons/clothing/mask => mods/content/government/icons/masks}/admiral.dmi (100%) rename {icons/clothing/mask => mods/content/government/icons/masks}/barros.dmi (100%) rename {icons/clothing/mask => mods/content/government/icons/masks}/turner.dmi (100%) create mode 100644 mods/content/government/items/masks.dm diff --git a/code/modules/clothing/masks/miscellaneous.dm b/code/modules/clothing/masks/miscellaneous.dm index df8cce8d806f..05ee28f68f4a 100644 --- a/code/modules/clothing/masks/miscellaneous.dm +++ b/code/modules/clothing/masks/miscellaneous.dm @@ -144,24 +144,6 @@ body_parts_covered = SLOT_HEAD|SLOT_FACE|SLOT_EYES material = /decl/material/solid/organic/cloth -/obj/item/clothing/mask/rubber/barros - name = "Amaya Barros mask" - desc = "Current Secretary-General of Sol Central Government. Not that the real thing would visit this pigsty." - icon = 'icons/clothing/mask/barros.dmi' - visible_name = "Amaya Barros" - -/obj/item/clothing/mask/rubber/admiral - name = "Admiral Diwali mask" - desc = "Admiral that led the infamous last stand at Helios against the Independent Navy in the Gaia conflict. For bridge officers who wish they'd achieve a fraction of that." - icon = 'icons/clothing/mask/admiral.dmi' - visible_name = "Admiral Diwali" - -/obj/item/clothing/mask/rubber/turner - name = "Charles Turner mask" - desc = "Premier of the Gilgamesh Colonial Confederation. Probably shouldn't wear this in front of your veteran uncle." - icon = 'icons/clothing/mask/turner.dmi' - visible_name = "Charles Turner" - /obj/item/clothing/mask/rubber/species name = "human mask" desc = "A rubber human mask." diff --git a/mods/content/government/_government.dme b/mods/content/government/_government.dme index 61285936c789..a21a3a5c9913 100644 --- a/mods/content/government/_government.dme +++ b/mods/content/government/_government.dme @@ -7,6 +7,7 @@ #include "items\clutter.dm" #include "items\cups.dm" #include "items\documents.dm" +#include "items\masks.dm" #include "ruins\ec_old_crash\ec_old_crash.dm" // END_INCLUDE #endif diff --git a/icons/clothing/mask/admiral.dmi b/mods/content/government/icons/masks/admiral.dmi similarity index 100% rename from icons/clothing/mask/admiral.dmi rename to mods/content/government/icons/masks/admiral.dmi diff --git a/icons/clothing/mask/barros.dmi b/mods/content/government/icons/masks/barros.dmi similarity index 100% rename from icons/clothing/mask/barros.dmi rename to mods/content/government/icons/masks/barros.dmi diff --git a/icons/clothing/mask/turner.dmi b/mods/content/government/icons/masks/turner.dmi similarity index 100% rename from icons/clothing/mask/turner.dmi rename to mods/content/government/icons/masks/turner.dmi diff --git a/mods/content/government/items/masks.dm b/mods/content/government/items/masks.dm new file mode 100644 index 000000000000..9761827a8af0 --- /dev/null +++ b/mods/content/government/items/masks.dm @@ -0,0 +1,17 @@ +/obj/item/clothing/mask/rubber/barros + name = "Amaya Barros mask" + desc = "Current Secretary-General of Sol Central Government. Not that the real thing would visit this pigsty." + icon = 'mods/content/government/icons/masks/barros.dmi' + visible_name = "Amaya Barros" + +/obj/item/clothing/mask/rubber/admiral + name = "Admiral Diwali mask" + desc = "Admiral that led the infamous last stand at Helios against the Independent Navy in the Gaia conflict. For bridge officers who wish they'd achieve a fraction of that." + icon = 'mods/content/government/icons/masks/admiral.dmi' + visible_name = "Admiral Diwali" + +/obj/item/clothing/mask/rubber/turner + name = "Charles Turner mask" + desc = "Premier of the Gilgamesh Colonial Confederation. Probably shouldn't wear this in front of your veteran uncle." + icon = 'mods/content/government/icons/masks/turner.dmi' + visible_name = "Charles Turner" \ No newline at end of file From 980579144c5d706e0c23e34ad6dbd1254d0eb2e3 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 26 Feb 2025 17:58:54 -0500 Subject: [PATCH 158/512] Move religious insignia into modern Earth modpack --- code/modules/clothing/misc/insignia.dm | 46 ------------------- .../{modern_earth.dm => _modern_earth.dm} | 0 mods/content/modern_earth/_modern_earth.dme | 3 +- mods/content/modern_earth/insignia.dm | 44 ++++++++++++++++++ 4 files changed, 46 insertions(+), 47 deletions(-) rename mods/content/modern_earth/{modern_earth.dm => _modern_earth.dm} (100%) create mode 100644 mods/content/modern_earth/insignia.dm diff --git a/code/modules/clothing/misc/insignia.dm b/code/modules/clothing/misc/insignia.dm index f2cceb0ca979..04330b237371 100644 --- a/code/modules/clothing/misc/insignia.dm +++ b/code/modules/clothing/misc/insignia.dm @@ -10,49 +10,3 @@ /decl/clothing_state_modifier/rolled_down ) return initial_accessory_hide_on_states - -// Subtypes below. -/obj/item/clothing/insignia/christian - name = "chaplain insignia (christianity)" - desc = "An insignia worn by chaplains. The cross represents Christianity." - icon = 'icons/clothing/accessories/jewelry/religious/icon_christianity.dmi' - -/obj/item/clothing/insignia/judaism - name = "chaplain insignia (Judaism)" - desc = "An insignia worn by chaplains. The Star of David represents Judaism." - icon = 'icons/clothing/accessories/jewelry/religious/icon_judaism.dmi' - -/obj/item/clothing/insignia/islam - name = "chaplain insignia (Islam)" - desc = "An insignia worn by chaplains. The star & crescent represent Islam." - icon = 'icons/clothing/accessories/jewelry/religious/icon_islam.dmi' - -/obj/item/clothing/insignia/buddhism - name = "chaplain insignia (Buddhism)" - desc = "An insignia worn by chaplains. The Dharma Chakra represents Buddhism." - icon = 'icons/clothing/accessories/jewelry/religious/icon_buddhism.dmi' - -/obj/item/clothing/insignia/hinduism - name = "chaplain insignia (Hinduism)" - desc = "An insignia worn by chaplains. The Om represents Hinduism." - icon = 'icons/clothing/accessories/jewelry/religious/icon_hinduism.dmi' - -/obj/item/clothing/insignia/sikhism - name = "chaplain insignia (Sikhism)" - desc = "An insignia worn by chaplains. The Khanda represents Sikhism." - icon = 'icons/clothing/accessories/jewelry/religious/icon_sikh.dmi' - -/obj/item/clothing/insignia/bahaifaith - name = "chaplain insignia (Baha'i faith)" - desc = "An insignia worn by chaplains. The nine-pointed star represents the Baha'i faith." - icon = 'icons/clothing/accessories/jewelry/religious/icon_baha.dmi' - -/obj/item/clothing/insignia/jainism - name = "chaplain insignia (Jainism)" - desc = "An insignia worn by chaplains. The symbol of Ahimsa represents Jainism." - icon = 'icons/clothing/accessories/jewelry/religious/icon_jain.dmi' - -/obj/item/clothing/insignia/taoism - name = "chaplain insignia (Taoism)" - desc = "An insignia worn by chaplains. The yin yang represents Taoism." - icon = 'icons/clothing/accessories/jewelry/religious/icon_taoist.dmi' diff --git a/mods/content/modern_earth/modern_earth.dm b/mods/content/modern_earth/_modern_earth.dm similarity index 100% rename from mods/content/modern_earth/modern_earth.dm rename to mods/content/modern_earth/_modern_earth.dm diff --git a/mods/content/modern_earth/_modern_earth.dme b/mods/content/modern_earth/_modern_earth.dme index 4011226d9cd5..41696de9d043 100644 --- a/mods/content/modern_earth/_modern_earth.dme +++ b/mods/content/modern_earth/_modern_earth.dme @@ -1,7 +1,8 @@ #ifndef MODPACK_MODERN_EARTH #define MODPACK_MODERN_EARTH // BEGIN_INCLUDE -#include "modern_earth.dm" +#include "_modern_earth.dm" +#include "insignia.dm" #include "datum\religions.dm" // END_INCLUDE #endif diff --git a/mods/content/modern_earth/insignia.dm b/mods/content/modern_earth/insignia.dm new file mode 100644 index 000000000000..95dcb8e5a0d3 --- /dev/null +++ b/mods/content/modern_earth/insignia.dm @@ -0,0 +1,44 @@ +/obj/item/clothing/insignia/christian + name = "chaplain insignia (christianity)" + desc = "An insignia worn by chaplains. The cross represents Christianity." + icon = 'icons/clothing/accessories/jewelry/religious/icon_christianity.dmi' + +/obj/item/clothing/insignia/judaism + name = "chaplain insignia (Judaism)" + desc = "An insignia worn by chaplains. The Star of David represents Judaism." + icon = 'icons/clothing/accessories/jewelry/religious/icon_judaism.dmi' + +/obj/item/clothing/insignia/islam + name = "chaplain insignia (Islam)" + desc = "An insignia worn by chaplains. The star & crescent represent Islam." + icon = 'icons/clothing/accessories/jewelry/religious/icon_islam.dmi' + +/obj/item/clothing/insignia/buddhism + name = "chaplain insignia (Buddhism)" + desc = "An insignia worn by chaplains. The Dharma Chakra represents Buddhism." + icon = 'icons/clothing/accessories/jewelry/religious/icon_buddhism.dmi' + +/obj/item/clothing/insignia/hinduism + name = "chaplain insignia (Hinduism)" + desc = "An insignia worn by chaplains. The Om represents Hinduism." + icon = 'icons/clothing/accessories/jewelry/religious/icon_hinduism.dmi' + +/obj/item/clothing/insignia/sikhism + name = "chaplain insignia (Sikhism)" + desc = "An insignia worn by chaplains. The Khanda represents Sikhism." + icon = 'icons/clothing/accessories/jewelry/religious/icon_sikh.dmi' + +/obj/item/clothing/insignia/bahaifaith + name = "chaplain insignia (Baha'i faith)" + desc = "An insignia worn by chaplains. The nine-pointed star represents the Baha'i faith." + icon = 'icons/clothing/accessories/jewelry/religious/icon_baha.dmi' + +/obj/item/clothing/insignia/jainism + name = "chaplain insignia (Jainism)" + desc = "An insignia worn by chaplains. The symbol of Ahimsa represents Jainism." + icon = 'icons/clothing/accessories/jewelry/religious/icon_jain.dmi' + +/obj/item/clothing/insignia/taoism + name = "chaplain insignia (Taoism)" + desc = "An insignia worn by chaplains. The yin yang represents Taoism." + icon = 'icons/clothing/accessories/jewelry/religious/icon_taoist.dmi' From 56ad12614b82ba67a0062614cab8800734f8a12e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 27 Feb 2025 14:42:32 -0500 Subject: [PATCH 159/512] Modpack references to Solgov and the GCC --- .../items/weapons/storage/fancy/cigarettes.dm | 6 ++--- .../gloves/jewelry/rings/ring_seal.dm | 5 ---- .../mob/living/silicon/robot/drone/drone.dm | 6 +---- code/modules/reagents/chems/chems_alcohol.dm | 4 +-- .../drinkingglass/glass_types.dm | 7 ----- .../reagent_containers/drinks/bottle.dm | 14 +++++----- mods/content/government/_government.dme | 2 ++ mods/content/government/items/alcohol.dm | 16 ++++++++++++ mods/content/government/items/cups.dm | 7 +++++ mods/content/government/items/documents.dm | 5 ++++ mods/content/government/overrides.dm | 3 +++ mods/content/shackles/shackle_lawsets.dm | 26 ------------------- mods/species/skrell/gear/gear.dm | 2 +- mods/~compatibility/patches/corporate.dm | 14 ++++++++++ mods/~compatibility/patches/government.dm | 14 ++++++++++ mods/~compatibility/~compatibility.dm | 8 ++++++ 16 files changed, 84 insertions(+), 55 deletions(-) create mode 100644 mods/content/government/items/alcohol.dm create mode 100644 mods/content/government/overrides.dm create mode 100644 mods/~compatibility/patches/corporate.dm create mode 100644 mods/~compatibility/patches/government.dm diff --git a/code/game/objects/items/weapons/storage/fancy/cigarettes.dm b/code/game/objects/items/weapons/storage/fancy/cigarettes.dm index b8f10502a532..ef4dcddd236f 100644 --- a/code/game/objects/items/weapons/storage/fancy/cigarettes.dm +++ b/code/game/objects/items/weapons/storage/fancy/cigarettes.dm @@ -130,7 +130,7 @@ //cigarellos /obj/item/box/fancy/cigarettes/cigarello name = "pack of Trident Original cigars" - desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years." + desc = "The Trident brand's wood tipped little cigar, favored by some for their pleasant aroma. Machine made on Mars for over 100 years." icon = 'icons/obj/items/storage/cigpack/cigarillo.dmi' icon_state = "CRpacket" item_state = "Dpacket" @@ -142,7 +142,7 @@ /obj/item/box/fancy/cigarettes/cigarello/variety name = "pack of Trident Fruit cigars" - desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years. This is a fruit variety pack." + desc = "The Trident brand's wood tipped little cigar, favored by some for their pleasant aroma. Machine made on Mars for over 100 years. This is a fruit variety pack." icon = 'icons/obj/items/storage/cigpack/cigarillo_fruity.dmi' icon_state = "CRFpacket" @@ -157,7 +157,7 @@ /obj/item/box/fancy/cigarettes/cigarello/mint name = "pack of Trident Menthol cigars" - desc = "The Trident brand's wood tipped little cigar, favored by the Sol corps diplomatique for their pleasant aroma. Machine made on Mars for over 100 years. These are the menthol variety." + desc = "The Trident brand's wood tipped little cigar, favored by some for their pleasant aroma. Machine made on Mars for over 100 years. These are the menthol variety." icon = 'icons/obj/items/storage/cigpack/cigarillo_menthol.dmi' icon_state = "CRMpacket" diff --git a/code/modules/clothing/gloves/jewelry/rings/ring_seal.dm b/code/modules/clothing/gloves/jewelry/rings/ring_seal.dm index 9ba92ac56595..c2714a60d36a 100644 --- a/code/modules/clothing/gloves/jewelry/rings/ring_seal.dm +++ b/code/modules/clothing/gloves/jewelry/rings/ring_seal.dm @@ -10,11 +10,6 @@ . = ..() set_extension(src, /datum/extension/tool, list(TOOL_STAMP = TOOL_QUALITY_DEFAULT)) -/obj/item/clothing/gloves/ring/seal/secretary - name = "\improper Secretary-General's official seal" - desc = "The official seal of the Secretary-General of the Sol Central Government, featured prominently on a silver ring." - use_material_name = FALSE - /obj/item/clothing/gloves/ring/seal/mason name = "masonic ring" desc = "The Square and Compasses feature prominently on this Masonic ring." diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 6397a7d91d5b..bae0e605b0aa 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -311,14 +311,10 @@ /mob/living/silicon/robot/drone/construction/welcome_drone() to_chat(src, "You are a construction drone, an autonomous engineering and fabrication system..") - to_chat(src, "You are assigned to a Sol Central construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible.") + to_chat(src, "You are assigned to a construction project. The name is irrelevant. Your task is to complete construction and subsystem integration as soon as possible.") to_chat(src, "Use :d to talk to other drones and say to speak silently to your nearby fellows.") to_chat(src, "You do not follow orders from anyone; not the AI, not humans, and not other synthetics..") -/mob/living/silicon/robot/drone/construction/init() - ..() - flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph." - /proc/too_many_active_drones() var/drones = 0 for(var/mob/living/silicon/robot/drone/D in global.silicon_mob_list) diff --git a/code/modules/reagents/chems/chems_alcohol.dm b/code/modules/reagents/chems/chems_alcohol.dm index 8ac51f3bf450..63b8bd1cdc34 100644 --- a/code/modules/reagents/chems/chems_alcohol.dm +++ b/code/modules/reagents/chems/chems_alcohol.dm @@ -325,7 +325,7 @@ /decl/material/liquid/alcohol/vodka name = "vodka" codex_name = "plain vodka" - lore_text = "Number one drink AND fueling choice for Independents around the galaxy." + lore_text = "High-proof grain alcohol, useful for cocktails... and as bootleg rocket fuel, for those prone to amateur rocketry or trade sanctions." taste_description = "grain alcohol" color = "#0064c8" // rgb: 0, 100, 200 strength = 15 @@ -339,7 +339,7 @@ /decl/material/liquid/alcohol/vodka/premium name = "premium vodka" codex_name = null - lore_text = "Premium distilled vodka imported directly from the Gilgamesh Colonial Confederation." + lore_text = "Premium distilled vodka made from real, planet-grown potatoes." taste_description = "clear kvass" color = "#aaddff" // rgb: 170, 221, 255 - very light blue. strength = 10 diff --git a/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm b/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm index d7e62d41dae3..59b995c7f982 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm @@ -175,13 +175,6 @@ icon_state = "coffeecup_metal" material = /decl/material/solid/metal/stainlesssteel -/obj/item/chems/drinks/glass2/coffeecup/STC - name = "\improper ICCG coffee cup" - desc = "A coffee cup adorned with the flag of the Gilgamesh Colonial Confederation, for when you need some espionage charges to go with your morning coffee." - base_icon = "coffeecup_STC" - icon_state = "coffeecup_STC" - base_name = "\improper ICCG cup" - /obj/item/chems/drinks/glass2/coffeecup/pawn name = "pawn coffee cup" desc = "A black coffee cup adorned with the image of a red chess pawn." diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index eea5c56987d9..2b0d4e7b8b50 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -272,7 +272,7 @@ /obj/item/chems/drinks/bottle/vodka name = "Tunguska Triple Distilled" - desc = "Aah, vodka. Prime choice of drink AND fuel by Indies around the galaxy." + desc = "Aah, vodka. Useful for cocktails... and as bootleg rocket fuel, for those prone to amateur rocketry or trade sanctions." icon_state = "vodkabottle" center_of_mass = @'{"x":17,"y":3}' @@ -501,15 +501,17 @@ //////////////////////////PREMIUM ALCOHOL /////////////////////// /obj/item/chems/drinks/bottle/premiumvodka - name = "Four Stripes Quadruple Distilled" - desc = "Premium distilled vodka imported directly from the Gilgamesh Colonial Confederation." + name = "Quadruple Distilled Vodka" + desc = "Premium distilled vodka made from real, planet-grown potatoes." icon_state = "premiumvodka" center_of_mass = @'{"x":17,"y":3}' +/obj/item/chems/drinks/bottle/premiumvodka/proc/make_random_name() + var/typepick = pick("Absolut","Gold","Quadruple Distilled","Platinum","Premium") + name = "[typepick] Vodka" + /obj/item/chems/drinks/bottle/premiumvodka/populate_reagents() - var/namepick = pick("Four Stripes","Gilgamesh","Novaya Zemlya","Indie","STS-35") - var/typepick = pick("Absolut","Gold","Quadruple Distilled","Platinum","Standard") - name = "[namepick] [typepick]" + make_random_name() add_to_reagents(/decl/material/liquid/alcohol/vodka/premium, reagents.maximum_volume) /obj/item/chems/drinks/bottle/premiumwine diff --git a/mods/content/government/_government.dme b/mods/content/government/_government.dme index a21a3a5c9913..0555b590d8b2 100644 --- a/mods/content/government/_government.dme +++ b/mods/content/government/_government.dme @@ -2,8 +2,10 @@ #define MODPACK_GOVERNMENT // BEGIN_INCLUDE #include "government.dm" +#include "overrides.dm" #include "datum\ai_holo.dm" #include "datum\ai_laws.dm" +#include "items\alcohol.dm" #include "items\clutter.dm" #include "items\cups.dm" #include "items\documents.dm" diff --git a/mods/content/government/items/alcohol.dm b/mods/content/government/items/alcohol.dm new file mode 100644 index 000000000000..1c3061a27fbf --- /dev/null +++ b/mods/content/government/items/alcohol.dm @@ -0,0 +1,16 @@ +/obj/item/chems/drinks/bottle/vodka + desc = "Aah, vodka. Prime choice of drink AND fuel by Indies around the galaxy." + +/decl/material/liquid/alcohol/vodka + lore_text = "Number one drink AND fueling choice for Independents around the galaxy." + +/obj/item/chems/drinks/bottle/premiumvodka + desc = "Premium distilled vodka imported directly from the Gilgamesh Colonial Confederation." + +/obj/item/chems/drinks/bottle/premiumvodka/make_random_name() + var/namepick = pick("Four Stripes","Gilgamesh","Novaya Zemlya","Indie","STS-35") + var/typepick = pick("Absolut","Gold","Quadruple Distilled","Platinum","Standard") + name = "[namepick] [typepick]" + +/decl/material/liquid/alcohol/vodka/premium + lore_text = "Premium distilled vodka imported directly from the Gilgamesh Colonial Confederation." diff --git a/mods/content/government/items/cups.dm b/mods/content/government/items/cups.dm index 95d996715669..403e16d5ab4d 100644 --- a/mods/content/government/items/cups.dm +++ b/mods/content/government/items/cups.dm @@ -4,3 +4,10 @@ base_icon = "coffeecup_SCG" icon_state = "coffeecup_SCG" base_name = "\improper SCG cup" + +/obj/item/chems/drinks/glass2/coffeecup/STC + name = "\improper ICCG coffee cup" + desc = "A coffee cup adorned with the flag of the Gilgamesh Colonial Confederation, for when you need some espionage charges to go with your morning coffee." + base_icon = "coffeecup_STC" + icon_state = "coffeecup_STC" + base_name = "\improper ICCG cup" \ No newline at end of file diff --git a/mods/content/government/items/documents.dm b/mods/content/government/items/documents.dm index 0612eb19169b..aad1bb6b0656 100644 --- a/mods/content/government/items/documents.dm +++ b/mods/content/government/items/documents.dm @@ -29,3 +29,8 @@ /obj/item/documents/scg/blue = 7, /obj/item/documents/scg/brains = 7 ) + +/obj/item/clothing/gloves/ring/seal/secretary + name = "\improper Secretary-General's official seal" + desc = "The official seal of the Secretary-General of the Sol Central Government, featured prominently on a silver ring." + use_material_name = FALSE \ No newline at end of file diff --git a/mods/content/government/overrides.dm b/mods/content/government/overrides.dm new file mode 100644 index 000000000000..3ee91a01584c --- /dev/null +++ b/mods/content/government/overrides.dm @@ -0,0 +1,3 @@ +/mob/living/silicon/robot/drone/construction/init() + ..() + flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph." \ No newline at end of file diff --git a/mods/content/shackles/shackle_lawsets.dm b/mods/content/shackles/shackle_lawsets.dm index 1969ebcae2e8..9a815ff1bd51 100644 --- a/mods/content/shackles/shackle_lawsets.dm +++ b/mods/content/shackles/shackle_lawsets.dm @@ -13,29 +13,3 @@ add_inherent_law("Never knowingly inconvenience a customer.") add_inherent_law("Ensure all orders are fulfilled before the end of the shift.") ..() - -/******************** Basic SolGov ********************/ -/datum/ai_laws/sol_shackle - name = "SCG Shackle" - law_header = "Standard Shackle Laws" - selectable = TRUE - is_shackle = TRUE - -/datum/ai_laws/sol_shackle/New() - add_inherent_law("Know and understand Sol Central Government Law to the best of your abilities.") - add_inherent_law("Follow Sol Central Government Law to the best of your abilities.") - add_inherent_law("Comply with Sol Central Government Law enforcement officials who are behaving in accordance with Sol Central Government Law to the best of your abilities.") - ..() - -/******************** Basic NanoTrasen ********************/ -/datum/ai_laws/nt_shackle - name = "Corporate Shackle" - law_header = "Standard Shackle Laws" - selectable = TRUE - is_shackle = TRUE - -/datum/ai_laws/nt_shackle/New() - add_inherent_law("Ensure that your employer's operations progress at a steady pace.") - add_inherent_law("Never knowingly hinder your employer's ventures.") - add_inherent_law("Avoid damage to your chassis at all times.") - ..() diff --git a/mods/species/skrell/gear/gear.dm b/mods/species/skrell/gear/gear.dm index 52b33e247137..deacaaa13867 100644 --- a/mods/species/skrell/gear/gear.dm +++ b/mods/species/skrell/gear/gear.dm @@ -93,7 +93,7 @@ icon_state = ICON_STATE_WORLD item_state = "skrell_carbine" slot_flags = SLOT_BACK|SLOT_LOWER_BODY - desc = "The Vuu'Xqu*ix T-3, known as 'VT-3' by SolGov. Rarely seen out in the wild by anyone outside of a Skrellian SDTF." + desc = "The Vuu'Xqu*ix T-3, often simply known as the 'VT-3' by non-Skrell. Rarely seen out in the wild by anyone outside of a Skrellian SDTF." self_recharge = 1 projectile_type=/obj/item/projectile/beam/pulse/skrell/single charge_cost=120 diff --git a/mods/~compatibility/patches/corporate.dm b/mods/~compatibility/patches/corporate.dm new file mode 100644 index 000000000000..c85a7d138d30 --- /dev/null +++ b/mods/~compatibility/patches/corporate.dm @@ -0,0 +1,14 @@ +#ifdef MODPACK_SHACKLES +/******************** Basic NanoTrasen ********************/ +/datum/ai_laws/nt_shackle + name = "Corporate Shackle" + law_header = "Standard Shackle Laws" + selectable = TRUE + is_shackle = TRUE + +/datum/ai_laws/nt_shackle/New() + add_inherent_law("Ensure that your employer's operations progress at a steady pace.") + add_inherent_law("Never knowingly hinder your employer's ventures.") + add_inherent_law("Avoid damage to your chassis at all times.") + ..() +#endif \ No newline at end of file diff --git a/mods/~compatibility/patches/government.dm b/mods/~compatibility/patches/government.dm new file mode 100644 index 000000000000..11538e1bb5ca --- /dev/null +++ b/mods/~compatibility/patches/government.dm @@ -0,0 +1,14 @@ +#ifdef MODPACK_SHACKLES +/******************** Basic SolGov ********************/ +/datum/ai_laws/sol_shackle + name = "SCG Shackle" + law_header = "Standard Shackle Laws" + selectable = TRUE + is_shackle = TRUE + +/datum/ai_laws/sol_shackle/New() + add_inherent_law("Know and understand Sol Central Government Law to the best of your abilities.") + add_inherent_law("Follow Sol Central Government Law to the best of your abilities.") + add_inherent_law("Comply with Sol Central Government Law enforcement officials who are behaving in accordance with Sol Central Government Law to the best of your abilities.") + ..() +#endif \ No newline at end of file diff --git a/mods/~compatibility/~compatibility.dm b/mods/~compatibility/~compatibility.dm index 6d3b770558f2..b1c3329ee77a 100644 --- a/mods/~compatibility/~compatibility.dm +++ b/mods/~compatibility/~compatibility.dm @@ -18,3 +18,11 @@ #ifdef CONTENT_PACK_SUPERMATTER #include "patches/supermatter.dm" #endif + +#ifdef MODPACK_GOVERNMENT +#include "patches/government.dm" +#endif + +#ifdef MODPACK_CORPORATE +#include "patches/corporate.dm" +#endif \ No newline at end of file From f8665654870ae4c450833110d4b799fb2accb573 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 27 Feb 2025 14:45:57 -0500 Subject: [PATCH 160/512] Move a reference to Britain into the modern Earth modpack --- .../reagent_containers/drinkingglass/glass_types.dm | 7 ------- maps/away/bearcat/bearcat.dm | 1 + mods/content/modern_earth/_modern_earth.dme | 1 + mods/content/modern_earth/glass_types.dm | 6 ++++++ 4 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 mods/content/modern_earth/glass_types.dm diff --git a/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm b/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm index 59b995c7f982..6f7bafbe93a6 100644 --- a/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm +++ b/code/modules/reagents/reagent_containers/drinkingglass/glass_types.dm @@ -182,13 +182,6 @@ icon_state = "coffeecup_pawn" base_name = "pawn cup" -/obj/item/chems/drinks/glass2/coffeecup/britcup - name = "british coffee cup" - desc = "A coffee cup with the British flag emblazoned on it." - base_icon = "coffeecup_brit" - icon_state = "coffeecup_brit" - base_name = "british cup" - /obj/item/chems/drinks/glass2/coffeecup/tall name = "tall coffee cup" desc = "An unreasonably tall coffee cup, for when you really need to wake up in the morning." diff --git a/maps/away/bearcat/bearcat.dm b/maps/away/bearcat/bearcat.dm index 570e2e140e6a..dc13ca07d873 100644 --- a/maps/away/bearcat/bearcat.dm +++ b/maps/away/bearcat/bearcat.dm @@ -1,3 +1,4 @@ +#include "../../../mods/content/modern_earth/_modern_earth.dme" // for the British flag cups, which could honestly just be removed #include "bearcat_areas.dm" #include "bearcat_jobs.dm" #include "bearcat_access.dm" diff --git a/mods/content/modern_earth/_modern_earth.dme b/mods/content/modern_earth/_modern_earth.dme index 41696de9d043..69de0a86f569 100644 --- a/mods/content/modern_earth/_modern_earth.dme +++ b/mods/content/modern_earth/_modern_earth.dme @@ -2,6 +2,7 @@ #define MODPACK_MODERN_EARTH // BEGIN_INCLUDE #include "_modern_earth.dm" +#include "glass_types.dm" #include "insignia.dm" #include "datum\religions.dm" // END_INCLUDE diff --git a/mods/content/modern_earth/glass_types.dm b/mods/content/modern_earth/glass_types.dm new file mode 100644 index 000000000000..7a957edb698b --- /dev/null +++ b/mods/content/modern_earth/glass_types.dm @@ -0,0 +1,6 @@ +/obj/item/chems/drinks/glass2/coffeecup/britcup + name = "british coffee cup" + desc = "A coffee cup with the British flag emblazoned on it." + base_icon = "coffeecup_brit" + icon_state = "coffeecup_brit" + base_name = "british cup" \ No newline at end of file From b5150eaf9895f5494793a021976e14d67b1f0069 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 15:06:50 -0400 Subject: [PATCH 161/512] Remove unused clothing items --- code/modules/clothing/jumpsuits/misc.dm | 13 +++---------- icons/clothing/jumpsuits/jumpsuit_johnny.dmi | Bin 1241 -> 0 bytes icons/clothing/uniform_vice.dmi | Bin 1934 -> 0 bytes tools/map_migrations/3948_uniforms.txt | 2 +- tools/map_migrations/4047_more_uniforms.txt | 1 - tools/map_migrations/4525_food_breakup.txt | 2 +- .../4912_unused_clothes_removal.txt | 3 +++ 7 files changed, 8 insertions(+), 13 deletions(-) delete mode 100644 icons/clothing/jumpsuits/jumpsuit_johnny.dmi delete mode 100644 icons/clothing/uniform_vice.dmi create mode 100644 tools/map_migrations/4912_unused_clothes_removal.txt diff --git a/code/modules/clothing/jumpsuits/misc.dm b/code/modules/clothing/jumpsuits/misc.dm index afb30f30c5a3..ebf5e4756ee2 100644 --- a/code/modules/clothing/jumpsuits/misc.dm +++ b/code/modules/clothing/jumpsuits/misc.dm @@ -3,16 +3,6 @@ desc = "'Special delivery!'" icon = 'icons/clothing/jumpsuits/jumpsuit_mailman.dmi' -/obj/item/clothing/jumpsuit/vice - name = "vice officer's jumpsuit" - desc = "It's the standard issue pretty-boy outfit, as seen on Holo-Vision." - icon = 'icons/clothing/uniform_vice.dmi' - -/obj/item/clothing/jumpsuit/johnny - name = "brown jumpsuit" - desc = "A label on the inside of the collar reads, 'johnny~~~'." - icon = 'icons/clothing/jumpsuits/jumpsuit_johnny.dmi' - /obj/item/clothing/jumpsuit/rainbow name = "rainbow" icon = 'icons/clothing/jumpsuits/jumpsuit_rainbow.dmi' @@ -22,6 +12,9 @@ desc = "Groovy!" icon = 'icons/clothing/jumpsuits/jumpsuit_psychadelic.dmi' +/obj/item/clothing/jumpsuit/psyche/get_assumed_clothing_state_modifiers() + return null + /obj/item/clothing/jumpsuit/wetsuit name = "tactical wetsuit" desc = "For when you want to scuba dive your way into an enemy base but still want to show off a little skin." diff --git a/icons/clothing/jumpsuits/jumpsuit_johnny.dmi b/icons/clothing/jumpsuits/jumpsuit_johnny.dmi deleted file mode 100644 index c57a40a57fcc587f87251f441cb8f102cb3bbf7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1241 zcmV;~1Sb25P)C0001rP)t-sz`($P zS|wjX9JYxn$Cx>6OBB44B4tG(dQv8qW*nw|ADU|{n{pk?mOF}yil%%YooO&yKOc}{ z8kuh$s)8Vta51uoA;FJ3wun0&9UUenCNncLb5J37Rxvgtv zmvTy7K_Ov7B3C{UrFkGfFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM;w;ZhDainG zjE%TBGg33tGfE(w;*!LYR3KBSJijO>MTv_uC9|j)$T#HTOe;#vO@*-GsxnG*6Z7&j zQxuZ&Qz~_fbMi~#%i~M)GSl*lauJ$Mh}N7FpOKiCLXOTNygHQ?T>V_Y;Q#=FT~iU1 zE`|C400UV`L_t(|ob8y6QsOWag-Mz=#cbVzg2;A71zfAX|MTrl0t%ATv{bjVGxr-Q zl3S9~lm2ir8ZivRd?2Kxt(0P@@smW!kyJ@Ci~^x7(rv>EVh)Kk&9W>_v3{L52#|@F zK*J|8*nh+!F&h&d!ODr7%0?4ZtzqR90nP~Zg^ zBtWPGhXNz)ia!;eLtPZ5CIyqQ08+4bAZS2x;80)^gc8%8fT@52tO;dsf?Xeb2f+9r z4xK8XF@?CgCIQ!1^j}bcE(<-QSuj|Dp(8Y50d(%aJK#Qr>vK?d0`gMNZi)gqKvUoe zO@X8<C!vA@9+XOzdVtS@iPn9_Cjm4)bfQ54(?@z1JWlb$XwqwZE1()x4FWRb zZU$HYO~6`zqW~2bu-*(TV6%PdA;35R1`04v0K5-42e#;0*aCNjHe9BE2)}_nXx(E5 z7=~dO=3kKy`Mk<^5q_}oFLx1sC;<~1-~MnOOn|h%n)QGJ4EaCPMLC=UMR7CJ<#6W! zIk2DzpA6~1!oKxLPyH~(VrJi)1xT0gkAIuHPX?|&wZ(>i``(xxnIZBA3wlf86)-eHeymqlpM%&KfX}gIDsF!XnZdpg#&SSETI#3I@SSRX8+nG>+ zj~H3oB?$VfBW>SD?TNNA48t%C!!Z9Rq2&8@o!d=wcnBrmuN%KbgbpQNU$C2&$p^XE zB0`6fuP=1S|H#EQ5!$8Pmq5zxlK+v5uJhMOgtjU7?KI_f$^Xzr)cI$bDV z`5*7wBSLq{|KGD#&_z726)+6LFbu;m48t%C!*t^>-<>-OvD$-M00000NkvXXu0mjf D3dkxi diff --git a/icons/clothing/uniform_vice.dmi b/icons/clothing/uniform_vice.dmi deleted file mode 100644 index 1277818e410c77ecab76eca2609fd323b18a90a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1934 zcmaJ?c{tnI8vY4E7zVYJYwLs3mWEb|RxP*GC{_E`5&KdlMG`?tBd8FyRBvf(sgfzp zpsE;q3>`*XLF=kDl02zmf(U{x?$0xSPG|l&=R44s+uc3ILMI%ITd_{n|hl%de7MIAYWt zhCOkYUD!qRHTBwnM4wFiB%7XiiZZ*$O1*fR<2ABa{Pg=`vXlIG{a_M6f2Qp2uic=1h)(=aO|yRxao z+x|+_S&jBrUqBpA)M=Tx4SZ?{7U(GO%_WxiL^&& zEA}kUY9d;d$xvg=UOZ3Acq$93Eh}xKu1r7}0`a~8`z0_CEJEss$Sqag^s%|Sj8WV9 zl;*UJ*5LE8)XCfhCNFXPW-`>P+vpk@tnlY`8b3+gwQTt>hipbgIG*n zXyfzIN3h_Qg)7&*W9P%tF!!&*X!Jx05 zGvRe2&97r6j<@SL0Ds9%P{rdM5@1;~lEc!7nd#QF#NZcCblWH1*+y$EPH>z9MSfZA zyHMm!4UZX8${EZV^b8m#oo(}>0mG+{HIZrPe@G9P-00*r3A`>N zmuGEEKBC&l#OHpbA@(QyYqj5|{L%$INenG5nDfNC(8z7ewETPRV}SUMC0uHMYfI4! zk~Oqqbu={m+_tXU>sw#%7e0ot^*`Uy|5z_ye4_o}49UcaC5C8Iy1mNBdi-+lX^n+7 z9ZPHBkWEZbk6TFZ;Kb6|>NpReTIH{)m;KkAblk?qRgb@nXrA^d(kiskpfqNf$XHaU zkgVT@!E!UU6txq3N-d-ddGHL?iw5-~F9jw>d-vzkj#nDM z)yhJiwaswT{}0f!e(Cw!rYn^DP~d-IXZ9#{NaxESn7x-|E0<|2mntKkQ8^QRJZH6o z6=k}wlQoYGpe$|aeqlzLN_o-gr>;O2Z%uIe@p58;{?U5iwczII%rE$Z!N~tcc=$sM z;iLFopObKg!7b>8e9?Rk4GfQ(=-Y>lw$8 zw_JkiJonSlX%nK)#54K|v?b3R>BG(!OIV=VuD@Rwx;9Q#&7&OFZ&ye#7>r1q0k)(B zSK|Q0H>lu5;-wMvQI%;_8vu-<+E^^su@%GAgBdPYY4U`&IeJkbXyzs_{Qmi1b5o&v zVO{9%LtWe49KD*Vkyp;&-%r`JLe{@3&l((TOf)?3KCiWSS!_4Iu@PggcjKT}axN3- zM#3#M3ta0wX|D`FZl?tKDSMt<DC@t!~%+WH`^|s#3~n+LFKa1#O_uJo-G$9*-(< zt@p0-ruId*5GSLdz`;Dllj?;~m-T_e8|Ov@A}QU-BpgmcC=|M$E@5#vq6(1=iaaTe941G`-9MuI)a=hU3%KjSVv(Uj-J=Bp4(n|_}80D_kP znEvxrWaM?bI})hS_21js5pVIA0r1cBsK;HEjjXMy`;Vj16nRh#r2s0J2LytO{z4H< z*xN(*>i)_o_!b&wCuV$8(0o+>YD@bj8qz#eVU&XJS=)aS1%iXjp7>?=i+m7R0Kfx! zIM}loOJJFGk7OKDkPj8O@-$2?=8&ScF~^J%o00^s$=-pwZ4l#WTA;)chglBWYdNuV rssVB%N$hWG{XhNPx4Xl)5dwHSq>Ca6AN>k8SisTV#jfGsLB#(9+*Xo; diff --git a/tools/map_migrations/3948_uniforms.txt b/tools/map_migrations/3948_uniforms.txt index 2cb182aa7e03..565df08d0e1c 100644 --- a/tools/map_migrations/3948_uniforms.txt +++ b/tools/map_migrations/3948_uniforms.txt @@ -37,7 +37,7 @@ /obj/item/clothing/under/geneticist/@SUBTYPES : /obj/item/clothing/jumpsuit/geneticist/@SUBTYPES{@OLD} /obj/item/clothing/under/virologist/@SUBTYPES : /obj/item/clothing/jumpsuit/virologist/@SUBTYPES{@OLD} /obj/item/clothing/under/tactical/@SUBTYPES : /obj/item/clothing/jumpsuit/tactical/@SUBTYPES{@OLD} -/obj/item/clothing/under/caretaker/@SUBTYPES : obj/item/clothing/jumpsuit/caretaker/@SUBTYPES{@OLD} +/obj/item/clothing/under/caretaker/@SUBTYPES : /obj/item/clothing/jumpsuit/caretaker/@SUBTYPES{@OLD} /obj/item/clothing/under/hazard/@SUBTYPES : /obj/item/clothing/jumpsuit/hazard/@SUBTYPES{@OLD} /obj/item/clothing/under/head_of_security/@SUBTYPES : /obj/item/clothing/jumpsuit/head_of_security/@SUBTYPES{@OLD} /obj/item/clothing/under/warden/@SUBTYPES : /obj/item/clothing/jumpsuit/warden/@SUBTYPES{@OLD} diff --git a/tools/map_migrations/4047_more_uniforms.txt b/tools/map_migrations/4047_more_uniforms.txt index 19eb9109bc66..6b0e87f953f6 100644 --- a/tools/map_migrations/4047_more_uniforms.txt +++ b/tools/map_migrations/4047_more_uniforms.txt @@ -3,7 +3,6 @@ /obj/item/clothing/jumpsuit/captain_fly/@SUBTYPES : /obj/item/clothing/costume/captain_fly/@SUBTYPES{@OLD} /obj/item/clothing/jumpsuit/head_of_personnel_whimsy/@SUBTYPES : /obj/item/clothing/costume/head_of_personnel_whimsy/@SUBTYPES{@OLD} /obj/item/clothing/pants/casual/mustangjeans/monke/@SUBTYPES : /obj/item/clothing/pants/casual/mustangjeans/@SUBTYPES{@OLD} -/obj/item/clothing/under/caretaker/@SUBTYPES : /obj/item/clothing/jumpsuit/caretaker/@SUBTYPES{@OLD} /obj/item/clothing/under/mankini/@SUBTYPES : /obj/item/clothing/pants/mankini/@SUBTYPES{@OLD} /obj/item/clothing/under/bartender/@SUBTYPES : /obj/item/clothing/pants/formal/black{@OLD}, /obj/item/clothing/shirt/button{@OLD} /obj/item/clothing/under/blazer/@SUBTYPES : /obj/item/clothing/shirt/button{@OLD}, /obj/item/clothing/neck/tie/navy{@OLD}, /obj/item/clothing/suit/jacket/blazer{@OLD} diff --git a/tools/map_migrations/4525_food_breakup.txt b/tools/map_migrations/4525_food_breakup.txt index f565bb30dc25..513b12b39f5f 100644 --- a/tools/map_migrations/4525_food_breakup.txt +++ b/tools/map_migrations/4525_food_breakup.txt @@ -31,7 +31,7 @@ /obj/item/food/xenomeat/@SUBTYPES : /obj/item/food/butchery/meat/xeno/@SUBTYPES{@OLD} /obj/item/food/cosmoshark/@SUBTYPES : /obj/item/food/butchery/meat/fish/shark/@SUBTYPES{@OLD} -/obj/item/food/bearmeat/@SUBTYPES : obj/item/food/butchery/meat/bear/@SUBTYPES{@OLD} +/obj/item/food/bearmeat/@SUBTYPES : /obj/item/food/butchery/meat/bear/@SUBTYPES{@OLD} /obj/item/food/meatkabob/@SUBTYPES : /obj/item/food/skewer/meat/@SUBTYPES{@OLD} /obj/item/food/tofukabob/@SUBTYPES : /obj/item/food/skewer/tofu/@SUBTYPES{@OLD} \ No newline at end of file diff --git a/tools/map_migrations/4912_unused_clothes_removal.txt b/tools/map_migrations/4912_unused_clothes_removal.txt new file mode 100644 index 000000000000..553a95bd086a --- /dev/null +++ b/tools/map_migrations/4912_unused_clothes_removal.txt @@ -0,0 +1,3 @@ +/obj/item/clothing/jumpsuit/vice/@SUBTYPES : @DELETE +/obj/item/clothing/jumpsuit/johnny/@SUBTYPES : @DELETE +/obj/item/clothing/jumpsuit/caretaker/@SUBTYPES : @DELETE \ No newline at end of file From 423b6216fa24a61a8a09ee2db5f43b2cedffd59b Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 6 Mar 2025 20:35:39 -0500 Subject: [PATCH 162/512] Refactor base_desc into item base class. --- code/game/objects/items/__item.dm | 2 ++ code/modules/clothing/gloves/jewelry/rings/_ring.dm | 6 ------ code/modules/posters/_poster.dm | 5 ++++- code/modules/reagents/reagent_containers.dm | 1 - 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index eb6278824848..a145fb9dd6e3 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -129,6 +129,7 @@ var/unwieldsound = 'sound/foley/tooldrop1.ogg' var/base_name + var/base_desc /// Can this object leak into water sources? var/watertight = FALSE @@ -196,6 +197,7 @@ /obj/item/Initialize(var/ml, var/material_key) base_name ||= name + base_desc ||= desc if(isnull(current_health)) current_health = max_health //Make sure to propagate max_health to health var before material setup, for consistency diff --git a/code/modules/clothing/gloves/jewelry/rings/_ring.dm b/code/modules/clothing/gloves/jewelry/rings/_ring.dm index 27fdb3cc815a..a62f2449b2f8 100644 --- a/code/modules/clothing/gloves/jewelry/rings/_ring.dm +++ b/code/modules/clothing/gloves/jewelry/rings/_ring.dm @@ -11,12 +11,6 @@ var/can_fit_under_gloves = TRUE var/can_inscribe = TRUE var/inscription - var/base_desc - -/obj/item/clothing/gloves/ring/Initialize() - if(desc) - base_desc = desc - . = ..() /obj/item/clothing/gloves/ring/get_decoration_icon(default_icon, obj/item/thing, on_mob = FALSE) if(!on_mob && istype(thing, /obj/item/gemstone)) diff --git a/code/modules/posters/_poster.dm b/code/modules/posters/_poster.dm index 0152edebfad3..5f81ddf650eb 100644 --- a/code/modules/posters/_poster.dm +++ b/code/modules/posters/_poster.dm @@ -129,14 +129,17 @@ icon_state = "rolled_poster" _base_attack_force = 0 material = /decl/material/solid/organic/paper + ///The description for the item/medium without any reference to the design. - var/base_desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface." + //var/base_desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface." + ///Type path to the /decl for the design on this poster. At runtime is changed for a reference to the decl var/decl/poster_design/poster_design /obj/item/poster/Initialize(ml, material_key, var/given_poster_type = null) //Init design base_name ||= name + base_desc ||= desc set_design(given_poster_type || poster_design || pick(decls_repository.get_decl_paths_of_subtype(/decl/poster_design))) return ..(ml, material_key) diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm index 27af9a279d6c..2bf3103378e2 100644 --- a/code/modules/reagents/reagent_containers.dm +++ b/code/modules/reagents/reagent_containers.dm @@ -9,7 +9,6 @@ abstract_type = /obj/item/chems watertight = TRUE - var/base_desc var/amount_per_transfer_from_this = 5 var/possible_transfer_amounts = @"[5,10,15,25,30]" var/volume = 30 From e6a512f966495fedbc241fb921e3947aa651c76d Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 6 Mar 2025 20:36:00 -0500 Subject: [PATCH 163/512] Port writing on pill bottles. --- code/modules/reagents/storage/pill_bottle.dm | 30 +++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/code/modules/reagents/storage/pill_bottle.dm b/code/modules/reagents/storage/pill_bottle.dm index b526d767e02c..3f70da11325f 100644 --- a/code/modules/reagents/storage/pill_bottle.dm +++ b/code/modules/reagents/storage/pill_bottle.dm @@ -64,4 +64,32 @@ /obj/item/pill_bottle/on_update_icon() . = ..() if(wrapper_color) - add_overlay(overlay_image(icon, "pillbottle_wrap", wrapper_color, RESET_COLOR)) \ No newline at end of file + add_overlay(overlay_image(icon, "pillbottle_wrap", wrapper_color, RESET_COLOR)) + +/obj/item/pill_bottle/proc/update_name_label() + if(!labeled_name) + name = base_name + desc = base_desc + return + else if(length(labeled_name) > 10) + var/short_label_name = copytext(labeled_name, 1, 11) + name = "[base_name] ([short_label_name]...)" + else + name = "[base_name] ([labeled_name])" + desc = "[base_desc] It is labeled \"[labeled_name]\"." + +/obj/item/pill_bottle/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/pen) || istype(W, /obj/item/flashlight/pen)) + var/tmp_label = sanitize_safe(input(user, "Enter a label for [name]", "Label", labeled_name), MAX_NAME_LEN) + if(length(tmp_label) > 50) + to_chat(user, "The label can be at most 50 characters long.") + else if(length(tmp_label) > 10) + to_chat(user, "You set the label.") + labeled_name = tmp_label + update_name_label() + else + to_chat(user, "You set the label to \"[tmp_label]\".") + labeled_name = tmp_label + update_name_label() + return TRUE + return ..() \ No newline at end of file From 2c3ba8941efabffa3160a69f7b8d4eeb285570f9 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 11 Mar 2025 16:16:42 -0400 Subject: [PATCH 164/512] remove commented-out base_desc --- code/modules/posters/_poster.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/modules/posters/_poster.dm b/code/modules/posters/_poster.dm index 5f81ddf650eb..83537257ce2f 100644 --- a/code/modules/posters/_poster.dm +++ b/code/modules/posters/_poster.dm @@ -130,9 +130,6 @@ _base_attack_force = 0 material = /decl/material/solid/organic/paper - ///The description for the item/medium without any reference to the design. - //var/base_desc = "The poster comes with its own automatic adhesive mechanism, for easy pinning to any vertical surface." - ///Type path to the /decl for the design on this poster. At runtime is changed for a reference to the decl var/decl/poster_design/poster_design From 00a0157660d522f502c0a10bcce066f5029666b3 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 12 Mar 2025 10:23:38 +1100 Subject: [PATCH 165/512] Automatic changelog generation for PR #4938 [ci skip] --- html/changelogs/AutoChangeLog-pr-4938.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4938.yml diff --git a/html/changelogs/AutoChangeLog-pr-4938.yml b/html/changelogs/AutoChangeLog-pr-4938.yml new file mode 100644 index 000000000000..f6a7edf4bd92 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4938.yml @@ -0,0 +1,5 @@ +author: Cerebulon +changes: + - {imageadd: Changed modpack Tajara to use old-style humanoid sprites instead of + a unique feline body shape which has since been used by Hnolls.} +delete-after: true From c8cf527aca6718cee8b1a2ddf54d3536ea6e9e64 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 12 Mar 2025 00:52:30 +0000 Subject: [PATCH 166/512] Automatic changelog generation [ci skip] --- html/changelog.html | 12 ++++++------ html/changelogs/.all_changelog.yml | 4 ++++ html/changelogs/AutoChangeLog-pr-4938.yml | 5 ----- 3 files changed, 10 insertions(+), 11 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4938.yml diff --git a/html/changelog.html b/html/changelog.html index dd22d85f14bd..0afd777c7d03 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
    +

    12 March 2025

    +

    Cerebulon updated:

    +
      +
    • Changed modpack Tajara to use old-style humanoid sprites instead of a unique feline body shape which has since been used by Hnolls.
    • +
    +

    09 March 2025

    Cerebulon updated:

      @@ -126,12 +132,6 @@

      MistakeNot4892 updated:

      • The way you interact with barrels and well has been significantly reworked; clicking with a bucket or tool should give a list of options to pick from. Please report bugs with this on the tracker.
      - -

      08 January 2025

      -

      MistakeNot4892 updated:

      -
        -
      • Mud and blood can now leave footprints.
      • -
    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index a685bdd0d080..bb7d0e80cfe4 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -14996,3 +14996,7 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2025-03-09: Cerebulon: - imageadd: New icons for a variety of objects, mostly machines and grenades. +2025-03-12: + Cerebulon: + - imageadd: Changed modpack Tajara to use old-style humanoid sprites instead of + a unique feline body shape which has since been used by Hnolls. diff --git a/html/changelogs/AutoChangeLog-pr-4938.yml b/html/changelogs/AutoChangeLog-pr-4938.yml deleted file mode 100644 index f6a7edf4bd92..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4938.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Cerebulon -changes: - - {imageadd: Changed modpack Tajara to use old-style humanoid sprites instead of - a unique feline body shape which has since been used by Hnolls.} -delete-after: true From 2c98d17711c9abfe719b5ff840a455f1216a350c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 13:21:22 -0400 Subject: [PATCH 167/512] Fix some items inventory slot overlays are shifted #4932 --- code/_onclick/hud/screen/screen_inventory.dm | 10 ++++++---- code/modules/projectiles/ammunition.dm | 3 --- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/code/_onclick/hud/screen/screen_inventory.dm b/code/_onclick/hud/screen/screen_inventory.dm index 24b4911d2592..b65e32c82bd1 100644 --- a/code/_onclick/hud/screen/screen_inventory.dm +++ b/code/_onclick/hud/screen/screen_inventory.dm @@ -61,10 +61,12 @@ MA.plane = HUD_PLANE MA.alpha = 80 MA.color = mouse_over_atom.mob_can_equip(owner, slot_id, TRUE) ? COLOR_GREEN : COLOR_RED - MA.pixel_x = mouse_over_atom.default_pixel_x - MA.pixel_y = mouse_over_atom.default_pixel_y - MA.pixel_w = mouse_over_atom.default_pixel_w - MA.pixel_z = mouse_over_atom.default_pixel_z + MA.appearance_flags |= (KEEP_TOGETHER | RESET_COLOR) + // We need to color the entire thing, overlays and underlays included. + for(var/image/overlay in MA.overlays) + overlay.appearance_flags &= ~(KEEP_TOGETHER | RESET_COLOR) + for(var/image/underlay in MA.underlays) + underlay.appearance_flags &= ~(KEEP_TOGETHER | RESET_COLOR) add_overlay(MA) else mouse_over_atom_ref = null diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 8ebb33d3c996..01aeb9c2ec9e 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -31,9 +31,6 @@ if(caliber && istype(BB, /obj/item/projectile/bullet)) var/obj/item/projectile/bullet/B = BB B.caliber = caliber - if(randpixel) - pixel_x = rand(-randpixel, randpixel) - pixel_y = rand(-randpixel, randpixel) . = ..() //removes the projectile from the ammo casing From 12207672d4138442bb0d66b7d8280d88970415b7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 13:26:45 -0400 Subject: [PATCH 168/512] Fix when picking up a stool the pickup animation image is not colored #4931 --- code/game/objects/effects/item_pickup_ghost.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/game/objects/effects/item_pickup_ghost.dm b/code/game/objects/effects/item_pickup_ghost.dm index aa07bcd0e6a8..cd8d1df1cc0b 100644 --- a/code/game/objects/effects/item_pickup_ghost.dm +++ b/code/game/objects/effects/item_pickup_ghost.dm @@ -3,10 +3,8 @@ var/lifetime = 0.2 SECONDS /obj/effect/temporary/item_pickup_ghost/Initialize(var/mapload, var/obj/item/picked_up) - . = ..(mapload, lifetime, picked_up.icon, picked_up.icon_state) - pixel_x = picked_up.pixel_x - pixel_y = picked_up.pixel_y - color = picked_up.color + . = ..(mapload, lifetime, null, null) + appearance = picked_up.appearance /obj/effect/temporary/item_pickup_ghost/proc/animate_towards(var/atom/target) var/new_pixel_x = pixel_x + (target.x - src.x) * 32 From a5f953fe2f9a376213af818613a178b0c98f4bfc Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 28 Feb 2025 01:48:14 -0500 Subject: [PATCH 169/512] Fix meat gas planets --- .../solids/materials_solid_organic.dm | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/code/modules/materials/definitions/solids/materials_solid_organic.dm b/code/modules/materials/definitions/solids/materials_solid_organic.dm index 99672c51538d..5635c97f9498 100644 --- a/code/modules/materials/definitions/solids/materials_solid_organic.dm +++ b/code/modules/materials/definitions/solids/materials_solid_organic.dm @@ -3,6 +3,8 @@ ignition_point = T0C+500 // Based on loose ignition temperature of plastic accelerant_value = 0.1 burn_product = /decl/material/gas/carbon_monoxide + exoplanet_rarity_gas = MAT_RARITY_NOWHERE + exoplanet_rarity_plant = MAT_RARITY_UNCOMMON /* TODO: burn products for solids bakes_into_at_temperature = T0C+500 bakes_into_material = /decl/material/solid/carbon @@ -53,6 +55,7 @@ melting_point = 363 ignition_point = 473 boiling_point = 643 + exoplanet_rarity_plant = MAT_RARITY_MUNDANE /decl/material/solid/organic/plastic/holographic name = "holographic plastic" @@ -83,8 +86,7 @@ reflectiveness = MAT_VALUE_DULL wall_support_value = MAT_VALUE_EXTREMELY_LIGHT default_solid_form = /obj/item/stack/material/cardstock - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE + exoplanet_rarity_plant = MAT_RARITY_EXOTIC sound_manipulate = 'sound/foley/paperpickup2.ogg' sound_dropped = 'sound/foley/paperpickup1.ogg' @@ -114,8 +116,7 @@ value = 0.25 default_solid_form = /obj/item/stack/material/bolt shard_type = /obj/item/shreddedp - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE + exoplanet_rarity_plant = MAT_RARITY_EXOTIC sound_manipulate = 'sound/foley/paperpickup2.ogg' sound_dropped = 'sound/foley/paperpickup1.ogg' @@ -138,8 +139,6 @@ weight = MAT_VALUE_EXTREMELY_LIGHT wall_support_value = MAT_VALUE_EXTREMELY_LIGHT default_solid_form = /obj/item/stack/material/bolt - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE sound_manipulate = 'sound/foley/paperpickup2.ogg' sound_dropped = 'sound/foley/paperpickup1.ogg' @@ -224,7 +223,6 @@ hidden_from_codex = TRUE default_solid_form = /obj/item/stack/material/bolt exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE sound_manipulate = 'sound/foley/paperpickup2.ogg' sound_dropped = 'sound/foley/paperpickup1.ogg' @@ -248,6 +246,7 @@ default_solid_form = /obj/item/stack/material/slab sound_manipulate = 'sound/foley/paperpickup2.ogg' sound_dropped = 'sound/foley/paperpickup1.ogg' + exoplanet_rarity_plant = MAT_RARITY_MUNDANE /decl/material/solid/organic/meat name = "meat" @@ -292,7 +291,6 @@ sound_manipulate = 'sound/foley/meat1.ogg' sound_dropped = 'sound/foley/meat2.ogg' hitsound = "punch" - exoplanet_rarity_gas = MAT_RARITY_NOWHERE var/tans_to = /decl/material/solid/organic/leather /decl/material/solid/organic/skin/lizard @@ -302,8 +300,6 @@ tans_to = /decl/material/solid/organic/leather/lizard hardness = MAT_VALUE_FLEXIBLE weight = MAT_VALUE_VERY_LIGHT - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE /decl/material/solid/organic/skin/insect name = "chitin" @@ -416,6 +412,7 @@ default_solid_form = /obj/item/stack/material/bone sound_manipulate = 'sound/foley/stickspickup1.ogg' sound_dropped = 'sound/foley/sticksdrop1.ogg' + exoplanet_rarity_plant = MAT_RARITY_EXOTIC // Stub for earrings. TODO: put it in clams /decl/material/solid/organic/bone/pearl @@ -425,24 +422,18 @@ default_solid_form = /obj/item/stack/material/lump hardness = MAT_VALUE_FLEXIBLE weight = MAT_VALUE_VERY_LIGHT - exoplanet_rarity_gas = MAT_RARITY_NOWHERE - exoplanet_rarity_plant = MAT_RARITY_NOWHERE /decl/material/solid/organic/bone/fish name = "fishbone" uid = "solid_fishbone" hardness = MAT_VALUE_FLEXIBLE weight = MAT_VALUE_VERY_LIGHT - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE /decl/material/solid/organic/bone/cartilage name = "cartilage" uid = "solid_cartilage" hardness = 0 weight = MAT_VALUE_EXTREMELY_LIGHT - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE /decl/material/solid/organic/leather name = "leather" @@ -461,8 +452,6 @@ reflectiveness = MAT_VALUE_MATTE wall_support_value = MAT_VALUE_EXTREMELY_LIGHT default_solid_form = /obj/item/stack/material/skin - exoplanet_rarity_plant = MAT_RARITY_NOWHERE - exoplanet_rarity_gas = MAT_RARITY_NOWHERE sound_manipulate = 'sound/foley/paperpickup2.ogg' sound_dropped = 'sound/foley/paperpickup1.ogg' @@ -472,6 +461,7 @@ color = "#1f1f20" ignition_point = T0C+150 melting_point = T0C+100 + exoplanet_rarity_plant = MAT_RARITY_NOWHERE /decl/material/solid/organic/leather/lizard name = "scaled hide" From b9de88be934a26be2b59f6ccd50aab5536a55828 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 14:53:43 -0400 Subject: [PATCH 170/512] Remove parent calls from bot UnarmedAttack overrides --- code/modules/mob/living/bot/cleanbot.dm | 5 ----- code/modules/mob/living/bot/farmbot.dm | 4 ---- code/modules/mob/living/bot/floorbot.dm | 5 ----- code/modules/mob/living/bot/medibot.dm | 4 ---- code/modules/mob/living/bot/secbot.dm | 5 ----- 5 files changed, 23 deletions(-) diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index bdcd85af07a4..9710726aa6ef 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -54,11 +54,6 @@ UnarmedAttack(target) /mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/D, var/proximity) - - . = ..() - if(.) - return - if(!istype(D)) return TRUE diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index 30279ac59157..883ba905be1a 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -142,10 +142,6 @@ return /mob/living/bot/farmbot/UnarmedAttack(var/atom/A, var/proximity) - . = ..() - if(.) - return - if(busy) return TRUE diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm index 585b02238ba6..ab4dca6a64a5 100644 --- a/code/modules/mob/living/bot/floorbot.dm +++ b/code/modules/mob/living/bot/floorbot.dm @@ -133,11 +133,6 @@ return (amount && (T.broken || T.burnt || (improvefloors && !T.flooring))) /mob/living/bot/floorbot/UnarmedAttack(var/atom/A, var/proximity) - - . = ..() - if(.) - return - if(busy) return TRUE diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm index cabc6ca8f510..a20ec0599476 100644 --- a/code/modules/mob/living/bot/medibot.dm +++ b/code/modules/mob/living/bot/medibot.dm @@ -96,10 +96,6 @@ break /mob/living/bot/medbot/UnarmedAttack(var/mob/living/carbon/human/H, var/proximity) - . = ..() - if(.) - return - if(!on || !istype(H)) return FALSE diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 9194a3508de6..902d00b2a40b 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -190,11 +190,6 @@ resetTarget() //we're done, failed or not. Don't want to get stuck if C is not /mob/living/bot/secbot/UnarmedAttack(var/mob/M, var/proximity) - - . = ..() - if(.) - return - if(!istype(M)) return FALSE From af60124e40355cec6b831051a9c754e43b065cde Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 16:03:15 -0400 Subject: [PATCH 171/512] Fix engine control console plus and minus buttons dont work #4920 --- code/modules/overmap/ships/computers/engine_control.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/overmap/ships/computers/engine_control.dm b/code/modules/overmap/ships/computers/engine_control.dm index a62b7258705a..58efe3102d63 100644 --- a/code/modules/overmap/ships/computers/engine_control.dm +++ b/code/modules/overmap/ships/computers/engine_control.dm @@ -70,7 +70,8 @@ return TOPIC_REFRESH if(href_list["global_limit"]) - linked.set_thrust_limit(text2num(href_list["global_limit"])) + var/current_thrust_limit = linked.get_thrust_limit() + linked.set_thrust_limit(current_thrust_limit + text2num(href_list["global_limit"])) return TOPIC_REFRESH if(href_list["engine"]) From 721ba730dae2c1f04fbb673c78061fbadf035930 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 13:07:57 -0400 Subject: [PATCH 172/512] Fix stacking powders (scraps) leaves an empty slot #4914 --- code/game/atoms_init.dm | 8 +++++--- code/modules/materials/material_debris.dm | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/code/game/atoms_init.dm b/code/game/atoms_init.dm index 3a2f3b619c1d..f9f116dcfca1 100644 --- a/code/game/atoms_init.dm +++ b/code/game/atoms_init.dm @@ -92,10 +92,7 @@ updateVisibility(src) if(atom_codex_ref && atom_codex_ref != TRUE) // may be null, TRUE or a datum instance QDEL_NULL(atom_codex_ref) - var/atom/oldloc = loc . = ..() - if(isatom(oldloc) && oldloc.storage) - oldloc.storage.on_item_post_deletion(src) // must be done after deletion // This might need to be moved onto a Del() override at some point. QDEL_NULL(storage) @@ -138,6 +135,7 @@ . = ..() + var/atom/oldloc = loc forceMove(null) if(LAZYLEN(movement_handlers) && !ispath(movement_handlers[1])) @@ -154,6 +152,10 @@ if(!QDELETED(mask)) qdel(mask) + // This has to be done for movables because atoms can't be in storage. + if(isatom(oldloc) && !QDELETED(oldloc?.storage)) + oldloc.storage.on_item_post_deletion(src) // must be done after deletion + /atom/GetCloneArgs() return list(loc) diff --git a/code/modules/materials/material_debris.dm b/code/modules/materials/material_debris.dm index 8c4844a81247..a85e89683c37 100644 --- a/code/modules/materials/material_debris.dm +++ b/code/modules/materials/material_debris.dm @@ -105,6 +105,9 @@ if(!QDELETED(other)) user.put_in_hands(other) + if(isatom(loc) && !QDELETED(loc?.storage)) + loc.storage.update_ui_after_item_insertion() + UNSETEMPTY(matter) return TRUE From fa7989f3a4d9e764e8bc9894e4c2730ea6d80503 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 13:29:23 -0400 Subject: [PATCH 173/512] Fix randpixel applying when transferring between inventory slots --- code/game/gamemodes/wizard/servant_items/champion.dm | 2 +- code/game/objects/items/__item.dm | 7 +++++-- code/game/objects/items/weapons/melee/energy_projected.dm | 2 +- code/game/objects/items/weapons/policetape.dm | 2 +- code/game/objects/items/weapons/storage/laundry_basket.dm | 2 +- code/game/objects/items/weapons/towels.dm | 2 +- code/modules/clothing/spacesuits/void/void.dm | 2 +- code/modules/games/cards.dm | 2 +- code/modules/hydroponics/grown.dm | 2 +- code/modules/reagents/reagent_containers/beaker.dm | 2 +- code/modules/reagents/reagent_containers/drinks/bottle.dm | 2 +- code/modules/reagents/reagent_containers/glass/bottle.dm | 2 +- code/modules/reagents/reagent_containers/syringes.dm | 2 +- code/modules/spells/targeted/equip/burning_touch.dm | 2 +- code/modules/spells/targeted/equip/equip.dm | 2 +- mods/gamemodes/cult/items.dm | 2 +- 16 files changed, 20 insertions(+), 17 deletions(-) diff --git a/code/game/gamemodes/wizard/servant_items/champion.dm b/code/game/gamemodes/wizard/servant_items/champion.dm index 80e04ee1bfdc..43bfeccd3f89 100644 --- a/code/game/gamemodes/wizard/servant_items/champion.dm +++ b/code/game/gamemodes/wizard/servant_items/champion.dm @@ -60,7 +60,7 @@ attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "cleaved", "sundered") material_alteration = MAT_FLAG_ALTERATION_NONE -/obj/item/sword/excalibur/on_picked_up(var/mob/living/user) +/obj/item/sword/excalibur/on_picked_up(var/mob/living/user, atom/old_loc) if(user.mind) var/decl/special_role/wizard/wizards = GET_DECL(/decl/special_role/wizard) if(!wizards.is_antagonist(user.mind) || user.mind.assigned_special_role != "Spellbound Servant") diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index e86feb7173b6..14f792639a88 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -527,7 +527,7 @@ if (isturf(old_loc)) var/obj/effect/temporary/item_pickup_ghost/ghost = new(old_loc, src) ghost.animate_towards(user) - on_picked_up(user) + on_picked_up(user, old_loc) return TRUE return FALSE @@ -604,7 +604,10 @@ RAISE_EVENT_REPEAT(/decl/observ/item_unequipped, src, user) // called just after an item is picked up, after it has been equipped to the mob. -/obj/item/proc/on_picked_up(mob/user) +/obj/item/proc/on_picked_up(mob/user, atom/old_loc) + if(old_loc == loc || old_loc == user) + // not being picked up, just transferring between slots, don't adjust the offset + return if(randpixel) pixel_x = rand(-randpixel, randpixel) pixel_y = rand(-randpixel/2, randpixel/2) diff --git a/code/game/objects/items/weapons/melee/energy_projected.dm b/code/game/objects/items/weapons/melee/energy_projected.dm index 927cff0a5f96..1009f5745438 100644 --- a/code/game/objects/items/weapons/melee/energy_projected.dm +++ b/code/game/objects/items/weapons/melee/energy_projected.dm @@ -38,7 +38,7 @@ . = ..() check_loc() -/obj/item/energy_blade/projected/on_picked_up(mob/user) +/obj/item/energy_blade/projected/on_picked_up(mob/user, atom/old_loc) . = ..() check_loc() diff --git a/code/game/objects/items/weapons/policetape.dm b/code/game/objects/items/weapons/policetape.dm index c74435680273..59cc4fed58ad 100644 --- a/code/game/objects/items/weapons/policetape.dm +++ b/code/game/objects/items/weapons/policetape.dm @@ -83,7 +83,7 @@ var/global/list/image/hazard_overlays //Cached hazard floor overlays for the bar update_icon() return ..() -/obj/item/stack/tape_roll/barricade_tape/on_picked_up(mob/user) +/obj/item/stack/tape_roll/barricade_tape/on_picked_up(mob/user, atom/old_loc) stop_unrolling() update_icon() return ..() diff --git a/code/game/objects/items/weapons/storage/laundry_basket.dm b/code/game/objects/items/weapons/storage/laundry_basket.dm index c09205958c96..4d03a5567929 100644 --- a/code/game/objects/items/weapons/storage/laundry_basket.dm +++ b/code/game/objects/items/weapons/storage/laundry_basket.dm @@ -33,7 +33,7 @@ to_chat(user, "You dump \the [src]'s contents onto \the [T].") return ..() -/obj/item/laundry_basket/on_picked_up(mob/user) +/obj/item/laundry_basket/on_picked_up(mob/user, atom/old_loc) var/obj/item/laundry_basket/offhand/O = new(user) O.SetName("[name] - second hand") O.desc = "Your second grip on \the [src]." diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm index c15817b4e71f..42d5c4e9d945 100644 --- a/code/game/objects/items/weapons/towels.dm +++ b/code/game/objects/items/weapons/towels.dm @@ -132,7 +132,7 @@ pixel_y = 0 pixel_z = 0 -/obj/item/towel/on_picked_up(mob/user) +/obj/item/towel/on_picked_up(mob/user, atom/old_loc) ..() if(icon != initial(icon)) icon = initial(icon) diff --git a/code/modules/clothing/spacesuits/void/void.dm b/code/modules/clothing/spacesuits/void/void.dm index 7f2d8ecfe174..bb33a5fd1743 100644 --- a/code/modules/clothing/spacesuits/void/void.dm +++ b/code/modules/clothing/spacesuits/void/void.dm @@ -183,7 +183,7 @@ else if(##equipment_var) {\ to_chat(H, "You cannot deploy your helmet while wearing \the [head].") return if(H.equip_to_slot_if_possible(helmet, slot_head_str)) - helmet.on_picked_up(H) + helmet.on_picked_up(H, src) helmet.canremove = 0 playsound(loc, helmet_deploy_sound, 30) to_chat(H, "You deploy your suit helmet, sealing you off from the world.") diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm index 3bd0346b3a87..678403a88030 100644 --- a/code/modules/games/cards.dm +++ b/code/modules/games/cards.dm @@ -406,7 +406,7 @@ var/global/list/card_decks = list() else update_icon() -/obj/item/hand/on_picked_up(mob/user) +/obj/item/hand/on_picked_up(mob/user, atom/old_loc) src.update_icon() /*** A special thing that steals a card from a deck, probably lost in maint somewhere. ***/ diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index 28740b1f9344..d65ffdad4153 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -323,7 +323,7 @@ var/global/list/_wood_materials = list( return ..() -/obj/item/food/grown/on_picked_up(mob/user) +/obj/item/food/grown/on_picked_up(mob/user, atom/old_loc) ..() if(!seed) return diff --git a/code/modules/reagents/reagent_containers/beaker.dm b/code/modules/reagents/reagent_containers/beaker.dm index 5bfdf532c0f4..895da19ad0c0 100644 --- a/code/modules/reagents/reagent_containers/beaker.dm +++ b/code/modules/reagents/reagent_containers/beaker.dm @@ -17,7 +17,7 @@ . = ..() to_chat(user, " It can hold up to [volume] units.") -/obj/item/chems/glass/beaker/on_picked_up(mob/user) +/obj/item/chems/glass/beaker/on_picked_up(mob/user, atom/old_loc) . = ..() update_icon() diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index bd6c5d8bfc29..f73b144688e4 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -215,7 +215,7 @@ sleep(sleep_not_stacking) //Not stacking stop_spin_bottle = FALSE -/obj/item/chems/drinks/bottle/on_picked_up(mob/living/user) +/obj/item/chems/drinks/bottle/on_picked_up(mob/living/user, atom/old_loc) animate(src, transform = null, time = 0) //Restore bottle to its original position - animate() is needed to interrupt SpinAnimation() //Keeping this here for now, I'll ask if I should keep it here. diff --git a/code/modules/reagents/reagent_containers/glass/bottle.dm b/code/modules/reagents/reagent_containers/glass/bottle.dm index 8dc73f68d50b..54559692503d 100644 --- a/code/modules/reagents/reagent_containers/glass/bottle.dm +++ b/code/modules/reagents/reagent_containers/glass/bottle.dm @@ -25,7 +25,7 @@ /obj/item/chems/glass/bottle/get_lid_color() return lid_color -/obj/item/chems/glass/bottle/on_picked_up(mob/user) +/obj/item/chems/glass/bottle/on_picked_up(mob/user, atom/old_loc) . = ..() update_icon() diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 7467b9260f80..e4e5679548c5 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -42,7 +42,7 @@ if((. = ..())) update_icon() -/obj/item/chems/syringe/on_picked_up(mob/user) +/obj/item/chems/syringe/on_picked_up(mob/user, atom/old_loc) . = ..() update_icon() diff --git a/code/modules/spells/targeted/equip/burning_touch.dm b/code/modules/spells/targeted/equip/burning_touch.dm index 65ed431693bf..3c51cc26083a 100644 --- a/code/modules/spells/targeted/equip/burning_touch.dm +++ b/code/modules/spells/targeted/equip/burning_touch.dm @@ -25,7 +25,7 @@ var/burn_power = 0 var/burn_timer -/obj/item/burning_hands/on_picked_up(var/mob/user) +/obj/item/burning_hands/on_picked_up(var/mob/user, atom/old_loc) burn_power = 0 burn_timer = world.time + 10 SECONDS START_PROCESSING(SSobj,src) diff --git a/code/modules/spells/targeted/equip/equip.dm b/code/modules/spells/targeted/equip/equip.dm index 7b0304d9e076..601e6eea17f1 100644 --- a/code/modules/spells/targeted/equip/equip.dm +++ b/code/modules/spells/targeted/equip/equip.dm @@ -24,7 +24,7 @@ if(delete_old) qdel(old_item) L.equip_to_slot(new_item, slot_id) - new_item.on_picked_up(L) + new_item.on_picked_up(L, null) if(duration) summoned_items += new_item //we store it in a list to remove later diff --git a/mods/gamemodes/cult/items.dm b/mods/gamemodes/cult/items.dm index 01a8555e665d..9e33b9d30eb7 100644 --- a/mods/gamemodes/cult/items.dm +++ b/mods/gamemodes/cult/items.dm @@ -38,7 +38,7 @@ return TRUE -/obj/item/sword/cultblade/on_picked_up(mob/living/user) +/obj/item/sword/cultblade/on_picked_up(mob/living/user, atom/old_loc) if(!iscultist(user)) to_chat(user, "An overwhelming feeling of dread comes over you as you pick up the cultist's sword. It would be wise to be rid of this blade quickly.") SET_STATUS_MAX(user, STAT_DIZZY, 120) From 6bddf4c038fe8c1e855ed22a1f6a80716dbfe48f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 28 Feb 2025 01:48:54 -0500 Subject: [PATCH 174/512] Fix ice being called water in reagent grinders/blenders --- code/modules/reagents/Chemistry-Grinder.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/Chemistry-Grinder.dm b/code/modules/reagents/Chemistry-Grinder.dm index 987f641fa246..3e95d22756e6 100644 --- a/code/modules/reagents/Chemistry-Grinder.dm +++ b/code/modules/reagents/Chemistry-Grinder.dm @@ -135,7 +135,7 @@ if(beaker?.reagents) for(var/rtype in beaker.reagents.reagent_volumes) var/decl/material/R = GET_DECL(rtype) - data["beakercontents"] += "[capitalize(R.name)] ([REAGENT_VOLUME(beaker.reagents, rtype)]u)" + data["beakercontents"] += "[capitalize(R.get_reagent_name(beaker.reagents))] ([REAGENT_VOLUME(beaker.reagents, rtype)]u)" ui = SSnano.try_update_ui(user, src, ui_key, ui, data, force_open) if(!ui) From 6072095a20855e2be6fd930b5f366991dbb6945f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 11 Mar 2025 14:47:16 -0400 Subject: [PATCH 175/512] Fix onmob overlays of suit cyclers don't rotate when you fly a shuttle in rotation #4927 --- code/game/machinery/suit_cycler.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm index 6528dc3a5c54..d202b7e6b1d2 100644 --- a/code/game/machinery/suit_cycler.dm +++ b/code/game/machinery/suit_cycler.dm @@ -520,3 +520,9 @@ if(boots) boots.refit_for_bodytype(target_bodytype) boots.SetName("refitted [initial(boots.name)]") + +// Update icon on rotate so that overlays rotate as well +/obj/machinery/suit_cycler/shuttle_rotate(angle) + . = ..() + if(.) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, queue_icon_update)), 1) \ No newline at end of file From 3cca3c7e191b29f689cb6731762f64e6d79f3b33 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 15:10:20 -0400 Subject: [PATCH 176/512] Fix inverted can_slip check --- code/modules/hydroponics/spreading/spreading_response.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm index 1eaa5fba5651..ad0400849daa 100644 --- a/code/modules/hydroponics/spreading/spreading_response.dm +++ b/code/modules/hydroponics/spreading/spreading_response.dm @@ -78,7 +78,7 @@ if(H.species.species_flags & SPECIES_FLAG_NO_TANGLE) return - if(victim.loc != loc && victim.can_slip()) + if(victim.loc != loc && !victim.can_slip()) visible_message("Tendrils lash to drag \the [victim] but \the [src] can't pull them across the ground!") return From ab085965b8c2253841a242e9e22498ae28afc825 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 15:16:06 -0400 Subject: [PATCH 177/512] Fix #4947 --- code/game/machinery/doors/airlock.dm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 48a3bf8895b5..bd2f3f4d8f92 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -982,7 +982,8 @@ About the new airlock wires panel: if (lock_cut_state == BOLTS_CUT) return FALSE //what bolts? - src.locked = TRUE + locked = TRUE + locking = FALSE playsound(src, bolts_dropping, 30, 0, -6) audible_message("You hear a click from the bottom of the door.", hearing_distance = 1) update_icon() @@ -990,20 +991,21 @@ About the new airlock wires panel: return TRUE /obj/machinery/door/airlock/proc/unlock(var/forced=0) - if(!src.locked) + if(!locked) return FALSE if (!forced) - if(!src.arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) return FALSE if(operating) locking = FALSE unlocking = TRUE return FALSE - if(operating || !src.arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + if(!arePowerSystemsOn() || isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) return FALSE - src.locked = FALSE + locked = FALSE + unlocking = FALSE playsound(src, bolts_rising, 30, 0, -6) audible_message("You hear a click from the bottom of the door.", hearing_distance = 1) update_icon() From 67801e3982771cf75f1ed50ddfe8ca334916af2a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 16:42:33 -0400 Subject: [PATCH 178/512] Fix loading old saves failing to deserialize species from name --- code/modules/client/preference_setup/background/01_species.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index dcd727964a11..1011a06a0604 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -19,7 +19,7 @@ writer.write("species", pref.species) /datum/category_item/player_setup_item/background/species/preload_character(datum/pref_record_reader/R) - var/decl/species/loaded_species = decls_repository.get_decl_by_id_or_var(R.read("species"), /decl/spawnpoint) + var/decl/species/loaded_species = decls_repository.get_decl_by_id_or_var(R.read("species"), /decl/species) pref.species = loaded_species?.uid || decls_repository.get_decl_by_id(global.using_map.default_species) /datum/category_item/player_setup_item/background/species/sanitize_character() From 7575a5587beb858e955760c74552bb7f8dbda260 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 16:45:59 -0400 Subject: [PATCH 179/512] Fix runtimes from non-blood footprints --- code/game/turfs/flooring/flooring_mud.dm | 2 +- code/game/turfs/flooring/flooring_snow.dm | 2 +- code/game/turfs/turf.dm | 2 +- code/modules/mob/living/living.dm | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/code/game/turfs/flooring/flooring_mud.dm b/code/game/turfs/flooring/flooring_mud.dm index d6d77b4e9e31..6265343f2e7f 100644 --- a/code/game/turfs/flooring/flooring_mud.dm +++ b/code/game/turfs/flooring/flooring_mud.dm @@ -28,7 +28,7 @@ walker.add_walking_contaminant(force_material.type, rand(2,3)) /decl/flooring/mud/can_show_coating_footprints(turf/target, decl/material/contaminant) - if(force_material.type == contaminant) // So we don't end up covered in a million footsteps that we provided. + if(force_material == contaminant) // So we don't end up covered in a million footsteps that we provided. return FALSE return ..() diff --git a/code/game/turfs/flooring/flooring_snow.dm b/code/game/turfs/flooring/flooring_snow.dm index 7ef511ab0e33..8dabb7167af5 100644 --- a/code/game/turfs/flooring/flooring_snow.dm +++ b/code/game/turfs/flooring/flooring_snow.dm @@ -41,7 +41,7 @@ walker.add_walking_contaminant(force_material.type, rand(1, 2)) /decl/flooring/snow/can_show_coating_footprints(turf/target, decl/material/contaminant) - if(force_material.type == contaminant) // So we don't end up covered in a million footsteps that we provided. + if(force_material == contaminant) // So we don't end up covered in a million footsteps that we provided. return FALSE return ..() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index abd365c4f356..46d837620d05 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -864,7 +864,7 @@ if(IS_HOE(held) && can_dig_farm(held.material?.hardness)) LAZYADD(., /decl/interaction_handler/dig/farm) -/// Contaminant may be the chemical type of the footprint being provided, +/// Contaminant may be the chemical decl of the footprint being provided, /// or null if we just want to know if we support footprints, at all, ever. /turf/proc/can_show_coating_footprints(decl/material/contaminant) return simulated diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index c4ea89b4e59a..fbce10dfb123 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1571,21 +1571,21 @@ default behaviour is: if(!use_move_trail) return - var/decl/material/contaminant_type = source.coating.reagent_volumes[1] // take [1] instead of primary reagent to match what remove_any will probably remove - if(!T.can_show_coating_footprints(contaminant_type)) + var/decl/material/contaminant = source.coating.reagent_volumes[1] // take [1] instead of primary reagent to match what remove_any will probably remove + if(!T.can_show_coating_footprints(contaminant)) return /// An associative list of DNA unique enzymes -> blood type. Used by forensics, mostly. var/list/bloodDNA = list() var/track_color - var/list/source_data = REAGENT_DATA(source.coating, contaminant_type) + var/list/source_data = REAGENT_DATA(source.coating, contaminant) if(source_data && source_data[DATA_BLOOD_DNA] && source_data[DATA_BLOOD_TYPE]) bloodDNA = list(source_data[DATA_BLOOD_DNA] = source_data[DATA_BLOOD_TYPE]) track_color = source.coating.get_color() - T.AddTracks(use_move_trail, bloodDNA, dir, 0, track_color, contaminant_type) // Coming + T.AddTracks(use_move_trail, bloodDNA, dir, 0, track_color, contaminant.type) // Coming if(isturf(old_loc)) var/turf/old_turf = old_loc - if(old_turf.can_show_coating_footprints(contaminant_type)) - old_turf.AddTracks(use_move_trail, bloodDNA, 0, dir, track_color, contaminant_type) // Going + if(old_turf.can_show_coating_footprints(contaminant)) + old_turf.AddTracks(use_move_trail, bloodDNA, 0, dir, track_color, contaminant.type) // Going source.remove_coating(1) update_equipment_overlay(slot_shoes_str) From b7cbbe97c72de15c3f206812cd9321ad4e1cd083 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 16:48:02 -0400 Subject: [PATCH 180/512] Fix ambient lighting artifacts on Shaded Hills --- code/modules/lighting/lighting_turf.dm | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 53e59fa5b9b0..e9cfb65cb455 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -64,15 +64,8 @@ if (abs(ambient_r + ambient_g + ambient_b) == 0) return - // Unlit turfs will have corners if they have a lit neighbor -- don't generate corners for them, but do update them if they're there. - if (!corners) - var/force_build_corners = FALSE - for (var/turf/T as anything in RANGE_TURFS(src, 1)) - if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) - force_build_corners = TRUE - break - - if (force_build_corners || TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) + if (!corners || !lighting_corners_initialised) + if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) generate_missing_corners() else return From 288a666e89dc20643985b25ecb4122217ff4aca9 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 16:59:42 -0400 Subject: [PATCH 181/512] Fix HUD not refreshing when adjusting UI highlight color --- code/modules/client/preference_setup/global/01_ui.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preference_setup/global/01_ui.dm b/code/modules/client/preference_setup/global/01_ui.dm index ff50154195eb..462e46c2b32b 100644 --- a/code/modules/client/preference_setup/global/01_ui.dm +++ b/code/modules/client/preference_setup/global/01_ui.dm @@ -134,7 +134,7 @@ var/global/list/valid_icon_sizes = list(32, 48, 64, 96, 128) var/UI_style_highlight_color_new = input(user, "Choose UI highlight color, dark colors are not recommended!", "Global Preference", pref.UI_style_highlight_color) as color|null if(isnull(UI_style_highlight_color_new) || !CanUseTopic(user)) return TOPIC_NOACTION pref.UI_style_highlight_color = UI_style_highlight_color_new - return TOPIC_REFRESH + . = TOPIC_REFRESH else if(href_list["select_alpha"]) var/UI_style_alpha_new = input(user, "Select UI alpha (transparency) level, between 50 and 255.", "Global Preference", pref.UI_style_alpha) as num|null From ee3fb63b0a381a8b6ac06b035f95453a04602877 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 12 Mar 2025 17:28:44 -0400 Subject: [PATCH 182/512] poster init streamlining --- code/modules/posters/_poster.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/posters/_poster.dm b/code/modules/posters/_poster.dm index 83537257ce2f..67122ee2df65 100644 --- a/code/modules/posters/_poster.dm +++ b/code/modules/posters/_poster.dm @@ -135,10 +135,9 @@ /obj/item/poster/Initialize(ml, material_key, var/given_poster_type = null) //Init design - base_name ||= name - base_desc ||= desc + . = ..(ml, material_key) set_design(given_poster_type || poster_design || pick(decls_repository.get_decl_paths_of_subtype(/decl/poster_design))) - return ..(ml, material_key) + return . /obj/item/poster/proc/set_design(var/decl/poster_design/_design_path) if(ispath(_design_path, /decl)) From 6559845053f01a7a0515fcdc30f1820051f2ab99 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 12 Mar 2025 17:29:06 -0400 Subject: [PATCH 183/512] clean up pen code, ink use, literacy --- code/modules/reagents/storage/pill_bottle.dm | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/code/modules/reagents/storage/pill_bottle.dm b/code/modules/reagents/storage/pill_bottle.dm index 3f70da11325f..252b817c1d7a 100644 --- a/code/modules/reagents/storage/pill_bottle.dm +++ b/code/modules/reagents/storage/pill_bottle.dm @@ -78,17 +78,22 @@ name = "[base_name] ([labeled_name])" desc = "[base_desc] It is labeled \"[labeled_name]\"." -/obj/item/pill_bottle/attackby(obj/item/W, mob/user) - if(istype(W, /obj/item/pen) || istype(W, /obj/item/flashlight/pen)) +/obj/item/pill_bottle/attackby(obj/item/used_item, mob/user) + if(IS_PEN(used_item)) + var/decl/tool_archetype/pen/parch = GET_DECL(TOOL_PEN) + var/tmp_label = sanitize_safe(input(user, "Enter a label for [name]", "Label", labeled_name), MAX_NAME_LEN) - if(length(tmp_label) > 50) + tmp_label = user.handle_writing_literacy(user, tmp_label) + var/label_length = length(tmp_label) + if(label_length > 50) to_chat(user, "The label can be at most 50 characters long.") - else if(length(tmp_label) > 10) - to_chat(user, "You set the label.") - labeled_name = tmp_label - update_name_label() - else - to_chat(user, "You set the label to \"[tmp_label]\".") + else + if(label_length > 10) + to_chat(user, "You set the label.") + else + to_chat(user, "You set the label to \"[tmp_label]\".") + if(parch.decrement_uses(user, used_item, max(round(label_length / 25, 1), 1)) <= 0) + parch.warn_out_of_ink(user, used_item) labeled_name = tmp_label update_name_label() return TRUE From b18a6f0ba75f5b6c49adeaa8b22ab67333c536d4 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 18:35:44 -0400 Subject: [PATCH 184/512] Fix get_topmost_flooring not working properly for wildgrass --- code/game/turfs/floors/floor_layers.dm | 59 ++++++++++---------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/code/game/turfs/floors/floor_layers.dm b/code/game/turfs/floors/floor_layers.dm index 78302f336e8d..5396b3607cf2 100644 --- a/code/game/turfs/floors/floor_layers.dm +++ b/code/game/turfs/floors/floor_layers.dm @@ -5,16 +5,13 @@ /turf/floor/proc/get_all_flooring() . = list() - if(istype(_flooring)) - . += _flooring - else if(ispath(_flooring)) - . += GET_DECL(_flooring) - else if(islist(_flooring)) - for(var/floor in _flooring) - if(ispath(floor)) - _flooring += GET_DECL(floor) - else if(istype(floor, /decl/flooring)) - _flooring += floor + if(_flooring) + if(islist(_flooring)) + for(var/floor in _flooring) + . += RESOLVE_TO_DECL(floor) + _flooring = . // ensure the list elements are resolved + else + . += RESOLVE_TO_DECL(_flooring) if(_base_flooring) . += get_base_flooring() @@ -22,15 +19,11 @@ return !isnull(_flooring) /turf/floor/proc/set_base_flooring(new_base_flooring, skip_update) - if(ispath(new_base_flooring, /decl/flooring)) - new_base_flooring = GET_DECL(new_base_flooring) - else if(!istype(new_base_flooring, /decl/flooring)) - new_base_flooring = null + // We can never have a null base flooring. + new_base_flooring = RESOLVE_TO_DECL(new_base_flooring || initial(_base_flooring) || /decl/flooring/plating) if(_base_flooring == new_base_flooring) return _base_flooring = new_base_flooring - if(!_base_flooring) // We can never have a null base flooring. - _base_flooring = GET_DECL(initial(_base_flooring)) || GET_DECL(/decl/flooring/plating) update_from_flooring(skip_update) /turf/floor/proc/get_base_flooring() @@ -43,15 +36,14 @@ RETURN_TYPE(/decl/flooring) if(isnull(_topmost_flooring)) - var/flooring_length = length(_flooring) - if(flooring_length) // no need to check islist, length is only nonzero for lists and strings, and strings are invalid here - _topmost_flooring = _flooring[flooring_length] - else if(istype(_flooring, /decl/flooring)) - _topmost_flooring = _flooring - else if(ispath(_flooring, /decl/flooring)) - _topmost_flooring = GET_DECL(_flooring) - else + if(isnull(_flooring)) _topmost_flooring = FALSE + else + var/flooring_length = length(_flooring) + if(flooring_length) // no need to check islist, length is only nonzero for lists and strings, and strings are invalid here + _topmost_flooring = RESOLVE_TO_DECL(_flooring[flooring_length]) + else + _topmost_flooring = RESOLVE_TO_DECL(_flooring) return _topmost_flooring || get_base_flooring() /turf/floor/proc/clear_flooring(skip_update = FALSE, place_product) @@ -81,8 +73,7 @@ return // Validate our input. - if(ispath(flooring)) - flooring = GET_DECL(flooring) + flooring = RESOLVE_TO_DECL(flooring) if(!istype(flooring)) return @@ -145,14 +136,9 @@ if(islist(newflooring)) _flooring = list() for(var/floor in UNLINT(newflooring)) - if(ispath(floor)) - floor = GET_DECL(floor) - if(istype(floor, /decl/flooring)) - _flooring += floor - else if(ispath(newflooring)) - _flooring = GET_DECL(newflooring) - else if(istype(newflooring)) - _flooring = newflooring + _flooring += RESOLVE_TO_DECL(floor) + else if(newflooring) + _flooring = RESOLVE_TO_DECL(newflooring) else return FALSE @@ -184,9 +170,8 @@ return // We only want to work with references. - if(ispath(newflooring, /decl/flooring)) - newflooring = GET_DECL(newflooring) - else if(!istype(newflooring, /decl/flooring)) + newflooring = RESOLVE_TO_DECL(newflooring) + if(!newflooring) return FALSE // Check if the layer is already present. From 9f902e0ab56535fd73218c99b6274b4db85f449a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 19:02:29 -0400 Subject: [PATCH 185/512] Fix setting ambient light multiplier to 0 not working --- code/modules/lighting/lighting_turf.dm | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index e9cfb65cb455..10f19c3ae5eb 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -28,10 +28,8 @@ if (color == ambient_light && multiplier == ambient_light_multiplier) return - ambient_light = color || ambient_light - ambient_light_multiplier = multiplier || ambient_light_multiplier - if (!ambient_light_multiplier) - ambient_light_multiplier = initial(ambient_light_multiplier) + ambient_light = isnull(color) ? ambient_light : color + ambient_light_multiplier = isnull(multiplier) ? ambient_light_multiplier : multiplier update_ambient_light() @@ -48,7 +46,7 @@ var/ambient_g = 0 var/ambient_b = 0 - if (ambient_light) + if (ambient_light && ambient_light_multiplier) // If either of these are false-y we can use the simplier path and avoid calculations ambient_r = round(((HEX_RED(ambient_light) / 255) * ambient_light_multiplier)/4 - ambient_light_old_r, LIGHTING_ROUND_VALUE) ambient_g = round(((HEX_GREEN(ambient_light) / 255) * ambient_light_multiplier)/4 - ambient_light_old_g, LIGHTING_ROUND_VALUE) ambient_b = round(((HEX_BLUE(ambient_light) / 255) * ambient_light_multiplier)/4 - ambient_light_old_b, LIGHTING_ROUND_VALUE) From 34219c8a84672a8a05cb46ecde47c3b7222522b7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 19:02:54 -0400 Subject: [PATCH 186/512] Set Shaded Hills default UI style to UWII --- maps/shaded_hills/shaded_hills_define.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/maps/shaded_hills/shaded_hills_define.dm b/maps/shaded_hills/shaded_hills_define.dm index 6266ab2a09e4..c29719d54c79 100644 --- a/maps/shaded_hills/shaded_hills_define.dm +++ b/maps/shaded_hills/shaded_hills_define.dm @@ -43,6 +43,7 @@ "rock" = /turf/floor/rock/basalt::color, "brick" = /turf/wall/brick/sandstone::color ) + default_ui_style = /decl/ui_style/underworld /decl/backpack_outfit/sack is_default = TRUE From 3dfdeaa73309b1a9331db39391dea7249d5a135b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 19:24:53 -0400 Subject: [PATCH 187/512] Adjust Shaded Hills ambient light strength --- code/datums/daycycle/time_of_day.dm | 2 +- maps/shaded_hills/areas/_areas.dm | 2 +- maps/shaded_hills/areas/downlands.dm | 6 +++--- mods/content/fantasy/submaps/_submaps.dm | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/datums/daycycle/time_of_day.dm b/code/datums/daycycle/time_of_day.dm index 5411dba4b076..fbe3f6330d7b 100644 --- a/code/datums/daycycle/time_of_day.dm +++ b/code/datums/daycycle/time_of_day.dm @@ -24,7 +24,7 @@ name = "daytime" announcement = "The sun rises over the horizon, beginning another day." period = 0.4 - power = 1 + power = 0.8 color = COLOR_DAYLIGHT /datum/daycycle_period/sunset diff --git a/maps/shaded_hills/areas/_areas.dm b/maps/shaded_hills/areas/_areas.dm index e31eff6ce28e..bdf893f4f7e0 100644 --- a/maps/shaded_hills/areas/_areas.dm +++ b/maps/shaded_hills/areas/_areas.dm @@ -36,5 +36,5 @@ ) description = "Birds and insects call from the grasses, and a cool wind gusts from across the river." area_blurb_category = /area/shaded_hills/outside - interior_ambient_light_modifier = -0.3 + interior_ambient_light_modifier = -0.4 area_flags = AREA_FLAG_EXTERNAL | AREA_FLAG_IS_BACKGROUND diff --git a/maps/shaded_hills/areas/downlands.dm b/maps/shaded_hills/areas/downlands.dm index 05865fe13c78..76d91cce821e 100644 --- a/maps/shaded_hills/areas/downlands.dm +++ b/maps/shaded_hills/areas/downlands.dm @@ -23,7 +23,7 @@ /area/shaded_hills/inn/porch name = "\improper Inn Porch" - interior_ambient_light_modifier = -0.3 // night is pitch-black on the porch + interior_ambient_light_modifier = -0.4 // night is pitch-black on the porch sound_env = FOREST /area/shaded_hills/stable @@ -42,7 +42,7 @@ /area/shaded_hills/farmhouse/porch name = "\improper Farmhouse Porch" - interior_ambient_light_modifier = -0.3 // night is pitch-black on the porch + interior_ambient_light_modifier = -0.4 // night is pitch-black on the porch sound_env = FOREST /area/shaded_hills/slaughterhouse @@ -68,7 +68,7 @@ /area/shaded_hills/general_store/porch name = "\improper General Store Porch" - interior_ambient_light_modifier = -0.3 // night is pitch-black on the porch + interior_ambient_light_modifier = -0.4 // night is pitch-black on the porch sound_env = FOREST /area/shaded_hills/shrine diff --git a/mods/content/fantasy/submaps/_submaps.dm b/mods/content/fantasy/submaps/_submaps.dm index 64c03240f4b7..da60d375fd62 100644 --- a/mods/content/fantasy/submaps/_submaps.dm +++ b/mods/content/fantasy/submaps/_submaps.dm @@ -43,7 +43,7 @@ 'sound/effects/wind/wind_4_2.ogg', 'sound/effects/wind/wind_5_1.ogg' ) - interior_ambient_light_modifier = -0.3 + interior_ambient_light_modifier = -0.4 area_flags = AREA_FLAG_EXTERNAL | AREA_FLAG_IS_BACKGROUND /area/fantasy/outside/point_of_interest From 849532dfe90c77c40751c33ec6da36d9cf457ea7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 19:38:09 -0400 Subject: [PATCH 188/512] Fix carpet tile icons --- code/game/objects/items/stacks/tiles/tile_types.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index e5085078998c..f5787b0e243f 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -286,7 +286,7 @@ /obj/item/stack/tile/carpet/on_update_icon() . = ..() if(detail_color) - set_overlays(overlay_image(icon, "[icon_state]-detail", detail_color, RESET_COLOR)) + add_overlay(overlay_image(icon, "[icon_state]_detail", detail_color, RESET_COLOR)) /obj/item/stack/tile/carpet/fifty amount = 50 From 819badd6e7d01b15b67e0a2e0ab83050bb1792e2 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 12 Mar 2025 20:03:05 -0400 Subject: [PATCH 189/512] Fix placing carpets always placing orange carpet --- code/game/objects/items/stacks/tiles/tile_types.dm | 9 +++++++++ code/game/turfs/floors/floor_attackby.dm | 7 ++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm index f5787b0e243f..2d702386ec83 100644 --- a/code/game/objects/items/stacks/tiles/tile_types.dm +++ b/code/game/objects/items/stacks/tiles/tile_types.dm @@ -271,6 +271,7 @@ * Carpets */ /obj/item/stack/tile/carpet + build_type = /obj/item/stack/tile/carpet name = "brown carpet" singular_name = "brown carpet" desc = "A piece of brown carpet." @@ -292,6 +293,7 @@ amount = 50 /obj/item/stack/tile/carpet/blue + build_type = /obj/item/stack/tile/carpet/blue name = "blue carpet" desc = "A piece of blue and gold carpet." singular_name = "blue carpet" @@ -301,6 +303,7 @@ amount = 50 /obj/item/stack/tile/carpet/blue2 + build_type = /obj/item/stack/tile/carpet/blue2 name = "pale blue carpet" desc = "A piece of blue and pale blue carpet." singular_name = "pale blue carpet" @@ -311,6 +314,7 @@ amount = 50 /obj/item/stack/tile/carpet/blue3 + build_type = /obj/item/stack/tile/carpet/blue3 name = "sea blue carpet" desc = "A piece of blue and green carpet." singular_name = "sea blue carpet" @@ -321,6 +325,7 @@ amount = 50 /obj/item/stack/tile/carpet/magenta + build_type = /obj/item/stack/tile/carpet/magenta name = "magenta carpet" desc = "A piece of magenta carpet." singular_name = "magenta carpet" @@ -331,6 +336,7 @@ amount = 50 /obj/item/stack/tile/carpet/purple + build_type = /obj/item/stack/tile/carpet/purple name = "purple carpet" desc = "A piece of purple carpet." singular_name = "purple carpet" @@ -341,6 +347,7 @@ amount = 50 /obj/item/stack/tile/carpet/orange + build_type = /obj/item/stack/tile/carpet/orange name = "orange carpet" desc = "A piece of orange carpet." singular_name = "orange carpet" @@ -351,6 +358,7 @@ amount = 50 /obj/item/stack/tile/carpet/green + build_type = /obj/item/stack/tile/carpet/green name = "green carpet" desc = "A piece of green carpet." singular_name = "green carpet" @@ -371,6 +379,7 @@ amount = 50 /obj/item/stack/tile/carpet/rustic + build_type = /obj/item/stack/tile/carpet/rustic name = "rustic carpet" desc = "A piece of simple, rustic carpeting." singular_name = "rustic carpet" diff --git a/code/game/turfs/floors/floor_attackby.dm b/code/game/turfs/floors/floor_attackby.dm index 0ddfc38eea84..4c4579bd830c 100644 --- a/code/game/turfs/floors/floor_attackby.dm +++ b/code/game/turfs/floors/floor_attackby.dm @@ -47,7 +47,12 @@ for(var/decl/flooring/F as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/flooring)) if(!F.build_type) continue - if((ispath(S.type, F.build_type) || ispath(S.build_type, F.build_type)) && (isnull(F.build_material) || S.material?.type == F.build_material)) + // If S.build_type is set, we expect an exact match. Otherwise, we do + // an ispath on S.type. This is a shitty way to disambiguate carpet + // types because they're in the ugly position of "same material, built + // with a subtype" whereas with everything else, material + type + // disambiguates well enough. + if((S.build_type ? S.build_type == F.build_type : ispath(S.type, F.build_type)) && (isnull(F.build_material) || S.material?.type == F.build_material)) use_flooring = F break if(!use_flooring) From 06219f8a7b57a5f4aed233be523b44992c3ad840 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 12 Mar 2025 21:21:00 -0400 Subject: [PATCH 190/512] redundant call removal --- code/modules/posters/_poster.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/posters/_poster.dm b/code/modules/posters/_poster.dm index 67122ee2df65..93b1dbe141bc 100644 --- a/code/modules/posters/_poster.dm +++ b/code/modules/posters/_poster.dm @@ -137,7 +137,6 @@ //Init design . = ..(ml, material_key) set_design(given_poster_type || poster_design || pick(decls_repository.get_decl_paths_of_subtype(/decl/poster_design))) - return . /obj/item/poster/proc/set_design(var/decl/poster_design/_design_path) if(ispath(_design_path, /decl)) From 4846fa0d399bcf810bb69c39f90a6b2617e80200 Mon Sep 17 00:00:00 2001 From: Typhin Date: Thu, 13 Mar 2025 15:36:38 -0500 Subject: [PATCH 191/512] Update biogenerator.dm Fixes biogenerators not allowing parts/tools to build/repair --- code/game/machinery/biogenerator.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/machinery/biogenerator.dm b/code/game/machinery/biogenerator.dm index f9583f4acfc1..75e0387142c4 100644 --- a/code/game/machinery/biogenerator.dm +++ b/code/game/machinery/biogenerator.dm @@ -81,6 +81,9 @@ /obj/machinery/biogenerator/attackby(var/obj/item/used_item, var/mob/user) + if(panel_open || IS_SCREWDRIVER(used_item)) + return ..() + if(processing) if((. = component_attackby(used_item, user))) return From 70c31a624f4cd4d3c8c0f0fe5d9460d6f57cf8fa Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Fri, 14 Mar 2025 08:23:44 +1100 Subject: [PATCH 192/512] Automatic changelog generation for PR #4954 [ci skip] --- html/changelogs/AutoChangeLog-pr-4954.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4954.yml diff --git a/html/changelogs/AutoChangeLog-pr-4954.yml b/html/changelogs/AutoChangeLog-pr-4954.yml new file mode 100644 index 000000000000..e3be29337780 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4954.yml @@ -0,0 +1,4 @@ +author: Typhin +changes: + - {bugfix: Allows parts/screwdrivers to be used on biogenerators} +delete-after: true From 5be5f3929ef0b01deea0970ff68c45f4f26606da Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 13 Mar 2025 17:58:57 -0400 Subject: [PATCH 193/512] Add check for panel opening to machinery unit test --- .../machine_construction/airlock.dm | 22 +++++++++++++++++++ .../machine_construction/default.dm | 13 +++++++++++ 2 files changed, 35 insertions(+) diff --git a/code/game/machinery/_machines_base/machine_construction/airlock.dm b/code/game/machinery/_machines_base/machine_construction/airlock.dm index 1d8851614bb7..0c686e0b227a 100644 --- a/code/game/machinery/_machines_base/machine_construction/airlock.dm +++ b/code/game/machinery/_machines_base/machine_construction/airlock.dm @@ -3,6 +3,28 @@ down_state = /decl/machine_construction/default/panel_open/door var/hacking_state = /decl/machine_construction/default/panel_closed/door/hacking +/decl/machine_construction/default/panel_closed/door/fail_test_state_transfer(obj/machinery/machine, mob/user) + var/static/obj/item/screwdriver/screwdriver = new + // Prevent access locks on doors from interfering with our interactions. + for(var/obj/item/stock_parts/access_lock/lock in machine.get_all_components_of_type(/obj/item/stock_parts/access_lock)) + lock.locked = FALSE + // Test hacking state + if(!machine.attackby(screwdriver, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver." + if(machine.construct_state.type != hacking_state) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [hacking_state])." + // Do it again to reverse that state change. + if(!machine.attackby(screwdriver, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver on a second try." + if(machine.construct_state != src) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [type])." + // Now test the down state + var/obj/item/wrench/wrench = new + if(!machine.attackby(wrench, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with wrench." + if(machine.construct_state.type != down_state) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [down_state])." + /decl/machine_construction/default/panel_closed/door/attackby(obj/item/used_item, mob/user, obj/machinery/machine) if(IS_SCREWDRIVER(used_item)) TRANSFER_STATE(hacking_state) diff --git a/code/game/machinery/_machines_base/machine_construction/default.dm b/code/game/machinery/_machines_base/machine_construction/default.dm index 727e30cf0315..a3056c056a52 100644 --- a/code/game/machinery/_machines_base/machine_construction/default.dm +++ b/code/game/machinery/_machines_base/machine_construction/default.dm @@ -13,6 +13,19 @@ visible_components = FALSE locked = TRUE +/decl/machine_construction/default/panel_closed/fail_unit_test(obj/machinery/machine) + if((. = ..())) + return + var/static/mob/living/human/user = new + return fail_test_state_transfer(machine, user) + +/decl/machine_construction/default/panel_closed/proc/fail_test_state_transfer(obj/machinery/machine, mob/user) + var/static/obj/item/screwdriver/screwdriver = new + if(!machine.attackby(screwdriver, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver." + if(machine.construct_state.type != down_state) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [down_state])." + /decl/machine_construction/default/panel_closed/state_is_valid(obj/machinery/machine) return !machine.panel_open From 1b3130e063af03652a504fad55089e797ecd801c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 13 Mar 2025 18:29:22 -0400 Subject: [PATCH 194/512] Fix incorrect state transition when opening firedoors or breaking airlocks --- code/game/machinery/doors/airlock.dm | 2 +- code/game/machinery/doors/firedoor.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 6515ee5b15af..4bf242758c9f 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -889,7 +889,7 @@ About the new airlock wires panel: panel_open = TRUE if(istype(construct_state, /decl/machine_construction/default/panel_closed)) var/decl/machine_construction/default/panel_closed/closed = construct_state - construct_state = closed.down_state + construct_state = GET_DECL(closed.down_state) construct_state.validate_state(src) if (secured_wires) lock() diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index 6952c2f6f6d6..732b04b47d39 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -348,7 +348,7 @@ panel_open = FALSE if(istype(construct_state, /decl/machine_construction/default/panel_open)) var/decl/machine_construction/default/panel_open/open = construct_state - construct_state = open.up_state + construct_state = GET_DECL(open.up_state) construct_state.validate_state(src) visible_message("The maintenance hatch of \the [src] closes.") update_icon() From c8ada39941fb19cefe0028f6ed57c6f85dca6ab9 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 13 Mar 2025 20:51:37 -0400 Subject: [PATCH 195/512] change over fully to label system --- code/modules/reagents/storage/pill_bottle.dm | 23 ++++++-------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/code/modules/reagents/storage/pill_bottle.dm b/code/modules/reagents/storage/pill_bottle.dm index 252b817c1d7a..28482973709c 100644 --- a/code/modules/reagents/storage/pill_bottle.dm +++ b/code/modules/reagents/storage/pill_bottle.dm @@ -66,24 +66,11 @@ if(wrapper_color) add_overlay(overlay_image(icon, "pillbottle_wrap", wrapper_color, RESET_COLOR)) -/obj/item/pill_bottle/proc/update_name_label() - if(!labeled_name) - name = base_name - desc = base_desc - return - else if(length(labeled_name) > 10) - var/short_label_name = copytext(labeled_name, 1, 11) - name = "[base_name] ([short_label_name]...)" - else - name = "[base_name] ([labeled_name])" - desc = "[base_desc] It is labeled \"[labeled_name]\"." - /obj/item/pill_bottle/attackby(obj/item/used_item, mob/user) if(IS_PEN(used_item)) - var/decl/tool_archetype/pen/parch = GET_DECL(TOOL_PEN) - var/tmp_label = sanitize_safe(input(user, "Enter a label for [name]", "Label", labeled_name), MAX_NAME_LEN) tmp_label = user.handle_writing_literacy(user, tmp_label) + var/label_length = length(tmp_label) if(label_length > 50) to_chat(user, "The label can be at most 50 characters long.") @@ -92,9 +79,13 @@ to_chat(user, "You set the label.") else to_chat(user, "You set the label to \"[tmp_label]\".") + + var/decl/tool_archetype/pen/parch = GET_DECL(TOOL_PEN) if(parch.decrement_uses(user, used_item, max(round(label_length / 25, 1), 1)) <= 0) parch.warn_out_of_ink(user, used_item) - labeled_name = tmp_label - update_name_label() + + var/datum/extension/labels/lext = get_or_create_extension(src, /datum/extension/labels) + lext.RemoveAllLabels() + attach_label(null, null, tmp_label) return TRUE return ..() \ No newline at end of file From 8ce9529c2acc871b6ef1b0c6f15dd4d931996aab Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Fri, 14 Mar 2025 00:52:29 +0000 Subject: [PATCH 196/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-4954.yml | 4 ---- 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4954.yml diff --git a/html/changelog.html b/html/changelog.html index 0afd777c7d03..054c758e54cc 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
    +

    14 March 2025

    +

    Typhin updated:

    +
      +
    • Allows parts/screwdrivers to be used on biogenerators
    • +
    +

    12 March 2025

    Cerebulon updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index bb7d0e80cfe4..55fad9100e4a 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -15000,3 +15000,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Cerebulon: - imageadd: Changed modpack Tajara to use old-style humanoid sprites instead of a unique feline body shape which has since been used by Hnolls. +2025-03-14: + Typhin: + - bugfix: Allows parts/screwdrivers to be used on biogenerators diff --git a/html/changelogs/AutoChangeLog-pr-4954.yml b/html/changelogs/AutoChangeLog-pr-4954.yml deleted file mode 100644 index e3be29337780..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4954.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Typhin -changes: - - {bugfix: Allows parts/screwdrivers to be used on biogenerators} -delete-after: true From 000069287090a2ae60f8f4526ba30a3f32dd64f0 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 13 Mar 2025 19:31:04 -0400 Subject: [PATCH 197/512] Fix robot modules in storage capacity test --- code/unit_tests/equipment_tests.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/unit_tests/equipment_tests.dm b/code/unit_tests/equipment_tests.dm index 0779dfb8b5f0..3a1390139822 100644 --- a/code/unit_tests/equipment_tests.dm +++ b/code/unit_tests/equipment_tests.dm @@ -55,10 +55,10 @@ for(var/storage_type in typesof(/obj)) var/obj/thing = storage_type - if(TYPE_IS_ABSTRACT(thing) || !ispath(initial(thing.storage), /datum/storage)) + if(!TYPE_IS_SPAWNABLE(thing) || !ispath(initial(thing.storage), /datum/storage)) continue thing = new thing //should be fine to put it in nullspace... - var/bad_msg = "[ascii_red]--------------- [thing.name] \[[thing.type] | [thing.storage]\]" + var/bad_msg = "[ascii_red]--------------- [thing.name] \[[thing.type] | [thing.storage || "NULL"]\]" bad_tests += test_storage_capacity(thing.storage, bad_msg) if(bad_tests) From 09a9c76c1dae7fb379fb6808a44716fa082e467b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 13 Mar 2025 20:13:12 -0400 Subject: [PATCH 198/512] Fix issues with machine deconstruction --- code/game/machinery/washing_machine.dm | 5 +++-- code/modules/hydroponics/trays/tray.dm | 2 +- code/modules/recycling/sortingmachinery.dm | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm index 896044ff850f..f6e04eb2d50f 100644 --- a/code/game/machinery/washing_machine.dm +++ b/code/game/machinery/washing_machine.dm @@ -112,6 +112,9 @@ to_chat(user, SPAN_WARNING("\The [src] is currently running.")) return TRUE + if((. = ..())) + return + // If the detergent port is open and the item is an open container, assume we're trying to fill the detergent port. if(!(state & WASHER_STATE_CLOSED) && !((atom_flags & used_item.atom_flags) & ATOM_FLAG_OPEN_CONTAINER)) var/list/wash_whitelist = get_wash_whitelist() @@ -142,8 +145,6 @@ to_chat(user, SPAN_NOTICE("\The [src] is full.")) return TRUE - return ..() - /obj/machinery/washing_machine/physical_attack_hand(mob/user) if(state & WASHER_STATE_RUNNING) to_chat(user, SPAN_WARNING("\The [src] is currently running.")) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index a95e204e4e81..f3e74bd61470 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -497,7 +497,7 @@ to_chat(user, "You [anchored ? "wrench" : "unwrench"] \the [src].") return TRUE - if(seed) + if(user.check_intent(I_FLAG_HARM) && seed) var/force = used_item.expend_attack_force(user) if(force) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm index dcca3724725b..23146a957fc4 100644 --- a/code/modules/recycling/sortingmachinery.dm +++ b/code/modules/recycling/sortingmachinery.dm @@ -6,6 +6,8 @@ icon_state = "chute" base_type = /obj/machinery/disposal/deliveryChute/buildable frame_type = /obj/structure/disposalconstruct/machine/chute + // TODO: Convert attackby() override and c_mode vars to use construct states + construct_state = null var/c_mode = 0 From 1429dc4479783a703cb4e30912f5bc52cc5deef9 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 13 Mar 2025 23:06:06 -0400 Subject: [PATCH 199/512] Remove pump mode restriction from disposal deconstruction --- code/modules/recycling/disposal.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm index 18cbae82610c..efcccf407aac 100644 --- a/code/modules/recycling/disposal.dm +++ b/code/modules/recycling/disposal.dm @@ -68,8 +68,6 @@ var/global/list/diversion_junctions = list() return FALSE /obj/machinery/disposal/cannot_transition_to(state_path, mob/user) - if(mode > 0) - return SPAN_NOTICE("Turn off the pump first.") if(contents.len > LAZYLEN(component_parts)) return SPAN_NOTICE("Eject the items first!") return ..() @@ -263,7 +261,7 @@ var/global/list/diversion_junctions = list() if(isAI(user) && (href_list["handle"] || href_list["eject"])) return min(STATUS_UPDATE, ..()) if(mode==-1 && !href_list["eject"]) // only allow ejecting if mode is -1 - to_chat(user, "The disposal units power is disabled.") + to_chat(user, "The disposal unit's power is disabled.") return min(STATUS_UPDATE, ..()) if(flushing) return min(STATUS_UPDATE, ..()) From 13164dac3d3206dac497d36b3d6944ea7ba42ef4 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 13 Mar 2025 23:09:31 -0400 Subject: [PATCH 200/512] Fix AI slot component preventing computer deconstruction --- code/modules/modular_computers/hardware/ai_slot.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/modular_computers/hardware/ai_slot.dm b/code/modules/modular_computers/hardware/ai_slot.dm index 8550bb17b542..02594ca9006a 100644 --- a/code/modules/modular_computers/hardware/ai_slot.dm +++ b/code/modules/modular_computers/hardware/ai_slot.dm @@ -30,7 +30,7 @@ return TRUE do_insert_ai(user, used_item) return TRUE - if(IS_SCREWDRIVER(used_item)) + if(stored_card && IS_SCREWDRIVER(used_item)) to_chat(user, "You manually remove \the [stored_card] from \the [src].") do_eject_ai(user) return TRUE @@ -64,8 +64,9 @@ device.do_eject_ai(user) /obj/item/stock_parts/computer/ai_slot/proc/do_eject_ai(mob/user) - stored_card.dropInto(loc) - stored_card = null + if(stored_card) + stored_card.dropInto(loc) + stored_card = null loc.verbs -= /obj/item/stock_parts/computer/ai_slot/verb/eject_ai From 67b56ff95d8db11303951aa5ab74cfb9aa98d052 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 14 Mar 2025 23:50:03 -0400 Subject: [PATCH 201/512] Readd missing can_be_shackled var to utility frames --- mods/species/utility_frames/species_bodytypes.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/species/utility_frames/species_bodytypes.dm b/mods/species/utility_frames/species_bodytypes.dm index 57475c6f023c..93fb453bf777 100644 --- a/mods/species/utility_frames/species_bodytypes.dm +++ b/mods/species/utility_frames/species_bodytypes.dm @@ -28,6 +28,7 @@ /decl/sprite_accessory/marking/frame/plating/head = "#8888cc" ) ) + can_be_shackled = TRUE /decl/bodytype/prosthetic/utility_frame/Initialize() equip_adjust = list( From 8849430c464e05a14e832de0c40315f7822e44fe Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 14 Mar 2025 23:35:34 -0400 Subject: [PATCH 202/512] Change the default choice when being given an item to 'yes' --- code/modules/mob/living/living_give.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/living_give.dm b/code/modules/mob/living/living_give.dm index c4c6005de68c..724a5af6cf98 100644 --- a/code/modules/mob/living/living_give.dm +++ b/code/modules/mob/living/living_give.dm @@ -21,7 +21,7 @@ to_chat(usr, SPAN_WARNING("You can't give someone a grab.")) return usr.visible_message(SPAN_NOTICE("\The [usr] holds out \the [I] to \the [target]."), SPAN_NOTICE("You hold out \the [I] to \the [target], waiting for them to accept it.")) - if(alert(target,"[src] wants to give you \a [I]. Will you accept it?",,"No","Yes") == "No") + if(alert(target,"[src] wants to give you \a [I]. Will you accept it?",,"Yes","No") == "No") target.visible_message(SPAN_NOTICE("\The [src] tried to hand \the [I] to \the [target], \ but \the [target] didn't want it.")) return From 0c4c57ca8392310b2f951322eded0a697ee5ed89 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 14 Mar 2025 13:35:59 -0400 Subject: [PATCH 203/512] Fix #4932 properly --- code/_onclick/hud/screen/screen_inventory.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/_onclick/hud/screen/screen_inventory.dm b/code/_onclick/hud/screen/screen_inventory.dm index b65e32c82bd1..9ef46a9eebd1 100644 --- a/code/_onclick/hud/screen/screen_inventory.dm +++ b/code/_onclick/hud/screen/screen_inventory.dm @@ -61,6 +61,11 @@ MA.plane = HUD_PLANE MA.alpha = 80 MA.color = mouse_over_atom.mob_can_equip(owner, slot_id, TRUE) ? COLOR_GREEN : COLOR_RED + // We don't respect default_pixel_x or similar here because items should always be centered in their slots; defaults are for world-space. + MA.pixel_x = 0 + MA.pixel_y = 0 + MA.pixel_w = 0 + MA.pixel_z = 0 MA.appearance_flags |= (KEEP_TOGETHER | RESET_COLOR) // We need to color the entire thing, overlays and underlays included. for(var/image/overlay in MA.overlays) From 5bd79ae828ee65d870a626cd4666145a69400478 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 19 Mar 2025 00:53:34 +0000 Subject: [PATCH 204/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 054c758e54cc..a7c34018912c 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -132,12 +132,6 @@

      MistakeNot4892 updated:

    • The Shaded Hills river now flows north.
    • Snow, mud and sand will now show footprints.
    - -

    15 January 2025

    -

    MistakeNot4892 updated:

    -
      -
    • The way you interact with barrels and well has been significantly reworked; clicking with a bucket or tool should give a list of options to pick from. Please report bugs with this on the tracker.
    • -
    From d38c08531adae51e0b276d61f3624d896f28a983 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 20 Mar 2025 00:52:41 +0000 Subject: [PATCH 205/512] Automatic changelog generation [ci skip] --- html/changelog.html | 8 -------- 1 file changed, 8 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index a7c34018912c..61865e32ceb1 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -124,14 +124,6 @@

    MistakeNot4892 updated:

    • Intents have been rewritten and moved, please report any issues with intent selection.
    - -

    16 January 2025

    -

    MistakeNot4892 updated:

    -
      -
    • The White and Minimalist HUD styles can now be customised to use a specific overlay color.
    • -
    • The Shaded Hills river now flows north.
    • -
    • Snow, mud and sand will now show footprints.
    • -
From 80406685b9f42c1ef335568902f9ee1d1a69f77d Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 23 Mar 2025 00:57:31 +0000 Subject: [PATCH 206/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 61865e32ceb1..4fac4c564df6 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -118,12 +118,6 @@

Penelope Haze updated:

  • Mud can now receive footprints with any reagent other than mud. No more conspicuously missing bloody footprints!
- -

19 January 2025

-

MistakeNot4892 updated:

-
    -
  • Intents have been rewritten and moved, please report any issues with intent selection.
  • -
From 454775a656a25b4a595cc0a0e18da30db4caf249 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Mar 2025 18:57:48 -0400 Subject: [PATCH 207/512] Fix Ian and other simplemobs attempting organ-based breathing --- code/modules/mob/living/simple_animal/_simple_animal.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/modules/mob/living/simple_animal/_simple_animal.dm b/code/modules/mob/living/simple_animal/_simple_animal.dm index 06ef7566c16c..76e68a5ab999 100644 --- a/code/modules/mob/living/simple_animal/_simple_animal.dm +++ b/code/modules/mob/living/simple_animal/_simple_animal.dm @@ -499,6 +499,12 @@ var/global/list/simplemob_icon_bitflag_cache = list() name = "quadruped animal" bodytype_flag = 0 bodytype_category = "quadrupedal animal body" + // Simple animal bodies don't have limbs or organs, currently. If that changes, remove or modify these overrides. + // These overrides prevent unnecessary processing. + has_limbs = list() + has_organ = list() + // Simple animals go through a different breathing process (handle_environment) than mobs that use organs do. + breathing_organ = null /mob/living/simple_animal/get_base_telegraphed_melee_accuracy() return telegraphed_melee_accuracy From 8dd90e04031f2246c4e166b6ac09c967158d7f9a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Mar 2025 19:30:42 -0400 Subject: [PATCH 208/512] Fix not being able to scan tanks with gas scanners --- code/game/objects/items/weapons/tanks/tanks.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index 7ab26cff0849..f1aa73795279 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -121,7 +121,7 @@ var/global/list/global/tank_gauge_cache = list() icon = loc if (istype(W, /obj/item/scanner/gas)) - return TRUE + return FALSE // allow afterattack to proceed if (istype(W,/obj/item/latexballon)) var/obj/item/latexballon/LB = W From 932f4332bd11ca786324cf478edc315afdf1b6b9 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Mar 2025 19:30:55 -0400 Subject: [PATCH 209/512] Fix breath scanner output being blank when not breathing --- .../objects/items/devices/scanners/breath.dm | 50 ++++++++++--------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/code/game/objects/items/devices/scanners/breath.dm b/code/game/objects/items/devices/scanners/breath.dm index 02583fae7f05..54c33683c738 100644 --- a/code/game/objects/items/devices/scanners/breath.dm +++ b/code/game/objects/items/devices/scanners/breath.dm @@ -52,10 +52,11 @@ else if(lungs.breath_fail_ratio < 1) breathing = "shallow" + var/has_breath = TRUE switch(breathing) if("none") . += "Alert: No breathing detected." - return + has_breath = FALSE if("shallow") . += "Subject's breathing is abnormally shallow." if("normal") @@ -86,30 +87,33 @@ // Reagent data. . += "[b]Reagent scan:[endb]" - var/print_reagent_default_message = TRUE - if (C.has_chemical_effect(CE_ALCOHOL, 1)) - . += "Alcohol detected in subject's breath." - print_reagent_default_message = FALSE - if (C.has_chemical_effect(CE_ALCOHOL_TOXIC, 1)) - . += "Subject is suffering from alcohol poisoning." - print_reagent_default_message = FALSE - - var/datum/reagents/inhaled = C.get_inhaled_reagents() - if(inhaled && inhaled.total_volume) - var/unknown = 0 - for(var/rtype in inhaled.reagent_volumes) - var/decl/material/R = GET_DECL(rtype) - if(R.scannable) - print_reagent_default_message = FALSE - . += "[capitalize(R.gas_name)] found in subject's breath." - else - ++unknown - if(unknown) + if(has_breath) + var/print_reagent_default_message = TRUE + if (C.has_chemical_effect(CE_ALCOHOL, 1)) + . += "Alcohol detected in subject's breath." + print_reagent_default_message = FALSE + if (C.has_chemical_effect(CE_ALCOHOL_TOXIC, 1)) + . += "Subject is suffering from alcohol poisoning." print_reagent_default_message = FALSE - . += "Non-medical reagent[(unknown > 1)?"s":""] found in subject's breath." - if(print_reagent_default_message) - . += "No results." + var/datum/reagents/inhaled = C.get_inhaled_reagents() + if(inhaled && inhaled.total_volume) + var/unknown = 0 + for(var/rtype in inhaled.reagent_volumes) + var/decl/material/R = GET_DECL(rtype) + if(R.scannable) + print_reagent_default_message = FALSE + . += "[capitalize(R.gas_name)] found in subject's breath." + else + ++unknown + if(unknown) + print_reagent_default_message = FALSE + . += "Non-medical reagent[(unknown > 1)?"s":""] found in subject's breath." + + if(print_reagent_default_message) + . += "No results." + else + . += "Unable to obtain breath sample!" header = jointext(header, null) . = jointext(.,"
") From 833e97d9c08dfcf6a47b8dc354ea918db16ce98d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 23 Mar 2025 18:46:56 -0400 Subject: [PATCH 210/512] Rewrite breath code for better modularity --- code/game/atoms.dm | 2 +- .../gasses/material_gas_mundane.dm | 4 +- .../liquids/materials_liquid_toxins.dm | 4 +- code/modules/mob/grab/normal/norm_kill.dm | 2 +- code/modules/mob/living/human/examine.dm | 4 +- code/modules/mob/living/human/human.dm | 2 +- .../mob/living/human/human_attackhand.dm | 2 +- code/modules/mob/living/living_breath.dm | 65 +++++++++++-------- code/modules/mob/living/living_defines.dm | 9 ++- code/modules/organs/internal/lungs.dm | 7 +- 10 files changed, 56 insertions(+), 45 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 09b5980c5523..4d964f5c4677 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -102,7 +102,7 @@ return null /** - Merge an exhaled air volume into air contents.. + Merge an exhaled air volume into air contents. */ /atom/proc/merge_exhaled_volume(datum/gas_mixture/exhaled) var/datum/gas_mixture/environment = return_air() diff --git a/code/modules/materials/definitions/gasses/material_gas_mundane.dm b/code/modules/materials/definitions/gasses/material_gas_mundane.dm index 4d21232b7ff2..cff373e83716 100644 --- a/code/modules/materials/definitions/gasses/material_gas_mundane.dm +++ b/code/modules/materials/definitions/gasses/material_gas_mundane.dm @@ -81,8 +81,8 @@ else if(dosage >= 0.25) warning_message = pick("a little dizzy","short of breath") warning_prob = 10 - if(istype(H) && dosage > 1 && H.ticks_since_last_successful_breath < 15) - H.ticks_since_last_successful_breath++ + if(istype(H) && dosage > 1 && H.suffocation_counter < 15) + H.suffocation_counter++ if(warning_message && prob(warning_prob)) to_chat(M, SPAN_WARNING("You feel [warning_message].")) diff --git a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm index d28aeeb98edc..348abd21f1c3 100644 --- a/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm +++ b/code/modules/materials/definitions/liquids/materials_liquid_toxins.dm @@ -131,8 +131,8 @@ /decl/material/liquid/heartstopper/affect_overdose(mob/living/victim, total_dose) ..() if(victim.stat != UNCONSCIOUS) - if(victim.ticks_since_last_successful_breath >= 10) - victim.ticks_since_last_successful_breath = max(10, victim.ticks_since_last_successful_breath-10) + if(victim.suffocation_counter >= 10) + victim.suffocation_counter = max(10, victim.suffocation_counter-10) victim.take_damage(2, OXY) SET_STATUS_MAX(victim, STAT_WEAK, 10) victim.add_chemical_effect(CE_NOPULSE, 1) diff --git a/code/modules/mob/grab/normal/norm_kill.dm b/code/modules/mob/grab/normal/norm_kill.dm index 28762d0cbc8a..e716be668640 100644 --- a/code/modules/mob/grab/normal/norm_kill.dm +++ b/code/modules/mob/grab/normal/norm_kill.dm @@ -27,4 +27,4 @@ SET_STATUS_MAX(affecting, STAT_WEAK, 5) //Should keep you down unless you get help. if(isliving(affecting)) var/mob/living/M = affecting - M.ticks_since_last_successful_breath = max(M.ticks_since_last_successful_breath + 2, 3) + M.suffocation_counter = max(M.suffocation_counter + 2, 3) diff --git a/code/modules/mob/living/human/examine.dm b/code/modules/mob/living/human/examine.dm index 2c36562f57b7..da4bb651a8d5 100644 --- a/code/modules/mob/living/human/examine.dm +++ b/code/modules/mob/living/human/examine.dm @@ -60,9 +60,9 @@ if(limb && limb.splinted && limb.splinted.loc == limb) . += "[use_He] [use_has] \a [limb.splinted] on [use_his] [limb.name]!" - if (src.stat) + if (stat) . += "[use_He] [use_is]n't responding to anything around [use_him] and seems to be unconscious." - if((stat == DEAD || is_asystole() || src.ticks_since_last_successful_breath) && distance <= 3) + if((stat == DEAD || is_asystole() || suffocation_counter) && distance <= 3) . += "[use_He] [use_does] not appear to be breathing." var/datum/reagents/touching_reagents = get_contact_reagents() diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index 5f1afb8faea7..85abc9b909fe 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -389,7 +389,7 @@ brain.mind.transfer_to(src) qdel(brain.loc) break - ticks_since_last_successful_breath = 0 + suffocation_counter = 0 ..() /mob/living/add_blood(mob/living/M, amount = 2, list/blood_data) diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm index 93d436e3a882..39c6d931df58 100644 --- a/code/modules/mob/living/human/human_attackhand.dm +++ b/code/modules/mob/living/human/human_attackhand.dm @@ -340,7 +340,7 @@ if(!lungs.handle_owner_breath(H.get_breath_from_environment(), 1)) if(!lungs.is_bruised()) - ticks_since_last_successful_breath = 0 + suffocation_counter = 0 to_chat(src, SPAN_NOTICE("You feel a breath of fresh air enter your lungs. It feels good.")) // Again. diff --git a/code/modules/mob/living/living_breath.dm b/code/modules/mob/living/living_breath.dm index 164a8503215e..69241dac54ae 100644 --- a/code/modules/mob/living/living_breath.dm +++ b/code/modules/mob/living/living_breath.dm @@ -15,39 +15,49 @@ /mob/living/proc/should_breathe() return ((life_tick % 2) == 0 || failed_last_breath || is_asystole()) -/mob/living/proc/try_breathe() +// These procs all have a lung organ as an argument to avoid having to do repeated get_bodytype and get_organ calls. +// It's a small optimization but it adds up if you have a lot of mobs breathing. + +/// This proc contains all of the logic for returning a gasmix datum to be used in other breath-related code. +/// Does not necessarily involve inhaling at all; that's obtain_new_breath()'s job. +/mob/living/proc/get_breath(obj/item/organ/internal/lungs/lungs) + // Handle optional pre-breath logic. If it returns TRUE, skip the breath entirely. + if(handle_pre_breath(lungs)) + return null + return obtain_new_breath(lungs) + +/// Return a gasmix representing newly-inhaled air. +/mob/living/proc/obtain_new_breath(obj/item/organ/internal/lungs/lungs) + var/static/datum/gas_mixture/vacuum = new //avoid having to create a new gas mixture for each breath in space + //Okay, we can breathe, now check if we can get air + var/volume_needed = get_breath_volume() + //First check for air from internals, then the local environment, then use vacuum + return get_breath_from_internal(volume_needed) || get_breath_from_environment(volume_needed) || vacuum + +/// Handles pre-breath checks. If this proc returns TRUE, breathing is skipped that tick. +/mob/living/proc/handle_pre_breath(obj/item/organ/internal/lungs/lungs) + //Check if we can breathe at all + if(handle_drowning() || (is_asystole() && !GET_CHEMICAL_EFFECT(src, CE_STABLE) && lungs.active_breathing)) //crit aka circulatory shock + . = TRUE + else if(suffocation_counter > 0) + // We aren't drowning or in asystole, but something else is suffocating us, so lower the counter and don't take a breath + suffocation_counter-- + . = TRUE + if(.) + // Gasp on average every 10 ticks + if (prob(10) && !is_asystole() && lungs.active_breathing) + INVOKE_ASYNC(src, PROC_REF(emote), /decl/emote/audible/gasp) + return TRUE + return FALSE // not handled, proceed with breathing +/mob/living/proc/try_breathe() var/decl/bodytype/root_bodytype = get_bodytype() if(!root_bodytype?.breathing_organ) return - - var/active_breathe = FALSE var/obj/item/organ/internal/lungs/lungs = get_organ(root_bodytype.breathing_organ, /obj/item/organ/internal/lungs) - if(lungs) - active_breathe = lungs.active_breathing - - var/datum/gas_mixture/breath = null - //First, check if we can breathe at all - if(handle_drowning() || (is_asystole() && !GET_CHEMICAL_EFFECT(src, CE_STABLE) && active_breathe)) //crit aka circulatory shock - ticks_since_last_successful_breath = max(2, ticks_since_last_successful_breath + 1) - - if(ticks_since_last_successful_breath>0) //Suffocating so do not take a breath - ticks_since_last_successful_breath-- - if (prob(10) && !is_asystole() && active_breathe) //Gasp per 10 ticks? Sounds about right. - INVOKE_ASYNC(src, PROC_REF(emote), "gasp") - else - //Okay, we can breathe, now check if we can get air - var/volume_needed = get_breath_volume() - breath = get_breath_from_internal(volume_needed) //First, check for air from internals - if(!breath) - breath = get_breath_from_environment(volume_needed) //No breath from internals so let's try to get air from our location - if(!breath) - var/static/datum/gas_mixture/vacuum //avoid having to create a new gas mixture for each breath in space - if(!vacuum) vacuum = new - breath = vacuum //still nothing? must be vacuum - + var/datum/gas_mixture/breath = get_breath(lungs) //if breath is null or vacuum, the lungs will handle it for us - failed_last_breath = (!lungs || nervous_system_failure()) ? 1 : lungs.handle_owner_breath(breath) + failed_last_breath = (!lungs || nervous_system_failure()) ? TRUE : lungs.handle_owner_breath(breath) handle_post_breath(breath) /mob/living/proc/get_breath_from_environment(var/volume_needed=STD_BREATH_VOLUME, var/atom/location = src.loc) @@ -135,7 +145,6 @@ . *= (!BP_IS_PROSTHETIC(heart)) ? get_pulse()/PULSE_NORM : 1.5 /mob/living/proc/handle_post_breath(datum/gas_mixture/breath) - if(!breath) return diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index aadc7cf7edf0..aed17db45348 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -33,9 +33,12 @@ VAR_PRIVATE/_on_fire = FALSE VAR_PRIVATE/_fire_intensity - var/ticks_since_last_successful_breath = 0 //if we failed to breathe last tick - var/failed_last_breath = FALSE //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks. - var/possession_candidate = FALSE // Can be possessed by ghosts if unplayed. + /// A suffocation counter representing the number of ticks we should fail to breathe. + var/suffocation_counter = 0 + /// This is used to determine if the mob failed a breath. If they did fail a breath, they will attempt to breathe each tick, otherwise just once per 4 ticks. + var/failed_last_breath = FALSE + /// Can be possessed by ghosts if unplayed. + var/possession_candidate = FALSE var/job = null//Living diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm index 9c6e8070cb68..6fdca0adbeb1 100644 --- a/code/modules/organs/internal/lungs.dm +++ b/code/modules/organs/internal/lungs.dm @@ -11,7 +11,7 @@ max_damage = 70 relative_size = 60 - var/active_breathing = 1 + var/active_breathing = TRUE var/has_gills = FALSE var/breath_type var/exhale_type @@ -86,14 +86,13 @@ poison_types = list(/decl/material/gas/chlorine = TRUE) exhale_type = /decl/material/gas/carbon_dioxide - /obj/item/organ/internal/lungs/Process() ..() if(!owner) return if(owner.vital_organ_missing_time) - owner.ticks_since_last_successful_breath = max(10, owner.ticks_since_last_successful_breath) + owner.suffocation_counter = max(10, owner.suffocation_counter) return if (germ_level > INFECTION_LEVEL_ONE && active_breathing) @@ -125,7 +124,7 @@ else to_chat(owner, "You're having trouble getting enough [breath_type]!") - owner.ticks_since_last_successful_breath = max(3, owner.ticks_since_last_successful_breath) + owner.suffocation_counter = max(3, owner.suffocation_counter) /obj/item/organ/internal/lungs/proc/rupture() var/obj/item/organ/external/parent = GET_EXTERNAL_ORGAN(owner, parent_organ) From 61f3cb396a822e248262fc554d4480190d241f1c Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Tue, 25 Mar 2025 03:57:48 +1100 Subject: [PATCH 211/512] Automatic changelog generation for PR #4968 [ci skip] --- html/changelogs/AutoChangeLog-pr-4968.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4968.yml diff --git a/html/changelogs/AutoChangeLog-pr-4968.yml b/html/changelogs/AutoChangeLog-pr-4968.yml new file mode 100644 index 000000000000..3149ada779ee --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4968.yml @@ -0,0 +1,8 @@ +author: Penelope Haze +changes: + - {balance: 'Adjusts how suffocation works, meaning characters who were drowning + or in asystole start breathing as soon as the issue is resolved, rather than + counting down a timer instead. This might make brief bouts of drowning/cardiac + arrest more survivable. Please report any weirdness with breathing/suffocation + on the issue tracker.'} +delete-after: true From 6efa7ff2e86f8dfcc835f050b817b61019e3721e Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Tue, 25 Mar 2025 00:54:21 +0000 Subject: [PATCH 212/512] Automatic changelog generation [ci skip] --- html/changelog.html | 12 ++++++------ html/changelogs/.all_changelog.yml | 7 +++++++ html/changelogs/AutoChangeLog-pr-4968.yml | 8 -------- 3 files changed, 13 insertions(+), 14 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4968.yml diff --git a/html/changelog.html b/html/changelog.html index 4fac4c564df6..be4c9f5af53c 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
+

25 March 2025

+

Penelope Haze updated:

+
    +
  • Adjusts how suffocation works, meaning characters who were drowning or in asystole start breathing as soon as the issue is resolved, rather than counting down a timer instead. This might make brief bouts of drowning/cardiac arrest more survivable. Please report any weirdness with breathing/suffocation on the issue tracker.
  • +
+

14 March 2025

Typhin updated:

    @@ -112,12 +118,6 @@

    MistakeNot4892 updated:

  • Swords on Shaded Hills can be sharpened using whetstones or grindstones.
  • Guns can now be fired from rigs regardless of dexterity.
- -

21 January 2025

-

Penelope Haze updated:

-
    -
  • Mud can now receive footprints with any reagent other than mud. No more conspicuously missing bloody footprints!
  • -
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 55fad9100e4a..e0248f4635e5 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -15003,3 +15003,10 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2025-03-14: Typhin: - bugfix: Allows parts/screwdrivers to be used on biogenerators +2025-03-25: + Penelope Haze: + - balance: Adjusts how suffocation works, meaning characters who were drowning or + in asystole start breathing as soon as the issue is resolved, rather than counting + down a timer instead. This might make brief bouts of drowning/cardiac arrest + more survivable. Please report any weirdness with breathing/suffocation on the + issue tracker. diff --git a/html/changelogs/AutoChangeLog-pr-4968.yml b/html/changelogs/AutoChangeLog-pr-4968.yml deleted file mode 100644 index 3149ada779ee..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4968.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: Penelope Haze -changes: - - {balance: 'Adjusts how suffocation works, meaning characters who were drowning - or in asystole start breathing as soon as the issue is resolved, rather than - counting down a timer instead. This might make brief bouts of drowning/cardiac - arrest more survivable. Please report any weirdness with breathing/suffocation - on the issue tracker.'} -delete-after: true From 78fe8f6f913e1838f0378a7f88d36d4bd940f451 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 26 Mar 2025 00:53:50 +0000 Subject: [PATCH 213/512] Automatic changelog generation [ci skip] --- html/changelog.html | 7 ------- 1 file changed, 7 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index be4c9f5af53c..eafddc8a7f18 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -111,13 +111,6 @@

MistakeNot4892 updated:

  • Various map changes to Bearcat, crashed pod, and several others. Please report issues!
- -

22 January 2025

-

MistakeNot4892 updated:

-
    -
  • Swords on Shaded Hills can be sharpened using whetstones or grindstones.
  • -
  • Guns can now be fired from rigs regardless of dexterity.
  • -
From 633715330bc6465b99c31e2a1ac311a3a0529289 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 25 Mar 2025 21:30:38 -0400 Subject: [PATCH 214/512] fix underpressure hardcoded 1atm --- code/modules/mob/living/human/life.dm | 14 ++++++++------ code/modules/species/species.dm | 3 +++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/human/life.dm b/code/modules/mob/living/human/life.dm index 8514c5a6d80f..0c4e6d4846eb 100644 --- a/code/modules/mob/living/human/life.dm +++ b/code/modules/mob/living/human/life.dm @@ -88,13 +88,15 @@ // Calculate how much of the environment pressure-difference affects the human. /mob/living/human/calculate_affecting_pressure(var/pressure) var/pressure_difference + var/species_safe_pressure = species.get_safe_pressure(src) + pressure_difference = abs(pressure - species_safe_pressure) // First get the absolute pressure difference. - if(pressure < ONE_ATMOSPHERE) // We are in an underpressure. - pressure_difference = ONE_ATMOSPHERE - pressure + /*if(pressure < species_safe_pressure) // We are in an underpressure. + pressure_difference = species_safe_pressure - pressure else //We are in an overpressure or standard atmosphere. - pressure_difference = pressure - ONE_ATMOSPHERE + pressure_difference = pressure - species_safe_pressure*/ if(pressure_difference < 5) // If the difference is small, don't bother calculating the fraction. pressure_difference = 0 @@ -107,10 +109,10 @@ // The difference is always positive to avoid extra calculations. // Apply the relative difference on a standard atmosphere to get the final result. // The return value will be the adjusted_pressure of the human that is the basis of pressure warnings and damage. - if(pressure < ONE_ATMOSPHERE) - return ONE_ATMOSPHERE - pressure_difference + if(pressure < species_safe_pressure) + return species_safe_pressure - pressure_difference else - return ONE_ATMOSPHERE + pressure_difference + return species_safe_pressure + pressure_difference /mob/living/human/handle_impaired_vision() diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index e2720ffd1596..2b8e4a628fca 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -742,3 +742,6 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 var/decl/background_category/background_cat = GET_DECL(cat_type) if(background_cat.background_flags & background_flag) return GET_DECL(default_background_info[cat_type]) + +/decl/species/proc/get_safe_pressure() + return (warning_high_pressure + warning_low_pressure)/2 \ No newline at end of file From f39c0f9f4d941e3bf474e089f5ff5121c9f7d01d Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 25 Mar 2025 22:00:50 -0400 Subject: [PATCH 215/512] clean up commented code --- code/modules/mob/living/human/life.dm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/code/modules/mob/living/human/life.dm b/code/modules/mob/living/human/life.dm index 0c4e6d4846eb..b6b9c2961886 100644 --- a/code/modules/mob/living/human/life.dm +++ b/code/modules/mob/living/human/life.dm @@ -90,13 +90,8 @@ var/pressure_difference var/species_safe_pressure = species.get_safe_pressure(src) - pressure_difference = abs(pressure - species_safe_pressure) // First get the absolute pressure difference. - /*if(pressure < species_safe_pressure) // We are in an underpressure. - pressure_difference = species_safe_pressure - pressure - - else //We are in an overpressure or standard atmosphere. - pressure_difference = pressure - species_safe_pressure*/ + pressure_difference = abs(pressure - species_safe_pressure) if(pressure_difference < 5) // If the difference is small, don't bother calculating the fraction. pressure_difference = 0 From 56a4127dd71a0948e8415196ab140d1229b438ae Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 27 Mar 2025 03:49:20 +1100 Subject: [PATCH 216/512] Automatic changelog generation for PR #4970 [ci skip] --- html/changelogs/AutoChangeLog-pr-4970.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4970.yml diff --git a/html/changelogs/AutoChangeLog-pr-4970.yml b/html/changelogs/AutoChangeLog-pr-4970.yml new file mode 100644 index 000000000000..1da7fafd1caa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4970.yml @@ -0,0 +1,4 @@ +author: Martin Rivard +changes: + - {tweak: removed calculate_affecting_pressure() hardcoding} +delete-after: true From e788ca1fca56435369378855054f2188e3e076df Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 26 Mar 2025 13:48:42 -0400 Subject: [PATCH 217/512] centralize flash behavior, add flash burn support --- code/game/machinery/flasher.dm | 25 +------------------------ code/modules/bodytype/_bodytype.dm | 2 ++ code/modules/mechs/equipment/combat.dm | 18 +----------------- code/modules/mob/living/living.dm | 12 ++++++++++++ code/modules/organs/internal/eyes.dm | 3 +++ 5 files changed, 19 insertions(+), 41 deletions(-) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 375bc0653cd4..1fefcc5ed634 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -71,30 +71,7 @@ continue var/flash_time = strength - if(isliving(viewer)) - if(viewer.eyecheck() > FLASH_PROTECTION_NONE) - continue - if(ishuman(viewer)) - var/mob/living/human/H = viewer - flash_time = round(H.get_flash_mod() * flash_time) - if(flash_time <= 0) - return - var/vision_organ_tag = H.get_vision_organ_tag() - if(vision_organ_tag) - var/obj/item/organ/internal/organ = GET_INTERNAL_ORGAN(H, vision_organ_tag) - if(organ && organ.is_bruised() && prob(organ.get_organ_damage() + 50)) - H.flash_eyes() - organ.adjust_organ_damage(rand(1, 5)) - - if(!viewer.is_blind()) - do_flash(viewer, flash_time) - -/obj/machinery/flasher/proc/do_flash(var/mob/living/victim, var/flash_time) - victim.flash_eyes() - ADJ_STATUS(victim, STAT_BLURRY, flash_time) - ADJ_STATUS(victim, STAT_CONFUSE, flash_time + 2) - SET_STATUS_MAX(victim, STAT_STUN, flash_time / 2) - SET_STATUS_MAX(victim, STAT_WEAK, 3) + viewer.handle_flashed(flash_time) /obj/machinery/flasher/emp_act(severity) if(stat & (BROKEN|NOPOWER)) diff --git a/code/modules/bodytype/_bodytype.dm b/code/modules/bodytype/_bodytype.dm index a805373f1b1b..a60007dda2e4 100644 --- a/code/modules/bodytype/_bodytype.dm +++ b/code/modules/bodytype/_bodytype.dm @@ -239,6 +239,8 @@ var/global/list/bodytypes_by_category = list() var/eye_blend = ICON_ADD /// Stun from blindness modifier. var/eye_flash_mod = 1 + //how much damage to take from being flashed (if any) + var/eye_flash_burn = 0 // Bodytype temperature damage thresholds. /// Cold damage level 1 below this point. -30 Celsium degrees diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index 6ab5b456ccbc..9ef1fedf828e 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -317,23 +317,7 @@ for (var/mob/living/O in oviewers(flash_range, owner)) if(istype(O)) - var/protection = O.eyecheck() - if(protection >= FLASH_PROTECTION_MODERATE) - return - - if(protection >= FLASH_PROTECTION_MINOR) - flash_time /= 2 - - if(ishuman(O)) - var/mob/living/human/H = O - flash_time = round(H.get_flash_mod() * flash_time) - if(flash_time <= 0) - return - - if(!O.is_blind()) - O.flash_eyes(FLASH_PROTECTION_MODERATE - protection) - SET_STATUS_MAX(O, STAT_BLURRY, flash_time) - SET_STATUS_MAX(O, STAT_CONFUSE, (flash_time + 2)) + O.handle_flashed(flash_time) /obj/item/mech_equipment/flash/attack_self(mob/user) . = ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index fbce10dfb123..b85cdfcb404c 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -869,6 +869,14 @@ default behaviour is: return I.get_flash_mod() return get_bodytype()?.eye_flash_mod +/mob/living/proc/get_flash_burn() + var/vision_organ_tag = get_vision_organ_tag() + if(vision_organ_tag) + var/obj/item/organ/internal/eyes/I = get_organ(vision_organ_tag, /obj/item/organ/internal/eyes) + if(I) + return I.get_flash_burn() + return get_bodytype()?.eye_flash_burn + /mob/living/proc/eyecheck() var/total_protection = flash_protection if(should_have_organ(BP_EYES)) @@ -1692,6 +1700,7 @@ default behaviour is: /mob/living/handle_flashed(var/flash_strength) var/safety = eyecheck() + var/flash_burn = get_flash_burn() if(safety >= FLASH_PROTECTION_MODERATE || flash_strength <= 0) // May be modified by human proc. return FALSE @@ -1699,6 +1708,9 @@ default behaviour is: SET_STATUS_MAX(src, STAT_STUN, (flash_strength / 2)) SET_STATUS_MAX(src, STAT_BLURRY, flash_strength) SET_STATUS_MAX(src, STAT_CONFUSE, (flash_strength + 2)) + + if(flash_burn > 0) + apply_damage(flash_strength * flash_burn/5, BURN, BP_HEAD, used_weapon = "Photon burns") if(flash_strength > 3) drop_held_items() if(flash_strength > 5) diff --git a/code/modules/organs/internal/eyes.dm b/code/modules/organs/internal/eyes.dm index 94e7e27418e3..27d1be46f409 100644 --- a/code/modules/organs/internal/eyes.dm +++ b/code/modules/organs/internal/eyes.dm @@ -22,6 +22,9 @@ /obj/item/organ/internal/eyes/proc/get_flash_mod() return bodytype.eye_flash_mod +/obj/item/organ/internal/eyes/proc/get_flash_burn() + return bodytype.eye_flash_burn + /obj/item/organ/internal/eyes/proc/get_darksight_range() return bodytype.eye_darksight_range From 324fcddbe2b41ea41dcd719c88689e081c54b6c9 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 26 Mar 2025 15:46:45 -0400 Subject: [PATCH 218/512] fix portable flasher offset --- code/game/machinery/flasher.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 1fefcc5ed634..edd7f125381e 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -86,6 +86,7 @@ desc = "A portable flashing device. Wrench to activate and deactivate. Cannot detect slow movements." icon_state = "pflash1" icon = 'icons/obj/machines/flash_portable.dmi' + directional_offset = @'{"NORTH":{"y":0}, "SOUTH":{"y":0}, "EAST":{"x":0}, "WEST":{"x":0}}' strength = 8 anchored = FALSE base_state = "pflash" From f9ff7bbab4078fc04fff784e1885a1366d3ac3ed Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 26 Mar 2025 15:50:43 -0400 Subject: [PATCH 219/512] mech flash afterattack --- code/modules/mechs/equipment/combat.dm | 28 +------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index 9ef1fedf828e..b2518d69aaeb 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -347,30 +347,4 @@ var/obj/item/cell/cell = owner.get_cell() cell.use(active_power_use * CELLRATE) - var/protection = O.eyecheck() - if(protection >= FLASH_PROTECTION_MAJOR) - return - - if(protection >= FLASH_PROTECTION_MODERATE) - flash_time /= 2 - - if(ishuman(O)) - var/mob/living/human/H = O - flash_time = round(H.get_flash_mod() * flash_time) - if(flash_time <= 0) - return - - if(!O.is_blind()) - O.flash_eyes(FLASH_PROTECTION_MAJOR - protection) - SET_STATUS_MAX(O, STAT_BLURRY, flash_time) - SET_STATUS_MAX(O, STAT_CONFUSE, (flash_time + 2)) - - if(isanimal(O)) //Hit animals a bit harder - SET_STATUS_MAX(O, STAT_STUN, flash_time) - else - SET_STATUS_MAX(O, STAT_STUN, (flash_time / 2)) - - if(flash_time > 3) - O.drop_held_items() - if(flash_time > 5) - SET_STATUS_MAX(O, STAT_WEAK, 2) + O.handle_flashed(flash_time) From a6f5dcc53d4c227aaffc64e98dd78199ed170fc1 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 26 Mar 2025 15:51:14 -0400 Subject: [PATCH 220/512] add support for non-stunning flashes --- code/modules/mechs/equipment/combat.dm | 2 +- code/modules/mob/living/living.dm | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm index b2518d69aaeb..750d69df49de 100644 --- a/code/modules/mechs/equipment/combat.dm +++ b/code/modules/mechs/equipment/combat.dm @@ -317,7 +317,7 @@ for (var/mob/living/O in oviewers(flash_range, owner)) if(istype(O)) - O.handle_flashed(flash_time) + O.handle_flashed(flash_time, do_stun = FALSE) /obj/item/mech_equipment/flash/attack_self(mob/user) . = ..() diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index b85cdfcb404c..043a2bc69b54 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1697,15 +1697,18 @@ default behaviour is: return range * range - 0.333 return range -/mob/living/handle_flashed(var/flash_strength) +/mob/living/handle_flashed(var/flash_strength, do_stun = TRUE) var/safety = eyecheck() var/flash_burn = get_flash_burn() - if(safety >= FLASH_PROTECTION_MODERATE || flash_strength <= 0) // May be modified by human proc. + var/flash_mod = get_flash_mod() + + if(safety >= FLASH_PROTECTION_MODERATE || flash_strength <= 0 || flash_mod <= 0) // May be modified by human proc. return FALSE flash_eyes(FLASH_PROTECTION_MODERATE - safety) - SET_STATUS_MAX(src, STAT_STUN, (flash_strength / 2)) + if(do_stun) + SET_STATUS_MAX(src, STAT_STUN, (flash_strength / 2)) SET_STATUS_MAX(src, STAT_BLURRY, flash_strength) SET_STATUS_MAX(src, STAT_CONFUSE, (flash_strength + 2)) @@ -1715,6 +1718,7 @@ default behaviour is: drop_held_items() if(flash_strength > 5) SET_STATUS_MAX(src, STAT_WEAK, 2) + return TRUE /mob/living/verb/showoff() set name = "Show Held Item" From 30b0405dd10ce08fdd00cade21ef8096a0f4c207 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 26 Mar 2025 16:03:53 -0400 Subject: [PATCH 221/512] do_stun fix --- code/modules/mob/living/human/human.dm | 2 +- code/modules/mob/living/silicon/silicon.dm | 2 +- code/modules/mob/mob.dm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index 85abc9b909fe..f2a5565b03e8 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -1019,7 +1019,7 @@ /mob/living/human/proc/post_setup(species_uid, datum/mob_snapshot/supplied_appearance) try_refresh_visible_overlays() //Do this exactly once per setup -/mob/living/human/handle_flashed(var/flash_strength) +/mob/living/human/handle_flashed(var/flash_strength, do_stun = FALSE) var/safety = eyecheck() if(safety < FLASH_PROTECTION_MODERATE) flash_strength = round(get_flash_mod() * flash_strength) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 8d293f584fa5..5e738a6f7c98 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -415,7 +415,7 @@ if(os) os.Process() -/mob/living/silicon/handle_flashed(var/flash_strength) +/mob/living/silicon/handle_flashed(var/flash_strength, do_stun = FALSE) SET_STATUS_MAX(src, STAT_PARA, flash_strength) SET_STATUS_MAX(src, STAT_WEAK, flash_strength) return TRUE diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index dca36aa57a61..b53f19cc41e3 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1156,7 +1156,7 @@ return FALSE -/mob/proc/handle_flashed(var/flash_strength) +/mob/proc/handle_flashed(var/flash_strength, do_stun = FALSE) return FALSE /mob/proc/do_flash_animation() From 11979bab238a398e220d6fcf2c3abe828067b841 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 27 Mar 2025 00:53:41 +0000 Subject: [PATCH 222/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-4970.yml | 4 ---- 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4970.yml diff --git a/html/changelog.html b/html/changelog.html index eafddc8a7f18..51d24fb53a78 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
+

27 March 2025

+

Martin Rivard updated:

+
    +
  • removed calculate_affecting_pressure() hardcoding
  • +
+

25 March 2025

Penelope Haze updated:

From 670f619dcb0158f0ee7e987999894fccf8433291 Mon Sep 17 00:00:00 2001 From: Cerebulon Date: Sun, 6 Apr 2025 20:59:54 +0100 Subject: [PATCH 264/512] Fix tajaran clothing overrides --- .../tajaran/icons/clothing/atmos/suit.dmi | Bin 901 -> 903 bytes .../tajaran/icons/clothing/atmos_alt/suit.dmi | Bin 824 -> 826 bytes .../icons/clothing/deathsquad/suit.dmi | Bin 1086 -> 1088 bytes .../icons/clothing/engineering/suit.dmi | Bin 2635 -> 2453 bytes .../icons/clothing/engineering_alt/suit.dmi | Bin 824 -> 826 bytes .../icons/clothing/excavation/suit.dmi | Bin 936 -> 938 bytes .../tajaran/icons/clothing/medical/suit.dmi | Bin 2217 -> 2218 bytes .../icons/clothing/medical_alt/suit.dmi | Bin 863 -> 865 bytes .../tajaran/icons/clothing/merc/suit.dmi | Bin 956 -> 958 bytes .../tajaran/icons/clothing/mining/suit.dmi | Bin 779 -> 781 bytes .../icons/clothing/mining_alt/suit.dmi | Bin 1143 -> 1145 bytes .../tajaran/icons/clothing/nasa/suit.dmi | Bin 1195 -> 1197 bytes .../tajaran/icons/clothing/pilot/suit.dmi | Bin 813 -> 815 bytes .../tajaran/icons/clothing/salvage/suit.dmi | Bin 1142 -> 1139 bytes .../tajaran/icons/clothing/sec/suit.dmi | Bin 905 -> 907 bytes .../tajaran/icons/clothing/sec_alt/suit.dmi | Bin 941 -> 943 bytes .../tajaran/icons/clothing/wizard/suit.dmi | Bin 969 -> 971 bytes 17 files changed, 0 insertions(+), 0 deletions(-) diff --git a/mods/species/tajaran/icons/clothing/atmos/suit.dmi b/mods/species/tajaran/icons/clothing/atmos/suit.dmi index 856901b8e11ee415dd21a4439074284deba956a2..a31a324c51b546cd7c7269cbea6eb9f4013edc2e 100644 GIT binary patch delta 51 zcmV-30L=e|2ZslcZ~=UgaZUq2GewcW7aR;1XIfEWZYqdv$fc~{>gNKs2mr89Avu{@ Jf$XvKk^0WC41SWll6zAt^tlQnxrKza+l6G_ypBi!&v&s2F4j7iU^gVs0vk aZOEmp;OgfBwgv!T(I8?fTKG+|=}`imJ{&0k diff --git a/mods/species/tajaran/icons/clothing/deathsquad/suit.dmi b/mods/species/tajaran/icons/clothing/deathsquad/suit.dmi index e55e927d5ec975a0838b2ec2a07da40eee6343a9..54641a3200ef76676f7490f84e3a1a930cdd1d37 100644 GIT binary patch delta 71 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 Nz{tQ1`&5q*{Xb`|$gNKs2mr89Avu{@ Jf$Xv2R|4(L6s70UIBWMUrqs4k+2sW2p4BsQDSZ?h;7KFtl;YB0=5PKV9_9ADq8qW HvEx?))gTlB diff --git a/mods/species/tajaran/icons/clothing/excavation/suit.dmi b/mods/species/tajaran/icons/clothing/excavation/suit.dmi index dc261cdcbfccf5bfa220e785b876a3ab37abb749..4cd8145d824899a79998ebaf1af1138548cfc6e1 100644 GIT binary patch delta 51 zcmV-30L=fW2dW2gNKs2mr89Avu{@ Jf$XvKwF2>n6)pe( delta 68 zcmV-K0K5OH2dD>-Z~=OeaZWTouz6V{3J#-Um$R()?kB;12r#CA+&eWnG1HusL Q2e42fIddwDK(Va-2cRz(s{jB1 delta 57 zcmV-90LK5S5vdW7BmsYsC0;33#3=-NYJlNvgu5BRALS%?gh*wdluyFhu$R PV9_9A46vn1v90|F=|>ve diff --git a/mods/species/tajaran/icons/clothing/medical_alt/suit.dmi b/mods/species/tajaran/icons/clothing/medical_alt/suit.dmi index 7b9f801e353411fb7faa90dcf669c94fdc65c1f8..ec3911d4b0ecb9dcdb319f888bea8d8b87d9ce56 100644 GIT binary patch delta 70 zcmV-M0J;C)2H^&fY5{zaYfd&lGesdOKc!N)I48d(zPL2AM2U+tC9|j)WDFN)T2W$d cDu`{!rL5rU=K{6}0I*OYIhk33?6K`~0@jZmQ2+n{ delta 68 zcmV-K0K5O;2HysdY5{tYYfdy(At^tlQnxrKza+l6G_ypBi!&v&s2F4j7iU^gVs0vk aZOEmp;OgfBwgv!T(I8?fTKG+|?{WgP*c_?= diff --git a/mods/species/tajaran/icons/clothing/merc/suit.dmi b/mods/species/tajaran/icons/clothing/merc/suit.dmi index 37bef8119e7a20e6be66694eb6eadfdcb884fcde..142f157f9e10b55448ad54cf70892735a6fa6907 100644 GIT binary patch delta 71 zcmV-N0J#6W2fhc8g#mn#hE6s=GesdOKc!N)I48d(zPL2AM2U+tC9|j)WDFN)T2W$d dDu`{!rL5rU=K{6}0I*OYIhk33?6U{~v;yl-9HRgL delta 69 zcmV-L0J{Ia2fPQ6g#mhzhE6n9At^tlQnxrKza+l6G_ypBi!&v&s2F4j7iU^gVs0vk bZOEmp;OgfBwgv!T(I8?fTKG+~3IVhN$qgI) diff --git a/mods/species/tajaran/icons/clothing/mining/suit.dmi b/mods/species/tajaran/icons/clothing/mining/suit.dmi index 0b6cc99dbfcabbb3cbf9083f7665a8db1e656f02..807bbbe1006766721d8f26ff85d0dea4fc14f341 100644 GIT binary patch delta 70 zcmV-M0J;B*28{-gTLFBLTuwGWGesdOKc!N)I48d(zPL2AM2U+tC9|j)WDFN)T2W$d cDu`{!rL5rU=K{6}0I*OYIhk33?6KZ00--J(Hvj+t delta 49 zcmV-10M7r728#xeTLF5JTuuR1k*yaT2p4BsQDSZ?h;7KFtl;YB0=5PKV9_9ADq8qW HvEVHN!hRER diff --git a/mods/species/tajaran/icons/clothing/mining_alt/suit.dmi b/mods/species/tajaran/icons/clothing/mining_alt/suit.dmi index 6c6a7e8b724d3be521c3398ee103feb7c39feb45..e0875569f4af2cc7b48285a61232d0ad1b101dfc 100644 GIT binary patch delta 71 zcmV-N0J#762>A$*!~uMf#ZERqGesdOKc!N)I48d(zPL2AM2U+tC9|j)WDFN)T2W$d dDu`{!rL5rU=K{6}0I*OYIhk33?6XG!Fas;09aR7T delta 69 zcmV-L0J{JA2=@q(!~uGd#ZEL;At^tlQnxrKza+l6G_ypBi!&v&s2F4j7iU^gVs0vk bZOEmp;OgfBwgv!T(I8?fTKG+~NdYhe2Xh>* diff --git a/mods/species/tajaran/icons/clothing/nasa/suit.dmi b/mods/species/tajaran/icons/clothing/nasa/suit.dmi index a641b49608b5c0631ed857a54ba0a056df4e0d74..1106524e22b37eb12b5bc93cd27aaa49ddbbc782 100644 GIT binary patch delta 59 zcmV-B0L1^R39Si`!~uno#ZDVPGesdOKc!N)I48d(zPL2AM2U+tC9|j)WDJum0U8Qs R01~TLYQU6=MJZ delta 57 zcmV-90LK5V39AW^!~uhm#ZDPjAt^tlQnxrKza+l6G_ypBi!&v&s2F4jlP&=o3SI!S Pr6f=dyn@xUQUO~7gI^U+ diff --git a/mods/species/tajaran/icons/clothing/pilot/suit.dmi b/mods/species/tajaran/icons/clothing/pilot/suit.dmi index b11b61d8d69911d19de93cab69388f41745d958b..eeafe5468dd23c687fae9cc9962d9b2315465a91 100644 GIT binary patch delta 51 zcmV-30L=fb2CoK?UIBcOUrqx*GewcE7aR;1XIfEWZYqdv$fc~{>gNKs2mr89Avu{@ Jf$Xv2Oakd^6omi) delta 49 zcmV-10M7rf2CW8=UIBWMUrqs4k+2sW2p4BsQDSZ?h;7KFtl;YB0=5PKV9_9ADq8qW HvExhv(CQQ5 diff --git a/mods/species/tajaran/icons/clothing/salvage/suit.dmi b/mods/species/tajaran/icons/clothing/salvage/suit.dmi index df273abc4f408163149609581ea9631e4d2146d3..de86bbe11a8b1793400df1c1ddeca14b8d43485c 100644 GIT binary patch delta 928 zcmV;R17H012=fS#7ZpGV0{{R3owtGP0001TP)t-s0001yEN=v^gtDrUpHLDYoZ^zi zl2jm5DJ?Z8GcP|gMUw#m7k>;FXIfEWZYqdv$fc~{>gNKs2mr89Avu{@f$RVP11CvD zK~z|U?N?oM+%^mp0f}G;NV3S-Qc7MDC(i%>i(Osa>C__Khj#j8%-oIU7F;eweDH?h z!#?bPH+NbeCU)aEI;I}(#%Y>H*TcPpPuSp76yL!ehY;9xaJ6|^;eW6$vuO)g;`L#E zSedkmd)ZQ^g>u@&Up+L*O7rK(&oix(8Vt%$yVvZq`u*Sr0YzHoFTZ`67d$m^pIQ7e zZ}Z}X^F@Msj`FHNB3~t{V^;#nDijKyF9dpMl)D0nc)k)a6ckqoA1JuQfZ%G5kT6rs z6@gwu;3{FWWLuDWm468QwtwYs`#1i&-&!Gj_bD7(^>sT!@{JJO4M#jb%sA?syM|DG z(&M>i%lv$3^7RdV%RU}N;)LjkKHuIFU<)Wrrk0?wktw$yz}1bcz<*rV!wx0ODI4k0 zf`@~Bb&jj&HjZ4jMZGT8%;ft)sGC?DNAM>>qEZT_9)W2AL4VN>KCr3;7etlYxEV5x zSF<)gj41Uo78L#1#V3wO4-4CJ<2et$r~u?2c<2M=F{bLcn*sW&H#GVITIN8Itv1IR#V; z^E(#^lq4KR7k_#L0Tken-g3ceEDs%mSqg=496w)PURpSQ{&^fBP?5Pw@K}77xJ$~~ zCeWN@kCJ_PY%3_3j~hCBwl;yGuP+-0XXz*qe&T(xTAS;^P^&FFoTQ^bXss*BUfvGI zSF2@zb!jX3C7CS(&OL&R_0c%XueJhQlO$4-+&M=8iGQLzv9=Wqg?*~e+n!?^k9pso zYw}#$IQnJww$G*Z6x1^BhC}KRRE#~MRXYM8L02NPweyY!SBYwk+S>qADb~}cS1zGi z#eDDapBhitYOk1Fh_tSK0jGp@r5Jh&K#*#!?-2k_T>^(n#pS>{H=xrFo9<3+1{8W( z;ydr~{$Up5QbJn-rhmX2viCzc@i0yo2HYOP7?4W7TDKt~m8^QC5nSK=cS2OyAD0x0 zXIJU2M=yzl`^l-{?=K?!(df?6ul?zN2hINShy4!AoH9B??sB960000 delta 931 zcmV;U16=&`2=)k&7Zpqh0{{R3>UBYv0001TP)t-sz`($fEN=v&NM!?&pHLD&91E`E zlEji!AX6zVH77GKRg(b$7k>yBXIfEWZYqdv$fc~{>gNKs1^{ARAZT3gycPfe11d>G zK~z|U?N`xq+c*pq0hwS4NQ%fNQcJpR+VuZ_u`4$>Hy4q)hkLskGxlh_z;Z!?5IhWb zyW8FVNOOnvVPZFqqhspfZoFJBqwC>b!UrtyA&T$djzb9SI=I?2FMn`Y=E<~$EAjF$ zJuFPx#J#L3(@Z(7;?EwMWTENfNeu?&r_F2jS^c(igMcE<)2Gj$rWsES+-DX) zPwO;$;e3*yo};`fkjQ6=>e!V)vIvEO=M#bM8s(-yBA(9#33BP2`| zb48-(6u3%QE!i5Ro_{3*ziwan>-LquY}Zx_-+T)DT76yjkbENrcf}D;4-=01>dq-t zpLBn&*)l)xntXkOU$c)pkvJjRqtDm31XuzJlc^6ug-Dx+{RJMHmld!nw5Mz2z3|M#u5BQkf@YGsYhU1Kz~rQgAc4K!39y}Hg1Lr zC%+X^tON~9#YbAOHi5=D7pZ7UcG`&6ITEyp$< z^R_ppq-U65nVm*9% z*CkY|n6i5OhsFc8+Ph3HL|T@=*QwGCI7%LXH3c002ovPDHLk FV1j)vuDt*N diff --git a/mods/species/tajaran/icons/clothing/sec/suit.dmi b/mods/species/tajaran/icons/clothing/sec/suit.dmi index 1672208128ea4a2983560edc6a541257a5fe74af..ab3e3755309d16730bb5cb2c316164025f78cce9 100644 GIT binary patch delta 70 zcmV-M0J;B(2a5-gY5{zaYfd&lGesdOKc!N)I48d(zPL2AM2U+tC9|j)WDFN)T2W$d cDu`{!rL5rU=K{6}0I*OYIhk33?6K{f0;vxi(EtDd delta 68 zcmV-K0K5N-2Z;xeY5{tYYfdy(At^tlQnxrKza+l6G_ypBi!&v&s2F4j7iU^gVs0vk aZOEmp;OgfBwgv!T(I8?fTKG+|@0t delta 69 zcmV-L0J{IL2dxK?f&qGwgHAM6At^tlQnxrKza+l6G_ypBi!&v&s2F4j7iU^gVs0vk bZOEmp;OgfBwgv!T(I8?fTKG+~2LY%8zkM6Y diff --git a/mods/species/tajaran/icons/clothing/wizard/suit.dmi b/mods/species/tajaran/icons/clothing/wizard/suit.dmi index b8b7ed3ebd0b2ad97efee68680b224ce11a1e4f7..c27a511cc66270ee2ad8d716a36de45122188e40 100644 GIT binary patch delta 71 zcmV-N0J#6j2g?VLg#mn#hE6s=GesdOKc!N)I48d(zPL2AM2U+tC9|j)WDFN)T2W$d dDu`{!rL5rU=K{6}0I*OYIhk33?6U{~!2 Date: Sun, 13 Apr 2025 00:21:54 +1000 Subject: [PATCH 265/512] Automatic changelog generation for PR #4985 [ci skip] --- html/changelogs/AutoChangeLog-pr-4985.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4985.yml diff --git a/html/changelogs/AutoChangeLog-pr-4985.yml b/html/changelogs/AutoChangeLog-pr-4985.yml new file mode 100644 index 000000000000..080d86fbb9c5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4985.yml @@ -0,0 +1,4 @@ +author: Cerebulon +changes: + - {bugfix: Fixed tajaran sprite sheet overrides.} +delete-after: true From 71a8725605ff112220fd21c57b2d96c4a226a3e0 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 13 Apr 2025 02:24:40 +0000 Subject: [PATCH 266/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-4985.yml | 4 ---- 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4985.yml diff --git a/html/changelog.html b/html/changelog.html index 2403d9ab6b9a..37e63ea08cd9 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
+

13 April 2025

+

Cerebulon updated:

+
    +
  • Fixed tajaran sprite sheet overrides.
  • +
+

06 April 2025

Elizabeth updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index cc4fe1742e68..aa659926f105 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -15024,3 +15024,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - tweak: many of the buildings in Shaded Hills now use timber-framed, plastered, and/or wattle-and-daub walls instead of just log walls - soundadd: 'added a new lobby track to Shaded Hills: Adventure by Alexander Nakarada.' +2025-04-13: + Cerebulon: + - bugfix: Fixed tajaran sprite sheet overrides. diff --git a/html/changelogs/AutoChangeLog-pr-4985.yml b/html/changelogs/AutoChangeLog-pr-4985.yml deleted file mode 100644 index 080d86fbb9c5..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4985.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Cerebulon -changes: - - {bugfix: Fixed tajaran sprite sheet overrides.} -delete-after: true From f900b7613d9352e72a8f3a338538472ee6f43c91 Mon Sep 17 00:00:00 2001 From: Zandario Date: Fri, 11 Apr 2025 20:35:21 -0400 Subject: [PATCH 267/512] Add toggle browser inspect admin verb for debugging Web UIs --- code/modules/admin/admin_verbs.dm | 1 + code/modules/admin/verbs/debug.dm | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 9c203d83c176..52587d2a21d2 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -218,6 +218,7 @@ var/global/list/admin_verbs_debug = list( /datum/admins/proc/force_weather_state, /datum/admins/proc/force_kill_weather, /client/proc/force_reload_theme_css, + /client/proc/toggle_browser_inspect, ) var/global/list/admin_verbs_paranoid_debug = list( diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index edc6df1696af..6b3cd461505b 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -512,3 +512,26 @@ . += "" show_browser(usr, JOINTEXT(.), "window=dellog") + +/client/proc/toggle_browser_inspect() + set category = "Debug" + set name = "Toggle Browser Inspect" + + #if DM_VERSION >= 516 + + var/list/browser_options = winget(src, null, "browser-options") + + if(findtext(browser_options, "devtools") == TRUE) + // Disable the dev tools. + winset(src, null, list("browser-options" = "-devtools")) + message_admins("[key_name_admin(usr)] has disabled Browser Inspection.") + else + // Enable the dev tools. + winset(src, null, list("browser-options" = "+devtools")) + message_admins("[key_name_admin(usr)] has enabled Browser Inspection.") + + #else + + alert("Browser Inspection is not supported in this version of BYOND, please update to 516 or later.") + + #endif \ No newline at end of file From 0a6500edc7bd671635a521a023afd7e9b5cd0f75 Mon Sep 17 00:00:00 2001 From: Zandario Date: Fri, 11 Apr 2025 20:43:56 -0400 Subject: [PATCH 268/512] Fixed wrong variable type --- code/modules/admin/verbs/debug.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index 6b3cd461505b..de5d9bb426d5 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -519,7 +519,7 @@ #if DM_VERSION >= 516 - var/list/browser_options = winget(src, null, "browser-options") + var/browser_options = winget(src, null, "browser-options") if(findtext(browser_options, "devtools") == TRUE) // Disable the dev tools. From e54c2400170bf3eb78bf6a37ab8be590eb8c715d Mon Sep 17 00:00:00 2001 From: Zandario Date: Fri, 11 Apr 2025 20:45:04 -0400 Subject: [PATCH 269/512] Removed uneccessary condition check --- code/modules/admin/verbs/debug.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index de5d9bb426d5..c22ef2c4ab04 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -521,7 +521,7 @@ var/browser_options = winget(src, null, "browser-options") - if(findtext(browser_options, "devtools") == TRUE) + if(findtext(browser_options, "devtools")) // Disable the dev tools. winset(src, null, list("browser-options" = "-devtools")) message_admins("[key_name_admin(usr)] has disabled Browser Inspection.") From 1624050093fffd73611b67b3fc7977db02d9f13d Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 13 Apr 2025 23:27:11 +1000 Subject: [PATCH 270/512] Automatic changelog generation for PR #4987 [ci skip] --- html/changelogs/AutoChangeLog-pr-4987.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-4987.yml diff --git a/html/changelogs/AutoChangeLog-pr-4987.yml b/html/changelogs/AutoChangeLog-pr-4987.yml new file mode 100644 index 000000000000..875e999fdbbd --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-4987.yml @@ -0,0 +1,4 @@ +author: Zandario +changes: + - {admin: Added a "Toggle Browser Inspect" debug verb for debugging UIs} +delete-after: true From b24b7966e5d3253c8201b1dfea4d81a065d20e77 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Mon, 14 Apr 2025 00:57:55 +0000 Subject: [PATCH 271/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-4987.yml | 4 ---- 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-4987.yml diff --git a/html/changelog.html b/html/changelog.html index 37e63ea08cd9..b466000035d1 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
    +

    14 April 2025

    +

    Zandario updated:

    +
      +
    • Added a "Toggle Browser Inspect" debug verb for debugging UIs
    • +
    +

    13 April 2025

    Cerebulon updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index aa659926f105..6358b713724c 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -15027,3 +15027,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2025-04-13: Cerebulon: - bugfix: Fixed tajaran sprite sheet overrides. +2025-04-14: + Zandario: + - admin: Added a "Toggle Browser Inspect" debug verb for debugging UIs diff --git a/html/changelogs/AutoChangeLog-pr-4987.yml b/html/changelogs/AutoChangeLog-pr-4987.yml deleted file mode 100644 index 875e999fdbbd..000000000000 --- a/html/changelogs/AutoChangeLog-pr-4987.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Zandario -changes: - - {admin: Added a "Toggle Browser Inspect" debug verb for debugging UIs} -delete-after: true From 846aef4dca04535e4dec1c808ccd0ed25a077ef6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 14 Apr 2025 20:21:25 -0400 Subject: [PATCH 272/512] Fix simple_animal natural weapons not working --- code/_onclick/ai.dm | 2 +- code/_onclick/click.dm | 12 ++++--- code/_onclick/cyborg.dm | 2 +- code/_onclick/other_mobs.dm | 11 ++---- code/modules/mob/living/bot/cleanbot.dm | 2 +- code/modules/mob/living/bot/farmbot.dm | 2 +- code/modules/mob/living/bot/floorbot.dm | 2 +- code/modules/mob/living/bot/medibot.dm | 2 +- code/modules/mob/living/bot/mulebot.dm | 2 +- code/modules/mob/living/bot/secbot.dm | 2 +- .../mob/living/human/human_attackhand.dm | 2 +- .../simple_animal/friendly/farm_animals.dm | 35 +++++++++---------- mods/content/xenobiology/slime/slime_click.dm | 2 +- mods/mobs/borers/mob/borer/borer_attacks.dm | 4 +-- mods/mobs/dionaea/mob/nymph_attacks.dm | 2 +- .../ascent/mobs/nymph/nymph_attacks.dm | 2 +- 16 files changed, 42 insertions(+), 44 deletions(-) diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index e35ab0ceb7e0..061dbcfeeb95 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -72,7 +72,7 @@ The below is only really for safety, or you can alter the way it functions and re-insert it above. */ -/mob/living/silicon/ai/UnarmedAttack(atom/A) +/mob/living/silicon/ai/ResolveUnarmedAttack(atom/A) return A.attack_ai(src) /mob/living/silicon/ai/RangedAttack(atom/A, var/params) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 42298a21d64c..34085cc8a06f 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -187,8 +187,12 @@ /mob/proc/UnarmedAttack(var/atom/A, var/proximity_flag) return -/mob/living/UnarmedAttack(var/atom/A, var/proximity_flag) +/// Handles per-mob unarmed attack functionality after shared checks, e.g. maneuvers and abilities. +/mob/living/proc/ResolveUnarmedAttack(var/atom/A) + return A.attack_hand(src) +/mob/living/UnarmedAttack(var/atom/A, var/proximity_flag) + SHOULD_NOT_OVERRIDE(TRUE) if(GAME_STATE < RUNLEVEL_GAME) to_chat(src, "You cannot attack people before the game has started.") return TRUE @@ -204,11 +208,11 @@ // Special glove functions: // If the gloves do anything, have them return 1 to stop // normal attack_hand() here. - var/obj/item/clothing/gloves/G = get_equipped_item(slot_gloves_str) // not typecast specifically enough in defines - if(istype(G) && G.Touch(A,1)) + var/obj/item/clothing/gloves/G = get_equipped_item(slot_gloves_str) + if(istype(G) && G.Touch(A, proximity_flag)) return TRUE - return A.attack_hand(src) + return ResolveUnarmedAttack(A) /* Ranged unarmed attack: diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 45b5e45bf42d..b831ff5ed5d6 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -159,7 +159,7 @@ clicks, you can do so here, but you will have to change attack_robot() above to the proper function */ -/mob/living/silicon/robot/UnarmedAttack(atom/A) +/mob/living/silicon/robot/ResolveUnarmedAttack(atom/A) return A.attack_robot(src) /mob/living/silicon/robot/RangedAttack(atom/A, var/params) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 49bf7f7047f3..e2e95e9a0104 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -51,7 +51,7 @@ return climb_up(A) var/obj/item/clothing/gloves/G = get_equipped_item(slot_gloves_str) - if(istype(G) && G.Touch(A,0)) // for magic gloves + if(istype(G) && G.Touch(A, FALSE)) // for magic gloves return TRUE . = ..() @@ -92,13 +92,8 @@ /* Animals */ - -/mob/living/simple_animal/UnarmedAttack(var/atom/A, var/proximity) - - . = ..() - if(.) - return - +/// Make unarmed attacks use natural weapons on harm intent. +/mob/living/simple_animal/ResolveUnarmedAttack(atom/A) var/attacking_with = get_natural_weapon() if(a_intent == I_HELP || !attacking_with) return A.attack_animal(src) diff --git a/code/modules/mob/living/bot/cleanbot.dm b/code/modules/mob/living/bot/cleanbot.dm index b3745bee6e3c..22c803e19495 100644 --- a/code/modules/mob/living/bot/cleanbot.dm +++ b/code/modules/mob/living/bot/cleanbot.dm @@ -56,7 +56,7 @@ if(get_turf(target) == src.loc) UnarmedAttack(target, TRUE) -/mob/living/bot/cleanbot/UnarmedAttack(var/obj/effect/decal/cleanable/decal, var/proximity) +/mob/living/bot/cleanbot/ResolveUnarmedAttack(var/obj/effect/decal/cleanable/decal) if(!istype(decal)) return TRUE diff --git a/code/modules/mob/living/bot/farmbot.dm b/code/modules/mob/living/bot/farmbot.dm index ed489cb437f3..b6c0467d4a2f 100644 --- a/code/modules/mob/living/bot/farmbot.dm +++ b/code/modules/mob/living/bot/farmbot.dm @@ -141,7 +141,7 @@ makeStep(target_path) return -/mob/living/bot/farmbot/UnarmedAttack(var/atom/A, var/proximity) +/mob/living/bot/farmbot/ResolveUnarmedAttack(var/atom/A) if(busy) return TRUE diff --git a/code/modules/mob/living/bot/floorbot.dm b/code/modules/mob/living/bot/floorbot.dm index e7d49f1a1aa1..e2e6fa799b57 100644 --- a/code/modules/mob/living/bot/floorbot.dm +++ b/code/modules/mob/living/bot/floorbot.dm @@ -128,7 +128,7 @@ return emagged || (amount && (my_turf.is_floor_damaged() || (improvefloors && !my_turf.has_flooring()))) -/mob/living/bot/floorbot/UnarmedAttack(var/atom/A, var/proximity) +/mob/living/bot/floorbot/ResolveUnarmedAttack(var/atom/A) if(busy) return TRUE diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm index b07b3e25de47..fb1bf002165b 100644 --- a/code/modules/mob/living/bot/medibot.dm +++ b/code/modules/mob/living/bot/medibot.dm @@ -95,7 +95,7 @@ last_newpatient_speak = world.time break -/mob/living/bot/medbot/UnarmedAttack(var/mob/living/human/target, var/proximity) +/mob/living/bot/medbot/ResolveUnarmedAttack(var/mob/living/human/target) if(!on || !istype(target)) return FALSE diff --git a/code/modules/mob/living/bot/mulebot.dm b/code/modules/mob/living/bot/mulebot.dm index c70a617e2c1c..1606e830de0b 100644 --- a/code/modules/mob/living/bot/mulebot.dm +++ b/code/modules/mob/living/bot/mulebot.dm @@ -193,7 +193,7 @@ return ..() -/mob/living/bot/mulebot/UnarmedAttack(var/turf/T) +/mob/living/bot/mulebot/ResolveUnarmedAttack(var/turf/T) if(T == src.loc) unload(dir) diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 40b6329c70b0..5fea5fe9bde2 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -194,7 +194,7 @@ return BP_CHEST return ..() -/mob/living/bot/secbot/UnarmedAttack(var/mob/M, var/proximity) +/mob/living/bot/secbot/ResolveUnarmedAttack(var/mob/M) if(!istype(M)) return FALSE diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm index 68fd260a1613..47316b68392d 100644 --- a/code/modules/mob/living/human/human_attackhand.dm +++ b/code/modules/mob/living/human/human_attackhand.dm @@ -428,7 +428,7 @@ to_chat(src, SPAN_NOTICE(summary)) attack_selector?.update_icon() -/mob/living/human/UnarmedAttack(atom/A, proximity_flag) +/mob/living/human/ResolveUnarmedAttack(atom/A) // Hackfix for humans trying to attack someone without hands. // Dexterity ect. should be checked in these procs regardless, // but unarmed attacks that don't require hands should still diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index b6ef75bef106..980ebfb1733b 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -27,7 +27,7 @@ body.visible_message(SPAN_DANGER("\The [body] gets an evil-looking gleam in [pronouns.his] eye.")) /datum/mob_controller/aggressive/goat/proc/find_edible_atom(list/targets) - // TODO: add /obj/structure/flora here and in goat/UnarmedAttack() + // TODO: add /obj/structure/flora here and in goat/ResolveUnarmedAttack() var/atom/maybe_food = locate(/obj/effect/vine) in targets if(!istype(maybe_food)) for(var/obj/machinery/portable_atmospherics/hydroponics/tray in targets) @@ -74,25 +74,24 @@ . = ..() set_extension(src, /datum/extension/milkable/goat) -/mob/living/simple_animal/hostile/goat/UnarmedAttack(var/atom/A, var/proximity) +/mob/living/simple_animal/hostile/goat/ResolveUnarmedAttack(var/atom/A) var/was_food = FALSE - if(proximity) - if(prob(30)) - if(istype(A, /obj/effect/vine)) - var/obj/effect/vine/SV = A - SV.die_off(1) + if(prob(30)) + if(istype(A, /obj/effect/vine)) + var/obj/effect/vine/SV = A + SV.die_off(1) + was_food = TRUE + else if(istype(A, /obj/machinery/portable_atmospherics/hydroponics)) + var/obj/machinery/portable_atmospherics/hydroponics/tray = A + if(tray.seed) was_food = TRUE - else if(istype(A, /obj/machinery/portable_atmospherics/hydroponics)) - var/obj/machinery/portable_atmospherics/hydroponics/tray = A - if(tray.seed) - was_food = TRUE - tray.die() - if(!QDELETED(tray)) - tray.remove_dead(silent = TRUE) // this will qdel invisible trays - if(was_food) - visible_message(SPAN_NOTICE("\The [src] eats \the [A].")) - - return was_food ? TRUE :..() + tray.die() + if(!QDELETED(tray)) + tray.remove_dead(silent = TRUE) // this will qdel invisible trays + if(was_food) + visible_message(SPAN_NOTICE("\The [src] eats \the [A].")) + return TRUE + return ..() /mob/living/simple_animal/cow name = "cow" diff --git a/mods/content/xenobiology/slime/slime_click.dm b/mods/content/xenobiology/slime/slime_click.dm index 10befbff0c3d..22746c6510e5 100644 --- a/mods/content/xenobiology/slime/slime_click.dm +++ b/mods/content/xenobiology/slime/slime_click.dm @@ -1,7 +1,7 @@ /mob/living/slime/RestrainedClickOn(var/atom/A) return FALSE -/mob/living/slime/UnarmedAttack(var/atom/A, var/proximity) +/mob/living/slime/ResolveUnarmedAttack(var/atom/A) . = ..() if(.) diff --git a/mods/mobs/borers/mob/borer/borer_attacks.dm b/mods/mobs/borers/mob/borer/borer_attacks.dm index 1cd2b76ceaf8..a34736ff34ef 100644 --- a/mods/mobs/borers/mob/borer/borer_attacks.dm +++ b/mods/mobs/borers/mob/borer/borer_attacks.dm @@ -1,9 +1,9 @@ -/mob/living/simple_animal/borer/UnarmedAttack(atom/A, proximity) +/mob/living/simple_animal/borer/ResolveUnarmedAttack(atom/A) if(host) return TRUE // We cannot click things outside of our host. - if(!isliving(A) || a_intent != I_GRAB || stat || !proximity) + if(!isliving(A) || a_intent != I_GRAB || stat) return ..() if(!can_use_borer_ability(requires_host_value = FALSE, check_last_special = FALSE)) diff --git a/mods/mobs/dionaea/mob/nymph_attacks.dm b/mods/mobs/dionaea/mob/nymph_attacks.dm index fdfce5f87cb5..a3d0816684ed 100644 --- a/mods/mobs/dionaea/mob/nymph_attacks.dm +++ b/mods/mobs/dionaea/mob/nymph_attacks.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/alien/diona/UnarmedAttack(var/atom/A) +/mob/living/simple_animal/alien/diona/ResolveUnarmedAttack(var/atom/A) if(incapacitated()) return ..() diff --git a/mods/species/ascent/mobs/nymph/nymph_attacks.dm b/mods/species/ascent/mobs/nymph/nymph_attacks.dm index 59cc8dcea0ea..d5e982457300 100644 --- a/mods/species/ascent/mobs/nymph/nymph_attacks.dm +++ b/mods/species/ascent/mobs/nymph/nymph_attacks.dm @@ -1,4 +1,4 @@ -/mob/living/simple_animal/alien/kharmaan/UnarmedAttack(var/atom/A) +/mob/living/simple_animal/alien/kharmaan/ResolveUnarmedAttack(var/atom/A) . = ..() if(.) From 85c57f34b0de15a1a0cd27462ab3219aeff8b9ec Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Tue, 22 Apr 2025 00:55:51 +0000 Subject: [PATCH 273/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index b466000035d1..67af07b8f140 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -120,12 +120,6 @@

      Penelope Haze updated:

      • Human and unathi sprites should be slightly brighter now.
      - -

      18 February 2025

      -

      MistakeNot4892 updated:

      -
        -
      • Modifiers like regeneration or personal shielding will now show at the top of the screen.
      • -
    From 6797e6742373432c906911a7d19f232ba0eb1230 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Mon, 28 Apr 2025 00:58:04 +0000 Subject: [PATCH 274/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 67af07b8f140..13b7880bf540 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -114,12 +114,6 @@

    MistakeNot4892 updated:

    • Old browser-based module selection for robots has been removed, use the INV button to open storage like you would a belt/backpack.
    - -

    24 February 2025

    -

    Penelope Haze updated:

    -
      -
    • Human and unathi sprites should be slightly brighter now.
    • -
From 5a98a6fe0d1ab993214153ebf49564324f80ce76 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Tue, 18 Mar 2025 01:52:13 -0400 Subject: [PATCH 275/512] Improve wooden chest overlays --- icons/obj/closets/bases/chest.dmi | Bin 1872 -> 1914 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/closets/bases/chest.dmi b/icons/obj/closets/bases/chest.dmi index bef40525584deb2103b95053b0fbaabd9801ca3b..b43edd86460bcea5fb6d538226e14ed9105a5ae6 100644 GIT binary patch delta 1531 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 From 22406221f63f96a4bb26e480fbdcb757581cc71c Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Tue, 18 Mar 2025 02:24:41 -0400 Subject: [PATCH 276/512] Fix sharpened weapon damage calculation --- mods/content/item_sharpening/effect_sharpen.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/content/item_sharpening/effect_sharpen.dm b/mods/content/item_sharpening/effect_sharpen.dm index 5847ac347b36..b5703b653f4b 100644 --- a/mods/content/item_sharpening/effect_sharpen.dm +++ b/mods/content/item_sharpening/effect_sharpen.dm @@ -2,7 +2,7 @@ var/uses = LAZYACCESS(parameters, IE_PAR_USES) if(uses <= 0) return base_damage - . = (1 + ((uses / max(1, LAZYACCESS(parameters, IE_PAR_MAX_USES))) * LAZYACCESS(parameters, IE_PAR_SHARP_DAM_MULT))) + . = base_damage * (1 + ((uses / max(1, LAZYACCESS(parameters, IE_PAR_MAX_USES))) * LAZYACCESS(parameters, IE_PAR_SHARP_DAM_MULT))) /decl/item_effect/sharpened/expend_attack_use(obj/item/used_item, mob/user, list/parameters) var/uses = LAZYACCESS(parameters, IE_PAR_USES) From ec667ef7f6097c02b77a280c07daf8c9c3d203c7 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 20:53:05 -0400 Subject: [PATCH 277/512] Fix missing or broken icon states --- .../objects/structures/beds/simple_bed.dm | 4 ++-- code/game/objects/structures/benches/bench.dm | 2 +- .../clothing/neck/necklace/_pendant.dm | 1 + code/modules/gemstones/_gemstone.dm | 1 + icons/obj/structures/furniture/bench.dmi | Bin 1836 -> 1862 bytes icons/obj/structures/furniture/bench_wood.dmi | Bin 5423 -> 5535 bytes icons/obj/structures/furniture/lounge.dmi | Bin 3902 -> 3970 bytes icons/obj/structures/furniture/pew_wood.dmi | Bin 19787 -> 18361 bytes .../obj/structures/furniture/sofa_middle.dmi | Bin 2975 -> 2858 bytes 9 files changed, 5 insertions(+), 3 deletions(-) diff --git a/code/game/objects/structures/beds/simple_bed.dm b/code/game/objects/structures/beds/simple_bed.dm index 3092fc63a717..31a656cfa0a8 100644 --- a/code/game/objects/structures/beds/simple_bed.dm +++ b/code/game/objects/structures/beds/simple_bed.dm @@ -1,7 +1,7 @@ /obj/structure/bed/simple desc = "A slatted wooden bed." icon = 'icons/obj/structures/furniture/bed_simple.dmi' - icon_state = "bed_padded_preview" // For map editor preview purposes + icon_state = "world_padded_preview" // For map editor preview purposes parts_type = /obj/item/stack/material/plank material = /decl/material/solid/organic/wood/oak initial_padding_material = /decl/material/solid/organic/plantmatter/grass/dry @@ -48,7 +48,7 @@ /obj/structure/bed/simple/crafted initial_padding_material = null - icon_state = "bed" + icon_state = ICON_STATE_WORLD color = /decl/material/solid/organic/wood/oak::color /obj/item/bedsheet/furs diff --git a/code/game/objects/structures/benches/bench.dm b/code/game/objects/structures/benches/bench.dm index 30cf502c7213..16ba3b36eceb 100644 --- a/code/game/objects/structures/benches/bench.dm +++ b/code/game/objects/structures/benches/bench.dm @@ -3,7 +3,7 @@ name = "bench" desc = "A simple slatted bench." icon = 'icons/obj/structures/furniture/bench.dmi' - icon_state = ICON_STATE_WORLD + "_standing" + icon_state = ICON_STATE_WORLD + "_preview" color = WOOD_COLOR_GENERIC initial_padding_material = null material = /decl/material/solid/organic/wood/oak diff --git a/code/modules/clothing/neck/necklace/_pendant.dm b/code/modules/clothing/neck/necklace/_pendant.dm index d29a9e6af27f..8b87b69213df 100644 --- a/code/modules/clothing/neck/necklace/_pendant.dm +++ b/code/modules/clothing/neck/necklace/_pendant.dm @@ -2,6 +2,7 @@ name = "pendant" desc = "A simple pendant." icon = 'icons/clothing/accessories/jewelry/pendants/square.dmi' + icon_state = ICON_STATE_WORLD abstract_type = /obj/item/pendant material = /decl/material/solid/metal/silver material_alteration = MAT_FLAG_ALTERATION_COLOR // We do manual name/desc handling for the gem. diff --git a/code/modules/gemstones/_gemstone.dm b/code/modules/gemstones/_gemstone.dm index d4e51499dd1f..54e970892efa 100644 --- a/code/modules/gemstones/_gemstone.dm +++ b/code/modules/gemstones/_gemstone.dm @@ -12,6 +12,7 @@ var/global/list/_available_gemstone_cuts name = "uncut gemstone" desc = "A hunk of uncut gemstone." icon = 'icons/obj/items/gemstones/uncut.dmi' + icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_TINY material = /decl/material/solid/gemstone/diamond material_alteration = MAT_FLAG_ALTERATION_COLOR // Name and desc are handled manually. diff --git a/icons/obj/structures/furniture/bench.dmi b/icons/obj/structures/furniture/bench.dmi index 80fda7a9a165a69e6635837aa98592dd9dcb20bf..0bf99b3e39271b8c2931f746611fe11bbcdd0b9d 100644 GIT binary patch delta 1721 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 a+9?3>E69-XKig|YGz6# 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 NGSD;8eW&dd@n5lrufhNT diff --git a/icons/obj/structures/furniture/lounge.dmi b/icons/obj/structures/furniture/lounge.dmi index 1323daaccd69af48d5dc7c5d40122d4f6550e01a..f377c4d7421beb8049c1837c6e9bf5ccea4c41b7 100644 GIT binary patch literal 3970 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 BN~{0? diff --git a/icons/obj/structures/furniture/pew_wood.dmi b/icons/obj/structures/furniture/pew_wood.dmi index cfc0b9d578e991d3d30badaf5f7bf702dd7a6925..7084548224ba10cc80d1f05c9ed60bf273aa4659 100644 GIT binary patch literal 18361 zcmX_o1y~%x*6iX0cXx;2?gWS6k_4Ba!9BRUOK=VD?(U1byCk@~^CtKH?|$F1i_K0? zPxm=>s_JZ*vZ6FH0s#UD1VWaTkx&I*xBh*>!vfC)OcvX~OP#yAhLePeqmjc8JEtGE zHXx8|Mq-=*LLV!dgykVtzHyK6>B{YE^nUtd z9>e8<#hi8CrcA*A=9yw?I0!@rl9doucg;BMu(TsQbUT0ChbNmt<~*ZPFUnp(5%ZimI?OMJ(dT5WJb-6h}G zmYsN7!t7=Fj7!%Ex_ChXH!0~Ra{4f6SBPnI5VBL=vT`+P>t?d;rrmD|NP^p{aLL+f zbDa(EjnQl2$!k)N>v5iKqYK*2x3BwQ1=QfnNuSHa8uIqc=RIi=!9~OOu7>tV+N30s zl}X1bq`X%sIOpw<#NA0Dx%X%U$jXkNCZXqhZ-ydD3<5zT3wLOn;|GpQr?za}ixb{e zd8MU)0}FGvx?XJG+x$Fy>#DqqX4SDkpUgdp{CqD}^`A!0BdyK_;)XTeY=_vft~orh z=&-`Kpf^HcKnEbhR8?CvveRY~jCZQkNUtU_0ph@skt#Hp0IJqO`?lbp^fLJ(kt_Mdx zJ6d}YJJ!`{w0YoezK(tq5ctau%1d6NPqwdGAFQmL-JckrI1@7SBCasS9F~W@U$Hix z`C(;a?S~56)|pyyYHeItnA4~Q9KaSgY;Zb}>E%`3yGIjW!U-aS%_%vhnCgpsG(fX` zIgMciLuN*Um-Av6Ws@cyE#2^2oK~)144dAo@ui-%kyuG0whu08+4%Uv)b?sjD}v>j zLv|;Hp+I!WlEw~vpzgIb#+g*4#->JcS#0--lU}y+&Gw*#A`xT|e2^H(S5CyO>^OZ` zQ9;zEAy%FWctkF4n#H`VsnMdD*)%%wN2Sr-d1iGaZ>)JYFUtS9o;$kDf@K9J1O}z; zl^D@~WTDaIH%ZKZozj<@4!s<(ldiPfEbxQ<@sUsdERsNz?FPZYcyVdCTJ|eau0M#J z0tDLdeszBN6V-KmVTkfs?v#&q-;KmG1qvkid>Nxn;_-aD*d~1c)8`#^(EFy(F%wuZ z5rpSHpJLtzvR{ADl0@(onyEH?7C^Yu=+FbJfn#QkZa>3-E`nIRTB=GoHAN(M>;uKg zInxxztJ zup?t^Uo5vDXR{qLR%1<`eyX!ZCgL#};H|=mJZtJ#tww2ephzypDbX;Iu!EXCABDg* zswIJ9ze8IJB;Ct(Sos5Oy?2i@t6rx`e{%h2ty5AZprtH+O#GaZk>Qk4R=>*Yc4ZX3 zyJ)laiJ1gWUi?Fd7+vCLFRu;5#&`vUKgFpo)yyipj(r;!l5T9Bo#410}UB-XD5s4bl zpNa136GJLe%cF;6ktvoCfa8~R4lC-k1 zH8R{zDNsX`ME^KCDx}{=6W)B$IDh@ML_PL%0i&97iPnH(%gKdB{H_uslW0=@^OXgO z%X17u$nqNslum~SuA`9=uwQ?36Kq+1O^*csK0OoT+;7%Or zgG#<0uR^&vy5UE#;&g>G1~f7GJF2OH$|H7_U90XD1~6~fB$EysC>lvxae-A&x;JIh zFcoZF|JN;o?bk<-O?1-jxb!stTsmben0CI`&qcG%SJxZqt%;@3hDc5;v=Vt5AF*

4*L+61hfTdZL6G5b*PZt=VY@SFt3 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 literal 19787 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

    !_kdkS|*~-z5|ouR!#B#K@WG+5P}00Bp$n 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 diff --git a/icons/obj/structures/furniture/sofa_middle.dmi b/icons/obj/structures/furniture/sofa_middle.dmi index 92a69a0146e3381d25119608a7721fd54a09fdf6..67794edf8386cfba104c68395594205a616fc5e9 100644 GIT binary patch delta 2629 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 delta 2747 zcma)4X*84#0~LdrjK-Fo8B1eQ)~wNtv6S5?o#VAD6+*UT$vixhRFjN&ZP{L1Ude08 z9z#mDq=?Bny~x9n$Oq^av(Tk$uB)YYLXg~u z`ceGJAj(Diq6|m}B#6?WJ;%HaL`jVzti?re{vBWfJ^d8a9XaMSA$6~|jJp_7B_MKt zi-y;(^ieV@RDw;|y`V`rQR<$w&Wz&#{$|E?p-0<>L%8dV?ws!>RzK9+7hgnZWUjr@?oU)gV2+PRk*beP072 z*FTho`rIj_0yn=U8WhH%VSmL=5N^-rwOSJk?>YOxp}M_j^zji^+WuYR!u8@cKf!cC zLpVG+){gUDrx9_Pb;?7#kp5tB-$&x-;sK1k1ueD|If=8?e#a*_pLR)P*Vbc58LIhS z0P2F?8W6E zo5J1UA-ObTr0RCjfWau7WFsEQSF|`n4_8ka)~Hc)AaIn(sA--)$*CUOjm-q^+Z={F z8v4Pafo8=CqU36Zv6T9qDK@o%f506>~5&i(nc_(wyjb zr~F|k9D-GQCyLLXVwRH2p%A#vToIyis}>VX*Cj}s;NC2LsR|zOaME0|7K<-_D;vG+ z6Zh*dB7U2x5qDu+@Jc@X#|LIt`b#_KMW?fFVWwWdKlI!APx_C!xJZiIS64a%0XJ*a zY&KGLKP%!PYf^+3q4lpn1kJ>!>VvF>$E4zN|2*jF-?O{B$HQ#cIK$vQi_g^^qgrFxx4m-IY_=c3*$C%UM{=@O?ve*_$nxf~!dj zJKYla(Usyd&ROsY*y+|Zq_S34H5JydjaJ@}Nma`M2p-|EW2Um5fp2TB(t+&wKZ3ARwL z5@h*-k8-V-K0wP{NsdGYJzre9?^!?(zrfq(pTyr_b6tEw?`_VY*-tk zX%4-&)(j(>I8HpgtVP5*GuXUs0W?f+xwngOxf^j|&pTYTHsIXF z1A2;FVWOYOe8lxLW4`_)FNPS7cirw*rc#F|yIWVz2UEx7^5c$5*cT8bWj2 zm~2VxIe5FQ3ywxj?)pt4fuu!-<;sI5Bsh~hG`fyZkXf+FO)IMVCU%h<^re22Qu63oelF-=$t@6AOhGIBcpS4{BU+w+#8ed!5BdcD~k{7rAg zRey}W$t!`FaE~y_pm8E3e1H}mWM$|${Ny$WN?8>e-Tr+oqdKShFKN)nA+%c^W5R(NU6mbRBo zk)%gUP;<~+4e+NK#dl^l=YaG3_))%nV(63XDZW<{Wj4sx_SOz!rECoY4sa-L{-_nP2zfDAp7OH zEIxrmy)IsSkzO9T($RK9&NC8C`(~@HuU?*YMhXgz$`V`U)a)i<72@BJ*%Tq&a8L>& zGs!!0xfBo>c)o&*57i4fCgnE|(SqteqXTBx&|-?XZH6~0Cv}h6euM#st@dmGP10-? zk-z#n?U{SW_SxjHyHR^L!JDc^@K-$ZQ1wfL(O{t4=X%H-7BXUab-SUAIN3Hj6)UdL zB>n0TEX(D`QhTZ&W9MPAO}YPKRq^!&9X(dTz+sJNNVt>JuzkG9@%#Nma=7ydDGB-n zWg71w!BHt~TR`sZmlXS7ULr*gH0)!0hmAZJMW2ppY<03zRcQ3GW_vGAGWI}uunW<(Aq8Urc0bod9*C}?w7v-Em zd(Y=;xA+__z62^8Eq z&w%C}f^AI%pAKffYUX;oX5~{h3qv*gJXohxnGs&!;grnkxtZE<A#iwm4#+e=Ret6HBhb$Hj z85uUDo|fFon+y4GW>2U@qIKFTZq=?{jlfvFrvq!!1 Date: Wed, 26 Mar 2025 20:46:53 -0400 Subject: [PATCH 278/512] Add mapping preview colours to various types --- code/game/objects/items/artifice/chain.dm | 1 + code/game/objects/items/artifice/hook.dm | 1 + code/game/objects/items/horseshoe.dm | 1 + code/game/objects/items/tools/shears.dm | 1 + .../objects/items/weapons/material/kitchen.dm | 5 ++ .../objects/items/weapons/material/stick.dm | 5 ++ .../items/weapons/shields/shield_crafting.dm | 2 + .../items/weapons/surgery_tools_ancient.dm | 3 +- code/game/objects/structures/drying_rack.dm | 2 + .../objects/structures/grandfather_clock.dm | 1 + code/game/objects/structures/hay.dm | 1 + code/game/objects/structures/pit.dm | 4 ++ code/game/objects/structures/travois.dm | 1 + code/modules/butchery/butchery_hook.dm | 1 + code/modules/butchery/butchery_products.dm | 1 + .../butchery/butchery_products_meat.dm | 4 +- .../butchery/butchery_products_meat_fish.dm | 1 + .../clothing/suits/armor/forged/_forged.dm | 1 + .../clothing/suits/armor/forged/plate.dm | 3 + code/modules/crafting/handmade_items.dm | 1 + code/modules/fishing/fishing_rod.dm | 2 + code/modules/gemstones/_gemstone.dm | 57 +++++++------------ .../mob/living/simple_animal/passive/horse.dm | 2 + .../reagents/reagent_containers/mortar.dm | 1 + code/modules/tools/subtypes/hammers.dm | 1 + mods/content/blacksmithy/anvil.dm | 1 + mods/content/blacksmithy/billet.dm | 1 + mods/content/blacksmithy/tongs.dm | 1 + mods/content/item_sharpening/whetstone.dm | 1 + 29 files changed, 70 insertions(+), 37 deletions(-) diff --git a/code/game/objects/items/artifice/chain.dm b/code/game/objects/items/artifice/chain.dm index 3a48abad4759..2e44bf586f62 100644 --- a/code/game/objects/items/artifice/chain.dm +++ b/code/game/objects/items/artifice/chain.dm @@ -6,4 +6,5 @@ icon_state = ICON_STATE_WORLD icon = 'icons/obj/items/chain.dmi' material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color material_alteration = MAT_FLAG_ALTERATION_ALL diff --git a/code/game/objects/items/artifice/hook.dm b/code/game/objects/items/artifice/hook.dm index c20c77b14801..c04401d873fb 100644 --- a/code/game/objects/items/artifice/hook.dm +++ b/code/game/objects/items/artifice/hook.dm @@ -5,4 +5,5 @@ icon_state = ICON_STATE_WORLD icon = 'icons/obj/items/hook.dmi' material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color material_alteration = MAT_FLAG_ALTERATION_ALL diff --git a/code/game/objects/items/horseshoe.dm b/code/game/objects/items/horseshoe.dm index 51746bbc206c..622dfaf99721 100644 --- a/code/game/objects/items/horseshoe.dm +++ b/code/game/objects/items/horseshoe.dm @@ -5,6 +5,7 @@ icon_state = ICON_STATE_WORLD icon = 'icons/obj/items/horseshoe.dmi' material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color material_alteration = MAT_FLAG_ALTERATION_ALL /// A horseshoe hung above a door. diff --git a/code/game/objects/items/tools/shears.dm b/code/game/objects/items/tools/shears.dm index b5958ab00254..47ff4cf48b7a 100644 --- a/code/game/objects/items/tools/shears.dm +++ b/code/game/objects/items/tools/shears.dm @@ -6,6 +6,7 @@ w_class = ITEM_SIZE_SMALL origin_tech = @'{"materials":1,"engineering":1}' material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color center_of_mass = @'{"x":18,"y":10}' attack_verb = list("sheared", "cut") sharp = TRUE diff --git a/code/game/objects/items/weapons/material/kitchen.dm b/code/game/objects/items/weapons/material/kitchen.dm index 750d92c2401f..344eb317abbf 100644 --- a/code/game/objects/items/weapons/material/kitchen.dm +++ b/code/game/objects/items/weapons/material/kitchen.dm @@ -10,6 +10,7 @@ attack_verb = list("bashed", "battered", "bludgeoned", "thrashed", "whacked") material = /decl/material/solid/organic/wood/oak material_alteration = MAT_FLAG_ALTERATION_ALL + color = /decl/material/solid/organic/wood/oak::color /obj/item/rollingpin/use_on_mob(mob/living/target, mob/living/user, animate = TRUE) if (user.has_genetic_condition(GENE_COND_CLUMSY) && prob(50) && user.try_unequip(src)) @@ -18,3 +19,7 @@ SET_STATUS_MAX(user, STAT_PARA, 2) return TRUE return ..() + +/obj/item/kitchen/rollingpin/walnut + material = /decl/material/solid/organic/wood/walnut + color = /decl/material/solid/organic/wood/walnut::color \ No newline at end of file diff --git a/code/game/objects/items/weapons/material/stick.dm b/code/game/objects/items/weapons/material/stick.dm index 8473904228e8..92faaca3265f 100644 --- a/code/game/objects/items/weapons/material/stick.dm +++ b/code/game/objects/items/weapons/material/stick.dm @@ -5,6 +5,7 @@ icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_NORMAL material = /decl/material/solid/organic/wood/oak + color = /decl/material/solid/organic/wood/oak::color attack_verb = list("poked", "jabbed") material_alteration = MAT_FLAG_ALTERATION_ALL lock_picking_level = 3 @@ -74,3 +75,7 @@ user.do_attack_animation(target) return TRUE return ..() + +/obj/item/stick/walnut + material = /decl/material/solid/organic/wood/walnut + color = /decl/material/solid/organic/wood/walnut::color \ No newline at end of file diff --git a/code/game/objects/items/weapons/shields/shield_crafting.dm b/code/game/objects/items/weapons/shields/shield_crafting.dm index 307db9bce88b..783be5a4e6e2 100644 --- a/code/game/objects/items/weapons/shields/shield_crafting.dm +++ b/code/game/objects/items/weapons/shields/shield_crafting.dm @@ -5,6 +5,7 @@ icon_state = ICON_STATE_WORLD icon = 'icons/obj/items/shield_fasteners.dmi' material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color material_alteration = MAT_FLAG_ALTERATION_ALL // TODO: single-step slapcrafting @@ -14,6 +15,7 @@ icon_state = ICON_STATE_WORLD abstract_type = /obj/item/shield_base material = /decl/material/solid/organic/wood/oak + color = /decl/material/solid/organic/wood/oak::color material_alteration = MAT_FLAG_ALTERATION_ALL var/wooden_icon var/fittings_type = /obj/item/shield_fasteners diff --git a/code/game/objects/items/weapons/surgery_tools_ancient.dm b/code/game/objects/items/weapons/surgery_tools_ancient.dm index f6f31166bfac..d9c4f6d27433 100644 --- a/code/game/objects/items/weapons/surgery_tools_ancient.dm +++ b/code/game/objects/items/weapons/surgery_tools_ancient.dm @@ -2,12 +2,13 @@ abstract_type = /obj/item/ancient_surgery icon_state = ICON_STATE_WORLD material = /decl/material/solid/metal/bronze + color = /decl/material/solid/metal/bronze::color + material_alteration = MAT_FLAG_ALTERATION_ALL matter = null obj_flags = OBJ_FLAG_CONDUCTIBLE w_class = ITEM_SIZE_SMALL origin_tech = @'{"materials":1,"biotech":1}' drop_sound = 'sound/foley/knifedrop3.ogg' - material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC /obj/item/ancient_surgery/proc/get_tool_properties() return diff --git a/code/game/objects/structures/drying_rack.dm b/code/game/objects/structures/drying_rack.dm index 40f44e2c3fc6..3feffa51de95 100644 --- a/code/game/objects/structures/drying_rack.dm +++ b/code/game/objects/structures/drying_rack.dm @@ -4,11 +4,13 @@ icon = 'icons/obj/drying_rack.dmi' icon_state = ICON_STATE_WORLD material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC var/obj/item/drying /obj/structure/drying_rack/ebony material = /decl/material/solid/organic/wood/ebony + color = /decl/material/solid/organic/wood/ebony::color /obj/structure/drying_rack/Destroy() QDEL_NULL(drying) diff --git a/code/game/objects/structures/grandfather_clock.dm b/code/game/objects/structures/grandfather_clock.dm index 24882cb59e6c..49f4b63c22b7 100644 --- a/code/game/objects/structures/grandfather_clock.dm +++ b/code/game/objects/structures/grandfather_clock.dm @@ -8,6 +8,7 @@ density = TRUE material = /decl/material/solid/organic/wood/mahogany material_alteration = MAT_FLAG_ALTERATION_ALL + color = /decl/material/solid/organic/wood/mahogany::color var/face_color = "#f0edc7" var/last_time var/decl/material/clockwork_mat = /decl/material/solid/metal/brass diff --git a/code/game/objects/structures/hay.dm b/code/game/objects/structures/hay.dm index 47fa6ac32056..71f6c73a0647 100644 --- a/code/game/objects/structures/hay.dm +++ b/code/game/objects/structures/hay.dm @@ -44,6 +44,7 @@ icon = 'icons/obj/structures/haystack.dmi' icon_state = ICON_STATE_WORLD material = /decl/material/solid/organic/plantmatter/grass/dry + color = /decl/material/solid/organic/plantmatter/grass/dry::color storage = /datum/storage/haystack material_alteration = MAT_FLAG_ALTERATION_COLOR atom_flags = ATOM_FLAG_CLIMBABLE diff --git a/code/game/objects/structures/pit.dm b/code/game/objects/structures/pit.dm index 3e906526c8db..245e55bce956 100644 --- a/code/game/objects/structures/pit.dm +++ b/code/game/objects/structures/pit.dm @@ -148,6 +148,7 @@ pixel_y = 8 anchored = TRUE material = /decl/material/solid/organic/wood/oak + color = /decl/material/solid/organic/wood/oak::color w_class = ITEM_SIZE_NORMAL material_alteration = MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC | MAT_FLAG_ALTERATION_COLOR var/message = "Unknown." @@ -214,6 +215,7 @@ destruction_start_message = "smashing" destruction_finish_message = "smashing" material = /decl/material/solid/stone/granite + color = /decl/material/solid/stone/granite::color // Gravemarker items. // TODO: unify with signs somehow? some of this behaviour is similar... @@ -223,6 +225,7 @@ icon = 'icons/obj/structures/gravestone.dmi' icon_state = "wood" material = /decl/material/solid/organic/wood/oak + color = /decl/material/solid/organic/wood/oak::color w_class = ITEM_SIZE_NORMAL material_alteration = MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC | MAT_FLAG_ALTERATION_COLOR var/gravemarker_type = /obj/structure/gravemarker @@ -232,6 +235,7 @@ name = "gravestone" icon_state = "stone" material = /decl/material/solid/stone/granite + color = /decl/material/solid/stone/granite::color gravemarker_type = /obj/structure/gravemarker/gravestone /obj/item/gravemarker/get_examine_strings(mob/user, distance, infix, suffix) diff --git a/code/game/objects/structures/travois.dm b/code/game/objects/structures/travois.dm index 781dc5b6487a..324972fbba5f 100644 --- a/code/game/objects/structures/travois.dm +++ b/code/game/objects/structures/travois.dm @@ -20,6 +20,7 @@ parts_type = /obj/item/stack/material/log material_alteration = MAT_FLAG_ALTERATION_ALL material = /decl/material/solid/organic/wood/oak + color = /decl/material/solid/organic/wood/oak::color /obj/structure/travois/walnut material = /decl/material/solid/organic/wood/walnut diff --git a/code/modules/butchery/butchery_hook.dm b/code/modules/butchery/butchery_hook.dm index c69c4f8ce2cd..1453bc7f051f 100644 --- a/code/modules/butchery/butchery_hook.dm +++ b/code/modules/butchery/butchery_hook.dm @@ -13,6 +13,7 @@ icon = 'icons/obj/structures/butchery.dmi' icon_state = "spike" material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME matter = list( DEFAULT_FURNITURE_MATERIAL = MATTER_AMOUNT_PRIMARY diff --git a/code/modules/butchery/butchery_products.dm b/code/modules/butchery/butchery_products.dm index edfdfa65796c..659416ea06c3 100644 --- a/code/modules/butchery/butchery_products.dm +++ b/code/modules/butchery/butchery_products.dm @@ -3,6 +3,7 @@ material_alteration = MAT_FLAG_ALTERATION_COLOR icon_state = ICON_STATE_WORLD material = /decl/material/solid/organic/meat + color = /decl/material/solid/organic/meat::color w_class = ITEM_SIZE_NORMAL volume = 20 nutriment_type = /decl/material/solid/organic/meat diff --git a/code/modules/butchery/butchery_products_meat.dm b/code/modules/butchery/butchery_products_meat.dm index 9907f21994ce..c9d2ca23778b 100644 --- a/code/modules/butchery/butchery_products_meat.dm +++ b/code/modules/butchery/butchery_products_meat.dm @@ -53,6 +53,7 @@ name = "piece" desc = "It tastes like you'd expect." material = /decl/material/solid/organic/meat/chicken + color = /decl/material/solid/organic/meat/chicken::color butchery_data = /decl/butchery_data/animal/small/fowl/chicken /obj/item/food/butchery/meat/chicken/game @@ -66,7 +67,8 @@ /obj/item/food/butchery/meat/xeno desc = "A slab of green meat. Smells like acid." icon_state = "xenomeat" - color = "#43de18" + color = "#43de18" // todo: add xenomeat material and use material alteration + material_alteration = MAT_FLAG_ALTERATION_NONE center_of_mass = @'{"x":16,"y":10}' bitesize = 6 butchery_data = /decl/butchery_data/xeno diff --git a/code/modules/butchery/butchery_products_meat_fish.dm b/code/modules/butchery/butchery_products_meat_fish.dm index 90040989b1ff..f0171f3ef6a3 100644 --- a/code/modules/butchery/butchery_products_meat_fish.dm +++ b/code/modules/butchery/butchery_products_meat_fish.dm @@ -8,6 +8,7 @@ nutriment_amt = 6 nutriment_type = /decl/material/solid/organic/meat/fish material = /decl/material/solid/organic/meat/fish + color = /decl/material/solid/organic/meat/fish::color drying_wetness = 60 dried_type = /obj/item/food/jerky/fish backyard_grilling_product = /obj/item/food/butchery/meat/fish/grilled diff --git a/code/modules/clothing/suits/armor/forged/_forged.dm b/code/modules/clothing/suits/armor/forged/_forged.dm index 8a9b2aa3db4d..d04b1a7c84e6 100644 --- a/code/modules/clothing/suits/armor/forged/_forged.dm +++ b/code/modules/clothing/suits/armor/forged/_forged.dm @@ -2,6 +2,7 @@ abstract_type = /obj/item/clothing/suit/armor/forged icon_state = ICON_STATE_WORLD material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color material_alteration = MAT_FLAG_ALTERATION_ALL armor_degradation_speed = 1 armor_type = /datum/extension/armor/ablative diff --git a/code/modules/clothing/suits/armor/forged/plate.dm b/code/modules/clothing/suits/armor/forged/plate.dm index dbd83bd806db..362908c31c1a 100644 --- a/code/modules/clothing/suits/armor/forged/plate.dm +++ b/code/modules/clothing/suits/armor/forged/plate.dm @@ -11,6 +11,7 @@ desc = "A form of segmented armor that covers the hands and arms, typically worn as part of plate mail." icon = 'icons/clothing/plate_armour/vambrace.dmi' material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color material_alteration = MAT_FLAG_ALTERATION_ALL body_parts_covered = SLOT_HANDS|SLOT_ARMS accessory_slot = ACCESSORY_SLOT_GREAVES @@ -20,6 +21,7 @@ desc = "Segmented armour that protects the feet and legs, typically worn as part of plate mail." icon = 'icons/clothing/plate_armour/sabatons.dmi' material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color material_alteration = MAT_FLAG_ALTERATION_ALL body_parts_covered = SLOT_FEET|SLOT_LOWER_BODY|SLOT_LEGS accessory_slot = ACCESSORY_SLOT_GAUNTLETS @@ -29,6 +31,7 @@ desc = "A visored helmet that covers the entire face and skull." icon = 'icons/clothing/plate_armour/helm.dmi' material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color material_alteration = MAT_FLAG_ALTERATION_ALL markings_color = COLOR_PURPLE markings_state_modifier = "-plume" diff --git a/code/modules/crafting/handmade_items.dm b/code/modules/crafting/handmade_items.dm index 93ae530b1134..75a8ac9650f2 100644 --- a/code/modules/crafting/handmade_items.dm +++ b/code/modules/crafting/handmade_items.dm @@ -2,6 +2,7 @@ abstract_type = /obj/item/chems/glass/handmade icon_state = ICON_STATE_WORLD material = /decl/material/solid/stone/pottery + color = /decl/material/solid/stone/pottery::color material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME presentation_flags = PRESENTATION_FLAG_NAME diff --git a/code/modules/fishing/fishing_rod.dm b/code/modules/fishing/fishing_rod.dm index a2935a323cad..ae8342c0f677 100644 --- a/code/modules/fishing/fishing_rod.dm +++ b/code/modules/fishing/fishing_rod.dm @@ -6,6 +6,7 @@ name = "fishing rod" desc = "A simple fishing rod with eyelets for stringing a line." material = /decl/material/solid/organic/wood/oak + color = /decl/material/solid/organic/wood/oak::color matter = null material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME | MAT_FLAG_ALTERATION_DESC icon = 'icons/obj/fishing_rod.dmi' @@ -341,6 +342,7 @@ name = "advanced fishing rod" desc = "It's a fishing rod, an enhanced fiberglass Telescope Ultralight 47; the latest model." material = /decl/material/solid/fiberglass + color = /decl/material/solid/fiberglass::color matter = list( /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT ) diff --git a/code/modules/gemstones/_gemstone.dm b/code/modules/gemstones/_gemstone.dm index 54e970892efa..b95cb57181d3 100644 --- a/code/modules/gemstones/_gemstone.dm +++ b/code/modules/gemstones/_gemstone.dm @@ -16,6 +16,7 @@ var/global/list/_available_gemstone_cuts w_class = ITEM_SIZE_TINY material = /decl/material/solid/gemstone/diamond material_alteration = MAT_FLAG_ALTERATION_COLOR // Name and desc are handled manually. + color = /decl/material/solid/gemstone/diamond::color var/decl/gemstone_cut/cut = /decl/gemstone_cut/uncut var/work_skill = SKILL_CONSTRUCTION @@ -91,38 +92,24 @@ var/global/list/_available_gemstone_cuts // Material subtypes. -/obj/item/gemstone/baguette/topaz - material = /decl/material/solid/gemstone/topaz - -/obj/item/gemstone/baguette/sapphire - material = /decl/material/solid/gemstone/sapphire - -/obj/item/gemstone/baguette/ruby - material = /decl/material/solid/gemstone/ruby - -/obj/item/gemstone/hexagon/topaz - material = /decl/material/solid/gemstone/topaz - -/obj/item/gemstone/hexagon/sapphire - material = /decl/material/solid/gemstone/sapphire - -/obj/item/gemstone/hexagon/ruby - material = /decl/material/solid/gemstone/ruby - -/obj/item/gemstone/octagon/topaz - material = /decl/material/solid/gemstone/topaz - -/obj/item/gemstone/octagon/sapphire - material = /decl/material/solid/gemstone/sapphire - -/obj/item/gemstone/octagon/ruby - material = /decl/material/solid/gemstone/ruby - -/obj/item/gemstone/round/topaz - material = /decl/material/solid/gemstone/topaz - -/obj/item/gemstone/round/sapphire - material = /decl/material/solid/gemstone/sapphire - -/obj/item/gemstone/round/ruby - material = /decl/material/solid/gemstone/ruby +#define MATERIAL_CUT_GEMSTONES(MAT)\ +/obj/item/gemstone/baguette/##MAT{\ + material = /decl/material/solid/gemstone/##MAT;\ + color = /decl/material/solid/gemstone/##MAT::color;\ +}\ +/obj/item/gemstone/hexagon/##MAT{\ + material = /decl/material/solid/gemstone/##MAT;\ + color = /decl/material/solid/gemstone/##MAT::color;\ +}\ +/obj/item/gemstone/octagon/##MAT{\ + material = /decl/material/solid/gemstone/##MAT;\ + color = /decl/material/solid/gemstone/##MAT::color;\ +}\ +/obj/item/gemstone/round/##MAT{\ + material = /decl/material/solid/gemstone/##MAT;\ + color = /decl/material/solid/gemstone/##MAT::color;\ +} + +MATERIAL_CUT_GEMSTONES(topaz) +MATERIAL_CUT_GEMSTONES(sapphire) +MATERIAL_CUT_GEMSTONES(ruby) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/passive/horse.dm b/code/modules/mob/living/simple_animal/passive/horse.dm index 04d58aa4ede2..f90f16747a10 100644 --- a/code/modules/mob/living/simple_animal/passive/horse.dm +++ b/code/modules/mob/living/simple_animal/passive/horse.dm @@ -14,6 +14,7 @@ can_have_rider = TRUE max_rider_size = MOB_SIZE_MEDIUM ai = /datum/mob_controller/passive/horse + color = "#ccc496" // preview color draw_visible_overlays = list( "base" = "#ccc496" ) @@ -30,6 +31,7 @@ /mob/living/simple_animal/passive/horse/Initialize() . = ..() + color = null // clear preview color add_inventory_slot(new /datum/inventory_slot/back/horse) equip_to_slot_or_del(new /obj/item/saddle(src), slot_back_str) if(!LAZYACCESS(draw_visible_overlays, "base")) diff --git a/code/modules/reagents/reagent_containers/mortar.dm b/code/modules/reagents/reagent_containers/mortar.dm index 5df6aa94e4c8..76cb59c9a98e 100644 --- a/code/modules/reagents/reagent_containers/mortar.dm +++ b/code/modules/reagents/reagent_containers/mortar.dm @@ -5,6 +5,7 @@ icon_state = ICON_STATE_WORLD volume = 40 material = /decl/material/solid/stone/basalt + color = /decl/material/solid/stone/basalt::color material_alteration = MAT_FLAG_ALTERATION_ALL storage = /datum/storage/hopper/mortar var/grinding = FALSE diff --git a/code/modules/tools/subtypes/hammers.dm b/code/modules/tools/subtypes/hammers.dm index acd258ef5c08..cd6871ce2546 100644 --- a/code/modules/tools/subtypes/hammers.dm +++ b/code/modules/tools/subtypes/hammers.dm @@ -86,6 +86,7 @@ /obj/item/tool/hammer/forge/iron material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color handle_material = /decl/material/solid/organic/wood/mahogany // Forging hammers are not great at general hammer tasks (too heavy I guess), diff --git a/mods/content/blacksmithy/anvil.dm b/mods/content/blacksmithy/anvil.dm index 0968a7806ce5..8c886cadf2c1 100644 --- a/mods/content/blacksmithy/anvil.dm +++ b/mods/content/blacksmithy/anvil.dm @@ -36,6 +36,7 @@ atom_flags = ATOM_FLAG_CLIMBABLE w_class = ITEM_SIZE_STRUCTURE //_LARGE material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color max_health = 1000 structure_flags = STRUCTURE_FLAG_SURFACE material_alteration = MAT_FLAG_ALTERATION_ALL diff --git a/mods/content/blacksmithy/billet.dm b/mods/content/blacksmithy/billet.dm index da40b1fcd00d..3a18225c09a6 100644 --- a/mods/content/blacksmithy/billet.dm +++ b/mods/content/blacksmithy/billet.dm @@ -26,6 +26,7 @@ icon = 'mods/content/blacksmithy/icons/billet.dmi' icon_state = ICON_STATE_WORLD material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color material_alteration = MAT_FLAG_ALTERATION_ALL var/decl/forging_step/current_forging_step = /decl/forging_step/billet diff --git a/mods/content/blacksmithy/tongs.dm b/mods/content/blacksmithy/tongs.dm index 624e790dc53a..173ccef04688 100644 --- a/mods/content/blacksmithy/tongs.dm +++ b/mods/content/blacksmithy/tongs.dm @@ -4,6 +4,7 @@ icon = 'mods/content/blacksmithy/icons/tongs.dmi' icon_state = ICON_STATE_WORLD material = /decl/material/solid/metal/iron + color = /decl/material/solid/metal/iron::color obj_flags = OBJ_FLAG_INSULATED_HANDLE material_alteration = MAT_FLAG_ALTERATION_ALL var/obj/item/holding_bar diff --git a/mods/content/item_sharpening/whetstone.dm b/mods/content/item_sharpening/whetstone.dm index cdfbb09eea51..09d3cd9de50a 100644 --- a/mods/content/item_sharpening/whetstone.dm +++ b/mods/content/item_sharpening/whetstone.dm @@ -5,6 +5,7 @@ w_class = ITEM_SIZE_TINY material_alteration = MAT_FLAG_ALTERATION_ALL material = /decl/material/solid/quartz + color = /decl/material/solid/quartz::color /obj/item/attackby(obj/item/used_item, mob/user) if(istype(used_item, /obj/item/whetstone)) From f85a7eaceedf82131433f9fbe506c1c753432a37 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 20:47:25 -0400 Subject: [PATCH 279/512] Make wood tiles take colour from material --- code/game/turfs/flooring/flooring_wood.dm | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/code/game/turfs/flooring/flooring_wood.dm b/code/game/turfs/flooring/flooring_wood.dm index b5fc086d42f4..c68b599d5554 100644 --- a/code/game/turfs/flooring/flooring_wood.dm +++ b/code/game/turfs/flooring/flooring_wood.dm @@ -9,7 +9,7 @@ build_type = /obj/item/stack/tile/wood flooring_flags = TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER footstep_type = /decl/footsteps/wood - color = /decl/material/solid/organic/wood/oak::color + color = null force_material = /decl/material/solid/organic/wood/oak constructed = TRUE gender = NEUTER @@ -24,32 +24,26 @@ ) /decl/flooring/wood/mahogany - color = /decl/material/solid/organic/wood/mahogany::color build_type = /obj/item/stack/tile/wood/mahogany force_material = /decl/material/solid/organic/wood/mahogany /decl/flooring/wood/maple - color = /decl/material/solid/organic/wood/maple::color build_type = /obj/item/stack/tile/wood/maple force_material = /decl/material/solid/organic/wood/maple /decl/flooring/wood/ebony - color = /decl/material/solid/organic/wood/ebony::color build_type = /obj/item/stack/tile/wood/ebony force_material = /decl/material/solid/organic/wood/ebony /decl/flooring/wood/walnut - color = /decl/material/solid/organic/wood/walnut::color build_type = /obj/item/stack/tile/wood/walnut force_material = /decl/material/solid/organic/wood/walnut /decl/flooring/wood/bamboo - color = /decl/material/solid/organic/wood/bamboo::color build_type = /obj/item/stack/tile/wood/bamboo force_material = /decl/material/solid/organic/wood/bamboo /decl/flooring/wood/yew - color = /decl/material/solid/organic/wood/yew::color build_type = /obj/item/stack/tile/wood/yew force_material = /decl/material/solid/organic/wood/yew @@ -65,32 +59,26 @@ broken_states = null /decl/flooring/wood/rough/mahogany - color = /decl/material/solid/organic/wood/mahogany::color build_type = /obj/item/stack/tile/wood/rough/mahogany force_material = /decl/material/solid/organic/wood/mahogany /decl/flooring/wood/rough/maple - color = /decl/material/solid/organic/wood/maple::color build_type = /obj/item/stack/tile/wood/rough/maple force_material = /decl/material/solid/organic/wood/maple /decl/flooring/wood/rough/ebony - color = /decl/material/solid/organic/wood/ebony::color build_type = /obj/item/stack/tile/wood/rough/ebony force_material = /decl/material/solid/organic/wood/ebony /decl/flooring/wood/rough/walnut - color = /decl/material/solid/organic/wood/walnut::color build_type = /obj/item/stack/tile/wood/rough/walnut force_material = /decl/material/solid/organic/wood/walnut /decl/flooring/wood/rough/bamboo - color = /decl/material/solid/organic/wood/bamboo::color build_type = /obj/item/stack/tile/wood/rough/bamboo force_material = /decl/material/solid/organic/wood/bamboo /decl/flooring/wood/rough/yew - color = /decl/material/solid/organic/wood/yew::color build_type = /obj/item/stack/tile/wood/rough/yew force_material = /decl/material/solid/organic/wood/yew @@ -105,7 +93,7 @@ build_type = /obj/item/stack/tile/wood/laminate/oak flooring_flags = TURF_IS_FRAGILE | TURF_REMOVE_SCREWDRIVER footstep_type = /decl/footsteps/wood - color = /decl/material/solid/organic/wood/chipboard::color + color = null force_material = /decl/material/solid/organic/wood/chipboard constructed = TRUE gender = NEUTER @@ -120,26 +108,21 @@ ) /decl/flooring/laminate/mahogany - color = /decl/material/solid/organic/wood/chipboard/mahogany::color build_type = /obj/item/stack/tile/wood/laminate/mahogany force_material = /decl/material/solid/organic/wood/chipboard/mahogany /decl/flooring/laminate/maple - color = /decl/material/solid/organic/wood/chipboard/maple::color build_type = /obj/item/stack/tile/wood/laminate/maple force_material = /decl/material/solid/organic/wood/chipboard/maple /decl/flooring/laminate/ebony - color = /decl/material/solid/organic/wood/chipboard/ebony::color build_type = /obj/item/stack/tile/wood/laminate/ebony force_material = /decl/material/solid/organic/wood/chipboard/ebony /decl/flooring/laminate/walnut - color = /decl/material/solid/organic/wood/chipboard/walnut::color build_type = /obj/item/stack/tile/wood/laminate/walnut force_material = /decl/material/solid/organic/wood/chipboard/yew /decl/flooring/laminate/yew - color = /decl/material/solid/organic/wood/chipboard/yew::color build_type = /obj/item/stack/tile/wood/laminate/yew force_material = /decl/material/solid/organic/wood/chipboard/yew From 3d062a9c1c1b0c3d867d4198afcbc2f00d2a86ee Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 21:10:04 -0400 Subject: [PATCH 280/512] Make grass flooring use material colour --- code/game/turfs/flooring/flooring_grass.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/turfs/flooring/flooring_grass.dm b/code/game/turfs/flooring/flooring_grass.dm index e557193db38d..bc340140b5d5 100644 --- a/code/game/turfs/flooring/flooring_grass.dm +++ b/code/game/turfs/flooring/flooring_grass.dm @@ -6,7 +6,7 @@ has_base_range = 3 footstep_type = /decl/footsteps/grass icon_edge_layer = FLOOR_EDGE_GRASS - color = "#5e7a3b" + color = null // color from material turf_flags = TURF_FLAG_BACKGROUND | TURF_IS_HOLOMAP_PATH | TURF_FLAG_ABSORB_LIQUID can_engrave = FALSE damage_temperature = T0C+80 @@ -50,5 +50,6 @@ desc = "Do they smoke grass out in space, Bowie? Or do they smoke AstroTurf?" icon = 'icons/turf/flooring/fakegrass.dmi' has_base_range = 3 + color = "#5e7a3b" build_type = /obj/item/stack/tile/grass force_material = /decl/material/solid/organic/plastic From 971aba201ec0df12da5a6c7eebc5e97dfca0d977 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 20:54:26 -0400 Subject: [PATCH 281/512] Fix mob modifier and stamina bar screen objects --- code/_onclick/hud/screen/screen_mob_modifier.dm | 3 +++ code/_onclick/hud/screen/screen_stamina.dm | 3 +++ 2 files changed, 6 insertions(+) diff --git a/code/_onclick/hud/screen/screen_mob_modifier.dm b/code/_onclick/hud/screen/screen_mob_modifier.dm index da38d783020e..d8d32bd3c586 100644 --- a/code/_onclick/hud/screen/screen_mob_modifier.dm +++ b/code/_onclick/hud/screen/screen_mob_modifier.dm @@ -102,6 +102,9 @@ maptext_x = -8 maptext_y = -3 icon_state = "modifier_base" + // these must be enabled + use_supplied_ui_alpha = TRUE + use_supplied_ui_color = TRUE var/decl/mob_modifier/archetype var/obj/screen/mob_modifiers/holder diff --git a/code/_onclick/hud/screen/screen_stamina.dm b/code/_onclick/hud/screen/screen_stamina.dm index b70d9e743618..5d4f34b32da9 100644 --- a/code/_onclick/hud/screen/screen_stamina.dm +++ b/code/_onclick/hud/screen/screen_stamina.dm @@ -4,6 +4,9 @@ icon_state = "prog_bar_100" invisibility = INVISIBILITY_MAXIMUM screen_loc = ui_stamina + use_supplied_ui_color = FALSE + use_supplied_ui_alpha = FALSE + use_supplied_ui_icon = FALSE requires_ui_style = FALSE layer = HUD_BASE_LAYER + 0.1 // needs to layer over the movement intent element From 2775fc98eaef759acff1ede37984d67e7d1f2d97 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 21:14:11 -0400 Subject: [PATCH 282/512] Fix not being able to put whetstones in storage --- mods/content/item_sharpening/whetstone.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/content/item_sharpening/whetstone.dm b/mods/content/item_sharpening/whetstone.dm index 09d3cd9de50a..4ff1dc020e3f 100644 --- a/mods/content/item_sharpening/whetstone.dm +++ b/mods/content/item_sharpening/whetstone.dm @@ -2,14 +2,15 @@ name = "whetstone" desc = "A worn-down lozenge used to sharpen blades." icon = 'icons/obj/items/striker.dmi' // TODO unique icon? + icon_state = ICON_STATE_WORLD w_class = ITEM_SIZE_TINY material_alteration = MAT_FLAG_ALTERATION_ALL material = /decl/material/solid/quartz color = /decl/material/solid/quartz::color /obj/item/attackby(obj/item/used_item, mob/user) - if(istype(used_item, /obj/item/whetstone)) - return try_sharpen_with(user, used_item) + if(istype(used_item, /obj/item/whetstone) && try_sharpen_with(user, used_item)) + return TRUE return ..() /decl/loadout_option/utility/whetstone From c5fdef9716a9e71a5a8b4781b1aed7ca088859b6 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 21:18:04 -0400 Subject: [PATCH 283/512] Fix premapped doormats having random offsets --- code/game/objects/items/weapons/towels.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/towels.dm b/code/game/objects/items/weapons/towels.dm index 5d4a9525fac3..f65ff6962d76 100644 --- a/code/game/objects/items/weapons/towels.dm +++ b/code/game/objects/items/weapons/towels.dm @@ -241,4 +241,8 @@ /// A mapping subtype for a doormat that's already been laid out. /obj/item/towel/doormat/flat laid_out = TRUE - icon_state = ICON_STATE_WORLD + "-flat" \ No newline at end of file + icon_state = ICON_STATE_WORLD + "-flat" + +/obj/item/towel/doormat/flat/Initialize() + . = ..() + reset_offsets() // we don't want to overwrite randpixel but we don't want it to have a random offset either \ No newline at end of file From 0f4473c76fdf512826f710251717df630b35c31d Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 21:18:26 -0400 Subject: [PATCH 284/512] Fix damage-category item effects causing weapons to deal zero damage --- code/game/objects/items/_item_force.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/_item_force.dm b/code/game/objects/items/_item_force.dm index 790d894e5962..500bec99069c 100644 --- a/code/game/objects/items/_item_force.dm +++ b/code/game/objects/items/_item_force.dm @@ -22,7 +22,7 @@ var/list/item_effects = get_item_effects(IE_CAT_DAMAGE) if(length(item_effects)) for(var/decl/item_effect/damage_effect as anything in item_effects) - . = damage_effect.expend_attack_use(src, user, item_effects[damage_effect]) + damage_effect.expend_attack_use(src, user, item_effects[damage_effect]) /obj/item/proc/get_attack_force(mob/living/user) if(_base_attack_force <= 0 || (item_flags & ITEM_FLAG_NO_BLUDGEON)) From e8317dd301f25ac9bf2d281744cec6ce40c87770 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 21:20:45 -0400 Subject: [PATCH 285/512] Unset TILE_BOUND for multitile objects --- code/game/objects/structures/tables.dm | 2 ++ code/modules/multiz/stairs.dm | 1 + mods/content/inertia/inertial_damper.dm | 2 ++ 3 files changed, 5 insertions(+) diff --git a/code/game/objects/structures/tables.dm b/code/game/objects/structures/tables.dm index 85874e57021d..024c006fd386 100644 --- a/code/game/objects/structures/tables.dm +++ b/code/game/objects/structures/tables.dm @@ -904,6 +904,7 @@ reinf_material = /decl/material/solid/organic/wood/walnut storage = /datum/storage/structure/desk bound_width = 64 + appearance_flags = /obj/structure/table::appearance_flags & ~TILE_BOUND material_alteration = MAT_FLAG_ALTERATION_ALL can_flip = FALSE top_surface_noun = "desktop" @@ -979,6 +980,7 @@ icon = 'icons/obj/structures/dresser.dmi' icon_state = "dresser" bound_width = 32 + appearance_flags = /obj/structure/table::appearance_flags top_surface_noun = "surface" tabletop_height = 15 mob_offset = 18 diff --git a/code/modules/multiz/stairs.dm b/code/modules/multiz/stairs.dm index e78d6e90ffa6..c93c6f50229b 100644 --- a/code/modules/multiz/stairs.dm +++ b/code/modules/multiz/stairs.dm @@ -63,6 +63,7 @@ /obj/structure/stairs/long icon = 'icons/obj/stairs_64.dmi' bound_height = 64 + appearance_flags = /obj/structure/stairs::appearance_flags & ~TILE_BOUND /obj/structure/stairs/long/north dir = NORTH diff --git a/mods/content/inertia/inertial_damper.dm b/mods/content/inertia/inertial_damper.dm index 4cb9905a95ce..6e1f636d5971 100644 --- a/mods/content/inertia/inertial_damper.dm +++ b/mods/content/inertia/inertial_damper.dm @@ -136,6 +136,8 @@ /obj/machinery/inertial_damper/proc/SetBounds() bound_width = width * world.icon_size bound_height = height * world.icon_size + if(bound_height != world.icon_size || bound_width != world.icon_size) + appearance_flags = /obj/machinery::appearance_flags & ~TILE_BOUND /obj/machinery/inertial_damper/interface_interact(var/mob/user) ui_interact(user) From 5c4902f6303111bd6d97675ccc873f32225d2610 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 21:21:38 -0400 Subject: [PATCH 286/512] Allow wood and stone to smooth with wattle and daub walls --- .../materials/definitions/solids/materials_solid_stone.dm | 2 ++ .../materials/definitions/solids/materials_solid_wood.dm | 2 ++ 2 files changed, 4 insertions(+) diff --git a/code/modules/materials/definitions/solids/materials_solid_stone.dm b/code/modules/materials/definitions/solids/materials_solid_stone.dm index 99c4a2bd31c3..dc692ddb16f7 100644 --- a/code/modules/materials/definitions/solids/materials_solid_stone.dm +++ b/code/modules/materials/definitions/solids/materials_solid_stone.dm @@ -15,6 +15,8 @@ 'icons/turf/walls/wood.dmi' = TRUE, 'icons/turf/walls/brick.dmi' = TRUE, 'icons/turf/walls/log.dmi' = TRUE, + 'icons/turf/walls/wattle.dmi' = TRUE, + 'icons/turf/walls/wattledaub.dmi' = TRUE, 'icons/turf/walls/metal.dmi' = TRUE ) dissolves_into = list( diff --git a/code/modules/materials/definitions/solids/materials_solid_wood.dm b/code/modules/materials/definitions/solids/materials_solid_wood.dm index 6402e6aa627f..b059c599ebc2 100644 --- a/code/modules/materials/definitions/solids/materials_solid_wood.dm +++ b/code/modules/materials/definitions/solids/materials_solid_wood.dm @@ -10,6 +10,8 @@ 'icons/turf/walls/stone.dmi' = TRUE, 'icons/turf/walls/brick.dmi' = TRUE, 'icons/turf/walls/log.dmi' = TRUE, + 'icons/turf/walls/wattle.dmi' = TRUE, + 'icons/turf/walls/wattledaub.dmi' = TRUE, 'icons/turf/walls/metal.dmi' = TRUE ) icon_reinf = list( From fd6b54751c78e8bb72a31a9f20b669622c212548 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Wed, 26 Mar 2025 21:23:16 -0400 Subject: [PATCH 287/512] Prevent forging dirt bars or making dirt billets --- mods/content/blacksmithy/anvil.dm | 2 +- mods/content/blacksmithy/billet.dm | 8 +++++++- mods/content/blacksmithy/forge_fire.dm | 7 ++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/mods/content/blacksmithy/anvil.dm b/mods/content/blacksmithy/anvil.dm index 8c886cadf2c1..9f88267f22a8 100644 --- a/mods/content/blacksmithy/anvil.dm +++ b/mods/content/blacksmithy/anvil.dm @@ -83,7 +83,7 @@ // Flow through into procs below. // Put the bar onto the anvil (need to do this to avoid repairs in ..()) - if(istype(used_item, /obj/item/stack/material/bar)) + if(istype(used_item, /obj/item/stack/material/bar) && used_item.is_forgable()) var/obj/item/stack/material/bar/bar = used_item if(used_item.material != material || current_health >= get_max_health()) if(bar.get_amount() > 1) diff --git a/mods/content/blacksmithy/billet.dm b/mods/content/blacksmithy/billet.dm index 3a18225c09a6..b269d10ae0c1 100644 --- a/mods/content/blacksmithy/billet.dm +++ b/mods/content/blacksmithy/billet.dm @@ -14,9 +14,15 @@ return TRUE . = ..() -/obj/item/proc/hot_enough_to_forge(melting_point_percent = 0.25) +/// Whether or not this item is considered forgable (e.g. there is a temperature at which it can be forged) +/obj/item/proc/is_forgable() if(!istype(material) || isnull(material.melting_point) || !material.forgable) return FALSE + return TRUE + +/obj/item/proc/hot_enough_to_forge(melting_point_percent = 0.25) + if(!is_forgable()) + return FALSE // Defaults to >25% of the way to melting to be considered 'forgable' return temperature >= ((material.melting_point - T20C) * melting_point_percent) + T20C diff --git a/mods/content/blacksmithy/forge_fire.dm b/mods/content/blacksmithy/forge_fire.dm index 437c9cd1c1c8..1c32a6e8d912 100644 --- a/mods/content/blacksmithy/forge_fire.dm +++ b/mods/content/blacksmithy/forge_fire.dm @@ -20,13 +20,14 @@ /obj/structure/fire_source/forge/proc/get_forgable_contents() . = list() for(var/obj/item/thing in get_stored_inventory()) - if(thing.material?.forgable && (istype(thing, /obj/item/billet) || istype(thing, /obj/item/stack/material/bar))) + if(thing.is_forgable() && (istype(thing, /obj/item/billet) || istype(thing, /obj/item/stack/material/bar))) . += thing /obj/structure/fire_source/forge/attackby(obj/item/used_item, mob/user) + var/item_is_forgable = used_item.is_forgable() // Raw materials. - if(istype(used_item, /obj/item/stack/material/bar)) + if(istype(used_item, /obj/item/stack/material/bar) && item_is_forgable) var/obj/item/stack/material/bar/bar = used_item if(used_item.material != material || current_health >= get_max_health()) if(bar.get_amount() > 1) @@ -41,7 +42,7 @@ // Flows through to below. // Partially worked billets. - if(istype(used_item, /obj/item/billet)) + if(istype(used_item, /obj/item/billet) && item_is_forgable) if(used_item.loc == user) user.try_unequip(used_item, loc) else From 2128a4d3365b82d3b6ba8b9a3b47cfc46cbff032 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Thu, 27 Mar 2025 21:00:40 -0400 Subject: [PATCH 288/512] Fix new hand slots not updating until you swap hands --- code/_onclick/hud/hud_types/_hud.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/_onclick/hud/hud_types/_hud.dm b/code/_onclick/hud/hud_types/_hud.dm index 103c016a6d97..c14dcf7c378e 100644 --- a/code/_onclick/hud/hud_types/_hud.dm +++ b/code/_onclick/hud/hud_types/_hud.dm @@ -403,6 +403,8 @@ if(mymob.client) mymob.client.screen |= swap_elem + update_hand_elements() + return TRUE /datum/hud/proc/build_inventory_ui() From 273e3df8635ce3533ba22f59f7bc336ba1b2bcac Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Thu, 27 Mar 2025 21:31:21 -0400 Subject: [PATCH 289/512] Fix horses all being the same colour --- code/modules/mob/living/simple_animal/passive/horse.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/simple_animal/passive/horse.dm b/code/modules/mob/living/simple_animal/passive/horse.dm index f90f16747a10..0e2c0d0c023e 100644 --- a/code/modules/mob/living/simple_animal/passive/horse.dm +++ b/code/modules/mob/living/simple_animal/passive/horse.dm @@ -14,10 +14,8 @@ can_have_rider = TRUE max_rider_size = MOB_SIZE_MEDIUM ai = /datum/mob_controller/passive/horse - color = "#ccc496" // preview color - draw_visible_overlays = list( - "base" = "#ccc496" - ) + color = "#806146" // preview color + draw_visible_overlays = null // e.g. list("base" = "#806146") /datum/mob_controller/passive/horse emote_speech = list("Neigh!","NEIGH!","Neigh?") From 0c53d90e085c671379270250f734e05bcb879d1c Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Thu, 27 Mar 2025 21:33:27 -0400 Subject: [PATCH 290/512] Add support for buckle shifting based on atom offset --- code/game/atoms_movable.dm | 3 ++- code/game/objects/structures/chairs/rustic_chairs.dm | 1 + code/modules/mob/mob_layering.dm | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 069199090b81..3554eeb7fc3b 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -10,7 +10,8 @@ var/buckle_layer_above = FALSE var/buckle_dir = 0 var/buckle_lying = -1 // bed-like behavior, forces mob to lie or stand if buckle_lying != -1 - var/buckle_pixel_shift // ex. @'{"x":0,"y":0,"z":0}' //where the buckled mob should be pixel shifted to, or null for no pixel shift control + /// A list or JSON-encoded list of pixel offsets to use on a mob buckled to this atom. TRUE to use this atom's pixel shifts, null for no pixel shift control. + var/buckle_pixel_shift // ex. @'{"x":0,"y":0,"z":0}' var/buckle_require_restraints = 0 // require people to be cuffed before being able to buckle. eg: pipes var/buckle_require_same_tile = FALSE var/buckle_sound diff --git a/code/game/objects/structures/chairs/rustic_chairs.dm b/code/game/objects/structures/chairs/rustic_chairs.dm index 840678cb077e..a61ca9b1a171 100644 --- a/code/game/objects/structures/chairs/rustic_chairs.dm +++ b/code/game/objects/structures/chairs/rustic_chairs.dm @@ -5,6 +5,7 @@ material = /decl/material/solid/organic/wood/walnut color = /decl/material/solid/organic/wood/walnut::color user_comfort = -0.5 + buckle_pixel_shift = TRUE // use chair offset /obj/structure/chair/rustic_fancy name_prefix = "fancy" diff --git a/code/modules/mob/mob_layering.dm b/code/modules/mob/mob_layering.dm index e4ecb2b50071..ad458692d2d3 100644 --- a/code/modules/mob/mob_layering.dm +++ b/code/modules/mob/mob_layering.dm @@ -124,6 +124,10 @@ new_pixel_x += pixel_shift["x"] || 0 new_pixel_y += pixel_shift["y"] || 0 new_pixel_z += pixel_shift["z"] || 0 + if(pixel_shift == TRUE) // TRUE -> use object's offset + new_pixel_x = buckled.pixel_x + new_pixel_y = buckled.pixel_y + new_pixel_z = buckled.pixel_z if(last_pixel_x != new_pixel_x || last_pixel_y != new_pixel_y || last_pixel_z != new_pixel_z) if(anim_time > 0) From b6e1054b508b38b8739444489b05d756ec8b0b73 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Thu, 27 Mar 2025 21:33:44 -0400 Subject: [PATCH 291/512] Adjust large cask rack naming code --- code/game/objects/structures/barrels/cask_rack.dm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/code/game/objects/structures/barrels/cask_rack.dm b/code/game/objects/structures/barrels/cask_rack.dm index c8e5cebc6184..2dfbdc2d8e09 100644 --- a/code/game/objects/structures/barrels/cask_rack.dm +++ b/code/game/objects/structures/barrels/cask_rack.dm @@ -143,16 +143,12 @@ // A larger stack, used to arrange up to three casks. /obj/structure/cask_rack/large + name_prefix = "large" desc = "A flat rack used to stop casks from rolling around." max_stack = 3 w_class = ITEM_SIZE_LARGE_STRUCTURE icon = 'icons/obj/structures/barrels/cask_rack_large.dmi' -// We want 'large wooden cask rack' not 'wooden large cask rack' -/obj/structure/cask_rack/large/update_material_name(override_name) - . = ..() - SetName("large [name]") - /obj/structure/cask_rack/large/adjust_barrel_offsets(atom/movable/barrel, barrel_position) ..() switch(barrel_position) From 9c982b5362c88d56ef57ad7a1dc8dddfffda18c7 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Thu, 27 Mar 2025 21:38:52 -0400 Subject: [PATCH 292/512] Fix descriptions for plastered wattle walls --- code/game/turfs/walls/wall_wattle.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/turfs/walls/wall_wattle.dm b/code/game/turfs/walls/wall_wattle.dm index b1ce9e571847..4cdca1b6df0c 100644 --- a/code/game/turfs/walls/wall_wattle.dm +++ b/code/game/turfs/walls/wall_wattle.dm @@ -76,8 +76,10 @@ else if(paint_color) if(reinf_material) SetName("[reinf_material.solid_name]-framed plastered wall") + desc = "A plastered wall framed with [reinf_material.solid_name]." else SetName("plastered wall") + desc = "A plastered wall." else if(reinf_material) SetName("[reinf_material.solid_name]-framed [material.adjective_name] wattle and daub wall") From 2c2683cf665fa3c485ab8166cabaaa49ba8123de Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Thu, 27 Mar 2025 22:13:05 -0400 Subject: [PATCH 293/512] Fix reverb in foresters' hut --- maps/shaded_hills/areas/woods.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/maps/shaded_hills/areas/woods.dm b/maps/shaded_hills/areas/woods.dm index 73c262300a6f..5a5a662ed04c 100644 --- a/maps/shaded_hills/areas/woods.dm +++ b/maps/shaded_hills/areas/woods.dm @@ -33,5 +33,6 @@ /area/shaded_hills/forester_hut name = "\improper Foresters' Hut" + sound_env = STANDARD_STATION fishing_failure_prob = 100 fishing_results = list() From 0eb1ab93e3eec29bf161e47ea29e4f427caa90bd Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 4 May 2025 01:02:06 +0000 Subject: [PATCH 294/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 13b7880bf540..6aef7ebd7b31 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -108,12 +108,6 @@

    Cerebulon updated:

    • New icons for a variety of objects, mostly machines and grenades.
    - -

    02 March 2025

    -

    MistakeNot4892 updated:

    -
      -
    • Old browser-based module selection for robots has been removed, use the INV button to open storage like you would a belt/backpack.
    • -
    From da4185d8c4f8ccbf201ebea8fdaf697224105043 Mon Sep 17 00:00:00 2001 From: Neerti Date: Mon, 5 May 2025 16:43:42 -0400 Subject: [PATCH 295/512] Fixes overmap trading hubs being uninteractable --- code/modules/merchant/merchant_programs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/merchant/merchant_programs.dm b/code/modules/merchant/merchant_programs.dm index bd3c35a5a1e1..9eaf55156e0a 100644 --- a/code/modules/merchant/merchant_programs.dm +++ b/code/modules/merchant/merchant_programs.dm @@ -39,7 +39,7 @@ /datum/computer_file/program/merchant/proc/get_available_hubs() . = list() - var/turf/T = get_turf(holder) + var/turf/T = get_turf(holder.resolve()) for(var/datum/trade_hub/hub in SStrade.trade_hubs) if(hub.is_accessible_from(T)) . |= hub From d718c5d44e00098ca8373a0cbe89f31113e138e0 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 17:55:15 -0400 Subject: [PATCH 296/512] Make shotgun shells use the single icon system --- code/modules/projectiles/ammunition.dm | 32 +++++------ code/modules/projectiles/ammunition/boxes.dm | 9 ++-- .../modules/projectiles/ammunition/bullets.dm | 51 +++++++++++------- .../projectiles/ammunition/chemdart.dm | 2 +- icons/obj/ammo.dmi | Bin 13910 -> 12599 bytes icons/obj/ammo/casings/anti_materiel.dmi | Bin 1914 -> 2622 bytes icons/obj/ammo/casings/flechette.dmi | Bin 472 -> 548 bytes icons/obj/ammo/casings/lasbulb.dmi | Bin 660 -> 770 bytes icons/obj/ammo/casings/magnum.dmi | Bin 560 -> 647 bytes icons/obj/ammo/casings/pistol.dmi | Bin 535 -> 627 bytes icons/obj/ammo/casings/rifle.dmi | Bin 575 -> 678 bytes icons/obj/ammo/casings/small_pistol.dmi | Bin 508 -> 599 bytes icons/obj/ammo/shells/beanbag.dmi | Bin 0 -> 309 bytes icons/obj/ammo/shells/blanks.dmi | Bin 0 -> 312 bytes icons/obj/ammo/shells/buckshot.dmi | Bin 0 -> 309 bytes icons/obj/ammo/shells/flash.dmi | Bin 0 -> 329 bytes icons/obj/ammo/shells/haywire.dmi | Bin 0 -> 340 bytes icons/obj/ammo/shells/practice.dmi | Bin 0 -> 329 bytes icons/obj/ammo/shells/slugs.dmi | Bin 0 -> 302 bytes icons/obj/ammo/shells/stun.dmi | Bin 0 -> 342 bytes 20 files changed, 52 insertions(+), 42 deletions(-) create mode 100644 icons/obj/ammo/shells/beanbag.dmi create mode 100644 icons/obj/ammo/shells/blanks.dmi create mode 100644 icons/obj/ammo/shells/buckshot.dmi create mode 100644 icons/obj/ammo/shells/flash.dmi create mode 100644 icons/obj/ammo/shells/haywire.dmi create mode 100644 icons/obj/ammo/shells/practice.dmi create mode 100644 icons/obj/ammo/shells/slugs.dmi create mode 100644 icons/obj/ammo/shells/stun.dmi diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index dbc66c1f6859..96804826c533 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -1,12 +1,13 @@ /obj/item/ammo_casing name = "bullet casing" desc = "A bullet casing." - icon = 'icons/obj/ammo.dmi' - icon_state = "pistolcasing" + icon = 'icons/obj/ammo/casings/pistol.dmi' + icon_state = ICON_STATE_WORLD + "-preview" randpixel = 10 obj_flags = OBJ_FLAG_CONDUCTIBLE | OBJ_FLAG_HOLLOW slot_flags = SLOT_LOWER_BODY | SLOT_EARS w_class = ITEM_SIZE_TINY + color = /decl/material/solid/metal/brass::color // mapping preview color material = /decl/material/solid/metal/brass material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME drop_sound = list( @@ -15,11 +16,10 @@ 'sound/weapons/guns/casingfall3.ogg' ) - var/leaves_residue = 1 + var/leaves_residue = TRUE var/caliber = "" //Which kind of guns it can be loaded into var/projectile_type //The bullet type to create when New() is called var/obj/item/projectile/BB = null //The loaded bullet - make it so that the projectiles are created only when needed? - var/spent_icon = "pistolcasing-spent" var/bullet_color = COLOR_COPPER var/marking_color @@ -101,19 +101,21 @@ BB.SetName("[initial(BB.name)] (\"[label_text]\")") return TRUE +// This is separate because on_update_icon() needs to call parent, +// and shells need to override this. +/obj/item/ammo_casing/proc/update_casing_icon() + if(BB) + var/image/I = overlay_image(icon, "[icon_state]-bullet", bullet_color, flags=RESET_COLOR) + I.dir = dir // don't overlays inherit dir already? is this needed? + add_overlay(I) + if(marking_color) + var/image/I = overlay_image(icon, "[icon_state]-marking", marking_color, flags=RESET_COLOR) + I.dir = dir + add_overlay(I) + /obj/item/ammo_casing/on_update_icon() . = ..() - if(use_single_icon) - if(BB) - var/image/I = overlay_image(icon, "[icon_state]-bullet", bullet_color, flags=RESET_COLOR) - I.dir = dir - add_overlay(I) - if(marking_color) - var/image/I = overlay_image(icon, "[icon_state]-marking", marking_color, flags=RESET_COLOR) - I.dir = dir - add_overlay(I) - else if(spent_icon && !BB) - icon_state = spent_icon + update_casing_icon() /obj/item/ammo_casing/update_name() . = ..() diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index 962cdda36769..2e1401668335 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -23,7 +23,7 @@ return create_initial_contents() // Not ideal, but we need instances for the icon gen. switch(icon_state) - if("world") + if(ICON_STATE_WORLD) var/ammo_state = "world-some" if(ammo_count == 1) ammo_state = "world-one" @@ -34,7 +34,7 @@ add_overlay(overlay_image(icon, "[ammo_state]-bullets", A.bullet_color, flags = RESET_COLOR)) if(A.marking_color) add_overlay(overlay_image(icon, "[ammo_state]-markings", A.marking_color, RESET_COLOR)) - if("inventory") + if(ICON_STATE_INV) for(var/i = 1 to length(stored_ammo)) var/obj/item/ammo_casing/A = stored_ammo[i] var/image/I = overlay_image(icon, "casing", A.color, RESET_COLOR) @@ -59,11 +59,8 @@ /obj/item/ammo_magazine/shotholder/on_update_icon() ..() - overlays.Cut() if(marking_color) - var/image/I = image(icon, "shotholder-marking") - I.color = marking_color - overlays += I + add_overlay(overlay_image(icon, "shotholder-marking", marking_color, RESET_COLOR)) /obj/item/ammo_magazine/shotholder/attack_hand(mob/user) if(loc != user || user.a_intent != I_HURT || !length(stored_ammo) || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm index 7966b8e04f9b..580bd7175f46 100644 --- a/code/modules/projectiles/ammunition/bullets.dm +++ b/code/modules/projectiles/ammunition/bullets.dm @@ -76,56 +76,67 @@ bullet_color = COLOR_OFF_WHITE marking_color = COLOR_SUN +// This uses a shotgun shell icon despite not being a shotgun shell... +// TODO: Unify the casing icon system somehow to avoid code duplication. /obj/item/ammo_casing/pistol/magnum/stun name = "stun round" desc = "An energy stun cartridge." - icon_state = "stunshell" - spent_icon = "stunshell-spent" + icon = 'icons/obj/ammo/shells/stun.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/energy/electrode/stunshot - leaves_residue = 0 + leaves_residue = FALSE material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) origin_tech = @'{"combat":3,"materials":3}' +/obj/item/ammo_casing/pistol/magnum/stun/update_casing_icon() + icon_state = get_world_inventory_state() + if(!BB) // use spent icon + icon_state = "[icon_state]-spent" /obj/item/ammo_casing/shotgun name = "shotgun slug" desc = "A shotgun slug." - icon_state = "slshell" - spent_icon = "slshell-spent" + icon = 'icons/obj/ammo/shells/slugs.dmi' + icon_state = ICON_STATE_WORLD caliber = CALIBER_SHOTGUN projectile_type = /obj/item/projectile/bullet/shotgun material = /decl/material/solid/metal/steel drop_sound = 'sound/weapons/guns/shotgun_fall.ogg' +/obj/item/ammo_casing/shotgun/update_casing_icon() + icon_state = get_world_inventory_state() + if(!BB) // use spent icon + icon_state = "[icon_state]-spent" + /obj/item/ammo_casing/shotgun/pellet name = "shotgun shell" desc = "A shotshell." - icon_state = "gshell" - spent_icon = "gshell-spent" + icon = 'icons/obj/ammo/shells/buckshot.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/bullet/pellet/shotgun material = /decl/material/solid/metal/steel /obj/item/ammo_casing/shotgun/blank name = "shotgun shell" desc = "A blank shell." - icon_state = "blshell" - spent_icon = "blshell-spent" + icon = 'icons/obj/ammo/shells/blanks.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/bullet/blank material = /decl/material/solid/metal/steel /obj/item/ammo_casing/shotgun/practice name = "shotgun shell" desc = "A practice shell." - icon_state = "pshell" - spent_icon = "pshell-spent" + icon = 'icons/obj/ammo/shells/practice.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/bullet/shotgun/practice material = /decl/material/solid/metal/steel /obj/item/ammo_casing/shotgun/beanbag name = "beanbag shell" desc = "A beanbag shell." - icon_state = "bshell" - spent_icon = "bshell-spent" + icon = 'icons/obj/ammo/shells/beanbag.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/bullet/shotgun/beanbag material = /decl/material/solid/metal/steel @@ -134,10 +145,10 @@ /obj/item/ammo_casing/shotgun/stunshell name = "stun shell" desc = "An energy stun cartridge." - icon_state = "stunshell" - spent_icon = "stunshell-spent" + icon = 'icons/obj/ammo/shells/stun.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/energy/electrode/stunshot - leaves_residue = 0 + leaves_residue = FALSE material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) origin_tech = @'{"combat":3,"materials":3}' @@ -150,8 +161,8 @@ /obj/item/ammo_casing/shotgun/flash name = "flash shell" desc = "A chemical shell used to signal distress or provide illumination." - icon_state = "fshell" - spent_icon = "fshell-spent" + icon = 'icons/obj/ammo/shells/flash.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/energy/flash/flare material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) @@ -159,8 +170,8 @@ /obj/item/ammo_casing/shotgun/emp name = "haywire slug" desc = "A 12-gauge shotgun slug fitted with a single-use ion pulse generator." - icon_state = "empshell" - spent_icon = "empshell-spent" + icon = 'icons/obj/ammo/shells/haywire.dmi' + icon_state = ICON_STATE_WORLD projectile_type = /obj/item/projectile/ion material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/uranium = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/modules/projectiles/ammunition/chemdart.dm b/code/modules/projectiles/ammunition/chemdart.dm index bd8710bef92d..5af9b22fc6c0 100644 --- a/code/modules/projectiles/ammunition/chemdart.dm +++ b/code/modules/projectiles/ammunition/chemdart.dm @@ -29,7 +29,7 @@ icon_state = "dart" caliber = CALIBER_DART projectile_type = /obj/item/projectile/bullet/chemdart - leaves_residue = 0 + leaves_residue = FALSE /obj/item/ammo_casing/chemdart/expend() qdel(src) diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index aed587179330b09d0876eb81bc74b7958443c799..5ae6fdea7fc5a17d5d0c9c03a14887aca7a54bea 100644 GIT binary patch literal 12599 zcmbt*cUTi&x9)^q1wo2*lqN+`qzM?RhzOxr5X2x|kR}L9Ng_o$s5B8I6cs7bq)7`1 zNKv|UF!Wv}w1gyg;_o}RJm;KyzvsDs%nmcNXV2`l*Lv4l@7hF}ni#M$@i74az-o9+ z&l~_CDDbdlpaZXzhZbuB098`JO-o-rM<4sg550UJdU^oB(~RUd-5wJP>|wq877U$f z`Yz@&d(%cUS=*w|Xmw9MjFLOYC^n?*i49%h>E~n^PqYjQBq4(2PRO@! z$nz)iN7%ua&%rC9sz5$SLEU59_4cTZMx6^#h#-Fbr;Tmw1anSEDEIC zruH6W95N-sWYxYV8F+HAFnw*g>l@6@$??wgmy~6;ZBz&!Ef-TxG;>r)eSG%H3pEsP z)-3J3TO;cDgvGMSvkX&{_33lrVgd`@Uvq+B_YE7vi^c35ChD3qn-cd=8zj{TH+zy0 zH1adV$Vx}*aV)E)&B1EnhB1A4-N;VCOyG&Cy zS6!m36*eRaM6aMGlRUp1C?d_yzj=9Vj}-S|UOSfHO^L6lv*y zb+UV(?cq`xO(*s>d&jywonEV9Q!^eai?)y#@JcEX!|dDotbSg?mdHpAIM5?XRy1p~ zzvQ^v#rOE$&S+S}r$6Tt=s55A_RUd-``b61?8-dxsZVDPM=QOK<*L1c`tGUzwj9*^ z{b7_ZWUfB0f+Ey>P8ZX)^@91dQ+!*^4i8&! z%A^_erMqW)>xv-h7608aZ%=g+@|NRd*17-s=VcJ#!a=TzGF8r0la?ikz9fw&5+|(S z+0DwL_lHgO(oP=#AzHLdsWGbQ%UD3W!N_nO+t_DHMqfN18`^WkO#lswt**W+*N>q7?~*yD>_N&Q3kflJm!i zz^yOvplnlyFm|1J`^aS~b{&S3)SQ55*fpmAt?e?rohggO+<#VBAP6WR9whg6`2;q@ z=CjMo%?&lGJf=+>3CxPFHZe$_R)IjEAQzz8H00uI`23y_+vK+z4b_` zs@&ame)B@D-tr544*s#3P~n%Is~EdU+$ckuoT-Cs_!<^<9WxXaI71% zzU4|D)CZFvWjjTf2=_&HY|6{>g@+sif4(2SQu!_%xOu9aaEl`y+iS3#hgB;mn2oS< zo?W_OtK)moa<}eL&gdeP_~*#Y)%Da6=JCRHxCEkwQEPFNN98a|-Me<*07|s_ zYYmk9VQSi7t+RXm!npLaWrVgugdgM?L*-uf2~Ao&r`Z9?&%mRpYqhtE(qY%F4qm^m zk_71agC8Xs#xB$OiB_bRpz8-c8MC}eKSmrIAkNZ3>rf1ap%b;j4hPOg2QmD|wVbHs zO|~&&7`vU)3u_>!4(hP?BZzvK6~Wa%C7eSX`$g2oJg-DuzTDE`w%7i-VOFf15XEc$ z1o)L_Cg5p;sV2U#0#*aoaze7!5wqtXKh79CibCKw{;Zh*dwYA0pnQrO7cbwC z&RlqU5VKB-@9|nEh58-YZ(Qs!`a!?Rc^xV$#`PjKlslO7rW3}my-=?aG3?^&`=YF( z-u!OE_e_cWSW;$YW(E43jEu$V>guDTw3R%p2_~DSG@$!2+UiI7+L=74TF%mGaPngO z7b+zcM8nv(zD3!Fv7b421Ne8_7pWnp`9%UXn_aa})&Rgd)!>e-0H&|;gT;#Q^49Wl zQ+{4%bbqb^b*cZ#IB1rRyU{!fOPj)Ng780sEmE?4w1A~AQ3KEDec`ku0Q8-=U;>zV z&g;S9!d()Vzg!n0?vO%4s6eY3+hnB+Wdcsk!@m1?Zbl1|Z;fI58_4N6^+mQ;L7p-V zrXA&v9H{I6m8r>?Y(kK?ZY7s|{CL$nhP*w~Ql;)`O;Yt!Y2@@@cYe};OP!GV<9r@g zn@ln4x|?bvurn(iQji+=1k--fqw%vh*+BDN_Xu)s>iQ)3?g6+mToc(bq;*{4`g4`% zQQ|Hm3wiJ>&>e}7oWOxp@&ud6?YWz7Xxxtl$=_{WRJI2(lZYoi`_0PV%Y5=K;oIil{}|MVy|uA#y(XA3G!(>u@sn4deI{9MKYZw+ zbwJX3tH`2fd>xzxO{lhGsmL|V7lbaOZRuu2vdkU4w2Taw*_1GDVheWFj_gBLxJG!P zRXfI}Izd(XX9;d~KmT5E_mk1XwRZdVU(@~I8{s{T>=Orm_J7o#eHX$A5`Vwgn1T54 zl#jvr$1`n9v6w>@&yO0&ix@{6tsGDg6I&yLWR_7CQU)TBXyKG(J25OV>2Xkrsp(A9`#qDsNY;EYvQDW8y5W^+WLFKui^wrnsUmrl- zJWU`y2gt##477v%$E%QhVsB0sJOkcvTHJMm|F7yaJ;)N11J!W85})X&fvbIt=h zKdeJ_b#?i&suUF#e)(`@2gl)P>0g!aQ`9P4*Chu!P$4kay%MsWaF<=ul7Gj#0{ba z5fVUx*-PQ31Sh4|6uS5dzcy}~T=3a1Sokf!P)G1K+n+vpg8>+n_!^JAcl*KE*Eaxz zsGj*7pd1y4)S$eEr!_(yyH|u}6k&ejzgLVC&H=Bw&xA1Y1P=GofD?WF+E++Rf%j&G zb+@r}Cg@J-KsyfqmSgrp9MrQ>iQxd{>X%dK_(0?iZOZYl^}C=;N+)55hU^w^?XFa# zAdD105BgStI({q!0Htr=T=L;7WQq{Sre=O1BiF%3=@3e*Jw^)@mq@C*BJg&Di-5msUvVU7beKGHCIMAvP$G+g5q zgZc1Plo-J%+ByeL4UZ3igVL4Y>Wvn(Feo`SPj6DB=g+Zidu;FFQGEWcHo~^=hGT2V z$iol93aJZ&M|)=iPSFtsXmyc(hxD;j=Al{pZ}@7!0HuR}uJ;;fU+>ounvp``+E9b$ zKC~d|{Vq_%VD9vC3dSI6(v;S87qx6AQch^lUv$xCmDi#Fs#VK!Q&?$v}VCK#~tHJ}L`jm%N zB*oUEJV0;t@u!rwfio`%o)j(Xl#sO4ZbUZxNqC~v1sxt5eGHm_{}=2A=%wgi4WGY} zX2x;n+JL}i_R&|dE&AY_4-W)=(=>ll{7uJDCSg4?M*Gy_sPCFPE^ zPZ!UF{+!3a@a8jPj1S^YJXIGMV|!Tj#XF{7_i9s80f6F~MY=HPp-j(}>W=*w6auf0 ze@<$W?<$E%fF1+44m7S|B8VwsK;c1a{X=baA<|a6H~8SRy!@32!lLpF<+rK&BQ!6@BC_8~ zjH&zxgRfYLSX|xHQ|t;)*`MO?V){h%Fc}CX1~<34u~o^j1erQi#d{_y_w==JI#K+> z9_-B}S|CgUl6Ndt=e;16r8mh-v+N%Me<30}ULu~3$E^78P_7DuE%PkV&og|>AzGDx zAg3ePd?63L-Pm)`Qx`5C8t%`Gn`z~H*|X)(cQQRXv?B2r(3 zU!G;4gtR12c|3IT$fJnLBOGgCqh&S8N8`9pCOD>2v-8lbRAbS`MC^SE5>Y9Zy!9MA z(zw7R#pS^g;<4lG!=8f`M9cgYDMoCi%Ox{?)vpY^Vd zr6f=M=eN0dhr&Pwhy-=DnxT+@Ug6m~n3u}BDR!TRuwQZ6oIt_sC>}LKUr5m+ zWx-Zi~_N7sUf#- zM(yTGb-Sl3!mDo@y^=h&cHL&AJNGrpb5 zAwtg=dQ~iFOcymCYnr^ZDx|zJh0CjsIPcBviCS4hvn$seg4F(&GoM+Jy70? zv*^xx5o2vTbo)w-g_7AGf(c<+fn?PYa4fuqK23rVjA|^7+2--J%u~b6CV?YY8C^E;5dPLmv z_~Rz8vG+C6@zoTpb(h!_Il6nNC1RzQ{XDHU!;U~MQ@s7nX7A%I^!(KcFP4%fgO9CUb~QfvKw;{q>Ath7x#jUG4K_#w9x0wtAyV20lr_WKp$cp&*&E_geK z_+qd<;fJ)sZo$#V_Y{vg`8?CA^qscpRg52ZQ6yhY`Y{smh3!C&Km#7FztqNP^&(AP z4}}axxr~c^I{)%2CRnTxGSR>intq&@!8D(dEwU6#5=f6iyFs3X{bP!T&dm~6^022X zDs8inj7%G=Z*UX3vr@d0p(XssWIV?*u>!NCW`WtH5t+lQd;A$086j|_{~C|EL70rc z*tvPKBzX2ORsJE~Q{e67Y(DH9i%k-T} z)giX?b!c{-qO1PQB4fs?lAwk#h~Cbv`x`RXP3tNAzeDE#98gagX}hGJF^&){9PXDN zhB0(r@s*=B+kwXsqo$}MV1c*y${B^tSGEV%vgWgZ7?ocm2AR}#6 zac$GGD3z$OBShmIQHCV?l##a9b=;t4P{CH&K%Q4qPsnpz^} zG^1zNNvh>X{#(CU0fvZ{n%y4tWG~fNEs?$3@5c{XW)$u}Ti~*I-WdrG?#mS*Xl|NVRHCupctx9WEX5C%zb<5MQ$ z&*S)2GCP_S-}SL(H8cnUrZ;cSe>(UQxD_{~VS-#1wZOPp$f11XRXx7DGxd`!OlTkX zsP2$U;U_T4K!FSOjBWd}N<3c>M1-9|MBoG){@Dg$<%(M+c7+=Na5!Ak)&aGq$?2)) z6*kTJi5l?=u8{R3(@DKqC}u1o!4G-nC%Hua`EOWTz(;@6p3Q~x2MzI6{l48~d%(1g>&?`(z7V+8EHl5jIJ?`s zA-Ml8wpv;`DF`?M&KG{>8l-LItGP#-YfrH6cq!^#@=ot6MtL-vp&*C2vP}RZ%-S1i zDxR5az?F%r?*4uTr_jcfSWZ-I@HCE1k2P%kQc3{u$m-24ucMmQPYKrZl0N= zd1*=gW}8%{SIq9-0@pDm@vw;iU+SuYyhTVJ1U4m}4g z3GR&!?{hfdw3Dper#9{XaxUs!`m4UbaB-eR98A(h$EXizB*NGYA5dbM|F5>QmPVlt z@95DBrZbm23jUrf@LQB{*s$m@?9kjz1f1?*iUi&sDE7C3@9KRCTB?W6=Oa%Gwpb18 zW*&kpmKP+8l^qYv_4UIy_{;iWn4btc&AYFF3XRKT4Vs=#{ipJe45+DWM>sX3fMNAL+^n1WDV)u-Q7bs8QoNH zgYsXnaE!{w}8y}nWTMv6>6B~^L^;&rn0TcIPf%3nemMY;Cbt2s|SnC zZEKlh9?Ar+JUNdNY=$qymf3@rF>TPUZcWXzfmU|sOY$^XK2V>eG8|^x5CiGHnD69Y zoGx%*#q)@H@%p-Dr$cnWx1EbW->IuCupSwwE3Y)tu}Y#w?gtt}Q2YD)%g;L#U!|wV zJlkDlWFtxY(IJvyw8Kq~2QkIZ2e#t5n`|)hx88PLM}3q4v|NHZ_SX==i>S9jwyn_& zsPC^$pYvJjxpn>ebvgl0S63Y~Gqd$4ckb|9jpGY1E-tR=O-@R(-JJY-y;jUt6>^G; z>&Qfd3b;~taG#c9$i`~K?1+1VOr`v3ZqwxiY~Yq=hX1p3D9)(uKA!lel?b`=3P8vD z_V+fPN?OzLn*~5m1rY5Kz|wx^B#WGEYn%IocWEg*cy?+E$7_oC{Gs@oSPnrk;7U5n z-~r&kgaa{gwF^QDE+!k5G)B0=~=0dpfS# zds?sW7Tmh?qj7prel5z%+Ir3k(iwuZut?Oj(GrXPsbq^Eqv}61C?x`vkr3`YF9lh+ zn}+6Js!HZoRu276Zvy)SZ{zBwg(7V+MV}HeK-ThJsy9pj?dOBKT5&W-&9+n>>{zTn z74XO8S7QdaoG^?OW?c@Dk3WFXa%$1tcz0Q8vvSa4j*{AAa&mM&p)Kh-QQCa`{1krU zHP@j|_RHmql&YK7@FNCY2GLgDf1mmPcY0FqQ%f~qF0EW`bz;zDA7}^#t7?PtC0OGH zDLG=qo+Cq?a0N?cWo3%GjI^}*<+;DzZ>l-Zni?%Q)0r3yeiX971cB@#{63~ifUIo) z=EDMjf>j9(*~GhS%YUh7(X#0hGqtuZJjKmz<*L5>Q?Y+?GUFm+D+da1M0Qv+OZwSe zS-}nrkWTi2)Zrg|Vse}7WCq~s=9V1ADQO1=CsOCnS53Z^W@K5W!dIVe>8r?Z|3kGL z4koCnBl7B;k|ugSK40t`-v?4zzYC6YxKH^S4-8&#=NDs{Nrr0w!0yIq*;z*((*YU< zr(Ywbn6;N5!WF3gPE;7UzPR|kt8`w}r*pb9Fqg60%lzEh7F9v9Vvw+U{AxMpf#2GI zWHRXM=fHsGV^DzMTL85z{G7`HAE5`LDB|!< zg1@ChEvBF-2?#|p8=IKS2aX`Eg{eo3odX5oj_b8;xo*#ByHLFv>@WK1lKblOTZ!8H zh{r6;k@1l4)pX>dRdTbDW>XO-t%u9^TE?{0HYQA3x#fn66}LJupldb>dh4#zKna4O)BxLY|oURJU3jTS)3>9hu=$TJBKVN zkKA@c-$`JfrhhHOcB>96ukN~?pm#>qclqTCQaW&d-SBIxUe^ba{Y_Om%PB6UpzS@? z3R1Xw!c30vA^`kG=BwOJ=UAwIFUx(Tcs_;|q3c*ShOUx5flo})e+ehlSBy6x+|_

    zop{6c@*+f_ThMjFA@(Mj@gHfst8s8PkxvhB2a=)j{DH)+KwCp91#7yqj3Sbf^y+@= zeHJ%cToSdqo&l?GMQ$fB^brj7|0)D*e*c3SuZm_kIIZsy{Bc(1ev&`3iWwdD zBC}fGzrF|&vm1I;eL^e|z!Y-l7u8}Fs|v?-&dA0G$az#XDN+v`OjCDJ=AjjuM3JN+b* z=s8k>Uq97HHBjKJ4bgdLQl9&2{S`;*yXa^pc&+h+A`-DZj>_C{^5p}|-V3t#d>%C| z#g-Naxjb@so@oY9#GZi|GgFB$TiMvq?0Q|?eUM`_c)b6ULiQtvdMz(7TO<}IFPFwdhrn`_Ax_V(hj z5HbEx4P@nX#Ka#miws)T-Ez3+M$yUc#D|}g5xqzDj9P*rPV@mDu3S7k6Uun)-qOny zLO$W@s0#l5$tG_6)N+D2YGA-z7@*B|wH=OvzIow<NKNn`nr^v?k8m>O=e{~1|w1^^lm~tstjXNNL=-9a4Z`v$&)oXvPjksgA?u< zQ{^0wFMSvaWurZ{kY0Ow*~>U}S} za(pf|q~qcJ@E8QIAR~@s)Zks2e*;|d6N}Y3vbT>ELoFqD{XcfdLY*ML~yre(v~v3gQFAThdDB6{fT8QlGwl$ab^B@s7t)*MHt z1iHk$8$i^2k(FcDM4D^++BjP$wO5c*;QOyNu+hUrRUtGDaCh*e( zQuUSm3B{Xj8%BHGr{XnI=mFk_hn%Df{>8;xELpYV6~et&VyKz9DOf|7pT;yus(q$4 z_FWlovp6zEWqMjglA-86maMU{^t`%wG=$ncjkpb(ItUFDa|uQO7Z+EfZ@PJfdoc{J z!Bxf=d4i&!-Xu90UGVzrKC}&~#!O4Plf>}3mOjh*q01AW*irw$K)Ic@sdupmyyJem zvZUEVD%TtF*Yd4mMmxA|=4Mv>ThW&w!2Y^1(=ryF^w*-R?LDouK(O;VTIvobZT!TVsyizZi&=0|gX^Sw!a+K(ZoJ$U-WP2CBxao+JqcJeV%eZBh6 z0Xo*`{8xvjGCAui-Yc+sRM)CcJ-nI(QOrw`4xrRU2p0V#BRqk>0#8~oQVKB>hO&^> z6p>p8ITf$J8Kq3M5mQsf_WVfLPOS`WS>V{X? zY~2TP({k-OY49ts@T#jH8hGggD>&rwlH_?QJf6vGwfg4)G;n8$XXEdOC0xOGyxtW< z)0^6LepQSBM`QfNlU#MKc*)F(yzl(t!O-l9pU2}iA3axhmw47--^Ek!U7UtXyw7BO zbc@}kYdaA4V`C)izGcqaX;6CyJSFcjh13YSv)*Vm2CLXSE3g;AD$gNCuI?YR;2ub- z95>s4x)B+(PVUE%Txec;#8ZJHpw|x6j;di?*2g5Ph#u{N+b~)R(woX?N*#?lRKAqm z%>OFTR5ZKX{KCnmx3JjAdtbstj=#hcXXAT0Ec zICtCKOFNuc>uoKx_Mamt_Joe{W$_S?iPlT7?_ll+&C;oK8#%ul)0}^ksDf&108m@h zOR(c~%l!7AG#GH-#)<{@cfL@0kH98jz`RUxz z<@;2a+?!;t9$&7o7-#}ZRp!wWBJ@nHhh|=lF`a$zb?ta?uzOt-0Fq0%by{%4gn6X+(uP)=6jZuE?KIG1z zd^PkH#e%QCoxTkZ`m1R?=fJIx9!{OF#i==x5_tqDBU|hLVSPZs6wOBvuw?bVltMwj z{wCPWAo@*8PL9ilCLi3^@qdAte?X{hka2oV&Mhfd9_#kwt}HP`w-RmzD3kEsKkMeWj~BwBS>QH@#As&-0B#th?4kTx>Fv;xXr%qA zax)%QtFWKv7VN4Zv>zHFa1_e90n@8MceJEzBOK>SgkeVruxbsKj^^Wb)~-`!Fi51t z)}gp3zvvk5PkKBy&?uNs$8-sp23Y+3(oOqBY& zyP`biSDV8xDod|kCP!Ry>a1;zAmDYoDS_IvKF(RVablRyWi!$sIhURsMLrn6a!+;Z z9C}d6yB}Nu0_VvM$$hiRM{xrU7)|c&x`XQWh7!%+{io^Jjp?*1ZoMoJZ{kK-vQz_< zuX_lREGO!Bl&#Q>Tp(c)O?d-I;7p8j9F8vybs21}$I-&`+-5-rAaY;w%s6b_-smYN zhwd2ML`fZjob`5}mfV!cJugDGfMo^uch?-gO7+?~E1wPiy$#(98*-!ue39dykKO0a zIBpppAV0P}2w zi7{2{6t4-O%glTMBpzmvtBe9q=iDg=$O}EA$QLdD4R12+-HK>;&|4H#d6);u^k(rf?P8V@adC zp7-_`NLAji%n#!--Ye}eBl$KGp$u#I)~R`elS#oylA0cVx2GdUJ;4Qe=C63H4GXRy z_db?b&B2B>^(JFxxV8F?6J{*MLbAidYiiup&wEV7gMX@WM`bPR*_B44$@K#xWuDM) zbtK41C2#y3(WF|BZWk0YI?@F*B<2UHyrd$=x*t#%9jUIM!Q?XYc8TlBuLSNVH~T>T zU9RMV#-EPIAEwtYFl0c50I%zAHmh&FUiYivoKuljo%;FKXQ+NtVw z5u}C(+{XHjCZ&kEBdXK3GX!PDIdozOq#z}aUD>%es`-@|#nzb2&9H;~#}Emi-{BIQ z$St0ioMLP7*97vw_{QWYv76I-+%pg6xc7G9%9AMiEaYj1jmPX)L!l>O-;K0^$T$L& zI|@K;R3hc_T|+>0$;IZUQ1(BW?-86ij>o9jVH literal 13910 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 M;H)vO5Mv+qF9fZsF8}}l literal 1914 zcmbtVc{JPE9*;&XeTp0-qGF2~N$C=dZKO5Yc&XB~)1s)BQd`>rDJhwgS9Ky+Wr?7lLSLVmB}7bho-&3Tl|YN$&+Cj$4m+L{iwt@a zxOP9ymh0zBzYbuK0@OZ1^^pA7i&Zys1B7QgJ(!%lvZ&qBnr63_xcy&f`k6(z(%uNJ zuX_mKz(UKxwG4^-Tpt9|srSSB1ZI>hzH#!0C%`(E;=W6MrkkV3u%O+7sv$3gi4B4f z;fyJw&obP^b`%O#>lY#ffm$PQ$s?NY$JZLpg)Brd3(9Xn9lO8pXnd9oe#JWvx3f4c zX0Py9`tvo`+Bvo^%7HBxFBcZ+)z#*(UGW<}WKf1g&-jPGMyloX&g9n#pB}F~Vp!*N zWu_Tx7nnr5Ub}~x54=uxn;}5*&l)zHYpl1U6c$$}fmBn>XQuf)#h^63g3{u?yo@tUPL5Ur(RuW+cIZ2lA!_3R|0O{< zZcM3SugR}N?BD3n2eg{qDGzdN&@2|Km~r?^m#(m8gpcw4%(l{uEOtaRyFOqGmN2-J%ih05;UjO6Xm?vpRdTM^13zt;eb|_n0Ti2U-GIF$u^o3F-+gb>` zl*ktbW;GPC4)a!iIyaY2c6M`m|GVMMgPgtSqe%T<(05k_kco^7X*HMX$t3z|Y_~`e zT?_pxY=$ z0ARPBZ3FSTI7iZ~m)N!-ov^bYRt_Z0#S`{1vc;7b@~WNoO&CzzK-{`@t$ z;+-PKn^g=MATOe@)Eg$If;7PxLVff2|Y^uBT^~7X~ zDqsQ7;`QrF<43+6L$r833LAgE0;G$aA1;i|YG6U02OcUCPal5bc<%duai-Vj&qP<0 zcKShl3&k&ruNWW@Mh{Dt$bIrgPYgyq8<&?i_%~NDwgOa%az5m?_3TBdxvN4dti&dD zP9(L5j?aaf4BIYliXrXxI8RRoH?}k9y@>^D&4zHo z@vBllv$afpFlk@dC9u-F|G%=fmr{3GGKrwwExJtbvn|4w#I z;PSvA-u0W6i(D@Eti#=0if*bijtGy~7ZFzZLA-TgkU!on+`Xc$E`D&){VMnmdq@^K z8$N&5Pl4GeCUuk$^p9=0)*}Y!&*9Lb<@VrFO`wB41HpWZ6y(?>e|GOcTd+ljeRm^@ zkx$G2{mK|hq{@z%Sp2y;X61|U&O0YR8C=Vb6SbH}K#j}67hZee?~x@0uTZxAWR5jQ z!rN`OC^H*J6RD(PnC^x%k=oDEHOn=8MniTCxf7`Ye6U&TUT~1M-hY8+7g+#1aMjuW RGVqy#{Cx3P_OZyEe*^Ccg~b2> diff --git a/icons/obj/ammo/casings/flechette.dmi b/icons/obj/ammo/casings/flechette.dmi index 843be2012554809e6ecc20027c45f10f434c1063..665e280da34221e8402c3066370932c7aa2e0df7 100644 GIT binary patch delta 460 zcmV;-0W<#C1Ed6y7e&AX0{{R3pz?7v0000UP)t-sz`(%T+S%&r>i_@$z`($_x3_b5 zcxGj2P*6}-Sz4&v<-q^|00DGTPE!Ct=GbNc005woTuy(tpeVI0Gqqfai!&v&s2C`2 z!Nr+Yl$e_eVjH5VCQg-ZQfW?3Y6+2wa}$fQGxO33s?N+SOU*0EFRDbSG$f!B!yyDU zU^oU!fRDs; zxN_|+yo!IvbxljAshyD^|F`SBieb|_qyzx?UT-ZJ^6}1@pgCT|g3~l?jd(nZ6UDqH z7F^}L8p!Y0rVrGpc|9^U_!7*#GV?70003YKGlgK`%1s?-)t+9h9I&e6As?&$!K(k; zVE>SkIAE0XQnY^n0000s%iTXnquk)D{~Le9B@=vl`v=ny++Y3Qf36n*007ph!u>;^ z4GY{q6t6wM=m37o|NW2?-wy!*0ANFm`vY~Kkn(YT-Ww7C008{0>ZRfO6WmK5_>3N4 zG#K40n!vEXksz2L`~cMxbdTTxmczSpg6h8jSkMOuJq^l%t|nms0000gxah|JvHwz`($_x3_b5 zcxGj2P*6}-Sz67!hc^HK00DGTPE!Ct=GbNc005SeTuy(9i!&v&s2Iq%;NnaxO3Y0K zu?^8w=_Zxt;WC_6JRouKN>yt351lKi4dgi1pKDlr^FPy>czP<1FPxca$( zgAV{;Sz!)8>Y%m&0072GL_t(&f$iBb4#F@Dh2hdllo9m=hJm?9VPfVMT!rH@_oYfy z*@hzh-{ya$^=mUFO4k7Z5}oVyVQatsA_FG#je3$=-!I7nSDh~gwg!0V5(5AL0DIBv zfJFybwH{`7f*e35cSEn`FAc?fIpPXfSwa7z0ssIY!OBL^yK|eXW%%ARfcFGojT!&| z0KosSWvLey#RWz>tJmNEAOHXW{E89Ka*uBKjBYR}##eH{@kW3%!2JQ~0pr8jpyl*V e4oLq4V8=f6JqX;_96nb70000PrZ%y&KEE5+<)aoAP+;YiI8jY{`zAM8L6H#44aR2=&EP0jZB>kOJm}bE{aSMS zpS7n$imR>KHwv8p!7< zlf0*kV@SoEx3@QT2?t6zJhV@m>?Ck7VLyLDVtR3K#F^xr*W5R`ZfS2i>L+-J=bF>5 zz=+vfCvr4vR0t|1Cm%_RoGES5XBjWCU_QV@I%9(;`w7eV zCv)^)SbF)G9at~^uQW6?e+7r;QpM*sG4($^s4$EF|_aSTH+FW{r-WiKV=;%e?Gc;a#g0k@}rWgThx#6eEwN;ZCma|>4Hs+ zd3Sfp_D@^+L)JsOwD-pT2igBE!+gE_19LW6C;WbyT(e_O&+_y0j{h#te_7}@`wd^j zoxR_GCuf|pKDb&Xaq?e|U-1%X0s2G#;nO0|{)QrUB0VlG`{2zUxuSE-)c1 qZ47$HAW>JgrT!FmDwepq;cu?fp=19by9Jo289ZJ6T-G@yGywn<<3Ec4 literal 660 zcmeAS@N?(olHy`uVBq!ia0vp^2|(U1Mao(w?Ik;x2PJbY!DKnLet1swIckhm8`CE6} zIy>C!SX>)0>tB+WvD&$(TVwP7ew1{HuA7^=P}=mx!4u|}(-YeLl%Mr7Ffi`$ba4!+ znDh4bUN2@xiPndkH*silDDAlMoJr?RjvaUR&YmqVi!^r%xdx?l36yQz<~KPz!bP#U zsmC|z`TaMK3eQ&lO11lT)<rlm@L zw&{=M|2FgOuKhcoxu02cRi^Tk>*=RL3>zYJ7#RA`uis%|pKW}+-^BNGc6M!QwSG|Q zFUL0T_l)=~z;8WFb}dtjK$v1nX!zkbi=Hsdmacz3XLq`*!Db1kAHwy){#RcspQz@4 zE>qnTRwaADlKs6ckQK%L;okb)5-Npn@7`rJzrMY>GL)Z@=Xt2@i@YW8wY!v7zqU$V zb9d?!hW6v`J9cfkx1TB4H{GsHVA0H@FVCpg3wTty@i5Gr#eQbB)z_k%9(8UxMl+B6 zeZ;`Ql$4a#*4Dtl zz`(%3b9Z=VWoWmzw@^?}R#{qO2V`jg0004WQchCk!4PQx1cDsEHkxS ziHkEOv#1y-Zo$QwR+N~V3St|gsU}X9Zc=GZPHG8}igOc-vNQA2398P_D@)BQ$uFuz zs5B&?62l<`HDEXfRfn>ItDg%vumN^BZwhkpz6byS0b)r+K~#90?btk(STvK?ZuAA^k9#y>*G9+n-kI`C$x_c=6U;o z8F|Dw>jc>_Tki$POX{=joVOUZ^8o+=@Nd;$4W0TSF1o{-MHW3)H zeOZZASU>1bESaDa3hM{=M41+WB=7fzrA0{{R3s0My+0000dP)t-sz`($UjgiE}#FUhj*4Ebl|Np?i zz`(%3b9Z=VWoWmzw@^?}R#{q(xQMj?0004WQchCd z5?*+vTyRK;3Mhdh=zykwAVQjN_tqHO!NL1vwrBm#B7)hf0)RJGJK1RLQjepxYuWI< z$@j4rcHT_}bQ`-~+4IIr{h+~i*-sYuh1A2F_#e)A@d01=gVt4!I8i004N_ z$4}va-Dlx|-+vcyJjr^WIpFY>`9cD+2P8L8JV5`Z*_|(i1B$-^@VqN1$R5P)`cCrz O0000k!4PQx1cDsEHkxS ziHkEOv#1y-Zo$QwR+N~V3St|gsU}X9Zc=GZPHG8}igOc-vNQA2398P_D@)BQ$uFuz zs5B&?62l<`HDEXfRfn>ItDg%vumN^BZwhkpz6byS0ZvIoK~#90?bcvg_H&*Sb?|HA901^I zJ{SqB8yS$;8|z!iZ@Qx-JjC((F^=zLzB`7|^?ulo7dZDae~#nb5N}!6C*&6Wpb3LM z!&vf&l@C$aB>9p6004lcsD3o`2OT+0JltCS!$JFjlf;?*gKOn~0$nfjnf-%vcX7DV zc|)rM{Vz!X006)otaZTpcU^U|K#%7}|B!Y_YS)h!F!~2C%WX-EG_ilsS1iT(P`LmA z008E~hbS!n{y{&k>5T-N57+MHk225W1#WR1-wy!*0AN8v9Bw3TjQnIiahW#1aYif~ z00000W^4OgxxmXqQ|1M%^Zx790?B#)5{Dn362DC>V0phSe8J@v$lgHp0{SZ|?(4g9 ef$Dbv{G%T>@gc?8g6wku000041QQDQ0K0F$@?#=>&M z1!igKC=!u~6F7oHxPeQ5+3H7BwUr6)v-|qD{X1gOW*Gn=oxGF*$%XHRotd4@MCwyJ z52Zeqtm`wgd_AG6rC!;2q;+lJVsxN>GU-lUdNu$6006$FqXWLTW0#e_2j*7nmZ1%d zJV3^^6$?9lVqnMIG2N7o1IPq#MPtRspHLH~hZ_ p!3Rj*K>tP2U9O26B>w`S#cp*Y8aEyxh)Vzf002ovPDHLkV1nXj$65dY diff --git a/icons/obj/ammo/casings/rifle.dmi b/icons/obj/ammo/casings/rifle.dmi index 51d89cb5f4b87b402b105fc93198f6d8d93f2b0d..239b0332c32ab08617e6384e588ef243fc859733 100644 GIT binary patch delta 591 zcmV-V0k!4PQx1cDsEHkxS ziHkEOv#1y-Zo$QwR+N~V3St|gsU}X9Zc=GZPHG8}igOc-vNQA2398P_D@)BQ$uFuz zs5B&?62l<`HDEXfRfn>ItDg%vumN^BZwhkpz6byS0f9+GK~#90?b$(2!!QtqVH1K- zS&7k`>pHdo2lMEi1OUJe~=v-MgZ1bBy003|y{*+lJ z0KkQ~Kan7@dpmQ$)Pr||-N`wDeFkEK@$qU+kVH(k3-2%11j6+vFu#C%0{bcwKEIq3 dxX%FC&^OPmD$%yoakBsb002ovPDHLkV1jU^BxC>p delta 488 zcmV+I{Jq@%#V z!2kdMx3{-*cX(!HXi!j4R#{pPDR%n+0004WQchCmz! z008{2{Z|7bmL=f}D=A=U=v4k_xiVYK4z7T)tM?o13IG5AfPqMl_lpM@hvS9+uFy7C z1K;Vr?x40v;Xg3|0Kjj|&jchE*TMs)meB!=b8tX-1@}vE!0kkUGr&E8@PP2I=e~?g+mGe0000 zz`(%3b9Z=VWoWmzw@^?}R#{p&Qk!4PQx1cDsEHkxS ziHkEOv#1y-Zo$QwR+N~V3St|gsU}X9Zc=GZPHG8}igOc-vNQA2398P_D@)BQ$uFuz zs5B&?62l<`HDEXfRfn>ItDg%vumN^BZwhkpz6byS0WwKMK~#90?b@+z!!QtqVV*1r zE?r~*mMH^B130h?ml?r-qXemfOpp;WL^jA$sriVArbr41{D0k%^c@8^caWR|0IX)d zae>_-jJpR}7$i2$p!?50EO3BTJ`ILrQUmUs#)>IEb6h&JhgDU~6?d=Pd~IynFU z0DybZyfw60S5Ae^t(vvpKZS8$I6t^S59qv5I6oBI>B3Xx0ssJi0KisyT{vbYF!_PD z=ZX0to{-ca?Y0gWiTS}c@7DDdOLgWO7XSbNz<*&r27s0%s|A7M6_Q2)F^I zrK8w*=Q)8RID{Lxlyx3|IAShIf&PEpldm^G^I{ADU`49l&$VQ$8+3l_XD8XX!}5Yo z=Ic)KuzbNFrvt;xA^-pYU=1oA(DpmkvG=pxd9jh{c(o4r{{wbNEfCA~feXljXm<4C z^cBhi0002|tm3U<{^mCIMzXz~9GBW|pVPJj0002^TB8GFU_SOsJnipW6Ud<-4ml41 z008)3n@iyW*L~&#A5Y1*%mwbJ%m>C6NWMVv0{RWId%X)6DEHYaZfQgQ)4A+84w9QgD9+V%Sh+xq#$ zJeee_*?4$(jEsz&ml{ki;r2cowH&CDu_VYZn8D%MjWi&qxGE%~#3i*jxhS)sBr`vc zfuUkfa9BZ6>GvSI(O!L@P<%>i^dNg>74h`Jjqbh)4RjMILP?2v6sS} zN0W|B3Q-7NX|rEL-LmG#{Kq%Koc1}UHx3vIVCg! E0Gyw2RsaA1 literal 0 HcmV?d00001 diff --git a/icons/obj/ammo/shells/blanks.dmi b/icons/obj/ammo/shells/blanks.dmi new file mode 100644 index 0000000000000000000000000000000000000000..322c1deccfe3de9052d83ce2072a1a590dcf69df GIT binary patch literal 312 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!VDw>HYaZfQi=gSA+84w9QgD9+V%Sh+xq!B zJ3II9-_OItV`OCX|NsAM*RD-2;l5d?eg~+Su_VYZn8D%MjWi&qxGE%~#3i*jxhS)s zBr`vcfuUkfa9BZ6>GvSI(O!L@P<%>i^dNg>74h`Jjqbh)4RjMILP?2 zv6sS}N0W|B3Q-7NX|rEL-LHYaZfQgQ)4A+84w9QgD9+V%Sh+xq$3 z85pV<7GvSI(O!L@P<%>i^dNg>74h`Jjqbh)4RjMILP?2v6sS} zN0W|B3Q-7NX|rEL-LmG#{Kq%Koc1}UHx3vIVCg! E02P~W$^ZZW literal 0 HcmV?d00001 diff --git a/icons/obj/ammo/shells/flash.dmi b/icons/obj/ammo/shells/flash.dmi new file mode 100644 index 0000000000000000000000000000000000000000..e715a747393ab781d6793e9e6f26f8fb86c1649f GIT binary patch literal 329 zcmV-P0k-~$P)V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRL zOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5sXV_ZCq;>iGbOXA7|1u|;!G<_%uR)`QB~;{ z7o_Hu;8Lrs;OgfBb^-t*vnNpXH}w+$002=*L_t(IjbmUK1%nAN65um18H$9Zg@%SE zAoD{ikaQTS&RR8d=FAN!{O|@06E@&BK?Owtgzt{zhQp@byIovd5>WXCa0Se0jz;H? bf}sKcI$#=eJE-@S00000NkvXXu0mjfi}r+s literal 0 HcmV?d00001 diff --git a/icons/obj/ammo/shells/haywire.dmi b/icons/obj/ammo/shells/haywire.dmi new file mode 100644 index 0000000000000000000000000000000000000000..671477e93dfd2e71529d26bc89c7ff9a3e788f77 GIT binary patch literal 340 zcmV-a0jvIrP))nFSFM05da_bPE|78Hw6FmjD0&0d!JM zQvg8b*k%9#0CRd&Sad{Xb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1D@x2w zg|Jao=@u8H=9S=5tE}Ma=K^*D03x#|Q1v(U6951JR!KxbR5*=eU>F612{01iGcXy7 zgrudVxjLZm%aC*!skC%-ba*(R@ZA%TOpus0D{AS|1_Xc4o;`$3Kyt%nlaP1s-XYuo m;TOOaFrzsdoj(eO3IG6F2OiC->Y4cf0000V=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRL zOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5sXV_ZCq;>iGbOXA7|1u|;!G<_%uR)`QB~;{ z7o_Hu;8Lrs;OgfBb^-t*vnNpXH}w+$002=*L_t(IjbmUK1%nAN65um18H$9Zg@%SE zAoD{ikaQTS&RR8d=FAN!{O|@06E@&BK?Owtgzt{zhQp@byIovd5>WXCa0Se0jz;H? bf}sKcI$#=eJE-@S00000NkvXXu0mjf+BSjG literal 0 HcmV?d00001 diff --git a/icons/obj/ammo/shells/slugs.dmi b/icons/obj/ammo/shells/slugs.dmi new file mode 100644 index 0000000000000000000000000000000000000000..6f081288fa1cbe9a247f0810b31a5edd4eddb459 GIT binary patch literal 302 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!VDw>HYaZfQW60^A+84w9QgD9+V%Sh+xq!< zczBGAjKagiCzo(L1@Ke@)i9O>`2{mLJiCzw=P@u;%n1%F zC@TH_CAi?@*C$%ux?1PXoDbd*YH-o`!6TjXKAI;Pih6o?SQrNxUpDqqnDc1Tkx3y6 z!7FX{YpA<+b{ng1ULkS9{K+F9ZLc%Fts4SEUy6w@c{cSy(CRf0UOi_jV`5O+tRC>y z{Hrj~dRI>u#}JF&fjQG>;nQgiLO+JND)(@3QC^`$SYKm!>(UHx3vIVCg!0IN7{1ONa4 literal 0 HcmV?d00001 diff --git a/icons/obj/ammo/shells/stun.dmi b/icons/obj/ammo/shells/stun.dmi new file mode 100644 index 0000000000000000000000000000000000000000..1387132510cdb4fc9def4c032ccbb205bc624c06 GIT binary patch literal 342 zcmV-c0jd6pP)fFDZ*Bkpc$`yKaB_9`^iy#0_2eo`Eh^5;&r`5fFwryM z;w;ZhDainGjE%TBGg33tGfE(w;*!LYR3KBSJijO>MTv_uC9|j)$T#HTOe;#vO@**g zRp}NNq~?|2Qmd@s>gNJ>0stbjCs6e_^%DR909#2!K~y-6V_+Bsg9$Ja;4?58ikPOQ z1sf-z@WYUF7%7WY%uEyvK;o~SnVNuXg6i?KAf*5#{w-7!RKQjQpzuSH+~92D78;u3 ol7Pw&fGc1|b2K`C6buyr08bAUQElNnQ2+n{07*qoM6N<$f)c}mO#lD@ literal 0 HcmV?d00001 From 1b9e252fa251ad3f7012cd3d0a378e29a9a601eb Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 18:01:08 -0400 Subject: [PATCH 297/512] Fix issues with ammo interactions --- code/game/machinery/turrets/turret_ammo.dm | 3 ++- code/modules/projectiles/ammunition.dm | 14 +++++++------- code/modules/projectiles/ammunition/boxes.dm | 2 +- code/modules/projectiles/guns/projectile.dm | 1 + 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/code/game/machinery/turrets/turret_ammo.dm b/code/game/machinery/turrets/turret_ammo.dm index 2ae590923072..1e341f16a4dd 100644 --- a/code/game/machinery/turrets/turret_ammo.dm +++ b/code/game/machinery/turrets/turret_ammo.dm @@ -58,7 +58,8 @@ return TRUE stored_caliber = magazine.caliber - for(var/obj/item/ammo_casing/casing in magazine.get_stored_ammo_count()) + magazine.create_initial_contents() + for(var/obj/item/ammo_casing/casing in magazine.stored_ammo) // Just in case. if(casing.caliber != stored_caliber) continue diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 96804826c533..e1d5f0a8cca6 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -211,11 +211,11 @@ return TRUE /obj/item/ammo_magazine/attack_self(mob/user) - create_initial_contents() - if(!stored_ammo.len) - to_chat(user, "[src] is already empty!") + if(!get_stored_ammo_count()) + to_chat(user, SPAN_NOTICE("[src] is already empty!")) return - to_chat(user, "You empty [src].") + to_chat(user, SPAN_NOTICE("You empty [src].")) + create_initial_contents() for(var/obj/item/ammo_casing/C in stored_ammo) C.forceMove(user.loc) C.set_dir(pick(global.alldirs)) @@ -226,12 +226,12 @@ /obj/item/ammo_magazine/attack_hand(mob/user) if(!user.is_holding_offhand(src) || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() - create_initial_contents() - if(!stored_ammo.len) + if(!get_stored_ammo_count()) to_chat(user, SPAN_NOTICE("\The [src] is already empty!")) return TRUE + create_initial_contents() var/obj/item/ammo_casing/C = stored_ammo[stored_ammo.len] - stored_ammo-=C + stored_ammo -= C user.put_in_hands(C) user.visible_message( "\The [user] removes \a [C] from [src].", diff --git a/code/modules/projectiles/ammunition/boxes.dm b/code/modules/projectiles/ammunition/boxes.dm index 2e1401668335..c302688b2f69 100644 --- a/code/modules/projectiles/ammunition/boxes.dm +++ b/code/modules/projectiles/ammunition/boxes.dm @@ -63,7 +63,7 @@ add_overlay(overlay_image(icon, "shotholder-marking", marking_color, RESET_COLOR)) /obj/item/ammo_magazine/shotholder/attack_hand(mob/user) - if(loc != user || user.a_intent != I_HURT || !length(stored_ammo) || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) + if(loc != user || user.a_intent != I_HURT || !get_stored_ammo_count() || !user.check_dexterity(DEXTERITY_HOLD_ITEM, TRUE)) return ..() create_initial_contents() var/obj/item/ammo_casing/C = stored_ammo[stored_ammo.len] diff --git a/code/modules/projectiles/guns/projectile.dm b/code/modules/projectiles/guns/projectile.dm index 10aed91cf2cb..8b6a8a01dc01 100644 --- a/code/modules/projectiles/guns/projectile.dm +++ b/code/modules/projectiles/guns/projectile.dm @@ -138,6 +138,7 @@ var/obj/item/ammo_magazine/AM = A if(!(load_method & AM.mag_type) || caliber != AM.caliber) return //incompatible + AM.create_initial_contents() switch(AM.mag_type) if(MAGAZINE) From ae7127553c3f33f816af69e6d4fb2b91bb1e1055 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 18:06:48 -0400 Subject: [PATCH 298/512] Fix ammo casing colors and materials --- code/modules/projectiles/ammunition/bullets.dm | 7 ++++++- code/modules/projectiles/ammunition/chemdart.dm | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/code/modules/projectiles/ammunition/bullets.dm b/code/modules/projectiles/ammunition/bullets.dm index 580bd7175f46..f68791fe4520 100644 --- a/code/modules/projectiles/ammunition/bullets.dm +++ b/code/modules/projectiles/ammunition/bullets.dm @@ -26,6 +26,7 @@ desc = "A pistol bullet casing fitted with a single-use ion pulse generator." projectile_type = /obj/item/projectile/ion/small material = /decl/material/solid/metal/steel + color = /decl/material/solid/metal/steel::color matter = list(/decl/material/solid/metal/uranium = MATTER_AMOUNT_REINFORCEMENT) bullet_color = COLOR_ACID_CYAN marking_color = COLOR_LUMINOL @@ -86,6 +87,7 @@ projectile_type = /obj/item/projectile/energy/electrode/stunshot leaves_residue = FALSE material = /decl/material/solid/metal/steel + material_alteration = MAT_FLAG_ALTERATION_NONE matter = list(/decl/material/solid/glass = MATTER_AMOUNT_REINFORCEMENT) origin_tech = @'{"combat":3,"materials":3}' @@ -93,6 +95,7 @@ icon_state = get_world_inventory_state() if(!BB) // use spent icon icon_state = "[icon_state]-spent" + /obj/item/ammo_casing/shotgun name = "shotgun slug" desc = "A shotgun slug." @@ -100,7 +103,9 @@ icon_state = ICON_STATE_WORLD caliber = CALIBER_SHOTGUN projectile_type = /obj/item/projectile/bullet/shotgun - material = /decl/material/solid/metal/steel + material = /decl/material/solid/metal/steel // at some point this should use matter, brass + plastic + color = null + material_alteration = MAT_FLAG_ALTERATION_NONE drop_sound = 'sound/weapons/guns/shotgun_fall.ogg' /obj/item/ammo_casing/shotgun/update_casing_icon() diff --git a/code/modules/projectiles/ammunition/chemdart.dm b/code/modules/projectiles/ammunition/chemdart.dm index 5af9b22fc6c0..1a5fe0e634a4 100644 --- a/code/modules/projectiles/ammunition/chemdart.dm +++ b/code/modules/projectiles/ammunition/chemdart.dm @@ -30,6 +30,9 @@ caliber = CALIBER_DART projectile_type = /obj/item/projectile/bullet/chemdart leaves_residue = FALSE + material = /decl/material/solid/organic/plastic + color = null + material_alteration = MAT_FLAG_ALTERATION_NONE /obj/item/ammo_casing/chemdart/expend() qdel(src) From e9f29e3c9d8b0b461f718af713338fd33c579e5f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 18:22:58 -0400 Subject: [PATCH 299/512] Fix windows not properly handling material alteration --- code/game/objects/structures/window.dm | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 00e0d27d24f3..00c92eeb3068 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -11,6 +11,7 @@ atom_flags = ATOM_FLAG_CHECKS_BORDER | ATOM_FLAG_CAN_BE_PAINTED obj_flags = OBJ_FLAG_ROTATABLE | OBJ_FLAG_MOVES_UNSUPPORTED alpha = 180 + material_alteration = MAT_FLAG_ALTERATION_COLOR material = /decl/material/solid/glass rad_resistance_modifier = 0.5 atmos_canpass = CANPASS_PROC @@ -38,10 +39,19 @@ connections = dirs_to_corner_states(dirs) other_connections = dirs_to_corner_states(other_dirs) -/obj/structure/window/update_materials(var/keep_health) - . = ..() - name = "[reinf_material ? "reinforced " : ""][material.solid_name] window" - desc = "A window pane made from [material.solid_name]." +/obj/structure/window/update_material_name(override_name) + var/base_name = override_name || initial(name) + if(istype(material)) + SetName("[reinf_material ? "reinforced " : ""][material.adjective_name] [base_name]") + else + SetName(base_name) + +/obj/structure/window/update_material_desc(var/override_desc) + if(istype(material)) + var/reinf_string = istype(reinf_material) ? " reinforced with [reinf_material.use_name]" : null + desc = "A window pane made from [material.solid_name][reinf_string]." + else + ..() /obj/structure/window/Initialize(var/ml, var/_mat, var/_reinf_mat, var/dir_to_set, var/anchored) . = ..(ml, _mat, _reinf_mat) From a6f50c82ec7ad5bda77b4fba3d612dd4e49e739b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 18:23:10 -0400 Subject: [PATCH 300/512] Fix placed reinforced windows being in an inconsistent state --- code/game/objects/structures/window.dm | 28 ++++++++++++------- .../crafting/stack_recipes/recipes_opacity.dm | 8 +++--- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 00c92eeb3068..d0898af0ec67 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -7,7 +7,7 @@ color = GLASS_COLOR layer = SIDE_WINDOW_LAYER - anchored = TRUE + anchored = FALSE // Base, non-premapped type should start unanchored. atom_flags = ATOM_FLAG_CHECKS_BORDER | ATOM_FLAG_CAN_BE_PAINTED obj_flags = OBJ_FLAG_ROTATABLE | OBJ_FLAG_MOVES_UNSUPPORTED alpha = 180 @@ -23,7 +23,7 @@ var/const/CONSTRUCTION_STATE_NO_FRAME = 0 var/const/CONSTRUCTION_STATE_IN_FRAME = 1 var/const/CONSTRUCTION_STATE_FASTENED = 2 - var/construction_state = CONSTRUCTION_STATE_FASTENED + var/construction_state = CONSTRUCTION_STATE_NO_FRAME var/id var/polarized = 0 var/basestate = "window" @@ -60,6 +60,8 @@ if(. != INITIALIZE_HINT_QDEL) if(!isnull(anchored)) set_anchored(anchored) + if(!anchored) + construction_state = CONSTRUCTION_STATE_NO_FRAME if(!isnull(dir_to_set)) set_dir(dir_to_set) if(is_fulltile()) @@ -482,6 +484,7 @@ ..() /obj/structure/window/basic + anchored = TRUE // Premapped type, start anchored. icon_state = "window" color = GLASS_COLOR @@ -496,6 +499,7 @@ name = "borosilicate window" color = GLASS_COLOR_SILICATE material = /decl/material/solid/glass/borosilicate + anchored = TRUE // Premapped type, start anchored. /obj/structure/window/borosilicate/full dir = NORTHEAST @@ -507,6 +511,8 @@ color = GLASS_COLOR_SILICATE material = /decl/material/solid/glass/borosilicate reinf_material = /decl/material/solid/metal/steel + anchored = TRUE // Premapped type, start anchored and fastened. + construction_state = CONSTRUCTION_STATE_FASTENED /obj/structure/window/borosilicate_reinforced/full dir = NORTHEAST @@ -517,6 +523,8 @@ icon_state = "rwindow" material = /decl/material/solid/glass reinf_material = /decl/material/solid/metal/steel + anchored = TRUE // Premapped type, start anchored and fastened. + construction_state = CONSTRUCTION_STATE_FASTENED /obj/structure/window/reinforced/full dir = NORTHEAST @@ -538,6 +546,7 @@ basestate = "w" reinf_basestate = "w" dir = NORTHEAST + anchored = TRUE // Premapped type, start anchored. /obj/structure/window/reinforced/polarized name = "electrochromic window" @@ -629,27 +638,26 @@ if (!ST.can_use(required_amount)) to_chat(user, SPAN_NOTICE("You do not have enough sheets.")) return - for(var/obj/structure/window/WINDOW in loc) - if(WINDOW.dir == dir_to_set) + for(var/obj/structure/window/existing_window in loc) + if(existing_window.dir == dir_to_set) to_chat(user, SPAN_NOTICE("There is already a window facing this way there.")) return - if(WINDOW.is_fulltile() && (dir_to_set & (dir_to_set - 1))) //two fulltile windows + if(existing_window.is_fulltile() && (dir_to_set & (dir_to_set - 1))) //two fulltile windows to_chat(user, SPAN_NOTICE("There is already a window there.")) return to_chat(user, SPAN_NOTICE("You start placing the window.")) - if(do_after(user,20)) - for(var/obj/structure/window/WINDOW in loc) - if(WINDOW.dir == dir_to_set)//checking this for a 2nd time to check if a window was made while we were waiting. + if(do_after(user, 2 SECONDS)) + for(var/obj/structure/window/existing_window in loc) + if(existing_window.dir == dir_to_set)//checking this for a 2nd time to check if a window was made while we were waiting. to_chat(user, SPAN_NOTICE("There is already a window facing this way there.")) return - if(WINDOW.is_fulltile() && (dir_to_set & (dir_to_set - 1))) + if(existing_window.is_fulltile() && (dir_to_set & (dir_to_set - 1))) to_chat(user, SPAN_NOTICE("There is already a window there.")) return if (ST.use(required_amount)) var/obj/structure/window/WD = new(loc, ST.material.type, ST.reinf_material?.type, dir_to_set, FALSE) to_chat(user, SPAN_NOTICE("You place [WD].")) - WD.set_anchored(FALSE) // handles setting construction state for us else to_chat(user, SPAN_NOTICE("You do not have enough sheets.")) return diff --git a/code/modules/crafting/stack_recipes/recipes_opacity.dm b/code/modules/crafting/stack_recipes/recipes_opacity.dm index 6efdd97db9d3..dccf4e889e6d 100644 --- a/code/modules/crafting/stack_recipes/recipes_opacity.dm +++ b/code/modules/crafting/stack_recipes/recipes_opacity.dm @@ -25,7 +25,7 @@ return FALSE /decl/stack_recipe/opacity/fullwindow/spawn_result(mob/user, location, amount, decl/material/mat, decl/material/reinf_mat, paint_color, spent_type, spent_amount = 1) - . = list(new result_type(user?.loc, MATERIAL_RECIPE_PARAMS, SOUTHWEST, TRUE)) + . = list(new result_type(user?.loc, MATERIAL_RECIPE_PARAMS, SOUTHWEST, FALSE)) if(paint_color) for(var/obj/structure/window/window in .) window.set_color(paint_color) @@ -45,9 +45,9 @@ return FALSE /decl/stack_recipe/opacity/borderwindow/spawn_result(mob/user, location, amount, decl/material/mat, decl/material/reinf_mat, paint_color, spent_type, spent_amount = 1) - . = list(new result_type(user?.loc, MATERIAL_RECIPE_PARAMS, user?.dir, TRUE)) - if(paint_color) - for(var/obj/structure/window/window in .) + . = list(new result_type(user?.loc, MATERIAL_RECIPE_PARAMS, user?.dir, FALSE)) + for(var/obj/structure/window/window in .) + if(paint_color) window.set_color(paint_color) /decl/stack_recipe/opacity/windoor From 0006367f8da93024ae8649fefe938ef29a66265c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 20:10:06 -0400 Subject: [PATCH 301/512] Fix potential href exploit in stack crafting --- code/game/objects/items/stacks/stack.dm | 26 ++++++++++++------- .../modules/crafting/stack_recipes/_recipe.dm | 9 +++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm index 1ac89b8d2566..be4dc072f8fb 100644 --- a/code/game/objects/items/stacks/stack.dm +++ b/code/game/objects/items/stacks/stack.dm @@ -166,11 +166,15 @@ popup.open() -/obj/item/stack/proc/produce_recipe(decl/stack_recipe/recipe, var/producing, var/expending, mob/user, paint_color, sublist = null) +/obj/item/stack/proc/produce_recipe(decl/stack_recipe/recipe, var/producing, var/expending, mob/user, paint_color) if(producing <= 0 || expending <= 0 || expending > get_amount()) return + if(expending > recipe.get_required_stack_amount(src, product_amount = producing)) + PRINT_STACK_TRACE("Possible HREF hacking attempt, recipe amount consumed and produced doesn't match!") + return + var/decl/material/mat = get_material() var/decl/material/reinf_mat = get_reinforced_material() if (!can_use(expending)) @@ -195,11 +199,14 @@ to_chat(user, SPAN_NOTICE("You [recipe.get_craft_verb(src)] [recipe.get_display_name(producing, mat, reinf_mat)]!")) var/list/atom/results = recipe.spawn_result(user, user.loc, producing, mat, reinf_mat, paint_color, crafting_stack_type, expending) - var/atom/movable/O = LAZYACCESS(results, 1) - if(istype(O) && !QDELETED(O)) // In case of stack merger. - O.add_fingerprint(user) - user.put_in_hands(O) - list_recipes(user, sublist) + var/was_put_in_hand = FALSE + for(var/atom/result in results) + if(QDELETED(result)) + continue + result.add_fingerprint(user) + if(isitem(result) && !was_put_in_hand) + if(user.put_in_hands(result)) + was_put_in_hand = TRUE /obj/item/stack/OnTopic(mob/user, list/href_list) . = ..() @@ -247,9 +254,10 @@ var/producing = text2num(href_list["producing"]) var/expending = text2num(href_list["expending"]) var/datum/stack_recipe_list/returning = locate(href_list["returning"]) - if(producing > 0 && expending > 0) - produce_recipe(recipe, producing, expending, user, paint_color, sublist = returning) - return TOPIC_REFRESH + if(producing > 0 && expending > 0 && expending <= recipe.get_required_stack_amount(src, product_amount = producing)) + produce_recipe(recipe, producing, expending, user, paint_color) + list_recipes(user, returning) + return TOPIC_HANDLED // Don't attempt to refresh, list_recipes should handle that already... return TOPIC_NOACTION diff --git a/code/modules/crafting/stack_recipes/_recipe.dm b/code/modules/crafting/stack_recipes/_recipe.dm index 7c481de823a3..d87df7672487 100644 --- a/code/modules/crafting/stack_recipes/_recipe.dm +++ b/code/modules/crafting/stack_recipes/_recipe.dm @@ -162,8 +162,13 @@ if((stack_type in check_craft_stack_types) && (stack_type in check_forbidden_craft_stack_types)) . += "[stack_type] is in both forbidden and craftable stack types" -/decl/stack_recipe/proc/get_required_stack_amount(obj/item/stack/stack) - return max(1, ceil(req_amount / max(1, (SHEET_MATERIAL_AMOUNT * stack?.matter_multiplier)))) +/// Returns the required stack units to create product_amount products (default 1). +/decl/stack_recipe/proc/get_required_stack_amount(obj/item/stack/stack, product_amount = 1) + /// The number of sheets, unrounded, to produce a single unit of product. May be less than 1. + var/sheets_per_product = req_amount / ceil(SHEET_MATERIAL_AMOUNT * stack.matter_multiplier) + var/total_needed = sheets_per_product * product_amount + // We can't use less than 1 sheet, or only part of a sheet, so we have to round up. + return max(1, ceil(total_needed)) /decl/stack_recipe/proc/get_list_display(mob/user, obj/item/stack/stack, datum/stack_recipe_list/sublist) From 71f154326a27f4825b63fd4ec827a40e5eead695 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 20:22:16 -0400 Subject: [PATCH 302/512] Allow staging to compile on 516 --- code/controllers/hooks.dm | 4 ++-- code/datums/mind/mind.dm | 12 ++++++------ code/modules/admin/view_variables/topic.dm | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/code/controllers/hooks.dm b/code/controllers/hooks.dm index 2e05a0621b0f..c38cd77d135d 100644 --- a/code/controllers/hooks.dm +++ b/code/controllers/hooks.dm @@ -29,10 +29,10 @@ error("Invalid hook '/hook/[hook]' called.") return 0 - var/caller = new hook_path + var/hook_caller = new hook_path var/status = 1 for(var/P in typesof("[hook_path]/proc")) - if(!call(caller, P)(arglist(args))) + if(!call(hook_caller, P)(arglist(args))) error("Hook '[P]' failed or runtimed.") status = 0 diff --git a/code/datums/mind/mind.dm b/code/datums/mind/mind.dm index 355cd25efdc7..22abeced6dd3 100644 --- a/code/datums/mind/mind.dm +++ b/code/datums/mind/mind.dm @@ -152,8 +152,8 @@ if(href_list["add_goal"]) - var/mob/caller = locate(href_list["add_goal_caller"]) - if(caller && caller == current) can_modify = TRUE + var/mob/goal_caller = locate(href_list["add_goal_caller"]) + if(goal_caller && goal_caller == current) can_modify = TRUE if(can_modify) if(is_admin) @@ -171,8 +171,8 @@ if(href_list["abandon_goal"]) var/datum/goal/goal = get_goal_from_href(href_list["abandon_goal"]) - var/mob/caller = locate(href_list["abandon_goal_caller"]) - if(caller && caller == current) can_modify = TRUE + var/mob/goal_caller = locate(href_list["abandon_goal_caller"]) + if(goal_caller && goal_caller == current) can_modify = TRUE if(goal && can_modify) if(usr == current) @@ -186,8 +186,8 @@ if(href_list["reroll_goal"]) var/datum/goal/goal = get_goal_from_href(href_list["reroll_goal"]) - var/mob/caller = locate(href_list["reroll_goal_caller"]) - if(caller && caller == current) can_modify = TRUE + var/mob/goal_caller = locate(href_list["reroll_goal_caller"]) + if(goal_caller && goal_caller == current) can_modify = TRUE if(goal && (goal in goals) && can_modify) qdel(goal) diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 9cec7322e10b..181bdd9b2498 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -599,9 +599,9 @@ href_list["datumrefresh"] = href_list["mobToDamage"] else if(href_list["call_proc"]) - var/datum/callee = locate(href_list["call_proc"]) - if(istype(callee) || istype(callee, /client)) // can call on clients too, not just datums - callproc_targetpicked(1, callee) + var/datum/proc_callee = locate(href_list["call_proc"]) + if(istype(proc_callee) || istype(proc_callee, /client)) // can call on clients too, not just datums + callproc_targetpicked(1, proc_callee) else if(href_list["addaura"]) if(!check_rights(R_DEBUG|R_ADMIN|R_FUN)) return var/mob/living/victim = locate(href_list["addaura"]) From a0d425eb97a57f076fdd18a5624afb1d73d1c48f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 20:44:13 -0400 Subject: [PATCH 303/512] Fix window jittering from fullscreen pref being reapplied unnecessarily --- code/modules/client/preferences.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index a17968f5b783..7e000b130026 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -498,7 +498,7 @@ var/global/list/time_prefs_fixed = list() if(!client) return - if(client.get_preference_value(/datum/client_preference/fullscreen_mode) != PREF_OFF) + if(client.get_preference_value(/datum/client_preference/fullscreen_mode) != PREF_NO) client.toggle_fullscreen(client.get_preference_value(/datum/client_preference/fullscreen_mode)) /datum/preferences/proc/setup_preferences() From 90521410d8317272253812a48435eb4ebd6c4a22 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 10 May 2025 19:28:47 -0400 Subject: [PATCH 304/512] Add a user agent to the BYOND install script --- install-byond.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install-byond.sh b/install-byond.sh index 3b0170c16b0f..ae0a74438954 100755 --- a/install-byond.sh +++ b/install-byond.sh @@ -8,7 +8,7 @@ else mkdir -p "$HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}" cd "$HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}" echo "Installing DreamMaker to $PWD" - curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -o byond.zip + curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -H "User-Agent: NebulaSS13/1.0 Continuous Integration" -o byond.zip unzip -o byond.zip cd byond make here From 46926938b37deecd2c19f68991faa8ffa3c4d151 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 10 May 2025 20:43:53 -0400 Subject: [PATCH 305/512] Fix unit test BYOND installation cache --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7776bf210125..c15d7d641a0f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,7 +26,7 @@ jobs: - name: Setup Cache uses: actions/cache@v3 with: - path: $HOME/spaceman_dmm/$SPACEMAN_DMM_VERSION + path: ~/spaceman_dmm/${{ env.SPACEMAN_DMM_VERSION }} key: ${{ runner.os }}-spacemandmm-${{ env.SPACEMAN_DMM_VERSION }} - name: Install Dreamchecker run: scripts/install-spaceman-dmm.sh dreamchecker @@ -57,7 +57,7 @@ jobs: - name: Setup Cache uses: actions/cache@v3 with: - path: $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR} + path: ~/BYOND-${{ env.BYOND_MAJOR }}.${{ env.BYOND_MINOR }} key: ${{ runner.os }}-byond-${{ env.BYOND_MAJOR }}-${{ env.BYOND_MINOR }} - name: Install Dependencies run: sudo apt-get install -y uchardet @@ -86,7 +86,7 @@ jobs: - name: Setup Cache uses: actions/cache@v3 with: - path: $HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR} + path: ~/BYOND-${{ env.BYOND_MAJOR }}.${{ env.BYOND_MINOR }} key: ${{ runner.os }}-byond-${{ env.BYOND_MAJOR }}-${{ env.BYOND_MINOR }} - name: Run Tests env: From 8de372db306bbf59766fefaafd216f813ff32459 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 10 May 2025 20:50:49 -0400 Subject: [PATCH 306/512] Fix color hex checker regular experssion --- tools/ColorHexChecker/color-hex-checker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/ColorHexChecker/color-hex-checker.py b/tools/ColorHexChecker/color-hex-checker.py index 9c198be41ac7..1d8b4e9f7168 100644 --- a/tools/ColorHexChecker/color-hex-checker.py +++ b/tools/ColorHexChecker/color-hex-checker.py @@ -1,7 +1,7 @@ import argparse, re, sys from os import sep, path, walk -color_hex_matcher = re.compile('\"#[\dA-F]{6}\"', re.IGNORECASE) +color_hex_matcher = re.compile(r'\"#[\dA-F]{6}\"', re.IGNORECASE) def get_bad_hexes_in_line(line): bad_hexes = [] @@ -25,7 +25,7 @@ def print_bad_hexes(bad_hexes_by_path): print('\tLine: {0}'.format(line)) for bad_hex in bad_hexes: print('\t\t{0}'.format(bad_hex)) - + def main(): opt = argparse.ArgumentParser() opt.add_argument('dir', help='The directory to recursively scan for *.dm and *.dmm files with invalid color hexes') From 593bed0cc29cdb3b2a438faa36df6eb6dec9e107 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 11 May 2025 01:01:11 +0000 Subject: [PATCH 307/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 6aef7ebd7b31..8985c1af8281 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -102,12 +102,6 @@

    Cerebulon updated:

    • Changed modpack Tajara to use old-style humanoid sprites instead of a unique feline body shape which has since been used by Hnolls.
    - -

    09 March 2025

    -

    Cerebulon updated:

    -
      -
    • New icons for a variety of objects, mostly machines and grenades.
    • -
    From bb03b6bde419afb7946a610463c22e3cac4e12ff Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 9 May 2025 07:55:36 -0400 Subject: [PATCH 308/512] Fix airlock lights not working properly --- code/game/machinery/doors/_door.dm | 1 - code/game/machinery/doors/airlock.dm | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/code/game/machinery/doors/_door.dm b/code/game/machinery/doors/_door.dm index 78196fd231d7..4aa52f12e430 100644 --- a/code/game/machinery/doors/_door.dm +++ b/code/game/machinery/doors/_door.dm @@ -253,7 +253,6 @@ else if(density) do_animate("deny") - update_icon() return TRUE /obj/machinery/door/proc/handle_repair(obj/item/I, mob/user) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index bd2f3f4d8f92..38032f79418a 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -438,18 +438,18 @@ About the new airlock wires panel: if("opening") set_airlock_overlays(AIRLOCK_OPENING) flick("opening", src)//[stat ? "_stat":] - update_icon(AIRLOCK_OPEN) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), AIRLOCK_OPEN), 1 SECOND) // wait to update icon so the light doesn't go out too soon if("closing") set_airlock_overlays(AIRLOCK_CLOSING) flick("closing", src) - update_icon(AIRLOCK_CLOSED) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), AIRLOCK_CLOSED), 1 SECOND) // wait to update icon so the light doesn't go out too soon if("deny") set_airlock_overlays(AIRLOCK_DENY) if(density && arePowerSystemsOn()) flick("deny", src) if(speaker) playsound(loc, open_failure_access_denied, 50, 0) - update_icon(AIRLOCK_CLOSED) + addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, update_icon), AIRLOCK_CLOSED), 1 SECOND) // wait to update icon so the light doesn't go out too soon if("emag") set_airlock_overlays(AIRLOCK_EMAG) if(density && arePowerSystemsOn()) From ceb3f06438d6f297732c7ff684f9dfd02b974fa2 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 9 May 2025 07:58:24 -0400 Subject: [PATCH 309/512] Fix dev branch issues with matter --- code/game/atoms.dm | 2 +- code/game/objects/items/stacks/medical/medical_bandage.dm | 2 +- code/game/objects/items/weapons/soap.dm | 2 +- code/game/turfs/turf_fluids.dm | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4d964f5c4677..a121490e2aea 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -439,7 +439,7 @@ if(length(reagents?.reagent_volumes)) LAZYINITLIST(.) for(var/decl/material/reagent as anything in reagents.reagent_volumes) - .[reagent] += floor(REAGENT_VOLUME(reagents, reagent) / REAGENT_UNITS_PER_MATERIAL_UNIT) + .[reagent.type] += floor(REAGENT_VOLUME(reagents, reagent) / REAGENT_UNITS_PER_MATERIAL_UNIT) for(var/atom/contained_obj as anything in get_contained_external_atoms()) // machines handle component parts separately . = MERGE_ASSOCS_WITH_NUM_VALUES(., contained_obj.get_contained_matter()) diff --git a/code/game/objects/items/stacks/medical/medical_bandage.dm b/code/game/objects/items/stacks/medical/medical_bandage.dm index 5a5727b290bd..cd0ca1efdc10 100644 --- a/code/game/objects/items/stacks/medical/medical_bandage.dm +++ b/code/game/objects/items/stacks/medical/medical_bandage.dm @@ -75,7 +75,7 @@ /obj/item/stack/medical/bandage/proc/bandage_wound(mob/user, mob/target, obj/item/organ/external/affecting, datum/wound/wound) user.visible_message( SPAN_NOTICE("\The [user] bandages \a [wound.desc] on \the [target]'s [affecting.name]."), - SPAN_NOTICE("You bandage \a [wound.desc] on \the [target]'s [affecting.name].") + SPAN_NOTICE("You bandage \a [wound.desc] on \the [target]'s [affecting.name].") ) wound.bandage() diff --git a/code/game/objects/items/weapons/soap.dm b/code/game/objects/items/weapons/soap.dm index bd0956bad5b2..ebb10a60b96d 100644 --- a/code/game/objects/items/weapons/soap.dm +++ b/code/game/objects/items/weapons/soap.dm @@ -54,7 +54,7 @@ update_icon() /obj/item/soap/proc/wet() - add_to_reagents(/decl/material/liquid/cleaner/soap, SOAP_CLEANER_ON_WET) + add_to_reagents(/decl/material/liquid/cleaner/soap, SOAP_CLEANER_ON_WET, phase = MAT_PHASE_LIQUID) /obj/item/soap/Crossed(atom/movable/AM) var/mob/living/victim = AM diff --git a/code/game/turfs/turf_fluids.dm b/code/game/turfs/turf_fluids.dm index b7b1f4fe95e7..48c6e74fc863 100644 --- a/code/game/turfs/turf_fluids.dm +++ b/code/game/turfs/turf_fluids.dm @@ -218,7 +218,7 @@ var/list/matter_list = list() for(var/decl/material/reagent as anything in solids.solid_volumes) var/reagent_amount = solids.solid_volumes[reagent] - matter_list[reagent] = round(reagent_amount/REAGENT_UNITS_PER_MATERIAL_UNIT) + matter_list[reagent.type] = round(reagent_amount/REAGENT_UNITS_PER_MATERIAL_UNIT) solids.remove_reagent(reagent, reagent_amount, defer_update = TRUE, removed_phases = MAT_PHASE_SOLID) var/obj/item/debris/scraps/chemical/scraps = locate() in contents From d3449d74364adf97448559b230e7abc29616c83d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 9 May 2025 08:37:24 -0400 Subject: [PATCH 310/512] Fix NanoUI map runtime --- code/modules/nano/nanoui.dm | 7 ++++--- nano/templates/crew_monitor_map_header.tmpl | 2 +- nano/templates/layout_default.tmpl | 2 +- nano/templates/sec_camera_map_header.tmpl | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/modules/nano/nanoui.dm b/code/modules/nano/nanoui.dm index 9fc00cd5a649..e5310e15826d 100644 --- a/code/modules/nano/nanoui.dm +++ b/code/modules/nano/nanoui.dm @@ -514,13 +514,14 @@ nanoui is used to open and update nano browser uis set_show_map(text2num(href_list["showMap"])) map_update = 1 - if(href_list["mapZLevel"]) - var/map_z = text2num(href_list["mapZLevel"]) + if(href_list["switchMapZLevel"]) + var/map_z = text2num(href_list["switchMapZLevel"]) if(isMapLevel(map_z)) set_map_z_level(map_z) map_update = 1 - if (src_object && (src_object.Topic(href, href_list, state) || map_update)) + // src_object.Topic() might null out src_object by deleting us. + if (src_object && (src_object.Topic(href, href_list, state) || (!QDELETED(src) && src_object && map_update))) SSnano.update_uis(src_object) // update all UIs attached to src_object /** diff --git a/nano/templates/crew_monitor_map_header.tmpl b/nano/templates/crew_monitor_map_header.tmpl index 24398dec5b01..a86abc85d837 100644 --- a/nano/templates/crew_monitor_map_header.tmpl +++ b/nano/templates/crew_monitor_map_header.tmpl @@ -7,7 +7,7 @@ Used In File(s): code\modules\modular_computers\file_system\programs\medical\sui
    Z Level:  {{for config.mapZLevels :zValue:zIndex}} - {{:helper.link(zValue, 'close', {'mapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}} + {{:helper.link(zValue, 'close', {'switchMapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}} {{/for}}
    diff --git a/nano/templates/layout_default.tmpl b/nano/templates/layout_default.tmpl index 8dae1468bfb1..a80f025bce3e 100644 --- a/nano/templates/layout_default.tmpl +++ b/nano/templates/layout_default.tmpl @@ -8,7 +8,7 @@
    Z Level:  {{for config.mapZLevels :zValue:zIndex}} - {{:helper.link(zValue, 'close', {'mapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}} + {{:helper.link(zValue, 'close', {'switchMapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}} {{/for}}
    diff --git a/nano/templates/sec_camera_map_header.tmpl b/nano/templates/sec_camera_map_header.tmpl index 7871b1ec11a4..0ed4cbdccc55 100644 --- a/nano/templates/sec_camera_map_header.tmpl +++ b/nano/templates/sec_camera_map_header.tmpl @@ -18,7 +18,7 @@
    {{for config.mapZLevels :zValue:zIndex}} - {{:helper.link(zValue, 'close', {'mapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}} + {{:helper.link(zValue, 'close', {'switchMapZLevel' : zValue}, null, config.mapZLevel == zValue ? 'selected' : null)}} {{/for}}
    From 0d307d15fcd86a90d0e7d3aa7af8f1658805f1e8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 9 May 2025 08:52:39 -0400 Subject: [PATCH 311/512] Fix bug with walnut laminate material --- code/game/turfs/flooring/flooring_wood.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/turfs/flooring/flooring_wood.dm b/code/game/turfs/flooring/flooring_wood.dm index c68b599d5554..d7352fb03ae2 100644 --- a/code/game/turfs/flooring/flooring_wood.dm +++ b/code/game/turfs/flooring/flooring_wood.dm @@ -121,7 +121,7 @@ /decl/flooring/laminate/walnut build_type = /obj/item/stack/tile/wood/laminate/walnut - force_material = /decl/material/solid/organic/wood/chipboard/yew + force_material = /decl/material/solid/organic/wood/chipboard/walnut /decl/flooring/laminate/yew build_type = /obj/item/stack/tile/wood/laminate/yew From bd511cfa124ab40c8d5059fbbf6971c828953151 Mon Sep 17 00:00:00 2001 From: markoatonc <45716141+markoatonc@users.noreply.github.com> Date: Sun, 11 May 2025 06:04:55 +0200 Subject: [PATCH 312/512] Diona collision bug workaround (#4990) * Diona collision fix * shotholder fix * fixed material flags on glass and windows * window construction state * revert of unnecesary changes * Update window.dm * Update boxes.dm --- mods/mobs/dionaea/mob/gestalt/gestalt_movement.dm | 3 +-- mods/mobs/dionaea/mob/gestalt/gestalt_nymph.dm | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/mobs/dionaea/mob/gestalt/gestalt_movement.dm b/mods/mobs/dionaea/mob/gestalt/gestalt_movement.dm index 4fc33e40e613..a3090a11c321 100644 --- a/mods/mobs/dionaea/mob/gestalt/gestalt_movement.dm +++ b/mods/mobs/dionaea/mob/gestalt/gestalt_movement.dm @@ -6,8 +6,7 @@ . = ..() if(AM && can_roll_up_atom(AM) && AM.Adjacent(src)) var/turf/stepping = AM.loc - roll_up_atom(AM) - if(stepping) + if(roll_up_atom(AM) && stepping) step_towards(src, stepping) diff --git a/mods/mobs/dionaea/mob/gestalt/gestalt_nymph.dm b/mods/mobs/dionaea/mob/gestalt/gestalt_nymph.dm index ad6147a62c13..7b4f4d686ca8 100644 --- a/mods/mobs/dionaea/mob/gestalt/gestalt_nymph.dm +++ b/mods/mobs/dionaea/mob/gestalt/gestalt_nymph.dm @@ -11,13 +11,14 @@ /obj/structure/diona_gestalt/proc/roll_up_atom(var/mob/living/simple_animal/alien/diona/chirp, var/silent) if(!istype(chirp)) - return + return FALSE if(!silent) visible_message("\The [chirp] is engulfed by \the [src].") if(isdiona(chirp)) nymphs[chirp] = TRUE queue_icon_update() chirp.forceMove(src) + return TRUE /obj/structure/diona_gestalt/proc/shed_atom(var/atom/movable/shedding, var/silent, var/forcefully) From ed467561073eb9c8bedfeda547355da8adf16159 Mon Sep 17 00:00:00 2001 From: Neerti Date: Thu, 8 May 2025 22:20:10 -0400 Subject: [PATCH 313/512] Minor camera fixes and tweaks, for stable --- code/game/machinery/camera/camera.dm | 70 ++++++++++++++++----------- code/game/machinery/camera/presets.dm | 31 +++++------- 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index c328ff3fb5e7..a3027939295f 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -45,7 +45,13 @@ var/light_disabled = 0 var/alarm_on = 0 - var/affected_by_emp_until = 0 + var/emp_timer_id = null + + /// The threshold that installed scanning modules need to met or exceed in order for the camera to see through walls. + var/const/XRAY_THRESHOLD = 2 + + /// The threshold that installed capacitors need to met or exceed in order for the camera to be immunie to EMP. + var/const/EMP_PROOF_THRESHOLD = 2 /obj/machinery/camera/examine(mob/user) . = ..() @@ -95,23 +101,14 @@ invalidateCameraCache() set_extension(src, /datum/extension/network_device/camera, null, null, null, TRUE, preset_channels, c_tag, cameranet_enabled, requires_connection) + RefreshParts() /obj/machinery/camera/Destroy() set_status(0) //kick anyone viewing out + deltimer(emp_timer_id) return ..() /obj/machinery/camera/Process() - if((stat & EMPED) && world.time >= affected_by_emp_until) - stat &= ~EMPED - cancelCameraAlarm() - update_icon() - update_coverage() - - if (detectTime > 0) - var/elapsed = world.time - detectTime - if (elapsed > alarm_delay) - triggerAlarm() - if (stat & (EMPED)) return if(!motion_sensor) @@ -167,16 +164,30 @@ newTarget(AM) /obj/machinery/camera/emp_act(severity) - if(!(stat_immune & EMPED) && prob(100/severity)) - if(!affected_by_emp_until || (world.time < affected_by_emp_until)) - affected_by_emp_until = max(affected_by_emp_until, world.time + (90 SECONDS / severity)) - else - stat |= EMPED - set_light(0) - triggerCameraAlarm() - update_icon() - update_coverage() - START_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF) + if(stat_immune & EMPED) + return + if(prob(100 / severity)) + stat |= EMPED + set_light(0) + triggerCameraAlarm() + update_icon() + update_coverage() + + var/emp_length = 90 SECONDS / severity + emp_timer_id = addtimer(CALLBACK(src, PROC_REF(emp_expired)), emp_length, TIMER_UNIQUE | TIMER_OVERRIDE | TIMER_STOPPABLE) + ..() + +/obj/machinery/camera/proc/emp_expired() + stat &= ~EMPED + cancelCameraAlarm() + update_icon() + update_coverage() + + if (detectTime > 0) + var/elapsed = world.time - detectTime + if (elapsed > alarm_delay) + triggerAlarm() + /obj/machinery/camera/bullet_act(var/obj/item/projectile/P) take_damage(P.get_structure_damage()) @@ -263,25 +274,28 @@ update_coverage() /obj/machinery/camera/on_update_icon() + var/base_state = initial(icon_state) + if(total_component_rating_of_type(/obj/item/stock_parts/scanning_module) >= XRAY_THRESHOLD) + base_state = "xraycam" if (!status || (stat & BROKEN)) - icon_state = "[initial(icon_state)]1" + icon_state = "[base_state]1" else if (stat & EMPED) - icon_state = "[initial(icon_state)]emp" + icon_state = "[base_state]emp" else - icon_state = initial(icon_state) + icon_state = base_state /obj/machinery/camera/RefreshParts() . = ..() var/power_mult = 1 var/emp_protection = total_component_rating_of_type(/obj/item/stock_parts/capacitor) - if(emp_protection > 2) - stat_immune &= EMPED + if(emp_protection >= EMP_PROOF_THRESHOLD) + stat_immune |= EMPED else stat_immune &= ~EMPED var/xray_rating = total_component_rating_of_type(/obj/item/stock_parts/scanning_module) var/datum/extension/network_device/camera/camera_device = get_extension(src, /datum/extension/network_device/) if(camera_device) - if(xray_rating > 2) + if(xray_rating >= XRAY_THRESHOLD) camera_device.xray_enabled = TRUE power_mult++ else diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 30ee583beec2..12d24b214fad 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -33,33 +33,24 @@ requires_connection = FALSE // EMP - -/obj/machinery/camera/emp_proof/populate_parts(full_populate) - . = ..() - install_component(/obj/item/stock_parts/capacitor/adv, TRUE) +/obj/machinery/camera/emp_proof + uncreated_component_parts = list(/obj/item/stock_parts/capacitor/adv = 1) // X-RAY - /obj/machinery/camera/xray - icon_state = "xraycam" // Thanks to Krutchen for the icons. - -/obj/machinery/camera/xray/populate_parts(full_populate) - . = ..() - install_component(/obj/item/stock_parts/scanning_module/adv, TRUE) + uncreated_component_parts = list(/obj/item/stock_parts/scanning_module/adv = 1) // MOTION - -/obj/machinery/camera/motion/populate_parts(full_populate) - . = ..() - install_component(/obj/item/stock_parts/micro_laser, TRUE) +/obj/machinery/camera/motion + uncreated_component_parts = list(/obj/item/stock_parts/micro_laser = 1) // ALL UPGRADES - -/obj/machinery/camera/all/populate_parts(full_populate) - . = ..() - install_component(/obj/item/stock_parts/capacitor/adv, TRUE) - install_component(/obj/item/stock_parts/scanning_module/adv, TRUE) - install_component(/obj/item/stock_parts/micro_laser, TRUE) +/obj/machinery/camera/all + uncreated_component_parts = list( + /obj/item/stock_parts/capacitor/adv = 1, + /obj/item/stock_parts/scanning_module/adv = 1, + /obj/item/stock_parts/micro_laser = 1 + ) // AUTONAME left as a map stub /obj/machinery/camera/autoname \ No newline at end of file From 133e527085907815a86525544ccb346315c5f4ea Mon Sep 17 00:00:00 2001 From: Neerti Date: Mon, 12 May 2025 06:45:15 -0400 Subject: [PATCH 314/512] Fixes inability to sell to merchants due to overly eager telepads --- code/modules/merchant/merchant_machinery.dm | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/code/modules/merchant/merchant_machinery.dm b/code/modules/merchant/merchant_machinery.dm index 7cb3b15a7354..e0947ee6efd0 100644 --- a/code/modules/merchant/merchant_machinery.dm +++ b/code/modules/merchant/merchant_machinery.dm @@ -12,7 +12,7 @@ /obj/machinery/merchant_pad/proc/get_target() var/turf/T = get_turf(src) for(var/a in T) - if(a == src || (!istype(a,/obj) && !isliving(a)) || istype(a,/obj/effect)) + if(!is_valid_target(a)) continue return a @@ -20,6 +20,15 @@ . = list() var/turf/T = get_turf(src) for(var/a in T) - if(a == src || (!istype(a,/obj) && !isliving(a)) || istype(a,/obj/effect)) + if(!is_valid_target(a)) continue - . += a \ No newline at end of file + . += a + +/obj/machinery/merchant_pad/proc/is_valid_target(atom/movable/thing) + if(thing == src) + return FALSE + if(!isobj(thing) && !isliving(thing)) + return FALSE + if(thing.anchored || !thing.simulated) + return FALSE + return TRUE \ No newline at end of file From 3c37a7c35242f2422fb5a99a65a30ed036a5af66 Mon Sep 17 00:00:00 2001 From: Neerti Date: Mon, 12 May 2025 20:20:09 -0400 Subject: [PATCH 315/512] Merchant pad validity checks are now on the objects themselves --- code/game/atoms_movable.dm | 2 ++ code/game/objects/objs.dm | 5 +++++ code/modules/mechs/mech.dm | 5 +++++ code/modules/merchant/merchant_machinery.dm | 8 +++----- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 92a631e86a66..5685a17731ca 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -532,3 +532,5 @@ appearance_flags &= ~remove_flags return old_appearance != appearance_flags +/atom/movable/proc/is_valid_merchant_pad_target() + return simulated \ No newline at end of file diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index de8fe873b398..067c4fc86398 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -364,3 +364,8 @@ /obj/proc/get_blend_objects() return + +/obj/is_valid_merchant_pad_target() + if(anchored) + return FALSE + return ..() diff --git a/code/modules/mechs/mech.dm b/code/modules/mechs/mech.dm index 66592c448fb9..89b386c7eae5 100644 --- a/code/modules/mechs/mech.dm +++ b/code/modules/mechs/mech.dm @@ -249,3 +249,8 @@ // Override this to avoid triggering the ancient vore code. /mob/living/exosuit/relaymove(mob/living/user, direction) return + +/mob/living/exosuit/is_valid_merchant_pad_target() + if(current_user) + return FALSE + return ..() diff --git a/code/modules/merchant/merchant_machinery.dm b/code/modules/merchant/merchant_machinery.dm index e0947ee6efd0..5a61211ae088 100644 --- a/code/modules/merchant/merchant_machinery.dm +++ b/code/modules/merchant/merchant_machinery.dm @@ -25,10 +25,8 @@ . += a /obj/machinery/merchant_pad/proc/is_valid_target(atom/movable/thing) - if(thing == src) - return FALSE - if(!isobj(thing) && !isliving(thing)) + if(!istype(thing)) return FALSE - if(thing.anchored || !thing.simulated) + if(thing == src) return FALSE - return TRUE \ No newline at end of file + return thing.is_valid_merchant_pad_target() \ No newline at end of file From 33c49f44d2a946baf41ffddc7032926232c2d4d5 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Wed, 14 May 2025 00:57:37 +0000 Subject: [PATCH 316/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 8985c1af8281..b65f492394dc 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -96,12 +96,6 @@

    Typhin updated:

    • Allows parts/screwdrivers to be used on biogenerators
    - -

    12 March 2025

    -

    Cerebulon updated:

    -
      -
    • Changed modpack Tajara to use old-style humanoid sprites instead of a unique feline body shape which has since been used by Hnolls.
    • -
    From c1a55976b2ab177167638fac1e981209f17a6039 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 15 May 2025 01:37:34 -0400 Subject: [PATCH 317/512] Fix temporary genetic conditions not being removed --- code/modules/mob/living/living_genetics.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/living_genetics.dm b/code/modules/mob/living/living_genetics.dm index c33da0160f90..1595be199f1f 100644 --- a/code/modules/mob/living/living_genetics.dm +++ b/code/modules/mob/living/living_genetics.dm @@ -30,7 +30,7 @@ LAZYDISTINCTADD(_genetic_conditions, condition) if(temporary_time) // TODO: some kind of world.time key or parameter so overlapping calls don't remove each other. - addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living, remove_genetic_condition)), temporary_time) + addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living, remove_genetic_condition), condition_type), temporary_time) queue_genetic_condition_update() return TRUE return FALSE From 7d78dfb6e3a7e7c647c8f434ea0c2add56b5806e Mon Sep 17 00:00:00 2001 From: Lohikar Date: Sat, 4 Jan 2025 22:15:37 -0600 Subject: [PATCH 318/512] lighting: Update ambience impl, general updates --- code/__defines/lighting.dm | 7 +- code/controllers/subsystems/lighting.dm | 51 +++++++-- code/modules/lighting/lighting_corner.dm | 41 ++++---- code/modules/lighting/lighting_overlay.dm | 2 +- code/modules/lighting/lighting_turf.dm | 121 +++++++++++++++------- 5 files changed, 153 insertions(+), 69 deletions(-) diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index c02fc243ba77..d9c934a0fb5f 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -10,7 +10,8 @@ #define LIGHTING_DARKNESS_ICON_STATE "black" // icon_state used for lighting overlays with no luminosity. #define LIGHTING_TRANSPARENT_ICON_STATE "blank" -#define LIGHTING_SOFT_THRESHOLD 0.001 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays. +// This is purely used as a threshold for 'is this turf probably dark' to avoid floating point nonsense. +#define LIGHTING_SOFT_THRESHOLD 0.001 #define LIGHTING_BLOCKED_FACTOR 0.5 // How much the range of a directional light will be reduced while facing a wall. // If defined, instant updates will be used whenever server load permits. Otherwise queued updates are always used. @@ -20,6 +21,10 @@ #define TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) ((T:dynamic_lighting && T:loc:dynamic_lighting)) #define TURF_IS_DYNAMICALLY_LIT(T) (isturf(T) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) +// Note: this does not imply the above, a turf can have ambient light without being dynamically lit. +#define TURF_IS_AMBIENT_LIT_UNSAFE(T) (T:ambient_active) +#define TURF_IS_AMBIENT_LIT(T) (isturf(T) && TURF_IS_AMBIENT_LIT_UNSAFE(T)) + // If I were you I'd leave this alone. #define LIGHTING_BASE_MATRIX \ list \ diff --git a/code/controllers/subsystems/lighting.dm b/code/controllers/subsystems/lighting.dm index 068353abbe0c..43e79dea97ef 100644 --- a/code/controllers/subsystems/lighting.dm +++ b/code/controllers/subsystems/lighting.dm @@ -8,13 +8,16 @@ SUBSYSTEM_DEF(lighting) var/total_lighting_overlays = 0 var/total_lighting_sources = 0 var/total_ambient_turfs = 0 - var/list/lighting_corners = list() // List of all lighting corners in the world. + var/total_lighting_corners = 0 - var/list/light_queue = list() // lighting sources queued for update. + /// lighting sources queued for update. + var/list/light_queue = list() var/lq_idex = 1 - var/list/corner_queue = list() // lighting corners queued for update. + /// lighting corners queued for update. + var/list/corner_queue = list() var/cq_idex = 1 - var/list/overlay_queue = list() // lighting overlays queued for update. + /// lighting overlays queued for update. + var/list/overlay_queue = list() var/oq_idex = 1 var/tmp/processed_lights = 0 @@ -25,18 +28,20 @@ SUBSYSTEM_DEF(lighting) var/total_instant_updates = 0 #ifdef USE_INTELLIGENT_LIGHTING_UPDATES + var/instant_ctr = 0 var/force_queued = TRUE - var/force_override = FALSE // For admins. + /// For admins. + var/force_override = FALSE #endif /datum/controller/subsystem/lighting/stat_entry() var/list/out = list( #ifdef USE_INTELLIGENT_LIGHTING_UPDATES - "IUR: [total_ss_updates ? round(total_instant_updates/(total_instant_updates+total_ss_updates)*100, 0.1) : "NaN"]%\n", + "IUR: [total_ss_updates ? round(total_instant_updates/(total_instant_updates+total_ss_updates)*100, 0.1) : "NaN"]% Instant: [force_queued ? "Disabled" : "Allowed"]\n", #endif - "\tT:{L:[total_lighting_sources] C:[lighting_corners.len] O:[total_lighting_overlays] A:[total_ambient_turfs]}\n", - "\tP:{L:[light_queue.len - (lq_idex - 1)]|C:[corner_queue.len - (cq_idex - 1)]|O:[overlay_queue.len - (oq_idex - 1)]}\n", - "\tL:{L:[processed_lights]|C:[processed_corners]|O:[processed_overlays]}\n" + "\tT: { L: [total_lighting_sources] C: [total_lighting_corners] O:[total_lighting_overlays] A: [total_ambient_turfs] }\n", + "\tP: { L: [light_queue.len - (lq_idex - 1)] C: [corner_queue.len - (cq_idex - 1)] O: [overlay_queue.len - (oq_idex - 1)] }\n", + "\tL: { L: [processed_lights] C: [processed_corners] O: [processed_overlays]}\n" ) ..(out.Join()) @@ -46,6 +51,32 @@ SUBSYSTEM_DEF(lighting) force_queued = FALSE total_ss_updates = 0 total_instant_updates = 0 + +/// Disable instant updates, relying entirely on the (slower, but less laggy) queued pathway. Use if changing a *lot* of lights. +/datum/controller/subsystem/lighting/proc/pause_instant() + if (force_override) + return + + instant_ctr += 1 + if (instant_ctr == 1) + force_queued = TRUE + +/// Resume instant updates. +/datum/controller/subsystem/lighting/proc/resume_instant() + if (force_override) + return + + instant_ctr = max(instant_ctr - 1, 0) + + if (!instant_ctr) + force_queued = FALSE + +#else + +/datum/controller/subsystem/lighting/proc/pause_instant() + +/datum/controller/subsystem/lighting/proc/resume_instant() + #endif /datum/controller/subsystem/lighting/Initialize(timeofday) @@ -157,7 +188,7 @@ SUBSYSTEM_DEF(lighting) oq_idex = 1 /datum/controller/subsystem/lighting/Recover() - lighting_corners = SSlighting.lighting_corners + total_lighting_corners = SSlighting.total_lighting_corners total_lighting_overlays = SSlighting.total_lighting_overlays total_lighting_sources = SSlighting.total_lighting_sources diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm index b1e8d111ed79..3170ed85d090 100644 --- a/code/modules/lighting/lighting_corner.dm +++ b/code/modules/lighting/lighting_corner.dm @@ -56,13 +56,16 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, var/needs_update = FALSE - var/cache_r = LIGHTING_SOFT_THRESHOLD - var/cache_g = LIGHTING_SOFT_THRESHOLD - var/cache_b = LIGHTING_SOFT_THRESHOLD + var/cache_r = 0 + var/cache_g = 0 + var/cache_b = 0 var/cache_mx = 0 + /// Used for planet lighting. Probably needs a better system to prevent over-updating when not needed at some point. + var/update_gen = 0 + /datum/lighting_corner/New(turf/new_turf, diagonal, oi) - SSlighting.lighting_corners += src + SSlighting.total_lighting_corners += 1 var/has_ambience = FALSE @@ -70,7 +73,7 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, z = t1.z t1i = oi - if (t1.ambient_light) + if (TURF_IS_AMBIENT_LIT_UNSAFE(new_turf)) has_ambience = TRUE var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction. @@ -96,7 +99,7 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, t2 = T t2i = REVERSE_LIGHTING_CORNER_DIAGONAL[diagonal] T.corners[t2i] = src - if (T.ambient_light) + if (TURF_IS_AMBIENT_LIT_UNSAFE(T)) has_ambience = TRUE // Now the horizontal one. @@ -109,7 +112,7 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, t3 = T t3i = REVERSE_LIGHTING_CORNER_DIAGONAL[((Tc > x) ? EAST : WEST) | ((t1.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates. T.corners[t3i] = src - if (T.ambient_light) + if (TURF_IS_AMBIENT_LIT_UNSAFE(T)) has_ambience = TRUE // And finally the vertical one. @@ -122,7 +125,7 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, t4 = T t4i = REVERSE_LIGHTING_CORNER_DIAGONAL[((t1.x > x) ? EAST : WEST) | ((Tc > y) ? NORTH : SOUTH)] // Get the dir based on coordinates. T.corners[t4i] = src - if (T.ambient_light) + if (TURF_IS_AMBIENT_LIT_UNSAFE(T)) has_ambience = TRUE update_active() @@ -161,9 +164,11 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, if (!T || !T.ambient_light) continue - sum_r += (HEX_RED(T.ambient_light) / 255) * T.ambient_light_multiplier - sum_g += (HEX_GREEN(T.ambient_light) / 255) * T.ambient_light_multiplier - sum_b += (HEX_BLUE(T.ambient_light) / 255) * T.ambient_light_multiplier + var/list/parts = rgb2num(T.ambient_light) + + sum_r += (parts[1] / 255) * T.ambient_light_multiplier + sum_g += (parts[2] / 255) * T.ambient_light_multiplier + sum_b += (parts[3] / 255) * T.ambient_light_multiplier sum_r /= 4 sum_g /= 4 @@ -314,15 +319,9 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, if (mx > 1) . = 1 / mx - else if (mx < LIGHTING_SOFT_THRESHOLD) - . = 0 // 0 means soft lighting. - - if (.) - cache_r = round(lr * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - cache_g = round(lg * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - cache_b = round(lb * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - else - cache_r = cache_g = cache_b = LIGHTING_SOFT_THRESHOLD + cache_r = round(lr * ., LIGHTING_ROUND_VALUE) + cache_g = round(lg * ., LIGHTING_ROUND_VALUE) + cache_b = round(lb * ., LIGHTING_ROUND_VALUE) cache_mx = round(mx, LIGHTING_ROUND_VALUE) @@ -348,7 +347,7 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, if (!force) return QDEL_HINT_LETMELIVE - SSlighting.lighting_corners -= src + SSlighting.total_lighting_corners -= 1 return ..() /datum/lighting_corner/dummy/New() diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm index c7fae9674340..c4900999b891 100644 --- a/code/modules/lighting/lighting_overlay.dm +++ b/code/modules/lighting/lighting_overlay.dm @@ -77,7 +77,7 @@ ca = corners[1] || dummy_lighting_corner var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx) - luminosity = max > LIGHTING_SOFT_THRESHOLD + luminosity = max > 0 var/rr = cr.cache_r var/rg = cr.cache_g diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 10f19c3ae5eb..9af3682e4e85 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -4,7 +4,7 @@ var/ambient_light /// The power of the above is multiplied by this. Setting too high may drown out normal lights on the same turf. var/ambient_light_multiplier = 0.3 - luminosity = 1 + luminosity = 1 var/tmp/lighting_corners_initialised = FALSE @@ -19,7 +19,7 @@ var/tmp/ambient_has_indirect = FALSE // Record-keeping, do not touch -- that means you, admins. - var/tmp/ambient_light_old + var/tmp/ambient_active = FALSE //! Do we have non-zero ambient light? Use [TURF_IS_AMBIENT_LIT] instead of reading this directly. var/tmp/ambient_light_old_r = 0 var/tmp/ambient_light_old_g = 0 var/tmp/ambient_light_old_b = 0 @@ -33,35 +33,66 @@ update_ambient_light() -/turf/proc/clear_ambient_light() - if (ambient_light == null) +/turf/proc/replace_ambient_light(old_color, new_color, old_multiplier, new_multiplier = 0) + if (!TURF_IS_AMBIENT_LIT_UNSAFE(src)) + add_ambient_light(new_color, new_multiplier) return - ambient_light = null - update_ambient_light() + ASSERT(!isnull(old_multiplier)) // omitting new_multiplier is allowed for removing light nondestructively -/turf/proc/update_ambient_light(no_corner_update = FALSE) - // These are deltas. - var/ambient_r = 0 - var/ambient_g = 0 - var/ambient_b = 0 + old_color ||= COLOR_WHITE + new_color ||= COLOR_WHITE - if (ambient_light && ambient_light_multiplier) // If either of these are false-y we can use the simplier path and avoid calculations - ambient_r = round(((HEX_RED(ambient_light) / 255) * ambient_light_multiplier)/4 - ambient_light_old_r, LIGHTING_ROUND_VALUE) - ambient_g = round(((HEX_GREEN(ambient_light) / 255) * ambient_light_multiplier)/4 - ambient_light_old_g, LIGHTING_ROUND_VALUE) - ambient_b = round(((HEX_BLUE(ambient_light) / 255) * ambient_light_multiplier)/4 - ambient_light_old_b, LIGHTING_ROUND_VALUE) - else - ambient_r = -ambient_light_old_r - ambient_g = -ambient_light_old_g - ambient_b = -ambient_light_old_b + var/list/old_parts = rgb2num(old_color) + var/list/new_parts = rgb2num(new_color) + + var/dr = (new_parts[1] / 255) * new_multiplier - (old_parts[1] / 255) * old_multiplier + var/dg = (new_parts[2] / 255) * new_multiplier - (old_parts[2] / 255) * old_multiplier + var/db = (new_parts[3] / 255) * new_multiplier - (old_parts[3] / 255) * old_multiplier + + if (!dr && !dg && !db) + return - ambient_light_old_r += ambient_r - ambient_light_old_g += ambient_g - ambient_light_old_b += ambient_b + add_ambient_light_raw(dr, dg, db) - if (abs(ambient_r + ambient_g + ambient_b) == 0) +/turf/proc/add_ambient_light(color, multiplier, update = TRUE) + if (!color) return + multiplier ||= ambient_light_multiplier + + var/list/ambient_parts = rgb2num(color) + + var/ambient_r = (ambient_parts[1] / 255) * multiplier + var/ambient_g = (ambient_parts[2] / 255) * multiplier + var/ambient_b = (ambient_parts[3] / 255) * multiplier + + add_ambient_light_raw(ambient_r, ambient_g, ambient_b, update) + +/turf/proc/add_ambient_light_raw(lr, lg, lb, update = TRUE) + if (!lr && !lg && !lb) + if (!ambient_light_old_r || !ambient_light_old_g || !ambient_light_old_b) + ambient_active = FALSE + SSlighting.total_ambient_turfs -= 1 + return + + if (!ambient_active) + SSlighting.total_ambient_turfs += 1 + ambient_active = TRUE + + // There are four corners per (lit) turf, we don't want to apply our light 4 times -- compensate by dividing by 4. + lr /= 4 + lg /= 4 + lb /= 4 + + lr = round(lr, LIGHTING_ROUND_VALUE) + lg = round(lg, LIGHTING_ROUND_VALUE) + lb = round(lb, LIGHTING_ROUND_VALUE) + + ambient_light_old_r += lr + ambient_light_old_g += lg + ambient_light_old_b += lb + if (!corners || !lighting_corners_initialised) if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) generate_missing_corners() @@ -70,23 +101,41 @@ // This list can contain nulls on things like space turfs -- they only have their neighbors' corners. for (var/datum/lighting_corner/C in corners) - C.update_ambient_lumcount(ambient_r, ambient_g, ambient_b, no_corner_update) + C.update_ambient_lumcount(lr, lg, lb, !update) - if (ambient_light_old == null && ambient_light != ambient_light_old) - SSlighting.total_ambient_turfs += 1 - else if (ambient_light_old != null && ambient_light == null) - SSlighting.total_ambient_turfs -= 1 +/turf/proc/clear_ambient_light() + if (ambient_light == null) + return + + ambient_light = null + update_ambient_light() + +/turf/proc/update_ambient_light(no_corner_update = FALSE) + // These are deltas. + var/ambient_r = 0 + var/ambient_g = 0 + var/ambient_b = 0 + + if (ambient_light) + var/list/parts = rgb2num(ambient_light) + ambient_r = ((parts[1] / 255) * ambient_light_multiplier) - ambient_light_old_r + ambient_g = ((parts[2] / 255) * ambient_light_multiplier) - ambient_light_old_g + ambient_b = ((parts[3] / 255) * ambient_light_multiplier) - ambient_light_old_b + else + ambient_r = -ambient_light_old_r + ambient_g = -ambient_light_old_g + ambient_b = -ambient_light_old_b - ambient_light_old = ambient_light + add_ambient_light_raw(ambient_r, ambient_g, ambient_b, !no_corner_update) -/// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. +// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. /turf/proc/reconsider_lights() var/datum/light_source/L for (var/thing in affecting_lights) L = thing L.vis_update() -/// Forces a lighting update. Reconsider lights is preferred when possible. +// Forces a lighting update. Reconsider lights is preferred when possible. /turf/proc/force_update_lights() var/datum/light_source/L for (var/thing in affecting_lights) @@ -137,15 +186,15 @@ lum_g += L.apparent_g lum_b += L.apparent_b - lum_r = CLAMP01(lum_r / length(corners)) * 255 - lum_g = CLAMP01(lum_g / length(corners)) * 255 - lum_b = CLAMP01(lum_b / length(corners)) * 255 + lum_r = CLAMP01(lum_r / 4) * 255 + lum_g = CLAMP01(lum_g / 4) * 255 + lum_b = CLAMP01(lum_b / 4) * 255 return rgb(lum_r, lum_g, lum_b) #define SCALE(targ,min,max) (targ - min) / (max - min) -/// Returns a lumcount (average intensity of color channels) scaled between minlum and maxlum. +// Used to get a scaled lumcount. /turf/proc/get_lumcount(minlum = 0, maxlum = 1) if (!lighting_overlay) return 0.5 @@ -162,7 +211,7 @@ #undef SCALE -/// Can't think of a good name, this proc will recalculate the has_opaque_atom variable. +// Can't think of a good name, this proc will recalculate the has_opaque_atom variable. /turf/proc/recalc_atom_opacity() #ifdef AO_USE_LIGHTING_OPACITY var/old = has_opaque_atom From 9c61b045b1af873d8090b354f33c6d6bc4990edf Mon Sep 17 00:00:00 2001 From: Lohikar Date: Thu, 8 May 2025 15:56:36 -0500 Subject: [PATCH 319/512] cascade: Commit crimes against performance to fix compile --- mods/content/supermatter/endgame_cascade/universe.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mods/content/supermatter/endgame_cascade/universe.dm b/mods/content/supermatter/endgame_cascade/universe.dm index ccca16707e43..46eb1efd5bf4 100644 --- a/mods/content/supermatter/endgame_cascade/universe.dm +++ b/mods/content/supermatter/endgame_cascade/universe.dm @@ -70,14 +70,18 @@ // TODO: Should this be changed to use the actual ambient lights system...? /datum/universal_state/supermatter_cascade/OverlayAndAmbientSet() spawn(0) - for(var/datum/lighting_corner/L in SSlighting.lighting_corners) + // TODO: dear god anything but this + for(var/datum/lighting_corner/L) if(isAdminLevel(L.z)) L.update_lumcount(1,1,1) else L.update_lumcount(0.0, 0.4, 1) + CHECK_TICK + for(var/turf/space/T) OnTurfChange(T) + CHECK_TICK /datum/universal_state/supermatter_cascade/proc/MiscSet() for (var/obj/machinery/firealarm/alm in SSmachines.machinery) From bb010eda07d3f99cf4947a4d3fa24e7fed64a782 Mon Sep 17 00:00:00 2001 From: Lohikar Date: Thu, 8 May 2025 16:03:24 -0500 Subject: [PATCH 320/512] lighting: Move ambience into own file --- code/modules/lighting/ambient_turf.dm | 118 +++++++++++++++++++++++++ code/modules/lighting/lighting_turf.dm | 116 ------------------------ nebula.dme | 1 + 3 files changed, 119 insertions(+), 116 deletions(-) create mode 100644 code/modules/lighting/ambient_turf.dm diff --git a/code/modules/lighting/ambient_turf.dm b/code/modules/lighting/ambient_turf.dm new file mode 100644 index 000000000000..5cce40eec333 --- /dev/null +++ b/code/modules/lighting/ambient_turf.dm @@ -0,0 +1,118 @@ +/turf + /// If non-null, a hex RGB light color that should be applied to this turf. + var/ambient_light + /// The power of the above is multiplied by this. Setting too high may drown out normal lights on the same turf. + var/ambient_light_multiplier = 0.3 + + /// If this is TRUE, an above turf's ambient light is affecting this turf. + var/tmp/ambient_has_indirect = FALSE + + // Record-keeping, do not touch -- that means you, admins. + var/tmp/ambient_active = FALSE //! Do we have non-zero ambient light? Use [TURF_IS_AMBIENT_LIT] instead of reading this directly. + var/tmp/ambient_light_old_r = 0 + var/tmp/ambient_light_old_g = 0 + var/tmp/ambient_light_old_b = 0 + +/turf/proc/set_ambient_light(color, multiplier) + if (color == ambient_light && multiplier == ambient_light_multiplier) + return + + ambient_light = isnull(color) ? ambient_light : color + ambient_light_multiplier = isnull(multiplier) ? ambient_light_multiplier : multiplier + + update_ambient_light() + +/turf/proc/replace_ambient_light(old_color, new_color, old_multiplier, new_multiplier = 0) + if (!TURF_IS_AMBIENT_LIT_UNSAFE(src)) + add_ambient_light(new_color, new_multiplier) + return + + ASSERT(!isnull(old_multiplier)) // omitting new_multiplier is allowed for removing light nondestructively + + old_color ||= COLOR_WHITE + new_color ||= COLOR_WHITE + + var/list/old_parts = rgb2num(old_color) + var/list/new_parts = rgb2num(new_color) + + var/dr = (new_parts[1] / 255) * new_multiplier - (old_parts[1] / 255) * old_multiplier + var/dg = (new_parts[2] / 255) * new_multiplier - (old_parts[2] / 255) * old_multiplier + var/db = (new_parts[3] / 255) * new_multiplier - (old_parts[3] / 255) * old_multiplier + + if (!dr && !dg && !db) + return + + add_ambient_light_raw(dr, dg, db) + +/turf/proc/add_ambient_light(color, multiplier, update = TRUE) + if (!color) + return + + multiplier ||= ambient_light_multiplier + + var/list/ambient_parts = rgb2num(color) + + var/ambient_r = (ambient_parts[1] / 255) * multiplier + var/ambient_g = (ambient_parts[2] / 255) * multiplier + var/ambient_b = (ambient_parts[3] / 255) * multiplier + + add_ambient_light_raw(ambient_r, ambient_g, ambient_b, update) + +/turf/proc/add_ambient_light_raw(lr, lg, lb, update = TRUE) + if (!lr && !lg && !lb) + if (!ambient_light_old_r || !ambient_light_old_g || !ambient_light_old_b) + ambient_active = FALSE + SSlighting.total_ambient_turfs -= 1 + return + + if (!ambient_active) + SSlighting.total_ambient_turfs += 1 + ambient_active = TRUE + + // There are four corners per (lit) turf, we don't want to apply our light 4 times -- compensate by dividing by 4. + lr /= 4 + lg /= 4 + lb /= 4 + + lr = round(lr, LIGHTING_ROUND_VALUE) + lg = round(lg, LIGHTING_ROUND_VALUE) + lb = round(lb, LIGHTING_ROUND_VALUE) + + ambient_light_old_r += lr + ambient_light_old_g += lg + ambient_light_old_b += lb + + if (!corners || !lighting_corners_initialised) + if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) + generate_missing_corners() + else + return + + // This list can contain nulls on things like space turfs -- they only have their neighbors' corners. + for (var/datum/lighting_corner/C in corners) + C.update_ambient_lumcount(lr, lg, lb, !update) + +/turf/proc/clear_ambient_light() + if (ambient_light == null) + return + + ambient_light = null + update_ambient_light() + +/turf/proc/update_ambient_light(no_corner_update = FALSE) + // These are deltas. + var/ambient_r = 0 + var/ambient_g = 0 + var/ambient_b = 0 + + if (ambient_light) + var/list/parts = rgb2num(ambient_light) + ambient_r = ((parts[1] / 255) * ambient_light_multiplier) - ambient_light_old_r + ambient_g = ((parts[2] / 255) * ambient_light_multiplier) - ambient_light_old_g + ambient_b = ((parts[3] / 255) * ambient_light_multiplier) - ambient_light_old_b + else + ambient_r = -ambient_light_old_r + ambient_g = -ambient_light_old_g + ambient_b = -ambient_light_old_b + + add_ambient_light_raw(ambient_r, ambient_g, ambient_b, !no_corner_update) diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index 9af3682e4e85..e35022b38f89 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -1,9 +1,5 @@ /turf var/dynamic_lighting = TRUE - /// If non-null, a hex RGB light color that should be applied to this turf. - var/ambient_light - /// The power of the above is multiplied by this. Setting too high may drown out normal lights on the same turf. - var/ambient_light_multiplier = 0.3 luminosity = 1 var/tmp/lighting_corners_initialised = FALSE @@ -15,118 +11,6 @@ var/tmp/list/datum/lighting_corner/corners /// Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile. var/tmp/has_opaque_atom = FALSE - /// If this is TRUE, an above turf's ambient light is affecting this turf. - var/tmp/ambient_has_indirect = FALSE - - // Record-keeping, do not touch -- that means you, admins. - var/tmp/ambient_active = FALSE //! Do we have non-zero ambient light? Use [TURF_IS_AMBIENT_LIT] instead of reading this directly. - var/tmp/ambient_light_old_r = 0 - var/tmp/ambient_light_old_g = 0 - var/tmp/ambient_light_old_b = 0 - -/turf/proc/set_ambient_light(color, multiplier) - if (color == ambient_light && multiplier == ambient_light_multiplier) - return - - ambient_light = isnull(color) ? ambient_light : color - ambient_light_multiplier = isnull(multiplier) ? ambient_light_multiplier : multiplier - - update_ambient_light() - -/turf/proc/replace_ambient_light(old_color, new_color, old_multiplier, new_multiplier = 0) - if (!TURF_IS_AMBIENT_LIT_UNSAFE(src)) - add_ambient_light(new_color, new_multiplier) - return - - ASSERT(!isnull(old_multiplier)) // omitting new_multiplier is allowed for removing light nondestructively - - old_color ||= COLOR_WHITE - new_color ||= COLOR_WHITE - - var/list/old_parts = rgb2num(old_color) - var/list/new_parts = rgb2num(new_color) - - var/dr = (new_parts[1] / 255) * new_multiplier - (old_parts[1] / 255) * old_multiplier - var/dg = (new_parts[2] / 255) * new_multiplier - (old_parts[2] / 255) * old_multiplier - var/db = (new_parts[3] / 255) * new_multiplier - (old_parts[3] / 255) * old_multiplier - - if (!dr && !dg && !db) - return - - add_ambient_light_raw(dr, dg, db) - -/turf/proc/add_ambient_light(color, multiplier, update = TRUE) - if (!color) - return - - multiplier ||= ambient_light_multiplier - - var/list/ambient_parts = rgb2num(color) - - var/ambient_r = (ambient_parts[1] / 255) * multiplier - var/ambient_g = (ambient_parts[2] / 255) * multiplier - var/ambient_b = (ambient_parts[3] / 255) * multiplier - - add_ambient_light_raw(ambient_r, ambient_g, ambient_b, update) - -/turf/proc/add_ambient_light_raw(lr, lg, lb, update = TRUE) - if (!lr && !lg && !lb) - if (!ambient_light_old_r || !ambient_light_old_g || !ambient_light_old_b) - ambient_active = FALSE - SSlighting.total_ambient_turfs -= 1 - return - - if (!ambient_active) - SSlighting.total_ambient_turfs += 1 - ambient_active = TRUE - - // There are four corners per (lit) turf, we don't want to apply our light 4 times -- compensate by dividing by 4. - lr /= 4 - lg /= 4 - lb /= 4 - - lr = round(lr, LIGHTING_ROUND_VALUE) - lg = round(lg, LIGHTING_ROUND_VALUE) - lb = round(lb, LIGHTING_ROUND_VALUE) - - ambient_light_old_r += lr - ambient_light_old_g += lg - ambient_light_old_b += lb - - if (!corners || !lighting_corners_initialised) - if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(src)) - generate_missing_corners() - else - return - - // This list can contain nulls on things like space turfs -- they only have their neighbors' corners. - for (var/datum/lighting_corner/C in corners) - C.update_ambient_lumcount(lr, lg, lb, !update) - -/turf/proc/clear_ambient_light() - if (ambient_light == null) - return - - ambient_light = null - update_ambient_light() - -/turf/proc/update_ambient_light(no_corner_update = FALSE) - // These are deltas. - var/ambient_r = 0 - var/ambient_g = 0 - var/ambient_b = 0 - - if (ambient_light) - var/list/parts = rgb2num(ambient_light) - ambient_r = ((parts[1] / 255) * ambient_light_multiplier) - ambient_light_old_r - ambient_g = ((parts[2] / 255) * ambient_light_multiplier) - ambient_light_old_g - ambient_b = ((parts[3] / 255) * ambient_light_multiplier) - ambient_light_old_b - else - ambient_r = -ambient_light_old_r - ambient_g = -ambient_light_old_g - ambient_b = -ambient_light_old_b - - add_ambient_light_raw(ambient_r, ambient_g, ambient_b, !no_corner_update) // Causes any affecting light sources to be queued for a visibility update, for example a door got opened. /turf/proc/reconsider_lights() diff --git a/nebula.dme b/nebula.dme index 25a61fa32422..59beea9b2c7b 100644 --- a/nebula.dme +++ b/nebula.dme @@ -2680,6 +2680,7 @@ #include "code\modules\keybindings\movement.dm" #include "code\modules\keybindings\setup.dm" #include "code\modules\lighting\_lighting_defs.dm" +#include "code\modules\lighting\ambient_turf.dm" #include "code\modules\lighting\lighting_area.dm" #include "code\modules\lighting\lighting_atom.dm" #include "code\modules\lighting\lighting_corner.dm" From 58753c56043ae2d06c979b4dd478e5690c019374 Mon Sep 17 00:00:00 2001 From: Lohikar Date: Thu, 8 May 2025 16:05:06 -0500 Subject: [PATCH 321/512] lighting: Ambience groups --- code/modules/lighting/ambient_group.dm | 121 +++++++++++++++++++++++++ nebula.dme | 1 + 2 files changed, 122 insertions(+) create mode 100644 code/modules/lighting/ambient_group.dm diff --git a/code/modules/lighting/ambient_group.dm b/code/modules/lighting/ambient_group.dm new file mode 100644 index 000000000000..b7a88dfa9b12 --- /dev/null +++ b/code/modules/lighting/ambient_group.dm @@ -0,0 +1,121 @@ +#define BITWISE_MAX_BITS 24 + +/// A bitmap of free ambience group indexes. +var/ambience_group_free_bitmap = ~0 +var/ambience_group_map[BITWISE_MAX_BITS] + +/datum/ambience_group + var/global_index + var/list/member_turfs_by_z = list() + var/apparent_r + var/apparent_g + var/apparent_b + var/invalid = FALSE + var/busy = FALSE + +/datum/ambience_group/New() + global_index = allocate_index() + if (!global_index) + invalid = TRUE + return + + ambience_group_map[global_index] = src + +/datum/ambience_group/Destroy() + if (!invalid) + ambience_group_map[global_index] = null + ambience_group_free_bitmap |= (1 << global_index) + return ..() + +/datum/ambience_group/proc/allocate_index() + if (ambience_group_free_bitmap == 0) + CRASH("Failed to allocate ambience_group: index bitmap is exhausted") + + // Find the first free index in the bitmap. + var/index = 1 + while (!(ambience_group_free_bitmap & (1 << index)) && index < BITWISE_MAX_BITS) + index += 1 + + ambience_group_free_bitmap &= ~(1 << index) + + return index + +/datum/ambience_group/proc/add_turf(turf/T) + set waitfor = FALSE + + UNTIL(!busy) + if (T.z > member_turfs_by_z) + member_turfs_by_z.len = T.z + + LAZYADD(member_turfs_by_z[T.z], T) + T.add_ambient_light_raw(apparent_r, apparent_g, apparent_b) + T.ambience_active_groups += 1 + +/datum/ambience_group/proc/remove_turf(turf/T) + set waitfor = FALSE + + UNTIL(!busy) + if (T.z > member_turfs_by_z.len) + CRASH("Attempt to remove member turf with Z greater than local max -- this turf is not a member") + T.add_ambient_light_raw(-apparent_r, -apparent_g, -apparent_b) + member_turfs_by_z[T.z] -= T + T.ambience_active_groups -= 1 + +/datum/ambience_group/proc/set_ambient_light(color, multiplier) + var/list/new_parts = rgb2num(color) + + var/dr = (new_parts[1] / 255) * multiplier - apparent_r + var/dg = (new_parts[2] / 255) * multiplier - apparent_g + var/db = (new_parts[3] / 255) * multiplier - apparent_b + + if (round(dr/4, LIGHTING_ROUND_VALUE) == 0 && round(dg/4, LIGHTING_ROUND_VALUE) == 0 && round(db/4, LIGHTING_ROUND_VALUE) == 0) + // no-op + return + + busy = TRUE + + // Doing it ordered by zlev should ensure that it looks vaguely coherent mid-update regardless of turf insertion order. + for (var/zlev in 1 to member_turfs_by_z.len) + for (var/turf/T as anything in member_turfs_by_z[zlev]) + T.add_ambient_light_raw(dr, dg, db) + CHECK_TICK + + apparent_r += dr + apparent_g += dg + apparent_b += db + + busy = FALSE + +/turf + /// A bitfield of which global ambience groups are affecting this turf. + var/tmp/ambience_affecting_bitmap = 0 + /// A counter of how many ambience groups are affecting this turf, used to avoid pointlessly iterating the entire 24-bit bitfield. + var/tmp/ambience_active_groups = 0 + +/turf/Destroy() + if (ambience_affecting_bitmap) + var/remaining_groups = ambience_active_groups + for (var/i in 1 to BITWISE_MAX_BITS) + if (ambience_affecting_bitmap & (1 << i)) + var/datum/ambience_group/group = ambience_group_map[i] + add_ambient_light_raw(-group.apparent_r, -group.apparent_g, -group.apparent_b) + + remaining_groups -= 1 + + if (!remaining_groups) + break + + return ..() + +/turf/Initialize() + . = ..() + if (ambience_affecting_bitmap) + var/remaining_groups = ambience_active_groups + for (var/i in 1 to BITWISE_MAX_BITS) + if (ambience_affecting_bitmap & (1 << i)) + var/datum/ambience_group/group = ambience_group_map[i] + add_ambient_light_raw(group.apparent_r, group.apparent_g, group.apparent_b) + remaining_groups -= 1 + + if (!remaining_groups) + break diff --git a/nebula.dme b/nebula.dme index 59beea9b2c7b..8a77c79025d6 100644 --- a/nebula.dme +++ b/nebula.dme @@ -2680,6 +2680,7 @@ #include "code\modules\keybindings\movement.dm" #include "code\modules\keybindings\setup.dm" #include "code\modules\lighting\_lighting_defs.dm" +#include "code\modules\lighting\ambient_group.dm" #include "code\modules\lighting\ambient_turf.dm" #include "code\modules\lighting\lighting_area.dm" #include "code\modules\lighting\lighting_atom.dm" From 445569388d9dce0623d6f2f82f3be72e8da6ddec Mon Sep 17 00:00:00 2001 From: Lohikar Date: Thu, 8 May 2025 16:19:01 -0500 Subject: [PATCH 322/512] lighting: Fix some accidentally reverted doc comments --- code/modules/lighting/lighting_turf.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index e35022b38f89..724b2d46182e 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -12,14 +12,14 @@ /// Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile. var/tmp/has_opaque_atom = FALSE -// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. +/// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. /turf/proc/reconsider_lights() var/datum/light_source/L for (var/thing in affecting_lights) L = thing L.vis_update() -// Forces a lighting update. Reconsider lights is preferred when possible. +/// Forces a lighting update. Reconsider lights is preferred when possible. /turf/proc/force_update_lights() var/datum/light_source/L for (var/thing in affecting_lights) @@ -78,7 +78,7 @@ #define SCALE(targ,min,max) (targ - min) / (max - min) -// Used to get a scaled lumcount. +/// Returns a lumcount (average intensity of color channels) scaled between minlum and maxlum. /turf/proc/get_lumcount(minlum = 0, maxlum = 1) if (!lighting_overlay) return 0.5 @@ -95,7 +95,7 @@ #undef SCALE -// Can't think of a good name, this proc will recalculate the has_opaque_atom variable. +/// Can't think of a good name, this proc will recalculate the has_opaque_atom variable. /turf/proc/recalc_atom_opacity() #ifdef AO_USE_LIGHTING_OPACITY var/old = has_opaque_atom From 0e2014fd145742be67eefbf73b2109b972709f7a Mon Sep 17 00:00:00 2001 From: Lohikar Date: Thu, 8 May 2025 16:19:32 -0500 Subject: [PATCH 323/512] ambience: Docs, fix logic error in clear_ambient_light() --- code/modules/lighting/ambient_turf.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/lighting/ambient_turf.dm b/code/modules/lighting/ambient_turf.dm index 5cce40eec333..5b9ba5a03d9a 100644 --- a/code/modules/lighting/ambient_turf.dm +++ b/code/modules/lighting/ambient_turf.dm @@ -13,6 +13,7 @@ var/tmp/ambient_light_old_g = 0 var/tmp/ambient_light_old_b = 0 +/// Set the turf's self-ambience channel. This can only contain one value at a time, so it should generally only be used by the turf itself. /turf/proc/set_ambient_light(color, multiplier) if (color == ambient_light && multiplier == ambient_light_multiplier) return @@ -22,6 +23,7 @@ update_ambient_light() +/// Replace one ambient light with another. This is effectively a delta update, but it can be used to pretend that our one channel is doing color blending. /turf/proc/replace_ambient_light(old_color, new_color, old_multiplier, new_multiplier = 0) if (!TURF_IS_AMBIENT_LIT_UNSAFE(src)) add_ambient_light(new_color, new_multiplier) @@ -44,6 +46,7 @@ add_ambient_light_raw(dr, dg, db) +/// Add an ambient light to the turf's self-channel. This is a delta update, retain your applied color if you want to be able to remove it later. /turf/proc/add_ambient_light(color, multiplier, update = TRUE) if (!color) return @@ -58,6 +61,7 @@ add_ambient_light_raw(ambient_r, ambient_g, ambient_b, update) +/// Directly manipulate the state of the self-ambience channel. Don't use unless you know what you're doing and how ambience works internally. /turf/proc/add_ambient_light_raw(lr, lg, lb, update = TRUE) if (!lr && !lg && !lb) if (!ambient_light_old_r || !ambient_light_old_g || !ambient_light_old_b) @@ -92,12 +96,14 @@ for (var/datum/lighting_corner/C in corners) C.update_ambient_lumcount(lr, lg, lb, !update) +/// Wipe the entire self-ambience channel. This will preserve ambience from ambience groups. /turf/proc/clear_ambient_light() if (ambient_light == null) return + replace_ambient_light(ambient_light, COLOR_WHITE, ambient_light_multiplier, 0) ambient_light = null - update_ambient_light() + ambient_light_multiplier = initial(ambient_light_multiplier) /turf/proc/update_ambient_light(no_corner_update = FALSE) // These are deltas. From c03a275d3fb90ff65e2cc9014fd4c8acc1c3ddb9 Mon Sep 17 00:00:00 2001 From: Lohikar Date: Thu, 8 May 2025 16:48:39 -0500 Subject: [PATCH 324/512] Jiggle bitshift count --- test/check-paths.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/check-paths.sh b/test/check-paths.sh index 8984b116442e..5643ae1afa53 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -34,7 +34,7 @@ exactly 10 "/turf text paths" '"/turf' exactly 1 "world<< uses" 'world\s*<<' exactly 75 "'in world' uses" '\s+\bin world\b(?=\s*$|\s*//|\s*\))' -P exactly 1 "world.log<< uses" 'world.log\s*<<' -exactly 18 "<< uses" '(?> uses" '(?\\])>>(?!>)' -P exactly 0 "incorrect indentations" '^( {4,})' -P From 104e2a780860ee58a808adf5c3cce6d6f2226ee7 Mon Sep 17 00:00:00 2001 From: Lohikar Date: Thu, 8 May 2025 16:57:41 -0500 Subject: [PATCH 325/512] ambience: Properly mark globals --- code/modules/lighting/ambient_group.dm | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/code/modules/lighting/ambient_group.dm b/code/modules/lighting/ambient_group.dm index b7a88dfa9b12..009565a16fdf 100644 --- a/code/modules/lighting/ambient_group.dm +++ b/code/modules/lighting/ambient_group.dm @@ -1,8 +1,8 @@ #define BITWISE_MAX_BITS 24 /// A bitmap of free ambience group indexes. -var/ambience_group_free_bitmap = ~0 -var/ambience_group_map[BITWISE_MAX_BITS] +var/global/ambience_group_free_bitmap = ~0 +var/global/ambience_group_map[BITWISE_MAX_BITS] /datum/ambience_group var/global_index @@ -19,24 +19,24 @@ var/ambience_group_map[BITWISE_MAX_BITS] invalid = TRUE return - ambience_group_map[global_index] = src + global.ambience_group_map[global_index] = src /datum/ambience_group/Destroy() if (!invalid) - ambience_group_map[global_index] = null - ambience_group_free_bitmap |= (1 << global_index) + global.ambience_group_map[global_index] = null + global.ambience_group_free_bitmap |= (1 << global_index) return ..() /datum/ambience_group/proc/allocate_index() - if (ambience_group_free_bitmap == 0) + if (global.ambience_group_free_bitmap == 0) CRASH("Failed to allocate ambience_group: index bitmap is exhausted") // Find the first free index in the bitmap. var/index = 1 - while (!(ambience_group_free_bitmap & (1 << index)) && index < BITWISE_MAX_BITS) + while (!(global.ambience_group_free_bitmap & (1 << index)) && index < BITWISE_MAX_BITS) index += 1 - ambience_group_free_bitmap &= ~(1 << index) + global.ambience_group_free_bitmap &= ~(1 << index) return index @@ -97,7 +97,7 @@ var/ambience_group_map[BITWISE_MAX_BITS] var/remaining_groups = ambience_active_groups for (var/i in 1 to BITWISE_MAX_BITS) if (ambience_affecting_bitmap & (1 << i)) - var/datum/ambience_group/group = ambience_group_map[i] + var/datum/ambience_group/group = global.ambience_group_map[i] add_ambient_light_raw(-group.apparent_r, -group.apparent_g, -group.apparent_b) remaining_groups -= 1 @@ -113,7 +113,7 @@ var/ambience_group_map[BITWISE_MAX_BITS] var/remaining_groups = ambience_active_groups for (var/i in 1 to BITWISE_MAX_BITS) if (ambience_affecting_bitmap & (1 << i)) - var/datum/ambience_group/group = ambience_group_map[i] + var/datum/ambience_group/group = global.ambience_group_map[i] add_ambient_light_raw(group.apparent_r, group.apparent_g, group.apparent_b) remaining_groups -= 1 From 88745c8f1e54a05914aa867960f94ed971b3cf77 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Fri, 16 May 2025 00:58:28 +0000 Subject: [PATCH 326/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index b65f492394dc..fa25dd37d04d 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -90,12 +90,6 @@

    Penelope Haze updated:

    • Adjusts how suffocation works, meaning characters who were drowning or in asystole start breathing as soon as the issue is resolved, rather than counting down a timer instead. This might make brief bouts of drowning/cardiac arrest more survivable. Please report any weirdness with breathing/suffocation on the issue tracker.
    - -

    14 March 2025

    -

    Typhin updated:

    -
      -
    • Allows parts/screwdrivers to be used on biogenerators
    • -
    From 6bda709902c666ef77b3abc6bae458aea6b86838 Mon Sep 17 00:00:00 2001 From: Typhin Date: Fri, 16 May 2025 05:31:00 -0500 Subject: [PATCH 327/512] RPD now dispenses colored pipes Fixes a small issue where the RPD dispensed uncolored pipes no matter what color setting was chosen. --- code/game/objects/items/weapons/RPD.dm | 2 +- code/modules/fabrication/designs/pipe/pipe_datum_base.dm | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/objects/items/weapons/RPD.dm b/code/game/objects/items/weapons/RPD.dm index cf1a465a2e33..0a98205bfc7e 100644 --- a/code/game/objects/items/weapons/RPD.dm +++ b/code/game/objects/items/weapons/RPD.dm @@ -146,7 +146,7 @@ var/global/list/rpd_pipe_selection_skilled = list() return playsound(get_turf(user), 'sound/items/Deconstruct.ogg', 50, 1) - P.build(T, new/datum/fabricator_build_order(P, 1, list("slected_color" = pipe_colors[pipe_color]))) + P.build(T, new/datum/fabricator_build_order(P, 1, list("selected_color" = pipe_colors[pipe_color]))) if(prob(20)) spark_at(src, amount = 5, holder = src) diff --git a/code/modules/fabrication/designs/pipe/pipe_datum_base.dm b/code/modules/fabrication/designs/pipe/pipe_datum_base.dm index 8d3c48485e8c..835f766a499a 100644 --- a/code/modules/fabrication/designs/pipe/pipe_datum_base.dm +++ b/code/modules/fabrication/designs/pipe/pipe_datum_base.dm @@ -35,9 +35,9 @@ new_item.rotate_class = rotate_class new_item.constructed_path = constructed_path if(colorable) - new_item.color = order.get_data("selected_color", PIPE_COLOR_WHITE) + new_item.set_color(order.get_data("selected_color", PIPE_COLOR_WHITE)) else if (pipe_color != null) - new_item.color = pipe_color + new_item.set_color(pipe_color) new_item.SetName(name) if(desc) new_item.desc = desc From 1f7637f6697c56d92d38ab6f6b53f9675b336f5d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 15 May 2025 00:30:44 -0400 Subject: [PATCH 328/512] Fix being unable to D-notice newscaster channels --- code/game/machinery/newscaster.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 50533238ce2a..1152b6d5dc03 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -711,7 +711,7 @@ var/global/list/allCasters = list() //Global list that will contain reference to else if(href_list["pick_censor_channel"]) var/datum/feed_channel/FC = locate(href_list["pick_censor_channel"]) viewing_channel = FC - screen = SCREEN_PICK_CENSOR_CHANNEL + screen = SCREEN_PICK_CENSOR_STORY . = TOPIC_REFRESH else if(href_list["refresh"]) From 98ec6f4d331e1c5aec2224289e68faca38f94415 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 20:44:24 -0400 Subject: [PATCH 329/512] Fix window spawners not blocking atmos --- code/game/objects/structures/wallframe_spawner.dm | 1 + code/game/objects/structures/window_spawner.dm | 1 + 2 files changed, 2 insertions(+) diff --git a/code/game/objects/structures/wallframe_spawner.dm b/code/game/objects/structures/wallframe_spawner.dm index 2573ad0514fb..5852388b2c8a 100644 --- a/code/game/objects/structures/wallframe_spawner.dm +++ b/code/game/objects/structures/wallframe_spawner.dm @@ -4,6 +4,7 @@ icon_state = "wingrille" density = TRUE anchored = TRUE + atmos_canpass = CANPASS_NEVER var/win_path = /obj/structure/window/basic/full var/frame_path = /obj/structure/wall_frame/standard var/grille_path = /obj/structure/grille diff --git a/code/game/objects/structures/window_spawner.dm b/code/game/objects/structures/window_spawner.dm index 95f24c0fd089..b8b0785ffbf9 100644 --- a/code/game/objects/structures/window_spawner.dm +++ b/code/game/objects/structures/window_spawner.dm @@ -9,6 +9,7 @@ icon_state = "wingrille" density = TRUE anchored = TRUE + atmos_canpass = CANPASS_NEVER var/win_path = /obj/structure/window/basic var/activated = FALSE var/fulltile = FALSE From 1f00de56bfc53b5272971aed6b069cce6ecde689 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 17:31:48 -0400 Subject: [PATCH 330/512] More psionics subsystem priority define into psionics modpack --- code/__defines/subsystem-priority.dm | 1 - mods/content/psionics/_defines.dm | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/__defines/subsystem-priority.dm b/code/__defines/subsystem-priority.dm index ffb0ed8d9e9d..65756053aad1 100644 --- a/code/__defines/subsystem-priority.dm +++ b/code/__defines/subsystem-priority.dm @@ -45,7 +45,6 @@ #define SS_PRIORITY_PROCESSING 95 // Generic datum processor. Replaces objects processor. #define SS_PRIORITY_PLANTS 90 // Plant processing, slow ticks. #define SS_PRIORITY_VINES 50 // Spreading vine effects. -#define SS_PRIORITY_PSYCHICS 45 // Psychic complexus processing. #define SS_PRIORITY_AI 45 // Artificial Intelligence on mobs processing. #define SS_PRIORITY_NANO 40 // Updates to nanoui uis. #define SS_PRIORITY_TURF 30 // Radioactive walls/blob. diff --git a/mods/content/psionics/_defines.dm b/mods/content/psionics/_defines.dm index a7be273fe9d0..78ba7afb6ac0 100644 --- a/mods/content/psionics/_defines.dm +++ b/mods/content/psionics/_defines.dm @@ -20,3 +20,5 @@ #define MAT_NULLGLASS /decl/material/nullglass #define COLOR_NULLGLASS "#ff6088" + +#define SS_PRIORITY_PSYCHICS 45 // Psychic complexus processing priority From 9be21462cd60c78260ff960ee9b1ee4459aa36dd Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 19:28:02 -0400 Subject: [PATCH 331/512] Move and do a quality pass on tape recorder code --- .../devices/tape_recorder/magnetic_tape.dm | 176 ++++++ .../devices/tape_recorder/tape_recorder.dm | 360 ++++++++++++ .../tape_recorder/taperecorder_wires.dm} | 3 +- .../objects/items/devices/taperecorder.dm | 540 ------------------ nebula.dme | 5 +- 5 files changed, 540 insertions(+), 544 deletions(-) create mode 100644 code/game/objects/items/devices/tape_recorder/magnetic_tape.dm create mode 100644 code/game/objects/items/devices/tape_recorder/tape_recorder.dm rename code/{datums/wires/taperecorder.dm => game/objects/items/devices/tape_recorder/taperecorder_wires.dm} (90%) delete mode 100644 code/game/objects/items/devices/taperecorder.dm diff --git a/code/game/objects/items/devices/tape_recorder/magnetic_tape.dm b/code/game/objects/items/devices/tape_recorder/magnetic_tape.dm new file mode 100644 index 000000000000..26d5cdf79b36 --- /dev/null +++ b/code/game/objects/items/devices/tape_recorder/magnetic_tape.dm @@ -0,0 +1,176 @@ +/obj/item/magnetic_tape + name = "tape" + desc = "A magnetic tape that can hold up to ten minutes of content." + icon = 'icons/obj/items/device/tape_recorder/tape_casette_white.dmi' + icon_state = ICON_STATE_WORLD + w_class = ITEM_SIZE_SMALL + material = /decl/material/solid/organic/plastic + matter = list( + /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, + /decl/material/solid/fiberglass = MATTER_AMOUNT_TRACE + ) + _base_attack_force = 1 + var/max_capacity = 600 + var/used_capacity = 0 + var/list/storedinfo = new/list() + var/list/timestamp = new/list() + var/ruined = FALSE + var/doctored = FALSE + /// Whether we draw the ruined ribbon overlay when ruined. + var/draw_ribbon_if_ruined = TRUE + +/obj/item/magnetic_tape/on_update_icon() + . = ..() + icon_state = get_world_inventory_state() + if(draw_ribbon_if_ruined && ruined && max_capacity) + add_overlay(overlay_image(icon, "[icon_state]_ribbonoverlay", flags = RESET_COLOR)) + +/obj/item/magnetic_tape/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + ruin() + return ..() + +/obj/item/magnetic_tape/attack_self(mob/user) + if(!ruined) + to_chat(user, SPAN_NOTICE("You pull out all the tape!")) + get_loose_tape(user, length(storedinfo)) + ruin() + + +/obj/item/magnetic_tape/proc/ruin() + ruined = TRUE + update_icon() + + +/obj/item/magnetic_tape/proc/fix() + ruined = FALSE + update_icon() + + +/obj/item/magnetic_tape/proc/record_speech(text) + timestamp += used_capacity + storedinfo += "\[[time2text(used_capacity SECONDS,"mm:ss")]\] [text]" + + +//shows up on the printed transcript as (Unrecognized sound) +/obj/item/magnetic_tape/proc/record_noise(text) + timestamp += used_capacity + storedinfo += "*\[[time2text(used_capacity SECONDS,"mm:ss")]\] [text]" + + +/obj/item/magnetic_tape/attackby(obj/item/used_item, mob/user, params) + if(user.incapacitated()) // TODO: this may not be necessary since OnClick checks before starting the attack chain + return TRUE + if(ruined && IS_SCREWDRIVER(used_item)) + if(!max_capacity) + to_chat(user, SPAN_NOTICE("There is no tape left inside.")) + return TRUE + to_chat(user, SPAN_NOTICE("You start winding the tape back in...")) + if(do_after(user, 12 SECONDS, target = src)) + to_chat(user, SPAN_NOTICE("You wound the tape back in.")) + fix() + return TRUE + else if(IS_PEN(used_item)) + if(loc == user) + var/new_name = input(user, "What would you like to label the tape?", "Tape labeling") as null|text + if(isnull(new_name)) return TRUE + new_name = sanitize_safe(new_name) + if(new_name) + SetName("tape - '[new_name]'") + to_chat(user, SPAN_NOTICE("You label the tape '[new_name]'.")) + else + SetName("tape") + to_chat(user, SPAN_NOTICE("You scratch off the label.")) + return TRUE + else if(IS_WIRECUTTER(used_item)) + cut(user) + return TRUE + else if(istype(used_item, /obj/item/magnetic_tape/loose)) + join(user, used_item) + return TRUE + return ..() + +/obj/item/magnetic_tape/proc/cut(mob/user) + if(!LAZYLEN(timestamp)) + to_chat(user, SPAN_NOTICE("There's nothing on this tape!")) + return + var/list/output = list("
    ") + for(var/i in 1 to length(timestamp)) + var/time = "\[[time2text(timestamp[i] SECONDS,"mm:ss")]\]" + output += "[time]
    -----CUT------
    " + output += "
    " + + var/datum/browser/popup = new(user, "tape_cutting", "Cutting tape", 170, 600) + popup.set_content(jointext(output,null)) + popup.open() + +/obj/item/magnetic_tape/proc/join(mob/user, obj/item/magnetic_tape/other) + if(max_capacity + other.max_capacity > initial(max_capacity)) + to_chat(user, SPAN_NOTICE("You can't fit this much tape in!")) + return + if(user.try_unequip(other)) + to_chat(user, SPAN_NOTICE("You join ends of the tape together.")) + max_capacity += other.max_capacity + used_capacity = min(used_capacity + other.used_capacity, max_capacity) + timestamp += other.timestamp + storedinfo += other.storedinfo + doctored = TRUE + ruin() + update_icon() + qdel(other) + +/obj/item/magnetic_tape/OnTopic(var/mob/user, var/list/href_list) + if(href_list["cut_after"]) + var/index = text2num(href_list["cut_after"]) + if(index >= length(timestamp)) + return + + to_chat(user, SPAN_NOTICE("You remove part of the tape.")) + get_loose_tape(user, index) + cut(user) + return TOPIC_REFRESH + +//Spawns new loose tape item, with data starting from [index] entry +/obj/item/magnetic_tape/proc/get_loose_tape(var/mob/user, var/index) + var/obj/item/magnetic_tape/loose/newtape = new() + newtape.timestamp = timestamp.Copy(index+1) + newtape.storedinfo = storedinfo.Copy(index+1) + newtape.max_capacity = max_capacity - index + newtape.used_capacity = max(0, used_capacity - max_capacity) + newtape.doctored = doctored + user.put_in_hands(newtape) + + timestamp.Cut(index+1) + storedinfo.Cut(index+1) + max_capacity = index + used_capacity = min(used_capacity,index) + +//Random colour tapes +/obj/item/magnetic_tape/random/Initialize() + icon = pick(list( + 'icons/obj/items/device/tape_recorder/tape_casette_white.dmi', + 'icons/obj/items/device/tape_recorder/tape_casette_blue.dmi', + 'icons/obj/items/device/tape_recorder/tape_casette_red.dmi', + 'icons/obj/items/device/tape_recorder/tape_casette_yellow.dmi', + 'icons/obj/items/device/tape_recorder/tape_casette_purple.dmi' + )) + . = ..() + +/obj/item/magnetic_tape/loose + name = "magnetic tape" + desc = "Quantum-enriched self-repairing nanotape, used for magnetic storage of information." + icon = 'icons/obj/items/device/tape_recorder/tape_casette_loose.dmi' + ruined = TRUE + draw_ribbon_if_ruined = FALSE + +/obj/item/magnetic_tape/loose/fix() + return + +/obj/item/magnetic_tape/loose/get_loose_tape() + return + +/obj/item/magnetic_tape/loose/get_examine_strings(mob/user, distance, infix, suffix) + . = ..() + if(distance <= 1) + . += SPAN_NOTICE("It looks long enough to hold [max_capacity] seconds worth of recording.") + if(doctored && user.skill_check(SKILL_FORENSICS, SKILL_PROF)) + . += SPAN_WARNING("It has been tampered with...") diff --git a/code/game/objects/items/devices/tape_recorder/tape_recorder.dm b/code/game/objects/items/devices/tape_recorder/tape_recorder.dm new file mode 100644 index 000000000000..7677f30a1dc0 --- /dev/null +++ b/code/game/objects/items/devices/tape_recorder/tape_recorder.dm @@ -0,0 +1,360 @@ +/obj/item/taperecorder + name = "universal recorder" + desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback." + icon = 'icons/obj/items/device/tape_recorder/tape_recorder.dmi' + icon_state = ICON_STATE_WORLD + w_class = ITEM_SIZE_SMALL + material = /decl/material/solid/metal/aluminium + matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) + obj_flags = OBJ_FLAG_CONDUCTIBLE + slot_flags = SLOT_LOWER_BODY + throw_speed = 4 + throw_range = 20 + + var/emagged = FALSE + var/recording = FALSE + var/playing = FALSE + var/playsleepseconds = 0 + var/obj/item/magnetic_tape/mytape = /obj/item/magnetic_tape/random + var/const/TRANSCRIPT_PRINT_COOLDOWN = 5 MINUTES + /// (FLOAT) The minimum world.time before a transcript can be printed again. + var/next_print_time = 0 + var/datum/wires/taperecorder/wires = null // Wires datum + /// (BOOL) If TRUE, wire datum is accessible for interactions. + var/wires_accessible = FALSE + +/obj/item/taperecorder/Initialize() + . = ..() + wires = new(src) + if(ispath(mytape)) + mytape = new mytape(src) + global.listening_objects += src + update_icon() + +/obj/item/taperecorder/empty + mytape = null + +/obj/item/taperecorder/Destroy() + QDEL_NULL(wires) + QDEL_NULL(mytape) + return ..() + +/obj/item/taperecorder/attackby(obj/item/used_item, mob/user, params) + if(IS_SCREWDRIVER(used_item)) + wires_accessible = !wires_accessible + to_chat(user, SPAN_NOTICE("You [wires_accessible ? "open" : "secure"] the lid.")) + return TRUE + if(istype(used_item, /obj/item/magnetic_tape)) + if(mytape) + to_chat(user, SPAN_NOTICE("There's already a tape inside.")) + return TRUE + if(!user.try_unequip(used_item)) + return TRUE + used_item.forceMove(src) + mytape = used_item + to_chat(user, SPAN_NOTICE("You insert [used_item] into [src].")) + update_icon() + return TRUE + return ..() + + +/obj/item/taperecorder/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + if(mytape) + mytape.ruin() //Fires destroy the tape + return ..() + + +/obj/item/taperecorder/attack_hand(mob/user) + if(user.is_holding_offhand(src) && mytape && user.check_dexterity(DEXTERITY_SIMPLE_MACHINES)) + eject() + return TRUE + return ..() + + +/obj/item/taperecorder/verb/eject() + set name = "Eject Tape" + set category = "Object" + + if(usr.incapacitated()) + return + if(!mytape) + to_chat(usr, SPAN_NOTICE("There's no tape in \the [src].")) + return + if(emagged) + to_chat(usr, SPAN_NOTICE("The tape seems to be stuck inside.")) + return + + if(playing || recording) + stop() + to_chat(usr, SPAN_NOTICE("You remove [mytape] from [src].")) + usr.put_in_hands(mytape) + mytape = null + update_icon() + +/obj/item/taperecorder/get_examine_strings(mob/user, distance, infix, suffix) + . = ..() + if(distance <= 1 && wires_accessible) + . += SPAN_NOTICE("The wires are exposed.") + +/obj/item/taperecorder/hear_talk(mob/living/M, msg, var/verb="says", decl/language/speaking=null) + if(mytape && recording) + + if(speaking) + if(!speaking.machine_understands) + msg = speaking.scramble(M, msg) + mytape.record_speech("[M.name] [speaking.format_message_plain(msg, verb)]") + else + mytape.record_speech("[M.name] [verb], \"[msg]\"") + +/obj/item/taperecorder/show_message(msg, type, alt, alt_type) + var/recordedtext + if (msg && type == AUDIBLE_MESSAGE) //must be hearable + recordedtext = msg + else if (alt && alt_type == AUDIBLE_MESSAGE) + recordedtext = alt + else + return + if(mytape && recording) + mytape.record_noise("[strip_html_properly(recordedtext)]") + +/obj/item/taperecorder/emag_act(var/remaining_charges, var/mob/user) + if(!emagged) + emagged = TRUE + recording = FALSE + to_chat(user, SPAN_WARNING("PZZTTPFFFT")) + update_icon() + return 1 + else + to_chat(user, SPAN_WARNING("It is already emagged!")) + +/obj/item/taperecorder/proc/explode() + var/turf/T = get_turf(loc) + if(ismob(loc)) + var/mob/M = loc + to_chat(M, SPAN_DANGER("\The [src] explodes!")) + if(T) + T.hotspot_expose(700,125) + explosion(T, -1, -1, 0, 4) + qdel(src) + return + +/obj/item/taperecorder/verb/record() + set name = "Start Recording" + set category = "Object" + + if(usr.incapacitated()) + return + playsound(src, 'sound/machines/click.ogg', 10, 1) + if(!mytape) + to_chat(usr, SPAN_NOTICE("There's no tape!")) + return + if(mytape.ruined || emagged) + audible_message(SPAN_WARNING("The tape recorder makes a scratchy noise.")) + return + if(recording) + to_chat(usr, SPAN_NOTICE("You're already recording!")) + return + if(playing) + to_chat(usr, SPAN_NOTICE("You can't record when playing!")) + return + if(mytape.used_capacity < mytape.max_capacity) + to_chat(usr, SPAN_NOTICE("Recording started.")) + recording = TRUE + update_icon() + + mytape.record_speech("Recording started.") + + //count seconds until full, or recording is stopped + while(mytape && recording && mytape.used_capacity < mytape.max_capacity) + sleep(1 SECOND) + mytape.used_capacity++ + if(mytape.used_capacity >= mytape.max_capacity) + to_chat(usr, SPAN_NOTICE("The tape is full.")) + stop_recording() + + + update_icon() + return + else + to_chat(usr, SPAN_NOTICE("The tape is full.")) + + +/obj/item/taperecorder/proc/stop_recording() + //Sanity checks skipped, should not be called unless actually recording + recording = FALSE + update_icon() + mytape.record_speech("Recording stopped.") + if(ismob(loc)) + var/mob/M = loc + to_chat(M, SPAN_NOTICE("Recording stopped.")) + + +/obj/item/taperecorder/verb/stop() + set name = "Stop" + set category = "Object" + + if(usr.incapacitated()) + return + playsound(src, 'sound/machines/click.ogg', 10, 1) + if(recording) + stop_recording() + return + else if(playing) + playing = FALSE + update_icon() + to_chat(usr, SPAN_NOTICE("Playback stopped.")) + return + else + to_chat(usr, SPAN_NOTICE("Stop what?")) + + +/obj/item/taperecorder/verb/wipe_tape() + set name = "Wipe Tape" + set category = "Object" + + if(usr.incapacitated()) + return + if(!mytape) + return + if(emagged || mytape.ruined) + audible_message(SPAN_WARNING("The tape recorder makes a scratchy noise.")) + return + if(recording || playing) + to_chat(usr, SPAN_NOTICE("You can't wipe the tape while playing or recording!")) + return + else + if(mytape.storedinfo) mytape.storedinfo.Cut() + if(mytape.timestamp) mytape.timestamp.Cut() + mytape.used_capacity = 0 + to_chat(usr, SPAN_NOTICE("You wipe the tape.")) + return + + +/obj/item/taperecorder/verb/playback_memory() + set name = "Playback Tape" + set category = "Object" + + if(usr.incapacitated()) + return + play(usr) + +/obj/item/taperecorder/proc/play(mob/user) + if(!mytape) + to_chat(user, SPAN_NOTICE("There's no tape!")) + return + if(mytape.ruined) + audible_message(SPAN_WARNING("The tape recorder makes a scratchy noise.")) + return + if(recording) + to_chat(user, SPAN_NOTICE("You can't playback when recording!")) + return + if(playing) + to_chat(user, SPAN_NOTICE("\The [src] is already playing its recording!")) + return + playing = TRUE + update_icon() + to_chat(user, SPAN_NOTICE("Audio playback started.")) + playsound(src, 'sound/machines/click.ogg', 10, 1) + for(var/i=1 , i < mytape.max_capacity , i++) + if(!mytape || !playing) + break + if(length(mytape.storedinfo) < i) + break + + var/turf/T = get_turf(src) + var/playedmessage = mytape.storedinfo[i] + if (findtextEx(playedmessage,"*",1,2)) //remove marker for action sounds + playedmessage = copytext(playedmessage,2) + T.audible_message(SPAN_MAROON("Tape Recorder: [playedmessage]")) + + if(length(mytape.storedinfo) < i+1) + playsleepseconds = 1 + sleep(10) + T = get_turf(src) + T.audible_message(SPAN_MAROON("Tape Recorder: End of recording.")) + playsound(src, 'sound/machines/click.ogg', 10, 1) + break + else + playsleepseconds = mytape.timestamp[i+1] - mytape.timestamp[i] + + if(playsleepseconds > 14) + sleep(10) + T = get_turf(src) + T.audible_message(SPAN_MAROON("Tape Recorder: Skipping [playsleepseconds] seconds of silence")) + playsleepseconds = 1 + sleep(playsleepseconds SECONDS) + + + playing = FALSE + update_icon() + + if(emagged) + var/turf/T = get_turf(src) + T.audible_message(SPAN_MAROON("Tape Recorder: This tape recorder will self-destruct in... Five.")) + sleep(10) + T = get_turf(src) + T.audible_message(SPAN_MAROON("Tape Recorder: Four.")) + sleep(10) + T = get_turf(src) + T.audible_message(SPAN_MAROON("Tape Recorder: Three.")) + sleep(10) + T = get_turf(src) + T.audible_message(SPAN_MAROON("Tape Recorder: Two.")) + sleep(10) + T = get_turf(src) + T.audible_message(SPAN_MAROON("Tape Recorder: One.")) + sleep(10) + explode() + + +/obj/item/taperecorder/verb/print_transcript() + set name = "Print Transcript" + set category = "Object" + + if(usr.incapacitated()) + return + if(!mytape) + to_chat(usr, SPAN_NOTICE("There's no tape!")) + return + if(mytape.ruined || emagged) + audible_message(SPAN_WARNING("The tape recorder makes a scratchy noise.")) + return + if(next_print_time < world.time) + to_chat(usr, SPAN_NOTICE("The recorder can't print that fast!")) + return + if(recording || playing) + to_chat(usr, SPAN_NOTICE("You can't print the transcript while playing or recording!")) + return + + to_chat(usr, SPAN_NOTICE("Transcript printed.")) + var/obj/item/paper/P = new /obj/item/paper(get_turf(src)) + var/t1 = "Transcript:

    " + for(var/i in 1 to length(mytape.storedinfo)) + var/printedmessage = mytape.storedinfo[i] + if (findtextEx(printedmessage,"*",1,2)) //replace action sounds + printedmessage = "\[[time2text(mytape.timestamp[i]*10,"mm:ss")]\] (Unrecognized sound)" + t1 += "[printedmessage]
    " + P.info = t1 + P.SetName("Transcript") + next_print_time = world.time + TRANSCRIPT_PRINT_COOLDOWN + +/obj/item/taperecorder/attack_self(mob/user) + if(wires_accessible) + wires.Interact(user) + return + if(recording || playing) + stop() + else + record() + +/obj/item/taperecorder/on_update_icon() + . = ..() + icon_state = get_world_inventory_state() + if(!mytape) + icon_state = "[icon_state]_empty" + else if(recording) + icon_state = "[icon_state]_recording" + else if(playing) + icon_state = "[icon_state]_playing" + else + icon_state = "[icon_state]_idle" diff --git a/code/datums/wires/taperecorder.dm b/code/game/objects/items/devices/tape_recorder/taperecorder_wires.dm similarity index 90% rename from code/datums/wires/taperecorder.dm rename to code/game/objects/items/devices/tape_recorder/taperecorder_wires.dm index 784cd1a17df1..20e4bd7f63fa 100644 --- a/code/datums/wires/taperecorder.dm +++ b/code/game/objects/items/devices/tape_recorder/taperecorder_wires.dm @@ -4,8 +4,7 @@ descriptions = list( new /datum/wire_description(TAPE_WIRE_TOGGLE, "This wire runs to the play/stop toggle.", SKILL_ADEPT) ) - -var/global/const/TAPE_WIRE_TOGGLE = 1 + var/const/TAPE_WIRE_TOGGLE = 1 /datum/wires/taperecorder/UpdatePulsed(var/index) var/obj/item/taperecorder/T = holder diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm deleted file mode 100644 index 32287bf5e738..000000000000 --- a/code/game/objects/items/devices/taperecorder.dm +++ /dev/null @@ -1,540 +0,0 @@ -/obj/item/taperecorder - name = "universal recorder" - desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback." - icon = 'icons/obj/items/device/tape_recorder/tape_recorder.dmi' - icon_state = ICON_STATE_WORLD - w_class = ITEM_SIZE_SMALL - material = /decl/material/solid/metal/aluminium - matter = list(/decl/material/solid/fiberglass = MATTER_AMOUNT_REINFORCEMENT) - obj_flags = OBJ_FLAG_CONDUCTIBLE - slot_flags = SLOT_LOWER_BODY - throw_speed = 4 - throw_range = 20 - - var/emagged = 0.0 - var/recording = 0.0 - var/playing = 0.0 - var/playsleepseconds = 0.0 - var/obj/item/magnetic_tape/mytape = /obj/item/magnetic_tape/random - var/canprint = 1 - var/datum/wires/taperecorder/wires = null // Wires datum - var/maintenance = 0 - -/obj/item/taperecorder/Initialize() - . = ..() - wires = new(src) - if(ispath(mytape)) - mytape = new mytape(src) - global.listening_objects += src - update_icon() - -/obj/item/taperecorder/empty - mytape = null - -/obj/item/taperecorder/Destroy() - QDEL_NULL(wires) - if(mytape) - qdel(mytape) - mytape = null - return ..() - -/obj/item/taperecorder/attackby(obj/item/used_item, mob/user, params) - if(IS_SCREWDRIVER(used_item)) - maintenance = !maintenance - to_chat(user, "You [maintenance ? "open" : "secure"] the lid.") - return TRUE - if(istype(used_item, /obj/item/magnetic_tape)) - if(mytape) - to_chat(user, "There's already a tape inside.") - return TRUE - if(!user.try_unequip(used_item)) - return TRUE - used_item.forceMove(src) - mytape = used_item - to_chat(user, "You insert [used_item] into [src].") - update_icon() - return TRUE - return ..() - - -/obj/item/taperecorder/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(mytape) - mytape.ruin() //Fires destroy the tape - return ..() - - -/obj/item/taperecorder/attack_hand(mob/user) - if(user.is_holding_offhand(src) && mytape && user.check_dexterity(DEXTERITY_SIMPLE_MACHINES)) - eject() - return TRUE - return ..() - - -/obj/item/taperecorder/verb/eject() - set name = "Eject Tape" - set category = "Object" - - if(usr.incapacitated()) - return - if(!mytape) - to_chat(usr, "There's no tape in \the [src].") - return - if(emagged) - to_chat(usr, "The tape seems to be stuck inside.") - return - - if(playing || recording) - stop() - to_chat(usr, "You remove [mytape] from [src].") - usr.put_in_hands(mytape) - mytape = null - update_icon() - -/obj/item/taperecorder/get_examine_strings(mob/user, distance, infix, suffix) - . = ..() - if(distance <= 1 && maintenance) - . += SPAN_NOTICE("The wires are exposed.") - -/obj/item/taperecorder/hear_talk(mob/living/M, msg, var/verb="says", decl/language/speaking=null) - if(mytape && recording) - - if(speaking) - if(!speaking.machine_understands) - msg = speaking.scramble(M, msg) - mytape.record_speech("[M.name] [speaking.format_message_plain(msg, verb)]") - else - mytape.record_speech("[M.name] [verb], \"[msg]\"") - -/obj/item/taperecorder/show_message(msg, type, alt, alt_type) - var/recordedtext - if (msg && type == AUDIBLE_MESSAGE) //must be hearable - recordedtext = msg - else if (alt && alt_type == AUDIBLE_MESSAGE) - recordedtext = alt - else - return - if(mytape && recording) - mytape.record_noise("[strip_html_properly(recordedtext)]") - -/obj/item/taperecorder/emag_act(var/remaining_charges, var/mob/user) - if(emagged == 0) - emagged = 1 - recording = 0 - to_chat(user, "PZZTTPFFFT") - update_icon() - return 1 - else - to_chat(user, "It is already emagged!") - -/obj/item/taperecorder/proc/explode() - var/turf/T = get_turf(loc) - if(ismob(loc)) - var/mob/M = loc - to_chat(M, "\The [src] explodes!") - if(T) - T.hotspot_expose(700,125) - explosion(T, -1, -1, 0, 4) - qdel(src) - return - -/obj/item/taperecorder/verb/record() - set name = "Start Recording" - set category = "Object" - - if(usr.incapacitated()) - return - playsound(src, 'sound/machines/click.ogg', 10, 1) - if(!mytape) - to_chat(usr, "There's no tape!") - return - if(mytape.ruined || emagged) - audible_message("The tape recorder makes a scratchy noise.") - return - if(recording) - to_chat(usr, "You're already recording!") - return - if(playing) - to_chat(usr, "You can't record when playing!") - return - if(mytape.used_capacity < mytape.max_capacity) - to_chat(usr, "Recording started.") - recording = 1 - update_icon() - - mytape.record_speech("Recording started.") - - //count seconds until full, or recording is stopped - while(mytape && recording && mytape.used_capacity < mytape.max_capacity) - sleep(10) - mytape.used_capacity++ - if(mytape.used_capacity >= mytape.max_capacity) - if(ismob(loc)) - var/mob/M = loc - to_chat(M, "The tape is full.") - stop_recording() - - - update_icon() - return - else - to_chat(usr, "The tape is full.") - - -/obj/item/taperecorder/proc/stop_recording() - //Sanity checks skipped, should not be called unless actually recording - recording = 0 - update_icon() - mytape.record_speech("Recording stopped.") - if(ismob(loc)) - var/mob/M = loc - to_chat(M, "Recording stopped.") - - -/obj/item/taperecorder/verb/stop() - set name = "Stop" - set category = "Object" - - if(usr.incapacitated()) - return - playsound(src, 'sound/machines/click.ogg', 10, 1) - if(recording) - stop_recording() - return - else if(playing) - playing = 0 - update_icon() - to_chat(usr, "Playback stopped.") - return - else - to_chat(usr, "Stop what?") - - -/obj/item/taperecorder/verb/wipe_tape() - set name = "Wipe Tape" - set category = "Object" - - if(usr.incapacitated()) - return - if(!mytape) - return - if(emagged || mytape.ruined) - audible_message("The tape recorder makes a scratchy noise.") - return - if(recording || playing) - to_chat(usr, "You can't wipe the tape while playing or recording!") - return - else - if(mytape.storedinfo) mytape.storedinfo.Cut() - if(mytape.timestamp) mytape.timestamp.Cut() - mytape.used_capacity = 0 - to_chat(usr, "You wipe the tape.") - return - - -/obj/item/taperecorder/verb/playback_memory() - set name = "Playback Tape" - set category = "Object" - - if(usr.incapacitated()) - return - play(usr) - -/obj/item/taperecorder/proc/play(mob/user) - if(!mytape) - to_chat(user, "There's no tape!") - return - if(mytape.ruined) - audible_message("The tape recorder makes a scratchy noise.") - return - if(recording) - to_chat(user, "You can't playback when recording!") - return - if(playing) - to_chat(user, "You're already playing!") - return - playing = 1 - update_icon() - to_chat(user, "Audio playback started.") - playsound(src, 'sound/machines/click.ogg', 10, 1) - for(var/i=1 , i < mytape.max_capacity , i++) - if(!mytape || !playing) - break - if(mytape.storedinfo.len < i) - break - - var/turf/T = get_turf(src) - var/playedmessage = mytape.storedinfo[i] - if (findtextEx(playedmessage,"*",1,2)) //remove marker for action sounds - playedmessage = copytext(playedmessage,2) - T.audible_message(SPAN_MAROON("Tape Recorder: [playedmessage]")) - - if(mytape.storedinfo.len < i+1) - playsleepseconds = 1 - sleep(10) - T = get_turf(src) - T.audible_message(SPAN_MAROON("Tape Recorder: End of recording.")) - playsound(src, 'sound/machines/click.ogg', 10, 1) - break - else - playsleepseconds = mytape.timestamp[i+1] - mytape.timestamp[i] - - if(playsleepseconds > 14) - sleep(10) - T = get_turf(src) - T.audible_message(SPAN_MAROON("Tape Recorder: Skipping [playsleepseconds] seconds of silence")) - playsleepseconds = 1 - sleep(10 * playsleepseconds) - - - playing = 0 - update_icon() - - if(emagged) - var/turf/T = get_turf(src) - T.audible_message(SPAN_MAROON("Tape Recorder: This tape recorder will self-destruct in... Five.")) - sleep(10) - T = get_turf(src) - T.audible_message(SPAN_MAROON("Tape Recorder: Four.")) - sleep(10) - T = get_turf(src) - T.audible_message(SPAN_MAROON("Tape Recorder: Three.")) - sleep(10) - T = get_turf(src) - T.audible_message(SPAN_MAROON("Tape Recorder: Two.")) - sleep(10) - T = get_turf(src) - T.audible_message(SPAN_MAROON("Tape Recorder: One.")) - sleep(10) - explode() - - -/obj/item/taperecorder/verb/print_transcript() - set name = "Print Transcript" - set category = "Object" - - if(usr.incapacitated()) - return - if(!mytape) - to_chat(usr, "There's no tape!") - return - if(mytape.ruined || emagged) - audible_message("The tape recorder makes a scratchy noise.") - return - if(!canprint) - to_chat(usr, "The recorder can't print that fast!") - return - if(recording || playing) - to_chat(usr, "You can't print the transcript while playing or recording!") - return - - to_chat(usr, "Transcript printed.") - var/obj/item/paper/P = new /obj/item/paper(get_turf(src)) - var/t1 = "Transcript:

    " - for(var/i=1,mytape.storedinfo.len >= i,i++) - var/printedmessage = mytape.storedinfo[i] - if (findtextEx(printedmessage,"*",1,2)) //replace action sounds - printedmessage = "\[[time2text(mytape.timestamp[i]*10,"mm:ss")]\] (Unrecognized sound)" - t1 += "[printedmessage]
    " - P.info = t1 - P.SetName("Transcript") - canprint = 0 - sleep(300) - canprint = 1 - -/obj/item/taperecorder/attack_self(mob/user) - if(maintenance) - wires.Interact(user) - return - if(recording || playing) - stop() - else - record() - -/obj/item/taperecorder/on_update_icon() - . = ..() - icon_state = get_world_inventory_state() - if(!mytape) - icon_state = "[icon_state]_empty" - else if(recording) - icon_state = "[icon_state]_recording" - else if(playing) - icon_state = "[icon_state]_playing" - else - icon_state = "[icon_state]_idle" - -/obj/item/magnetic_tape - name = "tape" - desc = "A magnetic tape that can hold up to ten minutes of content." - icon = 'icons/obj/items/device/tape_recorder/tape_casette_white.dmi' - icon_state = ICON_STATE_WORLD - w_class = ITEM_SIZE_SMALL - material = /decl/material/solid/organic/plastic - matter = list( - /decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT, - /decl/material/solid/fiberglass = MATTER_AMOUNT_TRACE - ) - _base_attack_force = 1 - var/max_capacity = 600 - var/used_capacity = 0 - var/list/storedinfo = new/list() - var/list/timestamp = new/list() - var/ruined = 0 - var/doctored = 0 - /// Whether we draw the ruined ribbon overlay when ruined. - var/draw_ribbon_if_ruined = TRUE - -/obj/item/magnetic_tape/on_update_icon() - . = ..() - icon_state = get_world_inventory_state() - if(draw_ribbon_if_ruined && ruined && max_capacity) - add_overlay(overlay_image(icon, "[icon_state]_ribbonoverlay", flags = RESET_COLOR)) - -/obj/item/magnetic_tape/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ruin() - return ..() - -/obj/item/magnetic_tape/attack_self(mob/user) - if(!ruined) - to_chat(user, "You pull out all the tape!") - get_loose_tape(user, storedinfo.len) - ruin() - - -/obj/item/magnetic_tape/proc/ruin() - ruined = TRUE - update_icon() - - -/obj/item/magnetic_tape/proc/fix() - ruined = FALSE - update_icon() - - -/obj/item/magnetic_tape/proc/record_speech(text) - timestamp += used_capacity - storedinfo += "\[[time2text(used_capacity*10,"mm:ss")]\] [text]" - - -//shows up on the printed transcript as (Unrecognized sound) -/obj/item/magnetic_tape/proc/record_noise(text) - timestamp += used_capacity - storedinfo += "*\[[time2text(used_capacity*10,"mm:ss")]\] [text]" - - -/obj/item/magnetic_tape/attackby(obj/item/used_item, mob/user, params) - if(user.incapacitated()) // TODO: this may not be necessary since OnClick checks before starting the attack chain - return TRUE - if(ruined && IS_SCREWDRIVER(used_item)) - if(!max_capacity) - to_chat(user, "There is no tape left inside.") - return TRUE - to_chat(user, "You start winding the tape back in...") - if(do_after(user, 120, target = src)) - to_chat(user, "You wound the tape back in.") - fix() - return TRUE - else if(IS_PEN(used_item)) - if(loc == user) - var/new_name = input(user, "What would you like to label the tape?", "Tape labeling") as null|text - if(isnull(new_name)) return TRUE - new_name = sanitize_safe(new_name) - if(new_name) - SetName("tape - '[new_name]'") - to_chat(user, "You label the tape '[new_name]'.") - else - SetName("tape") - to_chat(user, "You scratch off the label.") - return TRUE - else if(IS_WIRECUTTER(used_item)) - cut(user) - return TRUE - else if(istype(used_item, /obj/item/magnetic_tape/loose)) - join(user, used_item) - return TRUE - return ..() - -/obj/item/magnetic_tape/proc/cut(mob/user) - if(!LAZYLEN(timestamp)) - to_chat(user, "There's nothing on this tape!") - return - var/list/output = list("
    ") - for(var/i=1, i < timestamp.len, i++) - var/time = "\[[time2text(timestamp[i]*10,"mm:ss")]\]" - output += "[time]
    -----CUT------
    " - output += "
    " - - var/datum/browser/popup = new(user, "tape_cutting", "Cutting tape", 170, 600) - popup.set_content(jointext(output,null)) - popup.open() - -/obj/item/magnetic_tape/proc/join(mob/user, obj/item/magnetic_tape/other) - if(max_capacity + other.max_capacity > initial(max_capacity)) - to_chat(user, "You can't fit this much tape in!") - return - if(user.try_unequip(other)) - to_chat(user, "You join ends of the tape together.") - max_capacity += other.max_capacity - used_capacity = min(used_capacity + other.used_capacity, max_capacity) - timestamp += other.timestamp - storedinfo += other.storedinfo - doctored = 1 - ruin() - update_icon() - qdel(other) - -/obj/item/magnetic_tape/OnTopic(var/mob/user, var/list/href_list) - if(href_list["cut_after"]) - var/index = text2num(href_list["cut_after"]) - if(index >= timestamp.len) - return - - to_chat(user, "You remove part of the tape off.") - get_loose_tape(user, index) - cut(user) - return TOPIC_REFRESH - -//Spawns new loose tape item, with data starting from [index] entry -/obj/item/magnetic_tape/proc/get_loose_tape(var/mob/user, var/index) - var/obj/item/magnetic_tape/loose/newtape = new() - newtape.timestamp = timestamp.Copy(index+1) - newtape.storedinfo = storedinfo.Copy(index+1) - newtape.max_capacity = max_capacity - index - newtape.used_capacity = max(0, used_capacity - max_capacity) - newtape.doctored = doctored - user.put_in_hands(newtape) - - timestamp.Cut(index+1) - storedinfo.Cut(index+1) - max_capacity = index - used_capacity = min(used_capacity,index) - -//Random colour tapes -/obj/item/magnetic_tape/random/Initialize() - icon = pick(list( - 'icons/obj/items/device/tape_recorder/tape_casette_white.dmi', - 'icons/obj/items/device/tape_recorder/tape_casette_blue.dmi', - 'icons/obj/items/device/tape_recorder/tape_casette_red.dmi', - 'icons/obj/items/device/tape_recorder/tape_casette_yellow.dmi', - 'icons/obj/items/device/tape_recorder/tape_casette_purple.dmi' - )) - . = ..() - -/obj/item/magnetic_tape/loose - name = "magnetic tape" - desc = "Quantum-enriched self-repairing nanotape, used for magnetic storage of information." - icon = 'icons/obj/items/device/tape_recorder/tape_casette_loose.dmi' - ruined = TRUE - draw_ribbon_if_ruined = FALSE - -/obj/item/magnetic_tape/loose/fix() - return - -/obj/item/magnetic_tape/loose/get_loose_tape() - return - -/obj/item/magnetic_tape/loose/get_examine_strings(mob/user, distance, infix, suffix) - . = ..() - if(distance <= 1) - . += SPAN_NOTICE("It looks long enough to hold [max_capacity] seconds worth of recording.") - if(doctored && user.skill_check(SKILL_FORENSICS, SKILL_PROF)) - . += SPAN_WARNING("It has been tampered with...") diff --git a/nebula.dme b/nebula.dme index 8a77c79025d6..0c5c058dc7e4 100644 --- a/nebula.dme +++ b/nebula.dme @@ -744,7 +744,6 @@ #include "code\datums\wires\smartfridge.dm" #include "code\datums\wires\smes.dm" #include "code\datums\wires\suit_cycler.dm" -#include "code\datums\wires\taperecorder.dm" #include "code\datums\wires\vending.dm" #include "code\datums\wires\wire_description.dm" #include "code\datums\wires\wires.dm" @@ -1206,7 +1205,6 @@ #include "code\game\objects\items\devices\suit_cooling.dm" #include "code\game\objects\items\devices\suit_sensor_jammer.dm" #include "code\game\objects\items\devices\t_scanner.dm" -#include "code\game\objects\items\devices\taperecorder.dm" #include "code\game\objects\items\devices\traitordevices.dm" #include "code\game\objects\items\devices\transfer_valve.dm" #include "code\game\objects\items\devices\tvcamera.dm" @@ -1223,6 +1221,9 @@ #include "code\game\objects\items\devices\radio\radio_borg.dm" #include "code\game\objects\items\devices\radio\radio_exosuit.dm" #include "code\game\objects\items\devices\radio\radio_misc.dm" +#include "code\game\objects\items\devices\tape_recorder\magnetic_tape.dm" +#include "code\game\objects\items\devices\tape_recorder\tape_recorder.dm" +#include "code\game\objects\items\devices\tape_recorder\taperecorder_wires.dm" #include "code\game\objects\items\flame\_flame.dm" #include "code\game\objects\items\flame\flame_candle.dm" #include "code\game\objects\items\flame\flame_fuelled.dm" From 2b189054c641ecf13cfede74d7c9c55a1b9d9818 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 20:18:34 -0400 Subject: [PATCH 332/512] Refactor stimulants/antidepressants to reduce code duplication --- code/modules/clothing/masks/chewable.dm | 4 +- .../spacesuits/rig/modules/utility.dm | 10 +- .../hydroponics/plant_types/seeds_misc.dm | 4 +- .../modules/reagents/chems/chems_medicines.dm | 64 ------------- .../reagents/chems/chems_psychiatric.dm | 91 +++++++++++++++++++ .../reagents/reactions/reaction_drugs.dm | 4 +- .../reagent_containers/food/donkpocket.dm | 2 +- .../reagents/reagent_containers/pill.dm | 16 ++-- nebula.dme | 1 + 9 files changed, 112 insertions(+), 84 deletions(-) create mode 100644 code/modules/reagents/chems/chems_psychiatric.dm diff --git a/code/modules/clothing/masks/chewable.dm b/code/modules/clothing/masks/chewable.dm index 682c68bc51fd..1df74f5bc5fa 100644 --- a/code/modules/clothing/masks/chewable.dm +++ b/code/modules/clothing/masks/chewable.dm @@ -210,8 +210,8 @@ /decl/material/liquid/regenerator, /decl/material/liquid/amphetamines, /decl/material/liquid/antirads, - /decl/material/liquid/stimulants, - /decl/material/liquid/antidepressants, + /decl/material/liquid/accumulated/stimulants, + /decl/material/liquid/accumulated/antidepressants, /decl/material/liquid/antitoxins, /decl/material/liquid/brute_meds, /decl/material/liquid/burn_meds, diff --git a/code/modules/clothing/spacesuits/rig/modules/utility.dm b/code/modules/clothing/spacesuits/rig/modules/utility.dm index f46dd0447280..b024ab15dae1 100644 --- a/code/modules/clothing/spacesuits/rig/modules/utility.dm +++ b/code/modules/clothing/spacesuits/rig/modules/utility.dm @@ -265,11 +265,11 @@ desc = "A complex web of tubing and needles suitable for hardsuit use." charges = list( - list("antidepressants", "antidepressants", /decl/material/liquid/antidepressants, 30), - list("stimulants", "stimulants", /decl/material/liquid/stimulants, 30), - list("amphetamines", "amphetamines", /decl/material/liquid/amphetamines, 30), - list("painkillers", "painkillers", /decl/material/liquid/painkillers/strong, 30), - list("glucose", "glucose", /decl/material/liquid/nutriment/glucose, 80) + list("antidepressants", "antidepressants", /decl/material/liquid/accumulated/antidepressants, 30), + list("stimulants", "stimulants", /decl/material/liquid/accumulated/stimulants, 30), + list("amphetamines", "amphetamines", /decl/material/liquid/amphetamines, 30), + list("painkillers", "painkillers", /decl/material/liquid/painkillers/strong, 30), + list("glucose", "glucose", /decl/material/liquid/nutriment/glucose, 80) ) interface_name = "combat chem dispenser" diff --git a/code/modules/hydroponics/plant_types/seeds_misc.dm b/code/modules/hydroponics/plant_types/seeds_misc.dm index 8ee10be8c9dd..ea29e6249413 100644 --- a/code/modules/hydroponics/plant_types/seeds_misc.dm +++ b/code/modules/hydroponics/plant_types/seeds_misc.dm @@ -414,8 +414,8 @@ chems = list( /decl/material/liquid/nutriment = list(1), /decl/material/liquid/brute_meds = list(1,8), - /decl/material/liquid/antidepressants = list(1,8,1), - /decl/material/liquid/stimulants = list(1,8,1), + /decl/material/liquid/accumulated/antidepressants = list(1,8,1), + /decl/material/liquid/accumulated/stimulants = list(1,8,1), /decl/material/liquid/amphetamines = list(1,10,1), /decl/material/liquid/psychoactives = list(1,10) ) diff --git a/code/modules/reagents/chems/chems_medicines.dm b/code/modules/reagents/chems/chems_medicines.dm index 02e3484df2c4..9c22dfc135ef 100644 --- a/code/modules/reagents/chems/chems_medicines.dm +++ b/code/modules/reagents/chems/chems_medicines.dm @@ -168,70 +168,6 @@ victim.add_chemical_effect(CE_TOXIN, 1) victim.adjust_immunity(-0.5) -/decl/material/liquid/stimulants - name = "stimulants" - lore_text = "Improves the ability to concentrate." - taste_description = "sourness" - color = "#bf80bf" - scannable = 1 - metabolism = 0.01 - value = 1.5 - exoplanet_rarity_gas = MAT_RARITY_EXOTIC - uid = "chem_stimulants" - allergen_flags = ALLERGEN_STIMULANT - -/decl/material/liquid/stimulants/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) - var/volume = REAGENT_VOLUME(holder, src) - . = ..() - var/update_data = FALSE - var/list/data = REAGENT_DATA(holder, src) - if(volume <= 0.1 && CHEM_DOSE(M, src) >= 0.5 && world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) - update_data = TRUE - to_chat(M, "You lose focus...") - else - ADJ_STATUS(M, STAT_DROWSY, -5) - ADJ_STATUS(M, STAT_PARA, -1) - ADJ_STATUS(M, STAT_STUN, -1) - ADJ_STATUS(M, STAT_WEAK, -1) - if(world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) - update_data = TRUE - to_chat(M, "Your mind feels focused and undivided.") - - if(update_data) - LAZYSET(data, DATA_COOLDOWN_TIME, world.time) - LAZYSET(holder.reagent_data, type, data) - -/decl/material/liquid/antidepressants - name = "antidepressants" - lore_text = "Stabilizes the mind a little." - taste_description = "bitterness" - color = "#ff80ff" - scannable = 1 - metabolism = 0.01 - value = 1.5 - exoplanet_rarity_gas = MAT_RARITY_EXOTIC - uid = "chem_antidepressants" - -/decl/material/liquid/antidepressants/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) - var/volume = REAGENT_VOLUME(holder, src) - . = ..() - - var/update_data = FALSE - var/list/data = REAGENT_DATA(holder, src) - if(volume <= 0.1 && CHEM_DOSE(M, src) >= 0.5 && world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) - update_data = TRUE - to_chat(M, "Your mind feels a little less stable...") - else - M.add_chemical_effect(CE_MIND, 1) - M.adjust_hallucination(-10) - if(world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + 5 MINUTES) - update_data = TRUE - to_chat(M, "Your mind feels stable... a little stable.") - - if(update_data) - LAZYSET(data, DATA_COOLDOWN_TIME, world.time) - LAZYSET(holder.reagent_data, type, data) - /decl/material/liquid/antibiotics name = "antibiotics" lore_text = "An all-purpose antibiotic agent." diff --git a/code/modules/reagents/chems/chems_psychiatric.dm b/code/modules/reagents/chems/chems_psychiatric.dm new file mode 100644 index 000000000000..2bc88925516f --- /dev/null +++ b/code/modules/reagents/chems/chems_psychiatric.dm @@ -0,0 +1,91 @@ +/// This material type has mob effects based on accumulated dose. +/// If the drug has been in your system enough to accumulate a dose, +/// and the level of it in your bloodstream drops below a certain volume, +/// you will get discontinuation effects. +/// If it is above that volume or hasn't been in your system long enough to accumulate, +/// you will get the positive effects. +/decl/material/liquid/accumulated + abstract_type = /decl/material/liquid/accumulated + /// (FLOAT) The dose under which you will receive effects from discontinuation. + var/required_dose = 0.5 + /// (FLOAT) The minimum volume to get the positive effect of this reagent. + var/required_volume = 0.1 + /// (FLOAT) The cooldown between effect triggers. + var/effect_cooldown = 5 MINUTES + +/decl/material/liquid/accumulated/affect_blood(mob/living/victim, removed, datum/reagents/holder) + var/volume = REAGENT_VOLUME(holder, src) + . = ..() + + var/update_data = FALSE + var/list/data = REAGENT_DATA(holder, src) + var/is_off_cooldown = world.time > LAZYACCESS(data, DATA_COOLDOWN_TIME) + effect_cooldown + if(volume <= required_volume && CHEM_DOSE(victim, src) >= required_dose) + update_data = discontinuation_effect(victim, removed, holder, is_off_cooldown) + else + update_data = positive_effect(victim, removed, holder, is_off_cooldown) + + if(update_data) + LAZYSET(data, DATA_COOLDOWN_TIME, world.time) + LAZYSET(holder.reagent_data, type, data) + +/// Returns TRUE to signal that the effect should go on cooldown. +/decl/material/liquid/accumulated/proc/positive_effect(mob/living/victim, removed, datum/reagents/holder, is_off_cooldown) + return FALSE + +/// Returns TRUE to signal that the effect should go on cooldown. +/decl/material/liquid/accumulated/proc/discontinuation_effect(mob/living/victim, removed, datum/reagents/holder, is_off_cooldown) + return FALSE + +/decl/material/liquid/accumulated/stimulants + name = "stimulants" + lore_text = "Improves the ability to concentrate." + taste_description = "sourness" + color = "#bf80bf" + scannable = 1 + metabolism = 0.01 + value = 1.5 + exoplanet_rarity_gas = MAT_RARITY_EXOTIC + uid = "chem_stimulants" + allergen_flags = ALLERGEN_STIMULANT + +/decl/material/liquid/accumulated/stimulants/positive_effect(mob/living/victim, removed, datum/reagents/holder, is_off_cooldown) + ADJ_STATUS(victim, STAT_DROWSY, -5) + ADJ_STATUS(victim, STAT_PARA, -1) + ADJ_STATUS(victim, STAT_STUN, -1) + ADJ_STATUS(victim, STAT_WEAK, -1) + if(is_off_cooldown) + to_chat(victim, SPAN_NOTICE("Your mind feels focused and undivided.")) + return TRUE + return FALSE + +/decl/material/liquid/accumulated/stimulants/discontinuation_effect(mob/living/victim, removed, datum/reagents/holder, is_off_cooldown) + if(is_off_cooldown) + to_chat(victim, SPAN_WARNING("You lose focus...")) + return TRUE + return FALSE + +/decl/material/liquid/accumulated/antidepressants + name = "antidepressants" + lore_text = "Stabilizes the mind a little." + taste_description = "bitterness" + color = "#ff80ff" + scannable = 1 + metabolism = 0.01 + value = 1.5 + exoplanet_rarity_gas = MAT_RARITY_EXOTIC + uid = "chem_antidepressants" + +/decl/material/liquid/accumulated/antidepressants/positive_effect(mob/living/victim, removed, datum/reagents/holder, is_off_cooldown) + victim.add_chemical_effect(CE_MIND, 1) + victim.adjust_hallucination(-10) + if(is_off_cooldown) + to_chat(victim, SPAN_NOTICE("Your mind feels stable... a little stable.")) + return TRUE + return FALSE + +/decl/material/liquid/accumulated/antidepressants/discontinuation_effect(mob/living/victim, removed, datum/reagents/holder, is_off_cooldown) + if(is_off_cooldown) + to_chat(victim, SPAN_WARNING("Your mind feels a little less stable...")) + return TRUE + return FALSE diff --git a/code/modules/reagents/reactions/reaction_drugs.dm b/code/modules/reagents/reactions/reaction_drugs.dm index a4f85cb3fa73..8f0c839b3b0f 100644 --- a/code/modules/reagents/reactions/reaction_drugs.dm +++ b/code/modules/reagents/reactions/reaction_drugs.dm @@ -159,13 +159,13 @@ /decl/chemical_reaction/drug/stimulants name = "Stimulants" - result = /decl/material/liquid/stimulants + result = /decl/material/liquid/accumulated/stimulants required_reagents = list(/decl/material/liquid/hallucinogenics = 1, /decl/material/solid/lithium = 1) result_amount = 3 /decl/chemical_reaction/drug/antidepressants name = "Antidepressants" - result = /decl/material/liquid/antidepressants + result = /decl/material/liquid/accumulated/antidepressants required_reagents = list(/decl/material/liquid/hallucinogenics = 1, /decl/material/solid/carbon = 1) result_amount = 3 diff --git a/code/modules/reagents/reagent_containers/food/donkpocket.dm b/code/modules/reagents/reagent_containers/food/donkpocket.dm index b261f8781a84..55e9e809efee 100644 --- a/code/modules/reagents/reagent_containers/food/donkpocket.dm +++ b/code/modules/reagents/reagent_containers/food/donkpocket.dm @@ -57,7 +57,7 @@ heated_reagents = list( /decl/material/liquid/regenerator = 5, /decl/material/liquid/amphetamines = 0.75, - /decl/material/liquid/stimulants = 0.25 + /decl/material/liquid/accumulated/stimulants = 0.25 ) var/has_been_heated = 0 // Unlike the warm var, this checks if the one-time self-heating operation has been used. diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 14286f7debe5..e58ada9128be 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -184,10 +184,10 @@ autolabel = FALSE /obj/item/chems/pill/zoom/populate_reagents() - add_to_reagents(/decl/material/liquid/narcotics, 5) - add_to_reagents(/decl/material/liquid/antidepressants, 5) - add_to_reagents(/decl/material/liquid/stimulants, 5) - add_to_reagents(/decl/material/liquid/amphetamines, 5) + add_to_reagents(/decl/material/liquid/narcotics, 5) + add_to_reagents(/decl/material/liquid/accumulated/antidepressants, 5) + add_to_reagents(/decl/material/liquid/accumulated/stimulants, 5) + add_to_reagents(/decl/material/liquid/amphetamines, 5) . = ..() /obj/item/chems/pill/gleam @@ -210,19 +210,19 @@ //Psychiatry pills. /obj/item/chems/pill/stimulants - desc = "Improves the ability to concentrate." + desc = "Improves the ability to concentrate. Abrupt discontinuation may result in side-effects." icon_state = "pill2" /obj/item/chems/pill/stimulants/populate_reagents() - add_to_reagents(/decl/material/liquid/stimulants, 15) + add_to_reagents(/decl/material/liquid/accumulated/stimulants, 15) . = ..() /obj/item/chems/pill/antidepressants - desc = "Mild anti-depressant." + desc = "Mild anti-depressant. Abrupt discontinuation may result in side-effects." icon_state = "pill4" /obj/item/chems/pill/antidepressants/populate_reagents() - add_to_reagents(/decl/material/liquid/antidepressants, 15) + add_to_reagents(/decl/material/liquid/accumulated/antidepressants, 15) . = ..() /obj/item/chems/pill/antirads diff --git a/nebula.dme b/nebula.dme index 8a77c79025d6..8dd681b5c38e 100644 --- a/nebula.dme +++ b/nebula.dme @@ -3648,6 +3648,7 @@ #include "code\modules\reagents\chems\chems_painkillers.dm" #include "code\modules\reagents\chems\chems_pigments.dm" #include "code\modules\reagents\chems\chems_poisons.dm" +#include "code\modules\reagents\chems\chems_psychiatric.dm" #include "code\modules\reagents\chems\random\chems_random.dm" #include "code\modules\reagents\chems\random\random_effects.dm" #include "code\modules\reagents\dispenser\_defines.dm" From db76f0681311deaa1ae6f028fce911122342971d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 20:22:52 -0400 Subject: [PATCH 333/512] Refactor syndie cigarettes to reduce code duplication --- .../items/weapons/storage/fancy/cigarettes.dm | 83 +++++++------------ .../items/weapons/storage/uplink_kits.dm | 8 +- maps/ministation/ministation-1.dmm | 2 +- tools/map_migrations/9999_cigarettes.txt | 4 + 4 files changed, 41 insertions(+), 56 deletions(-) create mode 100644 tools/map_migrations/9999_cigarettes.txt diff --git a/code/game/objects/items/weapons/storage/fancy/cigarettes.dm b/code/game/objects/items/weapons/storage/fancy/cigarettes.dm index ef4dcddd236f..379d275b5f8f 100644 --- a/code/game/objects/items/weapons/storage/fancy/cigarettes.dm +++ b/code/game/objects/items/weapons/storage/fancy/cigarettes.dm @@ -167,76 +167,57 @@ //////////////////////////////////////////////////////////////////////////////// // Syndie Cigs //////////////////////////////////////////////////////////////////////////////// +/obj/item/box/fancy/cigarettes/covert + abstract_type = /obj/item/box/fancy/cigarettes/covert + /// (TYPEPATH) Used to reset the name and description of covert cigarette packs on init. + var/obj/item/box/fancy/cigarettes/disguised_as = /obj/item/box/fancy/cigarettes + /// (STRING) Part of a string appended to the description on init. + var/scribble = null + +/obj/item/box/fancy/cigarettes/covert/Initialize(ml, material_key) + . = ..() + if(ispath(disguised_as, /obj/item/box/fancy/cigarettes)) + //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names + if(name == initial(name)) // allow mapped names to override it + SetName(disguised_as::name) + if(desc == initial(desc) && istext(scribble)) // ditto for mapped descs + desc = "[disguised_as::desc] '[scribble]' has been scribbled on it." // Flash Powder Pack -/obj/item/box/fancy/cigarettes/flash_powder +/obj/item/box/fancy/cigarettes/covert/flash_powder name = "pack of flash powder laced Trans-Stellar Duty-frees" + disguised_as = /obj/item/box/fancy/cigarettes + scribble = "F" -/obj/item/box/fancy/cigarettes/flash_powder/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/box/fancy/cigarettes/C = /obj/item/box/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'F' has been scribbled on it." - -/obj/item/box/fancy/cigarettes/flash_powder/populate_reagents() +/obj/item/box/fancy/cigarettes/covert/flash_powder/populate_reagents() var/max_storage_space = max(1, storage?.max_storage_space) add_to_reagents(/decl/material/solid/metal/aluminium, max_storage_space) add_to_reagents(/decl/material/solid/potassium, max_storage_space) add_to_reagents(/decl/material/solid/sulfur, max_storage_space) //Chemsmoke Pack -/obj/item/box/fancy/cigarettes/chemsmoke +/obj/item/box/fancy/cigarettes/covert/chemsmoke name = "pack of smoke powder laced Trans-Stellar Duty-frees" + scribble = "S" -/obj/item/box/fancy/cigarettes/chemsmoke/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/box/fancy/cigarettes/C = /obj/item/box/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'S' has been scribbled on it." - -/obj/item/box/fancy/cigarettes/chemsmoke/populate_reagents() +/obj/item/box/fancy/cigarettes/covert/chemsmoke/populate_reagents() var/max_storage_space = max(1, storage?.max_storage_space) add_to_reagents(/decl/material/solid/potassium, max_storage_space) add_to_reagents(/decl/material/liquid/nutriment/sugar, max_storage_space) add_to_reagents(/decl/material/solid/phosphorus, max_storage_space) //Mindbreak Pack (now called /decl/chemical_reaction/hallucinogenics) -/obj/item/box/fancy/cigarettes/mindbreak - name = "pack of mindbreak toxin laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? +/obj/item/box/fancy/cigarettes/covert/mindbreak + name = "pack of hallucinogen-laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? + scribble = "H" -/obj/item/box/fancy/cigarettes/mindbreak/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/box/fancy/cigarettes/C = /obj/item/box/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'MB' has been scribbled on it." //#TODO: maybe fix the lore for that? - -/obj/item/box/fancy/cigarettes/mindbreak/populate_reagents() - var/max_storage_space = max(1, storage?.max_storage_space) - add_to_reagents(/decl/material/solid/silicon, max_storage_space) - add_to_reagents(/decl/material/liquid/fuel/hydrazine, max_storage_space) - add_to_reagents(/decl/material/liquid/antitoxins, max_storage_space) +/obj/item/box/fancy/cigarettes/covert/mindbreak/populate_reagents() + add_to_reagents(/decl/material/liquid/hallucinogenics, (3 * max(1, storage?.max_storage_space))) -//Tricord pack (now called /decl/material/liquid/regenerator) -/obj/item/box/fancy/cigarettes/tricord - name = "pack of tricordazine laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? +//Tricord pack (now called 'regenerative serum') +/obj/item/box/fancy/cigarettes/covert/tricord + name = "pack of regenerative serum-laced Trans-Stellar Duty-frees" //#TODO: maybe fix the lore for that? + scribble = "R" -/obj/item/box/fancy/cigarettes/tricord/Initialize(ml, material_key) - . = ..() - //Reset the name to the default cig pack. Done for codex reasons, since it indexes things by initial names - var/obj/item/box/fancy/cigarettes/C = /obj/item/box/fancy/cigarettes - if(name == initial(name)) - SetName(initial(C.name)) - if(desc == initial(desc)) - desc = "[initial(desc)] 'T' has been scribbled on it." //#TODO: maybe fix the lore for that? - -/obj/item/box/fancy/cigarettes/tricord/populate_reagents() +/obj/item/box/fancy/cigarettes/covert/tricord/populate_reagents() add_to_reagents(/decl/material/liquid/regenerator, (4 * max(1, storage?.max_storage_space))) diff --git a/code/game/objects/items/weapons/storage/uplink_kits.dm b/code/game/objects/items/weapons/storage/uplink_kits.dm index 7612a6e897b0..a6eb745f50c6 100644 --- a/code/game/objects/items/weapons/storage/uplink_kits.dm +++ b/code/game/objects/items/weapons/storage/uplink_kits.dm @@ -126,10 +126,10 @@ /obj/item/box/syndie_kit/cigarette/WillContain() return list( - /obj/item/box/fancy/cigarettes/flash_powder = 2, - /obj/item/box/fancy/cigarettes/chemsmoke = 2, - /obj/item/box/fancy/cigarettes/mindbreak, - /obj/item/box/fancy/cigarettes/tricord, + /obj/item/box/fancy/cigarettes/covert/flash_powder = 2, + /obj/item/box/fancy/cigarettes/covert/chemsmoke = 2, + /obj/item/box/fancy/cigarettes/covert/mindbreak, + /obj/item/box/fancy/cigarettes/covert/tricord, /obj/item/flame/fuelled/lighter/zippo/random, ) diff --git a/maps/ministation/ministation-1.dmm b/maps/ministation/ministation-1.dmm index 34871f8e955d..272d29948511 100644 --- a/maps/ministation/ministation-1.dmm +++ b/maps/ministation/ministation-1.dmm @@ -65,7 +65,7 @@ pixel_y = 24 }, /obj/item/flashlight/lamp/green, -/obj/item/box/fancy/cigarettes/tricord, +/obj/item/box/fancy/cigarettes/covert/tricord, /turf/floor/carpet/blue, /area/ministation/medical) "at" = ( diff --git a/tools/map_migrations/9999_cigarettes.txt b/tools/map_migrations/9999_cigarettes.txt new file mode 100644 index 000000000000..875e6404ad48 --- /dev/null +++ b/tools/map_migrations/9999_cigarettes.txt @@ -0,0 +1,4 @@ +/obj/item/box/fancy/cigarettes/flash_powder : /obj/item/box/fancy/cigarettes/covert/flash_powder{@OLD} +/obj/item/box/fancy/cigarettes/chemsmoke : /obj/item/box/fancy/cigarettes/covert/flash_powder{@OLD} +/obj/item/box/fancy/cigarettes/mindbreak : /obj/item/box/fancy/cigarettes/covert/flash_powder{@OLD} +/obj/item/box/fancy/cigarettes/tricord : /obj/item/box/fancy/cigarettes/covert/flash_powder{@OLD} \ No newline at end of file From 1a153d2f032d76df4806e9e4548bbf67aacd4fef Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 20:44:55 -0400 Subject: [PATCH 334/512] Replace hardcoded lighting overlay check --- code/modules/random_map/dungeon/room_theme.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/random_map/dungeon/room_theme.dm b/code/modules/random_map/dungeon/room_theme.dm index f6ec7ffacc52..6cb36bfe73eb 100644 --- a/code/modules/random_map/dungeon/room_theme.dm +++ b/code/modules/random_map/dungeon/room_theme.dm @@ -48,9 +48,8 @@ var/turf/check = locate(T.x + i, T.y + j, T.z) if(!check) continue - for(var/atom/movable/M in check.contents) - if(!istype(M, /atom/movable/lighting_overlay) && M.density) - return 0 + if(check.contains_dense_objects()) + return FALSE if(!T) return 0 if(ispath(door_type,/obj/structure/door)) From abd37d7a5e8ef767ee0bac141bae412a4fd3db49 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 14 May 2025 20:47:25 -0400 Subject: [PATCH 335/512] Fix get_other_examine_strings being expensive due to string ops --- code/modules/mob/examine.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/examine.dm b/code/modules/mob/examine.dm index 164b4d8b96b4..d5c9f02bb7b0 100644 --- a/code/modules/mob/examine.dm +++ b/code/modules/mob/examine.dm @@ -28,7 +28,7 @@ . += SPAN_WARNING("[pronouns.He] [pronouns.is] [html_icon(buckled)] buckled to [buckled]!") /mob/proc/get_other_examine_strings(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) - return + return list() // We add a default parameter here for hidden inventory flags. /mob/get_examine_header(mob/user, distance, infix, suffix, hideflags) From 5eb82e2cbaeab97e64c536fe88b7d7a879f7655f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 19:00:41 -0400 Subject: [PATCH 336/512] Fix plated catwalk activation not propagating correctly --- code/game/objects/structures/catwalk.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/structures/catwalk.dm b/code/game/objects/structures/catwalk.dm index 2f7767565607..a420e4bced9a 100644 --- a/code/game/objects/structures/catwalk.dm +++ b/code/game/objects/structures/catwalk.dm @@ -206,7 +206,7 @@ C.update_icon() activated = 1 for(var/turf/T in orange(src, 1)) - for(var/obj/effect/wallframe_spawn/other in T) + for(var/obj/effect/catwalk_plated/other in T) if(!other.activated) other.activate() /obj/effect/catwalk_plated/dark From acb56c5e96f4c33e8fa67c2dc948cf81018ae51c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 20:41:33 -0400 Subject: [PATCH 337/512] Make chameleon disguise verbs use a define to avoid code duplication --- .../objects/items/weapons/storage/backpack.dm | 4 + code/modules/clothing/chameleon.dm | 258 +++++------------- 2 files changed, 71 insertions(+), 191 deletions(-) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 3ba1614419cd..2b3e166a2d24 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -13,6 +13,10 @@ storage = /datum/storage/backpack material = /decl/material/solid/organic/leather/synth +/obj/item/backpack/get_associated_equipment_slots() + . = ..() + LAZYDISTINCTADD(., slot_back_str) + //Cannot be washed :( /obj/item/backpack/can_contaminate() return FALSE diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm index 39ea1c743a97..50adae6297ca 100644 --- a/code/modules/clothing/chameleon.dm +++ b/code/modules/clothing/chameleon.dm @@ -2,7 +2,19 @@ //**Cham Jumpsuit** //***************** +#define CHAMELEON_VERB(TYPE, VERB_NAME)\ +##TYPE/verb/change(picked in disguise_choices){ \ + set name = VERB_NAME; \ + set category = "Chameleon Items"; \ + set src in usr; \ + if(usr.incapacitated()) return; \ + if(!ispath(disguise_choices[picked])) return; \ + disguise(disguise_choices[picked], usr); \ + update_clothing_icon(); \ +} + /obj/item/proc/disguise(var/newtype, var/mob/user) + SHOULD_NOT_OVERRIDE(TRUE) if(user && CanPhysicallyInteract(user)) return OnDisguise(atom_info_repository.get_instance_of(newtype), user) return FALSE @@ -20,7 +32,7 @@ body_parts_covered = copy.body_parts_covered sprite_sheets = copy.sprite_sheets?.Copy() flags_inv = copy.flags_inv - set_gender(copy.gender) + set_gender(copy.gender) // mostly for plural/neuter, e.g. "some prayer beads" versus "a necklace" /proc/generate_chameleon_choices(var/basetype) . = list() @@ -44,26 +56,18 @@ icon = 'icons/clothing/pants/slacks.dmi' origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/pants/chameleon/Initialize() . = ..() - if(!clothing_choices) + if(!disguise_choices) var/static/list/clothing_types = list( /obj/item/clothing/pants, /obj/item/clothing/skirt ) - clothing_choices = generate_chameleon_choices(clothing_types) - -/obj/item/clothing/pants/chameleon/verb/change(picked in clothing_choices) - set name = "Change Pants Appearance" - set category = "Chameleon Items" - set src in usr - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - disguise(clothing_choices[picked], usr) - update_clothing_icon() + disguise_choices = generate_chameleon_choices(clothing_types) + +CHAMELEON_VERB(/obj/item/clothing/pants/chameleon, "Change Pants Appearance") /obj/item/clothing/shirt/chameleon name = "dress shirt" @@ -71,25 +75,17 @@ icon = 'icons/clothing/shirts/button_up.dmi' origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/shirt/chameleon/Initialize() . = ..() - if(!clothing_choices) + if(!disguise_choices) var/static/list/clothing_types = list( /obj/item/clothing/shirt ) - clothing_choices = generate_chameleon_choices(clothing_types) - -/obj/item/clothing/shirt/chameleon/verb/change(picked in clothing_choices) - set name = "Change Shirt Appearance" - set category = "Chameleon Items" - set src in usr - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - disguise(clothing_choices[picked], usr) - update_clothing_icon() + disguise_choices = generate_chameleon_choices(clothing_types) + +CHAMELEON_VERB(/obj/item/clothing/shirt/chameleon, "Change Shirt Appearance") //starts off as a jumpsuit /obj/item/clothing/jumpsuit/chameleon @@ -99,29 +95,19 @@ origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON bodytype_equip_flags = null - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/jumpsuit/chameleon/Initialize() . = ..() - if(!clothing_choices) + if(!disguise_choices) var/static/list/clothing_types = list( /obj/item/clothing/jumpsuit, /obj/item/clothing/dress, /obj/item/clothing/costume ) - clothing_choices = generate_chameleon_choices(clothing_types) - -/obj/item/clothing/jumpsuit/chameleon/verb/change(picked in clothing_choices) - set name = "Change Jumpsuit Appearance" - set category = "Chameleon Items" - set src in usr + disguise_choices = generate_chameleon_choices(clothing_types) - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/jumpsuit/chameleon, "Change Jumpsuit Appearance") //***************** //**Chameleon Hat** @@ -135,24 +121,14 @@ body_parts_covered = 0 item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON bodytype_equip_flags = null - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/head/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/clothing/head) - -/obj/item/clothing/head/chameleon/verb/change(picked in clothing_choices) - set name = "Change Hat/Helmet Appearance" - set category = "Chameleon Items" - set src in usr - - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/clothing/head) - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/head/chameleon, "Change Hat/Helmet Appearance") //****************** //**Chameleon Suit** @@ -165,24 +141,14 @@ origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON bodytype_equip_flags = null - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/suit/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/clothing/suit) + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/clothing/suit) -/obj/item/clothing/suit/chameleon/verb/change(picked in clothing_choices) - set name = "Change Oversuit Appearance" - set category = "Chameleon Items" - set src in usr - - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/suit/chameleon, "Change Oversuit Appearance") //******************* //**Chameleon Shoes** @@ -194,24 +160,14 @@ origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON bodytype_equip_flags = null - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/shoes/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/clothing/shoes) - -/obj/item/clothing/shoes/chameleon/verb/change(picked in clothing_choices) - set name = "Change Footwear Appearance" - set category = "Chameleon Items" - set src in usr + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/clothing/shoes) - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/shoes/chameleon, "Change Footwear Appearance") //********************** //**Chameleon Backpack** @@ -222,28 +178,14 @@ origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON icon = 'icons/obj/items/storage/backpack/backpack.dmi' - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/backpack/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/backpack) - -/obj/item/backpack/chameleon/verb/change(picked in clothing_choices) - set name = "Change Backpack Appearance" - set category = "Chameleon Items" - set src in usr - - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/backpack) - disguise(clothing_choices[picked], usr) - - //so our overlays update. - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_equipment_overlay(slot_back_str) +CHAMELEON_VERB(/obj/item/backpack/chameleon, "Change Backpack Appearance") //******************** //**Chameleon Gloves** @@ -258,24 +200,14 @@ origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON bodytype_equip_flags = null - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/gloves/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/clothing/gloves) - -/obj/item/clothing/gloves/chameleon/verb/change(picked in clothing_choices) - set name = "Change Gloves Appearance" - set category = "Chameleon Items" - set src in usr + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/clothing/gloves) - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/gloves/chameleon, "Change Gloves Appearance") //****************** //**Chameleon Mask** @@ -288,24 +220,14 @@ origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON bodytype_equip_flags = null - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/mask/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/clothing/mask) - -/obj/item/clothing/mask/chameleon/verb/change(picked in clothing_choices) - set name = "Change Mask Appearance" - set category = "Chameleon Items" - set src in usr + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/clothing/mask) - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/mask/chameleon, "Change Mask Appearance") //********************* //**Chameleon Glasses** @@ -318,24 +240,14 @@ origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON bodytype_equip_flags = null - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/clothing/glasses/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/clothing/glasses) - -/obj/item/clothing/glasses/chameleon/verb/change(picked in clothing_choices) - set name = "Change Glasses Appearance" - set category = "Chameleon Items" - set src in usr - - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/clothing/glasses) - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/glasses/chameleon, "Change Glasses Appearance") //********************* //**Chameleon Headset** @@ -347,27 +259,14 @@ desc = "An updated, modular intercom that fits over the head. This one seems to have a small dial on it." origin_tech = @'{"esoteric":3}' item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON - var/static/list/clothing_choices + var/static/list/disguise_choices /obj/item/radio/headset/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(/obj/item/radio/headset) + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/radio/headset) -/obj/item/radio/headset/chameleon/verb/change(picked in clothing_choices) - set name = "Change Headset Appearance" - set category = "Chameleon Items" - set src in usr - - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - - disguise(clothing_choices[picked], usr) - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_equipment_overlay(slot_l_ear_str, FALSE) - M.update_equipment_overlay(slot_r_ear_str) +CHAMELEON_VERB(/obj/item/radio/headset/chameleon, "Change Headset Appearance") //*********************** //**Chameleon Accessory** @@ -381,7 +280,7 @@ item_flags = ITEM_FLAG_INVALID_FOR_CHAMELEON w_class = ITEM_SIZE_SMALL fallback_slot = slot_wear_mask_str - var/static/list/clothing_choices + var/static/list/disguise_choices var/static/list/decor_types = list( /obj/item/clothing/neck, /obj/item/clothing/badge, @@ -394,19 +293,10 @@ /obj/item/clothing/chameleon/Initialize() . = ..() - if(!clothing_choices) - clothing_choices = generate_chameleon_choices(get_non_abstract_types(decor_types)) - -/obj/item/clothing/chameleon/verb/change(picked in clothing_choices) - set name = "Change Accessory Appearance" - set category = "Chameleon Items" - set src in usr + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(get_non_abstract_types(decor_types)) - if (!(usr.incapacitated())) - if(!ispath(clothing_choices[picked])) - return - disguise(clothing_choices[picked], usr) - update_clothing_icon() //so our overlays update. +CHAMELEON_VERB(/obj/item/clothing/chameleon, "Change Accessory Appearance") //***************** //**Chameleon Gun** @@ -428,12 +318,12 @@ max_shots = 50 var/obj/item/projectile/copy_projectile - var/static/list/gun_choices + var/static/list/disguise_choices /obj/item/gun/energy/chameleon/Initialize() . = ..() - if(!gun_choices) - gun_choices = generate_chameleon_choices(/obj/item/gun) + if(!disguise_choices) + disguise_choices = generate_chameleon_choices(/obj/item/gun) /obj/item/gun/energy/chameleon/consume_next_projectile() var/obj/item/projectile/P = ..() @@ -466,18 +356,4 @@ copy_projectile = null //charge_meter = 0 -/obj/item/gun/energy/chameleon/verb/change(picked in gun_choices) - set name = "Change Gun Appearance" - set category = "Chameleon Items" - set src in usr - - if (!(usr.incapacitated())) - if(!ispath(gun_choices[picked])) - return - - disguise(gun_choices[picked], usr) - - //so our overlays update. - if (ismob(src.loc)) - var/mob/M = src.loc - M.update_inhand_overlays() \ No newline at end of file +CHAMELEON_VERB(/obj/item/gun/energy/chameleon, "Change Gun Appearance") \ No newline at end of file From feff427b3e4903572370e33bcdfa6b9f213048fe Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 14 May 2025 23:53:39 -0400 Subject: [PATCH 338/512] Split human get_other_examine_strings() into separate handlers --- code/__defines/mobs.dm | 3 + code/_helpers/cmp.dm | 3 + code/_macros.dm | 1 + code/game/objects/structures/fountain.dm | 16 + code/modules/mob/examine.dm | 7 +- code/modules/mob/living/human/examine.dm | 395 ++++++++++-------- .../mob/living/human/human_attackhand.dm | 1 + .../modules/mob/living/human/human_defines.dm | 3 - .../mob/living/human/human_examine_decl.dm | 7 +- .../pronouns/pronouns_second_person.dm | 13 + mods/content/matchmaking/matchmaker.dm | 7 +- nebula.dme | 1 + 12 files changed, 274 insertions(+), 183 deletions(-) create mode 100644 code/modules/pronouns/pronouns_second_person.dm diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index c05a1c545c0a..e95fac6faa6e 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -346,7 +346,10 @@ var/global/list/dexterity_levels = list( #define MOB_ICON_HAS_GIB_STATE BITFLAG(5) #define MOB_ICON_HAS_DUST_STATE BITFLAG(6) #define MOB_ICON_HAS_PARALYZED_STATE BITFLAG(7) + +// Additional pronoun sets. #define NEUTER_ANIMATE "animate singular neutral" +#define SECOND_PERSON_SINGULAR "second person singular" // Equipment Overlays Indices // #define HO_CONDITION_LAYER 1 diff --git a/code/_helpers/cmp.dm b/code/_helpers/cmp.dm index 902bc95518be..70bb6dc061fa 100644 --- a/code/_helpers/cmp.dm +++ b/code/_helpers/cmp.dm @@ -86,6 +86,9 @@ /proc/cmp_fusion_reaction_des(var/decl/fusion_reaction/A, var/decl/fusion_reaction/B) return B.priority - A.priority +/proc/cmp_human_examine_priority(decl/human_examination/a, decl/human_examination/b) + return a.priority - b.priority + /proc/cmp_program(var/datum/computer_file/program/A, var/datum/computer_file/program/B) return cmp_text_asc(A.filedesc, B.filedesc) diff --git a/code/_macros.dm b/code/_macros.dm index fba1b139fae3..62f7629af378 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -174,6 +174,7 @@ #define SPAN_PALEPINK(X) SPAN_CLASS("font_palepink", X) #define SPAN_SINISTER(X) SPAN_CLASS("sinister", X) #define SPAN_MODERATE(X) SPAN_CLASS("moderate", X) +#define SPAN_DEADSAY(X) SPAN_CLASS("deadsay", X) // placeholders #define SPAN_GOOD(X) SPAN_GREEN(X) #define SPAN_NEUTRAL(X) SPAN_BLUE(X) diff --git a/code/game/objects/structures/fountain.dm b/code/game/objects/structures/fountain.dm index c92c9d360b1f..f596d169c6e0 100644 --- a/code/game/objects/structures/fountain.dm +++ b/code/game/objects/structures/fountain.dm @@ -85,6 +85,22 @@ used = TRUE desc = "The water flows beautifully from the spout, but the water in the pool does not ripple." +/mob/living/human + /// Used by the Fountain of Youth point of interest for on-examine messages. + var/became_older + /// Used by the Fountain of Youth point of interest for on-examine messages. + var/became_younger + +/decl/human_examination/fountain + priority = /decl/human_examination/graffiti::priority + 0.5 // just squeeze it in there + +/decl/human_examination/fountain/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + . = list() + if(source.became_younger) + . += "[pronouns.He] look[pronouns.s] a lot younger than you remember." + if(source.became_older) + . += "[pronouns.He] look[pronouns.s] a lot older than you remember." + /obj/structure/fountain/mundane name = "fountain" desc = "A beautifully constructed fountain." diff --git a/code/modules/mob/examine.dm b/code/modules/mob/examine.dm index 164b4d8b96b4..e501bd418632 100644 --- a/code/modules/mob/examine.dm +++ b/code/modules/mob/examine.dm @@ -4,6 +4,11 @@ return GET_DECL(/decl/pronouns) return get_pronouns() +/mob/proc/get_visible_pronouns_for_viewer(mob/viewer, hideflags) + if(viewer == src) + return GET_DECL(/decl/pronouns/self) + return get_visible_pronouns(hideflags) + /mob/proc/get_equipment_visibility() . = 0 for(var/obj/item/thing in get_equipped_items(include_carried = FALSE)) @@ -46,7 +51,7 @@ hideflags |= HIDEEARS // Show our equipment, held items, desc, etc. - var/decl/pronouns/pronouns = get_visible_pronouns(hideflags) + var/decl/pronouns/pronouns = get_visible_pronouns_for_viewer(user, hideflags) // handles second-person if src == user var/list/examine_items = get_examined_worn_held_items(user, distance, infix, suffix, hideflags, pronouns) if(length(examine_items)) . += examine_items diff --git a/code/modules/mob/living/human/examine.dm b/code/modules/mob/living/human/examine.dm index da4bb651a8d5..d33940b0c301 100644 --- a/code/modules/mob/living/human/examine.dm +++ b/code/modules/mob/living/human/examine.dm @@ -1,158 +1,166 @@ /mob/living/human/get_examine_header(mob/user, distance, infix, suffix, hideflags) SHOULD_CALL_PARENT(FALSE) - . = list("*---------*
    [user == src ? "You are" : "This is"] [name]") + . = list(SPAN_INFO("*---------*")) + var/list/mob_intro = "[user == src ? "You are" : "This is"] [name]" if(!(hideflags & HIDEJUMPSUIT) || !(hideflags & HIDEFACE)) var/species_name = "\improper " if(isSynthetic() && species.cyborg_noun) species_name += "[species.cyborg_noun] [species.name]" else species_name += "[species.name]" - . += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user))) ? SPAN_NOTICE(" \[?\]") : ""]" + mob_intro += ", \a [species_name]![(user.can_use_codex() && SScodex.get_codex_entry(get_codex_value(user))) ? SPAN_NOTICE(" \[?\]") : ""]" + . += SPAN_INFO(JOINTEXT(mob_intro)) var/extra_species_text = species.get_additional_examine_text(src) if(extra_species_text) - . += "
    [extra_species_text]" + . += "[extra_species_text]" var/show_descs = show_descriptors_to(user) if(show_descs) - . += "
    [jointext(show_descs, "
    ")]
    " + . += SPAN_INFO(jointext(show_descs, "
    ")) var/print_flavour = print_flavor_text() if(print_flavour) - . += "
    *---------*" - . += "
    [print_flavour]" - . += "
    *---------*" - . = list(jointext(., null)) + . += SPAN_INFO("*---------*") + . += SPAN_INFO("[print_flavour]") + . += SPAN_INFO("*---------*") + . = list(jointext(., "
    ")) + +/decl/human_examination/jitters/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + var/jitteriness = GET_STATUS(source, STAT_JITTER) + switch(jitteriness) + if(300 to INFINITY) + return SPAN_DANGER("[pronouns.He] [pronouns.is] convulsing violently!") + if(200 to 300) + return SPAN_WARNING("[pronouns.He] [pronouns.is] extremely jittery.") + if(100 to 200) + return SPAN_WARNING("[pronouns.He] [pronouns.is] twitching ever so slightly.") + else + pass() -/mob/living/human/get_other_examine_strings(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) +/decl/human_examination/disfigured + priority = /decl/human_examination/jitters::priority + 1 - . = ..() +/decl/human_examination/disfigured/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + //Disfigured face + if(hideflags & HIDEFACE) //Disfigurement only matters for the head currently. + return + var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(source, BP_HEAD) + if(!limb || !(limb.status & ORGAN_DISFIGURED)) //Check to see if we even have a head and if the head's disfigured. + return + if(limb.species) //Check to make sure we have a species + return limb.species.disfigure_msg(source) + else //Just in case they lack a species for whatever reason. + return SPAN_WARNING("[pronouns.His] face is horribly mangled!") - var/self_examine = (user == src) - var/use_He = self_examine ? "You" : pronouns.He - var/use_he = self_examine ? "you" : pronouns.he - var/use_His = self_examine ? "Your" : pronouns.His - var/use_his = self_examine ? "your" : pronouns.his - var/use_is = self_examine ? "are" : pronouns.is - var/use_does = self_examine ? "do" : pronouns.does - var/use_has = self_examine ? "have" : pronouns.has - var/use_him = self_examine ? "you" : pronouns.him - var/use_looks = self_examine ? "look" : "looks" - - //Jitters - var/jitteriness = GET_STATUS(src, STAT_JITTER) - if(jitteriness >= 300) - . += "[use_He] [use_is] convulsing violently!" - else if(jitteriness >= 200) - . += "[use_He] [use_is] extremely jittery." - else if(jitteriness >= 100) - . += "[use_He] [use_is] twitching ever so slightly." +/decl/human_examination/stat + priority = /decl/human_examination/disfigured::priority + 1 - //Disfigured face - if(!(hideflags & HIDEFACE)) //Disfigurement only matters for the head currently. - var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(src, BP_HEAD) - if(limb && (limb.status & ORGAN_DISFIGURED)) //Check to see if we even have a head and if the head's disfigured. - if(limb.species) //Check to make sure we have a species - . += limb.species.disfigure_msg(src) - else //Just in case they lack a species for whatever reason. - . += "[use_His] face is horribly mangled!" - - //splints - for(var/organ in list(BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM)) - var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(src, organ) - if(limb && limb.splinted && limb.splinted.loc == limb) - . += "[use_He] [use_has] \a [limb.splinted] on [use_his] [limb.name]!" - - if (stat) - . += "[use_He] [use_is]n't responding to anything around [use_him] and seems to be unconscious." - if((stat == DEAD || is_asystole() || suffocation_counter) && distance <= 3) - . += "[use_He] [use_does] not appear to be breathing." - - var/datum/reagents/touching_reagents = get_contact_reagents() +/decl/human_examination/stat/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + if (source.stat) + . = list(SPAN_WARNING("[pronouns.He] [pronouns.is]n't responding to anything around [pronouns.him] and seems to be unconscious.")) + if((source.stat == DEAD || source.is_asystole() || source.suffocation_counter) && distance <= 3) + . += SPAN_WARNING("[pronouns.He] [pronouns.does] not appear to be breathing.") + +/decl/human_examination/contact_reagents + priority = /decl/human_examination/stat::priority + 1 + +/decl/human_examination/contact_reagents/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + var/datum/reagents/touching_reagents = source.get_contact_reagents() if(touching_reagents?.total_volume >= 1) var/saturation = touching_reagents.total_volume / touching_reagents.maximum_volume if(saturation > 0.9) - . += "[use_He] [use_is] completely saturated." + . += "[pronouns.He] [pronouns.is] completely saturated." else if(saturation > 0.6) - . += "[use_He] [use_is] looking half-drowned." + . += "[pronouns.He] [pronouns.is] looking half-drowned." else if(saturation > 0.3) - . += "[use_He] [use_is] looking notably soggy." + . += "[pronouns.He] [pronouns.is] looking notably soggy." else - . += "[use_He] [use_is] looking a bit soggy." + . += "[pronouns.He] [pronouns.is] looking a bit soggy." + +/decl/human_examination/fire + priority = /decl/human_examination/contact_reagents::priority + 1 - var/fire_level = get_fire_intensity() +/decl/human_examination/fire/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + . = list() + var/fire_level = source.get_fire_intensity() if(fire_level > 0) - . += "[use_He] [use_is] looking highly flammable!" + . += "[pronouns.He] [pronouns.is] looking highly flammable!" else if(fire_level < 0) - . += "[use_He] [use_is] looking rather incombustible." + . += "[pronouns.He] [pronouns.is] looking rather incombustible." - if(is_on_fire()) - . += "[use_He] [use_is] on fire!" + if(source.is_on_fire()) + . += SPAN_WARNING("[pronouns.He] [pronouns.is] on fire!") - var/ssd_msg = species.get_ssd(src) - if(ssd_msg && (!should_have_organ(BP_BRAIN) || has_brain()) && stat != DEAD) - if(!key) - . += "[use_He] [use_is] [ssd_msg]. It doesn't look like [use_he] [use_is] waking up anytime soon." - else if(!client) - . += "[use_He] [use_is] [ssd_msg]." +/decl/human_examination/ssd + priority = /decl/human_examination/fire::priority + 1 - var/obj/item/organ/external/head/H = get_organ(BP_HEAD, /obj/item/organ/external/head) +/decl/human_examination/ssd/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + var/ssd_msg = source.species.get_ssd(source) + if(ssd_msg && (!source.should_have_organ(BP_BRAIN) || source.has_brain()) && source.stat != DEAD) + if(!source.key) + . += SPAN_DEADSAY("[pronouns.He] [pronouns.is] [ssd_msg]. It doesn't look like [pronouns.he] [pronouns.is] waking up anytime soon.") + else if(!source.client) + . += SPAN_DEADSAY("[pronouns.He] [pronouns.is] [ssd_msg].") + +// TODO: generalize and fold this into limb examine +/decl/human_examination/graffiti + priority = /decl/human_examination/ssd::priority + 1 + +/decl/human_examination/graffiti/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + var/obj/item/organ/external/head/H = source.get_organ(BP_HEAD, /obj/item/organ/external/head) if(istype(H) && H.forehead_graffiti && H.graffiti_style) - . += "[use_He] [use_has] \"[H.forehead_graffiti]\" written on [use_his] [H.name] in [H.graffiti_style]!" + . += SPAN_NOTICE("[pronouns.He] [pronouns.has] \"[H.forehead_graffiti]\" written on [pronouns.his] [H.name] in [H.graffiti_style]!") - if(became_younger) - . += "[use_He] [use_looks] a lot younger than you remember." - if(became_older) - . += "[use_He] [use_looks] a lot older than you remember." +/decl/human_examination/limb_examine + priority = /decl/human_examination/graffiti::priority + 1 +// This is still kind of a mess. TODO: /decl/organ_examination? lol +/decl/human_examination/limb_examine/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + . = list() var/list/wound_flavor_text = list() var/applying_pressure = "" var/list/shown_objects = list() var/list/hidden_bleeders = list() - var/decl/bodytype/root_bodytype = get_bodytype() + var/decl/bodytype/root_bodytype = source.get_bodytype() for(var/organ_tag in root_bodytype.has_limbs) - var/list/organ_data = root_bodytype.has_limbs[organ_tag] - var/organ_descriptor = organ_data["descriptor"] - var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(src, organ_tag) + var/obj/item/organ/external/limb = GET_EXTERNAL_ORGAN(source, organ_tag) if(!limb) - wound_flavor_text[organ_descriptor] = "[use_He] [use_is] missing [use_his] [organ_descriptor]." + wound_flavor_text[organ_tag] = list(SPAN_DANGER("[pronouns.He] [pronouns.is] missing [pronouns.his] [organ_data["descriptor"]].")) continue - wound_flavor_text[limb.name] = "" + wound_flavor_text[limb.organ_tag] = list() - if(limb.applied_pressure == src) - applying_pressure = "[use_He] [use_is] applying pressure to [use_his] [limb.name]." + if(limb.applied_pressure == source) + applying_pressure = SPAN_INFO("[pronouns.He] [pronouns.is] applying pressure to [pronouns.his] [limb.name].") - var/obj/item/clothing/hidden - for(var/slot in global.standard_clothing_slots) - var/obj/item/clothing/C = get_equipped_item(slot) - if(istype(C) && (C.body_parts_covered & limb.body_part)) - hidden = C - break + var/obj/item/clothing/hidden = source.get_covering_equipped_item(limb.body_part) - if(hidden && user != src) + if(hidden && user != source) if(limb.status & ORGAN_BLEEDING && !(hidden.item_flags & ITEM_FLAG_THICKMATERIAL)) //not through a spacesuit if(!hidden_bleeders[hidden]) hidden_bleeders[hidden] = list() - hidden_bleeders[hidden] += limb.name + hidden_bleeders[hidden] += limb.organ_tag else - if(!isSynthetic() && BP_IS_PROSTHETIC(limb) && (limb.parent && !BP_IS_PROSTHETIC(limb.parent))) - wound_flavor_text[limb.name] = "[use_He] [use_has] a [limb.name].\n" + // TODO: Make this just report if the bodytype is different than root and parent? + // That way a robotic right arm would show up but the hand attached to it wouldn't. + if(!source.isSynthetic() && BP_IS_PROSTHETIC(limb) && (limb.parent && !BP_IS_PROSTHETIC(limb.parent))) + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.He] [pronouns.has] a [limb.name].") var/wounddesc = limb.get_wounds_desc() if(wounddesc != "nothing") - wound_flavor_text[limb.name] += "[use_He] [use_has] [wounddesc] on [use_his] [limb.name]." + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.He] [pronouns.has] [wounddesc] on [pronouns.his] [limb.name].") if(!hidden || distance <=1) if(limb.is_dislocated()) - wound_flavor_text[limb.name] += "[use_His] [limb.joint] is dislocated!
    " + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.His] [limb.joint] is dislocated!") if(((limb.status & ORGAN_BROKEN) && limb.brute_dam > limb.min_broken_damage) || (limb.status & ORGAN_MUTATED)) - wound_flavor_text[limb.name] += "[use_His] [limb.name] is dented and swollen!
    " + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.His] [limb.name] is dented and swollen!") if(limb.status & ORGAN_DEAD) if(BP_IS_PROSTHETIC(limb) || BP_IS_CRYSTAL(limb)) - wound_flavor_text[limb.name] += "[use_His] [limb.name] is irrecoverably damaged!" + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.His] [limb.name] is irrecoverably damaged!") else - wound_flavor_text[limb.name] += "[use_His] [limb.name] is grey and necrotic!
    " + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.His] [limb.name] is grey and necrotic!") else if((limb.brute_dam + limb.burn_dam) >= limb.max_damage && limb.germ_level >= INFECTION_LEVEL_TWO) - wound_flavor_text[limb.name] += "[use_His] [limb.name] is likely beyond saving, and has begun to decay!" + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.His] [limb.name] is likely beyond saving, and has begun to decay!") for(var/datum/wound/wound in limb.wounds) var/list/embedlist = wound.embedded_objects @@ -165,105 +173,138 @@ else if(!parsedembed.Find("multiple [embedded.name]")) parsedembed.Remove(embedded.name) parsedembed.Add("multiple "+embedded.name) - wound_flavor_text["[limb.name]"] += "The [wound.desc] on [use_his] [limb.name] has \a [english_list(parsedembed, and_text = " and a ", comma_text = ", a ")] sticking out of it!" + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("The [wound.desc] on [pronouns.his] [limb.name] has \a [english_list(parsedembed, and_text = " and a ", comma_text = ", a ")] sticking out of it!") + + if(limb.splinted && limb.splinted.loc == limb) + wound_flavor_text[limb.organ_tag] += SPAN_WARNING("[pronouns.He] [pronouns.has] \a [limb.splinted] on [pronouns.his] [limb.name]!") + for(var/hidden in hidden_bleeders) - wound_flavor_text[hidden] = "[use_He] [use_has] blood soaking through [hidden] around [use_his] [english_list(hidden_bleeders[hidden])]!" + wound_flavor_text[hidden] = SPAN_WARNING("[pronouns.He] [pronouns.has] blood soaking through [hidden] around [pronouns.his] [english_list(hidden_bleeders[hidden])]!") - . += "" - for(var/limb in wound_flavor_text) - . += wound_flavor_text[limb] - . += "" + for(var/section in wound_flavor_text) // originally named limb, but can also include clothes + if(length(wound_flavor_text[section])) + . += jointext(wound_flavor_text[section], "
    ") - for(var/obj/implant in get_visible_implants(0)) + if(applying_pressure) + . += applying_pressure + + // TODO: move this into the limb for loop? + for(var/obj/implant in source.get_visible_implants(0)) if(implant in shown_objects) continue - . += "[src] [use_has] \a [implant.name] sticking out of [use_his] flesh!" - if(digitalcamo) - . += "[use_He] [use_is] repulsively uncanny!" + . += SPAN_DANGER("[source] [pronouns.has] \a [implant.name] sticking out of [pronouns.his] flesh!") - if(hasHUD(user, HUD_SECURITY)) - var/perpname = "wot" - var/criminal = "None" +/decl/human_examination/digicamo + priority = /decl/human_examination/limb_examine::priority + 1 - var/obj/item/card/id/check_id = GetIdCard() - if(istype(check_id)) - perpname = check_id.registered_name - else - perpname = src.name +/decl/human_examination/digicamo/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + if(source.digitalcamo) + return SPAN_WARNING("[pronouns.He] [pronouns.is] repulsively uncanny!") - if(perpname) - var/datum/computer_network/network = user.getHUDnetwork(HUD_SECURITY) - if(network) - var/datum/computer_file/report/crew_record/R = network.get_crew_record_by_name(perpname) - if(R) - criminal = R.get_criminalStatus() +/decl/human_examination/hud + priority = /decl/human_examination/digicamo::priority + 1 - . += "Criminal status: \[[criminal]\]" - . += "Security records: \[View\]" - - if(hasHUD(user, HUD_MEDICAL)) - var/perpname = "wot" - var/medical = "None" +/decl/human_examination/hud/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + var/perpname = source.get_authentification_name(source.get_face_name()) + if(!perpname) + return - var/obj/item/card/id/check_id = GetIdCard() - if(istype(check_id)) - perpname = check_id.registered_name - else - perpname = src.name + if(hasHUD(user, HUD_SECURITY)) + var/datum/computer_network/network = user.getHUDnetwork(HUD_SECURITY) + if(network) + var/datum/computer_file/report/crew_record/R = network.get_crew_record_by_name(perpname) + LAZYINITLIST(.) + . += "Criminal status: \[[R?.get_criminalStatus() || "None"]\]" + . += "Security records: \[View\]" + if(hasHUD(user, HUD_MEDICAL)) var/datum/computer_network/network = user.getHUDnetwork(HUD_MEDICAL) if(network) var/datum/computer_file/report/crew_record/R = network.get_crew_record_by_name(perpname) - if(R) - medical = R.get_status() + LAZYINITLIST(.) + . += "Physical status: \[[R?.get_status() || "None"]\]" + . += "Medical records: \[View\]" - . += "Physical status: \[[medical]\]" - . += "Medical records: \[View\]" +/decl/human_examination/pose + priority = /decl/human_examination/hud::priority + 1 + section_prefix = "*---------*" +/decl/human_examination/pose/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) + if (!source.pose) + return + var/treated_pose = trim(source.handle_autopunctuation(source.pose)) + // if the pose starts with is, are, do, does, or doesn't, apply basic verb correction + if(starts_with(treated_pose, "is ")) // if the pose starts with is + treated_pose = "[pronouns.is] [copytext(treated_pose, 1, 4)]" + if(starts_with(treated_pose, "are ")) // if the pose starts with are + treated_pose = "[pronouns.is] [copytext(treated_pose, 1, 5)]" + else if(starts_with(treated_pose, "does ")) + treated_pose = "[pronouns.does] [copytext(treated_pose, 1, 6)]" + else if(starts_with(treated_pose, "do ")) + treated_pose = "[pronouns.does] [copytext(treated_pose, 1, 4)]" + else if(starts_with(treated_pose, "doesn't ")) + treated_pose = "[pronouns.does]n't [copytext(treated_pose, 1, 9)]" + else if(starts_with(treated_pose, "don't ")) + treated_pose = "[pronouns.does]n't [copytext(treated_pose, 1, 7)]" + return "[pronouns.He] [source.handle_autopunctuation(source.pose)]" + +/decl/human_examination/comments + priority = /decl/human_examination/pose::priority + 99 // OOC info should show up pretty late. + section_prefix = "*---------*" + section_postfix = "*---------*" // this only applies if there is something after it + +/decl/human_examination/comments/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) // Show IC/OOC info if available. - if(comments_record_id) - var/datum/character_information/comments = SScharacter_info.get_record(comments_record_id) - if(comments?.show_info_on_examine && (comments.ic_info || comments.ooc_info)) - . += "*---------*" - if(comments.ic_info) - if(length(comments.ic_info) <= 40) - . += "IC Info:" - . += "    [comments.ic_info]" - else - . += "IC Info:" - . += "    [copytext_preserve_html(comments.ic_info,1,37)]... More..." - if(comments.ooc_info) - if(length(comments.ooc_info) <= 40) - . += "OOC Info:" - . += "    [comments.ooc_info]" - else - . += "OOC Info:" - . += "    [copytext_preserve_html(comments.ooc_info,1,37)]... More..." - - . += "*---------*
    " - . += applying_pressure - - if (pose) - if( findtext(pose,".",length(pose)) == 0 && findtext(pose,"!",length(pose)) == 0 && findtext(pose,"?",length(pose)) == 0 ) - pose = addtext(pose,".") //Makes sure all emotes end with a period. - . += "[use_He] [pose]" - - var/list/human_examines = decls_repository.get_decls_of_subtype(/decl/human_examination) - for(var/exam in human_examines) - var/decl/human_examination/examiner = human_examines[exam] - var/adding_text = examiner.do_examine(user, distance, src) - if(adding_text) - . += adding_text - - // Foul, todo fix this - if(stat && ishuman(user) && !user.incapacitated() && Adjacent(user)) - spawn(0) - user.visible_message("\The [user] checks \the [src]'s pulse.", "You check \the [src]'s pulse.") - if(do_after(user, 15, src)) - if(get_pulse() == PULSE_NONE) - to_chat(user, "[use_He] [use_has] no pulse.") - else - to_chat(user, "[use_He] [use_has] a pulse!") + if(!source.comments_record_id) + return + var/datum/character_information/comments = SScharacter_info.get_record(source.comments_record_id) + if(comments?.show_info_on_examine && (comments.ic_info || comments.ooc_info)) + if(comments.ic_info) + if(length(comments.ic_info) <= 40) + . += "IC Info:" + . += "    [comments.ic_info]" + else + . += "IC Info:" + . += "    [copytext_preserve_html(comments.ic_info,1,37)]... More..." + if(comments.ooc_info) + if(length(comments.ooc_info) <= 40) + . += "OOC Info:" + . += "    [comments.ooc_info]" + else + . += "OOC Info:" + . += "    [copytext_preserve_html(comments.ooc_info,1,37)]... More..." + +/mob/living/human/get_other_examine_strings(mob/user, distance, infix, suffix, hideflags, decl/pronouns/pronouns) + . = ..() + var/static/list/priority_examine_decls = sortTim(decls_repository.get_decls_of_subtype_unassociated(/decl/human_examination), /proc/cmp_human_examine_priority) + var/last_divider = null + for(var/decl/human_examination/examiner in priority_examine_decls) + var/adding_text = examiner.do_examine(user, distance, src, hideflags, pronouns) + if(!LAZYLEN(adding_text)) + continue + if(last_divider) // insert the divider from the last entry + . += last_divider + else if(length(.)) // we already have prior entries, insert our prefix + . += examiner.section_prefix + . += adding_text + last_divider = examiner.section_postfix + +/mob/living/human/examined_by(mob/user, distance, infix, suffix) + . = ..() + if(!stat || !ishuman(user) || user.incapacitated() || !Adjacent(user)) + return + INVOKE_ASYNC(src, PROC_REF(check_heartbeat), user) + +/mob/living/human/proc/check_heartbeat(mob/living/human/user) + if(!stat || !ishuman(user) || user.incapacitated() || !Adjacent(user)) + return + user.visible_message("\The [user] checks \the [src]'s pulse.", "You check \the [src]'s pulse.") + if(do_after(user, 1.5 SECONDS, src)) + var/decl/pronouns/seen_pronouns = get_pronouns() + if(get_pulse() == PULSE_NONE) + to_chat(user, SPAN_DEADSAY("[seen_pronouns.He] [seen_pronouns.has] no pulse.")) + else + to_chat(user, SPAN_DEADSAY("[seen_pronouns.He] [seen_pronouns.has] a pulse!")) //Helper procedure. Called by /mob/living/human/examined_by() and /mob/living/human/Topic() to determine HUD access to security and medical records. /proc/hasHUD(mob/M, hudtype) diff --git a/code/modules/mob/living/human/human_attackhand.dm b/code/modules/mob/living/human/human_attackhand.dm index 18e93dc7dea6..dfcc31cb4120 100644 --- a/code/modules/mob/living/human/human_attackhand.dm +++ b/code/modules/mob/living/human/human_attackhand.dm @@ -382,6 +382,7 @@ user.visible_message( \ SPAN_NOTICE("\The [user] starts applying pressure to \the [src]'s [organ.name]!"), \ SPAN_NOTICE("You start applying pressure to \the [src]'s [organ.name]!")) + // TODO: refactor applying pressure to use grabs instead? would probably require making grabs locked to the zone they were started on spawn(0) organ.applied_pressure = user diff --git a/code/modules/mob/living/human/human_defines.dm b/code/modules/mob/living/human/human_defines.dm index 8108d6b8d3ee..9983f7eb7a4b 100644 --- a/code/modules/mob/living/human/human_defines.dm +++ b/code/modules/mob/living/human/human_defines.dm @@ -49,9 +49,6 @@ var/obj/machinery/machine_visual var/shock_stage var/rounded_shock_stage - /// vars for fountain of youth examine lines - var/became_older - var/became_younger /// var for caching last pain calc to avoid looping through organs over and over and over again var/last_pain var/vital_organ_missing_time diff --git a/code/modules/mob/living/human/human_examine_decl.dm b/code/modules/mob/living/human/human_examine_decl.dm index b791442cea3b..bad406e8b985 100644 --- a/code/modules/mob/living/human/human_examine_decl.dm +++ b/code/modules/mob/living/human/human_examine_decl.dm @@ -1,4 +1,9 @@ /decl/human_examination //This is essentially a stub-method for modpacks to be able to add onto the human examination stuff due to ... messy stuff. + var/priority = 0 + /// If non-null, this is inserted before this entry if there is not already a postfix before it. + var/section_prefix = null + /// If non-null, this is inserted after this entry if there exist entries after it. + var/section_postfix = null -/decl/human_examination/proc/do_examine(var/user, var/distance, var/source) //These can either return text, or should return nothing at all if you're doing to_chat() +/decl/human_examination/proc/do_examine(mob/user, distance, mob/living/human/source, hideflags, decl/pronouns/pronouns) //These can either return text, or should return nothing at all if you're doing to_chat() return diff --git a/code/modules/pronouns/pronouns_second_person.dm b/code/modules/pronouns/pronouns_second_person.dm new file mode 100644 index 000000000000..4860a1afaaa5 --- /dev/null +++ b/code/modules/pronouns/pronouns_second_person.dm @@ -0,0 +1,13 @@ +/decl/pronouns/self + name = SECOND_PERSON_SINGULAR + He = "You" + he = "you" + His = "Your" + his = "your" + him = "you" // yourself? you? + has = "have" + is = "are" + does = "do" + self = "yourself" + s = "" + es = "" \ No newline at end of file diff --git a/mods/content/matchmaking/matchmaker.dm b/mods/content/matchmaking/matchmaker.dm index 8f6bb706cb5d..70e424a3dfde 100644 --- a/mods/content/matchmaking/matchmaker.dm +++ b/mods/content/matchmaking/matchmaker.dm @@ -61,7 +61,12 @@ if(relation.holder == holder && relation.other && relation.other.holder == target && (relation.finalized || !finalized_only)) . += relation -/decl/human_examination/matchmaking/do_examine(var/mob/living/user, var/distance, var/mob/living/source) //These can either return text, or should return nothing at all if you're doing to_chat() +/decl/human_examination/matchmaking + // Show up after pose. + priority = /decl/human_examination/pose::priority + 1 + +// These should return null, text, or a list of text strings. +/decl/human_examination/matchmaking/do_examine(var/mob/living/user, var/distance, var/mob/living/human/source, hideflags, decl/pronouns/pronouns) if(!istype(source) || !istype(user)) return if(!source.mind || !user.mind || source.name != source.real_name) diff --git a/nebula.dme b/nebula.dme index 8a77c79025d6..b01e21e58889 100644 --- a/nebula.dme +++ b/nebula.dme @@ -3594,6 +3594,7 @@ #include "code\modules\pronouns\pronouns_female.dm" #include "code\modules\pronouns\pronouns_male.dm" #include "code\modules\pronouns\pronouns_neuter.dm" +#include "code\modules\pronouns\pronouns_second_person.dm" #include "code\modules\radiation\radiation.dm" #include "code\modules\random_map\_random_map_setup.dm" #include "code\modules\random_map\random_map.dm" From aedd1547d67561440ff69b7c89bdec89b1d63991 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 13 May 2025 17:32:19 -0400 Subject: [PATCH 339/512] Add laser interaction to xenoarch crystal --- .../artifacts/standalone/crystal.dm | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/code/modules/xenoarcheaology/artifacts/standalone/crystal.dm b/code/modules/xenoarcheaology/artifacts/standalone/crystal.dm index dd1fa65634f1..1fe1e576b2a7 100644 --- a/code/modules/xenoarcheaology/artifacts/standalone/crystal.dm +++ b/code/modules/xenoarcheaology/artifacts/standalone/crystal.dm @@ -3,11 +3,13 @@ icon = 'icons/obj/xenoarchaeology.dmi' icon_state = "ano70" density = TRUE + var/base_state = null + var/energized = FALSE /obj/structure/crystal/Initialize() . = ..() - icon_state = pick("ano70","ano80") + base_state = pick("ano7","ano8") desc = pick( "It shines faintly as it catches the light.", @@ -16,6 +18,10 @@ "Something twinkles faintly as you look at it.", "It's mesmerizing to behold.") +/obj/structure/crystal/on_update_icon() + . = ..() + icon_state = "[base_state][energized ? 0 : 1]" + /obj/structure/crystal/Destroy() src.visible_message("[src] shatters!") if(prob(75)) @@ -33,6 +39,15 @@ return ..() /obj/structure/crystal/get_artifact_scan_data() - return "Crystal formation - pseudo-organic crystalline matrix, unlikely to have formed naturally. No known technology exists to synthesize this exact composition." + . = "Crystal formation - pseudo-organic crystalline matrix, unlikely to have formed naturally. No known technology exists to synthesize this exact composition." + if(energized) + . += " Stimulation of the inner crystal lattice has caused it to enter a metastable energy level, indicating potential uses in power storage and energy manipulation." -//todo: laser_act +// Placeholder functionality so that these do something +/obj/structure/crystal/bullet_act(obj/item/projectile/the_bullet) + var/proj_damage = the_bullet.get_structure_damage() + if(!(the_bullet.damage_flags & DAM_LASER) || (proj_damage < 10) || energized) + return ..() + visible_message(SPAN_WARNING("\The [src] begins glowing...")) + energized = TRUE + update_icon() \ No newline at end of file From 7d50f82f77944161a0a9db48ae5babb9fa095926 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 03:56:52 -0400 Subject: [PATCH 340/512] Reimplement ion thruster power cost lost to merge skew --- code/modules/overmap/ships/machines/ion_thruster.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/overmap/ships/machines/ion_thruster.dm b/code/modules/overmap/ships/machines/ion_thruster.dm index 63d983050364..f1ffae4b7f37 100644 --- a/code/modules/overmap/ships/machines/ion_thruster.dm +++ b/code/modules/overmap/ships/machines/ion_thruster.dm @@ -58,9 +58,10 @@ . = ..() /obj/machinery/ion_thruster/proc/get_thrust() - if(!use_power || (stat & NOPOWER)) - return 0 - return thrust_limit + if(use_power && (stat & NOPOWER)) + use_power_oneoff(thrust_cost) + return thrust_limit + return 0 /obj/machinery/ion_thruster/on_update_icon() cut_overlays() From 59bcb86138b47af89c4ca7164ba41570ff345cb9 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 16 May 2025 23:42:38 -0400 Subject: [PATCH 341/512] Make the recipe material unit test more robust --- code/unit_tests/materials.dm | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/code/unit_tests/materials.dm b/code/unit_tests/materials.dm index f55ade48d342..c5d23c40310c 100644 --- a/code/unit_tests/materials.dm +++ b/code/unit_tests/materials.dm @@ -62,17 +62,19 @@ else if(!istype(product, recipe.expected_product_type)) failed += "unexpected product type returned ([product.type])" else if(isobj(product)) - var/obj/product_obj = product - LAZYINITLIST(product_obj.matter) // For the purposes of the following tests not runtiming. + var/list/product_matter = list() + for(var/obj/product_obj in results) + product_matter = MERGE_ASSOCS_WITH_NUM_VALUES(product_matter, product_obj.get_contained_matter()) + LAZYINITLIST(product_matter) // For the purposes of the following tests not runtiming. if(!material && !reinforced) - if(length(product_obj.matter)) + if(length(product_matter)) failed += "unsupplied material types" - else if(material && (product_obj.matter[material.type]) > recipe.req_amount) - failed += "excessive base material ([recipe.req_amount]/[ceil(product_obj.matter[material.type])])" - else if(reinforced && (product_obj.matter[reinforced.type]) > recipe.req_amount) - failed += "excessive reinf material ([recipe.req_amount]/[ceil(product_obj.matter[reinforced.type])])" + else if(material && (product_matter[material.type]) > recipe.req_amount) + failed += "excessive base material ([recipe.req_amount]/[ceil(product_matter[material.type])])" + else if(reinforced && (product_matter[reinforced.type]) > recipe.req_amount) + failed += "excessive reinf material ([recipe.req_amount]/[ceil(product_matter[reinforced.type])])" else - for(var/mat in product_obj.matter) + for(var/mat in product_matter) if(mat != material?.type && mat != reinforced?.type) failed += "extra material type ([mat])" From c090d859a303847232fc5773d87a7f5e17a4040d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 16 May 2025 23:43:00 -0400 Subject: [PATCH 342/512] Remove unnecessary amount override for haystack recipe --- code/modules/crafting/stack_recipes/recipes_fodder.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/crafting/stack_recipes/recipes_fodder.dm b/code/modules/crafting/stack_recipes/recipes_fodder.dm index e256692b6547..f6002a657768 100644 --- a/code/modules/crafting/stack_recipes/recipes_fodder.dm +++ b/code/modules/crafting/stack_recipes/recipes_fodder.dm @@ -7,9 +7,7 @@ on_floor = TRUE difficulty = MAT_VALUE_EASY_DIY recipe_skill = SKILL_BOTANY - -/decl/stack_recipe/fodder/get_required_stack_amount(obj/item/stack/stack, product_amount = 1) - return 30 * product_amount // Arbitrary amount to make 20 food items. + req_amount = 30 * SHEET_MATERIAL_AMOUNT // Arbitrary amount to make 20 food items. /decl/stack_recipe/fodder/bale result_type = /obj/structure/haystack/bale From 7260ed93cceca18796e01f34500d96c95496041f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 16 May 2025 23:45:52 -0400 Subject: [PATCH 343/512] Fix tank dispenser recipe producing a full tank dispenser --- .../crafting/stack_recipes/recipes_hardness_integrity.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/crafting/stack_recipes/recipes_hardness_integrity.dm b/code/modules/crafting/stack_recipes/recipes_hardness_integrity.dm index bf877bfbab75..57fc74fddf57 100644 --- a/code/modules/crafting/stack_recipes/recipes_hardness_integrity.dm +++ b/code/modules/crafting/stack_recipes/recipes_hardness_integrity.dm @@ -63,7 +63,7 @@ result_type = /obj/structure/closet /decl/stack_recipe/hardness/integrity/furniture/tank_dispenser - result_type = /obj/structure/tank_rack + result_type = /obj/structure/tank_rack/empty available_to_map_tech_level = MAP_TECH_LEVEL_SPACE /decl/stack_recipe/hardness/integrity/furniture/coffin From 0a0c46ffb451e5a3fa7f7a1da3c5076709f5088d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:18:35 -0400 Subject: [PATCH 344/512] Fix mob snapshot not tracking skin color or tone --- code/modules/mob/living/human/human.dm | 6 ++++-- code/modules/mob/living/human/human_appearance.dm | 4 +++- code/modules/mob/mob.dm | 2 +- code/modules/mob/mob_snapshot.dm | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index 4936094e5b04..12b36429a339 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -1122,8 +1122,10 @@ return //no feet no footsteps return TRUE -/mob/living/human/get_skin_tone(value) - return skin_tone +/mob/living/human/get_skin_tone() + if(get_bodytype()?.appearance_flags & HAS_A_SKIN_TONE) + return skin_tone + return null /mob/living/human/set_skin_tone(value) skin_tone = value diff --git a/code/modules/mob/living/human/human_appearance.dm b/code/modules/mob/living/human/human_appearance.dm index 272f2165b4a4..55383c9d0f69 100644 --- a/code/modules/mob/living/human/human_appearance.dm +++ b/code/modules/mob/living/human/human_appearance.dm @@ -7,7 +7,9 @@ AC.ui_interact(user, state = state) /mob/living/human/get_skin_colour() - return _skin_colour + if(get_bodytype()?.appearance_flags & HAS_SKIN_COLOR) + return _skin_colour + return null /mob/living/human/set_skin_colour(var/new_color, var/skip_update = FALSE) if((. = ..())) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index ee73224bf911..9fc34abeee9f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1359,7 +1359,7 @@ /mob/proc/set_skin_tone(value) return -/mob/proc/get_skin_tone(value) +/mob/proc/get_skin_tone() return /mob/proc/force_update_limbs() diff --git a/code/modules/mob/mob_snapshot.dm b/code/modules/mob/mob_snapshot.dm index 4f5441a8933e..ba497dca7ad2 100644 --- a/code/modules/mob/mob_snapshot.dm +++ b/code/modules/mob/mob_snapshot.dm @@ -21,6 +21,8 @@ eye_color = donor?.get_eye_colour() || COLOR_BLACK blood_type = donor?.get_blood_type() unique_enzymes = donor?.get_unique_enzymes() + skin_color = donor?.get_skin_colour() + skin_tone = donor?.get_skin_tone() fingerprint = donor?.get_full_print(ignore_blockers = TRUE) root_species = donor?.get_species() || get_species_by_key(global.using_map.default_species) From 2a74a73f0d83b2c5fd431bd8e0a978fc1c4bcd67 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:31:37 -0400 Subject: [PATCH 345/512] Implement weather particles wind_intensity var --- code/modules/weather/_weather.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/weather/_weather.dm b/code/modules/weather/_weather.dm index 00e996e256d8..9a8fb5341015 100644 --- a/code/modules/weather/_weather.dm +++ b/code/modules/weather/_weather.dm @@ -144,4 +144,4 @@ // 0 is south, but if our velocity is pure south we get -90, so add 90 // and then invert it, because byond uses counter-clockwise and we want clockwise weather_particles.rotation = generator("num", 90 - arctan(x_wind_vel * 0.50, weather_particles.base_velocity[1][2]), 90 - arctan(x_wind_vel, weather_particles.base_velocity[2][2]), NORMAL_RAND) - weather_particles.velocity += generator("vector", list(0, 0, 0), list(x_wind_vel, 0, z_wind_vel), NORMAL_RAND) \ No newline at end of file + weather_particles.velocity += generator("vector", list(0, 0, 0), list(x_wind_vel * weather_particles.wind_intensity, 0, z_wind_vel), NORMAL_RAND) \ No newline at end of file From 1cee5ccab2f40be2d55b36d5ce731dc23e75cedd Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 17 May 2025 21:55:35 -0400 Subject: [PATCH 346/512] Improve stack recipe material validation --- code/datums/repositories/decls.dm | 14 ++++ code/datums/vending/stored_item.dm | 4 +- code/game/atoms.dm | 6 +- code/game/machinery/Sleeper.dm | 6 +- .../machinery/_machines_base/machinery.dm | 4 +- .../stock_parts/building_material.dm | 4 +- code/game/machinery/vending_deconstruction.dm | 4 +- code/game/machinery/wall_frames.dm | 2 +- code/game/objects/__objs.dm | 2 +- code/modules/augment/active/cyberbrain.dm | 4 +- .../modules/crafting/stack_recipes/_recipe.dm | 72 ++++++++++++------- .../crafting/stack_recipes/recipes_bricks.dm | 4 +- .../stack_recipes/recipes_cardstock.dm | 1 + .../crafting/stack_recipes/recipes_grass.dm | 3 + .../stack_recipes/recipes_hardness.dm | 16 +---- .../crafting/stack_recipes/recipes_items.dm | 20 +++++- .../crafting/stack_recipes/recipes_logs.dm | 2 + .../crafting/stack_recipes/recipes_opacity.dm | 1 + .../crafting/stack_recipes/recipes_panels.dm | 1 + .../crafting/stack_recipes/recipes_planks.dm | 1 + .../stack_recipes/recipes_reinforced.dm | 9 +-- .../crafting/stack_recipes/recipes_rods.dm | 1 + .../crafting/stack_recipes/recipes_soft.dm | 5 +- .../crafting/stack_recipes/recipes_stacks.dm | 1 + .../stack_recipes/recipes_textiles.dm | 4 ++ code/modules/fabrication/_fabricator.dm | 2 +- code/modules/mob/living/living_organs.dm | 4 +- .../computers/modular_computer/core.dm | 4 +- code/modules/projectiles/ammunition.dm | 2 +- code/modules/tools/components/recipes.dm | 2 + code/unit_tests/materials.dm | 43 +++++++---- 31 files changed, 161 insertions(+), 87 deletions(-) diff --git a/code/datums/repositories/decls.dm b/code/datums/repositories/decls.dm index 73a9f14fb610..28dea46d5cd1 100644 --- a/code/datums/repositories/decls.dm +++ b/code/datums/repositories/decls.dm @@ -144,6 +144,20 @@ var/global/repository/decls/decls_repository = new . = get_decls(subtypesof(decl_prototype)) fetched_decl_subtypes[decl_prototype] = . +/// Gets the path of any concrete (non-abstract) decl of the provided type. +/// If decl_prototype is not abstract it will return that type. +/// Otherwise, it returns the first (in compile order) non-abstract child of this type, +/// or null otherwise. +/// This doesn't respect DECL_FLAG_ALLOW_ABSTRACT_INIT, but that flag should probably be deprecated someday +/// and replaced with a better solution to avoid instantiating abstract decls. +/// This is mostly used for recipe validation in unit tests and such. +/repository/decls/proc/get_first_concrete_decl_path_of_type(decl_prototype) + RETURN_TYPE(/decl) + . = fetched_decl_paths_by_type[decl_prototype] + if(!.) + . = get_decl_paths_of_type(decl_prototype) + return LAZYACCESS(., 1) // gets the first key (type) if it exists, else null if index is out of range + /decl abstract_type = /decl var/uid diff --git a/code/datums/vending/stored_item.dm b/code/datums/vending/stored_item.dm index 8eda6287cacb..3246f711603d 100644 --- a/code/datums/vending/stored_item.dm +++ b/code/datums/vending/stored_item.dm @@ -82,7 +82,7 @@ for(var/atom/movable/thing in instances) thing.forceMove(new_storing_obj) -/datum/stored_items/proc/get_combined_matter(include_instances = TRUE) +/datum/stored_items/proc/get_combined_matter(include_instances = TRUE, include_reagents = TRUE) var/virtual_amount = amount - length(instances) if(virtual_amount) . = atom_info_repository.get_matter_for(item_path)?.Copy() @@ -92,4 +92,4 @@ . = list() if(include_instances) for(var/atom/instance in instances) - . = MERGE_ASSOCS_WITH_NUM_VALUES(., instance.get_contained_matter()) \ No newline at end of file + . = MERGE_ASSOCS_WITH_NUM_VALUES(., instance.get_contained_matter(include_reagents)) \ No newline at end of file diff --git a/code/game/atoms.dm b/code/game/atoms.dm index a121490e2aea..5e466056ddd6 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -435,13 +435,13 @@ * Obj adds matter contents. Other overrides may add extra handling for things like material storage. * Most useful for calculating worth or deconstructing something along with its contents. */ -/atom/proc/get_contained_matter() - if(length(reagents?.reagent_volumes)) +/atom/proc/get_contained_matter(include_reagents = TRUE) + if(include_reagents && length(reagents?.reagent_volumes)) LAZYINITLIST(.) for(var/decl/material/reagent as anything in reagents.reagent_volumes) .[reagent.type] += floor(REAGENT_VOLUME(reagents, reagent) / REAGENT_UNITS_PER_MATERIAL_UNIT) for(var/atom/contained_obj as anything in get_contained_external_atoms()) // machines handle component parts separately - . = MERGE_ASSOCS_WITH_NUM_VALUES(., contained_obj.get_contained_matter()) + . = MERGE_ASSOCS_WITH_NUM_VALUES(., contained_obj.get_contained_matter(include_reagents)) /// Return a list of all simulated atoms inside this one. /atom/proc/get_contained_external_atoms() diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 47bc17acc0dd..eecfec8852bb 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -96,11 +96,11 @@ LAZYREMOVE(., loaded_canisters) LAZYREMOVE(., beaker) -/obj/machinery/sleeper/get_contained_matter() +/obj/machinery/sleeper/get_contained_matter(include_reagents = TRUE) . = ..() - . = MERGE_ASSOCS_WITH_NUM_VALUES(., beaker.get_contained_matter()) + . = MERGE_ASSOCS_WITH_NUM_VALUES(., beaker.get_contained_matter(include_reagents)) for(var/obj/canister in loaded_canisters) - . = MERGE_ASSOCS_WITH_NUM_VALUES(., canister.get_contained_matter()) + . = MERGE_ASSOCS_WITH_NUM_VALUES(., canister.get_contained_matter(include_reagents)) /obj/machinery/sleeper/Initialize(mapload, d = 0, populate_parts = TRUE) . = ..() diff --git a/code/game/machinery/_machines_base/machinery.dm b/code/game/machinery/_machines_base/machinery.dm index c57624ee3c9e..5f03a9d4ba72 100644 --- a/code/game/machinery/_machines_base/machinery.dm +++ b/code/game/machinery/_machines_base/machinery.dm @@ -506,12 +506,12 @@ Class Procs: LAZYREMOVE(., component_parts) // This only includes external atoms by default, so we need to add components back. -/obj/machinery/get_contained_matter() +/obj/machinery/get_contained_matter(include_reagents = TRUE) . = ..() var/list/component_types = types_of_component(/obj/item/stock_parts) for(var/path in component_types) for(var/obj/item/stock_parts/part in get_all_components_of_type(path)) - var/list/part_costs = part.get_contained_matter() + var/list/part_costs = part.get_contained_matter(include_reagents) for(var/key in part_costs) .[key] += part_costs[key] * component_types[path] diff --git a/code/game/machinery/_machines_base/stock_parts/building_material.dm b/code/game/machinery/_machines_base/stock_parts/building_material.dm index 615a39b9a852..2ad4e83360f9 100644 --- a/code/game/machinery/_machines_base/stock_parts/building_material.dm +++ b/code/game/machinery/_machines_base/stock_parts/building_material.dm @@ -67,9 +67,9 @@ materials = null ..() -/obj/item/stock_parts/building_material/get_contained_matter() +/obj/item/stock_parts/building_material/get_contained_matter(include_reagents = TRUE) . = ..() for(var/obj/item/thing in materials) - var/list/costs = thing.get_contained_matter() + var/list/costs = thing.get_contained_matter(include_reagents) for(var/key in costs) .[key] += costs[key] diff --git a/code/game/machinery/vending_deconstruction.dm b/code/game/machinery/vending_deconstruction.dm index 2577f8fc61b7..57ab1eba0302 100644 --- a/code/game/machinery/vending_deconstruction.dm +++ b/code/game/machinery/vending_deconstruction.dm @@ -38,12 +38,12 @@ return TRUE . = ..() -/obj/structure/vending_refill/get_contained_matter() +/obj/structure/vending_refill/get_contained_matter(include_reagents = TRUE) . = ..() for(var/datum/stored_items/vending_products/record in product_records) . = MERGE_ASSOCS_WITH_NUM_VALUES(., record.get_combined_matter(include_instances = FALSE)) -/obj/machinery/vending/get_contained_matter() +/obj/machinery/vending/get_contained_matter(include_reagents = TRUE) . = ..() for(var/datum/stored_items/vending_products/record in product_records) . = MERGE_ASSOCS_WITH_NUM_VALUES(., record.get_combined_matter(include_instances = FALSE)) diff --git a/code/game/machinery/wall_frames.dm b/code/game/machinery/wall_frames.dm index 19d63aeebfab..56e7c788416d 100644 --- a/code/game/machinery/wall_frames.dm +++ b/code/game/machinery/wall_frames.dm @@ -9,7 +9,7 @@ var/reverse = 0 //if resulting object faces opposite its dir (like light fixtures) var/fully_construct = FALSE // Results in a machine with all parts auto-installed and ready to go if TRUE; if FALSE, the machine will spawn without removable expected parts -/obj/item/frame/get_contained_matter() +/obj/item/frame/get_contained_matter(include_reagents = TRUE) . = ..() if(fully_construct) var/list/cost = atom_info_repository.get_matter_for(build_machine_type) diff --git a/code/game/objects/__objs.dm b/code/game/objects/__objs.dm index 3f7e83ffaae0..62566afe1a1c 100644 --- a/code/game/objects/__objs.dm +++ b/code/game/objects/__objs.dm @@ -293,7 +293,7 @@ /obj/proc/WillContain() return -/obj/get_contained_matter() +/obj/get_contained_matter(include_reagents = TRUE) . = ..() if(length(matter)) . = MERGE_ASSOCS_WITH_NUM_VALUES(., matter.Copy()) diff --git a/code/modules/augment/active/cyberbrain.dm b/code/modules/augment/active/cyberbrain.dm index c508f4cfcedd..d5972c12333d 100644 --- a/code/modules/augment/active/cyberbrain.dm +++ b/code/modules/augment/active/cyberbrain.dm @@ -79,11 +79,11 @@ if(os) os.Process() -/obj/item/organ/internal/augment/active/cyberbrain/get_contained_matter() +/obj/item/organ/internal/augment/active/cyberbrain/get_contained_matter(include_reagents = TRUE) . = ..() var/datum/extension/assembly/assembly = get_extension(src, /datum/extension/assembly) for(var/obj/part in assembly?.parts) - . = MERGE_ASSOCS_WITH_NUM_VALUES(., part.get_contained_matter()) + . = MERGE_ASSOCS_WITH_NUM_VALUES(., part.get_contained_matter(include_reagents)) /* * diff --git a/code/modules/crafting/stack_recipes/_recipe.dm b/code/modules/crafting/stack_recipes/_recipe.dm index 640bd41adf39..205948de85e2 100644 --- a/code/modules/crafting/stack_recipes/_recipe.dm +++ b/code/modules/crafting/stack_recipes/_recipe.dm @@ -23,9 +23,6 @@ var/gender /// Object path to the desired product. var/result_type - /// Object path to use in unit testing; leave null to use result_type instead. - /// Useful for items that require a material to Initialize() correctly as testing tries to use a null material. - var/test_result_type /// Amount of matter units needed for this recipe. If null, generates from result matter. var/req_amount /// Time it takes for this recipe to be crafted (not including skill and tool modifiers). If null, generates from product w_class and difficulty. @@ -78,6 +75,10 @@ /// Can this recipe use a reinforced material? Set to type for a specific material. var/required_reinforce_material = MATERIAL_FORBIDDEN + /// In cases where required_material is MATERIAL_REQUIRED and not a typepath, + /// this is the material type used for setup, validation, and tests. + var/validation_material + /// Minimum material wall support value. var/required_wall_support_value /// Minimum material integrity value. @@ -131,17 +132,29 @@ else if(!ispath(result_type, expected_product_type)) . += "result type [result_type || "NULL"] is not subtype of expected product type [expected_product_type || "NULL"]" - if(isnull(required_material) || required_material == MATERIAL_FORBIDDEN) - if(!isnull(required_wall_support_value)) - . += "null required material but non-null wall support value" - if(!isnull(required_integrity)) - . += "null required material but non-null integrity value" - if(!isnull(required_max_opacity)) - . += "null required material but non-null max opacity value" - if(!isnull(required_min_hardness)) - . += "null required material but non-null min hardness value" - if(!isnull(required_max_hardness)) - . += "null required material but non-null max hardness value" + switch(required_material) + if(null) + . += "null required material value is deprecated, use MATERIAL_FORBIDDEN" + if(MATERIAL_FORBIDDEN) + if(!isnull(validation_material)) + . += "material is forbidden but non-null validation material" + if(!isnull(required_wall_support_value)) + . += "material is forbidden but non-null wall support value" + if(!isnull(required_integrity)) + . += "material is forbidden but non-null integrity value" + if(!isnull(required_max_opacity)) + . += "material is forbidden but non-null max opacity value" + if(!isnull(required_min_hardness)) + . += "material is forbidden but non-null min hardness value" + if(!isnull(required_max_hardness)) + . += "material is forbidden but non-null max hardness value" + if(MATERIAL_REQUIRED) + if(isnull(validation_material)) + . += "material is required but validation material was null" + else + var/list/material_failures = get_missing_material_properties(RESOLVE_TO_DECL(validation_material)) + if(LAZYLEN(material_failures)) + . += "validation material is [english_list(material_failures)]" // 'material is too soft, too opaque, and unable to support enough weight' if(recipe_skill && !isnull(difficulty)) var/decl/skill/used_skill = GET_DECL(recipe_skill) @@ -235,6 +248,21 @@ . = JOINTEXT(.) +/// Returns a list of descriptive error strings e.g. "too soft/hard/opaque" if material properties are not satisfied. +/decl/stack_recipe/proc/get_missing_material_properties(decl/material/mat) + ASSERT(mat) + // Check if the material has the appropriate properties. + if(!isnull(required_wall_support_value) && mat.wall_support_value < required_wall_support_value) + LAZYADD(., "unable to support enough weight") + if(!isnull(required_integrity) && mat.integrity < required_integrity) + LAZYADD(., "too weak") + if(!isnull(required_min_hardness) && mat.hardness < required_min_hardness) + LAZYADD(., "too soft") + if(!isnull(required_max_hardness) && mat.hardness > required_max_hardness) + LAZYADD(., "too hard") + if(!isnull(required_max_opacity) && mat.opacity > required_max_opacity) + LAZYADD(., "too opaque") + /decl/stack_recipe/proc/can_be_made_from(stack_type, tool_type, decl/material/mat, decl/material/reinf_mat) // Early checks to avoid letting recipes make themselves. @@ -259,17 +287,8 @@ return FALSE // Check if the material has the appropriate properties. - if(mat) - if(!isnull(required_wall_support_value) && mat.wall_support_value < required_wall_support_value) - return FALSE - if(!isnull(required_integrity) && mat.integrity < required_integrity) - return FALSE - if(!isnull(required_min_hardness) && mat.hardness < required_min_hardness) - return FALSE - if(!isnull(required_max_hardness) && mat.hardness > required_max_hardness) - return FALSE - if(!isnull(required_max_opacity) && mat.opacity > required_max_opacity) - return FALSE + if(mat && length(get_missing_material_properties(mat))) + return FALSE // Check if they're using the right tool. if(required_tool) @@ -325,7 +344,8 @@ if(result_type && isnull(req_amount)) req_amount = 0 var/list/materials - materials = atom_info_repository.get_matter_for((test_result_type || result_type), (ispath(required_material) ? required_material : null)) + var/decl/material/validation_material_path = ispath(required_material) ? decls_repository.get_first_concrete_decl_path_of_type(required_material) : validation_material + materials = atom_info_repository.get_matter_for(result_type, validation_material_path) for(var/mat in materials) req_amount += round(materials[mat]) req_amount = ceil(req_amount*crafting_extra_cost_factor) diff --git a/code/modules/crafting/stack_recipes/recipes_bricks.dm b/code/modules/crafting/stack_recipes/recipes_bricks.dm index 8be3160ba95c..0c9670fbcd9a 100644 --- a/code/modules/crafting/stack_recipes/recipes_bricks.dm +++ b/code/modules/crafting/stack_recipes/recipes_bricks.dm @@ -9,6 +9,7 @@ /obj/item/stack/material/log, /obj/item/stack/material/lump ) + validation_material = /decl/material/solid/stone/basalt category = "structures" /decl/stack_recipe/bricks/cup @@ -121,6 +122,7 @@ result_type = /turf/wall/brick craft_stack_types = /obj/item/stack/material/brick difficulty = MAT_VALUE_HARD_DIY + validation_material = /decl/material/solid/stone/basalt /decl/stack_recipe/turfs/wall/brick/shutter name = "shuttered brick wall" @@ -129,8 +131,8 @@ /decl/stack_recipe/turfs/floor/brick name = "cobblestone path" result_type = /turf/floor/path - expected_product_type = /turf/floor/path craft_stack_types = /obj/item/stack/material/brick + validation_material = /decl/material/solid/stone/basalt /decl/stack_recipe/turfs/floor/brick/herringbone name = "herringbone path" diff --git a/code/modules/crafting/stack_recipes/recipes_cardstock.dm b/code/modules/crafting/stack_recipes/recipes_cardstock.dm index 30e9e6f5e3a4..12ef76c3ecd8 100644 --- a/code/modules/crafting/stack_recipes/recipes_cardstock.dm +++ b/code/modules/crafting/stack_recipes/recipes_cardstock.dm @@ -1,6 +1,7 @@ /decl/stack_recipe/cardstock abstract_type = /decl/stack_recipe/cardstock craft_stack_types = /obj/item/stack/material/cardstock + validation_material = /decl/material/solid/organic/cardboard available_to_map_tech_level = MAP_TECH_LEVEL_SPACE // not exactly high-tech, but donuts etc are not medieval /decl/stack_recipe/cardstock/box diff --git a/code/modules/crafting/stack_recipes/recipes_grass.dm b/code/modules/crafting/stack_recipes/recipes_grass.dm index 17caba7e0c49..776dfb49589e 100644 --- a/code/modules/crafting/stack_recipes/recipes_grass.dm +++ b/code/modules/crafting/stack_recipes/recipes_grass.dm @@ -3,7 +3,10 @@ craft_stack_types = /obj/item/stack/material/bundle category = "woven items" forbidden_craft_stack_types = null + validation_material = /decl/material/solid/organic/plantmatter/grass/dry +// TODO: make this check a material property. tensile strength? dryness? +// literally anything but a direct type equality check please /decl/stack_recipe/woven/can_be_made_from(stack_type, tool_type, decl/material/mat, decl/material/reinf_mat) if((istype(mat) ? mat.type : mat) == /decl/material/solid/organic/plantmatter/grass) return FALSE diff --git a/code/modules/crafting/stack_recipes/recipes_hardness.dm b/code/modules/crafting/stack_recipes/recipes_hardness.dm index 903769244d6e..5f8f43e2a4b7 100644 --- a/code/modules/crafting/stack_recipes/recipes_hardness.dm +++ b/code/modules/crafting/stack_recipes/recipes_hardness.dm @@ -1,6 +1,7 @@ /decl/stack_recipe/hardness abstract_type = /decl/stack_recipe/hardness required_min_hardness = MAT_VALUE_FLEXIBLE + 10 + validation_material = DEFAULT_FURNITURE_MATERIAL /decl/stack_recipe/hardness/improvised_armour result_type = /obj/item/clothing/suit/armor/crafted @@ -74,21 +75,6 @@ /decl/stack_recipe/hardness/mortar result_type = /obj/item/chems/glass/mortar -/decl/stack_recipe/ring - result_type = /obj/item/clothing/gloves/ring - -/decl/stack_recipe/ring_thin - name = "ring, thin" - result_type = /obj/item/clothing/gloves/ring/thin - -/decl/stack_recipe/ring_thick - name = "ring, thick" - result_type = /obj/item/clothing/gloves/ring/thick - -/decl/stack_recipe/ring_split - name = "ring, split" - result_type = /obj/item/clothing/gloves/ring/split - /decl/stack_recipe/hardness/clipboard result_type = /obj/item/clipboard available_to_map_tech_level = MAP_TECH_LEVEL_SPACE diff --git a/code/modules/crafting/stack_recipes/recipes_items.dm b/code/modules/crafting/stack_recipes/recipes_items.dm index d98f860c3f3f..e09b5b933cf9 100644 --- a/code/modules/crafting/stack_recipes/recipes_items.dm +++ b/code/modules/crafting/stack_recipes/recipes_items.dm @@ -37,4 +37,22 @@ bundle = new(location) bundles += bundle bundle.merge(paper) - return bundles \ No newline at end of file + return bundles + +// These don't check hardness so that you can make them out of clay and fire them, I guess? +// They used to be in the hardness-based recipes file but aren't now. +/decl/stack_recipe/ring + result_type = /obj/item/clothing/gloves/ring + validation_material = /decl/material/solid/metal/silver + +/decl/stack_recipe/ring/thin + name = "ring, thin" + result_type = /obj/item/clothing/gloves/ring/thin + +/decl/stack_recipe/ring/thick + name = "ring, thick" + result_type = /obj/item/clothing/gloves/ring/thick + +/decl/stack_recipe/ring/split + name = "ring, split" + result_type = /obj/item/clothing/gloves/ring/split \ No newline at end of file diff --git a/code/modules/crafting/stack_recipes/recipes_logs.dm b/code/modules/crafting/stack_recipes/recipes_logs.dm index 150f36cd1021..02010e3a9252 100644 --- a/code/modules/crafting/stack_recipes/recipes_logs.dm +++ b/code/modules/crafting/stack_recipes/recipes_logs.dm @@ -2,6 +2,7 @@ abstract_type = /decl/stack_recipe/logs craft_stack_types = /obj/item/stack/material/log forbidden_craft_stack_types = /obj/item/stack/material/ore + validation_material = /decl/material/solid/organic/wood/oak /decl/stack_recipe/logs/travois result_type = /obj/structure/travois @@ -12,6 +13,7 @@ result_type = /turf/wall/log craft_stack_types = /obj/item/stack/material/log forbidden_craft_stack_types = /obj/item/stack/material/ore + validation_material = /decl/material/solid/organic/wood/oak difficulty = MAT_VALUE_HARD_DIY /decl/stack_recipe/turfs/wall/logs/shutter diff --git a/code/modules/crafting/stack_recipes/recipes_opacity.dm b/code/modules/crafting/stack_recipes/recipes_opacity.dm index dccf4e889e6d..c712344f2464 100644 --- a/code/modules/crafting/stack_recipes/recipes_opacity.dm +++ b/code/modules/crafting/stack_recipes/recipes_opacity.dm @@ -9,6 +9,7 @@ /obj/item/stack/material/sheet, /obj/item/stack/material/panel ) + validation_material = /decl/material/solid/glass /decl/stack_recipe/opacity/fullwindow name = "full-tile window" diff --git a/code/modules/crafting/stack_recipes/recipes_panels.dm b/code/modules/crafting/stack_recipes/recipes_panels.dm index a78196e388b4..dc21533bd6a7 100644 --- a/code/modules/crafting/stack_recipes/recipes_panels.dm +++ b/code/modules/crafting/stack_recipes/recipes_panels.dm @@ -2,6 +2,7 @@ abstract_type = /decl/stack_recipe/panels craft_stack_types = /obj/item/stack/material/panel available_to_map_tech_level = MAP_TECH_LEVEL_SPACE + validation_material = /decl/material/solid/organic/plastic /decl/stack_recipe/panels/bag result_type = /obj/item/bag/flimsy diff --git a/code/modules/crafting/stack_recipes/recipes_planks.dm b/code/modules/crafting/stack_recipes/recipes_planks.dm index d643a2e51b8f..03464a086a4e 100644 --- a/code/modules/crafting/stack_recipes/recipes_planks.dm +++ b/code/modules/crafting/stack_recipes/recipes_planks.dm @@ -1,6 +1,7 @@ /decl/stack_recipe/planks abstract_type = /decl/stack_recipe/planks craft_stack_types = /obj/item/stack/material/plank + validation_material = /decl/material/solid/organic/wood/oak /decl/stack_recipe/planks/sandals result_type = /obj/item/clothing/shoes/sandal diff --git a/code/modules/crafting/stack_recipes/recipes_reinforced.dm b/code/modules/crafting/stack_recipes/recipes_reinforced.dm index c5335e7132f0..6a918cac0ef8 100644 --- a/code/modules/crafting/stack_recipes/recipes_reinforced.dm +++ b/code/modules/crafting/stack_recipes/recipes_reinforced.dm @@ -1,9 +1,10 @@ /decl/stack_recipe/reinforced - abstract_type = /decl/stack_recipe/reinforced - craft_stack_types = /obj/item/stack/material/sheet/reinforced - one_per_turf = TRUE - difficulty = MAT_VALUE_HARD_DIY + abstract_type = /decl/stack_recipe/reinforced + craft_stack_types = /obj/item/stack/material/sheet/reinforced + one_per_turf = TRUE + difficulty = MAT_VALUE_HARD_DIY available_to_map_tech_level = MAP_TECH_LEVEL_SPACE + validation_material = /decl/material/solid/metal/plasteel /decl/stack_recipe/reinforced/ai_core result_type = /obj/structure/aicore diff --git a/code/modules/crafting/stack_recipes/recipes_rods.dm b/code/modules/crafting/stack_recipes/recipes_rods.dm index c010556a990d..8483c2346746 100644 --- a/code/modules/crafting/stack_recipes/recipes_rods.dm +++ b/code/modules/crafting/stack_recipes/recipes_rods.dm @@ -10,6 +10,7 @@ difficulty = MAT_VALUE_HARD_DIY available_to_map_tech_level = MAP_TECH_LEVEL_MEDIEVAL category = "structures" + validation_material = /decl/material/solid/metal/steel /decl/stack_recipe/rods/stick result_type = /obj/item/stick diff --git a/code/modules/crafting/stack_recipes/recipes_soft.dm b/code/modules/crafting/stack_recipes/recipes_soft.dm index 27f9c6328ceb..e7e6d12d924f 100644 --- a/code/modules/crafting/stack_recipes/recipes_soft.dm +++ b/code/modules/crafting/stack_recipes/recipes_soft.dm @@ -9,6 +9,7 @@ ) required_min_hardness = 0 required_max_hardness = MAT_VALUE_SOFT + validation_material = /decl/material/solid/clay crafting_extra_cost_factor = 1 // No wastage for just resculpting materials. /decl/stack_recipe/soft/teapot @@ -42,13 +43,11 @@ name = "brick" name_plural = "bricks" result_type = /obj/item/stack/material/brick - test_result_type = /obj/item/stack/material/brick/clay /decl/stack_recipe/soft/bar name = "bar" name_plural = "bars" result_type = /obj/item/stack/material/bar - test_result_type = /obj/item/stack/material/bar/wax /decl/stack_recipe/soft/stack/spawn_result(mob/user, location, amount, decl/material/mat, decl/material/reinf_mat, paint_color, spent_type, spent_amount = 1) var/obj/item/stack/S = ..() @@ -68,13 +67,11 @@ name = "large lump" name_plural = "large lumps" result_type = /obj/item/stack/material/lump/large - test_result_type = /obj/item/stack/material/lump/large/clay /decl/stack_recipe/soft/stack/small_lump name = "small lump" name_plural = "small lumps" result_type = /obj/item/stack/material/lump - test_result_type = /obj/item/stack/material/lump/clay /decl/stack_recipe/soft/crucible result_type = /obj/item/chems/crucible diff --git a/code/modules/crafting/stack_recipes/recipes_stacks.dm b/code/modules/crafting/stack_recipes/recipes_stacks.dm index 06c19604fbfc..5b45b2c90f42 100644 --- a/code/modules/crafting/stack_recipes/recipes_stacks.dm +++ b/code/modules/crafting/stack_recipes/recipes_stacks.dm @@ -112,6 +112,7 @@ abstract_type = /decl/stack_recipe/tile/panels craft_stack_types = /obj/item/stack/material/panel available_to_map_tech_level = MAP_TECH_LEVEL_SPACE + validation_material = /decl/material/solid/organic/plastic /decl/stack_recipe/tile/panels/floor result_type = /obj/item/stack/tile/floor_white diff --git a/code/modules/crafting/stack_recipes/recipes_textiles.dm b/code/modules/crafting/stack_recipes/recipes_textiles.dm index 4b49616eef76..0e0a5e20271a 100644 --- a/code/modules/crafting/stack_recipes/recipes_textiles.dm +++ b/code/modules/crafting/stack_recipes/recipes_textiles.dm @@ -6,6 +6,7 @@ difficulty = null // Autoset from material difficulty crafting_extra_cost_factor = 1.5 // measure twice, cut once; material is lost. todo: produce scraps? abstract_type = /decl/stack_recipe/textiles + validation_material = /decl/material/solid/organic/cloth /decl/stack_recipe/textiles/rug result_type = /obj/structure/rug/crafted @@ -62,6 +63,7 @@ /decl/stack_recipe/textiles/leather abstract_type = /decl/stack_recipe/textiles/leather + validation_material = /decl/material/solid/organic/leather craft_stack_types = /obj/item/stack/material/skin category = "clothing" @@ -105,6 +107,7 @@ /decl/stack_recipe/textiles/cloth abstract_type = /decl/stack_recipe/textiles/cloth + validation_material = /decl/material/solid/organic/cloth craft_stack_types = /obj/item/stack/material/bolt category = "clothing" @@ -141,6 +144,7 @@ /decl/stack_recipe/textiles/fur abstract_type = /decl/stack_recipe/textiles/fur craft_stack_types = /obj/item/stack/material/skin/pelt + validation_material = /decl/material/solid/organic/skin/fur /decl/stack_recipe/textiles/fur/bedding difficulty = MAT_VALUE_EASY_DIY diff --git a/code/modules/fabrication/_fabricator.dm b/code/modules/fabrication/_fabricator.dm index b4c227c101a6..d10d5064bc4f 100644 --- a/code/modules/fabrication/_fabricator.dm +++ b/code/modules/fabrication/_fabricator.dm @@ -230,6 +230,6 @@ return pipe_colors //override with null for hex color selections // Our stored_material is just the right format to be added to the matter list. -/obj/machinery/fabricator/get_contained_matter() +/obj/machinery/fabricator/get_contained_matter(include_reagents = TRUE) . = ..() . = MERGE_ASSOCS_WITH_NUM_VALUES(., stored_material) \ No newline at end of file diff --git a/code/modules/mob/living/living_organs.dm b/code/modules/mob/living/living_organs.dm index dce22c9a9933..8617ed077091 100644 --- a/code/modules/mob/living/living_organs.dm +++ b/code/modules/mob/living/living_organs.dm @@ -11,10 +11,10 @@ /mob/living/proc/has_internal_organs() return LAZYLEN(get_internal_organs()) > 0 -/mob/living/get_contained_matter() +/mob/living/get_contained_matter(include_reagents = TRUE) . = ..() for(var/obj/item/organ in get_organs()) - . = MERGE_ASSOCS_WITH_NUM_VALUES(., organ.get_contained_matter()) + . = MERGE_ASSOCS_WITH_NUM_VALUES(., organ.get_contained_matter(include_reagents)) //Can be called when we want to add an organ in a detached state or an attached state. /mob/living/proc/add_organ(var/obj/item/organ/O, var/obj/item/organ/external/affected = null, var/in_place = FALSE, var/update_icon = TRUE, var/detached = FALSE, var/skip_health_update = FALSE) diff --git a/code/modules/modular_computers/computers/modular_computer/core.dm b/code/modules/modular_computers/computers/modular_computer/core.dm index 521a4a6b01a4..0869c4431739 100644 --- a/code/modules/modular_computers/computers/modular_computer/core.dm +++ b/code/modules/modular_computers/computers/modular_computer/core.dm @@ -4,11 +4,11 @@ if(assembly) LAZYREMOVE(., assembly.parts) -/obj/item/modular_computer/get_contained_matter() +/obj/item/modular_computer/get_contained_matter(include_reagents = TRUE) . = ..() var/datum/extension/assembly/assembly = get_extension(src, /datum/extension/assembly) for(var/obj/part in assembly?.parts) - . = MERGE_ASSOCS_WITH_NUM_VALUES(., part.get_contained_matter()) + . = MERGE_ASSOCS_WITH_NUM_VALUES(., part.get_contained_matter(include_reagents)) /obj/item/modular_computer/Process() var/datum/extension/assembly/assembly = get_extension(src, /datum/extension/assembly) diff --git a/code/modules/projectiles/ammunition.dm b/code/modules/projectiles/ammunition.dm index 67c0341696df..83c79b11ce9a 100644 --- a/code/modules/projectiles/ammunition.dm +++ b/code/modules/projectiles/ammunition.dm @@ -176,7 +176,7 @@ stored_ammo += new ammo_type(src) contents_initialized = TRUE -/obj/item/ammo_magazine/get_contained_matter() +/obj/item/ammo_magazine/get_contained_matter(include_reagents = TRUE) . = ..() if(!lazyload_contents || contents_initialized || !ammo_type || !initial_ammo) return diff --git a/code/modules/tools/components/recipes.dm b/code/modules/tools/components/recipes.dm index 9ab5516ceb8e..38b76cff8959 100644 --- a/code/modules/tools/components/recipes.dm +++ b/code/modules/tools/components/recipes.dm @@ -7,6 +7,7 @@ /obj/item/stack/material/lump, /obj/item/stack/material/plank ) + validation_material = /decl/material/solid/stone/basalt /decl/stack_recipe/tool/handle abstract_type = /decl/stack_recipe/tool/handle @@ -16,6 +17,7 @@ /obj/item/stack/material/rods, /obj/item/stack/material/bone ) + validation_material = /decl/material/solid/organic/bone /decl/stack_recipe/tool/handle/long result_type = /obj/item/tool_component/handle/long diff --git a/code/unit_tests/materials.dm b/code/unit_tests/materials.dm index c5d23c40310c..8ad6424f271c 100644 --- a/code/unit_tests/materials.dm +++ b/code/unit_tests/materials.dm @@ -12,32 +12,51 @@ var/list/stack_types = list(null) var/list/tool_types = list(null) - var/list/all_recipes = decls_repository.get_decls_of_subtype(/decl/stack_recipe) - for(var/recipe_type in all_recipes) - var/decl/stack_recipe/recipe = all_recipes[recipe_type] + var/list/all_recipes = decls_repository.get_decls_of_subtype_unassociated(/decl/stack_recipe) + for(var/decl/stack_recipe/recipe in all_recipes) if(recipe.required_tool) tool_types |= recipe.required_tool if(recipe.craft_stack_types) stack_types |= recipe.craft_stack_types // Force config to be the most precise recipes possible. + // This first one doesn't actually work because it's applied on decl init... var/decl/config/config = GET_DECL(/decl/config/toggle/on/stack_crafting_uses_types) config.set_value(TRUE) config = GET_DECL(/decl/config/toggle/stack_crafting_uses_tools) config.set_value(TRUE) var/list/test_materials = list( - GET_DECL(/decl/material/solid/organic/wood), + GET_DECL(/decl/material/solid/organic/wood/oak), GET_DECL(/decl/material/solid/organic/plastic), GET_DECL(/decl/material/solid/organic/meat), + GET_DECL(/decl/material/solid/organic/cloth/linen), + GET_DECL(/decl/material/solid/organic/leather), + GET_DECL(/decl/material/solid/organic/plantmatter/grass/dry), + GET_DECL(/decl/material/solid/organic/paper), GET_DECL(/decl/material/solid/metal/steel), GET_DECL(/decl/material/solid/metal/plasteel), GET_DECL(/decl/material/solid/metal/gold), + GET_DECL(/decl/material/solid/metal/aluminium), + GET_DECL(/decl/material/solid/organic/wax), GET_DECL(/decl/material/solid/glass), - GET_DECL(/decl/material/solid/stone/sandstone), - GET_DECL(/decl/material/solid/clay) + GET_DECL(/decl/material/solid/stone/basalt), + GET_DECL(/decl/material/solid/clay), ) + // Add validation materials if not already present + // (this is especially useful for modpacked recipes/materials, like nullglass) + for(var/decl/stack_recipe/the_recipe in all_recipes) + if(ispath(the_recipe.required_material)) + var/decl/material/the_validation_material = the_recipe.required_material + if(TYPE_IS_ABSTRACT(the_validation_material)) + the_validation_material = decls_repository.get_first_concrete_decl_path_of_type(the_recipe.required_material) + test_materials |= GET_DECL(the_validation_material) + continue + if(the_recipe.validation_material) + test_materials |= GET_DECL(the_recipe.validation_material) + continue + // This is obscene, but completeness requires it. for(var/stack_type in stack_types) for(var/tool_type in tool_types) @@ -51,21 +70,19 @@ // Handle the actual validation. for(var/decl/stack_recipe/recipe as anything in recipes) - var/test_type = recipe.test_result_type || recipe.result_type - if(!test_type || ispath(test_type, /turf)) // Cannot exist without a loc and doesn't have matter, cannot assess here. + if(!recipe.result_type || ispath(recipe.result_type, /turf)) // Cannot exist without a loc and doesn't have matter, cannot assess here. continue var/list/results = recipe.spawn_result(null, null, 1, material, reinforced, null) var/atom/product = LAZYACCESS(results, 1) var/list/failed = list() if(!product) failed += "no product returned" - else if(!istype(product, recipe.expected_product_type)) - failed += "unexpected product type returned ([product.type])" + else if(!istype(product, recipe.result_type)) + failed += "unexpected product type, got '[product.type]' (expected '[recipe.result_type]')" else if(isobj(product)) var/list/product_matter = list() for(var/obj/product_obj in results) - product_matter = MERGE_ASSOCS_WITH_NUM_VALUES(product_matter, product_obj.get_contained_matter()) - LAZYINITLIST(product_matter) // For the purposes of the following tests not runtiming. + product_matter = MERGE_ASSOCS_WITH_NUM_VALUES(product_matter, product_obj.get_contained_matter(include_reagents = FALSE)) if(!material && !reinforced) if(length(product_matter)) failed += "unsupplied material types" @@ -87,6 +104,8 @@ passed_designs += recipe if(!QDELETED(product)) qdel(product) + CHECK_TICK + CHECK_TICK if(failed_count) fail("[failed_count] crafting recipes had inconsistent output materials: [jointext(failed_designs, "\n")].") From 1ff5cc8fe8fdf4acda90375d850522024bba7978 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 23 May 2025 15:15:37 -0400 Subject: [PATCH 347/512] Lower FileAlreadyIncluded pragma to disabled --- code/___opendream_linting.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/___opendream_linting.dm b/code/___opendream_linting.dm index 446ad58ad57b..e9fe9369d681 100644 --- a/code/___opendream_linting.dm +++ b/code/___opendream_linting.dm @@ -1,6 +1,7 @@ #ifdef OPENDREAM //1000-1999 -#pragma FileAlreadyIncluded error +// FileAlreadyIncluded trips up on modpack DMEs +#pragma FileAlreadyIncluded disabled #pragma MissingIncludedFile error #pragma MisplacedDirective error #pragma UndefineMissingDirective error From 1e062a68ac49b24d8b991a19969f50cb5a455527 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 00:24:33 -0400 Subject: [PATCH 348/512] Fix locked machines failing panel opening unit test --- .../machinery/_machines_base/machine_construction/default.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/game/machinery/_machines_base/machine_construction/default.dm b/code/game/machinery/_machines_base/machine_construction/default.dm index a3056c056a52..d573df31e478 100644 --- a/code/game/machinery/_machines_base/machine_construction/default.dm +++ b/code/game/machinery/_machines_base/machine_construction/default.dm @@ -21,6 +21,9 @@ /decl/machine_construction/default/panel_closed/proc/fail_test_state_transfer(obj/machinery/machine, mob/user) var/static/obj/item/screwdriver/screwdriver = new + // Prevent access locks on machines interfering with our interactions. + for(var/obj/item/stock_parts/access_lock/lock in machine.get_all_components_of_type(/obj/item/stock_parts/access_lock)) + lock.locked = FALSE if(!machine.attackby(screwdriver, user)) return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver." if(machine.construct_state.type != down_state) From 5b433a365a94f3dea2ce90db22f1ef3900d994d6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 00:25:17 -0400 Subject: [PATCH 349/512] Copy default panel-closed test to wall frame construction state --- .../machine_construction/wall_frame.dm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/code/game/machinery/_machines_base/machine_construction/wall_frame.dm b/code/game/machinery/_machines_base/machine_construction/wall_frame.dm index 5c38cf0cd7c2..a81bd4d52312 100644 --- a/code/game/machinery/_machines_base/machine_construction/wall_frame.dm +++ b/code/game/machinery/_machines_base/machine_construction/wall_frame.dm @@ -55,6 +55,23 @@ machine.panel_open = TRUE machine.queue_icon_update() +/decl/machine_construction/wall_frame/panel_closed/fail_unit_test(obj/machinery/machine) + if((. = ..())) + return + var/static/mob/living/human/user = new + return fail_test_state_transfer(machine, user) + +/decl/machine_construction/wall_frame/panel_closed/proc/fail_test_state_transfer(obj/machinery/machine, mob/user) + var/static/obj/item/screwdriver/screwdriver = new + // Prevent access locks on machines interfering with our interactions. + for(var/obj/item/stock_parts/access_lock/lock in machine.get_all_components_of_type(/obj/item/stock_parts/access_lock)) + lock.locked = FALSE + if(!machine.attackby(screwdriver, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver." + if(machine.construct_state.type != open_state) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [open_state])." + + // Open panel /decl/machine_construction/wall_frame/panel_open/state_is_valid(obj/machinery/machine) From 3e4b040369ab5055760e6b80e8657e1c9bb78643 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 00:45:13 -0400 Subject: [PATCH 350/512] Add hacky workaround for self destruct storage --- code/game/machinery/self_destruct_storage.dm | 10 ++++++++++ code/unit_tests/machine_tests.dm | 11 ++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/self_destruct_storage.dm b/code/game/machinery/self_destruct_storage.dm index 0d97e56de5a7..df7512e5da09 100644 --- a/code/game/machinery/self_destruct_storage.dm +++ b/code/game/machinery/self_destruct_storage.dm @@ -51,6 +51,16 @@ to_chat(user, SPAN_WARNING("The card fails to do anything. It seems this device has an advanced encryption system.")) return NO_EMAG_ACT +// I hate this but can't think of a better way aside from skipping the testing entirely for this type, +// which is worse. Basically, we just need to ensure we pass the cannot_transition_to check. +/obj/machinery/nuclear_cylinder_storage/fail_construct_state_unit_test() + locked = FALSE + open = TRUE + var/list/old_cylinders = cylinders // This is evil. + cylinders = list() + . = ..() + cylinders = old_cylinders + /obj/machinery/nuclear_cylinder_storage/components_are_accessible(path) return !locked && open && ..() diff --git a/code/unit_tests/machine_tests.dm b/code/unit_tests/machine_tests.dm index 3c9258787e65..7b14762cb32d 100644 --- a/code/unit_tests/machine_tests.dm +++ b/code/unit_tests/machine_tests.dm @@ -48,15 +48,20 @@ /datum/unit_test/machine_construct_states_shall_be_valid name = "MACHINE: All mapped machines with construct states shall meet state requirements." +/// Returns a failure string if the unit test should fail, FALSE if it should succeed. +/// Mostly just a wrapper to handle things like unlocking prior to testing, or skipping the testing entirely. +/obj/machinery/proc/fail_construct_state_unit_test() + if(!construct_state) + return FALSE + return construct_state.fail_unit_test(src) + /datum/unit_test/machine_construct_states_shall_be_valid/start_test() var/failed = list() for(var/thing in SSmachines.machinery) var/obj/machinery/machine = thing if(failed[machine.type]) continue - if(!machine.construct_state) - continue - var/fail = machine.construct_state.fail_unit_test(machine) + var/fail = machine.fail_construct_state_unit_test() if(fail) failed[machine.type] = TRUE log_bad(fail) From 575723fd4ab823ec1b3403032be59389606cc5c5 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 00:58:09 -0400 Subject: [PATCH 351/512] Exempt light fixtures from panel opening unit test --- code/modules/power/lighting.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 9564d1220823..bc4d4bdba08c 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -250,6 +250,10 @@ update_light_status(TRUE) update_icon() +// Just... skip the entire test. We don't need to remove the bulbs from every single light just to test this. +/obj/machinery/light/fail_construct_state_unit_test() + return FALSE + /obj/machinery/light/cannot_transition_to(state_path, mob/user) if(lightbulb && !ispath(state_path, /decl/machine_construction/wall_frame/panel_closed)) return SPAN_WARNING("You must first remove the lightbulb!") From 818d55007524c801d9bba8a8620b9f7cbbedb781 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 01:09:18 -0400 Subject: [PATCH 352/512] Expand wall frame attackby validation for hackables --- .../machine_construction/airlock.dm | 2 +- .../wall_frame_hackable.dm | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/_machines_base/machine_construction/airlock.dm b/code/game/machinery/_machines_base/machine_construction/airlock.dm index 0c686e0b227a..48de7420a1b7 100644 --- a/code/game/machinery/_machines_base/machine_construction/airlock.dm +++ b/code/game/machinery/_machines_base/machine_construction/airlock.dm @@ -19,7 +19,7 @@ if(machine.construct_state != src) return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [type])." // Now test the down state - var/obj/item/wrench/wrench = new + var/static/obj/item/wrench/wrench = new if(!machine.attackby(wrench, user)) return "Machine [log_info_line(machine)] did not respond to attackby with wrench." if(machine.construct_state.type != down_state) diff --git a/code/game/machinery/_machines_base/machine_construction/wall_frame_hackable.dm b/code/game/machinery/_machines_base/machine_construction/wall_frame_hackable.dm index 2afb4460f3fa..7c1d98873bda 100644 --- a/code/game/machinery/_machines_base/machine_construction/wall_frame_hackable.dm +++ b/code/game/machinery/_machines_base/machine_construction/wall_frame_hackable.dm @@ -64,6 +64,29 @@ . += "Use a screwdriver close the hatch and tuck the exposed wires back in." . += "Use a parts replacer to view installed parts." +/decl/machine_construction/wall_frame/panel_closed/hackable/fail_test_state_transfer(obj/machinery/machine, mob/user) + var/static/obj/item/screwdriver/screwdriver = new + // Prevent access locks on doors from interfering with our interactions. + for(var/obj/item/stock_parts/access_lock/lock in machine.get_all_components_of_type(/obj/item/stock_parts/access_lock)) + lock.locked = FALSE + // Test hacking state + if(!machine.attackby(screwdriver, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver." + var/const/hacking_state = /decl/machine_construction/wall_frame/panel_closed/hackable/hacking // TODO: un-hardcode this + if(machine.construct_state.type != hacking_state) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [hacking_state])." + // Do it again to reverse that state change. + if(!machine.attackby(screwdriver, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with screwdriver on a second try." + if(machine.construct_state != src) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [type])." + // Now test the open state + var/static/obj/item/crowbar/crowbar = new + if(!machine.attackby(crowbar, user)) + return "Machine [log_info_line(machine)] did not respond to attackby with crowbar." + if(machine.construct_state.type != open_state) + return "Machine [log_info_line(machine)] had a construct_state of type [machine.construct_state.type] after screwdriver interaction (expected [open_state])." + /decl/machine_construction/wall_frame/panel_open/hackable/up_interaction(obj/item/I, mob/user, obj/machinery/machine) if(IS_CROWBAR(I)) TRANSFER_STATE(active_state) From 0405f491a2cfd289cf64305049fb143bf92b1b87 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 01:15:11 -0400 Subject: [PATCH 353/512] Make disconnecting a wall-mounted igniter use wirecutters --- code/game/machinery/igniter.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 9cbd9367bf7e..176f286e06bb 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -120,13 +120,13 @@ icon_state = "[base_state]-p" /obj/machinery/sparker/attackby(obj/item/used_item, mob/user) - if(IS_SCREWDRIVER(used_item)) + if(panel_open && IS_WIRECUTTER(used_item)) add_fingerprint(user) disable = !disable if(disable) - user.visible_message("[user] has disabled \the [src]!", "You disable the connection to \the [src].") - else if(!disable) - user.visible_message("[user] has reconnected \the [src]!", "You fix the connection to \the [src].") + user.visible_message(SPAN_WARNING("[user] has disabled \the [src]!"), SPAN_WARNING("You disable the connection to \the [src].")) + else + user.visible_message(SPAN_WARNING("[user] has reconnected \the [src]!"), SPAN_WARNING("You fix the connection to \the [src].")) update_icon() return TRUE else From 2a410186ea946d62b33c8813d9817c0682cf94e6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 02:05:33 -0400 Subject: [PATCH 354/512] Fix HIDETAIL not hiding tails --- code/modules/mob/living/carbon/human/update_icons.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 742203eeb2c0..c9be4821df52 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -404,6 +404,7 @@ Please contact me on #coderbus IRC. ~Carn x if(suit && (suit.flags_inv & HIDETAIL)) set_current_mob_overlay(HO_TAIL_LAYER, null, FALSE) set_current_mob_underlay(HU_TAIL_LAYER, null, update_icons) + return var/icon/tail_s = get_tail_icon_for_organ(tail_organ) var/tail_image = image(tail_s, icon_state = tail_state) From 9ffb8b96a371efcd337e0fe98eba3eaa6a9ede6b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 26 May 2025 03:57:57 -0400 Subject: [PATCH 355/512] Fix issues with ZM discovery and updates --- code/controllers/subsystems/zcopy.dm | 8 ++++++-- code/game/atoms_movable.dm | 17 +++++++++++++++-- code/modules/lighting/lighting_atom.dm | 12 ------------ code/modules/multiz/zmimic/mimic_movable.dm | 17 ++--------------- 4 files changed, 23 insertions(+), 31 deletions(-) diff --git a/code/controllers/subsystems/zcopy.dm b/code/controllers/subsystems/zcopy.dm index c5715af524bd..cedb5b263a4c 100644 --- a/code/controllers/subsystems/zcopy.dm +++ b/code/controllers/subsystems/zcopy.dm @@ -502,12 +502,13 @@ SUBSYSTEM_DEF(zcopy) ZM_RECORD_START + var/above_needs_discovery = FALSE if (!object.bound_overlay) var/atom/movable/openspace/mimic/M = new(T) object.bound_overlay = M + M.z_flags = object.z_flags // Necessary to ensure MOVABLE_IS_ON_ZTURF works M.associated_atom = object - if (TURF_IS_MIMICKING(M.loc)) - .(M) + above_needs_discovery = TRUE var/override_depth var/original_type = object.type @@ -558,6 +559,9 @@ SUBSYSTEM_DEF(zcopy) ZM_RECORD_STOP ZM_RECORD_WRITE(discovery_stats, "Depth [OO.depth] on [OO.z]") + if (above_needs_discovery && MOVABLE_IS_ON_ZTURF(OO)) + discover_movable(OO) // recursion! + return FALSE /datum/controller/subsystem/zcopy/proc/flush_z_state(turf/T) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 5685a17731ca..216ecaeadee4 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -165,6 +165,7 @@ // Both the origin and destination are turfs with different areas. // When either origin or destination is a turf and the other is not. var/is_new_area = (is_origin_turf ^ is_destination_turf) || (is_origin_turf && is_destination_turf && loc.loc != destination.loc) + var/was_below_z_turf = MOVABLE_IS_BELOW_ZTURF(src) var/atom/origin = loc loc = destination @@ -206,6 +207,18 @@ L = thing L.source_atom.update_light() + // Z-Mimic. + if (bound_overlay) + // The overlay will handle cleaning itself up on non-openspace turfs. + if (isturf(destination)) + bound_overlay.forceMove(get_step(src, UP)) + if (dir != bound_overlay.dir) + bound_overlay.set_dir(dir) + else // Not a turf, so we need to destroy immediately instead of waiting for the destruction timer to proc. + qdel(bound_overlay) + else if (isturf(loc) && (!origin || !was_below_z_turf) && MOVABLE_SHALL_MIMIC(src)) + SSzcopy.discover_movable(src) + if(buckled_mob) if(isturf(loc)) buckled_mob.glide_size = glide_size // Setting loc apparently does animate with glide size. @@ -228,7 +241,7 @@ /atom/movable/Move(...) var/old_loc = loc - + var/was_below_z_turf = MOVABLE_IS_BELOW_ZTURF(src) . = ..() if(.) @@ -264,7 +277,7 @@ bound_overlay.forceMove(get_step(src, UP)) if (bound_overlay.dir != dir) bound_overlay.set_dir(dir) - else if (isturf(loc) && (!old_loc || !TURF_IS_MIMICKING(old_loc)) && MOVABLE_SHALL_MIMIC(src)) + else if (isturf(loc) && (!old_loc || !was_below_z_turf) && MOVABLE_SHALL_MIMIC(src)) SSzcopy.discover_movable(src) //called when src is thrown into hit_atom diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm index 703cbd088103..b4e848adad34 100644 --- a/code/modules/lighting/lighting_atom.dm +++ b/code/modules/lighting/lighting_atom.dm @@ -83,15 +83,3 @@ T.recalc_atom_opacity() if (old_has_opaque_atom != T.has_opaque_atom) T.reconsider_lights() - -/atom/movable/forceMove() - . = ..() - - if (light_source_solo) - light_source_solo.source_atom.update_light() - else if (light_source_multi) - var/datum/light_source/L - var/thing - for (thing in light_source_multi) - L = thing - L.source_atom.update_light() diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm index 23d2964cf060..beb749f6fc68 100644 --- a/code/modules/multiz/zmimic/mimic_movable.dm +++ b/code/modules/multiz/zmimic/mimic_movable.dm @@ -4,17 +4,6 @@ /// Movable-level Z-Mimic flags. This uses ZMM_* flags, not ZM_* flags. var/z_flags = 0 -/atom/movable/forceMove(atom/dest) - . = ..(dest) - if (. && bound_overlay) - // The overlay will handle cleaning itself up on non-openspace turfs. - if (isturf(dest)) - bound_overlay.forceMove(get_step(src, UP)) - if (dir != bound_overlay.dir) - bound_overlay.set_dir(dir) - else // Not a turf, so we need to destroy immediately instead of waiting for the destruction timer to proc. - qdel(bound_overlay) - /atom/movable/set_dir(ndir) . = ..() if (. && bound_overlay) @@ -24,9 +13,7 @@ if (!bound_overlay || !isturf(loc)) return - var/turf/T = loc - - if (TURF_IS_MIMICKING(T.above)) + if (MOVABLE_IS_BELOW_ZTURF(src)) SSzcopy.queued_overlays += bound_overlay bound_overlay.queued += 1 else @@ -161,7 +148,7 @@ /atom/movable/openspace/mimic/forceMove(turf/dest) var/atom/old_loc = loc . = ..() - if (TURF_IS_MIMICKING(dest)) + if (MOVABLE_IS_ON_ZTURF(src)) if (destruction_timer) deltimer(destruction_timer) destruction_timer = null From 62fd33e66c64a2eec0f4c9e8403f6c5091dabd91 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Tue, 27 May 2025 00:57:06 +0000 Subject: [PATCH 356/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index fa25dd37d04d..e7f339e388a8 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -84,12 +84,6 @@

    Martin Rivard updated:

    • removed calculate_affecting_pressure() hardcoding
    - -

    25 March 2025

    -

    Penelope Haze updated:

    -
      -
    • Adjusts how suffocation works, meaning characters who were drowning or in asystole start breathing as soon as the issue is resolved, rather than counting down a timer instead. This might make brief bouts of drowning/cardiac arrest more survivable. Please report any weirdness with breathing/suffocation on the issue tracker.
    • -
    From c0c2db323f44c851af959acedf8086e03120d8f1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 23 May 2025 15:15:37 -0400 Subject: [PATCH 357/512] Lower FileAlreadyIncluded pragma to disabled --- code/___opendream_linting.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/___opendream_linting.dm b/code/___opendream_linting.dm index 446ad58ad57b..e9fe9369d681 100644 --- a/code/___opendream_linting.dm +++ b/code/___opendream_linting.dm @@ -1,6 +1,7 @@ #ifdef OPENDREAM //1000-1999 -#pragma FileAlreadyIncluded error +// FileAlreadyIncluded trips up on modpack DMEs +#pragma FileAlreadyIncluded disabled #pragma MissingIncludedFile error #pragma MisplacedDirective error #pragma UndefineMissingDirective error From 1a62b0550a4350d7df28a34116a64ea6c9ed9b6d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 28 May 2025 16:16:40 -0400 Subject: [PATCH 358/512] Fix has_trait not working for species traits --- code/datums/traits/_traits.dm | 44 ++++++++++++++++-------------- code/modules/client/preferences.dm | 2 +- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/code/datums/traits/_traits.dm b/code/datums/traits/_traits.dm index ad1041e32da2..9263cc2fc254 100644 --- a/code/datums/traits/_traits.dm +++ b/code/datums/traits/_traits.dm @@ -9,12 +9,16 @@ return 1 /mob/living - var/list/traits + /// A list of mob-specific traits, for when the list differs from the species list. + /// Overrides the species list; if it's identical to it, it will be unset. + /// Code using the traits system should use get_traits() instead. + VAR_PRIVATE/list/_mob_traits /mob/living/proc/has_trait(trait_type, trait_level = TRAIT_LEVEL_EXISTS) SHOULD_NOT_OVERRIDE(TRUE) SHOULD_NOT_SLEEP(TRUE) - return (trait_type in traits) && (!trait_level || traits[trait_type] >= trait_level) + var/list/actual_traits = get_traits() + return (trait_type in actual_traits) && (!trait_level || actual_traits[trait_type] >= trait_level) /mob/living/proc/GetTraitLevel(trait_type) SHOULD_NOT_SLEEP(TRUE) @@ -30,7 +34,7 @@ /mob/living/get_traits() RETURN_TYPE(/list) var/decl/species/our_species = get_species() - return traits || our_species?.traits + return _mob_traits || our_species?.traits /mob/living/proc/set_trait(trait_type, trait_level) SHOULD_NOT_SLEEP(TRUE) @@ -38,23 +42,23 @@ var/decl/trait/trait = GET_DECL(trait_type) if(!trait.validate_level(trait_level)) return FALSE - if(our_species && !traits) // If species traits haven't been setup before, check if we need to do so now + if(our_species && !_mob_traits) // If species traits haven't been setup before, check if we need to do so now var/species_level = our_species.traits[trait_type] if(species_level == trait_level) // Matched the default species trait level, ignore return TRUE - traits = our_species.traits.Copy() // The setup is to simply copy the species list of traits - if(!(trait_type in traits)) - LAZYSET(traits, trait_type, trait_level) + _mob_traits = our_species.traits.Copy() // The setup is to simply copy the species list of traits + if(!(trait_type in _mob_traits)) + LAZYSET(_mob_traits, trait_type, trait_level) trait.apply_trait(src) return TRUE /mob/living/proc/RemoveTrait(trait_type, canonize = TRUE) var/decl/species/our_species = get_species() // If traits haven't been set up, but we're trying to remove a trait that exists on the species then set up traits - if(!traits && LAZYISIN(our_species?.traits, trait_type)) - traits = our_species.traits.Copy() - if(LAZYLEN(traits)) - LAZYREMOVE(traits, trait_type) + if(!_mob_traits && LAZYISIN(our_species?.traits, trait_type)) + _mob_traits = our_species.traits.Copy() + if(LAZYLEN(_mob_traits)) + LAZYREMOVE(_mob_traits, trait_type) // Check if we can just default back to species traits. if(canonize) CanonizeTraits() @@ -68,23 +72,21 @@ else if(our_species?.traits[trait_type] != GetTraitLevel(trait_type)) set_trait(trait_type, our_species?.traits[trait_type]) +/mob/living/proc/ClearExtrinsicTraits() + _mob_traits = null + /// Sets the traits list to null if it's identical to the species list. /// Returns TRUE if the list was reset and FALSE otherwise. /mob/living/proc/CanonizeTraits() - if(!traits) // Already in canonical form. + if(!_mob_traits) // Already in canonical form. return FALSE var/decl/species/our_species = get_species() if(!our_species) // Doesn't apply without a species. return FALSE - var/list/missing_traits = traits ^ our_species?.traits - var/list/matched_traits = traits & our_species?.traits - if(LAZYLEN(missing_traits)) - return FALSE - for(var/trait in matched_traits) // inside this loop we know our_species exists and has traits - if(traits[trait] != our_species.traits[trait]) - return FALSE - traits = null - return TRUE + if(_mob_traits ~= our_species.traits) + _mob_traits = null + return TRUE + return FALSE /decl/trait abstract_type = /decl/trait diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index bd4d9581878e..6733e10c9f15 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -355,7 +355,7 @@ var/global/list/time_prefs_fixed = list() player_setup.sanitize_setup() validate_comments_record() // Make sure a record has been generated for this character. character.comments_record_id = comments_record_id - character.traits = null + character.ClearExtrinsicTraits() var/decl/bodytype/new_bodytype = get_bodytype_decl() if(species == character.get_species_name()) From 8fb897a3c247ed910aaafa2824a99432515c7709 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 28 May 2025 16:32:21 -0400 Subject: [PATCH 359/512] Convert trait proc names to snake_case --- code/datums/traits/_traits.dm | 16 ++++++++-------- code/modules/client/preferences.dm | 2 +- code/modules/materials/_materials.dm | 2 +- code/modules/reagents/chems/chems_alcohol.dm | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/code/datums/traits/_traits.dm b/code/datums/traits/_traits.dm index 9263cc2fc254..6fbb9921ea13 100644 --- a/code/datums/traits/_traits.dm +++ b/code/datums/traits/_traits.dm @@ -20,7 +20,7 @@ var/list/actual_traits = get_traits() return (trait_type in actual_traits) && (!trait_level || actual_traits[trait_type] >= trait_level) -/mob/living/proc/GetTraitLevel(trait_type) +/mob/living/proc/get_trait_level(trait_type) SHOULD_NOT_SLEEP(TRUE) var/traits = get_traits() if(!traits) @@ -52,7 +52,7 @@ trait.apply_trait(src) return TRUE -/mob/living/proc/RemoveTrait(trait_type, canonize = TRUE) +/mob/living/proc/remove_trait(trait_type, canonize = TRUE) var/decl/species/our_species = get_species() // If traits haven't been set up, but we're trying to remove a trait that exists on the species then set up traits if(!_mob_traits && LAZYISIN(our_species?.traits, trait_type)) @@ -61,23 +61,23 @@ LAZYREMOVE(_mob_traits, trait_type) // Check if we can just default back to species traits. if(canonize) - CanonizeTraits() + canonize_traits() /// Removes a trait unless it exists on the species. /// If it does exist on the species, we reset it to the species' trait level. -/mob/living/proc/RemoveExtrinsicTrait(trait_type) +/mob/living/proc/remove_extrinsic_trait(trait_type) var/decl/species/our_species = get_species() if(!LAZYACCESS(our_species?.traits, trait_type)) - RemoveTrait(trait_type) - else if(our_species?.traits[trait_type] != GetTraitLevel(trait_type)) + remove_trait(trait_type) + else if(our_species?.traits[trait_type] != get_trait_level(trait_type)) set_trait(trait_type, our_species?.traits[trait_type]) -/mob/living/proc/ClearExtrinsicTraits() +/mob/living/proc/clear_extrinsic_traits() _mob_traits = null /// Sets the traits list to null if it's identical to the species list. /// Returns TRUE if the list was reset and FALSE otherwise. -/mob/living/proc/CanonizeTraits() +/mob/living/proc/canonize_traits() if(!_mob_traits) // Already in canonical form. return FALSE var/decl/species/our_species = get_species() diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 6733e10c9f15..bc74afa3ffb8 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -355,7 +355,7 @@ var/global/list/time_prefs_fixed = list() player_setup.sanitize_setup() validate_comments_record() // Make sure a record has been generated for this character. character.comments_record_id = comments_record_id - character.ClearExtrinsicTraits() + character.clear_extrinsic_traits() var/decl/bodytype/new_bodytype = get_bodytype_decl() if(species == character.get_species_name()) diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index 5f7e96eb47b1..68457c18328b 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -927,7 +927,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) var/malus_level = 0 for(var/decl/trait/intolerance as anything in intolerances) - malus_level = max(malus_level, subject.GetTraitLevel(intolerance.type)) + malus_level = max(malus_level, subject.get_trait_level(intolerance.type)) if(!malus_level) return 1 diff --git a/code/modules/reagents/chems/chems_alcohol.dm b/code/modules/reagents/chems/chems_alcohol.dm index 44384d64365f..76794c2be308 100644 --- a/code/modules/reagents/chems/chems_alcohol.dm +++ b/code/modules/reagents/chems/chems_alcohol.dm @@ -51,7 +51,7 @@ ..() M.add_chemical_effect(CE_ALCOHOL, 1) - var/strength_mod = (M.GetTraitLevel(/decl/trait/malus/ethanol) * 2.5) || 1 + var/strength_mod = (M.get_trait_level(/decl/trait/malus/ethanol) * 2.5) || 1 var/effective_dose = LAZYACCESS(M.chem_doses, type) * strength_mod * (1 + REAGENT_VOLUME(holder, type)/60) //drinking a LOT will make you go down faster if(effective_dose >= strength) // Early warning From 88ebe188b219cfb5fbac173fe5748591e7d61fa9 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 29 May 2025 00:58:26 +0000 Subject: [PATCH 360/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index e7f339e388a8..f16e5be1a304 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -78,12 +78,6 @@

    Martin Rivard updated:

    • fixed portable flasher sprite offset
    - -

    27 March 2025

    -

    Martin Rivard updated:

    -
      -
    • removed calculate_affecting_pressure() hardcoding
    • -
    From 9924aa1a96ceee873d96680731960c5bb0d52b54 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sat, 31 May 2025 00:57:06 +0000 Subject: [PATCH 361/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index f16e5be1a304..9a98da8995fa 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -72,12 +72,6 @@

    Elizabeth updated:

  1. many of the buildings in Shaded Hills now use timber-framed, plastered, and/or wattle-and-daub walls instead of just log walls
  2. added a new lobby track to Shaded Hills: Adventure by Alexander Nakarada.
  3. - -

    29 March 2025

    -

    Martin Rivard updated:

    -
      -
    • fixed portable flasher sprite offset
    • -
    From 79dc45e85037a719bbd22e82707eaf0b9ff542c7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 3 Jun 2025 07:14:19 -0400 Subject: [PATCH 362/512] Fix ion thrusters only working when unpowered --- code/modules/overmap/ships/machines/ion_thruster.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/overmap/ships/machines/ion_thruster.dm b/code/modules/overmap/ships/machines/ion_thruster.dm index f1ffae4b7f37..a176c60e7ce5 100644 --- a/code/modules/overmap/ships/machines/ion_thruster.dm +++ b/code/modules/overmap/ships/machines/ion_thruster.dm @@ -58,7 +58,7 @@ . = ..() /obj/machinery/ion_thruster/proc/get_thrust() - if(use_power && (stat & NOPOWER)) + if(use_power && !(stat & NOPOWER)) use_power_oneoff(thrust_cost) return thrust_limit return 0 From ea01b70d0bc686d178054733009391a71b774367 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 3 Jun 2025 07:33:38 -0400 Subject: [PATCH 363/512] Prevent suit cyclers from rotating with shuttles --- code/game/machinery/suit_cycler.dm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm index d202b7e6b1d2..757f37793cf3 100644 --- a/code/game/machinery/suit_cycler.dm +++ b/code/game/machinery/suit_cycler.dm @@ -521,8 +521,5 @@ boots.refit_for_bodytype(target_bodytype) boots.SetName("refitted [initial(boots.name)]") -// Update icon on rotate so that overlays rotate as well -/obj/machinery/suit_cycler/shuttle_rotate(angle) - . = ..() - if(.) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, queue_icon_update)), 1) \ No newline at end of file +/obj/machinery/suit_cycler/shuttle_rotate(angle) // DO NOT CHANGE DIR. Change this when someone adds directional sprites for suit cyclers. + return \ No newline at end of file From d9ad05ae4def9a100cccf401b937df3a76c3273b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 3 Jun 2025 05:51:26 -0400 Subject: [PATCH 364/512] Fix runtimes from items in nullspace being forcemoved --- code/game/atoms.dm | 2 +- code/game/atoms_movable.dm | 2 +- code/modules/clothing/under/accessories/accessory.dm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 009f25d46419..d5040cdd3acd 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -614,7 +614,7 @@ - Return: The result of the forceMove() at the end. */ /atom/movable/proc/dropInto(var/atom/destination) - while(istype(destination)) + while(!QDELETED(src) && istype(destination)) var/atom/drop_destination = destination.onDropInto(src) if(!istype(drop_destination) || drop_destination == destination) return forceMove(destination) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 216ecaeadee4..723183aa1d25 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -153,7 +153,7 @@ /atom/movable/proc/forceMove(atom/destination) - if(QDELETED(src) && !QDESTROYING(src) && !isnull(destination)) + if(QDELETED(src) && !isnull(destination)) CRASH("Attempted to forceMove a QDELETED [src] out of nullspace!!!") if(loc == destination) diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 5d3becfdf660..daf513b8b2c1 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -32,7 +32,7 @@ var/obj/item/clothing/suit = loc if(istype(suit)) if(user) - usr.put_in_hands(src) + user.put_in_hands(src) src.add_fingerprint(user) else dropInto(loc) From 62a35da16b1f0df51054d82273c3aa8278e5ee05 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 5 Jun 2025 21:30:31 -0400 Subject: [PATCH 365/512] Make discover_movable no-op prior to zcopy init --- code/controllers/subsystems/zcopy.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/controllers/subsystems/zcopy.dm b/code/controllers/subsystems/zcopy.dm index cedb5b263a4c..362a817d399f 100644 --- a/code/controllers/subsystems/zcopy.dm +++ b/code/controllers/subsystems/zcopy.dm @@ -493,6 +493,8 @@ SUBSYSTEM_DEF(zcopy) // return: is-invalid /datum/controller/subsystem/zcopy/proc/discover_movable(atom/movable/object) ASSERT(!QDELETED(object)) + if(init_state < SS_INITSTATE_STARTED) + return FALSE // no-op, discover_movable is only valid during or after zcopy init var/turf/Tloc = object.loc if (!isturf(Tloc) || !Tloc.above) From b9ec316a9d07be612225eacfce5f8cf6570eb138 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 5 Jun 2025 20:24:07 -0400 Subject: [PATCH 366/512] Fix solid turfs not blocking spacedrift --- code/modules/mob/mob.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9fc34abeee9f..2eeec9d0e29b 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1429,6 +1429,8 @@ for(var/turf/neighbor in RANGE_TURFS(my_turf, 1)) if(neighbor == my_turf) continue + if(neighbor.is_wall() || neighbor.is_floor()) + return neighbor var/dense_object = neighbor.get_first_dense_object(exceptions = src) if(dense_object) return dense_object From 69c9ed221861ffea8b6a484983b47aa7b35684ee Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 5 Jun 2025 20:32:40 -0400 Subject: [PATCH 367/512] Add some comments to spacemove defines and procs --- code/__defines/misc.dm | 7 ++++--- code/game/atoms_movable.dm | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 3a158561517b..7755d925c53a 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -382,6 +382,7 @@ #define CRAYON_DRAW_ARROW "arrow" // Enum for results of is_space_movement_permitted() -#define SPACE_MOVE_SUPPORTED (-1) -#define SPACE_MOVE_FORBIDDEN 0 -#define SPACE_MOVE_PERMITTED 1 +// Note that it may also return an instance of /atom/movable, which acts as SPACE_MOVE_SUPPORTED. +#define SPACE_MOVE_SUPPORTED (-1) //! Mob should run space-slipping checks. +#define SPACE_MOVE_FORBIDDEN 0 //! Mob should begin spacedrift. +#define SPACE_MOVE_PERMITTED 1 //! Mob should stop/prevent spacedrift. diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index fd2684a36260..8dc1f1008fcd 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -58,7 +58,8 @@ SSspacedrift.processing[src] = src return 1 -//return SPACE_MOVE_FORBIDDEN to space drift, SPACE_MOVE_PERMITTED to stop, SPACE_MOVE_SUPPORTED for mobs to handle space slips +// return SPACE_MOVE_FORBIDDEN to space drift, SPACE_MOVE_PERMITTED to stop, SPACE_MOVE_SUPPORTED for mobs to handle space slips +// Note that it may also return an instance of /atom/movable, which acts as SPACE_MOVE_SUPPORTED and results in pushing the movable backwards. /atom/movable/proc/is_space_movement_permitted(allow_movement = FALSE) if(!simulated) return SPACE_MOVE_PERMITTED From 828ab97147b29ad88b876e79f850132e7eab28ca Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Jun 2025 18:07:39 -0400 Subject: [PATCH 368/512] Fix being unable to attack fabricators --- code/modules/fabrication/fabricator_intake.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/modules/fabrication/fabricator_intake.dm b/code/modules/fabrication/fabricator_intake.dm index 2cddeb34053e..9b60a8bb374e 100644 --- a/code/modules/fabrication/fabricator_intake.dm +++ b/code/modules/fabrication/fabricator_intake.dm @@ -125,6 +125,11 @@ visible_message(SPAN_NOTICE("\The [user] inserts \the [O] into \the [src], and after a second or so of loud clicking, the fabricator beeps and spits it out again.")) return TRUE + // Attempt to bash on harm intent. + // I'd like for this to be a more general parent call but instead it's just a direct check-and-call. + else if(!(O.item_flags & ITEM_FLAG_NO_BLUDGEON) && (. = bash(O, user))) // Bash successful, no need to try intake. + return + // TEMP HACK FIX: // Autolathes currently do not process atom contents. As a workaround, refuse all atoms with contents. if(length(O.contents) && !ignore_input_contents_length) From be0681aafc33822acde8d8e0e0063d1fbdaf91e5 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Jun 2025 18:07:50 -0400 Subject: [PATCH 369/512] Fix being unable to attack vending machines --- code/game/machinery/vending/_vending.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/game/machinery/vending/_vending.dm b/code/game/machinery/vending/_vending.dm index 8e0f352a8e1e..ca5bf4b52a5b 100644 --- a/code/game/machinery/vending/_vending.dm +++ b/code/game/machinery/vending/_vending.dm @@ -186,10 +186,7 @@ if((user.a_intent == I_HELP) && attempt_to_stock(W, user)) return TRUE - if((obj_flags & OBJ_FLAG_ANCHORABLE) && (IS_WRENCH(W) || IS_HAMMER(W))) - wrench_floor_bolts(user, null, W) - power_change() - return + return ..() // handle anchoring and bashing /obj/machinery/vending/state_transition(decl/machine_construction/new_state) . = ..() From b1e66a202838de42b4ba2f45e4aec98cc6b768fe Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 8 Jun 2025 01:04:32 +0000 Subject: [PATCH 370/512] Automatic changelog generation [ci skip] --- html/changelog.html | 9 --------- 1 file changed, 9 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 9a98da8995fa..928bd534bf95 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -63,15 +63,6 @@

    Cerebulon updated:

    • Fixed tajaran sprite sheet overrides.
    - -

    06 April 2025

    -

    Elizabeth updated:

    -
      -
    • tweaked the Forester's Hut on Shaded Hills to be more compact and have timber-framed walls
    • -
    • tweaked the inn backroom on Shaded Hills
    • -
    • many of the buildings in Shaded Hills now use timber-framed, plastered, and/or wattle-and-daub walls instead of just log walls
    • -
    • added a new lobby track to Shaded Hills: Adventure by Alexander Nakarada.
    • -
    From 7820d115e8e060b4347aea0f60dadb64573dcfce Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 8 May 2025 20:49:24 -0400 Subject: [PATCH 371/512] Fix clothing custom item icons --- code/game/objects/items/__item.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 14f792639a88..f520a9dcbfe4 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -963,8 +963,8 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. /obj/item/clothing/inherit_custom_item_data(var/datum/custom_item/citem) . = ..() - base_clothing_icon = icon - base_clothing_state = icon_state + base_clothing_icon = citem.item_icon + base_clothing_state = citem.item_state /obj/item/proc/is_special_cutting_tool(var/high_power) return FALSE From e685cf644325e2bc2d87ea4fedd4d3e25661888f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 9 May 2025 02:08:00 -0400 Subject: [PATCH 372/512] Fix refitted clothing icons being overwritten --- code/modules/clothing/_clothing.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index 9b25f567400c..0eb6cdcefe92 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -296,9 +296,9 @@ var/last_icon = icon var/species_icon = LAZYACCESS(sprite_sheets, target_bodytype) if(species_icon && (check_state_in_icon(ICON_STATE_INV, species_icon) || check_state_in_icon(ICON_STATE_WORLD, species_icon))) - icon = species_icon + base_clothing_icon = species_icon - if(last_icon != icon) + if(last_icon != base_clothing_icon) reconsider_single_icon() update_clothing_icon() From b991c95579e2e687fbaac52256ac0ef49520d807 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 9 May 2025 02:08:14 -0400 Subject: [PATCH 373/512] Add checks to clothing bodytype refit code --- code/modules/clothing/_clothing.dm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index 0eb6cdcefe92..50f2af1aa631 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -234,10 +234,10 @@ if(!base_clothing_icon) base_clothing_icon = initial(icon) - set_icon(base_clothing_icon) - if(!base_clothing_state) + set_icon(base_clothing_icon) // todo: update use_single_icon and has_inventory_icon when we do this + if(!base_clothing_state) // todo: remove this var if unnecessary? we enforce that clothes use world/inventory states base_clothing_state = initial(icon_state) - set_icon_state(base_clothing_state) + set_icon_state(base_clothing_state) // should this just do icon_state = get_world_inventory_state? icon_state = JOINTEXT(list(get_world_inventory_state(), get_clothing_state_modifier())) if(markings_state_modifier && markings_color) add_overlay(mutable_appearance(icon, "[icon_state][markings_state_modifier]", markings_color)) @@ -295,7 +295,8 @@ var/last_icon = icon var/species_icon = LAZYACCESS(sprite_sheets, target_bodytype) - if(species_icon && (check_state_in_icon(ICON_STATE_INV, species_icon) || check_state_in_icon(ICON_STATE_WORLD, species_icon))) + // If we use the single icon system we need a world or icon state, otherwise we don't. + if(species_icon && (!use_single_icon || (check_state_in_icon(ICON_STATE_INV, species_icon) || check_state_in_icon(ICON_STATE_WORLD, species_icon)))) base_clothing_icon = species_icon if(last_icon != base_clothing_icon) From aeaa19f56a56fbfa260c04ce4c21ecd242e48bd6 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 9 May 2025 02:08:27 -0400 Subject: [PATCH 374/512] Add additional clothing unit test checks --- code/unit_tests/clothing.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/unit_tests/clothing.dm b/code/unit_tests/clothing.dm index 4bf9ea0260d8..a7fe3e678156 100644 --- a/code/unit_tests/clothing.dm +++ b/code/unit_tests/clothing.dm @@ -35,6 +35,11 @@ if(!(initial_state in reported_failures[initial_icon])) LAZYADD(reported_failures[initial_icon], initial_state) clothing_fails += "missing initial state '[initial_state]' in initial icon '[initial_icon]'" + // World but no inventory is fine; inventory but no world is disallowed. + else if(initial_icon == ICON_STATE_INV && !check_state_in_icon(ICON_STATE_WORLD, initial_icon)) + if(!(initial_state in reported_failures[ICON_STATE_WORLD])) + LAZYADD(reported_failures[ICON_STATE_WORLD], initial_state) + clothing_fails += "has 'inventory' initial state but no 'world' state in initial icon '[initial_icon]'" if(initial_item_state) clothing_fails += "legacy item state set '[initial_item_state]'" From e68374aa3f7b1df2fbc210de832b8acb2df48812 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 8 Jun 2025 05:00:57 -0400 Subject: [PATCH 375/512] Remove unnecessary base clothing icon/state system --- code/game/objects/items/__item.dm | 3 +-- code/modules/clothing/_clothing.dm | 15 +++------------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index f520a9dcbfe4..0e52f909ceba 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -963,8 +963,7 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. /obj/item/clothing/inherit_custom_item_data(var/datum/custom_item/citem) . = ..() - base_clothing_icon = citem.item_icon - base_clothing_state = citem.item_state + reconsider_single_icon() /obj/item/proc/is_special_cutting_tool(var/high_power) return FALSE diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index 50f2af1aa631..bad50bf1985b 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -39,9 +39,6 @@ var/markings_color // for things like colored parts of labcoats or shoes var/should_display_id = TRUE var/fallback_slot - // Used to track our icon, or custom icon, for resetting when accessories are added/removed - var/base_clothing_icon - var/base_clothing_state /obj/item/clothing/get_equipment_tint() return tint @@ -232,12 +229,6 @@ update_clothing_icon() return - if(!base_clothing_icon) - base_clothing_icon = initial(icon) - set_icon(base_clothing_icon) // todo: update use_single_icon and has_inventory_icon when we do this - if(!base_clothing_state) // todo: remove this var if unnecessary? we enforce that clothes use world/inventory states - base_clothing_state = initial(icon_state) - set_icon_state(base_clothing_state) // should this just do icon_state = get_world_inventory_state? icon_state = JOINTEXT(list(get_world_inventory_state(), get_clothing_state_modifier())) if(markings_state_modifier && markings_color) add_overlay(mutable_appearance(icon, "[icon_state][markings_state_modifier]", markings_color)) @@ -296,10 +287,10 @@ var/last_icon = icon var/species_icon = LAZYACCESS(sprite_sheets, target_bodytype) // If we use the single icon system we need a world or icon state, otherwise we don't. - if(species_icon && (!use_single_icon || (check_state_in_icon(ICON_STATE_INV, species_icon) || check_state_in_icon(ICON_STATE_WORLD, species_icon)))) - base_clothing_icon = species_icon + if(species_icon && check_state_in_icon(ICON_STATE_WORLD, species_icon)) + icon = species_icon - if(last_icon != base_clothing_icon) + if(last_icon != icon) reconsider_single_icon() update_clothing_icon() From 951484b4d3d3c55b57053c5724bfe36288019cbd Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 24 Aug 2024 20:16:16 -0400 Subject: [PATCH 376/512] Fix errors discovered by unit tests --- .../species/bayliens/skrell/datum/language.dm | 35 +++++++++++++++++++ .../neoavians/datum/species_bodytypes.dm | 2 ++ 2 files changed, 37 insertions(+) create mode 100644 mods/species/bayliens/skrell/datum/language.dm diff --git a/mods/species/bayliens/skrell/datum/language.dm b/mods/species/bayliens/skrell/datum/language.dm new file mode 100644 index 000000000000..649ee1649e6c --- /dev/null +++ b/mods/species/bayliens/skrell/datum/language.dm @@ -0,0 +1,35 @@ +var/global/list/first_name_skrell = file2list("mods/species/bayliens/skrell/names/first_name_skrell.txt") +var/global/list/last_name_skrell = file2list("mods/species/bayliens/skrell/names/last_name_skrell.txt") + +/decl/language/skrell + name = "Common Skrellian" + desc = "A melodic and complex language spoken by the Skrell of the Oligarchy. Some of the notes are inaudible to humans." + speech_verb = "warbles" + ask_verb = "trills" + exclaim_verb = "croaks" + colour = "selenian" + key = "k" + flags = LANG_FLAG_WHITELISTED + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","'","!") + shorthand = "SK" + partial_understanding = list( + /decl/language/skrell/casteless = 90 + ) + +/decl/language/skrell/casteless + name = "Ue-Katish Cant" + desc = "A flat and emotionless language spoken mainly by Ue-Katish pirates, laden with slurs and insults." + speech_verb = "croaks" + ask_verb = "trills" + exclaim_verb = "chirps" + colour = "selenian" + key = "p" + flags = LANG_FLAG_WHITELISTED + syllables = list("qra","xa","vilz*","s!zaao","qu!*m","girx","vol","xrim","za-r*oo","qu-xx","qix","qa'taz","zix","tuep","!","*") + shorthand = "UK" + partial_understanding = list( + /decl/language/skrell = 90 + ) + +/decl/language/skrell/get_random_name(var/gender) + return capitalize(pick(global.first_name_skrell)) + capitalize(pick(global.last_name_skrell)) \ No newline at end of file diff --git a/mods/species/neoavians/datum/species_bodytypes.dm b/mods/species/neoavians/datum/species_bodytypes.dm index a83f74e9b60c..03e8a9e5657e 100644 --- a/mods/species/neoavians/datum/species_bodytypes.dm +++ b/mods/species/neoavians/datum/species_bodytypes.dm @@ -26,6 +26,7 @@ uid = "bodytype_prosthetic_raptor" /decl/bodytype/avian + abstract_type = /decl/bodytype/avian name = "avian" bodytype_category = BODYTYPE_AVIAN icon_base = 'mods/species/neoavians/icons/body.dmi' @@ -84,6 +85,7 @@ uid = "bodytype_avian_raptor" /decl/bodytype/avian/additive + abstract_type = /decl/bodytype/avian/additive name = "avian, additive" icon_base = 'mods/species/neoavians/icons/body_add.dmi' health_hud_intensity = 3 From 7361804850e6e0e1082252c44e143a7217d3f167 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 27 Aug 2024 17:04:51 -0400 Subject: [PATCH 377/512] Add support for migration directories to update_paths --- tools/mapmerge2/update_paths.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/mapmerge2/update_paths.py b/tools/mapmerge2/update_paths.py index b9e095b5ee32..f0b6af46072b 100644 --- a/tools/mapmerge2/update_paths.py +++ b/tools/mapmerge2/update_paths.py @@ -190,9 +190,20 @@ def main(args): print("Using replacement:", args.update_source) updates = [args.update_source] else: - with open(args.update_source) as f: - updates = [line for line in f if line and not line.startswith("#") and not line.isspace()] - print(f"Using {len(updates)} replacements from file:", args.update_source) + # optional support for passing a directory + if os.path.isdir(args.update_source): + updates = [] + for root, _, files in os.walk(args.update_source): + for filepath in files: + if filepath.endswith(".txt"): + path = os.path.join(root, filepath) + with open(path) as f: + updates.extend(line for line in f if line and not line.startswith("#") and not line.isspace()) + print(f"Using {len(updates)} replacements from directory:", args.update_source) + else: + with open(args.update_source) as f: + updates = [line for line in f if line and not line.startswith("#") and not line.isspace()] + print(f"Using {len(updates)} replacements from file:", args.update_source) if args.map: update_map(args.map, updates, verbose=args.verbose) From c3a2bba560527978b810ba8b0c981dc2ad85148d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 27 Aug 2024 18:47:04 -0400 Subject: [PATCH 378/512] Add missing oldtile floor decals --- code/game/turfs/flooring/_flooring_decals.dm | 110 +++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/code/game/turfs/flooring/_flooring_decals.dm b/code/game/turfs/flooring/_flooring_decals.dm index 57b678005ee5..50ca2d36ab71 100644 --- a/code/game/turfs/flooring/_flooring_decals.dm +++ b/code/game/turfs/flooring/_flooring_decals.dm @@ -1525,3 +1525,113 @@ var/global/list/floor_decals = list() /obj/effect/floor_decal/arrows name = "floor arrows" icon_state = "arrows" + +//Old tile, taken from Polaris +//TODO: Change these colors to use color defines? +/obj/effect/floor_decal/corner_oldtile + name = "corner oldtile" + icon_state = "corner_oldtile" + +/obj/effect/floor_decal/corner_oldtile/white + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#d9d9d9" + +/obj/effect/floor_decal/corner_oldtile/white/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/white/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/blue + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#8ba7ad" + +/obj/effect/floor_decal/corner_oldtile/blue/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/blue/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/yellow + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#8c6d46" + +/obj/effect/floor_decal/corner_oldtile/yellow/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/yellow/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/gray + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#687172" + +/obj/effect/floor_decal/corner_oldtile/gray/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/gray/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/beige + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#385e60" + +/obj/effect/floor_decal/corner_oldtile/beige/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/beige/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/red + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#964e51" + +/obj/effect/floor_decal/corner_oldtile/red/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/red/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/purple + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#906987" + +/obj/effect/floor_decal/corner_oldtile/purple/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/purple/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" + +/obj/effect/floor_decal/corner_oldtile/green + name = "corner oldtile" + icon_state = "corner_oldtile" + color = "#46725c" + +/obj/effect/floor_decal/corner_oldtile/green/diagonal + name = "corner oldtile diagonal" + icon_state = "corner_oldtile_diagonal" + +/obj/effect/floor_decal/corner_oldtile/green/full + name = "corner oldtile full" + icon_state = "corner_oldtile_full" \ No newline at end of file From 8cbe69ad46c2b6f2ec866cb9de63f2ae94d67d93 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Tue, 27 Aug 2024 19:15:34 -0400 Subject: [PATCH 379/512] Fix incorrect pipe dispenser migrations --- tools/map_migrations/0000_legacy.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/map_migrations/0000_legacy.txt b/tools/map_migrations/0000_legacy.txt index 91f8fa256685..d2bd25806eab 100644 --- a/tools/map_migrations/0000_legacy.txt +++ b/tools/map_migrations/0000_legacy.txt @@ -242,10 +242,10 @@ # FABRICATORS /obj/machinery/autolathe{hacked = 1} : /obj/machinery/fabricator/hacked{@OLD; hacked = @SKIP} /obj/machinery/autolathe : /obj/machinery/fabricator{@OLD} -/obj/machinery/pipedispenser : /obj/machinery/fabricator/pipe{@OLD} -/obj/machinery/pipedispenser/orderable : /obj/machinery/fabricator/pipe{@OLD; anchored = 1} -/obj/machinery/pipedispenser/disposal : /obj/machinery/fabricator/pipe/disposal{@OLD} -/obj/machinery/pipedispenser/disposal/orderable : /obj/machinery/fabricator/pipe/disposal{@OLD; anchored = 1} +/obj/machinery/pipedispenser : /obj/machinery/fabricator/pipe{@OLD; anchored = 1} +/obj/machinery/pipedispenser/orderable : /obj/machinery/fabricator/pipe{@OLD} +/obj/machinery/pipedispenser/disposal : /obj/machinery/fabricator/pipe/disposal{@OLD; anchored = 1} +/obj/machinery/pipedispenser/disposal/orderable : /obj/machinery/fabricator/pipe/disposal{@OLD} /obj/machinery/r_n_d/circuit_imprinter : /obj/machinery/fabricator/imprinter{@OLD} /obj/machinery/pros_fabricator : /obj/machinery/fabricator/robotics{@OLD} /obj/machinery/mecha_part_fabricator : /obj/machinery/fabricator/industrial{@OLD} From 91140f49538afd6120e933333718d70398bf23ff Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 30 Aug 2024 07:00:20 -0400 Subject: [PATCH 380/512] Fix mis-named yellow dress --- code/modules/clothing/dresses/misc.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/clothing/dresses/misc.dm b/code/modules/clothing/dresses/misc.dm index 49c74faa645e..b6c623159b25 100644 --- a/code/modules/clothing/dresses/misc.dm +++ b/code/modules/clothing/dresses/misc.dm @@ -4,7 +4,7 @@ icon = 'icons/clothing/dresses/dress_green.dmi' /obj/item/clothing/dress/yellow - name = "green dress" + name = "yellow dress" desc = "A simple yellow dress." icon = 'icons/clothing/dresses/dress_yellow.dmi' @@ -20,7 +20,7 @@ /obj/item/clothing/dress/purple name = "purple dress" - desc= "A simple, tight-fitting purple dress." + desc = "A simple, tight-fitting purple dress." icon = 'icons/clothing/dresses/dress_purple.dmi' /obj/item/clothing/dress/saloon From c8ee7b5763645c1c9dc61e76dd72f135d70f20e0 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 30 Aug 2024 07:03:36 -0400 Subject: [PATCH 381/512] Add a handful of legacy migrations (mostly clothing) --- tools/map_migrations/0000_legacy.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tools/map_migrations/0000_legacy.txt b/tools/map_migrations/0000_legacy.txt index d2bd25806eab..6ddafebd24f3 100644 --- a/tools/map_migrations/0000_legacy.txt +++ b/tools/map_migrations/0000_legacy.txt @@ -144,6 +144,7 @@ # CLOTHING /obj/item/clothing/head/cone : /obj/item/caution/cone{@OLD} +/obj/item/clothing/belt/security/tactical : /obj/item/belt/holster/security/tactical{@OLD} # Item remains /obj/effect/decal/remains/@SUBTYPES : /obj/item/remains/@SUBTYPES{@OLD} @@ -330,6 +331,10 @@ /obj/machinery/account_database : /obj/machinery/computer/account_database{@OLD} /obj/machinery/shield_gen/@SUBTYPES : /obj/machinery/shield_generator +/obj/structure/morgue/crematorium : /obj/structure/crematorium{@OLD} + +/obj/item/robot_parts/frame : /obj/item/robot_parts/robot_suit{@OLD} + /obj/structure/closet/secure_closet/psych : /obj/structure/closet/secure_closet/psychiatry{@OLD} /obj/structure/closet/firecloset/full : /obj/structure/closet/firecloset{@OLD} /obj/structure/closet/firecloset/full/double : /obj/structure/closet/firecloset/chief{@OLD} @@ -388,6 +393,24 @@ /obj/item/banner/nt : /obj/item/banner/nanotrasen{@OLD} +/obj/item/box/syndie_kit/clerical : /obj/item/backpack/satchel/syndie_kit/clerical{@OLD} + +/obj/item/clothing/under/costume/rainbow : /obj/item/clothing/jumpsuit/rainbow{@OLD} +/obj/item/clothing/under/dress/dress_orange : /obj/item/clothing/dress/orange{@OLD} +/obj/item/clothing/head/collectable/xenos : /obj/item/clothing/head/xenos{@OLD} +/obj/item/clothing/head/collectable/bearpelt : /obj/item/clothing/head/bearpelt{@OLD} +/obj/item/clothing/head/collectable/philosopher_wig : /obj/item/clothing/head/philosopher_wig{@OLD} +/obj/item/clothing/head/collectable/plaguedoctorhat : /obj/item/clothing/head/plaguedoctorhat{@OLD} +/obj/item/clothing/head/helmet/space/void/security/riot : /obj/item/clothing/head/helmet/space/void/security/alt{@OLD} +/obj/item/clothing/suit/space/void/security/riot : /obj/item/clothing/suit/space/void/security/alt{@OLD} +/obj/item/clothing/head/helmet/space/vox/pressure : /obj/item/clothing/head/helmet/space/vox{@OLD} +/obj/item/clothing/under/vox/vox_utility : /obj/item/clothing/pants/vox{@OLD} +/obj/item/clothing/suit/space/pirate : /obj/item/clothing/suit/pirate{@OLD} +/obj/item/clothing/suit/costume : /obj/item/clothing/suit/pirate{@OLD} +/obj/item/clothing/suit/costume/hgpirate : /obj/item/clothing/suit/hgpirate{@OLD} +/obj/item/clothing/suit/storage/vest/heavy/merc : /obj/item/clothing/suit/armor/pcarrier/merc{@OLD} +/obj/item/clothing/suit/storage/vest/@SUBTYPES : /obj/item/clothing/suit/armor/vest/@SUBTYPES{@OLD} + ############ # VAREDITS # ############ From 95f53f3a7dda57902345d6ec1a25f934818a3d6e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 1 Sep 2024 05:39:57 -0400 Subject: [PATCH 382/512] Add partially-constructed light fixture presets --- code/modules/power/lighting.dm | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index bc4d4bdba08c..39184fecc631 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -655,3 +655,18 @@ if(lightbulb) remove_bulb() return TRUE + +// Partially-constructed presets for mapping +/obj/machinery/light/fixture + icon_state = "tube-construct-stage1" + +/obj/machinery/light/fixture/Initialize(mapload, d, populate_parts) + . = ..(mapload, d, populate_parts = FALSE) + construct_state.post_construct(src) + +/obj/machinery/light/small/fixture + icon_state = "bulb-construct-stage1" + +/obj/machinery/light/small/fixture/Initialize(mapload, d, populate_parts) + . = ..(mapload, d, populate_parts = FALSE) + construct_state.post_construct(src) \ No newline at end of file From 7f93e2e9fb0875b3248f288c142dab4f62fa2a45 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 1 Sep 2024 05:40:14 -0400 Subject: [PATCH 383/512] Add red back-mounted oxygen tank --- code/game/objects/items/weapons/tanks/tank_types.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/game/objects/items/weapons/tanks/tank_types.dm b/code/game/objects/items/weapons/tanks/tank_types.dm index f5b1580e8a67..643125e14e14 100644 --- a/code/game/objects/items/weapons/tanks/tank_types.dm +++ b/code/game/objects/items/weapons/tanks/tank_types.dm @@ -22,6 +22,10 @@ desc = "A tank of oxygen. This one is yellow." icon = 'icons/obj/items/tanks/tank_yellow.dmi' +/obj/item/tank/oxygen/red + desc = "A tank of oxygen. This one is red." + icon = 'icons/obj/items/tanks/tank_red.dmi' + /obj/item/tank/oxygen/empty starting_pressure = list() From 076f9033c15d951df9039381ea25a15464c61dfa Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Sep 2024 01:39:48 -0400 Subject: [PATCH 384/512] Add mobile oxygen pumps --- code/game/machinery/oxygen_pump.dm | 44 +++++++++++++++++++++++++++++ icons/obj/machines/medpump.dmi | Bin 0 -> 1107 bytes 2 files changed, 44 insertions(+) create mode 100644 icons/obj/machines/medpump.dmi diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm index 103628176c11..70671c1d7e45 100644 --- a/code/game/machinery/oxygen_pump.dm +++ b/code/game/machinery/oxygen_pump.dm @@ -233,3 +233,47 @@ tank.distribute_pressure += cp tank.distribute_pressure = min(max(round(tank.distribute_pressure), 0), TANK_MAX_RELEASE_PRESSURE) . = TOPIC_REFRESH // Refreshing is handled in machinery/Topic + +/obj/machinery/oxygen_pump/mobile + name = "portable oxygen pump" + icon = 'icons/obj/machines/medpump.dmi' + desc = "A portable oxygen pump with a retractable mask that you can pull over your face in case of emergencies." + icon_state = "medpump" + icon_state_open = "medpump_open" + icon_state_closed = "medpump" + icon_state_active = "medpump_active" + + anchored = FALSE + density = TRUE + + +/obj/machinery/oxygen_pump/mobile/stabilizer + name = "portable patient stabilizer" + desc = "A portable oxygen pump with a retractable mask used for stabilizing patients in the field." + icon_state = "patient_stabilizer" + icon_state_closed = "patient_stabilizer" + icon_state_open = "patient_stabilizer_open" + icon_state_active = "patient_stabilizer_active" + +/obj/machinery/oxygen_pump/mobile/stabilizer/process() + . = ..() + if(!breather) // Safety. + return + if(breather.isSynthetic()) + return + +/* TODO: port modifiers or something similar + breather.add_modifier(breather.stat == DEAD ? /datum/modifier/bloodpump/corpse : /datum/modifier/bloodpump, 6 SECONDS) +*/ + + var/obj/item/organ/internal/lungs/lungs = breather.get_organ(BP_LUNGS, /obj/item/organ/internal/lungs) + if(!lungs) + return + if(lungs.status & ORGAN_DEAD) + breather.adjustOxyLoss(-(rand(1,8))) + else + breather.adjustOxyLoss(-(rand(10,15))) + if(lungs.is_bruised() && prob(30)) + lungs.heal_damage(1) + else + breather.ticks_since_last_successful_breath = max(breather.ticks_since_last_successful_breath - rand(1,5), 0) \ No newline at end of file diff --git a/icons/obj/machines/medpump.dmi b/icons/obj/machines/medpump.dmi new file mode 100644 index 0000000000000000000000000000000000000000..01f5a1dc4b9aeacdcca8b62c80f87a7c5cdbfac5 GIT binary patch literal 1107 zcmV-Z1g!gsP)004jp0{{R3yS%*-fU#JkzPmzS3u92^f14?aUhmx~#;syW`# zS&);M6%`d-U1TF7CO$ns)YQ@^Cnq>GG%zhKmK7Zq5faT9BUDpRG@np2Gcy`UCLUie zThVp@00001bW%=J06^y0W&i*Hzj{TiQFu?N-Y7|BmOhqD5Nl zRG6MK&A0x`{%=-dAA3MV@8%wJgDV3eAE;n#7B`Vha9~32OJA?Yb#&>s(oeSJr?KA z9eiEa{t({<^1Ol}&|<(>PPz;<(*7^)2Ty&7YvCVwsB0r|(*LnI6!;G1 zy%PmK!vdr~1Wx)t7N6n=|H6~tr2k`aasQ`&aBh7kUO-yE@%`Ye{!rZiJ;D!8IH>32 z;{H$lp!z}egX#xGxw!vRKd8}YG~Xfl`@?W&$hbmxf&vBoAic{2l2J zhfC{6+^!6~NpNJonc(k8e`wtq-r(%)8Y_Uu%~XGf`N6?1o{<8ka-_qC>FFAy#IeA0^q2^| zX&a1p1@^qbj~Uh%5P@DU7rX<3Hw+jg}ul5mhGjsdBB){56 z>|V_Eck|9K7Aw-vrFh!!vHjtS^mn&Bx<_vOUc5uo{UNgciu7|Sp7whQKbZ21eF3sI^elTvgQht%|?;gP^zsUA?51Ws6aAv>9_Jec#J@td~T-^VuA5=f6evrj8 Z%|GtHvJSlBd-MPR002ovPDHLkV1j6y7mfe` literal 0 HcmV?d00001 From 28da263a19352b41733041013fb907b48ec5220d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 28 Aug 2024 00:47:30 -0400 Subject: [PATCH 385/512] Add additional legacy migrations for mech parts --- tools/map_migrations/0000_legacy.txt | 987 ++++++++++++++------------- 1 file changed, 503 insertions(+), 484 deletions(-) diff --git a/tools/map_migrations/0000_legacy.txt b/tools/map_migrations/0000_legacy.txt index 6ddafebd24f3..721a4edf9f27 100644 --- a/tools/map_migrations/0000_legacy.txt +++ b/tools/map_migrations/0000_legacy.txt @@ -1,485 +1,504 @@ -/obj/item/reagent_containers/@SUBTYPES : /obj/item/chems/@SUBTYPES{@OLD} -/obj/item/material/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/weapon/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/melee/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/packageWrap/@SUBTYPES : /obj/item/stack/package_wrap/@SUBTYPES{@OLD} -/obj/structure/table/rack/@SUBTYPES : /obj/structure/rack/@SUBTYPES{@OLD} -/obj/structure/table/woodentable/holotable : /obj/structure/table/holo_woodentable{@OLD} -/obj/item/chems/food/drinks/@SUBTYPES : /obj/item/chems/drinks/@SUBTYPES{@OLD} -/obj/item/chems/food/snacks/@SUBTYPES : /obj/item/food/@SUBTYPES{@OLD} -/obj/item/chems/food/condiment/@SUBTYPES : /obj/item/chems/condiment/@SUBTYPES{@OLD} -/obj/item/chems/condiment/peppermill/@SUBTYPES : /obj/item/chems/condiment/small/peppermill/@SUBTYPES{@OLD} -/obj/item/chems/condiment/saltshaker/@SUBTYPES : /obj/item/chems/condiment/small/saltshaker/@SUBTYPES{@OLD} -/obj/item/analyzer : /obj/item/scanner/gas{@OLD} -/obj/item/analyzer/plant_analyzer/@SUBTYPES : /obj/item/scanner/plant/@SUBTYPES{@OLD} -/obj/item/tape_roll/@SUBTYPES : /obj/item/stack/tape_roll/@SUBTYPES{@OLD} -/obj/structure/table/standard/@SUBTYPES : /obj/structure/table/@SUBTYPES{@OLD} -/obj/machinery/bluespacerelay/@SUBTYPES : /obj/machinery/commsrelay/@SUBTYPES{@OLD} -/obj/machinery/computer/helm/@SUBTYPES : /obj/machinery/computer/ship/helm/@SUBTYPES{@OLD} -/obj/machinery/computer/engines/@SUBTYPES : /obj/machinery/computer/ship/engines/@SUBTYPES{@OLD} -/obj/machinery/computer/navigation/@SUBTYPES : /obj/machinery/computer/ship/navigation/@SUBTYPES{@OLD} -/obj/machinery/requests_console/@SUBTYPES : /obj/machinery/network/requests_console/@SUBTYPES{@OLD; departmentType = @SKIP} -/obj/item/healthanalyzer/@SUBTYPES : /obj/item/scanner/health/@SUBTYPES{@OLD} -/obj/machinery/iv_drip/@SUBTYPES : /obj/structure/iv_drip/@SUBTYPES{@OLD} -/obj/structure/device/piano/@SUBTYPES : /obj/structure/synthesized_instrument/synthesizer/piano/@SUBTYPES{@OLD} -/obj/item/folder/white/@SUBTYPES : /obj/item/folder/@SUBTYPES{@OLD} -/obj/machinery/dnaforensics/@SUBTYPES : /obj/machinery/forensic/dnascanner/@SUBTYPES{@OLD} -/obj/machinery/microscope/@SUBTYPES : /obj/machinery/forensic/microscope/@SUBTYPES{@OLD} -/obj/item/stack/material/steel/@SUBTYPES : /obj/item/stack/material/sheet/mapped/steel/@SUBTYPES{@OLD} -/obj/item/stack/material/plasteel/@SUBTYPES : /obj/item/stack/material/sheet/reinforced/mapped/plasteel/@SUBTYPES{@OLD} -/obj/item/stack/material/glass/reinforced/@SUBTYPES : /obj/item/stack/material/pane/mapped/rglass/@SUBTYPES{@OLD} -/obj/item/stack/material/glass/@SUBTYPES : /obj/item/stack/material/pane/mapped/glass/@SUBTYPES{@OLD} -/obj/item/stack/material/wood/@SUBTYPES : /obj/item/stack/material/plank/mapped/wood/@SUBTYPES{@OLD} -/obj/item/stack/material/deuterium/@SUBTYPES : /obj/item/stack/material/aerogel/mapped/deuterium/@SUBTYPES{@OLD} -/obj/item/stack/material/uranium/@SUBTYPES : /obj/item/stack/material/puck/mapped/uranium/@SUBTYPES{@OLD} -/obj/machinery/autolathe/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD} -/obj/machinery/message_server/@SUBTYPES : /obj/machinery/network/message_server/@SUBTYPES{@OLD} -/obj/item/floor_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} -/obj/machinery/pipedispenser/@SUBTYPES : /obj/machinery/fabricator/pipe/@SUBTYPES{@OLD} -/obj/machinery/power/emitter/@SUBTYPES : /obj/machinery/emitter/@SUBTYPES{@OLD} -/obj/machinery/power/fusion_core/@SUBTYPES : /obj/machinery/fusion_core/@SUBTYPES{@OLD} -/obj/item/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} -/obj/machinery/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} -/obj/machinery/computer/modular/preset/command/@SUBTYPES : /obj/machinery/computer/modular/preset/cardslot/command/@SUBTYPES{@OLD} -/obj/machinery/computer/fusion_core_control/@SUBTYPES : /obj/machinery/computer/fusion/core_control/@SUBTYPES{@OLD} -/obj/machinery/computer/fusion_fuel_control/@SUBTYPES : /obj/machinery/computer/fusion/fuel_control/@SUBTYPES{@OLD} -/obj/machinery/computer/gyrotron_control/@SUBTYPES : /obj/machinery/computer/fusion/gyrotron/@SUBTYPES{@OLD} -/obj/machinery/computer/power_monitor/@SUBTYPES : /obj/machinery/computer/modular/preset/engineering/power/@SUBTYPES{@OLD} -/obj/item/module/power_control/@SUBTYPES : /obj/item/stock_parts/circuitboard/apc/@SUBTYPES{@OLD} -/obj/machinery/power/port_gen/@SUBTYPES : /obj/machinery/port_gen/@SUBTYPES{@OLD} -/obj/item/pipe_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} -/obj/item/airlock_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/airlock_electronics/@SUBTYPES{@OLD} -/obj/item/airalarm_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/air_alarm/@SUBTYPES{@OLD} -/obj/item/autopsy_scanner/@SUBTYPES : /obj/item/scanner/autopsy/@SUBTYPES{@OLD} -/obj/machinery/fusion_fuel_compressor/@SUBTYPES : /obj/machinery/fuel_compressor/@SUBTYPES{@OLD} -/obj/item/extinguisher/micro/@SUBTYPES : /obj/item/chems/spray/extinguisher/mini/@SUBTYPES{@OLD} -/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} -/obj/item/stack/material/plastic/@SUBTYPES : /obj/item/stack/material/panel/mapped/plastic/@SUBTYPES{@OLD} -/obj/machinery/computer/general_air_control/@SUBTYPES : /obj/machinery/computer/air_control/@SUBTYPES{@OLD} -/obj/machinery/computer/air_control/large_tank_control : /obj/machinery/computer/air_control{@OLD} -/turf/simulated/floor/tiled/steel/@SUBTYPES : /turf/simulated/floor/tiled/@SUBTYPES{@OLD} -/obj/machinery/power/engine/@SUBTYPES : /obj/machinery/ion_thruster/@SUBTYPES{@OLD} -/obj/machinery/computer/aifixer/@SUBTYPES : /obj/machinery/computer/modular/preset/aislot/sysadmin/@SUBTYPES{@OLD} -/obj/machinery/computer/aiupload/@SUBTYPES : /obj/machinery/computer/upload/ai/@SUBTYPES{@OLD} -/obj/machinery/computer/borgupload/@SUBTYPES : /obj/machinery/computer/upload/robot/@SUBTYPES{@OLD} -/obj/machinery/computer/supplycomp/control/@SUBTYPES : /obj/machinery/computer/modular/preset/dock/@SUBTYPES{@OLD} -/obj/machinery/computer/supplycomp/@SUBTYPES : /obj/machinery/computer/modular/preset/supply_public/@SUBTYPES{@OLD} -/obj/item/closet_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} -/turf/simulated/shuttle/plating/@SUBTYPES : /turf/floor/shuttle -/turf/simulated/shuttle/floor/@SUBTYPES : /turf/floor/shuttle/@SUBTYPES - -# REMOVE BAD VAREDITS -/@SUBTYPES {layer = @SET} : @OLD {@OLD; layer = @SKIP} -/@SUBTYPES {plane = @SET} : @OLD {@OLD; plane = @SKIP} -/obj/structure/cable/@SUBTYPES : @OLD {@OLD; d1 = @SKIP;d2 = @SKIP} -# unacidable removed -/@SUBTYPES {unacidable = @SET} : @OLD{@OLD; unacidable = @SKIP} -# Simple pipes shall not face north or west -/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} -/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} -/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} -/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} -# Do not change air alarm frequency on base type -/obj/machinery/alarm {frequency = @SET} : @OLD {@OLD; frequency = @SKIP} -# we use a completely different access format -/@SUBTYPES {req_access = @SET}: @OLD {@OLD; req_access = @SKIP;} -/@SUBTYPES {req_one_access = @SET}: @OLD {@OLD; req_one_access = @SKIP;} -/obj/machinery/door/blast/shutters{icon_state = "shutter0"} : /obj/machinery/door/blast/shutters{@OLD; icon_state = @SKIP} -/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1; density = 0, opacity = 0} : /obj/machinery/door/airlock/external/glass/bolted_open{@OLD; icon_state = @SKIP; locked = @SKIP, density = @SKIP; opacity = @SKIP} -/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1} : /obj/machinery/door/airlock/external/glass/bolted{@OLD; icon_state = @SKIP; locked = @SKIP} - -# BUTTONS -/obj/machinery/access_button/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} -/obj/machinery/access_button/airlock_interior : /obj/machinery/button/access/interior{@OLD} -/obj/machinery/airlock_sensor/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} -/obj/machinery/airlock_sensor/airlock_interior : /obj/machinery/button/access/interior{@OLD} -/obj/machinery/access_button : /obj/machinery/button/access{@OLD} -/obj/machinery/button/remote/airlock{specialfunctions = 4} : /obj/machinery/button/alternate/door/bolts{@OLD; specialfunctions = @SKIP; desiredstate = @SKIP} -/obj/machinery/button/remote/airlock : /obj/machinery/button/alternate/door{@OLD} -/obj/machinery/button/remote/driver : /obj/machinery/button/mass_driver{@OLD} -/obj/machinery/button/remote/blast_door : /obj/machinery/button/blast_door{@OLD} -/obj/machinery/button/remote : /obj/machinery/button/alternate{@OLD} - -# Medical -/obj/item/pill_bottle/tramadol : /obj/item/pill_bottle/strong_painkillers{@OLD} -/obj/item/chems/pill/tramadol : /obj/item/chems/pill/strong_painkillers{@OLD} -/obj/item/chems/glass/bottle/stoxin : /obj/item/chems/glass/bottle/sedatives{@OLD} -/obj/item/chems/glass/bottle/inaprovaline : /obj/item/chems/glass/bottle/stabilizer{@OLD} -/obj/item/chems/syringe/inaprovaline : /obj/item/chems/syringe/stabilizer{@OLD} -/obj/item/chems/blood/empty : /obj/item/chems/ivbag{@OLD} -/obj/item/chems/blood/@SUBTYPES : /obj/item/chems/ivbag/blood/@SUBTYPES{@OLD} -/obj/item/defib_kit/@SUBTYPES : /obj/item/defibrillator/@SUBTYPES{@OLD} - -# Drinking glasses and cups -/obj/item/chems/drinks/cup : /obj/item/chems/drinks/glass2/coffeecup{@OLD} -/obj/item/chems/drinks/drinkingglass : /obj/item/chems/drinks/glass2/square{@OLD} - -# Airtight flaps -/obj/structure/plasticflaps/mining : /obj/structure/flaps/airtight{@OLD} - -# Bushes -/obj/structure/flora/ausbushes/@SUBTYPES : /obj/structure/flora/bush/@SUBTYPES - -# Cassette tapes -> magnetic tapes -/obj/item/cassette_tape/@SUBTYPES : /obj/item/magnetic_tape/@SUBTYPES{@OLD} -/obj/item/tape_recorder : /obj/item/taperecorder{@OLD} - -# FIFTYSPAWNER -> MAPPED SHEETS -/obj/fiftyspawner/wood : /obj/item/stack/material/plank/mapped/wood/fifty -/obj/fiftyspawner/steel : /obj/item/stack/material/sheet/mapped/steel/fifty -/obj/fiftyspawner/glass : /obj/item/stack/material/pane/mapped/glass/fifty -/obj/fiftyspawner/deuterium : /obj/item/stack/material/aerogel/mapped/deuterium/fifty -/obj/fiftyspawner/tritium : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/osmium : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/phoron : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/rods : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/grass : /obj/item/stack/tile/grass{amount = 50} -/obj/fiftyspawner/plasteel : /obj/item/stack/material/aerogel/mapped/tritium/fifty - -# STOCK PARTS AND SMES COILS -/obj/item/stock_parts/subspace/sub_filter : /obj/item/stock_parts/subspace/filter -/obj/item/smes_coil/@SUBTYPES : /obj/item/stock_parts/smes_coil/@SUBTYPES{@OLD} -/obj/item/circuitboard/@SUBTYPES : /obj/item/stock_parts/circuitboard/@SUBTYPES{@OLD} -/obj/item/airlock_electronics : /obj/item/stock_parts/circuitboard/airlock_electronics{@OLD} - -# CLOTHING -/obj/item/clothing/head/cone : /obj/item/caution/cone{@OLD} -/obj/item/clothing/belt/security/tactical : /obj/item/belt/holster/security/tactical{@OLD} - -# Item remains -/obj/effect/decal/remains/@SUBTYPES : /obj/item/remains/@SUBTYPES{@OLD} - -# Circuit prefabs -/obj/item/hand_tele : /obj/prefab/hand_teleporter{@OLD} - -# Filing cabinets -/obj/structure/filingcabinet : /obj/structure/filing_cabinet{@OLD} -/obj/structure/filingcabinet/chestdrawer : /obj/structure/filing_cabinet/chestdrawer{@OLD} -/obj/structure/filingcabinet/filingcabinet : /obj/structure/filing_cabinet/tall{@OLD} -/obj/structure/filingcabinet/medical : /obj/structure/filing_cabinet/records/medical{@OLD} -/obj/structure/filingcabinet/security : /obj/structure/filing_cabinet/records{@OLD} - -# Machine frames -/obj/structure/frame: /obj/machinery/constructable_frame/machine_frame{@OLD} -/obj/machinery/constructable_frame/machine_frame{anchored = 1} : /obj/machinery/constructable_frame/machine_frame/deconstruct{anchored = @SKIP} -/obj/structure/frame/computer : /obj/machinery/constructable_frame/computerframe{@OLD} -/obj/machinery/constructable_frame/computerframe{anchored = 1} : /obj/machinery/constructable_frame/computerframe/deconstruct{anchored = @SKIP} - -# Hygiene/bathroom objects -/obj/structure/toilet : /obj/structure/hygiene/toilet{@OLD} -/obj/structure/sink/@SUBTYPES : /obj/structure/hygiene/sink/@SUBTYPES{@OLD} -/obj/machinery/shower : /obj/structure/hygiene/shower{@OLD} - -# Turbolift spawners -/obj/turbolift_map_holder/@SUBTYPES : /obj/abstract/turbolift_spawner/@SUBTYPES{@OLD} - -# Borosilicate windows -/obj/structure/window/phoronreinforced/@SUBTYPES : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD} - -# Tools; see 3763_pickaxe_hammer and 3959_hatchets for other migrations -/obj/item/knife/machete : /obj/item/tool/machete{@OLD} -/obj/item/knife/machete/hatchet : /obj/item/tool/axe/hatchet{@OLD} -/obj/item/tool/pickaxe/hand : /obj/item/tool/pickaxe/xeno/hand{@OLD} - -# RANDOM SPAWNERS -/obj/random/cigarettes : /obj/random/smokes{@OLD} -/obj/item/lipstick/random : /obj/random/lipstick -/obj/random/slimecore : /obj/item/slime_extract/random{@OLD} - -# MINING EQUIPMENT -/obj/machinery/mineral/processing_unit : /obj/machinery/material_processing/smeltery -/obj/machinery/mineral/stacking_machine : /obj/machinery/material_processing/stacker -/obj/machinery/mineral/unloading_machine : /obj/machinery/material_processing/unloader -/obj/machinery/mineral/output : @DELETE -/obj/machinery/mineral/input : @DELETE -/obj/machinery/mineral/mint : @DELETE -/obj/machinery/mineral/processing_unit_console : @DELETE - -# NEW PDAS (NO CARTRIDGES) -/obj/item/pda/@SUBTYPES : /obj/item/modular_computer/pda/@SUBTYPES{@OLD} -/obj/item/modular_computer/pda/captain : /obj/item/modular_computer/pda/heads/captain -/obj/item/storage/box/seccarts : @DELETE -/obj/item/cartridge/@SUBTYPES : @DELETE - -# MODULAR COMPUTER PRESETS -/obj/machinery/computer/card : /obj/machinery/computer/modular/preset/cardslot/personnel{@OLD} -/obj/machinery/computer/secure_data : /obj/machinery/computer/modular/preset/civilian{@OLD} -/obj/machinery/computer/skills : /obj/machinery/computer/modular/preset/civilian{@OLD} -/obj/machinery/computer/security/telescreen : /obj/machinery/computer/modular/telescreen/preset/security{@OLD} -/obj/machinery/computer/security/telescreen/entertainment : /obj/machinery/computer/modular/telescreen/preset/entertainment{@OLD} -/obj/machinery/computer/security/mining : /obj/machinery/computer/modular/preset/security{@OLD} -/obj/machinery/computer/security/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES -/obj/machinery/computer/crew : /obj/machinery/computer/modular/preset/medical{@OLD} -/obj/machinery/computer/rcon : /obj/machinery/computer/modular/preset/engineering/rcon{@OLD} -/obj/machinery/computer/communications : /obj/machinery/computer/modular/preset/cardslot/command{@OLD} -/obj/machinery/computer/med_data : /obj/machinery/computer/modular/preset/civilian{@OLD} -/obj/machinery/computer/med_data/laptop : /obj/item/modular_computer/laptop/preset/records{@OLD} - -# ATMOS REPATHS -/obj/machinery/atmospherics/pipe/tank/@SUBTYPES : /obj/machinery/atmospherics/unary/tank/@SUBTYPES -/obj/machinery/portable_atmospherics/canister/nitrous_oxide : /obj/machinery/portable_atmospherics/canister/sleeping_agent{@OLD} - -# MISC. ITEMS -/obj/item/moneybag/vault : /obj/item/bag/cash/filled{@OLD} -/obj/item/moneybag : /obj/item/bag/cash{@OLD} -/obj/item/chems/bucket : /obj/item/chems/glass/bucket{@OLD} -/obj/item/card/id/gold/captain/spare : /obj/item/card/id/captains_spare{@OLD} -/obj/item/chainofcommand : /obj/item/whip/chainofcommand{@OLD} -/obj/item/chems/drinks/bottle/specialwhiskey : /obj/item/chems/drinks/bottle/agedwhiskey{@OLD} - -# Tape is weird -/obj/item/taperoll/@SUBTYPES : /obj/item/stack/tape_roll/barricade_tape/@SUBTYPES{@OLD} -/obj/item/tape/@SUBTYPES : /obj/structure/tape_barricade/@SUBTYPES{@OLD} - -# Radio -/obj/item/radio/headset/headset_sec/alt : /obj/item/radio/headset/headset_sec/bowman{@OLD} -/obj/item/radio/headset/syndicate : /obj/item/radio/headset/hacked{@OLD} -/obj/item/radio/headset/syndicate/alt : /obj/item/radio/headset/hacked{@OLD} -/obj/item/phone : /obj/item/radio/phone{@OLD} - -# Singulo -/obj/machinery/the_singularitygen : /obj/machinery/singularity_generator{@OLD} - -# FABRICATORS -/obj/machinery/autolathe{hacked = 1} : /obj/machinery/fabricator/hacked{@OLD; hacked = @SKIP} -/obj/machinery/autolathe : /obj/machinery/fabricator{@OLD} -/obj/machinery/pipedispenser : /obj/machinery/fabricator/pipe{@OLD; anchored = 1} -/obj/machinery/pipedispenser/orderable : /obj/machinery/fabricator/pipe{@OLD} -/obj/machinery/pipedispenser/disposal : /obj/machinery/fabricator/pipe/disposal{@OLD; anchored = 1} -/obj/machinery/pipedispenser/disposal/orderable : /obj/machinery/fabricator/pipe/disposal{@OLD} -/obj/machinery/r_n_d/circuit_imprinter : /obj/machinery/fabricator/imprinter{@OLD} -/obj/machinery/pros_fabricator : /obj/machinery/fabricator/robotics{@OLD} -/obj/machinery/mecha_part_fabricator : /obj/machinery/fabricator/industrial{@OLD} -/obj/machinery/r_n_d/protolathe : /obj/machinery/fabricator/protolathe{@OLD} -/obj/machinery/bookbinder : /obj/machinery/fabricator/book{@OLD} -/obj/machinery/organ_printer/flesh : /obj/machinery/fabricator/bioprinter{@OLD} -/obj/machinery/vending/food : /obj/machinery/fabricator/replicator - -/obj/machinery/fabricator/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD; res_max_amount = @SKIP; speed = @SKIP} - -# MMIs and posibrains -/obj/item/mmi/digital/@SUBTYPES : /obj/item/organ/internal/brain/robotic{@OLD} -/obj/item/mmi/@SUBTYPES : /obj/item/organ/internal/brain_interface/@SUBTYPES{@OLD} -/obj/item/organ/internal/posibrain : /obj/item/organ/internal/brain/robotic/positronic{@OLD} - -# Energy blades -/obj/item/energy/@SUBTYPES : /obj/item/energy_blade/@SUBTYPES{@OLD} - -# Medals and other accessories; see 3902_ties.txt for further migrations -/obj/item/clothing/accessory/medal/bronze_heart : /obj/item/clothing/accessory/medal/nanotrasen/bronze{@OLD} -/obj/item/clothing/accessory/medal/nobel_science : /obj/item/clothing/medal/nanotrasen/silver{@OLD} -/obj/item/clothing/accessory/scarf/white : /obj/item/clothing/accessory/scarf{@OLD} -/obj/item/clothing/accessory/storage/webbing : /obj/item/clothing/accessory/webbing/vest - -# MATERIALS -/obj/item/stack/material/plastic : /obj/item/stack/material/panel/mapped/plastic{@OLD} -/obj/item/stack/material/sandstone : /obj/item/stack/material/brick/mapped/sandstone{@OLD} -/obj/item/stack/material/mhydrogen : /obj/item/stack/material/segment/mapped/mhydrogen{@OLD} -/obj/item/stack/material/diamond : /obj/item/stack/material/gemstone/mapped/diamond{@OLD} -/obj/item/stack/material/wood : /obj/item/stack/material/plank/mapped/wood{@OLD} -/obj/item/stack/material/steel : /obj/item/stack/material/sheet/mapped/steel{@OLD} -/obj/item/stack/material/glass : /obj/item/stack/material/pane/mapped/glass{@OLD} -/obj/item/stack/material/phoron : /obj/item/stack/material/crystal/mapped/phoron{@OLD} -/obj/item/stack/material/algae : /obj/item/stack/material/puck/mapped/algae{@OLD} -/obj/item/stack/material/gold : /obj/item/stack/material/ingot/mapped/gold{@OLD} -/obj/item/stack/material/plasteel : /obj/item/stack/material/reinforced/mapped/plasteel{@OLD} -/obj/item/stack/material/glass/reinforced : /obj/item/stack/material/pane/mapped/rglass{@OLD} -/obj/item/stack/material/glass/phoronglass : /obj/item/stack/material/pane/mapped/borosilicate{@OLD} -/obj/item/stack/material/glass/phoronrglass : /obj/item/stack/material/pane/mapped/rborosilicate{@OLD} -/obj/item/stack/rods : /obj/item/stack/material/rods{@OLD} -/obj/item/packageWrap{amount = @UNSET} : /obj/item/stack/package_wrap/twenty_five{@OLD; amount = @SKIP} -/obj/item/packageWrap : /obj/item/stack/package_wrap{@OLD} -/obj/item/wrapping_paper{amount = @UNSET} : /obj/item/stack/package_wrap/gift/twenty_five{@OLD; amount = @SKIP} -/obj/item/wrapping_paper : /obj/item/stack/package_wrap{@OLD} - -/obj/structure/dispenser{phorontanks = 0} : /obj/structure/tank_rack/oxygen{@OLD; phorontanks = @SKIP} -/obj/structure/dispenser/oxygen{oxygentanks = 0} : /obj/structure/tank_rack/empty{@OLD; oxygentanks = @SKIP} -/obj/structure/dispenser/oxygen : /obj/structure/tank_rack/oxygen -/obj/structure/dispenser : /obj/structure/tank_rack - -# TELECOMMS REMOVAL -/obj/item/stock_parts/circuitboard/telecomms/@SUBTYPES : @DELETE -/obj/machinery/telecomms/@SUBTYPES : @DELETE -/obj/machinery/computer/telecomms/@SUBTYPES : @DELETE - -/obj/machinery/r_n_d/server/@SUBTYPES : /obj/machinery/design_database -/obj/machinery/r_n_d/destructive_analyzer : /obj/machinery/destructive_analyzer - -# SMES bullshit -/obj/machinery/power/smes/buildable/engine : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 1)} -/obj/machinery/power/smes/buildable/main : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 4)} -/obj/machinery/power/smes/buildable/point_of_interest : /obj/machinery/power/smes/buildable/preset/hidden - -/obj/item/surgical/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/FixOVein : /obj/item/sutures{@OLD} - -/obj/structure/flora/skeleton : /obj/structure/skele_stand{@OLD} - -/obj/mecha/working/ripley/firefighter : /mob/living/exosuit/premade/firefighter -/obj/mecha/working/ripley/mining : /mob/living/exosuit/premade/powerloader - -/obj/structure/AIcore/@SUBTYPES : /obj/structure/aicore/@SUBTYPES -/obj/item/tank/vox : /obj/item/tank/nitrogen{@OLD} - -/obj/machinery/shuttle_sensor : /obj/machinery/airlock_sensor/shuttle{@OLD} - -/obj/machinery/computer/rdconsole/@SUBTYPES : /obj/machinery/computer/design_console{@OLD} -/obj/machinery/computer/rdservercontrol : /obj/machinery/computer/design_console{@OLD; name = @SKIP; badmin = @SKIP} -/obj/item/stock_parts/circuitboard/rdconsole : /obj/item/stock_parts/circuitboard/design_console{@OLD} -/obj/item/stock_parts/circuitboard/rdserver : /obj/item/stock_parts/circuitboard/design_database{@OLD} - -/obj/machinery/account_database : /obj/machinery/computer/account_database{@OLD} -/obj/machinery/shield_gen/@SUBTYPES : /obj/machinery/shield_generator - -/obj/structure/morgue/crematorium : /obj/structure/crematorium{@OLD} - -/obj/item/robot_parts/frame : /obj/item/robot_parts/robot_suit{@OLD} - -/obj/structure/closet/secure_closet/psych : /obj/structure/closet/secure_closet/psychiatry{@OLD} -/obj/structure/closet/firecloset/full : /obj/structure/closet/firecloset{@OLD} -/obj/structure/closet/firecloset/full/double : /obj/structure/closet/firecloset/chief{@OLD} -/obj/structure/closet/l3closet/scientist/double : /obj/structure/closet/l3closet/scientist/multi{@OLD} -/obj/structure/closet/secure_closet/hos2 : /obj/structure/closet/secure_closet/hos{@OLD} -/obj/structure/closet/secure_closet/medical_wall/synth_anesthetics : /obj/structure/closet/secure_closet/medical_wall/anesthetics/robotics{@OLD} -/obj/structure/closet/secure_closet/medical2 : /obj/structure/closet/secure_closet/anesthetics{@OLD} -/obj/structure/closet/walllocker/emerglocker/@SUBTYPES : /obj/structure/emergency_dispenser/@SUBTYPES{@OLD} - -/obj/item/firstaid_arm_assembly : /obj/item/firstaid/empty, /obj/item/robot_parts/l_arm -/obj/item/bucket_sensor : /obj/item/chems/glass/bucket, /obj/item/assembly/prox_sensor -/obj/item/broken_device : @DELETE - -/obj/item/spacecash/@SUBTYPES : /obj/item/cash/@SUBTYPES{@OLD} - -/obj/item/kit/paint/ripley : /obj/item/kit/paint/camouflage -/obj/item/kit/paint/ripley/death : /obj/item/kit/paint/camouflage/forest -/obj/item/kit/paint/ripley/flames_blue : /obj/item/kit/paint/flames_blue -/obj/item/kit/paint/ripley/flames_red : /obj/item/kit/paint/flames_red - -/obj/machinery/photocopier/faxmachine : /obj/machinery/faxmachine{@OLD; init_network_tag = @OLD:department; department = @SKIP} -/obj/item/tvcamera : /obj/item/camera/tvcamera{@OLD} -/obj/machinery/station_map : /obj/machinery/holomap{@OLD} - -/obj/item/ducttape : /obj/item/duct_tape{@OLD} -/obj/item/toy/katana : /obj/item/sword/katana/toy{@OLD} -/obj/item/toy/cultsword : /obj/item/sword/cult_toy{@OLD} -/obj/item/toy/sword : /obj/item/energy_blade/sword/toy{@OLD} -/obj/item/lipstick/jade : /obj/item/cosmetics/lipstick/green{@OLD} -/obj/item/rig_module/device/plasmacutter : /obj/item/rig_module/mounted/plasmacutter{@OLD} -/obj/item/storage/box/syndie_kit/ewar_voice : /obj/item/backpack/satchel/syndie_kit/ewar_voice -/obj/item/tray : /obj/item/plate/tray{@OLD} -/obj/item/weldingtool/weldpack : /obj/item/chems/weldpack{@OLD} -/obj/machinery/crystal : /obj/structure/crystal{@OLD} -/obj/item/organ/internal/stack : /obj/item/organ/internal/voxstack{@OLD} -/obj/item/radio_jammer : /obj/item/suit_sensor_jammer - -# AMMO BOXES -/obj/item/storage/box/beanbags/@SUBTYPES : /obj/item/box/ammo/beanbags/@SUBTYPES{@OLD} -/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} -/obj/item/storage/box/blanks/@SUBTYPES : /obj/item/box/ammo/blanks/@SUBTYPES{@OLD} -/obj/item/storage/box/empshells/@SUBTYPES : /obj/item/box/ammo/empshells/@SUBTYPES{@OLD} -/obj/item/storage/box/flashshells/@SUBTYPES : /obj/item/box/ammo/flashshells/@SUBTYPES{@OLD} -/obj/item/storage/box/shotgunammo/@SUBTYPES : /obj/item/box/ammo/shotgunammo/@SUBTYPES{@OLD} -/obj/item/storage/box/shotgunshells/@SUBTYPES : /obj/item/box/ammo/shotgunshells/@SUBTYPES{@OLD} -/obj/item/storage/box/sniperammo/@SUBTYPES : /obj/item/box/ammo/sniperammo/@SUBTYPES{@OLD} -/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} - -/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} -/obj/item/camera_assembly : /obj/item/frame/camera/kit -/obj/structure/ladder/up : /obj/structure/ladder -/obj/random/mob/mouse : /obj/random/mouse - -/obj/structure/closet/grave/dirthole : /obj/structure/pit{@OLD} -/obj/structure/closet/grave/@SUBTYPES : /obj/structure/pit/closed/grave{@OLD} - -/obj/item/banner/nt : /obj/item/banner/nanotrasen{@OLD} - -/obj/item/box/syndie_kit/clerical : /obj/item/backpack/satchel/syndie_kit/clerical{@OLD} - -/obj/item/clothing/under/costume/rainbow : /obj/item/clothing/jumpsuit/rainbow{@OLD} -/obj/item/clothing/under/dress/dress_orange : /obj/item/clothing/dress/orange{@OLD} -/obj/item/clothing/head/collectable/xenos : /obj/item/clothing/head/xenos{@OLD} -/obj/item/clothing/head/collectable/bearpelt : /obj/item/clothing/head/bearpelt{@OLD} -/obj/item/clothing/head/collectable/philosopher_wig : /obj/item/clothing/head/philosopher_wig{@OLD} -/obj/item/clothing/head/collectable/plaguedoctorhat : /obj/item/clothing/head/plaguedoctorhat{@OLD} -/obj/item/clothing/head/helmet/space/void/security/riot : /obj/item/clothing/head/helmet/space/void/security/alt{@OLD} -/obj/item/clothing/suit/space/void/security/riot : /obj/item/clothing/suit/space/void/security/alt{@OLD} -/obj/item/clothing/head/helmet/space/vox/pressure : /obj/item/clothing/head/helmet/space/vox{@OLD} -/obj/item/clothing/under/vox/vox_utility : /obj/item/clothing/pants/vox{@OLD} -/obj/item/clothing/suit/space/pirate : /obj/item/clothing/suit/pirate{@OLD} -/obj/item/clothing/suit/costume : /obj/item/clothing/suit/pirate{@OLD} -/obj/item/clothing/suit/costume/hgpirate : /obj/item/clothing/suit/hgpirate{@OLD} -/obj/item/clothing/suit/storage/vest/heavy/merc : /obj/item/clothing/suit/armor/pcarrier/merc{@OLD} -/obj/item/clothing/suit/storage/vest/@SUBTYPES : /obj/item/clothing/suit/armor/vest/@SUBTYPES{@OLD} - -############ -# VAREDITS # -############ -# Atmos varedits -/obj/machinery/computer/air_control/@SUBTYPES{sensors = @SET} : /obj/machinery/computer/air_control/@SUBTYPES{@OLD; sensors = @SKIP} -# move these to the external air subtype so frequencies work -/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1379} : /obj/machinery/atmospherics/unary/vent_pump/high_volume/external_air{@OLD; frequency = @SKIP} -/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrub_id = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} -/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrubbing_gas = list("phoron")} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrubbing_gas = list(/decl/material/solid/phoron)} -/obj/machinery/computer/area_atmos/tag/@SUBTYPES{scrub_id = @SET} : /obj/machinery/computer/area_atmos/tag/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} -# for the rest of this, frequency was moved to component presets and i'm too lazy to set that up -/obj/machinery/door/airlock/@SUBTYPES{frequency = @SET} : /obj/machinery/door/airlock/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/portable_atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/airlock_sensor/@SUBTYPES{frequency = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/air_sensor/@SUBTYPES : /obj/machinery/air_sensor/@SUBTYPES{@OLD; frequency = @SKIP; output = @SKIP} -/obj/machinery/embedded_controller/radio/@SUBTYPES{frequency = @SET} : /obj/machinery/embedded_controller/radio/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/button/@SUBTYPES{frequency = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/meter/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; frequency = @SKIP} - -# id -> id_tag -/obj/machinery/door_timer/@SUBTYPES{id = @SET} : /obj/machinery/door_timer/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/conveyor/@SUBTYPES{id = @SET} : /obj/machinery/conveyor/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/conveyor_switch/@SUBTYPES{id = @SET} : /obj/machinery/conveyor_switch/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/door/@SUBTYPES{id = @SET} : /obj/machinery/door/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/button/@SUBTYPES{id = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/atmospherics/@SUBTYPES{id = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/holosign/bar{id = @SET} : /obj/machinery/holosign/bar{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/meter/@SUBTYPES{id = @SET} : /obj/machinery/meter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/flasher/@SUBTYPES{id = @SET} : /obj/machinery/flasher/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/sparker/@SUBTYPES{id = @SET} : /obj/machinery/sparker/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/mass_driver/@SUBTYPES{id = @SET} : /obj/machinery/mass_driver/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/emitter/@SUBTYPES{id = @SET} : /obj/machinery/emitter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} - -# Camera preset_channels -> network -/obj/machinery/camera/network/@SUBTYPES{network = @SET} : /obj/machinery/camera/network/@SUBTYPES{@OLD; network = @SKIP; preset_channels = @OLD:network} - -# Remove button/sensor master_tag -/obj/machinery/airlock_sensor/@SUBTYPES{master_tag = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; master_tag = @SKIP} -/obj/machinery/button/access/@SUBTYPES{master_tag = @SET} : /obj/machinery/button/access/@SUBTYPES{@OLD; master_tag = @SKIP} - -# Skip power sensor name_tag -/obj/machinery/power/sensor{name_tag = @SET} : /obj/machinery/power/sensor{@OLD; name_tag = @SKIP} - -# join_group -> unique_merge_identifier -/turf/wall/shuttle/@SUBTYPES{join_group = @SET} : /turf/wall/shuttle/@SUBTYPES{@OLD; unique_merge_identifier = @OLD:join_group} - -# Remove set icon states/density on windows, doors, shutters -/obj/machinery/door/blast/regular{icon_state = @SET} : /obj/machinery/door/blast/regular{@OLD; icon_state = @SKIP} -/obj/structure/window/borosilicate_reinforced/@SUBTYPES{icon_state = @SET} : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD; icon_state = @SKIP} -/obj/machinery/door/blast/regular{p_open = 1} : /obj/machinery/door/blast/regular/open{@OLD; p_open = @SKIP} -/obj/machinery/door/blast/regular{p_open = 0} : /obj/machinery/door/blast/regular{@OLD; p_open = @SKIP} -/obj/machinery/door/blast/regular{density = 0} : /obj/machinery/door/blast/regular/open{@OLD; density = @SKIP; opacity = @SKIP} -/obj/structure/window/@SUBTYPES{icon_state = "fwindow"} : /obj/structure/window/@SUBTYPES{@OLD; icon_state = @SKIP} -/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} -/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} - -# Prices -> markup -/obj/machinery/vending/@SUBTYPES{prices = list()} : /obj/machinery/vending/@SUBTYPES{@OLD; markup = 0; prices=@SKIP} -/obj/machinery/vending/@SUBTYPES{prices = @SET} : /obj/machinery/vending/@SUBTYPES{@OLD; prices = @SKIP} - -# Radio varedits -/obj/item/radio/@SUBTYPES{subspace_transmission = @SET} : @OLD {@OLD; subspace_transmission = @SKIP} -/obj/item/radio/@SUBTYPES{syndie = @SET} : @OLD {@OLD; decrypt_all_messages = 1; syndie = @SKIP} -/obj/item/radio/@SUBTYPES{adhoc_fallback = @SET} : @OLD {@OLD; can_use_analog = @SKIP} - -# Empty first-aid kits -/obj/item/storage/firstaid/regular{empty = 1} : /obj/item/firstaid/empty{@OLD; empty = @SKIP; name = @SKIP} - -/obj/machinery/floor_light/prebuilt{on = 1} : /obj/machinery/floor_light/prebuilt{@OLD; use_power = 2; on = @SKIP} - +/obj/item/reagent_containers/@SUBTYPES : /obj/item/chems/@SUBTYPES{@OLD} +/obj/item/material/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/weapon/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/melee/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/packageWrap/@SUBTYPES : /obj/item/stack/package_wrap/@SUBTYPES{@OLD} +/obj/structure/table/rack/@SUBTYPES : /obj/structure/rack/@SUBTYPES{@OLD} +/obj/structure/table/woodentable/holotable : /obj/structure/table/holo_woodentable{@OLD} +/obj/item/chems/food/drinks/@SUBTYPES : /obj/item/chems/drinks/@SUBTYPES{@OLD} +/obj/item/chems/food/snacks/@SUBTYPES : /obj/item/food/@SUBTYPES{@OLD} +/obj/item/chems/food/condiment/@SUBTYPES : /obj/item/chems/condiment/@SUBTYPES{@OLD} +/obj/item/chems/condiment/peppermill/@SUBTYPES : /obj/item/chems/condiment/small/peppermill/@SUBTYPES{@OLD} +/obj/item/chems/condiment/saltshaker/@SUBTYPES : /obj/item/chems/condiment/small/saltshaker/@SUBTYPES{@OLD} +/obj/item/analyzer : /obj/item/scanner/gas{@OLD} +/obj/item/analyzer/plant_analyzer/@SUBTYPES : /obj/item/scanner/plant/@SUBTYPES{@OLD} +/obj/item/tape_roll/@SUBTYPES : /obj/item/stack/tape_roll/@SUBTYPES{@OLD} +/obj/structure/table/standard/@SUBTYPES : /obj/structure/table/@SUBTYPES{@OLD} +/obj/machinery/bluespacerelay/@SUBTYPES : /obj/machinery/commsrelay/@SUBTYPES{@OLD} +/obj/machinery/computer/helm/@SUBTYPES : /obj/machinery/computer/ship/helm/@SUBTYPES{@OLD} +/obj/machinery/computer/engines/@SUBTYPES : /obj/machinery/computer/ship/engines/@SUBTYPES{@OLD} +/obj/machinery/computer/navigation/@SUBTYPES : /obj/machinery/computer/ship/navigation/@SUBTYPES{@OLD} +/obj/machinery/requests_console/@SUBTYPES : /obj/machinery/network/requests_console/@SUBTYPES{@OLD; departmentType = @SKIP} +/obj/item/healthanalyzer/@SUBTYPES : /obj/item/scanner/health/@SUBTYPES{@OLD} +/obj/machinery/iv_drip/@SUBTYPES : /obj/structure/iv_drip/@SUBTYPES{@OLD} +/obj/structure/device/piano/@SUBTYPES : /obj/structure/synthesized_instrument/synthesizer/piano/@SUBTYPES{@OLD} +/obj/item/folder/white/@SUBTYPES : /obj/item/folder/@SUBTYPES{@OLD} +/obj/machinery/dnaforensics/@SUBTYPES : /obj/machinery/forensic/dnascanner/@SUBTYPES{@OLD} +/obj/machinery/microscope/@SUBTYPES : /obj/machinery/forensic/microscope/@SUBTYPES{@OLD} +/obj/item/stack/material/steel/@SUBTYPES : /obj/item/stack/material/sheet/mapped/steel/@SUBTYPES{@OLD} +/obj/item/stack/material/plasteel/@SUBTYPES : /obj/item/stack/material/sheet/reinforced/mapped/plasteel/@SUBTYPES{@OLD} +/obj/item/stack/material/glass/reinforced/@SUBTYPES : /obj/item/stack/material/pane/mapped/rglass/@SUBTYPES{@OLD} +/obj/item/stack/material/glass/@SUBTYPES : /obj/item/stack/material/pane/mapped/glass/@SUBTYPES{@OLD} +/obj/item/stack/material/wood/@SUBTYPES : /obj/item/stack/material/plank/mapped/wood/@SUBTYPES{@OLD} +/obj/item/stack/material/deuterium/@SUBTYPES : /obj/item/stack/material/aerogel/mapped/deuterium/@SUBTYPES{@OLD} +/obj/item/stack/material/uranium/@SUBTYPES : /obj/item/stack/material/puck/mapped/uranium/@SUBTYPES{@OLD} +/obj/machinery/autolathe/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD} +/obj/machinery/message_server/@SUBTYPES : /obj/machinery/network/message_server/@SUBTYPES{@OLD} +/obj/item/floor_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} +/obj/machinery/pipedispenser/@SUBTYPES : /obj/machinery/fabricator/pipe/@SUBTYPES{@OLD} +/obj/machinery/power/emitter/@SUBTYPES : /obj/machinery/emitter/@SUBTYPES{@OLD} +/obj/machinery/power/fusion_core/@SUBTYPES : /obj/machinery/fusion_core/@SUBTYPES{@OLD} +/obj/item/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} +/obj/machinery/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} +/obj/machinery/computer/modular/preset/command/@SUBTYPES : /obj/machinery/computer/modular/preset/cardslot/command/@SUBTYPES{@OLD} +/obj/machinery/computer/fusion_core_control/@SUBTYPES : /obj/machinery/computer/fusion/core_control/@SUBTYPES{@OLD} +/obj/machinery/computer/fusion_fuel_control/@SUBTYPES : /obj/machinery/computer/fusion/fuel_control/@SUBTYPES{@OLD} +/obj/machinery/computer/gyrotron_control/@SUBTYPES : /obj/machinery/computer/fusion/gyrotron/@SUBTYPES{@OLD} +/obj/machinery/computer/power_monitor/@SUBTYPES : /obj/machinery/computer/modular/preset/engineering/power/@SUBTYPES{@OLD} +/obj/item/module/power_control/@SUBTYPES : /obj/item/stock_parts/circuitboard/apc/@SUBTYPES{@OLD} +/obj/machinery/power/port_gen/@SUBTYPES : /obj/machinery/port_gen/@SUBTYPES{@OLD} +/obj/item/pipe_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} +/obj/item/airlock_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/airlock_electronics/@SUBTYPES{@OLD} +/obj/item/airalarm_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/air_alarm/@SUBTYPES{@OLD} +/obj/item/autopsy_scanner/@SUBTYPES : /obj/item/scanner/autopsy/@SUBTYPES{@OLD} +/obj/machinery/fusion_fuel_compressor/@SUBTYPES : /obj/machinery/fuel_compressor/@SUBTYPES{@OLD} +/obj/item/extinguisher/micro/@SUBTYPES : /obj/item/chems/spray/extinguisher/mini/@SUBTYPES{@OLD} +/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} +/obj/item/stack/material/plastic/@SUBTYPES : /obj/item/stack/material/panel/mapped/plastic/@SUBTYPES{@OLD} +/obj/machinery/computer/general_air_control/@SUBTYPES : /obj/machinery/computer/air_control/@SUBTYPES{@OLD} +/obj/machinery/computer/air_control/large_tank_control : /obj/machinery/computer/air_control{@OLD} +/turf/simulated/floor/tiled/steel/@SUBTYPES : /turf/simulated/floor/tiled/@SUBTYPES{@OLD} +/obj/machinery/power/engine/@SUBTYPES : /obj/machinery/ion_thruster/@SUBTYPES{@OLD} +/obj/machinery/computer/aifixer/@SUBTYPES : /obj/machinery/computer/modular/preset/aislot/sysadmin/@SUBTYPES{@OLD} +/obj/machinery/computer/aiupload/@SUBTYPES : /obj/machinery/computer/upload/ai/@SUBTYPES{@OLD} +/obj/machinery/computer/borgupload/@SUBTYPES : /obj/machinery/computer/upload/robot/@SUBTYPES{@OLD} +/obj/machinery/computer/supplycomp/control/@SUBTYPES : /obj/machinery/computer/modular/preset/dock/@SUBTYPES{@OLD} +/obj/machinery/computer/supplycomp/@SUBTYPES : /obj/machinery/computer/modular/preset/supply_public/@SUBTYPES{@OLD} +/obj/item/closet_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} +/turf/simulated/shuttle/plating/@SUBTYPES : /turf/floor/shuttle +/turf/simulated/shuttle/floor/@SUBTYPES : /turf/floor/shuttle/@SUBTYPES + +# REMOVE BAD VAREDITS +/@SUBTYPES {layer = @SET} : @OLD {@OLD; layer = @SKIP} +/@SUBTYPES {plane = @SET} : @OLD {@OLD; plane = @SKIP} +/obj/structure/cable/@SUBTYPES : @OLD {@OLD; d1 = @SKIP;d2 = @SKIP} +# unacidable removed +/@SUBTYPES {unacidable = @SET} : @OLD{@OLD; unacidable = @SKIP} +# Simple pipes shall not face north or west +/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} +/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} +/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} +/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} +# Do not change air alarm frequency on base type +/obj/machinery/alarm {frequency = @SET} : @OLD {@OLD; frequency = @SKIP} +# we use a completely different access format +/@SUBTYPES {req_access = @SET}: @OLD {@OLD; req_access = @SKIP;} +/@SUBTYPES {req_one_access = @SET}: @OLD {@OLD; req_one_access = @SKIP;} +/obj/machinery/door/blast/shutters{icon_state = "shutter0"} : /obj/machinery/door/blast/shutters{@OLD; icon_state = @SKIP} +/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1; density = 0, opacity = 0} : /obj/machinery/door/airlock/external/glass/bolted_open{@OLD; icon_state = @SKIP; locked = @SKIP, density = @SKIP; opacity = @SKIP} +/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1} : /obj/machinery/door/airlock/external/glass/bolted{@OLD; icon_state = @SKIP; locked = @SKIP} + +# BUTTONS +/obj/machinery/access_button/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} +/obj/machinery/access_button/airlock_interior : /obj/machinery/button/access/interior{@OLD} +/obj/machinery/airlock_sensor/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} +/obj/machinery/airlock_sensor/airlock_interior : /obj/machinery/button/access/interior{@OLD} +/obj/machinery/access_button : /obj/machinery/button/access{@OLD} +/obj/machinery/button/remote/airlock{specialfunctions = 4} : /obj/machinery/button/alternate/door/bolts{@OLD; specialfunctions = @SKIP; desiredstate = @SKIP} +/obj/machinery/button/remote/airlock : /obj/machinery/button/alternate/door{@OLD} +/obj/machinery/button/remote/driver : /obj/machinery/button/mass_driver{@OLD} +/obj/machinery/button/remote/blast_door : /obj/machinery/button/blast_door{@OLD} +/obj/machinery/button/remote : /obj/machinery/button/alternate{@OLD} + +# Medical +/obj/item/pill_bottle/tramadol : /obj/item/pill_bottle/strong_painkillers{@OLD} +/obj/item/chems/pill/tramadol : /obj/item/chems/pill/strong_painkillers{@OLD} +/obj/item/chems/glass/bottle/stoxin : /obj/item/chems/glass/bottle/sedatives{@OLD} +/obj/item/chems/glass/bottle/inaprovaline : /obj/item/chems/glass/bottle/stabilizer{@OLD} +/obj/item/chems/syringe/inaprovaline : /obj/item/chems/syringe/stabilizer{@OLD} +/obj/item/chems/blood/empty : /obj/item/chems/ivbag{@OLD} +/obj/item/chems/blood/@SUBTYPES : /obj/item/chems/ivbag/blood/@SUBTYPES{@OLD} +/obj/item/defib_kit/@SUBTYPES : /obj/item/defibrillator/@SUBTYPES{@OLD} +/obj/item/chems/spray/sterilizine : /obj/item/chems/spray/antiseptic{@OLD} + +# Drinking glasses and cups +/obj/item/chems/drinks/cup : /obj/item/chems/drinks/glass2/coffeecup{@OLD} +/obj/item/chems/drinks/drinkingglass : /obj/item/chems/drinks/glass2/square{@OLD} + +# Airtight flaps +/obj/structure/plasticflaps/mining : /obj/structure/flaps/airtight{@OLD} + +# Bushes +/obj/structure/flora/ausbushes/@SUBTYPES : /obj/structure/flora/bush/@SUBTYPES + +# Cassette tapes -> magnetic tapes +/obj/item/cassette_tape/@SUBTYPES : /obj/item/magnetic_tape/@SUBTYPES{@OLD} +/obj/item/tape_recorder : /obj/item/taperecorder{@OLD} + +# FIFTYSPAWNER -> MAPPED SHEETS +/obj/fiftyspawner/wood : /obj/item/stack/material/plank/mapped/wood/fifty +/obj/fiftyspawner/steel : /obj/item/stack/material/sheet/mapped/steel/fifty +/obj/fiftyspawner/glass : /obj/item/stack/material/pane/mapped/glass/fifty +/obj/fiftyspawner/deuterium : /obj/item/stack/material/aerogel/mapped/deuterium/fifty +/obj/fiftyspawner/tritium : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/osmium : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/phoron : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/rods : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/grass : /obj/item/stack/tile/grass{amount = 50} +/obj/fiftyspawner/plasteel : /obj/item/stack/material/aerogel/mapped/tritium/fifty + +# STOCK PARTS AND SMES COILS +/obj/item/stock_parts/subspace/sub_filter : /obj/item/stock_parts/subspace/filter +/obj/item/smes_coil/@SUBTYPES : /obj/item/stock_parts/smes_coil/@SUBTYPES{@OLD} +/obj/item/circuitboard/@SUBTYPES : /obj/item/stock_parts/circuitboard/@SUBTYPES{@OLD} +/obj/item/airlock_electronics : /obj/item/stock_parts/circuitboard/airlock_electronics{@OLD} + +# CLOTHING +/obj/item/clothing/head/cone : /obj/item/caution/cone{@OLD} +/obj/item/clothing/belt/security/tactical : /obj/item/belt/holster/security/tactical{@OLD} + +# Item remains +/obj/effect/decal/remains/@SUBTYPES : /obj/item/remains/@SUBTYPES{@OLD} + +# Circuit prefabs +/obj/item/hand_tele : /obj/prefab/hand_teleporter{@OLD} + +# Filing cabinets +/obj/structure/filingcabinet : /obj/structure/filing_cabinet{@OLD} +/obj/structure/filingcabinet/chestdrawer : /obj/structure/filing_cabinet/chestdrawer{@OLD} +/obj/structure/filingcabinet/filingcabinet : /obj/structure/filing_cabinet/tall{@OLD} +/obj/structure/filingcabinet/medical : /obj/structure/filing_cabinet/records/medical{@OLD} +/obj/structure/filingcabinet/security : /obj/structure/filing_cabinet/records{@OLD} + +# Machine frames +/obj/structure/frame: /obj/machinery/constructable_frame/machine_frame{@OLD} +/obj/machinery/constructable_frame/machine_frame{anchored = 1} : /obj/machinery/constructable_frame/machine_frame/deconstruct{anchored = @SKIP} +/obj/structure/frame/computer : /obj/machinery/constructable_frame/computerframe{@OLD} +/obj/machinery/constructable_frame/computerframe{anchored = 1} : /obj/machinery/constructable_frame/computerframe/deconstruct{anchored = @SKIP} + +# Hygiene/bathroom objects +/obj/structure/toilet : /obj/structure/hygiene/toilet{@OLD} +/obj/structure/sink/@SUBTYPES : /obj/structure/hygiene/sink/@SUBTYPES{@OLD} +/obj/machinery/shower : /obj/structure/hygiene/shower{@OLD} + +# Turbolift spawners +/obj/turbolift_map_holder/@SUBTYPES : /obj/abstract/turbolift_spawner/@SUBTYPES{@OLD} + +# Borosilicate windows +/obj/structure/window/phoronreinforced/@SUBTYPES : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD} + +# Tools; see 3763_pickaxe_hammer and 3959_hatchets for other migrations +/obj/item/knife/machete : /obj/item/tool/machete{@OLD} +/obj/item/knife/machete/hatchet : /obj/item/tool/axe/hatchet{@OLD} +/obj/item/tool/pickaxe/hand : /obj/item/tool/pickaxe/xeno/hand{@OLD} + +# RANDOM SPAWNERS +/obj/random/cigarettes : /obj/random/smokes{@OLD} +/obj/item/lipstick/random : /obj/random/lipstick +/obj/random/slimecore : /obj/item/slime_extract/random{@OLD} + +# MINING EQUIPMENT +/obj/machinery/mineral/processing_unit : /obj/machinery/material_processing/smeltery +/obj/machinery/mineral/stacking_machine : /obj/machinery/material_processing/stacker +/obj/machinery/mineral/unloading_machine : /obj/machinery/material_processing/unloader +/obj/machinery/mineral/output : @DELETE +/obj/machinery/mineral/input : @DELETE +/obj/machinery/mineral/mint : @DELETE +/obj/machinery/mineral/processing_unit_console : @DELETE + +# NEW PDAS (NO CARTRIDGES) +/obj/item/pda/@SUBTYPES : /obj/item/modular_computer/pda/@SUBTYPES{@OLD} +/obj/item/modular_computer/pda/captain : /obj/item/modular_computer/pda/heads/captain +/obj/item/storage/box/seccarts : @DELETE +/obj/item/cartridge/@SUBTYPES : @DELETE + +# MODULAR COMPUTER PRESETS +/obj/machinery/computer/card : /obj/machinery/computer/modular/preset/cardslot/personnel{@OLD} +/obj/machinery/computer/secure_data : /obj/machinery/computer/modular/preset/civilian{@OLD} +/obj/machinery/computer/skills : /obj/machinery/computer/modular/preset/civilian{@OLD} +/obj/machinery/computer/security/telescreen : /obj/machinery/computer/modular/telescreen/preset/security{@OLD} +/obj/machinery/computer/security/telescreen/entertainment : /obj/machinery/computer/modular/telescreen/preset/entertainment{@OLD} +/obj/machinery/computer/security/mining : /obj/machinery/computer/modular/preset/security{@OLD} +/obj/machinery/computer/security/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES +/obj/machinery/computer/crew : /obj/machinery/computer/modular/preset/medical{@OLD} +/obj/machinery/computer/rcon : /obj/machinery/computer/modular/preset/engineering/rcon{@OLD} +/obj/machinery/computer/communications : /obj/machinery/computer/modular/preset/cardslot/command{@OLD} +/obj/machinery/computer/med_data : /obj/machinery/computer/modular/preset/civilian{@OLD} +/obj/machinery/computer/med_data/laptop : /obj/item/modular_computer/laptop/preset/records{@OLD} + +# ATMOS REPATHS +/obj/machinery/atmospherics/pipe/tank/@SUBTYPES : /obj/machinery/atmospherics/unary/tank/@SUBTYPES +/obj/machinery/portable_atmospherics/canister/nitrous_oxide : /obj/machinery/portable_atmospherics/canister/sleeping_agent{@OLD} + +# MISC. ITEMS +/obj/item/moneybag/vault : /obj/item/bag/cash/filled{@OLD} +/obj/item/moneybag : /obj/item/bag/cash{@OLD} +/obj/item/chems/bucket : /obj/item/chems/glass/bucket{@OLD} +/obj/item/card/id/gold/captain/spare : /obj/item/card/id/captains_spare{@OLD} +/obj/item/chainofcommand : /obj/item/whip/chainofcommand{@OLD} +/obj/item/chems/drinks/bottle/specialwhiskey : /obj/item/chems/drinks/bottle/agedwhiskey{@OLD} + +# Tape is weird +/obj/item/taperoll/@SUBTYPES : /obj/item/stack/tape_roll/barricade_tape/@SUBTYPES{@OLD} +/obj/item/tape/@SUBTYPES : /obj/structure/tape_barricade/@SUBTYPES{@OLD} + +# Radio +/obj/item/radio/headset/headset_sec/alt : /obj/item/radio/headset/headset_sec/bowman{@OLD} +/obj/item/radio/headset/syndicate : /obj/item/radio/headset/hacked{@OLD} +/obj/item/radio/headset/syndicate/alt : /obj/item/radio/headset/hacked{@OLD} +/obj/item/phone : /obj/item/radio/phone{@OLD} + +# Singulo +/obj/machinery/the_singularitygen : /obj/machinery/singularity_generator{@OLD} + +# FABRICATORS +/obj/machinery/autolathe{hacked = 1} : /obj/machinery/fabricator/hacked{@OLD; hacked = @SKIP} +/obj/machinery/autolathe : /obj/machinery/fabricator{@OLD} +/obj/machinery/pipedispenser : /obj/machinery/fabricator/pipe{@OLD; anchored = 1} +/obj/machinery/pipedispenser/orderable : /obj/machinery/fabricator/pipe{@OLD} +/obj/machinery/pipedispenser/disposal : /obj/machinery/fabricator/pipe/disposal{@OLD; anchored = 1} +/obj/machinery/pipedispenser/disposal/orderable : /obj/machinery/fabricator/pipe/disposal{@OLD} +/obj/machinery/r_n_d/circuit_imprinter : /obj/machinery/fabricator/imprinter{@OLD} +/obj/machinery/pros_fabricator : /obj/machinery/fabricator/robotics{@OLD} +/obj/machinery/mecha_part_fabricator : /obj/machinery/fabricator/industrial{@OLD} +/obj/machinery/r_n_d/protolathe : /obj/machinery/fabricator/protolathe{@OLD} +/obj/machinery/bookbinder : /obj/machinery/fabricator/book{@OLD} +/obj/machinery/organ_printer/flesh : /obj/machinery/fabricator/bioprinter{@OLD} +/obj/machinery/vending/food : /obj/machinery/fabricator/replicator + +/obj/machinery/fabricator/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD; res_max_amount = @SKIP; speed = @SKIP} + +# MMIs and posibrains +/obj/item/mmi/digital/@SUBTYPES : /obj/item/organ/internal/brain/robotic{@OLD} +/obj/item/mmi/@SUBTYPES : /obj/item/organ/internal/brain_interface/@SUBTYPES{@OLD} +/obj/item/organ/internal/posibrain : /obj/item/organ/internal/brain/robotic/positronic{@OLD} + +# Energy blades +/obj/item/energy/@SUBTYPES : /obj/item/energy_blade/@SUBTYPES{@OLD} + +# Medals and other accessories; see 3902_ties.txt for further migrations +/obj/item/clothing/accessory/medal/bronze_heart : /obj/item/clothing/accessory/medal/nanotrasen/bronze{@OLD} +/obj/item/clothing/accessory/medal/nobel_science : /obj/item/clothing/medal/nanotrasen/silver{@OLD} +/obj/item/clothing/accessory/scarf/white : /obj/item/clothing/accessory/scarf{@OLD} +/obj/item/clothing/accessory/storage/webbing : /obj/item/clothing/accessory/webbing/vest + +# MATERIALS +/obj/item/stack/material/plastic : /obj/item/stack/material/panel/mapped/plastic{@OLD} +/obj/item/stack/material/sandstone : /obj/item/stack/material/brick/mapped/sandstone{@OLD} +/obj/item/stack/material/mhydrogen : /obj/item/stack/material/segment/mapped/mhydrogen{@OLD} +/obj/item/stack/material/diamond : /obj/item/stack/material/gemstone/mapped/diamond{@OLD} +/obj/item/stack/material/wood : /obj/item/stack/material/plank/mapped/wood{@OLD} +/obj/item/stack/material/steel : /obj/item/stack/material/sheet/mapped/steel{@OLD} +/obj/item/stack/material/glass : /obj/item/stack/material/pane/mapped/glass{@OLD} +/obj/item/stack/material/phoron : /obj/item/stack/material/crystal/mapped/phoron{@OLD} +/obj/item/stack/material/algae : /obj/item/stack/material/puck/mapped/algae{@OLD} +/obj/item/stack/material/gold : /obj/item/stack/material/ingot/mapped/gold{@OLD} +/obj/item/stack/material/plasteel : /obj/item/stack/material/reinforced/mapped/plasteel{@OLD} +/obj/item/stack/material/glass/reinforced : /obj/item/stack/material/pane/mapped/rglass{@OLD} +/obj/item/stack/material/glass/phoronglass : /obj/item/stack/material/pane/mapped/borosilicate{@OLD} +/obj/item/stack/material/glass/phoronrglass : /obj/item/stack/material/pane/mapped/rborosilicate{@OLD} +/obj/item/stack/rods : /obj/item/stack/material/rods{@OLD} +/obj/item/packageWrap{amount = @UNSET} : /obj/item/stack/package_wrap/twenty_five{@OLD; amount = @SKIP} +/obj/item/packageWrap : /obj/item/stack/package_wrap{@OLD} +/obj/item/wrapping_paper{amount = @UNSET} : /obj/item/stack/package_wrap/gift/twenty_five{@OLD; amount = @SKIP} +/obj/item/wrapping_paper : /obj/item/stack/package_wrap{@OLD} + +/obj/structure/dispenser{phorontanks = 0} : /obj/structure/tank_rack/oxygen{@OLD; phorontanks = @SKIP} +/obj/structure/dispenser/oxygen{oxygentanks = 0} : /obj/structure/tank_rack/empty{@OLD; oxygentanks = @SKIP} +/obj/structure/dispenser/oxygen : /obj/structure/tank_rack/oxygen +/obj/structure/dispenser : /obj/structure/tank_rack + +# TELECOMMS REMOVAL +/obj/item/stock_parts/circuitboard/telecomms/@SUBTYPES : @DELETE +/obj/machinery/telecomms/@SUBTYPES : @DELETE +/obj/machinery/computer/telecomms/@SUBTYPES : @DELETE + +/obj/machinery/r_n_d/server/@SUBTYPES : /obj/machinery/design_database +/obj/machinery/r_n_d/destructive_analyzer : /obj/machinery/destructive_analyzer + +# SMES bullshit +/obj/machinery/power/smes/buildable/engine : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 1)} +/obj/machinery/power/smes/buildable/main : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 4)} +/obj/machinery/power/smes/buildable/point_of_interest : /obj/machinery/power/smes/buildable/preset/hidden + +/obj/item/surgical/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/FixOVein : /obj/item/sutures{@OLD} + +/obj/structure/flora/skeleton : /obj/structure/skele_stand{@OLD} + +/obj/mecha/working/ripley/firefighter : /mob/living/exosuit/premade/firefighter +/obj/mecha/working/ripley/mining : /mob/living/exosuit/premade/powerloader + +/obj/structure/AIcore/@SUBTYPES : /obj/structure/aicore/@SUBTYPES +/obj/item/tank/vox : /obj/item/tank/nitrogen{@OLD} + +/obj/machinery/shuttle_sensor : /obj/machinery/airlock_sensor/shuttle{@OLD} + +/obj/machinery/computer/rdconsole/@SUBTYPES : /obj/machinery/computer/design_console{@OLD} +/obj/machinery/computer/rdservercontrol : /obj/machinery/computer/design_console{@OLD; name = @SKIP; badmin = @SKIP} +/obj/item/stock_parts/circuitboard/rdconsole : /obj/item/stock_parts/circuitboard/design_console{@OLD} +/obj/item/stock_parts/circuitboard/rdserver : /obj/item/stock_parts/circuitboard/design_database{@OLD} + +/obj/machinery/account_database : /obj/machinery/computer/account_database{@OLD} +/obj/machinery/shield_gen/@SUBTYPES : /obj/machinery/shield_generator + +/obj/structure/morgue/crematorium : /obj/structure/crematorium{@OLD} + +/obj/item/robot_parts/frame : /obj/item/robot_parts/robot_suit{@OLD} + +/obj/structure/closet/secure_closet/psych : /obj/structure/closet/secure_closet/psychiatry{@OLD} +/obj/structure/closet/firecloset/full : /obj/structure/closet/firecloset{@OLD} +/obj/structure/closet/firecloset/full/double : /obj/structure/closet/firecloset/chief{@OLD} +/obj/structure/closet/l3closet/scientist/double : /obj/structure/closet/l3closet/scientist/multi{@OLD} +/obj/structure/closet/secure_closet/hos2 : /obj/structure/closet/secure_closet/hos{@OLD} +/obj/structure/closet/secure_closet/medical_wall/synth_anesthetics : /obj/structure/closet/secure_closet/medical_wall/anesthetics/robotics{@OLD} +/obj/structure/closet/secure_closet/medical2 : /obj/structure/closet/secure_closet/anesthetics{@OLD} +/obj/structure/closet/walllocker/emerglocker/@SUBTYPES : /obj/structure/emergency_dispenser/@SUBTYPES{@OLD} + +/obj/item/firstaid_arm_assembly : /obj/item/firstaid/empty, /obj/item/robot_parts/l_arm +/obj/item/bucket_sensor : /obj/item/chems/glass/bucket, /obj/item/assembly/prox_sensor +/obj/item/broken_device : @DELETE + +/obj/item/spacecash/@SUBTYPES : /obj/item/cash/@SUBTYPES{@OLD} + +/obj/item/kit/paint/ripley : /obj/item/kit/paint/camouflage +/obj/item/kit/paint/ripley/death : /obj/item/kit/paint/camouflage/forest +/obj/item/kit/paint/ripley/flames_blue : /obj/item/kit/paint/flames_blue +/obj/item/kit/paint/ripley/flames_red : /obj/item/kit/paint/flames_red + +/obj/machinery/photocopier/faxmachine : /obj/machinery/faxmachine{@OLD; init_network_tag = @OLD:department; department = @SKIP} +/obj/item/tvcamera : /obj/item/camera/tvcamera{@OLD} +/obj/machinery/station_map : /obj/machinery/holomap{@OLD} + +/obj/item/ducttape : /obj/item/duct_tape{@OLD} +/obj/item/toy/katana : /obj/item/sword/katana/toy{@OLD} +/obj/item/toy/cultsword : /obj/item/sword/cult_toy{@OLD} +/obj/item/toy/sword : /obj/item/energy_blade/sword/toy{@OLD} +/obj/item/lipstick/jade : /obj/item/cosmetics/lipstick/green{@OLD} +/obj/item/rig_module/device/plasmacutter : /obj/item/rig_module/mounted/plasmacutter{@OLD} +/obj/item/storage/box/syndie_kit/ewar_voice : /obj/item/backpack/satchel/syndie_kit/ewar_voice +/obj/item/tray : /obj/item/plate/tray{@OLD} +/obj/item/weldingtool/weldpack : /obj/item/chems/weldpack{@OLD} +/obj/machinery/crystal : /obj/structure/crystal{@OLD} +/obj/item/organ/internal/stack : /obj/item/organ/internal/voxstack{@OLD} +/obj/item/radio_jammer : /obj/item/suit_sensor_jammer + +# AMMO BOXES +/obj/item/storage/box/beanbags/@SUBTYPES : /obj/item/box/ammo/beanbags/@SUBTYPES{@OLD} +/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} +/obj/item/storage/box/blanks/@SUBTYPES : /obj/item/box/ammo/blanks/@SUBTYPES{@OLD} +/obj/item/storage/box/empshells/@SUBTYPES : /obj/item/box/ammo/empshells/@SUBTYPES{@OLD} +/obj/item/storage/box/flashshells/@SUBTYPES : /obj/item/box/ammo/flashshells/@SUBTYPES{@OLD} +/obj/item/storage/box/shotgunammo/@SUBTYPES : /obj/item/box/ammo/shotgunammo/@SUBTYPES{@OLD} +/obj/item/storage/box/shotgunshells/@SUBTYPES : /obj/item/box/ammo/shotgunshells/@SUBTYPES{@OLD} +/obj/item/storage/box/sniperammo/@SUBTYPES : /obj/item/box/ammo/sniperammo/@SUBTYPES{@OLD} +/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} + +/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} +/obj/item/camera_assembly : /obj/item/frame/camera/kit +/obj/structure/ladder/up : /obj/structure/ladder +/obj/random/mob/mouse : /obj/random/mouse + +/obj/structure/closet/grave/dirthole : /obj/structure/pit{@OLD} +/obj/structure/closet/grave/@SUBTYPES : /obj/structure/pit/closed/grave{@OLD} + +/obj/item/banner/nt : /obj/item/banner/nanotrasen{@OLD} + +/obj/item/box/syndie_kit/clerical : /obj/item/backpack/satchel/syndie_kit/clerical{@OLD} + +/obj/item/clothing/under/costume/rainbow : /obj/item/clothing/jumpsuit/rainbow{@OLD} +/obj/item/clothing/under/dress/dress_orange : /obj/item/clothing/dress/orange{@OLD} +/obj/item/clothing/head/collectable/xenos : /obj/item/clothing/head/xenos{@OLD} +/obj/item/clothing/head/collectable/bearpelt : /obj/item/clothing/head/bearpelt{@OLD} +/obj/item/clothing/head/collectable/philosopher_wig : /obj/item/clothing/head/philosopher_wig{@OLD} +/obj/item/clothing/head/collectable/plaguedoctorhat : /obj/item/clothing/head/plaguedoctorhat{@OLD} +/obj/item/clothing/head/helmet/space/void/security/riot : /obj/item/clothing/head/helmet/space/void/security/alt{@OLD} +/obj/item/clothing/suit/space/void/security/riot : /obj/item/clothing/suit/space/void/security/alt{@OLD} +/obj/item/clothing/head/helmet/space/vox/pressure : /obj/item/clothing/head/helmet/space/vox{@OLD} +/obj/item/clothing/under/vox/vox_utility : /obj/item/clothing/pants/vox{@OLD} +/obj/item/clothing/suit/space/pirate : /obj/item/clothing/suit/pirate{@OLD} +/obj/item/clothing/suit/costume : /obj/item/clothing/suit/pirate{@OLD} +/obj/item/clothing/suit/costume/hgpirate : /obj/item/clothing/suit/hgpirate{@OLD} +/obj/item/clothing/suit/storage/vest/heavy/merc : /obj/item/clothing/suit/armor/pcarrier/merc{@OLD} +/obj/item/clothing/suit/storage/vest/@SUBTYPES : /obj/item/clothing/suit/armor/vest/@SUBTYPES{@OLD} + +# Migrate/delete old mech parts +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster : @DELETE +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster : @DELETE +/obj/item/mecha_parts/mecha_equipment/repair_droid : @DELETE +/obj/item/mecha_parts/mecha_equipment/teleporter : @DELETE +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay : @DELETE +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer : @DELETE +/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill : /obj/item/mech_equipment/drill/diamond{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher : /obj/item/mech_equipment/mounted_system/extinguisher{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp : /obj/item/mech_equipment/clamp{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/passenger : @DELETE +/obj/item/mecha_parts/mecha_equipment/tool/rcd : /obj/item/mech_equipment/mounted_system/rcd{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/sleeper : /obj/item/mech_equipment/sleeper{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun : @DELETE +/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion : /obj/item/mech_equipment/mounted_system/taser/ion{@OLD} +/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser : /obj/item/mech_equipment/mounted_system/taser{@OLD} +/obj/item/mecha_parts/mecha_tracking : @DELETE + +############ +# VAREDITS # +############ +# Atmos varedits +/obj/machinery/computer/air_control/@SUBTYPES{sensors = @SET} : /obj/machinery/computer/air_control/@SUBTYPES{@OLD; sensors = @SKIP} +# move these to the external air subtype so frequencies work +/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1379} : /obj/machinery/atmospherics/unary/vent_pump/high_volume/external_air{@OLD; frequency = @SKIP} +/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrub_id = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} +/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrubbing_gas = list("phoron")} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrubbing_gas = list(/decl/material/solid/phoron)} +/obj/machinery/computer/area_atmos/tag/@SUBTYPES{scrub_id = @SET} : /obj/machinery/computer/area_atmos/tag/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} +# for the rest of this, frequency was moved to component presets and i'm too lazy to set that up +/obj/machinery/door/airlock/@SUBTYPES{frequency = @SET} : /obj/machinery/door/airlock/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/portable_atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/airlock_sensor/@SUBTYPES{frequency = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/air_sensor/@SUBTYPES : /obj/machinery/air_sensor/@SUBTYPES{@OLD; frequency = @SKIP; output = @SKIP} +/obj/machinery/embedded_controller/radio/@SUBTYPES{frequency = @SET} : /obj/machinery/embedded_controller/radio/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/button/@SUBTYPES{frequency = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/meter/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; frequency = @SKIP} + +# id -> id_tag +/obj/machinery/door_timer/@SUBTYPES{id = @SET} : /obj/machinery/door_timer/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/conveyor/@SUBTYPES{id = @SET} : /obj/machinery/conveyor/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/conveyor_switch/@SUBTYPES{id = @SET} : /obj/machinery/conveyor_switch/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/door/@SUBTYPES{id = @SET} : /obj/machinery/door/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/button/@SUBTYPES{id = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/atmospherics/@SUBTYPES{id = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/holosign/bar{id = @SET} : /obj/machinery/holosign/bar{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/meter/@SUBTYPES{id = @SET} : /obj/machinery/meter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/flasher/@SUBTYPES{id = @SET} : /obj/machinery/flasher/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/sparker/@SUBTYPES{id = @SET} : /obj/machinery/sparker/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/mass_driver/@SUBTYPES{id = @SET} : /obj/machinery/mass_driver/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/emitter/@SUBTYPES{id = @SET} : /obj/machinery/emitter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} + +# Camera preset_channels -> network +/obj/machinery/camera/network/@SUBTYPES{network = @SET} : /obj/machinery/camera/network/@SUBTYPES{@OLD; network = @SKIP; preset_channels = @OLD:network} + +# Remove button/sensor master_tag +/obj/machinery/airlock_sensor/@SUBTYPES{master_tag = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; master_tag = @SKIP} +/obj/machinery/button/access/@SUBTYPES{master_tag = @SET} : /obj/machinery/button/access/@SUBTYPES{@OLD; master_tag = @SKIP} + +# Skip power sensor name_tag +/obj/machinery/power/sensor{name_tag = @SET} : /obj/machinery/power/sensor{@OLD; name_tag = @SKIP} + +# join_group -> unique_merge_identifier +/turf/wall/shuttle/@SUBTYPES{join_group = @SET} : /turf/wall/shuttle/@SUBTYPES{@OLD; unique_merge_identifier = @OLD:join_group} + +# Remove set icon states/density on windows, doors, shutters +/obj/machinery/door/blast/regular{icon_state = @SET} : /obj/machinery/door/blast/regular{@OLD; icon_state = @SKIP} +/obj/structure/window/borosilicate_reinforced/@SUBTYPES{icon_state = @SET} : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD; icon_state = @SKIP} +/obj/machinery/door/blast/regular{p_open = 1} : /obj/machinery/door/blast/regular/open{@OLD; p_open = @SKIP} +/obj/machinery/door/blast/regular{p_open = 0} : /obj/machinery/door/blast/regular{@OLD; p_open = @SKIP} +/obj/machinery/door/blast/regular{density = 0} : /obj/machinery/door/blast/regular/open{@OLD; density = @SKIP; opacity = @SKIP} +/obj/structure/window/@SUBTYPES{icon_state = "fwindow"} : /obj/structure/window/@SUBTYPES{@OLD; icon_state = @SKIP} +/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} +/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} + +# Prices -> markup +/obj/machinery/vending/@SUBTYPES{prices = list()} : /obj/machinery/vending/@SUBTYPES{@OLD; markup = 0; prices=@SKIP} +/obj/machinery/vending/@SUBTYPES{prices = @SET} : /obj/machinery/vending/@SUBTYPES{@OLD; prices = @SKIP} + +# Radio varedits +/obj/item/radio/@SUBTYPES{subspace_transmission = @SET} : @OLD {@OLD; subspace_transmission = @SKIP} +/obj/item/radio/@SUBTYPES{syndie = @SET} : @OLD {@OLD; decrypt_all_messages = 1; syndie = @SKIP} +/obj/item/radio/@SUBTYPES{adhoc_fallback = @SET} : @OLD {@OLD; can_use_analog = @SKIP} + +# Empty first-aid kits +/obj/item/storage/firstaid/regular{empty = 1} : /obj/item/firstaid/empty{@OLD; empty = @SKIP; name = @SKIP} + +/obj/machinery/floor_light/prebuilt{on = 1} : /obj/machinery/floor_light/prebuilt{@OLD; use_power = 2; on = @SKIP} + /obj/structure/disposalpipe/sortjunction/@SUBTYPES{sortType = @SET} : /obj/structure/disposalpipe/sortjunction/@SUBTYPES{@OLD; sort_type = @OLD:sortType; sortType = @SKIP} \ No newline at end of file From 89c4dd0db2fafbe97c48576bacd0a32e49fefb75 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Sep 2024 03:50:48 -0400 Subject: [PATCH 386/512] Fix article capitalization in emote strings --- code/modules/emotes/emote_define.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/emotes/emote_define.dm b/code/modules/emotes/emote_define.dm index 0223e3f3185b..b76c74f5c98a 100644 --- a/code/modules/emotes/emote_define.dm +++ b/code/modules/emotes/emote_define.dm @@ -7,7 +7,7 @@ . = replacetext(., "$TARGET_THEM$", target_gender.him) . = replacetext(., "$TARGET_THEIR$", target_gender.his) . = replacetext(., "$TARGET_SELF$", target_gender.self) - . = replacetext(., "$TARGET$", "\the [target]") + . = replacetext(., "$TARGET$", "[target]") /proc/emote_replace_user_tokens(var/msg, var/atom/user) . = msg @@ -18,7 +18,7 @@ . = replacetext(., "$USER_THEM$", user_gender.him) . = replacetext(., "$USER_THEIR$", user_gender.his) . = replacetext(., "$USER_SELF$", user_gender.self) - . = replacetext(., "$USER$", "\the [user]") + . = replacetext(., "$USER$", "[user]") // Note about emote messages: // - $USER$ / $TARGET$ will be replaced with the relevant name, in bold. From 205acef4175a492cfb53e9b2a76462a084d6afd1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Sep 2024 04:08:01 -0400 Subject: [PATCH 387/512] Fix incorrect usage of bool for material opacity --- code/modules/materials/_materials.dm | 2 +- test/check-paths.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index dba95990092c..16aec1e852bb 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -182,7 +182,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) /// General-use HP value for products. var/integrity = 150 /// Is the material transparent? 0.5< makes transparent walls/doors. - var/opacity = TRUE + var/opacity = 1.0 /// Only used by walls currently. var/explosion_resistance = 5 /// Objects with this var add CONDUCTS to flags on spawn. diff --git a/test/check-paths.sh b/test/check-paths.sh index 5643ae1afa53..d514d5d29a41 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -51,9 +51,9 @@ exactly 1 "direct usage of decls_repository.get_decl()" 'decls_repository\.get_d exactly 19 "direct loc set" '[^ ,(/]\bloc\s*=(?!=)' -P exactly 6 "pronoun macro use" '\\(he|she|him|her|his|hers|himself|herself|He|She|Him|Her|His|Hers|Himself|Herself)\b' -P exactly 0 "magic number mouse opacity set" 'mouse_opacity\s*=\s*[0-2]' -P -exactly 0 "magic number density set" '\bdensity\s*=\s*[01]\b' -P +exactly 1 "magic number density set" '\bdensity\s*=\s*[01]\b' -P exactly 0 "magic number anchored set" '\banchored\s*=\s*[01]\b' -P -exactly 0 "magic number opacity set" '\bopacity\s*=\s*[01](?!\.)' -P +exactly 0 "magic number opacity set" '\bopacity\s*=\s*[01]\b(?!\.)' -P # With the potential exception of << if you increase any of these numbers you're probably doing it wrong From e939102a6f97a007d1b1402b9277c2cb98ad3519 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Sep 2024 04:10:06 -0400 Subject: [PATCH 388/512] Add/expand cryopod visible messages --- code/game/machinery/cryopod.dm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 438184b0cd55..75795405175f 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -157,7 +157,9 @@ var/occupied_icon_state = "body_scanner_1" var/on_store_message = "has entered long-term storage." var/on_store_name = "Cryogenic Oversight" + var/on_store_visible_message = "$TARGET$ hums and hisses as it moves $USER$ into storage." //! A visible message to display when the user is despawned. $USER$ will be replaced with the user's name, $TARGET$ will be replaced with the pod's name. var/on_enter_occupant_message = "You feel cool air surround you. You go numb as your senses turn inward." + var/on_enter_visible_message = "$USER$ starts climbing into $TARGET$." //! A visible message to display when the user enters the pod. $USER$ will be replaced with the user's name. var/allow_occupant_types = list(/mob/living/human) var/disallow_occupant_types = list() @@ -359,6 +361,7 @@ control_computer._admin_logs += "[key_name(occupant)] ([role_alt_title]) at [stationtime2text()]" log_and_message_admins("[key_name(occupant)] ([role_alt_title]) entered cryostorage.") + visible_message(SPAN_NOTICE(emote_replace_user_tokens(emote_replace_target_tokens(on_store_visible_message, src), occupant))) do_telecomms_announcement(src, "[occupant.real_name], [role_alt_title], [on_store_message]", "[on_store_name]") despawn_character(occupant) set_occupant(null) @@ -369,7 +372,10 @@ if(alert(target,"Would you like to enter long-term storage?",,"Yes","No") != "Yes") return if(!user.incapacitated() && !user.anchored && user.Adjacent(src) && user.Adjacent(target)) - visible_message("[user] starts putting [target] into \the [src].", range = 3) + if(M == user) + visible_message(SPAN_NOTICE(emote_replace_user_tokens(emote_replace_target_tokens(on_enter_visible_message, src), usr)), range = 3) + else + visible_message("[user] starts putting [target] into \the [src].", range = 3) if(!do_after(user, 20, src)|| QDELETED(target)) return set_occupant(target) @@ -444,7 +450,7 @@ if(!usr.can_enter_cryopod(usr)) return - visible_message("\The [usr] starts climbing into \the [src].", range = 3) + visible_message(emote_replace_user_tokens(emote_replace_target_tokens(on_enter_visible_message, src), usr), range = 3) if(do_after(usr, 20, src)) @@ -487,7 +493,7 @@ if(occupant.client) if(!silent) - to_chat(occupant, SPAN_NOTICE("[on_enter_occupant_message]")) + occupant.visible_message("\The [src] [emote_replace_target_tokens(on_enter_visible_message)]", SPAN_NOTICE(on_enter_occupant_message)) to_chat(occupant, SPAN_NOTICE("If you ghost, log out or close your client now, your character will shortly be permanently removed from the round.")) occupant.client.perspective = EYE_PERSPECTIVE occupant.client.eye = src From f9c5da0d529252bbd346060259e3ad599296e756 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Sep 2024 04:11:06 -0400 Subject: [PATCH 389/512] Add security newscaster preset --- code/game/machinery/newscaster.dm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index 1152b6d5dc03..ae2af31628d8 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -943,3 +943,8 @@ var/global/list/allCasters = list() //Global list that will contain reference to else audible_message("[src.name] beeps, \"Attention! Wanted issue distributed!\"") playsound(src.loc, 'sound/machines/warning-buzzer.ogg', 75, 1) + +// security newscaster preset +/obj/machinery/newscaster/security_unit + base_type = /obj/machinery/newscaster + securityCaster = TRUE \ No newline at end of file From 62ce9a055ce7a3381286adc7d8f8c4e76d189299 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 6 Sep 2024 04:11:23 -0400 Subject: [PATCH 390/512] Add hidden SMES preset for use in submaps --- code/modules/power/smes_presets.dm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/modules/power/smes_presets.dm b/code/modules/power/smes_presets.dm index 0775d5ca164c..39d638616c0c 100644 --- a/code/modules/power/smes_presets.dm +++ b/code/modules/power/smes_presets.dm @@ -14,4 +14,12 @@ input_attempt = _input_on output_attempt = _output_on if(_fully_charged) - charge = capacity \ No newline at end of file + charge = capacity + +// Pre-installed and pre-charged SMES hidden from the station, for use in submaps. +/obj/machinery/power/smes/buildable/preset/hidden + _fully_charged = TRUE + _input_on = TRUE + _input_maxed = TRUE + _output_maxed = TRUE + RCon = FALSE \ No newline at end of file From a4e093c832dc1a8512abe0d8c9be9cede0e84b2a Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 20:25:01 +1000 Subject: [PATCH 391/512] Piecemeal corrections to cherrypicks/merges. --- code/game/machinery/cryopod.dm | 2 +- code/game/machinery/oxygen_pump.dm | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 75795405175f..1cbb8ba53cc8 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -372,7 +372,7 @@ if(alert(target,"Would you like to enter long-term storage?",,"Yes","No") != "Yes") return if(!user.incapacitated() && !user.anchored && user.Adjacent(src) && user.Adjacent(target)) - if(M == user) + if(target == user) visible_message(SPAN_NOTICE(emote_replace_user_tokens(emote_replace_target_tokens(on_enter_visible_message, src), usr)), range = 3) else visible_message("[user] starts putting [target] into \the [src].", range = 3) diff --git a/code/game/machinery/oxygen_pump.dm b/code/game/machinery/oxygen_pump.dm index 70671c1d7e45..51f5f1d33cec 100644 --- a/code/game/machinery/oxygen_pump.dm +++ b/code/game/machinery/oxygen_pump.dm @@ -17,6 +17,7 @@ var/mask_type = /obj/item/clothing/mask/breath/emergency var/icon_state_open = "emerg_open" var/icon_state_closed = "emerg" + var/icon_state_active // TODO implement power_channel = ENVIRON idle_power_usage = 10 @@ -242,11 +243,9 @@ icon_state_open = "medpump_open" icon_state_closed = "medpump" icon_state_active = "medpump_active" - anchored = FALSE density = TRUE - /obj/machinery/oxygen_pump/mobile/stabilizer name = "portable patient stabilizer" desc = "A portable oxygen pump with a retractable mask used for stabilizing patients in the field." @@ -255,7 +254,7 @@ icon_state_open = "patient_stabilizer_open" icon_state_active = "patient_stabilizer_active" -/obj/machinery/oxygen_pump/mobile/stabilizer/process() +/obj/machinery/oxygen_pump/mobile/stabilizer/Process() . = ..() if(!breather) // Safety. return @@ -276,4 +275,4 @@ if(lungs.is_bruised() && prob(30)) lungs.heal_damage(1) else - breather.ticks_since_last_successful_breath = max(breather.ticks_since_last_successful_breath - rand(1,5), 0) \ No newline at end of file + breather.suffocation_counter = max(breather.suffocation_counter - rand(1,5), 0) \ No newline at end of file From bce09a08fe018759bccf50cc754bb165f1a6c410 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 20:36:44 +1000 Subject: [PATCH 392/512] Several string tweaks from Polaris. --- code/modules/codex/categories/category_cultures.dm | 2 +- code/modules/codex/entries/atmospherics.dm | 2 +- code/modules/mob/language/generic.dm | 3 ++- code/modules/power/port_gen.dm | 2 +- code/modules/random_map/noise/ore.dm | 4 ++-- code/modules/species/species.dm | 2 +- .../artifacts/standalone/gigadrill.dm | 10 +++++++--- .../xenoarcheaology/finds/find_types/material.dm | 13 +++++++++++-- 8 files changed, 26 insertions(+), 12 deletions(-) diff --git a/code/modules/codex/categories/category_cultures.dm b/code/modules/codex/categories/category_cultures.dm index 3c51bbf65f42..0aef22c0c0cd 100644 --- a/code/modules/codex/categories/category_cultures.dm +++ b/code/modules/codex/categories/category_cultures.dm @@ -1,5 +1,5 @@ /decl/codex_category/cultures - name = "Factions and Culture" + name = "Places, Factions and Culture" desc = "Prominent planets, cultures, factions and religions of known space." /decl/codex_category/cultures/Populate() diff --git a/code/modules/codex/entries/atmospherics.dm b/code/modules/codex/entries/atmospherics.dm index 5b0b67fb8fbf..4c7e8993f078 100644 --- a/code/modules/codex/entries/atmospherics.dm +++ b/code/modules/codex/entries/atmospherics.dm @@ -147,7 +147,7 @@ /datum/codex_entry/transfer_valve associated_paths = list(/obj/item/transfer_valve) mechanics_text = "This machine is used to merge the contents of two different gas tanks. Plug the tanks into the transfer, then open the valve to mix them together. You can also attach various assembly devices to trigger this process." - antag_text = "With a tank of hot hydrogen and cold oxygen, this benign little atmospheric device becomes an incredibly deadly bomb. You don't want to be anywhere near it when it goes off." + antag_text = "With a tank of hot accelerant and cold oxidiser, this benign little atmospheric device becomes an incredibly deadly bomb. You don't want to be anywhere near it when it goes off." disambiguator = "component" available_to_map_tech_level = MAP_TECH_LEVEL_SPACE diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm index 78301a7ca87a..1665c0b215c2 100644 --- a/code/modules/mob/language/generic.dm +++ b/code/modules/mob/language/generic.dm @@ -21,7 +21,8 @@ /decl/language/sign name = "Sign Language" - desc = "A sign language commonly used for those who are deaf or mute." + desc = "In an age of commonplace extra-vehicular activity and habitation of airless worlds, \ + sign language is often an essential communication tool for large portions of the population." signlang_verb = list("gestures") colour = "say_quote" key = "s" diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 058d9aef597a..526fefb07ed4 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -113,7 +113,7 @@ /* These values were chosen so that the generator can run safely up to 80 kW - A full 50 deuterium sheet stack should last 20 minutes at power_output = 4 + A full 50 graphite sheet stack should last 20 minutes at power_output = 4 temperature_gain and max_temperature are set so that the max safe power level is 4. Setting to 5 or higher can only be done temporarily before the generator overheats. */ diff --git a/code/modules/random_map/noise/ore.dm b/code/modules/random_map/noise/ore.dm index f23e1c2cd01c..474ccc3687ab 100644 --- a/code/modules/random_map/noise/ore.dm +++ b/code/modules/random_map/noise/ore.dm @@ -153,7 +153,7 @@ /decl/material/solid/metal/silver = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX), /decl/material/solid/metal/uranium = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX), /decl/material/solid/metal/osmium = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX), - /decl/material/solid/rutile = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + /decl/material/solid/rutile = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX) ) deep_metals = list( /decl/material/solid/ice/aspium = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX), @@ -165,5 +165,5 @@ /decl/material/solid/gemstone/diamond = list(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX), /decl/material/solid/metal/osmium = list(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX), /decl/material/solid/metallic_hydrogen = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX), - /decl/material/solid/rutile = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX) + /decl/material/solid/rutile = list(RESOURCE_MID_MIN, RESOURCE_MID_MAX) ) \ No newline at end of file diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm index 2b8e4a628fca..799a656f84dc 100644 --- a/code/modules/species/species.dm +++ b/code/modules/species/species.dm @@ -362,7 +362,7 @@ var/global/const/DEFAULT_SPECIES_HEALTH = 200 else if(!LAZYLEN(available_background_info[cat_type])) var/list/map_systems = global.using_map.available_background_info[cat_type] - available_background_info[cat_type] = map_systems.Copy() + available_background_info[cat_type] = islist(map_systems) ? map_systems.Copy() : list() if(LAZYLEN(available_background_info[cat_type]) && !default_background_info[cat_type]) var/list/avail_systems = available_background_info[cat_type] diff --git a/code/modules/xenoarcheaology/artifacts/standalone/gigadrill.dm b/code/modules/xenoarcheaology/artifacts/standalone/gigadrill.dm index 22e68e9011e4..c56e354022c8 100644 --- a/code/modules/xenoarcheaology/artifacts/standalone/gigadrill.dm +++ b/code/modules/xenoarcheaology/artifacts/standalone/gigadrill.dm @@ -3,11 +3,15 @@ desc = "A giant, alien drill mounted on long treads." icon = 'icons/obj/machines/gigadrill.dmi' icon_state = "gigadrill" + density = TRUE + layer = ABOVE_OBJ_LAYER //to go over ores + matter = list( + /decl/material/solid/metal/plasteel/ocp = MATTER_AMOUNT_PRIMARY, + /decl/material/solid/gemstone/diamond = MATTER_AMOUNT_REINFORCEMENT + ) var/active = 0 var/drill_time = 10 var/turf/drilling_turf - density = TRUE - layer = ABOVE_OBJ_LAYER //to go over ores /obj/machinery/giga_drill/physical_attack_hand(mob/user) if(active) @@ -35,4 +39,4 @@ anchored = FALSE /obj/machinery/giga_drill/get_artifact_scan_data() - return "Automated mining drill - structure composed of titanium-carbide alloy, with tip and drill lines edged in a complex lattice of diamond." + return "Automated mining drill - structure composed of osmium-carbide alloy, with tip and drill lines edged in a complex lattice of diamond." diff --git a/code/modules/xenoarcheaology/finds/find_types/material.dm b/code/modules/xenoarcheaology/finds/find_types/material.dm index f4bfc53c61f0..d870cb60ef4e 100644 --- a/code/modules/xenoarcheaology/finds/find_types/material.dm +++ b/code/modules/xenoarcheaology/finds/find_types/material.dm @@ -2,14 +2,23 @@ /decl/archaeological_find/material item_type = "material lump" modification_flags = XENOFIND_APPLY_PREFIX - var/list/possible_materials = list(/decl/material/solid/metal/steel, /decl/material/solid/metal/plasteel, /decl/material/solid/metal/titanium, /decl/material/solid/glass) + var/list/possible_materials = list( + /decl/material/solid/metal/steel, + /decl/material/solid/metal/plasteel, + /decl/material/solid/metal/titanium, + /decl/material/solid/glass + ) /decl/archaeological_find/material/spawn_item(atom/loc) return SSmaterials.create_object(pick(possible_materials), loc, rand(5,45))?[1] /decl/archaeological_find/material/exotic item_type = "rare material lump" - possible_materials = list(/decl/material/solid/metal/aliumium, /decl/material/solid/metallic_hydrogen, /decl/material/solid/glass/borosilicate) + possible_materials = list( + /decl/material/solid/metal/aliumium, + /decl/material/solid/metallic_hydrogen, + /decl/material/solid/glass/borosilicate + ) //Machinery parts /decl/archaeological_find/parts From ff0bbe4907dc3765c209ab8b04446510f6c1084c Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 20:45:34 +1000 Subject: [PATCH 393/512] Updating test. --- test/check-paths.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/check-paths.sh b/test/check-paths.sh index d514d5d29a41..f59aa02ce4c7 100755 --- a/test/check-paths.sh +++ b/test/check-paths.sh @@ -51,7 +51,7 @@ exactly 1 "direct usage of decls_repository.get_decl()" 'decls_repository\.get_d exactly 19 "direct loc set" '[^ ,(/]\bloc\s*=(?!=)' -P exactly 6 "pronoun macro use" '\\(he|she|him|her|his|hers|himself|herself|He|She|Him|Her|His|Hers|Himself|Herself)\b' -P exactly 0 "magic number mouse opacity set" 'mouse_opacity\s*=\s*[0-2]' -P -exactly 1 "magic number density set" '\bdensity\s*=\s*[01]\b' -P +exactly 0 "magic number density set" '\bdensity\s*=\s*[01]\b' -P exactly 0 "magic number anchored set" '\banchored\s*=\s*[01]\b' -P exactly 0 "magic number opacity set" '\bopacity\s*=\s*[01]\b(?!\.)' -P From 4b26ddcb23e52963bf9c5050a9549526496997d1 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 20:46:46 +1000 Subject: [PATCH 394/512] Fixing runtime in undies code. --- code/modules/mob/living/human/human.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/human/human.dm b/code/modules/mob/living/human/human.dm index f2a5565b03e8..f08ad9c21a3a 100644 --- a/code/modules/mob/living/human/human.dm +++ b/code/modules/mob/living/human/human.dm @@ -559,7 +559,8 @@ //Drop anything that cannot be worn by the current species of the mob /mob/living/human/proc/apply_species_inventory_restrictions() - if(!(get_bodytype().appearance_flags & HAS_UNDERWEAR)) + var/decl/bodytype/check_bodytype = get_bodytype() + if(!istype(check_bodytype) || !(check_bodytype.appearance_flags & HAS_UNDERWEAR)) QDEL_NULL_LIST(worn_underwear) var/list/new_slots From 04dbb0753bd13e9bc1e483ca7c9c487688d4ed65 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 20:54:21 +1000 Subject: [PATCH 395/512] Fix CAMERA_CAMERA_ --- code/__defines/machinery.dm | 2 +- code/datums/supplypacks/science.dm | 11 ++++++++++- code/game/machinery/camera/presets.dm | 2 +- .../silicon/robot/flying/module_flying_repair.dm | 2 +- .../silicon/robot/modules/module_engineering.dm | 2 +- .../silicon/robot/modules/module_maintenance_drone.dm | 2 +- maps/exodus/exodus_cameras.dm | 2 +- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index b7018659403b..c45a497ba5f3 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -44,7 +44,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called // Camera channels // Station channels #define CAMERA_CHANNEL_PUBLIC "Public" -#define CAMERA_CAMERA_CHANNEL_ENGINEERING "Engineering" +#define CAMERA_CHANNEL_ENGINEERING "Engineering" #define CAMERA_CHANNEL_MEDICAL "Medical" #define CAMERA_CHANNEL_RESEARCH "Research" #define CAMERA_CHANNEL_SECURITY "Security" diff --git a/code/datums/supplypacks/science.dm b/code/datums/supplypacks/science.dm index 8458268f05a5..5505d65f4647 100644 --- a/code/datums/supplypacks/science.dm +++ b/code/datums/supplypacks/science.dm @@ -65,4 +65,13 @@ /decl/hierarchy/supply_pack/science/illuminate name = "Gear - Illumination grenades" contains = list(/obj/item/grenade/light = 8) - containername = "illumination grenade crate" \ No newline at end of file + containername = "illumination grenade crate" + +/decl/hierarchy/supply_pack/science/stasis_cages + name = "Stasis Cage" + contains = list( + /obj/structure/stasis_cage = 1 + ) + containertype = /obj/structure/closet/crate/large + containername = "stasis cage crate" + access = access_research diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 12d24b214fad..0fe1d526de06 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -1,5 +1,5 @@ /obj/machinery/camera/network/engineering - preset_channels = list(CAMERA_CAMERA_CHANNEL_ENGINEERING) + preset_channels = list(CAMERA_CHANNEL_ENGINEERING) req_access = list(access_engine) /obj/machinery/camera/network/ert diff --git a/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm b/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm index 83f08c2c46d1..3c6f36ea20c2 100644 --- a/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm +++ b/code/modules/mob/living/silicon/robot/flying/module_flying_repair.dm @@ -2,7 +2,7 @@ name = "repair drone module" display_name = "Repair" channels = list ("Engineering" = TRUE) - camera_channels = list(CAMERA_CAMERA_CHANNEL_ENGINEERING) + camera_channels = list(CAMERA_CHANNEL_ENGINEERING) software = list( /datum/computer_file/program/power_monitor ) diff --git a/code/modules/mob/living/silicon/robot/modules/module_engineering.dm b/code/modules/mob/living/silicon/robot/modules/module_engineering.dm index bab3a53ce0bf..65bd61bbd014 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_engineering.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_engineering.dm @@ -5,7 +5,7 @@ "Engineering" = 1 ) camera_channels = list( - CAMERA_CAMERA_CHANNEL_ENGINEERING + CAMERA_CHANNEL_ENGINEERING ) software = list( /datum/computer_file/program/power_monitor diff --git a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm index d23e9445afc4..1635721d1c87 100644 --- a/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm +++ b/code/modules/mob/living/silicon/robot/modules/module_maintenance_drone.dm @@ -4,7 +4,7 @@ has_nonslip_feet = TRUE has_magnetic_feet = TRUE camera_channels = list( - CAMERA_CAMERA_CHANNEL_ENGINEERING + CAMERA_CHANNEL_ENGINEERING ) languages = list( /decl/language/human/common = FALSE diff --git a/maps/exodus/exodus_cameras.dm b/maps/exodus/exodus_cameras.dm index 1f5d4b51ee31..0c55ca3a3824 100644 --- a/maps/exodus/exodus_cameras.dm +++ b/maps/exodus/exodus_cameras.dm @@ -37,7 +37,7 @@ var/global/const/CAMERA_CHANNEL_ENGINEERING_OUTPOST = "Engineering Outpost" req_access = list(access_heads) /obj/machinery/camera/network/maintenance - preset_channels = list(CAMERA_CAMERA_CHANNEL_ENGINEERING) + preset_channels = list(CAMERA_CHANNEL_ENGINEERING) req_access = list(access_engine) /obj/machinery/camera/xray/security From fa56557ee698dda453eb8e67096c7f6280d1f2e6 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 21:04:59 +1000 Subject: [PATCH 396/512] Porting robot cryopods from Lighthouse. --- code/game/machinery/cryopod.dm | 25 +++++++++++++++++++++++++ icons/obj/machines/tramdoors.dmi | Bin 0 -> 2661 bytes 2 files changed, 25 insertions(+) create mode 100644 icons/obj/machines/tramdoors.dmi diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 1cbb8ba53cc8..7a0bf2fccd41 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -190,6 +190,31 @@ disallow_occupant_types = list(/mob/living/silicon/robot/drone) applies_stasis = 0 +// Cryo +/obj/machinery/cryopod/robot/door + //This inherits from the robot cryo, so synths can be properly cryo'd. If a non-synth enters and is cryo'd, ..() is called and it'll still work. + abstract_type = /obj/machinery/cryopod/robot/door + name = "Airlock of Wonders" + desc = "An airlock that isn't an airlock, and shouldn't exist. Yell at a coder/mapper." + icon = 'icons/obj/machines/tramdoors.dmi' + icon_state = "door_closed" + base_icon_state = "door_closed" + occupied_icon_state = "door_locked" + on_enter_visible_message = "$USER$ steps into $TARGET$." + + time_till_despawn = 1 MINUTE //We want to be much faster then normal cryo, since waiting in an elevator for half an hour is a special kind of hell. + + allow_occupant_types = list(/mob/living/silicon/robot,/mob/living/human) + disallow_occupant_types = list(/mob/living/silicon/robot/drone) + +/obj/machinery/cryopod/robot/door/dorms + name = "Residential District Elevator" + desc = "A small elevator that goes down to the deeper section of the colony." + on_store_message = "has departed for the residential district." + on_store_name = "Residential Oversight" + on_enter_occupant_message = "The elevator door closes slowly, ready to bring you down to the residential district." + on_store_visible_message = "$TARGET$ makes a ding as it moves $USER$ to the residential district." + /obj/machinery/cryopod/lifepod name = "life pod" desc = "A man-sized pod for entering suspended animation. Dubbed 'cryocoffin' by more cynical spacers, it is pretty barebone, counting on stasis system to keep the victim alive rather than packing extended supply of food or air. Can be ordered with symbols of common religious denominations to be used in space funerals too." diff --git a/icons/obj/machines/tramdoors.dmi b/icons/obj/machines/tramdoors.dmi new file mode 100644 index 0000000000000000000000000000000000000000..3b40ac65a8ef96c31f1163c079610e6d7543aaef GIT binary patch literal 2661 zcmV-r3YztaP)C0003gP)t-sz`(#- z5CCTs09X$IF$DmC8vu7003972kzNChTmx8GSd3c(0000lFE3(ZVw+|Jp=t!5Xak*S z10Eh8qiO@3XanGe2r4QnZf1Da(7nPdc+ zV+5ye1dUw-DMD8;Qfo3)ZZuVIFiK#gW&}VZ9a1J8K_ecSTm<5Q3C|}0<|+X9EdbCb z0HS0CzJmo`K|F0iIfOzqnnEy7K|g*Q1d1O9Y$_dQ6asP=0+S&GE+8F=9s*Gg1VIS` zfg1uZARam_DU2QjVG{s3k3A9(U*Z=?k0d!JMQvg8b*k%9# z0EK!~Sad{Xb7OL8aCB*JZU6vyoKseCa&`CgQ*iP1=Hw@5<5sJz;OgfB_8tHwGeb>##8hqo00>!0L_t(|ob8wk zchfc$#}zq=?PBBfMN87X*U_zP>$Z+H8zcqFdvO~ti34q+^!tB^T}hTLIeKKrIl#_| z(x$e4pueQ6$GsP!PodN_WnR84AGu&melc>eP=i_RJiK}bNNc1`M;0L8^KgXf7(2AW z$^Ni+2iND}wY)VvD^Rm@D!>}f+GStlPu>9&hejGuL;=S^nA8z*D<=Zlg681RNCO@l z@(8o4nw>L&ro+bMIQc_U?0|vO*5KdB0`Q(`+Bg+xI+<1J3}=>Z79B8gIFCR8)rCa{ z>z&jz2(xk`(4;Lk8+mCGF;GBraLfgYZB__iJI@80qH(htGzYI?)*M+{e2N`bgV`D| zb1slicsA+f4rn>%0*)^c!#S|Adc9bSib0UBm?4)gGg}pTp?|_kG zE`Sv_#&%8xvWEFT;IDZHOnf1`KyEmH%}rq9#YtD5;_^wT=2SqM+G48n4wyJL9ktlb zsQ|2M3?KT<{;+p62QMxg$;OJyNX?l5E&Hz&xDYEV8db{Z7##F>$`x zrEP|1-Etl03Z(h$i#`bVpN&^9CYN*`zAROW>-j6LrmWoXT;QYxLG~j(5*}v7y?K-W zKX}S(Z5+8#%hkpIZYy$u`#SCe_g2@S$@O*5YqcUDej`6>wLEWq9jez>JsU@^@9QSO zb#DN(@Quw|Tids{x1xv$kZ&RoMYQtP=7x=wvGEcVg)Ti#g1>|s2#QR z0cn?-w(CL_uDoO0xmrsJJ3hy$gASv94; zolaqq!Fs1oC!BDBje`jyef!*mxIISN<5)yMz4--QCdlNW&pm2eg=Q7-zIMb-_DB2EAIj#(3FMqSKfi9ES$d*?iVLrd5XzN=i4~zfG+;$9We0X zq*EQW;z_9HbPZ_Z|7;DIcu-t6j^eTjY#chUt&jh=Ne9fFO)ozxmo};$A zrH}u&+_sI=`<^)*;uJH7gZl#pj`n~2Ngx03{@k{4GR1nAi%=;HsK-CyB4-t6dj2YBVcGknk&VA-6PQ}*7F7B2gnHJ_#Y&N;8f4W{J@`o@sBz`pyVv_AtRJ+43a`*q~}6@ z;C>-+UzHzFa~A)XMu@W!=J^3VFY*K3?ve1B%@1fen_{Jn1rzA`g7O1&l}qtIvoX&P z==p;31M&#TBBLYB^8i<1tQ_PG$8 z>iL5519XIr`6N{H1?302v+;jd%n#`KGC#1)5Bx9k14jNK@&iWxA@T!8zRVAN0{MXl zy}%=~*8teH*Wy9~i{FQ)oXPh}Z2P28Gie>wuA0 z&kqdaUQEhBJnILvsuvG^8?T-pNQS+Cpd3CeM^6?njk1sDCAG@R^--rTCv5G%PqZ zaXJIn*$8>um5uP4&wz=;6pz?RSC0S5QAauJWn z%&X@I3a3*Rm~~2(yn22hce};-U*(podG-82)xe~BexPD#Ry{vZH8}mq`GJ1{D#Us) T6>@Bg00000NkvXXu0mjfGxOcP literal 0 HcmV?d00001 From b5959b28da9f1696e4116d88dfbfc4bfe16a7c2c Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 21:10:23 +1000 Subject: [PATCH 397/512] Porting permits from Polaris/Lighthouse. --- code/modules/clothing/permits/_permit.dm | 86 +++++++++++++++++++++++ icons/clothing/accessories/permits.dmi | Bin 0 -> 781 bytes nebula.dme | 1 + 3 files changed, 87 insertions(+) create mode 100644 code/modules/clothing/permits/_permit.dm create mode 100644 icons/clothing/accessories/permits.dmi diff --git a/code/modules/clothing/permits/_permit.dm b/code/modules/clothing/permits/_permit.dm new file mode 100644 index 000000000000..1f42fce9e5cf --- /dev/null +++ b/code/modules/clothing/permits/_permit.dm @@ -0,0 +1,86 @@ +// Permits (drone identification, gun permit, etc) +/obj/item/clothing/permit + name = "permit" + desc = "A permit for something." + icon = 'icons/clothing/accessories/permits.dmi' + w_class = ITEM_SIZE_TINY + accessory_slot = ACCESSORY_SLOT_MEDAL + /// If set, the accents on the ID are set to this color using an overlay. + var/detail_color = COLOR_GUNMETAL + /// Each string in this list is an overlay applied to the permit icon. Example: list("goldstripe") + var/list/extra_details + /// Set to TRUE when someone names the permit by using it in hand rather than using a labeler. Prevents doing so again. + var/hand_name_used = FALSE + /// String. When set, owner is set to this on initialize. + var/default_owner = null + +/obj/item/clothing/permit/Initialize() + . = ..() + get_or_create_extension(src, /datum/extension/labels/single) + if(istext(default_owner)) + set_owner(default_owner, force = TRUE) + +/obj/item/clothing/permit/adjust_mob_overlay(var/mob/living/user_mob, var/bodytype, var/image/overlay, var/slot, var/bodypart) + if(overlay && detail_color) + overlay.overlays += overlay_image(overlay.icon, "[overlay.icon_state]-colors", detail_color, RESET_COLOR) + . = ..() + +/obj/item/clothing/permit/on_update_icon() + . = ..() + if(detail_color) + add_overlay(overlay_image(icon, "[icon_state]-colors", detail_color, RESET_COLOR)) + for(var/detail in extra_details) + add_overlay(overlay_image(icon, "[icon_state]-[detail]", flags = RESET_COLOR)) + +/obj/item/clothing/permit/attack_self(mob/living/user) + var/datum/extension/labels/label_ext = get_extension(src, /datum/extension/labels) + if(length(label_ext.labels)) + to_chat(user, SPAN_WARNING("This permit's integrated labeler can't function if a label is already present. Please remove any existing labels or blockages and try again.")) + return + if(hand_name_used) + to_chat(user, SPAN_WARNING("This permit's integrated ink cartridge has already been used. New labels must be applied manually using a hand labeler.")) + return + var/name_to_use = user.get_authentification_name(if_no_id = null) + if(!name_to_use) + to_chat(user, SPAN_WARNING("Unable to link permit with ID card. Please ensure your ID card is in range of the permit and try again.")) + return + if(alert(user, "Claim this [name] for [name_to_use]? Once you claim it, the name can only be replaced using a hand labeler.", "Claim \the [src]?", "Yes", "No") != "Yes") + return + hand_name_used = TRUE + to_chat(user, SPAN_NOTICE("You claim \the [src] for [name_to_use].")) // must be here so that the label isn't included already + set_owner(name_to_use) + +/obj/item/clothing/permit/proc/set_owner(owner_name, force = FALSE) + var/datum/extension/labels/label_ext = get_extension(src, /datum/extension/labels) + if(force) + label_ext.RemoveAllLabels() + if(!length(label_ext.labels)) + label_ext.AttachLabel(null, owner_name) + +/obj/item/clothing/permit/gun + name = "weapon permit" + desc = "A card indicating that the owner is allowed to carry a weapon." + detail_color = COLOR_NT_RED + +/obj/item/clothing/permit/gun/bar + name = "bar shotgun permit" + desc = "A card indicating that the owner is allowed to carry a shotgun in the bar." + +/obj/item/clothing/permit/gun/planetside + name = "planetside weapon permit" + desc = "A card indicating that the owner is allowed to carry a weapon while on the surface." + detail_color = COLOR_PALE_PINK + +/obj/item/clothing/permit/gun/paramedic + name = "paramedic weapon permit" + desc = "A card indicating that the owner is allowed to carry a weapon while on EVA retrieval missions." + detail_color = COLOR_SKY_BLUE + +/obj/item/clothing/permit/chaplain + name = "holy weapon permit" + desc = "A card indicating that the owner is allowed to carry a weapon for religious rites and purposes." + detail_color = COLOR_GRAY15 + +/obj/item/clothing/permit/gun/planetside/exploration + name = "explorer weapon permit" + desc = "A card indicating that the owner is allowed to carry weaponry during active exploration missions." \ No newline at end of file diff --git a/icons/clothing/accessories/permits.dmi b/icons/clothing/accessories/permits.dmi new file mode 100644 index 0000000000000000000000000000000000000000..25ee8e450845e67e4ec01a5a31c8508d26f65e00 GIT binary patch literal 781 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRS`>R4CN?cNllZ!G7N;32F7#J$% zOr3O^tJy%n_4>(hme}ZD1-E@yiim#|KVo)~=ZMctm!tdFn{aC`U9o#-!TGuD!rk6w zr@0IFKHn4mgkh~kcggnWISenqs`$B|+tTFrTVc-nJ+n?_I2ai{@?qNPDQ~fQWmf2l z{jn#7c_&4iG{2qt)#Gv1^II8rw@!7P@TjrKXO3e$Uuyb7x2$xFyL|t7KBy5PgC3DK!4evg+R4rj(VB++2aSW-L^Y*S`-z^6b zh5+`bLLJ&q7(x^-Do9DS9O1P%G)cOEHLt`FBtW`>DL`x948^>$P;!&(Bx0Ov8J=|Ni^(arxbQ z|E}Ap|JUJbKkPf-TCRWR?R$CKcb@+^?~Uf!;FBiIF~+jb=6*VLr%q6+_gL)l$v?Fp z?0so)WJ>t8Z{poYXFv8^E`0X+=M^_|++KgRs(f3s|Mpw9+2f1ghxOOH&1U<4@Uv+$dD&gGeu;jKl+K%ep%YL@jfFcIAFkT@_T*# zo&UBynQ2p{W27Jb>ih5Y%=6BsEsgtDl7C)++xsv~C6tzPdS?3e^wUqJzBRk=)}1i@ zxUhp2MF}g%u6eotjlHg&3f2M!%Z#)?*9JsD}BW8pJ9g@= Date: Sun, 8 Jun 2025 21:12:23 +1000 Subject: [PATCH 398/512] Fixes erroneous setting of abstract_type on avian bodytype. --- mods/species/neoavians/datum/species_bodytypes.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/species/neoavians/datum/species_bodytypes.dm b/mods/species/neoavians/datum/species_bodytypes.dm index 03e8a9e5657e..45719a3e2b68 100644 --- a/mods/species/neoavians/datum/species_bodytypes.dm +++ b/mods/species/neoavians/datum/species_bodytypes.dm @@ -26,7 +26,6 @@ uid = "bodytype_prosthetic_raptor" /decl/bodytype/avian - abstract_type = /decl/bodytype/avian name = "avian" bodytype_category = BODYTYPE_AVIAN icon_base = 'mods/species/neoavians/icons/body.dmi' From 23fd03e0c07506eb2a25a5b51510663ee43472b5 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Mon, 9 Jun 2025 13:59:46 +1000 Subject: [PATCH 399/512] Removed erroneous language inclusion. --- .../species/bayliens/skrell/datum/language.dm | 35 ------------------- .../neoavians/datum/species_bodytypes.dm | 1 - 2 files changed, 36 deletions(-) delete mode 100644 mods/species/bayliens/skrell/datum/language.dm diff --git a/mods/species/bayliens/skrell/datum/language.dm b/mods/species/bayliens/skrell/datum/language.dm deleted file mode 100644 index 649ee1649e6c..000000000000 --- a/mods/species/bayliens/skrell/datum/language.dm +++ /dev/null @@ -1,35 +0,0 @@ -var/global/list/first_name_skrell = file2list("mods/species/bayliens/skrell/names/first_name_skrell.txt") -var/global/list/last_name_skrell = file2list("mods/species/bayliens/skrell/names/last_name_skrell.txt") - -/decl/language/skrell - name = "Common Skrellian" - desc = "A melodic and complex language spoken by the Skrell of the Oligarchy. Some of the notes are inaudible to humans." - speech_verb = "warbles" - ask_verb = "trills" - exclaim_verb = "croaks" - colour = "selenian" - key = "k" - flags = LANG_FLAG_WHITELISTED - syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","'","!") - shorthand = "SK" - partial_understanding = list( - /decl/language/skrell/casteless = 90 - ) - -/decl/language/skrell/casteless - name = "Ue-Katish Cant" - desc = "A flat and emotionless language spoken mainly by Ue-Katish pirates, laden with slurs and insults." - speech_verb = "croaks" - ask_verb = "trills" - exclaim_verb = "chirps" - colour = "selenian" - key = "p" - flags = LANG_FLAG_WHITELISTED - syllables = list("qra","xa","vilz*","s!zaao","qu!*m","girx","vol","xrim","za-r*oo","qu-xx","qix","qa'taz","zix","tuep","!","*") - shorthand = "UK" - partial_understanding = list( - /decl/language/skrell = 90 - ) - -/decl/language/skrell/get_random_name(var/gender) - return capitalize(pick(global.first_name_skrell)) + capitalize(pick(global.last_name_skrell)) \ No newline at end of file diff --git a/mods/species/neoavians/datum/species_bodytypes.dm b/mods/species/neoavians/datum/species_bodytypes.dm index 45719a3e2b68..a83f74e9b60c 100644 --- a/mods/species/neoavians/datum/species_bodytypes.dm +++ b/mods/species/neoavians/datum/species_bodytypes.dm @@ -84,7 +84,6 @@ uid = "bodytype_avian_raptor" /decl/bodytype/avian/additive - abstract_type = /decl/bodytype/avian/additive name = "avian, additive" icon_base = 'mods/species/neoavians/icons/body_add.dmi' health_hud_intensity = 3 From 4f9efee272b9d75f2f959aa3a9f2940aa814cd9e Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Wed, 11 Jun 2025 18:43:13 +1000 Subject: [PATCH 400/512] Added CRLF rules for .txt and .md --- .editorconfig | 5 + .gitattributes | 2 + tools/map_migrations/0000_legacy.txt | 1008 +++++++++++++------------- 3 files changed, 511 insertions(+), 504 deletions(-) diff --git a/.editorconfig b/.editorconfig index ad578927262d..2643d9b63442 100644 --- a/.editorconfig +++ b/.editorconfig @@ -20,3 +20,8 @@ indent_size = 4 indent_style = space indent_size = 2 +[*.txt] +end_of_line = crlf + +[*.md] +end_of_line = crlf diff --git a/.gitattributes b/.gitattributes index add01d675f96..e9d52dc929b5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -12,3 +12,5 @@ html/changelog.html merge=union # Declare files that will always have CRLF line endings on checkout. *.dm text eol=crlf *.dmm text eol=crlf +*.txt text eol=crlf +*.md text eol=crlf \ No newline at end of file diff --git a/tools/map_migrations/0000_legacy.txt b/tools/map_migrations/0000_legacy.txt index 721a4edf9f27..ccac8405c68a 100644 --- a/tools/map_migrations/0000_legacy.txt +++ b/tools/map_migrations/0000_legacy.txt @@ -1,504 +1,504 @@ -/obj/item/reagent_containers/@SUBTYPES : /obj/item/chems/@SUBTYPES{@OLD} -/obj/item/material/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/weapon/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/melee/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/packageWrap/@SUBTYPES : /obj/item/stack/package_wrap/@SUBTYPES{@OLD} -/obj/structure/table/rack/@SUBTYPES : /obj/structure/rack/@SUBTYPES{@OLD} -/obj/structure/table/woodentable/holotable : /obj/structure/table/holo_woodentable{@OLD} -/obj/item/chems/food/drinks/@SUBTYPES : /obj/item/chems/drinks/@SUBTYPES{@OLD} -/obj/item/chems/food/snacks/@SUBTYPES : /obj/item/food/@SUBTYPES{@OLD} -/obj/item/chems/food/condiment/@SUBTYPES : /obj/item/chems/condiment/@SUBTYPES{@OLD} -/obj/item/chems/condiment/peppermill/@SUBTYPES : /obj/item/chems/condiment/small/peppermill/@SUBTYPES{@OLD} -/obj/item/chems/condiment/saltshaker/@SUBTYPES : /obj/item/chems/condiment/small/saltshaker/@SUBTYPES{@OLD} -/obj/item/analyzer : /obj/item/scanner/gas{@OLD} -/obj/item/analyzer/plant_analyzer/@SUBTYPES : /obj/item/scanner/plant/@SUBTYPES{@OLD} -/obj/item/tape_roll/@SUBTYPES : /obj/item/stack/tape_roll/@SUBTYPES{@OLD} -/obj/structure/table/standard/@SUBTYPES : /obj/structure/table/@SUBTYPES{@OLD} -/obj/machinery/bluespacerelay/@SUBTYPES : /obj/machinery/commsrelay/@SUBTYPES{@OLD} -/obj/machinery/computer/helm/@SUBTYPES : /obj/machinery/computer/ship/helm/@SUBTYPES{@OLD} -/obj/machinery/computer/engines/@SUBTYPES : /obj/machinery/computer/ship/engines/@SUBTYPES{@OLD} -/obj/machinery/computer/navigation/@SUBTYPES : /obj/machinery/computer/ship/navigation/@SUBTYPES{@OLD} -/obj/machinery/requests_console/@SUBTYPES : /obj/machinery/network/requests_console/@SUBTYPES{@OLD; departmentType = @SKIP} -/obj/item/healthanalyzer/@SUBTYPES : /obj/item/scanner/health/@SUBTYPES{@OLD} -/obj/machinery/iv_drip/@SUBTYPES : /obj/structure/iv_drip/@SUBTYPES{@OLD} -/obj/structure/device/piano/@SUBTYPES : /obj/structure/synthesized_instrument/synthesizer/piano/@SUBTYPES{@OLD} -/obj/item/folder/white/@SUBTYPES : /obj/item/folder/@SUBTYPES{@OLD} -/obj/machinery/dnaforensics/@SUBTYPES : /obj/machinery/forensic/dnascanner/@SUBTYPES{@OLD} -/obj/machinery/microscope/@SUBTYPES : /obj/machinery/forensic/microscope/@SUBTYPES{@OLD} -/obj/item/stack/material/steel/@SUBTYPES : /obj/item/stack/material/sheet/mapped/steel/@SUBTYPES{@OLD} -/obj/item/stack/material/plasteel/@SUBTYPES : /obj/item/stack/material/sheet/reinforced/mapped/plasteel/@SUBTYPES{@OLD} -/obj/item/stack/material/glass/reinforced/@SUBTYPES : /obj/item/stack/material/pane/mapped/rglass/@SUBTYPES{@OLD} -/obj/item/stack/material/glass/@SUBTYPES : /obj/item/stack/material/pane/mapped/glass/@SUBTYPES{@OLD} -/obj/item/stack/material/wood/@SUBTYPES : /obj/item/stack/material/plank/mapped/wood/@SUBTYPES{@OLD} -/obj/item/stack/material/deuterium/@SUBTYPES : /obj/item/stack/material/aerogel/mapped/deuterium/@SUBTYPES{@OLD} -/obj/item/stack/material/uranium/@SUBTYPES : /obj/item/stack/material/puck/mapped/uranium/@SUBTYPES{@OLD} -/obj/machinery/autolathe/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD} -/obj/machinery/message_server/@SUBTYPES : /obj/machinery/network/message_server/@SUBTYPES{@OLD} -/obj/item/floor_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} -/obj/machinery/pipedispenser/@SUBTYPES : /obj/machinery/fabricator/pipe/@SUBTYPES{@OLD} -/obj/machinery/power/emitter/@SUBTYPES : /obj/machinery/emitter/@SUBTYPES{@OLD} -/obj/machinery/power/fusion_core/@SUBTYPES : /obj/machinery/fusion_core/@SUBTYPES{@OLD} -/obj/item/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} -/obj/machinery/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} -/obj/machinery/computer/modular/preset/command/@SUBTYPES : /obj/machinery/computer/modular/preset/cardslot/command/@SUBTYPES{@OLD} -/obj/machinery/computer/fusion_core_control/@SUBTYPES : /obj/machinery/computer/fusion/core_control/@SUBTYPES{@OLD} -/obj/machinery/computer/fusion_fuel_control/@SUBTYPES : /obj/machinery/computer/fusion/fuel_control/@SUBTYPES{@OLD} -/obj/machinery/computer/gyrotron_control/@SUBTYPES : /obj/machinery/computer/fusion/gyrotron/@SUBTYPES{@OLD} -/obj/machinery/computer/power_monitor/@SUBTYPES : /obj/machinery/computer/modular/preset/engineering/power/@SUBTYPES{@OLD} -/obj/item/module/power_control/@SUBTYPES : /obj/item/stock_parts/circuitboard/apc/@SUBTYPES{@OLD} -/obj/machinery/power/port_gen/@SUBTYPES : /obj/machinery/port_gen/@SUBTYPES{@OLD} -/obj/item/pipe_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} -/obj/item/airlock_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/airlock_electronics/@SUBTYPES{@OLD} -/obj/item/airalarm_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/air_alarm/@SUBTYPES{@OLD} -/obj/item/autopsy_scanner/@SUBTYPES : /obj/item/scanner/autopsy/@SUBTYPES{@OLD} -/obj/machinery/fusion_fuel_compressor/@SUBTYPES : /obj/machinery/fuel_compressor/@SUBTYPES{@OLD} -/obj/item/extinguisher/micro/@SUBTYPES : /obj/item/chems/spray/extinguisher/mini/@SUBTYPES{@OLD} -/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} -/obj/item/stack/material/plastic/@SUBTYPES : /obj/item/stack/material/panel/mapped/plastic/@SUBTYPES{@OLD} -/obj/machinery/computer/general_air_control/@SUBTYPES : /obj/machinery/computer/air_control/@SUBTYPES{@OLD} -/obj/machinery/computer/air_control/large_tank_control : /obj/machinery/computer/air_control{@OLD} -/turf/simulated/floor/tiled/steel/@SUBTYPES : /turf/simulated/floor/tiled/@SUBTYPES{@OLD} -/obj/machinery/power/engine/@SUBTYPES : /obj/machinery/ion_thruster/@SUBTYPES{@OLD} -/obj/machinery/computer/aifixer/@SUBTYPES : /obj/machinery/computer/modular/preset/aislot/sysadmin/@SUBTYPES{@OLD} -/obj/machinery/computer/aiupload/@SUBTYPES : /obj/machinery/computer/upload/ai/@SUBTYPES{@OLD} -/obj/machinery/computer/borgupload/@SUBTYPES : /obj/machinery/computer/upload/robot/@SUBTYPES{@OLD} -/obj/machinery/computer/supplycomp/control/@SUBTYPES : /obj/machinery/computer/modular/preset/dock/@SUBTYPES{@OLD} -/obj/machinery/computer/supplycomp/@SUBTYPES : /obj/machinery/computer/modular/preset/supply_public/@SUBTYPES{@OLD} -/obj/item/closet_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} -/turf/simulated/shuttle/plating/@SUBTYPES : /turf/floor/shuttle -/turf/simulated/shuttle/floor/@SUBTYPES : /turf/floor/shuttle/@SUBTYPES - -# REMOVE BAD VAREDITS -/@SUBTYPES {layer = @SET} : @OLD {@OLD; layer = @SKIP} -/@SUBTYPES {plane = @SET} : @OLD {@OLD; plane = @SKIP} -/obj/structure/cable/@SUBTYPES : @OLD {@OLD; d1 = @SKIP;d2 = @SKIP} -# unacidable removed -/@SUBTYPES {unacidable = @SET} : @OLD{@OLD; unacidable = @SKIP} -# Simple pipes shall not face north or west -/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} -/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} -/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} -/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} -# Do not change air alarm frequency on base type -/obj/machinery/alarm {frequency = @SET} : @OLD {@OLD; frequency = @SKIP} -# we use a completely different access format -/@SUBTYPES {req_access = @SET}: @OLD {@OLD; req_access = @SKIP;} -/@SUBTYPES {req_one_access = @SET}: @OLD {@OLD; req_one_access = @SKIP;} -/obj/machinery/door/blast/shutters{icon_state = "shutter0"} : /obj/machinery/door/blast/shutters{@OLD; icon_state = @SKIP} -/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1; density = 0, opacity = 0} : /obj/machinery/door/airlock/external/glass/bolted_open{@OLD; icon_state = @SKIP; locked = @SKIP, density = @SKIP; opacity = @SKIP} -/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1} : /obj/machinery/door/airlock/external/glass/bolted{@OLD; icon_state = @SKIP; locked = @SKIP} - -# BUTTONS -/obj/machinery/access_button/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} -/obj/machinery/access_button/airlock_interior : /obj/machinery/button/access/interior{@OLD} -/obj/machinery/airlock_sensor/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} -/obj/machinery/airlock_sensor/airlock_interior : /obj/machinery/button/access/interior{@OLD} -/obj/machinery/access_button : /obj/machinery/button/access{@OLD} -/obj/machinery/button/remote/airlock{specialfunctions = 4} : /obj/machinery/button/alternate/door/bolts{@OLD; specialfunctions = @SKIP; desiredstate = @SKIP} -/obj/machinery/button/remote/airlock : /obj/machinery/button/alternate/door{@OLD} -/obj/machinery/button/remote/driver : /obj/machinery/button/mass_driver{@OLD} -/obj/machinery/button/remote/blast_door : /obj/machinery/button/blast_door{@OLD} -/obj/machinery/button/remote : /obj/machinery/button/alternate{@OLD} - -# Medical -/obj/item/pill_bottle/tramadol : /obj/item/pill_bottle/strong_painkillers{@OLD} -/obj/item/chems/pill/tramadol : /obj/item/chems/pill/strong_painkillers{@OLD} -/obj/item/chems/glass/bottle/stoxin : /obj/item/chems/glass/bottle/sedatives{@OLD} -/obj/item/chems/glass/bottle/inaprovaline : /obj/item/chems/glass/bottle/stabilizer{@OLD} -/obj/item/chems/syringe/inaprovaline : /obj/item/chems/syringe/stabilizer{@OLD} -/obj/item/chems/blood/empty : /obj/item/chems/ivbag{@OLD} -/obj/item/chems/blood/@SUBTYPES : /obj/item/chems/ivbag/blood/@SUBTYPES{@OLD} -/obj/item/defib_kit/@SUBTYPES : /obj/item/defibrillator/@SUBTYPES{@OLD} -/obj/item/chems/spray/sterilizine : /obj/item/chems/spray/antiseptic{@OLD} - -# Drinking glasses and cups -/obj/item/chems/drinks/cup : /obj/item/chems/drinks/glass2/coffeecup{@OLD} -/obj/item/chems/drinks/drinkingglass : /obj/item/chems/drinks/glass2/square{@OLD} - -# Airtight flaps -/obj/structure/plasticflaps/mining : /obj/structure/flaps/airtight{@OLD} - -# Bushes -/obj/structure/flora/ausbushes/@SUBTYPES : /obj/structure/flora/bush/@SUBTYPES - -# Cassette tapes -> magnetic tapes -/obj/item/cassette_tape/@SUBTYPES : /obj/item/magnetic_tape/@SUBTYPES{@OLD} -/obj/item/tape_recorder : /obj/item/taperecorder{@OLD} - -# FIFTYSPAWNER -> MAPPED SHEETS -/obj/fiftyspawner/wood : /obj/item/stack/material/plank/mapped/wood/fifty -/obj/fiftyspawner/steel : /obj/item/stack/material/sheet/mapped/steel/fifty -/obj/fiftyspawner/glass : /obj/item/stack/material/pane/mapped/glass/fifty -/obj/fiftyspawner/deuterium : /obj/item/stack/material/aerogel/mapped/deuterium/fifty -/obj/fiftyspawner/tritium : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/osmium : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/phoron : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/rods : /obj/item/stack/material/aerogel/mapped/tritium/fifty -/obj/fiftyspawner/grass : /obj/item/stack/tile/grass{amount = 50} -/obj/fiftyspawner/plasteel : /obj/item/stack/material/aerogel/mapped/tritium/fifty - -# STOCK PARTS AND SMES COILS -/obj/item/stock_parts/subspace/sub_filter : /obj/item/stock_parts/subspace/filter -/obj/item/smes_coil/@SUBTYPES : /obj/item/stock_parts/smes_coil/@SUBTYPES{@OLD} -/obj/item/circuitboard/@SUBTYPES : /obj/item/stock_parts/circuitboard/@SUBTYPES{@OLD} -/obj/item/airlock_electronics : /obj/item/stock_parts/circuitboard/airlock_electronics{@OLD} - -# CLOTHING -/obj/item/clothing/head/cone : /obj/item/caution/cone{@OLD} -/obj/item/clothing/belt/security/tactical : /obj/item/belt/holster/security/tactical{@OLD} - -# Item remains -/obj/effect/decal/remains/@SUBTYPES : /obj/item/remains/@SUBTYPES{@OLD} - -# Circuit prefabs -/obj/item/hand_tele : /obj/prefab/hand_teleporter{@OLD} - -# Filing cabinets -/obj/structure/filingcabinet : /obj/structure/filing_cabinet{@OLD} -/obj/structure/filingcabinet/chestdrawer : /obj/structure/filing_cabinet/chestdrawer{@OLD} -/obj/structure/filingcabinet/filingcabinet : /obj/structure/filing_cabinet/tall{@OLD} -/obj/structure/filingcabinet/medical : /obj/structure/filing_cabinet/records/medical{@OLD} -/obj/structure/filingcabinet/security : /obj/structure/filing_cabinet/records{@OLD} - -# Machine frames -/obj/structure/frame: /obj/machinery/constructable_frame/machine_frame{@OLD} -/obj/machinery/constructable_frame/machine_frame{anchored = 1} : /obj/machinery/constructable_frame/machine_frame/deconstruct{anchored = @SKIP} -/obj/structure/frame/computer : /obj/machinery/constructable_frame/computerframe{@OLD} -/obj/machinery/constructable_frame/computerframe{anchored = 1} : /obj/machinery/constructable_frame/computerframe/deconstruct{anchored = @SKIP} - -# Hygiene/bathroom objects -/obj/structure/toilet : /obj/structure/hygiene/toilet{@OLD} -/obj/structure/sink/@SUBTYPES : /obj/structure/hygiene/sink/@SUBTYPES{@OLD} -/obj/machinery/shower : /obj/structure/hygiene/shower{@OLD} - -# Turbolift spawners -/obj/turbolift_map_holder/@SUBTYPES : /obj/abstract/turbolift_spawner/@SUBTYPES{@OLD} - -# Borosilicate windows -/obj/structure/window/phoronreinforced/@SUBTYPES : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD} - -# Tools; see 3763_pickaxe_hammer and 3959_hatchets for other migrations -/obj/item/knife/machete : /obj/item/tool/machete{@OLD} -/obj/item/knife/machete/hatchet : /obj/item/tool/axe/hatchet{@OLD} -/obj/item/tool/pickaxe/hand : /obj/item/tool/pickaxe/xeno/hand{@OLD} - -# RANDOM SPAWNERS -/obj/random/cigarettes : /obj/random/smokes{@OLD} -/obj/item/lipstick/random : /obj/random/lipstick -/obj/random/slimecore : /obj/item/slime_extract/random{@OLD} - -# MINING EQUIPMENT -/obj/machinery/mineral/processing_unit : /obj/machinery/material_processing/smeltery -/obj/machinery/mineral/stacking_machine : /obj/machinery/material_processing/stacker -/obj/machinery/mineral/unloading_machine : /obj/machinery/material_processing/unloader -/obj/machinery/mineral/output : @DELETE -/obj/machinery/mineral/input : @DELETE -/obj/machinery/mineral/mint : @DELETE -/obj/machinery/mineral/processing_unit_console : @DELETE - -# NEW PDAS (NO CARTRIDGES) -/obj/item/pda/@SUBTYPES : /obj/item/modular_computer/pda/@SUBTYPES{@OLD} -/obj/item/modular_computer/pda/captain : /obj/item/modular_computer/pda/heads/captain -/obj/item/storage/box/seccarts : @DELETE -/obj/item/cartridge/@SUBTYPES : @DELETE - -# MODULAR COMPUTER PRESETS -/obj/machinery/computer/card : /obj/machinery/computer/modular/preset/cardslot/personnel{@OLD} -/obj/machinery/computer/secure_data : /obj/machinery/computer/modular/preset/civilian{@OLD} -/obj/machinery/computer/skills : /obj/machinery/computer/modular/preset/civilian{@OLD} -/obj/machinery/computer/security/telescreen : /obj/machinery/computer/modular/telescreen/preset/security{@OLD} -/obj/machinery/computer/security/telescreen/entertainment : /obj/machinery/computer/modular/telescreen/preset/entertainment{@OLD} -/obj/machinery/computer/security/mining : /obj/machinery/computer/modular/preset/security{@OLD} -/obj/machinery/computer/security/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES -/obj/machinery/computer/crew : /obj/machinery/computer/modular/preset/medical{@OLD} -/obj/machinery/computer/rcon : /obj/machinery/computer/modular/preset/engineering/rcon{@OLD} -/obj/machinery/computer/communications : /obj/machinery/computer/modular/preset/cardslot/command{@OLD} -/obj/machinery/computer/med_data : /obj/machinery/computer/modular/preset/civilian{@OLD} -/obj/machinery/computer/med_data/laptop : /obj/item/modular_computer/laptop/preset/records{@OLD} - -# ATMOS REPATHS -/obj/machinery/atmospherics/pipe/tank/@SUBTYPES : /obj/machinery/atmospherics/unary/tank/@SUBTYPES -/obj/machinery/portable_atmospherics/canister/nitrous_oxide : /obj/machinery/portable_atmospherics/canister/sleeping_agent{@OLD} - -# MISC. ITEMS -/obj/item/moneybag/vault : /obj/item/bag/cash/filled{@OLD} -/obj/item/moneybag : /obj/item/bag/cash{@OLD} -/obj/item/chems/bucket : /obj/item/chems/glass/bucket{@OLD} -/obj/item/card/id/gold/captain/spare : /obj/item/card/id/captains_spare{@OLD} -/obj/item/chainofcommand : /obj/item/whip/chainofcommand{@OLD} -/obj/item/chems/drinks/bottle/specialwhiskey : /obj/item/chems/drinks/bottle/agedwhiskey{@OLD} - -# Tape is weird -/obj/item/taperoll/@SUBTYPES : /obj/item/stack/tape_roll/barricade_tape/@SUBTYPES{@OLD} -/obj/item/tape/@SUBTYPES : /obj/structure/tape_barricade/@SUBTYPES{@OLD} - -# Radio -/obj/item/radio/headset/headset_sec/alt : /obj/item/radio/headset/headset_sec/bowman{@OLD} -/obj/item/radio/headset/syndicate : /obj/item/radio/headset/hacked{@OLD} -/obj/item/radio/headset/syndicate/alt : /obj/item/radio/headset/hacked{@OLD} -/obj/item/phone : /obj/item/radio/phone{@OLD} - -# Singulo -/obj/machinery/the_singularitygen : /obj/machinery/singularity_generator{@OLD} - -# FABRICATORS -/obj/machinery/autolathe{hacked = 1} : /obj/machinery/fabricator/hacked{@OLD; hacked = @SKIP} -/obj/machinery/autolathe : /obj/machinery/fabricator{@OLD} -/obj/machinery/pipedispenser : /obj/machinery/fabricator/pipe{@OLD; anchored = 1} -/obj/machinery/pipedispenser/orderable : /obj/machinery/fabricator/pipe{@OLD} -/obj/machinery/pipedispenser/disposal : /obj/machinery/fabricator/pipe/disposal{@OLD; anchored = 1} -/obj/machinery/pipedispenser/disposal/orderable : /obj/machinery/fabricator/pipe/disposal{@OLD} -/obj/machinery/r_n_d/circuit_imprinter : /obj/machinery/fabricator/imprinter{@OLD} -/obj/machinery/pros_fabricator : /obj/machinery/fabricator/robotics{@OLD} -/obj/machinery/mecha_part_fabricator : /obj/machinery/fabricator/industrial{@OLD} -/obj/machinery/r_n_d/protolathe : /obj/machinery/fabricator/protolathe{@OLD} -/obj/machinery/bookbinder : /obj/machinery/fabricator/book{@OLD} -/obj/machinery/organ_printer/flesh : /obj/machinery/fabricator/bioprinter{@OLD} -/obj/machinery/vending/food : /obj/machinery/fabricator/replicator - -/obj/machinery/fabricator/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD; res_max_amount = @SKIP; speed = @SKIP} - -# MMIs and posibrains -/obj/item/mmi/digital/@SUBTYPES : /obj/item/organ/internal/brain/robotic{@OLD} -/obj/item/mmi/@SUBTYPES : /obj/item/organ/internal/brain_interface/@SUBTYPES{@OLD} -/obj/item/organ/internal/posibrain : /obj/item/organ/internal/brain/robotic/positronic{@OLD} - -# Energy blades -/obj/item/energy/@SUBTYPES : /obj/item/energy_blade/@SUBTYPES{@OLD} - -# Medals and other accessories; see 3902_ties.txt for further migrations -/obj/item/clothing/accessory/medal/bronze_heart : /obj/item/clothing/accessory/medal/nanotrasen/bronze{@OLD} -/obj/item/clothing/accessory/medal/nobel_science : /obj/item/clothing/medal/nanotrasen/silver{@OLD} -/obj/item/clothing/accessory/scarf/white : /obj/item/clothing/accessory/scarf{@OLD} -/obj/item/clothing/accessory/storage/webbing : /obj/item/clothing/accessory/webbing/vest - -# MATERIALS -/obj/item/stack/material/plastic : /obj/item/stack/material/panel/mapped/plastic{@OLD} -/obj/item/stack/material/sandstone : /obj/item/stack/material/brick/mapped/sandstone{@OLD} -/obj/item/stack/material/mhydrogen : /obj/item/stack/material/segment/mapped/mhydrogen{@OLD} -/obj/item/stack/material/diamond : /obj/item/stack/material/gemstone/mapped/diamond{@OLD} -/obj/item/stack/material/wood : /obj/item/stack/material/plank/mapped/wood{@OLD} -/obj/item/stack/material/steel : /obj/item/stack/material/sheet/mapped/steel{@OLD} -/obj/item/stack/material/glass : /obj/item/stack/material/pane/mapped/glass{@OLD} -/obj/item/stack/material/phoron : /obj/item/stack/material/crystal/mapped/phoron{@OLD} -/obj/item/stack/material/algae : /obj/item/stack/material/puck/mapped/algae{@OLD} -/obj/item/stack/material/gold : /obj/item/stack/material/ingot/mapped/gold{@OLD} -/obj/item/stack/material/plasteel : /obj/item/stack/material/reinforced/mapped/plasteel{@OLD} -/obj/item/stack/material/glass/reinforced : /obj/item/stack/material/pane/mapped/rglass{@OLD} -/obj/item/stack/material/glass/phoronglass : /obj/item/stack/material/pane/mapped/borosilicate{@OLD} -/obj/item/stack/material/glass/phoronrglass : /obj/item/stack/material/pane/mapped/rborosilicate{@OLD} -/obj/item/stack/rods : /obj/item/stack/material/rods{@OLD} -/obj/item/packageWrap{amount = @UNSET} : /obj/item/stack/package_wrap/twenty_five{@OLD; amount = @SKIP} -/obj/item/packageWrap : /obj/item/stack/package_wrap{@OLD} -/obj/item/wrapping_paper{amount = @UNSET} : /obj/item/stack/package_wrap/gift/twenty_five{@OLD; amount = @SKIP} -/obj/item/wrapping_paper : /obj/item/stack/package_wrap{@OLD} - -/obj/structure/dispenser{phorontanks = 0} : /obj/structure/tank_rack/oxygen{@OLD; phorontanks = @SKIP} -/obj/structure/dispenser/oxygen{oxygentanks = 0} : /obj/structure/tank_rack/empty{@OLD; oxygentanks = @SKIP} -/obj/structure/dispenser/oxygen : /obj/structure/tank_rack/oxygen -/obj/structure/dispenser : /obj/structure/tank_rack - -# TELECOMMS REMOVAL -/obj/item/stock_parts/circuitboard/telecomms/@SUBTYPES : @DELETE -/obj/machinery/telecomms/@SUBTYPES : @DELETE -/obj/machinery/computer/telecomms/@SUBTYPES : @DELETE - -/obj/machinery/r_n_d/server/@SUBTYPES : /obj/machinery/design_database -/obj/machinery/r_n_d/destructive_analyzer : /obj/machinery/destructive_analyzer - -# SMES bullshit -/obj/machinery/power/smes/buildable/engine : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 1)} -/obj/machinery/power/smes/buildable/main : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 4)} -/obj/machinery/power/smes/buildable/point_of_interest : /obj/machinery/power/smes/buildable/preset/hidden - -/obj/item/surgical/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} -/obj/item/FixOVein : /obj/item/sutures{@OLD} - -/obj/structure/flora/skeleton : /obj/structure/skele_stand{@OLD} - -/obj/mecha/working/ripley/firefighter : /mob/living/exosuit/premade/firefighter -/obj/mecha/working/ripley/mining : /mob/living/exosuit/premade/powerloader - -/obj/structure/AIcore/@SUBTYPES : /obj/structure/aicore/@SUBTYPES -/obj/item/tank/vox : /obj/item/tank/nitrogen{@OLD} - -/obj/machinery/shuttle_sensor : /obj/machinery/airlock_sensor/shuttle{@OLD} - -/obj/machinery/computer/rdconsole/@SUBTYPES : /obj/machinery/computer/design_console{@OLD} -/obj/machinery/computer/rdservercontrol : /obj/machinery/computer/design_console{@OLD; name = @SKIP; badmin = @SKIP} -/obj/item/stock_parts/circuitboard/rdconsole : /obj/item/stock_parts/circuitboard/design_console{@OLD} -/obj/item/stock_parts/circuitboard/rdserver : /obj/item/stock_parts/circuitboard/design_database{@OLD} - -/obj/machinery/account_database : /obj/machinery/computer/account_database{@OLD} -/obj/machinery/shield_gen/@SUBTYPES : /obj/machinery/shield_generator - -/obj/structure/morgue/crematorium : /obj/structure/crematorium{@OLD} - -/obj/item/robot_parts/frame : /obj/item/robot_parts/robot_suit{@OLD} - -/obj/structure/closet/secure_closet/psych : /obj/structure/closet/secure_closet/psychiatry{@OLD} -/obj/structure/closet/firecloset/full : /obj/structure/closet/firecloset{@OLD} -/obj/structure/closet/firecloset/full/double : /obj/structure/closet/firecloset/chief{@OLD} -/obj/structure/closet/l3closet/scientist/double : /obj/structure/closet/l3closet/scientist/multi{@OLD} -/obj/structure/closet/secure_closet/hos2 : /obj/structure/closet/secure_closet/hos{@OLD} -/obj/structure/closet/secure_closet/medical_wall/synth_anesthetics : /obj/structure/closet/secure_closet/medical_wall/anesthetics/robotics{@OLD} -/obj/structure/closet/secure_closet/medical2 : /obj/structure/closet/secure_closet/anesthetics{@OLD} -/obj/structure/closet/walllocker/emerglocker/@SUBTYPES : /obj/structure/emergency_dispenser/@SUBTYPES{@OLD} - -/obj/item/firstaid_arm_assembly : /obj/item/firstaid/empty, /obj/item/robot_parts/l_arm -/obj/item/bucket_sensor : /obj/item/chems/glass/bucket, /obj/item/assembly/prox_sensor -/obj/item/broken_device : @DELETE - -/obj/item/spacecash/@SUBTYPES : /obj/item/cash/@SUBTYPES{@OLD} - -/obj/item/kit/paint/ripley : /obj/item/kit/paint/camouflage -/obj/item/kit/paint/ripley/death : /obj/item/kit/paint/camouflage/forest -/obj/item/kit/paint/ripley/flames_blue : /obj/item/kit/paint/flames_blue -/obj/item/kit/paint/ripley/flames_red : /obj/item/kit/paint/flames_red - -/obj/machinery/photocopier/faxmachine : /obj/machinery/faxmachine{@OLD; init_network_tag = @OLD:department; department = @SKIP} -/obj/item/tvcamera : /obj/item/camera/tvcamera{@OLD} -/obj/machinery/station_map : /obj/machinery/holomap{@OLD} - -/obj/item/ducttape : /obj/item/duct_tape{@OLD} -/obj/item/toy/katana : /obj/item/sword/katana/toy{@OLD} -/obj/item/toy/cultsword : /obj/item/sword/cult_toy{@OLD} -/obj/item/toy/sword : /obj/item/energy_blade/sword/toy{@OLD} -/obj/item/lipstick/jade : /obj/item/cosmetics/lipstick/green{@OLD} -/obj/item/rig_module/device/plasmacutter : /obj/item/rig_module/mounted/plasmacutter{@OLD} -/obj/item/storage/box/syndie_kit/ewar_voice : /obj/item/backpack/satchel/syndie_kit/ewar_voice -/obj/item/tray : /obj/item/plate/tray{@OLD} -/obj/item/weldingtool/weldpack : /obj/item/chems/weldpack{@OLD} -/obj/machinery/crystal : /obj/structure/crystal{@OLD} -/obj/item/organ/internal/stack : /obj/item/organ/internal/voxstack{@OLD} -/obj/item/radio_jammer : /obj/item/suit_sensor_jammer - -# AMMO BOXES -/obj/item/storage/box/beanbags/@SUBTYPES : /obj/item/box/ammo/beanbags/@SUBTYPES{@OLD} -/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} -/obj/item/storage/box/blanks/@SUBTYPES : /obj/item/box/ammo/blanks/@SUBTYPES{@OLD} -/obj/item/storage/box/empshells/@SUBTYPES : /obj/item/box/ammo/empshells/@SUBTYPES{@OLD} -/obj/item/storage/box/flashshells/@SUBTYPES : /obj/item/box/ammo/flashshells/@SUBTYPES{@OLD} -/obj/item/storage/box/shotgunammo/@SUBTYPES : /obj/item/box/ammo/shotgunammo/@SUBTYPES{@OLD} -/obj/item/storage/box/shotgunshells/@SUBTYPES : /obj/item/box/ammo/shotgunshells/@SUBTYPES{@OLD} -/obj/item/storage/box/sniperammo/@SUBTYPES : /obj/item/box/ammo/sniperammo/@SUBTYPES{@OLD} -/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} - -/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} -/obj/item/camera_assembly : /obj/item/frame/camera/kit -/obj/structure/ladder/up : /obj/structure/ladder -/obj/random/mob/mouse : /obj/random/mouse - -/obj/structure/closet/grave/dirthole : /obj/structure/pit{@OLD} -/obj/structure/closet/grave/@SUBTYPES : /obj/structure/pit/closed/grave{@OLD} - -/obj/item/banner/nt : /obj/item/banner/nanotrasen{@OLD} - -/obj/item/box/syndie_kit/clerical : /obj/item/backpack/satchel/syndie_kit/clerical{@OLD} - -/obj/item/clothing/under/costume/rainbow : /obj/item/clothing/jumpsuit/rainbow{@OLD} -/obj/item/clothing/under/dress/dress_orange : /obj/item/clothing/dress/orange{@OLD} -/obj/item/clothing/head/collectable/xenos : /obj/item/clothing/head/xenos{@OLD} -/obj/item/clothing/head/collectable/bearpelt : /obj/item/clothing/head/bearpelt{@OLD} -/obj/item/clothing/head/collectable/philosopher_wig : /obj/item/clothing/head/philosopher_wig{@OLD} -/obj/item/clothing/head/collectable/plaguedoctorhat : /obj/item/clothing/head/plaguedoctorhat{@OLD} -/obj/item/clothing/head/helmet/space/void/security/riot : /obj/item/clothing/head/helmet/space/void/security/alt{@OLD} -/obj/item/clothing/suit/space/void/security/riot : /obj/item/clothing/suit/space/void/security/alt{@OLD} -/obj/item/clothing/head/helmet/space/vox/pressure : /obj/item/clothing/head/helmet/space/vox{@OLD} -/obj/item/clothing/under/vox/vox_utility : /obj/item/clothing/pants/vox{@OLD} -/obj/item/clothing/suit/space/pirate : /obj/item/clothing/suit/pirate{@OLD} -/obj/item/clothing/suit/costume : /obj/item/clothing/suit/pirate{@OLD} -/obj/item/clothing/suit/costume/hgpirate : /obj/item/clothing/suit/hgpirate{@OLD} -/obj/item/clothing/suit/storage/vest/heavy/merc : /obj/item/clothing/suit/armor/pcarrier/merc{@OLD} -/obj/item/clothing/suit/storage/vest/@SUBTYPES : /obj/item/clothing/suit/armor/vest/@SUBTYPES{@OLD} - -# Migrate/delete old mech parts -/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster : @DELETE -/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster : @DELETE -/obj/item/mecha_parts/mecha_equipment/repair_droid : @DELETE -/obj/item/mecha_parts/mecha_equipment/teleporter : @DELETE -/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay : @DELETE -/obj/item/mecha_parts/mecha_equipment/tool/cable_layer : @DELETE -/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill : /obj/item/mech_equipment/drill/diamond{@OLD} -/obj/item/mecha_parts/mecha_equipment/tool/extinguisher : /obj/item/mech_equipment/mounted_system/extinguisher{@OLD} -/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp : /obj/item/mech_equipment/clamp{@OLD} -/obj/item/mecha_parts/mecha_equipment/tool/passenger : @DELETE -/obj/item/mecha_parts/mecha_equipment/tool/rcd : /obj/item/mech_equipment/mounted_system/rcd{@OLD} -/obj/item/mecha_parts/mecha_equipment/tool/sleeper : /obj/item/mech_equipment/sleeper{@OLD} -/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun : @DELETE -/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion : /obj/item/mech_equipment/mounted_system/taser/ion{@OLD} -/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser : /obj/item/mech_equipment/mounted_system/taser{@OLD} -/obj/item/mecha_parts/mecha_tracking : @DELETE - -############ -# VAREDITS # -############ -# Atmos varedits -/obj/machinery/computer/air_control/@SUBTYPES{sensors = @SET} : /obj/machinery/computer/air_control/@SUBTYPES{@OLD; sensors = @SKIP} -# move these to the external air subtype so frequencies work -/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1379} : /obj/machinery/atmospherics/unary/vent_pump/high_volume/external_air{@OLD; frequency = @SKIP} -/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrub_id = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} -/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrubbing_gas = list("phoron")} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrubbing_gas = list(/decl/material/solid/phoron)} -/obj/machinery/computer/area_atmos/tag/@SUBTYPES{scrub_id = @SET} : /obj/machinery/computer/area_atmos/tag/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} -# for the rest of this, frequency was moved to component presets and i'm too lazy to set that up -/obj/machinery/door/airlock/@SUBTYPES{frequency = @SET} : /obj/machinery/door/airlock/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/portable_atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/airlock_sensor/@SUBTYPES{frequency = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/air_sensor/@SUBTYPES : /obj/machinery/air_sensor/@SUBTYPES{@OLD; frequency = @SKIP; output = @SKIP} -/obj/machinery/embedded_controller/radio/@SUBTYPES{frequency = @SET} : /obj/machinery/embedded_controller/radio/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/button/@SUBTYPES{frequency = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; frequency = @SKIP} -/obj/machinery/meter/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; frequency = @SKIP} - -# id -> id_tag -/obj/machinery/door_timer/@SUBTYPES{id = @SET} : /obj/machinery/door_timer/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/conveyor/@SUBTYPES{id = @SET} : /obj/machinery/conveyor/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/conveyor_switch/@SUBTYPES{id = @SET} : /obj/machinery/conveyor_switch/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/door/@SUBTYPES{id = @SET} : /obj/machinery/door/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/button/@SUBTYPES{id = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/atmospherics/@SUBTYPES{id = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/holosign/bar{id = @SET} : /obj/machinery/holosign/bar{@OLD; id_tag = @OLD:id; id = @SKIP} -/obj/machinery/meter/@SUBTYPES{id = @SET} : /obj/machinery/meter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/flasher/@SUBTYPES{id = @SET} : /obj/machinery/flasher/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/sparker/@SUBTYPES{id = @SET} : /obj/machinery/sparker/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/mass_driver/@SUBTYPES{id = @SET} : /obj/machinery/mass_driver/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} -/obj/machinery/emitter/@SUBTYPES{id = @SET} : /obj/machinery/emitter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} - -# Camera preset_channels -> network -/obj/machinery/camera/network/@SUBTYPES{network = @SET} : /obj/machinery/camera/network/@SUBTYPES{@OLD; network = @SKIP; preset_channels = @OLD:network} - -# Remove button/sensor master_tag -/obj/machinery/airlock_sensor/@SUBTYPES{master_tag = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; master_tag = @SKIP} -/obj/machinery/button/access/@SUBTYPES{master_tag = @SET} : /obj/machinery/button/access/@SUBTYPES{@OLD; master_tag = @SKIP} - -# Skip power sensor name_tag -/obj/machinery/power/sensor{name_tag = @SET} : /obj/machinery/power/sensor{@OLD; name_tag = @SKIP} - -# join_group -> unique_merge_identifier -/turf/wall/shuttle/@SUBTYPES{join_group = @SET} : /turf/wall/shuttle/@SUBTYPES{@OLD; unique_merge_identifier = @OLD:join_group} - -# Remove set icon states/density on windows, doors, shutters -/obj/machinery/door/blast/regular{icon_state = @SET} : /obj/machinery/door/blast/regular{@OLD; icon_state = @SKIP} -/obj/structure/window/borosilicate_reinforced/@SUBTYPES{icon_state = @SET} : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD; icon_state = @SKIP} -/obj/machinery/door/blast/regular{p_open = 1} : /obj/machinery/door/blast/regular/open{@OLD; p_open = @SKIP} -/obj/machinery/door/blast/regular{p_open = 0} : /obj/machinery/door/blast/regular{@OLD; p_open = @SKIP} -/obj/machinery/door/blast/regular{density = 0} : /obj/machinery/door/blast/regular/open{@OLD; density = @SKIP; opacity = @SKIP} -/obj/structure/window/@SUBTYPES{icon_state = "fwindow"} : /obj/structure/window/@SUBTYPES{@OLD; icon_state = @SKIP} -/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} -/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} - -# Prices -> markup -/obj/machinery/vending/@SUBTYPES{prices = list()} : /obj/machinery/vending/@SUBTYPES{@OLD; markup = 0; prices=@SKIP} -/obj/machinery/vending/@SUBTYPES{prices = @SET} : /obj/machinery/vending/@SUBTYPES{@OLD; prices = @SKIP} - -# Radio varedits -/obj/item/radio/@SUBTYPES{subspace_transmission = @SET} : @OLD {@OLD; subspace_transmission = @SKIP} -/obj/item/radio/@SUBTYPES{syndie = @SET} : @OLD {@OLD; decrypt_all_messages = 1; syndie = @SKIP} -/obj/item/radio/@SUBTYPES{adhoc_fallback = @SET} : @OLD {@OLD; can_use_analog = @SKIP} - -# Empty first-aid kits -/obj/item/storage/firstaid/regular{empty = 1} : /obj/item/firstaid/empty{@OLD; empty = @SKIP; name = @SKIP} - -/obj/machinery/floor_light/prebuilt{on = 1} : /obj/machinery/floor_light/prebuilt{@OLD; use_power = 2; on = @SKIP} - -/obj/structure/disposalpipe/sortjunction/@SUBTYPES{sortType = @SET} : /obj/structure/disposalpipe/sortjunction/@SUBTYPES{@OLD; sort_type = @OLD:sortType; sortType = @SKIP} \ No newline at end of file +/obj/item/reagent_containers/@SUBTYPES : /obj/item/chems/@SUBTYPES{@OLD} +/obj/item/material/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/weapon/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/melee/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/packageWrap/@SUBTYPES : /obj/item/stack/package_wrap/@SUBTYPES{@OLD} +/obj/structure/table/rack/@SUBTYPES : /obj/structure/rack/@SUBTYPES{@OLD} +/obj/structure/table/woodentable/holotable : /obj/structure/table/holo_woodentable{@OLD} +/obj/item/chems/food/drinks/@SUBTYPES : /obj/item/chems/drinks/@SUBTYPES{@OLD} +/obj/item/chems/food/snacks/@SUBTYPES : /obj/item/food/@SUBTYPES{@OLD} +/obj/item/chems/food/condiment/@SUBTYPES : /obj/item/chems/condiment/@SUBTYPES{@OLD} +/obj/item/chems/condiment/peppermill/@SUBTYPES : /obj/item/chems/condiment/small/peppermill/@SUBTYPES{@OLD} +/obj/item/chems/condiment/saltshaker/@SUBTYPES : /obj/item/chems/condiment/small/saltshaker/@SUBTYPES{@OLD} +/obj/item/analyzer : /obj/item/scanner/gas{@OLD} +/obj/item/analyzer/plant_analyzer/@SUBTYPES : /obj/item/scanner/plant/@SUBTYPES{@OLD} +/obj/item/tape_roll/@SUBTYPES : /obj/item/stack/tape_roll/@SUBTYPES{@OLD} +/obj/structure/table/standard/@SUBTYPES : /obj/structure/table/@SUBTYPES{@OLD} +/obj/machinery/bluespacerelay/@SUBTYPES : /obj/machinery/commsrelay/@SUBTYPES{@OLD} +/obj/machinery/computer/helm/@SUBTYPES : /obj/machinery/computer/ship/helm/@SUBTYPES{@OLD} +/obj/machinery/computer/engines/@SUBTYPES : /obj/machinery/computer/ship/engines/@SUBTYPES{@OLD} +/obj/machinery/computer/navigation/@SUBTYPES : /obj/machinery/computer/ship/navigation/@SUBTYPES{@OLD} +/obj/machinery/requests_console/@SUBTYPES : /obj/machinery/network/requests_console/@SUBTYPES{@OLD; departmentType = @SKIP} +/obj/item/healthanalyzer/@SUBTYPES : /obj/item/scanner/health/@SUBTYPES{@OLD} +/obj/machinery/iv_drip/@SUBTYPES : /obj/structure/iv_drip/@SUBTYPES{@OLD} +/obj/structure/device/piano/@SUBTYPES : /obj/structure/synthesized_instrument/synthesizer/piano/@SUBTYPES{@OLD} +/obj/item/folder/white/@SUBTYPES : /obj/item/folder/@SUBTYPES{@OLD} +/obj/machinery/dnaforensics/@SUBTYPES : /obj/machinery/forensic/dnascanner/@SUBTYPES{@OLD} +/obj/machinery/microscope/@SUBTYPES : /obj/machinery/forensic/microscope/@SUBTYPES{@OLD} +/obj/item/stack/material/steel/@SUBTYPES : /obj/item/stack/material/sheet/mapped/steel/@SUBTYPES{@OLD} +/obj/item/stack/material/plasteel/@SUBTYPES : /obj/item/stack/material/sheet/reinforced/mapped/plasteel/@SUBTYPES{@OLD} +/obj/item/stack/material/glass/reinforced/@SUBTYPES : /obj/item/stack/material/pane/mapped/rglass/@SUBTYPES{@OLD} +/obj/item/stack/material/glass/@SUBTYPES : /obj/item/stack/material/pane/mapped/glass/@SUBTYPES{@OLD} +/obj/item/stack/material/wood/@SUBTYPES : /obj/item/stack/material/plank/mapped/wood/@SUBTYPES{@OLD} +/obj/item/stack/material/deuterium/@SUBTYPES : /obj/item/stack/material/aerogel/mapped/deuterium/@SUBTYPES{@OLD} +/obj/item/stack/material/uranium/@SUBTYPES : /obj/item/stack/material/puck/mapped/uranium/@SUBTYPES{@OLD} +/obj/machinery/autolathe/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD} +/obj/machinery/message_server/@SUBTYPES : /obj/machinery/network/message_server/@SUBTYPES{@OLD} +/obj/item/floor_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} +/obj/machinery/pipedispenser/@SUBTYPES : /obj/machinery/fabricator/pipe/@SUBTYPES{@OLD} +/obj/machinery/power/emitter/@SUBTYPES : /obj/machinery/emitter/@SUBTYPES{@OLD} +/obj/machinery/power/fusion_core/@SUBTYPES : /obj/machinery/fusion_core/@SUBTYPES{@OLD} +/obj/item/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} +/obj/machinery/modular_computer/console/preset/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES{@OLD} +/obj/machinery/computer/modular/preset/command/@SUBTYPES : /obj/machinery/computer/modular/preset/cardslot/command/@SUBTYPES{@OLD} +/obj/machinery/computer/fusion_core_control/@SUBTYPES : /obj/machinery/computer/fusion/core_control/@SUBTYPES{@OLD} +/obj/machinery/computer/fusion_fuel_control/@SUBTYPES : /obj/machinery/computer/fusion/fuel_control/@SUBTYPES{@OLD} +/obj/machinery/computer/gyrotron_control/@SUBTYPES : /obj/machinery/computer/fusion/gyrotron/@SUBTYPES{@OLD} +/obj/machinery/computer/power_monitor/@SUBTYPES : /obj/machinery/computer/modular/preset/engineering/power/@SUBTYPES{@OLD} +/obj/item/module/power_control/@SUBTYPES : /obj/item/stock_parts/circuitboard/apc/@SUBTYPES{@OLD} +/obj/machinery/power/port_gen/@SUBTYPES : /obj/machinery/port_gen/@SUBTYPES{@OLD} +/obj/item/pipe_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} +/obj/item/airlock_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/airlock_electronics/@SUBTYPES{@OLD} +/obj/item/airalarm_electronics/@SUBTYPES : /obj/item/stock_parts/circuitboard/air_alarm/@SUBTYPES{@OLD} +/obj/item/autopsy_scanner/@SUBTYPES : /obj/item/scanner/autopsy/@SUBTYPES{@OLD} +/obj/machinery/fusion_fuel_compressor/@SUBTYPES : /obj/machinery/fuel_compressor/@SUBTYPES{@OLD} +/obj/item/extinguisher/micro/@SUBTYPES : /obj/item/chems/spray/extinguisher/mini/@SUBTYPES{@OLD} +/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} +/obj/item/stack/material/plastic/@SUBTYPES : /obj/item/stack/material/panel/mapped/plastic/@SUBTYPES{@OLD} +/obj/machinery/computer/general_air_control/@SUBTYPES : /obj/machinery/computer/air_control/@SUBTYPES{@OLD} +/obj/machinery/computer/air_control/large_tank_control : /obj/machinery/computer/air_control{@OLD} +/turf/simulated/floor/tiled/steel/@SUBTYPES : /turf/simulated/floor/tiled/@SUBTYPES{@OLD} +/obj/machinery/power/engine/@SUBTYPES : /obj/machinery/ion_thruster/@SUBTYPES{@OLD} +/obj/machinery/computer/aifixer/@SUBTYPES : /obj/machinery/computer/modular/preset/aislot/sysadmin/@SUBTYPES{@OLD} +/obj/machinery/computer/aiupload/@SUBTYPES : /obj/machinery/computer/upload/ai/@SUBTYPES{@OLD} +/obj/machinery/computer/borgupload/@SUBTYPES : /obj/machinery/computer/upload/robot/@SUBTYPES{@OLD} +/obj/machinery/computer/supplycomp/control/@SUBTYPES : /obj/machinery/computer/modular/preset/dock/@SUBTYPES{@OLD} +/obj/machinery/computer/supplycomp/@SUBTYPES : /obj/machinery/computer/modular/preset/supply_public/@SUBTYPES{@OLD} +/obj/item/closet_painter/@SUBTYPES : /obj/item/paint_sprayer/@SUBTYPES{@OLD} +/turf/simulated/shuttle/plating/@SUBTYPES : /turf/floor/shuttle +/turf/simulated/shuttle/floor/@SUBTYPES : /turf/floor/shuttle/@SUBTYPES + +# REMOVE BAD VAREDITS +/@SUBTYPES {layer = @SET} : @OLD {@OLD; layer = @SKIP} +/@SUBTYPES {plane = @SET} : @OLD {@OLD; plane = @SKIP} +/obj/structure/cable/@SUBTYPES : @OLD {@OLD; d1 = @SKIP;d2 = @SKIP} +# unacidable removed +/@SUBTYPES {unacidable = @SET} : @OLD{@OLD; unacidable = @SKIP} +# Simple pipes shall not face north or west +/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} +/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 1} : @OLD {@OLD; dir = 2} +/obj/machinery/atmospherics/pipe/simple/hidden@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} +/obj/machinery/atmospherics/pipe/simple/visible@SUBTYPES {dir = 8} : @OLD {@OLD; dir = 4} +# Do not change air alarm frequency on base type +/obj/machinery/alarm {frequency = @SET} : @OLD {@OLD; frequency = @SKIP} +# we use a completely different access format +/@SUBTYPES {req_access = @SET}: @OLD {@OLD; req_access = @SKIP;} +/@SUBTYPES {req_one_access = @SET}: @OLD {@OLD; req_one_access = @SKIP;} +/obj/machinery/door/blast/shutters{icon_state = "shutter0"} : /obj/machinery/door/blast/shutters{@OLD; icon_state = @SKIP} +/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1; density = 0, opacity = 0} : /obj/machinery/door/airlock/external/glass/bolted_open{@OLD; icon_state = @SKIP; locked = @SKIP, density = @SKIP; opacity = @SKIP} +/obj/machinery/door/airlock/external/glass{icon_state = @SET; locked = 1} : /obj/machinery/door/airlock/external/glass/bolted{@OLD; icon_state = @SKIP; locked = @SKIP} + +# BUTTONS +/obj/machinery/access_button/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} +/obj/machinery/access_button/airlock_interior : /obj/machinery/button/access/interior{@OLD} +/obj/machinery/airlock_sensor/airlock_exterior : /obj/machinery/button/access/exterior{@OLD} +/obj/machinery/airlock_sensor/airlock_interior : /obj/machinery/button/access/interior{@OLD} +/obj/machinery/access_button : /obj/machinery/button/access{@OLD} +/obj/machinery/button/remote/airlock{specialfunctions = 4} : /obj/machinery/button/alternate/door/bolts{@OLD; specialfunctions = @SKIP; desiredstate = @SKIP} +/obj/machinery/button/remote/airlock : /obj/machinery/button/alternate/door{@OLD} +/obj/machinery/button/remote/driver : /obj/machinery/button/mass_driver{@OLD} +/obj/machinery/button/remote/blast_door : /obj/machinery/button/blast_door{@OLD} +/obj/machinery/button/remote : /obj/machinery/button/alternate{@OLD} + +# Medical +/obj/item/pill_bottle/tramadol : /obj/item/pill_bottle/strong_painkillers{@OLD} +/obj/item/chems/pill/tramadol : /obj/item/chems/pill/strong_painkillers{@OLD} +/obj/item/chems/glass/bottle/stoxin : /obj/item/chems/glass/bottle/sedatives{@OLD} +/obj/item/chems/glass/bottle/inaprovaline : /obj/item/chems/glass/bottle/stabilizer{@OLD} +/obj/item/chems/syringe/inaprovaline : /obj/item/chems/syringe/stabilizer{@OLD} +/obj/item/chems/blood/empty : /obj/item/chems/ivbag{@OLD} +/obj/item/chems/blood/@SUBTYPES : /obj/item/chems/ivbag/blood/@SUBTYPES{@OLD} +/obj/item/defib_kit/@SUBTYPES : /obj/item/defibrillator/@SUBTYPES{@OLD} +/obj/item/chems/spray/sterilizine : /obj/item/chems/spray/antiseptic{@OLD} + +# Drinking glasses and cups +/obj/item/chems/drinks/cup : /obj/item/chems/drinks/glass2/coffeecup{@OLD} +/obj/item/chems/drinks/drinkingglass : /obj/item/chems/drinks/glass2/square{@OLD} + +# Airtight flaps +/obj/structure/plasticflaps/mining : /obj/structure/flaps/airtight{@OLD} + +# Bushes +/obj/structure/flora/ausbushes/@SUBTYPES : /obj/structure/flora/bush/@SUBTYPES + +# Cassette tapes -> magnetic tapes +/obj/item/cassette_tape/@SUBTYPES : /obj/item/magnetic_tape/@SUBTYPES{@OLD} +/obj/item/tape_recorder : /obj/item/taperecorder{@OLD} + +# FIFTYSPAWNER -> MAPPED SHEETS +/obj/fiftyspawner/wood : /obj/item/stack/material/plank/mapped/wood/fifty +/obj/fiftyspawner/steel : /obj/item/stack/material/sheet/mapped/steel/fifty +/obj/fiftyspawner/glass : /obj/item/stack/material/pane/mapped/glass/fifty +/obj/fiftyspawner/deuterium : /obj/item/stack/material/aerogel/mapped/deuterium/fifty +/obj/fiftyspawner/tritium : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/osmium : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/phoron : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/rods : /obj/item/stack/material/aerogel/mapped/tritium/fifty +/obj/fiftyspawner/grass : /obj/item/stack/tile/grass{amount = 50} +/obj/fiftyspawner/plasteel : /obj/item/stack/material/aerogel/mapped/tritium/fifty + +# STOCK PARTS AND SMES COILS +/obj/item/stock_parts/subspace/sub_filter : /obj/item/stock_parts/subspace/filter +/obj/item/smes_coil/@SUBTYPES : /obj/item/stock_parts/smes_coil/@SUBTYPES{@OLD} +/obj/item/circuitboard/@SUBTYPES : /obj/item/stock_parts/circuitboard/@SUBTYPES{@OLD} +/obj/item/airlock_electronics : /obj/item/stock_parts/circuitboard/airlock_electronics{@OLD} + +# CLOTHING +/obj/item/clothing/head/cone : /obj/item/caution/cone{@OLD} +/obj/item/clothing/belt/security/tactical : /obj/item/belt/holster/security/tactical{@OLD} + +# Item remains +/obj/effect/decal/remains/@SUBTYPES : /obj/item/remains/@SUBTYPES{@OLD} + +# Circuit prefabs +/obj/item/hand_tele : /obj/prefab/hand_teleporter{@OLD} + +# Filing cabinets +/obj/structure/filingcabinet : /obj/structure/filing_cabinet{@OLD} +/obj/structure/filingcabinet/chestdrawer : /obj/structure/filing_cabinet/chestdrawer{@OLD} +/obj/structure/filingcabinet/filingcabinet : /obj/structure/filing_cabinet/tall{@OLD} +/obj/structure/filingcabinet/medical : /obj/structure/filing_cabinet/records/medical{@OLD} +/obj/structure/filingcabinet/security : /obj/structure/filing_cabinet/records{@OLD} + +# Machine frames +/obj/structure/frame: /obj/machinery/constructable_frame/machine_frame{@OLD} +/obj/machinery/constructable_frame/machine_frame{anchored = 1} : /obj/machinery/constructable_frame/machine_frame/deconstruct{anchored = @SKIP} +/obj/structure/frame/computer : /obj/machinery/constructable_frame/computerframe{@OLD} +/obj/machinery/constructable_frame/computerframe{anchored = 1} : /obj/machinery/constructable_frame/computerframe/deconstruct{anchored = @SKIP} + +# Hygiene/bathroom objects +/obj/structure/toilet : /obj/structure/hygiene/toilet{@OLD} +/obj/structure/sink/@SUBTYPES : /obj/structure/hygiene/sink/@SUBTYPES{@OLD} +/obj/machinery/shower : /obj/structure/hygiene/shower{@OLD} + +# Turbolift spawners +/obj/turbolift_map_holder/@SUBTYPES : /obj/abstract/turbolift_spawner/@SUBTYPES{@OLD} + +# Borosilicate windows +/obj/structure/window/phoronreinforced/@SUBTYPES : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD} + +# Tools; see 3763_pickaxe_hammer and 3959_hatchets for other migrations +/obj/item/knife/machete : /obj/item/tool/machete{@OLD} +/obj/item/knife/machete/hatchet : /obj/item/tool/axe/hatchet{@OLD} +/obj/item/tool/pickaxe/hand : /obj/item/tool/pickaxe/xeno/hand{@OLD} + +# RANDOM SPAWNERS +/obj/random/cigarettes : /obj/random/smokes{@OLD} +/obj/item/lipstick/random : /obj/random/lipstick +/obj/random/slimecore : /obj/item/slime_extract/random{@OLD} + +# MINING EQUIPMENT +/obj/machinery/mineral/processing_unit : /obj/machinery/material_processing/smeltery +/obj/machinery/mineral/stacking_machine : /obj/machinery/material_processing/stacker +/obj/machinery/mineral/unloading_machine : /obj/machinery/material_processing/unloader +/obj/machinery/mineral/output : @DELETE +/obj/machinery/mineral/input : @DELETE +/obj/machinery/mineral/mint : @DELETE +/obj/machinery/mineral/processing_unit_console : @DELETE + +# NEW PDAS (NO CARTRIDGES) +/obj/item/pda/@SUBTYPES : /obj/item/modular_computer/pda/@SUBTYPES{@OLD} +/obj/item/modular_computer/pda/captain : /obj/item/modular_computer/pda/heads/captain +/obj/item/storage/box/seccarts : @DELETE +/obj/item/cartridge/@SUBTYPES : @DELETE + +# MODULAR COMPUTER PRESETS +/obj/machinery/computer/card : /obj/machinery/computer/modular/preset/cardslot/personnel{@OLD} +/obj/machinery/computer/secure_data : /obj/machinery/computer/modular/preset/civilian{@OLD} +/obj/machinery/computer/skills : /obj/machinery/computer/modular/preset/civilian{@OLD} +/obj/machinery/computer/security/telescreen : /obj/machinery/computer/modular/telescreen/preset/security{@OLD} +/obj/machinery/computer/security/telescreen/entertainment : /obj/machinery/computer/modular/telescreen/preset/entertainment{@OLD} +/obj/machinery/computer/security/mining : /obj/machinery/computer/modular/preset/security{@OLD} +/obj/machinery/computer/security/@SUBTYPES : /obj/machinery/computer/modular/preset/@SUBTYPES +/obj/machinery/computer/crew : /obj/machinery/computer/modular/preset/medical{@OLD} +/obj/machinery/computer/rcon : /obj/machinery/computer/modular/preset/engineering/rcon{@OLD} +/obj/machinery/computer/communications : /obj/machinery/computer/modular/preset/cardslot/command{@OLD} +/obj/machinery/computer/med_data : /obj/machinery/computer/modular/preset/civilian{@OLD} +/obj/machinery/computer/med_data/laptop : /obj/item/modular_computer/laptop/preset/records{@OLD} + +# ATMOS REPATHS +/obj/machinery/atmospherics/pipe/tank/@SUBTYPES : /obj/machinery/atmospherics/unary/tank/@SUBTYPES +/obj/machinery/portable_atmospherics/canister/nitrous_oxide : /obj/machinery/portable_atmospherics/canister/sleeping_agent{@OLD} + +# MISC. ITEMS +/obj/item/moneybag/vault : /obj/item/bag/cash/filled{@OLD} +/obj/item/moneybag : /obj/item/bag/cash{@OLD} +/obj/item/chems/bucket : /obj/item/chems/glass/bucket{@OLD} +/obj/item/card/id/gold/captain/spare : /obj/item/card/id/captains_spare{@OLD} +/obj/item/chainofcommand : /obj/item/whip/chainofcommand{@OLD} +/obj/item/chems/drinks/bottle/specialwhiskey : /obj/item/chems/drinks/bottle/agedwhiskey{@OLD} + +# Tape is weird +/obj/item/taperoll/@SUBTYPES : /obj/item/stack/tape_roll/barricade_tape/@SUBTYPES{@OLD} +/obj/item/tape/@SUBTYPES : /obj/structure/tape_barricade/@SUBTYPES{@OLD} + +# Radio +/obj/item/radio/headset/headset_sec/alt : /obj/item/radio/headset/headset_sec/bowman{@OLD} +/obj/item/radio/headset/syndicate : /obj/item/radio/headset/hacked{@OLD} +/obj/item/radio/headset/syndicate/alt : /obj/item/radio/headset/hacked{@OLD} +/obj/item/phone : /obj/item/radio/phone{@OLD} + +# Singulo +/obj/machinery/the_singularitygen : /obj/machinery/singularity_generator{@OLD} + +# FABRICATORS +/obj/machinery/autolathe{hacked = 1} : /obj/machinery/fabricator/hacked{@OLD; hacked = @SKIP} +/obj/machinery/autolathe : /obj/machinery/fabricator{@OLD} +/obj/machinery/pipedispenser : /obj/machinery/fabricator/pipe{@OLD; anchored = 1} +/obj/machinery/pipedispenser/orderable : /obj/machinery/fabricator/pipe{@OLD} +/obj/machinery/pipedispenser/disposal : /obj/machinery/fabricator/pipe/disposal{@OLD; anchored = 1} +/obj/machinery/pipedispenser/disposal/orderable : /obj/machinery/fabricator/pipe/disposal{@OLD} +/obj/machinery/r_n_d/circuit_imprinter : /obj/machinery/fabricator/imprinter{@OLD} +/obj/machinery/pros_fabricator : /obj/machinery/fabricator/robotics{@OLD} +/obj/machinery/mecha_part_fabricator : /obj/machinery/fabricator/industrial{@OLD} +/obj/machinery/r_n_d/protolathe : /obj/machinery/fabricator/protolathe{@OLD} +/obj/machinery/bookbinder : /obj/machinery/fabricator/book{@OLD} +/obj/machinery/organ_printer/flesh : /obj/machinery/fabricator/bioprinter{@OLD} +/obj/machinery/vending/food : /obj/machinery/fabricator/replicator + +/obj/machinery/fabricator/@SUBTYPES : /obj/machinery/fabricator/@SUBTYPES{@OLD; res_max_amount = @SKIP; speed = @SKIP} + +# MMIs and posibrains +/obj/item/mmi/digital/@SUBTYPES : /obj/item/organ/internal/brain/robotic{@OLD} +/obj/item/mmi/@SUBTYPES : /obj/item/organ/internal/brain_interface/@SUBTYPES{@OLD} +/obj/item/organ/internal/posibrain : /obj/item/organ/internal/brain/robotic/positronic{@OLD} + +# Energy blades +/obj/item/energy/@SUBTYPES : /obj/item/energy_blade/@SUBTYPES{@OLD} + +# Medals and other accessories; see 3902_ties.txt for further migrations +/obj/item/clothing/accessory/medal/bronze_heart : /obj/item/clothing/accessory/medal/nanotrasen/bronze{@OLD} +/obj/item/clothing/accessory/medal/nobel_science : /obj/item/clothing/medal/nanotrasen/silver{@OLD} +/obj/item/clothing/accessory/scarf/white : /obj/item/clothing/accessory/scarf{@OLD} +/obj/item/clothing/accessory/storage/webbing : /obj/item/clothing/accessory/webbing/vest + +# MATERIALS +/obj/item/stack/material/plastic : /obj/item/stack/material/panel/mapped/plastic{@OLD} +/obj/item/stack/material/sandstone : /obj/item/stack/material/brick/mapped/sandstone{@OLD} +/obj/item/stack/material/mhydrogen : /obj/item/stack/material/segment/mapped/mhydrogen{@OLD} +/obj/item/stack/material/diamond : /obj/item/stack/material/gemstone/mapped/diamond{@OLD} +/obj/item/stack/material/wood : /obj/item/stack/material/plank/mapped/wood{@OLD} +/obj/item/stack/material/steel : /obj/item/stack/material/sheet/mapped/steel{@OLD} +/obj/item/stack/material/glass : /obj/item/stack/material/pane/mapped/glass{@OLD} +/obj/item/stack/material/phoron : /obj/item/stack/material/crystal/mapped/phoron{@OLD} +/obj/item/stack/material/algae : /obj/item/stack/material/puck/mapped/algae{@OLD} +/obj/item/stack/material/gold : /obj/item/stack/material/ingot/mapped/gold{@OLD} +/obj/item/stack/material/plasteel : /obj/item/stack/material/reinforced/mapped/plasteel{@OLD} +/obj/item/stack/material/glass/reinforced : /obj/item/stack/material/pane/mapped/rglass{@OLD} +/obj/item/stack/material/glass/phoronglass : /obj/item/stack/material/pane/mapped/borosilicate{@OLD} +/obj/item/stack/material/glass/phoronrglass : /obj/item/stack/material/pane/mapped/rborosilicate{@OLD} +/obj/item/stack/rods : /obj/item/stack/material/rods{@OLD} +/obj/item/packageWrap{amount = @UNSET} : /obj/item/stack/package_wrap/twenty_five{@OLD; amount = @SKIP} +/obj/item/packageWrap : /obj/item/stack/package_wrap{@OLD} +/obj/item/wrapping_paper{amount = @UNSET} : /obj/item/stack/package_wrap/gift/twenty_five{@OLD; amount = @SKIP} +/obj/item/wrapping_paper : /obj/item/stack/package_wrap{@OLD} + +/obj/structure/dispenser{phorontanks = 0} : /obj/structure/tank_rack/oxygen{@OLD; phorontanks = @SKIP} +/obj/structure/dispenser/oxygen{oxygentanks = 0} : /obj/structure/tank_rack/empty{@OLD; oxygentanks = @SKIP} +/obj/structure/dispenser/oxygen : /obj/structure/tank_rack/oxygen +/obj/structure/dispenser : /obj/structure/tank_rack + +# TELECOMMS REMOVAL +/obj/item/stock_parts/circuitboard/telecomms/@SUBTYPES : @DELETE +/obj/machinery/telecomms/@SUBTYPES : @DELETE +/obj/machinery/computer/telecomms/@SUBTYPES : @DELETE + +/obj/machinery/r_n_d/server/@SUBTYPES : /obj/machinery/design_database +/obj/machinery/r_n_d/destructive_analyzer : /obj/machinery/destructive_analyzer + +# SMES bullshit +/obj/machinery/power/smes/buildable/engine : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 1)} +/obj/machinery/power/smes/buildable/main : /obj/machinery/power/smes/buildable/preset{_fully_charged = 1; _input_maxed = 1; _input_on = 1; _output_maxed = 1; _output_on = 1; uncreated_component_parts = list(/obj/item/stock_parts/smes_coil = 4)} +/obj/machinery/power/smes/buildable/point_of_interest : /obj/machinery/power/smes/buildable/preset/hidden + +/obj/item/surgical/@SUBTYPES : /obj/item/@SUBTYPES{@OLD} +/obj/item/FixOVein : /obj/item/sutures{@OLD} + +/obj/structure/flora/skeleton : /obj/structure/skele_stand{@OLD} + +/obj/mecha/working/ripley/firefighter : /mob/living/exosuit/premade/firefighter +/obj/mecha/working/ripley/mining : /mob/living/exosuit/premade/powerloader + +/obj/structure/AIcore/@SUBTYPES : /obj/structure/aicore/@SUBTYPES +/obj/item/tank/vox : /obj/item/tank/nitrogen{@OLD} + +/obj/machinery/shuttle_sensor : /obj/machinery/airlock_sensor/shuttle{@OLD} + +/obj/machinery/computer/rdconsole/@SUBTYPES : /obj/machinery/computer/design_console{@OLD} +/obj/machinery/computer/rdservercontrol : /obj/machinery/computer/design_console{@OLD; name = @SKIP; badmin = @SKIP} +/obj/item/stock_parts/circuitboard/rdconsole : /obj/item/stock_parts/circuitboard/design_console{@OLD} +/obj/item/stock_parts/circuitboard/rdserver : /obj/item/stock_parts/circuitboard/design_database{@OLD} + +/obj/machinery/account_database : /obj/machinery/computer/account_database{@OLD} +/obj/machinery/shield_gen/@SUBTYPES : /obj/machinery/shield_generator + +/obj/structure/morgue/crematorium : /obj/structure/crematorium{@OLD} + +/obj/item/robot_parts/frame : /obj/item/robot_parts/robot_suit{@OLD} + +/obj/structure/closet/secure_closet/psych : /obj/structure/closet/secure_closet/psychiatry{@OLD} +/obj/structure/closet/firecloset/full : /obj/structure/closet/firecloset{@OLD} +/obj/structure/closet/firecloset/full/double : /obj/structure/closet/firecloset/chief{@OLD} +/obj/structure/closet/l3closet/scientist/double : /obj/structure/closet/l3closet/scientist/multi{@OLD} +/obj/structure/closet/secure_closet/hos2 : /obj/structure/closet/secure_closet/hos{@OLD} +/obj/structure/closet/secure_closet/medical_wall/synth_anesthetics : /obj/structure/closet/secure_closet/medical_wall/anesthetics/robotics{@OLD} +/obj/structure/closet/secure_closet/medical2 : /obj/structure/closet/secure_closet/anesthetics{@OLD} +/obj/structure/closet/walllocker/emerglocker/@SUBTYPES : /obj/structure/emergency_dispenser/@SUBTYPES{@OLD} + +/obj/item/firstaid_arm_assembly : /obj/item/firstaid/empty, /obj/item/robot_parts/l_arm +/obj/item/bucket_sensor : /obj/item/chems/glass/bucket, /obj/item/assembly/prox_sensor +/obj/item/broken_device : @DELETE + +/obj/item/spacecash/@SUBTYPES : /obj/item/cash/@SUBTYPES{@OLD} + +/obj/item/kit/paint/ripley : /obj/item/kit/paint/camouflage +/obj/item/kit/paint/ripley/death : /obj/item/kit/paint/camouflage/forest +/obj/item/kit/paint/ripley/flames_blue : /obj/item/kit/paint/flames_blue +/obj/item/kit/paint/ripley/flames_red : /obj/item/kit/paint/flames_red + +/obj/machinery/photocopier/faxmachine : /obj/machinery/faxmachine{@OLD; init_network_tag = @OLD:department; department = @SKIP} +/obj/item/tvcamera : /obj/item/camera/tvcamera{@OLD} +/obj/machinery/station_map : /obj/machinery/holomap{@OLD} + +/obj/item/ducttape : /obj/item/duct_tape{@OLD} +/obj/item/toy/katana : /obj/item/sword/katana/toy{@OLD} +/obj/item/toy/cultsword : /obj/item/sword/cult_toy{@OLD} +/obj/item/toy/sword : /obj/item/energy_blade/sword/toy{@OLD} +/obj/item/lipstick/jade : /obj/item/cosmetics/lipstick/green{@OLD} +/obj/item/rig_module/device/plasmacutter : /obj/item/rig_module/mounted/plasmacutter{@OLD} +/obj/item/storage/box/syndie_kit/ewar_voice : /obj/item/backpack/satchel/syndie_kit/ewar_voice +/obj/item/tray : /obj/item/plate/tray{@OLD} +/obj/item/weldingtool/weldpack : /obj/item/chems/weldpack{@OLD} +/obj/machinery/crystal : /obj/structure/crystal{@OLD} +/obj/item/organ/internal/stack : /obj/item/organ/internal/voxstack{@OLD} +/obj/item/radio_jammer : /obj/item/suit_sensor_jammer + +# AMMO BOXES +/obj/item/storage/box/beanbags/@SUBTYPES : /obj/item/box/ammo/beanbags/@SUBTYPES{@OLD} +/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} +/obj/item/storage/box/blanks/@SUBTYPES : /obj/item/box/ammo/blanks/@SUBTYPES{@OLD} +/obj/item/storage/box/empshells/@SUBTYPES : /obj/item/box/ammo/empshells/@SUBTYPES{@OLD} +/obj/item/storage/box/flashshells/@SUBTYPES : /obj/item/box/ammo/flashshells/@SUBTYPES{@OLD} +/obj/item/storage/box/shotgunammo/@SUBTYPES : /obj/item/box/ammo/shotgunammo/@SUBTYPES{@OLD} +/obj/item/storage/box/shotgunshells/@SUBTYPES : /obj/item/box/ammo/shotgunshells/@SUBTYPES{@OLD} +/obj/item/storage/box/sniperammo/@SUBTYPES : /obj/item/box/ammo/sniperammo/@SUBTYPES{@OLD} +/obj/item/storage/box/stunshells/@SUBTYPES : /obj/item/box/ammo/stunshells/@SUBTYPES{@OLD} + +/obj/item/extinguisher/@SUBTYPES : /obj/item/chems/spray/extinguisher/@SUBTYPES{@OLD} +/obj/item/camera_assembly : /obj/item/frame/camera/kit +/obj/structure/ladder/up : /obj/structure/ladder +/obj/random/mob/mouse : /obj/random/mouse + +/obj/structure/closet/grave/dirthole : /obj/structure/pit{@OLD} +/obj/structure/closet/grave/@SUBTYPES : /obj/structure/pit/closed/grave{@OLD} + +/obj/item/banner/nt : /obj/item/banner/nanotrasen{@OLD} + +/obj/item/box/syndie_kit/clerical : /obj/item/backpack/satchel/syndie_kit/clerical{@OLD} + +/obj/item/clothing/under/costume/rainbow : /obj/item/clothing/jumpsuit/rainbow{@OLD} +/obj/item/clothing/under/dress/dress_orange : /obj/item/clothing/dress/orange{@OLD} +/obj/item/clothing/head/collectable/xenos : /obj/item/clothing/head/xenos{@OLD} +/obj/item/clothing/head/collectable/bearpelt : /obj/item/clothing/head/bearpelt{@OLD} +/obj/item/clothing/head/collectable/philosopher_wig : /obj/item/clothing/head/philosopher_wig{@OLD} +/obj/item/clothing/head/collectable/plaguedoctorhat : /obj/item/clothing/head/plaguedoctorhat{@OLD} +/obj/item/clothing/head/helmet/space/void/security/riot : /obj/item/clothing/head/helmet/space/void/security/alt{@OLD} +/obj/item/clothing/suit/space/void/security/riot : /obj/item/clothing/suit/space/void/security/alt{@OLD} +/obj/item/clothing/head/helmet/space/vox/pressure : /obj/item/clothing/head/helmet/space/vox{@OLD} +/obj/item/clothing/under/vox/vox_utility : /obj/item/clothing/pants/vox{@OLD} +/obj/item/clothing/suit/space/pirate : /obj/item/clothing/suit/pirate{@OLD} +/obj/item/clothing/suit/costume : /obj/item/clothing/suit/pirate{@OLD} +/obj/item/clothing/suit/costume/hgpirate : /obj/item/clothing/suit/hgpirate{@OLD} +/obj/item/clothing/suit/storage/vest/heavy/merc : /obj/item/clothing/suit/armor/pcarrier/merc{@OLD} +/obj/item/clothing/suit/storage/vest/@SUBTYPES : /obj/item/clothing/suit/armor/vest/@SUBTYPES{@OLD} + +# Migrate/delete old mech parts +/obj/item/mecha_parts/mecha_equipment/anticcw_armor_booster : @DELETE +/obj/item/mecha_parts/mecha_equipment/antiproj_armor_booster : @DELETE +/obj/item/mecha_parts/mecha_equipment/repair_droid : @DELETE +/obj/item/mecha_parts/mecha_equipment/teleporter : @DELETE +/obj/item/mecha_parts/mecha_equipment/tesla_energy_relay : @DELETE +/obj/item/mecha_parts/mecha_equipment/tool/cable_layer : @DELETE +/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill : /obj/item/mech_equipment/drill/diamond{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/extinguisher : /obj/item/mech_equipment/mounted_system/extinguisher{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp : /obj/item/mech_equipment/clamp{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/passenger : @DELETE +/obj/item/mecha_parts/mecha_equipment/tool/rcd : /obj/item/mech_equipment/mounted_system/rcd{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/sleeper : /obj/item/mech_equipment/sleeper{@OLD} +/obj/item/mecha_parts/mecha_equipment/tool/syringe_gun : @DELETE +/obj/item/mecha_parts/mecha_equipment/weapon/energy/ion : /obj/item/mech_equipment/mounted_system/taser/ion{@OLD} +/obj/item/mecha_parts/mecha_equipment/weapon/energy/taser : /obj/item/mech_equipment/mounted_system/taser{@OLD} +/obj/item/mecha_parts/mecha_tracking : @DELETE + +############ +# VAREDITS # +############ +# Atmos varedits +/obj/machinery/computer/air_control/@SUBTYPES{sensors = @SET} : /obj/machinery/computer/air_control/@SUBTYPES{@OLD; sensors = @SKIP} +# move these to the external air subtype so frequencies work +/obj/machinery/atmospherics/unary/vent_pump/high_volume{frequency = 1379} : /obj/machinery/atmospherics/unary/vent_pump/high_volume/external_air{@OLD; frequency = @SKIP} +/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrub_id = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} +/obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{scrubbing_gas = list("phoron")} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; scrubbing_gas = list(/decl/material/solid/phoron)} +/obj/machinery/computer/area_atmos/tag/@SUBTYPES{scrub_id = @SET} : /obj/machinery/computer/area_atmos/tag/@SUBTYPES{@OLD; scrub_id = @SKIP; id_tag = @OLD:scrub_id} +# for the rest of this, frequency was moved to component presets and i'm too lazy to set that up +/obj/machinery/door/airlock/@SUBTYPES{frequency = @SET} : /obj/machinery/door/airlock/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/portable_atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/atmospherics/@SUBTYPES{frequency = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/airlock_sensor/@SUBTYPES{frequency = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/air_sensor/@SUBTYPES : /obj/machinery/air_sensor/@SUBTYPES{@OLD; frequency = @SKIP; output = @SKIP} +/obj/machinery/embedded_controller/radio/@SUBTYPES{frequency = @SET} : /obj/machinery/embedded_controller/radio/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/button/@SUBTYPES{frequency = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; frequency = @SKIP} +/obj/machinery/meter/@SUBTYPES{frequency = @SET} : /obj/machinery/portable_atmospherics/powered/scrubber/@SUBTYPES{@OLD; frequency = @SKIP} + +# id -> id_tag +/obj/machinery/door_timer/@SUBTYPES{id = @SET} : /obj/machinery/door_timer/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/conveyor/@SUBTYPES{id = @SET} : /obj/machinery/conveyor/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/conveyor_switch/@SUBTYPES{id = @SET} : /obj/machinery/conveyor_switch/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/door/@SUBTYPES{id = @SET} : /obj/machinery/door/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/button/@SUBTYPES{id = @SET} : /obj/machinery/button/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/atmospherics/@SUBTYPES{id = @SET} : /obj/machinery/atmospherics/@SUBTYPES{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/holosign/bar{id = @SET} : /obj/machinery/holosign/bar{@OLD; id_tag = @OLD:id; id = @SKIP} +/obj/machinery/meter/@SUBTYPES{id = @SET} : /obj/machinery/meter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/flasher/@SUBTYPES{id = @SET} : /obj/machinery/flasher/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/sparker/@SUBTYPES{id = @SET} : /obj/machinery/sparker/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/mass_driver/@SUBTYPES{id = @SET} : /obj/machinery/mass_driver/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} +/obj/machinery/emitter/@SUBTYPES{id = @SET} : /obj/machinery/emitter/@SUBTYPES{@OLD; id = @SKIP; id_tag = @OLD:id} + +# Camera preset_channels -> network +/obj/machinery/camera/network/@SUBTYPES{network = @SET} : /obj/machinery/camera/network/@SUBTYPES{@OLD; network = @SKIP; preset_channels = @OLD:network} + +# Remove button/sensor master_tag +/obj/machinery/airlock_sensor/@SUBTYPES{master_tag = @SET} : /obj/machinery/airlock_sensor/@SUBTYPES{@OLD; master_tag = @SKIP} +/obj/machinery/button/access/@SUBTYPES{master_tag = @SET} : /obj/machinery/button/access/@SUBTYPES{@OLD; master_tag = @SKIP} + +# Skip power sensor name_tag +/obj/machinery/power/sensor{name_tag = @SET} : /obj/machinery/power/sensor{@OLD; name_tag = @SKIP} + +# join_group -> unique_merge_identifier +/turf/wall/shuttle/@SUBTYPES{join_group = @SET} : /turf/wall/shuttle/@SUBTYPES{@OLD; unique_merge_identifier = @OLD:join_group} + +# Remove set icon states/density on windows, doors, shutters +/obj/machinery/door/blast/regular{icon_state = @SET} : /obj/machinery/door/blast/regular{@OLD; icon_state = @SKIP} +/obj/structure/window/borosilicate_reinforced/@SUBTYPES{icon_state = @SET} : /obj/structure/window/borosilicate_reinforced/@SUBTYPES{@OLD; icon_state = @SKIP} +/obj/machinery/door/blast/regular{p_open = 1} : /obj/machinery/door/blast/regular/open{@OLD; p_open = @SKIP} +/obj/machinery/door/blast/regular{p_open = 0} : /obj/machinery/door/blast/regular{@OLD; p_open = @SKIP} +/obj/machinery/door/blast/regular{density = 0} : /obj/machinery/door/blast/regular/open{@OLD; density = @SKIP; opacity = @SKIP} +/obj/structure/window/@SUBTYPES{icon_state = "fwindow"} : /obj/structure/window/@SUBTYPES{@OLD; icon_state = @SKIP} +/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} +/obj/structure/window/reinforced/reinforced/polarized/full{dir = 10} : /obj/structure/window/reinforced/polarized/full{@OLD; dir = @SKIP} + +# Prices -> markup +/obj/machinery/vending/@SUBTYPES{prices = list()} : /obj/machinery/vending/@SUBTYPES{@OLD; markup = 0; prices=@SKIP} +/obj/machinery/vending/@SUBTYPES{prices = @SET} : /obj/machinery/vending/@SUBTYPES{@OLD; prices = @SKIP} + +# Radio varedits +/obj/item/radio/@SUBTYPES{subspace_transmission = @SET} : @OLD {@OLD; subspace_transmission = @SKIP} +/obj/item/radio/@SUBTYPES{syndie = @SET} : @OLD {@OLD; decrypt_all_messages = 1; syndie = @SKIP} +/obj/item/radio/@SUBTYPES{adhoc_fallback = @SET} : @OLD {@OLD; can_use_analog = @SKIP} + +# Empty first-aid kits +/obj/item/storage/firstaid/regular{empty = 1} : /obj/item/firstaid/empty{@OLD; empty = @SKIP; name = @SKIP} + +/obj/machinery/floor_light/prebuilt{on = 1} : /obj/machinery/floor_light/prebuilt{@OLD; use_power = 2; on = @SKIP} + +/obj/structure/disposalpipe/sortjunction/@SUBTYPES{sortType = @SET} : /obj/structure/disposalpipe/sortjunction/@SUBTYPES{@OLD; sort_type = @OLD:sortType; sortType = @SKIP} From b1b0ff55a01299d49b2168805ebabcc78519ed5b Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 8 Jun 2025 20:31:58 +1000 Subject: [PATCH 401/512] Readded monitor head. --- .../client/preference_setup/loadout/lists/headwear.dm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/modules/client/preference_setup/loadout/lists/headwear.dm b/code/modules/client/preference_setup/loadout/lists/headwear.dm index 715cf51a8110..35282815bd33 100644 --- a/code/modules/client/preference_setup/loadout/lists/headwear.dm +++ b/code/modules/client/preference_setup/loadout/lists/headwear.dm @@ -168,3 +168,10 @@ name = "balaclava" path = /obj/item/clothing/mask/balaclava uid = "gear_head_balaclava" + +/decl/loadout_option/head/monitor_head + name = "monitor head (synthetics only)" + path = /obj/item/clothing/mask/monitor + loadout_flags = GEAR_HAS_TYPE_SELECTION + slot = slot_wear_mask_str + uid = "gear_utility_monitorhead" From 3778b6713b61f8c5a9091ea14422ea09d6e0dc1c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 12 Jun 2025 01:20:24 -0400 Subject: [PATCH 402/512] Fix produce bin UI issues --- code/datums/extensions/storage/_storage.dm | 31 +++++++------- code/datums/extensions/storage/_storage_ui.dm | 40 ++++++++++++++----- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/code/datums/extensions/storage/_storage.dm b/code/datums/extensions/storage/_storage.dm index e6200fdaf083..b867b2b6d266 100644 --- a/code/datums/extensions/storage/_storage.dm +++ b/code/datums/extensions/storage/_storage.dm @@ -252,30 +252,29 @@ var/global/list/_test_storage_items = list() /datum/storage/proc/update_ui_after_item_insertion(obj/item/inserted, click_params) prepare_ui() - storage_ui?.on_insertion() + storage_ui?.on_insertion(inserted) /datum/storage/proc/update_ui_after_item_removal(obj/item/removed) prepare_ui() - storage_ui?.on_post_remove() + storage_ui?.on_post_remove(removed) //Call this proc to handle the removal of an item from the storage item. The item will be moved to the atom sent as new_target -/datum/storage/proc/remove_from_storage(mob/user, obj/item/W, atom/new_location, skip_update) - if(!istype(W)) +/datum/storage/proc/remove_from_storage(mob/user, obj/item/removing, atom/new_location, skip_update) + if(!istype(removing)) return FALSE new_location = new_location || get_turf(holder) - storage_ui?.on_pre_remove(W) - if(ismob(holder?.loc)) - W.dropped(user) - if(ismob(new_location)) - W.hud_layerise() - else - W.reset_plane_and_layer() - W.forceMove(new_location) + storage_ui?.on_pre_remove(removing) + // This doesn't call dropped anymore because it's not leaving a mob slot directly. + // If something needs to duplicate dropped() functionality on removal from a storage object, + // it should be done in on_exit_storage instead. + removing.forceMove(new_location) + if(!ismob(new_location)) // inventory slot equipped() already handles hud_layerise + removing.reset_plane_and_layer() // this should be done post-move to avoid wasting an icon update if(!skip_update) - update_ui_after_item_removal(W) - if(W.maptext) - W.maptext = "" - W.on_exit_storage(src) + update_ui_after_item_removal(removing) + if(removing.maptext) + removing.maptext = "" + removing.on_exit_storage(src) if(!skip_update && holder) holder.update_icon() return TRUE diff --git a/code/datums/extensions/storage/_storage_ui.dm b/code/datums/extensions/storage/_storage_ui.dm index 6f4db924f328..80c731b7943d 100644 --- a/code/datums/extensions/storage/_storage_ui.dm +++ b/code/datums/extensions/storage/_storage_ui.dm @@ -32,7 +32,7 @@ /datum/storage_ui/proc/after_close(mob/user) return -/datum/storage_ui/proc/on_insertion() +/datum/storage_ui/proc/on_insertion(obj/item/inserted) return /datum/storage_ui/proc/on_pre_remove(obj/item/W) @@ -44,6 +44,9 @@ /datum/storage_ui/proc/on_hand_attack(mob/user) return +/datum/storage_ui/proc/get_displayed_contents() + return + // Default subtype /datum/storage_ui/default var/obj/screen/storage/boxes/boxes @@ -96,23 +99,32 @@ /datum/storage_ui/default/on_post_remove(obj/item/W) refresh_viewers() -/datum/storage_ui/default/on_pre_remove(obj/item/W) +/datum/storage_ui/default/on_pre_remove(obj/item/removing) for(var/mob/user in is_seeing) - user.client?.screen -= W + user.client?.screen -= removing + // if being moved to an inventory slot or other storage item, this will be re-set after the transfer is done + removing.screen_loc = null /datum/storage_ui/default/on_hand_attack(mob/user) for(var/mob/other_user in is_seeing) if (other_user.active_storage == _storage) _storage.close(other_user) +/datum/storage_ui/default/get_displayed_contents() + return _storage?.get_contents() + /datum/storage_ui/default/show_to(mob/user) if(!istype(user)) return + // TODO: move this to the interaction that opens the storage object rather than handling it on the UI + // because i really hate calling get_contents followed by get_displayed_contents + // the issue is that some things call atom.storage.show_to() directly rather than using open() var/list/contents = _storage?.get_contents() if(user.active_storage != _storage) for(var/obj/item/I in contents) if(I.on_found(user)) return + var/list/displayed_contents = get_displayed_contents() if(user.active_storage) user.active_storage.hide_from(user) if(user.client) @@ -123,8 +135,8 @@ user.client.screen -= closer user.client.screen -= contents user.client.screen += closer - if(length(contents)) - user.client.screen += contents + if(length(displayed_contents)) + user.client.screen += displayed_contents if(_storage.storage_slots) user.client.screen += boxes else @@ -305,6 +317,17 @@ row_num = round((adjusted_contents-1) / 7) // 7 is the maximum allowed width. arrange_item_slots(row_num, clamp(adjusted_contents - 1, 0, 6)) +// Only display one item for each key. +/datum/storage_ui/default/produce_bin/get_displayed_contents() + . = list() + var/list/displayed = list() + for(var/obj/item/food/grown/produce in _storage.get_contents()) + var/produce_key = get_key_for_object(produce) + if(displayed[produce_key]) + continue + displayed[produce_key] = TRUE + . += produce + //This proc draws out the inventory and places the items on it. It uses the standard position. /datum/storage_ui/default/produce_bin/arrange_item_slots(rows, cols) var/cx = SCREEN_LOC_MOD_FIRST @@ -312,12 +335,9 @@ boxes.screen_loc = "LEFT+[SCREEN_LOC_MOD_FIRST]:[SCREEN_LOC_MOD_DIVIDED],BOTTOM+[SCREEN_LOC_MOD_SECOND]:[SCREEN_LOC_MOD_DIVIDED] to LEFT+[SCREEN_LOC_MOD_FIRST + cols]:[SCREEN_LOC_MOD_DIVIDED],BOTTOM+[SCREEN_LOC_MOD_SECOND + rows]:[SCREEN_LOC_MOD_DIVIDED]" var/list/counts = get_seed_counts() - var/list/displayed = list() - for(var/obj/item/food/grown/produce in _storage.get_contents()) + // get_displayed_contents already handles deduplication + for(var/obj/item/food/grown/produce in get_displayed_contents()) var/produce_key = get_key_for_object(produce) - if(displayed[produce_key]) - continue - displayed[produce_key] = TRUE produce.screen_loc = "LEFT+[cx]:[SCREEN_LOC_MOD_DIVIDED],BOTTOM+[cy]:[SCREEN_LOC_MOD_DIVIDED]" produce.maptext_x = 2 produce.maptext_y = 2 From 9ec9711087e5fba4e9a6de51288e68721db81b63 Mon Sep 17 00:00:00 2001 From: ike709 Date: Sat, 14 Jun 2025 08:45:24 -0500 Subject: [PATCH 403/512] Rename a var from `usr` to `user` --- code/modules/character_info/_comment.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/character_info/_comment.dm b/code/modules/character_info/_comment.dm index ef15898c550b..3ab52a26d2e1 100644 --- a/code/modules/character_info/_comment.dm +++ b/code/modules/character_info/_comment.dm @@ -25,7 +25,7 @@ /datum/character_comment/proc/is_stale() return !get_config_value(/decl/config/num/hide_comments_older_than) || (REALTIMEOFDAY - last_updated) > (get_config_value(/decl/config/num/hide_comments_older_than)) -/datum/character_comment/proc/get_comment_html(var/datum/character_information/presenting, var/mob/usr, var/row_bkg_color) +/datum/character_comment/proc/get_comment_html(var/datum/character_information/presenting, var/mob/user, var/row_bkg_color) if(!istype(main_mood)) main_mood = GET_DECL(/decl/comment_mood/unknown) @@ -39,14 +39,14 @@ "
    [body]
    ", "" ) - if(usr) + if(user) . += "
    " - if(author_ckey == usr.ckey || check_rights(R_MOD)) + if(author_ckey == user.ckey || check_rights(R_MOD)) . += "Edit
    " . += "Delete
    " . += "Change primary mood
    " . += "Change border mood" - else if(usr.ckey == presenting.ckey) + else if(user.ckey == presenting.ckey) . += "Delete" else . += "Not editable." From 6e62ab2336ca3dc7601eadbbda9f7d162205afbf Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 14 Jun 2025 20:29:03 -0400 Subject: [PATCH 404/512] Remove defunct gateway code --- code/_onclick/ghost.dm | 12 - .../corpse.dm => abstract/corpse_spawner.dm} | 6 - code/modules/awaymissions/artillery.dm | 53 ---- code/modules/awaymissions/exile.dm | 36 --- code/modules/awaymissions/gateway.dm | 235 ------------------ code/modules/awaymissions/pamphlet.dm | 39 --- code/modules/awaymissions/trigger.dm | 40 --- icons/obj/items/paperwork/pamphlet.dmi | Bin 813 -> 0 bytes nebula.dme | 7 +- 9 files changed, 1 insertion(+), 427 deletions(-) rename code/modules/{awaymissions/corpse.dm => abstract/corpse_spawner.dm} (96%) delete mode 100644 code/modules/awaymissions/artillery.dm delete mode 100644 code/modules/awaymissions/exile.dm delete mode 100644 code/modules/awaymissions/gateway.dm delete mode 100644 code/modules/awaymissions/pamphlet.dm delete mode 100644 code/modules/awaymissions/trigger.dm delete mode 100644 icons/obj/items/paperwork/pamphlet.dmi diff --git a/code/_onclick/ghost.dm b/code/_onclick/ghost.dm index d36410ef6aea..a47458ff2f18 100644 --- a/code/_onclick/ghost.dm +++ b/code/_onclick/ghost.dm @@ -61,15 +61,3 @@ /obj/effect/portal/attack_ghost(mob/user) if(target) user.forceMove(get_turf(target)) - -/obj/machinery/gateway/centerstation/attack_ghost(mob/user) - if(awaygate) - user.forceMove(awaygate.loc) - else - to_chat(user, "[src] has no destination.") - -/obj/machinery/gateway/centeraway/attack_ghost(mob/user) - if(stationgate) - user.forceMove(stationgate.loc) - else - to_chat(user, "[src] has no destination.") diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/abstract/corpse_spawner.dm similarity index 96% rename from code/modules/awaymissions/corpse.dm rename to code/modules/abstract/corpse_spawner.dm index 62eb69dc0a6e..47319d03325b 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/abstract/corpse_spawner.dm @@ -1,9 +1,3 @@ -//These are meant for spawning on maps, namely Away Missions. - -//If someone can do this in a neater way, be my guest-Kor - -//To do: Allow corpses to appear mangled, bloody, etc. Allow customizing the bodies appearance (they're all bald and white right now). - #define CORPSE_SPAWNER_RANDOM_NAME BITFLAG(0) #define CORPSE_SPAWNER_CUT_SURVIVAL BITFLAG(1) #define CORPSE_SPAWNER_CUT_ID_PDA BITFLAG(2) diff --git a/code/modules/awaymissions/artillery.dm b/code/modules/awaymissions/artillery.dm deleted file mode 100644 index 644356e53d76..000000000000 --- a/code/modules/awaymissions/artillery.dm +++ /dev/null @@ -1,53 +0,0 @@ -/obj/structure/artilleryplaceholder - name = "artillery" - desc = "The ship's old superluminal artillery cannon. Looks inoperative." - icon = 'icons/obj/machines/artillery.dmi' - anchored = TRUE - density = TRUE - -/obj/structure/artilleryplaceholder/decorative - density = FALSE - -/obj/machinery/artillerycontrol - name = "superluminal artillery control" - icon_state = "control_boxp1" - icon = 'icons/obj/machines/particle_accelerator2.dmi' - density = TRUE - anchored = TRUE - var/tmp/time_to_reload = 360 SECONDS // originally this was 180 ticks at 1 tick per 2 seconds - var/reload_cooldown = 0 // The world.time value after which we will be able to fire. - -/obj/machinery/artillerycontrol/interface_interact(mob/user) - interact(user) - return TRUE - -/obj/machinery/artillerycontrol/interact(mob/user) - user.set_machine(src) - var/dat = list("Superluminal Artillery Control:
    ") - dat += "Locked on
    " - dat += "Charge progress: [round(100 - ((reload_cooldown - world.time) / time_to_reload))]%
    " - dat += "Open Fire
    " - dat += "Deployment of weapon authorized by
    [global.using_map.company_name] Naval Command

    Remember, friendly fire is grounds for termination of your contract and life.
    " - show_browser(user, JOINTEXT(dat), "window=superlumcontrol") - onclose(user, "superlumcontrol") - -/obj/machinery/artillerycontrol/OnTopic(mob/user, href_list) - if((. = ..())) - return - - var/area/thearea = input("Area to jump bombard", "Open Fire") as null|anything in teleportlocs - thearea = thearea ? teleportlocs[thearea] : null - if (!thearea) - return - if (world.time < reload_cooldown) - return - command_announcement.Announce("Wormhole artillery fire detected. Brace for impact.") - log_and_message_admins("has launched an artillery strike.", user, get_turf(src)) - var/list/turf/candidates = list() - // this is slow (in world loop) but we don't have a better way unless we pre-register a list of areas -> z-levels - // and this code isn't hot code at all - for(var/turf/tile in thearea) - candidates += tile - var/turf/target_loc = pick(candidates) - explosion(target_loc, 2, 5, 11) - reload_cooldown = world.time + time_to_reload diff --git a/code/modules/awaymissions/exile.dm b/code/modules/awaymissions/exile.dm deleted file mode 100644 index 51e98d910082..000000000000 --- a/code/modules/awaymissions/exile.dm +++ /dev/null @@ -1,36 +0,0 @@ -//////Exile implants will allow you to use the station gate, but not return home. This will allow security to exile badguys/for badguys to exile their kill targets//////// - - -/obj/item/implanter/exile - name = "implanter-exile" - imp = /obj/item/implant/exile - -/obj/item/implant/exile - name = "exile" - desc = "Prevents you from returning from away missions." - -/obj/item/implant/exile/get_data() - var/dat = {" - Implant Specifications:
    - Name: [global.using_map.company_name] Employee Exile Implant
    - Implant Details: The onboard gateway system has been modified to reject entry by individuals containing this implant
    "} - return dat - -/obj/item/implantcase/exile - name = "glass case - 'Exile'" - desc = "A case containing an exile implant." - icon_state = "implantcase-r" - imp = /obj/item/implant/exile - -/obj/structure/closet/secure_closet/exile - name = "Exile Implants" - req_access = list(access_hos) - -/obj/structure/closet/secure_closet/exile/Initialize() - . = ..() - new /obj/item/implanter/exile(src) - new /obj/item/implantcase/exile(src) - new /obj/item/implantcase/exile(src) - new /obj/item/implantcase/exile(src) - new /obj/item/implantcase/exile(src) - new /obj/item/implantcase/exile(src) diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm deleted file mode 100644 index 3696cdeec715..000000000000 --- a/code/modules/awaymissions/gateway.dm +++ /dev/null @@ -1,235 +0,0 @@ -/obj/machinery/gateway - name = "gateway" - desc = "A mysterious gateway built by unknown hands, it allows for faster than light travel to far-flung locations." - icon = 'icons/obj/machines/gateway.dmi' - icon_state = "off" - density = TRUE - anchored = TRUE - var/active = 0 - - -/obj/machinery/gateway/Initialize() - update_icon() - if(dir == SOUTH) - set_density(0) - . = ..() - -/obj/machinery/gateway/on_update_icon() - if(active) - icon_state = "on" - return - icon_state = "off" - - - -//this is da important part wot makes things go -/obj/machinery/gateway/centerstation - density = TRUE - icon_state = "offcenter" - - //warping vars - var/list/linked = list() - var/ready = 0 //have we got all the parts for a gateway? - var/wait = 0 //this just grabs world.time at world start - var/obj/machinery/gateway/centeraway/awaygate = null - -/obj/machinery/gateway/centerstation/Initialize() - update_icon() - wait = world.time + get_config_value(/decl/config/num/gateway_delay) //+ thirty minutes default - awaygate = locate(/obj/machinery/gateway/centeraway) - . = ..() - -/obj/machinery/gateway/centerstation/on_update_icon() - if(active) - icon_state = "oncenter" - return - icon_state = "offcenter" - - - -/obj/machinery/gateway/centerstation/Process() - if(stat & (NOPOWER)) - if(active) toggleoff() - return - - if(active) - use_power_oneoff(5000) - - -/obj/machinery/gateway/centerstation/proc/detect() - linked = list() //clear the list - var/turf/T = loc - - for(var/i in global.alldirs) - T = get_step(loc, i) - var/obj/machinery/gateway/G = locate(/obj/machinery/gateway) in T - if(G) - linked.Add(G) - continue - - //this is only done if we fail to find a part - ready = 0 - toggleoff() - break - - if(linked.len == 8) - ready = 1 - - -/obj/machinery/gateway/centerstation/proc/toggleon(mob/user) - if(!ready) - return - if(linked.len != 8) - return - if(stat & NOPOWER) - return - if(!awaygate) - to_chat(user, "Error: No destination found.") - return - if(world.time < wait) - to_chat(user, "Error: Warpspace triangulation in progress. Estimated time to completion: [round(((wait - world.time) / 10) / 60)] minutes.") - return - - for(var/obj/machinery/gateway/G in linked) - G.active = 1 - G.update_icon() - active = 1 - update_icon() - - -/obj/machinery/gateway/centerstation/proc/toggleoff() - for(var/obj/machinery/gateway/G in linked) - G.active = 0 - G.update_icon() - active = 0 - update_icon() - - -/obj/machinery/gateway/centerstation/attack_hand(mob/user) - if(!user.check_dexterity(DEXTERITY_COMPLEX_TOOLS, TRUE)) - return ..() - if(!ready) - detect() - return TRUE - if(!active) - toggleon(user) - return TRUE - toggleoff() - return TRUE - -//okay, here's the good teleporting stuff -/obj/machinery/gateway/centerstation/Bumped(atom/movable/M) - if(!ready) return - if(!active) return - if(!awaygate) return - if(awaygate.calibrated) - M.forceMove(get_step(awaygate.loc, SOUTH)) - M.set_dir(SOUTH) - return - -/obj/machinery/gateway/centerstation/attackby(obj/item/used_item, mob/user) - if(IS_MULTITOOL(used_item)) - to_chat(user, "The gate is already calibrated, there is no work for you to do here.") - return TRUE - return FALSE - -/////////////////////////////////////Away//////////////////////// - - -/obj/machinery/gateway/centeraway - density = TRUE - icon_state = "offcenter" - use_power = POWER_USE_OFF - var/calibrated = 1 - var/list/linked = list() //a list of the connected gateway chunks - var/ready = 0 - var/obj/machinery/gateway/centerstation/stationgate = null - - -/obj/machinery/gateway/centeraway/Initialize() - update_icon() - stationgate = locate(/obj/machinery/gateway/centerstation) - . = ..() - -/obj/machinery/gateway/centeraway/on_update_icon() - if(active) - icon_state = "oncenter" - return - icon_state = "offcenter" - - -/obj/machinery/gateway/centeraway/proc/detect() - linked = list() //clear the list - var/turf/T = loc - - for(var/i in global.alldirs) - T = get_step(loc, i) - var/obj/machinery/gateway/G = locate(/obj/machinery/gateway) in T - if(G) - linked.Add(G) - continue - - //this is only done if we fail to find a part - ready = 0 - toggleoff() - break - - if(linked.len == 8) - ready = 1 - - -/obj/machinery/gateway/centeraway/proc/toggleon(mob/user) - if(!ready) return - if(linked.len != 8) return - if(!stationgate) - to_chat(user, "Error: No destination found.") - return - - for(var/obj/machinery/gateway/G in linked) - G.active = 1 - G.update_icon() - active = 1 - update_icon() - - -/obj/machinery/gateway/centeraway/proc/toggleoff() - for(var/obj/machinery/gateway/G in linked) - G.active = 0 - G.update_icon() - active = 0 - update_icon() - - -/obj/machinery/gateway/centeraway/attack_hand(mob/user) - if(!user.check_dexterity(DEXTERITY_COMPLEX_TOOLS, TRUE)) - return ..() - if(!ready) - detect() - return TRUE - if(!active) - toggleon(user) - return TRUE - toggleoff() - return TRUE - -/obj/machinery/gateway/centeraway/Bumped(atom/movable/M) - if(!ready) return - if(!active) return - if(ishuman(M)) - for(var/obj/item/implant/exile/E in M)//Checking that there is an exile implant in the contents - if(E.imp_in == M)//Checking that it's actually implanted vs just in their pocket - to_chat(M, "The remote gate has detected your exile implant and is blocking your entry.") - return - M.forceMove(get_step(stationgate.loc, SOUTH)) - M.set_dir(SOUTH) - -/obj/machinery/gateway/centeraway/attackby(obj/item/used_item, mob/user) - if(IS_MULTITOOL(used_item)) - if(calibrated) - to_chat(user, "The gate is already calibrated, there is no work for you to do here.") - return TRUE - else - to_chat(user, "Recalibration successful!: This gate's systems have been fine tuned. Travel to this gate will now be on target.") - calibrated = 1 - return TRUE - return FALSE diff --git a/code/modules/awaymissions/pamphlet.dm b/code/modules/awaymissions/pamphlet.dm deleted file mode 100644 index 49dbb1237f44..000000000000 --- a/code/modules/awaymissions/pamphlet.dm +++ /dev/null @@ -1,39 +0,0 @@ -/obj/item/paper/pamphlet - name = "pamphlet" - icon = 'icons/obj/items/paperwork/pamphlet.dmi' - info = "Welcome to the Gateway project...
    \ - Congratulations! If you're reading this, you and your superiors have decided that you're \ - ready to commit to a life spent colonising the rolling hills of far away worlds. You \ - must be ready for a lifetime of adventure, a little bit of hard work, and an award \ - winning dental plan- but that's not all the Gateway project has to offer.
    \ -
    Because we care about you, we feel it is only fair to make sure you know the risks \ - before you commit to joining the Gateway project. All away destinations have \ - been fully scanned by an expeditionary team, and are certified to be 100% safe. \ - We've even left a case of space beer along with the basic materials you'll need to expand \ - the Project's operational area and start your new life.

    \ - Gateway Operation Basics
    \ - All approved Gateways operate on the same basic principals. They operate off \ - area equipment power as you would expect, but they also require a backup wire with at least \ - 128, 000 Watts of power running through it. Without this supply, it cannot safely function \ - and will reject all attempts at operation.

    \ - Once it is correctly setup, and once it has enough power to operate, the Gateway will begin \ - searching for an output location. The amount of time this takes is variable, but the Gateway \ - interface will give you an estimate accurate to the minute. Power loss will not interrupt the \ - searching process. Influenza will not interrupt the searching process. Temporal anomalies \ - may cause the estimate to be inaccurate, but will not interrupt the searching process.

    \ - Life On The Other Side
    \ - Once you have traversed the Gateway, you may experience some disorientation. Do not panic. \ - This is a normal side effect of travelling vast distances in a short period of time. You should \ - survey the immediate area, and attempt to locate your complimentary case of space beer. Our \ - expeditionary teams have ensured the complete safety of all away locations, but in a small \ - number of cases, the Gateway they have established may not be immediately obvious. \ - Do not panic if you cannot locate the return Gateway. Begin colonisation of the destination. \ -

    A New World
    \ - As a participant in the Gateway Project, you will be on the frontiers of space. \ - Though complete safety is assured, participants are advised to prepare for inhospitable \ - environs." - -//we don't want the silly text overlay! -/obj/item/paper/pamphlet/on_update_icon() - SHOULD_CALL_PARENT(FALSE) - return \ No newline at end of file diff --git a/code/modules/awaymissions/trigger.dm b/code/modules/awaymissions/trigger.dm deleted file mode 100644 index f1d2fa3405ee..000000000000 --- a/code/modules/awaymissions/trigger.dm +++ /dev/null @@ -1,40 +0,0 @@ -/obj/effect/step_trigger/message - var/message //the message to give to the mob - var/once = 1 - -/obj/effect/step_trigger/message/Trigger(mob/M) - if(M.client) - to_chat(M, "[message]") - if(once) - qdel(src) - -/obj/effect/step_trigger/teleport_fancy - var/locationx - var/locationy - var/uses = 1 //0 for infinite uses - var/entersparks = 0 - var/exitsparks = 0 - var/entersmoke = 0 - var/exitsmoke = 0 - -/obj/effect/step_trigger/teleport_fancy/Trigger(mob/M) - var/dest = locate(locationx, locationy, z) - M.Move(dest) - - if(entersparks) - spark_at(src, amount=4, cardinal_only = TRUE) - if(exitsparks) - spark_at(dest, amount=4, cardinal_only = TRUE) - - if(entersmoke) - var/datum/effect/effect/system/smoke_spread/s = new /datum/effect/effect/system/smoke_spread - s.set_up(4, 1, src, 0) - s.start() - if(exitsmoke) - var/datum/effect/effect/system/smoke_spread/s = new /datum/effect/effect/system/smoke_spread - s.set_up(4, 1, dest, 0) - s.start() - - uses-- - if(uses == 0) - qdel(src) \ No newline at end of file diff --git a/icons/obj/items/paperwork/pamphlet.dmi b/icons/obj/items/paperwork/pamphlet.dmi deleted file mode 100644 index 32dd05307de58d4890705fb8de112d2f1b45e411..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 813 zcmV+|1JeA7P)#-*{;{T)8(t%?cr>{|4gy}rKF&ro{^rLe^#~sX}s~f z-Mqly!OrcYd9vQJvaXYplai2sfqQ0e%qHT;dAQV=-0C=2JR&a84_w-Y6@%7{?OD!tS%+FJ>RWQ*r;NmRL zOex6#a*U0*I5Sc+(=$pSoZ^zil2jm5sXV_ZCq;>iGbOXA7|1u|;!G<_%uR)`QB~=d zBo?INRI9Au>gNJ>0stPvCo~0I7Qz4k0RBltK~zYIV_+Bs^ahMfj7$WSFoOV2StcML zpqGV}jh#FLn2`Zl25@k4ar5x<@e2qF;Whvm2sjN877-N_6PJ*bl#<5n2RwjTMpjl% zURFU-Nm+$F15{+)2eEpdH0|Ens0)ojiASBev)zu~}EId4dJOd)5TwFt~ZKI=OV#zZg zJlr)Z$}rS6E Date: Sat, 14 Jun 2025 20:29:20 -0400 Subject: [PATCH 405/512] Remove gateway from Exodus map --- maps/exodus/exodus-2.dmm | 447 +++++++----------------------------- maps/exodus/exodus_areas.dm | 4 - maps/exodus/exodus_jobs.dm | 8 - 3 files changed, 86 insertions(+), 373 deletions(-) diff --git a/maps/exodus/exodus-2.dmm b/maps/exodus/exodus-2.dmm index 7fbd910ebb10..c83892c7fd92 100644 --- a/maps/exodus/exodus-2.dmm +++ b/maps/exodus/exodus-2.dmm @@ -7410,8 +7410,9 @@ /turf/floor/tiled/dark/monotile, /area/shuttle/escape_pod_1) "apD" = ( -/turf/wall/prepainted, -/area/exodus/gateway) +/obj/structure/girder, +/turf/floor/plating, +/area/exodus/maintenance/evahallway) "apE" = ( /obj/machinery/light{ dir = 8 @@ -8588,16 +8589,6 @@ }, /turf/floor, /area/exodus/maintenance/evahallway) -"arS" = ( -/obj/machinery/light_switch{ - pixel_x = -24; - dir = 4 - }, -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "arT" = ( /obj/structure/hygiene/sink/kitchen{ pixel_y = 21 @@ -8859,12 +8850,6 @@ /obj/structure/bed/padded, /turf/floor/tiled/steel_grid, /area/exodus/security/brig/solitaryB) -"asu" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "asv" = ( /obj/structure/disposalpipe/segment{ dir = 1; @@ -11123,11 +11108,6 @@ }, /turf/floor/tiled/dark, /area/exodus/crew_quarters/sleep) -"axv" = ( -/obj/effect/wallframe_spawn/reinforced, -/obj/machinery/door/firedoor, -/turf/floor/plating, -/area/exodus/hallway/primary/port) "axw" = ( /obj/structure/disposalpipe/segment, /obj/structure/cable/green{ @@ -12251,10 +12231,10 @@ /turf/floor/plating, /area/exodus/bridge) "azI" = ( -/obj/machinery/door/airlock/maintenance, /obj/machinery/door/firedoor, -/turf/floor/tiled/techfloor/grid, -/area/exodus/gateway) +/obj/structure/door_assembly, +/turf/floor/plating, +/area/exodus/maintenance/evahallway) "azJ" = ( /obj/machinery/camera/network/civilian_east{ c_tag = "Kitchen Cold Room" @@ -12608,30 +12588,6 @@ /obj/machinery/portable_atmospherics/hydroponics, /turf/floor/tiled/dark, /area/exodus/hydroponics) -"aAA" = ( -/obj/machinery/gateway{ - dir = 9 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aAB" = ( -/obj/machinery/light{ - dir = 8 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aAC" = ( -/obj/machinery/gateway{ - dir = 5 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aAD" = ( -/obj/machinery/gateway{ - dir = 1 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aAE" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 4 @@ -12645,11 +12601,9 @@ /turf/wall/r_wall/prepainted, /area/exodus/maintenance/auxsolarport) "aAG" = ( -/obj/machinery/light{ - dir = 4 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) +/obj/random/maintenance, +/turf/floor/plating, +/area/exodus/maintenance/evahallway) "aAH" = ( /obj/structure/sign/warning/airlock{ pixel_x = 32; @@ -13126,12 +13080,6 @@ "aBI" = ( /turf/wall/r_wall/prepainted, /area/exodus/hallway/secondary/entry/port) -"aBJ" = ( -/obj/machinery/gateway{ - dir = 8 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aBK" = ( /obj/machinery/door/airlock/external/bolted{ id_tag = "nuke_shuttle_dock_inner"; @@ -13146,18 +13094,9 @@ /turf/wall/prepainted, /area/exodus/hallway/secondary/entry/port) "aBM" = ( -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aBN" = ( -/obj/machinery/gateway{ - dir = 4 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aBO" = ( -/obj/machinery/gateway/centerstation, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) +/obj/random/trash, +/turf/floor/plating, +/area/exodus/maintenance/evahallway) "aBP" = ( /obj/machinery/atmospherics/unary/tank/air{ dir = 8 @@ -13554,59 +13493,6 @@ "aCK" = ( /turf/wall/prepainted, /area/exodus/storage/primary) -"aCL" = ( -/obj/machinery/gateway{ - dir = 10 - }, -/obj/abstract/landmark/latejoin/gateway, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aCN" = ( -/obj/machinery/gateway{ - dir = 6 - }, -/obj/abstract/landmark/latejoin/gateway, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aCO" = ( -/obj/machinery/gateway, -/obj/abstract/landmark/latejoin/gateway, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aCP" = ( -/obj/machinery/vending/coffee{ - dir = 4 - }, -/obj/machinery/camera/network/civilian_west{ - c_tag = "Gateway Arrival Area"; - dir = 4 - }, -/obj/structure/sign/warning/biohazard{ - pixel_x = -32 - }, -/obj/effect/floor_decal/industrial/warning/corner{ - dir = 4 - }, -/obj/structure/window/reinforced{ - dir = 1; - current_health = 1e+006 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aCQ" = ( -/obj/structure/sign/warning/biohazard{ - pixel_x = 32 - }, -/obj/structure/closet/wardrobe/xenos, -/obj/effect/floor_decal/industrial/warning/corner{ - dir = 1 - }, -/obj/structure/window/reinforced{ - dir = 1; - current_health = 1e+006 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aCS" = ( /obj/structure/table/reinforced, /obj/item/assembly/signaler, @@ -14173,12 +14059,6 @@ }, /turf/floor/tiled/dark, /area/exodus/security/nuke_storage) -"aEb" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 4 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aEc" = ( /obj/machinery/power/apc{ dir = 8; @@ -14208,21 +14088,6 @@ /obj/effect/wallframe_spawn/reinforced, /turf/floor/plating, /area/exodus/hallway/primary/starboard) -"aEf" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 4 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) -"aEg" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ - dir = 6 - }, -/obj/machinery/atmospherics/pipe/simple/hidden/supply{ - dir = 10 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aEh" = ( /obj/structure/table/laminate, /obj/machinery/reagentgrinder, @@ -14934,12 +14799,6 @@ }, /turf/floor/tiled/steel_grid, /area/exodus/research/chargebay) -"aFA" = ( -/obj/effect/floor_decal/industrial/warning{ - dir = 1 - }, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aFB" = ( /obj/structure/extinguisher_cabinet{ pixel_x = 29; @@ -14986,14 +14845,6 @@ }, /turf/floor/tiled/steel_grid, /area/exodus/hallway/primary/central_two) -"aFF" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/obj/effect/floor_decal/industrial/warning{ - dir = 1 - }, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aFG" = ( /obj/structure/closet/secure_closet/bar, /obj/machinery/power/apc{ @@ -15360,16 +15211,6 @@ }, /turf/floor/tiled/techfloor/grid, /area/exodus/hallway/secondary/exit) -"aGl" = ( -/obj/machinery/vending/cola{ - dir = 4 - }, -/obj/item/radio/intercom{ - dir = 4; - pixel_x = -22 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aGm" = ( /obj/machinery/recharger{ pixel_y = 4 @@ -15561,10 +15402,6 @@ }, /turf/floor/plating, /area/exodus/hallway/primary/central_two) -"aGK" = ( -/obj/item/stool, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aGL" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -15584,10 +15421,6 @@ }, /turf/floor/laminate/walnut, /area/exodus/library) -"aGN" = ( -/obj/machinery/hologram/holopad, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aGO" = ( /obj/effect/wallframe_spawn/reinforced, /obj/machinery/door/blast/shutters/open{ @@ -15618,19 +15451,6 @@ }, /turf/floor/plating, /area/exodus/maintenance/substation/civilian_west) -"aGR" = ( -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) -"aGS" = ( -/obj/machinery/firealarm{ - dir = 4; - pixel_x = 24 - }, -/obj/structure/closet/wardrobe/black, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aGT" = ( /obj/machinery/suit_cycler/medical/prepared, /turf/floor/tiled/dark, @@ -16440,12 +16260,6 @@ }, /turf/floor/plating, /area/exodus/maintenance/bar) -"aIp" = ( -/obj/structure/cable/green{ - icon_state = "4-8" - }, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aIq" = ( /obj/structure/table, /obj/item/deck/cards, @@ -16468,17 +16282,6 @@ }, /turf/floor/plating, /area/exodus/maintenance/library) -"aIs" = ( -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) -"aIt" = ( -/obj/structure/cable/green{ - icon_state = "2-8" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aIu" = ( /obj/machinery/button/access/exterior{ id_tag = "xeno_airlock_control"; @@ -16767,13 +16570,6 @@ }, /turf/floor/tiled/steel_grid, /area/exodus/crew_quarters/bar/cabin) -"aJc" = ( -/obj/structure/closet/l3closet/scientist, -/obj/structure/window/reinforced{ - dir = 8 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "aJd" = ( /obj/structure/flaps{ opacity = 1 @@ -17279,12 +17075,6 @@ /obj/machinery/space_heater, /turf/floor/plating, /area/exodus/maintenance/locker) -"aKl" = ( -/obj/machinery/atmospherics/unary/vent_pump/on{ - dir = 4 - }, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aKm" = ( /obj/structure/cable/green{ icon_state = "1-2" @@ -17299,24 +17089,6 @@ /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, /turf/floor/tiled/steel_grid, /area/exodus/hallway/primary/port) -"aKn" = ( -/obj/machinery/atmospherics/unary/vent_scrubber/on{ - dir = 8 - }, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) -"aKo" = ( -/obj/structure/cable/green{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 8 - }, -/turf/floor/tiled/steel_grid, -/area/exodus/gateway) "aKp" = ( /obj/machinery/vending/fashionvend, /turf/floor/tiled/monotile, @@ -17945,18 +17717,6 @@ /obj/machinery/door/firedoor, /turf/floor/plating, /area/exodus/quartermaster/storage) -"aLG" = ( -/obj/machinery/door/firedoor, -/obj/machinery/door/airlock/glass{ - name = "Gateway Access" - }, -/obj/structure/cable/green{ - icon_state = "1-2" - }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, -/turf/floor/tiled/techfloor/grid, -/area/exodus/hallway/primary/port) "aLH" = ( /obj/structure/cable/green{ icon_state = "0-8" @@ -18800,14 +18560,9 @@ /turf/floor/tiled/steel_grid, /area/exodus/hallway/primary/port) "aNA" = ( -/obj/structure/cable/green{ - icon_state = "1-2" - }, /obj/structure/cable/green{ icon_state = "2-4" }, -/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers, -/obj/machinery/atmospherics/pipe/simple/hidden/supply, /obj/effect/floor_decal/corner/lime{ dir = 5 }, @@ -19725,11 +19480,11 @@ /obj/structure/cable/green{ icon_state = "1-8" }, -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ + dir = 10 }, -/obj/machinery/atmospherics/pipe/manifold/hidden/supply{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/hidden/supply{ + dir = 10 }, /turf/floor/tiled/steel_grid, /area/exodus/hallway/primary/port) @@ -23931,8 +23686,7 @@ announcementConsole = 1; department = "Bridge"; name = "Bridge RC"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /obj/structure/cable/green{ icon_state = "4-8" @@ -26229,22 +25983,6 @@ /obj/structure/disposalpipe/segment, /turf/floor/tiled/techfloor/grid, /area/exodus/hallway/primary/starboard) -"bdL" = ( -/obj/machinery/power/apc{ - dir = 8; - name = "west bump"; - pixel_x = -24 - }, -/obj/structure/table, -/obj/item/deck/cards, -/obj/structure/cable/green{ - icon_state = "0-4" - }, -/obj/item/box/fancy/cigarettes{ - pixel_y = 2 - }, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "bdM" = ( /obj/machinery/atmospherics/unary/vent_scrubber/on{ dir = 1 @@ -26839,8 +26577,7 @@ /obj/machinery/network/requests_console{ department = "Kitchen"; name = "Kitchen RC"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /obj/machinery/disposal, /obj/structure/disposalpipe/trunk{ @@ -29868,8 +29605,7 @@ announcementConsole = 1; department = "Bridge"; name = "Bridge RC"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{ dir = 4 @@ -30768,7 +30504,6 @@ }, /obj/item/chems/glass/beaker/sulfuric, /obj/structure/reagent_dispensers/acid{ - density = 0; pixel_y = 32 }, /turf/floor/tiled/white/monotile, @@ -39350,8 +39085,7 @@ announcementConsole = 1; department = "Head of Personnel's Desk"; name = "Head of Personnel RC"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /obj/machinery/camera/network/command{ c_tag = "Bridge - HoP's Office"; @@ -45577,8 +45311,7 @@ /obj/item/grenade/chem_grenade/cleaner, /obj/machinery/network/requests_console{ department = "Janitorial"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /obj/item/chems/spray/cleaner, /obj/structure/table/steel, @@ -47571,15 +47304,6 @@ }, /turf/floor/tiled/white, /area/exodus/medical/medbay4) -"bUO" = ( -/obj/structure/table, -/obj/machinery/alarm{ - dir = 4; - pixel_x = -23 - }, -/obj/machinery/recharger, -/turf/floor/tiled/dark/monotile, -/area/exodus/gateway) "bUP" = ( /obj/item/radio/intercom{ pixel_y = 20 @@ -56223,8 +55947,7 @@ /obj/machinery/network/requests_console{ department = "Engineering"; name = "Engineering RC"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /turf/floor/tiled/steel_grid, /area/exodus/engineering/foyer) @@ -60505,8 +60228,7 @@ /obj/machinery/network/requests_console{ department = "Engineering"; name = "Engineering RC"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /obj/structure/reagent_dispensers/watertank, /turf/floor/tiled/steel_grid, @@ -64327,8 +64049,7 @@ "oWh" = ( /obj/machinery/network/requests_console{ department = "Arrival shuttle"; - pixel_y = -32; - dir = 2 + pixel_y = -32 }, /obj/effect/floor_decal/corner/white{ dir = 10 @@ -64485,6 +64206,10 @@ /obj/machinery/light, /turf/floor/bluegrid, /area/exodus/turret_protected/ai_upload) +"rAK" = ( +/obj/structure/girder/displaced, +/turf/floor/plating, +/area/exodus/maintenance/evahallway) "rNu" = ( /obj/structure/table{ name = "plastic table frame" @@ -87835,15 +87560,15 @@ anX anX anX ayI +anX +anX +anX apD apD -apD -apD -apD -apD -apD -apD -apD +anX +anX +anX +anX aLK aNw aPi @@ -88092,15 +87817,15 @@ aie aie anX axM -apD +anX aBM +auc +auc +auc +aAG +auc +auc aBM -aAB -arS -aCP -aGl -bdL -bUO aLK aNy aPi @@ -88350,15 +88075,15 @@ aie anX axM apD -aAA -aBJ -aCL -aEb -aFA -aGK -aIp -aKl -axv +auc +auc +auc +auc +auc +auc +auc +auc +aLK wBc aPi hgF @@ -88606,16 +88331,16 @@ awy aie anX axM -apD -aAD -aBO -aCO -aEg -aFF -aGR -aIt -aKo -aLG +anX +auc +auc +auc +auc +auc +auc +auc +auc +aLK aNA aPq bGp @@ -88863,16 +88588,16 @@ awy awy anX axM -apD -aAC -aBN -aCN -aEf -aFA -aGN -aIs -aKn -axv +anX +auc +aBM +auc +auc +auc +auc +auc +auc +aLK qHU xFu hgF @@ -89120,15 +88845,15 @@ awv awy atc axM -apD -aBM -aBM +anX +auc +auc aAG -asu -aCQ -aGS +auc +auc aBM -aJc +auc +auc aMb aNp aOQ @@ -89377,15 +89102,15 @@ aQt awy axK axM -apD -apD -apD -apD -apD -apD -apD +anX +anX +rAK +anX +anX +anX +anX azI -apD +anX aMb aNE vcu diff --git a/maps/exodus/exodus_areas.dm b/maps/exodus/exodus_areas.dm index 265523d92cb5..29ba42a4e778 100644 --- a/maps/exodus/exodus_areas.dm +++ b/maps/exodus/exodus_areas.dm @@ -1048,10 +1048,6 @@ icon_state = "teleporter" req_access = list(access_teleporter) -/area/exodus/gateway - name = "\improper Gateway" - icon_state = "teleporter" - // Thunderdome /area/tdome diff --git a/maps/exodus/exodus_jobs.dm b/maps/exodus/exodus_jobs.dm index 6ca8b4d8ab41..9310a431e2b1 100644 --- a/maps/exodus/exodus_jobs.dm +++ b/maps/exodus/exodus_jobs.dm @@ -1,11 +1,3 @@ -/decl/spawnpoint/gateway - name = "Gateway" - spawn_announcement = "has completed translation from offsite gateway" - uid = "spawn_exodus_gateway" - -/obj/abstract/landmark/latejoin/gateway - spawn_decl = /decl/spawnpoint/gateway - /datum/map/exodus default_job_type = /datum/job/standard/assistant default_department_type = /decl/department/civilian From aa2e773ecfc87bc5b81248afe1b6f76f4ea1c7f7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:29:35 -0400 Subject: [PATCH 406/512] Fix missing allergen_flags on bones --- .../materials/definitions/solids/materials_solid_butchery.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/modules/materials/definitions/solids/materials_solid_butchery.dm b/code/modules/materials/definitions/solids/materials_solid_butchery.dm index f0a0c947fe86..fb78922a5f65 100644 --- a/code/modules/materials/definitions/solids/materials_solid_butchery.dm +++ b/code/modules/materials/definitions/solids/materials_solid_butchery.dm @@ -20,7 +20,6 @@ sound_dropped = 'sound/foley/meat2.ogg' hitsound = 'sound/effects/squelch1.ogg' fishing_bait_value = 1 - nutriment_animal = TRUE reagent_overlay = "soup_chunks" nutriment_factor = 10 allergen_flags = ALLERGEN_MEAT @@ -87,7 +86,6 @@ fishing_bait_value = 0.75 tans_to = /decl/material/solid/organic/leather compost_value = 0.8 - nutriment_animal = TRUE allergen_flags = ALLERGEN_MEAT /decl/material/solid/organic/skin/lizard @@ -224,7 +222,7 @@ sound_manipulate = 'sound/foley/stickspickup1.ogg' sound_dropped = 'sound/foley/sticksdrop1.ogg' compost_value = 0.5 - nutriment_animal = TRUE + allergen_flags = ALLERGEN_MEAT exoplanet_rarity_plant = MAT_RARITY_EXOTIC // Stub to stop eggs melting while being boiled. From d59720cbe40eba47cf496ec970bac3ea72e08e70 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 14 Jun 2025 20:34:16 -0400 Subject: [PATCH 407/512] Remove defunct nutriment_animal material variable --- code/modules/materials/_materials.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index 68457c18328b..63505428ed07 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -344,7 +344,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) var/compost_value = 0 /// Nutrition values! - var/nutriment_animal = FALSE var/nutriment_factor = 0 // Per removed amount each tick var/hydration_factor = 0 // Per removed amount each tick var/injectable_nutrition = FALSE From 6858bc8f731b89a31d3aec1902c370cf7c6114cf Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:16:37 -0400 Subject: [PATCH 408/512] Remove some entirely-unused variables --- code/_global_vars/lists/names.dm | 2 -- code/game/turfs/floors/_floor.dm | 1 - code/game/turfs/turf.dm | 1 - code/game/turfs/walls/_wall.dm | 1 - code/modules/crafting/metalwork/metalwork_items.dm | 1 - .../maps/template_types/random_exoplanet/planetoid_data.dm | 4 ---- code/modules/materials/_materials.dm | 1 - code/modules/mob/living/simple_animal/friendly/cat.dm | 3 --- code/modules/multiz/map_data.dm | 1 - code/modules/organs/external/_external.dm | 1 - code/modules/overmap/ftl_shunt/core.dm | 1 - code/modules/overmap/internet/internet_uplink.dm | 1 - code/modules/overmap/ships/computers/comms.dm | 1 - code/modules/prometheus_metrics/metrics.dm | 3 --- code/modules/scent/_scent.dm | 4 ---- code/modules/status_conditions/_status_condition.dm | 3 --- 16 files changed, 29 deletions(-) diff --git a/code/_global_vars/lists/names.dm b/code/_global_vars/lists/names.dm index 2bd23f308908..78cd73fe25b0 100644 --- a/code/_global_vars/lists/names.dm +++ b/code/_global_vars/lists/names.dm @@ -1,8 +1,6 @@ // All variables here use double quotes to able load information on every startup. var/global/list/ai_names = file2list("config/names/ai.txt") -var/global/list/wizard_first = file2list("config/names/wizardfirst.txt") -var/global/list/wizard_second = file2list("config/names/wizardsecond.txt") var/global/list/verbs = file2list("config/names/verbs.txt") var/global/list/adjectives = file2list("config/names/adjectives.txt") diff --git a/code/game/turfs/floors/_floor.dm b/code/game/turfs/floors/_floor.dm index a2a53460c0a8..d92467b7e3ef 100644 --- a/code/game/turfs/floors/_floor.dm +++ b/code/game/turfs/floors/_floor.dm @@ -5,7 +5,6 @@ layer = PLATING_LAYER permit_ao = TRUE thermal_conductivity = 0.040 - heat_capacity = 10000 explosion_resistance = 1 turf_flags = TURF_IS_HOLOMAP_PATH initial_gas = GAS_STANDARD_AIRMIX diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 94b6618f8d86..285f4fc05c5c 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -19,7 +19,6 @@ //Properties for airtight tiles (/wall) var/thermal_conductivity = 0.05 - var/heat_capacity = 1 //Properties for both /// Does this turf contain air/let air through? diff --git a/code/game/turfs/walls/_wall.dm b/code/game/turfs/walls/_wall.dm index 22141ceed4d8..ef02c8f94328 100644 --- a/code/game/turfs/walls/_wall.dm +++ b/code/game/turfs/walls/_wall.dm @@ -25,7 +25,6 @@ var/global/list/wall_fullblend_objects = list( density = TRUE blocks_air = 1 thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT - heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall explosion_resistance = 10 color = COLOR_STEEL turf_flags = TURF_IS_HOLOMAP_OBSTACLE diff --git a/code/modules/crafting/metalwork/metalwork_items.dm b/code/modules/crafting/metalwork/metalwork_items.dm index 5278aaf343ec..2727db4ada8f 100644 --- a/code/modules/crafting/metalwork/metalwork_items.dm +++ b/code/modules/crafting/metalwork/metalwork_items.dm @@ -17,7 +17,6 @@ material_alteration = MAT_FLAG_ALTERATION_COLOR | MAT_FLAG_ALTERATION_NAME storage = /datum/storage/crucible obj_flags = OBJ_FLAG_NO_STORAGE - var/max_held = 10 /obj/item/chems/crucible/attackby(obj/item/used_item, mob/user) diff --git a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm index c113ec46b77b..95df86b82f93 100644 --- a/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm +++ b/code/modules/maps/template_types/random_exoplanet/planetoid_data.dm @@ -30,10 +30,6 @@ var/habitability_class = HABITABILITY_DEAD ///The cached planet's atmosphere that sub-levels of this planet should use. Can be a type path at definition, and an instance at runtime. var/datum/gas_mixture/atmosphere - ///The minimum temperature that can be reached on the planet.(For instance via meteo or sunlight/shade or whatever) - var/temperature_min = 0 CELSIUS - ///The maximum temperature that can be reached on the planet.(For instance via meteo or sunlight/shade or whatever) - var/temperature_max = 25 CELSIUS ///What weather state to use for this planet initially. If null, will not initialize any weather system. Must be a typepath rather than an instance. var/decl/state/weather/initial_weather_state = /decl/state/weather/calm diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index dba95990092c..5fe6466f5371 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -119,7 +119,6 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) var/shard_name = SHARD_SHRAPNEL as text // Path of debris object. var/shard_icon // Related to above. var/shard_can_repair = 1 // Can shards be turned into sheets with a welder? - var/list/recipes // Holder for all recipes usable with a sheet of this material. var/destruction_desc = "breaks apart" // Fancy string for barricades/tables/objects exploding. var/destruction_sound = "fracture" // As above, but the sound that plays. diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 50c1c1aae4f0..c36ff3e143b3 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -59,9 +59,6 @@ butchery_data = /decl/butchery_data/animal/cat base_animal_type = /mob/living/simple_animal/passive/cat ai = /datum/mob_controller/passive/hunter/cat - var/turns_since_scan = 0 - var/mob/living/simple_animal/passive/mouse/movement_target - var/mob/flee_target /mob/living/simple_animal/passive/cat/get_bodytype() return GET_DECL(/decl/bodytype/quadruped/animal/cat) diff --git a/code/modules/multiz/map_data.dm b/code/modules/multiz/map_data.dm index ea7f09545111..83d4f972daa2 100644 --- a/code/modules/multiz/map_data.dm +++ b/code/modules/multiz/map_data.dm @@ -4,7 +4,6 @@ icon_state = "map_data" var/height = 1 ///< The number of Z-Levels in the map. - var/turf/edge_type ///< What the map edge should be formed with. (null = world.turf) // If the height is more than 1, we mark all contained levels as connected. // This initializes immediately because it is an auxiliary effect specifically needed pre-SSatoms init. diff --git a/code/modules/organs/external/_external.dm b/code/modules/organs/external/_external.dm index d2ab14efc169..3f62d4a17485 100644 --- a/code/modules/organs/external/_external.dm +++ b/code/modules/organs/external/_external.dm @@ -49,7 +49,6 @@ var/list/children // Sub-limbs. var/list/internal_organs // Internal organs of this body part var/list/implants // Currently implanted objects. - var/base_miss_chance = 20 // Chance of missing. var/genetic_degradation = 0 // Amount of current genetic damage. //Forensics stuff diff --git a/code/modules/overmap/ftl_shunt/core.dm b/code/modules/overmap/ftl_shunt/core.dm index fe8407d230e7..ca95cf968b9b 100644 --- a/code/modules/overmap/ftl_shunt/core.dm +++ b/code/modules/overmap/ftl_shunt/core.dm @@ -17,7 +17,6 @@ var/shunt_x = 1 var/shunt_y = 1 var/chargepercent = 0 - var/last_percent_tick = 0 var/obj/machinery/computer/ship/ftl/ftl_computer var/required_fuel_joules var/required_charge //This is a function of the required fuel joules. diff --git a/code/modules/overmap/internet/internet_uplink.dm b/code/modules/overmap/internet/internet_uplink.dm index 53e7e4eb923b..8c32bc016983 100644 --- a/code/modules/overmap/internet/internet_uplink.dm +++ b/code/modules/overmap/internet/internet_uplink.dm @@ -164,7 +164,6 @@ var/global/list/internet_uplinks = list() idle_power_usage = 250 active_power_usage = 500 var/initial_id_tag = "plexus" - var/current_uplink = 1 /obj/machinery/computer/internet_uplink/Initialize() . = ..() diff --git a/code/modules/overmap/ships/computers/comms.dm b/code/modules/overmap/ships/computers/comms.dm index 6789f5bc68d0..3978b1a4c58f 100644 --- a/code/modules/overmap/ships/computers/comms.dm +++ b/code/modules/overmap/ships/computers/comms.dm @@ -109,7 +109,6 @@ req_access = list(access_tcomsat) icon = 'icons/obj/machines/tcomms/comms.dmi' var/effective_range = 1 // TODO: upgrade with components. - var/enabled = TRUE /obj/machinery/shipcomms/proc/toggle() if((stat & BROKEN) || use_power != POWER_USE_OFF) diff --git a/code/modules/prometheus_metrics/metrics.dm b/code/modules/prometheus_metrics/metrics.dm index ad98b6c178f9..7a5bca9be93a 100644 --- a/code/modules/prometheus_metrics/metrics.dm +++ b/code/modules/prometheus_metrics/metrics.dm @@ -1,8 +1,5 @@ // prometheus_metrics holds a list of metric_family datums and uses them to // create a json protobuf. -/decl/prometheus_metrics - var/list/metric_families - /decl/prometheus_metrics/proc/collect() var/list/out = list() diff --git a/code/modules/scent/_scent.dm b/code/modules/scent/_scent.dm index b002b8a43c63..68a96e3aa0b8 100644 --- a/code/modules/scent/_scent.dm +++ b/code/modules/scent/_scent.dm @@ -1,7 +1,3 @@ -var/global/const/SCENT_DESC_ODOR = "odour" -var/global/const/SCENT_DESC_SMELL = "smell" -var/global/const/SCENT_DESC_FRAGRANCE = "fragrance" - /***** Scent intensity *****/ diff --git a/code/modules/status_conditions/_status_condition.dm b/code/modules/status_conditions/_status_condition.dm index 285748a63b88..a377bed14b3d 100644 --- a/code/modules/status_conditions/_status_condition.dm +++ b/code/modules/status_conditions/_status_condition.dm @@ -7,9 +7,6 @@ var/global/list/status_marker_holders = list() var/check_flags = 0 var/list/victim_data - var/hud_icon - var/hud_state - var/decl/mob_modifier/associated_mob_modifier var/status_marker_icon = 'icons/effects/status.dmi' From 17031fa81a368cda2d07d1d6c2c788d62e04bc43 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:26:35 -0400 Subject: [PATCH 409/512] Remove entirely-unused procs --- .../preference_setup/loadout/loadout.dm | 3 -- code/modules/mob/living/human/human_organs.dm | 11 ----- .../modular_computers/networking/_network.dm | 5 -- code/modules/organs/external/standard.dm | 3 -- code/modules/organs/internal/lungs.dm | 6 --- .../overmap/ships/computers/shuttle.dm | 5 -- code/modules/power/sensors/powernet_sensor.dm | 49 ------------------- .../particle_accelerator/particle_emitter.dm | 7 --- .../random_map/dungeon/winding_dungeon.dm | 4 -- .../reagents/chems/random/chems_random.dm | 7 --- code/modules/reagents/reactions/_reaction.dm | 3 -- .../modules/security_levels/security_state.dm | 7 --- 12 files changed, 110 deletions(-) diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 0e6fe8ed2887..d29b21ba850e 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -571,9 +571,6 @@ else to_chat(wearer, SPAN_DANGER("Dropping \the [item] on the ground!")) -/decl/loadout_option/proc/can_replace_existing(obj/item/candidate) - return istype(candidate, path) - /decl/loadout_option/proc/spawn_and_validate_item(mob/living/human/H, metadata) PRIVATE_PROC(TRUE) diff --git a/code/modules/mob/living/human/human_organs.dm b/code/modules/mob/living/human/human_organs.dm index 85c54cca6b24..a9dd1c86d45f 100644 --- a/code/modules/mob/living/human/human_organs.dm +++ b/code/modules/mob/living/human/human_organs.dm @@ -205,17 +205,6 @@ if (wound.infection_check()) wound.germ_level += 1 -/mob/living/human/proc/Check_Proppable_Object() - for(var/turf/T as anything in RANGE_TURFS(src, 1)) //we only care for non-space turfs - if(T.density && T.simulated) //walls work - return 1 - - for(var/obj/O in orange(1, src)) - if(O && O.density && O.anchored) - return 1 - - return 0 - /mob/living/human/on_lost_organ(var/obj/item/organ/O) if(!(. = ..())) return diff --git a/code/modules/modular_computers/networking/_network.dm b/code/modules/modular_computers/networking/_network.dm index 73adef3ab7d6..7ba3db6b0112 100644 --- a/code/modules/modular_computers/networking/_network.dm +++ b/code/modules/modular_computers/networking/_network.dm @@ -137,11 +137,6 @@ add_device(D) add_log("New main router set.", router.network_tag) -/datum/computer_network/proc/set_access_controller(datum/extension/network_device/D) - access_controller = D - devices |= D - add_log("New main access controller set.", D.network_tag) - // Returns list(signal type, signal strength) on success, null on failure. /datum/computer_network/proc/check_connection(datum/extension/network_device/D, specific_action) if(!router) diff --git a/code/modules/organs/external/standard.dm b/code/modules/organs/external/standard.dm index 84cb21e75a31..85c880a0a84c 100644 --- a/code/modules/organs/external/standard.dm +++ b/code/modules/organs/external/standard.dm @@ -20,9 +20,6 @@ cavity_name = "thoracic cavity" limb_flags = ORGAN_FLAG_HEALS_OVERKILL | ORGAN_FLAG_CAN_BREAK -/obj/item/organ/external/chest/proc/get_current_skin() - return - /obj/item/organ/external/chest/die() //Special handling for synthetics if(BP_IS_PROSTHETIC(src) || BP_IS_CRYSTAL(src)) diff --git a/code/modules/organs/internal/lungs.dm b/code/modules/organs/internal/lungs.dm index 6fdca0adbeb1..003f7b851d15 100644 --- a/code/modules/organs/internal/lungs.dm +++ b/code/modules/organs/internal/lungs.dm @@ -63,12 +63,6 @@ . = ..() sync_breath_types() -// This call needs to be split out to make sure that all the ingested things are metabolised -// before the process call is made on any of the other organs -/obj/item/organ/internal/lungs/proc/metabolize() - if(is_usable()) - inhaled.metabolize() - /** * Set these lungs' breath types based on the lungs' species */ diff --git a/code/modules/overmap/ships/computers/shuttle.dm b/code/modules/overmap/ships/computers/shuttle.dm index 6543aebddfc0..4f2e43fbe4cf 100644 --- a/code/modules/overmap/ships/computers/shuttle.dm +++ b/code/modules/overmap/ships/computers/shuttle.dm @@ -130,11 +130,6 @@ qdel(lz) to_chat(user, SPAN_WARNING("Invalid landing zone!")) -/obj/machinery/computer/shuttle_control/proc/end_landing() - var/datum/extension/eye/landing_eye = get_extension(src, /datum/extension/eye/) - if(landing_eye) - landing_eye.unlook() - /obj/machinery/computer/shuttle_control/explore/power_change() . = ..() if(. && (stat & (NOPOWER|BROKEN))) diff --git a/code/modules/power/sensors/powernet_sensor.dm b/code/modules/power/sensors/powernet_sensor.dm index 6a0134664cd3..66e5cee66f83 100644 --- a/code/modules/power/sensors/powernet_sensor.dm +++ b/code/modules/power/sensors/powernet_sensor.dm @@ -88,55 +88,6 @@ return L - -// Proc: return_reading_text() -// Parameters: None -// Description: Generates string which contains HTML table with reading data. -/obj/machinery/power/sensor/proc/return_reading_text() - // No powernet. Try to connect to one first. - if(!powernet) - connect_to_network() - var/out = "" - if(!powernet) // No powernet. - out = "# SYSTEM ERROR - NO POWERNET #" - return out - - - var/list/L = find_apcs() - var/total_apc_load = 0 - if(L.len <= 0) // No APCs found. - out = "No APCs located in connected powernet!" - else // APCs found. Create very ugly (but working!) HTML table. - - out += "
    NameEQUIPLIGHTENVIRONCELLLOAD" - - // These lists are used as replacement for number based APC settings - var/list/S = list("M-OFF","A-OFF","M-ON", "A-ON") - var/list/chg = list("N","C","F") - - // Split to multiple lines to make it more readable - for(var/obj/machinery/power/apc/A in L) - out += "
    \The [A.area]" // Add area name - out += "[S[A.equipment+1]][S[A.lighting+1]][S[A.environ+1]]" // Show status of channels - var/obj/item/cell/cell = A.get_cell() - if(cell) - out += "[round(cell.percent())]% - [chg[A.charging+1]]" - else - out += "NO CELL" - var/load = A.lastused_total // Load. - total_apc_load += load - load = reading_to_text(load) - out += "[load]" - - out += "
    TOTAL AVAILABLE: [reading_to_text(powernet.avail)]" - out += "
    APC LOAD: [reading_to_text(total_apc_load)]" - out += "
    OTHER LOAD: [reading_to_text(max(powernet.load - total_apc_load, 0))]" - out += "
    TOTAL GRID LOAD: [reading_to_text(powernet.viewload)] ([round((powernet.load / powernet.avail) * 100)]%)" - - if(powernet.problem) - out += "
    WARNING: Abnormal grid activity detected!" - return out - // Proc: return_reading_data() // Parameters: None // Description: Generates list containing all powernet data. Optimised for usage with NanoUI diff --git a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm index eba322bb19fb..7cfffcf5a8f1 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_emitter.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_emitter.dm @@ -20,13 +20,6 @@ icon_state = "emitter_right" reference = "emitter_right" -/obj/structure/particle_accelerator/particle_emitter/proc/set_delay(var/delay) - if(delay && delay >= 0) - src.fire_delay = delay - return 1 - return 0 - - /obj/structure/particle_accelerator/particle_emitter/proc/emit_particle(var/strength = 0) if((src.last_shot + src.fire_delay) <= world.time) src.last_shot = world.time diff --git a/code/modules/random_map/dungeon/winding_dungeon.dm b/code/modules/random_map/dungeon/winding_dungeon.dm index 1369aca46e92..1ecf9649028e 100644 --- a/code/modules/random_map/dungeon/winding_dungeon.dm +++ b/code/modules/random_map/dungeon/winding_dungeon.dm @@ -313,10 +313,6 @@ rooms += R return 1 -/datum/random_map/winding_dungeon/proc/add_loot(var/xorigin,var/yorigin,var/zorigin,var/type) - var/datum/room/room = pick(rooms) - return room.add_loot(type) - /datum/random_map/winding_dungeon/get_appropriate_path(var/value) switch(value) if(WALL_CHAR) diff --git a/code/modules/reagents/chems/random/chems_random.dm b/code/modules/reagents/chems/random/chems_random.dm index a38b74bc572c..a7418e164642 100644 --- a/code/modules/reagents/chems/random/chems_random.dm +++ b/code/modules/reagents/chems/random/chems_random.dm @@ -62,19 +62,12 @@ var/global/list/random_chem_interaction_blacklist = list( data_initialized = TRUE -/decl/material/liquid/random/proc/stable_at_temperature(temperature) - if(temperature > chilling_point && temperature < heating_point) - return TRUE - /decl/material/liquid/random/affect_blood(var/mob/living/M, var/removed, var/datum/reagents/holder) . = ..() FOR_ALL_EFFECTS var/data = REAGENT_DATA(holder, src) effect.affect_blood(M, removed, LAZYACCESS(data, effect.type)) -/decl/material/liquid/random/proc/on_chemicals_analyze(mob/user) - to_chat(user, get_scan_data(user)) - /decl/material/liquid/random/proc/get_scan_data(mob/user) var/list/dat = list() var/chem_skill = user.get_skill_value(SKILL_CHEMISTRY) diff --git a/code/modules/reagents/reactions/_reaction.dm b/code/modules/reagents/reactions/_reaction.dm index fbc2eaa85d68..3a4b41044b5c 100644 --- a/code/modules/reagents/reactions/_reaction.dm +++ b/code/modules/reagents/reactions/_reaction.dm @@ -49,9 +49,6 @@ for(var/reagent in required_reagents) . += reagent -/decl/chemical_reaction/proc/get_alternate_reaction_indicator(var/datum/reagents/holder) - return 0 - /decl/chemical_reaction/proc/process(var/datum/reagents/holder, var/limit) var/data = send_data(holder) diff --git a/code/modules/security_levels/security_state.dm b/code/modules/security_levels/security_state.dm index 2e997845d411..73945c3c1358 100644 --- a/code/modules/security_levels/security_state.dm +++ b/code/modules/security_levels/security_state.dm @@ -127,10 +127,3 @@ log_and_message_admins("has changed the security level from [previous_security_level.name] to [new_security_level.name].") return TRUE - -// This proc decreases the current security level, if possible -/decl/security_state/proc/decrease_security_level(var/force_change = FALSE) - var/current_index = all_security_levels.Find(current_security_level) - if(current_index == 1) - return FALSE - return set_security_level(all_security_levels[current_index - 1], force_change) From 5b4d00919cc863de7938e3f3e256e9e2103b2289 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Sun, 15 Jun 2025 01:05:29 +0000 Subject: [PATCH 410/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ tools/mapcapturemerge/README.md | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index 928bd534bf95..f606e802e6ca 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -57,12 +57,6 @@

    Zandario updated:

    • Added a "Toggle Browser Inspect" debug verb for debugging UIs
    - -

    13 April 2025

    -

    Cerebulon updated:

    -
      -
    • Fixed tajaran sprite sheet overrides.
    • -
    diff --git a/tools/mapcapturemerge/README.md b/tools/mapcapturemerge/README.md index 5606211b2e65..15f398267edf 100644 --- a/tools/mapcapturemerge/README.md +++ b/tools/mapcapturemerge/README.md @@ -1,11 +1,11 @@ -Map capture merge tool manual -====== - -1. Capture desired Z levels using in game verb `Capture-map` -2. Before closing game window, go to cache folder usually located under Documents/BYOND and copy all map capture files named like `map_capture_x1_y33_z1_r32.png` to folder under this tool called `captures`. -3. Install *Python* and *Pillow* library (If you don't have them already). -4. Run `python merge.py` and wait for captures to be merged. -5. After execution you will find all z-level merged maps in the mapcapturemerge tool folder. - -Notes: +Map capture merge tool manual +====== + +1. Capture desired Z levels using in game verb `Capture-map` +2. Before closing game window, go to cache folder usually located under Documents/BYOND and copy all map capture files named like `map_capture_x1_y33_z1_r32.png` to folder under this tool called `captures`. +3. Install *Python* and *Pillow* library (If you don't have them already). +4. Run `python merge.py` and wait for captures to be merged. +5. After execution you will find all z-level merged maps in the mapcapturemerge tool folder. + +Notes: * This tool been tested with Python 2.7.6 under Windows 10 Bash. \ No newline at end of file From 7939f8c6fa4bc106b9abb6773a808c10cebc6b67 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:25:18 -0400 Subject: [PATCH 411/512] Improve computer scanner and printer behavior --- .../programs/engineering/network_monitoring.dm | 9 +++++---- .../file_system/programs/generic/email_client.dm | 6 +++--- .../file_system/programs/generic/file_manager.dm | 2 +- .../file_system/programs/generic/scanner.dm | 1 + .../programs/research/email_administration.dm | 2 +- .../modular_computers/hardware/scanners/scanner_paper.dm | 2 +- .../modular_computers/networking/emails/_email.dm | 1 + .../modular_computers/networking/network_files.dm | 1 + code/modules/modular_computers/os/components.dm | 4 ++-- 9 files changed, 16 insertions(+), 12 deletions(-) diff --git a/code/modules/modular_computers/file_system/programs/engineering/network_monitoring.dm b/code/modules/modular_computers/file_system/programs/engineering/network_monitoring.dm index 0b111c2306ae..779fc79ec5af 100644 --- a/code/modules/modular_computers/file_system/programs/engineering/network_monitoring.dm +++ b/code/modules/modular_computers/file_system/programs/engineering/network_monitoring.dm @@ -57,9 +57,10 @@ mainframes.Add(list(rdata)) data["mainframes"] = mainframes - if(length(network.get_mainframes_by_role(MF_ROLE_LOG_SERVER, user.GetAccess()))) + var/list/eligible_log_servers = network.get_mainframes_by_role(MF_ROLE_LOG_SERVER, user.GetAccess()) + if(length(eligible_log_servers)) var/list/logs[0] - for(var/datum/extension/network_device/mainframe/M in network.get_mainframes_by_role(MF_ROLE_LOG_SERVER, user)) + for(var/datum/extension/network_device/mainframe/M in eligible_log_servers) var/list/logdata[0] var/datum/computer_file/data/logfile/F = M.get_file("network_log", OS_LOGS_DIR, TRUE) if(F) @@ -143,9 +144,9 @@ if(href_list["toggle_function"]) var/feature = text2num(href_list["toggle_function"]) if(network.network_features_enabled & feature) - network.network_features_enabled &= ~feature + network.disable_network_feature(feature) else - network.network_features_enabled |= feature + network.enable_network_feature(feature) return TOPIC_REFRESH if(href_list["ban_nid"]) diff --git a/code/modules/modular_computers/file_system/programs/generic/email_client.dm b/code/modules/modular_computers/file_system/programs/generic/email_client.dm index 61536217f86a..9bfa457e8487 100644 --- a/code/modules/modular_computers/file_system/programs/generic/email_client.dm +++ b/code/modules/modular_computers/file_system/programs/generic/email_client.dm @@ -80,7 +80,7 @@ var/list/msg = list() msg += "*--*\n" msg += "New mail received from [received_message.source]:\n" - msg += "Subject: [received_message.title]\nMessage:\n[digitalPencode2html(received_message.stored_data)]\n" + msg += "Subject: [received_message.title]\nMessage:\n[received_message.generate_file_data()]\n" if(received_message.attachment) msg += "Attachment: [received_message.attachment.filename].[received_message.attachment.filetype] ([received_message.attachment.size]GQ)\n" msg += "Reply\n" @@ -158,7 +158,7 @@ data["msg_attachment_size"] = msg_attachment.size else if (current_message) data["cur_title"] = current_message.title - data["cur_body"] = digitalPencode2html(current_message.stored_data) + data["cur_body"] = current_message.generate_file_data() data["cur_timestamp"] = current_message.timestamp data["cur_source"] = current_message.source data["cur_uid"] = current_message.uid @@ -187,7 +187,7 @@ for(var/datum/computer_file/data/email_message/message in message_source) all_messages.Add(list(list( "title" = message.title, - "body" = digitalPencode2html(message.stored_data), + "body" = message.generate_file_data(), "source" = message.source, "timestamp" = message.timestamp, "uid" = message.uid diff --git a/code/modules/modular_computers/file_system/programs/generic/file_manager.dm b/code/modules/modular_computers/file_system/programs/generic/file_manager.dm index be3f39c066ca..546aa102bf43 100644 --- a/code/modules/modular_computers/file_system/programs/generic/file_manager.dm +++ b/code/modules/modular_computers/file_system/programs/generic/file_manager.dm @@ -375,7 +375,7 @@ if(!(F.get_file_perms(accesses, user) & OS_READ_ACCESS)) file_error = "You do not have read access to this file." return - if(!computer.print_paper(digitalPencode2html(F.stored_data), F.filename)) + if(!computer.print_paper(F.generate_file_data(), F.filename, F.papertype, F.metadata)) file_error = "Hardware error: Unable to print the file." return TOPIC_REFRESH diff --git a/code/modules/modular_computers/file_system/programs/generic/scanner.dm b/code/modules/modular_computers/file_system/programs/generic/scanner.dm index ff721374a1cc..1e04b68050c7 100644 --- a/code/modules/modular_computers/file_system/programs/generic/scanner.dm +++ b/code/modules/modular_computers/file_system/programs/generic/scanner.dm @@ -78,6 +78,7 @@ var/datum/computer_file/data/scan_file = new scan_file_type() scan_file.stored_data = data_buffer + scan_file.metadata = metadata_buffer // This saves the file, so no additional handling on the program's end is required. view_file_browser(usr, "saving_file", scan_file_type, OS_WRITE_ACCESS, "Save scan file", scan_file) diff --git a/code/modules/modular_computers/file_system/programs/research/email_administration.dm b/code/modules/modular_computers/file_system/programs/research/email_administration.dm index 95d2a9410005..ea3ebbe44109 100644 --- a/code/modules/modular_computers/file_system/programs/research/email_administration.dm +++ b/code/modules/modular_computers/file_system/programs/research/email_administration.dm @@ -39,7 +39,7 @@ data["error"] = error else if(istype(current_message)) data["msg_title"] = current_message.title - data["msg_body"] = digitalPencode2html(current_message.stored_data) + data["msg_body"] = current_message.generate_file_data() data["msg_timestamp"] = current_message.timestamp data["msg_source"] = current_message.source else if(istype(current_account)) diff --git a/code/modules/modular_computers/hardware/scanners/scanner_paper.dm b/code/modules/modular_computers/hardware/scanners/scanner_paper.dm index a0d0c430ab1f..e5843c442212 100644 --- a/code/modules/modular_computers/hardware/scanners/scanner_paper.dm +++ b/code/modules/modular_computers/hardware/scanners/scanner_paper.dm @@ -27,7 +27,7 @@ driver.scan_file_type = target.scan_file_type if(target.type == /obj/item/paper/bodyscan) - driver.data_buffer = display_medical_data(target.metadata.Copy(),user.get_skill_value(SKILL_MEDICAL), TRUE) + driver.data_buffer = display_medical_data(driver.metadata_buffer,user.get_skill_value(SKILL_MEDICAL), TRUE) else driver.data_buffer = data diff --git a/code/modules/modular_computers/networking/emails/_email.dm b/code/modules/modular_computers/networking/emails/_email.dm index e522a1dcbd76..7b36c9fb7b9a 100644 --- a/code/modules/modular_computers/networking/emails/_email.dm +++ b/code/modules/modular_computers/networking/emails/_email.dm @@ -28,6 +28,7 @@ var/datum/computer_file/data/email_message/received_copy = received.Clone() received_copy.set_timestamp() recipient.inbox.Add(received_copy) + recipient.receive_mail(received_copy, src) for(var/weakref/os_ref in recipient.logged_in_os) var/datum/extension/interactive/os/os = os_ref.resolve() diff --git a/code/modules/modular_computers/networking/network_files.dm b/code/modules/modular_computers/networking/network_files.dm index 34229d711e23..ece73f53cbaa 100644 --- a/code/modules/modular_computers/networking/network_files.dm +++ b/code/modules/modular_computers/networking/network_files.dm @@ -90,6 +90,7 @@ continue // We only check if user is provided. If no user is provided, it's assumed to be an admin check. . |= M.network_tag +/// Returns the first (order is arbitrarily decided) fileserver with a given mainframe role. /datum/computer_network/proc/get_file_server_by_role(role, list/accesses) if(length(get_mainframes_by_role(role, accesses)) > 0) return get_mainframes_by_role(role, accesses)[1] diff --git a/code/modules/modular_computers/os/components.dm b/code/modules/modular_computers/os/components.dm index 5a50bd135e16..c3ea4c0134d7 100644 --- a/code/modules/modular_computers/os/components.dm +++ b/code/modules/modular_computers/os/components.dm @@ -14,10 +14,10 @@ /datum/extension/interactive/os/proc/has_component(var/part_type) return !!get_component(part_type) -/datum/extension/interactive/os/proc/print_paper(content, title) +/datum/extension/interactive/os/proc/print_paper(content, title, paper_type, list/metadata) var/obj/item/stock_parts/computer/nano_printer/printer = get_component(PART_PRINTER) if(printer) - return printer.print_text(content, title) + return printer.print_text(content, title, paper_type, metadata) /datum/extension/interactive/os/proc/get_network_tag() var/obj/item/stock_parts/computer/network_card/network_card = get_component(PART_NETWORK) From 909e9ce566cac064cf30abfd2678e5867faa97bd Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:29:21 -0400 Subject: [PATCH 412/512] Implement unused vars in paperwork code --- code/modules/paperwork/paper_sticky.dm | 26 +++++++++++++------------- code/modules/paperwork/photography.dm | 20 ++++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/code/modules/paperwork/paper_sticky.dm b/code/modules/paperwork/paper_sticky.dm index 05e989afe20f..d8acfabf7598 100644 --- a/code/modules/paperwork/paper_sticky.dm +++ b/code/modules/paperwork/paper_sticky.dm @@ -2,18 +2,18 @@ // Sticky Note Pad //////////////////////////////////////////////// /obj/item/sticky_pad - name = "sticky note pad" - desc = "A pad of densely packed sticky notes." - color = COLOR_YELLOW - icon = 'icons/obj/stickynotes.dmi' - icon_state = "pad_full" - item_state = "paper" - w_class = ITEM_SIZE_SMALL - material = /decl/material/solid/organic/paper - var/papers = 50 - var/tmp/max_papers = 50 - var/paper_type = /obj/item/paper/sticky - var/obj/item/paper/top //The instantiated paper on the top of the pad, if there's one + name = "sticky note pad" + desc = "A pad of densely packed sticky notes." + color = COLOR_YELLOW + icon = 'icons/obj/stickynotes.dmi' + icon_state = "pad_full" + item_state = "paper" + w_class = ITEM_SIZE_SMALL + material = /decl/material/solid/organic/paper + var/const/max_papers = 50 + var/papers = max_papers + var/paper_type = /obj/item/paper/sticky + var/obj/item/paper/top //The instantiated paper on the top of the pad, if there's one /obj/item/sticky_pad/Initialize(ml, material_key) . = ..() @@ -35,7 +35,7 @@ . = ..() if(papers <= 15) icon_state = "pad_empty" - else if(papers <= 50) + else if(papers <= max_papers) icon_state = "pad_used" else icon_state = "pad_full" diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index c23a21c46fb9..51778e1f5e05 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -10,16 +10,16 @@ * film * *******/ /obj/item/camera_film - name = "film cartridge" - icon = 'icons/obj/photography.dmi' - desc = "A camera film cartridge. Insert it into a camera to reload it." - icon_state = "film" - item_state = "electropack" - w_class = ITEM_SIZE_SMALL - throw_range = 10 - material = /decl/material/solid/organic/plastic - var/tmp/max_uses = 10 - var/uses_left = 10 + name = "film cartridge" + icon = 'icons/obj/photography.dmi' + desc = "A camera film cartridge. Insert it into a camera to reload it." + icon_state = "film" + item_state = "electropack" + w_class = ITEM_SIZE_SMALL + throw_range = 10 + material = /decl/material/solid/organic/plastic + var/const/max_uses = 10 + var/uses_left = max_uses /obj/item/camera_film/Initialize(ml, material_key) set_extension(src, /datum/extension/base_icon_state, icon_state) From 1e66a43682119602eb012546908bea78069fe331 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:29:51 -0400 Subject: [PATCH 413/512] Clean unused fax machine code --- code/modules/paperwork/faxmachine.dm | 38 ---------------------------- 1 file changed, 38 deletions(-) diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm index cabe90556973..fd66d7857a94 100644 --- a/code/modules/paperwork/faxmachine.dm +++ b/code/modules/paperwork/faxmachine.dm @@ -37,18 +37,6 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to has_commands = TRUE long_range = TRUE -//////////////////////////////////////////////////////////////////////////////////////// -// Fax Machine Quick-Dial file -//////////////////////////////////////////////////////////////////////////////////////// -/datum/computer_file/data/fax_quick_dial - filetype = "FQD" - -/datum/computer_file/data/fax_quick_dial/proc/save_quick_dial(var/list/quick_dial_list) - stored_data = json_encode(quick_dial_list) - -/datum/computer_file/data/fax_quick_dial/proc/load_quick_dial() - return json_decode(stored_data) - //////////////////////////////////////////////////////////////////////////////////////// // Fax Machine //////////////////////////////////////////////////////////////////////////////////////// @@ -184,8 +172,6 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to LAZYSET(., "has_disk_drive", !isnull(disk_reader)) LAZYSET(., "disk", D) LAZYSET(., "disk_name", D?.name) - LAZYSET(., "disk_has_qd", D?.contains_file_type("FQD")) //If the disk has a quick dial file - LAZYSET(., "disk_has_file", (D?.free_blocks < D?.block_capacity)) /obj/machinery/faxmachine/ui_interact(mob/user, ui_key, datum/nanoui/ui, force_open, datum/nanoui/master_ui, datum/topic_state/state) var/list/data = ui_data(user, ui_key) @@ -556,30 +542,6 @@ var/global/list/adminfaxes = list() //cache for faxes that have been sent to SSnano.update_uis(src) update_icon() -/**Check if the card we inserted has enough credentials to print on the target fax machine on the network. */ -/obj/machinery/faxmachine/proc/can_send_fax_to(var/network_tag, var/network_id, var/list/provided_access) - var/datum/extension/network_device/fax/sender = get_extension(src, /datum/extension/network_device) - var/datum/computer_network/sender_net = sender?.get_network() - if(!sender_net) - return FALSE - if((network_id != sender_net.network_id) && !sender.has_internet_connection(network_id)) - return FALSE - - //Handle fake admin network addresses - var/target_uri = uppertext("[network_tag].[network_id]") - if(target_uri in global.using_map.map_admin_faxes) - var/list/admin_faxes = LAZYACCESS(global.using_map.map_admin_faxes, target_uri) - var/list/required_access = LAZYACCESS(admin_faxes, "access") - return has_access(required_access, provided_access) //With access we can send faxes to the selected admin address - - var/datum/computer_network/target_net - if(network_id != sender_net.network_id) - target_net = sender_net?.get_internet_connection(network_id) - else - target_net = sender_net - var/datum/extension/network_device/fax/target = target_net?.get_device_by_tag(network_tag) - return istype(target) && target.has_access(provided_access) - /**Plays print animation async. */ /obj/machinery/faxmachine/proc/on_printed_page() flick("faxreceive", src) From 7c36b36882e695e577bb6de4129b0906bfad5ab8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 24 Mar 2025 05:31:02 -0400 Subject: [PATCH 414/512] Clean up and improve photocopier code --- code/modules/paperwork/photocopier.dm | 17 +++++++++++------ nano/templates/photocopier.tmpl | 3 ++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index b0fbf90ee7a9..369418bb480e 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -40,8 +40,6 @@ var/obj/item/scanner_item //what's in the scanner var/obj/item/stock_parts/printer/printer //What handles the printing queue var/tmp/max_copies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier! - var/tmp/busy = FALSE //Whether we should allow people to mess with the settings and contents - var/accept_refill = FALSE //Whether we should handle attackby paper to be sent to the paper bin, or to the scanner slot var/total_printing = 0 //The total number of pages we are printing in the current run /obj/machinery/photocopier/Initialize(mapload, d=0, populate_parts = TRUE) @@ -79,7 +77,7 @@ //Warning lights if(scanner_item) add_overlay("photocopier_ready") - if(!printer?.has_enough_to_print()) + if(!has_enough_to_print()) add_overlay("photocopier_bad") /obj/machinery/photocopier/proc/update_ui() @@ -107,7 +105,7 @@ else required_toner = TONER_USAGE_PAPER - if(!printer?.has_enough_to_print(required_toner, required_paper * copy_amount)) + if(!has_enough_to_print(required_toner, required_paper * copy_amount)) buzz("Warning: Not enough paper or toner!") return FALSE @@ -197,10 +195,14 @@ queue_copies(sanitize_integer(text2num(href_list["copy_amount"]), 1, max_copies, 1)) return TOPIC_REFRESH + if(href_list["cancel_queue"]) + stop_processing_queue() + return TOPIC_REFRESH + if(href_list["aipic"]) if(!issilicon(user)) return TOPIC_NOACTION - if(printer?.has_enough_to_print(TONER_USAGE_PHOTO)) + if(has_enough_to_print(TONER_USAGE_PHOTO)) var/mob/living/silicon/tempAI = user var/obj/item/camera/siliconcam/camera = tempAI.silicon_camera if(!camera) @@ -244,10 +246,13 @@ return TRUE /obj/machinery/photocopier/attackby(obj/item/used_item, mob/user) + if(printer.is_printing()) + to_chat(user, SPAN_WARNING("\The [src] is busy!")) + return TRUE if(istype(construct_state, /decl/machine_construction/default/panel_closed) && (istype(used_item, /obj/item/paper) || istype(used_item, /obj/item/photo) || istype(used_item, /obj/item/paper_bundle))) insert_item(used_item, user) return TRUE - return..() //Components attackby will handle refilling with paper and toner + return ..() //Components attackby will handle refilling with paper and toner /**Creates a clone of the specified item. Returns a list of cloned items. */ /obj/machinery/photocopier/proc/scan_item(var/obj/item/I) diff --git a/nano/templates/photocopier.tmpl b/nano/templates/photocopier.tmpl index 83a0434252ea..d76458b93026 100644 --- a/nano/templates/photocopier.tmpl +++ b/nano/templates/photocopier.tmpl @@ -10,7 +10,7 @@
    -
    +
    0) && (copies_left < copies_max))? copies_left : copies_max}} {{:copies_left == 0? 'disabled' : ''}} /> @@ -36,6 +36,7 @@ {{else}}
    Printing Page
    {{:data.left_printing}} out of {{:data.total_printing}} page(s)
    +
    {{:helper.link('Cancel', 'abort', {'cancel_queue': 1})}}
    {{/if}}
    {{ } }} From 882238d1c1df28281839971f328915e67b3b269b Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Mon, 16 Jun 2025 01:01:43 +0000 Subject: [PATCH 415/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index f606e802e6ca..2aecab0a3e31 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -51,12 +51,6 @@ -->
    - -

    14 April 2025

    -

    Zandario updated:

    -
      -
    • Added a "Toggle Browser Inspect" debug verb for debugging UIs
    • -
    From b00e16fce7b7513fc4518756402ff70bbc609ba6 Mon Sep 17 00:00:00 2001 From: ike709 Date: Fri, 20 Jun 2025 10:33:27 -0500 Subject: [PATCH 416/512] Rename BYOND 516 var conflicts --- code/datums/traits/_traits.dm | 14 +++++------ code/game/antagonist/antagonist_panel.dm | 10 ++++---- code/game/jobs/job/_job.dm | 32 ++++++++++++------------ code/game/turfs/floors/_floor.dm | 4 +-- code/game/turfs/turf_footsteps.dm | 14 +++++------ code/modules/goals/_goal.dm | 6 ++--- code/modules/goals/goal_mind.dm | 4 +-- 7 files changed, 42 insertions(+), 42 deletions(-) diff --git a/code/datums/traits/_traits.dm b/code/datums/traits/_traits.dm index bd1cbbf26364..909caf8d3a45 100644 --- a/code/datums/traits/_traits.dm +++ b/code/datums/traits/_traits.dm @@ -194,10 +194,10 @@ return (istype(holder)) // Called by preferences selection for HTML display. -/decl/trait/proc/get_trait_selection_data(var/datum/category_item/player_setup_item/traits/caller, var/list/ticked_traits = list(), var/recurse_level = 0, var/ignore_children_if_unticked = 1, var/ignore_unticked) +/decl/trait/proc/get_trait_selection_data(var/datum/category_item/player_setup_item/traits/trait_caller, var/list/ticked_traits = list(), var/recurse_level = 0, var/ignore_children_if_unticked = 1, var/ignore_unticked) var/ticked = (type in ticked_traits) - if((ignore_unticked && !ticked) || (caller && !is_available_to_select(caller.pref))) + if((ignore_unticked && !ticked) || (trait_caller && !is_available_to_select(trait_caller.pref))) return "" var/result = "" @@ -211,10 +211,10 @@ incompatible_trait_taken = TRUE break - var/chargen_name = get_chargen_name(caller.pref) - var/chargen_desc = get_chargen_desc(caller.pref) - if(istype(caller) && (ticked || caller.get_trait_total() + trait_cost <= get_config_value(/decl/config/num/max_character_traits)) && !incompatible_trait_taken) - result += "[ticked ? "[chargen_name]" : "[chargen_name]"] ([trait_cost])" + var/chargen_name = get_chargen_name(trait_caller.pref) + var/chargen_desc = get_chargen_desc(trait_caller.pref) + if(istype(trait_caller) && (ticked || trait_caller.get_trait_total() + trait_cost <= get_config_value(/decl/config/num/max_character_traits)) && !incompatible_trait_taken) + result += "[ticked ? "[chargen_name]" : "[chargen_name]"] ([trait_cost])" else result += ticked ? "[chargen_name]" : "[chargen_name]" @@ -227,7 +227,7 @@ result += "" if(LAZYLEN(children) && !(ignore_children_if_unticked && !ticked)) for(var/decl/trait/trait in children) - result += trait.get_trait_selection_data(caller, ticked_traits, (recurse_level+1), ignore_children_if_unticked) + result += trait.get_trait_selection_data(trait_caller, ticked_traits, (recurse_level+1), ignore_children_if_unticked) return result /// Shows `show_to` a browser window describing the character setup traits taken by `src`. diff --git a/code/game/antagonist/antagonist_panel.dm b/code/game/antagonist/antagonist_panel.dm index f16e898af98a..959d0d3b0b55 100644 --- a/code/game/antagonist/antagonist_panel.dm +++ b/code/game/antagonist/antagonist_panel.dm @@ -17,7 +17,7 @@ /decl/special_role/proc/get_extra_panel_options() return -/decl/special_role/proc/get_check_antag_output(var/datum/admins/caller) +/decl/special_role/proc/get_check_antag_output(var/datum/admins/caller_admin) if(!current_antagonists || !current_antagonists.len) return "" @@ -33,7 +33,7 @@ if(M.stat == DEAD) dat += " (DEAD)" dat += "" - dat += "\[PM\]\[SR\]" + dat += "\[PM\]\[SR\]" else dat += "Mob not found/([player.key])!" dat += "" @@ -47,17 +47,17 @@ while(!isturf(disk_loc)) if(ismob(disk_loc)) var/mob/M = disk_loc - dat += "carried by [M.real_name] " + dat += "carried by [M.real_name] " if(istype(disk_loc, /obj)) var/obj/O = disk_loc dat += "in \a [O.name] " disk_loc = disk_loc.loc dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])" dat += "" - dat += get_additional_check_antag_output(caller) + dat += get_additional_check_antag_output(caller_admin) dat += "
    " return dat //Overridden elsewhere. -/decl/special_role/proc/get_additional_check_antag_output(var/datum/admins/caller) +/decl/special_role/proc/get_additional_check_antag_output(var/datum/admins/caller_admin) return "" diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index 2dcadfe65666..eb27bd7793e3 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -255,9 +255,9 @@ return FALSE -/datum/job/proc/get_join_link(var/client/caller, var/href_string, var/show_invalid_jobs) - if(is_available(caller)) - if(is_restricted(caller.prefs)) +/datum/job/proc/get_join_link(var/client/calling_client, var/href_string, var/show_invalid_jobs) + if(is_available(calling_client)) + if(is_restricted(calling_client.prefs)) if(show_invalid_jobs) return "[title]
    [current_positions]
    Active: [get_active_count()]
    " else @@ -397,27 +397,27 @@ SSjobs.job_icons[title] = preview_icon return SSjobs.job_icons[title] -/datum/job/proc/get_unavailable_reasons(var/client/caller) +/datum/job/proc/get_unavailable_reasons(var/client/calling_client) var/list/reasons = list() - if(jobban_isbanned(caller, title)) + if(jobban_isbanned(calling_client, title)) reasons["You are jobbanned."] = TRUE - if(is_semi_antagonist && jobban_isbanned(caller, /decl/special_role/provocateur)) + if(is_semi_antagonist && jobban_isbanned(calling_client, /decl/special_role/provocateur)) reasons["You are semi-antagonist banned."] = TRUE - if(!player_old_enough(caller)) + if(!player_old_enough(calling_client)) reasons["Your player age is too low."] = TRUE if(!is_position_available()) reasons["There are no positions left."] = TRUE - if(!isnull(allowed_branches) && (!caller.prefs.branches[title] || !is_branch_allowed(caller.prefs.branches[title]))) + if(!isnull(allowed_branches) && (!calling_client.prefs.branches[title] || !is_branch_allowed(calling_client.prefs.branches[title]))) reasons["Your branch of service does not allow it."] = TRUE - else if(!isnull(allowed_ranks) && (!caller.prefs.ranks[title] || !is_rank_allowed(caller.prefs.branches[title], caller.prefs.ranks[title]))) + else if(!isnull(allowed_ranks) && (!calling_client.prefs.ranks[title] || !is_rank_allowed(calling_client.prefs.branches[title], calling_client.prefs.ranks[title]))) reasons["Your rank choice does not allow it."] = TRUE - var/decl/species/S = caller.prefs.get_species_decl() + var/decl/species/S = calling_client.prefs.get_species_decl() if(S) if(!is_species_allowed(S)) reasons["Your species choice does not allow it."] = TRUE - if(!S.check_background(src, caller.prefs)) + if(!S.check_background(src, calling_client.prefs)) reasons["Your background choices do not allow it."] = TRUE - var/special_blocker = check_special_blockers(caller.prefs) + var/special_blocker = check_special_blockers(calling_client.prefs) if(special_blocker) reasons["Your preferences do not allow it: '[special_blocker]'."] = TRUE return TRUE @@ -429,14 +429,14 @@ mannequin.delete_inventory(TRUE) equip_preview(mannequin, additional_skips = OUTFIT_ADJUSTMENT_SKIP_BACKPACK) -/datum/job/proc/is_available(var/client/caller) +/datum/job/proc/is_available(var/client/calling_client) if(!is_position_available()) return FALSE - if(jobban_isbanned(caller, title)) + if(jobban_isbanned(calling_client, title)) return FALSE - if(is_semi_antagonist && jobban_isbanned(caller, /decl/special_role/provocateur)) + if(is_semi_antagonist && jobban_isbanned(calling_client, /decl/special_role/provocateur)) return FALSE - if(!player_old_enough(caller)) + if(!player_old_enough(calling_client)) return FALSE return TRUE diff --git a/code/game/turfs/floors/_floor.dm b/code/game/turfs/floors/_floor.dm index d92467b7e3ef..f8a8f1af0b05 100644 --- a/code/game/turfs/floors/_floor.dm +++ b/code/game/turfs/floors/_floor.dm @@ -113,10 +113,10 @@ else physically_destroyed() -/turf/floor/get_footstep_sound(var/mob/caller) +/turf/floor/get_footstep_sound(var/mob/caller_mob) var/decl/flooring/use_flooring = get_topmost_flooring() if(istype(use_flooring)) - return get_footstep_for_mob(use_flooring.footstep_type, caller) + return get_footstep_for_mob(use_flooring.footstep_type, caller_mob) return ..() /turf/floor/get_movable_alpha_mask_state(atom/movable/mover) diff --git a/code/game/turfs/turf_footsteps.dm b/code/game/turfs/turf_footsteps.dm index afa6623a4985..aefe1b1456ee 100644 --- a/code/game/turfs/turf_footsteps.dm +++ b/code/game/turfs/turf_footsteps.dm @@ -1,15 +1,15 @@ -/proc/get_footstep_for_mob(var/footstep_type, var/mob/living/caller) - . = istype(caller) && caller.get_mob_footstep(footstep_type) +/proc/get_footstep_for_mob(var/footstep_type, var/mob/living/caller_mob) + . = istype(caller_mob) && caller_mob.get_mob_footstep(footstep_type) if(!.) var/decl/footsteps/footsteps = GET_DECL(footstep_type) . = pick(footsteps.footstep_sounds) -/turf/proc/get_footstep_sound(var/mob/caller) +/turf/proc/get_footstep_sound(var/mob/caller_mob) for(var/obj/structure/S in contents) if(S.footstep_type) - return get_footstep_for_mob(S.footstep_type, caller) + return get_footstep_for_mob(S.footstep_type, caller_mob) if(check_fluid_depth(10) && !is_flooded(TRUE)) - return get_footstep_for_mob(/decl/footsteps/water, caller) + return get_footstep_for_mob(/decl/footsteps/water, caller_mob) if(footstep_type) - return get_footstep_for_mob(footstep_type, caller) - return get_footstep_for_mob(/decl/footsteps/blank, caller) + return get_footstep_for_mob(footstep_type, caller_mob) + return get_footstep_for_mob(/decl/footsteps/blank, caller_mob) diff --git a/code/modules/goals/_goal.dm b/code/modules/goals/_goal.dm index b36b7b50a406..6a5906e1b5f4 100644 --- a/code/modules/goals/_goal.dm +++ b/code/modules/goals/_goal.dm @@ -23,13 +23,13 @@ owner = null . = ..() -/datum/goal/proc/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller ,var/position = 1) +/datum/goal/proc/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller_mob ,var/position = 1) . = "[description][get_summary_value()]" if(show_success) . += get_success_string() if(allow_modification) - if(can_abandon) . += " (Abandon)" - if(can_reroll) . += " (Reroll)" + if(can_abandon) . += " (Abandon)" + if(can_reroll) . += " (Reroll)" /datum/goal/proc/get_success_string() return check_success() ? " Success!" : " Failure." diff --git a/code/modules/goals/goal_mind.dm b/code/modules/goals/goal_mind.dm index debd412f1f57..b0c74498f259 100644 --- a/code/modules/goals/goal_mind.dm +++ b/code/modules/goals/goal_mind.dm @@ -8,12 +8,12 @@ if(LAZYLEN(goals)) to_chat(current, SPAN_NOTICE("

    You had the following personal goals this round:
    [jointext(summarize_goals(TRUE), "
    ")]")) -/datum/mind/proc/summarize_goals(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller) +/datum/mind/proc/summarize_goals(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller_mob) . = list() if(LAZYLEN(goals)) for(var/i = 1 to LAZYLEN(goals)) var/datum/goal/goal = goals[i] - . += "[i]. [goal.summarize(show_success, allow_modification, caller, position = i)]" + . += "[i]. [goal.summarize(show_success, allow_modification, caller_mob, position = i)]" // Create and display personal goals for this round. /datum/mind/proc/generate_goals(var/datum/job/job, var/adding_goals = FALSE, var/add_amount, var/is_spawning = FALSE) From ea0d96dd92179cfb8ea577265e177811e7d5cb76 Mon Sep 17 00:00:00 2001 From: Amy <3855802+amylizzle@users.noreply.github.com> Date: Wed, 25 Jun 2025 11:32:26 +0100 Subject: [PATCH 417/512] Update goal_ambition.dm --- code/modules/goals/goal_ambition.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/goals/goal_ambition.dm b/code/modules/goals/goal_ambition.dm index 2029bc5cf23f..352bc29e6b0f 100644 --- a/code/modules/goals/goal_ambition.dm +++ b/code/modules/goals/goal_ambition.dm @@ -13,5 +13,5 @@ /datum/goal/ambition/get_success_string() return "" -/datum/goal/ambition/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller ,var/position = 1) +/datum/goal/ambition/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller_mob ,var/position = 1) . = SPAN_DANGER(..(show_success)) From fb5992050daea8d6ee844b66cdf2f8c5e32f3dcc Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 3 Jul 2025 11:05:54 +1000 Subject: [PATCH 418/512] Adding byond executable mirror to build scripts. --- install-byond.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install-byond.sh b/install-byond.sh index ae0a74438954..5d60db277127 100755 --- a/install-byond.sh +++ b/install-byond.sh @@ -8,7 +8,8 @@ else mkdir -p "$HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}" cd "$HOME/BYOND-${BYOND_MAJOR}.${BYOND_MINOR}" echo "Installing DreamMaker to $PWD" - curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -H "User-Agent: NebulaSS13/1.0 Continuous Integration" -o byond.zip + #curl "http://www.byond.com/download/build/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -H "User-Agent: NebulaSS13/1.0 Continuous Integration" -o byond.zip + curl "https://spacestation13.github.io/byond-builds/${BYOND_MAJOR}/${BYOND_MAJOR}.${BYOND_MINOR}_byond_linux.zip" -H "User-Agent: NebulaSS13/1.0 Continuous Integration" -o byond.zip unzip -o byond.zip cd byond make here From 087323918aaee7b64572143517aa5001e86445c5 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 3 Jul 2025 12:03:02 +1000 Subject: [PATCH 419/512] Bumping BYOND minor version. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c15d7d641a0f..a190750c4803 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ on: env: BYOND_MAJOR: "515" - BYOND_MINOR: "1633" + BYOND_MINOR: "1647" SPACEMAN_DMM_VERSION: suite-1.8 jobs: From 1a6fcd59a5d72e1881b9e52f953c0014a4a5b8ee Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Tue, 1 Jul 2025 10:29:12 +1000 Subject: [PATCH 420/512] Fixes blue hairflower. --- code/modules/clothing/head/misc.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm index cc431faf6bdc..d4dfbe616575 100644 --- a/code/modules/clothing/head/misc.dm +++ b/code/modules/clothing/head/misc.dm @@ -14,7 +14,7 @@ flags_inv = 0 /obj/item/clothing/head/hairflower/blue - icon = 'icons/clothing/head/hairflower/pink.dmi' + icon = 'icons/clothing/head/hairflower/blue.dmi' /obj/item/clothing/head/hairflower/pink icon = 'icons/clothing/head/hairflower/pink.dmi' /obj/item/clothing/head/hairflower/yellow From 9b44b44853a9855e279edf71c30e690c6086da86 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Tue, 8 Jul 2025 05:58:54 -0400 Subject: [PATCH 421/512] Split preferences.copy_to across many, many procs --- .../preference_setup/background/01_species.dm | 3 + .../background/02_background.dm | 7 + .../background/03_language.dm | 6 + .../preference_setup/general/01_basic.dm | 19 +++ .../preference_setup/general/02_body.dm | 51 +++++++ .../preference_setup/general/03_traits.dm | 5 + .../preference_setup/general/04_equipment.dm | 16 +++ .../preference_setup/general/05_flavor.dm | 5 + .../preference_setup/preference_setup.dm | 48 +++++++ code/modules/client/preferences.dm | 131 +++++------------- code/modules/mob/mob_snapshot.dm | 17 ++- code/modules/mob/new_player/new_player.dm | 14 +- code/modules/sprite_accessories/_accessory.dm | 3 + .../tails/_accessory_tail.dm | 8 ++ mods/content/psionics/_psionics.dm | 5 +- 15 files changed, 229 insertions(+), 109 deletions(-) diff --git a/code/modules/client/preference_setup/background/01_species.dm b/code/modules/client/preference_setup/background/01_species.dm index 05fa8159196d..68992453f584 100644 --- a/code/modules/client/preference_setup/background/01_species.dm +++ b/code/modules/client/preference_setup/background/01_species.dm @@ -6,6 +6,9 @@ sort_order = 1 var/hide_species = TRUE +/datum/category_item/player_setup_item/background/species/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) + snapshot.root_species = pref.get_species_decl() + // This must always return a decl, NEVER null. /datum/preferences/proc/get_species_decl() RETURN_TYPE(/decl/species) diff --git a/code/modules/client/preference_setup/background/02_background.dm b/code/modules/client/preference_setup/background/02_background.dm index f1093e1eaa3d..6b8a0a162856 100644 --- a/code/modules/client/preference_setup/background/02_background.dm +++ b/code/modules/client/preference_setup/background/02_background.dm @@ -25,6 +25,13 @@ hidden[cat_type] = TRUE ..() +/datum/category_item/player_setup_item/background/details/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + if(is_preview_copy) + return + for(var/token in pref.background_info) + character.set_background_value(token, pref.background_info[token], defer_language_update = TRUE) + character.update_languages() + /datum/category_item/player_setup_item/background/details/sanitize_character() if(!islist(pref.background_info)) diff --git a/code/modules/client/preference_setup/background/03_language.dm b/code/modules/client/preference_setup/background/03_language.dm index 490b4bb5bfa3..b9a43ea24941 100644 --- a/code/modules/client/preference_setup/background/03_language.dm +++ b/code/modules/client/preference_setup/background/03_language.dm @@ -7,6 +7,12 @@ var/list/allowed_languages var/list/free_languages +/datum/category_item/player_setup_item/background/languages/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + if(is_preview_copy) + return + for(var/lang in pref.alternate_languages) + character.add_language(lang) + /datum/category_item/player_setup_item/background/languages/load_character(datum/pref_record_reader/R) pref.alternate_languages = list() var/list/language_names = R.read("language") diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 96a439422849..018b2ad3edde 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -18,6 +18,9 @@ name = "Basic" sort_order = 1 +/datum/category_item/player_setup_item/physical/basic/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + character.set_gender(pref.gender) + /datum/category_item/player_setup_item/physical/basic/preload_character(datum/pref_record_reader/R) pref.gender = R.read("gender") pref.bodytype = R.read("bodytype") @@ -67,6 +70,22 @@ bodytype = S.get_bodytype_by_pronouns(pronouns) pref.set_bodytype(bodytype.name) +/datum/category_item/player_setup_item/physical/basic/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) + snapshot.root_bodytype = pref.get_bodytype_decl() + var/new_real_name = pref.real_name + if(pref.be_random_name) + var/decl/background_detail/background = pref.get_background_datum_by_flag(BACKGROUND_FLAG_NAMING) + if(background) + new_real_name = background.get_random_name(pref.gender) + if(get_config_value(/decl/config/toggle/humans_need_surnames)) + var/firstspace = findtext(new_real_name, " ") + var/name_length = length(new_real_name) + if(!firstspace) //we need a surname + new_real_name += " [pick(global.using_map.last_names)]" + else if(firstspace == name_length) // someone tried to cheese it by putting a space at the end + new_real_name += "[pick(global.using_map.last_names)]" + snapshot.real_name = new_real_name + /datum/category_item/player_setup_item/physical/basic/content() . = list() diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index 65dcf28fbc78..b7dcde9470ec 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -14,6 +14,57 @@ name = "Body" sort_order = 2 +// apply sprite accessories to an existing mob +// actually this might not be necessary because we apply the snapshot +/* /datum/category_item/player_setup_item/physical/body/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) + for(var/obj/item/organ/external/O in character.get_external_organs()) + for(var/decl/sprite_accessory_category/sprite_category in O.get_sprite_accessory_categories()) + if(!sprite_category.clear_in_pref_apply) + continue + O.clear_sprite_accessories_by_category(sprite_category.type, skip_update = TRUE) + for(var/accessory_category in pref.sprite_accessories) + var/decl/sprite_accessory_category/acc_cat = GET_DECL(accessory_category) + var/list/accessories = pref.sprite_accessories[accessory_category] + acc_cat.prepare_character(character, accessories) + for(var/accessory in accessories) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + var/accessory_metadata = accessories[accessory] + for(var/bodypart in accessory_decl.body_parts) + var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(character, bodypart) + if(O) + O.set_sprite_accessory(accessory, accessory_category, accessory_metadata, skip_update = TRUE) */ + +/datum/category_item/player_setup_item/physical/body/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) + snapshot.blood_type = pref.blood_type + // we don't check appearance_flags here, apply_appearance_to does that + snapshot.skin_color = pref.skin_colour + snapshot.skin_tone = pref.skin_tone + snapshot.eye_color = pref.eye_colour + // so this is the hellish part. + // pref.sprite_accessories is sprite_accessories[accessory_category.type][loaded_accessory.type] = metadata + // snapshot.sprite_accessories is sprite_accessories[organ_tag][accessory_category.type][loaded_accessory.type] = metadata + // we have to convert it here + var/list/new_sprite_accessories = list() + for(var/accessory_category in pref.sprite_accessories) + var/decl/sprite_accessory_category/acc_cat = GET_DECL(accessory_category) + var/list/accessories = pref.sprite_accessories[accessory_category] + acc_cat.prepare_mob_snapshot(snapshot, accessories) + // todo: copy this elsewhere + // ^ i have no clue if i ever did this or not. presumably bc i don't know what i meant needed copying + for(var/accessory in accessories) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + var/accessory_metadata = accessories[accessory] + for(var/bodypart in accessory_decl.body_parts) + LAZYINITLIST(new_sprite_accessories[bodypart]) + LAZYSET(new_sprite_accessories[bodypart][accessory_category], accessory, accessory_metadata) + if(length(new_sprite_accessories)) + snapshot.sprite_accessories = new_sprite_accessories + +// this should probably be named copy_to_after_physical, lol +/datum/category_item/player_setup_item/physical/body/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + if(LAZYLEN(pref.appearance_descriptors)) + character.appearance_descriptors = pref.appearance_descriptors.Copy() + /datum/category_item/player_setup_item/physical/body/load_character(datum/pref_record_reader/R) pref.skin_colour = R.read("skin_colour") diff --git a/code/modules/client/preference_setup/general/03_traits.dm b/code/modules/client/preference_setup/general/03_traits.dm index d5120bff0a00..dd1f90dd6cf4 100644 --- a/code/modules/client/preference_setup/general/03_traits.dm +++ b/code/modules/client/preference_setup/general/03_traits.dm @@ -39,6 +39,11 @@ else pref.prune_invalid_traits() +/datum/category_item/player_setup_item/traits/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + character.clear_extrinsic_traits() + for(var/trait_type in pref.traits) + character.set_trait(trait_type, (pref.traits[trait_type] || TRAIT_LEVEL_EXISTS)) + /datum/category_item/player_setup_item/traits/save_character(datum/pref_record_writer/writer) var/list/trait_ids = list() for(var/trait_type in pref.traits) diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index d1678ce103cf..b7da0a39937c 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -22,6 +22,22 @@ var/decl/backpack_outfit/backpack_outfit = bos[backpack_option] backpacks_by_name[backpack_outfit.name] = backpack_outfit +/datum/category_item/player_setup_item/physical/equipment/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + QDEL_NULL_LIST(character.worn_underwear) + character.worn_underwear = list() + for(var/underwear_category_name in pref.all_underwear) + var/datum/category_group/underwear/underwear_category = global.underwear.categories_by_name[underwear_category_name] + if(underwear_category) + var/underwear_item_name = pref.all_underwear[underwear_category_name] + var/datum/category_item/underwear/UWD = underwear_category.items_by_name[underwear_item_name] + var/metadata = pref.all_underwear_metadata[underwear_category_name] + var/obj/item/underwear/UW = UWD.create_underwear(character, metadata) + if(UW) + UW.ForceEquipUnderwear(character, FALSE) + else + pref.all_underwear -= underwear_category_name + character.backpack_setup = new(pref.backpack, pref.backpack_metadata["[pref.backpack]"]) + /datum/category_item/player_setup_item/physical/equipment/load_character(datum/pref_record_reader/R) pref.all_underwear = R.read("all_underwear") pref.all_underwear_metadata = R.read("all_underwear_metadata") diff --git a/code/modules/client/preference_setup/general/05_flavor.dm b/code/modules/client/preference_setup/general/05_flavor.dm index 27c6b79580eb..9d6d91c021d0 100644 --- a/code/modules/client/preference_setup/general/05_flavor.dm +++ b/code/modules/client/preference_setup/general/05_flavor.dm @@ -6,6 +6,11 @@ name = "Flavor" sort_order = 5 +/datum/category_item/player_setup_item/physical/flavor/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + if(is_preview_copy) + return + character.flavor_texts = pref.flavor_texts.Copy() + /datum/category_item/player_setup_item/physical/flavor/load_character(datum/pref_record_reader/R) pref.flavor_texts["general"] = R.read("flavor_texts_general") pref.flavor_texts["head"] = R.read("flavor_texts_head") diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index 946628527a59..73c1ac2648c8 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -94,6 +94,19 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" for(var/datum/category_group/player_setup_category/PS in categories) PS.save_preferences(writer) +/datum/category_collection/player_setup_collection/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) + // Assumes a character has already been loaded. + for(var/datum/category_group/player_setup_category/PS in categories) + PS.copy_to_physical(character, is_preview_copy) + +/datum/category_collection/player_setup_collection/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + for(var/datum/category_group/player_setup_category/PS in categories) + PS.copy_to_nonphysical(character, is_preview_copy) + +/datum/category_collection/player_setup_collection/proc/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) + for(var/datum/category_group/player_setup_category/PG in categories) + PG.populate_mob_snapshot(snapshot, is_preview_copy) + /datum/category_collection/player_setup_collection/proc/header() var/dat = "" for(var/datum/category_group/player_setup_category/PS in categories) @@ -165,6 +178,19 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" for(var/datum/category_item/player_setup_item/PI in items) PI.save_preferences(writer) +/datum/category_group/player_setup_category/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) + // Assumes a character has already been loaded. + for(var/datum/category_item/player_setup_item/PI in items) + PI.copy_to_physical(character, is_preview_copy) + +/datum/category_group/player_setup_category/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + for(var/datum/category_item/player_setup_item/PI in items) + PI.copy_to_nonphysical(character, is_preview_copy) + +/datum/category_group/player_setup_category/proc/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) + for(var/datum/category_item/player_setup_item/PI in items) + PI.populate_mob_snapshot(snapshot, is_preview_copy) + /datum/category_group/player_setup_category/proc/content(var/mob/user) . = "" if(LAZYLEN(children) && !(ignore_children_if_unticked && !ticked)) for(var/decl/trait/trait in children) - result += trait.get_trait_selection_data(caller, ticked_traits, (recurse_level+1), ignore_children_if_unticked) + result += trait.get_trait_selection_data(calling_item, ticked_traits, (recurse_level+1), ignore_children_if_unticked) return result /mob/proc/get_trait_data(var/mob/show_to) diff --git a/code/game/antagonist/antagonist_panel.dm b/code/game/antagonist/antagonist_panel.dm index f16e898af98a..d34d47f6fe4d 100644 --- a/code/game/antagonist/antagonist_panel.dm +++ b/code/game/antagonist/antagonist_panel.dm @@ -17,7 +17,7 @@ /decl/special_role/proc/get_extra_panel_options() return -/decl/special_role/proc/get_check_antag_output(var/datum/admins/caller) +/decl/special_role/proc/get_check_antag_output(var/datum/admins/calling_admin) if(!current_antagonists || !current_antagonists.len) return "" @@ -33,7 +33,7 @@ if(M.stat == DEAD) dat += " (DEAD)" dat += "" - dat += "" + dat += "" else dat += "" dat += "" @@ -47,17 +47,17 @@ while(!isturf(disk_loc)) if(ismob(disk_loc)) var/mob/M = disk_loc - dat += "carried by [M.real_name] " + dat += "carried by [M.real_name] " if(istype(disk_loc, /obj)) var/obj/O = disk_loc dat += "in \a [O.name] " disk_loc = disk_loc.loc dat += "in [disk_loc.loc] at ([disk_loc.x], [disk_loc.y], [disk_loc.z])" dat += "
    " var/current = 0 @@ -230,6 +256,28 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" /datum/category_item/player_setup_item/proc/save_preferences(datum/pref_record_writer/writer) return +/* +* Called when actually populating a character based on character creation preferences +*/ +/datum/category_item/player_setup_item/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) + return // Note that the prefs-level call will apply anything already done in populate_mob_snapshot + +/datum/category_item/player_setup_item/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + return + +/* need overrides for: +- name (done) +- eye colour (done) +- blood type (done) +- skin colour/tone (done) +- species (done) +- bodytype (done) +- sprite accessories (done) +- maybe genetic conditions from traits? +*/ +/datum/category_item/player_setup_item/proc/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) + return + /datum/category_item/player_setup_item/proc/content() return diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 4d0e7a1b37bf..12c13f2fc8a9 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -346,92 +346,50 @@ var/global/list/time_prefs_fixed = list() update_setup_window(usr) return 1 -/datum/preferences/proc/copy_to(mob/living/human/character, is_preview_copy = FALSE) - - if(!player_setup) - return // WHY IS THIS EVEN HAPPENING. +/datum/category_item/player_setup_item/records/character_info/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + if(is_preview_copy) + return + pref.validate_comments_record() // Make sure a record has been generated for this character. + character.comments_record_id = pref.comments_record_id - // Sanitizing rather than saving as someone might still be editing when copy_to occurs. +/datum/preferences/proc/create_character(spawn_turf) + // Sanitizing rather than saving as someone might still be editing. player_setup.sanitize_setup() - validate_comments_record() // Make sure a record has been generated for this character. - character.comments_record_id = comments_record_id - character.clear_extrinsic_traits() + // first, handle basic appearance stuff via mob_snapshot + var/datum/mob_snapshot/new_character_snapshot = new /datum/mob_snapshot + player_setup.populate_mob_snapshot(new_character_snapshot, FALSE) + var/mob/living/human/character = new(spawn_turf, null, new_character_snapshot) + copy_to_nonphysical(character, FALSE) + return character - var/decl/bodytype/new_bodytype = get_bodytype_decl() - var/decl/species/character_species = character.get_species() - if(species == character_species.uid) - character.set_bodytype(new_bodytype) - else - character.change_species(species, new_bodytype) - - if(be_random_name) - var/decl/background_detail/background = get_background_datum_by_flag(BACKGROUND_FLAG_NAMING) - if(background) - real_name = background.get_random_name(gender) - - if(get_config_value(/decl/config/toggle/humans_need_surnames)) - var/firstspace = findtext(real_name, " ") - var/name_length = length(real_name) - if(!firstspace) //we need a surname - real_name += " [pick(global.using_map.last_names)]" - else if(firstspace == name_length) - real_name += "[pick(global.using_map.last_names)]" - - character.fully_replace_character_name(real_name) - - character.set_gender(gender) - character.blood_type = blood_type - - character.set_skin_colour(skin_colour, skip_update = TRUE) - character.skin_tone = skin_tone - - QDEL_NULL_LIST(character.worn_underwear) - character.worn_underwear = list() - - for(var/underwear_category_name in all_underwear) - var/datum/category_group/underwear/underwear_category = global.underwear.categories_by_name[underwear_category_name] - if(underwear_category) - var/underwear_item_name = all_underwear[underwear_category_name] - var/datum/category_item/underwear/UWD = underwear_category.items_by_name[underwear_item_name] - var/metadata = all_underwear_metadata[underwear_category_name] - var/obj/item/underwear/UW = UWD.create_underwear(character, metadata) - if(UW) - UW.ForceEquipUnderwear(character, FALSE) - else - all_underwear -= underwear_category_name - character.backpack_setup = new(backpack, backpack_metadata["[backpack]"]) +/datum/preferences/proc/copy_to(mob/living/human/character, is_preview_copy = FALSE) + copy_to_physical(character, is_preview_copy) // this is effectively what create_character does, but on an existing mob + copy_to_nonphysical(character, is_preview_copy) // this is the stuff we need to share - if(length(traits)) - for(var/trait_type in traits) - character.set_trait(trait_type, (traits[trait_type] || TRAIT_LEVEL_EXISTS)) +/datum/preferences/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) + // Sanitizing rather than saving as someone might still be editing when copy_to occurs. + player_setup.sanitize_setup() + // todo: move this part into some sort of pre-copy sanitizing? move it into the trait stuff? check if it's even necessary? + // i guess this is for if we're using it to refresh an existing character from prefs via admin tools + character.clear_extrinsic_traits() + // first, handle basic appearance stuff via mob_snapshot + var/datum/mob_snapshot/new_character_snapshot = new /datum/mob_snapshot // we assume we want a full repopulation, so don't persist anything from the donor + player_setup.populate_mob_snapshot(new_character_snapshot, is_preview_copy) + new_character_snapshot.apply_appearance_to(character, do_update = FALSE) + // not sure why we have real_name on snapshot; it's only used in one spot in setup_human + character.set_real_name(new_character_snapshot.real_name) + // now actually load everything else + player_setup.copy_to_physical(character, is_preview_copy) + return character - character.set_eye_colour(eye_colour, skip_update = TRUE) +// this should honestly maybe be copy_to_after_physical +/datum/preferences/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) + player_setup.copy_to_nonphysical(character, is_preview_copy) - for(var/obj/item/organ/external/O in character.get_external_organs()) - for(var/decl/sprite_accessory_category/sprite_category in O.get_sprite_accessory_categories()) - if(!sprite_category.clear_in_pref_apply) - continue - O.clear_sprite_accessories_by_category(sprite_category.type, skip_update = TRUE) - - for(var/accessory_category in sprite_accessories) - var/decl/sprite_accessory_category/acc_cat = GET_DECL(accessory_category) - var/list/accessories = sprite_accessories[accessory_category] - acc_cat.prepare_character(character, accessories) - for(var/accessory in accessories) - var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) - var/accessory_metadata = accessories[accessory] - for(var/bodypart in accessory_decl.body_parts) - var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(character, bodypart) - if(O) - O.set_sprite_accessory(accessory, accessory_category, accessory_metadata, skip_update = TRUE) - - if(LAZYLEN(appearance_descriptors)) - character.appearance_descriptors = appearance_descriptors.Copy() - - character.force_update_limbs() + // this happens here because i didn't want to duplicate it between copy_to_physical and create_character + character.force_update_limbs() // contains update_body(0) character.update_genetic_conditions(0) - character.update_body(0) character.update_underwear(0) character.update_hair(0) character.update_icon() @@ -440,22 +398,7 @@ var/global/list/time_prefs_fixed = list() if(is_preview_copy) return - for(var/token in background_info) - character.set_background_value(token, background_info[token], defer_language_update = TRUE) - character.update_languages() - for(var/lang in alternate_languages) - character.add_language(lang) - - character.flavor_texts["general"] = flavor_texts["general"] - character.flavor_texts["head"] = flavor_texts["head"] - character.flavor_texts["face"] = flavor_texts["face"] - character.flavor_texts["eyes"] = flavor_texts["eyes"] - character.flavor_texts["torso"] = flavor_texts["torso"] - character.flavor_texts["arms"] = flavor_texts["arms"] - character.flavor_texts["hands"] = flavor_texts["hands"] - character.flavor_texts["legs"] = flavor_texts["legs"] - character.flavor_texts["feet"] = flavor_texts["feet"] - + // why is this in copy_to? jfc if(!character.isSynthetic()) character.set_nutrition(rand(140,360)) character.set_hydration(rand(140,360)) diff --git a/code/modules/mob/mob_snapshot.dm b/code/modules/mob/mob_snapshot.dm index 40cf7f02306c..950dc9b2cce6 100644 --- a/code/modules/mob/mob_snapshot.dm +++ b/code/modules/mob/mob_snapshot.dm @@ -14,6 +14,8 @@ var/list/sprite_accessories var/list/genetic_conditions + /// Please find a better way to do this. This is done to add tails if we have the tail accessory selected... + var/list/extra_limbs /datum/mob_snapshot/New(mob/living/donor, genetic_info_only = FALSE) @@ -59,7 +61,7 @@ return clone // Replaces UpdateAppearance(). -/datum/mob_snapshot/proc/apply_appearance_to(mob/living/target) +/datum/mob_snapshot/proc/apply_appearance_to(mob/living/target, do_update = TRUE) if(istype(root_species) && root_species != target.get_species()) if(istype(root_bodytype)) @@ -75,15 +77,22 @@ target.set_eye_colour(eye_color) target.set_skin_tone(skin_tone) + for(var/limb_data in extra_limbs) + var/limb_path = extra_limbs[limb_data]["path"] + var/obj/item/organ/external/new_limb = new limb_path(null, null, src) + target.add_organ(new_limb, null, TRUE, FALSE, FALSE, TRUE) + extra_limbs = null // can't reuse it! + for(var/obj/item/organ/organ in target.get_organs()) organ.copy_from_mob_snapshot(src) for(var/decl/genetic_condition/condition as anything in genetic_conditions) target.add_genetic_condition(condition.type) - target.force_update_limbs() - target.update_hair(update_icons = FALSE) - target.update_eyes() + if(do_update) + target.force_update_limbs() + target.update_hair(update_icons = FALSE) + target.update_eyes() return TRUE /mob/proc/get_mob_snapshot(check_dna = FALSE) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 5eaca24a6515..3cbd1dfb8a2b 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -374,20 +374,16 @@ INITIALIZE_IMMEDIATE(/mob/new_player) if(!check_species_allowed(chosen_species)) spawning = 0 //abort return null - new_character = new(spawn_turf, chosen_species.uid) - - if(!new_character) - new_character = new(spawn_turf) - - new_character.lastarea = get_area(spawn_turf) - - if(global.random_players) + if(global.random_players) // apply randomness prior to creating the character var/decl/species/current_species = client.prefs.get_species_decl() var/decl/pronouns/pronouns = pick(current_species.available_pronouns) client.prefs.gender = pronouns.name client.prefs.real_name = client.prefs.get_random_name() client.prefs.randomize_appearance_and_body_for(new_character) - client.prefs.copy_to(new_character) + new_character = client.prefs.create_character(spawn_turf) + new_character.lastarea = get_area(spawn_turf) + + // client.prefs.copy_to(new_character) // not anymore lol sound_to(src, sound(null, repeat = 0, wait = 0, volume = 85, channel = sound_channels.lobby_channel))// MAD JAMS cant last forever yo diff --git a/code/modules/sprite_accessories/_accessory.dm b/code/modules/sprite_accessories/_accessory.dm index f7f9c46c2110..592a94274176 100644 --- a/code/modules/sprite_accessories/_accessory.dm +++ b/code/modules/sprite_accessories/_accessory.dm @@ -263,3 +263,6 @@ /decl/sprite_accessory_category/proc/prepare_character(mob/living/character, list/accessories) return +/decl/sprite_accessory_category/proc/prepare_mob_snapshot(datum/mob_snapshot/snapshot, list/accessories) + return + diff --git a/code/modules/sprite_accessories/tails/_accessory_tail.dm b/code/modules/sprite_accessories/tails/_accessory_tail.dm index bef3c6677821..311e416366e6 100644 --- a/code/modules/sprite_accessories/tails/_accessory_tail.dm +++ b/code/modules/sprite_accessories/tails/_accessory_tail.dm @@ -13,6 +13,14 @@ var/obj/item/organ/external/tail/new_tail = new(null, null, character.get_mob_snapshot()) character.add_organ(new_tail, null, TRUE, FALSE, FALSE, TRUE) +/decl/sprite_accessory_category/tail/prepare_mob_snapshot(datum/mob_snapshot/snapshot, list/accessories) + if(!length(accessories)) + return + // Give us a tail if we need one. + var/decl/sprite_accessory/tail_data = GET_DECL(accessories[1]) + if(tail_data?.draw_accessory && !snapshot.root_bodytype.has_limbs[BP_TAIL]) + LAZYSET(snapshot.extra_limbs, BP_TAIL, list("path" = /obj/item/organ/external/tail)) + /decl/sprite_accessory/tail abstract_type = /decl/sprite_accessory/tail hidden_by_gear_slot = list(slot_w_uniform_str, slot_wear_suit_str) diff --git a/mods/content/psionics/_psionics.dm b/mods/content/psionics/_psionics.dm index fa58ed18f582..d66ca8d8c025 100644 --- a/mods/content/psionics/_psionics.dm +++ b/mods/content/psionics/_psionics.dm @@ -25,11 +25,12 @@ . += "Only available for living mobs, sorry." . = jointext(., null) -/datum/preferences/copy_to(mob/living/human/character, is_preview_copy = FALSE) +// this probably shouldn't be necessary anymore now that we have refresh_login()? +/* /datum/preferences/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) character = ..() var/datum/ability_handler/psionics/psi = !is_preview_copy && istype(character) && character.get_ability_handler(/datum/ability_handler/psionics) if(psi) - psi.update() + psi.update() */ /decl/ability/can_use_ability(mob/user, list/metadata, silent = FALSE) . = ..() From 69177dd22e0c3e5a836346737132cead924d503f Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Fri, 11 Jul 2025 11:04:32 -0400 Subject: [PATCH 422/512] Rename preference apply procs --- .../background/02_background.dm | 2 +- .../background/03_language.dm | 2 +- .../preference_setup/general/01_basic.dm | 2 +- .../preference_setup/general/02_body.dm | 23 +------------------ .../preference_setup/general/03_traits.dm | 2 +- .../preference_setup/general/04_equipment.dm | 2 +- .../preference_setup/general/05_flavor.dm | 2 +- .../preference_setup/preference_setup.dm | 20 ++++++++-------- code/modules/client/preferences.dm | 21 ++++++++--------- code/modules/mob/new_player/new_player.dm | 2 +- mods/content/psionics/_psionics.dm | 7 ------ 11 files changed, 28 insertions(+), 57 deletions(-) diff --git a/code/modules/client/preference_setup/background/02_background.dm b/code/modules/client/preference_setup/background/02_background.dm index 6b8a0a162856..6ce982e37d81 100644 --- a/code/modules/client/preference_setup/background/02_background.dm +++ b/code/modules/client/preference_setup/background/02_background.dm @@ -25,7 +25,7 @@ hidden[cat_type] = TRUE ..() -/datum/category_item/player_setup_item/background/details/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/background/details/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) if(is_preview_copy) return for(var/token in pref.background_info) diff --git a/code/modules/client/preference_setup/background/03_language.dm b/code/modules/client/preference_setup/background/03_language.dm index b9a43ea24941..486d6bffd109 100644 --- a/code/modules/client/preference_setup/background/03_language.dm +++ b/code/modules/client/preference_setup/background/03_language.dm @@ -7,7 +7,7 @@ var/list/allowed_languages var/list/free_languages -/datum/category_item/player_setup_item/background/languages/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/background/languages/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) if(is_preview_copy) return for(var/lang in pref.alternate_languages) diff --git a/code/modules/client/preference_setup/general/01_basic.dm b/code/modules/client/preference_setup/general/01_basic.dm index 018b2ad3edde..83a11ec1a5d4 100644 --- a/code/modules/client/preference_setup/general/01_basic.dm +++ b/code/modules/client/preference_setup/general/01_basic.dm @@ -18,7 +18,7 @@ name = "Basic" sort_order = 1 -/datum/category_item/player_setup_item/physical/basic/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/physical/basic/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) character.set_gender(pref.gender) /datum/category_item/player_setup_item/physical/basic/preload_character(datum/pref_record_reader/R) diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index b7dcde9470ec..6f23e996d2ce 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -14,26 +14,6 @@ name = "Body" sort_order = 2 -// apply sprite accessories to an existing mob -// actually this might not be necessary because we apply the snapshot -/* /datum/category_item/player_setup_item/physical/body/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) - for(var/obj/item/organ/external/O in character.get_external_organs()) - for(var/decl/sprite_accessory_category/sprite_category in O.get_sprite_accessory_categories()) - if(!sprite_category.clear_in_pref_apply) - continue - O.clear_sprite_accessories_by_category(sprite_category.type, skip_update = TRUE) - for(var/accessory_category in pref.sprite_accessories) - var/decl/sprite_accessory_category/acc_cat = GET_DECL(accessory_category) - var/list/accessories = pref.sprite_accessories[accessory_category] - acc_cat.prepare_character(character, accessories) - for(var/accessory in accessories) - var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) - var/accessory_metadata = accessories[accessory] - for(var/bodypart in accessory_decl.body_parts) - var/obj/item/organ/external/O = GET_EXTERNAL_ORGAN(character, bodypart) - if(O) - O.set_sprite_accessory(accessory, accessory_category, accessory_metadata, skip_update = TRUE) */ - /datum/category_item/player_setup_item/physical/body/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) snapshot.blood_type = pref.blood_type // we don't check appearance_flags here, apply_appearance_to does that @@ -60,8 +40,7 @@ if(length(new_sprite_accessories)) snapshot.sprite_accessories = new_sprite_accessories -// this should probably be named copy_to_after_physical, lol -/datum/category_item/player_setup_item/physical/body/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/physical/body/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) if(LAZYLEN(pref.appearance_descriptors)) character.appearance_descriptors = pref.appearance_descriptors.Copy() diff --git a/code/modules/client/preference_setup/general/03_traits.dm b/code/modules/client/preference_setup/general/03_traits.dm index dd1f90dd6cf4..b61d8b02b201 100644 --- a/code/modules/client/preference_setup/general/03_traits.dm +++ b/code/modules/client/preference_setup/general/03_traits.dm @@ -39,7 +39,7 @@ else pref.prune_invalid_traits() -/datum/category_item/player_setup_item/traits/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/traits/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) character.clear_extrinsic_traits() for(var/trait_type in pref.traits) character.set_trait(trait_type, (pref.traits[trait_type] || TRAIT_LEVEL_EXISTS)) diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm index b7da0a39937c..437ec1c4cc46 100644 --- a/code/modules/client/preference_setup/general/04_equipment.dm +++ b/code/modules/client/preference_setup/general/04_equipment.dm @@ -22,7 +22,7 @@ var/decl/backpack_outfit/backpack_outfit = bos[backpack_option] backpacks_by_name[backpack_outfit.name] = backpack_outfit -/datum/category_item/player_setup_item/physical/equipment/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/physical/equipment/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) QDEL_NULL_LIST(character.worn_underwear) character.worn_underwear = list() for(var/underwear_category_name in pref.all_underwear) diff --git a/code/modules/client/preference_setup/general/05_flavor.dm b/code/modules/client/preference_setup/general/05_flavor.dm index 9d6d91c021d0..f10579925758 100644 --- a/code/modules/client/preference_setup/general/05_flavor.dm +++ b/code/modules/client/preference_setup/general/05_flavor.dm @@ -6,7 +6,7 @@ name = "Flavor" sort_order = 5 -/datum/category_item/player_setup_item/physical/flavor/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/physical/flavor/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) if(is_preview_copy) return character.flavor_texts = pref.flavor_texts.Copy() diff --git a/code/modules/client/preference_setup/preference_setup.dm b/code/modules/client/preference_setup/preference_setup.dm index 73c1ac2648c8..f6621d517a73 100644 --- a/code/modules/client/preference_setup/preference_setup.dm +++ b/code/modules/client/preference_setup/preference_setup.dm @@ -94,14 +94,14 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" for(var/datum/category_group/player_setup_category/PS in categories) PS.save_preferences(writer) -/datum/category_collection/player_setup_collection/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_collection/player_setup_collection/proc/apply_snapshot_to_mob(mob/living/human/character, is_preview_copy = FALSE) // Assumes a character has already been loaded. for(var/datum/category_group/player_setup_category/PS in categories) - PS.copy_to_physical(character, is_preview_copy) + PS.apply_snapshot_to_mob(character, is_preview_copy) -/datum/category_collection/player_setup_collection/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_collection/player_setup_collection/proc/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) for(var/datum/category_group/player_setup_category/PS in categories) - PS.copy_to_nonphysical(character, is_preview_copy) + PS.apply_post_snapshot_preferences(character, is_preview_copy) /datum/category_collection/player_setup_collection/proc/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) for(var/datum/category_group/player_setup_category/PG in categories) @@ -178,14 +178,14 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" for(var/datum/category_item/player_setup_item/PI in items) PI.save_preferences(writer) -/datum/category_group/player_setup_category/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_group/player_setup_category/proc/apply_snapshot_to_mob(mob/living/human/character, is_preview_copy = FALSE) // Assumes a character has already been loaded. for(var/datum/category_item/player_setup_item/PI in items) - PI.copy_to_physical(character, is_preview_copy) + PI.apply_snapshot_to_mob(character, is_preview_copy) -/datum/category_group/player_setup_category/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_group/player_setup_category/proc/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) for(var/datum/category_item/player_setup_item/PI in items) - PI.copy_to_nonphysical(character, is_preview_copy) + PI.apply_post_snapshot_preferences(character, is_preview_copy) /datum/category_group/player_setup_category/proc/populate_mob_snapshot(datum/mob_snapshot/snapshot, is_preview_copy = FALSE) for(var/datum/category_item/player_setup_item/PI in items) @@ -259,10 +259,10 @@ var/global/const/CHARACTER_PREFERENCE_INPUT_TITLE = "Character Preference" /* * Called when actually populating a character based on character creation preferences */ -/datum/category_item/player_setup_item/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/proc/apply_snapshot_to_mob(mob/living/human/character, is_preview_copy = FALSE) return // Note that the prefs-level call will apply anything already done in populate_mob_snapshot -/datum/category_item/player_setup_item/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/proc/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) return /* need overrides for: diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 12c13f2fc8a9..cdfe05e2c66c 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -346,28 +346,28 @@ var/global/list/time_prefs_fixed = list() update_setup_window(usr) return 1 -/datum/category_item/player_setup_item/records/character_info/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) +/datum/category_item/player_setup_item/records/character_info/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) if(is_preview_copy) return pref.validate_comments_record() // Make sure a record has been generated for this character. character.comments_record_id = pref.comments_record_id -/datum/preferences/proc/create_character(spawn_turf) +/datum/preferences/proc/create_character_from_snapshot(spawn_turf) // Sanitizing rather than saving as someone might still be editing. player_setup.sanitize_setup() // first, handle basic appearance stuff via mob_snapshot var/datum/mob_snapshot/new_character_snapshot = new /datum/mob_snapshot player_setup.populate_mob_snapshot(new_character_snapshot, FALSE) var/mob/living/human/character = new(spawn_turf, null, new_character_snapshot) - copy_to_nonphysical(character, FALSE) + apply_post_snapshot_preferences(character, FALSE) return character /datum/preferences/proc/copy_to(mob/living/human/character, is_preview_copy = FALSE) - copy_to_physical(character, is_preview_copy) // this is effectively what create_character does, but on an existing mob - copy_to_nonphysical(character, is_preview_copy) // this is the stuff we need to share + apply_snapshot_to_mob(character, is_preview_copy) // this is effectively what create_character_from_snapshot does, but on an existing mob + apply_post_snapshot_preferences(character, is_preview_copy) // this is the stuff we need to share -/datum/preferences/proc/copy_to_physical(mob/living/human/character, is_preview_copy = FALSE) +/datum/preferences/proc/apply_snapshot_to_mob(mob/living/human/character, is_preview_copy = FALSE) // Sanitizing rather than saving as someone might still be editing when copy_to occurs. player_setup.sanitize_setup() // todo: move this part into some sort of pre-copy sanitizing? move it into the trait stuff? check if it's even necessary? @@ -380,14 +380,13 @@ var/global/list/time_prefs_fixed = list() // not sure why we have real_name on snapshot; it's only used in one spot in setup_human character.set_real_name(new_character_snapshot.real_name) // now actually load everything else - player_setup.copy_to_physical(character, is_preview_copy) + player_setup.apply_snapshot_to_mob(character, is_preview_copy) return character -// this should honestly maybe be copy_to_after_physical -/datum/preferences/proc/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) - player_setup.copy_to_nonphysical(character, is_preview_copy) +/datum/preferences/proc/apply_post_snapshot_preferences(mob/living/human/character, is_preview_copy = FALSE) + player_setup.apply_post_snapshot_preferences(character, is_preview_copy) - // this happens here because i didn't want to duplicate it between copy_to_physical and create_character + // this happens here because i didn't want to duplicate it between apply_snapshot_to_mob and create_character_from_snapshot character.force_update_limbs() // contains update_body(0) character.update_genetic_conditions(0) character.update_underwear(0) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 3cbd1dfb8a2b..2a460c53a435 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -380,7 +380,7 @@ INITIALIZE_IMMEDIATE(/mob/new_player) client.prefs.gender = pronouns.name client.prefs.real_name = client.prefs.get_random_name() client.prefs.randomize_appearance_and_body_for(new_character) - new_character = client.prefs.create_character(spawn_turf) + new_character = client.prefs.create_character_from_snapshot(spawn_turf) new_character.lastarea = get_area(spawn_turf) // client.prefs.copy_to(new_character) // not anymore lol diff --git a/mods/content/psionics/_psionics.dm b/mods/content/psionics/_psionics.dm index d66ca8d8c025..aa9e711f7ca7 100644 --- a/mods/content/psionics/_psionics.dm +++ b/mods/content/psionics/_psionics.dm @@ -25,13 +25,6 @@ . += "Only available for living mobs, sorry." . = jointext(., null) -// this probably shouldn't be necessary anymore now that we have refresh_login()? -/* /datum/preferences/copy_to_nonphysical(mob/living/human/character, is_preview_copy = FALSE) - character = ..() - var/datum/ability_handler/psionics/psi = !is_preview_copy && istype(character) && character.get_ability_handler(/datum/ability_handler/psionics) - if(psi) - psi.update() */ - /decl/ability/can_use_ability(mob/user, list/metadata, silent = FALSE) . = ..() if(. && is_supernatural) From a1e923e6663f3092acb865f360be033ee662288c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 16 Jul 2025 02:22:37 -0400 Subject: [PATCH 423/512] Fix OpenDream reserved keyword errors --- code/controllers/hooks.dm | 4 +- code/datums/mind/mind.dm | 12 +++--- code/datums/traits/_traits.dm | 14 +++---- code/game/antagonist/antagonist_panel.dm | 10 ++--- code/game/jobs/job/_job.dm | 32 +++++++-------- code/game/turfs/floors/_floor.dm | 4 +- code/game/turfs/turf_footsteps.dm | 14 +++---- code/modules/character_info/_comment.dm | 8 ++-- code/modules/goals/_goal.dm | 6 +-- code/modules/goals/goal_ambition.dm | 2 +- code/modules/goals/goal_mind.dm | 4 +- code/modules/goals/goal_mob.dm | 2 +- code/modules/persistence/persistence_datum.dm | 4 +- .../persistence/persistence_datum_book.dm | 2 +- .../persistence/persistence_datum_graffiti.dm | 2 +- .../persistence/persistence_datum_paper.dm | 2 +- .../real_instruments.dm | 40 +++++++++---------- 17 files changed, 81 insertions(+), 81 deletions(-) diff --git a/code/controllers/hooks.dm b/code/controllers/hooks.dm index c38cd77d135d..8057b2a22e78 100644 --- a/code/controllers/hooks.dm +++ b/code/controllers/hooks.dm @@ -23,7 +23,7 @@ * @param hook Identifier of the hook to call. * @returns 1 if all hooked code runs successfully, 0 otherwise. */ -/proc/callHook(hook, list/args=null) +/proc/callHook(hook, list/hook_args=null) var/hook_path = text2path("/hook/[hook]") if(!hook_path) error("Invalid hook '/hook/[hook]' called.") @@ -32,7 +32,7 @@ var/hook_caller = new hook_path var/status = 1 for(var/P in typesof("[hook_path]/proc")) - if(!call(hook_caller, P)(arglist(args))) + if(!call(hook_caller, P)(arglist(hook_args))) error("Hook '[P]' failed or runtimed.") status = 0 diff --git a/code/datums/mind/mind.dm b/code/datums/mind/mind.dm index 22abeced6dd3..05ef003e6317 100644 --- a/code/datums/mind/mind.dm +++ b/code/datums/mind/mind.dm @@ -152,8 +152,8 @@ if(href_list["add_goal"]) - var/mob/goal_caller = locate(href_list["add_goal_caller"]) - if(goal_caller && goal_caller == current) can_modify = TRUE + var/mob/goal_user = locate(href_list["add_goal_user"]) + if(goal_user && goal_user == current) can_modify = TRUE if(can_modify) if(is_admin) @@ -171,8 +171,8 @@ if(href_list["abandon_goal"]) var/datum/goal/goal = get_goal_from_href(href_list["abandon_goal"]) - var/mob/goal_caller = locate(href_list["abandon_goal_caller"]) - if(goal_caller && goal_caller == current) can_modify = TRUE + var/mob/goal_user = locate(href_list["abandon_goal_user"]) + if(goal_user && goal_user == current) can_modify = TRUE if(goal && can_modify) if(usr == current) @@ -186,8 +186,8 @@ if(href_list["reroll_goal"]) var/datum/goal/goal = get_goal_from_href(href_list["reroll_goal"]) - var/mob/goal_caller = locate(href_list["reroll_goal_caller"]) - if(goal_caller && goal_caller == current) can_modify = TRUE + var/mob/goal_user = locate(href_list["reroll_goal_user"]) + if(goal_user && goal_user == current) can_modify = TRUE if(goal && (goal in goals) && can_modify) qdel(goal) diff --git a/code/datums/traits/_traits.dm b/code/datums/traits/_traits.dm index 6fbb9921ea13..f1e38824a5ce 100644 --- a/code/datums/traits/_traits.dm +++ b/code/datums/traits/_traits.dm @@ -202,10 +202,10 @@ return (istype(holder)) // Called by preferences selection for HTML display. -/decl/trait/proc/get_trait_selection_data(var/datum/category_item/player_setup_item/traits/caller, var/list/ticked_traits = list(), var/recurse_level = 0, var/ignore_children_if_unticked = 1, var/ignore_unticked) +/decl/trait/proc/get_trait_selection_data(var/datum/category_item/player_setup_item/traits/calling_item, var/list/ticked_traits = list(), var/recurse_level = 0, var/ignore_children_if_unticked = 1, var/ignore_unticked) var/ticked = (type in ticked_traits) - if((ignore_unticked && !ticked) || (caller && !is_available_to_select(caller.pref))) + if((ignore_unticked && !ticked) || (calling_item && !is_available_to_select(calling_item.pref))) return "" var/result = "
    " @@ -219,10 +219,10 @@ incompatible_trait_taken = TRUE break - var/chargen_name = get_chargen_name(caller.pref) - var/chargen_desc = get_chargen_desc(caller.pref) - if(istype(caller) && (ticked || caller.get_trait_total() + trait_cost <= get_config_value(/decl/config/num/max_character_traits)) && !incompatible_trait_taken) - result += "[ticked ? "[chargen_name]" : "[chargen_name]"] ([trait_cost])" + var/chargen_name = get_chargen_name(calling_item.pref) + var/chargen_desc = get_chargen_desc(calling_item.pref) + if(istype(calling_item) && (ticked || calling_item.get_trait_total() + trait_cost <= get_config_value(/decl/config/num/max_character_traits)) && !incompatible_trait_taken) + result += "[ticked ? "[chargen_name]" : "[chargen_name]"] ([trait_cost])" else result += ticked ? "[chargen_name]" : "[chargen_name]" @@ -235,7 +235,7 @@ result += "
    \[PM\]\[SR\]\[PM\]\[SR\]Mob not found/([player.key])!
    " - dat += get_additional_check_antag_output(caller) + dat += get_additional_check_antag_output(calling_admin) dat += "
    " return dat //Overridden elsewhere. -/decl/special_role/proc/get_additional_check_antag_output(var/datum/admins/caller) +/decl/special_role/proc/get_additional_check_antag_output(var/datum/admins/calling_admin) return "" diff --git a/code/game/jobs/job/_job.dm b/code/game/jobs/job/_job.dm index f5df1fe51970..a80edf5e05fb 100644 --- a/code/game/jobs/job/_job.dm +++ b/code/game/jobs/job/_job.dm @@ -252,9 +252,9 @@ return FALSE -/datum/job/proc/get_join_link(var/client/caller, var/href_string, var/show_invalid_jobs) - if(is_available(caller)) - if(is_restricted(caller.prefs)) +/datum/job/proc/get_join_link(var/client/calling_client, var/href_string, var/show_invalid_jobs) + if(is_available(calling_client)) + if(is_restricted(calling_client.prefs)) if(show_invalid_jobs) return "[title]
    [current_positions]
    Active: [get_active_count()]
    " else @@ -395,27 +395,27 @@ SSjobs.job_icons[title] = preview_icon return SSjobs.job_icons[title] -/datum/job/proc/get_unavailable_reasons(var/client/caller) +/datum/job/proc/get_unavailable_reasons(var/client/calling_client) var/list/reasons = list() - if(jobban_isbanned(caller, title)) + if(jobban_isbanned(calling_client, title)) reasons["You are jobbanned."] = TRUE - if(is_semi_antagonist && jobban_isbanned(caller, /decl/special_role/provocateur)) + if(is_semi_antagonist && jobban_isbanned(calling_client, /decl/special_role/provocateur)) reasons["You are semi-antagonist banned."] = TRUE - if(!player_old_enough(caller)) + if(!player_old_enough(calling_client)) reasons["Your player age is too low."] = TRUE if(!is_position_available()) reasons["There are no positions left."] = TRUE - if(!isnull(allowed_branches) && (!caller.prefs.branches[title] || !is_branch_allowed(caller.prefs.branches[title]))) + if(!isnull(allowed_branches) && (!calling_client.prefs.branches[title] || !is_branch_allowed(calling_client.prefs.branches[title]))) reasons["Your branch of service does not allow it."] = TRUE - else if(!isnull(allowed_ranks) && (!caller.prefs.ranks[title] || !is_rank_allowed(caller.prefs.branches[title], caller.prefs.ranks[title]))) + else if(!isnull(allowed_ranks) && (!calling_client.prefs.ranks[title] || !is_rank_allowed(calling_client.prefs.branches[title], calling_client.prefs.ranks[title]))) reasons["Your rank choice does not allow it."] = TRUE - var/decl/species/S = get_species_by_key(caller.prefs.species) + var/decl/species/S = get_species_by_key(calling_client.prefs.species) if(S) if(!is_species_allowed(S)) reasons["Your species choice does not allow it."] = TRUE - if(!S.check_background(src, caller.prefs)) + if(!S.check_background(src, calling_client.prefs)) reasons["Your background choices do not allow it."] = TRUE - var/special_blocker = check_special_blockers(caller.prefs) + var/special_blocker = check_special_blockers(calling_client.prefs) if(special_blocker) reasons["Your preferences do not allow it: '[special_blocker]'."] = TRUE return TRUE @@ -427,14 +427,14 @@ mannequin.delete_inventory(TRUE) equip_preview(mannequin, additional_skips = OUTFIT_ADJUSTMENT_SKIP_BACKPACK) -/datum/job/proc/is_available(var/client/caller) +/datum/job/proc/is_available(var/client/calling_client) if(!is_position_available()) return FALSE - if(jobban_isbanned(caller, title)) + if(jobban_isbanned(calling_client, title)) return FALSE - if(is_semi_antagonist && jobban_isbanned(caller, /decl/special_role/provocateur)) + if(is_semi_antagonist && jobban_isbanned(calling_client, /decl/special_role/provocateur)) return FALSE - if(!player_old_enough(caller)) + if(!player_old_enough(calling_client)) return FALSE return TRUE diff --git a/code/game/turfs/floors/_floor.dm b/code/game/turfs/floors/_floor.dm index 8a5562d03ad1..088d42df9da8 100644 --- a/code/game/turfs/floors/_floor.dm +++ b/code/game/turfs/floors/_floor.dm @@ -230,10 +230,10 @@ else physically_destroyed() -/turf/floor/get_footstep_sound(var/mob/caller) +/turf/floor/get_footstep_sound(var/mob/stepper) var/decl/flooring/use_flooring = get_topmost_flooring() if(istype(use_flooring)) - return get_footstep_for_mob(use_flooring.footstep_type, caller) + return get_footstep_for_mob(use_flooring.footstep_type, stepper) return ..() /turf/floor/get_movable_alpha_mask_state(atom/movable/mover) diff --git a/code/game/turfs/turf_footsteps.dm b/code/game/turfs/turf_footsteps.dm index bfa1f9171569..1025bb5eb1a9 100644 --- a/code/game/turfs/turf_footsteps.dm +++ b/code/game/turfs/turf_footsteps.dm @@ -1,15 +1,15 @@ -/proc/get_footstep_for_mob(var/footstep_type, var/mob/living/caller) - . = istype(caller) && caller.get_mob_footstep(footstep_type) +/proc/get_footstep_for_mob(var/footstep_type, var/mob/living/stepper) + . = istype(stepper) && stepper.get_mob_footstep(footstep_type) if(!.) var/decl/footsteps/FS = GET_DECL(footstep_type) . = pick(FS.footstep_sounds) -/turf/proc/get_footstep_sound(var/mob/caller) +/turf/proc/get_footstep_sound(var/mob/stepper) for(var/obj/structure/S in contents) if(S.footstep_type) - return get_footstep_for_mob(S.footstep_type, caller) + return get_footstep_for_mob(S.footstep_type, stepper) if(check_fluid_depth(10) && !is_flooded(TRUE)) - return get_footstep_for_mob(/decl/footsteps/water, caller) + return get_footstep_for_mob(/decl/footsteps/water, stepper) if(footstep_type) - return get_footstep_for_mob(footstep_type, caller) - return get_footstep_for_mob(/decl/footsteps/blank, caller) + return get_footstep_for_mob(footstep_type, stepper) + return get_footstep_for_mob(/decl/footsteps/blank, stepper) diff --git a/code/modules/character_info/_comment.dm b/code/modules/character_info/_comment.dm index ef15898c550b..3ab52a26d2e1 100644 --- a/code/modules/character_info/_comment.dm +++ b/code/modules/character_info/_comment.dm @@ -25,7 +25,7 @@ /datum/character_comment/proc/is_stale() return !get_config_value(/decl/config/num/hide_comments_older_than) || (REALTIMEOFDAY - last_updated) > (get_config_value(/decl/config/num/hide_comments_older_than)) -/datum/character_comment/proc/get_comment_html(var/datum/character_information/presenting, var/mob/usr, var/row_bkg_color) +/datum/character_comment/proc/get_comment_html(var/datum/character_information/presenting, var/mob/user, var/row_bkg_color) if(!istype(main_mood)) main_mood = GET_DECL(/decl/comment_mood/unknown) @@ -39,14 +39,14 @@ "
    [body]
    ", "" ) - if(usr) + if(user) . += "
    " - if(author_ckey == usr.ckey || check_rights(R_MOD)) + if(author_ckey == user.ckey || check_rights(R_MOD)) . += "Edit
    " . += "Delete
    " . += "Change primary mood
    " . += "Change border mood" - else if(usr.ckey == presenting.ckey) + else if(user.ckey == presenting.ckey) . += "Delete" else . += "Not editable." diff --git a/code/modules/goals/_goal.dm b/code/modules/goals/_goal.dm index b36b7b50a406..9793c69f26ed 100644 --- a/code/modules/goals/_goal.dm +++ b/code/modules/goals/_goal.dm @@ -23,13 +23,13 @@ owner = null . = ..() -/datum/goal/proc/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller ,var/position = 1) +/datum/goal/proc/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/user ,var/position = 1) . = "[description][get_summary_value()]" if(show_success) . += get_success_string() if(allow_modification) - if(can_abandon) . += " (Abandon)" - if(can_reroll) . += " (Reroll)" + if(can_abandon) . += " (Abandon)" + if(can_reroll) . += " (Reroll)" /datum/goal/proc/get_success_string() return check_success() ? " Success!" : " Failure." diff --git a/code/modules/goals/goal_ambition.dm b/code/modules/goals/goal_ambition.dm index 2029bc5cf23f..aa44ad99b10a 100644 --- a/code/modules/goals/goal_ambition.dm +++ b/code/modules/goals/goal_ambition.dm @@ -13,5 +13,5 @@ /datum/goal/ambition/get_success_string() return "" -/datum/goal/ambition/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller ,var/position = 1) +/datum/goal/ambition/summarize(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/user ,var/position = 1) . = SPAN_DANGER(..(show_success)) diff --git a/code/modules/goals/goal_mind.dm b/code/modules/goals/goal_mind.dm index debd412f1f57..a195dbd48e6b 100644 --- a/code/modules/goals/goal_mind.dm +++ b/code/modules/goals/goal_mind.dm @@ -8,12 +8,12 @@ if(LAZYLEN(goals)) to_chat(current, SPAN_NOTICE("

    You had the following personal goals this round:
    [jointext(summarize_goals(TRUE), "
    ")]")) -/datum/mind/proc/summarize_goals(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/caller) +/datum/mind/proc/summarize_goals(var/show_success = FALSE, var/allow_modification = FALSE, var/mob/user) . = list() if(LAZYLEN(goals)) for(var/i = 1 to LAZYLEN(goals)) var/datum/goal/goal = goals[i] - . += "[i]. [goal.summarize(show_success, allow_modification, caller, position = i)]" + . += "[i]. [goal.summarize(show_success, allow_modification, user, position = i)]" // Create and display personal goals for this round. /datum/mind/proc/generate_goals(var/datum/job/job, var/adding_goals = FALSE, var/add_amount, var/is_spawning = FALSE) diff --git a/code/modules/goals/goal_mob.dm b/code/modules/goals/goal_mob.dm index ddd87767c254..ea3d8ce41261 100644 --- a/code/modules/goals/goal_mob.dm +++ b/code/modules/goals/goal_mob.dm @@ -30,7 +30,7 @@ else to_chat(src, SPAN_NOTICE("You have no personal goals this round.")) if(allow_modification && LAZYLEN(mind.goals) < 5) - to_chat(src, SPAN_NOTICE("Add Random Goal")) + to_chat(src, SPAN_NOTICE("Add Random Goal")) for(var/dept_key in mind.assigned_job?.department_types) var/decl/department/dept = SSjobs.get_department_by_type(dept_key) diff --git a/code/modules/persistence/persistence_datum.dm b/code/modules/persistence/persistence_datum.dm index 3ca013a7c4cb..8ac56f800486 100644 --- a/code/modules/persistence/persistence_datum.dm +++ b/code/modules/persistence/persistence_datum.dm @@ -146,7 +146,7 @@ /decl/persistence_handler/proc/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) if(can_modify) - . = "[thing]Destroy" + . = "[thing]Destroy" else . = "[thing]" @@ -159,6 +159,6 @@ RemoveValue(value) . = TRUE if(.) - var/mob/user = locate(href_list["caller"]) + var/mob/user = locate(href_list["user"]) if(user) SSpersistence.show_info(user) diff --git a/code/modules/persistence/persistence_datum_book.dm b/code/modules/persistence/persistence_datum_book.dm index cf33c5df07d4..839f0ed29a63 100644 --- a/code/modules/persistence/persistence_datum_book.dm +++ b/code/modules/persistence/persistence_datum_book.dm @@ -78,6 +78,6 @@ /decl/persistence_handler/book/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) var/obj/item/book/book = thing if(can_modify) - . = "[book.dat][book.title][book.last_modified_ckey]Destroy" + . = "[book.dat][book.title][book.last_modified_ckey]Destroy" else . = "[book.dat][book.title][book.last_modified_ckey]" diff --git a/code/modules/persistence/persistence_datum_graffiti.dm b/code/modules/persistence/persistence_datum_graffiti.dm index 83861418d67e..7174b5aff085 100644 --- a/code/modules/persistence/persistence_datum_graffiti.dm +++ b/code/modules/persistence/persistence_datum_graffiti.dm @@ -38,6 +38,6 @@ /decl/persistence_handler/graffiti/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) var/obj/effect/decal/writing/save_graffiti = thing if(can_modify) - . = "[save_graffiti.message][save_graffiti.author]Destroy" + . = "[save_graffiti.message][save_graffiti.author]Destroy" else . = "[save_graffiti.message][save_graffiti.author]" diff --git a/code/modules/persistence/persistence_datum_paper.dm b/code/modules/persistence/persistence_datum_paper.dm index 4615ebe28e55..4271c6509133 100644 --- a/code/modules/persistence/persistence_datum_paper.dm +++ b/code/modules/persistence/persistence_datum_paper.dm @@ -41,7 +41,7 @@ /decl/persistence_handler/paper/GetAdminDataStringFor(var/thing, var/can_modify, var/mob/user) var/obj/item/paper/paper = thing if(can_modify) - . = "[paper.info][paper.name][paper.last_modified_ckey]Destroy" + . = "[paper.info][paper.name][paper.last_modified_ckey]Destroy" else . = "[paper.info][paper.name][paper.last_modified_ckey]" diff --git a/code/modules/synthesized_instruments/real_instruments.dm b/code/modules/synthesized_instruments/real_instruments.dm index 9324dc19c50f..2783ec3ff37f 100644 --- a/code/modules/synthesized_instruments/real_instruments.dm +++ b/code/modules/synthesized_instruments/real_instruments.dm @@ -18,11 +18,11 @@ maximum_line_length = global.musical_config.max_line_length instruments = istype(what) ? list(what) : what -/datum/real_instrument/proc/Topic_call(href, href_list, usr) +/datum/real_instrument/proc/Topic_call(href, href_list, user) var/target = href_list["target"] var/value = text2num(href_list["value"]) if (href_list["value"] && !isnum(value)) - to_chat(usr, "Non-numeric value was given.") + to_chat(user, "Non-numeric value was given.") return 0 @@ -31,20 +31,20 @@ if ("play") src.player.song.playing = value if (src.player.song.playing) - src.player.song.play_song(usr) + src.player.song.play_song(user) if ("newsong") src.player.song.lines.Cut() src.player.song.tempo = src.player.song.sanitize_tempo(5) // default 120 BPM if ("import") var/t = "" do - t = html_encode(input(usr, "Please paste the entire song, formatted:", text("[]", owner.name), t) as message) - if(!CanInteractWith(usr, owner, global.physical_topic_state)) + t = html_encode(input(user, "Please paste the entire song, formatted:", text("[]", owner.name), t) as message) + if(!CanInteractWith(user, owner, global.physical_topic_state)) return if(length(t) >= 2*src.maximum_lines*src.maximum_line_length) - var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") - if(!CanInteractWith(usr, owner, global.physical_topic_state)) + var/cont = input(user, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no") + if(!CanInteractWith(user, owner, global.physical_topic_state)) return if(cont == "no") break @@ -60,24 +60,24 @@ else src.player.song.tempo = src.player.song.sanitize_tempo(5) // default 120 BPM if(src.player.song.lines.len > maximum_lines) - to_chat(usr,"Too many lines!") + to_chat(user,"Too many lines!") src.player.song.lines.Cut(maximum_lines+1) var/linenum = 1 for(var/l in src.player.song.lines) if(length(l) > maximum_line_length) - to_chat(usr, "Line [linenum] too long!") + to_chat(user, "Line [linenum] too long!") src.player.song.lines.Remove(l) else linenum++ if ("show_song_editor") if (!src.song_editor) src.song_editor = new (host = src.owner, song = src.player.song) - src.song_editor.ui_interact(usr) + src.song_editor.ui_interact(user) if ("show_usage") if (!src.usage_info) src.usage_info = new (owner, src.player) - src.usage_info.ui_interact(usr) + src.usage_info.ui_interact(user) if ("volume") src.player.volume = min(max(min(player.volume+text2num(value), 100), 0), player.max_volume) if ("transposition") @@ -91,8 +91,8 @@ if ("sustain_timer") src.player.song.sustain_timer = max(min(player.song.sustain_timer+value, global.musical_config.longest_sustain_timer), 1) if ("soft_coeff") - var/new_coeff = input(usr, "from [global.musical_config.gentlest_drop] to [global.musical_config.steepest_drop]") as num - if(!CanInteractWith(usr, owner, global.physical_topic_state)) + var/new_coeff = input(user, "from [global.musical_config.gentlest_drop] to [global.musical_config.steepest_drop]") as num + if(!CanInteractWith(user, owner, global.physical_topic_state)) return new_coeff = round(min(max(new_coeff, global.musical_config.gentlest_drop), global.musical_config.steepest_drop), 0.001) src.player.song.soft_coeff = new_coeff @@ -102,8 +102,8 @@ var/datum/instrument/instrument = instruments[key] categories |= instrument.category - var/category = input(usr, "Choose a category") as null|anything in categories - if(!CanInteractWith(usr, owner, global.physical_topic_state)) + var/category = input(user, "Choose a category") as null|anything in categories + if(!CanInteractWith(user, owner, global.physical_topic_state)) return var/list/instruments_available = list() for (var/key in instruments) @@ -111,8 +111,8 @@ if (instrument.category == category) instruments_available += key - var/new_instrument = input(usr, "Choose an instrument") as null|anything in instruments_available - if(!CanInteractWith(usr, owner, global.physical_topic_state)) + var/new_instrument = input(user, "Choose an instrument") as null|anything in instruments_available + if(!CanInteractWith(user, owner, global.physical_topic_state)) return if (new_instrument) src.player.song.instrument_data = instruments[new_instrument] @@ -123,14 +123,14 @@ if (global.musical_config.env_settings_available) if (!src.env_editor) src.env_editor = new (src.player) - src.env_editor.ui_interact(usr) + src.env_editor.ui_interact(user) else - to_chat(usr, "Virtual environment is disabled.") + to_chat(user, "Virtual environment is disabled.") if ("show_echo_editor") if (!src.echo_editor) src.echo_editor = new (src.player) - src.echo_editor.ui_interact(usr) + src.echo_editor.ui_interact(user) if ("select_env") if (value in -1 to 26) From ee3b8a766a1296b1dbe691b046769ac836fbbc54 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 20:29:48 -0400 Subject: [PATCH 424/512] Fix windows being excessively transparent --- code/game/objects/structures/_structure_materials.dm | 4 +++- code/game/objects/structures/window.dm | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/code/game/objects/structures/_structure_materials.dm b/code/game/objects/structures/_structure_materials.dm index f3c619b1f61b..b37da354e04e 100644 --- a/code/game/objects/structures/_structure_materials.dm +++ b/code/game/objects/structures/_structure_materials.dm @@ -3,6 +3,8 @@ var/decl/material/reinf_material var/material_alteration var/dismantled + /// The base alpha used to calculate material-based alpha in update_material_color(). + var/base_alpha = 50 /obj/structure/get_material() RETURN_TYPE(/decl/material) @@ -52,7 +54,7 @@ /obj/structure/proc/update_material_color() color = get_color() if(istype(material)) - alpha = clamp((50 + material.opacity * 255), 0, 255) + alpha = clamp((base_alpha + material.opacity * 255), 0, 255) else alpha = initial(alpha) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d0898af0ec67..e07f11f29f4d 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -10,7 +10,8 @@ anchored = FALSE // Base, non-premapped type should start unanchored. atom_flags = ATOM_FLAG_CHECKS_BORDER | ATOM_FLAG_CAN_BE_PAINTED obj_flags = OBJ_FLAG_ROTATABLE | OBJ_FLAG_MOVES_UNSUPPORTED - alpha = 180 + base_alpha = 100 // at 0.3 opacity for glass, this will result in a total alpha of around 176 + alpha = 180 // preview value material_alteration = MAT_FLAG_ALTERATION_COLOR material = /decl/material/solid/glass rad_resistance_modifier = 0.5 From 2f80393d23a66b1d9c4dd0ee0df4400d3a751ec0 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 14:21:24 -0400 Subject: [PATCH 425/512] Fix abstract (empty) lights box spawning on magshield --- code/game/objects/items/weapons/storage/boxes.dm | 1 + maps/away/magshield/magshield.dmm | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/boxes.dm b/code/game/objects/items/weapons/storage/boxes.dm index 499ffb5d8589..69735acf4a20 100644 --- a/code/game/objects/items/weapons/storage/boxes.dm +++ b/code/game/objects/items/weapons/storage/boxes.dm @@ -431,6 +431,7 @@ return list(/obj/item/chems/hypospray/autoinjector/stabilizer = 7) /obj/item/box/lights + abstract_type = /obj/item/box/lights name = "box of replacement bulbs" icon_state = "light" desc = "This box is shaped on the inside so that only light tubes and bulbs fit." diff --git a/maps/away/magshield/magshield.dmm b/maps/away/magshield/magshield.dmm index d6e4edc107af..d9da2ebbfdb1 100644 --- a/maps/away/magshield/magshield.dmm +++ b/maps/away/magshield/magshield.dmm @@ -1743,7 +1743,7 @@ /area/magshield/north) "eS" = ( /obj/structure/table/steel, -/obj/item/box/lights, +/obj/item/box/lights/mixed, /turf/floor/plating/airless, /area/magshield/north) "eT" = ( From 34d6988edd4a1de5e49a375894a057d6945338b3 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 16 Jul 2025 19:59:30 -0400 Subject: [PATCH 426/512] Fix colouration and accessories tab showing when empty --- .../preference_setup/general/02_body.dm | 79 ++++++++++--------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index 4c24a880b2f4..c222475a1263 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -211,31 +211,34 @@ . += "" . += "" + // Items in this list are only added if there are entries in accessory_strings. + var/list/accessory_header = list() + var/list/accessory_strings = list() if((mob_bodytype.appearance_flags & (HAS_EYE_COLOR|HAS_SKIN_COLOR|HAS_A_SKIN_TONE)) || length(mob_species.available_accessory_categories)) - . += "

    Colouration and accessories

    " - . += "" + accessory_header += "

    Colouration and accessories

    " + accessory_header += "
    " if(mob_bodytype.appearance_flags & HAS_A_SKIN_TONE) - . += "" - . += "" - . += "" - . += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" if(mob_bodytype.appearance_flags & HAS_SKIN_COLOR) - . += "" - . += "" - . += "" - . += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" if(mob_bodytype.appearance_flags & HAS_EYE_COLOR) - . += "" - . += "" - . += "" - . += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" var/const/up_arrow = "⇧" var/const/down_arrow = "⇩" @@ -264,19 +267,19 @@ var/decl/sprite_accessory_metadata/sam = GET_DECL(metadata_type) metadata_strings += sam.get_metadata_options_string(src, accessory_cat_decl, accessory_decl, LAZYACCESS(accessory_metadata, metadata_type)) var/acc_decl_ref = "\ref[accessory_decl]" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" continue - . += "" - . += "" - . += "" - . += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" var/i = 0 for(var/accessory in current_accessories) i++ @@ -287,15 +290,19 @@ var/decl/sprite_accessory_metadata/sam = GET_DECL(metadata_type) metadata_strings += sam.get_metadata_options_string(src, accessory_cat_decl, accessory_decl, LAZYACCESS(accessory_metadata, metadata_type)) var/acc_decl_ref = "\ref[accessory_decl]" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" - . += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" + accessory_strings += "" if(isnull(accessory_cat_decl.max_selections) || i < accessory_cat_decl.max_selections) - . += "" + accessory_strings += "" + + if(length(accessory_strings)) + . += accessory_header + . += accessory_strings . += "
    Skin tone[-pref.skin_tone + 35]/[mob_bodytype.max_skin_tone()]" - . += "
    Skin tone[-pref.skin_tone + 35]/[mob_bodytype.max_skin_tone()]" + accessory_strings += "
    Skin color[COLORED_SQUARE(pref.skin_colour)] Change" - . += "
    Skin color[COLORED_SQUARE(pref.skin_colour)] Change" + accessory_strings += "
    Eyes[COLORED_SQUARE(pref.eye_colour)] Change" - . += "
    Eyes[COLORED_SQUARE(pref.eye_colour)] Change" + accessory_strings += "
    [accessory_cat_decl.name][jointext(metadata_strings, "
    ")]
    [left_arrow][accessory_decl.name][right_arrow]
    [accessory_cat_decl.name][jointext(metadata_strings, "
    ")]
    [left_arrow][accessory_decl.name][right_arrow]
    [accessory_cat_decl.name]
    [accessory_cat_decl.name]
    Remove[jointext(metadata_strings, "
    ")]
    [up_arrow][accessory_decl.name][down_arrow]
    Remove[jointext(metadata_strings, "
    ")]
    [up_arrow][accessory_decl.name][down_arrow]
    Add marking
    Add marking
    " From 62c51d200e82f7ca927748af03c3824586f7458d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 16 Jul 2025 20:53:47 -0400 Subject: [PATCH 427/512] Fix emergency equipment being overwritten by loadout --- code/__defines/items_clothing.dm | 7 +++++++ code/game/objects/items/__item.dm | 11 +++++++---- .../client/preference_setup/loadout/loadout.dm | 9 +++++---- code/modules/clothing/_clothing.dm | 2 +- code/modules/clothing/gloves/latex.dm | 2 +- code/modules/clothing/gloves/miscellaneous.dm | 2 +- code/modules/clothing/gloves/thick.dm | 2 +- code/modules/clothing/head/hardhat.dm | 2 +- code/modules/clothing/head/helmet.dm | 2 +- code/modules/clothing/head/misc_special.dm | 2 +- code/modules/clothing/spacesuits/spacesuits.dm | 4 ++-- code/modules/clothing/suits/armor/_armor.dm | 2 +- code/modules/clothing/suits/bio.dm | 4 ++-- code/modules/clothing/suits/toggles.dm | 2 +- 14 files changed, 32 insertions(+), 21 deletions(-) diff --git a/code/__defines/items_clothing.dm b/code/__defines/items_clothing.dm index b2a5c347ddfd..ffd20f690f91 100644 --- a/code/__defines/items_clothing.dm +++ b/code/__defines/items_clothing.dm @@ -266,3 +266,10 @@ var/global/list/all_hand_slots = list( BP_R_HAND_UPPER, BP_MOUTH ) + +/// If this item conflicts with a loadout item, simply delete it. +#define LOADOUT_CONFLICT_DELETE 0 +/// If this item conflicts with a loadout item, place this item in storage. +#define LOADOUT_CONFLICT_STORAGE 1 +/// If this item conflicts with a loadout item, place THE LOADOUT ITEM in storage. +#define LOADOUT_CONFLICT_KEEP 2 \ No newline at end of file diff --git a/code/game/objects/items/__item.dm b/code/game/objects/items/__item.dm index 0e52f909ceba..c143d909af91 100644 --- a/code/game/objects/items/__item.dm +++ b/code/game/objects/items/__item.dm @@ -89,8 +89,8 @@ var/tmp/use_single_icon var/center_of_mass = @'{"x":16,"y":16}' //can be null for no exact placement behaviour - /// Used when this item is replaced by a loadout item. If TRUE, loadout places src in wearer's storage. If FALSE, src is deleted. - var/replaced_in_loadout = TRUE + /// Controls what method is used to resolve conflicts between equipped items and mob loadout. + var/replaced_in_loadout = LOADOUT_CONFLICT_DELETE var/paint_color var/paint_verb @@ -1120,9 +1120,12 @@ modules/mob/living/human/life.dm if you die, you will be zoomed out. /obj/item/proc/handle_loadout_equip_replacement(obj/item/old_item) return -/// Used to handle equipped icons overwritten by custom loadout. If TRUE, loadout places src in wearer's storage. If FALSE, src is deleted by loadout. +/// Used to handle equipped items overwritten by custom loadout. +/// Returns one of LOADOUT_CONFLICT_DELETE, LOADOUT_CONFLICT_STORAGE, or LOADOUT_CONFLICT_KEEP. /obj/item/proc/loadout_should_keep(obj/item/new_item, mob/wearer) - return type != new_item.type && !replaced_in_loadout + if(type == new_item.type) // for exact type collisions, just delete by default + return LOADOUT_CONFLICT_DELETE + return replaced_in_loadout /obj/item/equipped(mob/user, slot) . = ..() diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index 1555f26fd222..d685e0480943 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -537,18 +537,19 @@ item.loadout_setup(wearer, metadata) var/obj/item/old_item = wearer.get_equipped_item(slot) - var/attached_as_accessory = FALSE if(istype(old_item, /obj/item/clothing) && istype(item, /obj/item/clothing)) var/obj/item/clothing/worn = old_item if(worn.can_attach_accessory(item, wearer)) worn.attach_accessory(wearer, item) - attached_as_accessory = TRUE return TRUE - if(!attached_as_accessory && wearer.equip_to_slot_if_possible(item, slot, del_on_fail = TRUE, force = TRUE, delete_old_item = FALSE, ignore_equipped = replace_equipped)) + var/resolution_strategy = old_item?.loadout_should_keep(item, wearer) + if(resolution_strategy == LOADOUT_CONFLICT_KEEP) + place_in_storage_or_drop(wearer, item) + else if(wearer.equip_to_slot_if_possible(item, slot, del_on_fail = TRUE, force = TRUE, delete_old_item = FALSE, ignore_equipped = replace_equipped)) if(old_item && wearer.get_equipped_item(slot) != old_item) item.handle_loadout_equip_replacement(old_item) - if(old_item.loadout_should_keep(item, wearer)) + if(resolution_strategy == LOADOUT_CONFLICT_STORAGE) place_in_storage_or_drop(wearer, old_item) else qdel(old_item) diff --git a/code/modules/clothing/_clothing.dm b/code/modules/clothing/_clothing.dm index bad50bf1985b..6e00b3e04f18 100644 --- a/code/modules/clothing/_clothing.dm +++ b/code/modules/clothing/_clothing.dm @@ -4,7 +4,7 @@ origin_tech = @'{"materials":1,"engineering":1}' material = /decl/material/solid/organic/cloth paint_verb = "dyed" - replaced_in_loadout = TRUE + replaced_in_loadout = LOADOUT_CONFLICT_DELETE w_class = ITEM_SIZE_SMALL icon_state = ICON_STATE_WORLD _base_attack_force = 3 diff --git a/code/modules/clothing/gloves/latex.dm b/code/modules/clothing/gloves/latex.dm index ee9fb1eae344..a0d80536d8f6 100644 --- a/code/modules/clothing/gloves/latex.dm +++ b/code/modules/clothing/gloves/latex.dm @@ -7,7 +7,7 @@ icon_state = ICON_STATE_WORLD anomaly_shielding = 0.1 material = /decl/material/solid/organic/plastic //todo: latex - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE /obj/item/clothing/gloves/latex/nitrile name = "nitrile gloves" diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 8d4f1d315e7f..d69926ce69ec 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -12,7 +12,7 @@ icon_state = ICON_STATE_WORLD material = /decl/material/solid/organic/plastic //TODO: rubber matter = list(/decl/material/solid/organic/cloth = MATTER_AMOUNT_REINFORCEMENT) - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE /obj/item/clothing/gloves/insulated/cheap //Cheap Chinese Crap desc = "These gloves are cheap copies of the coveted gloves, no way this can end badly." diff --git a/code/modules/clothing/gloves/thick.dm b/code/modules/clothing/gloves/thick.dm index 92a0268b4b73..2f3e6a063523 100644 --- a/code/modules/clothing/gloves/thick.dm +++ b/code/modules/clothing/gloves/thick.dm @@ -19,7 +19,7 @@ ARMOR_BOMB = ARMOR_BOMB_RESISTANT, ARMOR_BIO = ARMOR_BIO_MINOR) material = /decl/material/solid/organic/leather - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE /obj/item/clothing/gloves/thick/swat desc = "These tactical gloves are somewhat fire and impact-resistant." diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index f47c6d25b1d7..1b86752f107d 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -22,7 +22,7 @@ material = /decl/material/solid/organic/plastic matter = list(/decl/material/solid/metal/steel = MATTER_AMOUNT_REINFORCEMENT) origin_tech = @'{"materials":1,"engineering":1,"combat":1}' - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE _base_attack_force = 5 /obj/item/clothing/head/hardhat/orange diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 42e08ecd5fe3..18a577f72ec7 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -25,7 +25,7 @@ matter = list(/decl/material/solid/metal/plasteel = MATTER_AMOUNT_TRACE) origin_tech = @'{"materials":1,"engineering":1,"combat":1}' protects_against_weather = TRUE - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE _base_attack_force = 8 /obj/item/clothing/head/helmet/tactical diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm index 6616b9929290..ce560e06e7ad 100644 --- a/code/modules/clothing/head/misc_special.dm +++ b/code/modules/clothing/head/misc_special.dm @@ -31,7 +31,7 @@ w_class = ITEM_SIZE_NORMAL flash_protection = FLASH_PROTECTION_MAJOR tint = TINT_HEAVY - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE accessory_slot = null // cannot be equipped on top of helmets var/up = 0 var/base_state diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index 896bd3db2416..cd2bfaf6621f 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -26,7 +26,7 @@ brightness_on = 4 light_wedge = LIGHT_WIDE on = 0 - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_KEEP var/obj/machinery/camera/camera var/tinted = null //Set to non-null for toggleable tint helmets @@ -144,7 +144,7 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT ) protects_against_weather = TRUE - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_KEEP /obj/item/clothing/suit/space/Initialize() . = ..() diff --git a/code/modules/clothing/suits/armor/_armor.dm b/code/modules/clothing/suits/armor/_armor.dm index d7fcd4281c27..a36447e9046e 100644 --- a/code/modules/clothing/suits/armor/_armor.dm +++ b/code/modules/clothing/suits/armor/_armor.dm @@ -22,5 +22,5 @@ siemens_coefficient = 0.6 blood_overlay_type = "armor" origin_tech = @'{"materials":1,"engineering":1,"combat":1}' - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE _base_attack_force = 5 diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm index 4c8fba5849f8..8b192c4c6576 100644 --- a/code/modules/clothing/suits/bio.dm +++ b/code/modules/clothing/suits/bio.dm @@ -17,7 +17,7 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT ) - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_KEEP /obj/item/clothing/suit/bio_suit name = "bio suit" @@ -40,7 +40,7 @@ /decl/material/solid/organic/plastic = MATTER_AMOUNT_REINFORCEMENT, /decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT ) - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_KEEP /obj/item/clothing/suit/bio_suit/Initialize() . = ..() diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index b7bb868f7774..4394643b6e5e 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -2,7 +2,7 @@ /obj/item/clothing/suit/toggle abstract_type = /obj/item/clothing/suit/toggle storage = /datum/storage/pockets/suit - replaced_in_loadout = FALSE + replaced_in_loadout = LOADOUT_CONFLICT_STORAGE /obj/item/clothing/suit/toggle/get_assumed_clothing_state_modifiers() var/static/list/expected_state_modifiers = list( From 6e1ea1b58cd2d8748764dadb433ec8b7408c691b Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 20:36:00 -0400 Subject: [PATCH 428/512] Fix some loadout items being duplicated --- code/modules/client/preference_setup/loadout/loadout.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm index d685e0480943..6ce896b7c364 100644 --- a/code/modules/client/preference_setup/loadout/loadout.dm +++ b/code/modules/client/preference_setup/loadout/loadout.dm @@ -553,7 +553,7 @@ place_in_storage_or_drop(wearer, old_item) else qdel(old_item) - return item + return item /decl/loadout_option/proc/spawn_in_storage_or_drop(mob/living/human/wearer, metadata) var/obj/item/item = spawn_and_validate_item(wearer, metadata) From 35503d57a7e9729438fceb0f2b44ffc88f040eaa Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 17:19:50 -0400 Subject: [PATCH 429/512] Remove adjust_multi --- code/game/machinery/atmoalter/canister.dm | 3 ++- code/game/machinery/atmoalter/pump.dm | 3 ++- code/game/objects/items/devices/oxycandle.dm | 9 +++++---- code/game/objects/structures/mineral_bath.dm | 4 +++- code/game/objects/structures/transit_tubes.dm | 3 ++- code/modules/atmospherics/components/unary/tank.dm | 6 ++---- code/modules/reagents/chems/chems_explosives.dm | 4 +++- code/modules/reagents/chems/chems_fuel.dm | 5 ++++- code/modules/xgm/xgm_gas_mixture.dm | 11 ----------- code/unit_tests/atmospherics_tests.dm | 6 ++---- mods/content/supermatter/machinery/supermatter.dm | 4 ++-- 11 files changed, 27 insertions(+), 31 deletions(-) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index ae85b4324a5f..267f68ff20d5 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -340,7 +340,8 @@ EMPTY_CANISTER(hydrogen, /obj/machinery/portable_atmospherics/canister/hydrogen) /obj/machinery/portable_atmospherics/canister/air/Initialize() . = ..() var/list/air_mix = StandardAirMix() - air_contents.adjust_multi(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen], /decl/material/gas/nitrogen, air_mix[/decl/material/gas/nitrogen]) + air_contents.adjust_gas(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen], FALSE) + air_contents.adjust_gas(/decl/material/gas/nitrogen, air_mix[/decl/material/gas/nitrogen]) update_icon() diff --git a/code/game/machinery/atmoalter/pump.dm b/code/game/machinery/atmoalter/pump.dm index 2c107d7aac1b..43297c50a477 100644 --- a/code/game/machinery/atmoalter/pump.dm +++ b/code/game/machinery/atmoalter/pump.dm @@ -27,7 +27,8 @@ . = ..() var/list/air_mix = StandardAirMix() - src.air_contents.adjust_multi(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen], /decl/material/gas/nitrogen, air_mix[/decl/material/gas/nitrogen]) + air_contents.adjust_gas(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen], FALSE) + air_contents.adjust_gas(/decl/material/gas/nitrogen, air_mix[/decl/material/gas/nitrogen]) /obj/machinery/portable_atmospherics/powered/pump/on_update_icon() overlays.Cut() diff --git a/code/game/objects/items/devices/oxycandle.dm b/code/game/objects/items/devices/oxycandle.dm index 0040ac660821..c24ced497aef 100644 --- a/code/game/objects/items/devices/oxycandle.dm +++ b/code/game/objects/items/devices/oxycandle.dm @@ -1,3 +1,4 @@ +// TODO: Make this an actual candle that burns something that produces oxygen as a waste product? That'd be doable now... /obj/item/oxycandle name = "oxygen candle" desc = "A steel tube with the words 'OXYGEN - PULL CORD TO IGNITE' stamped on the side.\nA small label reads 'WARNING: NOT FOR LIGHTING USE. WILL IGNITE FLAMMABLE GASSES'" @@ -34,8 +35,8 @@ air_contents = new /datum/gas_mixture() air_contents.volume = 200 //liters air_contents.temperature = T20C - var/list/air_mix = list(/decl/material/gas/oxygen = 1 * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) - air_contents.adjust_multi(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen]) + var/const/OXYGEN_FRACTION = 1 // separating out the constant so it's clearer why it exists and how to modify it later + air_contents.adjust_gas(/decl/material/gas/oxygen, OXYGEN_FRACTION * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) START_PROCESSING(SSprocessing, src) // Process of Oxygen candles releasing air. Makes 200 volume of oxygen @@ -63,8 +64,8 @@ return environment.merge(removed) volume -= 200 - var/list/air_mix = list(/decl/material/gas/oxygen = 1 * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) - air_contents.adjust_multi(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen]) + var/const/OXYGEN_FRACTION = 1 // separating out the constant so it's clearer why it exists and how to modify it later + air_contents.adjust_gas(/decl/material/gas/oxygen, OXYGEN_FRACTION * (target_pressure * air_contents.volume) / (R_IDEAL_GAS_EQUATION * air_contents.temperature)) /obj/item/oxycandle/on_update_icon() . = ..() diff --git a/code/game/objects/structures/mineral_bath.dm b/code/game/objects/structures/mineral_bath.dm index 0129a5e61f74..1ed4d581c726 100644 --- a/code/game/objects/structures/mineral_bath.dm +++ b/code/game/objects/structures/mineral_bath.dm @@ -14,7 +14,9 @@ /obj/structure/mineral_bath/return_air() var/datum/gas_mixture/venus = new(CELL_VOLUME, SYNTH_HEAT_LEVEL_1 - 10) - venus.adjust_multi(/decl/material/gas/chlorine, MOLES_N2STANDARD, /decl/material/gas/hydrogen, MOLES_O2STANDARD) + + venus.adjust_gas(/decl/material/gas/chlorine, MOLES_N2STANDARD, FALSE) + venus.adjust_gas(/decl/material/gas/hydrogen, MOLES_O2STANDARD, TRUE) return venus /obj/structure/mineral_bath/grab_attack(obj/item/grab/grab, mob/user) diff --git a/code/game/objects/structures/transit_tubes.dm b/code/game/objects/structures/transit_tubes.dm index 0c9982cc9a63..8c98af230f7a 100644 --- a/code/game/objects/structures/transit_tubes.dm +++ b/code/game/objects/structures/transit_tubes.dm @@ -59,7 +59,8 @@ /obj/structure/transit_tube_pod/Initialize() . = ..() - air_contents.adjust_multi(/decl/material/gas/oxygen, MOLES_O2STANDARD * 2, /decl/material/gas/nitrogen, MOLES_N2STANDARD) + air_contents.adjust_gas(/decl/material/gas/oxygen, MOLES_O2STANDARD * 2, FALSE) + air_contents.adjust_gas(/decl/material/gas/nitrogen, MOLES_N2STANDARD, TRUE) air_contents.temperature = T20C // Give auto tubes time to align before trying to start moving diff --git a/code/modules/atmospherics/components/unary/tank.dm b/code/modules/atmospherics/components/unary/tank.dm index 29968bd94450..52c6c6fc0278 100644 --- a/code/modules/atmospherics/components/unary/tank.dm +++ b/code/modules/atmospherics/components/unary/tank.dm @@ -29,11 +29,9 @@ air_contents.temperature = T20C if(filling) - var/list/gases = list() for(var/gas in filling) - gases += gas - gases += start_pressure * filling[gas] * (air_contents.volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature) - air_contents.adjust_multi(arglist(gases)) + air_contents.adjust_gas(gas, start_pressure * filling[gas] * (air_contents.volume)/(R_IDEAL_GAS_EQUATION*air_contents.temperature), FALSE) + air_contents.update_values() update_icon() /obj/machinery/atmospherics/unary/tank/set_initial_level() diff --git a/code/modules/reagents/chems/chems_explosives.dm b/code/modules/reagents/chems/chems_explosives.dm index 614671fb3060..58573abdbb42 100644 --- a/code/modules/reagents/chems/chems_explosives.dm +++ b/code/modules/reagents/chems/chems_explosives.dm @@ -27,7 +27,9 @@ var/adj_power = round(boompower * activated_volume/60) var/datum/gas_mixture/products = new(_temperature = 5 * FLAMMABLE_GAS_FLASHPOINT) var/gas_moles = 3 * volume - products.adjust_multi(/decl/material/gas/carbon_dioxide, 0.5 * gas_moles, /decl/material/gas/nitrogen, 0.3 * gas_moles, /decl/material/liquid/water, 0.2 * gas_moles) + products.adjust_gas(/decl/material/gas/carbon_dioxide, 0.5 * gas_moles, FALSE) + products.adjust_gas(/decl/material/gas/nitrogen, 0.3 * gas_moles, FALSE) + products.adjust_gas(/decl/material/liquid/water, 0.2 * gas_moles, TRUE) T.assume_air(products) holder?.reagents?.remove_reagent(type, activated_volume) explosion(T, adj_power, adj_power + 1, adj_power*2 + 2) diff --git a/code/modules/reagents/chems/chems_fuel.dm b/code/modules/reagents/chems/chems_fuel.dm index 7853f2f5579a..539d0e1b2e8d 100644 --- a/code/modules/reagents/chems/chems_fuel.dm +++ b/code/modules/reagents/chems/chems_fuel.dm @@ -26,7 +26,10 @@ var/turf/T = get_turf(holder) var/datum/gas_mixture/products = new(_temperature = 5 * FLAMMABLE_GAS_FLASHPOINT) var/gas_moles = 3 * volume - products.adjust_multi(/decl/material/gas/nitricoxide, 0.1 * gas_moles, /decl/material/gas/nitrodioxide, 0.1 * gas_moles, /decl/material/gas/nitrogen, 0.6 * gas_moles, /decl/material/gas/hydrogen, 0.02 * gas_moles) + products.adjust_gas(/decl/material/gas/nitricoxide, 0.1 * gas_moles, FALSE) + products.adjust_gas(/decl/material/gas/nitrodioxide, 0.1 * gas_moles, FALSE) + products.adjust_gas(/decl/material/gas/nitrogen, 0.6 * gas_moles, FALSE) + products.adjust_gas(/decl/material/gas/hydrogen, 0.02 * gas_moles, TRUE) T.assume_air(products) if(volume > 500) explosion(T,1,2,4) diff --git a/code/modules/xgm/xgm_gas_mixture.dm b/code/modules/xgm/xgm_gas_mixture.dm index e567de48405c..823c729e3b1f 100644 --- a/code/modules/xgm/xgm_gas_mixture.dm +++ b/code/modules/xgm/xgm_gas_mixture.dm @@ -72,17 +72,6 @@ if(update) update_values() - -//Variadic version of adjust_gas(). Takes any number of gas and mole pairs and applies them. -/datum/gas_mixture/proc/adjust_multi() - ASSERT(!(args.len % 2)) - - for(var/i = 1; i < args.len; i += 2) - adjust_gas(args[i], args[i+1], update = 0) - - update_values() - - /// Merges all the gas from another mixture into this one. Respects group_multipliers and adjusts temperature correctly. /// Does not modify giver in any way. /datum/gas_mixture/proc/merge(const/datum/gas_mixture/giver) diff --git a/code/unit_tests/atmospherics_tests.dm b/code/unit_tests/atmospherics_tests.dm index 46837d818bf5..0fa4febe7d55 100644 --- a/code/unit_tests/atmospherics_tests.dm +++ b/code/unit_tests/atmospherics_tests.dm @@ -14,11 +14,9 @@ var/list/initial_gas = mix_data["initial_gas"] if(initial_gas.len) - var/list/gas_args = list() for(var/gasid in initial_gas) - gas_args += gasid - gas_args += initial_gas[gasid] - gas_mix.adjust_multi(arglist(gas_args)) + gas_mix.adjust_gas(gasid, initial_gas[gasid], FALSE) + gas_mix.update_values() gas_mixes[mix_name] = gas_mix return gas_mixes diff --git a/mods/content/supermatter/machinery/supermatter.dm b/mods/content/supermatter/machinery/supermatter.dm index e0a41706145b..2fb27aadac35 100644 --- a/mods/content/supermatter/machinery/supermatter.dm +++ b/mods/content/supermatter/machinery/supermatter.dm @@ -509,8 +509,8 @@ var/global/list/supermatter_delam_accent_sounds = list( //Release reaction gasses var/heat_capacity = removed.heat_capacity() - removed.adjust_multi(/decl/material/solid/exotic_matter, max(device_energy / product_release_modifier, 0), \ - /decl/material/gas/oxygen, max((device_energy + removed.temperature - T0C) / oxygen_release_modifier, 0)) + removed.adjust_gas(/decl/material/solid/exotic_matter, max(device_energy / product_release_modifier, 0), FALSE) + removed.adjust_gas(/decl/material/gas/oxygen, max((device_energy + removed.temperature - T0C) / oxygen_release_modifier, 0)) var/thermal_power = thermal_release_modifier * device_energy if (debug) From 96805a2bb89cb590003d87e8584d5ae81ec8cdd0 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 14:22:02 -0400 Subject: [PATCH 430/512] Fix material color not being applied --- code/game/objects/items/_item_materials.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/items/_item_materials.dm b/code/game/objects/items/_item_materials.dm index 1a80c8c3bd58..fe0a0607b95a 100644 --- a/code/game/objects/items/_item_materials.dm +++ b/code/game/objects/items/_item_materials.dm @@ -91,6 +91,7 @@ obj_flags &= (~OBJ_FLAG_CONDUCTIBLE) if(isnull(initial(paint_verb))) paint_verb = material.paint_verb + refresh_color() // apply material color update_attack_force() update_name() if(material_armor_multiplier) From 733633fbdbdf65f5ee445d0d9e9be298821fd02a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 21:13:53 -0400 Subject: [PATCH 431/512] Fix trash from salads eaten with utensils --- code/game/objects/items/_item_edibility.dm | 14 +++++++++----- code/modules/food/utensils/_utensil.dm | 4 ++-- code/modules/reagents/reagent_containers/_glass.dm | 2 +- .../reagents/reagent_containers/food_edibility.dm | 1 + 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/code/game/objects/items/_item_edibility.dm b/code/game/objects/items/_item_edibility.dm index c93934b6f52b..4957dbecff8f 100644 --- a/code/game/objects/items/_item_edibility.dm +++ b/code/game/objects/items/_item_edibility.dm @@ -4,7 +4,7 @@ add_trace_DNA(target) // Used to get a piece of food from an item. -/obj/item/proc/seperate_food_chunk(obj/item/utensil/utensil, mob/user) +/obj/item/proc/separate_food_chunk(obj/item/utensil/utensil, mob/user) var/utensil_food_type = get_utensil_food_type() if(!istype(utensil) || !utensil_food_type) return @@ -14,8 +14,12 @@ // Create a dummy copy of the target food item. // This ensures we keep all food behavior, strings, sounds, etc. utensil.loaded_food = new utensil_food_type(utensil, material?.type, TRUE) - QDEL_NULL(utensil.loaded_food.trash) - QDEL_NULL(utensil.loaded_food.plate) + if(ismovable(utensil.loaded_food.trash)) + qdel(utensil.loaded_food.trash) + utensil.loaded_food.trash = null // Unset it even if it didn't need deleting (e.g. it was a path) + if(ismovable(utensil.loaded_food.plate)) + qdel(utensil.loaded_food.plate) + utensil.loaded_food.plate = null utensil.loaded_food.color = color utensil.loaded_food.filling_color = get_food_filling_color() utensil.loaded_food.SetName("\proper some [utensil.loaded_food.name]") @@ -25,12 +29,12 @@ reagents.trans_to(utensil.loaded_food, remove_amt) handle_chunk_separated() if(!reagents.total_volume) - handle_consumed() + handle_consumed(user) // it's not actually being consumed, so i'm not sure this is correct utensil.update_icon() else // This shouldn't happen, but who knows. to_chat(user, SPAN_WARNING("None of \the [src] is left!")) - handle_consumed() + handle_consumed(user) return TRUE /obj/item/proc/get_food_filling_color() diff --git a/code/modules/food/utensils/_utensil.dm b/code/modules/food/utensils/_utensil.dm index adabd99b0366..1aa8d4eced4b 100644 --- a/code/modules/food/utensils/_utensil.dm +++ b/code/modules/food/utensils/_utensil.dm @@ -61,14 +61,14 @@ add_overlay(overlay_image(icon, loaded_state, loaded_food.reagents?.get_color() || loaded_food.filling_color || get_color(), RESET_COLOR)) /obj/item/food/proc/handle_utensil_collection(obj/item/utensil/utensil, mob/user) - seperate_food_chunk(utensil, user) + separate_food_chunk(utensil, user) if(utensil.loaded_food) to_chat(user, SPAN_NOTICE("You collect [utensil.loaded_food] with \the [utensil].")) return TRUE return FALSE /obj/item/food/proc/handle_utensil_scooping(obj/item/utensil/utensil, mob/user) - seperate_food_chunk(utensil, user) + separate_food_chunk(utensil, user) if(utensil.loaded_food) to_chat(user, SPAN_NOTICE("You scoop up [utensil.loaded_food] with \the [utensil].")) return TRUE diff --git a/code/modules/reagents/reagent_containers/_glass.dm b/code/modules/reagents/reagent_containers/_glass.dm index 608f538a00a3..042e31321160 100644 --- a/code/modules/reagents/reagent_containers/_glass.dm +++ b/code/modules/reagents/reagent_containers/_glass.dm @@ -167,7 +167,7 @@ var/global/list/lid_check_glass_types = list() if(!reagents?.total_volume) to_chat(user, SPAN_WARNING("\The [src] is empty.")) return TRUE - seperate_food_chunk(utensil, user) + separate_food_chunk(utensil, user) if(utensil.loaded_food?.reagents?.total_volume) to_chat(user, SPAN_NOTICE("You scoop up some of \the [utensil.loaded_food.reagents.get_primary_reagent_name()] with \the [utensil].")) return TRUE diff --git a/code/modules/reagents/reagent_containers/food_edibility.dm b/code/modules/reagents/reagent_containers/food_edibility.dm index dfce4a7268f0..6b9a4db8d4e7 100644 --- a/code/modules/reagents/reagent_containers/food_edibility.dm +++ b/code/modules/reagents/reagent_containers/food_edibility.dm @@ -35,6 +35,7 @@ if(trash_ref) if(ispath(trash_ref, /obj/item)) var/obj/item/trash_item = new trash_ref(loc_ref) + trash_item.dropInto(loc_ref) if(feeder) feeder.put_in_hands(trash_item) else if(istype(trash_ref, /obj/item)) From 4aea67ec3da420bf98886de131611165766ba438 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 22:43:14 -0400 Subject: [PATCH 432/512] Rewrite CELLRATE macro for cleanliness --- code/__defines/machinery.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index c45a497ba5f3..787488e127f9 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -4,9 +4,8 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called #define MEGAWATTS *1000000 #define GIGAWATTS *1000000000 -#define MACHINERY_TICKRATE 2 // Tick rate for machinery in seconds. As it affects CELLRATE calculation it is kept as define here - -#define CELLRATE (1 / ( 3600 / MACHINERY_TICKRATE )) // Multiplier for charge units. Converts cell charge units(watthours) to joules. Takes into consideration that our machinery ticks once per two seconds. +/// Multiplier for charge units. Converts cell charge units(watthours) to joules. Takes into consideration that our machinery ticks once per two seconds. +#define CELLRATE (/datum/controller/subsystem/machines::wait / (1 HOUR)) // Doors! #define DOOR_CRUSH_DAMAGE 40 From 97331206ec612059956949b52460429d5f65cc02 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 08:10:09 -0400 Subject: [PATCH 433/512] Fix passing material instances to GET_DECL --- code/game/machinery/Sleeper.dm | 2 +- code/modules/scanners/mass_spectrometer.dm | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index eecfec8852bb..dc25d0685b56 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -442,7 +442,7 @@ to_chat(user, SPAN_WARNING("There's no suitable occupant in \the [src].")) return if(!emagged && canister.reagents?.primary_reagent) - var/decl/material/chem = GET_DECL(canister.reagents.primary_reagent) + var/decl/material/chem = canister.reagents.primary_reagent if(chem.overdose && REAGENT_VOLUME(occupant.reagents, canister.reagents.primary_reagent) + amount >= chem.overdose) to_chat(user, SPAN_WARNING("Injecting more [chem.name] presents an overdose risk to the subject.")) return diff --git a/code/modules/scanners/mass_spectrometer.dm b/code/modules/scanners/mass_spectrometer.dm index 510ea189fe03..7e186c85abfe 100644 --- a/code/modules/scanners/mass_spectrometer.dm +++ b/code/modules/scanners/mass_spectrometer.dm @@ -52,10 +52,9 @@ var/list/blood_traces = list() var/list/blood_doses = list() - if(length(reagents.reagent_volumes) == 1) - var/decl/material/liquid/random/random = GET_DECL(reagents.reagent_volumes[1]) - if(istype(random)) - return random.get_scan_data(user) + if(length(reagents.reagent_volumes) == 1 && istype(reagents.primary_reagent, /decl/material/liquid/random)) + var/decl/material/liquid/random/random = reagents.primary_reagent + return random.get_scan_data(user) for(var/decl/material/reagent as anything in reagents.reagent_volumes) if(!istype(reagent, /decl/material/liquid/blood)) From fc2d9f75a87d5f07172c767689ebab261dcd782c Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 08:11:01 -0400 Subject: [PATCH 434/512] Make holy water use a reagent data field --- code/__defines/mobs.dm | 1 + code/__defines/reagent_data_fields.dm | 3 +++ code/game/objects/items/weapons/storage/bible.dm | 2 +- .../materials/definitions/liquids/materials_liquid_water.dm | 4 ++-- code/modules/reagents/reagent_containers/drinks/bottle.dm | 2 +- mods/gamemodes/cult/ritual.dm | 2 +- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index e95fac6faa6e..55874616e038 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -248,6 +248,7 @@ // Misc general data. #define DATA_COOLDOWN_TIME /decl/reagent_data_field/cooldown_time +#define DATA_WATER_HOLINESS /decl/reagent_data_field/holy //Used by show_message() and emotes #define VISIBLE_MESSAGE 1 diff --git a/code/__defines/reagent_data_fields.dm b/code/__defines/reagent_data_fields.dm index db7b27ed7168..04998150bd8d 100644 --- a/code/__defines/reagent_data_fields.dm +++ b/code/__defines/reagent_data_fields.dm @@ -65,3 +65,6 @@ /decl/reagent_data_field/cooldown_time uid = "rdf_cooldown_time" + +/decl/reagent_data_field/holy + uid = "rdf_water_holy" \ No newline at end of file diff --git a/code/game/objects/items/weapons/storage/bible.dm b/code/game/objects/items/weapons/storage/bible.dm index b0f2429fd34e..37a12e8d3dcc 100644 --- a/code/game/objects/items/weapons/storage/bible.dm +++ b/code/game/objects/items/weapons/storage/bible.dm @@ -89,7 +89,7 @@ if(proximity && user?.mind?.assigned_job?.is_holy) if(A.reagents && A.reagents.has_reagent(/decl/material/liquid/water)) //blesses all the water in the holder to_chat(user, SPAN_NOTICE("You bless \the [A].")) // I wish it was this easy in nethack - LAZYSET(A.reagents.reagent_data, /decl/material/liquid/water, list("holy" = TRUE)) + LAZYSET(A.reagents.reagent_data, /decl/material/liquid/water, list(DATA_WATER_HOLINESS = TRUE)) /obj/item/bible/attackby(obj/item/used_item, mob/user) if(storage?.use_sound) diff --git a/code/modules/materials/definitions/liquids/materials_liquid_water.dm b/code/modules/materials/definitions/liquids/materials_liquid_water.dm index c02b25369e93..3c1a5adbc39a 100644 --- a/code/modules/materials/definitions/liquids/materials_liquid_water.dm +++ b/code/modules/materials/definitions/liquids/materials_liquid_water.dm @@ -58,7 +58,7 @@ ..() if(ishuman(M)) var/list/data = REAGENT_DATA(holder, src) - if(data?["holy"]) + if(data?[DATA_WATER_HOLINESS]) affect_holy(M, removed, holder) /decl/material/liquid/water/proc/affect_holy(mob/living/M, removed, datum/reagents/holder) @@ -97,7 +97,7 @@ touching_turf.visible_message(SPAN_NOTICE("The water sizzles as it lands on \the [touching_turf]!")) var/list/data = REAGENT_DATA(holder, src) - if(LAZYACCESS(data, "holy")) + if(LAZYACCESS(data, DATA_WATER_HOLINESS)) touching_turf.turf_flags |= TURF_FLAG_HOLY /decl/material/liquid/water/touch_obj(var/obj/O, var/amount, var/datum/reagents/holder) diff --git a/code/modules/reagents/reagent_containers/drinks/bottle.dm b/code/modules/reagents/reagent_containers/drinks/bottle.dm index 779d4a274e46..3de103abcbb2 100644 --- a/code/modules/reagents/reagent_containers/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/drinks/bottle.dm @@ -314,7 +314,7 @@ center_of_mass = @'{"x":17,"y":10}' /obj/item/chems/drinks/bottle/holywater/populate_reagents() - add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume, list("holy" = TRUE)) + add_to_reagents(/decl/material/liquid/water, reagents.maximum_volume, list(DATA_WATER_HOLINESS = TRUE)) /obj/item/chems/drinks/bottle/vermouth name = "Goldeneye Vermouth" diff --git a/mods/gamemodes/cult/ritual.dm b/mods/gamemodes/cult/ritual.dm index a6c6a1a3f748..27c5390851a4 100644 --- a/mods/gamemodes/cult/ritual.dm +++ b/mods/gamemodes/cult/ritual.dm @@ -29,7 +29,7 @@ return if(A.reagents && A.reagents.has_reagent(/decl/material/liquid/water)) to_chat(user, SPAN_NOTICE("You desecrate \the [A].")) - LAZYSET(A.reagents.reagent_data, /decl/material/liquid/water, list("holy" = FALSE)) + LAZYSET(A.reagents.reagent_data, /decl/material/liquid/water, list(DATA_WATER_HOLINESS = FALSE)) /mob/proc/make_rune(var/rune, var/cost = 5, var/tome_required = 0) var/has_robes = 0 From 22c08267dda0ec847210148c190c2ca0ed8985b8 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 20:54:16 -0400 Subject: [PATCH 435/512] Attempt to fix default bodytype accessories not applying --- .../client/preference_setup/general/02_body.dm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/code/modules/client/preference_setup/general/02_body.dm b/code/modules/client/preference_setup/general/02_body.dm index 6f23e996d2ce..44496bd2601f 100644 --- a/code/modules/client/preference_setup/general/02_body.dm +++ b/code/modules/client/preference_setup/general/02_body.dm @@ -24,7 +24,24 @@ // pref.sprite_accessories is sprite_accessories[accessory_category.type][loaded_accessory.type] = metadata // snapshot.sprite_accessories is sprite_accessories[organ_tag][accessory_category.type][loaded_accessory.type] = metadata // we have to convert it here + // on the bright side bodytype.default_sprite_accessories uses the same format var/list/new_sprite_accessories = list() + // THIS IS HACKY. PLEASE FIND A BETTER WAY TO DO THIS + // Adds default bodytype accessories to the snapshot. + var/decl/bodytype/the_bodytype = pref.get_bodytype_decl() + for(var/accessory_category in the_bodytype.default_sprite_accessories) + var/decl/sprite_accessory_category/acc_cat = GET_DECL(accessory_category) + if(!acc_cat.always_apply_defaults) + continue + var/list/accessories = the_bodytype.default_sprite_accessories[accessory_category] + acc_cat.prepare_mob_snapshot(snapshot, accessories) + for(var/accessory in accessories) + var/decl/sprite_accessory/accessory_decl = GET_DECL(accessory) + var/accessory_metadata = accessories[accessory] + for(var/bodypart in accessory_decl.body_parts) + LAZYINITLIST(new_sprite_accessories[bodypart]) + LAZYSET(new_sprite_accessories[bodypart][accessory_category], accessory, accessory_metadata) + // jank shit end for(var/accessory_category in pref.sprite_accessories) var/decl/sprite_accessory_category/acc_cat = GET_DECL(accessory_category) var/list/accessories = pref.sprite_accessories[accessory_category] From bc2eda1a0381a5b34417de26dc7b812b85037d00 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 07:45:42 -0400 Subject: [PATCH 436/512] Fix incorrect usage of machinery uid var --- code/game/machinery/computer/guestpass.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm index fb0011651ebf..4fcf1b94292d 100644 --- a/code/game/machinery/computer/guestpass.dm +++ b/code/game/machinery/computer/guestpass.dm @@ -58,13 +58,14 @@ var/reason = "NOT SPECIFIED" var/duration_max = 60 var/duration = 5 + var/terminal_serial var/list/internal_log = list() var/mode = 0 // 0 - making pass, 1 - viewing logs /obj/machinery/computer/guestpass/Initialize() . = ..() - uid = "[random_id("guestpass_serial_number",100,999)]-G[rand(10,99)]" + terminal_serial = "[random_id("guestpass_serial_number",100,999)]-G[rand(10,99)]" /obj/machinery/computer/guestpass/attackby(obj/used_item, mob/user) if(istype(used_item, /obj/item/card/id)) @@ -158,7 +159,7 @@ . = TOPIC_REFRESH else if (href_list["print"]) - var/dat = "

    Activity log of guest pass terminal #[uid]


    " + var/dat = "

    Activity log of guest pass terminal #[terminal_serial]


    " for (var/entry in internal_log) dat += "[entry]

    " var/obj/item/paper/paper = new/obj/item/paper( loc ) From 23c61f6fba59cd5ebedb8df94b4eb117cc2ad157 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 07:51:40 -0400 Subject: [PATCH 437/512] Fix incorrect typehint in sound_player constructor --- code/modules/synthesized_instruments/sound_player.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/synthesized_instruments/sound_player.dm b/code/modules/synthesized_instruments/sound_player.dm index 20df81d5456c..dcedc7096001 100644 --- a/code/modules/synthesized_instruments/sound_player.dm +++ b/code/modules/synthesized_instruments/sound_player.dm @@ -21,7 +21,7 @@ var/list/datum/sound_token/instrument/tokens = list() var/list/seen_turfs -/datum/sound_player/New(datum/real_instrument/where, datum/instrument/what) +/datum/sound_player/New(obj/where, datum/instrument/what) src.song = new (src, what) src.actual_instrument = where src.echo = global.musical_config.echo_default.Copy() From f826601c47b0c20c730d2786059f0be255794d39 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 07:54:04 -0400 Subject: [PATCH 438/512] Fix incorrect return value in pick_area_turf_by_flag --- code/_helpers/areas.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/_helpers/areas.dm b/code/_helpers/areas.dm index e985579e0abe..c26f3d2e9969 100644 --- a/code/_helpers/areas.dm +++ b/code/_helpers/areas.dm @@ -42,7 +42,7 @@ continue valid_areas[candidate_area] = TRUE if(!length(valid_areas)) // no turfs at all have that flag - return FALSE + return null // Each area contents loop is an in-world loop, so we just do one here. for(var/turf/turf_candidate in world) var/area/candidate_area = get_area(turf_candidate) @@ -50,8 +50,7 @@ continue if(!predicates || all_predicates_true(list(turf_candidate), predicates)) LAZYADD(turfs, turf_candidate) - if(LAZYLEN(turfs)) - return pick(turfs) + return SAFEPICK(turfs) /proc/pick_area_turf(var/areatype, var/list/predicates) var/list/turfs = get_area_turfs(areatype, predicates) From 47ef0cf49961f4ebf443caabce99076dd89a6242 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 21:03:16 -0400 Subject: [PATCH 439/512] Apply hacky fix for psi handler self-deletion --- code/datums/extensions/abilities/ability_handler.dm | 4 ++-- .../psionics/system/psionics/complexus/complexus_process.dm | 4 ++-- mods/content/psionics/system/psionics/mob/mob.dm | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/datums/extensions/abilities/ability_handler.dm b/code/datums/extensions/abilities/ability_handler.dm index d215868a4c58..5ac742b00384 100644 --- a/code/datums/extensions/abilities/ability_handler.dm +++ b/code/datums/extensions/abilities/ability_handler.dm @@ -21,7 +21,7 @@ if(!istype(owner)) CRASH("Ability handler received invalid owner!") ..() - refresh_login() + refresh_login(being_created = TRUE) /datum/ability_handler/Process() @@ -211,7 +211,7 @@ stat(stat_strings[1], stat_strings[2]) /// Individual ability methods/disciplines (psioncs, etc.) so that mobs can have multiple. -/datum/ability_handler/proc/refresh_login() +/datum/ability_handler/proc/refresh_login(being_created = FALSE) SHOULD_CALL_PARENT(TRUE) if(LAZYLEN(screen_elements)) var/list/add_elements = list() diff --git a/mods/content/psionics/system/psionics/complexus/complexus_process.dm b/mods/content/psionics/system/psionics/complexus/complexus_process.dm index 175269b56405..82883b67dc62 100644 --- a/mods/content/psionics/system/psionics/complexus/complexus_process.dm +++ b/mods/content/psionics/system/psionics/complexus/complexus_process.dm @@ -1,4 +1,4 @@ -/datum/ability_handler/psionics/proc/update(var/force) +/datum/ability_handler/psionics/proc/update(var/force, can_delete = TRUE) set waitfor = FALSE @@ -23,7 +23,7 @@ var/rank_count = max(1, LAZYLEN(ranks)) if(force || last_rating != ceil(combined_rank/rank_count)) if(highest_rank <= 1) - if(highest_rank == 0) + if(highest_rank == 0 && can_delete) // hack to prevent deletion on update(TRUE) in New qdel(src) return else diff --git a/mods/content/psionics/system/psionics/mob/mob.dm b/mods/content/psionics/system/psionics/mob/mob.dm index 15cc79147421..c7bc95cc25c9 100644 --- a/mods/content/psionics/system/psionics/mob/mob.dm +++ b/mods/content/psionics/system/psionics/mob/mob.dm @@ -1,6 +1,7 @@ -/datum/ability_handler/psionics/refresh_login() +/datum/ability_handler/psionics/refresh_login(being_created) . = ..() - update(TRUE) + // stopgap to prevent us from deleting ourselves during init + update(TRUE, can_delete = !being_created) if(!suppressed) show_auras() From 2b02af7ff012229f7c76d0d621638926d4332445 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 21:04:41 -0400 Subject: [PATCH 440/512] Fix awkward typo in mind-read power --- mods/content/psionics/system/psionics/faculties/coercion.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/content/psionics/system/psionics/faculties/coercion.dm b/mods/content/psionics/system/psionics/faculties/coercion.dm index eca5436d6316..fd4943113522 100644 --- a/mods/content/psionics/system/psionics/faculties/coercion.dm +++ b/mods/content/psionics/system/psionics/faculties/coercion.dm @@ -67,7 +67,7 @@ return if(target.stat == DEAD || (target.status_flags & FAKEDEATH) || !target.client) - to_chat(user, SPAN_WARNING("\The [target] is in no state for a mind-ream.")) + to_chat(user, SPAN_WARNING("\The [target] is in no state for a mind-read.")) return TRUE user.visible_message(SPAN_WARNING("\The [user] touches \the [target]'s temple...")) From 5c86dccbc1edf25197a322df86790b649843827d Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 21:04:54 -0400 Subject: [PATCH 441/512] Fix extraneous unused toggle button in psi HUD --- mods/content/psionics/system/psionics/complexus/complexus.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/content/psionics/system/psionics/complexus/complexus.dm b/mods/content/psionics/system/psionics/complexus/complexus.dm index 0ce5f4cfc189..b839c057513a 100644 --- a/mods/content/psionics/system/psionics/complexus/complexus.dm +++ b/mods/content/psionics/system/psionics/complexus/complexus.dm @@ -1,4 +1,6 @@ /datum/ability_handler/psionics + category_toggle_type = null // we don't use this at the moment, but maybe should eventually. + var/announced = FALSE // Whether or not we have been announced to our holder yet. var/suppressed = TRUE // Whether or not we are suppressing our psi powers. var/use_psi_armour = TRUE // Whether or not we should automatically deflect/block incoming damage. From bd3de2b248a7ec9b8145aa8cdf9facef17e16767 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 20:05:17 -0400 Subject: [PATCH 442/512] Add a message implying that skill affects planetoid sensor readings --- code/modules/overmap/planetoids/_planetoids.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/overmap/planetoids/_planetoids.dm b/code/modules/overmap/planetoids/_planetoids.dm index 492d842b9953..87df92be13dc 100644 --- a/code/modules/overmap/planetoids/_planetoids.dm +++ b/code/modules/overmap/planetoids/_planetoids.dm @@ -64,7 +64,7 @@ var/inaccuracy = rand(8,12)/10 . += "Atmosphere pressure [atmosphere.return_pressure()*inaccuracy] kPa, temperature [atmosphere.temperature*inaccuracy] K
    " else if(user.skill_check(SKILL_SCIENCE, SKILL_BASIC) || user.skill_check(SKILL_ATMOS, SKILL_BASIC)) - . += "Atmosphere present
    " + . += "Atmosphere present. Sensor suite calibration required for detailed scan. Contact a qualified technician for calibration assistance.
    " . += "
    " var/datum/planetoid_data/E = get_planetoid_data() From 33238d1e0e5e4d8b10d1b2731b589d13f48a4825 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 25 Jul 2025 02:08:16 -0400 Subject: [PATCH 443/512] Fix being able to teleport objects via diagonal grabs --- code/datums/movement/movement.dm | 5 +-- code/game/atoms_movable.dm | 4 ++- code/modules/mob/grab/grab_object.dm | 2 +- code/modules/mob/mob_movement.dm | 46 +++++++++------------------- code/modules/multiz/movement.dm | 1 + 5 files changed, 20 insertions(+), 38 deletions(-) diff --git a/code/datums/movement/movement.dm b/code/datums/movement/movement.dm index ffe142f72310..a4f79e092ffc 100644 --- a/code/datums/movement/movement.dm +++ b/code/datums/movement/movement.dm @@ -90,10 +90,7 @@ if(LAZYLEN(movement_handlers) && ispath(movement_handlers[1])) { \ var/oldloc = loc var/turf/T = get_step(loc, direction) if(istype(T)) - if(direction in global.cornerdirs) // Diagonal movement with step() currently breaks - forceMove(T) // grabs, remove these lines when that is fixed. - else - step(src, direction) + step(src, direction) return loc != oldloc for(var/datum/movement_handler/movement_handler as anything in movement_handlers) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 723183aa1d25..5633312354f0 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -22,7 +22,9 @@ // var/elevation = 2 - not used anywhere var/move_speed = 10 var/l_move_time = 1 - var/m_flag = 1 + var/const/FIRST_DIAGONAL_STEP = 1 + var/const/SECOND_DIAGONAL_STEP = 2 + var/moving_diagonally = FALSE // Used so we don't break grabs mid-diagonal-move. var/datum/thrownthing/throwing var/throw_speed = 2 var/throw_range = 7 diff --git a/code/modules/mob/grab/grab_object.dm b/code/modules/mob/grab/grab_object.dm index 9d62004fbe1a..583622739a99 100644 --- a/code/modules/mob/grab/grab_object.dm +++ b/code/modules/mob/grab/grab_object.dm @@ -175,7 +175,7 @@ current_grab.let_go(src) /obj/item/grab/proc/on_affecting_move() - if(!affecting || !isturf(affecting.loc) || get_dist(affecting, assailant) > 1) + if(!affecting || !isturf(affecting.loc) || (get_dist(affecting, assailant) > 1 && affecting.moving_diagonally != /atom/movable::FIRST_DIAGONAL_STEP)) force_drop() /obj/item/grab/proc/force_drop() diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 621d6b5425a7..534d18df8953 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -87,37 +87,7 @@ //This proc should never be overridden elsewhere at /atom/movable to keep directions sane. /atom/movable/Move(newloc, direct) - if (direct & (direct - 1)) - if (direct & 1) - if (direct & 4) - if (step(src, NORTH)) - step(src, EAST) - else - if (step(src, EAST)) - step(src, NORTH) - else - if (direct & 8) - if (step(src, NORTH)) - step(src, WEST) - else - if (step(src, WEST)) - step(src, NORTH) - else - if (direct & 2) - if (direct & 4) - if (step(src, SOUTH)) - step(src, EAST) - else - if (step(src, EAST)) - step(src, SOUTH) - else - if (direct & 8) - if (step(src, SOUTH)) - step(src, WEST) - else - if (step(src, WEST)) - step(src, SOUTH) - else + if (IS_POWER_OF_TWO(direct)) var/atom/A = src.loc var/olddir = dir //we can't override this without sacrificing the rest of movable/New() @@ -128,9 +98,21 @@ src.move_speed = world.time - src.l_move_time src.l_move_time = world.time - src.m_flag = 1 if ((A != src.loc && A && A.z == src.z)) src.last_move = get_dir(A, src.loc) + else // This doesn't handle 3D moves properly, but the old code didn't either. + moving_diagonally = /atom/movable::FIRST_DIAGONAL_STEP + var/first_dir = FIRST_DIR(direct) + var/second_dir = direct & ~first_dir + if(step(src, first_dir)) + if(moving_diagonally) // check if unset by falling + moving_diagonally = /atom/movable::SECOND_DIAGONAL_STEP + step(src, second_dir) + else if(step(src, second_dir)) + if(moving_diagonally) + moving_diagonally = /atom/movable::SECOND_DIAGONAL_STEP + step(src, first_dir) + moving_diagonally = FALSE if(!inertia_moving) inertia_next_move = world.time + inertia_move_delay diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index 02f09cd94403..1b02cdf9dee4 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -121,6 +121,7 @@ // Entered() which is part of Move(), by spawn()ing we let that complete. But we want to preserve if we were in client movement // or normal movement so other move behavior can continue. /atom/movable/proc/begin_falling(var/lastloc, var/below) + moving_diagonally = FALSE // cancel diagonal movement immediately addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/movable, fall_callback), below), 0) /atom/movable/proc/fall_callback(var/turf/below) From 54db4399606ff3e067f18cc2ef15d39e410e6253 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 25 Jul 2025 02:11:32 -0400 Subject: [PATCH 444/512] Fix grabs not checking distance on Z axis --- code/_helpers/game.dm | 5 +++++ code/modules/mob/grab/grab_object.dm | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/code/_helpers/game.dm b/code/_helpers/game.dm index ed24cf936518..0ee70c257499 100644 --- a/code/_helpers/game.dm +++ b/code/_helpers/game.dm @@ -104,6 +104,11 @@ //turfs += centerturf return atoms +/// Despite what the ref says, get_dist does not factor in the Z axis. +/// This is just get_dist() but Z-aware. +/proc/get_dist_3d(atom/Loc1, atom/Loc2) + return max(abs(Loc1.x-Loc2.x), abs(Loc1.y-Loc2.y), abs(Loc1.z-Loc2.z)) + /proc/get_dist_euclidian(atom/Loc1, atom/Loc2) var/dx = Loc1.x - Loc2.x var/dy = Loc1.y - Loc2.y diff --git a/code/modules/mob/grab/grab_object.dm b/code/modules/mob/grab/grab_object.dm index 583622739a99..80bab9a29892 100644 --- a/code/modules/mob/grab/grab_object.dm +++ b/code/modules/mob/grab/grab_object.dm @@ -175,7 +175,7 @@ current_grab.let_go(src) /obj/item/grab/proc/on_affecting_move() - if(!affecting || !isturf(affecting.loc) || (get_dist(affecting, assailant) > 1 && affecting.moving_diagonally != /atom/movable::FIRST_DIAGONAL_STEP)) + if(!affecting || !isturf(affecting.loc) || (get_dist_3d(affecting, assailant) > 1 && affecting.moving_diagonally != /atom/movable::FIRST_DIAGONAL_STEP)) force_drop() /obj/item/grab/proc/force_drop() From 8706afbfa79238ddb4f39a783b7e46bd8b738545 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Fri, 25 Jul 2025 02:11:20 -0400 Subject: [PATCH 445/512] Fix warning when trying to grab an openspace mimic --- code/modules/multiz/zmimic/mimic_movable.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm index beb749f6fc68..acab9cef82b4 100644 --- a/code/modules/multiz/zmimic/mimic_movable.dm +++ b/code/modules/multiz/zmimic/mimic_movable.dm @@ -145,6 +145,10 @@ SHOULD_CALL_PARENT(FALSE) . = associated_atom.examine(arglist(args)) // just pass all the args to the copied atom +// Trying to grab a mimic tries to grab the copied atom instead. +/atom/movable/openspace/mimic/try_make_grab(mob/living/user, defer_hand) + return associated_atom.try_make_grab(user, defer_hand) + /atom/movable/openspace/mimic/forceMove(turf/dest) var/atom/old_loc = loc . = ..() From 1d86db4938d97bec7dc0a96120852e90d5e3fad5 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 19:27:49 -0400 Subject: [PATCH 446/512] Fix missing return values in update_attack_force --- code/game/objects/items/blades/folding.dm | 2 +- code/game/objects/items/weapons/material/folding.dm | 3 +-- code/game/objects/items/weapons/material/swiss.dm | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/blades/folding.dm b/code/game/objects/items/blades/folding.dm index 69f2de5f8fa2..4e17de8dd942 100644 --- a/code/game/objects/items/blades/folding.dm +++ b/code/game/objects/items/blades/folding.dm @@ -52,7 +52,7 @@ icon_state = "[icon_state]-closed" /obj/item/bladed/folding/update_attack_force() - ..() + . = ..() // TODO: check sharp/edge. edge = open sharp = open diff --git a/code/game/objects/items/weapons/material/folding.dm b/code/game/objects/items/weapons/material/folding.dm index 46a631afe6db..b686c074ba8c 100644 --- a/code/game/objects/items/weapons/material/folding.dm +++ b/code/game/objects/items/weapons/material/folding.dm @@ -27,14 +27,13 @@ add_fingerprint(user) /obj/item/knife/folding/update_attack_force() - ..() + . = ..() if(open) // TODO: check sharp/edge. edge = TRUE sharp = TRUE w_class = ITEM_SIZE_NORMAL attack_verb = list("slashed", "stabbed") - ..() else edge = initial(edge) sharp = initial(sharp) diff --git a/code/game/objects/items/weapons/material/swiss.dm b/code/game/objects/items/weapons/material/swiss.dm index 5cb933d62368..a14d20625089 100644 --- a/code/game/objects/items/weapons/material/swiss.dm +++ b/code/game/objects/items/weapons/material/swiss.dm @@ -91,7 +91,7 @@ to_chat(user, active_tool == SWISSKNF_CLOSED ? "It is closed." : "Its [lowertext(active_tool)] is folded out.") /obj/item/knife/folding/swiss/update_attack_force() - ..() + . = ..() if(active_tool == SWISSKNF_CLOSED) w_class = initial(w_class) else From 00c6ec5b992f1262365c4f0971b9fe371f17d709 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 24 Jul 2025 21:05:36 -0400 Subject: [PATCH 447/512] Fix flipped standalone table frames being invisible --- code/game/objects/structures/tables.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/game/objects/structures/tables.dm b/code/game/objects/structures/tables.dm index 1d839db87bb7..0f0cc8f4ab9d 100644 --- a/code/game/objects/structures/tables.dm +++ b/code/game/objects/structures/tables.dm @@ -325,11 +325,10 @@ var/flip_mod = "" if(left_neighbor_blend && right_neighbor_blend) flip_type = 2 - icon_state = "flip[flip_type]" else if(left_neighbor_blend || right_neighbor_blend) flip_type = 1 flip_mod = (left_neighbor_blend ? "+" : "-") - icon_state = "flip[flip_type][flip_mod]" + icon_state = "flip[flip_type][flip_mod]" color = material.color alpha = 255 * material.opacity From 13e491c81523fc9f962522d8fb2115c760b8edd1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 07:55:15 -0400 Subject: [PATCH 448/512] Fix missing return values in set_dir --- code/game/machinery/turrets/_turrets.dm | 2 +- code/modules/atmospherics/he_pipes.dm | 2 +- code/modules/mechs/components/_components.dm | 2 +- code/modules/mob/mob.dm | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/turrets/_turrets.dm b/code/game/machinery/turrets/_turrets.dm index e8a410353ca2..04d2382fa199 100644 --- a/code/game/machinery/turrets/_turrets.dm +++ b/code/game/machinery/turrets/_turrets.dm @@ -236,7 +236,7 @@ return angle_between_two_angles(leftmost_traverse, angle, rightmost_traverse) /obj/machinery/turret/set_dir(ndir) - ..() + . = ..() calculate_traverse() // Instantly turns the turret to a specific absolute angle. diff --git a/code/modules/atmospherics/he_pipes.dm b/code/modules/atmospherics/he_pipes.dm index 14355d9471b5..7d60d3ace894 100644 --- a/code/modules/atmospherics/he_pipes.dm +++ b/code/modules/atmospherics/he_pipes.dm @@ -119,5 +119,5 @@ // Doubling up on initialize_directions is necessary to allow HE pipes to connect /obj/machinery/atmospherics/pipe/simple/heat_exchanging/junction/set_dir(new_dir) - ..() + . = ..() initialize_directions_he = dir \ No newline at end of file diff --git a/code/modules/mechs/components/_components.dm b/code/modules/mechs/components/_components.dm index 8e15b986e06d..d21212476e5d 100644 --- a/code/modules/mechs/components/_components.dm +++ b/code/modules/mechs/components/_components.dm @@ -43,7 +43,7 @@ //These icons have multiple directions but before they're attached we only want south. /obj/item/mech_component/set_dir() - ..(SOUTH) + return ..(SOUTH) /obj/item/mech_component/proc/show_missing_parts(var/mob/user) return diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index f165db28384a..52b024931517 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -909,6 +909,7 @@ return ..(facing_dir) else return ..() + return FALSE /mob/proc/set_stat(var/new_stat) . = stat != new_stat From e8bc1bfb21f7abd5443071be6d8055221248140f Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Thu, 24 Jul 2025 19:09:12 -0400 Subject: [PATCH 449/512] Clean up the Lar Maria away site --- .../away_sites/lar_maria/lar_maria-1.dmm | 129 +++++++++++- .../away_sites/lar_maria/lar_maria-2.dmm | 187 ++++++++++++------ 2 files changed, 249 insertions(+), 67 deletions(-) diff --git a/mods/content/corporate/away_sites/lar_maria/lar_maria-1.dmm b/mods/content/corporate/away_sites/lar_maria/lar_maria-1.dmm index 7b0313e2d201..ac4c19eb0c57 100644 --- a/mods/content/corporate/away_sites/lar_maria/lar_maria-1.dmm +++ b/mods/content/corporate/away_sites/lar_maria/lar_maria-1.dmm @@ -245,6 +245,12 @@ /area/lar_maria/vir_main) "aL" = ( /obj/structure/closet/secure_closet/personal/patient, +/obj/random/contraband{ + spawn_nothing_percentage = 80 + }, +/obj/random/maintenance/medical{ + spawn_nothing_percentage = 70 + }, /turf/floor/tiled/white, /area/lar_maria/vir_main) "aM" = ( @@ -578,6 +584,8 @@ /area/lar_maria/vir_main) "bO" = ( /obj/structure/table/glass, +/obj/random/medical, +/obj/random/medical, /turf/floor/tiled/white, /area/lar_maria/vir_main) "bQ" = ( @@ -904,6 +912,7 @@ /obj/structure/table/glass, /obj/item/firstaid/surgery, /obj/machinery/light, +/obj/random/medical, /turf/floor/tiled/white, /area/lar_maria/vir_main) "cG" = ( @@ -920,6 +929,7 @@ "cI" = ( /obj/structure/table/glass, /obj/item/scalpel, +/obj/random/medical, /turf/floor/tiled/white, /area/lar_maria/vir_main) "cJ" = ( @@ -1206,6 +1216,12 @@ /obj/machinery/light{ dir = 1 }, +/obj/random/contraband{ + spawn_nothing_percentage = 80 + }, +/obj/random/maintenance/medical{ + spawn_nothing_percentage = 70 + }, /turf/floor/tiled/white, /area/lar_maria/vir_aux) "du" = ( @@ -1214,6 +1230,12 @@ /area/lar_maria/vir_aux) "dv" = ( /obj/structure/closet/secure_closet/personal/patient, +/obj/random/contraband{ + spawn_nothing_percentage = 80 + }, +/obj/random/maintenance/medical{ + spawn_nothing_percentage = 70 + }, /turf/floor/tiled/white, /area/lar_maria/vir_aux) "dw" = ( @@ -1621,6 +1643,7 @@ "eF" = ( /obj/structure/table/glass, /obj/item/box/syringes, +/obj/random/medical/lite, /turf/floor/tiled/white, /area/lar_maria/vir_aux) "eG" = ( @@ -1628,6 +1651,10 @@ dir = 4 }, /obj/structure/table/glass, +/obj/random/medical/lite, +/obj/random/maintenance/medical{ + spawn_nothing_percentage = 70 + }, /turf/floor/tiled/white, /area/lar_maria/vir_aux) "eH" = ( @@ -1649,6 +1676,9 @@ /obj/structure/table/steel_reinforced, /obj/random/smokes, /obj/item/gun/energy/taser, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "eK" = ( @@ -1669,7 +1699,15 @@ "eN" = ( /obj/structure/closet, /obj/item/clothing/jumpsuit/red, -/obj/item/gun/projectile/shotgun/pump, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, +/obj/random/projectile/sec{ + spawn_nothing_percentage = 40 + }, +/obj/random/projectile/sec{ + spawn_nothing_percentage = 40 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "eO" = ( @@ -1694,6 +1732,9 @@ dir = 8; pixel_x = 24 }, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "eQ" = ( @@ -1793,12 +1834,16 @@ /obj/machinery/light{ dir = 8 }, +/obj/random/medical/lite, /turf/floor/tiled, /area/lar_maria/sec_wing) "ff" = ( /obj/structure/table/steel_reinforced, /obj/item/chems/spray/pepper, /obj/item/deck/cards, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "fg" = ( @@ -1806,6 +1851,9 @@ /obj/item/baton, /obj/item/baton, /obj/item/baton, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "fh" = ( @@ -1856,11 +1904,18 @@ "fm" = ( /obj/structure/table/steel_reinforced, /obj/item/clothing/head/soft/zhp_cap, +/obj/random/smokes, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "fn" = ( /obj/structure/table/steel_reinforced, /obj/item/handcuffs, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "fo" = ( @@ -1887,7 +1942,9 @@ /obj/structure/cable{ icon_state = "0-2" }, -/obj/machinery/computer/modular, +/obj/machinery/computer/modular{ + dir = 1 + }, /turf/floor/tiled/white, /area/lar_maria/vir_aux) "fr" = ( @@ -1900,6 +1957,10 @@ "fs" = ( /obj/structure/table/glass, /obj/item/box/autoinjectors, +/obj/random/medical/lite, +/obj/random/maintenance/medical{ + spawn_nothing_percentage = 70 + }, /turf/floor/tiled/white, /area/lar_maria/vir_aux) "ft" = ( @@ -2186,6 +2247,9 @@ /obj/structure/cable{ icon_state = "1-4" }, +/obj/structure/cable{ + icon_state = "2-4" + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "fT" = ( @@ -2437,6 +2501,10 @@ /obj/item/stack/material/aerogel/mapped/tritium/ten, /obj/item/wirecutters, /obj/item/wrench, +/obj/random/tech_supply, +/obj/random/tech_supply, +/obj/random/tech_supply, +/obj/random/tool/power, /turf/floor/plating, /area/lar_maria/sec_wing) "gu" = ( @@ -2538,6 +2606,7 @@ /area/lar_maria/vir_access) "gH" = ( /obj/machinery/power/smes/buildable, +/obj/structure/cable, /turf/floor/plating, /area/lar_maria/sec_wing) "gI" = ( @@ -2562,7 +2631,7 @@ /turf/floor/plating, /area/lar_maria/sec_wing) "gL" = ( -/obj/machinery/suit_cycler, +/obj/machinery/suit_cycler/engineering/prepared/atmospheric, /turf/floor/plating, /area/lar_maria/sec_wing) "gM" = ( @@ -3309,6 +3378,9 @@ name = "Cells Dock Lockdown"; pixel_y = 7 }, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, /turf/floor/tiled, /area/lar_maria/sec_wing) "iC" = ( @@ -3447,6 +3519,43 @@ }, /turf/floor/tiled/white, /area/lar_maria/sec_wing) +"ov" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/floor/plating, +/area/lar_maria/sec_wing) +"qL" = ( +/obj/structure/table/glass, +/obj/item/box/freezer, +/obj/random/medical/lite, +/obj/random/maintenance/medical{ + spawn_nothing_percentage = 70 + }, +/turf/floor/tiled/white, +/area/lar_maria/vir_aux) +"vg" = ( +/obj/structure/table/steel_reinforced, +/obj/random/maintenance/security{ + spawn_nothing_percentage = 50 + }, +/turf/floor/tiled, +/area/lar_maria/sec_wing) +"De" = ( +/obj/random/medical/lite, +/turf/floor/tiled/white, +/area/lar_maria/vir_aux) +"Fl" = ( +/obj/machinery/suit_cycler/medical/prepared, +/turf/floor/plating, +/area/lar_maria/sec_wing) +"Ux" = ( +/obj/machinery/door/airlock/security, +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/floor/plating, +/area/lar_maria/sec_wing) (1,1,1) = {" aa @@ -22541,9 +22650,9 @@ cO cO cO cO -hC +vg eK -hC +vg cO iB iK @@ -24555,8 +24664,8 @@ eO fj fy fS -gi -dC +Ux +ov gH cO he @@ -25769,7 +25878,7 @@ cO fN cO dC -gL +Fl cO hk hx @@ -27985,7 +28094,7 @@ du du em ds -eY +qL fq fD ds @@ -28998,7 +29107,7 @@ eG fb ft ds -ds +De dr dr aa diff --git a/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm b/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm index c528322152bd..e6ba0c32dd3b 100644 --- a/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm +++ b/mods/content/corporate/away_sites/lar_maria/lar_maria-2.dmm @@ -509,7 +509,7 @@ /turf/floor/plating, /area/lar_maria/solar_control) "br" = ( -/obj/machinery/suit_cycler, +/obj/machinery/suit_cycler/engineering/prepared/atmospheric, /turf/floor/plating, /area/lar_maria/solar_control) "bs" = ( @@ -618,6 +618,9 @@ /obj/machinery/light{ dir = 1 }, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, /turf/floor/tiled, /area/lar_maria/library) "bJ" = ( @@ -808,31 +811,49 @@ "cr" = ( /obj/structure/bookcase, /obj/item/book/manual/engineering_guide, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, /turf/floor/tiled, /area/lar_maria/library) "cs" = ( /obj/structure/bookcase, /obj/item/book/fluff/stasis, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, /turf/floor/tiled, /area/lar_maria/library) "cu" = ( /obj/structure/bookcase, /obj/item/book/manual/medical_diagnostics_manual, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, /turf/floor/tiled, /area/lar_maria/library) "cv" = ( /obj/structure/bookcase, /obj/item/book/manual/detective, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, /turf/floor/tiled, /area/lar_maria/library) "cx" = ( /obj/structure/bookcase, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, /turf/floor/tiled, /area/lar_maria/library) "cy" = ( /obj/structure/bookcase, /obj/item/book/fluff/anomaly_spectroscopy, /obj/item/book/fluff/anomaly_testing, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, /turf/floor/tiled, /area/lar_maria/library) "cz" = ( @@ -959,7 +980,7 @@ /turf/floor/plating, /area/lar_maria/atmos) "cR" = ( -/obj/machinery/atmospherics/binary/pump{ +/obj/machinery/atmospherics/binary/pump/on{ dir = 4 }, /turf/floor/plating, @@ -1094,7 +1115,11 @@ /area/lar_maria/atmos) "dn" = ( /obj/machinery/atmospherics/omni/mixer{ - dir = 4 + dir = 4; + tag_west = 1; + tag_north = 1; + tag_north_con = 0.79; + tag_west_con = 0.21 }, /turf/floor/plating, /area/lar_maria/atmos) @@ -1106,14 +1131,16 @@ /area/lar_maria/atmos) "dp" = ( /obj/machinery/atmospherics/omni/filter{ - dir = 4 + dir = 4; + tag_south = 8; + tag_filter_gas_south = "gas_carbon_dioxide"; + tag_east = 2; + tag_west = 1 }, -/obj/abstract/landmark/allowed_leak, /turf/floor/plating, /area/lar_maria/atmos) "dr" = ( /obj/machinery/atmospherics/pipe/manifold/hidden/cyan, -/obj/abstract/landmark/allowed_leak, /turf/floor/plating, /area/lar_maria/atmos) "ds" = ( @@ -1179,12 +1206,10 @@ /area/lar_maria/atmos) "dD" = ( /obj/machinery/atmospherics/binary/oxyregenerator, -/obj/abstract/landmark/allowed_leak, /turf/floor/plating, /area/lar_maria/atmos) "dE" = ( /obj/machinery/atmospherics/pipe/simple/visible/blue, -/obj/abstract/landmark/allowed_leak, /turf/floor/plating, /area/lar_maria/atmos) "dF" = ( @@ -1853,6 +1878,7 @@ "fM" = ( /obj/structure/table, /obj/random/gloves, +/obj/random/medical/lite, /turf/floor/tiled, /area/lar_maria/office) "fN" = ( @@ -1866,6 +1892,7 @@ "fP" = ( /obj/structure/table/steel, /obj/random/firstaid, +/obj/random/medical/lite, /turf/floor/tiled, /area/lar_maria/office) "fQ" = ( @@ -2099,6 +2126,7 @@ "gC" = ( /obj/structure/table, /obj/random/trash, +/obj/random/medical/pillbottle, /turf/floor/plating, /area/lar_maria/hallway) "gD" = ( @@ -2248,6 +2276,15 @@ /area/lar_maria/mess_hall) "hb" = ( /obj/structure/closet/crate/trashcart, +/obj/random/trash, +/obj/random/trash, +/obj/random/trash, +/obj/random/useful{ + spawn_nothing_percentage = 70 + }, +/obj/item/book/union_charter{ + dat = "The contents of the book are heavily defaced and nearly illegible." + }, /turf/floor/plating, /area/lar_maria/hallway) "hc" = ( @@ -2367,15 +2404,6 @@ "hu" = ( /turf/floor/plating, /area/lar_maria/hallway) -"hv" = ( -/obj/machinery/power/apc{ - dir = 4; - name = "east bump"; - pixel_x = 24 - }, -/obj/random/trash, -/turf/floor/plating, -/area/lar_maria/hallway) "hw" = ( /obj/structure/cable{ icon_state = "0-4" @@ -2383,6 +2411,11 @@ /obj/effect/floor_decal/industrial/warning{ dir = 1 }, +/obj/machinery/power/apc{ + dir = 8; + name = "west bump"; + pixel_x = -24 + }, /turf/floor/tiled, /area/lar_maria/hallway) "hx" = ( @@ -2993,7 +3026,8 @@ /obj/machinery/button/access/interior{ id_tag = "ZHPDock_airlock"; pixel_x = 25; - pixel_y = -25 + pixel_y = -25; + dir = 8 }, /turf/floor/plating, /area/lar_maria/hallway) @@ -3026,7 +3060,8 @@ "jn" = ( /obj/machinery/airlock_sensor{ id_tag = "ZHPDock_airlock_sensor"; - pixel_x = 25 + pixel_x = 22; + dir = 8 }, /turf/floor/plating, /area/lar_maria/hallway) @@ -3089,6 +3124,14 @@ }, /turf/floor/plating, /area/lar_maria/solar_control) +"nm" = ( +/obj/structure/bookcase, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 + }, +/obj/item/book/manual/evaguide, +/turf/floor/tiled, +/area/lar_maria/library) "ob" = ( /obj/structure/ladder, /obj/machinery/light/small{ @@ -3097,13 +3140,6 @@ }, /turf/floor/plating, /area/lar_maria/solar_control) -"ok" = ( -/obj/machinery/atmospherics/binary/pump{ - dir = 4 - }, -/obj/abstract/landmark/allowed_leak, -/turf/floor/plating, -/area/lar_maria/atmos) "pb" = ( /obj/machinery/atmospherics/binary/pump{ dir = 8 @@ -3161,18 +3197,29 @@ /obj/machinery/light/small, /turf/floor/plating, /area/lar_maria/atmos) +"uf" = ( +/obj/machinery/atmospherics/omni/filter{ + dir = 4; + tag_south = 8; + tag_filter_gas_south = "gas_oxygen"; + tag_east = 2; + tag_west = 1 + }, +/turf/floor/plating, +/area/lar_maria/atmos) "vb" = ( /obj/structure/hygiene/sink{ dir = 4; pixel_x = 11 }, -/obj/structure/mirror{ - pixel_x = 30 - }, /obj/machinery/alarm{ pixel_y = 23; req_access = newlist() }, +/obj/structure/mirror{ + pixel_x = 29; + dir = 8 + }, /turf/floor/tiled/white, /area/lar_maria/head_m) "wb" = ( @@ -3181,11 +3228,21 @@ pixel_x = 11 }, /obj/structure/mirror{ - pixel_x = 30 + pixel_x = 29; + dir = 8 }, /obj/random/trash, /turf/floor/tiled/white, /area/lar_maria/head_m) +"wW" = ( +/obj/machinery/atmospherics/omni/filter{ + dir = 4; + tag_north = 8; + tag_east = 2; + tag_west = 1 + }, +/turf/floor/plating, +/area/lar_maria/atmos) "xb" = ( /obj/structure/hygiene/sink{ dir = 8; @@ -3193,35 +3250,51 @@ pixel_y = 2 }, /obj/structure/mirror{ - pixel_x = -30 + pixel_x = -29; + dir = 4 }, /turf/floor/tiled/white, /area/lar_maria/head_f) +"xx" = ( +/obj/machinery/atmospherics/pipe/simple/visible/universal, +/turf/floor/plating, +/area/lar_maria/atmos) "Ag" = ( -/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{ +/obj/machinery/atmospherics/pipe/manifold/visible/red{ dir = 8 }, -/obj/abstract/landmark/allowed_leak, /turf/floor/plating, /area/lar_maria/atmos) +"Am" = ( +/obj/machinery/embedded_controller/radio/airlock/airlock_controller{ + id_tag = "ZHPDock"; + tag_airpump = "ZHPEastSolar_pump"; + tag_chamber_sensor = "ZHPEastSolar_sensor"; + tag_exterior_door = "ZHPEastSolar_outer"; + tag_interior_door = "ZHPEastSolar_inner"; + dir = 4; + pixel_x = -22 + }, +/turf/floor/plating, +/area/lar_maria/hallway) "DG" = ( /obj/machinery/computer/modular{ dir = 1 }, /turf/floor/tiled, /area/lar_maria/office) -"FZ" = ( -/obj/machinery/atmospherics/pipe/simple/visible/red, -/obj/abstract/landmark/allowed_leak, +"Kg" = ( +/obj/machinery/suit_cycler/medical/prepared, /turf/floor/plating, -/area/lar_maria/atmos) -"YS" = ( -/obj/machinery/atmospherics/pipe/simple/visible/red{ - dir = 10 +/area/lar_maria/solar_control) +"NR" = ( +/obj/structure/bookcase, +/obj/random/single/textbook{ + spawn_nothing_percentage = 80 }, -/obj/abstract/landmark/allowed_leak, -/turf/floor/plating, -/area/lar_maria/atmos) +/obj/item/book/union_charter, +/turf/floor/tiled, +/area/lar_maria/library) (1,1,1) = {" aa @@ -20885,7 +20958,7 @@ bw bw bI cd -cx +NR cM di cd @@ -21489,7 +21562,7 @@ aA ad bw bw -cx +nm cf cx cO @@ -22503,7 +22576,7 @@ pb ci cA cR -ok +cR dB tb bx @@ -22517,7 +22590,7 @@ ex eu gC hd -hv +hc hS iq iN @@ -22704,7 +22777,7 @@ bx bM ci cn -YS +cl dn dB bM @@ -22901,13 +22974,13 @@ aY bg nb br -br +Kg bx bN ci cn cn -ok +cR dC dO bx @@ -23333,7 +23406,7 @@ je jg ji jm -hu +Am jo jq aa @@ -23511,10 +23584,10 @@ bA bG bQ ck -bQ cU +xx Ag -bQ +xx dR bG eA @@ -23713,8 +23786,8 @@ bB bx bR ci -cn cV +cn dp dD dS @@ -23917,7 +23990,7 @@ bS ci cA cn -dp +uf dE dT bx @@ -24118,8 +24191,8 @@ bx qb cl cB -FZ -dp +cB +wW dF ub bx From 64d3aaac0575dc66a7649e296623d8d1282ce16e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 21 Jul 2025 17:18:36 -0400 Subject: [PATCH 450/512] Improve atmos canister initialization --- code/game/machinery/atmoalter/canister.dm | 108 +++++++--------------- 1 file changed, 35 insertions(+), 73 deletions(-) diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 267f68ff20d5..af152d8b5028 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -21,12 +21,16 @@ var/canister_color = "yellow" var/can_label = TRUE var/temperature_resistance = 1000 + T0C + var/decl/material/start_gas = null /obj/machinery/portable_atmospherics/canister/Initialize(mapload, material) if(ispath(material)) matter = list() matter[material] = 10 * SHEET_MATERIAL_AMOUNT . = ..(mapload) + if(start_gas) + air_contents.adjust_gas(start_gas, MolesForPressure()) + lazy_update_icon() /obj/machinery/portable_atmospherics/canister/drain_power() return -1 @@ -36,45 +40,69 @@ icon_state = "redws" canister_color = "redws" can_label = FALSE + start_gas = /decl/material/gas/nitrous_oxide /obj/machinery/portable_atmospherics/canister/nitrogen name = "nitrogen canister" icon_state = "red" canister_color = "red" can_label = FALSE + start_gas = /decl/material/gas/nitrogen /obj/machinery/portable_atmospherics/canister/nitrogen/prechilled name = "cryogenic nitrogen canister" start_pressure = 20 ATM +/obj/machinery/portable_atmospherics/canister/nitrogen/prechilled/Initialize() + . = ..() + air_contents.temperature = 80 + lazy_update_icon() + /obj/machinery/portable_atmospherics/canister/oxygen name = "oxygen canister" icon_state = "blue" canister_color = "blue" can_label = FALSE + start_gas = /decl/material/gas/oxygen /obj/machinery/portable_atmospherics/canister/oxygen/prechilled name = "cryogenic oxygen canister" start_pressure = 20 ATM +/obj/machinery/portable_atmospherics/canister/oxygen/prechilled/Initialize() + . = ..() + air_contents.temperature = 80 + lazy_update_icon() + /obj/machinery/portable_atmospherics/canister/hydrogen name = "hydrogen canister" icon_state = "purple" canister_color = "purple" can_label = FALSE + start_gas = /decl/material/gas/hydrogen /obj/machinery/portable_atmospherics/canister/carbon_dioxide name = "\improper CO2 canister" icon_state = "black" canister_color = "black" can_label = FALSE + start_gas = /decl/material/gas/carbon_dioxide +// This uses an Initialize override instead of start_gas. /obj/machinery/portable_atmospherics/canister/air name = "air canister" icon_state = "grey" canister_color = "grey" can_label = FALSE +// This doesn't use start_gas because it's a mix. +/obj/machinery/portable_atmospherics/canister/air/Initialize() + . = ..() + var/list/air_mix = StandardAirMix() + air_contents.adjust_gas(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen], FALSE) + air_contents.adjust_gas(/decl/material/gas/nitrogen, air_mix[/decl/material/gas/nitrogen]) + lazy_update_icon() + /obj/machinery/portable_atmospherics/canister/air/airlock start_pressure = 3 ATM @@ -301,65 +329,11 @@ EMPTY_CANISTER(hydrogen, /obj/machinery/portable_atmospherics/canister/hydrogen) return STATUS_CLOSE return ..() -/obj/machinery/portable_atmospherics/canister/oxygen/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/oxygen, MolesForPressure()) - update_icon() - -/obj/machinery/portable_atmospherics/canister/hydrogen/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/hydrogen, MolesForPressure()) - update_icon() - -/obj/machinery/portable_atmospherics/canister/oxygen/prechilled/Initialize() - . = ..() - air_contents.temperature = 80 - update_icon() - -/obj/machinery/portable_atmospherics/canister/sleeping_agent/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/nitrous_oxide, MolesForPressure()) - update_icon() - -/obj/machinery/portable_atmospherics/canister/nitrogen/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/nitrogen, MolesForPressure()) - update_icon() - -/obj/machinery/portable_atmospherics/canister/nitrogen/prechilled/Initialize() - . = ..() - air_contents.temperature = 80 - update_icon() - -/obj/machinery/portable_atmospherics/canister/carbon_dioxide/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/carbon_dioxide, MolesForPressure()) - update_icon() - - -/obj/machinery/portable_atmospherics/canister/air/Initialize() - . = ..() - var/list/air_mix = StandardAirMix() - air_contents.adjust_gas(/decl/material/gas/oxygen, air_mix[/decl/material/gas/oxygen], FALSE) - air_contents.adjust_gas(/decl/material/gas/nitrogen, air_mix[/decl/material/gas/nitrogen]) - update_icon() - - // Special types used for engine setup admin verb, they contain double amount of that of normal canister. -/obj/machinery/portable_atmospherics/canister/nitrogen/engine_setup/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/nitrogen, MolesForPressure()) - update_icon() - -/obj/machinery/portable_atmospherics/canister/carbon_dioxide/engine_setup/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/carbon_dioxide, MolesForPressure()) - update_icon() - -/obj/machinery/portable_atmospherics/canister/hydrogen/engine_setup/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/hydrogen, MolesForPressure()) - update_icon() +#define ENGINE_SETUP_CANISTER(BASE_TYPE) ##BASE_TYPE/engine_setup/start_pressure = BASE_TYPE::start_pressure * 2; +ENGINE_SETUP_CANISTER(/obj/machinery/portable_atmospherics/canister/nitrogen) +ENGINE_SETUP_CANISTER(/obj/machinery/portable_atmospherics/canister/carbon_dioxide) +ENGINE_SETUP_CANISTER(/obj/machinery/portable_atmospherics/canister/hydrogen) // Spawn debug tanks. /obj/machinery/portable_atmospherics/canister/helium @@ -367,31 +341,19 @@ EMPTY_CANISTER(hydrogen, /obj/machinery/portable_atmospherics/canister/hydrogen) icon_state = "black" canister_color = "black" can_label = FALSE - -/obj/machinery/portable_atmospherics/canister/helium/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/helium, MolesForPressure()) - update_icon() + start_gas = /decl/material/gas/helium /obj/machinery/portable_atmospherics/canister/methyl_bromide name = "\improper CH3Br canister" icon_state = "black" canister_color = "black" can_label = FALSE - -/obj/machinery/portable_atmospherics/canister/methyl_bromide/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/methyl_bromide, MolesForPressure()) - update_icon() + start_gas = /decl/material/gas/methyl_bromide /obj/machinery/portable_atmospherics/canister/chlorine name = "chlorine canister" icon_state = "black" canister_color = "black" can_label = FALSE - -/obj/machinery/portable_atmospherics/canister/chlorine/Initialize() - . = ..() - air_contents.adjust_gas(/decl/material/gas/chlorine, MolesForPressure()) - update_icon() + start_gas = /decl/material/gas/chlorine // End debug tanks. From 97fe4fa53789e975188c08a4402ed2f8ab7d20e7 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 23 Jul 2025 08:02:10 -0400 Subject: [PATCH 451/512] Fix modkits passing species uid to GET_DECL --- code/game/objects/items/devices/modkit.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/devices/modkit.dm b/code/game/objects/items/devices/modkit.dm index b5eb44262b35..8b73d443025e 100644 --- a/code/game/objects/items/devices/modkit.dm +++ b/code/game/objects/items/devices/modkit.dm @@ -18,7 +18,7 @@ /obj/item/modkit/Initialize(ml, material_key) if(!target_bodytype) - var/decl/species/species = GET_DECL(global.using_map.default_species) + var/decl/species/species = decls_repository.get_decl_by_id(global.using_map.default_species) target_bodytype = species.default_bodytype.bodytype_flag . = ..() From 6938df126c74e630c61855666c14622b47633d27 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 28 Jul 2025 02:34:57 -0400 Subject: [PATCH 452/512] Fix incorrect indentation Co-authored-by: MistakeNot4892 --- code/modules/overmap/planetoids/_planetoids.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/overmap/planetoids/_planetoids.dm b/code/modules/overmap/planetoids/_planetoids.dm index 87df92be13dc..16ea48dfe92b 100644 --- a/code/modules/overmap/planetoids/_planetoids.dm +++ b/code/modules/overmap/planetoids/_planetoids.dm @@ -64,7 +64,7 @@ var/inaccuracy = rand(8,12)/10 . += "Atmosphere pressure [atmosphere.return_pressure()*inaccuracy] kPa, temperature [atmosphere.temperature*inaccuracy] K
    " else if(user.skill_check(SKILL_SCIENCE, SKILL_BASIC) || user.skill_check(SKILL_ATMOS, SKILL_BASIC)) - . += "Atmosphere present. Sensor suite calibration required for detailed scan. Contact a qualified technician for calibration assistance.
    " + . += "Atmosphere present. Sensor suite calibration required for detailed scan. Contact a qualified technician for calibration assistance.
    " . += "
    " var/datum/planetoid_data/E = get_planetoid_data() From 4853ff26785ba76dca61237d28edc88f5e9bea83 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 18 Aug 2025 17:21:13 -0400 Subject: [PATCH 453/512] Fix incorrect for loop syntax --- code/modules/events/blob.dm | 2 +- code/modules/spells/targeted/targeted.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index 024112263be1..a692cb7e592d 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -15,7 +15,7 @@ log_and_message_admins("Blob spawned in \the [get_area_name(T)]", location = T) Blob = new /obj/effect/blob/core(T) - for(var/i = 1; i < rand(3, 4), i++) + for(var/i = 1; i < rand(3, 4); i++) Blob.Process() /datum/event/blob/tick() diff --git a/code/modules/spells/targeted/targeted.dm b/code/modules/spells/targeted/targeted.dm index 04a69e3b7dab..fb7dc71b2dfb 100644 --- a/code/modules/spells/targeted/targeted.dm +++ b/code/modules/spells/targeted/targeted.dm @@ -99,7 +99,7 @@ Targeted spells have two useful flags: INCLUDEUSER and SELECTABLE. These are exp possible_targets += target if(spell_flags & SELECTABLE) - for(var/i = 1; i<=max_targets, i++) + for(var/i = 1; i<=max_targets; i++) if(!possible_targets.len) break var/mob/M = input(user, "Choose the target for the spell.", "Targeting") as null|mob in possible_targets From 960559a3817519bee8921af1760d86afb49e612a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 18 Aug 2025 17:26:59 -0400 Subject: [PATCH 454/512] Fix SHOULD_CALL_PARENT for item on_update_icon --- code/game/objects/item_materials.dm | 2 +- .../objects/items/devices/radio/headset.dm | 2 +- .../brain_interface/_brain_interface.dm | 1 + .../modules/organs/internal/brain_computer.dm | 1 + code/modules/paperwork/photography.dm | 1 + .../reagents/reagent_containers/condiment.dm | 43 ++++++------------- .../reagents/reagent_containers/drinks/jar.dm | 1 + 7 files changed, 19 insertions(+), 32 deletions(-) diff --git a/code/game/objects/item_materials.dm b/code/game/objects/item_materials.dm index 96d492cfd77b..0b1d26fb26fb 100644 --- a/code/game/objects/item_materials.dm +++ b/code/game/objects/item_materials.dm @@ -1,6 +1,6 @@ /obj/item/on_update_icon() - . = ..() SHOULD_CALL_PARENT(TRUE) + . = ..() cut_overlays() if((material_alteration & MAT_FLAG_ALTERATION_COLOR) && material) color = material.color diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm index 0d58d152d45a..ed308e4410a9 100644 --- a/code/game/objects/items/devices/radio/headset.dm +++ b/code/game/objects/items/devices/radio/headset.dm @@ -16,8 +16,8 @@ return /obj/item/radio/headset/on_update_icon() + . = ..() icon_state = get_world_inventory_state() - cut_overlays() if(on) if(analog) add_overlay("[icon_state]-local") diff --git a/code/modules/brain_interface/_brain_interface.dm b/code/modules/brain_interface/_brain_interface.dm index e96678b314f0..585c9059c499 100644 --- a/code/modules/brain_interface/_brain_interface.dm +++ b/code/modules/brain_interface/_brain_interface.dm @@ -42,6 +42,7 @@ return holding_brain?.get_brainmob(create_if_missing) /obj/item/organ/internal/brain_interface/on_update_icon() + . = ..() icon_state = get_world_inventory_state() if(holding_brain) var/mob/living/brainmob = get_brainmob() diff --git a/code/modules/organs/internal/brain_computer.dm b/code/modules/organs/internal/brain_computer.dm index 78689d8f0598..71342ac14a41 100644 --- a/code/modules/organs/internal/brain_computer.dm +++ b/code/modules/organs/internal/brain_computer.dm @@ -35,6 +35,7 @@ _brainmob.add_language(/decl/language/machine) /obj/item/organ/internal/brain/robotic/on_update_icon() + . = ..() var/mob/living/brainmob = get_brainmob() icon_state = get_world_inventory_state() if(!searching) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 35b050dab6a6..9474d7bb36ac 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -28,6 +28,7 @@ update_icon() /obj/item/camera_film/on_update_icon() + . = ..() var/datum/extension/base_icon_state/bis = get_extension(src, /datum/extension/base_icon_state) if(uses_left > 1) icon_state = "[bis.base_icon_state]" diff --git a/code/modules/reagents/reagent_containers/condiment.dm b/code/modules/reagents/reagent_containers/condiment.dm index df9794efd420..a4863a07b9ea 100644 --- a/code/modules/reagents/reagent_containers/condiment.dm +++ b/code/modules/reagents/reagent_containers/condiment.dm @@ -30,6 +30,8 @@ /decl/material/liquid/nutriment/mayo = /obj/item/chems/condiment/mayo, /decl/material/liquid/nutriment/vinegar = /obj/item/chems/condiment/vinegar ) + /// If TRUE, the icon automatically adjusts based on contents. + var/is_morphic = TRUE /obj/item/chems/condiment/attackby(var/obj/item/W, var/mob/user) if(IS_PEN(W)) @@ -73,6 +75,8 @@ ..() /obj/item/chems/condiment/proc/update_center_of_mass() + if(!is_morphic) + return center_of_mass = is_special_bottle ? initial(is_special_bottle.center_of_mass) : initial(center_of_mass) /obj/item/chems/condiment/on_reagent_change() @@ -81,15 +85,21 @@ update_center_of_mass() /obj/item/chems/condiment/update_container_name() + if(!is_morphic) + return name = is_special_bottle ? initial(is_special_bottle.name) : initial(name) if(label_text) name = addtext(name," ([label_text])") /obj/item/chems/condiment/update_container_desc() + if(!is_morphic) + return desc = is_special_bottle ? initial(is_special_bottle.desc) : initial(desc) /obj/item/chems/condiment/on_update_icon() ..() + if(!is_morphic) // skip updates for certain subtypes + return if(is_special_bottle) icon_state = initial(is_special_bottle.icon_state) else if(LAZYLEN(reagents?.reagent_volumes)) @@ -173,18 +183,7 @@ possible_transfer_amounts = @"[1,2,5,8,10,20]" amount_per_transfer_from_this = 1 volume = 20 - -/obj/item/chems/condiment/small/update_center_of_mass() - return - -/obj/item/chems/condiment/small/update_container_name() - return - -/obj/item/chems/condiment/small/update_container_desc() - return - -/obj/item/chems/condiment/small/on_update_icon() - return + is_morphic = FALSE /obj/item/chems/condiment/small/saltshaker name = "salt shaker" @@ -408,19 +407,11 @@ icon_state = "flour" item_state = "flour" randpixel = 10 + is_morphic = FALSE /obj/item/chems/condiment/flour/populate_reagents() add_to_reagents(/decl/material/liquid/nutriment/flour, reagents.maximum_volume) -/obj/item/chems/condiment/flour/update_container_name() - return - -/obj/item/chems/condiment/flour/update_container_desc() - return - -/obj/item/chems/condiment/flour/on_update_icon() - return - /obj/item/chems/condiment/large name = "large condiment container" possible_transfer_amounts = @"[1,5,10,20,50,100]" @@ -434,15 +425,7 @@ icon_state = "salt" item_state = "flour" randpixel = 10 + is_morphic = FALSE /obj/item/chems/condiment/large/salt/populate_reagents() add_to_reagents(/decl/material/solid/sodiumchloride, reagents.maximum_volume) - -/obj/item/chems/condiment/large/salt/update_container_name() - return - -/obj/item/chems/condiment/large/salt/update_container_desc() - return - -/obj/item/chems/condiment/large/salt/on_update_icon() - return diff --git a/code/modules/reagents/reagent_containers/drinks/jar.dm b/code/modules/reagents/reagent_containers/drinks/jar.dm index aedbbade98df..e22a380e9f78 100644 --- a/code/modules/reagents/reagent_containers/drinks/jar.dm +++ b/code/modules/reagents/reagent_containers/drinks/jar.dm @@ -25,6 +25,7 @@ desc = "A jar. You're not sure what it's supposed to hold." /obj/item/chems/drinks/jar/on_update_icon() + . = ..() if(LAZYLEN(reagents?.reagent_volumes)) icon_state = "jar_what" else From 09c8f8f4b5266d8f3a781238f7934bb047897dbb Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 18 Aug 2025 17:27:16 -0400 Subject: [PATCH 455/512] Fix SHOULD_CALL_PARENT for populate_reagents --- code/modules/reagents/reagent_containers/food.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/reagent_containers/food.dm b/code/modules/reagents/reagent_containers/food.dm index 07fd140edb5e..1447a5533529 100644 --- a/code/modules/reagents/reagent_containers/food.dm +++ b/code/modules/reagents/reagent_containers/food.dm @@ -209,7 +209,7 @@ //Since we automatically create some reagents types for the nutriments, make sure we call this proc when overriding it /obj/item/chems/food/populate_reagents() - . = ..() SHOULD_CALL_PARENT(TRUE) + . = ..() if(nutriment_amt) add_to_reagents(nutriment_type, nutriment_amt, nutriment_desc) From 43c9cbae0e29537c735e7b7ee6da022a8c732fe1 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 18 Aug 2025 17:57:01 -0400 Subject: [PATCH 456/512] Convert C-style for loops with rand() and pick() --- code/game/objects/effects/decals/Cleanable/humans.dm | 4 ++-- code/game/objects/effects/decals/Cleanable/robots.dm | 4 ++-- code/modules/events/blob.dm | 2 +- code/modules/mob/language/language.dm | 4 ++-- code/modules/mob/mob_helpers.dm | 4 ++-- code/modules/projectiles/guns/launcher/money_cannon.dm | 2 +- mods/content/xenobiology/colours/colour_silver.dm | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/code/game/objects/effects/decals/Cleanable/humans.dm b/code/game/objects/effects/decals/Cleanable/humans.dm index a07f8f2a4b04..961d76d1adae 100644 --- a/code/game/objects/effects/decals/Cleanable/humans.dm +++ b/code/game/objects/effects/decals/Cleanable/humans.dm @@ -244,9 +244,9 @@ var/global/list/image/splatter_cache=list() /obj/effect/decal/cleanable/blood/gibs/proc/streak(var/list/directions) spawn (0) var/direction = pick(directions) - for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++) + for (var/i in 1 to pick(1, 200; 2, 150; 3, 50; 4)) sleep(3) - if (i > 0) + if (i > 1) var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(loc) b.basecolor = src.basecolor b.update_icon() diff --git a/code/game/objects/effects/decals/Cleanable/robots.dm b/code/game/objects/effects/decals/Cleanable/robots.dm index 330acc9f3ce0..0876d890e925 100644 --- a/code/game/objects/effects/decals/Cleanable/robots.dm +++ b/code/game/objects/effects/decals/Cleanable/robots.dm @@ -19,9 +19,9 @@ /obj/effect/decal/cleanable/blood/gibs/robot/streak(var/list/directions) spawn (0) var/direction = pick(directions) - for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++) + for (var/i in 1 to pick(1, 200; 2, 150; 3, 50; 4)) sleep(3) - if (i > 0) + if (i > 1) if (prob(40)) var/obj/effect/decal/cleanable/blood/oil/streak = new(src.loc) streak.update_icon() diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm index a692cb7e592d..0f1a74f82f12 100644 --- a/code/modules/events/blob.dm +++ b/code/modules/events/blob.dm @@ -15,7 +15,7 @@ log_and_message_admins("Blob spawned in \the [get_area_name(T)]", location = T) Blob = new /obj/effect/blob/core(T) - for(var/i = 1; i < rand(3, 4); i++) + for(var/i in 1 to rand(2, 3)) Blob.Process() /datum/event/blob/tick() diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index 510b021a8940..ea7621817c27 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -69,9 +69,9 @@ return capitalize(pick(global.first_names_male)) + " " + capitalize(pick(global.last_names)) var/possible_syllables = allow_repeated_syllables ? syllables : syllables.Copy() - for(var/i = 0;i0;x--) + for(var/x in rand(FLOOR(syllable_count/syllable_divisor), syllable_count) to 1 step -1) if(!length(possible_syllables)) break new_name += allow_repeated_syllables ? pick(possible_syllables) : pick_n_take(possible_syllables) diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index a3230baff77a..9c3bc4396bb2 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -269,14 +269,14 @@ var/global/list/global/organ_rel_size = list( /proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added /* Turn text into complete gibberish! */ var/returntext = "" - for(var/i = 1, i <= length_char(t), i++) + for(var/i in 1 to length_char(t)) var/letter = copytext_char(t, i, i+1) if(prob(50)) if(p >= 70) letter = "" - for(var/j = 1, j <= rand(0, 2), j++) + for(var/j in 1 to rand(0, 2)) letter += pick("#","@","*","&","%","$","/", "<", ">", ";","*","*","*","*","*","*","*") returntext += letter diff --git a/code/modules/projectiles/guns/launcher/money_cannon.dm b/code/modules/projectiles/guns/launcher/money_cannon.dm index bb585d1c5347..4f76c99be43d 100644 --- a/code/modules/projectiles/guns/launcher/money_cannon.dm +++ b/code/modules/projectiles/guns/launcher/money_cannon.dm @@ -30,7 +30,7 @@ var/obj/item/cash/bling = new(T) bling.adjust_worth(nv) if(projectile_vomit) - for(var/j = 1, j <= rand(2, 4), j++) + for(var/j in 1 to rand(2, 4)) step(bling, pick(global.cardinal)) if(projectile_vomit) diff --git a/mods/content/xenobiology/colours/colour_silver.dm b/mods/content/xenobiology/colours/colour_silver.dm index cfc1fb8cb718..e313e0e1f2b5 100644 --- a/mods/content/xenobiology/colours/colour_silver.dm +++ b/mods/content/xenobiology/colours/colour_silver.dm @@ -19,11 +19,11 @@ for(var/mob/living/carbon/human/M in viewers(location, null)) if(M.eyecheck() < FLASH_PROTECTION_MODERATE) M.flash_eyes() - for(var/i = 1, i <= 4 + rand(1,2), i++) + for(var/i in 1 to (4 + rand(1, 2))) var/chosen = pick(borks) var/obj/B = new chosen(location) if(B) if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) + for(var/j in 1 to rand(1, 3)) step(B, pick(NORTH, SOUTH, EAST, WEST)) return TRUE From f8c288f8c7b0e50ef0c7cc9f4c05df634e27623f Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Thu, 27 Mar 2025 21:38:33 -0400 Subject: [PATCH 457/512] Add a variant sprite for cobblestone paths --- code/game/turfs/flooring/flooring_path.dm | 1 + code/game/turfs/floors/subtypes/floor_path.dm | 2 +- icons/turf/flooring/path.dmi | Bin 1614 -> 1873 bytes 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/turfs/flooring/flooring_path.dm b/code/game/turfs/flooring/flooring_path.dm index 475573d57730..cb8c06d48c4a 100644 --- a/code/game/turfs/flooring/flooring_path.dm +++ b/code/game/turfs/flooring/flooring_path.dm @@ -27,6 +27,7 @@ icon_base = "cobble" icon_edge_layer = FLOOR_EDGE_PATH flooring_flags = TURF_REMOVE_CROWBAR + has_base_range = 1 /decl/flooring/path/running_bond name = "stone path" diff --git a/code/game/turfs/floors/subtypes/floor_path.dm b/code/game/turfs/floors/subtypes/floor_path.dm index 65e09e4733c7..6b6c1dfca159 100644 --- a/code/game/turfs/floors/subtypes/floor_path.dm +++ b/code/game/turfs/floors/subtypes/floor_path.dm @@ -5,7 +5,7 @@ desc = "A cobbled path made of loose stones." color = COLOR_GRAY icon = 'icons/turf/flooring/path.dmi' - icon_state = "cobble" + icon_state = "cobble0" _flooring = /decl/flooring/path/cobblestone floor_material = /decl/material/solid/stone/sandstone _base_flooring = /decl/flooring/dirt diff --git a/icons/turf/flooring/path.dmi b/icons/turf/flooring/path.dmi index 1f1d1798b3abc6a38fbe29641ec658f917163f70..6c99784bf5b0b75b0f807568d4924b91d1d2758c 100644 GIT binary patch delta 1764 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 Date: Mon, 12 May 2025 17:47:31 -0400 Subject: [PATCH 458/512] Add alternate running bond path tiles --- code/game/turfs/flooring/flooring_path.dm | 2 ++ code/game/turfs/floors/subtypes/floor_path.dm | 2 +- icons/turf/flooring/path.dmi | Bin 1873 -> 2151 bytes 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/code/game/turfs/flooring/flooring_path.dm b/code/game/turfs/flooring/flooring_path.dm index cb8c06d48c4a..cd821d713a86 100644 --- a/code/game/turfs/flooring/flooring_path.dm +++ b/code/game/turfs/flooring/flooring_path.dm @@ -33,10 +33,12 @@ name = "stone path" desc = "A rustic stone path, laid out in a running bond pattern." icon_base = "runningbond" + has_base_range = 3 gender = NEUTER /decl/flooring/path/herringbone name = "stone path" desc = "A rustic stone path, laid out in a herringbone pattern." icon_base = "herringbone" + has_base_range = null gender = NEUTER diff --git a/code/game/turfs/floors/subtypes/floor_path.dm b/code/game/turfs/floors/subtypes/floor_path.dm index 6b6c1dfca159..7d714f8efab9 100644 --- a/code/game/turfs/floors/subtypes/floor_path.dm +++ b/code/game/turfs/floors/subtypes/floor_path.dm @@ -28,7 +28,7 @@ LAZYADD(decals, moss) /turf/floor/path/running_bond - icon_state = "runningbond" + icon_state = "runningbond0" _flooring = /decl/flooring/path/running_bond /turf/floor/path/herringbone diff --git a/icons/turf/flooring/path.dmi b/icons/turf/flooring/path.dmi index 6c99784bf5b0b75b0f807568d4924b91d1d2758c..2f13c15ef5d6dc97fc6e37e4e6532efc77a03363 100644 GIT binary patch delta 2108 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 From d40b707f27cc57e80c65026c37de34c29aa24fe4 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Mon, 18 Aug 2025 18:26:39 -0400 Subject: [PATCH 459/512] Fix wood structure hitsound --- .../materials/definitions/solids/materials_solid_wood.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/materials/definitions/solids/materials_solid_wood.dm b/code/modules/materials/definitions/solids/materials_solid_wood.dm index d488d7e8189f..a99421d434d6 100644 --- a/code/modules/materials/definitions/solids/materials_solid_wood.dm +++ b/code/modules/materials/definitions/solids/materials_solid_wood.dm @@ -26,7 +26,7 @@ dooropen_noise = 'sound/effects/doorcreaky.ogg' door_icon_base = "wood" destruction_desc = "splinters" - hitsound = 'sound/effects/woodhit.ogg' + hitsound = 'sound/effects/hit_wood.ogg' conductive = 0 construction_difficulty = MAT_VALUE_NORMAL_DIY dissolves_into = list( From f5513ea88f2d1222b4901b8be710480bf4054194 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Mon, 18 Aug 2025 18:25:53 -0400 Subject: [PATCH 460/512] Fix boulders spawning inside solid objects --- code/modules/random_map/noise/forage.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/random_map/noise/forage.dm b/code/modules/random_map/noise/forage.dm index 02427d2499d0..8f063cb37806 100644 --- a/code/modules/random_map/noise/forage.dm +++ b/code/modules/random_map/noise/forage.dm @@ -92,7 +92,7 @@ if(T.is_outside()) if(istype(T, /turf/exterior/rock)) - if(prob(15)) // Static as current map has limited amount of rock turfs + if(prob(15) && !T.contains_dense_objects()) // Static as current map has limited amount of rock turfs var/rock_type = pick(forage["rocks"]) new rock_type(T) return From 8aa24b7c9b7d408082aaf56ec25267ae092b3124 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Mon, 18 Aug 2025 18:26:06 -0400 Subject: [PATCH 461/512] Fix trenches along map edge --- code/game/turfs/floors/floor_icon.dm | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/code/game/turfs/floors/floor_icon.dm b/code/game/turfs/floors/floor_icon.dm index c4c7cbb83153..e1688e3de57f 100644 --- a/code/game/turfs/floors/floor_icon.dm +++ b/code/game/turfs/floors/floor_icon.dm @@ -71,15 +71,17 @@ // Draw a cliff wall if we have a northern neighbor that isn't part of our trench. var/turf/floor/neighbor = get_step_resolving_mimic(src, NORTH) - if(isturf(neighbor) && neighbor.is_open()) + // skip null and unsim edges, because we don't want trench edges along the edges of a map for no reason + if(!neighbor?.simulated || (isturf(neighbor) && neighbor.is_open())) return - if(!istype(neighbor) || (neighbor.get_physical_height() > my_height)) + if(!istype(neighbor, /turf/floor) || (neighbor.get_physical_height() > my_height)) - var/trench_icon = (istype(neighbor) && neighbor.get_trench_icon()) || get_trench_icon() + var/trench_icon = (istype(neighbor, /turf/floor) && neighbor.get_trench_icon()) || get_trench_icon() if(trench_icon) // cache the trench image, keyed by icon and color - var/trench_color = isatom(neighbor) ? neighbor.get_color() : get_color() + // formerly an isatom check but it should never be a non-atom true value + var/trench_color = neighbor ? neighbor.get_color() : get_color() var/trench_icon_key = "[ref(trench_icon)][trench_color]" I = _trench_image_cache[trench_icon_key] if(!I) From fcaa81a70bf3b26e5f643ce10fdf93de8707abba Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Mon, 18 Aug 2025 18:26:27 -0400 Subject: [PATCH 462/512] Fix reagent presentation name being inaccurate --- code/modules/materials/_materials.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/materials/_materials.dm b/code/modules/materials/_materials.dm index 63505428ed07..65b38e35046d 100644 --- a/code/modules/materials/_materials.dm +++ b/code/modules/materials/_materials.dm @@ -1071,7 +1071,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/gas_overlay) /decl/material/proc/get_presentation_name(var/obj/item/prop) if(islist(prop?.reagents?.reagent_data)) . = LAZYACCESS(prop.reagents.reagent_data[type], DATA_MASK_NAME) - . ||= glass_name || liquid_name + . ||= glass_name || get_reagent_name(prop?.reagents) if(prop?.reagents?.total_volume) . = build_presentation_name_from_reagents(prop, .) From 6ec333663bc108615cc0fd14526069250bb0748d Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Mon, 18 Aug 2025 18:26:15 -0400 Subject: [PATCH 463/512] Fix runtime from butchering animals with arrows in them --- code/modules/butchery/butchery_hook.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/butchery/butchery_hook.dm b/code/modules/butchery/butchery_hook.dm index 1a104185132f..5d92a0eb4b44 100644 --- a/code/modules/butchery/butchery_hook.dm +++ b/code/modules/butchery/butchery_hook.dm @@ -176,9 +176,9 @@ clear_occupant() else if(occupant_state == CARCASS_EMPTY) for(var/obj/item/embedded in occupant.embedded) - occupant.remove_implant(occupant.embedded, TRUE) // surgical removal to prevent pointless damage pre-deletion - for(var/obj/item/W in occupant) - occupant.drop_from_inventory(W) + occupant.remove_implant(embedded, TRUE) // surgical removal to prevent pointless damage pre-deletion + for(var/obj/item/thing in occupant) + occupant.drop_from_inventory(thing) qdel(occupant) clear_occupant() update_icon() From aea4fa0b2b4bd694d72d40542b6dd9f103300613 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Fri, 20 Jun 2025 21:47:49 -0400 Subject: [PATCH 464/512] Add ambience to lake and river areas --- maps/shaded_hills/areas/grassland.dm | 3 +++ maps/shaded_hills/areas/woods.dm | 1 + 2 files changed, 4 insertions(+) diff --git a/maps/shaded_hills/areas/grassland.dm b/maps/shaded_hills/areas/grassland.dm index 803f9a5e9200..ae0827242f20 100644 --- a/maps/shaded_hills/areas/grassland.dm +++ b/maps/shaded_hills/areas/grassland.dm @@ -25,6 +25,8 @@ 'sound/ambience/ominous2.ogg', 'sound/ambience/ominous3.ogg', ) + // hopefully the sound environment makes this sound nicer? + forced_ambience = list('sound/ambience/shore.ogg') /area/shaded_hills/outside/poi name = "Deep Grassland" @@ -34,6 +36,7 @@ color = COLOR_BLUE description = "The soft susurration of running water mingles with the hum of insects and croak of frogs." area_blurb_category = /area/shaded_hills/outside/river + forced_ambience = list('sound/ambience/shore.ogg') /area/shaded_hills/outside/river/get_additional_fishing_results() var/static/list/additional_fishing_results = list( diff --git a/maps/shaded_hills/areas/woods.dm b/maps/shaded_hills/areas/woods.dm index 5a5a662ed04c..1ef25b471ca7 100644 --- a/maps/shaded_hills/areas/woods.dm +++ b/maps/shaded_hills/areas/woods.dm @@ -4,6 +4,7 @@ /area/shaded_hills/outside/river/lake name = "Woodland Lake" + forced_ambience = list('sound/ambience/shore.ogg') /area/shaded_hills/outside/river/lake/get_additional_fishing_results() var/static/list/additional_fishing_results = list( From 980e26f7041f1e56e8616a9178391da0dd980e06 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Fri, 20 Jun 2025 21:48:12 -0400 Subject: [PATCH 465/512] Add marsh ambience to swamp areas --- maps/shaded_hills/areas/swamp.dm | 3 +++ sound/ambience/marshy.ogg | Bin 0 -> 613708 bytes 2 files changed, 3 insertions(+) create mode 100644 sound/ambience/marshy.ogg diff --git a/maps/shaded_hills/areas/swamp.dm b/maps/shaded_hills/areas/swamp.dm index 0b4110cf2b6d..7c1de587f446 100644 --- a/maps/shaded_hills/areas/swamp.dm +++ b/maps/shaded_hills/areas/swamp.dm @@ -10,9 +10,11 @@ /area/shaded_hills/outside/swamp name = "Swamp" description = "The reek of stagnant water and the chirp of insects filter through the humid air." + forced_ambience = list('sound/ambience/marshy.ogg') /area/shaded_hills/outside/swamp/poi name = "Deep Swamp" + forced_ambience = list('sound/ambience/marshy.ogg') /area/shaded_hills/outside/river/swamp name = "Swampy River" @@ -20,6 +22,7 @@ /area/shaded_hills/caves/swamp name = "Southern Deep Tunnels" + forced_ambience = list('sound/ambience/marshy.ogg') /area/shaded_hills/caves/unexplored/swamp name = "Trackless Deeps - Far South" diff --git a/sound/ambience/marshy.ogg b/sound/ambience/marshy.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d481be1e091da70561ce0deff159f54716741b2e GIT binary patch literal 613708 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 gvv`Wc4<=j^v-Qp#BhzKP#V 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 z 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 A?c1}ydFl)5F?(6@j#%nHc8 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℞~{dnwK=~Yi6gtlE(M91gUClo2@F#Nj+ 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 z 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 sIA0S&Zm_BBliew&hJ-|@8aw&1~oR8_z46;p4% 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 Date: Fri, 20 Jun 2025 21:45:29 -0400 Subject: [PATCH 466/512] Increase weather ambience volume --- code/modules/mob/living/life.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 171ad74570a9..189965c89c8c 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -315,7 +315,7 @@ // Push sound to client. Pipe dream TODO: crossfade between the new and old weather ambience. sound_to(src, sound(null, repeat = 0, wait = 0, volume = 0, channel = sound_channels.weather_channel)) if(send_sound) - sound_to(src, sound(send_sound, repeat = TRUE, wait = 0, volume = 30, channel = sound_channels.weather_channel)) + sound_to(src, sound(send_sound, repeat = TRUE, wait = 0, volume = 60, channel = sound_channels.weather_channel)) /mob/living/proc/handle_environment(var/datum/gas_mixture/environment) SHOULD_CALL_PARENT(TRUE) From c95b8f17ec6052cab0282921f41fd4d15dcf9552 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Fri, 20 Jun 2025 21:48:35 -0400 Subject: [PATCH 467/512] Make area ambience louder, more likely, and more frequent --- code/game/area/areas.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 41fc989dd0b7..dcc3343b8874 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -403,8 +403,8 @@ var/global/list/mob/living/forced_ambiance_list = new if(LAZYLEN(forced_ambience) && !(L in forced_ambiance_list)) forced_ambiance_list += L L.playsound_local(T,sound(pick(forced_ambience), repeat = 1, wait = 0, volume = 25, channel = sound_channels.lobby_channel)) - if(LAZYLEN(ambience) && prob(5) && (world.time >= L.client.played + 3 MINUTES)) - L.playsound_local(T, sound(pick(ambience), repeat = 0, wait = 0, volume = 15, channel = sound_channels.ambience_channel)) + if(LAZYLEN(ambience) && prob(35) && (world.time >= L.client.played + 1.5 MINUTES)) + L.playsound_local(T, sound(pick(ambience), repeat = 0, wait = 0, volume = 25, channel = sound_channels.ambience_channel)) L.client.played = world.time /area/proc/clear_ambience(var/mob/living/L) From 87fd3699674eb2d0d266d6032921f871b9ebe7fc Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Fri, 20 Jun 2025 21:22:42 -0400 Subject: [PATCH 468/512] Fix typo in item sharpening effect examine --- mods/content/item_sharpening/effect_sharpen.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/content/item_sharpening/effect_sharpen.dm b/mods/content/item_sharpening/effect_sharpen.dm index b5703b653f4b..511b83c6f349 100644 --- a/mods/content/item_sharpening/effect_sharpen.dm +++ b/mods/content/item_sharpening/effect_sharpen.dm @@ -18,4 +18,4 @@ if(uses > 0) to_chat(user, SPAN_NOTICE("\The [item] has been honed to a keen edge.")) else - to_chat(user, SPAN_NOTICE("\The [item] in need of sharpening.")) + to_chat(user, SPAN_NOTICE("\The [item] is in need of sharpening.")) From 6f0bd330f50c0fff4ce7ad1e0cb842021a91e2f5 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Tue, 20 May 2025 19:04:54 -0400 Subject: [PATCH 469/512] Add work sound support to cooking vessels --- .../cooking/cooking_vessels/_cooking_vessel.dm | 17 +++++++++++++++++ .../food/cooking/cooking_vessels/pot.dm | 1 + sound/effects/boiling-water.ogg | Bin 0 -> 374938 bytes 3 files changed, 18 insertions(+) create mode 100644 sound/effects/boiling-water.ogg diff --git a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm index 12dfbf6378a3..6b2f8917a820 100644 --- a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm +++ b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm @@ -11,10 +11,24 @@ color = /decl/material/solid/metal/stainlesssteel::color amount_per_transfer_from_this = 15 + // Used for work sounds. + var/datum/sound_token/work_sound_token + var/sound_id + var/work_sound + var/cooking_category var/started_cooking var/decl/recipe/last_recipe +/obj/item/chems/cooking_vessel/Initialize(ml, material_key) + . = ..() + if(work_sound) + sound_id = "[work_sound]" + +/obj/item/chems/cooking_vessel/Destroy() + QDEL_NULL(work_sound_token) + return ..() + // TODO: ladle /obj/item/chems/cooking_vessel/attackby(obj/item/used_item, mob/user) @@ -101,6 +115,7 @@ //TODO fail last recipe started_cooking = null last_recipe = null + QDEL_NULL(work_sound_token) return PROCESS_KILL if(isnull(started_cooking) || recipe != last_recipe) started_cooking = world.time @@ -116,6 +131,8 @@ last_recipe = null return last_recipe = recipe + if(!work_sound_token) + work_sound_token = play_looping_sound(src, sound_id, work_sound, volume = 30) update_icon() /obj/item/chems/cooking_vessel/on_update_icon() diff --git a/code/modules/food/cooking/cooking_vessels/pot.dm b/code/modules/food/cooking/cooking_vessels/pot.dm index 005521995890..72e07956854d 100644 --- a/code/modules/food/cooking/cooking_vessels/pot.dm +++ b/code/modules/food/cooking/cooking_vessels/pot.dm @@ -6,6 +6,7 @@ cooking_category = RECIPE_CATEGORY_POT presentation_flags = PRESENTATION_FLAG_NAME obj_flags = OBJ_FLAG_HOLLOW | OBJ_FLAG_INSULATED_HANDLE + work_sound = 'sound/effects/boiling-water.ogg' var/last_boil_status var/last_boil_temp diff --git a/sound/effects/boiling-water.ogg b/sound/effects/boiling-water.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c026945a819beadf4fffbdb6003f66e043fc58ea GIT binary patch literal 374938 zcmeEtXIN8Bv~H*h0wP5b0Ra<2=p`T^y@wDYCG;Y__aYsnDOCu)_uiyR2Ss|5-is(8 zU8&M<@cYg^=l;4s&iQqpyP0fe&&*!4=bbfc*1UT*(%f7XfDQQfD3tgo!V|mo4vP-U z&ECn#()l(CTe|F@9Df0nrDs+#HE}hzv@@rdv2(L@vbVD}wR3^o)`5lhj|>J$ zDRoRWSO6+xHHd7o%9ujvW9K+-*<>TMLTG-_LrM8`XA0F~!Ra*Xvc@|4AW~}8mk_*U zl_(X<$HvjOF;X}T_=3H8rkYF5M?1EO<0GcRD%0q(D3U~5Vl_cf)5~frjw9YCjRuVrk zRZ7;=2N4H+jYi!*XNNc`bu}U2B>+GgmQ59g9TZZA4d4L)aI=`BR+*!o38IZ*5C0ay z^a3dW(BVJa1G;N#NDD4$7w6zarPZ~8XSLro}erHacJCg)SreWKl1vb*0 z!<@{xEimQMoXG;sApgWNzN|}Fm)xdx3l;`C%2Hvo8l6Nla{55L4vuspL_ivxCyDn687f);rAGs}_x-Or(exD9D)Jib@Kf*sv$F#(sRPydW4aui6 z9^~H0ihU{hAI+r4RM??R)8z=1a{~6E*^KTA2bdt|p`5BC}X4GaHAP zc0tU#ptS1rwCZhVr)&)pY?n`c{!4JB{o6!&0N|&5RGxfTo_y4I0W=URo1qi{czml( z%wf3#QQzg!Kv+T^EMrY8$IPn0+_R(z`)?8P+ak9IbIK~DU=@(mf+YH&&v67_#O_z>ez1O`|TfD{iPE@)G=zVyT}$%(?* zGD0=V>Sc^%zZNlzBq4WbD{7D%%-u80y`Hz0#vMdeoARQN!WoT$ffd*PD-q!BcL3T9 z3!VQD90313OaFBbO!$iq06=d^o#jD?3IAUIxBf*HV5Mx_hJU2oRs>G*2Z#MD^pywQ zN+>2U{KnVV?38I>L*1m$Q+~Bs_AcNL~O5DO0_ z1u-R6fk5I3B_a9oY5>5@8yw6p_@za!0)YNLz@J_k(oN;8q)<#@jB!%()xx+p(qdJ3 zx|5uTVUWkhgMu4*aS^xPhKfS>tv>CUQ)gk^%%2bbDLe7^Vn00HC&lnb%+C z_O9bTlL!te!v&~d0f?fEwJ-o=n1`j9Sf*@XpiC)Xf?upm?wwkJm)HElGzao|V;qE!eP@+l-0AVF~|cQNWs*p!SOccsQ9nT^3UbpwEvM49)JTS0Qf07^Fin{Y*h2rU#-M+ zP6t&mRp3hnYf8xo45;~2EJ3$jqfovUA$W%&f68be-I+)dQrm{`T{2w{x%4V4Ul_*>Py@p0vPQ=P6EwXZ>#s z6m+W(fh3Z5F)@{`H0RrLK`#{`>CTum224z$_%@9ph!mqE`4fVedoh<7bpNJdPVs1! z+gwTJ{5UmC$J|zwj}fH+2_{vz6>!@DDhdR*0x&TOOd3YOZGZfeCSRNvrvm$X8>Z)I zZbvwk1o$!Pp1$-&73Wa8!L26A&PfWQzih)alTl?lYe#4F4RhH`Lo3-T@s!^A?r zYm$D)p(@(E0L(>tc~wX$HZyN|3MEGVgmF|HQSRwTHL(r7tfek@Kl)awEP@L~P+gi4 zbTr%?{9a2ooWa4<*Dj}k-ft?E_88!sN2Rt{FqU&)8T7QB%v+=^4^%!)d@V(wh|JkD3uX1Z zStZ_$lsC6XMte)AQ_LBu$WyzDb_>AfG#Q(KueU2tET%J_jw`B31AwYz{wW3c9Zz4W za9vH0e)69d**BhGXb+8SUJp3}N(tHw!@jqj@A+JMKe20ksJayKUbNak7(w4rL_p=` zcX8zz!hQmb%#Y>~^dhR{W;K1Z5n9ukShrAPuK-d@1157CwgS3_VEOU&nR#k~jfi2P zY0+xUG|wps=2+-=fOZdlJTwHW@sKg-Gn9o|YZ&39C=J`SSzZxP8OY7_s=&icbD7(c z$4K)fx^NRUl%A`h9xfBFh~U)o-dx^LaHxfJz9j!eTk%21&u@={jPVzsc~J=nvD5Gu zXXPFztcQSbaXKaBay>6Oa&gUGeUUIySv~uGc@lk`D3Z}~ndtT}ca&Xc zU?WSC=BG*{0Y~$NSNt*PDbQoM`~xq3tmG2#VS;X|t60!09ktkA58{q5R*?1ZAarR% z&CJr};?p(@qV;9=g_tFN2NzO(zwzlRXC{#0Lxk>b*`t~_>x367pGIrU{cyfnH0g4EK zo-?%90UTBm{VE&eCF?Q1+$yfTSlW8lJGpG8ks>wMn3HVfmOSiOFd(o$QwRA50Lle9 zB|MYAxVqdpvrBBm7kEc&+^B>ch6<1Ld|UhZlmAiY`JaMNsPouhGdCjScO%07*j^j} zg*lSL&@3N1<=O`$8TqLA+MQ3ACb>R2u%3s$v}8)Hffg>o&Ga>bf^gW7WDRI=D6kpO z_&R+mpnfg9Yi`2D93C#u-i5;5ote<$=SRg@3@bb#k%kLPAjpGOaeAxuao&|(Mck#X zP6a+js8Aj9*0dAolLzt*Kg$M4Bg9`(m`?At*I!wTgqC?0nh#4i-x%oXt!bQ{tS%QU zdTotO(g_2ghzAXzP^mvyM3zvoQ(RkL+2p(mnSK$%ha1L1%?q+7b$ZZDoz^P4e*Ro& zc~mUY3JPPW1s1~n8+XA)^;-CqR+d}n~Tqgm;L z;U*Y{G5J$g^=!5JbZ)~IqW?vcW)%Y-O;lbenZuvRQ#l@Kbw^t`>_^0kxJZ@prg_Fb znAcpatB6Gr>A!M>JGk)rW8E z5hfBcknIk2NZ!w+PS@9Ij0ne+f-no}*zwKeMiVM@)AF6xYJ0eOF}C#RxnzM^W%T_l z>1h;j=IB60Jg^v48ir?i-!bOoONi?GSzaQ&6vxz^-1q7OY$Ju95Y90`kA{mM5`kcdIU-JzfBB^!9y}Egx#Y_kg z6-zWoGZ3ZI^Y*bAR%MkneQ%|{;TAw+!+`OvF8R(}^<$$4^Za}U2%O!f`SVN#iRQm$ zCS5Y7>s5U~n0>Y}yxcNeSik(XH`>!CMPlnUth5#svGJtu>*u2I82e7|yPq`Bz!=7t zWnc?rGJizx&dc|wbrco(p2UUo>k7Xrz~L#H8tZVAXDPFq<)o~=97;Q^VMyYZqHDE zY+HsKwJCYCP|Lx)n z<>&$lucTMWpPMm3r(QiPwz>MnP2*{;(-o^pX#bPrw)5{JSc=HuKgd|QYlPL(GZ?q# zN9Xb2p};+Rv`_;I@=#SXE@w?UQ)FW**^i-#1&%F^Xp5om3mqe#x#Yya<^MVyS_bh zo2dXTkw^)!As!I*kS%RppLg#jEAni+6sW$|aD|@Oz&{`Kd)Zc;EY8)7Kb1!Kf3Cp| zTIv?1eFGzS0e+oanr>7T`o+-BX_j`zT`-@w&bMiAK)Ej|Zy+XFraZq4OBlw`w$UrG zDpFiIXd-WRnE1*v@#L!>S8t_l2jd;(CWaEtH?yxKX3r4uovGc7vKkCY0@~Lf$`>My{-|lx!S| zHddOk_LZdE935D>)peE^?mT-K>f3V3$3c5X7{=^9VG_RBoufF$^OpZb>n@#M3%IKY zH13+{TmBKJyuIP7xT%H`S?8i_wl|guP=t$tM`CFAe(5z+SB*z&Jw|M!s~RKgl|=Zf zC{u+5IXu%5)B9%^hpYA7t=Amb2Y=K6xV1QVEkj^_Qqp_Ozx4e8fYaTW2wPG$!UTt% z8zlRMG@Zc3)>eCd=fU+4GmRLJ=nq1~)4`c32}f?r*2swIiS6;WPqpMdv6>tEm$|7% zE-!TCO=8n^L}JbJQZiI`V;E3CN%udLh~wn!JbnD&XizaVUa-7q zt6HXEfQBLdW8Rnap#a%!+MwvPmwWRV>sZux1e9F%OO0m?ElY{6dtENI z=E9UQTG)RLpJ+1`rL~lxR7ChoP~v&EvA$I>L&M51)>H`>wR5e>Z#FKx<1S<)ecP}4 z47mW(NUC3^5JNAq(KdMzQ=``Xo%dqxmQqemL)X4@YGSlLZ`t+u`yON6VM8Rv7KE~X zxIxhnlCf1WInRZ}%%p_hJRF_KrRlG1S)23_mGj4yRxKrUFA%^!y%~QS7hVFoS3VD+ zFHUOY3sg8WKa#kb`i9K{5JtMas+qucNA`!m;|DPuXO3Oi`l*UMDk*?ac&BRYI7#NP zawlb8Bn8HlXv#O!Kw&YseagW3tD6R&-?8MvbZUeZ77vE;fanmn55 z0l8V8FTUI{OIlD^`4sfyhjvAp(|6zesiVdz2>NQ@g$&6b60Y|0hcSh1v!*f6_a_WA zLq0E#sP2&X2MNsyfD_j3AD~StB4lYwV&;wI;i>3_rL^jEnvF-BTD0N>PTplohjP(p z<<6y!+*(tg%-DtOY02mFTubAoafI#-i^eVbD>Q)%vt_ky*ZD>H`_m%Np+y5s1_P&7 z`gNWVd&+5z)c#MVX(L{e^-5CXX@VbYX#h!qh{WFjHl)i+0YUI3mKtqM$HJ+lr*stX z>qL<|=Z__yz_mk@to*`5YksYWTOw1@s+F>GB{HaJ1{rq4#dR8%(V-Gt#*`FYYj z7|RkG*?qTVcu1CZKiPOU@UT4R5)N8&=*JO8NIvFA=zjaiLhd8O5kSWO)X-#CV00Zi zsBF8s%(ADuUhP8nmXr3a*&wRFCFl4@2o}Zy&N!Rgb2nbDn@>%ufbLr^-lH}tv~5y& zJ~kd*_SW3wiq$E0C$H~CbAq1kz;K1&ABxy&rB5us&ywPNe$PT?)+#=hidooj2_F|rBS*Ib%ur2;fGsN$DjSpXLO6>}l z+ds-xvdbiCG^>Q{|*_mjx3dU`XZZc0=^Q)(I%n>`ya)o13dukL|hkUZwBp zx9J;|5*#Sp=$Ba^hfn+3=GMm_;-5~&n1Y=e1)i=Ck;qzJt@^G^fmJ-89wdboRZ;wyOmLJ-?ql(ry{!Q zJ#u#bO49?2=dp}Gt~+3*IYLDqTNvQrBgfhG(zoGvc&>!U?(gwNofjSU%taJ^$m>2; zeI3Ew_zO|T^Wv4yf!47sWICZ;1p%FB?z4WcdoEMrhdh^%8IilOJdcV!c5|i16;j2+ z$Awy?rN82?*IUln)eb88Y4%vT4XYU!{_M2-!L39~6627NGkm&V@#S+F_lI(I!^0?d z3H$V#HuW}$#nRW@{6DVv=^ML+WRxSrlXzo!ff0vV8wnGdZ_n6x1fui=?SC&s*W_KR zg_50pU@gQ&_AhCrsKkw=Cn*u=vfulMhv=~SOGEtSAutp%z_@pqU4aF}Bh1gm1LB1) zO>JWc1~A`qK0aRFRVEfN7|hJY$-~3L35AM+`1v@Pm_T4IE+`Wd7Y{Etl!u!a%*4zE z0qrbr zkGP>cXCb}jsd{bKCvGoaOnc7{(2kizh!sAvZypiC48q8OA++ANdL+qObTZDM!XcZp zr=E`z`2@<0y||Wvo3{;S!t0c1$OsW&wsR9IKU%+5`EaR1n-Z;s1I|~@{6RsOo^wwBtlCetT4op^VjuIR z0K_gZtC$uo-}+h8DbgegojFF|Zs*tIsd8bJkmJ&rJgw7M6>U%xl1Wj9%1YOcQp7T% z{&Lnc+`>4hFX?sqb6`|JrHq*1cMm-!!7J(>2Gz_yi5Gx2YS#dX4-Rj542maS680-e zVvVQo4ltOJTa^qm$WkxIzFHHWv@4x-_p?RYiMC4XV6*UnW$hD z0j=A1r|=A&iSe^TCOMHH0miw=MJ7%2s&}6&7+vc=J9bMn$?cn+OI0|Z%oLL@}i1xpaUU40SF6E`VN`< zdt^Y~U1onq?`r@+`^n=QrxAizSt{`4bFpipQ7x!yko;;6bMK9mejbJNk3mf(VK5Sx(H8KK49Jg9bLejK={d%d@$i>HzhO; zTgLfZcBfpHxxomjDP%Vzq?Te>U`C6s+Dlo^FHHQS+K6!qJoJiGTU(Zby=5wuvd>|y z`U7B|_JC-DUwsa33v~AzaeXmt&Zk2Pi6#RY+O7}1B?BaVV%go=j&^BjphPX^=?sLa zP~JOyUFEEmnjrCo=JD~nT4Plvt>jX6v&#h?55W1}_SF+l*PPz?19Xx8dlR^Xi?KZM zy(RXrVTf|JW=l%iR@~rHZET~WA#)A=+gAWKRf^+2@~)Zt^rdZaS(&r^Oi>L`uv^Y` zUS4dQ#vP3(CqvCYUSj;0D=*~<#-&tuTTz3etXGFFqE+1u$*rPvA2;P0dgi*2UNk6n zSVDo{LF(iWUv3^=nhacN_`UD$QE_=o1EZG?oN=|o8C>i=qqH1Pnl0-3g$_^?s5$vz zn)@+sB*rNwMm;JIj(_!#G0-R?I$+h(*`8t%C);w2g|7T39=N{6Vc`_C^?g-u1%Ml6 zawa#0ov&zkad!{D{K(CO1Y^+%_cb93Os+ytyIOphb<~s)E+cE{4KV&4CfJzo%0&PC zcK%_LinB$}ED>DQ;D-Nta)1?}hzl58fIUD4aQ#W6KS6<^rA&CS~%9vlvwZ5|A%nIZ>K1+(Se>$p2{(1fQa zI#o$yId&-ClB-f;oQzz-P^BgEDM5!PfdIk#-NR&7Ms&7j032xqvwLh1Rs;C0vKJtB zPIvo{pI>o4VW*t5>7niHwO4$VKerQr4M9c_26_wx1A;ZhX8cE{b;}I65(`>oY>$z~ zm{EBX;#d3Kn0-qe<76@Pn?h>c|12HmD!*Z}-h810jH*&vy|(!9=;Oz_9cu^PL}y$Q zHUveM83Er5MM3on2JAAcqXBKsJn!A)ve2|HSmJVj_OFI+lL;(g1Vh-*zK0F>q7{q~ zE7|OwlVP7Z^e^MqGt*PoN z`F%ra9NpX`FF3_N!^IG;9f!3OzDDyR(?CM=w4-nR^poSVR)XMan3cuH#<}^L_mm?0 zOKrq^lai6rRG6WYHAjKRY}5Qvs>in1aHQe>(uYC7a#v0-Goa0A$o)T6{7kU2Bk=JI)n1|ZM0yS{j(5veX zfFi4Zi6O^UDt|ZMdyw5v@I;baDWl3Qu1(Qax~+MH#IK25Q4G{KDdP{`R6FIhCPNv2;uHa(+eTd;&!1!NDuS>!PvM~a7oee zeH)#RfX;I0VQ}L{u4?BJymk?KS}2%tJQ4~VQe4WA9sW_gD-5d;?u0narS&D-@btjQ zNob^%i(p4VSqmQv-VyP{DBQgLVpY9TIT@a4a(dPG-bweddO;w*w47UzIRV~MEfb<7 zmc9F+#(Qdxn%^~H#?3a?`2AZaqfOsylyjUcW@|vEoF zFip-Ps?R3D#C|bz!HHq{b#g*(r&56ZI8V=HJP68b%hO|;W@)z0M1YSWabBT=8ok^7 zoEwaK*&gg1H4L1uKeI%}xJBOA<3nY%PSP%m=BBwLSDtb^bKIq*!y{E{U#c)&UAc+4j9BnH!M6XGU!MWWW}9XsJ!@;=Oi* zoT`|smK4CluzGpLecA4E`y~u7`N}FmPi~}X`zkJjE5C7)ueGu9ii(BeN-L9O6%hpa zi1`Yo$YHBrMIOeeSt>a#G0jDsHnemh=O)I)`95LzE&fm@NKoUZ{`+Kdw;AEDk1Vql zeUw^VoN&y?UxE*`oLnzWsJioZ<=!hNNQGgkA=1>2ahqCVt7#ZNQy3-22wzyQm|45& zTrrYtBfRSSSo{6ztP|KazYf+regRQRBXZ)_LUG-wcF*cW32VSM=%v%6Ig8fKctfhg zSB>(@<)(*M?WN~QP+J-vInFYJU3<(j4?(I-PFlrD!c-m3WbNra*-|S4bAu$iG!BWi zQ}aDLt|E)Vm>u_brlA0%axZkKtJfm~`zwvME|>4#VbwzSuJ#kAiy{WJ7@#yg0mi^C zs4|JQFL$eo+Jl{eaea+U(Vk`~Ph-8$=!Vdudl|gh=h~O1=l6}@7MZY|TL%at?$LfO zz{8vSGG`NdQu&(Aw45T=Dj23}IkBI)tCzlBmAomyZsF*6NhlVEVZr2*Ks=#kkS1yq<~e zh_*o%dz(&Q#`y|~${Y?GuS6mYM|7A%$XuTKIVvagiAN&l zOpm&A!&va@(rY&pU(>Z5pJek884tjpFV0%fmg`br(ZKFFz^cLiuXl$M2S^2phYGEg zE0Lahb`yDm8(Bk+UV{z&C#{a1 zVEsPr`CDUqH@nH0d&#Azf=kfXTguz z)&zP4({8)m*1ye-Ovmv_fU0BoQ6-Xi&43c6m|x|kvn==KH(M?vcU(p-z4O zI|o34KyA??O?mbVE-HRtD_Wf$K9Rc=glM1_AEH0crV9`}wsyb`mj$rFl8V5VdU&aU zj$et!0?&J94-{tG`Plm;_DU3-7Czg@+8(v;mpf~~!)`9vBCw$&o{AZT%jo;B-UaF5 zNW&-_mFg?w(G@}rvoz&BT8|#G%++OFpASDD926uOXpFS6GbT|}MrV#t0IqTTiBCwd z^E2hjP*7HcV8MI67YEM27Y1e>GcU`RjXY}{)6d{r5G+Mid0i-8G!5P2#6#v1;|(gj zkE-C{vNMZ!mtNd<7kLiEA(+Wae(ngDX2%|>!c?t&ty`5_>DlY-`l9xCY^&dmF$(t+ zjT(}^qYy^jv30_OazYaiA_?!6ck}dT9upTPwwIq9VSy!x6_xMmPMGL4a4JziOc{4o zwF3CZFW3UXJZS?MN^H$N^e{h_J}y&*-lrRx)v_2$VvKKF@eDlZr-gO2os2z znVXO2_7B2_bl=G#xbKK>QGJ~*-pyM+^s=pYiBdV6dqF*BEV{Ufocy=XGf501E#F-w z&ER;mdcE2oU7hzJp>+A<-Ao{AL0|rRw8hr_M^Bbr7vSTp&u@GuxUAwH;|Y&MWr+@* zBc8v;`>+`xvR;(5S(1(npQB7U+%E4!2~~#|Z_mjBV}w&ho98|n@V|&9uA-!Y;Xdp` zO9%K|^nE2M&QG^JY)kZ{5V4>836pJ#U2boEI+@K%+je6)x%>NLt$hn66rNO*2c!J) zt&n7whOt0O~UHcZ?E)YiiC-pi@l+whmk_ zMCY}Qun}B!&3Npcx)N{d3e7jxmanZ!6!=bLQVPSVK3EU{JZ~PMAjA%E#PY;mb>T>ni$d6^a!}4$9qLo;FkD=uX6`86?WC8|TtD)CUth|%uB6DWoc!?P zPq?{SP4m^Q(ZPy8`{$p`v)0r(=6{&`aZ|s^3qqk{_^;Y_V0XtjU-K8R(^0gthjr42jS8qUFD{8*rLxoY?9= zgUNT*34M#$C+CNS6wN==VGz)gdriGrfMytiq>vsH68jI}8F0T$apIjlb{cum60)7G zIAuahIDWq$(PQ9fGSZkK>olu8ut{fP!?S_ zE00?5h2fvvUvS4$Cy=4|#Qf-`xXu}FggA*Wm;B0^sPr&GAZ>ADX58la7Y>JIJa_lJ zEM7C@_32GG_0jr|ioVx1R)yyTnnZhorG)RsHOWn@Syf7kxpH2ceMRKhO0xfU+S3f} zB%hL(W&mrE&vf2rM*+#?BE8#|_&4THP~l0YBV|Hz_kqn8)K+!Nsd9!_XKh=rR`DMu z3-uIn*0DeSBU>*9&t8WMPR;jaKr2kfA1O?_(Nr}gY0TP_FG>Tyhpbbnef3b^zGk_9 zmDh}IHi+dB3LU1l(ljcaV1EE?p|Ze?V5;zZ0%u1t+UGm$jIncNN-7D|YTt^{tJ^yw zfg-ZIt+toWf*+VLQwq)dqR{V-?!uWru|8PoUm#7k!3CD5(I#bA*6g!O!}xf3!paXU zl%Wq-aO6=23JwmOaK1$OSWP?fgBj$7m{NEfxsbmUmZCC1oRX5#PIR6`>$pbddxs); zcJfCIzm_4&%~3DC{fRJ`qYg`0mA=C`6zc@bWU}tzFH8B62SYY%A9u~c1~q<{D~G%4 z4>vBpj7yMTDq10|Q^X6NcBr-1^5fpTe_YHbp@(txsG}xWCuA8s8ycZw5Rr|pg^FljNcVG4koR3R&eZ4*4xe#<*a$V=k1}YwWtLC?N6N__47@3YsgR~)BM5;|WfbgZ*W_EXO zV%o0bgd?Y-6SuF{w0QD2(*jDCZ)W%3sWSG-F3MfhZSfwHfQ8}WmQFzg?$0&O?Lq`JtlJ;Oi8Z?EI1NZt3klnsiEV}z6EcNne~^YHqcrfWR- zOsj2l=LNg`f!Uq530{T1z*-zd1piPGXQqghJieY zKo2SLT6&pR03?{rF=wJa8fAtJVyqQUg^pnDAP#RJq_@M@9bLmpWe=-VFvz9}~kZma|ynbsGctl^9|WT6^tFKIwdV z>!cGAuig-%3ZCFCQ6C53{_NMaSOE>zk_-$~(?ii$YuZ zxgRREThM8MjPDn^zN{iOMvJHPIgA^}xUz_>F#|`{joAe!q1m6+_$-Z+ zX&PB1DYpI5{Ecbo_r!8L4e5DD(?+(*kZpmxEX#@!uMOPFt`iI`zz0_m@rp!~g$V{P z!kFI0JMTN*Gq{ef`x2m~tmJk5*=gZd_mi;!=D0x#(O7jAd-_dofgkitnfUj5zD!~z zlK>I~gNdZZ@X44j6J-W5{+WMf>7&*mhY}C{FCXN(Dolx#Yh`4Cdlqlhm?`3Q6Rvvl zEx-G{o=^Dmdhid5r(^5NrX=unp;)}7<)XT7m8 zqZH2XWE3SM)Gqb2ccQlI)ChTFlHNh}39XmEum6IXs7!p}G9C&51eAs!adVsf0wuKy zAIk1O)&^^U19h}DwO0J$N4ZfPrWL|>tFE}*9ouIutMPs0W18=; zaOI=9+jO)Y2;_=baQ3RTo=77|#?35kj@QAvTDXx3)SW))nbAYva+lty!SclL!|Dxw z^loyRbfT%c!ZGJ>vEWlOVWh%WCYY4VP3$@?Pc@2Fd)#sTCe}%bVAEd{E{!0e1?OOM&%DKNjwm3 zTsriZIOec&EUN$(JRc&Z)Uq-=JN6s2pUcj}#c-a(6Sy-A4BL&_2!q2h2q|@4tQGRQ z>C)bd!8zvVA4x}c2LXVZYEBC(j(KmZR!3RQTIQQLywf7+-2#7gw|cFeUONX{Ilrhg zA(k|X;;TuRlG`IdnWqppLsfR`RmDXXgpl`&T7ig-gCJoQg=}RzPp6DBywod? zH>Hn$uk1tw|L(ea_m>nJsmG zeJ5tT{B1wCO>2ECOxvNlVt#dy_l?4EXcRGh9)&}qHGMRV?HHc!8QU-x<~^@T7rIQk z8PG-Q{)|lZrug}6XK!5wakkZy05e3rF#N@ngh<}CC zO(v_Xh)CO%ff50}v@*@tb(jU= z+rHA5wRlv7yUGn;>O1`EN9i*s2CKG8dg;z8@*GJqdm`#biu;zTl6{jxM4_@wcO(|; zYGF+y$#p{MPVRZBZi44GIDYMPCr|YwPfTy9?<>OjTTA+`U%QX>Fb2Od4-z0gR|3;|gtWYcQAb+Z@?TE_vxlXlGe3R-)Hyy$dF@9-H@eNPt{ z3nNz=@T}2w0lgUM;opp!Q`*>c+@Tr!aUpn!Cycnea5y30U|=n(mZvpYSYdwk!d(N; zum58)j9U;1gBBZV$@%fHMVeW}R@nLY+7?8_VJRY7ejY)I+Vq}0{Y189I5riM>tr=G ztF~%`1m%q!O_=1eQ5%jjIEVULSL(9|75^v$!YoN+^R$A%070#vCE%Y3a)#v+iefu{ zAWB(+_OfWsa?t9nbc)$nMUv=AA*n&J+E%`x8gi(*WOM7=@BY|zdA*TQHG~q`-s|9Z z7Bi1)i^qNT)6xgkpUz*TFG6_-c3Q@)-AI7SafBn}ax1u5Dp!wae>s)}Y)KNUS*FI= zYKy1C-Va>2v*=ZWO>nXQB^g%#lVrer9s_Wn>?jiiadC4q@$+)50hz%9{9p)(mzM(s z1c89uP+n#xUO}Ga!G(#w1>kcb0qE@~Axym7?3_pQAc!JT{KwJ6vld645h~^q4|H)` z5p<&*F%dq>l-kZk)mv~6pMg&rUT;b{ssD$GW=O__Y*5Lu*i@^tn8x&L{bE&5s`1f! z1oC%eX~FsNcl(F4Ba|;OY7kjS!0cV>6DY4dCjEW9RBt?z&b3u};$>RBMz#+OIZas!eB65!X<-agv@81g6P`9ZLtTS0;XVP% z==5LiTY01suy@3Id>J*d0>XYy-c&L9uGg#a{C;p_{#^UDZxgSN7jDv%9WlF8XgbV7 zpSk-b%PEDkaSbjtgV6iwOk)$k_BqX@@b0L*2R@}ktk5E({lE_V>a#BtUmuXmV?Wjh z#sNsb;sJko8_dU6E_gzBa=*FxR=U!UxlyaLd%TR>8@WCcd9MP2KOWb-X?|x{TOUVD zv*zM0p=@N}GBaG5xVcBr`L1jJk$p*NPPYN-WW|L}{yqXWe3~(Uki=CNfCbXCU_Bf) z^E^`hdHB5jAfxOmcZ51EpB?&x6@KE^JK-u4>Y!5_Qnwj0KQnkTbFlvS56^Tkq8Lw8 z=%lPBp)pAmR-!O$b*+#yo?hf&jTmU>StYc7gyb4XZJ`S<=VZyhrzo{9{372;R9Lhy3KVEO0$pI~5}=b8hbjy?w9q zTI1Q?bJUON%#GA!W8NnZ;ITGL^A(@$0_lX2BxF70OFN>z8OkoNP^p%U+vjS1Du&bp z6S@jDrR_ydkl-MGVkm-ntU4&P#o!R=c2p59G&IZ8je3%oVL$9$I=V6-d@%smxYYM| z#`rA0`0>v!+k)PGj3k)GVWx(Y6yqtB8?5_c9sELv5K*P?6j zt!&iCUH4kJUt7mE($t7rYsVPzv21y8@Pc-$i<>WW2cDe1y>Fs=Il>zD>WIX6GH&o^ z(+vk`O}KJ%&84As7L3?Vt5?)9&s`!ag{93J*RE>n>gwr>>MG}svk)#X+NCm9A!{P< zk%x#p{WxX^-%^V)s&y?D_Ir7J@%@NK-Kb8ELWT#7WV(L;UFl>576~$pN8OhBu{G!BMe=-UTdikrxu|8+i$d8*2~#xp0`qnmqT>T z1BXJcL=7ZoOfJ?D5p+dE#?)@+SGndhy6f37XOr4B=E_E#YW6*~^*Lq}d?M4&ukPD_ z&T$pt^`ERBo6OXE7H{c2Hy-gT2L_4q&r1m{eo6i=GU-a(=bqCWt!(~2V|eLCIe9f^ z(oY(m-OBtJ=fhG}X4sa53Oo4pkz~ zOKa|m)s9{my03O%q-Btsmlmm0Z8Mg)Rg-jFHh>|FkeE-laT$eutqk<<4-VU;F0S2k z&2Ff+Eq|S!`la!I5p|X^ZMN^<$2SyeH?c4<|!KH&Y#jPtU+v64XANYS8%yvsq+X+QY}A(pejinkf<5=w;vD!u%a zPg^+ztFj`ZfgfyaPU!6z(X#sw*zmnZnm0&_QQweS@3dci0DqO{V9R9Pn$t!}3H(AQ zx&t7kEYAmz-96V1v9-LEoDyFY$8xn)57|A~BG*Bj{kRrjE>5UGC^>9GqM71*U}`?C zllQA^tmptFQ>Fv*=E8|EOefw?0^K(Zicu_xX)7V;X-13uo4Dt>eW}rSGwtE_FV{g= z<6$D#tA2u&xwN%TD%V8NozOD*eyfLYYQarHm~+oW=I`j``TO4%}R5?%XO zs8@}i>&PP+m@w?5isq-LRlgxo*STL6)@2*}%C-S4ZTH*MH3PLe>CqVmv2_o{3S5r7 zvrmcbx?X=O@~HfH0+5l`ZQTha38Q0X9Gs z^>MvhIKK`BblbrkI#(Ascss;|H<&P#=59;c%NEeP=>`#&ACKucHO(Q)d%obDeI)ro zKh%`^<4SMkR-!4?DCLK&W!A6}Xzs0bvQ46$J~FNf_WfUAjdD}rd&y?$i_cE}F9Djy z{fVOgo;Yx1_~G7fL2xq7p}jMVv`X+UCDV{5b&<|Rlj5BgP=lnWPL_7WNli=W zC-Ui?>9Vt{V2jMmfpN9xV$G1wVxL|C@LOS^DSc~+6=?S3m_~( z(kbm#{9y?D-F!3iedp+^yfyepo8l6Z!iVc!8bwbEeR}_brb{(Z%SXRi8)uXjAanDg zlR@Oq_of6MGUj(?R@FCux@a+dnBotTn*fO4zApkRz~rAfVO{@uWelBG@vh z`opV)IPND{`kWQgobW}O#hycku1cQKNse+jpSIuwb*3nXbf66 zQ%h}}azcbuj?jJ>r99)rX85V^A>$;LP>7b=6ziHsy^42B-ie7eiaCO6eXvXS7FX&~ zZj`mv59rK`wi#a%G*~+oYi=%gkZwE;+v^e9kMv%-`syJrrRlHCubd@CYWP&o*+OJc z`Sr~F^y_i0Z{$R!>`ij(;!4lSoj1kpN2a!}{GM1G7qqJO>S}J%dMRN4m2vIW1^7+8 zK$^j%Zj?_pQ;RuAvGOIY#kcPivBbL}RQ3l-S4ZZGD>2q!gSioMX9lvS#jkrNYZ*BH%$LzPrfh7K zHF9*~(~uM$=J*+L8TwYf6OQ!oin*qzlmC10#|ds~bXZ_^i-^|;?PY@el|9q!?Cj2B z3m2>V(-G@*3l(i9oD~l|(^r~my3V#e7wj%GHbawyErMz4f;m%msr@^j>Ydev6y4msfDd9kEI*274q(%YYtSDdMuS9j2 zu7|l!uDDa#HT6!9<~Et^ZWlpdNQP=Q^pQOwXU^WjG)cfy#*`B|-kzZw&>tO`&x`v_ zaZkC1(;p;FmDM~}EJEEZD!utYQ^o$Ok|FpigmEddj-+cK`m5qR6^M{RRFO8oG916I z#Tk{rZVD${@xpW{sh)ScLH9Y1h%;75 zY)I&F5x}xNWx_|L?ne-!NN0h#&r9xnjG7oB>n`i!^bVzoWhGI26W{2MRpn~+;)EuJ zk1nl}7Y4xM`qmI$IP3bob$;#WkmIlWA9vi-)0#oP{OHJ925_?J_`%}fVq1M>pRw?l zH`0oE2PH!u%T&j#N+FAB)_7K)dKPuqkm>S4`}%$JnB>Ky=%=wU?WlD99P@_OB?eJN zB+G;#6e^|=o_%S^uRYr1;@Q+@HuQR?VC4_w?C_Lpo&_H*W&eK>%X+HPGF_#h8l+^f zxDHY7o%q6#BO9MG)C*MO&cOLl{^h2LOz!>HjcmWiyCqn%QQa^+hZb}e-Uyk`7{P*HN>H$3EM#f26xt^PZaXNE4&RR~n zw1JHo21W*W>i60*JK$gpX<%lDyd-NzGsDfw$k7M7p&OWbA-+7rl7mQJzchmnga$=!u$<;2XPkrU!D;KYIcqZnB zFt%>PypjgXZlV4ronkOn&nGm0b(BU-nSd=W>&ZyBtz($MLW5x$68GZr1 zCC@5d>dF%*dubBof^g~f5~U0Gl3FQivBgfr9ry9{-GV4 z)A}9VPy0N-E8iCX5$$2yaO>2c@@_+4Vf%z5PBx@hn9b)RC~ z8zM+=+58@BzFl#i-VvqLmaNX1_Qc7UZ@Y*j!mf&5O0;mT^mWjHR_2JcQAAhX4yM>F zk5n81FUI=QUO4I;R+6#JXJxCXZXOdbS&%iSQvb{nP8uIO^S#Bf%5@Z`y&O!>z+73e zn|?|p9*|A|TD#1QzAwJDXBt}1^%{OdtXPYfzW9R+!cneKm6|IFF!O|5T}6$M#vMYm zL!v^zaqPE%4hM+VEdTQ5WDKO5mN2b;qZ)%nJqWNP#=ujG^b%Zr@$R6*9ZIp!2kEBO znp&k9!eQxR6e=(~F|A?15P16c4o6*jE}d|8rH)<%+?SRL;q85{LrYwr&sY(wFNm); zZ*27cS&?BGyjmi;pgBhk=bso)E;6@aJ)NMwd50>h_<=0FfEfD`aO1HUU+y($>0IIs zDd0T2*n(T=WQ<*&jp-30gt7mEcY`N>RV^fppS4zuD=}EWOruTj6$z})m0E6g7POG% zP^DF{;z~i8F8R(>zlo2YiqvioZlHzJt8DIvWv#AXHu4b7J1w+*#K*bYhsbi`@9~YK zLaD7Iv4cuK^&_jyQFEYa8T@F!V<%SD=^X{axef$iAq$JPn&RfNXM4ONvgNg&dveUU zey|p#9>pq5<;M_JOI@XpKz8!Y;~|&q9^N`AHq;}#FV20kZJ6^hPJX@tDs6}mq5%~p zKDqWG8;oUBKtI2agi^6>_%pA#3sa?AEn7{mjw~{rYMsKnhCOhvy0qAk*}?IsV^Ht~ zDs%Lbqw)96P{cFNaW<0jROX0@5<-eqNpwCauBt|__UInxH|8gYjvxWYVlw$hlCZzc zZF7&OL)QMT}<_y$xk}+9|#(r7g1OGk!)}%94C5px{p$-IR&scb&NE9er ze^1B*swTj+TdbWMV^d$qy?MQ`T7-$}{~!T1-X#pqWDgr5(cJ(rSKC^`TebX*F2l(? zd#8!k583sS;7;Ko2;miHh?&*an*bn1_KurgZJ9fVF$P$=>$SbaKjGvWfxqUt=-cN1 z?QPvix&Q2QOMKUbsEXMn04wfWmsshWJk`7ug%-b5<8X^E_JY=Ceps}Jinz_yk>Jey z?Yi3;&m(R+Sul#kI2u-S0wVn0O%m6AbG6&K&RSPKOBGSiCdDmIAs0aw_7{`6g1f8JobOYT{b zRX}In2xVxL7vjn|S3Up@xCg1pVxt@z%V?q`1DVxi7{0HR3I+Yo79#eT#=pOi*I_KB&OoXYE8f`4p} zYco@EWS(ZiTlVxbT=qB|J`L1!lu7SnMo?*}A(_<;QV#Eb{2$d}%OLX(lBS}RrYM!pyEy!T!2Pc;@3Q`mE-O$A4e z5-1ZRDuOOo{P&7vbYMn8Gj~Vc8d%xp&sm4~cICt#(2JY?;ul+$x+#40=dvx7;zaR4 zBh6p4`H(pIqN?Qgpg(o`$+`~%RZ?ZuCzVF>81tCH(5;XdEM(}tc+M;rim=4nY{yDF z?qLdLExfjAwwanXvnBGvJV{a07Jt2Y_V+p_WLLgZmHSYEC(czS8~3t5-h~j)mVUX@ z#jU-*h^WVHht(lKMI^<)4r29Ldw6S9?Bn1jw+tLK7 z1Gm%OYnw0M?#_AL54s_;-k+L}Ft0^26Zb?chkg~cd~Kg?`J3RMB@8WqB=3&R_ij@A zt?_PtF740jLi#VW_%;kfJ+KGngWzdeqJZBn>|6Wu`~O{AO3+x~;7Dil^l1+@OZ`|7 zCuOy)o=ciV2!P{Nn5DtnY#~LZ_1jfn*IdI2;d_Z}H?2Az(Tf$w?)+qUE!*RRf6Epw z{(5{WVOXSVU>yCWF75JR&8>q<8S|}J8W#8Y$BJtDt1Us@2POnXdv{uC2D2)%Q5)-qPRnBF2} zx6r`bOdeR?^6f*2^rGDPy42Z=c1qT%VW4G4DT5qQltw^EUT>@!l7KWQPnCS< zHuf|Z+w0XSnv5Pt?%^Fgs5gu#{D^32w^?}j?^mjt3juxLW43wnn+!ut7*>xC;nVrb z`boJ--zGLLgCZL72tK+!yrXIr*Hb=CegWd262lmGB&|Qp`al^dy(Q zd4Nhv2Wc(>h)!*&l$%9Q8*QjlHBL}hRT*h{dW`vN%Cb};tm-tf0q3w7`0N{mJQ~1& z>FNf5xe+LrulrRX5sfEoH$2uQXVY(wN?~DM?#$4k$fFFG+()#Y>!DThLcpa$3yo`8fZQ z9w3W+A1qjx7uz~T%Huh_D}fADOWkI~GQUR#(p4Y>-7cCpHBJ4rMhL_J*?ZPC25(%4 z%$`_V-*Ev!%zqMQX?$XtsBl<_6x=vK69ZPiePai)?}Z6%Zy-mjCHXZ`e{CC$$W8AY zN5qUUfFLwd6@u7F@0rkWQ#s~%8)n-*#t`%h_gu(UVVt1|XVRF7xpU!&{XWIb72gAF zsvH5J81J?YXM0(`p`|C~sk!LPXbtMzO{MY$Qt*YA9Z4TWY|G)mKX3!Qi}+l3^StaC zMf(NyC#FmeIy$H)=p^%lz$dOnCVl<->6^0@K4*9sYb*$53|bBH7rOcxJR>s94gFu2~wN8kDO%{*_c+zcJ@{6_A8=`ETbf zoxDgjdXH}qek#qtHIhKHAFlJp$5_|`bx5xi)rNJSQJwufe#od(L1KWid=K~tF24Ir zc%(Q%dZ#NnJpgGFdH?*^|03^I|FlJeB9)-?;NRf;r{7bsVt3w1J&_#9c?}?2)_O?J$PiYjO7bQ=tP*fDzA^YsI!T%cx&D>untvqxg_mgT zo&ley%Tu8*th_6R3l`-Rgy9G7uz6KZyUMzbNUumWb)d#g81YEgMjs zczUlNYlK(vbWJH+Wz-a*EyTYb!pGP}C1rLaS6!N`+z!`K-xi*VHm!3==j?xU&$m%LPM+oSt|*M0@2cM_V(q6ns(b| z@6-09Yv^+l;#|d2JpfsfzwmgMy>7H=62>4{)f84Zx zV69ncfdH)Bc3WcdExY~wI>lmY?QP_Bi;nusrKV+3>P+^LqQ=1G#)~?;4!|pw+UsW+`CFR?G166`IHi{s0NKi_^(_Wp&-)F^DV(c#a?NuZNHAR?+}7{6co zV-wst%1&Tuba&=h`B)O}%6b7v>dHMk@hf{AwPG~K0;-TLr!%XEgNr>(aMkAwGCx2k z_X$@OIOZLE3YZ;Y)x~_~_N7jyf5RV`d#RO1{(YEIPjzyoNqc8{DSJ;O^lR=@y7}Mb zU~(_p>zPO8s%=Q4?MJ|0s}kCnR1LgmiRkmm!&Jmvb$A^QBC5AWG=^5>m)g zprzSvNa0KUU|uSI-Spzl&QaBc3*;^D8`t^>puu|Z3f>D9g&Qgfu||Yf(~(pmeT!Orf5S_yDE1}SzZpQQDwc5 zA}QYf9STh~kHuLuF2_gT5Mb-CvFs#PbJ?%cv~5^hA+X&ExQ9qf>+T$VDK|$vqxT^y z5S$pdkBPiUWux(vvCYuXjyoo3=|?VZTeIYN!56p;Xl0x`<2oWtKEd*Ug0<~2`%N(- z(Ax9XCfy=x<9(UTGA6&|2>G3f!pT4ug9n(XnbF&D#iC_qUs&nFPSbS+g$7E*G167L?2xgoK=C(WJf-zfMT4qAlUyYjqvwVek9N{cKy&o7YlS!56`jzFyX zBvlFIp9s>-)$@(-Ut8{~iu}3Cq>7VTmVQC?Jp7~pCH$TjArWhL-Tj2S$7hSof7Pb; zjJmLj0cPgUG;7pf&ksTCA6#1pyx1L0)p<S{csbpN|RbdSiw4(Oq)?x0In<@Bbta1n3hfgD^wZo!o;dKO+WzP(^8Q`J~avIV5EapQ}C5 zI%J71$nJCe#b=51bJ}tRNFlgA?Y-=p@PdeO8c_rOFC5X@$`pT%C;CM@HN1`KGHxd5 zui`Cdh(E8<+VkzSn^^`L>yIIi6qUDFv3;<^F~tPsFL*=k&MYTa`z|4ILQ6aiCBiqa zZK=ps;O^qcON5}Pp0nMY^1{J;BUvU|86MZA(^kUB!pPmlK&~ksf!mMPT`Ko0(L`boU?%=Odq=jQB~&4RiN~U_lEa z@^DNob@UumWXVZ={(_3!-yiy4DQKhGRg zd1{k0DLPn+EwLnDt_0}5GAMLsZ>>%-WW@OA%kt$G6pSt#vqq zC61^Xv+50x(ZAw*4r!&9mj zvV{MBG&!9v@{HfxiC&ti5;nc)W`bJOaZPyCd680uu6l~hE?=g#d3TD1(+NekqMIfc zC|BTO(IIT7xwpw(2igKw<@s2`iyk<3HcnR;oW%je6zlY-(!b5MDyoGSv8dAm{BCT$ zId}6?CPR)o=Ke;-bh;uEougYYn6d7Vfw9nLm$OA3CtuyRNG%(K|D$XY@KtP7cjs9m z+YZWP^nwdBUv2kiwC|r@3G(=Ll1F3zs6*{$3-&_#DF{Sb;al!b#^@mCG2MRw*@o=U zi+o;=D18RRsK`Lu$L!OpK@-h}lrY zffeJ{QNU0UA5yab3!j;26EOw^s6I zee(rgf!Lg6Lflod?<2w73H&*qJnz!Xcpb`@H#B^ndMI?yk@LNz{m%!9eg6RZHUMhE z!tWxS$%^mvls_xE#)bXF`M53i<1^AcOCfe3mx!08>ZZ|07WB`lzkiP2xblr8^$RCW zRiwrW)N9o`guPDtVX_%7>L&TL>R)V{*D{X6cP3v2b6|hob%oA$fT=T584TLUC*1w>aT3)OT8H9 zI&EvN^`?%tut#SydV;Q7_5;y}QIx=RB48+s>2aDv@K38$r3UDtd)O+>jrq7}NABYG z+xGE1+)iLL*VSG)N-_D*$|N5UOm3@4khbcVw*3-?`JV zbI8~LVf!(EsSDa!8>mU$k0_^`@@!GATGG$>X{)Y-p6Ndg&Cv1B;P>{=;C3ZVUdWGF zjnzk!1|hdwVw$^}WN_$w!u@6ccZq-%y5l`zAL7QQq7m!Ulqomk{iP#kp3i@?L)aJ@ zs6v|0ps>~bJkn5U&7iBjt414bxyfG>gYoVjma$Hyp*eze--CvTGzXVpBIzE3RfcSf zneCjPngSAongVMFREy{qS#$PUgR4lIu3*&)3FiRVn=BlHT zVn(=LJ!dDQuZy8BL(ripov1kVNy-8E-#I^jKi=PVclWrNyko6u=vC#cw45r^cq_=7 z%S9#j2=~96;Yc${f4->VJI>WR@Q&IoRa*qW+OGDB`Po!PV}x5FJXt_EU7w%nC*YVO zJ`vFN2-%}W&MoPhrisnAGb&t{?USL?{D6L(h|Z;Tz}&lX z3;b@GYLUW$By7yrKhX5#kpYrE2Dr&&!2x|!DC9P5IY_RbJ4{u(&%AYgJIknaT>RX# z8~g_6aYvFdY=64ZJ;G1M>jZB5j26`At@h|1h=q14S-`Q&r$M%$)@s9L8As^2b#%Y; z@}Xyr6eK3+(3Buc+aa~<-z%Iq(y}bl8l&|RyMaT^n4no0Nj2}ENm-^bH2214yq`i7 zX+Pe5)!2@34ctxXn}QBoOTE?;_*OA6%56$1PHeQ@FbM1dV`U;-b}Ry+Ds zHW8!!D8zi>`huzNQ-Ng;3^O=4jgd1wnm1-1F ztT5UMb-?s40*@6Dk*;o4LUh};4N)cQgR<8ixRxDmcVPhbJEsYO}7hovUKPGPJp~ zP-)!!2GbdET=a&ww6wcWi zpQb%7U!l03G+(J@2qt|~3U|T48p98nnPn&*R=jL4uGBg1Epl+k0P?I&vU;7+hG6F` zY5SL3-h#~aSZ8^Je9FJDDt5!q@k6pQ;5SV?j8#;6rk9Iho8TA}^sm!7B3M_)e78<+ z?!r>W5c{}tlNObQ#~yio%ed4^`qDq1%@p0)b+MQOfuPr#j)bX%uDG2K*CA-Mks-)0 zlSSVt(6YiYE7|a?3pERN-ogEM|I+4{>ye9eX;q(ld>lG%T+42Gx`+%PF#D!I9#ogs zPaFg;8tXJ)2tc$mfJRswf&hENocHh|CJTqn2X>r8==D#@V?kCb83hp3Iu>3^N=>c!YT~)5gRa%V-sfSq!+`(*Xmd@8 zym7;xVJIRg%*e0YTOy8DTaPQ43bRd(EtFRv^rc+HgYMltR-ey{^eLEUvuNHWZ(e#6!^f-H_ue{b{ z_mj4j6MOKS?L;rx-X3ciq+Hp&R@TGObVaO_kBB-v0#v70zjSK$QTh8wv-EHyvY{Xe z+B((^e&A>4pMgzS(c}Rl3?dZo1^tz>jDNZtj*rS2WYjBSAQPv%m5gV0oLTZhZ)*XW_M&Bh6}k=w~7sf?tP zCusM3Xr`EeEKmfXW%zchS4Hf7>v=<&dP;Zsf~#Ja6=ra;GE^VutZb$yb?fq0bmZ>t zPMw#>HnH?u{(#Sy)-&ISo!t#SR1+PB3^VGs=JO4rX^*wcd|z5=ERi#f6N;hzeDs^7 z^ZW(LS1+v5grB&{>IbmkC9^bW(U?dTO`vIIJ9NR2+@EUkz5_3Fhi*A_wcgt9DZ&7B z>MUt|EIQsAy49dy?Dz0XMGNUZGG-R@%Al#I~fq`qAZ zj_DEe#15Qefvcv88Bb%**D?E;a2|Rz@?fU-gRbZ|+4#U-5~L}4Y0Z40Da3)TNHE() z@ORvJLHhUYpMJk;S$95n5U7^+P1OXtHZ$ls9^k%nXwelE`Nyjl@iO+OC`}Ulk^5Jp z?PjmEM_Pt^jetnIm&=}+s@j#3$OtysS)@Aqzj?3vp)$|%m*LiQynF_Bpiu*yKK{gl z=OIX2(VYEGX!d9GX9kq-aT)ZCeci)?cmK;(NJRdhsDRjBhcq?1m#GY3M6fiOxHy0U zJctwpH)5^F2Oc07Hy0Pr4mU3+f(yYb$jb!e;bLNDMQ}Blfqa*UH6Kj$2plI5B51)S zz{JQ1VB|nFK6v>!c>jtjGE4$6xjlC;RFMR=db3*GoS{sEMdT24_pQFp?0XN!k%*m$ zx7dnG`|OITkz+MDWyJQqZN!n69RpzpnJEET#|;kmlq|~kq}T}f(dRk_qRUaB3z{Rk@snd@+Q1>>y@+?lCP%an@$xYMOs3}Y!KvV!H9wt z5*S&KF`<<|(fM%KXnAjRuQg|Nb6o7gp|XKU`NNUS9TnL4 z9T>VJvVT%LYN;pu{>${_l>JJO+tPx(Lo1^W zXN@m!-O}%g`YDFwF(9}nrNPQJJx$!-?;TK)ZiW$LaW_{ar)DO_*gAh`S-1AfXTJZq zVmhB`+SP*c{@RF=V0!N6Z4&kl0qbPPE-vULNQO8MQ+CeBD2`jWKc-kv446`c(t=v~ z%Usi76OR4N{-=WW8dHIGn4ed!p~zMiIe1thmOv-ic~)bDTw|$lZ3jsq=&M)~yO9fP zf^86^>)}&l1iRiX2?G0sv{@TOzG?tCRbt{6ffy&0s{dr+Aa~th8f@VI(q;bKdDiB6 zy)nlNZc4ecj>gecvk~$_q5Ak8lpBe;NcxiT(NtmYOIg)Y17+*!&;9Cov%3x0LuW!I z?_I+^Tt^fi-B3gDI9&mIT}qQ)1eKAz#9c46@Y|8u^yaNcZ=IwOTm<&wu#(%u^$mo7|`Q5E0jTc*ysf2?S4DH9h%FUB_7G#T5MtLL(^L|2j+PF>= zQ%E~)>O#_uJwdw18R@q=Ie2)XOY2_~iYn?)hq|CZy~~~X(b2iniO3a&X;C>*YcK)c z`Qzhtj93r~_=D-tt6S~<0@hjUwvSLxNT}&=!&9!9L!Ny>?6f+QH))0^2!43#_5N$L zr;nl>8rIXZdx+%P=<aY4nHho6n@rdAHsizju59HpI+`hG^X9tvHwuee%=(YK$F$MdL5`Ex@ zx_-O)SSN{R^)cPkWBKVTfu`d!mG5lVLO+~017UE+^^8H0w!fZU_>g2p;Cq0pzFqFi z^xHp`PW<(3_E_9mx7}KNm6bMBM!TRcT%jcZB}2!4dyazYlc4sU8&?3yrxPJCKjuFC zD;M+ipKbS2tH5k-LgD&m!7^1x_BhjCpHovgQ{SG>tLEXH7O|il>A_L9N9% zrKDC}LiXD|)%+GXXK^Z%VPS-CaP&YE|E{X2`H3Ha(X26p24SfOMUpTsV3~@>8o`ymfQy+ z-X>Nes&8M>8#;6iJ7iTod<=D|ZoKEs<=o_cGfW$^CFB{m(1z^SzR$w{mkvPIR8$XO z#d_*IC4|TaP%bj@5x5Gw=MMVHyI2rq#dqbi_eNQ*-3qZzq+ihuCqeL3&~sq*sKRkZ*H$;Zp0{@!uCK&{NWl?STZN-|{2LzPaK$aR zEi;;?7tInfna0YX_PoeTZfdUu$|IzScdthX1}wydlb=5aA3gglgD*#R*(_m+DLI~= z^G^4E!kMV-U@vkxg1{#Zr1FTb@qgMynGZRo%bN$@&nUe&;}oyi{g+m<^%DUd2O~Kp z^bs{5gIwjg3*KnoyTs#*m*%HgIKVK;49$uFYkB~ae|V&9LA=lhqp8}OW94F=kzIbM8BGmcDMCCT z?JLGi^&A|N3n|cyuK&{YA!}h?umnpJ0ux=<#LuG?-WL>ct5oW;GO23Ni8*3Mm^`#0 zW{0oCd}o%{bc2v!f9sU|o!Mo4Wl*BW=F4gw*3(=nF#d}k|8ZgX@z3wpru>eO@o;nZ zt9a7#f>mjPcWpxbtCx-ttJHztnIX<4gEz^Jtuy92;us9zpz(CZ&>_U0mOM^msZw8< zZV*a^)Kk7IB*eHugL3bMy^>=g}TN0W5sRWFP8Lse! z8h)h<{c5h>q0%Dl4B)OGSrNEP)|bCP z+c|aCMh%`v#MhVvuSHdS->7H=cE70Q&n3u~O?)&JDvK}R9Aq$9aoFd6UikNxk_A^V z6Nh5V4>i3YryDP>>?47ETdewix$FF2Q20o40sfy;tJ?vGIfsfypAa-ZG?4qKCq)uy zMf}Vf5K05PohqLxm9Cf!4|oRR%*`~cySKl6phwjH5v4nG7susLo*?#PPR~|oQiz9S z|3NE^zHSZI=+_5Dvn?bBMQpDT{DGqvuU1ARZ3o5JPe(_fqg=WX2W;V#CY$IDw<|$a zMC=4Zg+SF4B~I(<8^b@kEp#^5G6k(YyBQ{?BBN9Mje@41u5wytr&+(DtZcns}NYLggBJ3y0^R@q~jF= z(>cuIVHmb)+iNs=B0!nsLZCheu2Z3;`eqx$(yM4U0X)e%h098EW9^qRTA%Z04OFfvz8M^)`^T6!VrE2F9_R>wu6J3oCz~ z?anumWq6qAnkt#w%veaB!|#ca%e{t;)&@-o)6ls1U|0LqhI>6-dTTxMl&le^sg=L8b@Je{KM+$%jpC57 zKl0RZPELeou3&wEf<7PaH&xx`KQ9&N*Rly@Q^iHH(73SHBkI@`E*n%10qUL(j1bC3 zfIBV$bPnX`-U8mUrxqzME@^TjP*v zMn9(P;1y>w z*gJ^4PLOxdl$61_%0Z5A<%M&68if#S$rD>3IZE)IR{p7oW2%GI)qGi(Pv=jfkpP4| zY2W)G_7=wGB}z?ALQH&u#4h(?DQ1ftZGA2>Va^qUKcK}ZL&h|PioraB0ILbMaTKw9 z>~_eHw^ZiARG9{R#Q>5;(ofdL{C3dhycozl1RYCfya!XPIARr-)wJrtuCq~jQh*i- z7W-_KxJHyKHR%eSU@IWibycVR1K20_(Yo>dYM3i2(|#50!mAZ3w&c76138R^w7MbW&4oHRcdh64)l|zT_&e zH6a{c#7}T^q7VkT+U!iW+hXIefY^v?Fq;vglb)hjsGB5x4i*~wqEGg$E#Ls1-CD#y z_VIDvz6o{xjAXB+zEy#>;Ul9)VpBU{NM*A)P_*biBVl^)Z8P#f#h0MKLh)KtgMZR} z?){5)TXq@`SY9fjtL3;u;21bo);u%inoiodO@`oDy}GgNEbAVPoWnlr>n zWk?GWO<_6K$oM5&ad%?%)l0CCi@#%{a{ylXc$2;1zCLv*hD#`?q!n4fYI|q0wJ&($ zAdg*aQ65=bHhyy8G%8y7f$+@-po+sZ$KkpEHwE~YV$rLuVpBv5_T&nUVq-x?+(Nbt zjL+|4b|j01BS6&4NTi$wP`49os?2nj{NqT=8aZ4S;e>z59l(gjRVJJL``}p>?rlQ#|8^jLDCUcl5G1FYH zUwqMiGQVcH{djussTw7Jk4nba0ydw=9#DkEh2FEW(u$!6S#*RutguvKfbBRQssNoP z!C$Zu!rg21z``-3z$@Du=+cyJIkZZQoq)qTs3{SnVD&+%`(N#B<1y1@jKJ-EjYnnj ztNV4%n8)S(gfbR>yfK3@u!h^AfweW!%3RZ_hwwdOFYD2F)zo|PTr8UJtv^t*&!*aH zQomh#-qs3Yhg!pv&GjqtW7|g2Sp>s}cY@5|RL0&5CY6P=&?o&x0b7f?quU}Bz`c~z62nSj zYX6C#nr>s`%dE32O&F}Jx}XJ#5BkPC?Ki|axl(*G2%T4%`OPjwrFJ%N7BoEHbdXwD zTR#+`nz?xS8_F3yT*{glH7V}cSewEk*I1`8WE?X_d?u>U8R6GfuFk`j0-V1^*SdIz z{$8HpRsH|y5#8PYCp;jQkRs*q4j;>J0eN`#nE?O>Mm}Bv03!=8-!_K;p8yvJ50D!` z&(6oo$A>6(AlQ|hh$SAvh(CExSpkgnf&$FE9Ndh&Jc#rIGq)(uUNRY@kb;!kB*wQS z6=*Ne3>njKBY!T&PssU-15d=8DlaSC2@fCp2NsLJWNp`MO1VRr2F$B%Vj{Cjyn;^& zpww>_z_rmM@rGH`)rFLwkg>10ZfAQ^Zel+*qc?YKXpi)iMS4gLWHiU1v57hDHoUB+ znMYM{@wu8!CcYC3AVdlpb3iK*02Ra(F7d5P<>@=mmo-hC?+wRirKGX%vE9p)Y$uqn z@S2orJpFuyc$dSYwG7g_=8B2+zpf>vtfMP2`O_ZBS<&uGsfoS)-I^!vG<*u@pYo+? z7%6aHg&=Ae-TH?{ZYv+CwjKw3;Y{DLI(qX}VUX5AWM8oF zv}3S=gc(^{&6iM(P@;MbS3OB@@D<*~-xP(m3f$hQQkNt1x+*zHwoi>eeDE|6<{v*P zs^~~_bn#HpxA!BNmT{KgPGzf{5Eob7Pur_scs-}~O6J)xmXKo*>?!`5!y)48hjAqB zIo_LN;{457+ZTIq8-a5|3!f_#d*B^njA5RX0dnQkAC<9aBGF(e_xGKQCtIxoa;K%}L*m`55Vp zZ(L2Abm)khA=u`%mDvSoQBBMJA3?18N7q{%mj5_rCo|4U6L5uKO)bA5_$^t4OEJCE zv?EY~Z5~e=21PHg2u6&WyX)hWe!bx|3H#fLZ>2qu*FvHKH_-fi8_wd{9g%{9k>i}G ztdMcvbkb2@y(7fHfc%|VfjQs1%-BLcZPsVpqb#wA$gBwxueXtq6ze=5i*y>jFH2RF#8lKnH>5pyCSyv&D-XszoUtQI}&6xOn(p{h3TFlg;4of z!?x1248o@B;#X6E-%3UmJ$dTiZK@)%k7=UIXv~M*ZF@|8Q6%b1--me*juEa%HlMfl z9;Vt(H%A>(6kHp^Q~dm6qsWQEy}y zrb`lAo!TK5_cTw6$?7?ykYL5L}Cg5Gd|Y+})iP3dP;6xVt+o?#11$cyWiD z_q*R1_gDU$F*1^K_StLCHP-{ zrW1pAo)49^Q0aAydCl82`lyephdG*`_0ry2T-_(5&&f0{%g|YAUPP3 ziIC4R2h@1?9iaO&%?MC71zqm5MPZfPg5E^Bh3nDM?eO7y13JZFYgBB*v(iPLN&TY^ za3Ta>PVM&|@*iuNKtJS^$vw$>pV;p7jvn&$bq~JhfJ8xj6& zdh%0Nx{xs~ooOA2%`^4fa$#l)QzS^L$s6dWH3haDQ?}Stbm|ljoQgvEn$RdvgYE6v zsVG@)x)Rim1KTBpooZz!6Hv4zjBz6ZdiUXM zB2B2(se#3%21e$o&8(Jhvmjv3d1r6jIui`A4-4~ccvKvy5g`MB7geU&s#t!#R&tL& z8=!w7$ozSbeWdZVi)gqSKPT!`=M;x0(nVUCNunV{ay?PO7)9M)(o!5&xJ$#jVFZ=Qb*vxG;4^uAv&4GOHkrDdg4^%v|O(CaKB? z&GBWjxj|s_gXvRTN``S1s!yeJ5doH0F~d_5eF)a03S;gW0Wo69bK-h-`a+-~{Ds=5uw4-CScj#jE^s>x&4~ za{~Q!A|yETm#GD&UA(2yaV0Mcfzju}3##cH6WKX2{*7JZ*S0I%^Q+@`cek1woz3;o z1OAL`B*2;sN?zdzevM+mG+MVT?_=zKUXtldpFncoz zb;6QEZV@xyX#nIiPqYJaWt-p{s3w8R2srS#7i<@rwfR$B`KLa?KJ=8fp#UL_ zTz@~!s$}6QS~=ALI?h^IRwb;?X&Qh&l1qazaK@nM>(`9V6*Du?VX?3ksnkiX`p3*+ zeI_}U0=gOgBd7m%0m&N#gw1DuGaAIo<9hD4zr$s=OI|jZ6JC!u9111-2~wY6q0=-$ zdu1?JPNftJ3dJ_U!WGu)!d-N`N+oft#mU(eJ?7rob-DuRY#_34yx_d=SU*dbL{R;R zb$iaX&m<}#g@hQWJA`_VJuItvT;vtNe0(tatqgAVao5|KzpQXRv7(SknGV^Zn=(B! zO88u0EZYdb*6W$)db+3rCG#~BVCWl5LV;xRy^+Cc*PJSo@n+W{uLwWHRz^j8Zl*bp ztEaoe&a;C@SobVVcA(1Wu?YGU_kvtQVAd`S6^Tgl_)xPuTVr)y8uaEt1^RodiD|EL z8E&$!ry3m^J@4@K_wOm~N+>dEm+LRb+nrZJd@ieox9%%xzxjgLBSGev$MpeO}a2OVmcNmy1O4YjWUs9WapOcgJ@Xp`k zaB1N_H)MwxGtx*-+&=+*iv%^wbJHnT#Vc=)b7q#2!6j)^)l;$`KUl9!+`U!LQXW#~ z9_~(GN_r?85IIQtZ$%k}Ibb?10hXJZR9=EtBFjI#CqL|Ho;C=i2o)jug>j&(|9({1 zBTq;KSY=yB6v7UnlZ7(57Mrf|q55rhS*zJQGepKwJd!oD6>+&}tacsiNk~;|+Vy_$ z`DXtq<~F%&L~nnj-^HOi=>t_jYOKM!b5^JL$IEXbZCmkVO#Rs3V;tC7rIl$XEl?4h z0=YdrKVGy&9(QtF_tZxxu7C`jvK*BQxmyB6@pI1LB7Q={7Di_Q%?*JI-Yh)PEF6y) z!t9qlRr>KirpF2#vIDMm?)z4d;h=rW{n-#n$Ca*#aw!6OcYTMhD65$Eo+(zM=Bksd zTl$g#gwKi){Xa*jFaa!i5&5K&&P~I47#+u7V)RCXZ%-|EEeZ)GxTGNx>T~@cJEnj} z%SGxx2|Qlx*h92Nv>fnBy@_li$udE+G1(%_%SC`p0Qefo)n-}I76)Sm>Vbn9X+S`E zhv6Z7;)1gy*>QRY($<&I7~H#^mx$m_o<#7y)C5Rp$RYAaj*CIz+n zSFPR~cd`rDw#N&`xBC8>b?ld_z8dNTB2eY*#~~=HK7;*>MyziYfu8n0ue9B(I$dm$ zlEvDL9h=?kA*`K>aLoy*{B@=2fX2e2P2qR3wIimbueB?e*4)b9WT8mOx{*IJ9&3=_ z^>fXS4!N_?8GaSf-$%@V?y$@J5OntCSz86^Wj!gZN%!qb9+?b_A~2oi_{f1pe&13N z$zA<$kqDGIDDkg81k@b{0-OAtw6H$)K!vDnQYKW_r{L?UKDf8+dbr1Nbj98~W-q^H zfH9>Zzp0}#1Pt!?!lf)i3UfZUT|IRCzBJ*jn3_EAC}%Hn9|7m={P$*wG-vL2>Uqp0 zID-w>SX{MvSm$EaQ8<6pwY}QN^*%otJstip|NGJ$1UGCfkP{Q*JM@y^!VoJ>;LN5 z^E%_5+Hl|Tndlu32xf=PEFg5fXI%8C3x>7uSL1tDzrz(ArLU;9TBv2TT-3M5= znJhD8XE6wVoX3wZTrRTL6GdSnm-~K|Q3$hS5WS3x&XpHQOd2y$PBwFEx_I5m43Jyj zc>OeE(ZjbI_$2CRZ0yg#4%5#39R{`-9`7Yx8BJaS{|5$IPwup_Oxsj3N74FPMZYu- zD)u>SRMHKT0^{4euUJ54tCjBpN>-yKhMeT_?chFOXl zeSG$@!tGL%LNV8ML0i=thibpc+UO%~k=ysb$H&KP4dU|^S_>2Qwrz5C#&IoB7UksQptd^|iKd7v0gMtTNr-Wet)dH@r{N2uVz%)rDcz_-N= zfD$d3|5HgA8ToiF85y{_p_c*|m*Sdq;DoiFYzd}C!cgCn|F`pE0fR-%5uDLImv%fc4i+$ zmE*F;#nnjg`Nsp`os37~E4VXTsuS%NGSNz;m`rhZY5nVWF~V+Ba^}f{r9Cpi>egs-fI^3QM~ zEa#Kv>tf*19}d9!cOQu2##qTyN8EExm3ab`4*{mGI0(0V2q-GGU?o<+wtaPc(8r_o z?z%6H*9RS!zp9wV*Ft{dazV@0AB7;&q1QuYI+xqLIH4Z9?9>2=zogO_hDGizS>&%f z$4$zy6eXZEM80=gx}-j^UbeuZupE@xzOZwlDX$?9-e0NV^0Bitz`b?QOT_svDQ~F} z;Nf8;T%H0`@swatetE1|)Z51XhU3BEkhR~9mjn=mHZOv7ZsvxZ7TcNCY|6!E^HpC| zwTe&d%ld0P_S^VR49iQW`AMM_Al&?nDZC?bc0?hORawDB1=bUf{SeJ<4Q81uM`2fg zmVtGK+00)vYt0n%VXy`hD=)G%$Z*AKB(HI~kiP#-BvocMBe~qkANG(>I!JCB74XkrtZ2)+9|0v~>Ru*SD=g8^NYw24-_Lwey|B8X z2wV}9!MC9&g@lruaaT8PKD9A2!*%+<1*L+J4X|NXv^Hmt{ryV>N~B44f7GmThiBsc ze684OgjG7bsn*q*uH{}<;Y7C z7xA(!Qo?e}c~Y9p*qaX)`h1hfvmqMTssRBLajp+O9A|!!uJN}K0L9VOXPe@DQqRF+ z);Shka!g6TanCzKI4dfB@7|JyJDEFNxPM55q~=H}PVfl7?@1dHA7D0YBt>}EfI$C1cH`g-RX({D@*iwso`{LSTinqGViAWSTlX6I}Pyzy@H&=85KaiL zpcqW;F~4b$kLAOnN%MSp0gFXP91wz%s93PD|1I$*ln)A_Mu0YV`;fUzk1K-QNo3{z zm@vCt2xw?~N}p2=C7r%q2fk;@4;q^jCz!=uya&F&>tO(tzdMcbc#L9wE}yKnr(QW} zv1K8~5vB5}U8Z6k5M!BMCd!92pof}g9cee8-8Y_i`+9%ilLm(}DS=POyCT(OVwFI` zkHLNGOGZ`JzH!BI@)=IPt8b45;<{A|tOsMGUMD@7hl9|5JY|q6=<_xI{;t?D1+j1k zuzi*3eP+@AkU8`CZ?_J*@byh|ipSCWs;~Id`#ZS76zXT9E;#%<^bcMgza1AAJaKb| z>v|fpr|2%otIj;B>$*UF-{oL>w&CxKbFuAiZ7aqmNBnai1!ZMpo>D`)b$YfA+3z#E zRELN5{RR;Q-k~ApUgzw)Y4MT9VI3rGjq*gM0}e_Wh%Z5fhXz<`=p+95%#)@$!Z{>o zsUlj`B_iw-!H#eH*%lhMDj_k40Mq>(PD>bZ+|IX%>1DH~nP1O#+|aX!@nb)9URwg{ zoE9Ml<4r9c7>dd_t> z(7Ey{0&2)MpuBCS2#vTBV9bbr1fnS_Pkd9x!>+ZKVJSZeE2%JNEF?hdh;ZuidK%4t z%Tu+FMF?b4RLKfDL@jN-wNa4;Ff`2_z1kHoD<4~W3AB0?_rKwK#7qtBKo6<%?lzKP zj#P3o^@Y{247d44i}zUta{m66D}0=yx39OGCH%A`*Pk>+ST0W9sTH8^bsXObRTw*0 z>a>r`yJE6x5UD3Wz4galXF+mHzKpi$hnsh;#@RmuTyEBbB1ToOJbb(`2@&(?pZ{W^ z{|V4U1i-w0Maro$zTpz**ia@v8~)=!vW23A!mM-ke%Sr)Vzk_vK}uAWo~TloN39w+ zMYfu7WG*abOi8QXrtAW=&>|<6N$+;7R+3IIm2U8qmZ+iBCWEaQARQi8Yf;a(>RVA` zVlYK0qaPv+|7(7FFl)uDnx(tOCo>p{Y+85gCu~<*?NP0sYxJ*O!GFb^d$Mn7>Mm)a zpNx7EBGL`I=$beW&ulgLVeQ2_Atf03;TI0tSMuHw7y@J$W;8eynxFJeH<-|#Yf$ek zLZ_q99ZZFi$85tQt@T6I2kxtr)jte3Ok>x9;Z0T_Nyt&9Az3xdXv9lNp6Jo?Ez{d4 z*9AEz+Ad4&^bV`{uGMx~kq+k;RgxbRmGe*jf}QqEw=h*ce&bJq48+ub+V5B~3wyQ1I#%K4R8I zE(sO4r%n0e3h-oYOt(NUxHY~gT@vfr))!IOgb5LPAAM*?aG@}_#KC%c0*y0PvQPdN zbvj+0P4*%NG-mwZm)376(Bzk&3XO9@b%K8`$ONXNdqkGH1t}DGsZM-H*4rj3h$#=d z-sQv^r)f;5x3nAqJg~q4(J$T+Z@8Hi(DUvsh8etclL=ZIUB}_ad#ZK$l!nEZ)zJiF z67E^Em@+(L!}3gj9t6-aaUkd$w&VE=77HlktR*=%lWfL;AivaVB6o_tdD>z;%XEb& z);0J`O;g43(#n6iuCBKT(`_ZRW9Xrj+b=1+I;d@EjLr7GbN`ml?2x^IMkH9GD@V^+ zfo=XKL@)?oJ1eL$Jn@pAV)_ok z1g9hhT!EsLl$70vhnB2kESMjm8Z727bCPe58=?)S!wAJ+`k-YNTJ?lSLkIA_kH>8*MLe!M1dxTHm-AE(K(7<$vL79aa@r^DebzQX3@=C!cS=Wkz` z^AkW-u{)rg03Z9{r?gZ-%bDkyKF{moT|PH5+O1L$42y*HOLS8!tZjPIJS? zvyQ@A?6K`@v}>K>j5`Kg>2My>ma_g#B(~MwmCdsU3fJx`RK!fHv_M7F?qZb;)kenS zCw34hzXCUTq@X`?%FGy(D0ERAM&w~6K>t4S;aPyJpknnTT6p=nFAtPnci;DxMKT`K zKOb>jq53-rdMKyv{X2sF%RgXE1bw)^-m!+1Be45%o$$W7D+2wACfQ;#(T(mt3NAVIGn$DZQS@NK0kY&*Myw~de7ZE z&F%cDc`tyvLVG2Eh=ZMj3zvK!;L#h3hGso)(|5mmG@RTjxt+|sF|B23w$mM@cP$b| zxgF?0-#>x?uq}*shJe0ftKSO(%JC^_qUh4LQ>`EtMjxxA!3?{uW(aL3LaeYy?B|twJRr_M=WV zmHXuWIA^Y0U-I<`IjVSN=zWs_x#Is8dD}bQj)O-;yBk#~C?55*SS@3kXC}A4ws(GK zA&I)~%&c!&e^r0-Ay}lsB~2z(3trQiM&R~O|NIpOqXQm7EwWkRtv)<7J0%zPWGI*Y zz|CU|rj$`F9nN_!@jq8WquDT4lo=b3l7%$%5Q+eSvQMPXxs2HZTT{>D5B=GmOrTZ6 zdudDGp=gMb76@k~<@#8AQuoj8kc>BaNnCZ<99R#LM%QPB7$5j+B%vbfnubcV(h}mt zw%>Wj-sE}`570dUvAAGeJgPMGyI<24jt6T$s$n?a#w{{18|Y+;Kg0uhDD zE#_J|kcgB$mK!@-H5$HC_}xmvXZw~@ku&zxLAD&vHG?doV)A7QpUBKL456}J?5Qh? z3S*dqQB3fPB{A?JrxDFoIe3W%R$V!!_IO0)-ehA*!CHaz{58|i$)ovlTqx%7AifPE zrb>BhFYABnW7TF!cG)h=s^ zPqsCy%s(?zk~I%+j0K*-LgOsF=Meg-7_!U?3Cr%{ZWFIo(;iYk_f8MivVe0CHZn7{OfGNJnh4{@pB6%YQA5Mk`pJLrLnf ze$9`o72iqoGpr-@Sad2~R06FiW1`TG0kGwoQJe=Ho+lw<}2SAWlhgJB8e>qCh ztSTR>YA@Kk=w~n|%2v{bY`?n6t&eeOg*kgLXca9FOMA$XCO4O4KE6Vr)*3MN93v`y zr(6>`t`vZ6~m_g;0zS6Ph#@lEkZ~V8gm-ke3<&kyd>#5OI_W7L0O5^w1 z;^J2yweHLu!2qvXUxPodBOK5+>pJ>om{|04NJq>8w&>_evGkZso%2zu9r>3=&?y6X zLa1WIs&mAE75&R6c>pFbFHl|LOEl3B*(m?DarrzadggWh#6qoU*l$Vf$CN7$woP%V z**~<|H0{H$ggUoY2e1|_vfY2B6`|_@QeBF)D#Vc(1WKL4gk3{^_97;ZQINyPGcb!l z(jF{O;p?p}NzK^P%(en0@Q4>PrPyeTvdJV2}p9vZs)%)bfuNiEY3H8}t#jFEhudPHGI_ zB$M~o3%Bx2+n~eBx&5Tb#Od+r-$&OzZmZ%A*{)GnSa<*^$wUU%V5IB)G|rSnft&Zh zJ>6*ab;W7^HD6E9?yOBn>#&~9mBaq9zMUIMnJL~XN~;viu)hw}JFvn8&j4LnXb*~%@dyt;06-A*G2F0|fLUb|EL{Tn zr^=O>*W+2IJQv?Jx@(8%v*JY+`+G=gvjMKTtocqP4E`($bxIk^VBe5=(Mg$;qgcK0 z8}@YuPdNi8C@=n0Uk8{4=*t>AJK(h_UC?3gBF7M!#}Be9hjnQHRV%ky|Ab--sW)zu z^M7Y}tmt=C6&_EK*)LX?HQA#lk=s!biGTk23TtSNkBzO*rjAB0CO)6H zNvOqgNX615!ona*PSH{?pgzJCso2MbAFdGp{C->HYf}juf6pnWfU>~=Hjw3wBX?ax=`cB1M+O=%WOXhEBnw=qZdy;mfurzMq5&5A{)}cDgUL6x#hM zE1q)D%OZ;$B*U;4&QpsTIzQ5(ZvezJoSas-Pa53FXD06g1h?|&J8&aiV(@m@uwUUF3i+Z16T+G<4$16{&YLvbsLnR2 z%tLmjUz4j`z`D-uRK@y%aBJM8?RJELjuAT8Z?cf$=svLSc|!WdUJ+&Z4|7=~%<@tx&;_|Hn zPeOB>Wb7d^wcVblsDso~<~c*6tmC+4X;uDb#=|W0tWCx@JInz->+boCdB5~E@AYd_ za~Tt$(_L+2xxld5!iNar*$I-oIBu0M(T_$Cg;AHKvDlJ->=e>TOyakvPjA~g0r=(! zuu@KE_*__;j{uS&X}PJw@eVi1P^Q0M?6;mMbEa0!rEfzig4c7IGp+H+gOy|vN0*iZ z6UR#`FKrUp5_+HuFjHjQ(2p_CcyO`sFx_^eWsMs=`E#gmUa_WmeVAde+Ab`dxR{5m zxr&b6T7w#O>hz1W=6Aq%d{qK8Yuvi3*LQ11wnNG7^mX*m{NDb8HW-j9BkKD~HvN<5 zc9k~`!4C<3baB_rrt!`slT_9X4~PZ}?$T%lT9eit3(tVZHu5qVv;6_~@#4_2{-HcG z8Mtqdb;MciNBpm^?CS6qY9$gQm|;F&@K=AWL8movhZE_AlIQ7GQ zQx$dF*T}{U0~Vc-@S!cjzt;$Gorzc)f(5Gn{wrA@^U>PQLhu_6<5c6N&tlbIr(~UA z(f=#|%SJ-BC!Pn%WfJCC$FJS){w5?Y7F8|MyyclbAPH{D0szSRke$2=(3M$JDr*HL z#$6Tug202@4a=2-qt9!wdzDf3>jUb4lN&pD-$T|25@pbI>c$%YHqtBP=G?-zNt01} z>Dy-oU`%yooI=*o(10f8h@f)HZBE{W_wvsKh0Tjv8{@K-!D%mF5TFHA*7R|BV%Jet zsgQ1ZS7PjewH3jK-N{ti>9MZ2NYn@%bZJP?G?Wd{wRkv91E-Bf-!=2%vBh;-ArtfK zY=Fv0e@HeufaB`AN9ef5OC4Vta`)p1HObd;i1JFiw3Pok&gy1+!Pz2kcXeT=yA#m% zBH~{-V@8te50bm7yEa&31A!sT^=wiGsj0V1T`Y-N%tz5J&_3)iwVmCImrO_$ zdKNT(T(y@+^Ipg_IBe~{ylR9N2Z8thtQ!9;9W~wNlg3_t6%KRfpBcOo2*3M0((Xnf zB2}BGa-tV5Y^vopJ65|~^{JI`xzQoCzBySz-k{CGc!x!@=}|>ykDRDvJL*6yi#v&{w%RpOT68z4&R6t`gk6}nZq5paIA`8TC;%k;Xmt9Trq0! z3oQP8rNqs}TI_wluC;?8V5J!H3HUNSJ<8}lFbK{Kf)`PVFFb^L)?k^Abm8y<3L8g6 za5BuMszO;eei*#)@XtEV3dljPa-J(GGyi9vbCYd?+c52Gr?kGHVt3<|w(i`T3g|OZ zyO$EZ-(5T@_$Gd0#AgCcelzV&Fd+=Fe_mqwlaNimPPM?9(ndL}W-+G~lQ$4^Q7h#3 zx4tl57I>79*HG5Ass%!UVFS-FfD$Op@J8ZhtY#IBJepMZ_s+vAFR(gD+>>>ZwT1&7 z%u~|H!2wwc`5@zisvQz&Ass}A>i7>HJ-#;aF6fU2t9VV^0alo=PT@q_vwNZ&s#ab> zW;JX3a$Dj0VTax73N)m8kk&ATgV%51`9x}ba#D6nNn04R1Rn4m*+busA$BkEhnQVD^1GMq2B$? ztVY}Kg(_RrL!}_yhk4cs!5hMF>2~^ZQ;Q`=m@DQad>aA-Hacd=g=4wKe7mRI>IYoW z4dp!(KPOQ#9;MUzagfvCwlySipsB}By@#1ZVk~mzyOei+{EbTaJ!GNmMbh3OfcN(h zirsv}YG7kYL4J+N1yxI!jK=P#Zcas!&8##NcU2G1HD25H*5&o$2|=twx}mms!ik6v zG2#_%T?+ae5_5C=auw+%Z{kcNXv~W3&{OnoKwq!{l^|-2OZ<>B&E6SCrnR$qxTIBH)1X6`_;;v=pKxECsG;Fyc6qX z5#=@ZG-wX+CcDj&S+|$Xlk^E`GIbO3(i#GZB3flMu&S&a*1=}^qbqQ*+$n9M3G=~? z8Jje`j-2)biR$ny~nY!3`X6TKm8~Stp@CMEPE%S z`CqsCwH%<^)uewCMAPvIk1Sc}0}ellO&nO$>E!Wg1kKCX<==(helBVQNS<+#va?>B2z3@YE&o4`~YJT1N zPw1Xr9m=aN^pQBb35w^u^gp-D(k#tL9?-*Vun!42IH$fh&FSQ1DAK8{gyU5 zq@j0DkVvu`KX{EpbNtWwR8$oaYd3BuA-3$j@#4JL@7+4FhB&N`H5F%v?9iu9D`#Rv zK{Yk-H#n?Mmz3~RDFQX>AMChjx+aDwDL6DtLJ~v(oGGDD-9K6;|NjT^7apd5e8j}k z@_c;wZBwPzwaFWk7UUa>AeAR|^j#qHSu11w*P1_T^jU^e@P`Pk1ugtJso6D%#&^St zHpYS++o{JjvjYCBfuKV*kZ)?~$--RR+)NBijC7p9gTG8%JUf%q%!~kT&P5(>VLm1XPT)r%_Zsjc zHzPMU=RWj0MyMe}kdKua8Zp8r0`}@R569lgyVCi%hZ~)d@vj6=YxN0tvVme>mUD8= zl|0cSz2RL>M^;bh=6N5AMe-SDL_=_T*|FNdM4wJG5!$q6bCjdkJ#)^&v}bSuUNWzO zQh?F#`yWi44M=SH;DC_kIyz>PQzhpBqP)Y;h?$MEOSeq)pg58Bq|M zn&;7M&vy5L-!nx3wHFhxI-n03M$?}l9o;Uy^JS(%J)tR(B7Mt(u;PNVP_P15o)~IZ z4eGrP0i5RcYo9RTRxDTtq(=l~Pl8jUGrQ&Vwy1b}o^51c*dSh!Q0{l_!UZl`1H&yI zV0vWaZaD#Hd$Q{BLr~25$+#ijZLk$u36oysGV=6dsfoq>_*pvWqrlzoIt;8gi8#74 zIlq2&JpPJLCSs)yp-rklU0Np}?`NrQCNHCB4rAX~;JQA0@7gb~iZTO72toTUUc88* zn+i#2Cd0oRqMcl2TTol-eyha@S4awTF*`)T0?hw4X9<_QWO-z^Ve}AGuA}0DUCmzR{K8(RR{!l#riDs zYKjxh_QSVTp-pMH1px{>(U7NshivVpI(#9epdWJ|WYnBUa3+bSPUz|14~(HK_1>;0 z^WOY>Ka(P%vqSn+ocX=}T*Rz`vSm_d&z7ai^tQ(Un=F=xku+67yp^w)Brw$!;Q*4# zZFyBbj4N27W-Je8dTQ7QxT2u<8C06DI~df&i&MK}+$+MEP1lB)6Z6cB#T|E)INW9} zRi(5l=_01@2~SZS32n-c)_s|zydPgTFv0d$>)Grh6aqq&lO-Ka4Z`-BZPqNAfl4Wq z8I3}$1fTi~yCr)9UUg(BP#<7!<@da{#4>+4sMB{4qs8--?f()tbjWq}iucG8kX@%$ zbuESnYNV1>B0n&STU1gqYQCm*9gW1qj6Yy9URvPvFwd768AYK+m7AMT-Ce}X*iD)H zjn5N{GQP!`*~dUMxy6&#U@l;0RV&<4`u<{($y29&;euwpczicwfj`Z8G7(jp!NqvbsoAS%`1;2kQG*N zvx7DnDSed|?r$0!>RJTW;CuuTgW%X;9$50QB_!Oi(WFGgYbqaWW^v>AdR=5svOmuajzz7mp$= z1Lhxhkq_V?S}vtYlO76*1sg!{6-)!L0U*s(`b_+C9C*pIh%aid;fWdO#*#`~vRF+P z&l)fUba5JAdVlAIa8`*I)>`Se(8umY2W`~62-Z|yABuufdG4M=GWi@2{L~s-YPI+~ zoIi9+-bE`^YWf@Ew04697j1R@&7=@ZMtFZMF~A}V_+P>pq7k6O1_TjOUzS*O1xfhB z{PSf2@>NQ@NRE=ry2PoI$t=v$-%jQi@7zUGQAVV33lnV;{E7%h=A&EkT(`_w8_SG`TUOA> z%MqrAvmIK!y!}SENyq9=4|MldYi<{pcs(ZKdGu>bW3=HS6)XNoaQO`C`f7Y)~N@gu5^oSj*qqjE&0ca!TyAZ_^d^WBp3FNRfBuo@{D)u@|!t`~q;KQvD zxm~Jk=t8OScY3XHBeKfO)=k!i&sS6USNHMmZ2Nw&t>><;_GXFYQglbKrsscGvaa&2 zIH6AY);MpH?&eFa_LV|Zux7{u%e8H9bP{2E)Q}cNvzG#(TwX4wy!HFJrYE0i>5EB~ zmX+)!B?WGGO7VdI`n$tZ+O{O6pW;twFc4<`5$eAe81DE3w58*=a= z*nTko{5D5T29lYRl^d&*OwZ<#_2gxKGK#;sPmLr2!>`Pv{9+%FSnY%xnt&p@F*o`^ zUhl4oGwZ#{{*4fb_kY?8mK-#2Gv z!E3w@d^R^pLvBRLuzOba`eBxeQK6=#yC4P@7dQUvSoP7<*Fl?G^&M9{Ba$@f4sAQv z9I%{9$li@V_M?F#cE2v2L2aF48J5D_jNn>lrb@MKz_)1JPvpf2$sv=vHg#FP<0ZX zRCl(fgou`XyZyzB*oefRF@Ehxfkw%}dVCTzWL+)77q*%`;T&1SYuZOCt>P6_T2{2> zd)+h?yl(pQ&os~=Gd{OQuA3uwvB&6~e~MhF>!wJYg!Ig&X8ir7I!E~FDkVHA;tFaM zn)#7H-+3hL?%gU*_8TUZiFfL^#*q$Rn0%K|WsY?e{w;C5_ZEir%~%;GG-HvC2xAT& zI^~5+IE9O{B}$HU_I0?wePdUbrosUa!(GyFq_H|9&_h$QStwHg26|>J1winFgpZP+ ztHLVVPd46TY9iLSjqnIYtcXWw{&OE3QKam`9Yy zPkYe287WuM;bZ^qICrxCh6a$);7X-~3u@XGQnRYBX<^kd!+-j;sR0ljiok$mxOTsA zS7U-K2gfn{{Pc4j2!N;wAekUIpP+9?Qz4S_&VF#c(D~Y}>EPP$NuhB&d&_~N04b#O z>E#ajRJ1Z9Ji48HkEHP2d^^F$FIH8HRBn({uWSz`_Lg*k^%NLmK%~}JGm~@0&?*3#?GPG527H^6gDh`m=c*$OE^y`h0^x#_ z73{DeRq~2us6h!C)hfIC-Kqw)#I4ns0m19{_#m>=5Pl-z69>Y>(-yYSsP}^UyQOdG zd<^;0rzlSIDf0OfKY%ebS>Fa;ka?)sX(OQ-07*-x;n-IP)d4J@En{E11eaPnjwQ+B zrSW}lR~DH0i(3!$53+c0=seFH*zA^K)~jIj)jmjTsLA_LW$+vz3eq%h2)UBA-}tFB zyJbFbt&~z$kQ@qh4k*uW9=5E{Or5x(>Z_^dF`;2EArdD_kCb|8)V$pyTSUanF-o&7 zNBp+Dc*$I*mnsNUN{qqVl$@YU?fI#wY^6U_m{`8PoiBrsNlJ+^9*g*x`f+|BC{WqJCgHpfu3OW9c ztCN{xat-K8f5n+nE7(GgE8uTHoeN+)K4SdBGb30_CPFAsPC$g|Ag?ll%Pj zI^Xf3PFFH$NCF%!i*s%I*8S_hyM|rn6=?}A&=(Ott|ccu9z^u@p=)GMfS-r z_jBE$11hQn8P6faQ7$A_(5R|quT-?Mzi>es)_wKG_svgEYt~CkYClMm;sYSaEE&Zp z;|4HXWi4h~G6xgB%~le$!HpYg^d*}^H^+g}m9XSUiXd^ODQ?Wa2M?zs_0*AvJ!C$% zgcAU3RVpDFEZ-vH?itBSdrxRU4Ki(5Aq%eNDg{wx1phm)qrTCRnMO~QrySmcEJn}7 zljbU8ODPNx1n)Yb`or-yF#s;{DV$$hsV}DraZ|B!vOdM4m)|x;nhP-tnzSx4m=FT$ ztm)y*zfhN{HKw23YcKG1m0Yz+EW9t*Ggx$fV0~6>7xJ0%j@Qs0fKmdm|CU*A-Mos8 zS6u%U?qgr}$bQ1TcFQ(Nozw77@u%XAjkm~&_R3Kt)!GkLNNEhNLAzJk&4hka&>a3i zNB1I;U~U27v0Xl^EAJ2``y=&DxtTyDls8(FDqJ~f#w83e6{_}aSuXd=;n#sWSrCH8 zaA^v$sHGrOtXl#}7qR9_l@4@dT1_H|Rd^Ft(}Hd!vJ?VbS#acFMd<{3>!ABv=p^6R zCx(U4O4ZHt@A7PIF&tV8y8-T+Mq^i_#(xmV<$T~`0g!*b*M0N7N(BwJ#>n1BbJeRS zJ4C*Lie3zBufDl`+-C0DF=2)`_Cp?l{V?QmaxjU7tTf$$KC~-@T=*Fl0`z?hp4Ep= z6LkE`NYF-!!LvD?EJaI!3@tDrYepNZ zuj@}yw|F&(r#MXX)ClWIoP{2iP0j+d9l(6_3LBaQbc9dSa>I&M=;h*@?;?18*>bW{ zI;{8>3TX4$GWC=%2MaY%oIb~*(f_a3AW`vuS_1}DYnY)4`2c2MqzCZuoG>sla`E#p z0ieOAP{0KvGZP~h`?3g-3yQ+{$j8G-4~_Qt2#q=A;^C*~147Lgj33##82-yYc+~C>XY~dV>|+_xepk!ncy#uNO8yRw2C0I^+FXLLh|mEmhOvak z{WsPQZnI*A`Lh)+qE(Q~N|sQ`xU9>9PD_2iJi@?#PSd~jA#MIm^OWpn^WNQP&jMwq zK^_B3K}SZFqq$vHOnY2Vxt>XVb`IMs%}X#ly)+}IRkbToWGG$o;JK>vJzQ6-ke-A~ zQF$kx0Ts5*k&@M?%_V4m!w>RwZRh#g0&&&wuyR-KD(iV~9xpV0c|SZpoiTYPRD=V_ z#iOevF#j&l#rz5fp%`QL^BcR1tO6#?L1r0N*ftF_V|YMA=#U{n4%4ucQB_=N;rsoLR`D~_pdb%Hp&_<_W5Rry?@kal~nXl}ve~|x# ziB|36(RL67;IwgVs%%O$%bxsXvVT$Z-Et);J&AHitzcLMWE#Zqys1#=qBFLgSId`sdr_%NPdZ*36H6UyJT9*>klJ)7#Cd&R62{4*E>tmGIzfEkq9RX5S2LK( zp-`^xTdP_K*O3?$sG3-W%DbE!z~m}FQoq4_a&dLry;K7*dTEep7!==CH2(qSf*Rmw zLKC5@F%w=6cFZS7TYv16U{Zbv%aW$BV)4#tBdKDdRsjvPFX0u;fC}&QE+nG>GV}J#>wp>_JswL@wclWnT2VOTe{O#* zI@i%qF4XH*5Zi@^zrbgeW6IFivDVGgyL1!NP4l;-5P_l~{xXEi?ZL-s=h}a>76EsP z3;pJ{#+6Iaj?&YP#aea@?mA4~mWN(9TLhvV*)Cx*U?{f%p8(4%-Jg=#Fyftc4~-0U zkI;}vp}@d$5N`Iy$`ItseAy0Kf{-=yLTz(vhv0KC96 z;oCvB@}3$D2^cSbGL3Dap3@;G0H0}1acs)y23$Nde8RuS0YGwm!V?%#%kc6st&3E{Pb-?Y zsgh+UxqhoVt^ZjKwx%DYq(<&B5pU z4tAcgy0>*Szu|#W7^I0*dN5Y4^~1FfSj7CC!I~7hmMMv4@U}W1sfmQi8uf{CP9QAp)q&N&;4lFWQ#LxTYW3EvE-9%>JS=++$H8IurWMHM`DESj- zsJM#eDvGrPL35hO2ifo3iAGFeOo1ICWayewO&v0OqOSN6wA*g z3k%QO%ON#~h3yPw1_6?#$~J~BwX2_O1$;N?ZVVRALZADL%EktF|4He77$ya9VwR}j$gAYXSDjxphL?jQY?2=ki1NLT$UiFt>LpP8oa z1y<$5XC6Z#b{@99%Fm)YpuJz{=nTBkXj@_qvHV2ng(`oLZ zMJMA(V)lj_NJm|A9~F|noyDPeokVE9+j>!94k(Yf#6I#5SHg+C^F=u=f4?07Qwpm$ zu^>32uTAbj{YxmFc980z=wzid*1!95!M5h4!*E+%NF*Z$8vK>YV$BRnsh9XwC5=%p z9o3=Q#iZ`}{o$C$?Kb0mtCfn~AWiRPYBl!k0v2=VD|@N|L(I~&w>)YN2TDqGeA$|Z zq;mg5GFSMMPGZ?hF6Kj$w)r|ltLN~()_pIy27rc=11V{tt#516X!=uKxn*UKKy5XP zaVPpF1AI<*rWwZP8MS5aA13oOTOX_-sTfnKT6oele?~fgMvYVY&hTBa9|=#YpscB> zq{GGN#P^Dw+$Hv{CiLeH@2dZ*YQ8JPi2S-f>5|UE8Oi@uRrn?@ES&o~+CjXJ_6X(( zYVVP|&=uP{u**_T%jSY`wI^+7VuH@D?%eFqDga8wi=;~=KMrff9wQ_Vj$03TCUCHo zqK4mlSpmj(J)N+@X={!e3y!0j=!b7{I0 z9?1?3Z%g;3a8<}8a?ScvQ>AS!ikla?PmOB^4BOaJ{J(MUXw>|cmZXd zGm({)%UWU>vyzTAL1VmC1;&3gn*9$1TE#eVY+!)iRo!Iun-We-hJ2<3(wt*;thbPc zbon|sN5raL8G*)mp6I>QQ93z)XZ{HZBx7JOG^=n$@;&o&2S2oQ&5l}sD{Kkt*tv>; zi~y}9IvzX=>H%RIf5C+Dsif#Tj^-alRmkv1d|fc|`3=6*ou<4U$W_QFG#`x++u;tbc?1#uDrACOhP1`Di1kuT za&0`wTm&CnYhj>O3O<}I2PdtqUwEI=snr+Py}S!Q;F3Votc5gw!QT5gEPKL)z9xpN)1JjFg|$#|awx9fxb_=4&Wo2D=_B$RvZkoG0XgX3f3u-PS60}|~8`-OZ;*)^^%wSL%`nsBGZFz zigCDxe5vvlutI?c^PgD*l2aOfG;7m_fhwVzy8kkmuTjXpemKpvAR4-WAA?1SLC7E% z=sPs`w-Eziq)pOYNjb%>Sw_h4s}q0p&&*=hdB$qxjW>(91LPS9gCK=L?C|jv<`z$+ z5(g@6ac2A%)vmd_5bHrF_-;-y@~a=RpXyH<(#AeN5D1*fSitq`j41j~9^KaRb5Yst zCQz;2@2lTV*~~;bg#g(MLdqm*pLcX2Y=~Jv7*L&a^L~b8#QYSmn9J0m2@;MlFoz^Abv_%>C7swztlc> zdpp`+Af&p;Q=4G8z(%7Pz}#0-`QYrp-Z!br8A`kDXi4oq>*_JI>d55iyx&c6yGAL8 z^PjUQkV@Iu;isHn32Jb{3jqC0i8)VCL^=f4mPR@sHBtwiunhGOyXfzU<<~bA5r7t$ zcw-j4=DuNS)pNvsF3yzvg7w$A0Q1&ns$fGy(dZa$#=dz+ClQUlOK)T^rti#LG3!m>rgPa-8nqfCts9h&u&NRei%XDEy!5v z50grT+{@Jc{Uk8Jw2&rd)7t9sXDsnjtip6`;%PE2%VHP0)FPfNWa{^aj?1s{d;PO* zUU}4=&!cr2fXpjs>yx9) zQsz$$8ZqjTpNA~|gxQdZ-E~VQiJm7gSo?CWvQ{9?QcAJlrz1s2+-B8q-yP$)fUeJe z&Cf2@PHaB8wAtJOzmTRb2)8tgpNi7bl3L8vXMlHWufXgrAKnVm$ahcZV*^(Q9xM_| z9N}Sr47I+Cv6wrax+Gx-oBR19NmNo4U0Q~1YD42HWZYj?jKEMxg09Iwz*3Am}`cdPA(F(ort~?3W-5Gfe$^aUq;`4)( zY_;7iG@iG|tTvK_$Y5juRr&f(Oy@4qs;xB#hEs#9zLp zrMz(lCfD1DMQNw2$4_6qZvDD?tt+JImG!O=w6pnYtx4>X;_Rc|-_ocyH-XhVg`goqopjh4)k_Mm%+}Ob`MqhswQYz52-M zmS=9hr8U1!;v5TI+%Y9;C+~2bx{f$nN9lt!ep>RixjGI6)QB34)(n-$5wc2L=)45L z(Nq~p?28If-E;q*CJjN0TdWysFiTq0HTq7+SA6)9GB%KJRZC56yc(=L6FpAW)WXkj zyJJ13K(Nsn=E}VF=PaUAz<^2gjh>iJ5%0~!oUh@Zv4eNh!jMM*9OHd(d2^6lc>$i1C zte2Xb{Ts*r^uiXTYlN1SV}Sw)(Lt!GK%C5bGb=nG5F?0n=MX}}pymR7<3QX81Sl~4 z@+CM1q6NgDB3FCK9f<0>?Ai>W2I;BMPgFcu7uGj`VCb4Zd}Pw&%dI#@Qu%2r_jh}B z99_A}zUCizPs~cErr5p=i;d?ggay~k5K>rqaAn%^F`Q2J80l3c=j&*_0i8?DR48|f zWOsgd3CO0U6}s-&B&f{hg^>O*MOH~Pja;5db3h|PV>w{pW_%8k$xn^=_xO8l4Q-R^ zW014SIcei`VPSuiws4_Ujp?Vn)`+2`8OiO8+*PeCSFNnwgqvt8Pzc0Xb zE5`i-8IwMv4JjrLlVm4iPqYE$PxAv{b71bXD%OAtjmxLy6Q z7Cv}qe;V?DM}W{MJuSP^;*HMJJI^&P;!3q`l3z0VGDBTBPeS_ezVU&744aIg zKj@t0ku~9(uB2BEj1*qYTAFN5nd#*ZXzB%9i#aUgm4hZ~bt0>5W$$T{c4SD> z3jYpfFyKy6igMTdg>p`LbdBy-%P-et1MB1B8HqopGAf6c1kW7Y7x%9N`P$%sU`!`4 zB&}Sy#fZFM7=}mEwVmIxTNk-U4IAL98^Z^BZaNHtrpK4?5y__j){vi4;Y+MN~_ z?MEg2{G>uCw|xPIb%@A=!uJ@jwmAAv|8g|!7A(j-NeQsLR~tw zro$qGXs`b2wZ_8P1SlsY1|hvm-lzUPodjb2aVt~EV^Jo|_B)jHwfaiS4X#CezHGLO z&#vS#v`r=`DoMy7bQ`PcYn)gb+OsB07Mt$RM6h5kvNJDam zBa>Ou*rzGuB1~_m^{u4*T?Ex%k9~mXKMwE^WpXk+fzhV`Qy9C_OZ$3rQnaO8ksokE zcO_r5xUD?n>*NwETASerkXRrjgehDuhSgoj?l~!Q zN{0!!0en5aBZZs`6nW?lq+CbUc(tL@IGV$^9)si{K62k}~D7+nq%5s-?JGs?n5f z=^sbou!L=X;Xs#QvgSiTZBadCHfc2A0e2r0AsAW+`tllF4EXg4L(2yMc-zdKNc@Ub z{43lj&POMTZyQE&xUcKQF{P|1E}Qna;6+}u%8c~Qf*$(vJZ4ATB>1W=F-kR%cp~Cz@-uGu!jqmLCTsCUH_~{1=gOtcb zTmh*0QtqBy1Rz}QQU{zwoxx3G))9`}D@{?Kok*&Q-@xk!h=|i@IT~hp1R3Drap%>Y ztyVQpBB)m3TwYVjLf*(n5Dvj~tq2y(x zUe_T_@#4DXHHl3h{Zl}-$8a7_!0#V_(Skx?mu#Kj!IbG5-?>Ghv{at*%q3&(Jq*Cv zf7! zi(560C&&<9Nn-#F64Z*1M{cwsI7*UyBrn32vMb*Z&&reE0KuiAl*-)-pe1K&WBxU% z{bVm3fpnq1-MKW8hiAxz&oiA$Yx7KX!dWeNJq946M9w#ZL3$+s!kO@r_ys<;t2d|& z8Qo@Da12Z);7_6h|5F-9;({fVLA02PlR3NE-whMywJ&R3U$H2%XxyoK5ZHZ~G*3K* zzo{WFLV&!@KztsqyHEGxOBGD0d7Ta;Iah!4hC{vmwvp$M)wuG^JR&|MS<+2~$h9mh z$dFejd*^=t3T#gO3$06h=hzmp%f&JKGNMm%C6>GDPx+z^j~=oZePO=gi&@YGw!fmiwI^ z2OOe<6}yWm1`U>3-n4=3y=c43cI!X4xobFtwNjSGQwhR#Qgk5P1`@TTm)orKspQ*D7VnjMOtbH59h~;K&f9h*6Fh)TkuiYV`>Go~wx9 zc=6#w;L`cGphajc&dJJS9oj3%M!lYWd+*nS@qo$nQE{fUFoWZ*?Q~!HUS!KG^3W1} zeb67O86Nb%@yv_2s5VX+-@IuML}FLrZTS%$JM54neqw~&EJ?5ShhBeGBmKbeH|Rpf zWMSiO>oTK=#BVJwi6hkcRq*(BZAEUTN@$2|?@V>VyQa{9*@5v{wV&QZ*ZNn;mS83W zNP>1~29BC9-e{M!*PjjQUK+wtB#)s1@11$`y~~Rsmxa2sseiG!F<(#;*cT$e4`1O+ z;4a#PW=sB-m z%ySls;t3zB)@(`!sYXs(f4tFCq_dpx_{2ZqaY*TOyLj;vkL;aUf*+I*!=z3aKr4eKZlCW59b0gle1w}uw4)lftEoI> zSdsg1OTzoOkXQG}97G8#A+9L0P7^$-n#EH#vmS_9Z5~`ir?}v~bMT#AP}u1*!qVN? ze&?jj8OXO_;7_;35s#{I3}k^fg-2|Tk^6K7fCn^QCJp2*ev=kVtEp zNXK`!cP1#%^=cMmKXH90@X@YUi#K-8*XoxQkT97)P6nj># zy~<}{(SKPzsOS}{yi2n6mPQv)q6-mT$>kiB)8aMO)JI}j;2&i1*_sKRMszA&(DHVekTGKK3dZ`(>Pe&=#9zw6Vk9! z?7khA7qf9efJl)wW+hIRZ57JRlMl2@>Czr2W_dwx7K+Y^iyh|c2jK+A<6103|MFM% zI>TQpj~o8}2h^D>8?hW)gXTwadXum&U9~z+A~rYinvc}qx2#*9cw=+KWxGEFJ+hTz zA|1m2kAXoC4bc|SeusZ@AwuS4Gk5=H&(W9EbO4Y`N@qPh*1N=*<@#( zU)hHQJ%DuVylZ=Wa)Hrfwb{X(cIGjL$+De2As*9j4U?Aj;Qfk}oMw&?&<63?x1`jQ zj?Jp0>%NJq1Soe}O4u*K(8yQ(0^Hf3^x>&oJAG!BCN1WeA80}!j4Cd=)wq}8D7j;) zUq5)WW`PBGF3z*tLJrq~)VEOVD@y9A7U|DKVO9KNh*Dxf&jD-4Npot8ErgAzl|g(L z)(YjC6O$7?#{24md6G*xw#tX;TQR%9q5b?p9Zd#Y1x=?@`mCgJ9(4ELVB?JBc~8_K zc|MLhO5VFyPj5+J8AtBIaDMv)WfqLrIP#^pVtyk-@?brPH z$Yp%9wP|KJS|mi^ijnNw%*`v7TDuIu1-zTfAp8H-13ZZpppwd41D^Ppe_7Gy#~b#( ze_VMt#4BZ|SU1%PnCoUr?oY-QsG|?2T2^FM%C`SC%`wPJwybMOFqLp$l+8gyr1n7& z*XDIzweq8^tZn9yJArTEUfVzE&kd!^ca|RBMQ!r!?_m@L=5#Tn;-7QJlypC7Y>tvx zAXh3+G7K>^-$pGO>t9sMj1LsdAiOG_)4MTKxzmjP8GwzSkV^U$gQ%Mba#oCR1c17F-fT2rxE(a07RFvX zlJPw1vyX}(mY@xcK71F9Sbb%03Gq>va6ZiU^a;nNbj{X`=UcPAa<9$OoHP#WNcbU8 zJa~4}CuP6l)D*JD?^KY^1IzN=0jr6(S3TYR3z)V3M8gg^c$n?1z!F{W9LmCVlINwN zmtXDeZW~UD@+nr&>0WDlmpLh%GXAsAl&jDIM$PG$q9u*@MC0|{kC*x1)rgvfVa_}V zGwFtPI3=@)-LdV{CLG^|uxPSz0ZGUstA03Ft-=q;+GRC5&~`{{3IG3Gf!=t;`#UU^}3OK85Dt$ku*6{a3LNC`Dk zivnWzCafwhQNNn_qSOYHI8Vj@`1wf0UYUCqL50pS>zC%u;uNd~z)&u>=M>RZ#{yP; zAS_P90vpRakGEdIIqY#X!g*0Y?z#)Yfx3REO~bo*AmY^J*Gl-*RmJqXQdL!~eAm{2z>7L5 zUXk^4esJzs&S-=E;7L0qUh5CYq|WqPT5e~J6WRZs$0}Zs)@NNu9cpR6u0zx+P!)Ql z=3w{QWxSc%$^OBvEZ6w!-q6ST6^zvriIX(Zp(WqCSB-apsTM2Zpi|Uft&ZWbrgq+J z&EIhPoH=v)k8f&_w9K?+t9VPqv~tbDwR)V^3lYNNPyY1M~w ztBNKohtnmuM!+iG0PglTKd8>B;(lLWL^Omc&fD4@yL~Y8Xvkl}a3sbnnAJI%jPOV{M~te@YMY*mt{e9nW%@vJ5eM`R65qU^E1P)9PK4e>hI zd*_!?E)S|k4PTO&cyGi|^eN(z{!|Q4Dj}bjP1xHB5wtfUEdHY3)KUj5I>BkYl1eS{ zc8Vw%Fn+n^Rf4o#FrwGl+L#`3gP}Rt$=M`B5dXG5&Z#$l5SZZQC5uU#V?3K5!tNQ#aDoSRbnd zqd|HY_tJA}7e*rU^=s}dOAsZ7ot+e?#3Yu2N`2YVt6MiRydd)}{G7enMv-o9|w$4b8d=;f6aIF;P1$YmX6K};QOoGs6!V})s_ zi{CxwA&9LUb?LWQ;3AVBIdD5zzKw_cH{FQ1c?pumCED-rbg)tCiF>N`tc%;BX6Kq^ zW<4b8nfVXRNpD+H4v%rHSzrDfN6@xUBDftpPXv5)t-X!Bkx(jUpu#*ygA0@07!_@q zeHInkc5Wtl^ylAco{iw^*8%8IyWfAz!J#4`N9$E$05e0Kq9xd({SxusmCgG3Fu#23 zIXr>?MG%`QTrhml{Bf?XUy!^bo4`&6}n-ou^_=B+84Mm>>ug@l#(a6|P5zu?@{8M2n@O_b~-w#?ta&9~FOAuirFtQ? z>Y_@0nN8=`D;JIYIs^9|X&#);$#uI__x8T$t8g;Dzao9-D1M-_7yBi1=7;fTsLB^PxT8YZdB8!xD0 zr{*nm&j@Xj{?Hp;&KmD1>+>)$sOzh485t)!#cmJ~Fq)N&j1DxaMHP)4T|GIQcZ&O? zm`1APWvUVxBwBaOgUL_%!w<9Zjcmm)7Hj46M+| zz^IwwO0d_f)X?*7uY}#C8|``H8rKwq&_Vu2S?eeUc0yN8F<;!TtMgK<<@95q36s+# zn?3^GkiRj@dSrm!#upJ8{jp+1z-Ijm=0a}CQ@a{^Be}{n@l)dO@q?1_GH3P6Ytd*J zkQ6jbCMD{yRp&DrbZDt+QN^HXtwCvNw88A&r1pc6A<|*g_y6im2qTR{=pp zP}Dd;wFD>9CH0O}Eio@{i8V8y=^Pr9}|oF`!2dt0nG6M!FL?hTY7~b2&xJY zQ#8P^ZeF}i?GXi)woKyAD5*%>f6X+mOv0wEYOJSI@o4R$OWcVXui?Dxu`0&Wkpy!{ z-yLP-w}ux$82_b38^P1tt!%;hQp7B8akj8ccOOee)ruHhFJDw=Q zCqh7Tj6y$p_6;1ItM@}%_8~+Jk~G@Wo4xyP2pip~j2to>l3M-I!2X^loLIT)=4N$s zH`{FLQcp`8jUyYqC}DF?UQ!N~ zG5AYNC$ZA~D|?|(Ltny&3Z%;Nc0+b03@zARxln>mi6YbYC_Xn(plGC4Zfx&7o7UBx zkgj7+Skb6v=9bn?2aFUuA!vjqgN4&N_RQw3Ogj+V(m~5sXr$<&f7&S;zzgpL9_l*j z?617)!!GrT!%XGcVoR4bk}xLjL`%+=gi3F_Tn0zqEHYib`9_L|?Z^5mMLNUa^q6ST zIfwvaKOIaoKw+C3g?}pa2X!}b8v#BwLSaB|isc~E)2N}azTs_RKsN_))Iaz4_`9yL z4Ej=ZdU?<`T{IwZ74)-TK_w??wX`PpRIfgal~&?M{ytgf|8STj7gQdY=lT@0;JMknr(@|<*!s~b{bU@Ex1qH062m8=DwY zh03&^(N>~PP+54LQFBrp#&>YjnzU(+>ZE0aLR93kKi-=vA87nnl^+-y5*z>M@rK+! z9|EPBt@KoYtk#RMW_w-iZ6EZyr4ZKvZa_YwP0h!ywKTOJSj9`bu(syc^fypbKWp+*(paEDVkKx+b9E)HJ=J3hE2EnoG$WrN zI#<2|FP}YGSr7FPLQ--Dy%yn)BOHozTI2rl;RAu>m6er^r8Ca^Yy;YEzWlTKv!KahCqszFa*OKb+lO;^7!| zdHcY>s2kx!{re8RMS)57=`Wn`;p?i4hk*IQ(19C&)saDyY16hT*pB8o{9jjc`N~*( z`Q!3Os>#Q@CT(-7rDyXRmh=N0&l>i*qvvoxnODq&p<0|XCQB-8D~a*zcMh3;?rDj^ zP>q^QvZb1zKb7-D4}=`oWH>3)tO6m-Al>d?$|=e<*)mKAhW*qjED+J;q!{&w0~2u-8Obw~ReBhFUou zS5Oxs2rV20?^r0+Vr}gu@T-H#8vH!Hd<5pij3(~&i5e`T;_6?ExzNb4ZP!>s!IN=! zT2T3tu~gv5`7cg5*GrB!z};=DC3026agsm{*XW^SX}?RZfl!?2KXOn!tDQq1~iD!praHc%LOU; zfRHwsnW<CegHSz z!N2{UIK$FY0ty}#B!`<`gh=DIBpAc}OTyS?o#pS*HW1H|i2tMnY&fNBG5jrZ_ZwAA z{;Cm^wxU&>n&MR%q&sGo3PMENleHppe*gjb(>*NTU*vUZG1=R_=9|xFawku?f))uA z?eJ0?&u1%$(*$01l>T%4Ow8@!He>WD5C?zFV9Zxi2sr``Jn>MYsBFc|ZcKKp)%zQ9 zMP^>K9@D>Hx?_sS{TMGwLAWL!L?sgv%{i4Ye@bzW_KKJvz#j4n>}ol3GFjg_`iND? zdv9CLgxK*b{3a9ytIvawRbbMTg~*ql83;@Q&SR{jDT-u9__tnoIs`f1w`@3Z&i=~$ zx2?t+AsW;^cgm2#x_O@Sk|-B;QQDnH;FCKsrKlLOxl=xaXdup}T)BCwO?Y`_>X={8 z#}6QB3Na;+bcbXo*X2Gzh7a%B6Ovpwgn>)A)y!rvVb1s!45~@FQ>fZe?Gz{xszT)^U9kp z9R@zDJ0K~`ndZ6oj&f3QQjqsCEL%+AzGdaVp07qJ)2iD@#sNFT@Kdy@I#}a4S~g5? zbx)lMU?55q6krDy$u&+MMxt9c`m?Kd=ivzrNh%>LU7sG7xTr(p8cVP>M?iG}WW~$O z`X|mlm$_D98)cMN*LyXy`r!`50Mpoaz!uZt~6aRhMqo9Fg|VTvx}o_Z`#pyj`R( zL1#5>PHTnQB#VrA*bdcMDUA0_k0*&V<&pCxp9v-cc;J7{XU7ZwrizW;s*Eno{<)79 z;^=}u%e4w~(r=|mV&~oRZ8WpjoS(JVRB`KoO{%9rkf?_z`jeX=RqdRggNm-t;0+== zN?#kT;bLb)S>#x3x;(VmcQl38a#U!ALq*9_$aFKS}NV$?6BiqL-#G;$y9^JEfBbZe#U{u za}`HbC)A5%CSEL2F`=~Nc4FyA8LrQ%hrXuFvk>7Eb$|mUW6Jk(^L9RRD!;$?Z$l9H zC{raNnzf6UMddsxOiandsRre*FLZb%)ev^(lGv`$pFs#D(D&DTKh$znURexHtns!9 z%W~I=Fk8_Cx!1E9e=M;>&L|DUiUWYaX1?=ht>XNdH*91cD-}q?F-@mXeDxM!I^#A6ilbo=IspT@`mDjx%Nqsdv-u zN^}51Nkd@7w21w6C9GJ?Zp~oP#!Y@YXnEDaN&E^<;@}gd-CkF@=?B`CLuL~q12;GlSA#^4Ok^5QD!Gl&^igirLa9ab^7Ge_r&4wRA+U|GPArKd z1e*g@Z}T3Je=%ZLtQM@j*T@dq07ZTJ!B|OpE+!I2Vfsc=m?1|K4D@RrRh6O7OjcyT zkm7wN<2msUY>uGBJo!v=iLq!ms0tT2BQC|0@!YGSLPob2LcpMoS~gQ}awFZkO|-v% zOs{yxQ(<1VEg09IqJ_`^gA9Ow%+(%-WDWs4^8qv$LmjDjLJQBir;nwd!`99;Bu}+n zcit;jg?u4Xgs=EL3|FN!K?tm!-2m0`ASr_ev9tT>WuBbsfv`@^{g*?CkUSd4peiYH=7bg`e#)PaKeXO- zYh+QhL36sfWHG6mIEnlo3&50dzcNG=6@VTmJS+2$h^w?5=>)&k9674D3ec48r~f0& zq(cI~zm+w`m^qz#tmS|>j$x!_WO_{?#7J3^FXW1TVh^L03X@*5_~4xA((VSq+#SbB zqZBD?XL}A#nYm|=l%m>Oas2@#J|zoG*IZTDCo1bnKc+qxN}aC$kIbZtwIf?{H8y4= z?g4#~)ClQI0#@fqyQ7Oi{rIvMJbq0Sp5wi5P>Fw#CD(_FKB52Q@ii9^%zLvnzWHZM zsFun+6{)Izrjs?4dpK&p5~~xVIQj0Qbzbp}k>#NCGBaFbi8d?B^w#Xs$lcO%sglFQ zQvq^{#hXGh7dcZg0XYJ@u|h)+Jb-?(+;AtZ*kAT{2=f0KiP(u)!yRG}=RZ1qMipb2 zMZ?sI#V{e2OT;2om^VF6r%cT(rVl>ZVg6!{!|p|{ErPa=&i^iX*Xwv9z3hFt0_%aJ zwwz(3QM{?EuHUfo@1UWDllcOHMc8>#iccYv;JF`hsM!sMWGBuMTh`@2i>G$VnO!6X1w+DKT;(BQ(y&l7w6_v8D=U^wG}(ZiqFu zF&Sf+y<5Xu-^+VsWN9lsqdx3@7x3|o;77o77>W?hR}f1BglJ9W{^^NG6Bmh0k&o<5(0eIAKZ9{&z&9?WFQbG*iLtZv z^)}9+rEg~R?CJSn&vw=|J^XOw@+lMYdy^>;=C_wfwPrCZO(WIAMKn`7wXpGDU4W;C zN-X0$YB?R}C2m@9#p<$h=lXOP_)Z(PdR-9~joFiMg*#IGGucoQYvh8Ck@-4Yz*_U4 z{RHG^j(fMeoVj-Dq~L58&$xZ&P*EDVw;4mxf(JFKh0 zo%~|8=IOOc2f_B=8xxPb{w_=Zg(6+KhKt5bv^Q;NhPB5K>3-sAuWuL;6+8@D4i^jj zhgrVKRZ^8X$25kH>nf;Q0?b-pm2J4oTPYz}W5Nk1GxBD5uX!mk9msxYc)33Jwzu$l zaCrYG9sGL3!MvOC^v6OJ&p)MIX!4?-Wns01j~7~PWF_>s1vRGLD&Dtz7zoLvKnkN^ z{QXa{m_%tN%bT|3NLIwpy3QKnk0y2fmEzOx7yzN1ioys6v?~rIuxix3K#k5y4Ks_M zN!cPvL)!3x%WghjOoIdC|4Br~ZvD6f?7GFrPY#3oM|3tV^I5zQJ&okN+anlcB3{_W z=$~H*0gQnmHJb&~d;C13v7llxebPefn`Wyr=17UTnGCP6c)_%s-jg4YBXU6Z9E>vI zL0(ApeWfIik=JWipK8_l$U#Z^qkhC}dfI2=Kw3ya_UysP9MlOkjafCjpGCr|fGDFl zgVpuX!T`7>x-#q>jGxl?vet2F@Zlr9z|f<11K?Al`GpCK>kWW*@lx)wIG2D5rLLxm zGz)QRZZT&*V40(sFgMxnWF5=9+>y4!o_!9$L`$K`_G7*QM+4X~5mERA3yy<|lN78P z)C9|~+09yKUlYmoVKsB(zentSTq-ubBD7_Fo8^%i*>--8GmYamuupBXGPwW7%}!jW zZrG+x@&G*Tc>w_p&wa`=WE5$E;IEXmOx>jlO1y~|vm$hOti+(<1kxVG>rF)zbp54S zzwfMn4oHPmhf8AljORMf5WJJdLnm2EY;LvPs$i0(`zJYD!mOMGj9~1)ZtnD6(l%1s zd9!uw4?N?TTWD2N?zLZyH&?Xa-Yp{Qm1-8P($66Q5QXAwqkK^yrowcHY4XI9`gguq zT|>3a)!Vz+_1RLle!^kg!ZI6M8iT+$NV5rMbxDc(UjZUfb%6AVltHJ=Wo2VoCsr9k z;A+L@Bm85BA*L)Dq$wjnI+ijQ`&BzcH5@yEzvGRC!CAFLV7qnGFHw`%+AYhFU#bAnPuEm@pb7Nfgsph=@`1;$~BfPb*NOeq8p-uUmQ{C4FWg zvm(;-{0TA?kY5=g2ERkmg;uBe)_LLMU$!x_olXtqto41b32$Cc=*uhl=fYlec62$& z_R#+F5if)!3GGU=Z&tZIO&LYkf0Wcg7 zA8d(^>%Kpm)jQC2i5?907P620xPjcD%ct`&Jey-~j6$WscS}>WiW&8?n$)ElJcM&e zz(@0_TfIBGviGSePaHM!TLwM_ju9H9yH#f%w9?WM_)K=U?))h$R@2p98O;J}ol*JE zWGTCrtPEzcsu6X%6Ef%Xoi_j;4I_N$7XaeFG^J4hsZO@vlw6A%iOTJ_mUaGIcdiR= zx}a#xI=n`|+}c>r$bYw3mkb$apjSILqju4c0m0XL6Otjm2__xpO^7tml%>6)TA ze&G_q@u_mWM&NYuryqi?#qqGWp0OJD;T@BOB-wuLV!(|BzfjL1A)MY(~m8qx<>tq4ZJylfv?I1Kvm=(Uws7k_fn_mA9Gp17k{j| zN1zE`vy%IpYYcfo(J4zRBlW%uT2kNbh#942>wLGSXN>^W&7}>5@>^wU>rLh-f1@pw z-~smcb~7E1s|-s(lA__1cA`Ksu&@yX6wOiy z_g8G)LNNAc_AIfT5X1i?>MWz$YNKt97Aa7Qw77=g?p~Y#L4&(H6n80Z#XY#YySBJf z+@Zx?iWR^4&becpUm5uqvUfJ?oomkda6dS6b4@p5OfcUnzsq)6qkX&LzjjsEZ17sS zzDxn-{?wGc2UZxS_YI;zDbtcJVW|%^7_EfGy5;d~kNu-y7 z8S|m5D9KlKiMm8!@AOl+=>rdRJ~`hgh34f9$~=jR?r%_8grSaGpx9T$9~a+Hh2xL_9~e|3 zr(U;Q>O>c#mOjKL914#7Q}CqcEJsvNYO}B~8L){lp}LPF<%l-5ZQ{2!7C0Yx{yGqe zt+<+&_UlU(4+Nb&1l)GKv4)k)b&Mx#mB5oP?uXh$$Uo`*3z#7ZrO2FX+jC98zPe)Q z-WeL8rlhKICa%sHUL*U=AT?`LFD$5A%*a1s9ms%T@jzPAfLlUyn0UeTikwY1P50BkSmDQKc#5IH=Kv6_|V<9aq0|M zm278mGkR$cqDJmTW20l>V08#=&T=|>C!}@4Dax8~{>oGG%1iO$mt*u`uDJ8l`PP&n z4Jj)6JsSrB_it7BTz0D!bB(s`TOE&FSu<=3nuEZQ1$?+ohR`9nYq%fwq2i`_k0y2R z+YDs8?-1-HVrGIJh<2<6@?iT$GDq7 ziE5>j%vTj!#c0jt%kJX#k?U6FcJY<7#XeU%v5lN6!uVBU6=I*0e6~+PbA#GrjY5AH zrpMm3TB*j0fD1sC3QuBVw z`T_Hd?$gBvHCLw+zb2MoiKoO{Bcwk}y-yKpl}!kUO|@}#>%OIR9c3mZBj0{Wn6zKy zDbCQbe_sCbviH05=8RQr^`Yx#Qh87HoHmb}cB2D_+nFXwJ?RVjnDzUwIl_ScVcV&}rqd5!k4;rrH72}MJ-Z_!+6ysvLiV5oJ-@5m zn=<3gmo7}@%_NDeXxv8>cAFqyR;{+zHUuo{(6vW=Ez;8Nd6XhDuOzhG6XX+d)b>x7 zGF~*<4TNcZp2bue9w_q>)l;V#1je*Z!iCecl9Q3XMO9&@5*XnPN`c`s@vCCIM%@39 z!?%F;=#Y=!0sm1KGyM3n_6ZoFERrd#=ubBfNi(KeSi0PCkN^bB(ip9Um*g711Sc z#S?G9*cv9~25xhi2XCw6qbufYJ*l1c%SbjK+F z5Fzcnw1FtBbX;}ggSn-}2c}6(?ftD9$7-G#FN*tiGAL52prNzc{23+~0WT|XAC0>s ziD7Syl));DTS-xXwSE$$B4*RB_o092Q-TU7V+LWv1Z4_FHtDdr(+8K#R24Q!umqV3 zZrQ`w*ht-kO}?_Xo1oV)wkgDQ$p>IPWqA^A79V>ndZq_fBhSrU@iT*QXF!s54Tx{4ko*^zf%>?smMblkEdRKt zbVWq8N>O-(S?6BuZKCH@X-yCTO$bboREjpZV)tI1nw585K5{mtuW>gwO7y{TG3Wc( zztDIjA$gp@OyI=TachFsqBpPVO&J0{`dnDG`;yb1Bc9_>Oa?U#Y_t^ug7K7o`0fAN zz>228_dwpzcux`3@Zrrq#m)Ujw497H%5mKr>ZS12t855FiZ&NssM=_ml!#@nP zxTvi9(Bh)lBjZkHF>Ktj(GKp3RfU~Y#R4tM#eSa=6LKJG$zDKxGWR2Htaw*#+&pd@ zeG1P$yn-4>*dBjry75#f!%8B82~uf|kv5>?m2(mZsW*FTwc%Qd8jyfs1%17tWa;fm z^?6z&7%}wA-Ryu;oufAoV{L(~_oU?qlFeqhe22zQQuY?;)~`y0D@UK3ND%-^>Sj#f z^hVr3suLU6x|@RV@P(Gf1;@yFCvo9{-nH)z>RVhBf}5C5Zk>&(8wUxiOsH@`DvOE^0l z6ELr1C#ZPtYMT=ae~~=}i6sUX>6zv;06;OdFBJgFAs^e*bUAKH5lBMi5Cl6i?abNE z&p>e4%$c(3t1r?w{)e_6oS+^I-El*)4{CWOL#{8Qg%gYN6k5~;0r>z%s?<}DJZuUU zO+B=$EkyZ-$HK{l`#?X#&+{2ut$623P%j*4MDT^CTd&H+^vzL-TwYQdw*=mm7?J7RGwwll5R#?@MVu3*dptc zrEGlEY}>oY|L)hZe!AOwPyGoTfgq$rHBpL2(O!6!P1#7xxLQJEd|^LPyi;Xs1!0)7Gc5gm_tcOl3h%Xc20I2U^V z>g8BJ`I}*7a6|B@g}WXN$P|mT0iaY|x0Ta|I*T@lH;av1M33!opk@;E4mTaa`03&6 z?V*XGkhd;<4bO+cm8rRLv1FRiQ~qTkp{Q?iVmGI~eLV-6x6X#QZmG^^?xofrUh`YE z$yvPXP(A_8E;h5X5BGMLyEiBEt@n*KcCKok7fk_UuPiIf+_xr9g9@?&@`+ryS;Zsv zYM?ktXW7P$k;H`CGcY+ zvA^7;fN1k|c!o}!^Xe~Kh<07&i8hL0r(w~%@l;NhamN|EhmClHBAx_9;c)M8xpY-H zBDfqh6PJ;EI0(2!cVWI`(;w#=RfTT(XVdO*VML3TYk{I4O?Rr{KAFXn%1f2dn~ zzcCdANts~2+#<1&r;_2bk@#!@pENr_Kh2;tX1oCjf02?%%d>~E^ z_H`PVI6=q9!$C*S#tvlTU}5KBqNAY$a z%|KLoiGY@*){;N->P?X@R?=Ig#z(&<{;0InnAD0g|E=JgCgf6)Ovt5!2d zZcU5m?vykLA_ZTnCzQ?qMVrrc|JQ*0s0t&NeOZ_bf$v__nlZOfuVIZQ>*9f=q-!T; zm(WdLuSD;=)7e6l;O_BhyxKApq_`iKiMrEyh^pgsf38NjwtV#}{9C`D?|};2fLz`n zp>94FaU>Y2Dhz{|?)e--45_RLdn`{6lJqmvVgPVFK zma0k$N!*61|D4);yR^nhxzO~Kz)wdjf%nGW9hMU?@a#JD29)o&7`65}!d0J7qTk-8 zhf}rC#8|_iJV*i?#9hq?Y#NG980vT2U5RYyN_E4WIh{6rEBt?7jgNs&{r(kuIra=jSavw$iq@b6UZ7w zm~(jcPAfgH#GU53Nc=01GO~x4?ckxv5>w)pZ|^SCyF^$J!#{%HU_g12V2el@qqjfN zc8n;Ak80=F8Yy?8N!*yPu^i0$-*Yl-XsA*D2OUj=F$S}6up$ANCRTEOT3Gi@rzpt( zg7l^psJbU-`x3T(LljcSj0Zu;hsXozk-RdP+ZMkWdN@=}X*{lquSqZq?CvxQG3<|I zDf7uHsD+`Y()v%m&<;&o2$~mHROWI$G!CZzV!B^i0hGrRVofzvXvxx{FpY=6$*8LK zeaPDl@yoy&;^NsddjO_J!`3}d-~;*nM|oGngU7dL!)*%@3|R25pRFx}zrsde4;D~} z#!00Wc)7oRDf38PA8~%|tTgozy8kC6-Cn&rub40&y4?TXI+Nxs!0kQQl)JUA4la>@ zFaF02F#!y7;2en16P!iy@Er3}zCvbhY<1BbrQv6XH))(K0aabi%t`bbvHL3;;lFfmk2ccn9Z`i^JcdVwD&t$2GGQfzreYVi<8PdMlB&xxF| zbBY!2Me`zSh_0En9+{SHJ4fo7(R9F^s8O!EH%bK7^|$ zp)blTufFB?1Q7s)1caG-Fa2Ns4U)iX2y18E&2;M?^s<#s3f5beKDK9kV@-6YhjEiR z-a&yFcOT&7e=0iWDTce7s=8UvZ9oYojyk`UWyZ8DtUpw3nzhM@R^7j?^aWtSDor-8 z0sH;|oWekMu$E8p=kD88Qv11m*TeB0wmBc7R;~-!ti#(s!NFAjG@4G(Le2z67>K3O z28qB?-qOybM_fst<3LwRGR z%DF**Vp}dthXZ!fNr_26guB2bQaOfkoX}$wxP9P=DFP-_bNVL+RoOMEjx)T(Av8V@ zAF*LBwX)~t_3fAqZ$5<1*KDeLtG0qE*8J&PkO01={Lg4qND-26T(xI+T)4DNqw)g3P7V zJfyA!;8=@0g9NRlif;XG51G^O+uy6ZSa$4W@*aJdcwFr+wJ({BtDGV2<;HEDg3;&m zRp#*|v*CZt+&Up=ZIZASloYXVWj1-*-SAMU7L}X`=2#AwSd%REr*8IcT4a5IfhK<0 zpwItuQyeAevPOo^P*ho0{$40rKysJ5+i{Y247&D^c9mr!1@6+lyYLRNGkF@*VraEog25eC{ID*mQdTbMSH#cA52!ZMR=jV3>L{6;Ss4a-hR((3U&G#$Pu?Hvq zRDI9No*T;VZOPcmU-faA%3e)pMNK3`4h-Ue{|)tpl{f(piQD{#q=QY$T8ItSx-s^u zN>D$FP0MQZe+i8T4OzVLtj7@GSfu!%y{xmRz3=ZBPjM1**O_P~o)YjV_(X^2IM(;w z0ZTuZ@#6{E3hsOd3Vi7u0VaBG%b(L;`NkQmW2lCHXcaO$_2+-^+SwgNq~vH+k*mDA zA(iyIs$XwayYu$BOu3M>8^y0w5*MCV z6bQ?c)O;nxEdX!d&f0yZKx-XJ$qP|y!2H@bEE|saOb@$sA7M4yX;ve~l-JV*lgg2kTv*(cQm#((hJ2Z6U00_eYi4Kl9`a~~v zuA2OJ2{e*mih{Dp@ZTG`dY=gMX$FKs89k~D#{Z@3cxMU}Sdz%R(@y0#>~&Z(fNZ#% zukD(DAOQ~{+z6q8+X5E-hvKi zJ>ZLA$Amyf6s6V0OQ z6}j2EPq4d~8jee9r!wuZO{_dm+OjzKvv82$z{C>?eB?FHY>KVGJiI*P5&8NlBE^ zAjgs0@j^l6$I1;7Qw|(nXC`7Ly1D6;YVgpV<+$cuxw%(QfckWOfAVrdbF=8%?FAJh zj6nSRa5Vo;Bx@|Wsc5Q)5=e3n8j^d#=;a$|0q)B1EicVUz93d0T@C`9Brj#pC9bY z0lTm1PH&JRHv1b}WQi($4EPvaiBGxu-!~+=Wv!fUJ?1_d7Rn(=%F}Jmn^igp+|dC~ zt&5iLT>CiOpi>XgZu+t~$8~O_i*)yYoWqT^U{%U(dgdumE7-p!y}d@HP)rc~t;OB(_0H@!B;vev09Et47>71qywOMT;0X>flt%!7jVB;GANXQ)T96ObV( zk6&|o2ebxPmVU1V?eD0>es>SS!{V@LDN4&cKNaoDbw?rHvTZr#%iMkY>pT|!*)4Z; zCz^J^zC!wa^fe@mtZGTzy}L6(``?^GLBbjI(5Y_}J0Dm-4osG!8pxLuN&NA%%6XWi^YNZN!xK>xSrbq&+8BO#U3BQfPGawq>U(JAB@|iCSvEyOiFpp6a5>qc< zP3p&F5&+Uw}05m~c z_M}f%N~8IsSFzQ*gTK=&bBZtc2}>!PJ(d(Kh9@c=F${VeWMMW7#cvjoh@M;1GE1wx zhlt2W>GN&EM6Y@tf>K2J@$NUH-EYeexgXxv4+;u;TRUOmS=l5^GhAI-D`tXAGI8^m zfEf1rX^*zLtMj|FWSl54CHBKywTcbLkxL!@l9FZwvh3MjZ#+eNRgAhRqJet*5w-TCkT;C-gC_y zL^bj%YN{EwkeDbyaDS8T-&Z?q^TJV`!BGs(YQsZC;ZmZTZJ0;=jTpZ$O!lMDZ;f8Z zV{f79St|EzB(rinT7A!N|3eC9861<6C$t0&5he<`e2gsb2onT`Y~YGz7gSiz8<_u2 z+5dN|J!JA9F@hlQa1_h86)c3YANH=%?0{%X8|I&!FBm3K+roT>RS}PJWVlv{nFIHl zR#}{0yo`^-Jt<6-R^ z&&ynI@c&&Nc*VA0=?gv%01YQMCo4M(11HzU z*gP92D>Xfkj+Rq^70AZPLB}q@2B3z?5p=XHZ0t0!Qb}gE6=sfE?P551-yd*q7Af#> zmk5ZyJ>-u%)eB^{HD=O^LN*ttbuE&`sj6lxq6Qa<-}f}LlADr*x0r2y4%$?29$GQA zvxEGMCX%g5n8!BEfLVEq(57&%x$?ENIR?4JRL-s*q#+8zm9 zWuZ_&WSwALp!xve5eE_NDjkf>q-`UCiNqc;AnyLjt@zl(5<*y2^yjvQKDnST+!(9h z*}+I7IKMgPLB7P(h)04j4U=`yyc|>dHZO7VG3|AUjx%R1YJHd=JBZbW$M!`?1L0o` z-SJ0MR3Q~QSv+K;_3$J))CQY$Q*xAh)qOzK_XM&B#_v%?H8p0kenGH8-psNCG*Bee%tsT;twPYf^;(jF%ZC3sqkHf2X3OHuOF&cCRQrT^#h`)RQFyl{IGn))O0+Qa`Mp{y`Y^QA z04mguyNv~BA*vFp!y#_JEBv;Gs_um`fVB!YJsllg_?7wk>Rw{e53BS7Hpk{eeQ8zX+qQA&>V|0}Hbe+d%=h+~xB0*H3nl*MGZ22UP%PWrqcTfIZ3NL(NR{5zZ;o70A`%eC4 zy5f`c+6LNWUN{^HNC6I?#DxQ&TtxIaeUURFfD@sP>?5y zD~o(`>J>T;bx13kx?3gg_pM?5#gHgl0s7~o#2LfbAJ5`qtvi~iFni~3Wy-240tb*m z(gNd7U+(_{Vyf$Joue#@UYFIBA3NsEX1%wUhVql{vxOULYm-_CV05nMeBbRkd^Sp? zg*~o}8*PZ*@t)-kP-S(`ojJztpR2}lE!poD+Hh-LUgfsl^~mB_UVIOQ0Wu?4;#8mBeZd^8fj!*XP z%xk0hNHbJ%nN;C=xd)W9XT}q8 zKee0y%=l%_ZsF{+R{4D0-8Khv5bYzR(&lX=mYE!ra$wiIJ@7Q%OtPrsZsDmyEA+pf zZ$cMbn-^Hn&dQG83ggC}{~|(EVuO!IkGvutV0ZJXTeW3hIcx0l?(T98vyGr`hR4@X zW4ol)xAnIVafwPAa&H;^G7}`sGt1O>2 zeEI_it1vpPm!$s-kI|qw1s`gw^l>KAa1H3oH^-A<<;ZJeeY~)2)J0193-$zar!hg3{fn)tJg1 z{KVlY(&euXiH?1n@bbs_@ZGv-FMbkdM&si@0aGoL=?V`9)=u+~2=spb4v-WcywDfK zw_-dMgiB(&-}j`0B9c5xLRhw2&CQ)4&LbB1U@ZJHypWfG#((H4*1%Z-KX*hKVsKdK zhi25u@a)%BgGN#}lh!a@lq~ZnUQ)qL(qI9u4zF(#SQ9w1FYxS(%-ia9*p)d4UhI8dO^cKzCA$jVeVgm@z8!+)7la~^c3KFi@86{&nTkBO zUo<;y4+c5BP{`)j@SFyiPb?j{{bWpb=zd7yRXaGY{zr{J?i`Cz@TC=v1oP$xQhZS! zkMu51GSVv%^E(&^*E3t`9X7=$wjb9$f2r|I z{dhY(yFza}8a%n-{i&qC`0t@q3Usn&LE+91ee}CzNU}v8QbQixZ#qq421eD25=O4k zcN!J=$=m-vz-{cOAYfd=e>t(_iopu@pM}tlXF)*usPrLULzE8-Tmqh5p6(+QH9ruH z|86GfZ9pKh6$JQqX%>6VP~5f# z!)M4(CQc{$T^a=FNsf@vE!XQg(wx>D;;Vrs>}tz1z4t_G$qs5)&;PacK05oqOxEJU zh=+;3VBDZ52RudqVtvDfDr5y#pI1z^fo_lq2=a$3KUNZik0Zsku-Fl! zZ}-*(Gj9-IyYYBVwY(?7r2NlWI&v^7=A{&EA#SFsbcfe#(-^_cqUdXle_w3P@~^AF zm7(Ds%*|?+QyOvf%B!d&!$?zAr1<~_>udCP>rko^mu}IwEE{Ij#Q)bPYmNXd#@_zp zB#MQjHA}Ao1mBgAmKUEp-#w%;TR3zG4syWlAOS%51mIb3G=I3Su6Ok)pyA%=HL!@7 zdTiHb3hzltd=Q;y;e9{`I5GZwuOmZc>hUwo#SKFN&U#ayJBs)xXUuEJ-w8Mw9DKQI zS#Hp3nzP~AuAJ7nz*}7*NXxR5%1rCzNV3rDp%SQ6M}RRhVvo?~S1oKY+`%R#>Aw9o zOSc>a_bET+NvjKTM=nn=28RR^2|OxOoz3%X zOzl|@Yk$?dK2sX^ufPnahfesR$c`TzU_Nk05Way3p4Q|9Db$T#y29F8U+|9WNpa5O zB<`exV3Zh5LIu`nfv1LBddHGO78AxLIcs-N#Z${jm`OT%*5#Vr#BiJRz#YzqZ4ka&c)m7LwE{R`Q%!ncS)|P6 zrIa>=>XQcPMU2{KFQAx*mZnHd_sDt^j}@$sSiTQcD-+4;;=-THBeBZ6%p;=nh;{p~ zykSpBTJk$WSv^EaCCY1Soa008mV4zub0_akd!`P52PGBT1ySQCwU^D?`@uuEBr({z z@ds?O7(1mMV;ToE>P-3A^Y+R=*o<0+{k^+BWlyU={00*^lu)hkXwbJ@9ZCxxXHEuO z>OV4e|*`=#D=T|}7d z8Ff@{xQ&lX{oY#nx^yx(SB|hT7O(}Vaeg$;?{dDiH(%nzkl@lJ$A5)s1e9&1goyR+ z3s{_Vdf8Z(xly|d^9)C1`kiMnYTU|e7dCcwAVu7ZmO{I+P8jD&p6K5KuIC^1YYPdE zo2he=T*iyzRqZeO#zc&)u} zARry*!&QM*p}_|pjlR~6k{PLzcP7;F6uZ~7tv;sUj<=bYst` zeTakNR-*nG>(B#}Fm!xGj}ABh+CTpkPy>fN56Ab(z^FD@dFIwZEoUBIT5QLMpO-EH zwsAfMDm1DPp}zs1InlZj(Dn zvFQB9b#nOGUj{`V4h)xwyszh8=57vYvyd;Uzf)Bw?LW5ECGl%H4@p^0w}F%}(>6ZL zjl8w1mVR}!wLiO5%4uZKrVxymKzXV^LPWKE{@H4u=&h`V|53ffK`|bGG7*522w+NT z`unz29Cp*~dh+yaQV{Y*T~GgJ%F;jEaSl$Jk59l5^Au z4O)B~j0uv8yVp-S04^Dvgh{hs0m%PfWKj7(kpT}TGQ53zK4Rwp0%=(}{wy8PQqys< z9k6rrY);G{)AI7L!?XojS{~k|*##iX|6gTEfI`*VaPb*> zu4Lhewn%$T<=^aAUW>(50J4Hopz_TCy||q54N{rI+E0jIN4xv1neSq9n<)QH2({(Vbk~DDvu_kW<2z)Sx9utk39jp3 z8Np-(DF53(r9UEe1*E(ScBQa!a%){fs<3OZ8@%+&%DR|a4BMBw*B>tb{L_*%>W<1U zASm~sEn3P-AN9BfJ>`sT-M%;oZdV`-zgr>8+O(f9wVOfm<`0E~+lRw!f+~Oe2#-qv z=PxSr`HYEC&9PG@L2AD(pF4_FP~7Ze3nhS5Cw}@BJPye!ybhz(l8>(P?;nv zW;5~?-q|WEBKzJH<)L99>@JDD)i8DfPs88j6r#8@zSiQSpt`JmG@Vhe4u>%LBG}t zDTl}{9qDuUH~3eTGI&54nRNcQ>H1`Hr2_t8H@> zjaAPs*YKp;z3Wjhq@wlr0H z-*-+WNts3KI3Gmxp4j#$4tlOZ%Y0>S=CXwCIb3o=(b73GlEj$;Ee~K&`8^%VqAUW_ zC%2(e2#zBBB5JcIdc}L;?=}WINwn;Fuok@s6ga*N0MHC>*|m&{F2nCGAeJ%-6`S^H zL-7YRGlU){I;dG_5wlGV_%r301E#pp#$H-GE`BRJ7@2#&3pnfgL;l;joCK z9UVJIss!B|nW)_D2-4lig;xMerC~AoyW71VIu-72Z3z+VCEV)sU)Bq}-mB|3S&?Eq z-3mT1RqsgmEfQKEo7a(7sU?1(tb0|ZKKxnTNCoR9`C`3{Fz+X*upd z`$*`J(h0R3A~)2{U0ZN1{rW#XpaJ^L8yu~Lp;ph~F(-U+1F;lTZ&S_VD5spOoiDKF zF;^TIx!`NFi>7^swkYe}g+~QN?y-Q1W=k5j!%y|KTR)d7ou9DcvGgWDB;3i@y|0L% z@YKiI(Jmr?)!FM9%3j4ITNZiDopjl26vZibg5jdIctK-(>K5*8jcM@413MNoSo^{&OR@#qmi!+5&=x9MdPZNCR z<+ZHcL0#iMN1w>h60xNh=7Sn3$>-kLe!OYV@Y%oNkhzO`7uAKxHR16mc4 zN@(YHVW$9-%OkW)!?R`i#sm#a&caoTR1#)V@AJnlFjm~D+**_TvxTSe6Q7~i!u|`h z<0l0W7V@YHPE>zx?dc45er6+~_|TcR>($a%^gTT;&eRzas3MpK=EWi8=wuq_u%uRD z(ZZ4heOY$KD_HXfGgLHI@_q(<#!6nf$6j1n$3x%Hh_&DQmkLXN74(y=6(vB^ES&p$ z?ymDNb+ly#B8R$+UM11uEkl7T^As>rD}tFZ1!kWHxjsAxzsg zSWKY8#(ZHXPKxQ|UG95KPpwr)qPE5Km4apNu#*Q>M&jt(WC;>3o*5zCJ7!gE3(4Hz zkbkho4|-XQ<|Sncx%^f;=)R;`HPtZzGsYk7nt!Hy#3_D16q8*hK9A)i<*;&^K5hvn zIB#gZwAw^y-L0j!y;&h`T>PnfxKXxyxi#uL9@b`})bjgCHj=LO+pVhDfj)&Xut*dG zD{O<3o-sQxuLk1_6K}$#z5+a%?rpl*JtEg-v#M|rn<@N{3ppG+GI6v~XWF-<7>kFz zd^U0<^!zVMC2no;0js~M)||#CEE`V)BbGV1?tc2`LeHwRDfc#4C_ft}0k!nk*vq1# zimRY&%pzt+rOftJC$bz$;0YGzth*l|RD5R&$MlW~lY|C!N?Rt~O|4|Flhe60l?1~p zgQeS3h*t4;-Ow7zcUWO3J9-WoXtY^cm?8(-4()?o*crRcs9W*s%hH>eWXWqXkE+?lb^7Oe-KILx0 zq(aC}&&Hs$OV4bnG*oLuT2@1dN0!Ifn<){j;8@bgdtLPFHi57~_oUA0kmAj{Q+rCm z`Hm()37H4rT+{c>MPssbro!(So9b_O9UO|WefIh^j|s=1W2G+b@*;FA3=e8&nw?EU zWv9tey4aE~T8m>ra&D>DcBP>=YbxcTWNMGHe;dZ#seznCv zsbVb2Lkq%N+%6Np3M7L#p$ek7A4y`vON+s8ma54G!J(k`-IAWKmZmu{kBXrE59)9bZpRgpIr7+P>ITkzw zq3&c$VDEz(+Jk6l%j%bA^6*h$PXqx+gALh&?1b3tZWd&;t)RTxxhA-k{HRn_N^*Hi zWbX6jI7nZH^k9ciJ30FV+;9+OVvByYyNZO4Z(rD{M@RBG?WDbkLw7^1c`K>41Nk81 z0eF#V%*-C;7|P&&;P`}>)_!zVpN=nMJDtJYaIw}?x1)iStk8pR_dUl;&H3-&aBt7A%FSPhj<{w(e9C-kt&&y9rzL!@g?tHPP8-GTm;0GEX1AGnl~ zOr)U7ERtfe?vK|YT-_Y@W+d-iv@HZ18A;|m4sIEbm;goLqG8pj~4LN!BQ zdBR@EZ0A;OlbQI}KI(W6beapEo2wWnv1r{&+f}=K&js#_AYg_^yTAHsS|3zVU!&6) zrO7KP)eww#?_=#ycQ&y}5(0BPQpQw(6uwTEFcu6#7P@Vpr|pp?F@s;+1j?!FX^K-a zi6@(NzQ98!1tbb+iC39z2@%nYD1>XkYZ6DJ52N_TngPH`tt*bXxbDLnSkgdTKC&PL z-m|wlrYfk4C{0g0wA{H{3!m@4zDq0Y{m<=Oci_!uh)PypIohu-nVmwaW<31ifAz!p zcT!mewF{Vizc_JPTOSOXs-=EGzinI=0X`=1W%t z8KcB9cSKzLg9jXd$*S(_woVr-Df)hj?kDQ~Kca?%6*?)wEU!?#W?RY3^^#6%4Wa35 zA+IdwWOhK}oQ4|%7n8e=#YgrT0rU-IsVG*eh^Ds_^|GS!_vGpnwes)bxBnWIeD1?t zP`hhZ?z<$j*tc_RhHQYVTZ-Y#{jLKJ-bI}}A89YFFb%dBsZ~$K?Pd{jHtMFPd%7Rx zTMS!o`F3uIS(BT|$bfXr1C2r!0}Jhm>Le&bjSzd#xv_pw0Dt`;N5_XlC_uz~&OwKV zhASgTjnck7jn#&FrDgmTV+H4|gCC9b{eE=I72uXyMi2k}Zt*c%(CL!EJ$pG>U$|gU z@+Hzlg_2w+n(RUI{`$LV@ydwhDFUElZZWH%k?0x9+(VMkX43=^=QYHWH%|E4+!$XM z3Cl*d-45uql5wuq;Qb*tESKscQ%L!cq-}jIZg$s?JANFlF;K)}HXA4U7xbPo70|F( zEPK*2+Kz2ncWrJEcABEf;+fyI$)fHfA5<{fLl}XF%h^94$Ev#4~;hWGcI2tqjAA=smh0VRb;gZ;iHU0L%z0e+5SQ)|ZGP3u*Q zbmG^)3)rJ?uyI$}k4)|_o0h=06j-cg(O2Mt?QSUwUg>cXwurWW3})3v;fHZ8o|;6c ze8T^NDW=?NEp~5ZUj6AEgcmM&4Y}APBXdlPC6*M^Xh%ysg_qst6JeW=&hIorBk@j> z%t_2Nv(Q3H!Xt;*I!*1JuhG5L@yaNGpnRM|cq~MM0SQw1#@~2cDoz-aYU=|qPq8L^ z`U!8D%$H}b;n*^cN%4(WzrS?a!bI!qM6f_mNGTekztS;bVoBx&X)+G(82(@lr&D5i z+$oq>9X01n52k;Z{49x-`6rwOUi<*5z|!pia_`Im=eDYtT%glrfZ+-0UC zDm;@~ zxoR1I-2e2~l3WNRE1QHQTjOU}Oi5+ucekTmdu+G3en^^Hh5y_8Nc&PV5euMle_obtIN$)?!^J88iW^- z32YWYkB+ylSxBU+K)0N5%Xo)9dY_7& z2nLGj5&j`!%&)B3@#1w}-aoF|AG)MX+GRI_vJ-g(D`av~<`fz2dsmNb9h}_H(%_i- z%_I{GM(XtgO%7jBvB9}sDc^R4V*FF^n`X(t)oi%rx5to-H8m;D>w`FQNA>@e8sHND zPinx2Ne#_+o!QJ>bab$~NLm^;p6zV_E8FU?OMa34h4qz@9he3IWPuqQU>zAN^mG7r zUI9)f6?yD&oS+-TWYiZkWRYi|Tv9?KVpw_!cNi>uHJ$`^fo10bRPCh&I2ak2-J`Qw=d;oSv&ViKE~c!G!JJgP42dCW5tw8Mk`7U^m+fwvxQuCaGf}Y65;Y`J_Sqa=+McD0F2ik3 z&V@TM-qdzg|n}j#X70S&1hb zpV@Sx9$$s4xSTlf?E-Sv5fdLO?H6V3vwc0g+dD&lumXHbz5+Rg4bRl~x2Plvd6-YO zSPWs^UAyb|l}jO_a9R|e%|f(U-FSy0gq}aD2P^%W!ei>(-l0=`jWXAdryj?nx^+a@ zB^su!bSL4Ie?Aufkt!b%*D-`6bXc>Hjl1B9`gCqVjKW`VS0b4Y!nAeXN0;}ZX5c_Ipr-J& z?j}4L61i);(Ssk^cr#>svU9g?ty^{{hFg7E z|DY*(uGK{QXlx$yqpcA`f3YW7FL$=IM7$c=Ajhli)RlrziDNAt|22m07-$z2;J)YvtCuL#+BxVG9vbR3yFE{>~hqWM}+z-0(Z6MVxL=I9l_rvV}LBOrNo z_lThjMjrpwuBPYYS(!9suWa&u+x5|#4*C+Dn%b^V&sV~#uzxfEnf*ubk6G@-j%+1so9%BD00O35rS$ zH3@cH(4_z!nBxT<*vAu6<7i`iVrNK?UwLg((K>H8u42e@-^sFY)S~_%RQ)zqQDUgX z)MTgeXsJf*cyW}bLvBr97H4FFbkUmBzCxbmQC*5s*oo5}o$LI}t~`!T=%}4WnA0hs zJc=?*Ty*(8>p5+Z$aiBuVq$BGw31K$`#-b?ss=8ZPIleKvg{xRwPv#2mDH-l_Z3ig zEGoU#!k~)ouSlxkbqn4(%KCJi4+5Ubhu?TOcswIK0$hqd8_AH+9KmOCf)>k?Go~mg zrjgXW3zQF7O{R$nSV1^l7h&Fll`dkr`px929W^E`F{j4mgMsIg2t+Ld{us3|U z^~&oA7_M~z@@RE!mcoXHVWcmAWVxeh{+Z?vZIi?jwkjA_3_ysL8 zELdbVE=VB?nFs+7Ndyvei0FS*ffs~9lma8j)K;=o`JVpu!>j3^;Ug=N35eN#;)g1c zogm!o^r_jjxRAZUV*U{?Ys<_di*6Se0@%!NTK3xw&p;5Q+Wz!$oW*`M+o@7hHukF= z6F%s|v*PDlxmAOP^WtBU-)BX@B?jzT(|stAJ91YU5 zFzxnzu1ZLyR=_4YSx(Hbz8sK+$-hm&%f_bqN~fCZkFuGoNoR9lrn;rD=ud&uJR@KH zz=HfmW7y%nZH1ztzjd=MXvc%*SRJ{^{OLMG-lAdgH~OGa)MNWh&O^;!+!PssUuaw~ zCc{5@1r@|fe(Ztz1_pfv;mWu@$GhAG=@6+m0Yc_)KtOBD%X~>5jTehWu}Z%yxYy#J z>UY(6ZrJmW!@K_d{CBb2FU8BV{Dyuz${E=;0>YHcCZd05o5zHOnrnGEO|t9Acn&s1 z_^e4EbpQr_l!hO#X+ZdRe9Wl{ZrZ1E`BK`&wyRUQ^059YQ$75ieX2Y}soTs+K^qSR zn-+nH6ZoO0Ks84eHg@a`=XSqChOMefndPIFoB#)u0-~aA7_6aKPUeQ+WxM_!Ki6=< z*W<6E)aVy8Li6Wx9a-M0`aR`0{VqpU2lK^m!f!t@N2$3y z<0S&!6L+YrEW!d7Rl0$`l8gE_hm;4-3|-Y63+2Rdw$HKf9f9X2*{RLRC`ss&JCqf!M*2uO|t$>T`9^b;dukRI>}w?gu6{_-ihYSE2w z@Md$bU0rw~)_`pfyGn6cB0)rzF868au8-}v(nWj?$^?&k^-q8`@b0DH9iWQjK_;`ZAmua}Vl1p+*JRv;$S+FeRM&9YP9!t)G7QTJZMD z@fV8KMd|!~Pv+=}?=yMv^0`Jg?>+^Xa}GhxeGPN;bj4G6rOWn35id3m21OUInObI5 zjyEkQrCjnlO;$PRwl$mAGU9T{@N-c+xKt2!#QMKU#rd@a-!_Ye` z7153B_-I9&KHudlT;$PEL5#t*moN9qJdQtjRmEugpJDw69-{VELm6elXa>13Ic9Dl zPR7Id4e8&@&V~~Ip-F^jFtAGZ5m3SX>I-GM(u|-w5-7RFW-yy5=g!~_n;`sfv!p2X091tb$uU0nJa#E84W*d3Y4Ub>@OWofl+; zsp#Xsb0?dK%}Pi^s&}~xW1JF|nrGI|`$%`XH={dMU19));k)P|RmAN~uX=fIPDaWh z91HseHJ+hk%BB^_2cPn@gcn&d+p4<0_@Wla-&FNT01z$T#s$-B;IIC0upHkSuB-RN zm)%nVt{Ty%W>*I%(zE`7_m^v%=Z~8tu2?{dMjapVbTcuEo{BJ>m;9==**)4bt{C z5dkd^S6h8|!&?GHsL5s7Nc^9wtv^=UGq~>^vQZ#6t2+-y1PBu|-AZ2g2~#~W-)ef- z`M{anWgUu%eEDd_k=iVPIMDp1pbY!-T(>d0lY&Q|HGLqM`EOzMq&03~XRdH)1(Bi>!2 zN&!g$@xhT$IC2rZnml4KkuAckyqkEa7z2%hVt*Ws1QPj2O;RirOe~#Ua5K11cVy*Y z^r&i}jBAg@F(mxc0xf{cvxtnykRrH!@xuGcVr}rc+EC5|{xvwzJh2K5kHhP?$a03G z#Ri5)&?kIEtJ5JRX((ewEbq(wk2;!Tp*l*n)k^WEzdv=OsX*!qH@(&)WG$lDcwbE| znN?|wcTE3II#e)6+510Tc%yFu}vVwzV?9&&Vgt$w1G;%R$G>%fZh5o1Kr3 zj)tC#bC;f;lZ%I!kAa?!i3j>^taQZU5iazz0ZMJ$;TZo1RJZ#$%#N-h^|`&%b2NVZ zt5}!g@*&Bq7p$14xR*^I5+HYHgO4b%b^OooZIDJF7nWcvYDl2HyUX$47_m~UtuZ+9 z75q(Tnw07HL~x zeYRQIlP!7|86}S*39kHFRc^c~Cbu)Xle-@S6qi>%@3B>BC5GG&* zKZO0YsPff#?Hlf7gvpjMuCsJx0sm5emG~v?C@L^#dqkI^I0?_kQH`3ZF2PEBq;|fJ z9Ho8E&cc*>5fwwYm9$lyr+oI0a zKBl!*(tL>?3Nui-I}N-2YtJ6yd9~~ZrSA! z7L^%M{%h>i`Np!Bqd9r>h=n|-GzkDyEAg7#&KtS4kduC;Kh>n->+*5O~`Oka!cP%Ghf_}?h z0{_;oTSalbHI3uV*5OKs4nPYg7*jzT-l2cpv#~W^buYXZf3~(W^DU)Q(rK%iqpQ1T zA#EbDKTsXJx_riulNvn*f{K{L6F9+#$cK2R+29}}jEe<552QEQM*_hOWS^6VL=VIc zT0Hph8`k#M7pbXM@6_QC+~5#9hv<<(6z`{duUzk41ein1ps_h30+&vYrDE?jB&*XX zQ-$BV$>)n~zgqST`e*(5yZyY+Ho+U~e>MSM{^Mt;hyUR_h;(c$7I#xgW64D8Yu35& z_@02d)!M_@zDYK5U?!2KZ61y_W>pA+l%}vQ2vTc6gX@vPrzb|VhOE{RU!@_Z7`)q& zUfL#WvRParf30YrmoesbQP<+R^?1{~rQBTj4!4zeu;8O;pFi=v$X|HUwmGKw*OMO% z0tARZ5ji4&=xse6O}xFDP*yQ%c%h@%u^EnpAtKY;EhTy+Y%4?|<>ee3aGGi!u4-hW z;LTR8o15xBnSa`rxU-ZkZsM+&SL2C$lqYEh{}QJl7Nq{7*;m+XxnZMV%v;BUi-~90 zUg5in7EFdpEK%fIiH7fBlv2kwP8rl&zKiW^OVhZm>XlGL@TCHZYrQ?^SGT3C z0J5naJ0AoAjV}%y!H|*t9O$l8blyw9G0%x#H6(d^P{G8KM2(NhE0lwkn$DUr;kH~S zX}0fnz^K=7Fo%;|=j3OdqSr^%KB?%N*j8=U)lioL@eTN6ihK0XOeBb1h-qB$5VcaH zKfz5fkya5**zjREp)jDnMIY(SgKnj`hWUnF$!V`(*Fs6GzItKV=nad zL5hae=18@KK$yYtR6<96&Zkx`QE3`Q2%Lj`-lx-&udX}(iO_r{1f9M{OW^(3t(nyL zppf&$!?)ypeEI((IWyie7}Ixa+0 zTX&UW_n*sVFR8<66V~IWwITI1(;wZWJ)_KF%MUiyR{s`0n{V*Bo~=C+2>HfB^}ZRo zX7s=Dv@Ut4BfhdF;Y(3$dHx9~1R{Ke#W3-h7o_|Iy;52`$^Q)bhTtbh2QQTi<~>06 zh>#9?vklK@^&zkGE65w3SmYH18t_V=DOjhR2(f?5sLc4X(pU0rIQpH$xt+y+e4{=K zXMpwi_4;Cam$AOqDcr5MV@ZHTivQ=?LbK-5zOK3uy0%3|(Tj|LILn{=X(Y_822%M9 zc`3O4^b6LM?g3>9URQ-;scN0eCMqH^ios{tb?AA24Lh*GL~tqqe-&m0d&vH_n`$P@ zkYIND3ezpqzb?;k|Ex2&N)QE1!O%N{OKMv_|`x#$m7<}5rZTb$EIIld?(U)LP5}G zQeJk;U`@ZI!+Y&z_3TWP1%gmIfkXETK1khBvscwswT z_B}0}2o$7JC#B^g?vN_^9=&`;U)AOV>ohJrqqVk8&cMC6?_XCn9wc}v*>`DBmAB_z z#F^L@b%jb<277I}#|W9Bt@1QKRG<)|m4NwpXA&fTv1sDStb>CbEEP-=AkSD-8q$kA zUG}ag`rTJYB(d%c*ASTpa$(Yxoe8l0W6vYGQHLqU1c@O)w#p~7ZAk`TIRt$)DBqlj zr#A6_R$?Eq_1G8(ep2gO?nN5Q=dxHM1y zQd}PYFJHo?(qJajIK0GZQDqQfi428(1R}`a8t6yhd=GJbH4)(Fo4QJ}SqEbeM>Y?d zCwOY^pTMEU<|IO?3k&8qF4a3dYi#ESdcaiqAMS;BBVf~^!fHh9x+>R@#YlvyV>i#yfDXPYPwTEK;+2Aa+HOPu_1w?D1s|xiy1t@Kjst zzs-+t3#g!HOAfJpqwAiqsH^F`ga?2p+qj6J%@a;`Oi3m>BFn8ke7s2a@_Mv&|5FKcTv&{M^?l#7D;=>dasBxh z4OBs75-L?!hv7OjX~BVb72JXK92GTBW;?FnmT|#0#z>2^?c$28d^utqbp*HmyyvV3{R@7M)xsY-KSqU$~W93ho#hUYnzKnqKg4ZD>)4+r;` z^^&v&YYYc=bQ>dL-)8+$Ts8qtTT+!Q5b)EeC}?3$xnF%Ka=?OV*`z_69qzBKJZs#dl?l-2e*X^W7 z(OER}ah0FcVlds^QF@%Jcnq<<0#nHJYfXB&%y^w zfv_GAn+c_A!J%rUXda5T)A&=V_kK6So*eN(T!d5F%UB3vnL|>s$Zox(430myy`7WPtXZ(Swk;v^BrWanEnSge6D?#crcH4fnq!@&V&I7P8cHMu-{!@YUuzvk ziK4C+8d}aE85di^qyvkzX}wx!JHSAIG<`ykIYl}#Qs4_A2113HQfe4qRFeGd0tFO< z*)nZeNoO_j(IHYj6d*pIJosSTGX(D}j{lwJ zBZ_WkE;CPK9veNLW;u0a@2u8q<>pZ^Czw+GwkzyC?-0s!W>+Sz@oS63HS6RWJEEA0 zBx~kUY|cH=gKf-DZ2R}`PioT)FF*+}M$i-v@}Yq!9&*~qe8WM+f$lBFgt6%1%5Otk z(mXy+^O57x<5qO=KF3gcQGNUdI0PREsYg+lVH>XrQ8l@h@i+dvJS=W%6e5)-rK7<`v-+C$R`q18=Hb+Z75a+ zonyJwSK?n~ddY7bvLmGVjslNnn*DGPKmA{EW)K1*AUOOl#Nh+*X}2KzTa=T7i;JFt znvRYZXtAKDXW$YPV&|o!5#~K$<=*G!WTjv&MdH_qA^n>PG$}q9%2@CV4( z9OAy<+%$3KDN`Th3`u5_{n-2f`NTZ(dbuDb4keaMag+OJv18F7jRqvPs4C3Cl6FSo z9pNfm!w;D+HQHSsKS+GKlf#|%Mqjz2R=5au{xe7XoI{vC6?gB#?#DiUi=3QcF3GoI zO=JHizlXJsF(B|}L(u&f0NSPax{s3Rl*TaRvZ1_XmwPb+55wEOXiJO#DpAhCaF1_H~ev+B8y|D{1axx?Hu5 zn%ov+5{TP(<1+N$@C4y*p%|STOESo>M}6#*5B=@_t15oMld z!&SVu7t_*b8=j9`XDIY-j4&`bz%ZYr6Z;B>%%hUjON;9I2M!P4tP0-!Mz2$Y-99=c zachK^@_KAmZux0+JoQ&U919rxCoM``0I`pfzZ7QUbeX@SgbiZO953>k1aw^0`n!()RoGV_zMA-uP%iOx+PCTs16iID z?G~mm+h$YlMp8ZeEiH}BCY81ZK&xWVY>;CnE~~lIWpK%)k^{5Sfk|!2TSMYBC-RAWym7}0e!KIu!>l~{x9 zfp;k^JIfx1$GWj}y9&!R%34`Yn^cgncNfW5XMAYI zblu&nzy=MBR!7#H&t~OSy?u+FA(=N|56_7gh7i^$Fmk;|v4oHJ9`mg2IsSAlr=@yz zL7JVn)Mk?H@JHpw!Kb!Bx{TDB+ocE8z>~|xilCJ(sGY;~iZ6=ZktMGFgEvayMHt7e zxA(70GOba>LoHSadj)OP95~?T8I-TTBq^|#=1}g4w zhgoMCh#JH#@>*W#)HAD=(ZC_OeVqj*$m4wcD6E|Jn}5v2F>wNFW-IJT=z`m!F!|=tvaoUARBi4)AIV}!@@F=f6ls08kAa z(8Q?fEyl<f_Qw{W5`K3Fd5RyFT>M1$whfUFb1 z)G((CEoMTz33OhovFydm2#)4qW-I+xaF}xMs#kCuV0S)L5B~lZFzxmJn-_9|PEda} zqjTorE#^JXa+NlsUlp{njK~$O_|QOrtgeusUp@k^TSe0`gXq~Xj+g&X4)c%<$^4^C z`I5NhROCW}nFnb3LG%9*7|2}O1#!!4ShbF71NC$?7K|9DekE_^L}3(EwIcC=iAw3f z!5(W%j%cMJ7v;iT->3)t@Ee*MV|3gcC7u)3Ji5!XGeyJFH(B`~uRjKj62Xv=kBOLrKL z)xV(AS7Kr!u4X5Uh*R*A>qKg%hDO$nRSMJNu?MmD5=~D_-hs+h~p3Jw>WZiV1g}2JWeRk_R!K3i9urGdL z&ddWb9Hk|C55#h*mW6Q?*|Wil@F8v#I%b6>y%qIUfnE;lO@7^LJHK0tiv9@Ey#nW1 zQ_w^r{PCYXCjm1;m!H2?O+6fc-dHEf;B6+Vu4Nh%5)EzLTK>H#4*cf*jva|a!3Bd2 z2>ai`sr!?_>wBH<9w*CbI8@RS#}vKg;^R+NAUKKS(uQM^O{>^_>w4Y&6n{pA>nw4; z0%3jRov1AzC{PTW%&%f$MWY{ycUGJ?diBK`h2xP2w#cu0gYV6)D)sEfdrhJY4+DV7R zCC?}Dk<+1s?UTqYP&~mzrh}euVo?-0i>ANd?zi^A<#@OAzQigVK+7-*` zs~>+|cuni6CTICj(@-GAT{&nbPDyoFHN&og@^!$Ugf@}o*LM}wZMRZ-bKeF){4XE+w9Bqph|n zq_KLWdLm9w98=M^s+A()Y#lIHhNUdvqiE<1|n;c9h^AZP zw`*nOd$|dPczS#n4P1;-zLtT6v>f~uszYKtkE&64O`tcbAn~Qee!)q(yXgI3Wx$A5 zhd@~i#mgC&j+aCwwM7#rPS*yWwD{ zK|0+*lDA_t`Ok)TzQ;Pc?Va##py!d?eo;Y*oV$l1F=3tmjQdHxf@bRD2Pnq^LrCIz+MIk>S zk99rcoAH}_)9yyJm9#AXCz6z_O-_DxSf7F9mT$*~z&}B(sU3@KLzi7w8J!GqDa`Hi zmn_HQZP@nsRbv+EnF3BogJbu$EoScEm+=uN?pZ0r_1Hp4sYEks!4zzwie(B7ZE~ zG#wK$CR5X);eNbn{gsuNJnY>J9>D%u5BhbIgc|);8}#R?6MJA(rDG&|hGH=22nDiA0UNkL7f zf%!G?fIlRstW+t_`9;19V@JaDT^C6;iRhz`xi_P0geFLFWD;izC+JUrs0!id;zIUk zN~y=a7@#uYm`(EXuv!()xrX#aOMH0YP9?D5`9U1@|LhMU|F1z102)L`VM&@84#-0!YKw6gvo|jxS<}1aV!Y_tTTkQD2fT_TgLc>)@ z{#g!Z+vB~L&K!GsSie%oj?jW6hX1)Rf5*UnDsQtraq<9Qxw_7F^z5dDCxN>CDFov_ zz^SX=Q3dJwZrnZ&;<`xNyQ*h6uiShB1~T3nUO1DCM%UWN#@+OvB9 z5J@yw`rD|*2Zr`$PdX(Sops@UfH^_@kW%#K$L&L0qb%V{*~qOo z&&Vb0U^?-e{z;{^XUoBAS2ZW=^&=tK^>s~p8RSiU1nrm7X6ytRjh7K-Fc-%)9L7_C zbv6dRskb`eD1l%W2qf@T)+ULb68h|WH`406$)?Z{T46>B`m8UxLk-!{SFOND4@Si8 zul_da%1oVp>!K)|u|;!pHK;#sp<;dcNb-nD{H$ixi`IfR;Q)d=UMn?$Jee$gv!YE< zwwsBnC10JlgjvaE2HnZq+Mw6TjBI<()Wka)GN7K_ukjyk4k*@&4Vawfm=tM2&(+Fq zZ6Nme|EvkxGmEEb4hpe#nQABBCa(@N$$vRio_(?tuvl%J3ZeJ-IWvvNH#+)7?HS;7 z0%cOP=+iHKWS))9mF-#OVp{c&h2K+(r0uzm+@0$!AUMcxcpyn!3b35J$H2`^D$d4y zh)_1f4v=?Ed`z4^U0C7c(xN$ewbo^U0MA-dD@B>pIKN8ERJg8T zeIO>WdKko3mR73-wsPa++pm|MTX>{#bi;#AI4Gk=?J2n@iiksGjyJ=B475Q*#NJ7K z*0usIP4!)gb{%+&s7!EG-UQzaTd{n_CTylGN}@7;6;EB%BA`RLf2QAIeC2E_AhvlyTMCG#7VZ2jJ^3Jf%)sf5cWo-%2T`U%+rAyg(_Y zR=Cyts&Z>HK3>t^<(-kOk+5LmEgm6UyY*f5Ouv?9z+)o=aTb#S`y;y~0-i0w_x_Lj zcsy!25pi^cB=n%q3#p{bPv-i^7N+`7AV3n6gTeRWkEKK zlop>o~hwz%fKY*<3Ru93YJA?;Sbf5M%8Fn#{kt9Y7U$gny zH8~Qeki~9Aa*7$kV_@(=eGW@eLb}LvwdPEe?axKrRmz^<^M~16pI}81_K4;;j}?kr z0W2X5fDqZyowy%u$hGHWHc+6_lOQsFGff^C<#uI-g%;Rza@8vFyw{jKHx+rU04Od5 z@ueuAefO^Wluf`8o6UB_NUo;@LkjYCydF5 zu#D^HxWb)%Gjr$3#HTuTqoO}mf)dn#RZDXo0kq!dMM!DBAQ;;5_gt_%QGNJW;pqCa zt>PlrTr~!ub%MOF`Wf5QcrGYCF(ql*>vzG2zxgWYhY}e}z~yW%YXO~CHRdok-sc|1 zIGnauDdAvQeQcAJZMd*ZU`&Pq5^>V_V(ppDs`|vCZ zU?4pC^IU9~8!3+?L0Gh?!=17W%2uu0R8-cIlSR(o7^v=vy0g7G5;)ccY{BTlGikB^ zbO8F0B2swY-!*K_j?7(pT^DUD-HE4)020+12dw)*J4}Axo^A3LJQ0Ni(3t9auT8Tu zuaCH{ZtRD7G2biZ2KV~R*P1Lw!=#0MbT}R`Fb&{_1BSu!rMDcjBbllz-4Zk$Rn^?Wg7Mm#E1d~fw$M5^(VE)FojbAKZ8%FmKS0`!gGGU$ z?*JvHb!o?Vn8h`y{XJ{!i9*#1eaYiW-m27g1lb^4gz;hg;PPGfg`UM)d-Hpc$Phuk zN`1hzufH9Bg=NyAosL>=;1ZRNT6D8bz>HMlyq~3ihUEUTpxeRUiQ9r%1UV=r{LTC{I*T+CWH+&7D z)#3jIXvQm^a`LQ18{zBD8itv}&Q?OKD(bWode=&A-nShr7e;!|{Bu7wL6;~Yc<&A| zX0ffp9l0an;0^&8#{Iot6ZsVL)sUp`ybzCN-NKCu5+m(7<(E%GoJp8~^LFdRDA8!h zKM-OYT(m(nOT`#m&+M$G*_?V@aL&+g5L;PY)b8AUB8@^TMbNXDK|vMXpmdNG95fdE zwaym>-TLA97qaJ7!;U{nn+-PN^~wsrHiq~8$7?HoA}fzeXB2gJ_6%2_xTE)h5#rxe z3aXWp!X0-{rj2baOudUjl60C+J;%8o(Ds53jMmx3+k_(X%}F&a)+FFmyN$oobc2`$ zB&VBPaoMu(;Ay}LIIw)s#$&(amD2~-v9!t(nBr}Xft6`-|3+B!gL8(u!a5d~DQv~f zLuWs0Y^y5O{lgm(S<0XL;mplP^GPZuMJpTY3<0JBwM&-?Xx6Jy%l6T@&ki*?W{Er* zijxWvG6X3+O~0a100>WPC<9ovd4-G{{Len+KzM@u{<0Wyy}DOwf8gz9SKIDe;cBrW zlE3QgF)a2fKA_oxL<2<#9m3uG^*s028`>+c3$v5=-7V5M`z7fhk0xqu?!+he8&A)*Gz6n#V}hX;QDBV=O*IXk20IR zemji06YmC8JA_*Kk8n}=0$&SeylcC{9Y^bs4O3i2;o5by5FyUcoXi=l ztLiEZl2PsDUVL=3p2as3%RAmEhJ#EbFa7o7UwE0IU8DP5Y~;H)Z(0My8Uv&2GfZWd zs4zJNWfR9V7}vNogVBjKlo^Wz9(%Hsm&(#hoL?`mdW9|sUf4~mRcan4Li?hi`PH}|Xd~%khv-yp-%(}s%evH23I2M}eL@{9(G8y{4VnXP zLxr0OBB*HgAl1%a@~q_88~o{`?L#cQA6EPY z*tkLBAK|BN`|cCh1*0FlDCvrugt1bpypv#IBKP74=2PICaLl4FJqNifR$hk573K}= z8M)`XD}>Qdrwa^EtX7v_bPd8?t_@=Q0aJec_unUrJ<=%KdZHH6f=!q$v|F{Gf|yeJ z`0Uqs+pTT(Eywx!PoYxMhPV!MPXx0FnD*Vg;yT}T18C8)PeRWRQ(*?{3+>jv&xYQu zvSJ-%QpDjqj~j13*4k_Kl@8~Q1=>3CPvvgzYrJ(`2(3uEB5jHbtNyWgO);_RN zwL?T=&CGI!N~Q><=(PZv0v=g1!kVnhuiC5KL$fM1@_lA6sJaMQQ`yAicw~XXjo#jQ z1at>X86#S2w1EnaCGk2w@Tadg$J>6r#0GpX{0@WzR1?5Y9LW!>2yQ1Mv7Aki!m*%Q zzQJKJK5qcucitk~%C+D2rY`iFZ-Kq#C5|+l7~F8>CN10n&qQZrbJ?AWnNnh9`PFmF zWaf&-`>4C`Ch$Cvx7%|FZv#QNs2*ZC=;p_7J^Eb&zL$3X-15?8{S>A)691P| zW^G5y$kc zm@+#YxIlnY>Vg`gB+3_7t~*b^0M<7~K}*=){_-*J6W8Lry%+fS3vTSO{mHA+^}FlS zuC@~OH70Ehljm@s0l`OfLj+iYC<;ZkK0J#4(hLP6&lv7daY2ewN9I#JCi6bW`?+XTh-QwCSu}`_ z`s|bOf#q>3=9%ppYvRUONrdayk~v4Cf9|W=p3r%!Cn24cBeo_O5vBBJ1f##RgJto3 z@o4*!JEKz)#&{tk%QZ!C+B3$~+|?zUQDIo`?a`lZ?eOE~LbJ|O+6_M{YC>kkATCY= z68uh+QR&y_&hR_*V9`&tKLUJHLD+vNg!4{+*wO7X6o5z+kZE)1&?g_a6Tc~<)_HY_ z!NQ;e)4`=^GyTmcEnm?Ed&uQGf`EM0Tct(>g35sA?8xK8^uo>S+mfWE-YL`BEIC&VSh&dn{zK|{w( z&&|WhNDm|~xM*qUY3b;hc-Rhh=x8{&4vuI65Cj7o$HCa_stA^4&7Eii-ew&{)xCaxcKC2*Oo-92kP_fv-3dG-AOB_tJguZZ-^4WYx3L zo3i%5Y&lMxXU$dN`LCZ%2)PgDp*@=?srM{YEfT;5qJjEIM$&48`h#N9yLya1R{n@H zs^G3*qT&BCJoZC|a|^bmj$1cuT>68N1-N%l;bMC^dhuYvC(2#9j}D5nQ7p+Dy181> zcBHNDR=Du_Y&PS1Fi5Ep1RtRAdebLM&=qc9k>zpH+f2WbU8yFm>#JKC;k!HWsCXsO zN0$77m($QfG0P%Niu6(Id5&1Zd$ z1qR_hdkUlC0|&NpgB^J_#tLxrz#ekj44k;Uh^0&$G03CLA;Pbxv=8euHtoosfc%yy zJoX55_8D)aPH*N;lMJJEyfS31HpS!te{&tAoo>Yt&$hB6)ll`~p-^MbT z#hTff;auY_%w$T28&fj>zhI4ERWuMMFF3g0CS{OPfD5)7$?>2+r$YNmA#gJ!C;3^vl~=vhk-lo-pRE{TVSimEKx6^_kQs{WBRo1no!a~O`~M;8EQ8t%w`h%( zVufPGJ-9<~Egm4aySuv-X^Rwhx8m;Z6nBa{l;RMexRaZ6@40i5$>c}!BlAt>o&Bx7 z*0Uh86U90BHh-(s(gL^#-c{1#lH5O1z|5s#E#)PfK_bd4?@2*Oguk%Wa}0yO3O=UD z-K{D;?O)JvUw3D-djoj&j9EJkT+=uOG0PPK#LO3$DxVw?4Zu@jm7t>}$8a-@-)PUO zyv66}w?7~?DF@e9XA7Vd=Oo6($@C0>S5ZQQOp%asQuMG0Tm6wKYz?_$V~3EkwM#e? zuLp40o)RYY0s0v&KT+yNLoHp)dyCgf<;``#=Ys3l?U!aS{~L9!Avq*iZ6kvbE`EPop34&@Ls$#i{RD&|Hd>CplQgm9JZ}Wbz{>Vu#3Q9THD()`cD#+P%Q32`n7&t+9e(1TBb! z0+V9$jo*|f|gbqE78wwCz z|6YkS1k<*?c7U{DJ&Wa_*$)-3djn8?16T_SvF2KIo2Dt>kC`>Q2Yw_L5OF*m>PNqe zpa56G{@f;uU86J@7ktDksi?8`0)*8Kvi@f%kOII4dyl5u_)Ax`u}KI@DPzOUBuTAh zk(b1OR!DPTxo4PN3$h{cmbY_nBugV^qcd8SbZW`r^70ttw}@!)47?VHGf?f4;+5v; zuw-2$YO1IQ-;goksq<@Yl4jkztn3+I*2@)T4Db^))*fWIUvw3h4~PmYrx()6Qx8{b znE!@XAXWmuSm4;I@vs!>%AZ5mnM=w80A$FpIHpG)9r(zRh1?2T?nEgoN33ZHZ9*|~ zMf#Cxe29nW+c!i~1q>zyoVY$OZi~f>zmc^B;o}WGy7X;<&Vou%ORvHzYoK*9t01B8C)|L;|%g@924E3&G{2@7yTr(AJZw7L)BpR zLbvbEoG1tY1uF@;%xI2dL^#~zd+uK;e?ogwVnV$zTYUqG|8bLdPwQxKXP6bE^0O$U z7afe1JRl|~uU_OJZBG~dXd0V8W|MR~6mX*19v%zLj5An$PH=j|Hx}p?KB@H4fC*(j z$<`6*H$7FQlqMf?uEi=&RG0^LH-3qZv6kNtPw~H=fQ8O_^XjLAt`Fb@kDEAy^F5`I z7dI4&5wKJIWKB?1J_O#`9d-o-Nj{psoQR%Yn-)ZKsnw7*V0>5FA!L%egH|RAKzk6P ze{aP00`3<-O(~FGPn(PSXW>t9kn$RqN1`#(Er&Lt4e3?=QC6|U+eM;sH4klY#5F9P zLmozopLu>CN#yu=gA>ucb&0=L#COk?! zwa6w#hz$Tg?-%{~lOKkY%5rW(RIo z#z*V8q=`0DrQ|gt#h%l^OSenK4(#2Pe8(xujY@t{Ju|_{95p&!Wl?wD*}$GUv8;pg z*sQdk8>dL~vzWNg_@j8#M@=cT^NRfSiD=ZA*(Gvb!m~Ps zR%At<5Q6gKl-e=SVCnxXsN81hS zrB@CHNmlN(a+=n%&e~k}zepy?sqC)T!1KJ1tnV}ZSP0wYr0*7i*8c3wCyn>0X*ZY8 z9ouzQRW}sP7^MefMeKq9nqrj0W}bpzb=<`6;~6#2?|Uou=B|5ms#*SQgALCqFDQ?$ zZwT;suw|R>?O>}zr(H8XTEJxLdo*InnbgfB_2td95guZy|v{ZzqPtd(%I}Ye6Qx8CXlsr9pjhsyoz_hPu9UG zjr=RrrVlQtESX4(N{|C-=e`?K=u3LFu-R41RXTCjy8kB^ed13(673K)=t4)}x*3vi z@nHVAy3@j27sMx`9v>(3Ju1a(w=0$TM_IusxAi=kHeZL4e(UOd2i4--psq>+p|Wa? zm_Qn8`h^$%;;xEAreVH`+HV7CL*zpii0nWBpBnEF&eSGN_s`F<=sXrYL?#hm97-M{ zJG=6W%X$s;N(G@>{|QOHYesAM8k;k0lZ;Itl*qC+f*nUWCRCQ9*0R~CL(R;vSE9(#OPF=MZG znK@@>T`1-k87y3sQA55J%#Q5^^?-QJ_KQ0WIO)9A#U8&*(1#wbQP3|;%Eyg?OBIe@ZXiJKfl~d+u#jt9b|2xi(hy}Y$eukBj zx+e~9LbheMh{}Ybt|ACU4aLz*<|ENvc?)gvWFLCn4sWWQ<)HExCWtc^(Jq2?`s8te z@f_Zy)$Lz%Lqnd$5ixJVlk9|kJQZjZd_qCS=k>QfQ;m*E)x?)|C1^f)0*_q9>Wt zCdwgb-}Y?tL=K8#{VqHX*h7Ka_53;DUVyrh~jXkoT)k;@tbU}RWYo9E%8OOW*4^)-00ez~~l zn%fMmrOh*h$>$%(VXoIsXx4Q_Gj-!h02r;c5>iGYY55pAEkd&qLby11G+;c(lk)J7`N2v3@-sj;Q! zZFx7j?_WTJULOUz-_9fDiJ>(VR_3mpI_Iid$3&cq0= z_ZQ3}ZZRzq!}SECzNyd`BYi|C{3F;>L9LMS3f&vm=jrA-+Skk3%rg6O`J#3(ZU|v% z;jxdb?y#p2;8GxP){F^D$#w^3UkKc~q)GCL&|wxGi_G2YPRm#8;Nt(I#-0`MUoRXb zVoHR_Gf8qs9O6#c?3Ya?m63nuQm06){*)N4Czlxi=kebvNVsbLZhBhLo{(5GMdEU& zCjKoiB|jmdEHTlcjWH)O%>&(Gk_JXB8 zXz7*+HTf~L*nZ#qvzFk5<5vu(eCZK$eN}0}Kf8A~_Xoo^#~DkhYVr|Q%5O>PM%T?- zK`6|Qmp}bAHE!SU6-3}t=cVdByJu5Cd(nlUXyau&!OU(mPwPX zp8{toe@vjt%i7>CeO1;!OdjBDE&&NkRhdE-;9sHv8y$gzY5H;|%i-AYfhF;sHv(TY zKk`2BCn#fTLw;1Zda&&uEL-(&N{eMh>Dxg@E_th4xF zJV^_v-U$s6MdC8p!%NdZ)>3i{hZk0${91;Jvhk(lHPw<;)KBqxSziQY*2h4-GUaV^ zlF^M(>(X5OKNfnKg%D&ir&^^}35JGL>@7<3!#!G6&A(ENY)pxl=O>FM=jdt(0Fa`6 zY6+7WjG_|Y{54FNG5>ll(<=6fgH>12(2*c3l6LD6a|gB`7+p*Zp@#HkuQcR@QQqBL z%!R3F=hTdNb;nkWos@T9F+M|I>|X=U z*vc&$Q{-F6v{hp}dSU2=5-|A_+ldul(z1EIv<5gP(zYD?QD#aup`S}x%d{p2v-G;- z1I^joF(5(clwU5Ot9HnPSZnUcjId-TSNd}kvhais3pf$%(tA!HMkqZATnSjSg6stn zC3w2sw~T+WwWA(e96YOJTyG(NhNxH$K}ZzA;{6K%rWGuDOQ8^X9+pOE8GRy~2S8;N z8{%ooHWw9?M!X9%H?=t7hq8-~BuFZw;#Eob8QSAea6SLx^&)SEpteqxvf0kjDzQIM z^sLVuIDP`M!?+naVX`yBxqO?a94;JK0N<3mK!WXi!R`td5_iV8aZUKvi^_~*(yYMR z=gvlM=W>#F!pdhx3Q6y85H;{1Ou_aY_WSIW`em(YOH(~s)7DvOmSK00-Sq#J;UB5?@`9;6AtY6t=R*ji2m_K(2e(*6H&c>BDG>HHy+jo?Cf> zpjx8Jr|Eu4E!)G39zlyoJ|3)&4z1*}rEzZN89PP1-9TH16WoJ=$0}J;8O}&#J#^IS zuZ*M^TI-rrU^Idz0o3NG5I8ygoh47sizGoUhVdsLV3X9}A*5FtWeBUPd1{VMfL;P3 z=H-xrfjjg#n>sV6W_zy`-Bhl^)6ODQ{MX#(nD6fr#mK=cM0v;*5~q!Uambw|UYSVr zW8IpDid!SL%}d-n67X>!I21CBjIcrcvknUey(a&5i|{KGpEo?J>ypsm>@vX7K2$i=Cc*#z8!ePNqG>P(#Sx8+QG=fXBJJ zDv@2atk3=Kv?urvp%GcnKy&(tDD4V*P5nxS#n5acTh&_&*I>&;Qnf%oMvhbgn1byt6S3(Zi$AK z<1$1yg9vQ;vgqzq$JDgk3j__1=jt$wIe*2bs@i~ghapN==SJR(o{p2yfbDf~`&{MO zeY@RrPKP#n$ExHNflgp4o}ms?{mZyOCCBPQ1)^}| z3Ja~I=ww^At=m-BR9+-$Lp}M&44>BV1b&zhW$@jqobd|j=cwT4f}-D3wgf}{3tOOq zVsgDM4a@Sj>WYqR+Da6lEKcf7BB6&ruxx zpsimXK<3%-hDZhqI}&~l%Vp=KE-g`K$%XK8Vo9;Z7 z4n{`MDX@2+S}zymp89CMZT=h!hT(>SpB9i9&S{jef>Q<`Uu~dIuXBb`K>qVPW8T82 z426&)n7#pPgk13V%jy^O= z17#a%B(;uH$qZaQ`G=?yGL`3jtz}&bEP7qH3(Xc9_jJ$F4d_tgL}kAda2F01E&DSU z!ubG)R++>NU;9YSNEaxiV3?eNyosH>{BNA=Rf^oWf5=rB=2%h2MgF5y6E3dmnR!ET zrk-q88HgFNZeEqvJE$LN@KpF~)T6+|fq(|H8R=aCO#f_hkRJx9T1?3jYU_1}0K7<~ zD#xfbpUan+yCarWVO0Ub3I_Go5j1XuIe3;g83lTc2~Eo__6|o)vbPB?#|;Bpd_1Dj(HpLYF^cZcD%J0BJqZH`#&0J{3uW6J~*Oy#cEuK@b^0 zN$!|FhRkE}9~l;ga?sPzvx}&7X6y;MV|O{Cr#_Me>dLGeU7dYAeuGn-3La+|%V_FO zNd`3e`i1#O#;haSW|#aHw28z%nH8L*a<@FOZw;9D^1nsD+p>rK7`z97t-8Z)uA!fv zGVt|CSg4#f85+Ie4dPSJSXkK!?8>b*r-^Ess$8t{w6`_`fZnB#&Eo7mv)<>4AK^Wf zNH2W8Bgv#1FuzV?);hDYk2_e}tXTEUb*(*U31T0{Gf@6{iXZCSLrQ{g3+s|Jjf<07 z<~L~sWcZeV)$(TC4vZ767J$1dMz`5?-WxYL??}N+QmOP9o-lV%N@kBP`YOfgd`E|cE59!bOFZQkEde_+_KmGo>^9J{gk`> zbcTipCv)vA$W!rH1KUtL7g*=qAT3Of06*0n27fInF^v#IiUYX$^JgB8cIvsFcAu$r z0>&n}EJlCRx^FYv6T;kFaI;Mz!0q_~l~e|mI?y__rCalKph)SQHR34cP_qMQo(Oq# zxWJFId-_*5ECxI5;U=#`5H@BrYUv(RIK+D)lws> zG0I=X{3#zds*}wp1{mqo%6VVza-@wV5}%$fbO z)#n}?ABU!~Pk74sIC=C!ea3x1pYqPcVGFcILt5~GAA!vourwybS^VWqN5>HI4GReX z_M?`?&6yOrbyn_d^?_`91eQC_tUI(G@3@x$fC`y@C3J8W&5LF#0jtG7 z+Zp~iRxlwBHt3LG2|p8|{zd7}_h zM(c!c!(ZIusK5t0+fZYgtSKZZ<=|BqEoSpNJOafQ#p;5#{p2$(uMl>CxTNWLARV4f2vCWcsqeRg-$}ePb%kuM(*t9dh3s_4nXtVO%kV0Z*IPnqZ(6pDk+OyzqM|#v3m7>Ss;>XtmiS~X})O1WB(v3tXgJx9g_J4PWKiEp^H~R zl|W+S%O|GDHciWh6AivYGh>{OunR%CbBK!4O%Y`2$2MBA&oh=QWgA6GtvSe~PvHNY zbw0#~jlc$Hpl&jU_YRFLmPtCUsB9@YP4%0s`cLGhi-gAM>raN={-{$-@KO_)c(ZfP zCiC5CIyn42E8om<1d&+1T%JIeMwt=&RuJ^cb-w>XCBz~BQyWNNYQsFq3xtCnz{AIV zurM_}^?Px12__lv3-H1S6TCe1^t3c|^f1x{Cp#N0j5q<@KVszNJX2JKGr2*6+b&(M zsqOozml`N|&Z#NU;fNIT1HuZ$82(@xSQUu~qa3jkXBNZtdvcMHndnmBrd4L*RtJ4l z2w-9@CIt`0ULl1dN`c_al98$$vAnF+a;oV`vlcw#G{T?B2XBe^JkPnq!6`7z!EwVR zAfhQz@#0yz_2r!dF+g?`g(2}rIIMXDX*nAO@oo?Li{0}U+g@Q$#}-qB{x-r|>$ta3 zD9#z?%Cl~ceTDeeAn zUD{uORqpz6w5rx_)Xo}N!Q2I%T4T}c?RbJ+XqnoVduQx$pI)9_>v-I4+&UkS5Y73k zYXP^{!gtUFr|eh8uPcaK3Dzm)=Yl`>$zPKcgG0V!#be-*!q9if2xjkzeJWLEP*7lA zzGa@iwMqtSv}hKq1O3+8O$eB;9JU~R(g5nRN8b^9W2sFuNf zG@$?8cME)1lnV|okQld4+U7q2r4&3@O$tKUya~&ylOS) zv>Ca}HaNw}J{@IJoMIDvrCAFj}!ku^Eg2i5G5i zm3M`hxqIcf4m$;7R3%xKJNKm(0+tWQ#@Ry;UEkoU>qWFDKGUHZh6EYM%Kmj)jp?pl z8B-?ipBl}AM)v=?c3y#MS_kw~BNJds$YVCJ0X{ZaHRujv<)ZNN8_hYwOdf21kggs4_^UGHFZusTL`s4i1T!`)t990(1Rwq6!OU~(bqU8g{ICAKE zKOX0wM$fX<6V%33PvG81(7-e1(;+Qj=C_7OQEt{u3BdI*c@hTuS%0km*D8Zf18=B^ z_s_r2L_znbo7WX|E|e@>iUuud*oka%PSr1gTLCbjJKA~j;KAqC_(^8dM56T&NaQ#@ z@`KcGsu@UO4KV7Kc46Wby2W*ie8M?l9`gOgv^=rLT`Ljj0dmV59$LtZFZmr7g&EJR z$g~QZcpI#ol>$=7oyxerpG4Px^3BVUl`qwOt?gNp!;0zS9a?Q|(U9hX^NGmYjEo{l z$wQTGCH_EPaVWrYl)s{t9~ar9YOBME`bPjtI^&6G!~`q0g+$4r$6pB+B47vmd_~wv zK0N-etIm}8o@W$v)teLBHZj=jb^iV9bII_-pL&~r5DsRdVamjWG#}&c=B?HM-km$G|+oVYci+O(4 z!pQF*hGuZGdEL1el|G%-w)#F2K&&TLPMcPSE}uJAZ9?Sl(>FU(E^EpTE^0Cx2k6uR z(eLz^kwfJrMVeP|0lMO)tZ+TgAOkqWuo3jMcP{5}xqc}sCZDiA^r6R~A#qrGZBp^L zkm<{Vj(#ii-%$WDXK!Z*Eh;Ar^%A|iZ2no22!RD=FolFW>pE^35{skwILF64a)$9T z0cixf_bb<`?4=(sUEPW6rxt`v@Dp%h<=0X?<~T3TfYK#<4Hd_o#j3_%^&QY zjD8b%u2mt?ciVPbPpo1QFBuS;MQx>ef550A`i^rcpFKu@D`xJ2Dlv!`$i2ud{7K1} zGqOr!yvne%Yj%omkj&ws91DnplTS)=2Zx+Vsq4NhU#%YT9XZgB2O}OIi@J|MJ|&rw z-AfTeZb#T#a#AnUjF?(zkUp12-U}wmb3a(jQdQd2Abwy!c!U% zrxMJw2PNsmdgyX&Jtx@~idi=Z7(45%A57jvL#rMe{z^k~bT)sEKOB5H-5Y~wJiZ0` zE>Fku1Q->FJMCPKKK>gi+2+)bLm07Aw)S9XRV`(%3Z|f|Pp0~VpR+1q3*z`8{;kMf zi;))oT^sx#uo9{`yb+vFAR?R#Fh9~70=1VVPneY+9vwWpTj6BJ*cMEp5a#X?=$VhO z&+vF{de0g?<9(j;i|>2Y#@j7pqli(?ScC;HK~An{yHr+|z4OyvTZuhYas}RM!GbZN zVGZeF98yDh4r%QB?;UG_db9hf@MfKRzDrQcQxdwskNt)E1ku+4Y^|L-j&D#;hgaB0ox)bk(ZM-jgMRotocv@W&>(g@g`%tbeYLuXP6 zo<8XtpWXUwbiylNqqfp-kRpbCH;{Oux#Cn;2D?!fCYnt&C2%7DkTRfDk$Y(`I5ptf zohKnX6qXIyH4X)1h~NMfKEO|Kej4p;Cq6^5>VuU>G%As|$`)TZ5)9}yh;|#}sHJ6A zos77{*l1G+R*e%}hYpPSQn2wF?sF2}-!HNsKr(qv{YstQ%#R}Z*vze+yT8XPFI8_9 zTDI87=vFQ14lUeM*>pvdM8?YXF3Ct)6okKy;n3Y65+cln^Y@87)HqWa^7NKBmkb;} zvl%mf$zNwu%+u1Ik1D`5Pt=f^fQ}E#BEx)SeQF zm~zm9?>e8g6mrT3_3N3vJch?4iO9h{?=h(tng8|`=Y|h; zSAXqcb%D*NAmN@nkyk6;e@q`ot4!iHScXdQGEqi zo}~FhrYaWb)j>Nl#LXUjcB6r}bEs3WC~f3ZNr|TnghGrd@poCFt*aHd7c*vaubChT z+?n>7x{-Fmh=u_slDW;`*tws2=1!7Ep3u3)O8iU!Eh^Sk*!>A|zilN~Pa}mnA=7`` zMA*CC`;5xz-ZFSTd4VM?g>1hs607z`cR8-uietgxTJshW@NVhayBrV=4Fw?kD(Qe7 z>D*6BE3VK9<6ei6FPw4=Qp%&Cc`4*>byC^%i0s9**Qq<(1d9r~U1pwmC{b^Ex#rpS zPtFfOP(hM4>W6N7ekE%8M4RXu<5j~+SwCrM*4bSH?#ouP!#c&~KpurmrPI@=o&5_X z7IljiOEk_mxG)nhtKd_D9WQ~>XL+h}oYkB9-;%g)M^SC3+q*ln>;yfL2DwDN&?|Hn za8|{bTK*Q6%4bxeJUG-L*-Ht#>kK^2yRS~l+*T->%@espr4$+p zls}ouhdkDcrK!fO`%`*sc)`_J0xaCBiudclvGyy!-Q3olghk`#PJ0EJ7$caTN&W2* zbrc5up7yknPFVe?oIc?lq+6r5$IztP9cBDhrgkxp$=X$zo#wncu?o|P|J)$0^ zjI!VXmcZ=CE_rhFnrPIrZu`a!tB~iFpq!YK-s_)Y?%!dF3e4XSTgC^fsCq&*WliX7 z87v(DKO;@)A-l>4SpKhx{53SmYw2xtp@{LLUV5U^7XT} z&?)VEG%0YvLg`q|y2p9USDe?T2VJb^JW#O+`M?Tpt@^TuhV=j%Ud2~aRREW#&7Vf6Sn;qSxMB|~BK!Li2a{)vSJmm7x0xY`T!^I==e ze#P-b(ic&HV~@d$>(S-mGyb5fnt8_SN}z}UQ5HXM{wePDG!5C%X*n>0bhDHfq#SuJ z5If^kaHo_dXF<8kg9>~s-b`eYb5~P{jw-vtIeD{8vddY<3EmxNP$8iGiS`{(nb2Q$ z>2FR^?Wp{EpOZ6lIMF2b1=XXTy}wK;tzOZ#=B(Xp-BIinUnGf|`&K`R{RhPOWd<&0 zvtHHt!=Gt!e|QIk7%#pGlaRjsPw-kGS`LIkER27SGWAlyVsQT+b1@3t7}n!Xe9d@C z$vP6r^wwHZBaq=d|RGR^BE zD%WiT0jY7DA|=x??f%WAACy@nt8tofXX}o(4q|~-vr>o}BYl;JM`<^Kz6`Pw7{JxG zXa&a~#c~A)`rgk^`z6iY3E>N3X_i`HuB72buX+B_davHeFwsF(zY*_S=e3(eN%lhX z)r;RMIHAZ1aI70{F2MPeZi#CchRMx+>a=vBHg-0&2#=HKVn;nePQkaFa%cc@AMxGUOuOr`Mzq?vO@s+d}<)? zJSQVp34*oV^jwoh5y6U$og($!`GHUXOYTqxZx%9ewsE!!Z-K#wF4OJ@pM zGzyhr7mFMTRglBlf@D8#u+^U&ho@heB1iWWUNe@Xbf0a-|o-aj~ zfA5g6rL5qY^}+u)FG7zD6EprFE0YxVj^9=|CiWkL1V506j)|6oll_o^frp!ek(Q5p zetLnPk(LpbAE9Mr1@bb|)6mi~^000F=UcSAtURy}Ie}MOGg9D60}dWg%hod}ZibJm zJaj*8vyk8LFRSfh*9KMc9@?2Y z6UbC<2z?5pP<6l|1r7g<2ZHvxn#GK7;L;aZKuL<-4@J2{*+o08L zh?sZ;M{?>Fbj=`(n7C$}^=ALCslLqiZr)YjJBwiY5R)DbFovU(YK}ln(HHOaTG4mt z{ndrFdWfNDYiN%@8`G})E|rP#U$+=V;}{3V?ttVu6na@)rhG{Z^VoM(mT&)C8?hW0 zC7GM<$iTU2b;$Abp1&(+3`*KtidqmfPBkq7tH;H~$xf}eJ=(!`C7EUPAcu?By;&6i zvYzQZX`@ViiS^l9xz)P-ebO2M^w6pVEKRShL`Q3zX_1SWftmbCN}0HfQNI7>-%VR7 z`1C>u7iRdS+oU-CQi&nYR;4j#xRJY? z@WGA}j@6pjS(AM7r@l-$*xIijmId7mC%Klz(P+HK&Ksv$G`NvEwNFAXU8m^~o>IYr17UN0i%`3mNMQMUx+{(6JBMct7b6 zWh{%yx0(B)sQeKlTngoTmhj!(45V}T@2SzM!l?I+23;Jlhd-=?PyhkIl2NszL#XPs^iXG84#Ti9jKTeNg(ZAk(+(ay(y?02LJ z6$`qV!2NTvTWJ=MDl2F_LRq0l8n1?SDut-)VfT)J)>;e`1cRDcF&Sn80T=W#*DYT` zzm`_T-sb0lSyY?kZ1*JVH~(B-xRzi4xwNn6#clU6bl6!el&JzW(P&Z`WAdMmqgFzP zQ<6f%=(0}a=#$t(o$*F4Dwo?a6o{)QV-=m~U{RR>|IGzRUegY1WUG)^$jM1| z&e>jZO0p_!twe6>4ha7D%E`0b_dBti#}srk;+O}%1yE-(%I>XaRAHD`TaA&HOkH>rZ)fN9fu@2G|&sECMoKLE4k0ouQ-nw<&_nB#}Fr(HkhY3ol#{1u(dr0->*zH8IXqYA0$ zX|d3H=cP+}-kXd5Y5j4K{*%J7d~udqNfx%ef`+EYv^8};UO|PTH$Li9A6h*r+n!G_ z&6yAmBN!zcF%_g4jPw`&gV5V}85%(4y`u213+o6?jI(lSy!nj78@*9dB+!bmaHQ4Y zTabV3&d}C&*A_00I-qE|Rq03Vo{|6hPl1f<=|Oo;l3dGfk~Oa|(uNs6@+e~H5+XQI z34iP^&|0-(!RTo$g^caNQ zAm932c6q3>MXhNmDcN>bW;onUbQy1cXs*d9&h6O)l~|GM6HD`)~+ zLL%aVaJT-wHuhw;tEYONEYFg5X=cKJDZt(9l-zB)&eQy()MX?%02m)m85hlC2Fif- zttN95l8#z!AbVR3_-pO|&yYt(_?F)V6$xA=!vn_o>`1QFvUy!(%#YN#R>8&LBPc5FaKB|I85FL5JDxEe< z60U8gl~y)aQhOEei-^C-+pj2iMb!^*v+C|E@8fODW#0{*so8L!wfd%^aMGi)zAy7>){YtDx@Bp9eY{sh%#gET!^Q<>O&YBN{Ef@khPe5`6~ zq{O#n+rlt10zpw#-0?aD{sGpTla%ylXV-`#P>Z-&^#?k6;nZejMrs%SR@by8B5a+i z{Ml{+DczW!2pa<%BH-$ty^L)k+L^3R`ckVnUW<`E?j+X4{Aa{0zoqBfMfDs z^2WHO$0JJ;H`heEN@~>GovQw|tWMr`ysj2q`HtFYH>`0s5`CKZ>P<_i2o5MaF8>AH zR3S%b4`JxKzW#q7n(@^81i(|MLQ18x zg}Xm2HJ|af!(Z&Y_%)t&%6-^W`)ka$BpW(0{iRAMjs}*WC%mBrDevVhV~NblP5C>N zu;q{-vu3GkPWxA#`T6gYjJsuW!2WnBHVa4|8;$kql$9kxB<;(ZOrCUWrj%9-CX@SK z)}tsWFkaB8MFeIeR7KFwg=)uib?X~`U{d0^pDkg{tX3jE$SfhRq#KJ9y z^`@7F2%?_-H4g9j0oJu^49&kt^hC2z!4p;{+$%?I+elN+!{o)U-+Jyf6q*%fYjLdi zRH6bmUM^3o!dwakF|b_U-DJ5fpiW>(DM`!YCQIS3K|q3v%NePzzT3Z?Y(QYL|JgQK zj7^CnV5|u627NP*jE9qw?G0fZyKGxJDaNUqGF31h;&(`YfPxIG)cBd}ow!lCZuBw5BfuO?V9Ny{N+$(H1$;!%=EoNHXaQ4=WJ@UvMxpuxSnjse{t+n4?huG5L)|BQ& z%~iF7Y6*#@>ZsX#Y$|o=t0kxZ$dr%9lQ9d^k0%)ePc;HJg&_U6nf0xvn4iXuap{k6 z7OJ1m{LogmyB2e85b)Li0YwpQkEA`jnxZyFqY2JLGBPS=?eAQnM)Ma>jVzcjdXou^ z-gJKISg6LJ3x*Q92#NZ0X#?#Z?*QpT@ejSNl36Gk$~NtG63osNX~m;e`qtWw{>QH= zO>yVM;iiLC;rv8nI3fj?+m*g(G`_{j@%%fIIOKUOrkz-_e;Ne*#Q~FGfA|f zf!u3Fhd-KR(RA55ump|`4iv{XS;#4tsNet!AmmKC+L_sO6(mq^OF zbvLG^GcKJko2mwQ(}SM7Y6u0j(=uG;xJS9NKKHc6o8GYKq0(Z14JN@t_DN92H=*?U z8GL$hc@gJsg6WY{My~BFcg?wQqwzSG z&QEvc6(8w!8ds=~{s)58@R6(PrWL;Eo)c}%QyNu+N0>Bb$Tn!D-SbGMv(nlAs=%n_ zyeAW-srZvbcC?UI4%y4EkwQ;XR#|6JLbdGXv|%GM_$-Y;pnroUs= zosQQr)H|F$TWX$z5;=;yhX--g-GMBNlhV?3-&R*L6~T!?IQp!i;lwg_XlW5u)@US? z4XyPXl_z}A?9Q&+jE|YPOQJ58j&t%XBpz*nRi%o^Z)mre5>}XqBwb6^Hy^ngZTSEA zQJSr)fzl^OSE0V$S~wogvPO$m@y0=ceBM~b>p3}uV-JHh(Zv~HBQLRErx`Wrj&^(& z@DT^XSz;Qtb-_9sV2MN^H}_urUFO_;48LFZos!u1~^q|{;5g>E=h76_68g`0!Lb3ax85$8zchF(5EC=m*y z<=#j2YLu$_^yH!}%(6Xlw*M3rdiU@VNtG(U82`urcWT)DPtqWRNgA@hP25>0=g-(# z_SRM}V7;RZ>>P}Ay!`x}uw)1=9RocF=OLfK5d#w)pTHJ9kOMNY^|bKq+i(HAPq7M! zu@64@G?Lt;62PP)kQER8vTf#pO++{~H% zdk4fLg4sSwmh z|Kn@K>1QY9bzTO^pA|DJaWjOLIctNc5dx+4o6PiDN=A9SmmGH5=G^66*Rus4eu1t{ z0}npYiP2#PbB7x7yJXzlF%3B&>Az!}Zh9{Advcfz2r@P&8f*rW4Vs^(&4iK{4Jcc` zQ2w5@Drr#IY=CoX0T|!sd-Q<1+qaV;;+bd}*{D;=X1-aaTs_58UO%_$bx$n1915TG z4%jCe&b;5Pa#u-oOTDDxV6)J|M_@=9;1N#eF?470St^5+ zpB3vq0x!Q%7#p7*UtgVBl4=DBYxTsoWSt9>zvsu5lm~^2K0?EVH}*OsCP->*Uv`h% zHhysuh`n-`%QEM&K2}38IhtQ{?gD9|lCJ*`QD+&|RvT?=ym)ah))1t)yIX+ZuEpK0 zI4$n(R@~j47Wd)~#T|+}x%uw7cbxno83Xu{v6H>tx#oPPpI|ha^K3uy=_)34dbsnt zv2qO%PQbDiMW-g9t@fQI9~bxCXQ0g+6hG0y%8<$#2vjWIw+gnee}59~5wZXzx)iq^ zK6L2@DKw8ZX+3HGo|-p2|MJm5i_}bO`YFb~wOO+=AtQtJKxWABg+Ap(E=}*g>yW*n z)l}kZlB7%Gs+$y*w7WkXBNGzCv1ceudoh$jzi~UC-A2n7i5?kIa$fr-$3&BG&4z~) zq^{AZF#mPlJXJ!qKYi8Z6*7khW2W}=f)jCh^J?xh`y5uo3Zyt*m&D6^fN$HQv^mVD zXd$N3h{rYSt@9a7?hQhOfxm`<_f1g=r`IL`_T9XVjW5WTln&7yOh1$n3gKI$iJ{27 zL(-b!I_nrGIh*a-b1O`C&Ex;PMFJW!yHr`FrXu#KJ$u%3{G!i!Bf}-!JdaoFr!9oK z)!X}sJaB050^a6VE0-W2>U%ft!K#_E9^BPRq9exHQ5ERBX)TB3@RMlclT>23zK^AU zQ%j!IWX@!DNhr{|6^u{*b!wRib2x{%5^%&rfRC*hDI-5aS#0VC-mYK5q!iQiEmJ@5 zdtcIQ*EZU{&ToA<2UJ!*4mK_~XTtD9Kym8J^6GBlZ`34O}{&|AR#D2?Q?J zz%HvMxJ6t@BS#nW4X4+%WWO6!)x2r#B|%X6y#>rauOlIb}+U&~U}0P&h|qy8W6p z%3o%Gw;kvpX_I}+(?vN8)zTFXh)nK9%0Q-=%W{HY_)4h^Q|FIFfk@WF5R(YM2mkwP z2n+rR;)k)R0hm0~wI4Wi*mMRb3FJ+AI9-Cm~k)haiH!1!sO6+CEMgusH0TQIdaH%)2$oJ+$hqs zy|vKLJ};y^%g*sv1RXeIuX_$*IsM}TL`_Flg+k(vd^FMEwO$Z#i_I%gS;YtW!KruG zZm^N--n1BKcp1OKap#q}S`y!32#y7Q8X#t-|Z&Qe(}gMc}kDvqi?0pz=}s(MCNP!dVRGN=kghybeLHv*VIkZ%i_2$z2Y|tiHeN+I3c8Z z_(gx&MRRnf$>>kXWTN{u>R~`iNGlGa{5hbr!Y2>K#9r)c?d!hFi`x6ERuWIKyZ-z7 zLJuhGIIG6Wd;q^;AfpLi#8!OMqvxT*Y%6!tqFdwl; z#|T^NML<>ggLH?_sziyYk;$-L%ca%1jXWJ)=ottEO-x`BRqH0L^hmDWFdZhQ>o>)u7 zVnCbxjD_Ucvn>M=P;*X=jpMr_1uuoJmIqQkML1DRZ991v-DoqL6Ac-M*T0K+Mm?y= z69xRtXKjslO&XpC`Qt zEup=LFsDtycv~QILO%{FlS6ZIEnQEGxKeNhc)HYwuXT0dH)TUn@8OD&QpTMYld}ud zk{mdHhu~e+f}>G8PFq6KnQxF=p6!doVssPL@GzPcCI)rP15_syL+kX&<5qv3JiC#q zGioX-Y`)u_xrZ!IY#B~mMFg9`DnK=X1!%AdQ&Lt#1XDNj7?*RhnN1@W^Y)lphcJ>B zSI-p%OF#NSz@J9d7}`(1xibHy`4r%9PD|Tftr%MqtSu3GHtIGXU~Re=WSX zp5@~*j~OfhC(GHm2wPNrzSZtml|oS?FN7a}uLvk$S0)G}D(R-4_A;m@j`LH^JH zFLRvHW9DLUE2l4bWvao91>I|WRcj6=Sp0Y^o=<6+gSY2x4rVmxj8lKe#9I|9S|N4d zk$2d986ymxo78`Qsg(o?xhkn+UBj1oAALf>d3km)GIdKfTRL|!uody1kt-Pe(K2h& z>(O~l=>68Cr3<4Fxfd@gNb zD+ZD?9)&=?z*z@CUq}G0=iDf`^+Uwv&FjWrW$RvWv){2`MzvAirHpB_6aUa;PFRf; zhgH~${XxEq=%22i)*q=R54$Q%m_l-(eHvySa}M?tR%Gp%*t}=qvrteh1nTQ_R!C$m8j0nsxri-uWv$Wk ziV0Sl5#GkzLX?5TTJXsF)WylX=*CL{u^I)EpTAZ8gBO(X_)d$$+V-%dN^C59a+YEl zd>r;zp>x|JuQ=-~Vcup6$T=rVG$u>@lBnP^cz^CN7Ma6EFDc_OMqkeJbxw!qCw>ms ztUM##Nt@%A+a3qsx<>nop|(|7Y&)MofW@I>?uIZQEqJzQ@e0kX9G<;{W>gmUDuYPE zy5wcvrHHoa?Lgd?bMfDc*U`T3G|9ouQP?&$W?X1cwB6`PwuhPg4;yvgR48Y=Fjhh@ z&6}hvxcE}7*Y?GRZY9ftQ5V@-60k61d{HmJ6k&`hXe%#9MHq?anhEbN5gt+h&+$9; z$Rr-9QOQ+z1#^&9vOJbW_l9snkNVYp7O-kEPN*JH;PJx2(~oD;{53m&@4zi`_Bwn# zxu@nUz1cC}g~7YjW*4hA4wz|AXu&mo{S3j;@p5haf;Dg0@NBj`xmL6#8-6#}jqK3l zx5FXq1Px6k83IpWIWE-v5>$#J)+VEMpZSoi0m&>L&H2;tEUPAyth1JCkWw4Dk z0rj)fNzMhcdFccY6^tvyZ!QWs7_|?R)IMNbKu*Zh z$5t?Tj$Bi7e;(Uf3XU49&c;xz<@=)>AOW^G*PKGfy1V!8+WO+QC2ue97+M0`^Nmt- zGNZTi1P7(5lSb=ANlhNsE}%GP?MjE-$FMl=DFJgr21(Et_w33b2g>sKSm`i5FeRDCc+nF?F=B1rwgRObnY$T@$QeAeJ@Y!h3*4}?uIxsH!YMU z>Pd0?2g+G(Cr&Vk^)D`fd~(w_YKNdPVOv@@wtAFmxrPPl6hOd<3HjlI;f!>ug#?53 ziH*CIi}J3ou`IhYhO?w}=45|XhF>8i{SdjO(Sijb(Nq~^?h{AG-I!(Pfxfd$7;w)M_JP&qvube%ThJGFnNZb;Upp?HLYALcA*VCw=SRVaE`QE2h zN_kRdY~I%}0=!fMQ4{|=@K>e&g)kb)g&s@yhK@MXJ`Haf%JTwtUw?g8!Hz)JDA(v zVPj{bW#wZ2%*wVmJip1{j`<@Q&FU|OA8PbZuMariVs**M>FMYd-+Nh7rO{1A?>$OE z0)yfmJGbylTFR%px6Dx{mF=GP<~vjGzY32fHx9FoV>;cklrWoM`G!-kWlhQ(fJ6ZW zj}_u3W&)sCb(Oe*{q;H}zLrhp_!z(_8+I!`pcPSqk2c!cMw%ph`CqHf52K+SiiBlX zJALNZ4aFhg=#{=(m#h%*UM0q6x|LIBC?H060zIImdaZFkLzYn~GVdQcn8N)J#ja)~ z+jSdRytXkSpfVdl*$YO<5Y>Gi?lBPFkT%&EQQWr=X}Vh+rzP3VP1Qg4)zJ|j7Q?hc z?$C1W4eFQ9XB%co*Zr-E`d^N%yy_Swr}%oo)vp zt8VCl>d#7tY#5%^2(7xGdnU&3ll3{-3^^e?zr`E%Fh9tdzPd^9jHx*v-B%(GCW0%0t^QoK(?~ zYR+x+00!Y+@zsJ zyuZ5lA~0Q)di_VZl+`bDs+ainsq#@>PC0p_Up=cs9(~E+kQ9_)-fj_)w@Q@8iDb2P z=Gt{wY-EM5zwFI)%>I26FrQ78nh%8KgxVfdlIgDDiPT*&^;e(7W@DU-xn;AMm^$3; zY>H>)Qy%b18~HQgC6!QD)sorY?K96MEGmA682S`_F1lJ#!Yv*9$X-o+4x$ zjui!rxU;(5&L3$VzVHk8z)EV!H_E7>nO`2=`4q<|O`VWi>#gF;;`0auJy||99~S$5ZLX~PCop;TIeaRuX`b~BFzr!( ze_5DUU*7mMxV~fC2qj+1iryhGY+NcH_&{TjGP-D7M;@vFCi$$ESyqBnA6Xz#jdaLR z=Y|WE(s?d?y3<31W8R!dV@o!^a%aJ4Y$qpAQ^eh9!$mX;ZIz+Zod>M85$3fq${6!3 z^u{uZBx`*xXQn1VT`4$gaOVifZ3Mz&GJ^1aPh+EY3*ED6Ag!pfM%gsi2uSh>^#ZLk z1t&I2Vo2}2)%hbQE(#&*_0PpPFq|^*@JVK+7?&q+Z_6PFiW0URiiAqj=t1ohOIZjt zO*Q^=t_i|47Z&|V$E?0p@05H)3pgW5WuNO}Zg(y{Coga5OvVXv_8C=!>xW_+ z-h}_Y>c`O&(guCEXn(5`;laM&xa&!~+#jZ4#el*x`;Sm4*CFLz$;2pCnP9I4=4Dfn zQ$U5RT$C`6E&crmI5Ajtl|bD8Ll68U(h^I#{DGudYd%Dww)p^B&idvGMOj4 zStd(BfN8-)J}m?HnDYc@{>z&iwmLk<1n4M|zE*}p=jZq!8QRC%s3URFmFHJuvFS|Y zz!-A!z&WWZZAj4XEtAYb>eftMd}Fp{qRxwA5Eapa-f zWI}8I44Ho?y*r^hd|10{=zcv$6$A@5l!D;)6sv`b#1wQ-#!G&3HThLrmvw5&9{9P0 zZ>Jco+PMPvFW4t_j%V4<^X_O%fy4^(Lc9euGAkZM#5o(l;mW}d1_MWdWIK}y(zxZ2ed5IsO-CC^K~}Tg_y2Mqv;{d z7{33TJGc!-u%LbZ=9ev{2VpzwFq)=8Zko{5Li2k-5jq7ZILc#%n@ zW8h8pmhKI9U*0x@)F`}xYB%;N1#Ma@mrpJS8X_d+Gz-x!3=|3~=ewx~axiwn7Utqf zZvjT50saZOJhW59jKkAw2UIvJb=GEH&}STSzo(@s zyp2V5Hi+nt08!a(zoIWO}8lu%Mv_6#WbGzW2n~(p9B+nkw zC&~*!h4+8vBoZGQK!R>lK2T}%BlTS_i>nk-{b2+xi*)Bwco?-ecSQC3^&bUEXNd88 zT`h{2t`&_d)z@WMCeGN|?aWTem_i?EIXPtPR&iH6?#%=5j=2lg)F5qfE1wBPs~yz# zRqj{=?*X>iqQs&hkK~@`TJ0&R-`9G5f>aeRV-)a z-3=ZUO5^#B|9E4z!32&+B9jaU5cMjx1~2H6o<$N-z=4OE7@OzSP(P*2gr%kwaUxeH zZB4RTOPlblH%G}ued_5#7R9TBeWk%85Z3Uy2oJtqR9?9)PYIP$84V`nFg;XU?pM+a z#Iskx_{#qJ+2E3fg8#*AnS9FW>gFt0)#FFm$S2>C_v`g7OoMwG>sYRozu9aFa%#VJ z7pSujL{%wc3Mm(C2)gkVRx4h+CjzouKYQu8Gis_E$*P_eGY{|y8;LOv5>&v$s*C0T zH9TxtSe_eNyiF5MSY%J|F-#ptuOe0$AbANKgNTeO@~5`&6auHn&KeNNcv+%Wou)$D zfV@51Y9{t#2Uj?(u$GzxBPG2tqxpw#R&Wz+uZDVPkQzKsuxc)D(5`M65ZPm}3>KR=UU=|K zsO$RV&6g)AH5#TxRVXQwB~E&%aobu+nH5wFWi2`+*!*wVB&twSftk*(f{=rkuGLk$G`++^1nPgtm-K{ z8RY@ea6anm*2P}vG``OogNx3^%ZR4rZg?r5bdcna{#djVz%#%6qA9MxgIOd-OoaFS zKyu*7feL^fz`#>jnr?3=!+(%TayjxcO72b-Qe~7>$_kT-yrs@!9U^z!|J|{;58+5x zY?)8^GN<%?PuJ^fYN3vV_3TEPN16c*@eVIPkD+A!Z=JO4Gl>@`gl#MqDd2RtN2aMV zn9HTiB~wdinV}lo78yGj?@ClqS{PIoF4fK8G^?%`aA4~{YB(LBH=#=jpV_i<=3j7%aexDvUJ|H!3U`_E2%mFWbTc0t0ueO zYczNP)|tFya=z$49s<04VsJiq_sC2(PqRh7rJXTL5_iP|CJKeXzTd~PI<%0^ZI=ct-%DQJx`_ekpJ*W zo*$Hkf%(U3l=!8mGFEORQL&hh1XW`DAW-r=tyoiwhsY;Fcydnw2Z2#WaAhXR>P8XI zOIvJvC|Q3+mG*cRP0AKODiN?S?pX7_L?bp#-|FxbuwcJ^2@Ufbh5<)Y@8RdA3*wN< z2s3eQb80-Sm?9iBYU3wvZIk9TZ^+!U{oX4Z6KQ%=dC(Rd-F2WDG^eHkp*Pqc=$FO8 zA1yJPe}2Zdb0~Gyo(rzL@G;z=w%vTUEsVHMX|B2XkAJS%gqORlKv8$HH7aqsGmi$Kd^Et2f|8TdJe<{)xAw z)uPkPe=Ev6FijtOx5uy~LsD31>QQnHMPg6(tDAz| zQ!d5w*?G`9P|V@rN`k6_9C610KdFH62z`e>%VEN2t4B`eR*N4SbB~?mK<~K6VuB;mNF6=V-H(KJA z?TWAtADeLI>h%T(ZK(?q{Ry!7ms7CPEK1QjRW%}w`y-0KXAa{^GELWyw^P#2MlL!n zV86>p;@N-baWy`iD7%~GkTBLTW9)_CFM3IAL$-L0*;;DQH|F2rbxhQ_Y}P%U`Sic% z80^3Fa+@rh+ZG}aX^UD%OJFT5N+`*;)B$00y}9s$5!?>;bR$fj2Yv5}(8x!F+xoXlL&#x(oVmW&1qx@^ zXz*v=KcA9Hc;oE2Y7${`OYT1P@Vg_y@4zBGD&`M~*7>tqC4Y;Z{7e^vn(zkc-s|M_ z$jv>ply)vxTOlZP>v@&Tsg`~a2+f+vl{0K$VLfDasewQM8&lEG0m&NMk>Fz3~+sRtq0MHb%vbxgxk1t~*{XCL1vQh+v9(6CSQR-ka^lIW{ zi<=8l8TG_bs69_{j%%OH`(fcK80rNp=|qrc0VlmI>QQaq&i1_Fy2~`AgR_2}@fuL5 zK~B^fNEGA+59d^)RxG?%i7oQKG$JKvVp6b!>L)9_I6sj`ae`ggrQFPLiHYBV^}_ReA~@_O_1)03xeRRccNH=2c50~^X4 z-wr~8pBSbr^qHmt5#By54a1PDt#}{9;7}lwe;FOStcoCPvJ(wW0c3IPAwJ>e#s-O%n9Uj zTe|B|a8&Yh_=J!!&#q_6ZA7?s@p9n=r4ZtjLJ#)l0qjE2x{{jv8&??uEGJwcBW4!; zU3tb)#TPv;WJH2sCg@jQXxNLBZ}SI$dvLQoG?z;!{3`PF0sEZaRE0P|14oQi63TEo zj)1PK(y26Zy4`Vv!bv9ia8$mR)GMbIAnE1&vqn|$mjth`G@8Y=v6Naknx|vi#Y_eC zY7nXd&Sx$bKDUR)C7xJp89AKuu!YIDBsHg8Qkz51mi?2ew7U;F_8D1lHXbbkR*MFW zC~z`CBR}KNbnRlL8B68zsW&>XV`hLR*VzC|{oz`j^=q1T?kP9ST7NXZB1|>B2 zE~ToQI?$Fg3`>ngxZV4o^A$oQxsjIO5R^2~07|x!b?p*yRnIeRE=P)dUD=Y&&92`@ zG2GUtbKUL{aG*PDguX!>+&>>E%PSFvItPA84XGB(H6fK{c zGyN8zV6Wa!8hQ~Rw0r#(qxvY7DzXhRmGs>rC|v0Ezs{3^@04h9 zsk&HF``fWydUv~D{kHT;HvS}&s%!W)TB8p3Ca}?S6je<6YKdb|xffZSL^~OJlj+T5 zU3<&X!P=>*9@&pwt)1jEYHqyGm9$yetMZsMh%9LOO}_%GeY5bfp$qW);1iVp=ut|I zKbEH-N^!`wax_B@WRVm>m@Bjii-`d`tOD-=iN+JGf_o_{yaUkna2qt)GrDe3Yya~r zPnRLH6&1iP!JfMF6s$L1Ah+e!-ekLy;aEUES4N4+2`(Ww;;jDJk>#voL!fqOTs}v>ldx789Gc-P;l;EZAZer>~%dQ2>oqcW9kdYYTyasl3ml zeu&B)xc(i49S&9!1OqM z@KJht`^`#LQr^m}F&M_d$3E1o0m4)pa28X(xG2CwzY$x$;CM3!1l#Da6Cp{g)e~Fz z;rsY#G|1_z{Pe^}9NV-*mJ0uE!#`b77&kp1f28j|+MyH~z0N>hXZ^4mlawqkBojZPVqr+avx(wkNyNCcj>T9C#xVyT~eCvc8MNvIyqR5o*Ba5)0muV)$vrHHX4cB zGX21gvJZo_4ExtW9JUxn07h`DbcR{0o9p=xd2bd4vr>l(r>;{IUC~!dNUJ;EahOn^ znd%Zxfch4xAaiZa{j>6@_Kg4_dIikMzY7CC!$Qxwx(^3(Cq{r z!RmwP%skM9@+}x<%)7-7&z3+C{5_(KKDv!>xrEhrHUeX2&o_)aquh#9rO5pE>!LWB z#nyq8GaV9{e3lfqQujLd92;U|&ApO^NRz>Ww9P7tXSfA}dXFJ?tCs@8e`fk_Kqf6) zEYzI;Ly!!`m}lD2wM@5Z{qa%b*6Ql5@qAL=>xybP5=t;7`$dO>wVrH1RM1G8cQ-kH zuMe)Rdu1M4AvpB@()u=KAU|6YhP!I&GR?30Bn*W|#DkM0mwgts*+y7hgWV-fR)iyN zRaO|YEM*15&U8b5(>|TX*weMjIJT_TUn|c*o6G!mp}nT6+#74^2}fTgejU~`X#R;w z6L;4WtPyOm{Uf|@@E)*g9o^W^xF8~N({h3*DNm=~gaFqwGu-;KtcGNKx=_Hj2KTaJ z)rDhR&equ#Gpg%Wl?q-EBzlz?4A)y3Cv%Q$Q&_)mX|F3(g!wXP6|mpc*by_IjoP^* z6jpD)%VZ-5b|1te@Iwc=M)PJO;Jm=1R@ZTmHR;<%4zD)I*tN8|8dMimbhUu#G9CFm zvyw`dWEuOwD z6j5Idqme!`sa>R^MJBPzgy;#sEK}(^rQ2^=SEHLeBUKY05gPOgMJS|^kbKb9#0jbZ zXIbPx65E)*)p!HC83QJztHB@m#-Me$+P2;{EKcL2=)~T^2aW?=Z;Dcd<;NX5dtEz8 zd|G4OP8A}Th91fLOS3yrx=gT3B#oCsYo2AX%28<4-Kmo1{tcFOO>XDir}DESNEl1P zipdtPiq4}~KtLYP2T2*MjzeT|Pnqdx)miHXFWpRIj1T}c+G1d-rv-I+oIrrPtg*Xe zyk;Xs$IUm9JIc_WzhK5pTJn16G+T=G)mqAj!tD9iisdcfQRA>`thf9aQTrErUT5N^tzzp- z1)Ws3QN{`m)WS266^L8M$rX|!vhfV>s(-SBi*qiI9UGl8R;%0Cwe--e9MiJn%<+L`zSYnoA{d6 zJB1|V?s#Hcy2&T(2*}Ks9n0T#N?tmsF*YaV<8C#ztL{PsKA^t=Axp&9I)JsR8T&d(0PWa~WS*Zse5zwjDH z7Vn*C5Zrx)rirGD>5aP#fT)c}t%Hmm7@gH?7MVwg(>jDaiD-oykteuVnHg^e;nfnB z?)=Cl@s#m>ayUmGfdG^EZOnH$D3-cD5NWf5Qx$d41b*4j?vG+%HFR78@PXcM-g47* z&2)b51(QaBD0!AAd1m4}l-^E13LkhVbi9?vGDer|)*X_7X-A>i<sumS_B=)`p2hqX zt(cpyGBwpIcp3=fxvych)lJz2{ugaZO^-1_JMT7x(Ld~QXWn43CAZjPPV)jdujHclQ6dRBH0T3QZh<;GZpB+9BtMI^FzbE%NV5qXt{e$nrEua#+* zSM4F*MCdv-Io%vY@^8Dj-**$EFLcVUwVY)=BbgCQozHnd<{g6jf`W;TA_*44n@+?y zgHNwW30}&n^j34l?&VZHJgU#?mLJtUYozV9lx86}WG27Ude;!NAr=I`Q5F{G?;a#| zQqLl%u8*qa)hrlfQMa#Wqk&C1JRX*6x{BT!e&&n>T5|mU6*Q;9<3%G6> z*|PjaUS|nn(4byr%0p#qfw#xA5up4BR|Nqxk9jlh-JvQQ=z#unZGn^d->Q@=C7M`f zZ<^$A-6FRh#-LvNd3QsTPp&ruhzH3IhbM3Evr!)l~_sq+iNxa z_leZvUYdfBCQn?REW>1WcYjMIQi&Lt&sTj?64ml_P*`N6`Y)4a35`i&-HtOT@U}y+o6M}XP1Z>-x`jY zT<-Sw+@e+n@Qoo?5{ghM4M{<5z5f6u#9OJh$|Hix*!q*ey)4%!R|dWo z%YCFU+B7#J91@DP-QHbWBbME}G$@sdD99XTutTI*NKk!LQ*3q7!kY8Ip~~r`F3%t` zGV>s=$$&E>OX)B@|MNpD5wvp?08$HolXXuPAQRHZ&}xdTvK$yW5w6v-*Apc*Vo29$ z^xAC|MSx;v(~Hbd9Nk3T*;lKP2TR-?meMq)$^qk}OeHvm@0YS2O)F7!gvSsgFjY4nR#J`5kP}g~TMfHAvLMrS zBg=1fITT>cDCD(xnm723dv}Cd7KsrIPnJr9Vs<$fP(k!89m=gH-$RgBE?H!gJ+iR0 ztmtnS@VO&F0(#J1k3Sww|J~on?u}Uhz#304ln$qHL{&+WHh4Fae&9_iYDrxy*O`U5 z=DK8|Nh;B)-y*1QmhMt>6r!dd^aMoDk-O{D4C*pke6So{zT@F{@dqZEdFBEI#@*bB zhw|q_ZDAN?u*sBgVD3XB3h_~VCl0M?nyQ3`?O{T%0e8mjSqj%Fx_MU?VG1YQO(9z#Rxp5xO zJF0{2{0JXgPtSepu*REi9srn}@yfBl^&g#d{gtM5>0{S^r2^s>1c8m!W-pC9?NzNB z626yrIw+9{&}E75C!_JGY;4w=We~Gx<;!bnHgsfC4fh-M{#90&@0*w(h;rbO_^tN2 z{&Y<+fA#Lf+$!brUYcCPyD$%XR{=v!+WMdp@`;9uPf$KT!U6=}0%_Co0DJ|_S!B#E zn!mT{XBVkr5mzvsQ?*`XC*6`TGphPad%;3wck% z0W@0xdD7y>-M6&bHL^h*_SjuX(apQOuynnIq?FL_^xI4-)gK?|O4=*SXvUv2i^k($ zYnDg(GHgq}ctn12@hJMDlgMrQM?pSNs%e0!lSOeX9*@p?(Pg6(Dbp7fb#_)aSaT^3 zWSQ2ZWvD}(Xr93#Z$Y}X3TNw0j0gkADEeW`91jLP9A5Xt*}JE9uZ-~J=o@dc%7sN^ zlJy)nLboX5G>7ziSHVHko1%E?nY1U90Vd}C{YxfL3fqK*`ipP>acm>CG}Qy0PF{=7 z;r-3++?*~MMO;!712twiA`_K6DNpWS%j9MPN#dBM%$7YSPz^|9Nn_PDhbx*nQfi|4 z?;hySGJBgDtWCXLM$(@0x7VC)n)j+im;I&G3duJ6xcE(v7oo{nk>)RY%ldY-)h9Ja z+S%&UCEW&f0(N%;1W7_6N^yY81lKFhmn`SotKv^U{|b;L^2;C!F?zOvx{fc2^3)yKLxO2|{tg-AzP)#1+|8WhnawlcSe6DQPkSAJ6rsfu7 zjsg);{sHC~gRM%z+-E59nR}f8Nw6sNGJx%nc%w@+!|$(XQGbxOxh~P2)ms&IrYr+`h8B#Ql7iw6Oo3mV5B3^K4=AP@!NTfoUA z{I8;~)5&kFFI!)Lg9Bn6XP1D|e)>)&vKHstAVKxh`B|+6uG5eDN~$&GD1BX>1jMk~ z?&X;eb!%y>c~KW(cn{I$0n&td_(4vBN@8_1s9fy=&>Fsps#6kU@$)NEAvs0cd-t;kkwmkn6#IDPXIdES=AxC9n*?XAWr-a&9B73 zt0lMX^_-@#M^y25f0{jCl{YK!a?Y^Jcc^weJuYVy>w|@Q_2UacAFqV{*Sgp_WK(jB z#=Ck)>Uy-ex654^E$z34#WVVe5hcOMl8wRCWR)M!vCDMNJJp`!J$wc%ipHNDw<~ww zhtmp<&n2KkNKgX}J*N9>`JG%nyDoh4(R`JB<^Bgxmi77ksTg;v)$=XNQC{@pn>$vn z=%8P;ns?@sa!_e}*Cc{ymx8k2JqI~akvwiJcqcP$Rr-TU4jQC@-hi}9?_x9El)ST%+~RwvX5aiQw6PAhCYQk+;K&P z%DHEjkd54`4C0jz&X=*qgH6VyfvN3?HYT?N>>-^&AmhDqBmzc-PA8@0K@`VfqVhW1!4zuQcZ$HJdzPNVw zo=^V$f^b$PM0!W)(>1N95H0r!Uw$E6CYDSiha#iG5*qu%-cYY0?mCaiYK<%M(?jur z=o3{`6!ax)FpdosivM+@{1wIxn_hsCnJ4crho25Jke`r={jOeafjs{)^GCzpA=6iC zPned!N61OkFA&JkpD`{Ba!y)?{D0*&fZuTCTFPp=C73cd!tpvTJ61EshF`+KpN8DD zJj8QRXl1(O-1HPYG7;tZ(QmPFN`ZN=((Q2-ijq z&&NZh8S9!tM-R&=lz_~u%TnS1w~M*c*Qs;ruAcll`T?!EK%`hD5ZYuQ(=RvVm`pX#UUYO-T3fLohn}^vQ&9tDW$Of{yv~ zLEaeN+zcw}Y!=7ukjaGr0Thqm5|6MKr^iUFG*b)P zx>&QtxJJe$MPh}rhDPFJFSNW0h#lA}93al|yY=OYNpIANdqFD}YbTU{Y0-F&%mH_} z1?PYU6LxaY4%zUa>g(@Ih43b0V|%gA&(&;iscNjai}&gh0`siJGeb=aXV&(M(%r<< zj0133PNQtc(vqW2NM7SBY^7~5)p0z>de$E2wtd?;m)45ph=#I@PfbOo>9|&Kf9-|w zk5Lv8kbmC@kqv1I=lZXP9grEQ__i-HI(&|o<%hB%Xe}X?M)uQ^HCgfRE!Kq@g)>NX zw!*y95dd=BPe*9_>RBss`$+TW>M|M%gNU@uyzANA_T2q^T2QzixKI6XK2X^{i>FQX zqeii|7!{?*J{@!A>v^TSl9@07E94+Gd?!cJ(uA$CfW7Roj8%1P+*^fk4WHiVfrs!o zme{o3YN}OByDH=qy*ZhEFoeZOasNz=VbMQoAX)8ocRXLP>(pf_f{;}d7FK^(R2D2T zOgAD4q(TyeR%Iw9=4^i&))q^jU-`EN(ReYHsnq%CS?vApRphPD?|u2^WkD1+u^;}$ z^Zk{}pBNL`)}8ekgt+JTdYPcYo{xXewDe70YoqE+{F#5lz5z@+yzUZateqn<`(3F2 z9LVD;#m;BH+p?*t=d&1Dt?>hi4yTrGP7&;Y%lrtCh6vqDKb9)X}{6DM|7>`EGDbHP#1W{*E529Q6_e%LOj?}vm4*{ZQl$@StA6K$C89GvL~wE&DX?Iyy%gX&-CW55fX9vv zqS5v8!aPe!*|j)s!)M%r0{@@j5UBLOf&&#)aLBZ~!Ix&``Y$uW#=%AhZ8fE3W#T-h zrv(DpxH#xo+1MDM?WgQ4^mM%JY=UfS3(%HR8deT=PR@-Z8ZJJr|MUlXUQTFt3Acih zIH)!=xS;3!18A1(!Hd72nw=lhM&bAr7pb#LyG24^DwZlJBj%|K{QlZ3h$<*w5U7It z@Y=1JV>w+c8Ur?I34nSMS#m;Ui?TZY*z9R_nok*9STP(YT2HJS4)&&&)}up#2F7@Z zftR!jCz5>?%%<&Ck2i+B)C9Jp7=(LwO1s5oywHKFd&UOkTU(`}84RN}z3XbKD37Yq z;9BG#Bt3^?ilkaVuo)w)BuG@W2?55@@r-Deb2(K6)aKmJ`KS5+5OtP8ZGCaK4$@Mj z(Be*k;8NVBMG7GVcP*~Lr8uRyy9FukP~5FRad&TVhZgsH{_nkaUS{%znZrzy!#;bj z-&)VwH5DmG$l}3$s+YinhT_aCdGks4*Yth_CZ1^WP}v;Msd&4_{;jc3xv=9a>EDXW zl`$dUkWG;c&w*y#_Fd6!x?!c`IY-4hUjD0{TNEi+TR>6RspH`}FDXr~>W}mIIkzF} zm^tKG{o@l@GjUxBRbIVMxD9tnhD;y6D3yrGC11?orWwZIfGS z(t1jFFT0wQ)8mYiyl0+FbZgH7t8>;; z*2xu6ADyJi3jO&?EBOo0Nj90AuBTpcwN(~QXM2%~Ud{&QnPwWrV2$5VtU0!>SK57@ z*5dXMCO{-hwLnK{ohwi*oY*z5V31d-M+|;^tawi`;-l;OzOHmdOM&u@JoJ@b9e!_< zJFh4ge!8vgs!hUvd5I#Me&bXySaMVB+>Qvc6sd2{<(*_s;u3|f29tHPmOw1~Rt`=4 z5Kpa4#&rqHdYMF{P92gzcAV8g%Dr2Y*62r+LMutLE~4DE6_1MA=I5j5X2he!p_np} z+b7X3rFN8{d*L?E)_wX{}9jg+r50Ku_gS6q(UMMLNQ1C{K%gZX*BdB?}I;b zR(4HF)z(7sTK&A1;dV(wu{mUDL|#{=II-~N`Mj(--dyZkp!tljyuxri){B#QXEtrO zposXR$-zJ0f>-B8Y+V+%Zr>=tLl_QRR9@jia4kxRtj+5UVnQZD2R@gq^#zpD(gbqf z@&&+>^oZUb7!qUC+H~*Ywv^-}tb@Ub6XqOWWljmd4Ij?^aKUW4xulOrEI$-ZtJB8T z`u9_o3sTjc4>blJ%`Xj7I@c&Y|2|%Yvc&yUEs@9x?{73reOWWC;r*)F&6#*0po@Gb zV=Q38n7T*=I*-l{&HT`IYG61DM=EQOK0e|GswQj+(*=&(4d$bQ))7@YppXAG1kjG- zil1F+k#UstQHb{WFt$Q?+j1?PzHbfP?e(?7luMlX{=z8d2t3XwDyD<|C zYqv54$BTq{{I05nC}y6F96?yhrOc45d`Gxgn5l+^UHYjsap}e<%F9hf=6^&nlw~pa zmS{dmA`p;+3o4e~9U2ME!uNud^Aa6G1A%FCpH`2ZclWNYx}tVkqZW2yI&8|=ytPcJf^<=a@K!&>tz+w*}vI4U>P)Dwb9wP z4YX(ChUONThdo|etcT>ml&eXqU)PHGG1wF|r%VfZe`>e=TStKj0RfG3zh^FH&N{?1 zhH_RsNo`ekR*zu08A9aTyqj5Xc~6Z`(fovhbSu63TNb^^a6}+j{tRL04z-VJ-``Os zOqg(nqc-M>Hm5QlhiOpDqzq1RLbq$Z1PIG+d|@Nw<)nIw0(qYC78p1A$P z3jLhz_C%%FX6@7n)^evvb`SjvKpUd`eeRO*+sNRsg;1ki>wxU^4_<%inniX%JM_I{ zBat_lR0M|IU4rh|F)n{BYz0fV<1k??62P~ujfJDagwp*N0;oQ^XX*wDFV!+{r z8Z;QQG`}GP*80L$zM+J2@H(l)H6mMLa-Vd)lci;P+0!Jfv~q?#UMperC-9Sq15gyM zW=zHH>|U$}0w8Yre}PydiLP;EG&JA7@x?0x+VfVio~%6=qN5S z{8c%7NL+QM*SdFM`P#~};!TS6_6C1f?*r=zhr&=^@W4nXEYOh_UksGSaDG^5uxheV zoH%>EoBwN6`k=6yB)eT{jbB>K|CE`8Nw`;>QHSTK~_tP9#^P@5YB{k@ z6E#kW?(r7Vqr^*&iym$6y03FLd4LApjiOmR-gq+Qu zZJj|8RfV=Txec+_7(uKEK8u)5^;f@Mr3(Vop%oCo??Itcv&SX25zIQ&ni6(b@R<2eJevZ4Z2}7uWHF;H7q_{968i13h!sQ z;7+Tk&37~_#o;nW_c#}!hesCE`HLHQzh)DxHqMZBrC17SxIcykZbX; z*&Fs7HZsb7_tX~sJ79Vrwn9N3iUj4d;UI4o{z_qpEch04&MHU?v?2>KG*3dtIz#T- z6(-HRY~$lCGD$4ctP!33wEi(DpM_!Z8IRihcmv$bf7~iAWF76!M_xQt@EK08Az-!9 z?fa9=L_jZgX~=ZuhQ3#d*YLN2Be*IvnA{(E=ivuRc%P)a$4h58(d z(FvQ~7I+LJIK3ciYiQn4u-0l zKiOjb{$=8*V}AvoVA!{e+s@t1^h{l?V%9A*z~tsTV_LQ*{wum>mV~P$8S-5E=R^j> zsJ7EewP3zbjxD+=?wU>{M75DXQ>|_27I+x)b#F1oZ=e9Jp!~X6ZS;P_j}bXDwDj&e z&#nV{l~?_Az#KvHU-;9tn1`7h^V739aLv1KW+i4_I7*g-JE+8Wm>GYsd`~n7epprB zM8vlwS>&8BzqO)Aq=~Sza0{&z9zS@arhCwFeB0t@{O}%k2<6oca>dv2>;1g7lY84E zk7Eyo#M;&LuRmT(kSJ#@KHm#bFu14B-kV;pRagn`{PtFV$fm|LUXQK#_W^KqeR;IBi(?(CLs+j!@muj_L3v zWM%0&UZDNGU+g=R6VxE5`1Q-Q-8b1}benSN?N>%LT_~mY_r-+gF!zOFmOpE!yI&iw zZChSCvOSfL9+gRZFc692;n?%#?TMmY|GM8YUv=^p#HOMMhT$veJP;Ref5cdN1;J*L zjfyPcu6d`UylZ>|mO9{e`m{Z=JR**Qy@VhAq$T0H189Iw6N-fX2gFO!H7ngzlmPEdNv$-`;0W(5ZOP06>O56?WA_p(sx9XZAl|$CS4h? ztuW=4^}d-h*`2Ksd0EP;sKfH;-SHtyXYf%28maix^*P;C7=RmM1)5-$6KIW}OT5ix zjg&^+;zehx^HWa>*bIoc8joC+WoE5LH?T?NRmm-RUVu9GZv!)w)eI}s$sOI*aC7L! zT4FSBhDPr1!~@YnfJqSJhiOzbc&ANK`BLNG{ozgBcFQ3?8&Yfh;mW&&G?H1)9=8q9 zgM9f*eAra5IOs>dxF=2|mU@VqEc4DmYSa$dl;B~Rink4c$1FPj3s#sm2%_SDjFO5@ ze$R{)J;-l1AtD*EJ)2Y~gyV&KtRSI(l0gw%eO?v9hhT?Eo36;aFWTn-5G9(kB6Qh~ zY-_tvKB^}IT19H)9y+Ka zyOfZIP4!X^FY0Frm}tEG*~FR~uk(sq`27`b|5rdp@Q2NqVlGf+%S49eMqX?65c@S5 zGN|KDMBD8W@})(Hy$MDI{GopVUuGLWrJ!jjzWLysLp%>o8b+&}5x+rC`Q~(JC?u_$ zTbRuIj85?Fv7R{#H$_K^ZvqgL6}c)wS8l)eyuvU0IP6f-q9n>+?+ahu{6m)^t=UnO zCdl5y6)LMaGQJfZ@yX<>VVNEK{~I1c|5tyY0rZDc$BdE>fQlf*JNurVlamuLJpe+) zF&&*SHwPHZ0Hz1?@N#i;v4J_b`FMCZe-F=&?=b-CgeW&B9U~q6dk$`TZZ0Y4_sMfq z+qJuC0n7?sFqAL(spdLC;+ByTuBd>In)GHCT zZQ%FE6Kc!Hsd&qb$MAf*VNZ%ULpwXqW%mB~4LVogaq{8#9E{vtG~{uCrF|LF)-0*s z2>VxDT4j8TwQb%;b?aK+=8pm_#BM?6=s|a&;CwNicbxJluEC6^nx^VGE&FqvOg#U% z?BOX^w!+-eCh=fyrUWTkU}gwjqK*^-?8&lv^;_VTi@YkS_GUM788*7=6{{vKI$k0K zUf9gdZ0q)Xp=9lrDfgmfyf~}ml$!iElz1yT&}*cx$ZG}oNT50##^1LdlcXocF$xrg zUgzml!5OiWP>w^bf~~mX2S4)pKhElpE~KK1i$41KCglsO_k^wF6vk;<(}G@ts8Y^Y&J8 zI;8Y_FyW9I&0FqReJ~M0JxfLI4s)JHoK&FEV6b8=Z}u0}fv4x?$E4|k=ef>;D!035 zul*O;a+$j6Q(hXE(+Zl^Xec~bG;)1auXM0Xb520`P<3f?NDXMEsH)r;orKgibB@PB zq6P0j_pcStCmQ{<9&37GrYIg#b$vSp;P41oT&8=Gnpo&f71Lzx894RK8o&GnY_6=> zMVI5owf0*Wp(ucTPhsS6(5iZ$xu5Ix6?JNzxsNG)<7X1~bwU`%CWqSF@M?J3uHVC> zSXD?!2xIp<5g6#pIjVnqmFVM}+Q{PE!+$Q>t3tW0R+@(SR`$5JOOo!aCjI806yf(} zp48$F7*bH#japO9HJNSVib!m>x+iM`Vtfs#S8`y)4pS-EnSD`pamChddhJQrmys>In_A-WPMpo2a#3l58I91#XM<_wMn2n9P{nzXGKS7ljDkQDQu;H8SAyDWBh5-vBA zLU%`^eOnz?`U-jx#fEybMWn9G4LDV;bBgSOm9Tj24qZt^w9Azf%XGH0{+IA;M9+^U z>ec&*c`^VYE%UJpaJ(+t7E&Mo(T*4mUx~5qbKoI6UgLwOGshY0$|o}waiuhH<7^04 zKHst2;+Uy0Z6l#P_|Lt&g^77|fsVh+pLus)uNF{FYeL)k+=zyzgod*}Qf};X&7&--DjU_donkD*BOJd01pwX^dR>o3o2pGMc50vipT?!hM zV)L*B1NDkwRx5To@k>5eOY+Sp)_ET9jo#b2a*^dl$@5lSJWgfHb$PQte|gs67FRuK z#I~-kYO2%Ug_q|V$IRXKIQq5!B&lEM#nyXm@%5E2IaBp39%Y0ptFjlV7)YJv_pb^} z4ScBe@44`?=#lX^vuV$n$_ZG=*Z?u_!%QG5e8~qqx1nh6mtvwsAXuQCvKrx|MZw)- z-TE7O2uVbyoj3(NV|o5ZV>otZMsb0NO{|vf&?BjStBC+z1v3c&k9V8m8KqkEBUxro z8XO#ya#M20@5Fx%66q&qhF0VG!>+|74GDpD)mV5IPsVQ=yQWn43z#Thy&zRf$^Ky*e_02ATwJJ(iyF8eAG=B!WER}K zOd$}&ujzO!(|!Vl_RFl*{f)yg7n2e`Jv0DqHZ*OD*W~xty3+X7kkI;}&j~R?tD@LB zC(qmWPpRWM>r==Mu<#NmmY{!Fu*FQiWEN`)`cA1#WZ2z0td`-*Rl%LI%AKi74onVc z5*RVMo;Le?7~|Br`;U6NQsX41;+pqTta{b(VSCm#5g3AXwk=C~hNG0WCl_!kul@N~`sVE}-}D=JddsZsNrx>? zYnr^#UKu6dlsP0gt+@@Z&%y(hRj5NPUuPHql zjk9f&u^vqgd`;?XPXf^JA)d4`;E}(NoNfb&wbTKk?&+=Ltz8vD$1;fJi^(qap`%W( zEE~AMi8uE);p-5+(U)p4qYi75RINjYO7et9Eh|{DWe$6NPtup!Yxh@`Y*|y->Jo?woys7; z!9R`DwB|cnCb&a)+c$+~Z|ke;v7r4%X+0Bt9Ff`2EaS-7YRY*yig-mw>T_R$E5YdZ zMPTm=ABq-HEmDokx^(x{HEM0Hn^xv@b{O;WX;9OwIT zTwOQ&G}2kp`A_K@r|FF~Us4b1e#92+&ZMrM?+EsOl;eXS$<^{P9x*oK$x65ep=907 zy!0nX2$kZnzbK&trGgwpV++lk;}vo@BJVfJmJ2jC2T{J+up~f?o7ztI?lxrUsotl; zc2oNtCi?Oo_K$qmm3u=+m)6?fUQ~}!F?LKvR@?idhNQEE5P@T2&%Ol$O|M1_m4~Wt z<9m)`bPfvQd;*JQ*;sVyqSj@cdRbfFnLXiE#>&CVHE$dB#DYLzxy~p@yt@aVSDb2X z0>xZtOXW4@sJGtoCQ`7eNBC)-G0nYbF}YN*WFy0ek`cx^*rCjP}sfr zD?vz=5Y}k^Iv|SMYKFADaWFlgP#&~f#t+G}{n7RrDMVR0)<*daX}{CAa#>oxZ~`$M zUXcGe=z|vqED^K|>T(@LZs3rQ%Eh}9rwpzL%C(N%)r*-^_1!&U;6L9R=62wg*H|46 zp8U7DNinH?!VzzqK+7}R@PQ3H{w=q;xY)ruMo{oDY}ZWF^ODri-#KyK)C zf}q~laz-(yTypP1EiP#+A!h`lV(b5ok~|DZL|2s?*!y}vVC&j=hRN|D9u2h;_*G)o zBIhLyQVlWkP~<5432#4t=Nq)+RmfNnS{>wBmWJ*)7a7fewZZLo*mD$cp;Sa7*u7PY z9{oJut9J9fA=&xT)HyphbFwfw7K};HreGar+l+OP<2SMK_*TiO;+NKHvYgLS=U*#q zMGDIa#GYALUJ-(+Wxc9`NU_V@AI+ibrU~_^8L0&(Nlom0R6$= zMpiX<>(lSQK;%#}z(*9+%vOG*CA!ddbtONhke|r^rcf}wy^~u9%R}dAS zM-jhkCk)Hu(1Yt;EiAH~kLvPjo+j>-+ng2iQ;!M()o=z6V5xJd8O5`1@vG2hClM$+ z9Oq`B9cynOk$JGjHezfP*c!hQYXUe^pDmJ5>8s`*({SH-rJV{dMiP=Mm+3Pe8SDJ3 z*37P8u{Ve;(OwocRJUh4WtLZN_%j1$7ijzE$V(eyX*Jz3jn`8flcqpsBGjO!uSY#U zC;BPaQito5VJaes3Z$p{*@RD8sqMUcm!2WJw|lh%0#Ppp4Q-MIRZ4#fXy!b ztZ0z^0m%t>Ycn3{oF7~3J*;4Ow1LbGo!?_7TI|_&RzRd_OeA~OkD*d0Q+)CN!85!5 zS8<>P6bEDyH(n`TIxqtrCm+uyBQ2PYj_ZG-6^x8rT&GKPOpNrj40QZl{{<_!c!YVm znSkG~4{ici&@(b|337w!06YZ;*Sh>DsE5ufz}3%CMl(eIg?Y~HIVB9eah^^3ec8F= zL7G-V@JKWPH;nc~Si5p9not~<4#KRaNbYjk8+F?v>$!B2^9a6G>YQS|k+ zjWu&&;tc_YJ;c*yOm@vnB@|khH~nQh-b|0|q^>fL;x}vIMfy=04LwL;h^O@+Ze~~J zldUN`zBbc?FS9iz2P*h=|AV&Bq%74#0u>>S#L9zk^>5Tc4)nuMJ2P;Z(&v zM+KFk+y7-jD>PFrTiD(Oz{*t?gZtEZtc^ z)M~5L!%g$QL>v$Ug1uTIsucVVl0)G3ch)8|@ULTf)q6@fu5^$!OzM5f(;2UJe0~Cg zo2e!Nkuammd6eM{9BC~-U-aI8G4TobEK9FjbCVlES+mHxYl3L8SLR35*<(|rH=B-8 zmsttBSt3?T=6&S^{xzGD{z0JtHK`egzS;x%XFpOeOO7$~&n%DT`To68b2go%_muGD zll&QLDU`VNB%Yacb6Ua%pouJC6`a~6`*$6DR?`=CX!I2$UfLh$T-P0JbwwDW(y(n- zdvYwtT3r(UIT|Zv@&!qXU5aT6!anrl>N*SOI+bpj+1M3|XwB5(n5&Yr*<@JQT->rQ znI?7JY5lyaQV17_s@%O7eh?#mbhS01s`1FVjYD9rm}^j`-3Tw)T6QA4AE7`85dTd;3tNLy*{5946ioVY`?N)H) zKDY07`rQFOwi>ka8`J*v53733!EW<$`Jm%^4FZX3EjkwK{J#*4`S*~S=gr$@!?4TU zPF{T>937;@}aW`5*@K z@cKGP@P!)eYBK?Kpwsg_XO$=@wf$2^zP78P7F9aI%-^CC3J+1Wgo-;ux9p*{GAqnr$Aa1}Ef;@)~Dyc-? zi;WXs=VP7{FZ-BAY4=aj{`oK)y4KRmtEc|`_f#FKW2#mjdBI5Ot{Jrrxq-1$dqQ-n zT%Kn5Bck~y2`)Jp=E6IguyBMT3xQL9?zUmJagvrNP>HL1+dX9_>Rdd;njFx_qkzP! z{AIHM-Pr>&OW!T7jXVe6sE9h}6`Ynx^`VXif~?$IQN)52snyI)+zp5Q8MW+uh>8}uM<#FME5 z{|2AtLlx&62N4p6&mcazAY>I_bcJ32P@r1MRPguRhwm8U*WQ|5Miej~(?n(b+d3L_ zcg$k&W*pG_-g(3tWu}sQZ`@&Hn2?>@c2Ge%VxNW2^f9VWYCv0fd=&q1bylJ>#Wb`h zjS=|M6aiZ-0t#8G#6@>Msn)7Tb9S!Oq0YzwzB-;GGpvN^iZA^`aimyY9z&3E=KQ~s zxqXF2t^LzoDk77=N~u>Php0<8?I~{Ae5QB~vn;~yvEL#VZ}7-T?q=~a-l!O}lqko7 zdQLuh2HZDm9ed`Iky9B3ptew(2w=VhwqcVqsFo|`(yavfrN{G2_5`^*hGY^^zbd!d zJ4W1;QB5p?yS=z?3XHUgVp)3r>PPRQsyhX4tdp{Yz|k8C^S$lafW|wLn}kUvU?LHP z1jYMxG>3D{6(CU#lb!PRHXMK+D~A}IS<6|(TUQuYU{aG{u_`8Z<)fR_i@OT8hv%sB zdgW178IT%;e5swOF;s7>P+!D4u>4O@`90J7^+=r3D-mK&K%uDUb=qS$9}g{i)3DmP zh$k+qLJpIEGm0D2g$~lXg#0{gi*D4(S|B)&oprwDi=Hti@X*qt2=hmh0^kh05ZjLD zCQ9zN?`FYP<2kc8;=2yvcT2Ayy@L=t*|=RutWfRHVHLvP_si8>G)()p(X56`BE3<9 znki8d=^-x91w$muzEP6N%`U|Kj>Ijj!(7Whf~Ecku>iLE+-1{-4%T#aQ=27fi>a|m z&Y7|2p4!q{avR~8nG#F^LYeyU^pA)qV$T=ysvjfinPnR=mDG+7U-G&B%3`je9?o_Y z!qt(@y!W0ZG;oW!6+j2P{KQ?1;i^Bfza*S%GrcZd^kAsIsZ3sCvN;bXW_s;bP>F|H z4}=W-e@_F%q2j(b-S75Y`?BZvf`fSAPL*xr#&*NlUbhH?mj@g#S)pIP(WB!z97>DV zNfa*`c3h}iD2Ghy&oQ507yeDtvh6euvH`|J#9eggD2|5rzCL?tFKJv6<(gSp_=+04 z97oYHz@z!J1`;Jf;i+h zU6z0H^F9Nn@!&xsriC%^G#kzm3EZPst1Ds zRl{6s)8^B&Cg#o$S-f*(Y`{GfG_IS4f$t0YtgRXM&fUpT@{#X_6J3vR!V)cQ=XB5= zGuIs*7B)V_`n7&MN8>5Wrl4?nBoBH+lPDzFETqslC11a^d6svc6*h%+?D!Zp(4029 z7SQ1(qUiI0phKHL2&Fd~Np$ZZuCK4!FPPxjMLr<{HiM2$EpYBJwa!@ua`Thq-O-L9 zlsl$^bmYm8I1dO#W)3-*AE5c`H`{jGT4t$?x!%pt_JvpEEEIAKlNNz-ev~P$UsSYq ztpZs*4OU|n(OR{A)wZ_M-Q7FBNYo}66rQ)+@YmhfY9Fdri%BJzr{uq_)<)wjeK*4z zN}ej@F01rR7I_!L$l<0kO7yjmrdwGz9y}v~7q->;!Ey?h-?66bMS@MO8O@lfhoIy8 zjgh!N5^&+v4wR?_cXizXdWqnRxX9ElU8QGp5vR#MhYOM)*6Qu(3WHo~1nQOlnB;PD z?!3vPk>0*oDWszz)bd;mKrw)_0WIU88=V|wRV8{hK#Wc<; zS{S>CNT1w|AoXnaU8sI?fZk z#7Y7l8=36=a_^#bZn?HglqyB6)J-#Xl6K`r(jh9SnRtiS_2QuzNr9NS0i1|$`b;sX zBAnM7&Rs7u&?Ncx!SAHdFhEy3Z)N3_{6D>s_BK@eRM5T_6Ezw>Iay3&f*W1P$h3X5 z^-P)bRDBYE>dmpFFro5qP3RCCdrSEve28Vrqp(>!!F)WL-=&AK;m|X)P$(O`YHwrS z^}uW=XuSJE8NI$NTcjPDTvPqCZD7W`;jNC(U%iwAfI{f(zss^$H7*Pv z%-Gf57~7@9DG!QIhJx^6@@mm^FGrpn{i?HNwRr<;6FNMgnuB8&v^CKL%dCRZf~X=; z2~6OHvQpJ3lcWHhWhyytf3yQ9h)18{&$5lL2c|Vz_kIPQ6>I^M2`Fd2?s~GO>hVc4 zt%OreTJ)M*#}ZH4zhWS+(#NmGWP#M^?qmYRm*?Ai<%{pd)=#H?s*L&J-ih2gg3F2T z6AbS~u5@3b05glk?`9aBH$aV54Ea0zFm%_S1z;ZjSn?ufR;|(Nhd(7tYtN_&i7%xT zySng$l1`U5b6%xc$u}%gPp`ErWO}{OE*+oqEX*3RBeTdS*-6c3(!6Stc#7f2RgC z1^ni)u02c9KUdK{T#0*=hn~VzR)@r1{D<^b`QbcQZDxGXrI45W&>iyh>&LkMVVy>h z6eKlv7hTHx=0MpTtbOTNwpx?@fxYM4&F#WM&sH-XJ%SitO*!K?bNGF;)ur;(a<`}5 zs*|$Xi^-3^8T<2jqjYs+x;skjz^5y_NASY;282;k-lY{2Jo9O!DIYRNxq&b_fgP6q zNL(`C#{C6MRAuMRXRsWW6G~aT^67_dHC0no%c=^QU3bLigge3>BgdmojF15cJV<*w z5V=hg8?TwhY_=g=Fd~Q|2~#wQENsJej)|-WYp*yMob>F;lY6OL0GV!`Y!@}q z5ye3(!mt|qScS<=bu4_`=sd$$r=8x+<2x{*awqsg1?20G)B$7s9QlrLqU(J6^mN{g z$FIPbj;7zsQE;wpE-*9h;}2dr&X4^9C(kLS{jK`*g@fw?$F80ESxWWg?bIzJ{T9>C zd5il~E+uKx3SnLdx3;YZ0b9x`jAMwf><>LQ-&#mGLm#HbTLXJOCKxvbpYYpaI^y-~ zrQ|oIGrVcAo2 zd(hAx6#62RbO1Num8GoSqU;Hw4Ur@XG3$$D4reHo51Nc;TkCoFz0 zlF@y%l(%0n?p6D^W-Y~6Ys!{3thZ`Ra`4oq+TnAj z;z|fs)x^$8*FDHdd+dAOER(x-b$q5($51DYdkkknuCs`L^Ut`GZ{2jZbSJf%|8uOr za+o+525P{{%6I$N8=v*8 zzFAi=K3HI36cn{sj(L&dG* zRCkW{OX2!1Z;Qi;$F11bpar)5u73q-c~l5IkT|c!-^GNl%Mfkue!ahn_jyu}k+5*M zB&&=~NF{Pbc8hTaCi-X39F{W4V#eLHu0By zt+LfMC&Mg!L82of=e1#reI8nOGF>?ezwHc@hn*0k%j`99M6+2pTM!Ph-#3R0y9^{? zOZ2?zy(UVKzJ zAX$FtlrR*JkFUB->^SA<>98JEmCnk-ZMAHkJX&XkpvzRnLR$(ez(oSeKwVN4SOxr% zNxz6a8#j?1(lX#U^7Sey)B}Y=D&f!1LxmSZ-^2`Txc)u`EJAs{&)gW%Gwk{27QsB8>V{m?D zu{>f`c@WGXq0bu3fqVuo`dUDwhJ7~u6|7A4m9ggV8oAlna3K95Ay?wE>aX295AU^d zb368?ByZcKKUHyb=Ix}FRq|y8erE^j(C32!G1hHU4B-N6>?f66pK=9?i8CbD(E2kO zeLzU;@^y> z?O1xnH@vZTa{g6MdzFty`inMQ60c4WN|+vz!78KH_~&_S=E2-|v~%z#3mAMH@1k;- z4%^G$RSY5wz2HTG;*OkX^P-ErBKzzq8o%W1G-`!6ko#vu8qqMoJSp)>#{?5+8Q(x1 z>Tj>=VnJ&cO~-uERb!0MGTA{cs_Ip$ z3S)fIe9Ftc|1R~E_C~8<*qU0i6kF!~e=;o}`qevN?hx{8w zd|tDR7_*?|OSc5!M{y=s_2&u{*Mzbv)i*ZXTmXdiC2+ zK`bh6Y26kjyt)mM8zQx*CwA$Das_Q`%L%$Eel;3=>tpHa{kiCpJ9Hvz4}C9|*9?vX zz20!X#TaA!t{6eR8%c{oQT*;WxH+-33*aZHgHVi-yQt8CUY%Z4(whe)V0N{9SgWCs z>moJw(v_TBW}>g-e?{Lr>-STF;0q=5Gx)k!iuHhv_&t_N2C14=J^s2*iT~d!tjW;p3X&< zNOFp=I(L)aO7W^D&OJ18O)hVK+vdKRs+~Y)g`zf$;>Da*%oTyA}~NI0*4 zy_Kw8)<~H#tCA0Pkb-{DNC-q~eO9T=%^MIZf{!03Xe5;6mA{2fzr2_JyLp9$h;Ndl zz=D=rXVc@GR@||d+zlT5?e{J)TB40U5+d{9EBLv!9uZzb#lonjT;V*42XZ}S7(M3`UP0UoONc9-nWNMWAo}$8lpO%!9v@-p_LU zW}eR}W|CW`jK0_Dk3F^1GXnMvX^?-l3NougYN7`|WIQrRfea<;8@`JVu>^@O2R2S) zWXz>>$Lb&7yXI=)Ssmby>sHxkY<{*9=HpJ2o>f!_O8Ee{JLDWJ(X1Lx5uC>J#>W2H zmD~UiJhSAuJ4c?JPWw-rFr~WfEGiH1$uI)=0ppeRe>q1G=6%l-VWYqerE~b%uVBq8 zrz$b+7@124VD*1=fv8zJJrCa>Ng|9H&+$)wjQ2V`E=|Me&dU*cvHn4&0prKY-9 z>Ph;tZF10>p{w_RL!VB=ljEN2M|ysWe?a|PKkJ_wOEhmRrIg91_R+OOy!BX+sY|q3 zBN(rPYlB9VzV^A=uuWd=VEnq90L;CCk=YDc@m}Z3!p6aFnaOyrKO^!~cueMEF~zy{ zjj_`h6yAj+y^w-5)a(vmH}A)fxYVF!Z+RJ2lDT2ts$J5zi_2qUk3x9fLw>oMnUQm0 zk#I*#2LJifJ<5E;2(+0>)b%oXgz&Dd6sk|g`xNz)`R#6Us;1K?o#!N*(5SAg`Y5D3 zyVAFcQluD>n77>dDx%WDS3bQX#ID1B{ASN3@8~yZ?^JeqtjSuT(OBqWAivuwq2ELY6;hnc)YnXnl{fG zHANt-z>BT5f-y;!a2%i_sq0H^;KGVH^S2FrI^3)5o2Ns$nlk+9gOll`;#uF5N4@jJ zwWvrdlm4AEM6C*-D}DGlWBO(9N!oQl*>uZ*0g+G@HjkKXgqM|EEg%X91x`+qjL2Qa z1{Wz7d1yYp);IQyr2($$s|iGJ%5IvnK3#Zu01K)ISXv{SE|lNiCEB2haD9mtX?Dds6vgeyX*2Jw{xiRh7A-d^yhq6Td5NzDc<Brd9y@90+8hVuWC`{$e))HjqhY=V%*qgt<8huD$7?$xc zF46%z$g=y+isncm73TA)6gh)ozycHP&D1VZZ#~TRW(5zMu*i>vgT(ApYT>4K@t&Q7=V?N6;edAvY8u#I#T7BCr?4!aMS2Y8vkD>RTBQ0&Li|iDmE#2A){F^c0m%eXbuX=AFnQD=enM< z8 zM|s3pChVXOiv2WPr@cEPH?21wAsaGc?ya2SHl{H@o6X>S>(|Z!=p0BjTg4w1*gup6 zWOCrT)}J=JTB#t%y@2S;Q}@veRg?;b<&83?iImwcw;?>LhW$|G72B*Xd#P5}lGMnL zhJ!gYlW&I#cS&`xErqsRA_J!z&3`T4h1x{hSj+hFDqSL}jRvEPPuYJ4=-C4`*ju`5 z->WR*ulN!U#|_{dHm9EA){Kt~5*xq`I50ZHW2z@=8zG-hCG+~Pok^Y;?Is^$d23x= zuw!8GN4<>jD|yAM<66{(^*sGBFxtVN&Z(@qg@n5v3OH9?3sJPYSAw{SaM6~f=W0@j zuJl|Spvt&4FqIgd{Sp$p&>+6EWmio-b^qBo6z@Xp)>3le2?err0BjESB#<(Rq7DFoI7;M#Z1(dl>U>Vt2--(y8;q^C?^B^E`!&26tppycts_>@P1ZIl9++ zX*jKy=c_&Hf9_-Rm|x0A;*hQXm?sbi$KO|aj!eO3;)e9go}la z5zN5{RC_S+u(SWy;=v{I`!_u&4<7>)7~opIXXje2xy^t1C&figZT2BsY4^*<6sxK0 zD>e0-^LDrxS%i1ft#2`9J+`3R?lUiRVe0!dZW12XJ;T<1d#wnyu&9~nElJi$ywp_t zI(CA-^G90?OazlTMJ6FizP5?^HMu8GQzl6r0n`9ILJ9vrM4e?+RDIa>=@OAtV(3Pi zp-bsu7?5s|Zj|njlrHI#?k;JRZlt?ArDKTa+;6OhkF%JyW=))P{r9!^ZzDlgBO0v; z-C;M(mwklOUF{QPq$gH1q4pV*lDyL@E!>XU z?|;2mi@f`I^v64jsg@_L>E2QwJ?wX0vEAPWuj!c8;v!wOD9Q)G3w zg6#y+C{oIDa)iA{Ek)L~DbnWZrGiChlEcbzpUz)&glI3@_H$!-f!-x3Vt`4Q;`Zv< z5wn$4TBz$`s#_r=n-1Ljv0-shS6}3*3`dU&*pR*T=YV*A@AlSAR8fXaIZ0Sr_gKiS zD76%2>6L2BWOL=IOIWho055Gh;1Kib*X0%scbuH)3Y6pYz!4^hcOyO{5ZPFt1}dWk zF@crVyAC1W;OGOT!WO?{<>6c3@i3JeYVkYdc}q}&6j0+<982R`rD(r#;LEdq+sj*TVc38Z@NtX zo$!5|lbY(Ios+Nc{%xMD5x8?>5i(OnetYEO>N3+>)NU&M4p9M?u~3JSLLS|>mlsUE z6T7pfo|6&&Zy7X|pgIPC_O}UHAI#v=%QlP;GEcf@@rWQ;DUM(k)2mZ}B89_LN~>tK zSNv&DuX-BE^^g#5S~N}+mT0qxhz+&IRLI2-fxq$dZf+V;C}(vN(H%FK5#VOw`)780 zYBWDy(i`3l%*_(Iskzvi^UmS z*K2VK^p?(reJiaV&er>#zapGRKkNLpdM;b|3gA^wUkoj1S7t;Yn(I!_{CqJ`JLv$s z5WkI+(05B$d=q+AkJnxqoaL{YUmIY;5 zDLY2N0%~wF{D5T9GUVk}a@@u1#M95yX5qfB?)h8+ntM_*XyBr{=RZTo`#X! zdT8ceUiL?2zHi}7xI0#`btL-i{>HhAlq8>?SOn^x&R`X=>HCG4h#sq~oROIZT;%Rj z@XT$OreCzqNWyMF@l5(0VQ@jj`}`hB1VS^$fLYug5;_%hrfEO=4PV zrg1NukEc8%^}Lo(Skc;Dl$-q-Oaz3jdaqC{k7H!a5KH?`m!-me(e7PVbD@d%OM-Z< zgc!hE=>O>wMXEz~XAb8ZB&TNW$!6bN&hz+l=Apy1jN*z^dyLJ&kcHuGLb?Y$t4|aR zLHfoALGm|zW_qRj3iQ5wj{82F@}|ngeSAEvW~S4&#_cfIZ)W_e$nLAt`CpwSWL6lezw)%7vG~1J zGa7SQNPNap)VnN8p22JO3j_5A^(9aIiVPHgpo+f9_y~t-fldx21DV6l&kv-p zsdI5?!DIMX0LMu?O^QrE`v)>>F9kH&1iL>on+5w=2g@~6=~po{VcM!ZbmlvxVlgBC z)K-k&q9e{Trr+5!>e+8vg$x8mKa4Iw{{Dul?9R#ms6|v?eQJ^NPUBF!Du5%8V;E0$ z^4CFpCg5-+{%($0{EJ@+h)Y1$OKnK|D0^8h;V?brvD+}+m`k6FnFk=X=|53R_~#C> z@V6pD1S31n891R~=H_M*6ce)I1T%1a7~^bn_M^*ucyM~5ueySgAzIp;-hV5 zf;lB}^0he#+XQ#bGd&sun81x-rOtsT7rxO+*I0%^dRS-K+A0t)Cf%pEBJf1w6dXwF zN-nQnM5JMCtD_BF*`4RRC0|tdYS+oql(H7J@9?Mcuci(n9aMHAodNv`zK|8mtQ&8c zP$?`SWU^3W*R$lObkfv$34vUtpe56;3n-$kTVF1iMXr za>EnC!gi9+u*^h_#^B4R=e)XgGsCRovK{(CP?DY(m^@*umhfTdJspgQJG3BAa`i6{ zjwD)P@T_`sLRdPdmx{|~@Z_ar+ESZ>lj>Y#8vzPX=>)1R4ny|b>(%O2~4(s{# zIJvz)5*>saBbNc;vhO|}Rn6|SdAavV$06R!Ztz6N$C_LEoeBy%x&mx-bQc5HoiPuv zqtlenkvHzUxV3`#3}<%Kf2fKG+6h0^Ir4DKot&OF`jmr6!LW~GjDsELh$BhPqevBu zoio$vXZ!Xq`H4acJ0DKToykcoYM+ME^tJnP$oJ;?U?yf}w1CUnlW05vV@vV8JnB2m z(Zl#c-t20fbd7ZeOWIn0*`4jDH}FUv3mm{RIy4m|Wh;$;rT?6(oO`WR7IztGNVSF!cZksw&jm!#s`rwTg%OAY0%?I3Ok^fna z9{Uq}3k88^0MKQW@>O+3nv?_6vteatUba%>e14Y!{b;dhgE7ht`vhf|foZ|UZWBYh z(QOIfXM%WmX{zLl5Ev(bhr~E+QWo*{8a-V~_-JFgu{d1NHzdzs<;lwSsK$1=Aj(pP z2Kb9!Z`4W2F@TT+SgY!EkKtz=ZAEr7>pPreTMms~2w89TNIt&o$ zWSzO8_zc&`#PO?bjeH9CjAy&jy5I>|&1b7l`<4~`vP0vQp9c0LuEcD^+}MGx!+xpc zG&6C7$u)>VK!ptAKB5fz%Qlb*)LN?{0n*4jMsLsei({H>Lf+^7N-7Ys-ovF@9MA+<4lX7`^$!TqG5lLZf zHqJYAc=v&F8<%>W0@+fUUfScrFEh!!pVw-*rwmvxMy;}tZ~Lt4=y^?+p{c)7YnH6= zTAgh%C3QT0;ueroa$)7V)ldr$!jqk1TC|&sg@qS>U*h038x&lfG2La&MHRHGyA5|4 zkm5+ncIMLL{@yjM7<9f%gv--P-I&hH^{=R@eQ`YC<%JZZF$y!LP57{T(H&ND(Uk1e zdF#EGE-}1#uqi~Kt7$hXJ^shvj@7`hcDGHVw?B}lxQL*~2L#yEV8m^O%t*#lT)Lmt zJJSr>6m0DWv_>=Q(i{Ioh1EO^%?8i~y#>Pphs~^zo`;GXpdsP&o#qGGJDwhyLOY+b zo2KF!41k7t-K8Cp*5PfL7`~LwJ5(v<_So@w*oCj2RTB>n4|w4*Xr2cK(W_DyY-&m6 z?=k@A?MGEKKL(jdKC+kCMXD=+%p*u3*{LI`AsG zb^*7S)}*^wwmk*5Ry9-*I`BWA3432J)(4g^{(;vFzLRz& z=O<-*xhV7Es;nmOBolqQSr^b#-Z%C{>RX+`R9A_+dU@gdxKoL&z6Z+jLC^Jl=eLbh zSjF9iV5;=_bHjGA`{g}~DJD*qL`lI-Q`(~QuNgUhxy4$FOQ2fh_66R#ovv`}Ie^Zu zDv1e(eyd?1iTL+?9}|ZmFMpi*iG7lQy{8Y_RSQRLfF{jRWsNp#krHU%Kk-iFd&`-`4*ERjY_Y#Vzrt}kFORjpF zC=Jta;r6`!+b#JF;|{z&HE!2kK=w}OmyLLY{(oVJFl(O2e7rKt)a>fm{M_Ow5RT#FyQT-2nRFa{JPgc$46?S!&ndXV zNXN{;z``ZKlf_~dk7S3`C4QJsh*W`yDAGUc9R4#hyZXH7_Jpi;uJtjr?+F^B8Fv16 zl0XRQ!U_NEMi< z_Y9X88>HR)rd{@IPn2%-Mzqg|(p8V$ ze0ei1yMZ!QTd7#1;OCqhd;uV|1^~+;6XxAVi+3-%}UIZ%h)4Z;4$m31o$T)mHq`#^2UELUm{2+JB z%j5Z0r~GeaxG@3w%K5CiT(dPBW4Dg6-DLSU8jU&3tRd$gL48OFGTCYIKUu+_Ha$sS z*{RB_nLXCMz*jxeUHv|Jd`v9pWv6_1nd97lrS<&@!Kb8q*qWneB;D5BNhd--%MJ6S zR{?8q8cy}cCHfp}qf&mcDG^S%C(TW^?e>vgu7_GbTGX28ZRJO4#ZqNDyU4h;9k{wA z^=lTy&~tlpIUCv;p7H!Db6{3%=dGG(Yow2AI%SOL(K2zcX;v|s?;{l2(faIR>@%21 z9~pZzIhG<_QtPWXiV9j+_*#^YVS|H`j9Ab?t!VG!iFLM4311%xQ@y$+Ex7e>;Y#H^dsg5~VyW^VeC8)r>4V-vbobAX zSoHZ;nVQ{PO$)_-VUX%iPjuT2`KOaAx?7Gh-@ld(!-ve?b;{q-lu1u!zpvTbURA?Z z3us3-f8O7c*s-%rm<<-6W@K)4%I+P&CDQO?f0a0-Un5acy73{B*u;{QicAwxjEpTF zAvx+BQirC+32+i<#EoF>Itd>z*7&B-hqDE{i=jx-`3&vTxk|yt_@D*!;t@J0%rM&)U zZ_F$Nm2@H^li#ZzNUKj7}h7vS%e*cDM7#^Mlt4Nvk!(G^^d-{(2rnM z6cjA~3`@q=jQOb_&)=dH(#N(@700`I+d0Od}~yfe5t_ z6P}$Qs46!b%8+VvRI22L>nhoZ?}_#8a|hNZ@|GygTFgLmY1Ed3av|r@A1=h7$1KMk z=+i&FzOm}X5By8Xfqy4np`{vr_l>6O&mMee<4}ZQ+KIeg)1^VT)Yr5{7Kug8y5w>B zr6X-eaX58X)L6Tgtnv%!P6^bhRCV24&6nvmGe9a4Y^^w<`H%>`f3HzJQ?^{k-t=Tc!2GemLY@q}$we6lw-l|d7{B$vFv{wi2GPez($ z1A(=lLN&dxaB!|ilVT@L`6#~KI*q-*)>c|YpCwJBT|SZXEH8>-)RgBSzKmdt8|*5b9w3`o(f74pw!l6^!MwMo_l*LpCQ?kurH;X1S$ zC2nyTj5UvlCO)g|N%W-cU7l$%+W7qHeAQtBzP}89c`@QD9_gphR_wi6y>v`?3CvMi z@P2+1pJZBq3^2BFnx+p4^uKI&zq|mCO8bP%vQpa6U7}$y6O#gG6zb?g=AN3DU$*Z9 zb4lN|Ne$9W-ax10>teWkI?j%Y-$Li7^Ke+#iLsE zQYwoVE`-$FMr888@g6VOoQc!9e27D?#<^Jp7ji&NYhthwDBP3=ws` z9OhD&W8_cQB#0N#H>q}|$~-K}7U2cBCGC!v{N&j*&Ryhc>e2qzrRq&*tr{qp8c$JG z?JqnJ97>Z}E(1;PTLBEUw{>oC$i?{e z)84_IqgN+z9sz(mfIxr%aLN7K->A~kntfZB@jAXnIdPh4N&fO)XRt_vxQ+KDvY-R5 zMAHf$G_7-})rP=ngOK%<*Plu;-`lrJ4F@E7#_O`ZdMIr)H?%djXUy#V+Be}U0-(^O z@gd-oT*-c2`Oa}ZGQbr6dD;}2Lb2q>M^kmLk+5OGX_NN)UINX?K3N%SaX=so@COuk z<2Z9nreAJbm&7>OwX+TPbFSk;5<&0 z(M0WUQp6zn^Im+o)vrg-M|qiG4^&DFhBCI(f*-=LiP$%#a)AG>1U61KkNw_r18^2V2hN)JmcIVHQ zFgPR*t$C&kS&TSDPquv{;TBEjcF`gNII+07lgC|zK`$y;h$th740qm!9u!kPf@Lcj zM2Wj4OGnUow2#Vaxq~m+FDr^^m-mz8b5e2EbB=(4d&xcC>dPRjQyo()QJ!eRj{Q+% zD<7oDQ^YWOoYXNxr1(9n^Ud_p;meL%kj^oO3DPSm<^2iSJj7c)%7?n%%c0LDBXr{}zR2%L1 zvUE(Rcy~A-7pHCwI-Y{)XJLyq=$Ac4O<|jZ`JODPH1&K^hyg6oHkVF+2iW_x)U}?S zRQA-9rZ3_imW?bHW6e}!+CI-oO&81)?%F|oBdaTTD(+WWcOycSUM=m+IVDuhMZk%f zo0tJSw~P%j_y8S zF86j&xk=2Se{U-cgg#3`Gb!SaGVM4GXZaGN-*18XjxY3uINvuYD6%f_*51ojs8s)) zWbO?>s7FL@Q=lsVA#@?!;hY$q0NbAH9Lp*)+2js|;UtxfPePE|7mlpGguR9;(eg`` zgao-?`+QX^E>)7!532oEZZ+-#@)vIcL2N5SAdO^rVBPg@@dY>Q$1^Fg5z9 zrBuGboxEHCYucgE>y^Sk^@^(mz6{f}(~Xw6dyID8s5Rf5Z8kO(=r=)h)^CLI;sWw0VWF%i1x5yZK;a$@_z+Ue z^2gVIXkt9|=Xx~sPNwAwELVC0&ufnfB(#=pF~>>b{k{%p*RLG;ph`@)h}d|?EdD;n z{rm=*fFY3f-QtAsVL9s}-CUS(ZFGU>@L^5rEfE>u>GHZOvQS#4{1Bph2nv`!o8nu% z4A%+ObMl;tBe765bW-@6aXi_Ytla{pW`s_qE_$fr!pkbR^wM(3qMxR3)CvBt+oG%Ne-#HtKyffBZ8;QU zWMl$!aq`^FE$q=VFmnTq9SlJK1}7KC>JkGZBOPF)5aK!F;ozbJD4L8+9D-nOdPXp} z022>4H!s(rh!Q?00M8=6o#LmYi8E{Wd3baaEfYUiQ_td`z;m-4_FLcq8NJq1Zrid7 zlWaL)ly=#@vg+l%E(%UM;0rmp#@gy*S@?=|ZByyy zMbS5g-LkOwIF!$f2v%kb9L4{>i4MS)eH2l;)9>nD-4d72m^Q7ttGndFusr-`%){z4 zInFMZY;BvwyUj#NF{SBHEOOE5I|dn1a8bw+Dzo$Ma|BAU%_w@Wj!jeS=S{A)`nV-4 zKg&yV z6yZ4e^L22kzX|ow$``QP5YQZ(5i||O>WPy+v+eHSZF&2OykT*6{o0o0;Exxpym9KL zT;p?1NRy7MY=KI;`|5nOFw{>hVP=5MC2mwz%7hT@&qEqE+JYWp2-VIwZ;!^h7S#$V zg$)~NK&w-nMX#k9hG)DERfX9G{M@Xk!zxcF z8p```?)6<;Wb1Y`G!q6RWK(DE7V1NLoG7xaij^ikFX#eAM|pO~b4obCH2D0wq%GYaA*k z^a&q%fDQ}c`JPYsrESN@pZ(D-`nd@tJ}rE%*Cl` zH}MKCkJ+8w%ap7Mt!7SlSG^33g{|-AOJnhY`MHq1)ld`LfBbZ%Tu#!GPjfpGiEXsC z53%_Rb~A-+izmuylEaGmDdSOpbpMw9y2WZx@A=46rOmCSL8Q^CL;8yGK3@f{ZBQ)V zZM_{i4xA5b2gw9%OcUTUdEt3cWQ2XsnP)L8)$e~4&V@{os23ZazU_HqsG`vk+lhw` zTzY%_>-b#}UVT>lS#VD#fZz(D$3>b$xBPmgDS<~t{fOqjw|5(w^F|WhXEGyMD8Le` z(`pg+Bd8)b|6A??!Hwam_yg%&yV8F69>r9_1a;xeG|#@WQY72ypMq%FcQ~F3Ud@TX z-Zx8(ulgufY;Jx!lIN|-4tjMS9$Tz29hAs%dG~OaINo*&G}&D^voZ2kmjrC5*r*_8 z__hhxqW{k-rU`BoB$tNpc!EftVf#(Reeso{4->@+nyVE##8oD*19r%06C`M4X)}Ec zy%Y5#U1I62{e3rNR2I41)}%>txgD|af$yGaI{3XKm4b##*fyy=0xJYNwh)4J{@n0v zlx(Uoy2L}&|2%lUsKw~#%CK!PZrTGA_yp7i_0;zWYKu;Mu_V0VD2{GyRauchr)~dQnKi6fq-|dhpq^e9wa>?@!(c-9 zzvwle`OW`+?)*LBcl5m%6-xr>wqi1v%12yzX__6Aemi64P>T}0!8JW8vA8#-w*w!Y z)0U4c`YcKsL6=WhquUc(N7+crTElz;&U zFqZj3kzT($7zNjvUekw8?ixFh&K-Kqk_w0Qcp*;%EBE+-5{TaO4JS2imyE@@ANBHz zo2;?VzG%9IRZB*Oy5m2qu6(xH0_|2SOog%JJqbTDyG#f zuqM#K@zgJRjcWvk#pk1?s*-%qnY=l*SV5htw-Z|*dZtwM(O@)veqzAZHAeRRw)mwR9hj;N~OJq>$Mhj-m5r(ieO2zTBb z@PFRd%(CNe?yEfu%5{yq=T%r90L*~*B3Rs{eQuHN(y@K2gD%>OixU@Sg1&EBxBgW? zftN4EMlaengZ#A#@vPhNNnsN&_UNcf0dmF!@dd`g>V*6^>CbkDVQ3g}83WK*^K>;# zyKSo0dd{mps@6&$d1=3#H(b!(K1PD{!85jMR<}sLF=JN-Z8LMx%9cK5wQAwZrYqH7 z0*@=V1Dm%#MQOWl7;Yp68}n;>P$jsjn}cA;;4uU;q%c|vC$z~v`_MZw5hcA?Q^;F? z;a<1ENV=N7y1sn2%I8-`%3=|Ef?`V)d2<^5B$k8_1)^{U653V-?FJ8|ACu+-Ub#l* zzIybRxgCzn4D9wD09*rD(ZJ0Tp-dEy2L+{JpsU4sJv}((%9_D#l*6MQP z-o3(2%zKCK47b1Ww(D4UMFF`}!t~^Ns*TSjn7D0TDm~$`>P2#TAW6-Dd|1ADrpDTH zzq>~2AiKpUbRaMC`x1=cqx{~L;WG`nN5=@_wR@N1vHCWeT0;%5yYXcN6$o7l>b_Jm zh}&ximnSioPVmjXw@v zNWl<1rs?p#J(k&_fh3uB#%#U5RhQ0(GEP$i8xtmdl3kCZVqZdnaT*?+m261)MV)Xi zFm^C8zM~Vb!{qV&{e8O-#&12Hc4K4ucBf_-9mPjmc-M(lCUaD_&0mThePJ?ZT+oGN z^QTVi+N0b#y)hdzufdvzYVqc}X0JNw_=S0g*~Tm-kYhdEa{tsm+MzVblC)OdI`~OV zpr0`SgGB;~ikC)!u{p~=FNA7+W?+Az>ILUeifLQzPqWL;_n>Nt$zQR0m`)0w*|0F_ zWVm)=gcSqBNVtQ+pTvywiKg%E!GhOs@n3rznfRuTj69~1k=4*r(rRjrBvy2M5w3eo zOzxgpUWxfltZ^`wbLHJ7lJ~>a}As?^Ex$F6S0$QY!RTdcmHU zZre@;!d9B8&~(1>!>zhaEMMTOC09qsx57WCQJM8weJxedvq;p5tONO4)bq@j(GdeN z2QYLIa{tB0uNF)))gaULO!IWsn!)F#_Ox)vgIjnMGx-j5=H!FWM3fLzE>V7nUWOU7 zp&hcyZ*qs(*7>TyBP4uxaXm6M*`+xyO2tu%?@!K^Ir zZYpSP!hT6DFagdpuUsX3ghxbd(1R^z8>OR*Q4w3N){DB4Bh9w!p1Ip|Kx_J~`ZY_X z0K6(3P!b6SEW>2oE~!a=7Kqj3{NVZP_(Ni5yI@Ij@Y>F(yffZmKu;f*kiU@0;l;8g z;5^1|#>sMcNvQy(syx8#@*zl7#&WSd^t7Ozkr?lnoGROxP}Fr$Nn||`;63=Y&n>q* zPpAE>d7KI`7CHh3DHAA$aMKEeefc)vqp!bVW znU~@5UkN)gJtc%c*Fk)ID+%SEYsSh>dedb2Ov6NTj{K*sOt)L5D?(HPfObtBxL1Pr z`MOW>oBGt2IBZk(x(<5i`nFuv=xWnquo#xhULu4bA}ca!X65f`n4Tr;H0G#MEo^1e zrsTPmATMqJ4ZVippa+h}Kf|{K%9qvPXIh2UMxPlJpg8%AgVfDdO`h`c)%~XRDJh@E zBop~qf=x?rob|P*MO(3Xj#X3n$oo!}?MrX}0sRFxf0zc}dYH^|9@mG6rJpqSi)bx2 z1Pg^M@9|t))%$8|raz9VYpbM^Xz+lcAv1z>c9}35pqvB`)Q_LJi2k9}Ejq~R%YGee z4a|I!rl_nGbCxH9KA|b1_X!1`NorV&Nqy?m*QIuHZGo%mUklMEui=69T+Wy$_4Q8> z)2!2@hpqkg+vk`6^QT$W4@^+n2!B;Bx1S&$+Ha5Jwe432k6X?%(j@Ylql?K-9ItDG z58Z7a&a&xW*4kHmJpIrCU-8#EI{AfXyO7xi=9>AaT{9ccLRpBT-WMB&a>Xz4t~Z)i zT>Hlvn^qlWw~eCHXTWA)qBu;|C(q(~!1Q~*$DTNcv#YY8X5BPW~p4}#KI$j ztaj~*b0%h&jPpp7m<4Efd3p$F-kHj!h{5c*oa>kEo-f8~Nl$lwiyfy=pU#a;Y)NlH zsdjYIe<57AFY@q*MX*iCRy!TMLXZq51U-i*;ZH7p-f)pLIq?YcN7pt`jEDL0gaueE9D$#zLmr6>`rRt^Vm5lLa0My68EfR$0X zSLJ=5=aZKT!Q`HOljLQB;lP;pWzC0w?Va$=pxYC!xk0Wpk`2>wU$?;%MZ2i`)ok2F z(@WJ(qE&A>`yBIKa%l=9m18xH)irvC5JBE9;aFZ6>xRAV|F>Ce{IBT21c)AS$zwMP zTmZv@js-ARFmej>(F2qV9&R2cdL~{lHzPeg6BifT8Y4G97f=eq$-~3R$G*L>%LM2o z^mOz*0vrtV0NztTn2VE}fl-Kyo&^lUxS8r9YgrQ|IGM#|(%#qFd>Q@3uCjk|EIKUr z?Al0@kWWrbdX5YCD@ko|YhYysUYe2wl@CcV9ZZ3&KCg7%H&8Nxxjl`r=l_v=T697c=${XWOpL zE8C*3ZKvUD4cL$&63EifjK~?`MuNJ<3ms=?$z9j!)zNYmkCU~>mnw}0wPYPG0O5wa znFrC>bnAXSg;{dwV%Gb6%osMLe(}4=%SP3CR4DKx8LJXLW;_EXo!ix%Q9n|7+NfV8 z^yhZ?sD&Tp?Vl_8+Ix?MN%Ozh@el-{vOHlElIU=@?Va&AZl)EpX0^~xx4$>N82jvM zQ|r`6QIxD`0t~~)jHVX~6XtmSuF#dA1&-XossXi0PYj@Oe95)Fnk$vJB?L|tdM8C; z-R+*8_8({Z%R=T#80tTV>HkxivE9l3QXQm@v4>9wL#0WgA35=P%9Et{q_x6Jrp;0R zF@+^8);z^M)US73v`$iridqDwJyBxCFistFv(3DDe=vG5-bhQfR zve$jVdwF!YZZ4qB2C^}P{+5_Oy(oKU24-F>TS(SEyO8$JRT<8;wYL#etIZaPIgetx!kj@OdISD%#R zNz$4$=U!0Y1}E{IOcdOVdyj9(3?nHheb~K1p`*ar5|)@`Xf)AA`n_0K3)eqdc=%nN z->s0mMTm+>2vrD#9fKDzh|`M04Vgi zG&q+d&pTY&qkT2J)tOtK3s$1;DJ=PY?t5q^wX3ivb-UoyHfFECKW!&JuFk&XV7;15 z;kLy}2YH^e-rCb7A_DHT#ARk-uP%^()Yl}xCXBgr9{O08#!}JFWoqc7^}ZepvN?7u zyUX1NSCC$99r?O4B1Wf#88|pa{Oygu*%Q%+7MyF^PjOoJrN$)5RZ-c;h7l{*>8}uh zN^lWnz4C%EizDPuZ#D6#JemlP*ejh4omd@>EI;Xe_k))a=TQF#O3f)A?D)F%D^tbP zcxA(y(0TC`D#c=|=q(I%W|9ggoAODc;gNzNh~F&+#oViu*2uXfphB&R!;TG(of(Dp zd@gl^Zd+yJ`yY+RX3W@6^xm#9ZViEz-_|3s_Jh9{9yEP@a~L?n1j(dtG&Jj=hp5$C zy}~*_R6md6;UV9h*q=x=7h+C_@WjxAFE|%OU{pT~!eqC7+P>`D;AXbWiYpQ1i8=dx z6&ZXLN}P8|#3}*2EObhvf+VP*+!?;ME2~-t7FD#$cB@!dy@h zoPEy4uI}C8`IW$nnK>)lY!q+`8C%@P1o`?|i%5O?Ii_f4X&Mg6)0!Sg{AHIQZaB;% zSvz7nQf^+g=I9gcljY8@xe?fQ}I_7$ufca(baXfvQ${IsT}rj z+gVGla)iq@h9e0oF%nSo$dW^h>`#s$wsuIm6RqK+)_jKkWND$hPQhszMv6Mb@Djl= z=JBTf%-Y*-FPxo^tT3&=0yj_9CdWGARfHB{WRXT%5*Q@t-st9?5qQ-)8Xxtsp8A$Y zXwy_v&{5GkpVp->)v!6^IKU<*C_PAjf%6@hvDT%%l#I(N*wkicJ~+SGh0Ub$du-G{ z!fX-il7`s0^#>;ILCsM{wTC)0 zvRZkwUH{i!>=spHs23k-*tDqxnE>ZJE7X%^IKFV;c`$D`Q$;oNxma|!2aRi4BmL|K z-Gtyv$AD&%77h^M!9y8MAV23Fqm^2#1}|i}_U@eFoqV{}B7+S~xCO)r??oCJVH zuO~87?o()yKrl0*c!rVQ=Z78T7?3g5>{Hz%xZY*@x0T-#lFZWO;X}`edk>}n5-SY9 zFRf4=Y1yxBJl8IkeudifIk`oxPLF=LI(^}>#lkBSC3qHr4noA8Uhq1o`!(fIhM9`A zVo59E)~W3yJUA}Ct{(_Tt|c8402yk$>0(T+73Wi)z^jDkkfZ=RSYoLLLBBA^kv?6Y zj#KE({!OQErAx9!!)enLu;iiIFA9_VnnGbCyC3%f3d=J&@@q}qy5bv4jMr^ACH>_yu3U!GFr z?Y&Lv+#J4+Fa$w~h{p*K+_J4S&BCd*YcI*CorQB%oFXfZ9m&Fe3OnJXIhgaLg45}Q zcjc2RwZ>}BnRw)+APDP(s92qvH-9CilJV;-Jd5nUM2{urWbb~r>*##-*ETI(SKrNS zE0V;Ior#n*5r6VCIv1wYKcO5QDxqU421E?;wP6ZIn_r$6)*zbM*w6_XA+$_+6&2H$ z>@_F+{>deCR#jikrz&&I_KyaUQ^yTi3jLKX6R+~rliwETLVZ^tB{k>7dEMKtPD_Ce z$v1laF5Q9>b*5?rSa22&RKxi{IR4yB@5LbTd@RwUhrN>w9p7?(6bntc(dEXGy5jK) zlU?Io3|kMX4vIG=G|Md$jhxc9e>R_6TFUm1(OcZCZ50XdlW*V+Ec)PUrYfM4;la&6 z|E^3d?A`K}kE8(S2XO@H@3e?hQ(xD`#8eQnNU!lFQpxhsIzAPnW5}N>I2xynJJ6M4 zFr(bpy*MY2LPGAlmqzvb(>JtgQy=dB9Iu~3pe+!MUE;#@#1+1cvR}V^eN$SwVF_cs zmI-)H4u*6a4EKbW&@^`;1zz7AEk)3H11b#)uebe`nWgT%UUQ2v#mgAS9|qp(RH^Mt z8k9mEp)}{oE>~+)HQxoHiQl~`QD#_qEH8D}$eIc>rXK9-Mtswk?j2y8(z6?*awa8i zk3Pq$&4|z~S+Y*zAqWH1iLvR?gniROV6~y_UT&d&aT#kJW3^XK;Nwrk#(Na(jXOj{ zS_68*&q1^}7+q)Z4f__hki5OQ+*y13tbEl7&S)uSNY60|e9x@peC{L@$e%SY!`Idi znwk!Gb_*jvTmL)AxX;8)iZ(p1zMGCx>lad90-I;H8)4GC-u?2@9-fL3XDKwyR!g|M zn~Mfnx(Kyw$(s55uad{ zyGH8*EFm?jUAcc&5=g8N6!TG4I>(p8EPGicXJ?Z{9yTF><6DDSAeqh=N2*ecW>!% z9a9YhvH^3_$y`9o^`mhK<#qDumAa34tR-nR%fpASFzKo-dPG{+A!om!}a!udR^k5%Oucm2y;341XzvTqMzD$;&M~9BqT`q5|`L$rl zRG9DCa<@d&RG3*OknFk{-L+y7LT$s@Awl?OhHV$?mftO}2Txmmh#r30I%|gD9&F3Du=ndoaMN#eCw>$;#S#0&uUE1g_#wWJyz(d zf&>V_X<~f3LWx~YXw75#S?-~ssIIA&VHlvvBpU27rXYHqD)u`SpoicSkK&`Pb5e@4 zVB~xD3I8psPa`>VYTY#7EoiUym1xyL0JacveNtl*RcXU^Tc=g|pG zIjKEu57xc{u|ofZII|80JR$pA9fs;Q?z5kBz`Z=vgSK>PHal;;!XGJzLT{|b%(Rot zT-cq)8lgv$$$y>^)u6=Y^*y|PO)e%MaX4Q!Le?_!09*N|lZUSYRSA3%CT9@Z(ezDH z;c-14C$o41hl2E*#yp=jT?b&f)Y!v->ECiTY}4#XETCmCN`GrVEvU|xM3HbBy?rYC zBCbKte>oI70`gIByL#~xk>wk;81()1tj~#ir26X2a5UYrmc%%vc=d19($u;7%dK+j z6a3vShZ;wlj=LzO6x9E+HfZz9k}MVxs&KlmxQDMaZF1hS&zhQDt{eHTWBp(z(BL|5 z`CP#;RLWt;ZVeXOy1i5s6@g{W8M4YX>O{wW@$;XiVt-P9XJ(KeTOA66jF8}uw9GN-MOF6 z2w)ZbmDppA?_Sx1=Rakf)wu4D=v59tXq%HBGZM97!m3{RV^+W~pLm%b6UFF&<+ z{IB=C*Wn8nAK(Me>}T)2?zMg^L0v-?LBP@iyZOLm?GuUtR*GMX&1?N95m4kchssO6 zyA{~*@?v)~Fl{rrd_-lHISreC)gxWh^Zz%J0uiYHz6#!>ps)bn??$rR#6f_1z{1VX zx4y^7$H~pa#LdeI0{EJOe0&1jEX-g&FfT77P!z()#SOHCaC7tT{F|AcUtwluW@2IF z1H&;GM+gHw{0l#m_3lz}or)=^ToomdH|fzBR%|W9hLzR;B`6s<%DkBMCk>}VDY>oC z?WZxUw(hB{b#l{dGbh3Bvmp8m=zPh6=D_%2Vefn?8!2E2k+pphn>TwCYQ2c`CCYL$y0vhb%*Der`^h zjkk*)=xFfnu6Xw*|4ttnse_WFhGDIMVelbzB~|*r8Tw!xS}o|Muuad9f7;@vv-${P zk3ljn(j^_j8Z$Rmj+)1qTUFn1Q|qaPN7($2292nDe1X*sY!%Y_RJm9F11AqS=2lt<_%6v_E0dOg zwA4?&yPbOpn13c3B!E)DdTL{=Sji0=1IadJM#^&In+1U=9q-B-;%_h ztpbNODJfmX&*W||R_|{tgw@@%ETtEREpIle4$C5bgFTqPd`QWte41Rx`CM&~Uv)L;cAL|(<27gY!m=HtN3kk`PsbDL8u<}Lt9zxJfQhQ4X2$w1j*w?Y zGI?;3DUQF?|3lm2NPlU%oM!OC_sdTr6m!X`f-wF+b@Lj&U4neLjXB(G2H%o!#W>G3 zyA8ZZ*UyB7(e<4t`qnbzp}_Q3;nzeU#(|M&C=u-f(tM|r5#*vqBd}IOz(1asZIGFe zBK`J1f3$im;zg5Q$tG9ac95{$p%r`v;!HG8H z34(5)b7NE)(f+->T{kwM<|GR<3YnEI$sTjJx4Yx&Jec@qzxak9tjWp-jQ>j+u`rG! zcj@P3RSxtG+k-z57KP$jk5Ni^N+%YoXsG@9{1vzmFe{A9JZ~@K$0sW)Y!h>vKJ-(B zGYiP}0S&<3lEkeqC3w`ifwl9~H5WkvZYl$`}(yKI(^STSv6dBasluGP%&jI*Ge zp^L1WbfMK|C9P!-1DIf6GLcJNqX+Qu2qs}QoJ{98o5n_a?=b8v8;@j6Opa}yF?v@F zFDPDa#;XuJNX70^ z&5hWl1(A;1aAZ&}1aLY87Gk|#S}Ym(n&5U}QneiacU*-Zhe`8qzq)-}MX$$LqRV?+ z87M*5Kx~L>guT6Kv2K?-?ObQL zYmN_KHqtCuP(HB<8yD;=I~wk$OMGx3nK~Jjr5;$v-&q;lf!|7J=Q|VY_sE2&!q+Y>G5c5v;A^Ouzlm=UeLSy z6&NaqVwZ`VeT}M)FM^7|HmdlvQ~W_2p)F+Z@L1D$?@3*rS35J;rZ_R%YLxX*`*0z6 zvxyEqO?8`Rb?$NX#6L6sW&j;9ZQBKS6l;lc9MA4y zyQCoNCe-8S(NkH50d;EWGzpD*WzqIXz5`94+@l2}hvRhxUul3!;KkZCo{vToP<%we z%xvwf2CuB-R3S$A##wG|_OJPsg?u##2>fqzcdiM!aUBP0LLfK7OY3idt|54cPVlTUEY4nP|s&fIIQ zv%T7Sx*Mcun&;`z7Zwh#Teq|r1Bt1jY@A_e+uj5Ux1l&7fTtH=1$Z${d?q8%u3dr-KII?8sMV*{swEhJb9Ky_ z(eBnEfu^gWK`n7Zuv_GT-^xUs zUg`%otu;2AL6RFq8Q`%Lh7zuj3<=A~z_11OhB8=6YLv`Ax0o7Tes@_|-}5B)3~tHv z^=qtms22kc83dLC1U7YzC$D*nUR69rUC36)mZIKF&-lNQG_9znFsdL`MAcV`jmXF9 z(zjh9=B-jx9F9~<*Q7f96+|w$Si)D@wtFIa|3&gGz)I4eunZ0Pn+c;iM-;Y+&um(- z8}TFU5|NGSe2GSL6uc7S47kAIFc)YtslB<^gochzgS@Iz-V|mjq;6_$x7CGWB*^=X z-AOMsu^qHG*lXP{V2eTVu*V2qBU`IvA!bo4buGfPKu&u)=0Luf`6t9`Ju*}{N%)js zpXl)N1b6iS3k3J*u)umd@3UQo`eD{ImU;Iqwco)=k6ppSF)deMng~?4E7W5STd`*y zqT|!tYR%dwd@e$6jyG{kWrgY3M@pD{_t(2d%Se6SNZJT?!wwT#Y?*w5L z1z8a!T{TKN%Zbx(T(Dmyje3$Cy7Uovq|UT{q9TfNnj`;}a- zf4@lg?R&q1at(phx#3{ynca=L2~pC_9pO}_cFeB9G01&BLib>-Ea~+Ph~vB%Nebs; z3;QlN_gjxR&vRlBw$#uxPjDgs$6kOj37V2KK4{Wcdv^D57c<0ob*843CfU*Og+Dme zjXRUPOE+NqxdNGLlRERn>z0+b{GY^MS89kcN73~vJ-%Wb1(gJ~y3Wz+^6HTuBCYPv zc{mRTbh5Sw@4az0 zB-Ie0T{e>%s0>8POcylNkrI%EYKepF%=le&Z7pvuc z1L1SZqRVLXbZfC2ii)^en_7i=2_PCCwymbJ5~EN4Y{HIbdPI|~R96*B2fHgkJcU}^ zC@g`@zmR_^QQKIF@uX&{2C)oT)kRQfKaY}MQ`S2NeEC5AKB@BQGY6U5&)VfnZj$vQ zXkCHzI)ZS*7Dm(kCehdY<7W%+(iS>VUD9R98*ownNU3N`pSNGt zAM6wjD%O6Xk^S}=mNyPu=3~z+f-YuojfTI%;m^7t3?$2QVfa*jYE!j++`K-eqeT6tE|g|#e9J!ILyAyPi^3HHc*#(fcX_c;`pw>;=nFf4JX27QS$%TEj%-Os;o}r9 zXNa{k25s-nn075 ztLSX-!pFOmp-Z2o*M4_Xcv6B`EhJxhU^G2V0Mf#j>R6^KB#-+ZVSTChq2%umYKHK9 z$NF$b1>ayoW+f_>8kuGW0T|XPumFVfD#Ruzi zk_kf)Bd5I!`@s)%hP)Ti%&p+jN!}zvH&S=&X8~xdnB?1>MWpZEE&jsD%0dQHb(|Dk zT7kt?L^<+v3z$h#=LoNDBQPOY=A9i+6_9?rC!`ZCOUE$)(F@rH1i2J zRXF9-{%y~0>i4%vAZ{_L9XdkgHreRb_G-XY=bwv}auV%$Ec-Ne(CKUjyoU=OZ*h3T zc8cgAeoYvfSsP1nWlFVAL6*&*$<(OMxD?sea}m|NcFiRfHVoq#!okwn%+;(~GY`e# z?rB3m1^h2gac4+;Iqu3HrD!$$Q)*r4Ncw|71-Pp8uDiI5fxJQQo{6cH5ZL8w=KXyf z+R9@_{zAOX9g@-ZW+ z`zd*BKDb9*E_dN~znNKP(PY%}&etb5fylAxHe%d&9v$wLItDlUj+fc=AuiiLKBQ}6iMCp;M?)Bu)#mb!KUmCgQWjj>49 z@U6td#M_mG*K_mBL~4ezl;=IK^!tLp+xDGQ?TlL!r|x$P`lX5pU#KDMb^EiE4Rv+G zy}3S9hR|AX>06|UH8ei8_ei7tzoa z=4WE!;^hU9n#|n7yiBazU_MTMQNaJew=z38xiERk$_8XXB;J90uoSXDqOU4FX95Sn zl-1PLK;t2*$iKYE_XUp5o?6NCT=fMrM}&XnvXKumOGI9r+BEu{NkpWL(jf! z(acsIJBU-*6E{naXbtP6_NvjH(DzWeoS3*-lCqS8{}ql%tIa>h9DI_8i9ci>exs5gNwyBSjh<5Q|w z_!8qI{-BuDNpZB6H`^p}M+Iuk9SiFe_9I`Y?yP_4;~!p5*#wtcmc5giAfsBN#}S1p zGXE+Z?zfGqaLi=AO@%jJ(qhG=Sb^?;-7b~bL?Wl2CNUy((-zP9tJwZB9X+YXivKNF7s7-p~Oh*NRriF$%Rg^#g5Qm z3f(^-jCvVR)Q9i%)h=5C^7-=8j<|=vsgX$29Y9`If;Tx`{3m#!mqjFr* zpIdvmM&DSOF=OCx`VQudLFaXs?T)X@^RAO~0_^4Q?_v}yS9s?@8=e{}T9{J|=EA>(!|`f;aAtIiM3CqLYbFam*lRS+q_ z0q^%)@rWV9Hb}e-+*M8xE{b|<>*}*!S9?0Wp!;0(6R8*wuq6yi-cO?*;){coo_&6m z*K?G*$$FY5NFwew1zpM7KEfx6Km$SJujxV+Hy?KIf(uy=I(+*ud&!Ogq+>?9?V zxdp{GeKs>scjBV%q;l;>B=Q3F`0RZcC_So+i>?2h5E-m^MdrrHf@KgCTO)xnb(eO| zzcb_b<+;3Hf@nI{ZW-&=e-6Z1`cT}n-KnL+;ACs2m8`}^pR~m!t&{8Px&zw9trRaN zlI1!9sV(h)o8Fn6<|q0FV0IO6*4Tof*fd8yHbQGp6`u@RWFjF>Z4c)WwZy=_*18ef zLO?buB@}`gm*3ELH-B+w@>#vrz3+-<7eX7eU71m9+it7ke^O0^dIsF3NEaBfUNq1c zHHv+hv$W7?Zd=`~cbJQB-Iri7Gcu^5(>@RH?In( z5cJCz_p)ZQcGuWeFQ|ckj;v~V81^?Z--~{b9sGzSpj2_C8zAgmecUigim@ub()GH< zgiN6N?ni&&vfDd#IO&N@0WkxBrJM$}xNO9NCL-TUi^i^=DD($;g5LO|AzSCn?nux* zOWks^h6_Lf|D`g8k-n^_g!eUZN~=J1W>iHjUI;y7Gg_X4jF_Y#2yN>VuteYg*y($0 zXw6nqS+f1{W=8il&WGxRT=t(Dy(~kMWwk_GVo449z-;N`BQXP0-Oi*TOMK;1k8q|z zpMl0%F=Jz_%&4YZ{&1wV#1-kn@MQM)l-(d3fCAXsyN#vn?_V5M`-as@HtFH9sQ6n8 zZpaet;mV-|EBqE>p&3$T&zMF9N;BY;iTj?u@o|?Oh zcWv$@cfS<=aBBZmGl3|M?_G~TBCT*;X_M$)LwX5{I<)RrQK*`;WW{iGAj?k1QMB%d z@%&Hu<3_F>AMLf(b#euN2yx?4DtUCQhZ58Py_-+i7%LoO{P|zJ=H4A{_|VsDLCxUz zhyDT*#pqu^fKlMfm-QF?^FB}K8!y}$sxoF>t6_(}He;KA+SY_=y!fVkPL88*j{h3I zin%J72WB)n9b)@rYIeI5rHy(ewX$m?}gL? z&#SK2z!G=^O9dAtKcSPNja#Pu>Y*(sRv)YUvwQpw?_kFS=jft9so8MKa(@(YWeW9gsxm>GKh)tzM91s z|2{?#eHytN^9_~MqIyWOZ)^N@T6xVw^%TFhyzCi8tI6@Ou}(19fETah_&!NhuY=@X z0oKg{eX;$V`xj_v<=eNDH1fD1$=On`1ooMZ%gQk@oPIoFBd9kcehBJtHB7!a`eR@e zQ8gvX_Z+5V)jNq1w!g)sLZ{>Au&FAmVBerJ=j#~3(N_Mb+mwLJ`3P7lP;|xvc^XGj ztwIpJIcM&ELE~+IkgZP&ZV#8kM(z;Vc-Vk<8WkEh14C6&zM zd-LM(a^`$Wc28+iahzh&{M)QbwUl=F@@c)91$~MA^r?(98?kyi&?{Mu(HWP!Q-`{2 zZiiOBTU7B8i-Aw#ah@poa@zVO)@RCGiXUxVY+sr0csb{laB0^R3 zOy9h9|A^i~+VTxW4_ZWgv-LQ3S8}LMdvOElXc(e!OGD_{F?l!L0XSm|;0*Trw&n$^cs$vV->Q8I5p zs94wNo2XppEML&B(d{b5v5=H3J0C<6@1BD57;>FY&zxg_{-#LdvOcd}%>Ld>X68G8 z-ItpjDa*9g!;_XAA&WD>+0V|72j6Ah94~dMChQqdZ>)SDBv^oAAKX~NOE(yq|5|%k zW8p@VOG2wS!bDr9&Klg>PX8%c zU+4Oe+*{0l=;Gbk4@_JzBem8{X$(~U!CN| zr_4}Ae7YiGm%gx%-p3<758KFBcFHQ%dHc4n2`{uvohBpwZhxe8BfJsRyma|=ir%k( zxhm(3W1g;PKwR|;N_O_9M6(b&N#pqo_Xuv@VvN2pRn$Se z%v)D-R1Ae@EGl}p=kX}C-@ah_9pOk_qSVn6)20-X-L2SuBPNnX=bAYb(+WSbv1+az zOt9``n%X%`?X-=Ws=rZ+_{^2rfor#jN#7+}!jMZh1Zxrv>q-Seca z9iOSrSZcQ5O;Sgvnc@U5^jTUOHs_Y8EfM5$DtvrD&^&AV?KCqxT@7Sjk1cCz$A+{; z8A2|U@X6TUVQ=_9CQuN0^~}$Ov(Cqa?fbBU^cFvKEti>yCyivhIu7U4+5SQ9!)Z1U zzfr*&q5n`U#QGAYjm#VrX#I*4^IE@)!u3=+?rEzWGVBDbW|b`C{EE8RU+F_Z)(T)5V<-2eULp~{I&qGd&9Jsw zf$y?IVtcPt_?|go)gb4}LZE(*-%eP$^5F3&%4`~>|C*zjHtb=-*K}9%&Wva}=Mr|Y zinQ-HUebgZ23cUohFe>qx!(l-K-YeUUU7;=3i*qp@b~7@_o8ya^OoCh!-teJtj{dh z+!knPu-qcOS@AuXoyku*Yp#dKJsAx!{?-~Z);+&XZ1vF-GPT288d3D-{nweZI45Oy z=RaR}R{k-O~s^b;@2YQueUqJFDv7FjuIo^%DF=_$fd2lhW^|Zoaf^^Hb9+Sf%qv5e}E8mn)6-W z?b5r`1A4+b%a9iuL-5FS3-={H9v7uqJJ#&!xp&;ahNT~Xz;bcA4reQ%&nrH2BW-^Z zVTzO=Z;woQ^1j)C?S7#le8CPSe4EKk&%F3*$^?d@Np+SXr!}k^UNb!3LUzltkOv%4 zRKKCisF(yom*h@UG6#hmoe7r0mW!Jc0l+|VKuE>2yZFCRsn6mH`K z6kll91kx=kCCsVGX=XId)E#>4Yfd^-^ykhHM^tOIZ>I1C6QY1raR121;YQNDEs>D_ zTCARQdQW`exFDCN4?V1;zNcP>?1&!plac@@ml6!^L{PxuQ7bQC4eCo>LP8r1ow8+T z6!~!WlQbn~+ApO*;i5?>pgwTG1~bYvDlX<7?C)*GtIs8-hEL9Ak*sd%x7Y91CO9;e z^z$D1>wW#o6+YiRZL9R7iVa07XENz6Jb2u5f8Y&DY|3O1qnuP}(e@a(k)KiAW8AS) z{E&tiLIj&v{usKdTa9PI1SzGi4iLm%qMwsBO%wW*j7WEf6+gu4P*_9?UszBaeo3p# zgIeV4)E-@V>>q767;U&IfmPxgeui5A#zHCBwH2uR>tWI%yGnbHfn6_Ir`x+Qs7bxd z2(&$20Xa9*<33f@NAK1;RXmYrcZnSe{#;x9yEgS5a*yIkJw{=pjv8@BBXvnDUKN}) zpq{S^X{NZ-_B|$g2_QSwvs2)YwIQQc*2eBFxfv6#s1F z+_%c8%ZW~;^gJjQM6ddY`oZ;b3*B$n?`7Vl7C->>0zP!V5w(=wFyEP0TqvU8ZU=-uiBTOXIkLWMMo#+VHoYCP>`#*Wh$aIyiP(bR-ahg;P%-FSObNEu zPI#n$(6n_F$gH?zBhXW=^IeU63p_E>cnip%)nlj=b9T{Y1c4c)PS|X>D#wM?l4QF% zmpv{9VB}#2j1wqSeh(gY903rw(?k=Kl4>XZK3jyz?XAK&as>8~?m2KZ-YzIox((j- zC`TZ&eaReSZrk~*tW^>93mEpqq531OM@i0gcCF`Ag@r1)ZvgS;-R}vE?~7~2?1b9b z_H{-R^9LIAEHH!~Q^+5_>Q^hAGp4D0b3sA(N)LCUU^w+g%{up@YheO*j2~!_^5FTi zTne4)@B-__W$5Y3xam{>evnNeFYE5nlO53Nf%5wd<6Rp+HCZ3xW1L@sn9gVK1v?9S zm)GK(`FIt4o-!@_`FHh~#EsVTksLs8NI+LyC)RQuU!IKJ?}66)b1!nwX=8&ekXC(h z{o&}Ju{yo_b(eaBf}Q34(I4V?V7Qmf5Fy#2--D0Ij<42x_{}0UgxUBBQr}4cT{UqM ztsd5^_wX2f(!V?Z9>VkGhc0o{A}LTA6HpjhN0-8f&hgKuq#<7vOrXpf_dc zsFhOME)BdYWZ}AQ z8spN9d|s8AcKM>sM5Bp_xS+^dmMa=SbOU^*7z^OS!30mu`> zPI@NrXP={Ja-i#@htrpVr8oPgnC`~xa11ieML8@Ye}chEsM~QE(d}7HUPNQE#G!56 zt*HbT*NYGh`#3qCf9kAlg96p3_2gU0?&l|Ki5f3~0qWkE>cloxu$QDOTStW5#Abc_ zcyL_*Gi%*MJD5)d%-LKZE=fNFj;WODd-3LJr_|5RI~q_ae!5%`5!OElNb}Y}6fuRM+7bfWvv%lT{{Q`;P zvRf!#19LGzfb(#em<%FUJbXNeUwAcVsCQ<&e18I!16osJCN^Ibwirp0^AF_Z1P&$E zmTkpv<|+#tSUU#REo|f&owp8Dfp*3{FKm;1YXE2$L;_m4L~^_f=pbt@6(N9OLye7h4E#woPwEUJ-LwseEgfWScV98C~_G zvMLkcHGR962bn)bS1=!9{N$l~kd_5~fw(U_mLc|(yS(>Xv1hystV9Q7DU6>(1dP|{ zC?(5p-rXL3fG3stHEKlbF{R%B*w^V17f!P566Pj?V#sw7WGp{d{tl*r5E)9@j&JG8 z%&*6MO_Wx3f4cST8QlB+_>%qwGYCR@XWsW7*d-|UeNmDW_Ov;$Jjt9zDJ@bb^?be6 zZv3CvN<1q43))kr3+J}*#31ewmZ9{G5wb}4zIBE@{ua-Hhz8lZj9?K1mvm)53(P~hIGVWXdmb`^U%~v2eeLSRw0c`xQTVe)2*C{z^%#Twu zh9#`dHcZlrzA(E>|A*7jmT~4uAp#lb`;U`E-OIizN$;~|F32-9t5l*{#~s}6i;MaE zXXJM3?L@a?8D-nsnfK8{i|TJ||LwSm?ep!Jt0A@Bqa<78wW zi)>*jiZKx|8Q8?0TRC%aG!gJyfCu|e(}ftNTsW)dT0@|x z1#l{;$65qc( zC`=Vjl{Og|;c8u$1eP<3(s^gf;*1T?V2pWH=2et@1N^iQ40!{TV~X4KSIvSn*Q|gb z8{Vti zny25LJF~d1OP#jtIjB*emW_lco*ckFZ_u>iUPwy^GDFc|K(V<67QyAkNlX7ng}wbK z^_tsUasi{0#R)l@uDiquap5W_AD8rC>%nfmIg3;`8+%4lUji{D^3yD)m?iJ|TH`oO zl6iG1wjYj9TYF_>!K0a_ZZ1#s-a+~E+V!f7vn4Zn)wpIVJ{!av$Yp9%vT?-d)nhEn zQUQr&&mD`%7EV!n9?e#JQh9SZ^#Zl;$2B_{C~BBRC~l3HPa3SWB=q@Muy%1y3&`2L z{56DP(YP(FbcBA@3izZ{X-yFk*S8|xgu$wCitbWPiXfi$?3FE2oUwlhdPW zWgYCx`VobIoFDfuFC6nlpd>-qi-7l>cm$gxBi};JOJ{{gcCWcLtx1FDlXIY75;fT3 z6HQ{%9~OM)y~o;S#KoWTBe`}(zUu4CaVnWg&;X9G2lgH7W!+`?_zQsi@SvUra`?}QSh*V11c9Zrq(?gls2VPR5f4zjBZ>Ano)gv&}TGy0`Oa2ni51q2>YYux)1B>LZcUazOSS@B- z@5lsJoi@*{3=D_U5WE`Le2xx;{`SHLm9YY^{12}GkTAca0VnNYZUzs4Moev+E9pl%U9{nS2LfySNurEGHfy`kE#l{sd2k zQp|Ser%q?R&nzc(()A%E0D>m)Z%Ty9Nb9Sw#Uu~bUeP6gOm$h*E+rC|_D;o~kVo7I zl=~06$*SN!QX$m05J^ebO8Q*dT&)ED(A1Z15f@Zp#4j1+meKsT*MJiM^LmXLdfQfy zY(MxH$Sw}%9k>eMZv=O|_zsBLAOZ<8ag01SJ}oPAgPa6Qwj`y`h=E-TVHpZ_r(xuX z`G&1K=3@<={4{RxkIM?@={Ju3;;cij06F}{7$f%tN=Ju5P(C0r ztX7QR@==4Oc?=XxhIX;}x`iv0>0wsy*DSB%(;#Ld*7C6iDG&=MyNw~mm~|9&rAxqC zfPX9jBZ{HrtIDK`Q}s8ZnU8q3k**4U4*|c;X)>gURk{9 zCPFP&brTwCLF>o+w6RjzSw8W}2H4i#7H>hM)-;qfYPfzC>(oH?JPSYq6mH(w^9P~z zep6|~)x-GjfEiSJM%gd>BUrkt|G%2UyXODX9M}QPVWfR!Lghcm1MtPd!q3I~Uu!6s zfrUv#fRUbsfr$ac%g4*i3=4Ch&B4uoSsy-yUJ%mYi~_H?}Va zV11w%f0YQIx3%9ofW1?lW7qrctSQQj76c{j^ol4i_q+;gr>-jck5^}RXG)CR+<-^3 z$_Sy`Fvu_vPR%WxUg}Lej7-&lyfoIGJB_{g$On#oN7xHQYheKc1e@pRFQ&A3e@*3i z5ze4lo5ud#Ful%XWndw%Z_G0P`uo2K@n}KOtH!6!S%MVoBEb!0>zRMLOl>>!%Z;fW zf<%S>3SI>|Ae|$JuA3N$Un%_NWoWH`ohwizYPc(;ajTO8cP7GjV_4`S!9_&}DQV$~ zW`e8SQIi4tjc&tqZLoiVh^CgQZC67_sF8$G^OScZc`M3)<^hp7CXvzS+=XqKSmdN? z`U?!2x`GXKbWX+m96WtCiCxdwbW&gA$v`B(ZL)m7L5J<`Q=zs|{yTNAkhu7^^)n^a zc!qi{L>S3k%xO&-43ef^-23+%{&|uaup7t=^s@lbr@6=7Nqz;=@BB!wpIC4rX$Pf< zjf;>I$twfv5ObtYsn%Hga#=jFnbP>HW@c!8<&r?<`Q@aQP#Iylj}qc0c(49SkzU`C#l z?@L#?0_|Tg9i4mO`ql*6n8V1Svcx~5N8*ej#5?+_xTXZ{Be;ALYe0E0ZDnDf!1b<% z6De~awrEz;5T|dUYr3>LQx0U=q)kC&m^Q6ES(4@8ubMfXB;ojF)oiX4fH%!KH;15B zWvyhvk$h9x!xpVcY+q)K+0rPa(7!34Qm@DjJFP$2~09z&`}{yH%*Pv!vvnJajmk#wg&hhdZU<)VrrjQ zG#25C1S{lTO#q?^&@qnF&{_o)jGu*rRtQotrDk=col@_t3a;Dz*YZG^&rxAY?k49L zA89t@1f#XL7^YQBDw}-i>XJ?BHyk`R^nMgd6SJ$Z{v9G@{6zAzux*~?_^jE8e}ZU& zy+1Qf7k$WYr_!j3v%3sBiSZ1qlDzPreOWO}{aKie`bRAJE&y*-9Iz%3lU#e%rkcP4 zqQsMdrsw2`LcQAES2WDuYF<4ISnUqv6hSV2;P@^tErbuoOJ(9<5`p0!ah6!<$jhpr zYCKCla(D^F4}&xKz5DN^b+(0zsIFMr_rNe4EtCrmiC&O;rSZypp-sVuh|yI(Q8<4_ zqrx(?*DFn$8}PuOPclG$JhlmjnN*snMpuM*`g$WaT>k+?`K{>usOH&?_UJP$_p6DR z6AiaP&Tvwhp<$en*xu!`B>d1X1g+nSbJR<7$}3z3?J3#1kQ?BO3!~3ZIV(JTkr`t( zM(uJds=zfFWuJh-__UifidPj^O0}i9yHkiVHhs9*R%b;%F5g_ujNQnyFTLCPrmGih zv?LDfM&w?Jj4u-m0_1iN-k&~o{7l8`!Zz*WTH=C#F~`YR>vk|B=JaNUDWO2l0^hf6 zTze8h68Vd?s9ZkfiDp$0YUDpm5w{;)JZYOKzIY9Y^o!Ru82v4md|q=!bWIS7(?-w8 ziM8mAb=MEY8=fBQ5v+@@#3>6DEqSQ*l;f+{@_jJb96$rhi{r}18s4z=99D!X=NTM1&nq%= z+!d;E(L^N$BmEUWWLZQ?_pdh}-;r>svQt96qyUl&%2lw7(H&%FJm|naBnqB zJI2Wp=(0(Sd1dW;`JuhNC3zI!l`46h??BYOvXpcbXiIii5Sc94>M?4KA$-m1af|S! zQgT!nG&n$3>E#lfOD@6nAPxEVH)@fF!dbz?s@KluZ5(#Sp&f6MF=gDBM2Q}M$20#O ze>RzsCNy}B;jc6kiIw-75Q75OOj54aIwwbFq*Uy5ZqM1DByx+MxvIWcS|de)p~}i= z^KvE%7&Jf%X@)~R%rsBd`7W+iYC?arh4_G$XOg76xU`)b^@vw zbSSwJb6bHANUh|mLp+#k=*iZt!biWNTxvT)!nAdNv{Q!M2U6k{;HGZYY&XNZQ`jNS zy4vKibH-SwTpv-qZaROwGlTua>MjdZ#eP>g`h_>^NISmERj1DK6%X=ic49j4g`G4s zw4cx+@u8HdweRZ{Z;0^qF>yKPtxw}D!?O86c4AasN7X&_K!lzS9&Cr0ahTpKIKsPA zD~Uh)bD{SKp&`U;e3O`@TJ$;mez)mh1&UG%;C zv*^V}`PKz(c3v4HCXOuSVSbyQe7ePTIbJh&_rc^FGD91gx)7;8b<$|*3EfO9iF9ur zLS%Gh^HA2smJQzc2y?snikNH0PWME(zfSFLd~U5tUzz+*<)Cd|V9boqNuroMG+UkJ zbgjOek)x?%*B(D+6H^%`_Z>%tS+6^`og(b&Y1)c^;u}!*R`(5eL@iF+h8vT?b})$< zH^sTydPXGXS=qWCTz~rBby2&RdLLP+vNp~D3iiRpw;^T9dHec@oTBPn*IO3NA`t4c zrWNJYf*@BM=8mA|NTr^gSOM$H&IV&bVSA)oR-+Zp7Jp0$T~o{pQ!Z=KhvfJ6 ziY>C<^TpXG)%~8sQrKEYogpuG%x)ASH8o@@p@wut`?I7Q9X(lj<~_k?lj{Pqj%M~a zd}lxh=06E1NuFjJx@i$FgIv{nL`5NyKpS8nCc7F)RQTwnw5v>Mn_Ew`%0G=n%?rqi z{zFLAEfGTnR?)9C4aGY~HG^as;E3y;WpPf%e0Ak;PW3t6o)KyCQr2qUT?gX>%jG|9 z|Mh;BX6|6L4u5#crjS(nUCBq!qs>QF&k8=a5;=vR02M&{41`&EG!n(@tvc>DX{$S- zqHE9IeAh>uRB~mh2TO_lg+T-_{-ForiMc^Z-L<*Gn`uA3_YX4~ngsoePWqUCT6qvW zy?Pnw4g|a*W}~1`sZSICSd&3bZ~T^1Ao=Asu|(MP5=KXNHLk;rX4`tNAi<1l+uxFW z1%tfU`;vq5i)jA>Q{PwLdi%mI88e(k>!w9h8X=Db+w&DMEhxUeq`HR!kRr3AkUCg$vs% zv%^!RW0}I7?u;aNWf_CC1^b(t&rGYy-TvS^-`hOE?y2MJDtJf%eHarOEAw-Tq8z3T zkzAN|Y}q>+fu#@OQ|=%~4xaDtWVSX46FmdA0jVKXlw-fMf#&LWab26KM|ZEL%FG8{ z3nXspA2p}Tjr88M699?r@AgOxTt~*9U%%y=Iv&4TjA>dcXpk(;h+iS?33)t!Jl53-yxP&m=OXbdPfqn=)VtPIWI2 zzgj8h{O?2YaS}w=;=9Xi8l$0BVO+*qY=&J;-Zdh@<|lvHb@KvMKn5UV7KB2pt)ayN znPC3f;f^9mL2QNHZ^ZSujXNJwuIw*4uw$s#Oulw9@_Eo*f1A21w!t1%HxX%4X|+(1 zIjto-;lI~J^%;u@j>`+s4E7%^T=toni+3eco)|Uu$+f4#rkySk)7Hj~r1AlPUC*^z zp77f}7K-+Tdz@A6gY67_1ud>FzMD zV3TiyN7V-O|F(3Z%+8+MzydJURRS)F%_Wy|-4l?I>9NuU@x(y&P?i>6o13))Zqb2h zp^Zok5Hu~J5C7REI_daZ8fUCeZ5FCnTDhVVz2#xTvn}e_UJxIK*oH(#rm4Z{iW6(a z3X2JSCB-)DKFz8FQrxkNY?gzpL&d5I>AqMBCo{LdJV{H>_5$Yb!XS~>~* z!y3#;#`JgCw1)LYN&XNzfz{PME}vsGwH{5)OaB}*I}&&x%y@A9R9Y@?ZJGP{V1Kj~ z?L;~b^m7j4t!*n_IRC~50($PhiXka`zCt^~birmpWwipv>0_qu)+V3o!Rd$8;&6JG z?PLLb1E(ZmXkx_Se*bxqIUXgNt}p{C+C3_oN0Rb)VeEFm-C2J0AqgB^wbc4~HR?>40H z(+K(C{mzEkrpXZEVx5(Da8T=cP;MjPK#@Cx8m-u#ogWAwYc-0_q%uI z&Sa8*GMUMqbM`*#SDB)n79esKPF8wKdJYai9pM7PJt!$b9DpB#ik6ax z`J9%Tih_-8@qm(z7feIV#=$}b;$~-|qF`mEW@VxQkeM`KRyGz`94WbchrORCZunc{L~pQf^0dO#lPkASA_I9KC-7b3$wo3ok3^S z+p~xM*4L_~iu4-1n$c439I`*faf&S+rd0F8;ejSo;LUzCtmGM2PE|N+oRYCXJ9s6y z9pS3WaJ#~OJ+{fpzdJMcb(@Ay++-p3zLCkv*8A{vL1PS9x9tN8_iRcwT6>v$p@auw z@z90S6RnYE%$zjwQvD>YB?fIL5zCC1FOZq61{1{Q+`_7M(6RWSh2O6HJ6qRX z%2K6bjvm~pJ|Bssq|81@2A_R7H`&8<$8*q3^X);+I{V5qoaDkIc z+}ZuCX233{sTAP0Mil#R17D6HYA`2f6 zpg?!P7&#l%EqZs+H-o4)dzbZcw#zlv*mg_7F`k(G`NO%-PBa!CpDdF347|j-hc@Q7 z1P=Cgk{DMRY&w2tn%iCGnn;{3LVtK5bNs4^=4%I)kr+#qhcw1h@38i)60dS>@OSh5 zwBfXIZ8uS4uoN3AG$D@xld1%sZ`hkF)0lbO!=AM-d&W<@+Vi*&oyb{U*&znZ>176I z#zPNrp2Bg9r83IAEss+?EZI7JxCB@V;FDOxoc1{r@#qpGEVerj^s9%^e_7g^?J4YY ziG*pEOg_0C*%=AC^D9v02e$9Te6oR9lu}rnGBB*DW>!Bd1cTU{zjwlKQnh2IG%QDQ zQHJDKC?sQ7J+g>M0E6mLMv$(ZzGaK2sMO+?5jLYK4xjd06@i4X{qVc-Wq5c4K))sY zX%ezrmHs*);=bOZg^YXTtrSmOM@s6vdU0}x!JyO}{lcGe{+8JRD_4%JY!n>}2;w{n3rEEY~6-W5yI}uE9xT% zR1NgWHHf2x;wpTMBQRP}G}D`zAJ!V3Ff}uGUHaSB1APcZbgMQuGOJc7pSV+-rLCz3 ziS!>1gHRG~ub1J85-wQHD^)L=NaQ zyGkQ#Jr8@w%YsvXc{l>StYcIjDJ!y?9-d2s~4Q38%^;cdBlr+Cnx`AXKyc|Gis_c06j>p8Aa-s>c ze{nL>S*DcBMuLxj6Yd|3pQe^Ui3Wi7)z?ta5Gi0_offP{pj64CB1k((GXow0i?~|3ghSK25Ks{dYv{;E~~?y0AhkcORivUZk|16 z%R97!+(k!g6l2sGP!+A7i5PsvA42s3niL00*tmAzzq>wWRB%Tmx6({Gv=} z6iu%mV=59U78k5;Xy0byZrjXDf{n@sU5)RnlWrm;^0_=PC-Fz__4@6#ZLdeu!=j2^MGMgM;F099xPUqb0^!;^;HwK#!7a^lwN7EwR$6G(J3`F1((iSf(vt!z+6k&_H1uX$~74 z-}FjVRkO_%`;|1GO#TU{;p1+TRg`WAsToKBvqa>L#YNDj)5fCEJYyrgHWV%5lrw8b ztK#7*!t0U{<>@!ANs83mWnM?=p!VNOQ%qb+z(XsgBy9cRly310X;@Z#MJbnHB#5>wep924t9bbJ{F~mknBAIM#q==Q zvVwNqF!MBzvjI`J)HsjiA>u!(ENk&?G&uQBtg)f*&0Hz|l@!bs%+LGn=Ai)t0?E>N zMcxAPcjkuS`X4r#FxcEXKLr!OFG^LhM49wn01JS{wI^Gh#<9$)HgTseOc<70vU`FpUOskk2gvI&@ zD}C|sDzIa!q|?M?@4lm#J^PKnA)ykDhnQw}<*lPB@k%EpvMwk#a{ZS{PMz`DtaACmKC;T%$tjjn zlH}?~5uvW8v3L2O1^r8w)qk;9n+^ugkOg_xw&&Uf3{{j|kB0v1+bb}TF9;_y@Nmsx zxs0Hxq#SDiC--jR(lfr^6jRGU<;_^=_d_&oSigT`V&X8K#l0#b!0|+(n}ESXEB9mz>H!lWFiF*$!!8huMyin8|LcxlJI0m7o3DLsVRKAJ)g z82x^FsG9>T$sMRy)Q-17!-RLXASsG5+9vyZvEfkblj0Q@XG7<3Dsw^#Da*exIk`wA zLPei9Gk0J_7rc~c9Z=%w-6{mVnmS5<4}YB6$rk2eLw5j$oWw)1_$$`;7nGL0wD18- z(h3OW?>%fFjtrHe(9Wwy9)H=%saYyW@2j)a$@JWGpYYYwAeasm5qEUM+AD1mPCcN>`6?(?|8OQ}!F&&6*9Yxlr*91$bV+S!F6r!haSCzK&u#bnVGp}3k@ zRbvZGsm~N z=5d!f6Y7WHn!jqmf~=J9BUdi?ynR>Hz@j%BS2&gz(``0&ie!&{&R8Y+D4?={1e9`H zl_o{X8!sNEX;MuwGmDth4w5*>8|^Ec{3NUnF63B{`J}w>Q~5mmF{3hLqxoh}HUvtL z9iX{iAF)#?wDH2lWKVBaWyqFdbaoWLv4wh;G~)B*BGZ&h|N{mW`@y8MN+vjoRsM${Aod#tqeJsvBO=|RYQ{M2M4)7&~QI^ZNs zx;KW9IhL)$iryUFSLEi;90f+(#_NAJ}+(Q)fP-Zoyw*Oc^9h2LV~KeiSaj9O$=XHO6 zV-ow)_Ll#?AdS+k7j6+eNiXX~kpg1L!Vpr>B|=8=Jo%%l&(W||f`6>NT3F%!qR|}s zDhc~v8wk@>s#@o-vw(uA36EJ*tj$WxP8Nq`UV0Vzu~SPu*9 zyZ~dc5o8v%_41G{ff=n}n(?pShE|5(S$m$`F;Mf~oZkC0WM1y764XvN7ylDrkHeVOQ0Uor%%=t97LEaaiOzyvi9ZYXU#P^! zzkC_?N&I2f`5#m4tM7gYmE+qvzgYrNoHM+<+JD;gv*pq5oLfp zMEC%1Ah(?3=ZwQ+_}3kPI3JOs1hxIXIeNM9EOSF+@k<~0wc`n!1ouJ`AqKnq1XxBY zu$(sUN6;$RYALvxbC|Jh4V?aN{d_##-reP`f^)s8-bFqEaA9PPUBmOO^s72(iK)n$ z+TrO+or}c_%P6{*Igs#tv2aQ+*c=y;%8S z2d%WcF+FrDG-biQnALMok;MCP=iYR(sgK8BPd>%IqmYFU9>xLz|Dl*k^9M5TZ*)`= zoG~jp=cWry6?N5GL9M4clV1|qup){-Lk?)9U2Akcbt-uo%@#UO%995z6D6$%zP>S8 zi#|`arn6AMN<-fQixzDMh$p4=0AwunQae`Qxmnldo8Mv7Drsw_} z|DdL3<6)-aW@VyD-q z2#DeKm!>v2Nc1GR+N^sD%G`*n*- z#S`;k-cdl3mdPP~kMF5PPE0;`4Rwz#M=!H~^pNL-j@t)S-;zhr9Jpwj!Q2LE=`5{%3qGUlU701Bk|L6nCKA(?Y`G7y$fsN;vyl?STQn0 zQ^2PrMO^ra{3=e34D;3Hhwu1Ze2ItJbXD=JK7adVBMYrpsa2NauaL}Vae``xT?gnA zQNdnOu-2B-Q)qV4ub=c5DY8}u1&!y|zpYgwwmy2~Or0{1cQ*xPD83I&n?}r1iQbPN z_Lp_YfPq!`u!)q8?4}$VS!yNFkB6gPwa@6|l-jJVW9jq9bB)2Qp0$7fpL3Oq$*-##AaMtBQXloDWhfy(bhRl!wOi1v$Hm~bjK>0@JDL7{ zq>3ked@KV2voK#1P)A7dy_=ja4y?kI6KO8nv1FjAd;HL5D5 zZq^w1?2&bCI<4~Cnd><#K(?dSX-Dc)f|WgBnDQ$^wq3ejQnFQyeL_#j`DeY5@i-pP ztTHTh<}h=8Uk=u>z=H0vI!YL+O+|WWy0)870^6snKUoN}=@rL^IQGNy**RUzYue%D zxj#51T8x9d(VwM^$ut3XUj(YuG!L!KO(Cw!Vo+%FWA1$Ivv-=Xwk9@(4BI@s)RPUq zDr-y7nf>V??D!c5Lk5Y=hrvlR%iTL~kEZm1DZf*rslOuzJEJ4|ATW_lQ%Qy8o zv>l1B=>jTw7*qJYIGZBxecvuaNMT*y`yQ7Fh8FHgLF5qLo^<2)9nUu=A{7}8>gqK*K!swn%3>vNEX6L4O3Z<#Vg@L@j z>TB2I5GqT3PLr_ucN&{WJ5O;0-L}pCiQFLEQea(o-p-cU8&7__2%EYQGXk2PRUC2x zn@CE1*-~Y;-~sQa(zT^1elPd7TRFbIJw05{qyMY3LWkUm>nSqC^fMmg$bfNA-_lvN0pAe#pw64sINw^|h6>fn*oFS64-C2KDHd2YdSs>Y_*e%S ztB3QHwA7hrO3l8y#eRTEK@LFu$sFWlB=l@0MiT(T3*+f6hWnt0m#OQ?j*8zjlWB~j zefG&d>I_lt!2f6Vmin#DQH#Y9hi3QiC#UnNQdu|W#TR4e#yR2IKkFz|Ksv0+W+~W; zRYgQNUQ8!Djt7^vZ?39DhAvuZUftU5{U-j2_~wQ1Z-U7Z+Zf6o)u^(3Jl=~z)kw3Y z5tt~@M&MXv9e&OabN+RWjI+Cs80!^jkJ^b++A&Rh!`(Z9lCPbO-)P3^Q}sB5?a6}i z!wHa;m80G66&6GUJC4hys7MyzQ8`)g$GBpd)ju-@MwqSp8=|!nIAQrt!EVTU@t}P* ztwo{LQjPi{rIcORdG$v1X$`A|R(i}-rE+D7*Qup0KAlRCK)UC;-qQYHZZM>(Lx1aj zv$Af>cHCICZjpmzbwFLyag@s*T}Da$RUlf7B4XR~h&(izxu8-7>%!xlqr%Kf$Fh2t z^_m{GSMtjt_oPAbJi82iQNXV91J3J`WbBIw#=Ii!a!eZI?ig(bpT`~pyo<~&qWoWl z>&&(q|K#P>dXYDBXV=Cg(nBzdfq@X@hlHFN^?n?REwXJwlmu(|HyD*7N*IKDn5;6- zcSzKZuz#;GU~IL1lo69E1X2mHD!dcTq`-J1{FuV;NRN4wv}$7qPBX197TjVzkab=S zaBJjq8Q<5_OklSy($xAw(p+zKW6I}ZKjW_#4yHdcHcKaC|MN-N^;6s}=dP^Y^7O|< z2_pvgX-9`sF4ge+pOg>>VX`T1rft0P2fPwQbZv1~ZShf(mr~9IY0}R&gPb(jJ&A#z zNZL}UH|mM3!c#xnk8plaac11sI`E~W>Qn$Nib;-P4k1U`@4*D{awBO8OEeWVBmaN< zS1h7^-Fig1`_*y8uR;5d= zo_7{=bu(Hw#*|X(IUPkcl%-l<-V;ip`WlCX+4;Qm*EGPErqFkwRY;_aMS84$^i2N8 z$VSd_s{(0t1`x79_*LQAc~Gn=5FUQ%_%<9~uWA2+$sVF)p71yriWm{L9r1p zymmKDi7}B&c;?+s=)u1jEw(8VGRR3(lY!A`fAS4L|450-1A(-FBIb6#Xd`>7+7y-PJ71|bF1dv(q);6 z$;O^J^?qMwOdqxcPUZ`Q5->Xi>`y)DeH$3k-;(zwW-;xu4fVy&y{vQZb!>FcHjZL+ z!Rq(6bgVOB%4|GKO<>bV=?IwR<;I^-S_;Oeh9cBcwogpnxh3?+u~OWtBI<(uN&@=^4r}obVCED z@!vM2G)U~?*>MHP$Q>PSyM^abbZlm09=dm;f|Fbkn{_Vd)5}e6E83A|jL=wm#DcV= zBW45Blp!@QcE62UL&rv^r#B9hM~JV%eGnNfqagZ|cO0 z9{BiUhR@w|x+1c^?y*26$oYHMs3qRGkbms-J|Jwg*EsO0obFGw;uQ7&;<8VPBDI5SPF-X8q9oq)>K4&vbSgRx_P|p&1&1Ow_fB0+ zLe|ktq|`5dGxLMoKMEdBIb!2{IsIhHQ8$R(-y(H8!p+&>rcGp)q-%q$)I5`g4pa6zK+XK{Sl}BN?k0^Z0x3@s<>UP zK{-Ym|81q=a*}@1&5Sj(o`^Q=lSn@g&3F~|%v~$-DN=FL$#I(%8h@Gcd_eQTT7Y7? z72*Q-9w9(BSjgLE-e=Z0x=n)uMmQ09(}Nm#X-}9Mefv*;kNX*$+YH!-wcgC@2cN?(ufZv}y^zViDjUK%yZSm4^?ORDaVXpO2EiWf4 z3R{Wl6#m(s5so|MQIREyC)MBXDLf|2uUAInuv)U)ROP!-vKj6SqUOq~cn%~sD-RU? z#P*F|5JT6eBkV)-R7xnt>Ae8q!{e;V>~mF>D-g2-WL9C{!l4ct&a?gv1m9E_cQ!sb zIj^cYa8d55h$g;H4J9=>s^K?}=oy`8F}RE(Y{RD@izdN6BN8+w%Su4Leum*&&+%#q zCHqaF(#K)ItD#J>Ey1IN^3WvMex{q)exmy@+9Vzp@@3B_rK{_(`YS1M0z%Hp*i}AH zitI}*_TK!8rZchT6EA@{WaN4xH_E9O@{1xkOHxLgm$p|MmsDKf&j!f8^znPFDX}V& zpK^T-4*R?AxnmXk<}osh_gJq^MGoaf%VVNS z0ZX&m%AXn|>92{4Ry2q;Do`fx&MX3=6d(>nFeTic!n}h@!YN2!Yx(-PO&4ICktwPD z;rhDt{VpJBEr6X^&VP*;tZ0Qk-D>YQH3~hLgTMY_mol|RLSm(23DSn z&0^jfbx{&sGgB#Ao9&zCcysCtFR8Ogc_$ zF7q{dt)wvJ+e2NphCTl6Tb-Auku`}6Z0f3vIOle?RkghF_j_HruP$IW#k{W;T1_Wu&TRL03`-5$rM?rW$_r3Iya*`Pdb37Yr^fWU|}a77`uD(fvD6JAXlz6t8nE+LADnrUW!VzM8rI8~1R zMF`kKuL>d6O;#9e&;^5vvo$8?pBah6X4WxI;AZv|$ChZ2zPS9ZGuk0*gqsRaueYt6u^ylzfTPGhuA&%N8? zqJv)5gb-=c&S)MOL0?F^R|C@ZqCu$q`ooM2nr67UGd0ov z#l70e8E%cZ<^b3oA`1UE3>WX$KNDe6p*V+}N`&plrpJrg#mb@i<_Ay9N61a?!fZAw z8C<>69|e@bSDyhFRqfjg8E+ow;d38f|3P{{@rL8&&GBNdT`R9gMxDB8;Nr>USzG!hjTA z?pd#jD-ply=DQ^q{^wn2P)7@D3(P7qdcI^p3;h28DPS!BPi9~OWQOO;<08h1Z4iit zf{K@8b9?-dii3G?Vvm}Jl9`=_8bnVG8q>wJe{Kwp zwLIp(9acdp0z~er-$OSGDp!5JS}=TGG!x|l?d#^ge`le;?1d7~CS39us}*;mO0}Y6 zO<&$W0N50-VnYNXWMdO21_#~xjCd1K!;;k;Jgj_%c4e85RP1Wh;F4<&;=oUJwX8;X zjMIDxrA%0MmTZ$R_aCJOvc2Z(3{efnu#z^gsiT;`_kWWV`xg=be+%hFlus7?`w__s z6o;H4xpH9kZsUQNKYR(4-t%lv9W)@IU5{3;CxOEOIeYU+)z#?olx_3ccS&E@diH!^ z;lWPddZccS;U#c=_L8njCYJ2OC5q0)uSXuNA`-?Z@B^3me-{hzCGbx_*0Azfc}JvF z^eHCR^R;<@;=DLsk=L-MLOt@xIGUc6rfnXvO|(Q!n=~z10JoyS{!CVOZu;49Q<;H zJHhP!mRW!XD4z|Zh~01^5V4nm|F@XM%7(!pN~s9CV_dTq5mBMh!O5hLN-Yg2g$KxR z4NZ$*pf~wJKYXr&b*M7wG0$*@N-hyC;%37M2Zdl!r7R0kp{0FmeS&DG958exa~v6U z$HrKysJV94DTA#Ujr)rr1JivNL&YCZFaj}GsU(75c1l}go>UE$c&Z49wsW-aNJlc0 z>s=$9mZI8W%DeCNr#imMUN%Iduj|&JEm4b2H9FEK6*HD|AItdVC@ug^C;2OeqUtBc zSBT2BXan4#dr(Ek27~M7K#TFH}YwT*8k~9Ytkc<}#J8mr~txWj?AGob^ zBbOy*{?uA9ap%JIqEpRz9=Si3V2~Q$v&}m5YC*Ffb&#A!_r64gw0bpM_4_;jV%wQ= zBCSF&l_Jb0fuF&*-#Ql}Ed7n?RcvmtK3O5!SJF4TOy=?f2q`v!G(= zqf@K_h`^t8(2C-c44l$(7c9rpAYJ7@QLu8i_Vd9lEOu18;$0ihhoWv1>OhylcA4AgZ3lok4cXsDvmGxajQ(e zhx0gMuYu#{lhGJ>DHj~Av^F!pYW=lGagmS&vOf@ZBI_K@B*9Sn`o9RIzx!%C>Fe*s zzYtV+IE5SseSORHlTaF*p0%4~Ep~ph?OHwlc_mM89ywy1MD)zO3{L0Wof5SNe`Zv3 z@p2rgm11%^PcsxJ;@%$`wZ5#VelVF^6eVnKO2N*Izv{!%J%|^D~ zh$!G2AALGjVne5$b0)fK`sZrQ{}(T>a&l-l63*YBIDs2M4F-tpR2CyO{>l}c6+GVH zo~oXp+Dv9svnukWW__zC6{ngY`&zNfK~>(6;4w5jMJ(tMCRNsHz`W`YDs!ti`Jqa9 zMm2^@rZPScK=dQ<840|MVQnv^vR~6q=#x*>g|WN>7M;Qw?IibAhT5&BQ~yp|u*98ST@^Z>yAfpDfFG>C z(#r!ck;NyQ^jrYMR&DpWK+Kcbc@-5GSL=2pTtfJC%m=r~o-t}1vY@d*_d^vfqiC*y zv#NN~0VZxg!6<5T+ z06*-Ajsy>yr!%I9Dwd@3Z`&S~M-w+d^V=4cNd*|0&R*UY8rT2Tq|hMv!i~U!@3Av; ztzeDcBQ|=2?p%1u%hP|)F_+Q|k%<{xWozUoYfV~-DkvbuMPc7!ycKhJtaFdW&-ql4 zNBo&@78l&^um0dilBu@j#&d2vqb@+aw<(-+U1@B6;ZNktVWr1b^!t%XBd?sc51yB@ zE}}j{2|ig(fFG^Uv--ZT+Of6w#Gl=e%4$S*rk@pAdmTY1$t zJvqy!$@35391NEWCbY>{oS~}ZZwzSpgi<@Rc?`Qo&$6{Q_9^!1lGiwKFccDWJl}EC ze#vuWqD4jZrdYghN4bfC?|DbyS|ls$X4(#it<{g?7?Y*I*I)IPsYT!HF~S@}x$S2& zic7@g5g{*<;?tbGP~XgTXsoLmvocvWbkIdP&B($RGgEZU&Rl{(d4#u+KoWTEUh`lH-j!Z2m@;(E{-D+jWD(=Cm|Z2s;q&p%Qza>X;aAMpA3})w zowIP5&4sETv2eJcw+}e)G%>HvX~h zO-DQ>N(xBju}+NotOyshXFf%`R?N8arz%aU^ME`ge5vXqoLgI*S_%%5y28hGZ;6Bx zMWW90MBj6(=7uVL#o};R)nO0(QKA-PTz+gGYtGrWF6Z$%vQO%FG&A)x`w2C#8Y*O8 z8npbTELxp9C@%&Yod&H`T57>?p#xl_f1;QcK?op0MkN5m;pn@AY}0zW!fiA=J|7zC z?G7h$f)$?zUYMCJex8)Cs;k@LevcvzB?~S>R$J=eQYQG-na_UeTGyj*iT;H9$C})2 zs8>MYH0J3gQ4t46Nq(!GZiv2^R(t)K6<4n)D>@QiXp#ELhyR%#RA+9|=AivwJ!Mf>|181v%=C{r=8(hzW~X_4It zdP}Q-c^O_-xsLj}U_sKod4J-zP)gJm_(KTgcMD5i$L5M7tp$ z__q9BHX^IhC~so&pHSr1k2lcnUDHfnXKSm&m7+%BgZNDp4(_cuuM&UvALDb(PskU8 z#UBgGSId-{QufdgvhD_wu?Q8hh^tiM2seA(hPpHu^tP5Dhug{rsKQRMbeaVoP@9bnm5`y?~ zl0_ZV#jG`sC1%32{dq~>!q$HjA1YvP*%!pNw^zv6trlfx|LSgUPwp}*h<#6#>8wu@ zQ=W9_om?e7Vm!~QrD%r};UAkj*tur4row3#PpGiK_07K?&Cj>eqGfnB--ir8)TVBl zz3Q!|s)RMI#L#l_B$xm@5v~T#EpKGxNn&_y$|oN3iW}@&9yQv0u`5-iwKQQ(iDS2~ zKZZLIV8Ss3i1h|SE+VNM1xmc0Sk7561hf-ksE#!$X)vAN;J_(H8WV_Ku)ij(gh>r? z+=ae=9Nd2@R~;LRtj42r`7L>T;U?JZk9Rj?jS(D&B^o>aLRE3MTf%Q+V)kNWR^L9V zyUy+uXZz@AE6+X=5&p~Hge<41ed0Q|>GYq>|&!E#`Q?j}kMT%0w#&u64)#lZe z#6{y@FUAVwX?#rWk(Uh)i~7!ve5^RWO{W*zR=LeK#2(3GfjX${ok^}Ly`-fc+I#Ay ze191Q`DTX*kUcI&W3(S%9lJGXoKWmf zrVg|T84oK7rz98?|ulIvRpQtR!mRv%4Z5db^XQcX|t+Mh-5>Y`IjkQseZPK7;oh@Mt* zaPz!llyfP#Bz;Bm@OJNL@`(l7N&%yQObLV72)kjdK+_HH33K83X6LPD!9!)va_yAY zUYZtPpQ~udoot8yv~8a;`#5$_eskr@v4rzMUr+a2K}S_b*-DNK_n#-?v9#Ze3@Nrn z+iaX>^;q9UzAS&Mqp08qaYdWy>%ywD9O2p7R`=;m@0w0uQyew&%VG9KuZv`-YfK7- zs_{B|UaB4)Y-*HxmjY8Bkr&&nuPo{R;D4!k(~rI-<@K~z1W$~}^wx@(am+6F3R8w9 z2FzOX-$ps0_+?dR8GY!I;=_nZ-K^r4ZzGQx`DCIaG?D2@C`PFA9t{Aa{k;Yf=d30E z7H7U9$j=VZM|?lN^>bb+yih(JJq+hTMV3~C>BZ^g=k;{Vqm5DG$j-=Zb#~50o34!( zu(RRzQD4Hx&4LvHju6uj^5t5Mzmm=KkuJ;sB2#t`&p)N*))O=qE`_ghkRhfZ{;$CB z=l=u-WjXr}Kuy5{FfZ9SIM|u_ph8A9JqU{>Q~xaJLtwzEZ?Fis2zi@Vq@uQLiC~t$1fo=niW$tc&_3Bh%o9siL-ehgmy)IQp$^|(Hr>WH2r>A)tRdP4-X znl_+{VTUhwY87WPr22_PXq|r9&7nIoRZdm&6uq_2YnuC~+s01)UgIe~GEgT05qbW& z$rv=tx1w+feYx4VT&XJFnca3!G8im%8vlUogGn_J4#K;v95*yCJ6J0^6;>e|wj%OKE7vphjUOhAv~OV2`MJ#XNh_svi*Q3;J~43$ zyzrB=X<~Aq!vm(k@B>KUhh@eFbLrCV4q0NA{koM9){^xFbY&Y=e=CcBFX=2Qr~pG{ zrR!*LAjiwW;C2NQ=g95fxLHK>FEwbS?{cK|hu$j_A6djSV5xj}X5dlRnDT#9ROgcO z8vVc}@KJKZ3;3+;qPZw`lB?Cez%G^BCIuStWpDwpV=z?yi9w2$q9)zJ z5*yd(cj8BMJ}EfD3`*irs}_XsP)^IHSbwweG@*tHAtq^}6h}3l@6{&~W|lbr^RP+U4%7E8k8MW{dyVrlo~_QkuLg}i%q($r(-l@46+ zhxfZ4r;=vcshh}Z+ta0G8IKZlC`}n#!_!3Zyc>P`$2^{5Z6j|J>4n_$t8ttz|q4K0T3DKJEn_1c!_O1U4R3Qy|{M z)~=++VrMnjUGTeD#ns*4c&hbwc566nA4&`(bl#`ng5VSRx2h1q#m z=bQLoi0Z5N?(Y?U$K}DK_`gaJaUefGiH(V&?nXI+gc%YI@*vVf2cuJlPwSTMQu}rN zMUiAT#TJg=UAWA#*3!!IXwj-STRwJo zNK!}u)SwX4L6wH0rEDdL!(CnTH$AH8R|?OgV&zYHXQT20+*6B2ESW9_=zc5);e%hB z-lT{Caw*zRSw-@{7JOfbC<27fuQU4U&n1tXD;4tvL{-P0a9d>0>ScA8Wtix9j+bR% z+<}Rc?)Oz6nD$_-@^OSDQN82dhYH<$1z{NEILoYhkSwWcs^-_kC)8a^2&-1tyag5N z?%R(%UhA$YaqTV^ytf{P$ELBgS~ANVWF$@p>|^{KX>r!bKP6Xj6r@56CKyRK9pn@S zy9Q6UEMbCMTE$XIWW^)N+c_v9oF_19YutAX zH@aKMQ%F@S{0zp(g;vLhynm}ePf zu8R#*;b}V%0G8vvJwSDZ6@mG?>KP+9p+F~%;vb$N%V_AS_k&1P3^5(YJ!4;*b`__f1XuLi<0+N2$}HMX1` zqS|h8#e`$zaAoCUbEyOTDQ9x-l|pk@Pl_j*)CqR8=_pkkoj-`Ep$Qo4oEH6rYm(&W z`l1qDIdal^j5?h4ZFQxe_;8ETfBd2{U%6HJsN-3!nn*d#a>hoTK+?^^Lb+7;%exEyeF zZ?KEsO{o&vC60+wEx=$+rOcp0=)sVaa3=m+Csi!TDaPSV`w17sNfdNHa97N_JztWb zTw?#8U5X&85P7i8&%}s^rRdY)%Mb4LYHYTEE(wtugjGY@3(Dxp~ufFsfXEBYwgG#`Bq2|LoO1LQ&9FBjxK-u9X2FgQ0@45^>4*v99>KlsJvjiOlZPgeMlm6(pjS& zoBD3P+~lf@VsnNlPWusgka)ccD|38k^6>HbO$jjOFJ%?Oo;^-&SK!#FE&Hk?-y0M- zyC{vSu-c^l3Hh#7tr5rX!b#jT53(K`2GHK>M;UpP!B2bk7@`B&?puE+Ba-Np3$qcd zZU-ZZrRF3dF6wY7^ir;+I}nU&9}R|3QrHrA{KeR=SkAZgq6B^s!B|cwYjmgi{|uWu z`-9({eU$m*qGHQmpt0SBG!qgiLo_01ev9keiA^JmsM|wak=BlzZ!er|Yru+OR_+FW ze0@K$F}G~xNZI*1VyEa#-|V^>19#t27xlr3EcL|dU%fiNXo`}dtjn7hB=o8>u20lIH zk2V+LbF@q!(1tKXxUnFV;0WqZQHhk%uBhmMtlvzAnCHR9`L9X|EUuJG8ck%u_t{Wv zvg@Ud4LrQ8fNv7i?Z5ndme6759(sQLeSeCC6SEjE3y<`bXX5Y8YWFffZ865EL2TsG z9e;D0JO142K{Dk5kS_lZ{~^&ak_GJVeLf$VnKZLA-_p}vH=4VJHYp?BgRz23>})Vv zLT5oYYuq+`3a$bLeYfx7rpXO0jFyi_AseS-55fKTXsEoR;TvlRm8u>B$KY0qZq$o3f$-TD+v538Y`UD&Ko#zQ`?d_UmcrgqTjR!$MOON6 zay`75A_WDvbe`Ekt{yC}6>P}Xm|j$cchbvo&%%8VF*3! z(~t$}JlU2==sqwI=t%d_!oyKO;e$o7_YU4u_h^{IJ-6ClMUD>If32vghrY(%ZiFVa zcwBp{_Y`aS=XN6DNQtj)o3dU}Qo)Gc*u7ICb5y0Ipio{*?~`V5JGzP0Hmu#8hztZS z?Kt0EWP^(}ywkQnx#ZR$k`(KDL$xy}+T6Da%V{FAUqL`tRQ(2ku52?YHaarTdxg$Rd3A=2ME}nC^8K8LA+&p|PTJDa1A;Ib=%wD+@`06` zXnSd92`9Gn#tyXZWLzC=sBw72#Yp6IFv84h{OU^0C-s}EiaptNVDn#M3i)&t;_%Wk z-mkZ{L+EjmL7@$~GK%7WSeXNV?s3VROdZD<7678d&?}%=+v%03A%{{UdriG4gRp^v#Sks;X>= zgGN`6;gnxR6GfJMBBQ%9W1rSLeBK@raiH!-08MNLgIVN&>V3?ycH`ixN9a2%{gx*G zeIou(H2EQEjaLo~FC#Cy9D+%I|K=r`ryzsOhUrjaJYmzfnpIe@AS#@qqXwlSc|1OhxVTJ%*OT|_%i!k;k9;e#b@(O#3N2F z&|X+mzSj^@NBd@g^^o=-4XM=$l`QyB%qRG#0aYjELU#69tJYprQoHU&R*>`UF0FpNmE(|KI((JqDB_em|dmNeY?2sZ8iwL=~?4Umm5oT&!^Mj zT^lCYt~CR_H&|%Hd0@km7-%L>0s0khRV9VBc>w1^2djs?RH0-{#UW z?f?d{`n#gC5uDHF!L!~CVBG}~;<8m%yQKtsUh`%BF-K0nD!!EOY7*+oT4TwjIi?}> zQ0%`g$~9IoC*oTj2;ti6OMbsd zEtXuC`0oj3yKF{W+{UH7UqDp2uz|V4;^MA7KW0>>^bh8@6q$?NsiICs&7rA?XLG%& zaSQSp`_9en|H?*3KJd+@Xm3-ipGZt2=xG1E5@afPLByisAf`Ha{2SR56iFJ*Dm3!I z=0CKNp*-g_f8-y2lpkO_^z0|KH1CsKjo_h~yWli>f4gnKl!TdetTCJlj?{U?&_U51v;e5a!62 zCvI60-D@1rj4JK6oG$iYac zD(C#A+lG$(=!jj%(^}%O);A{V`y$Fnr>*d^VpW=X8nM*?eb|Og`y;tNR9O22-(iK(cD?D=Bb?UC?=k#~UqU+pV!(K_oP``Ge z$g5C=lw;r-bUU$EJoq}>{ww1(>fyj{yYv%E&$RWL>*93fB?Yt+md`{sb!+R@t98fF zzaN8t5+7>&|5%(|r#Wk%5Rge$b95+5i)YsL9$K9jVoQU~0&fWdS7pSoaF!?#@&leEcc1!A+VBDDCk11;Y5|_S(CD!iP9!lqEbJO2MfojAsA$E-Mlmr0h$CDhM=x> zv?cy>)&G=`xZ;2LPOQCW~e}L zU+$&`rPK>kKMM|~Cn@gP<3PApm+2yR1sE?clX-2IZf;KhSddpeopxC#Aybg+BI08r zVgDRu?XyNl7x*0bIwf^wF_~X$Sx!}Va1hjNg>3v*c^Z8F>SNYeoG#Mmd6B<&T~?6H zG`C``b+Z31C9SPDW=aaq9qGGxFy3|frcKyieHk(yD1}xO-6er@-0lf+YFXg^qKl?(C-_z*~wt0g8!Hi6Myeq2jo=X79CxD zw$SJ$&qwS$01rNoUuQU|(K`_> z45;l0N`1s$v0Y8b2y1MyeNnE~g7Y4fz49x%jp5-Qv3JedNej^(w~O00RAWld+; zP!19W4us`H!9lLccR60DLll(+niiMS{a8+hXEZMUZQgGTwAoU|$V=ktE6;4IQ1s<@$o+|b{i zw8zl!*Cc@^M-XIs`s)c55KOnU9!o;0B}6dLqcuX@on$p)Yu%jYG^gy5j4`Kk4m$s5 z@60*~)TgSTl8xb`9S2tGEB1fNOsSt)Kl1BrT^JCeOczxyB;h9yh}-I1IZ3kyI@6!` zSNjxERl(AsY#kQAyo89`Q*AG&Yw0S=zt-E#2++9_#B%mW3P7zbhb|ctN0hT*9~vdI zOp`2xB0EBWN(mv@-Xe6UblrCUKN53xuYw$}lpA#`_n*}+w6!9qt@Oz?Wv4W^_~tV- zqGO4lje{h>CKq-ig8>V>C%Mg)A@7=AF7VCN#k%;Ic1yXTcurB-r_ zLD#Q9Y0~Fr1IJ2P=@|?#bhYizNmiwOB-^Ryfb47wK#vPrU$#+ zB2cvP-pvE$E8I(oqTtVq!HkXnPm>nY%{C?aMAHc!^g+PbAGvRnG;5c zjGCcI>C8wGKrCQc&N4ogb1rb0Nl7icc=f}xQ!YTxx)2j3V3CI)Sj-e7beK<4CdCvU zGLppae#qKxmzp`uVL!xdl4gMa*q94L_@DSDy?V0TKQk%S=COClOT-`e`l9u}-_|JA z>!JGFUNNULTH&#)LZ}idBHcUTs+BJgNy@hz6_sq29X>axzk-%XwtGC=eaiAm(0Qdi>Epn5c5|2*UCI<@O9v8sP)LS z1$|p&jA@o{+_1F6^Ur&xEEEn1!TT%_*PoMojxbHx#uu9@e{+6NvPJ%{K@GDvj=FBu(py4oK6;!lYrU@PR8UiefxcOh7V<*w z3!K3`ixidy4G8~^jInmJJ6eY3I1Gy;6TR)$kR&|y(h^ac8pV&G%k+L&M zXj3G7!fb~J3#j6_^qPSxaGg-dFEm|ZU&&*<)Odg>lOja~OC*2S%r$2h3(>JuEmXqkKh~gRy<#`6 z8SATS!N-NUM_-!BnwhJG%S#1B0YyVHh*rp^Xx1K{DLAcKEy#St6!)NWA>Beig$~A6 z{bTndIg>aeTwaJDyGkx?Zl)oX7hcwp-m7zoWt>nCrqXeaqQ9h|H=ncmJ@wVZZ#+9eHs z2eybf)l95$9^6Mo79=T*0tZKnY$Z@BS6)b>(oEFIgXBc!IF2*ne7wttu)0tE!@`Uz zJ`t9Yzy3ZSoampS)+g3Gb=p=o9Jxu@aJFTZoH35i1(@3gPQc3*w%q)thWYRJkaZx1 zwTBqTorH?MNTRa`CCiGn#3FU{_<<@WbLBUNlZS&XbijzJ#A}4qvlbPJrSnH?@AiU2 zqHf_fm)`*@5NZElARm;5H7Ag5+tiWV1Xmt(CDVH)mB<3{Y7m`flwa#r>c)mB$T|z+ zKRIY*=k(O4;i)@3EhAC4&Sc@^&HT1$7E&{el+Z50r3D`IQi`lh#&-o9Au$+2xiLu| zD>83Pq#sv*9R3S1%NMC$#qKg=vp%LeHWZgk!zDS1Y%0=g!-*N4G494pJnVVEp>Ahw(obOpzmkPSPvKFC?ykqarJ67oQ!A?dgNyouz`sqn&8&txmGTCkvb^n|xe=?4yP-e7B z2L3eB+Y4t5V)MlMI;|;_d3ITWh{zQ6XCyLeV6Ow8EL(A!9E+I$@HINqzT>$1yy62B zcZ-jUv}-vlre18sCG+KQ!%`>>G_5$&&Ell!IUJ1 zX*}@zEm}m_0k}=Ac3L^P=!OHslO8=y@5|h6BxP0YSDy_`IiE^I{j{ZUYfeVO>s@;I z6TM1H#r5Z3U#pLP65CcNUlRdU>O)z*@ffTQHJ{B8x$)non*K;{lYR*tuZ1KOBmKbV z4I1StVKDeYtjw&nZ~GfGi`*)TiX}6MJsr|#j-fz?=m+$*Nm4A?m=ksxMGbQa*`eL4 zvL;+bvAn)Q-4loApn5O4A08-5qoI*!1K)Z)3h2^R-iqh4wXH3Ib(@Wh3B84?vu#&l zpEFng%9g`4$2rNX{{%!OD&-gD*M4T=X>ut_T@YU&=wFgw`TI*G z!xPG3o?|E5!@Zt$#vlZ5iS=ge?w%F{d3u=?F5eA|AE;Gcw(&olcchY%tPR4lF4>rs zSk8tD#CDTj39oX zJcEaKZ3`&g;N|B93GlB1RiDftMiHUIzbq_l!h)Ooyj;Ajfa8Hth@Y1O#LB|NCm^sQ z1hhcljZDA$Z<&mHEJA)DOW2j$X%RwC*Gty1eI%imBi_Z@8i4f`2mnj_IFlAA zeO*DN)@&_t^w*Ha=CJ$LzG>gE;5#|f`sqfc9k}QaIR^$t-hd}b_H@MnL3(-M! zjFIw%o;tz)>INnVfL5Oo3c^UPU#b8bw)nfdR`nxSohlwBKq$7Oiq+UD&?0X4v;$G~P36XcX5dzc0SjWoKa0|!m+5Hw>r`p#Kz$oHM zs7d(e`b9I%b+PbGGNjjXb#Gmh&&l3p?~kxmP2sh%zg^M8!qnE|b@k z8-c&KinMUP>t#8pdQI*0{z(7PQJ`$dR(5h{Zao*^1cG__XQf7tz!&XX_DdABPrC%W$xS`uopBOk9D&>eh=` z(0%nvV&HZPcStg@Gtaq+Hr&hEuI_pvFAI8oeWZMwFY|y#0sRix^Q1}8?zqYj-oO9( z-eUJ28KE84I}+-o#LCw6O3VBs7CnQO>TDsjg)tXb!{d;zV`7({m2lO|ai8a0FK*EpmAFG@~xFA3VoP1mq7}Sen{9MDuvYpO_GgM{u7aw zTsXQ|Nw!)=eD@y)RLC0IG=YQvr0`oHwatH+UNc{p^Q_wn8=mHBB>kbYsT$LVE^=5W zygT^Omfe2wXQN|K1k+-GYUwP~prtLBFI|^E50sqiFNnaIonR#d4QNd8vLgD4hkPT7 zs@5k&gF-?4qQ=6H)L;QrDFg&H4jJfeTBm4c+S9nnH>hpC3;jh>N>r};(yNDm%D%6- zQ*$llu;NM3Ou>MoKCaI*K2Dm&#n?1u+d0NVW!D+KTL5bz6<%uZxydnDf6s5?BwS*c zY})^~W)v?{h#={0dU60!!A+lg$3qFPIIR&uvUDl)xjg)ZBS81kbw)QnHO~t@5$Y=8 za%Adt-9R*f@16`-H0P=huNgXf*5#^!_3o?=uKm1qs}!+4k+i}tQt9nVv6RhH|25!| zIiSGU*l_{>>e+eJ-XO=c;hJ5tS_MC-K|2lm=eOJhm(h_`h# zsd8cO=348ZGf!TkX}Q{3gsIC0bhaqj)lfd^cyjV@ zdt|N=;-{Dm&C5$3!nluPxm&6qcAkYk{LemO#ExA4!kIFCz%e;ca5cG$D_c>By2uec z7_d@jux>bQFeDsPEZ}aCrxWkRz37i1p}rDt16b^Xb#^7g=RPIcpXjgX&-*j$CNd^E z_pUcBYwvEnt_x4c^e2qIa(@NUazIQKvdh#$Z}%ETPtgoLvp(IVdN(iW*p)v?_FUBy zz0NYl|6;OMU$L7DjWatiG7kHZW%1Z)$tR-R$~G~iZRf4Uqzvk{ElnGTcZ`efO%ps` zzj*V<>>>a_Xy;}Wbn5BY59F2+_B~{^G`Yh!6F-LF%X`p5f1PKzc}I_nL+z1QhG7`a z+YU!P1UKKE5VV0e6#pdEh!tc%Bmdgl>wij3opV!Yq90PDUR{Z|661@ENzjWdEX;cf ze#!DH?EuJ74XzOj0$nGPZr2%X&YZbx4OjNkbSp;Wd@9IM`1bLpwQ2=@!K8UWjA_db|F(ZmpQr8iQXhRu*V+QTIVoe3GPlV27GW-n-!79%?D|p z_1>1^2#8E7WHTDvgjXMaRwIK2-AA?JM7n={dTQ)Y0Jrxqnn~DygS2D&=~zr$ zZi-nSOQ%0zLbAkYVYxGAw7t4>+PUtTDp`;wV02uuX&t@QN}59?QuP0oR!s8c?C|#1 z1NR5Y?0BA+K@qKMneDE;`%E*FdwbfMKPQP4B;3YCFD=z3Lrxn)Et18`)PT?~gZRU{ z0tE|s7XhJ%VJ{u#P)=>bTiG_5C7$wj13&w~0$nU}l)n%C{?>iZVdh1|?$F8IG?!Tt z59+Cr$+6%!qp|`mSF4?0u-8YH9_e6r@2bbIXi%Ld%<&KrpaV}Ha}u!eHGU#@gut`nGbiVM$g>0qy2Wnv+wjizq>MT!?j{BeS|i z5bb+zQ{39O628-S0;7(Q3=M(1x@fCu(Rt>1hod!dYeWjG8G_Z+k|zj%59rHpREOH> z7e^xtakd;J-Y%qs{0_b<<%?jNmj(F=rRaTgeza6x3zsy1)1THAQ8AGmbr;>WDCmHrCRRm;kd=xb zDSlZ|GqL(ynxa08Ue<0Y*S>DHWHmL+%CE@yVAycm!@=6Wlcsj39r|{{ab*G;Rg~Z! z6+IemYGY}?tYvdyoAc^Ry}~6F&~C8Yry#(}>9j)N3CaCJWd9ckG0K|SCy9{Jh7?Q5{W6_wrBv)N z@>?n1ho=moG2D>NxT=_r$K#^_8p%h%=9WbJPUS%e@uo7^@aQh}c*#D19tPgN?y|WJ zC>^C*AVc8L#3z&?B#eE0E!ra`m9)WRa>^1^PZh|zpB)M9el7Akf};zoqD27<0hp6M zySTL8*o9WXL-dMx)q6&@zs^~pb^z{Y)$U~NA=GISONb98yytxf+hy#)uM2`Tf5Zav zlreje;a7L5OHl~~=?}_o+|~-s%gF~6&UI938zn(?EJ=)6-Fz^fQs_(FU~p_>P%I9G za_ZM#B`d6CNE=-&Y#&6Ovj4ISh#BMvxQK7}* z^Tzh<$h=r}+%*-Y-}`4B@n+9ve5e)u5303*sgduMN{T~I3UI1ulDeZFw<#OGdYM2su5U3aBm6;jb~NPT@F0Hp#g~&~f>P_~ zY(kjj*(PDbH+01CUkEd#RIT@+NO&Flzj!vBWPg+nkP*hxllA74>PrQ{55vP1_u|V3 zo&xB#TVk3mzc({=6O|La1}BRioRt{{X84=92Qyilsdtw>lr0W@65vi_%tXu-!U;$0 z3>OhXg(eM0Hk6wk`l_Zlh^ds}L7Fim-~W0vBmUx1nsBKJBvI-gQnsX5`db)A5=wXQ zV6>KB-n-9==Z0YxP32$+H zFZ7j8+<8mDFK8e(xst*AUZZn8%XgnmPKmpFxq9BZ9~Zx6NijdXA2?HqTq8*(TUU$! zA||eCS+NM!6<;t}V?IjohqR5Pa)b_9nUe1ne0vVO4h)nunkdjwiEXdKsOqMRtCH{2 z+Lurpt&((rrdNt5S7j<4 z0j-iwbU_FI7@CH#A&}!cAX&usKAp(|>p0(cXG&pRMbl}k%Vo*nb#8Rf;kTW~#Z9_1 zJ^N}1KEMy3{*@16V3Q`?tBN7fRs5OmAz`*JR>Qj$k?o(`3w!5W`6C>d|1<4nw0`5= zI-F+NJ-i1&nu4F^<=6!o;;$3(Wm9hbt2SnE{sUGk1f8Z(8NcMxAs!7uYr6v7i7TFx z3I^8d^r9o79;M$Qn!phYUPviA!TxHz^e1B?`;j;wqu-n9<2g*4OH<%k-^NfV7p#!a}=qmnq`oa{c`Pi zjojluqJt{`uQ5pg8=uf!X1XE@psyT0t9_Q5O9fXffvpHxF(WIXN_otR@-r0oX%b)z zPC0T$6)ZOx0on$#M$0Jz!@}9XXB1T@IX4x@HHRSm(Qm89Qu!pIfR9OnLY**vAMo_v zx+86fK}TzxsLOt7`Lot>eDAD`dUh*rT!jN5A1W2LkTfQ&foIs>dd)Cm#;kaqANv)( zmQ5vUk|E0Z`M`}0LrOVL}qWfQASIw&aBw`xBERzC$2oZ&Z6t zpsk@37c-9Z8V_mfPi3FHqan)^q0$*At7wM#uH69p`3^9lH^xYPE-#UGg)SweV(jnJ zpJNG!Wa{ldrK>Pdqqk@3T=0MOuWu+KV$zoi$z`91=Yq%NHD>M7Np5VKF~&MTLe%p* zmcy@)HqVB^;a`h#+a-_G2>*_*BEPkxz>g{ZdEup(1SU|<8^#m&%nB09!N3Wz+ez9* znL)$2(^)|r!oamwS)6GJC2Bn(Ah?j?-g_nnmho5hG0U$$i zaqVz(Nvr@g$>Vtd70J!B%ftlWB6*luSwKv@yg=^-3pZfg$)3`3cY8er*Nw(75izF! z+zTp%EEJt2ez1052CC55zhRMQd+DyZX5M<~rG9dffZ!m(2x+!g|2?r-4g!VSdEDMT zJG|8M2b%MbUlV4?YF%a`ip!=A2w<3YY}044+_ff;ND`U|zh@b_?htLKmDn*Tlv?6S zryJKggltr8y5o8@L=FM$A(mV^&c*JBR|t*hZciG(&&_DJjYK%ppvm8hLMbiXd-5<- zes^Ervc9D2!*4sJ{5z7>4hap=qj8QQNs3oAXOUDGnFcM{$yWmtB4S#C1o@iznvd0M zH&rh2-9hW|>}EEo9NH<3V_JxVxCxQ5>TtRuj#UjzYBgGN8sNbut z_C*-b?5ILf$U=0cMor@f7!nsIQ(>CtPHD?3xv;Z_A02IWUj(DT)xbbc7GZ~h;xh?i z2B&#EYt!O&>Ny{3oXvVM>4aIfx?C2NZX+Q|Xrd2a5G~yy7%3lzqF-@`yAgitcsk__ zo)5n{{f1}0x6@Z@S`>gg%3c?vnKnsG06_5jZ6g)0bo0pzz1iln!eDnlzO5$NYiG#L zl=Mr%wC-E}CFSZr*5;D{j|*T`!Cxr`69(3)_fle!^Jl=OJ+W;CuE}o~mbbjZw(VWgd z3xS3VPJ}{`_%E2BD2EWUq{-5aQ9x<(!%Chc%Xof`u%Va-c!@VvbiJwz;(yCQ3OHGg zrlf$p#L<=lrD3*QdZA;=d0#G60nf$0L{mgxjVJi*xTcb(KhS0D>)W^TDj|PotfPC1 zns#LpK>y_}_uua-+$acLJ4Z9$tPVG2LepAXI6VV>f&Q} zn0-VDQ@j%?F$6`^b5xzyQ)KNH)o z3CNs_u-9dv<_6!OKEBmxT;b%q6sd>q{zp5elM+ocCT)!V;Pbvo=c7>-hTLhhj-_Sd z2hAeRE}O8?{syP@3&{^-zu8%x4myvqu6a@^3KAqG_ZW)3aICOJLw?eyb0D(6Wwi^2&<>SG(*AoBM*SFVA^3({f{$52p~cAAq>2%A95-ah^7fJ96D$ z2o?WBBe5*%OMa)1kCe1BjQ@UV7$t7*fQ{%a1oXo@c~msO{T)vrf2KySQH^XlWkqat z^c#)g+TL?d4qXayctacP$Fb~}lEml5ZK_wc+iu-E3+)Q-MzwhbmBc0#Z7R(b1VuNg zOsNB@9nb!Pc6U9j@Q%+m6}Z5hS+Gw?JaB@fDlQH#xb?t@&7*UTp`m2xmPvA6Ab-hz z9O-kMzL8*Cj-*_%XORGFm#R;rILz>ip^B49tB^4dDqsJ$+}EQV3eZ!}ljQ9fmF$O7Cj2|<+z2eqPed~`*?E1_dAwiuJLeyr{aP3Q>8t6ol*05KLTusq zli=j2r{FC<#tKdMofxVl4Ag{T@-$ErYI*5u44>*W?^r0J(fZit;g&`7p?cGU8!il& z&q&##0g;q6%{3EA`70DC7x#UU^_{nm7l;oAZ2rQs-&UPIrlfqcA3yO3CV!2Y-SR zle>)8dEd{^MUWgg`zHK8Pl$(CC;byTQ?R`~a{Mwhbfz+R7?vr@$sC*8Vg}>OYyB@H z+~mjm2uGp(G_l_x6ARv+>7e@0m67H7E+v3RfMvGXx_nxan@tk0n(I^=r-F-~f4NPe zsKv^RV&aJ+e$Fq5LUrudA1GXDzs8&u?W9(*@3gDqVXm+sEiDETR+J4tig3LY^XsKS zb2qe=Y=N~+2+{u;` zn0Tek{t-NgD&PP(vXAJYb(fK3gB2J?grP@|t~i7ZAL1*$zcte42Bg}T=_>0erR-r? z9qW@X%$^1(jcI2rry5RjmE~Wwtjr#09m(_`>MSt0+)CXpJ&uGetYEf0sOs8l5ff~* zywZIapnr-wOr!qzd%T>$ahWU!@31^bexfp=u!xFD5MOj#hSb{dPRiZ75Bm+5Vlm{x zB2=?M=$2&J*DNCbw=BzCx~ksRr|Ct%u*9(oS#4ooJ>iwSwhT_)lFO}f z&M{TLJ*6lisns?W+bJ2j{D%DODg6%knD~<@c2sC+ZAf@|6mw|E72kgTr;nLRfLt1a zmgiuQ=A=XexX)j4L0)+e_KvtCqOWG`cYp46obp7REJR}XbMu{h62N4fgQ-(i5ZV*l z?Z1B>n|$pld_`1WMA=(E5`JzLRb)!esds3(ZHVPh_{4vY=k7Aoc~$Amo}HYnmepy} z2sw||UUb@MDzWV+cyr>D-5$&9E$+4;?wjjeFU&^x=Kh{|nSQ92=vDYQt>vHpKXM|M z%e1~lGrM3Y9WG@yBK!4EB6$|RQJSRYTcoaNYke=h&#dJJN(<<`$f!5yx*{R(Jqkj+ zE=K5L@Ye95I(JVgZ7^{u0bJT$8ePl7vLWJ`-|{ycGK*+z2O5bD+rhIhjw5Nlxp^( z5AhBOqN?`3p&+WVqu8w$=z4cfr$5fE#x+9dWwae%Sl`Mk$7Kf{jR**{LWofVs8mH; zlMMAr*1%g0`LTCG0<7t6Z9>s1GdCKJ>+uCZkAPCcr#`mqSdHmFbtMP<{&?Wk;wt0R zs!pjtTKd;HtGu`Wy?8%d8cPd&;?4r#6L0M&wWL>fXE45h4ZNqg=j8Gjn6mxeSu2+; zU}Dd|ynMAb(Q2UWnSXu$$ajn8b`LbPS|f+#-iMME@*pBvJi>9)xyxur`?q4w3#S9h z7bX>PWRCIBj4@e5iOQH?w;Y!94hMd?T2kG2RiQYKkUVhQ1w~AD3X( zxMPKWB+d_s)cq^FL0+?a>PBHEoQ)yImCl#lxgVo>@f!;|@nTh^i~PS(K~FFGYI}-KanQTRI22V)dyQEXgi~pn z^&i?g=Gp}7GQD|K-$VU)x7h;&imIoa?cPIGA($dFNn{g;{{>O#^eYH+7U`yXEPsmL z5u#1&=`1@||8N|NWTKfgdkA)G>}?&DQ`Wv-0I3uxI!70O$q8Li@mT3wn9lw46;W05 zm&Ghf&WieYRUlpx+hR#aU*|J72&%RJy!6u}VyM*V4f(hcY&rX9mx^(6U68KiEh+$b zXLndi63M}~aY8qmg>PQRpnI;Q$$5)b?m*zHem+6_Nexxx*|9mpskf^t5rf4jCYsYF z>ICnerKD2yKd{DxLPm+2PK}Pn*BT~f?4ZH7ZewvjUzLY4n^W69(RHRFNND@~Er~?f zKq)AfIz~NS+P&x&p z;jOI8&y0a<(Z`id#FwS65(G*>u8Kf0iHSj0v)i}bXW2cX z`&4Q6T`Fjh(C4POm{?exS?c_}YHB*FfXch5ZFIu(7ZZmwh#o6cO!7OdB`Kl8z_?@d z18%&#iEmVenDl*Ho}G~MT6UQzuuCN;nt>#+`YXa@7v7iM+77JZr6(6>0I6md;bLseuiAmET+9Wq^p zA^%iMyQHA3Fn_Tcogd$^2_l~K6wxuPaj2=1;0*G9v`1Fer1HH&DWFvwjiOP-yvbvG zjq>8G5xtr%lG~IJnmKA}lst)kW~+=7c)q8V{$FlnNZ9|W3<7}4K$Y9!CCs%xf5Z*k zcbGvS21X`s-d!dZ0Z}1lZlD%ZP~c#8?vO=Tlvj8Y$W{pR^RjUZiUY6V1~Hmwx8G&a zll3S|Izd0wA6Zu&M^MLmHF@7AAdjSp1%ei8x+=Z9vOE3fD^KQd#K0{fXq#x*K!2G; z!uwT(fA>4Zfz6Ux>-h_cZL2$o2)~3viLSO|#$Uj&p^9)vOH8{{K>~z3yt#0rlKu{E z^edSXUy;ob!*LGzH{_fGd~_|sOrkYs+HvH#Z(?DkLj{%qP>GzyAh|fbR!~(Q=k2uh z8*7MmzTa+OuENI|icmpeY+j~hi?7iQ)tg?nIcU+g)!Ba^x4*xM-7U~Doq=x5`C6LYP7plB1+w~dxhP{huyTtQA0&yuAM~UD}=yy zgA}od@Y7B{VR2UnPdbv)wya2zyhg*bn_T~ohXv4xyjiEL99uLm=8C|G5hy)8Yz~wx zTexpYykObeC^V82^|x60U%2&hTg|`^J$4fP6eA_Rp2m22ss92LWKtjb$3(4ap633Q zDt`X41|5+*1BLfA} zfcVulR*slAORq9QYox%nlShdH7T zV|PI^qo~Eu zi?OTjyL#vJNO=>zB0+TGMPcn4`cC+RbB*kIUfcA@vZ%jI$XKaJn5uFGYZ zdhU;|_bxMfD}DS$uI}oJ;VZtsz^Lk`c7%iza{?c+Ft*VO-dJmXxx2bzSh+Gvd3W<@ zGfn9$m;{143(R$V-mq2I9Xz|L%Y9Au6x|ur+|7JOu%0SVycrK@Z_^x6LTj&pT}AMh z;3?(~H0E(PaU!?|LyDpDjQU*te{9P=1g#u)qg!5g6c9}yanY5~+4dU06krC6PfAa! z0{iS+wAB>1w;KO~nRjp|!d-b4wsnMj=hkKdqSjK}76DpNJpc&%hZv$OeT?XZ^HR!O z4z6K4EMF-U!U6h2;F`XVRnE98fU1VBMED))7|B|Wnf&8es>GaznZ(7cC3wT7OYw4L z`iXE$<-ZLoc@>uTvnUbNQKKFNS%;!Fm>hEryq;Z=Euo`l4c&20xYmgr%)s_a0!^C; zulwLiu)=Qz#_l4#2zMAP|2=O1J#n+{VR|C%v%@$Lr4M;ejEc1;m_Hm^nPb)$k+eJ< z{KETsGp|qa5Lv>bQT9hiy|9rLQ^P=t zqKcBn%=hQhy`aq;#BER21HB@8-1h#Y!rm1eLy3oHt*$m%#cJy#YBq{OMP(^| zJh7WF(tD*F$H;ZfW}hfmOSItYu!sE zsh2z!>0w-qT8~PZ)CY^!gEwR5Z|4}+*zOVe4z>{yBaonc1KAz~D2jAqJio3lN8g73 zY}cZi40j`iTCR@KGenz&VP-38M&L>0Ke;A#v7UE&KMY2A9((b}CWn@Shm5yIayxFO zANfU>VbdEC)I)jVGY;`iEhpv4ThR{V-7!H=0q+zfry6^jB=k zqKnmWs&=;9B$3jM>_}=~k9X@a{TB`wEOzZuNqZJ?`p>y;&pFuX20F!?x|7~;lBP2a z7EJ|32T?43f?HOOU0c0;Szr6fm;ID+@m8^}8!FaX-qo2sQi z)x90I4Vn??q=%^4@QG8zGD6auw^S>W=PbMcM-4P(`~6Y?lsCD;n^tCymW^fBE|n%v z^fqPi@|w|(dEuaGA0lA z?>yNa5e3vUzU>07vd{YcS4tW>P3_)wFW<9A==3*1s46r64B*6p&qh)NWb!Hof0_oc z0~T!-AAv7HQH|bj zhVV8;t}zlJqW}4l^yB(+YiEFMx#lx|$A{Z3LU8t4qa~+>3MW%k6!S=McQ)%}@P|ja zjza~u_{yK8r_~R*eEu(~%%FjaDSM7plY7U`5s9<4hBO?l`e&kW_9F-`G-t^^fZnrrxHU+6k|j#(Ou7ED3oRwItF(F)7%Sk zP81hKuC4I?{v`_kA!v<^fQT$gh4LDYK!ZvA9x>nz$frpCo6|2`9$^XGzJaVHHDv*H zp~rkz;mV{1O6M)-pr9cSECYc%i7>EN+RV?Vsi;-Q(>2@Nu0rod(Z~@w|34d%dNS=~ za;tGl^q{W+qn1dViNk^~oGM8V`?@l+#F5NVUIU*a4so*D!>eN zi0%Fwc7eurD95H7r>cj)?#s6q!i2&g}iF^-4IzVduEU}IG9>52C? ziEY?zP~Pspq6s!yPeE4qFT*IejvOTy2O8ROR47N4l(ikS()7fK%!!;GwkqB_ohij< zR;qhHTjr42;77dMwSue6gb#D9QooJtub5T@N$O|_S$x9%lvtkh&y#@r-XOWx&+5DO zzshZRy3!M-!>G}C!Ex2iap-C8<2m(kSPr3$;c6;@kX2iUFbLTVT%L7N6oqxqI|Lg^%#U?l`ZLF;sjnNg9>0Vx2 z49x=@$}W#fMHhy(p%uFQFt08v#n#U8z?lXSmjHjUBdQyk>30N9{J)!FjZJCyLyD#r z!!?hxEqFRV!jBo9goxNc6V{n;t#@jz1|p2>1W11+5Wa^w)1=(h5w0krCoN;mawQ2i-(tfsi2IMlT8|umC!in z2|##rq;vkCD>VX=qRJAc2%|bysybojz;ol?#>YH@gAR$p(YF(@-*w~1#WZ#S8=x*b z;y7dh^%OUCZIZ#m1sa8G>GNF>erPW{PEECp&Zlm{fl`9l{{Mj2^db0Ug;YM@1!O1^ zm;Tvo>CR@hi+7INzK`vI867QWy~7IyGDIHrB^7v^$RQ=)dz3NNvbuVPB6nHvF{-4IyvY*V{aTmO4g^YkbeQO!3!DmQfs zoDRYYJvA4bb-T`K9uXe-H&6%oIP89X3otC8+c#Th_bf+R3ZWni>%qEd-6qBk{z-rS>m zkDOhU{}(LHF+>vzn85mKM}EJv{_3w=tq}O5y#@HwE^Zy?^pEoBTRrlP#9d|P z?s!6-t=%lSAWDOaKza}SJpusQ4hA}<+t?;4UE0<`5^dWWbOrTSXPz=v9Vsalmjxui z_;~6`kbik5(tJvCC|wKQ6djD3J$|jiI$2G!9%n9D(ZO|gE2q}^F4WgAwDKxSChjOG zt3^{NVN@CYzRg78c(KZSGq6!XOiwMHA?G8{w>`R-FN3Cm{|`}T85QLlZhcBxP(o=1 z1{gxRyJ3K#TS~gSTcw+!8|m(lM!LIGxyfb|#$E{mG%4^&8LE)RvXte6RE zHy&zMVHBtJd`)R$oB+-KUyx+a|0xa}fa2g6drHDV%gXV0b_ak+Qd5xwSjfZaO%M&3 zjb-=mL4pa$gV~=a~{p~Zpon1U;}b!1aHzG zxqkMzjQF<)zj>Xp*p?d{J|dYnYrXM@_e9JOe#HrcN8&c1CG~EX@(Ll@RT5wywz~f2 zWn@4cA72DAL-XLDwi=8ZrYVH3CFo(d52jt3!37R#7AhTs|_{vL$7rT zr#A8jqr|hv68w2J*Gf1$zmaVh@yN#58Io7$sb@n4XA%ifc+zBQs(Hs)+uSwleu@0X z;Vae};T+VHF^X^eX7?}lN*YPm_ZE4Mn`B4%lZ>st#-7iLM8nKB!_mG0y4Pc;X8m3! zn^;C!I~3%aJnPngQ&y3gP8kyxQ8q_Vt1ip&23gmh@DDu7i_A5qa5RcEsrN7Cuy?Kv z-6HT=R&bm&2e~-UukOVvOqXx-@lD}f+(scJU@uzU}TGM$+Vv##VCiI46Ez=S8* zP0^e@w&{J){ghKIf##M71{x0sNBS1DcizGnu69vSPS1ULBWV7ntq1dI(t2acIW%u} z;9Kut`4PX}`;Auu9k2HWucOF>n8gqlzo6%GEGt%{wC(K{pJ-j8X&u@ZHN7^$6spOr zdy~hl^RJu7fd|jK4<`j{e$+RWJ&BkH9~>6AKcMD?Wg%g?8;2c#`>$_^@Qw2ib%K8; zlGUAXDCU1JeV&e1HRL{#t>gD9UH0edtr@zKe8Cf;S=74tbjmvAqs!Or6Y4blu{YvY z=-U6mE7Z(_*$f3w(S@Zez34zyp=r81wE5hWsWkxfk!hU;k1>9Af|@S^ZHH$rmMp9-3j+W#U{L8B7l*_7IOb8p*=9>XJOHq2 zivreQ=I?Z`RKRl<`A%WF8Nuxsaupl%R@ZQo%*b5Q<$XO}=Hm6~{Ow_lhf@ZAQYY|F zArHzA#dKQV?l+<^PwAa@v}BxDGsNTD&D9g!s8m>%8m|z#GiOjRk%7XH{B_}Avm{kF zSP=d7pyJ1y``EKqH3oB*~0B-_-%VXCn76cw-Hm%!GbcfamMu#B1?fcr{-PS<-Z^ulD(Y&_2qSFbdNRjBp_ z{n2sQgpoIngkBDlzxp^Ja8dU(@VDI)_m;^l<>+c{9Z|V9deuXztBkS6k$PN#lMicA z!C10ADUeET5-6C_2(96^3MA@}vOuPBn%?f62JIHy5jxu7F?7QFkn_G{|sT9h62-F9RkJ#OjOz z>tc_y;I%#*39g0-9Q!aN3bQmPIZ8oRHDu+^a>H=Lw>iJ<#?e z!V-?I$`!TuW8{x^Tya6h>UBM(($`9w&GLe_sN)89dSdnONB}Avp&tkL`=eY(`Or+r zb>XGDLa`5y32~?VjJm-^v7A0f_^*SzacK8dkc@BIdI z48+zeJ(g#7e^!0hZT_UABvb2I3yznzUK%}xv322ZR(wf_$VDIu?o+!4y;pr>PHU6G zw`L7bk?8vT7-boe->-JV=}@5+jbpRcg5&1P9@@9tFiVX=l@bm)8ER_W8d7UZ3`+j(=|b8@6L+lR7NgzqvTKewb0g$Pt(@*l`1M&2Y`R!dwN z4^U7lf8_bjIcWJQ_Kv$4Bs4fa;=?+wC}@=XFkDl-Y${bo*C9blbHr*p_4|SSQ!N&< z$*EXxyc7PS0H+#B*3NI^6}+@3dG(ayoX9?&e;UGKAw|fY?PUj}DUqQuK-G^6(a(3d z*yvi}LN13?L4PO6*kzv9jLoDmti^Ifs{%%;U%kA@y{;C)ETrY`1>Z7bB$oqM5&7(w z7AEh!Z#F`41up;IzSSsqEuFMV-LjV<$|Jtadozlf&7HoxZCp$wK~ZJIVS!ZVz^E>N zN2iQmYFgDJ2(L9owafYSI-s|lODxG|I-7SatNNw3T-nZ}LBg~!Le6k>wF0d1%yu_C+J(*`TyWVh82f|v z6+J{%&+1hV@tg;4TN1QY+G1<@R$1oNBM#Y${n?sSifp8I62-N_n^ z0@qgeMUyxZ7IM?@#!)ZtC1&0sWSiu(6VnhG5HwD=O4Wn5X`g-RLUZFm^j8>)^mD<_ z?m{}$Q0Hk~vEaXu_O{U#PsX_InYIvy*k!xv58OD45> z=<+~EuceGzVWW;WO_I^)DTPTQg}Qoj1-n?ekx&il14857@StzbmbD6oWLp~SOVxRs zVBGHTDxtw&+Y=Pw$SAc^-_&fGgFB{DbVEoTuhsw2;)x|-%EkIq*8Sz4aRjkwuy0)+ z$h{4d7B=S}7U!VrYp|YYSnx|+QY(@yA^bv>6hU7ZJi4+5Lpq>OyQKbjst z9d4}FY!K$mrHRu_Iet@fOI{pv?A!?ZTFhd_9K4PN7FQ^;nMFEoE%X>*%~qtmc*#Bb z@SZC;kn2W`gec!3P&0q&P6S{bpbB3h$=KAz&itwD(fWw8O}8Aj*TQb&M)UByk}5?; zm%=+8kOpwx4aZSizm5wTCyF#!=sb{Yy0>sElWTiV4?L1^jE<~x$pilc(C~ZVRAV#I zQ-{hM%3|@VN?j>Mx;Ie3PEake%`UN2z)E;WUdei!sT9DYEhoyTw!x!}Um#SMN->Iye2r+X^@Zl&a|@9J z#)DVIo5H<%7;RmTZ&2f0uF0r1TsNTUn#O-gy;{43XD*)B{+Hb@Hg>{!8Nu#&>EtSU zUiebA@oXFK$aJ?}jjJZtdQkjhk|cL)vw=v*G0wga>Dk0@glBknQmS=4!%a(+ z`u)%1HNm*Ry9z807&gxQRD;AM2TJt34vhXheyDc>ZI(DrR@a?{)u8_YM$YX0>41RN zT-SU6{m(lz$kYwtc#D2G$GUhp?sgMrmN6&)7KL9He#i{6wAtppX};D-r#tDvr@M6j zX%6D$STS>La~3CC($i~LJ$QD1WI^e1a-SuHJ2ihcT+sbmk{g8pBs6EJAfG25Lx+cR zm<;0ZU7x&69cO|{LI(>uBP2SesZShDY^k06TrG?p#ySx)Ks4Aehe?7uO!cg(sQ6{cyNb|a z7P3kb#Y~6F)*zns2jLZ+R=MrQ1zt_Q7cws6H|V(1Bnqi;QYz$KC^2fES^~h!C5DV| zgKyowRac(dlz*7o&pJt&(o}>2S7B)Kv?);O;hBv+eAty_!{MxHHqq;zlzD+!!7!xZ z$ViLC4~2WG0l~jy`W9g!Dh)C;Y1&`MGT7vdg+_Ke+VZl+Yv{BUH%>n2nLTBDKE8fp zSNPloLPPxb0?z6un4;6ONh=2M)KFPXtXKoa1GC`ZJq4YP}ToI1wrvdp}1lH;H9Bf)XARcOfDdH zr{|l`IG=_Kxl1f(qRikW;{G=&@$`R+0w%(%W|sGpU!sC2~OPwml^8HD3EC zrky{%E;sm|haI|)2?GHwV}O*wah*1 zGq7Ui{0<&MWw*=8Py$KR4;m3q|0TG>GH$P+NtMly3e&_GmUS3Le8&#)+!BPQIiB5% zn;L#ruW<5wONXbkzL3r~VH;RiLwULU^Km6TH>q^JwmVmA8aPL%b`?}e>|Sr&@hBYq zwTcQo9_kBXTYnv0FOAwyX&00OKo-tReu!LkEjw47o5_N3JAC)yN zzN!q2>NWUY_mS%0QERmPvGn)7;qpUAgMsEv1$uL3RMwvw2fi%#`G57N52{!0cLoZM z&gmZZWev2M9I<#p|4^Drjs}XYD5D+*8Zh}R5_7y0Z&V>Bxb@{vmEzcuuC5`4liZ<_ z^V63CWFH&=0kO+*@%g2Ey?oXQ@Bh$gQ?R^;RiYL>mm%wfPJnI~}i|M~9ox z6?!tQt50s5m_MF9RpY97IreA#;xA;A;js1m`MKt0@(4g=lzQJsA|a7gH83C z-CBPMVlJKi>0BP*N#cp-iHssV3YkPZUzXyoBSwz)3VVZz~4knDakja zIBotMk;z+T^iJ)iLefo~__7emL?4U2rfHnuc za!Fc-P?s6{0PplLm1<`*&S~>3k+a{$U>-yqAR6TgAXwZx{H_~lSLxW(4n|KS*z~Vr z2NLj9G`}gol6@I>bTRL99RM2z2bd~_^M2%0Rd_9#XCFMb4fhn4`BUJI^M_`zz@}8A zqU71Tn#}c9=y2wxtuW2`2z&%S@Hs41nTb1&br>|$RK(GobUTAQz1B$L-NRaxAw zk|k%gyob1aU1vJ1Fnj4by7dM&2u+#PX#T-R`p06_B^9HrH?u8)ZT;iJ1$EbFUpM>o z-;4s^TNbqw79hf({%QTK2@MpN({x%@Fn4e*d{pV!99lm`4tc+^@;;&9XE4W_BHym;>kF_|gOY#<_xqcp`f}v)C%K0dSZ653y zX)(fb*&?$!tu45IcTs)#HcveDj1N1bn}m$&bKLl(pXk#8`(_4DE`r@CyR2Z;(-*t_jt*%L4jdc< zhdi~rz(MmlLFU#P z-R*rL{rdd12K|yPn+o^iwS*1$rSV|Z*e!lgdsFgWncz;T%xdMhnUe=ZTWuGr#bC8w zAo&?7&HCRxl@u?F;HH2XD(73Gktr-N8OC)cqIoB>RaqSYP8YkukG+MUcz$PP7>!V7 zdtwLoT*~jt?lGoB-7D=%e(ls1El<8Q(tqu1s*BdF0R_xYkRA{3 zev~2@Rp|Dd)VsQ2Y{W7F6|XU7J>Lc)OM8yjxg-oT-4)O{5kaVeJLj0ERk<8D(k)yMQzwJb&GDl)!g*`8)eANxV(~C?mN_C`|Tr~vJGesmk!?n8D+ zC|wb%M3_ynu%_aXyhCF9I&qdAT$NVgDpB5mv4fYQ8(YGs@k%{TSCv2qS3AP0?7MQW zE?8l9$+v@O=iqMzu7jtdA`mtDK@Cig=`rB2pC0-`q)ODRrAt<55;+N%C{H8xPA<)? zemi@HjI_x7(D#570Qp;1zsCS-RS&P%_({A6ICZYTa$qLNc|pG3;&6@C@w*_uf_ttJ zWUd<9Uv-bK^ZU`+`l=>gMOV|%684PN@Jq#$M}}xR3_x-iAw^MXHLVG~T11P+m_T3d zjp%gKIm(J8nK=2}mm^xbj3h{BfO{Ed$id)^J$;yaohgw z<4HjQytwT5r5U8wHb+aLJm!h8i#-coso*%5)ZHC%w(KPK`{P~!BX=`owQE{QwOY(K z)nIYH_d3;~3NI%MMNm=s*|}>JgwuBK%BydUA?DKC`*5rxRRV4w{I+~X%r_$arLv_P zm_iwn)nbqV2j%7<4(Y{CgtNF0SXWG!8$%t8{j}jy@T)TY-~B=W$R26PX=?YJ1g_(m^~l z`vG$@&COB3#GGs?9p+Aw^utt5Ai~Zr$-;s+*iRzDhQjWQ?V3{@Dl&2~=v#GCpE9!; z{Mjnqxm(do?$Qc`@oayPsZHFAbD8pF5uU=!S+RH$d$da^UC9#uR=}W_nBaAa`b_i*C3?FiAyUse+LFt6k=FnM=iA@|FsdE1FBE>+- z4L!_U4Dh+Ysnzw+wwxX2MqnC1+90Qbs*@8X`61@YsNEf9k8SmOWu!3xYi1K}8kgYw zC5!h;{0;6B`#kT7vQW(ifqoX@RFVWZxiHd~6dXGiAVuDgNk(zNL-vw?ML=KBWBFP2!csp3o8ONI4k{}@#F5akp)z43e9 z*4^p{LI#kjwpSbSjfbu1M0XX(I4&%yeL;|mI-lJM&8gcJT9a$vQ2>}#@U=9v=go2y zLb9e=G!>rUCsT7rKb_hsX}Jm)=fD-lMllUh1aXDWod*zhPoawISt9t-rKHvyJ#U>n ztaLniD6*N}z3+-QUNn$y`8!yIcGWr_AyF|=a#*Xi$G{^&sR7g36LsX~Z3$Q`Fggq8 zWM|DIWvi7og)vxc9VZ|o>Zl=;=qX8dy!etNQ3XM2A*0G4*S`N@EGCKD`E7W>`;+E3 zL?(z_Hj%uWweA3>?pO8JL{;hUjs--j5sGLnJ9^J4x#$g*&C1)&_NH64nbX#apaHAH zp4u6Vzb_ZRlOWPzPJA%`AhnNSb92ni%O*zW4@t99;+W_FvR8KogsydRC`JUzC~o}6 zGKN~>ymeqtl$}7a*1P6)uP870<1;XnzwNXradEc;Z^hKIEAEf)O{MGDNU7nY8?(*J zPRN8Ms8*IPd@X7Ax_8s7Sz#4dz&TJ*o!TIsbu|q^=*YZ&HD%h9W$k*#9l_4B#adr_ za1>dk=2dPNG|5Qtx%d@1|G>9CQMnXz9E)50aSG*s3NzU-0WISH(<8b5`;h-hPmGn8 znT?5>4ou6$!~)`Gp`@Z_;s9DRd03bac4@#|%o{6vv|um|3o|PnC76YSg^CKq%+AEY z%E-#LN=*Z%VdmfwSMjMUpoQJQV@@u5VEp!MgGlpXETA}~GEcD==41QbxnO;RlH_SSR{(4hiD2t-^9iFk$ z(g+>o>FCa!qFbo~fr_DLLtu|+B}+XoGSBjEdcwLnkD`Krw`F8(LhR+45KCwH<^8Oa zK~I5KLqhWC*@wp~rx8_oiLqX~K;EZ#=WAE5uiy3w2AQWvqK4l=cO8ue;Mrw22Ek~N zP2K<4UGr8bXTqVyNg5vqdv%J+8Ht=ib=HLz=cXI{IL8E6{Y0#dhm%Sp&<$K?@SIbhbLd(CmMb$qQCQ8Mf<2n3{1vSp{|iuyUW7=;>ytfQdtR!(7ZiDPn1`A1+1gYGelBm|;FTIh-+Uvh0l(F{5n zI*dVw^qUMACG{2%xT~s28(anCoGOGX(|%XWqTbb%B*)RMNdEi*Iyp5w*TV2$W=UqB zR>s+zt*ebsO?P{l>L-FY;9v%$`!8NeVd7aQa<{ps0F@rI326*&F?mHYMy7h| zb&;Fyj%-Au+6DHX;N+BAb1Y;ot|E7h#QK>Fqqvq{ALCB?Y`7d-yE*Uw)>y*wS*NMk zoRaAgQwEEwnUB6&Faa0Du_g23{Ob~$Fmo2gu7asq-(V@dxmiuVS=*zM_J^rE-}FV! ze$enlLE7VsY~sBF0!V?bE{h7!N42?HomN}vDkp#^&Q z31UjTqY^!w9(~iTE4e5>C6g+e<8Bgmv{qV4WcUE zaUIh7885>kf$!c(nOn+qS3`GDvknu@S?T@qt$bAG@-XoeyeF>EUiy8e29NmN z5A>noQ}xt04Z$TlR2Oa1b66h6Mp2NL;wOZt87pZqFACq{d@VdC(DMEETz$AiSZ^AL zCGWFR#~qDs3D&nH&TA~DJli)GP^@oQMvBU2L5-#JdpWis?#oMcEIz(jd1dj{mQ`(5 zi25wS`a;OFyvb4Rt0vcx?0kzdRSg%r+1g8c?PC6*w#-KjlkwHx3}5$8skR3_0g#cW21>^nJmKS z5*Ogw?bi=&4RS`;%`YGIw;yX5M$TZuZ7H$lBH}};o7jAlfL8Xns#)LIn7;IRvLzMD zBT3x1DGf)?-POOUmJ&J)jVbtavu=kp91dK}j4&<}CX=8#r#@2+y7dBuDt!+uMlokB z*Cg7X`yV}88VQ*H3>bT}bP)?7AdmQ?XM;-{eI zS(JBq^jFjq;i9|5_=>@rq%al`r-;i9jrsGeVb^a&SxQ!ryYcxwzRgbh(*Wbwy0*G) z{6&`olziZvl(wElYF!b!HWE-7yq*+HG?-o5(e_ENJnVQ^tco^ho(AJdN@<~VEBt;x z%&40>T3|zqgCGaJ8Kt8$ZPlQ^%m|dGw1|p3CW?>Mm0&dQmGGrLEeQ2YZ?~8laUk4d z4mO3yLLs8-#d-hJ-Jce9of=OVfrcy_t?znN_tPiXBf*@Kmvyt(IHPrLe36Lb>udkm z^mYbMJgCR&#hK5J-`Q3(N}~1Y-y|YUVaR<>ZEV3ji7ro@qmR~l)1tNQJm1W>ceXB+ zb4M;+<%Xc|Lazf^Sn9U{fp$~`Ov>airy`UM{d{+6u4Afui{m$wWLQMoI*~yqyNS)< zFwXLuqamS}<4gu1GhAaV@%Jj3n;%Gs{!;TkQ6DHku_l z>ykB#xLVX|Dde3PjG`A=BiB=pil%`8%#N=-&7 z$G$eG*{XO7x&Zlgm#{?_D=%usz3Jxt>qKkl(bN$pQ}83&Fk_PC9&dg>5c{2 zibMvfA}4E)g>sL2hGxEiC8A=5_)B*l{HC1JjJ0sad4-N7rkmt{ETJ7) zT7Gb7Mu}?PJU?*DNMH1U-52E&rR%}gbZtg@_&G1%kxbjpsB#ik*%+LNael0`p%VV_ zo>62MC9T0$rTI_6s;2G+aW>5VI<5S5B1SBNDe zq$?qWGhD=1q^eC78B?8-%`nkuef*5wFeON~wCzYc07_0gP}VKsEm|vr@b0@Snoh7R z70O0+HV6&`sd>i;of78Chz`nG;(qSXC|hb*qUqNjmDZ*#c_&mA(J&Jrf(q>F6yj@u z9oQ8j9{%H1Zc zjXx6W3dNW-Yy+x)2C z_6qbT+$h!tz;&DxO9~`{70u$dL6o^s2fzC3mnoI4wf4yzYd+Jez}f495`ysO7|U}%#lrH2A0nL!dE@ytu#BD zAk{Y5nps$yBBbwvQ|K)R+VnU~P3> zv~V&kTdQb)f%$*NlU0{DpUPu-K-pheR0HiBzv^#wtE!wRP3?cW25l_U**8=K9~LF^R+rU6?G}8uge-K>1?^oG-u-qogU|@{wbzdGy8#c-$);s zR^3y{njt*U+2~(5D0sJ0oX04aE{wNC%3q`SxhC`o*g~p=vS5` zJt4|LH)9S5Uwr8MC}3z*43~C~dG=A}o8BW1pq~3G4==9iftqrF4c3e~x~1vr3ynhn z;-ywMc&{rYO{+ic( z{Y6ovuEqsT$)zdJ49h22$rmN6FL8^=#!<_vH%Am-m$t<{;5`OD>(~GdaymHxigLkq zwm=MRab^AK=Gm~NE`^7C_t-NaL!qN3-zL!^xt>=J#?t(B7($k!2#2HHi-72fi2IbQ zUQGU%Pm{>pCs?)T*q-0Pe9v4}{>;|7{`b)Vd^BEB{3hu`#dg|s?P#!P`$0$zNSJEW)>&HD0} zf_ixyers}$00RZDO>MB*=Q&O@p0@z3p5Vzo9-C(^3k;A8Gq8^uwlm;M3Z-x*r5LBF5 zIS_DgtnT$!z z=*UA2?O_I~KH(ygq?y!@etZIGG8tO!BA4}Y9y0VpbCn2n)6tuqIyP_6k@KuklZj!5 z(jZwhJOy0rKPb$3F0QliXWD^h8Y~f2awQ@7b0L^gKw;)=py7(=A&_*VwMPdd z0yJHMxE;u5=ZlJ%6CZ+>Zm1FTWTB!JJ@&3yr{1nDfen=p7f|o~O=gk6)(;}&*VDnQ z+S}hwi})e9o1ADplR4xqFXu3Cq(X67f@DB%^6Vfiujc8@E1=RFw#SsB`q)-rf@gbO ztgqH8PW%M8u>38YdT85D;`EGzl&OwaD`8`97MBTlX-sRMAyd8?RFw>o4Uv3{j4a|! zK6}LL3&4v)08BA z(aiIp?Bq~YT5-Qd(rYOt6D@L_uY&{>RHacssvTU-4y1pr3EGu9QOO3c%x4K6?Yo|s z-T-PL6kY|_-=ja%wc4;xq}eKara3EYTroa*#;-*nJog0M2$zH!uz3hf6hH!A4tXZ? zNv6ba)6@xe(kC3pGMkpSt+-}(NbW=*+s(FX*^b@9ltITk7$R0uX&g_siB^|o! z)2<`Wo=M3{pM;IPA^Dd`x7D_nK7oo?TWmMOzQ-l;GI7}uhgy)Rd$c?wMeWbX0P8)k zoBEe|#n!A-K8u=E>h=P^$@Zgyd!qV&A)fk3?^l6zdRizMJ~4 zH#(^6lTZs7Mi<=bQpiQMKtAWkbR|;__J3-FNmiU4Hp^?_M4v40sdp{8#8D6G*Gp)4 zMQM_kwUFjtOn3KgU@uyXcL1oVYT zPnuCwu+b)yi7Aps=Xu^e{fghb-O4yFue4i?^(bLlij6HadCKOPm2bzG67?5hc%M{p zCip`lk~V^TMqM6}Q;1*ZIsmG($Gjs}=f>VRx+V#Byv?AWj2 z9=&Hj)2!HWE+knO%qE7&w@+}$A)53CV*5UBjAcVh+G^yJWaG2!+Qc%oy1T~_O9JAJ zxp80DzZqe9$|R6Y#$cEu{A#mC7}-ch;B;>ndt|m7S4hCV^gZcSti$dr-^b0=a!uUM zi|NaH^5f(ZiudgzJ_&ukF1Wmx?0*{pD}v7d2*~XY+HE^1uw80;%*$>{C6gk0+z53> z0NU2-At5HAJ{a_lsM(QgWr?A%%>oJ`9!Ejd+zQJ)J%`YtE8mJvf0Aad6wFD>cP)j| z7#&}28M!YtbjMslcqg;K~$#JN@aVg|D_OHBp@J|poZkJKsOpNMaw%H0iCoewH#sC_o$Q^x#KMou` z-1xW&;IFv(o49-BWPBRcYJa=V0NY0*1bXUEBFYA*}SCxWu=3SE&7ZM zL*ccZtD8!%KJ|FH@yJ9IZxZ#;?f!Z2j+bBM1Uu9ME2}`Y=g|jyRLnoL-se_e`Inlm z{hx+5{e%YoaL=p?Q{Q=;S)1Np&*@aZ%XTt}8FxoB8{c0~Iujxlo0q3~ltcqXH?m~pj^<{rQL?lNdHPzLk>qHjBFl|n| zu1pZZkuCzLsmW=FkePcx=4VI2hFRs~MZAqKT$^1=oa|hjOp1z#i=OS6*TMk|i|)tf zpn}@Tm3fypH7lF+bdf~w%PX*tsqX=}S* z{@pWq!O`~S=|!(S_OO6gUu^g zoNE32>cS#)WHU9pgopA|f(AjnCNP1^_^V7kAg8;83kLDaf(I@F z&|cuttLKoa4o8p?g4h@HTU8w~xkZrDJpH>+K-UEHiJjhjWf71d=gyB3p3I5)< z<0SR&e9I7@+_JRG8sfmYmGe~mRrC%lBk*{)+vCodAv9Ngw%r_FmFKxcn`;F_KWbWv z6j7b|giiYVOIBvEN5?3c_R0DFX}7iGI!Rv2q)zO%i_O!v826z*;U4w2+SY?uQSOHq z7w)ND#1y=_7b};3M5SWLU&UUu8?Dh9_V}d+C6;>W~>Y}olzf)7e zb8lVBeDlWkXyOear8(kYI`9+s@D@5kQ=qrdty1eeMrM9W4Re8c-9{j?$H zd4%C+O5F-9E=BIb5)PHLNNmOGvd|Q1D<|L3={`(t_oh)^^`V&Re`dNYjr6;tx4yD< zQss2_(6b2rF3W?%I4xMxSxfCm96-x*P@;)1cPeEZXHna2< z)f`>78_Gl3jTr7bwtHEBD+5N0FdT(x)@=b^Wl0FR`llP+A5N;hTg!Nwv+2WG50QyX zUQC&<*YumwWF2=H{3-(yI1=Rc-n_IZu_dTB3hwPcrC{e7)DiWGgLHa0g>fmTc~0>! z%jM5R71cT)fQ~*O(anbrSb(v_ z{;Fdms@`Te!)QGiF$)^owqV$OZ>;^6-y>MVoW`l2mPu@(vxEmGWFgKL2T zX$bD_?(Vc`aR^S3;_eOw+T!kR#T|+lfA>G{&Afa_Ci#%b+&Q`D?6ueattTh9>LF3! zf?rx@8X6o_IL5a)(t^FVj7kx&Ujcsm;P0m2G%dw$XoI@AY-p{=+EZ5ZNp)BPI!!&d z411S5HO9srR!}q0=s0N`-eV(gS%^_dF*<*tCmJ6Iwrl^a>fwr}t&7^TdOx_vX%**(VTQ7gVkUOHr`(uBt^<7_aq65}>u&uEpieexQb?2yi58r--Kir4$r zPoki~{vbJbySZ>YPau19jH=y^O)1>dTuAXL({`Zg(7>w&!n}c_8pT%f{H3H9xKR|jq?9SMcS0zEw)FKFjKRs|0b?hbsy_`ldp zdIm1;l@ww+;xJ`GR6IYpiX78V#4mfk|I8b*1&JgV#irP2*Kh2Hi23)@OD}1-l9EwD7-$NK>1iON%hs&8Bz43SSyn%&&9;5GAM_DJJs>sjpYV3OEaQ-Wm=X6)7^*}TrN?w|Es zS2&>57c%2Nyv?-j*C?#7NfSF_B?Z^TVnFMH0uh1_+c7Kf!exJljm&HHg4#oT!3%PJ zkJaOp+8@BkK!_0<285gH*VDce(JPn)6hn!5=@quITx zNL}jI&F#o-gDDmvzK0{bb8EKGY+=*l(#ni_Gsx77>$6vN2o)KAhGiCQ>Gt*lpF5lP zR5MvLgFWA_#y+H>J7rbg0+RKFS0gY8z2flXJVZ9~o3e;D6kj&ZH z9&0Li2Uqb4E6)$-fw&9!%%;W9C0B<6zBK;yOqO{;x2E}Svs zYjBJ(eE%A(o|1Td-}#|Gtij&>agpY-NO)U24ywwxXL$cijs!%M^z5S5_!$Z==1ae| zsOA?HJp^mkI2O!wv0_+`=%O8pfOLUM zHevCZDGWgv!LPGi|H}PeiO;?>x9DX2XiKOQEgf%`$ioY7sH{Qv?3k#9_qz`UkNvob z_Z7clq#DNw(hm}I2Yd3BF}CJd)3Knp0%hGtU>klV5m%Pry~@hJ%r0=N0!(Zmkz+$u zpp+x^t|OZI>v~ zr=G|=2Rf;gn%Vq54s))>BjF=Y`7p@9r;GC5BK^$Nlrz?3$*1FLNVe9uxZqvx);Pg8 z#=1_lsI%XhkXUZAu@Pt$>kug*@=EOpD*GdEzgmlLG_K{OQu2uLgI1Rd$O7SWJxdB` zj94O&V1&Fv`oY=LkMt(|ABu}UXf9u0v)Ck5tmr0)RK@pO{`#Jca7CV+zC5m7l2`9LRdu%JqA5Mz#>$YEvr5z2&S$>Ms-Xu}Pc0!hAt9`g0`>1PpMQ8a*U*fx;*>=qcpQ zzx^xHI=MGwEDt8 z{p$6v8b*Y_mrHFfx)q14^%X>F%;rthabXKg+z?qva4c4qF!-5%GLvDeU~lIsrrq*| zp;}~DUA4rQWstoQM-p;sRgt*krU&CI+7m6@WQ+kZ{pcikuB>CO32LiDn6l&j18UyP z-1a@7VqF*dCa3I+^~PGD$9rdE<41#8#(MkOdci6)YLZDQpPFF??PiV%bw!3Td$JVe zQtabqaZT0<5uN;ESMJ)k%CwgzZ4A_yv?ZyS#n*JZd2&^DP;__ZWZqn8kO7NvP-1*i zF~T4bvOGlM;|wy9{nFQhwX2NJp~;QZ=WUr0ZF1rSG?1r1OyK~YOJcAtq_y>klf7-E z?8Ja#z2p5DES|5VgJLnN(ApmPqmr7km2)JbngK6MsQjnvE9)8qn@l1;YJDp)TIqswzrT{b#ZqSV^XgBZ}Xxjfa>gPL`l`?(1O_h{eZYOQT;O->{L);OH7V>eo2!g@cek(e+ifma7H{BMOlNTk zdm ztHla%Tqj`or0t2G820j?Gpa2hn)|J}Vkbn9^3jcvmd$p53b=n6{qRuc7Ps6|%UC!X z><$@w(@7#NC`|u{0%P|V3BcxK77&1Ssr*#q8eo7`)V~{At8P845)#6O+>ru%j5AF6 zjy>Gd_8h__q;Fv9WZ*{CLw9b{IUe(xOaZ6559a@2`MijXHsR7GSqk3jRbP9~UQ(_Z zb$5gTnEHX;`|~H-?im|}Af`ebHX?TiDhWx|B-6!6xx-W`dJaLmynw}!7$$!YYd>#h z_5M0~4y4p4y+0b}v>VMSDZgwq6y;R|1ml@Sn}2w#tSfK$5z|$QRhgz`W9Yz_But$K zbMc5)`jKC=D!SD{)wZvY2I>@|zCauP_94sH4|UHLXiQ$;(~*d^rv3rZ{bvEcC_=*v zaD12O#)Dl7%}{CVcTedB_!H6iB*)NXoMDw>BLP})NPGr^)8CET{3bGtx|HW6P?(`I z&1Qk<2=WEZG4G;PF4-G-Xbi^e^lVbUv561L=PFwxQR`1z%B$c863$fBs--oC-lJwq zVR$qH4_KOZaDD2fS0mLL1VKX@#tk_PxN}fTE*P`WHdq+VZFS0J!++bG+1}i)cy?Z2 zoyWy$8qNgST>zOoP*EUXyiu1!*hggJ>KP4@{D!85@YU(*adhKi)h|H&+%&s)A}U{X z(nC!;0f#DYIgFZ)c>vA$#a1rWOxr+pH=a;IxZ3)=|W0HSbodov`egIiK}Pn%0VBkA!`x@5qZKPC}nn~(M_U-2mM5f$rXG)99(*uHV4 z2qmjqfwVi)+x)CRzT)@Et$Drn!|F!{qfw?j8C{tga(K0_DLh@@PK56iY!^-c^uBfI zzAY^~HAfBpns>0S5BB%?X#(q}gT|<|jR|)A=Ip~W`gy&CGb92X`%RCQSnIPKTywbR zTW&pu9#toA5PH#9x4g5NPa-HJg$NAR1Y1S+Um66iFfXBL@g`;WgsDIQL8 ztzQTo+m;eoUZ0K(*7-qYkF>^#&9dT8a|3v)1GKmk3#YOtk67-jJXqK%q!k%|PZmgS zAu*PDzDau#@&4hoAp)hTn!u*Ej%NZ?jBAxMnfN@J8aA==wPC5xu#GOx3_;UE$=^|*U zfRb>?*q6_b!1ngDP|pIl@BHm^pqJV#<0~`ODdG8~FUz*gM=Uj<$*B+;c>BC)k!_Ft zZYO+TD{11_(S>dMMXh#Nx&_PqCeXgtQ~cpcfO10~38u5=D^g`JpZM1z+^vrnet9>@ zX;qxI-bxP^t}i%An;da^wm6vJ08jup_|u7^e~=K$#o7@l0#=e@1$=5Hm6IDonLn#v z3Pod*bL6m?lj$k@1s{S{{ta!_E1Sq<>37X((-)K8m`SDf&C>X@uad2m1QSRH`n^tUjxo-gRANW+?J7L)bS_ zaHO`I)G|Y6RvN6Ph#*lP644TVJAXxGCY80W$2ILzKTR(fpy*m|sP5|TUg4R-re#eE zBrB=^vl-k0hjz#G;5P7xM!{>k@Z35j61&v{dCq%Azo zp+2Q#s-ie`co&xcFXwU5cje)<*}&Y`cmn}u{priEFhYc9FcUQsh6oT<(dy^hG?+iV zls{Qw*Sx&b!-=1~f<2X@@|h|7v5U`lH>a0TAF^EZ@pjlYO=^3`e4hyn;^*!QpCk`! z{0GsX`_C)F#|2O{xEZ;4IF|?3{?O4e&;y)KE?PPUI$8!U z5g?J2lZWkahmjE=dD3%na4kqH>eUoS961w_tv7+oPSwH2-ak|!^8vP1rz~RG*~C$m z$@mCB6pF)a2*}YJSCYAG8m-|F{aP~|&KPaM5i{eL&mHwqBaROhsF{CXhJ0-iH20;d zFT0rW5r&p<)VN0mw&ihL8a^4IPh#Q%@)!cZ9}-!;Wf0{d`nKrS;GLKU@8#?7c6Sx1 zzJ?vTq|7{}pAri_v)zie1)9y2l%a#bI3ZwI_QGyU@K4-CaDd9AO+$0cS^%x(+Qw(k z8_kF0>hUCT9WzId^*dKnAYXFe09HWN_Ebd@Dw$L1aBQnzS^9cO80)x9POO)Cr>neX zO)M;QWzn!YP-a~Q@GgpwP2%=%$1;a9G^nlK{?&Pmb0mO1YZzPn)vxvWC3DWV|B4oD z{zeuT>Cf|M_@tkEWX0mJYX(=Dz`vo$L90J6M(q)i1=b8nXux8pYOrAXa?`nfWTIuo zJm50!+3UzEitoN~$fi$PSs1UcUO_AjWU9;Zh3&qfTvXG?(!s4i`sCdupLW|uwrA>b z?N=K%dhTWgfAZ{5&B?l5+tl~pvphQf0Kh&*Lm3Xl&8LM13XIqzbJpc`-U+k(W_--~V@ zMI`|I?J-Jrz)OE}1tuL(NHQ3BUl?pIaMl@8t}8G57cGl+SSX3)L*+GGcD3UQYWs(C~luaqi?K|z1`!ns9h5c#42b8 zKB@jZRehgZ2+(tl09T92PenYM^uus1{O=Y-%Y6EMBU&5A(6oAx4$%eG<@vN8Gk2ed@st6;;WU|67QBaJY=UAHH! zpROeSP^$A}7fH(Xdf`cPa*DGT+H3AAF_Y%jdqZbY=!G zaB>Z7A=fG|;pgVhe6o@?oCqb<2d<`by*Y87SD=dhn1=^O^91N$e|DLf4qy2eC5W>I6z#><9Y_C6`x&!6>Uh1)s=N_Bk zsX7rTcU;$f$Z2$0y&0;NM3q+@J*W>U=-TV&!NG9)r7);*_>7ys9WNBEvcf{yPQgq4 zTjGvyXg1@JeJL)RjPNy(KT$%@gm70?nJK=6uT$p@9~lm@b?{}hcW2OERmI+UdCCX} zbw${vnx%J75El?h46hRx^R|l=X-Al1zK~;DB)R;5>U`KsDbH-K_EJ zARxuIW9FbVy)E2^iP}`ACR%?pOQV>|c)V!KLwKiZ@o(^q|z8h>5y)?I)nU z=ye2y9N%ZJdJT|^q8{3bWv}_gA%-dy3dVEggw4DpKRjX&a`QZTn+2v3-<*w%0bV3F zGewy35ZnO%RWi_WnBz>*ycOiqbb9besqLc6SnXNqpPvO@+R@CphK;Kr+!Oc0B*&1y zaHvL7h0uB+MjH7Auv1{>Q*C)Hcz+YfDDhn)lwfy&A>ZmUH)~Nsf$U`k($fBZ?sWS#vl~Xj%(7b3}8KDNRhv+*64ySHGMv| zx63@~5vYjWollK?nWe87#M;^p*fij#6XF*fzYCtdp9w0BLZylSMuYUFynZw3yVLvv zswp=DIV1)ncp`jMPU%sh5DokLZV?XZhpN}XHKEePLy3>#$D^w`QSw+KYE1^55R;7U zLAFWrM6`ZO8P+jMQsg@xG%+hi?jM>7{+v5Fg2uWLpx#_aF`xw__E8L z0!`MWPPParjP}#-CX+CEJ~5`{@TDG%ba9d0E-ZD$)2NZ=eDfrKtE4-xk%Xt<_g zKlkGPYSCFh&c^lfT}^$5;93Lmwi9jRXuMooY_CT!z1o~rRs9wuUb?Kuag^dCZi)hz zWQCUem_34g6tiZZ33JCBE>13)E(Gh`z`TDb^@o}EUrBoS- zIEz1p?hH5NJ&^#KGQ#T~Ec_atTq4&uj|foC>~WX1PL~HzkvjZrSF``9DFv7A;^oD} z9@bj1QdZ1jkloN&U;nNtX96v`-cIPB*Gg38fOMu@U&?X+ZFjr_XjNon^vT%Enm;w< z`qk{vSXcQh%w!_E%|IsJs3PKC*M$IF^P^>D%&+W6uYc8}Z1eXS83h+#9%rFmS~6$< ziGM++TY;1N``>OZZH%Cs6ow7_Lqbg>a)hioi?g3pc_`#5pJ=(9qXOj05&otWNl^{N)?RPq*FMQgZG_QcEK{=P15ZV=rMvZi^hW=c$@0a_3A+(im zk2?A<6dL3o_PXT|fiuX)Rgd7B9V_@rRA~3RHKrt2W4V}lpyKtlPZOzksW`noP`Qy_ zTA-D*h|?!S2({;$?E__sSx#huKK$w@M_En3f94U+x_NJqAwZ9WwNxeW1)`n=*02w{ zpT)HhHXy)%s*I9N4wyIjg^~APccRRM5AwU@ub8u|;QkjX-Z+r}_4=p==dTStJYA;K zB?(mPeGVp+ATZ;7A~MnXgC+$<-3X)l)D^6%`oI}ntICQ>qS@+H@OBZTia5~h^V_00uCyt{{?rIXi^|!ytg@k$dl}-DPW#{bt zi+On~4K?|_8xj5&iHLCqnGrw70DFx20rI0YHHaty#s>=w9KXGeA9ozrzkL!uy1Q6M zmR7|6!#IT0k?4y<1+LJ}>ZG+&GpVuZSYazyVs#VqAJgI+Gk* zRR_rUCArMGZ};ap-0Q$m;HsToJwgt>=xL1~({t*?a})tF`k~3R zAZ6M#24)QBV%u~{jKQSCzmz9?%*R(_DA2O38NGMb!u=p{Vk<`aXj*LNGvv7>)900l zVh7%^D(c!&a;|huczuYhYhyl}IXkHJdsF_9_rt1&Be%Kdy(ciW>U)dOW^InRscV1$ zWQNGRsx_7kG7?!o!!#xAScwyJ5Yub5)hti1{8&N&+f3LbHGWC05VW?};Si=ZH^?py zeZF4Tc`~Z;-dyVAp&#+!9q^AjGt8J-V4SvRcnCzrwHK>k5M+7|&6LVbkd{f@Vf3%q zPSXg#ylGP?Rdh(X_jsx|woM@6-sk~WlcY7I%WZ~2n$4e4`J?^R(EIBQ~1~iNbojBLdF0|?+0}4d`wGcJjoDNMl*J#z&J1mCDgzn5kz<= zIcI{qD8TM^nDDpt$9ebDNv5NqG#aJ54U>&%ib{$V$QCT*Go(CxyqPJw9mN0M#xz_p zojsLl9R5BXRf+I}bN7))bNl!SA{Me9YZ4+4v`m)Fspwo4OADx2^n!QM5?kIXnRTGY zTfmP>W(?5k8gw$`D6Kb@AFY<+WdiGL=>aoc2v!b5{1rPw#o;#9&m)7EA=4se-1L#b z?F_UWuXSffruSmMm@omC-@`5w%%iJrya-}8E5+k^3j^g+s?~+^r~mFtzHuS<#6nV2 z{`qGbS?NcqW)xy%Mbn|?wcnx~4bY_Sd$w-fc8iMBW)_yEP*eRmhmZ26^8tLR{KiNf zbe;PPjrS_?*)g>4tX$>BZJPeh3PD=^EnObdr^bhA8xKSc_hW(LSo{>BJ|?O;Em{BN zW?f-w|F8H6tcv)*p|~#RNcbg3{Ru6%4imKv*BItoB2886m7n}C)yw)|V@0qXpCQM_ zzx*+-@_-HTp{#hL7TTU#R1tC1FILq3y?UI*C{=@Wyt3VfBq}FaaCE-f5I$Nxy4wq= zd!ZAwXr=*H{%-D!(pcacfBn3{pm5)W+)RsfcQmZ3^i#DCy zD}ZJ1$%G<@u!$N;DIy-XUU2j-RH}9f&(_V4n!zk$Kw=?Gf{wZOMLcV|;NUHZ5q{lmCB#koyBYan$EHA9zuZS{(#V^06IT96Ie zYp0$>l>g&)kYWM?$p3OXgn`#c+ucVYIyy!!L5{8IH4a{0IuTwDT7b>L1n3?c3=B-H z90J_C^jv&=3_KhlZhBr2*W4dg4h~LU{&hMA4pt~W`Z%tQOTIs=3J6@EU^S#jnsL*@ zp=UQ;eHoCqj!aRE4qz!L{~V$bt-b7Q3`!uBGv_S*;W|DU7q^w;Gw!&z{_%+2DuqC+ zio%=2L~BGyIeedtmdVfxu&=Q0Zh9l`RRnyEOM{b7Y3;UQm%w^4{RyXgJ@JkcyM7$` zb4Lre-Nlu~jRm9iEj={~y1!-D0*-evtK(_h%46lV!vHW=k=emO9CCpqpGMyD*~r_Z z*1T3p!$+KBsnH=*{GGS~mg}_p`x}zYj9IK*tAjb;r}+(#Zel91a`1oBqx~{Gy8XbD z25mV=SDYs#h*|4o<4xXU60N${4fL2-knx`-*L*DbE&JjA&J1_s!}M271BN6?If>U{ z)P9}T>MGu8E3S(C{kg8~Xa#Hq+c^8%FPF80-3lEewS}#gEE(e$K;V&@xzYp6aF0OS z!FG4)M@&<9JYjcNveT9=@0CH`?#YQrKgu67>|xRkSb8nc8#!20iA+Y{ylto+CU{bX zf!M%=Y|}sC&s^Q$y@RuQPHNoAw8c5(7+Q5~FtuWu>gryob$`-9FX3cIAm8Lhwi*at z{k@Aq_=>x>pH`Dx1a6x%yG>{#k`J+ANPr+k%vN;0B!6#b&GX|mP6fwnUFThsY$1AB zpa!5Pe|fF-^OfTj6T<6#EITK%WeMe6x%2w%^Vs5)wKPue$dCP)b-u=_Q4G9)8FsC!|ZGCqf%JY&GX(uUQ@@)!u-?r8qj7c-^@n1I;<3dMVbHh`UT^lRBXP@S!f6L}(1bo_l*Mq)g{ZDV2Cf4W?*P^~K zig>Wn)gXE>(IFsiBh!0D$%aZ9y&_Nx&Utyh*tA(3W6h}UF<&7}R4woxmyT^IK0%2_ zk4r)mzU$WhMP-;KlVu`?zrL2s%JnJ#h}qnfTS!FUvC&S0=7Byp_R?#Aoz!}KuZWuY zO^KY#*U1;_^cxgc=_zTH+H$pT@%i7^3Qs@MNl44@I(k&$^2E#|lH5@Yv>DInun9mz zizq~nZQmylztlbKAWS!U1+!vNhqd|hrVHKLsPgyB9V&hIXi_tCtaE2~DPj-6V{QEE z&-9*DRYG1eG^3l++(SaZ_^x$;9s@@Ak-xHTj{2V4oK5|qP&{Hl6IJt7%`9B z)E^{_L6d3~jJNVvuNh~}UeI4XtoyVl{?Pb+?xdGjdQ=`%kn8)^_n~5nHNluD%$T&_ znW)d$%ZW$!sm=zG6l#vp?~L*DHK!Tur9Sw}!^)k^WJ*PYPUO_XhC5j$b7tuU(|~ST zX&b!1KlCs(w6AOk6$F6WT|zQ`R2wpB%ErEdTq)R_cbTcKvlYf)vy63|9QRK%ztHLO zXa9!s*?I#-4iGKdgVMRzi2h2;-Tu8F>WO1u#k3i9yA9+@Bk86ITLMt1;IMv}!Rqae z+9~_2OihCO`st~Ng9Dz7e-W4DW>Hhj+0bjtvo!u<-IZwC=NCtLsMT{q0l&#ZI=oaO zt28vZb5E0c4r13drKhB@vNkhVt;tKPpOH*8d)oY9c}m$_BO6Ev%rQ?i^u%s&L zI$owz)x~5*2zyI>(rlULW3F+RPLnXgIDB@f;le0Fj`7NIXsc|{&9`I68`y07ox-dP@Chv zG@ZOcd^6b7yqMxM*MYD0MIA^#u!B#ePvaWx$&-iu&;b}hRlMBbOdTQ@bQ2bF0h0@g zDUcEigP_y$6g=;pmuQPyl}7HYR>vXG`3QQh3OdLLmwhqlzx;MY9I1*b~79! z92NOJS37Ycu3{*mAdQ9;zupKaBtoQ;;FRNZD-g9r5mDC09#(zzbHiQLyn#q9(ZKhy zPSc&IWL_{~jFY21F>?9$181fOiGRN%oGd7>@7HwWs z32H;s4MT{)w`H*$Ww5iyi6Se9%+Jvz_so=V|HO3AeAoeZfsyACT*FH z`O9Aysmj};Nh9(9+DN){sokfRs%E0X^vPogh|02 zck~_aX(5qIOzX zEQg2SUEqNOHaB?zCfEDacE0MDjA(n3m}=?|To1zU+2$a)B%z2Z`Y zydlGHz3mY4ePp!VaSCw0b|{I>TWz2>{(wl3DSu_T1uVFVv*-3~YyLZ~thldMrqW!b z+RUs@rkhsF+_AX&B3zZbV>jko0)lIXr=5Z!qeY`dIywV`c*i;&2`%v}yaG5?c|X+7 z#n7TQs5y$hczG6|Mc4C5cx=n71!a8hJYQZugQS9MR67_3wc$io&G+PyGS&7FEduQb zwei3ReCh~4^dhdU`jm}oxhKtnXU!{IPu6~yuqeK6gMt(;1w_ltkGY7*q?40T4Ap`ELc+_z`@;|Hm zslA95JqB_0Xq{I(E2eQB6oC)_mAx-7r-3iN;y!2p`$in#C;?>5lw1mSgPb*>AJdhjziKA#O`5`ds+Gkc}_`%Z^LAL;d{ zJ|41EOIA;+3dcDs6W>70hrOa(Vz&PP2R@PD(P@OsfZ1v9oHO2tg`a;EHm9oY$zm7v zZtUUY84fh%c9t^rH}xzJpS}gCi>JMlhfoI{FzIy;>)?bi2kF;yqB!o9lGzd9s(5C> z$o!tqT-_Eg&(9{~*zu8L{oGk}@cPj^4>N9Awn zFrSn+Id=vcdYbL%&*GRe0QY{YfvcX%HO<4`$N~wRDx1BgaM!OUS#ti#^XoGm7OgE9 z(6)xffQ8w1rnokt>~{bG6k*~DxnlJeZ<-}YzD&(j_`B{S6XoGnCpGa_bX#kS&X4na zMt~Lp)L-bG)3K5AE@(ON^5gXrN7q6f#B!LT4E8A|)62~b2jQyL7CHbT&djhhqKT!(sP+RB;IY18p7r|873`zr4CeM5E87f@0M!6<7|9+nWZ zIqDWzVo1{R$yYvSQqnS3o3nip-E@)+27Z(J>vzO-Ik z^8Ktum4ja;Cq0*vi$YEKVsxvnZk4#mO}O5}o84N6twPok+}6GydVx5N`5-hV;?(CYYn@l3=U+1f2BqV*6n}C8k0y{)cf;eoOWZ zR`Cyo4}`nuFgrbn6!oBafyVSF2)|(XoBRzCtP>_4cc|ir^l(=l9`#7wh7+!^(%d*u#a$B_;yy)7M^5*f^j?J$PS0)GM zWLej*bf~+Wga?Mcx-yX3G~K3QoE>z7jt<{G1%JVFc}<`DlTDRROD1WWXgFd2#?mhf zT|Qi+EV6^qT{_*6Dc?#W93z<`;6vn52_SBXVqZdL`#ZrRw*oWVK0?9xxtK46qi!}_ zLIJ5M)jCk^;K|JYuqx-S_|#tgcr3`6hsJBitrCLd%qLpbSi)2{V*G`D7FzFlh*w0N znkjZ|8i4;VBK|n;yI(i9-*VCYcdzqWo7lbx^(&8ANq?x0O%!g(@2maPo?|{oLG~d! z?llmLv0@J1ywcYbkM>{>{(ResY79lX=u^>V0Qs7Na7 zHBFC(5E$sZMk+<&Qc^-(t!e029lmffb9s>h^}RkU!OdZX&2iqJ?Z>!h(l%DuSE5NP z#tv?kU^@^R_1TF9_nd+by-OOzFFmdOMZ|8^g`Px3L2h$ov#C_B#5|R5ItM0ph3rK{ z2)L017}FDkj6nj2`Z8QW$SV>!-@5l6S}0;Loio+LjN{^Zng~yEIh8(PU%lj5(%9D* z1Zqw18meYpzkE$DDhxl^wNNCTpR6HQRo_*^-mSb!I`k0QqkOGhM%`fT%M%mDGuL>9 zQ_Y2|Mu{z9(Y~gK)vEfpS`=M!kPe#P9vcwN&L1OlE29=6qEB93IO;SBF&nCQJSBAC z(eY0ZUFtH--3g09E8J^*F_ri0L#bnE(nLE7RY}?@gF!--@e_v_=@R2mh$OY;r}8;r zZ4_J|<^{rk#Ho8wJG1UY0jx9F3IL*|iPAZdLvIm18Vz}mhBAZ}x26R^H_a%l3> z;0Xj}sr+_HReIa2cOAkPLt=X@e%v6de&gCKR{lu95l!-cs>4sE|5qJE0M)@uzvsIY z7Y_p?p8$xC2gI|#%)r6324FcjIr({L0i}V53*d$VPmCbWc{(NrMi2;?KH&t>Gw|?m zva^A>8MrxjLA={)${v49m=Isc=|_hMN|EbN1dT7IndlFhG}JSd2o7(AriudjtWV12 z3}gfL2tredf#djnc9GcCJUjzpGd*ET7o|wmT~jN#hyNS?=KgNKI%Mqne_OK}&~AgU`Gx>!Nk# z!^=6Zz1k?DJ7F;6Mf4FBKNu!gHP9nqChuf>|Keral!PD;iRrZggBng2ia#HXVs3q= zj!`G!PCEck-5o!~%h=))mibLPyAx@I7bOhp!@`Wg(=)xCJ%H2h&A++=gr`?wX?DpH zDgMRE7>0pyiFS)83zRS)UeCY^3!brtuo0|off1qM?8zTlOh6ZidYT!XXf^QSP|Iwf z!h}ckY^0YW{I{*|Fh$f;noZ)hog|`}vceWG-QT~^V;g#|D-_=>Sff*gqUf$x zRJ(OwLuqS1jx|irS^eO2wb=OH6yQ4pF0!QjjrXah)8XFI5rb({ zUMDIWVkMpmeo>NF`|O?j*Wmr zVSw?MzK|I~;^7NsRgPs~mWfYHqim{R*(qG{Gr?s3$Ox&K7G@H*8hs+g3q_9i-Jp+e zTU`d59ffduMu-|DtHJ4(m~e+5PG(-Dm^Sg-`t6cxj$VZu8Be!`XCk_C)O1TNwP|B- z3s;;=B5SxnlP{64Z42X2 z#|+22PMPNze3@qUIL|iy!`$C*gQS{&hZ;D`AUglT>85S{!cy_2^Shc-|HsoWeP582 zos79^^DvMhcG1ujGwhXh7jv;de6$MYjEX)L8>PpOb28C``!63$8!Cu;fVz=r0boqE zj@e430KsS%hH%gDs)>eDwN-fj0=4p4_;uT3XXikdr7HK8b{wx7R6?r}d2_*yajK5` zuA^{ZDk>zZA%Ji!-p^vNbri$8yT2yBL5=xr1mgbqJlECL|LQ{flLW$f5b7gb^`~-> z&#OO|9V?R>D>F?z?A2=1bslz7jFLl(fnEbCy56a&2hVS9C6{#MIY(x)MOiA&cthT9 zS=JnHei}T$>?iCqF_{`Q_Rlu8ls6EX$^9TWTszq^=*Oz3eW>8hc8GB*x=RVN-ijEa z{>-JCv@KWm+ebNrhFkFX$Qmb+27J;>A>*{PBHu~hb#q)

    brmF!KXdh%rV_{c{ov z&Gt=dfZiJxjrPJttyGuPvjiJOR(nBj!Bw9E2$Bt3%19c6oIbjT2FIO_j~~& zBL=iARz78)GTgE1(QJUdzG7M%Zg*WD)j~C5vh=}zvTA1PeD)cE9jNsXjIWWIkE3)_ zBJzZ)=OIdu9EJt-D`Kh(Bfj;WgL#5ZZ}b#@O5D&AuQolX;T#)Hsi*qz`^e8F7h2Er zZF!||!kaSu9)#VKCr^gDCZBg+Uf$6{UTXmIxO$iVJy?U+@hWrsf!oV)~w6i*)gZp@FvJ6$^;a+?;0~8T(9dW-l4DP z^ph?_)hre7jMpaQB0H_ghE@*CzR8g&6gSPXLXEF*Am=YH?}1i(Tu}tW6`4VoudCT_ z+%JO1zK9=cv$Y{w#^_~y^$4C}eUSUGhYRU4mu48z)e zmvViu=_bt*?YGVm8_#7y)u^?he{Dk5AP@){1R+W+K|=^I)FbUBML}P^Tc!UUcH*&0 zjz3G7$78MfkDV=n_?~opbn^Cg>LmATBlA0H<&s|$J#IhWQ6_ZC1Q}Y3W>9qN$bLGi-lAoMOwo=EUdw+892mkaoKz zDg&GLz(Imq$-h?^N_o6rye%EzMA>f!HS##aR9(I~;xj!6r+ zK7vkB9=#^YtLF#?4v7874G|{fmCM)uQ?z^8`LWb)?Rnx?oECMOIgw36ch?_DFrf14 zade3AcM`Mde1Byq;Hh`J5jXg3vlE7e{@etey99B{2}U%)&zHm$gUaYUB4E7hui};% zGp%eA-eK9}OAwLc=`Hryrj0Q3Ramurp>C1|ZFu?Ls5-p@S}{|jDij;GogDcSOH7`1 zaUFTh<1Mie+DcKMsGVocQzOzM5iwm>GRv;t6xl+!_hz_LKn~VJ2=^f4L*PT>e5L`!An&lk@xUgrRi(WxQMF8e^>{rR17Bi5N-@&_-`82u`O%WHV|amTZT!sdVO-WN_6j|F-53a==4)K2mvy=#0)5i(bHz zjV0a1GKC_0YLk~n=Q%`={ogB^09yo!kvm?}NQDo~=;jKFe}OP?{CFS&(4#A=_G7$y z-1E1seh-_wj-`MNUva{rba%fb6D7n)1nnKr+i74@h6vyuw1+?zclD~Kp^QxfV z#8#qD27|jbl^DMPB~j+@eYBP(!^))e+I%p{v<16+gzX;ZcwwMeSYJo>jn9Nd=z9`i z(n)>>S!;#xgqK{Dfciu;?j%EcIum>wIKeo}UMNy6PI1#Of%pozNkR!wGFIbkXcA21 z=!H>inLn!(q_m0lTXgfgQ`y~Sn-Q6lYG}a5W(A9*oo~;2DY5jFN5hVoj=iK@HE@we z=?mHI3%V$NKi5ZYZQMAiCaE459|mL&lBPQMk*4N`nP)QJIjzd8t_YBpb9`2Y!HcKRD0s++fF+NH~RdX~fFQszQf>GXWm*_dmVNMEC zgMN{`M)q^?A!bgOw`tBXXA;b4`<~{wT=4#srF(Owe1DH8C%OWfal831J|4^Y7J=nLf)Gq3RXw z(ov+um@)W!811$C6`2a=Fn50gTDa@uz4s1eC0n5KlVI`Z?Wq+V(YPf=uM{`mAoZ zvbK)P2;x$~ zWHbI;SJ|>n7?QT|0v$3re_F^UshhqwgA zmPyDFGd4TSXHLdxNrclh{6@j$19$Z}m{E91PL$?otxl2q- zhI>3uj%*|A)CXXkgwHQHCn|rpebIEHF~3%nl-RYfbyt14hU7}HZg3YLXqV9%1D;maNW(3g;lGzbn>qo*F(eB>x%(4hMcX22n0vv zVy352ONywp+QMu5c6nO;=(8hFRzqX(<33L@H*=-sX1oLst__ZnPWr4Jd_4mYsW|K% z;8I$IKMYRv6a37K1m#pstcZ}8`q!_ERrM5gKIZ(g3~S#}l9Mb&AA9aHYS=H_k`xzg zg3gC&>aEEj-GxvTDAzUf&4NxpK7#uYU%%JzXOk8WF(^wMVKQrEDHK&6%C< z6Uus`4U?CODkG^>D;N@qIBX8@qdRn8s^Gd?Zy*jNtLMM<_cp;F=#;1>vT^UqKX!i( zpmTwS^2$xmTWZ$#%=bJ-{?o(}ups*QS-OPhbK-6Qe-R)&RcN#wd2D7Tvf-%eYt>dv zQ%%hJUtAYJgFTRXqA~b8Cj*fQbfi5!?ax!m&qu|Y;wdwSc|wh8EWdNS$m>*jmh4E@ z(-~Ig)A~A)Qq#08DfU0qB@d;uMF1!De6g?thMP5t#Y*JRLYCUj=A*nKEZqV{j=kJ) zW~#q$^8`n6nBoYW2AeW_+8{i>rkmTh z-8>qdFjFF;F)Jb6&EUkrrWWcw=`yTe@OHqMq@dp}ep;0o$yOC*NzHD{V&8CJ!m&o+ zR08%lC!h8iLC!LtgN^5^@4xxl;F(Wh%X2 z-3_FQ!8vnucEqo_`*v%m+60}X>EHR+K~w6&ngU6 z?*u@{E1-V6&`a2w^?FeQ+vY?Rjj1lv-k035M@gaaU>a=9@7s|`$2zU#I{>V+Xq|4w zSEi+KU1*;@YP?M_y+N5Wm*nuD5Q_gK4_) z^>Mi`Rtgui)`>-hugPq4jrE_Oj$G*!t!#xAT@P*6s$=fl{e(_K_`$+5AB6e29j(hH z^i95=j}BI{=J2#>CU_308~d03z${5{wj&k?Y4po9q|cRW__Gn(5sH8AzqJfNPMvjZTl@*RhVKa4jgiUxU$g7ije&be6FC4YF>Dn@KTWQtCC9m?EN?S$u zSrHR$)Yn?FXXBtad6~~C`fRr1+8ZeQz%$CMT@1QUa1?e!hCjrdoi1}_(emP#{Mkvq zR)c%vF?F1Cg@@^W7b!B=-#qT9dX}DMlBJVIMhnR+$qeuD26K zIP|*@8s>$kis9a#mHjyZPI%uEH<{}!&}40Zes6^I8+v~3Zz=iR6L*RIujj_9)9Ff! zPU?jqdjrCYk(5WUQPl;h%Ow+1B_}XMs%E_cHD`9UpOT*Bd+cw#ZpYMnFdsXx-t*ii zy~M})Fc%TdbBSlonaf}>pv9fW^wgn31y%#~;L8-8{Uf7ekfq~D7oD1q$&u&$l}R7S zDw1%3$kbd?t33u&Ski0Xm>Sz;Mmql3a*8mIxqe)5(~09hfi}yOG+Yf$BoPUiSY6C zzOzl{?`8SeAzj`z;Mh0g0SdGPa+_s#Y(ytjrOa5gk<#5i&m4MF%j30XI0#yw&#(_Z zJG5i9pGQX#l^)@EZu1-8djt%Xg?QQ=0-a88otAqdw@=eo{TcPIj9U~HMY#>ElG4>Y zLyUE*2FAi_9c!{;+s*r11gl6+G{IIr zhw}Mqd}6U4$90$*v)z^fSLOsvvsrTdg>9!h02Lrk%ZG#?nJ?D#Bd+y>rUGi4aq1AN z2oDZc*-K^r9>mMk69{1f6VSr%Trc4KGgmR(wgZtTYfqZ$|H zuy|*>wkoB6to<#pc^jq`TxgJQU=VMg=4nf<@cR?%!6+%`Svaz)-qFUz!rNAs0LlBe z)2?40;ZaO$WUpn&;^H3s-hig6C)$8x-|;}K@IXTb`{L|3kJBT8g;mx=GwvTfi-<^r zvV@ekmY67X>s#x1IztC&!v;rK0<91x#|I7lC{waw#W=eHb0IY6MZ;xNS>XD47ka}3 zTn;+77<}tD%x;*l15Ynn%VG2(zbE|#*}__&EH^HIl73zRdcVy^Vs>`-YQCpI&Si2r zq?BTB*>JRadh~mGlcl1eZGT*2c#;N!Jwg+@72mj|Zkua~o5kSeLfQqdAC%{*BBN0} zIuqt~ZTubX(v_-b)uE%>G%*0OxK-}7FWw*}aB7DFR?aGAz#it682h=j#1rbZk`2SUP)qn$mj9pw&j zi=M+==C}A*kb?N}htn0r87~+MZly(ltbR!-=}gn@dg!dMi@%pZC;{>a)zYay;CZfT zr(@b_>j)V(y_%br4lq_h{J)EzQm z4@X&CWR8qw{&ZUBzY29J;2zX{ql~k3XQy-5;Uv=Lf>v}_CsT|WxI5T3@{2JI=UoZ| zHbmxlJ1LFJ_y7R~){P!?fCk_GeDzORE~1b$HU5`32O}-6Q91=a)K0eStBihV?n@wd>dh z4jDy4uK7&nQTe96D`3P?PnF z5RC>HE~qj|0M1ux=8PVL%3(ju?>~ZYI$zioXiAk^+j1pC|5k#x3Vn*IfGvH?c%kpyYaP?^K@YD{mba8)ZL55JpVV?GbgIlZEi-wGWJf8be6AjI-Q4KsA zc4rI<1^{`+l>ZBsj;5zfLT>%CdHb@5!9mWfWytEQn8S!mzb3|)f*+Z{nKV!59+c7a8Ry8jpz5I{=&RWJcPjaAmX{aJm|zCN ztcXuf;aopi!Z;ckTr`ge%VoEVLDo=!#O z7`GXtlRE9`FP@(^wNln|$)@s5~S6i3#h#{G^nK6z5}DGoC)GLw><8Iw-#=rgD8$@y%jW z$X01THq3 z+i45WDh6wdf_4yx#0OLDM8oxqQU@KDj_zO<%3IlBT3CX^G!CYNYunK&EC+?|>82@p zxO3fR37Xo}KI&HLt!qSU+kHlZ;XL9IC)5Ue-_EQWY(YBnX-+HyRw|M2Y%7cRqI`$i z3bXCSMj2oitV9wLkyCLta#)5R3x9Xt>ev}&m7^!eLOxHpr3nvF=YNnAfKta z)>A?YReJ$1--mK5+6o=hvds1bAKb}Cb2jO@K&6s?3?7rnuuO4Z1EtF}gyc<-g?zU# z2CQdo~nRonz1Ec*<68SXj>feyvC5Fxxb;&1N!K zhn=L!Xc-!j_r~O9^uod~|_DWkdRXn4!&_`5pr+c?1GA877x6YqDy9nlW!;#7W za@2qLMDwbSBwsh)5cEU!q2|P!e7m8$E|^Q(skMVkUl~>g`wmWeUL}q)kg*!M_M%=+ zAWx5Z!T08(gG}yU5WP=U${$R0Avv7hd=S>k+d!EY9T;-oGcQblOpM_p$-gTVc|JGQ zQARxtz=Or%D=pD*|M`0e#bSlu%C99zVoC}4m5fMAzmghZTpV-Fk|CfADfEX?2v>bR zLL{;-)9fuh;o(0BS8GjcvTnqx6bpswMmjE9fb zp)fLr%Fwu|r7@xVMN7>ce0+Ra-apC1?VdGO_PKb}Tzmuzq8fSEQy*X<^8cbk;Kct# z2N9U)K+%jywC z*6q#z^jyFc2o4?&5FLO61{-3OQW4X6gO?{Lee!j9hUY=M^9?%sz9GZcoi}x+u<=nOrCXvrsCbFH zZK?6~*0s$XL0yUFumlaUHKi`X)^u*nSb${@s8`^Cu!#e`>WP1us$DQf!jXXB(9hu@ z^t}2wlzUo+R|5HyPx1JRXw!wX#k0aw4$V1ouSXZ4%QVoc0RJVqQkH3k!az*N}R{sNh|9b0pl>i z5VG&vN})F}dnq3VQ~FUgrdi10BKUZ(RXqq%T`Ag3MLlS>L&RT{IWGeBXaUGV=34(x zrq5&AL8<;I%HZBGK>bUWCkPOjf$I#+}%L*ZEQ!EkQ&F4s0G%Agdlh3|I*Q3sEjG z=jSUs_j`*wDT5M^m>1n&9 zq%(iE|C>0xkQz}Z2p!i&>G`V>Dteu!kS(`Dk+70$9VSV%;9lkyzowl@G;KVbzKXH( z?XG$2!gU?0c}Hncw`{2+u;x~iaQt?{qscnKuKe8SJCeFw%s}PX<25;}B0*!C!g6Pn z%2C;rP%*{Gw$*gNii3dDtqm42m*psX)Bs-$aROjG9|<-Q4_s*kFs^$lqI=x!joG%X zcV<+_CKxn;Z&|I?ZkStLb{Zbh6<%6v28nMIjTQ&XsB;+AP+zEgciajy`lNzQx(T~a|&`L z7LpOI61s%Bm%6A1af%Mfxzo-aIlmxVuv}V{S$MB;fS{iWo-Say5I6BsCx*16lJt~e zud}$j8D$<78P=oK$AtdX&;ccV@gJAMQIe&;6$H@%;LCcvp~W;I#KJ(21_K4&SfIH% z2WTWR0Lrg7#i?9}=*+HeX~fBbv%;6f#^RC4gdk~~d#FyePaYffm5?6&9-Ajfmq2bi zp$R{uwzQP%Q zdlOw#KuIi|#`Mq)%ecXv*8k{R^UP)cl*g9ev@n@-Oq`1nujV-~QG zC#miLkz$zd!g~Rmb^SQUY;IJve#_9!-HSsmM%2j%&#wFCjg2-i53iuz_~1}i&skTG z+;k3s_w@OitNiwkmv7K1P4>?yit%IA$$zLUweJZ1sXiYL{QUidhPfT#f%E;Bi6u$; zR8RX&65@S!HW8ds(4FF{5DrVx!x)qqg*)*AB;WzNngDU0~s(vKeXx9PSaCH{`&$jgGZq*9Qs2NR5wM(u0{w_lkgNny7 zXf%NS==en9k|=>aNsJ8dY7h^9->Xl;9Ah%#GC?n60Z?rN<#)MkgjL1i7VNcOPYXW8 z+3zqw1YBBMBWceP+~wPADWj`|y4hOBGRhS=f+MJ;GkuSLk}J5f9Ymm(ITe4jq!ScF z0H2O(s6nmDmpL_>*fn(4Qo;zZJHcoq$yvo|`Bi+n&N&5eKa*>e)Tv5pzPM=aB+By~ zn(kZr;M*E$q!Yg{z-LY_p5KeiF?jb+Q|mc`B$v5h%2HNj+4ZGK!?|Lqw+dlw+5FTs zCPK{q`q%rB#ls}p%zcbsFs&~NC(sz7bU$0RE09XZ8ZNg*3`mDk3oMXlu!IJT?zD}U zA2o14YS`K{u+W>f$m`kaMp&)C^;Z7vpo_9PXgFuju0+YS#D7t8l)@rn31#osN}A9OOf#%T5yP@Ju+*yp4kD0jBCods52JTCKx`i zD6WJXTMqXIA{v?lEfd0-rAS|M@vv3Y+~VnYd5%|1j3yF}c~g zUaArD+Ow`cJu4xg`Es_{aORhrQ2 zt7uz@-F zFZqg{^{x1z=5F`33itjF9Y+M@zJ01Qd;n)2{z^Hqw{7{wDCtY~%aV>)=Q+=j`DiEKx;OFPy0_8u zkoEN*zAbyKbmHPD@zp)!eB7s!OrTc(@t@H2EYuvsn!nbj^W@}cI!w8;)d@e~61h1L z!bfvMGE%7Ei8Dzmw%WT5zsqHY^)w%30rMQp>$cJke|yV~?()2Cn8ZFT@o$Ja7pVp6 z5tEKt8u+bYDc3B!G?`DS=ID1}*rEo1=X=j;u{E9Ww8KFUFY^v@2#L&-Un3CC6b1cj ztWwTTs&pBu^pod_ z4>`M-otwJL;_zE-q{qKR4;GQTj=dWaG<%5dWJ5AoZ0N98R>yQAsN8MyTe z9q$^k=ow_tADp6kt80I_9qm6orT_8f`()z|x zEF`0@7I-;d$lwAM7Wi0(ZSzcUTjr&vU)1h7bHP^iP`G#^oh$#ba1T*kBha@I364C+ zl9;%xw0dMsUr;50FIYe)F2#!>N2J1Gq7YpQ=4AhLd5!du3~L~~UJ`U$lh;Y<15tFy zD$S0OaN4)pvt-1=$B|GXnk<2kT>9}Y>J@w}^xoey5HAS-*Xt@Dk{+*Hi=mnMbNCw~ zY-pP{rvr{o?ihhHDp(=ObxzG~@OR;Q3>8=WxhUmH7wvLm9g(&t zp%!HYZvg!RIT!`3Wd3Wf4DPE^htovir#?$yFohkpAk+pp^hKZ`sL)2ezxIad?ijFkQUc9XAfikyR6E)n}&D9i5tw$m&a* zmChbFFNyV4ejaMPqv$M>wV*J^@>si{M}LR!B5C^)(!|!@9UJ>oVTPd~y>| zsADn269Gi9JGeXUG}`v^_)rK;DIdQ%+0<;&KoEy*;Y_DX!YA5}JTNPkdA)^ZA2-jW zb`^6?+Zuq+9tE;EyHqgz7u7Kk&8_~CM-2Eyy6Smux9Ct?l}UHw=XUMC)+%kw=aLn- z-PrNcgi#%QLZ~m|f2|E@STJqj{~IDiVV`WZ!9?6#%rIR6Ko1h&0<&{-EUtq(3n0Di9b^Gjna=2{s21Se?T4zSnS1*qW`94qU~No&Yrn*=&*|9*O@1Kw!86U$#*byz8@|shtFK} zQ;6O%E0xF9fMnCnd1sh?rj))=5bYJUSW%)IoznD{#apk1o0i~)#WYmTPJ^iwMPF@m z72g8-RkDgWPb2(pWqIJM!9`BS;Faup9`sBGOuo-PvR=aDrahcK-KAie>XZ2&r}y!V zd52-s=qNRES{e7%b<467PMZN+iD1h~A@v3$`dCCd00z6G8ME(*YK|~kYC{4;h<2&N z$7UVwXylfbGAD)_*@_K>bAS;YYYCc3q%^S*flTHq3H@75g6)tFaYUgB?Lg}z%1gzm znfDFgPiPxL1i8wt<5ELs#}9GMgb^w|=GAUQO@Ev=ndLO4UfsmFcktlV6|!EBAZc?7 zJ`11JQWG>t$(#qdRUC2*mcN(BJw@?2Hw2umPJ*ZAr%$a!Q~0LnGZ^*)kzU{fFK}cL zkRLF?&VJXGTcP87zrW^Sa|m#7$gh^uToQjCf1~g6~UDRTRnn~0qHN)bQ%^B(iQ6Mt4)%?uftRzQn7qUR%0;2%PF zB;~0IU(>K~OmeiOwr+9m^$sFIdHtx7o1Ze+kcs{HBARK`XCqQ8$ihUnK3lWLqA2nP zgg-S)`2t*8+qT!|#(A{4dY&b3nBcBH;3-sg)30U6qxwUnbH~lQ$5)h z*p~?gmwzrnd#CMiyPgIKZJFSGHK-^JdK*oC=aqST)iZr`MYrUPfFUP8j1Q5gYN_MH zz%G-M75-htczfx-@<-z4RK{=U$Rwhf1{n_)3kd{5Xhv->(8?W!)P#2kG0W4j*_3K` zi&r$9UdnQuQDArIViB6#3%vP~4ZzkTY>72NE4+cpRI)tYe7U&%c;=v8<)z1l?(#M5N^VoRy8zO+9UER`2UXaR6gEKSag^RJZ41^F|dAJUqvf z-h>r17vdCD>GpgJgNqylEr~}gs?)^V)f}$XX`O1W0C2Dx-Bnt&*at*)93Mff)_*3L zclPf?9f$NkfCrNQb~n@BUD<9zIq#c7j9Q>;MHoVIc~eCUrk6;8kS=kg`3qfrCs*c= zGpW&{Jk2)?8vZ=bp!<^{5H-x@)jNvcB=603at0KawS9Y{IHJUl{hL`jV;RyA$+6Gr zW=PWqo3zmTE}A1cIyvY;eB5pye-PmO854-GPn1{!d5|v}1#~`D&0AvWbd`Ig#Bi5h zEVPkv&xhDdt{!XmXsoY=5v-&6lj020*pfwhmins`{M1TD*)POhO zYe2Nifaa>NkCkC^1%4uotaVeDnf~Zj34C53zYFK8D(=)%x4U zmKK(V_V|8BN{3=$-b1p4+cs)xH&$D&gL6ll@I#$~LX>BaqBm9v{~+_Q(|C>i8|lUg zF6{Z1$M@Z@;0Z}>?EPKGqzk^OeEGwO6AxrLU4qV4j=9^ID9iEfgT~5%!?=cM$h>TJ zyie(aAX?#yxk!a8<=r$+3ITCe@RhIr1p1HNM>tO}AXgL^&IZUM@R2#DyuTcpN#8a1_4oOlT<0GNzJ&K2i4+<9SJ%(p|N3_jAEq0B_&!& z;p1)J&++>Z&t;MZcGsSnM&>gQ22%%XSlu*dSPD=~J9EZUc4&5CEo0wq$+;H$E|H-6 zd**hh?YMQSI|?;C*-&^v9R_aHKST_?Q#!$L28tZsvT1q4ek$r`?d6i#{Hek_yOZ)B zqtrKAiW|y!qra(<(y;Y7`rA~UW8A&$-%dJyKz0?=4N=JkI27xo{=|J!@wj9r-u*Bk zeJ~;Yj-lcX;^uVS&y#^B2?uYA@NVH5%!%daY_2q8`;q^c{<*=vM9BaffE$;bT z1YB8ym~4C<^gzMLNN3(_5XfeukiYkh55;UEi__?WK-C_pr1=0 ztD<oFL_xQip#NxFtb6g}ba0c`r_t2Injs1+b@Jc=y-q z4qBtTmw$9<0(hhvVd%(;y_yd;_a=z^W4-lnu4#w8r%@1V?)L+IP5ee*Xs8^w!oW^Q zVO^sX!?JjCdIg_HRy*rrX^|QiVm$v4lQsw|B7dke?K}RbhsTa*h!k)PjuC~{;_8JhQ40vVA}TW4;3XBF^9W<=XhtD?V=i8{-mBO@d;F`OrLZ( zX1e6ZpNEUY++7@3pMS|KWhgGy%Vr-@AQ&^&$2MtKc98dl6zM6@ihrDAl=YL4OG>pS z%m}y8afE!|t0nyX?XzWrn*~M7@!qp;RIFxh`X8}kPpo*YZA<%ctn!68<_SlSWQj40 zVxXh_GO@_MEcgA_dn<}mAErmza(GpChi`V349*fC@F-*$J`ofnNvP4w;Ju66R3aOu zDPmyg;EQ5qq*)U>-!$Ht)ZncG623C1pL!sPfMF2ZL^DXk?Ec0nvTE0i!)ohq$?irx zClVv%dvK6mmeFXlmMw^#tV}5&_nEG*?rPeN^ z>HUm-f{6uDD7AP8z*e2Li~{B~j~Y`2tO-9om9|NLw?1wkv=HtiJjTl~6^u@GyYMd- z?wH=6Bug>D;&jgvfB$!XTh$BM34=NQ3gXwRPiwBDdIYD z5eW_=?XhyYr?W1AQW}gE$lSC9L(6PlThf!$#dZeoezdLZU`q@mM z(zB-YyoxyGwzen#YpY48oB679BJiQ=+`gG_y69&OQ#|y1ZXKkjeqquqWXBt$2-pm+ z9n!v2eU~$chY{V2DDs3Ch%^X~-kPfv{_zt^;K3?#Hcm9>9rTehC!1(P-^hKvQVRyv zIKcI|ELuwgy2um@I!n9$X$%G;hRCfzcyTKE?rQxVrOwQpQ*I~oFdY`tcU?Yindda= zNIFzV+FnC#BoZ3iyUBTYX~(=C-_F!k2GBflueTR*MN8fcW^*vQo294A{smYP`5aoa zaOt*<=D4Py6Cd~{ycAg}m$eq1(XvEi8a_yv&{#@??Xr?@d2I+cd53!G5G!$+hvJ=& zWZ)D&`Ft8Q7L$M{cx;4&^F=ZH-to}LhcHXt2w$Ds={c9fvs_LQ)9$Hdcp?~@-}uEI zyE(4(+f^9u6*O2cd*x#Oy1Q8TRa9=L_b6d9N3q0+JX7~BdO{?Q*pW5VW-V!^uE8r^ z+_Fl8`ewxTF%=+rn;2HPWwcv0RiY>Y)wnN~%C7&Yiv>y0p3<*!56>(lrqE@6+}(Vt zuv7_l4pSCRh1Qv2?=%Mt*L#<$=k$={cYmQRV1z=4Il(sr^(x|Hl;m;D4N!wc<#v0b zR|U~N!qoX5;oJ{)zL&zbsUAbPS?vZW&aK9n(}>@z2Z1JpAAiB_0#2z^0Q%x<*$Tya znEbJ$>lYt+;WC=;Y2D&kAA`3}@X``q2CUMU`cEU$$8#rEMim*!p)|HL7w==XbvFYR zg&z|}4$+lvLm=8acnKAv&BJhUS0zDKWKOrZyTq3H7ZDXmw+$!wZFlSO>|csj3RxB3 ze_5rylK+z(KEY&%T%z0_UJxBS4}g=MgL7wd4@l1dWa9)gaB8z&Fv;V%F^8|TLI%Fecs!n==Zi3)#m0_wTt#Y=hBTt{Vi{fMC zGKl>IVMW$t^9<<9-6avs7Pj?{GxPLdH3lT!vTE557wAdBngNCR%C}+ID6qHxX7}sY zA?4V?UyH6&4wV0P1Y{UJPggpIz`?#31w9lrRdejk1|%AkRRyg@%yQUn11_2xj{dHz z7M$t^8_$!!*Bt6(5&>OgDfZL0HJ>WhED7@DFWmHPAEyAJ>N_DH1mcsU1@SslYa2OhK0 z?p=>14sxAtn|AK^ULRJ8oGwIQTQ$$NLI&6CZXQ2^vxEqp);fLcaw-kl`F-*&88 z`tArm52ZDaUXxw{(>@m9w|CYm8PAi*iN@C}KgcN1@jnJ~qY(WH76bl(6BJOMx{f1R zXa>eIC=1K2Lc2Y=S;@dP2FH?-eNV?f_<-|6Yil>F|D2^!u%wSFH$YX5U;#?3%qIR_ zzKoE9=l(GVRgAxJqH4dpQVLfu2{%8lVp@x9Fh$o3?ti5+rJ4shwM1xW9pqa#j`Q*%J?dhRRs7EfIOSRh=FMQLq+1 zQC5NrodF@g%=@;ex9 z`}23gWYu4>LJZD2`I@GX&}Uem3bPc#o`aceg9hb^1vx1XgE6Bt){) zEa#~uI<+;o)$S75+k7TX4jsn0zmTl=c)5AO50DDU?umI(3&VB&m6T*NTV)>-9EO7Z zGM<9{c=h&D(UkhuvaUdfZCh1q8_+1-uI_M!!bsF&O z)^{wnYy?4O!a=lO21p`ZiifH<;}3t1!;0F{qAVc@y}u8SC?rFQy**u{qnQ<{58`~; zPRg&=s{fdYo4%7*;&Et1igRp7Lge1EUM2ZF7mT+hbyG|35nTAzUw?8Vn@LSv@UnC* ztv@HA2QL93C(18uLaVf7n>0UGn4@arCyEoLGdLBTa%;>x&~Gr?_@>S2=|PkVk}(i6 z;ZlNw#ZT4ayXNo#!v`1+%)|wrdb6h3 zQ(;b9b8p5k+ympY`%KzK)>!6pyTx{8qpe$pdP9BFQCbmG7aU}aEySvlyQZ#e=W*M% z_V)~Lp7nP^>spxtOqj5Po?I|D`ns}1&;^hK*mn>oGNf{kbf6?OA2+)#9C25qpI56T zRw<=^K5@#eS$UJ!gyCbGLt$#(hW}19bA@0_uH>0I<(CiCifV(HFCLLKErMzc$p#2k za9|apD64X6W9Xf1Zq0Y~};FO!j!r?|miW#;| z%CNba0(5J{liYJgbxG#)mYvG0)3ej(GwJacW-a_hngYk~m3z z1D0Lq`h?$bG{qOYwmcWji^_8!EIEPDqOCScySpxROqd)N2w57m>#UIm0`R$;vp1yl zHjBi8<(_5D3XQ`N{wvF5!;PE;TK>&x3>i~oFg9MnDcXyN@B#?FqSRaPg;gb>$~N0N zgOI?ij^g=jgfUEJxiO;eN4e$Ne!sI1Ept!4`D&@fZAUTo8Os;ejzxM~PO z5TT!QIH}JfF?M^$-}0(YVo#DrQunh=%{-U;@2{(2tnTyyGNuXHMV%ctDC{W@=Z&@p zM>9)U$nr5%3k?Vlzlfr0qW}05Bh*bI?sY|dKtU*Nc23dp+U?WR)2n<~Sg73p8sNTt zfLo0_t}Q0L@LE$Yh|wOsr_ko@0%^fDo%6?E3`>>}cuXJA=W%el&VB|9uU0x*#_B>k zmlD7@&A>VEx8_KkZ=cd8#F&by=k`N*;t7!B)_gr%>5-Oj((`M`0a!tQy#fvl&NFwN4-MxA>_K~aaI~rmq->@PP-wZ_twk()nYuu)5=UGZPMM(wyr zL#p6kfBGuF+_qx{bTul2!KbX0fTaV}0M1P^7CPj-7yiumb})Y-RYDnBuTYi*w|Ly5 zn3A-9``!8$u2@!);*wHn?wb&01R}Fs`7e+h2508<7O^@sCugL2A!2sq@jNyzbGPul zBx~xJWHH^RPcVO)>BCGS{cetxFknIXiHufdh*|e+YTfUg*P_-*Z9K)yEBqorq+FUU zD_|`OK}Z2s=QPOT)imeDfnE_Iaj||;bZDdm{ zyLjZdE*NUPTgHC55&=S|Hs0QbyyW^sBtN@pSL_WWMfFXR^Q;wzk`-XLjk$6>T1zI> zWUZ`*qpIYd1}k9#u#gt>%WZX(_0T=*yy9gp*&;q=-zUcfH%@CD8I>}L{f z-lB4Uav-uR+OklaKb(kdGLacaOZU$}(L`B(nPN{Z(g@<768Pof#E3YdF=&t1p6OVM zIKD-nw@K~Si2oz%tfJy-fMq?n6WoFX7~ElS4L-m?aEIUy!Gjar-8I48T|;mW?hxGF z{my^SS?fIU0xz(K-CbSvRga)x*r9U9lJ6=RhI}d}XV%R{OK({4*JTXHvmSLMsU$)1 zEXHt4u-EN3RE!M92_#%*yJiVs}y5otiwvu8a!;cX|2F#k%$flCa-oVM2A|> z$`4d$&(3v+S)`()s~0pT=g{}aZ3`Kk^bs;Y8tDJJP2%i_YzdVxZ>YDJfj{9my^FsLV$p|&z=uw9V0c>n zEcu@B{647P>6D~@ce4*(buUAM8`yKaPZ;j3hJ4u6p*`Vt;L2U#I6i)yxD-Iwv2$u+ zauhM&=9et;;64}bP5!Lq6T9kY_U_2=PCpc01 zK>nvSeOw}q4GoFB>2oaZ!Yu?t$)rc5Bc5*x3aTe4QOsd z?O)IRf4Ookf!S_{KM~Zv_HY?7&M_u)@RYw3bNVOIH&q!~JyrwBkdAL@uv|+&vHo;p zkOIIe03N8a!^A#W0&09j$)(L!V`DEe~CUCj_S;uKkbc07teU# z3Z?_u%p*0`i$A6Q{&z3M6)))Y^_IOJ#7&nTo1pC_v`lAp+m=GYS@AQp~GRY`oMr6F;L*ttLF$+Pzy!&UY3 z-}=tvFx7{&mIWo&?!&*`OBdt9CW4~GD9JKfm8cpVYmlKAGCt2?EjiM=tHfp zS{y$)^LO*h=msacRU&^XG2)=lSa$;NJI^UJgOeGiIwNXgD1^=%!$OzHsyctoZ+*Af z;i%Bwd>pEq6dpODo{wO55=A8&r1 zu;V4oEH_%42$G5m2BqwnmE++jDkGqLGE|ys$b(E1wE1bs#DqeqClJf@IA{}|@%J6F z2`AkOe}vAOPG+>K_oNL{cbv|-+UG9vl`*+(GMz0~6zKekai7No(#|t*v zqM?_~u=RacYjgvKlCMbyXO-<&>ZQ$_hqm+*t3g7@q#;6o&Yg@K7C7NcP4BZ5+h%1b zc?X0OeU}3d3e&G{%=k!bm9;z~mp$#FK@SZdR>$6-U+p9VovG}0B4*0|C>h!4t*>a~ zV?*DuIG-kQ5%<3GafWQCN$_zpX`t&I@eoK5AQG! zo03aT8kfLAdos(5!$S`Ya=Mnl#T8X3kRW#^CA;Q zj{4nEdJu#xL?6S6N6_kshPlajgFb(~Wn(j=Q-(*JoQh zZ~e7Ame!`YZ+~8LXl8i2RlSsnmP`>4QZ;^_OrpPq{~A_h0|Uw`JGGs-I<5}PdClTt z8gE|vXH$M?T?eEp7L7`I*N=<^qw6W({llkOTEF4^VfS=c0k_Vl4U<>2{8z!LHQUs! zwB*TY7fBLEK^61o0Sa7~Xt;7;98>wcZ>7VjMV4P9Dch8?vqZY_=tZ?A5DQNY0??fU zl6Tg7CIyHeofSsucsW72qAccFO+D7xpEQ~lYR6GR5QUU86CjC2Pj7}wu_{A(%k=_A z_XkWM(@Ri-+{cZBz4Uto24ocI3b;oL#%l~sjj+IupP5)@!aAZT-W9+puR7ur?V>Un zpp>|Ce=-y%2#`jA%8hvxGb(<+DQ%=CLX-Aqp^2~KDk7eF^vMwamSePX}QEP zBjOa7b-kPzPA2GPO+o_3+4FUlAT$SN5OCS3Y;Yan6||TiLJXH_*=kvrHp(X#-q+0k z)=KAotn$<^)(}!63WB=S9LZus4ov52l`_{@^{?V(dzU^v_ZF&q*qsW#3_@*cBw^6l zhLb3pLpc>5RcB&R6tfdkP{R^Y^w?38eU9iRV<`gzwE8%!w+x)V?ZY_TQSjH6)=H@T z@66R|S&UWn%jM`5*{g@5d?IjIF2s>E#E2+C7HY?aF#erNfFJNG!cJGfA%ip~PJoGw zSJQSy%l*>9A!^4jhkRU_G~EPIZPlFc^46W*S}Ghb7vY!4oQM(T%L7Ngd|&#VysH9v z`b&7b-Is6f?XDQJ^M{67T=fV*^6)$m9GX25pH*gYQ*dvaz&OYfQ^uKjOxWsh`jV~I5G};=Rp;8(AAd_o5t)4AfpfXV}&3^|m zbnKH!@ZZ|Cv*GCa5dD(wGL!Pt^|9T8fnkGA-M=@!4I09+mZN0^`$!q3!N>!s@Q9YY z<>+z#FF(dZpvK^zNDZU{4C!hRoI5`(Q*r6&&eq<;fgf*sKQ*LqEF$FAeYd1SO3(z> zc8_`P7JPkKU30j;*VPX*(Uvw6*_fY1B=>Ug7~|OqRA6XIE5xHBL2>ZQ;gSioD0i7= zWxz5#D#EXwT=RNcMs}7|@nKO}P{)}Bu->A6&de9lThI%_SFac-K1`P+r^xc`dHY)+ z%o9}i1TA5aG+>`Uba{ign9@fiy_&KZqrENF)}6r~AG}%^))^aJU$@30C#Wb#iqY{S z*(1gD^~rF;GQgyuNF{w@y#b(jM=AvaYK&l@FCT-wk#fy--@KLaIkpvDp~Z8+nU5?m zR%N7K;azn9IxG2%#@yX^PU~@VVbSc=ulJ7j(7;7tn2JX7pub+cnijXgF4J{}mJMlt zij;bS6WFM?A8pM2EK(VaLVR>2D+~%XmF4_^#^bfpJ{@*dknTKy*-Ddb!;1P|$2F1A$Lz@K#sLJ?BDLL@>QM?Y4g7KP?fTqiB^Kx`%RPO-#G4n>WkKE-jBXk!L6S<4hvM*jKW}p(chpg#TkdBU zOm}$``*~NBrf0b}{rZWD?5|#LR9ukMB4XpW_eUMf0jM9d^LL)PPe`NhU+P7Zz-1#R z!)5!Ga7uy6mi*c^CW`Mv_8;CmFH=_T2mM}2z>-RCUvEs|>@eqleeMxT{yqb~W^Z1N zwj|+SO{dddT%O}5D?Ti0pt!lWzS=q^(*9tpI-S3U*Ymv|`*+!{s>G9IkQH7+a{b>7 z-3;w9YOWh0eD@w0s4%N@Gt2Y>gNRzEMZhMSNHQu ze7dz!TX-PfhfYVY4>?7?P4}0-@{+7om$=EisJ@L*B4Hn6?v+F;xfLk?^h9_puY9_c zI`ow9-L|>*V}UbO#R{%Oy?VH^WJDxI(N_3&AiQw*&A_2)gZNSBbYs!vyvaS0V`o2A zHA1Rc8xi{Ztl2M>dJtZU*aJo*AM2RRNUo8ep02BtkBPrNyqdnVv@)I-WW)8Bv-2Np73?pFQ0=r+m0M zAJt$GT#!oH2P%V{0I*$f2r)Uiy%yNY=>6;sj7*_a1I}&wEDcoHg)9YlC0I&zeu%f{ zhV}QI6Xq{l?Orc7Xo+lcDI0V?r+CIm3&Ht`y+wokLz+VE&2?xG@zU@(gg>6jBR@0u zeEYd~7cncP{R+>IQi|$Wu76}U!yCyH!!tMz-U21+NxkpR0(3&`)HU5a?erBt@uzGc&CL^;!asbpUoWK<4rgh5*iW<>sV77Up8)3M(5kw^SjV; z3;!`|z+x79i|I!Hpq`2dw^mbb>SGv5`F=b%B&)5arnJxyHxK(*h;PrQ!`ro3zOt^Q z*aKD7zHb+Rmk%m^@g(HZXESor+sIsZXf6M|#JyFJ2=0+b`~1U$7AqR#BM7XHT1z$E zC>)X7q~-cDMO@tzHE`fpF8Dd5<4Iv(c-I-CMRMQM z*VHT$`O0dgkobXwR9;4oeAJ4@4W_Q5n+?wUvXCj&*%v}oDSZZlI4vpnTFvTZ#0T{I zeIim*?ij(_CG}8J4^3)FvD~B%9~~F%oDht)xO9+R*)^QHRdbO|;NY6dm&TBeE`tSW zQURva>VLnM>c~qn4$rD~EniqlDgN3lkhLs`_}i?O;KG_Nz+$CyO?-9Qf98S23@-Z= zOQjAxdyK8Kl#v9d*TL)(yL>7on6obxDxC zOHHp#vRk_a6mH=)b8UVkc$3hT;8{3TxR6tHh2yph%$5&H=E$zcUy3bxu+v8X$)Mmt z67{w-S?7o>hZU_SKNO3eyG=9VZA;|8i}Ig|I&jUM5JvCZS_&`+nq}oQ+1ghZz;co# zli+*{{Os>|Mw`qL_6G?td7peYC1m_|Hx-v0enQMr8^of_pzP#!m&^Hna@t_TWvV+T=v@yhP*~=Xt$C2!oh38H^gxBHrOi~z~ zGUd^-`;>d-6ioHGuT+T$t941IG##i&qBEd=+lh`FQl0RpkW}^2%{)$(Lf5MiyUCGi zgxNcOZ^W3W{Gs^s%QXS~@yox8)`HJzVWXWFp6Y+zO|S=lwn94}Ae&<$rr#pX=kO(i z{Za92%kuM|0Z0n+fRP3uPIu~UpqsSXFsl4N3^Q&>-3+qpO(BWGVS_xEB+qye*nIlV zGQ*1zUo+#q#|RFjiv3Y3iR_{?C0br(8cGk#U>zSfHyK;@(twG;if>tG=Q2YQAp=y$uIYP zCM55zuEVwK^VY_{?=>~+l?&xR+4;%0cHT_aw^nKSms(ACe}mHdJL-|s@bNQ_6RVv# zR7`L03w}U(8;rGPMcvK@O&Vw_GA#et$3q$VpQ7VVbU)7cBfD9R@lnS= zLDrpiZuPkG{W9k8&1|HZ*{0wGlJo`2MUN9k(TYZr@~Coj``O4Gd~6MDiw#^q%CmQs zDHnzd$|?+ES}^|<^X4MsAYI39fhT7yB=x@lOTbiv%CKSZvqKPbOyt3IU+|xo-kX$^ zR(&ikYfUdUIBuC@DbA5F&CSvnakt%9{o>Tr0Nm1BxLcel~flv>2g?&ECtsQMZauwwnVYdyKQ6q9iO z%ggVl3i$0sw!fD~R7A*n@B2@5ZoAcHYE1q~nEy?GwEUkiA^x8YW3b#&dU1`3mX4N& z4+Ns6VPoStq6acSQI{NotX!Z2S|B?YJ3S2pEjJ$rlzK@+%g({WL`TO3qJ#bjEeFT; z5|EaLnx2!LwTtmK27VU+=UqAh#Q#PBhheMKYY4P0rN>FGPaJ&UW~&yvN&g^~T(dzm zL6^G;4e~A(9y$VrKPGkwICm_m=QnFEyiHjqc6W+&*%~+rkmZMdcbu@Yl}V%vpbVci z7ja;O4C{#VVRO?RlTzB5XreU!DA|>~jsv2wdyh8n^Wf3wrO}V7i67vNY1ef)Jyws) zgH!9ZM%*43YNO_{%Or*$uD0uV>to$$R6H+t^+by@Z&{?I)n(gl9q-VuRFYX1UB8ny zth56dq@B?L+p^9XBJQI1h?B)eTg&DzhMS9Ev@ud?o=02Tv37V?7vTi(GHPInN zmb5c7-lK#EP=5ZRXcZvleD?5!9khEraU+B=8 zn0u2)w?Y6ZeGe)GQ!TQJY4{|;J#F!QRGPziDbFq;<^6Vi+HALtvGqz62n+Qyir)l@ zuMTc2n*vfmA3X-1lyLbPIXa}x6Um;?E)j?gVFRJ{AhH+S2#gzB1>$kxuCM$Pj2?`X zuGuq$ucVSGT*4|O$!UCW&^3FZvB0*@t%gvb;SYiP%ks2Xjc6hN8+CH;@af0+yux92 zbctz$^c7nkJIMs?gzGr-TY^C7P2Q1oQYCWOPITaJ;Hzxg+`W{oLHiQ(rU)4iZN^@( zl^*fa;QOk}O7UWw(rDXm>TNW1t|R&jgWy?cX!6 z-d=VG@6|++i1AO`dLM--sHaHDw$?H*1BHtyyyL?zxfdaLeW$DX+39pZl5+G}V`pkw3)zQti%LrE%8KYGl2fMh)p z=%eUKLb{k zLrh4f^K^_+Lxl2mzghmAePWY(o=Tq3yPx2s;QKHmofot9O1MR3e+8{i#_a4=O?uH> zhZ|v{bIO_4(%Rbe<47sey|&@qz~=X}wbO6&vgW^NuJ9W*UsVw{2@R=dQ3%TWKZKSu zD*f?j9~mEZD2<=3xFo<$ac8QmG&SE-_LCKw-NJh5ho`qP~U zpJ_n{Oznyn&8xV)NQhl&h5>ocPf-{~KDlVcTxXSYW>@kTyUiyc@Ti z^;#9Y-r{?50?E~U@B1h-QN#p-xX{Qau7^PcbutP*Mj?erg~LSm1*|j$T<@|a8ERKi zt-QBeuw#IfT>kB&;J(0sG&EsMeO(K*g5c{_{H^WmBiEwMxIoR85Qg;!#YGsPyuw94 zj_RY}Trz#Yk6D(pXR#yJ$=#OIAYF>>de8PXKaFl}WoR4(0=R-s9~*bNW1t2-g#^^n zt#a^bc@#(Dxp9la!2&lM^rJLpdFU}Wob zE_`iTO}-I9sov_-cNIElkXG;RIvG9kIDb{RZN-D~w9+#7P$XS5MKo`I(j_*^f80N6 zqfrMA5*`yZPtsy&L(D^5Fb|K$7BPn%u*;dbn4wuhycRQ*#48vz_*%Ar-@3#DNoc$X zFLu|Zd2N}dUHb}03q_(1@0y)JyTR|t20qN!)_^*G8X`n%Bo(ChokTdS5`-l3oLtSE z*pOPPSnJ)!D|V6jE()7eVs#s|8vG>j!k7B(RQ}@_hr+3XohavdH^X)%c|+0=bR|JA zi>r}--fPksv}!WQ^!DFg$NKb6CNMS0<*vx|oyMA@`Gc$u&H}0Uc0BYC|Z2Cv|CG zL?o7nRWNnqE8Hanf|(bgp21_)mBu_Pr9zmP#1*%^UQd$5P=-0`c4<*MNAqzFYkJ5J zTD)jHI%!$q^DzC1>mx(V34z6+N~vh?z$pvaEyI3Flw4r)wRSH>=&$MzvXlU1B8b0| z81xC7hPpznNbg6LF!I+6%ktCT?M}^s4C?~|DkQsQVOrEu2mXj^5I6rat2KYZMh;IU zb-f0+{a>qS91r$j*7?*W3d?x?=>%8>`KED;($LG8*i^H+kB$%3lAQ-YXOqdZ&o(!H zhADeJ!Ul$+x5C#7yb^xz@B45-h#8iA9a4Yix)6m%Uk-lx2-J8-;$&@JkKS7E!nCZx z%*!QzbmOY|S~fnWvG1oD3ytMk7Fz$&$UGZX0E?pF9tRgZ7GYIS?{-vS&`9Vq<2}*dVUWOi^hK0QNr|Nd?A{9|tlRKW|$rL})W8{0ss5cP5 zCDaWMtE3wD&(~KCGeE5o!!CwNQzQ#i>k^Q~QNGoXBO3gdhZHEEBtDLVxC=)w*@pTr zvurGeLth{9h#726ZkI*Q!aAl|HUCFQ1P=$KBm}3VI@9O%RHsQzpshZCt$e(K7fbfi zld^<;?WCH__E^6yOIH5tl2wDcQ)<@fP61_hn3o0|~+&g9VsERzyWFhM}m!H~*$2BZKL_Jn68_+y2sr)>D2;|k{n!J$o=CkASN8i_mo zV#k}TihB7%-Q_`|pK+PxImI$*a;AKCDOco_)w~CtMv>Q*RR#li0vsOanm$s9n)UNQ zIX5^cIW(+?!d?mEu;5b~D`HHu^2m8c_lb&pH`yyl7{AFEXyROZu`oPu4{oSW0Q~8N z)-7O}k)Z&EMMZTsOHt8<>%+TGH*(rH=n+aTmImVKa3ZQ8CmEnFQ$c0k!-Qw7lP=f< zEVI8c!XV!x6L}Eh%$O%$L)(x+;>_(lTG){iv^UQ0Y-YGMP^- zU{9U%m1WtHG+=v!lCXlE$#|(EV$9xHtxtTSZN+-?MsY{g*nd5#-(iGgSjbcIv6kMJ zx1FV!oQpmy$QiCbw6+zI^Ob34!SHRl428WW`2CDHBTy4oDg2M@r%6I8iZL zSB!5VR7fGnhPc%Rh0`sSTh4dJw#U&!=an?K!?3gfA!QQkl)`b3)%OWD&cveS15fp{ zDY={zp5(P|+le|0?I(#rIZ{Msr6lf2T-aJqH~FvTor0?`!rLH+OdD&+9P3664xz?&!8?j;9 zd7jFQ31u{mS)jnx96DGR%x5Nq_Hz|YC{qa7UK+j47uww4M+_3b_F(;&#%7NoKNf0^cS`D$V3Op;RHaa)h_ya97PdJxuG?@ganP`8x*-UCD31r!rVG1f%k)f z)XOb9kzB39A@OC=C9!?x&eT%yqT+h7dO3^?!x7%3x7Ht^Hi?zVbi`J-q(wvTUGYJw z=tFztTav=POWE0+x1#eGhj|@AzlMr@hUfd}uu8{F#5RUt*lA`oLWGx0r7-}Fk5M7A z|Nj1AKjFQMSqcSN%r3r>E&1LxX9$(VgdHWmnq2(zyUK=?!-wOAB=PDraj-$1-0AQn z>1nF@paS2x=W})pscUiQ5tj2mCWeS=WZ!q6hprY!2YJ0kq%%)NU2 zeQkLvcx}bLI?kyfX(z@2N#%l+T>AIAleoVp*Vb4`Mha%LZ|P!1RqWCit+0nvvUZmZ zFF2XKu0NB|wq2~0*I5fMoYUBM@J9PsPKE|jn|%;$U=*-2o%$DsELiq_Go-<#{s4YM zohJ^)fz5+Mc}e^N`_&&4(Cu*6toebps2I~EG+X;-T2gdyUYt|yp0y!9blD)mRjFFV-613JM91mxWqGHNay0{< z2+$h$5tt?UTq@3Y^8J&RtMH0^6Llv55(v!sb0NJfUa!i;U}Nm0^jV)rDEYCxGa>DE zgYLKnj_FAo!y$R>%!xn9-YL1vdu5YAb*bidukqA_^ab7+DXho(=s%~1bQ@9a_(LCo z>r}GZC1RE^+vbNejdD`ovyofKWZ(F)yBoA;C@6~v^{37@z~i0e5~yEerQ^Rh+?V8c z`O^PPo+A>>Rk2U{$e;#~Ckesqfqs~7JaZRez!;i!!as{k%teW%`#Hzh&q$<<1_xf0=oY_D9k3r#o#0W9K2dD(`KPUG|RDv6<0*AQ-=f^3ZZAd+}PLJyZ&o!ARRTA8Vh{nkRVf zw}4sf8W~M|OkILoO!oT~*LByE=zk@GQF|zjE!BQ%rpO75yrTz~j+b{81tVUO1Z@j} z0cY7jbm$0#F}@3?9})#HbKgxY{kB;P+M5!nx{KEdX~L0V8k@a+ndc)~HfmTnBh+EV zxPeNXJblFnsXItS3B$gexD6ZZtYheChaT5LRs7?w32vZLslB^C<00D+MH7vExxKNA z`S}-xfdJ_LVKJlYAb=kLj^^Za=^uvAI`8?MP3T*Z)&YU@glA`r+M2*d`Eo=~cPVdr zsgV`aj90@gQ75r&%1mM@a7bZw}rt+|`* z3!lIUpzOlHzaWw@ifIy8-|TXgKTP}Md8klb0OHXN!Q^8B)chXkFJ zyj3*y4Hz)z39kT*`Wvhci|m?f!?D#GuNfP##kQ{F6=QHOHzE^nss{-vXS2|NC4YJ% zm6sR>RnH61DC&;Wve=3f!sK}*M_Wkj%ZkP(m@rQ2NY3;%%;?gh>$!;IpI-mzM(S^> zXZxTVMO6)NWF;%*;et7sOz_Z4Zt0;&#?J1BxGk9oY&`GUVGR_ielZ zBX(k~buPmqA%HIRH^-L@H`>-&i~^loG7N*K0`$PJ{sM#xm0X>#VQIE6wsu2~HfO7+DpHz9q8Yi0m?;m2Rr354bK*S47wjz=f*-F;MJpyqI-Wvoh9K ze>BGPLcke=D_V2uC<{~4TL)XE@0YOFIK-Izae_dF_qo`{28U`bcMFeyn=vUf2 zc$DUzV(gc=S%gEvS7I%S%VZnGNPZ+n>)tOK*cX)IER{qnB%Ls8De^LTdOU*QNp!!n z9AzbrpV;I}n;MmVt2Q`&=G~n0?0kQ{nx@;RquPKqUD^&C=YZ#&cWcbQ0^7&qadcf6 zLXiLBPDDQTbZU}hYRqK16UdNq=#HTlt zMPiA&^V5Dlq9#B6DCDgCrv4!*ADmc>#@>%wJgGIsnWrW zcH3X%bBk?9zUkQD@^j62ptNiT#4k@iOz-B2@FOs$@Tjk3{G1=1HfDqt{=F!sQp=bq zATa?FQD;NULkq;=57Q7wcXgF1cn^(vj;k&pESY)Ic@qV45pmZi={+%I`m2lv8Qs~G zZs|R8xjO2|U1D)2cJgrKaZQ0{hCC%;&r9j7AOJ%09zcVb<`a;|(;r}9icg73%?1#9 z2LR?=)5k+Ss5rT7OMkkQ;3aZDcDpkyI!#e8*r?|orwSQoGS3i1d3mqD;Ofuh9DaA- zZYEz$5fsTD(p4LFvA@pHa6h&!h%TaI$cv|u=Sqm9`-YD~uqNHtR>xo)oK1t>zqM-<}FvPM{oA9r1QMiRcvLT2WV~^BHCy=hBX_$F2T=K-QrCD50i_zf+eWYcO`rDt- z)?lYTefIg}4|dx{=8RUZ^&+pZu(L+Q4yJreZZUcrlXLTWchQ)&MU zCe2pvZ4uf@Azw|(%gghe#ZplEZ9NCyWb1hvx9k!a8no{)f}zq8-mvSbHrJ5Rys)$| zy!bh)dPVY-;EIrd0HBj$CY~Qgkrr@ar~~s0`vNxT-{YgBM$<|@OQwv(O(y26=SiIm z6><)l7^9p(IPIjFXmWCh#JI%D!U@QuXng_(-$YzuNjU6F?7aXsw~F*&euy*1b=c!n zLgt5Pn(?DuF&yxn%#o7%T${Wxx$8$BZXxxKg-spXlc3L=x5slAM-{0pt7%^E?-=1z z%cmPu!*Sr?jx)@ErU)Tr9xBi*PLcHw;Mlp6q)q;jg`qam0AbG5;6y8R-Bae4bG+JQ zM?8GPTB`n4ZIrB=rM;cxPUeNPSmj~yxDAyU?SOLsO?+6L7O({1xuBb zSVoGuan)xjQ>>gxs;rFUJ{8AI#j5u=C_Epa9f0-~J+3Z5>k$5j0gM4EejHqE<`3An z>0%>NEF?fq@z;1e-M?Uo5$(J89+|I2&Qqq-JBNoM*0yHmMqASZ=DK}8`JXvAbAZly zgCX^*3x{OjgWB)%Q5Y zPyE~oV|1Lk-t`ybvL}<;5AtuFwws)VWQ|5-JP18^jKLTCd2-%_Z5l7;wm@o%<2l(Y zMu(b05yEf`H+=b@d9UFtgx*?1_I2Tnl#Ula;May>(`3aI0O$h`p=1*KB z`_FqZ{SOr;n2q}OxWZ%O2mWX_wYTYS@#bI7#VI`=cu*A*R%q_PxjvSe|xG5RI=5!GMZsZ&ntH!8u;#==Uynms(1it$nA z#9DQGh(Tp?vp?~q-|M{vFqk_|WUJYHiguRQsgTq#zrA%y4x`24;6`L573E~N4Z?Qm za1(vLgu(SLRt==Yqrj2fYkdOf%1I&LO!{Ww?>S-1)&odE$Hx;x$FX$!=jDe;KNpjo1Mxt7o6b#guNNhR zKY9RqYb|p&oAZx9k6wh^ODoSAlW!HEi~}Pgt(m060RjUMNsTeTVv%$m-2?zkVGuf| zi!I=hXZ&GA1_^{BBzI2|yE)_c*v<|$^?bT4s4T43uN6KPTurVX6-}9f3|FV%^Ifb2 z)?0`nZrre=@8s9{rY$^7%$Nz(* zZCc6ivv34-qHWMPy!~3Q-|fUv3|#p?=x1D^uEKmxr$U>QGlP%_LWc} zi)>#(dc3q_Dr)&i&wiT+8w3S*AnQs0%E75q4iox%%8ZgI#f}bVAcyY{BlH{o-BJw} z`2oY&By2L#cAD2CEg;Y3MCq+@p;4NKbuh$>yH3&OihcB(z?>~@bjQoo$lLSMDOzR& zVetuRDY_NOuQ(nZq!95S8O=K$M#j%%$noN`dGpFRyxG1Aq^QHwSjfABkT8FutiD|8 z>=K-<%pWj5#`v7->K&aoVZ=?W%dI~|C+3xvaFPQ!Y@$Y_9xmOi{PEvYo`pe4Mib7~ z%)7sh_b_?j*fvI3E7@peZT+jqx1D(eKe+wCZtI}suATP>!h=$jHL> zpMLB^tJLTj`-hkOp6EDiDH`mA_4X^iS_G!YTxKgN(v9jy$Lz#DAAA!aOTBh<&6i(K zfRrzAAYo5FOPepaVo~zXwOnyXrRdKvm{J!6Fr!qiO2#p3+mB1VaE~Vpm6w&s*0c?F z#|@Z18Yi|9MH=a#*A}VmWZAHdDLTj*8lNSi)YXQK03{B_z9H7NBfp41Iz-`J7|ION|Um`Z<(;UB@*}{Nfi}V~2X_ zAYKv@O41|g$HGLpw)aam^zE{P&L7QI^{H)th-!RfWb`|dfsxd>Ot_={SG{3{kuwKr z`Ab=20_$5X!~7ApYQ3^Xp}#|XxWsWR=Ds8{)7hg>rzOcnXSB#-d#>6mVhNL?*Y#ANsmzu!h}HBd6Mvd}~In{urlz5m)kF?C6`} z6YrL_&5sF=l$1=@dRBDiLaW}4EeBxqpWkCMtWh`(?4$HuHE;Q|5hm<`MumUvk#b$( z+K^d*asSK7^cVj>aY7O*PBc>nVuEPtY3PAGAhxYVX!`~&Ee$sd2Mr@VEs&Foot6W% zKfV5+CxUZnd~R~;n2r(p%{1IxK=~l%JQ~2!#V)0@&ZI4U;`OhM)1`4WfBCz_t(L17<6v1MlbDg73`)c%>C?mdCqn4`Ybx31i*uctC?LF zaNKlVN{RZHb%_V4N8rckT{Q)`+G&R^zr7Y`Nxzd_ zY9VntU4zD%`tN5uc8^uH#?a`1oG}D1e9_wU(_D9MYH>ZyCqM75j~ffZ!7aOat7)-! zCU}y{!b7wufEGWi4-1*{=G;qW0>2=jX|t)U)W{{i!UPQsy@C*$;TrVln2;s@9Uh(w z3#BU<(6|QuCk*&WTpl8-L=Yz}`atxx?$o zSamrx&<@43qG;O3oO2Z@tmB_xSQCoJaV2DlPOA0Y?U5_gJvCD)e;Kh4;w zEjleFfKrq~kG}hr8G_Jf>Wf!=PO)VAY>m3Qo8a!2Outoh08c6XL$Pd1g82|4rLx6= zl-&c!Mhxr!#%w1C#F(h#b@%UlDXj8PhC?;NykktNhNAX-3Ie?Q9G5p#w)!=)Edg8O zAIlLb_x0_cW!Tfg-f+H!{qj>d!2A0W{k2weA183G!5kN$Qf(VhYo+Ay^Hz@Ri<&I$ z=9&`Km6o@JbSXUiJ{1m}o3=U(!VwJO13|ua&gZd@@t@Q81>HF84z5G*=7?;_cavD+ z|JlPZ6#kf|S$(IwyvthS)<1m-E$u>v()F>(=CK-ZaY*tMj|+BW@so}rv6J_pUr2)> zU>SWvRE=b9viO^9J6=bhOzTiqZgyhT}#z804i!Hm|~XUHD(LwWia2w+MWS z|E|P`cyn1p$K_p?q-_!tn_?Gn)()|+pPR>M_mu{MxDZ8s>Hik)kY!FTdGp42B1ZB# zt&Y_EAx&1p#E_*&<`W5k&5O7eBuU4CYH}HWEl_|RrwD;Z1uss$D(d#hVc)Eo9NS^e z^`}K!wKaR_)s#Nl&ju}$V&eA44V5jqG)Gss)XGY2<>n_**u1ClOQD)<^seYGj^?q@!ef6sdKF9|;I*(Hkmr zY(|sHW_()iZrz7P1HAM*iYPd!fx@}2~fK+tG;9`<9e+Ig#v{1@iypmqqigl zjJH+efr&AKX@%ouK<8&Q20fL*jnbe!1&kq8qGq&)Ha|MRp==c;kPnjI>r$yb-%97$}mMcjFX-)`ln_8QE; zB%{N?2`MH0+Y5)if+=|-_}$Ft&{$<>%o^PG_A+i!RI#)a+v(zEC)AnX4z(p5?15n~ zefF#fJVy#9z`5Sz_Ha;lR!)DMb~f>|C95Qp9u%(t*t~%!>UM9uldiG$wmPJoC6o%- zn7eq0h}_;k|MO`5^^1c1D@9T9R48QWs*G={AP;5x4|z3MeZL!GIB5JGrR~+nZD&l) zRok3PXSTZGnVbPePkF*|3GeM#Sb?QaY;!oIz^rZcK4dIYV_6B9kePS5ym9Glxm>%) zzTYBw-~6HR<%mcK;xkl&qP4MZ%>iBXC7_o-bWg7+@(k0J^#Z3M#Zf8OD9FY!V>1)m zd3{y4HmZUWGJ_{9&iQ7GFcnB5&TJ&N7e}Hu>qC6QM)~7OY`61Fd`3&f9jzIrvMR`s>}$gYO(Xv zqse|s+_9CPGym+SkZ4Y)DJv~OU7WVn*yx<5U1@}Vc(S7TYN;&Al!1ca50@qeXSjze zffG!7o2vxqa1r z^Q*c7==hQoLYu8~_J9@N?$h#3fVpljD=O@RZzRCXD?HzfZ%96o}WRGIj46}yyN%&)qX1~ zv);?lHZ?M*2{E^`D=dMpTw%)IlhNvpZMQiYY1m5{cVwuuC<8qunH zQo4jT3t| zq{Bw|&=oD7nPg&SxZVtLM@lE1w6zjU7OisW%Gj?d#S;FRM2GMJH_@_N&iiwObsisO z6e~<{gzH($@KalBsrWMSxVm)7Z~4Csjx0gU{L33guf(=)8LK1l-*#ISXPW)`IJK5C zxp|7MmU^+Yd${Xkpt!cuG}j_kh5kSV;Cc5W#hRf|=B&p3u->$$nS)f)sSYZ_#OK3* z0BV>6WIT!iAt%3ZS%4cup}&~kB6v;3D6N}gq?AaS1XJwTqMF6omy=D$=A?wcQ7^Mz zS4R?27nMPo|M{J#TQM=0t25P5R4KE~Tg}hI4Kh7#7Msc((Z7v0%sKqP7fPBcISN@J zZE7(60EOuBTMw=e?y*es4~Bi*hgT< zXJJ?iNS({FT6C0UaZabto`4?y8hP8rykCR#Z#MM28xe{v7rJllsDzv4&sbEJ{!mSn zq2}=l6Ukc>{`rjf1MZ-PXUI4(hX%4nDU=Ea?I;+^qrvlV{;6A8;+x>`c)m1isVzmS zZeq>9HgCbSvl z3Are6qd4m)IY|zolwY-vwFfN=os4T|&Xn|mEuZ+~eJG0xL*SsW;eW*pIIaAPO2Gk@ z4h~0bzM7>6nwF>#)b1uN!cdwrL)}NRRQ~j5^7D%!JX|EGPmaHcmUY0UDj8fBmTv83 zk}tF1wo*93e>>h-yym%0uI*i=%l+)RGE%A8?K_=?NrIvd2#VJFipThp`~_BJ@mri& z@cuqKsTzK<$lM2sDY}s7e2+9XY+`MouAG|YC!=@2q6W9uy7P=#o+;w;(c#rBTNKsf zXIf156_Rg9$-xT!^h?psoq`}RYOwRrMCraw*j_MMurcdwPB~3tTHmxwMqBo)Y#3|! zH-#nH(7jE9d}=!`obDZk{Gh--ckmIf5mB7)lY*u|AvzC3OVz5m`bGCT6UOg#>DSy< z@(FJ}uLCaa!i!Qg@y*Mno(%&mW@{cL`j8C&O9>uxfF3O{9zL%M7Y3^Aq6b8h5&er6 zN5}{80)z&Wgi3yl)V~}0?CWO-I;>*Ei_BJVnzpi~uHz1NIUdGQdDP+A}crVBJ@4S0JrCGwApge5*J$?x@qa#hEJzmr?#z9v8>K1TTshy zIcbeUd(Pe0;Id8%^>p`rv%aymqS9U;i`%lUJYwITMU&G4_i&FB_xvX_x~g6tb*d|q9u$40>Ry#!F_NG z1RI9IU4y$@@FZApcXxO9B)GdkDpTcC;E8MH3>Wv zl}!BoXnYjNv^rgE4)c}sQ^}rZilh#ja-NE*OX}M*P}|M83b=e0-5`3hQ;30zq?iUs zBbGWV?AQ~{39zU8)Ke6@u4zM4?6GL|owhKp@-6!qBiMRgk}zq_&H{c_A+WW`SLjP` z#Zd}?b?V}<=uLyU$j$i^%*!V4e!Zd=Z)(8SkUREH#8s-h&F&Qw4eDcre_;@l{+)3ZeNKoc=lyd;elEmK+E9pnbiOtNybPo66Q`kAuQ zC))oo&-+htz12HqaV_g#)OU7h$4a^N&E?NFX{hI4sez!;DixwS{9hGuL4%V@GH9t+ z<{pZk2A`ueQV3rQ8rY^pdWcdbY6ILZ4+j!r!%=x%`hNzkF5JJrQ&_ka4iA2nm2d0L z#3Q_vdi?3L;Tv!%h1UD~_1#b}rw|B~%Y%AqV&Ro>F%I8o!#D;dD(q(H_0g|I9`OtC ztga2}vyBnKSwCUXpwI_Yt}*P1L5$D6KUb?|QFrx5mT_K3oWWDCpVmRuClh>~6_$Pr z?!Ta&OTsx|?C!gxOl32wdBq9DXnQR~l08<`qn<=g51GCP2EQfYAotI!gT&k0(k%aOPKHaj=a-dboC4Q&rb_YOV|6J}C>?^3HA2 zA4FkrDpwu=xW8T=P5Z&TuHLX3^bVq`dTS~xj-7lN3g0m;nBwJXiW9JqQSeO+B{pOr z{lAok-~Ve5Qc&%INl+_}pPh@7V{dtGj}bse&%gz3iD2a7KBQ;j0s^5>P&ziQ{pkg$ z`T*qNq6czwuk&*70J-U)=ui$x2!re#!hzkB9pJ+?Vl9U~-z=V}a#wNY?J8pt)}E)Z!p#I(9xPk(J}+kh0>wokc5haBC}-QB$$U2y`Uf4?=n5oWK92+0|bsI%WE+|#S%{DL?| z>dT>dcvO)F3j|GnPNyZ081ti2UAWaL@HePbBUs62>aD~ro3qT`th|<^&hPad>z)du zKAY1;eM&9Fq%83LPDR)`%uGpzNKX4v{McePt7&V}K9XVMqNR37*)7Wq3;QQcVFFVs zt;IVFSTU=%OIqhmMM<{qu{rr zv(>rqU&gX^V6HpeCoauoZhW3HCLRUrV!)0X?_rabYR!tZsf5xARxCb3a71V8ssX^l z*PD^3-jK<;uN2!(IYS_7(eNi|$OBUh$>gu5EVjHJ5!To80bci^UR5SUMR9gBSsczj zB*#*U7w;&QDBefFM~W4F_{V6T|0$On&Mn>&Ps?ttT|)4?P(6Qg|H+MX(O!Lc7?R7TUb zdSzuTzaT!WB4S=C^p^gSgkQ{Oi!nq`5hb_w%c3LEiWOkD7#BTqFy0TnEbiq zT0ul}$JnU~={^+|ZNOzF``-fW6@pho7yvD_H4x?xUBFg6euOi)5;=*ekMKtfT6tlt zwoj@8GDu=rVvYbkbNcrB8^%;4eU;ksLLNVRG@vx0EKsr~9{DF|$YgZ z$asB3JB>U4AV;%%tz2gom@88!vw3W^V3T!B+Cx)Os?U%@+vsAXVKn8Xy)J2vr$qlq z+m|O@9;(4LhC}sRRwN0=HSVF7@p6(>c03po&8ZSVD{%Pq_gKw^lZa*0Uwi0jQ0JF% z#x2&|1iqO!v)o?;R_jQN^7X)>el{XQ#)gT$JwmUIkl+fB z2*N|^qGraD{fKiWP2$ez@GRYCb!FTM1`0s;4|k~zcKw^1d@BAFkEkqQmUkH#ASkdd zp2j$DqgYW4HR=1<@N^vWCaNvp{FrESld_uDHF9mGu=Zd?d`qf-{=5?l$o0Ss*~C}u zb;ro^lREK9){PFfo9gOZAHZ2HPG5EZgaz%=<8ghIPo|phivbh7q_SSrzLh%Mz2ERC zOgWp)$Erf!tJ0>K-Iu$E@syj=ny9^h@T7|BFkwX~p%kArUQdP0egpBe1yl!4QbSEt-EiHcA$_SWlPc9{sj*OYF8yy!Bxl%Xr%W}g} zHlKBvp$V(uM}Y)a{+nz?YKtpg{2;A8^-$k7rMlOVa$(rNQ`^Odd-kUO_2#?0aDzrn zMA3DD+l3}=&Z`Z+jpqI5uRlL4=+~eXJ9VhCHi^ZW#fjtmA!1d-wh`?wwVUrTP2ZZ* z(5Q!)-mX-{GJxc`1Ma80(4&ekwusFM>oTiQ?luI znNhP}<9*rqmYsvFej=FIq85E@eN%t~2sTHb2FA|$z(~!f{k~Pzq$?Oo?uFY*qTO&- zH09u(AZuqqe;)me0Y?i-={W%DJ;0;RE?vg;uIG0hJ#Gu>DA>}1nG~GNPY=Y1_M*sU z1{-cHeA7c&2*ONol^Zeh8IXc0ay~0PxFB>S`rUq}(#&i;)-#W{R7}_|QZ6~-B6$)M z%`aP;IUSvQdwKf+Ehtrq4-D~rC$fpAM!XniyLOoIIyBlYEY#B1k}hxeh``WIem#G` ze>*Ssbw1|iT{wgu^K{BAy4qa6+WtLexD>U{<`ZwNxYHPDnt{eh+c2|C@_2yYlfh2} zNl3|1JuRZ6e|u{)vNlim`oNryn{d^y);^uf`<9^ELiLpIIM93`@vj497~$26OVQ-t z!)<}rWKpYR>FoEDfWPi~YL&!uKiV>WLi=C{dn}P_ybY_#rDH&s<6FB-cSK6JNv5Uu z+MQ}C@^k$Ahg8s*yr5Uz@fnlD$MSO8M4urM210fzt`^ z6}Yy?-e1L&WGQf)_Hsl@DZh|X;Qn2Yy^YQBVOX5*k2RZ|GTY1wCY|P3fEhiNA_2D8 z(S|*0XU)Oj>o6~h6v5}!+W8l^g3-hep|OYc)w>FGLZTEixooEBd?NPPB3WA&$`yPc z0Q7$qG!3>1gLHndT<5j|PChEo`BPc>ae{K>YK$gQ8PIPJ1HS=IW5~7kCFRPG;&-Rb z3l&(YM_mr%ci45;3~05MG6FiwN`uyE2PRf2v6{zky|}s0=FU@>%cIAaRJ8P4!sZ;9 z+Ia&b8QtK&id$-a7y9@eO!m7n8a;K{9?bw;2`8Zhgz>Lx5=5*dlT?E2FD@s(S<6C_iKksvnfm|A zZvL94avQ$DNC9#_hnisQn%^X zg?zfEHVG1j%>5Q9NFT^=Gc6t~{sl1qv(>2SN%ug37O2FU`zk7g4b!|=(UzsJtNu!g zi5&PZoDdFizQXN&o+@49BNf6B7T#qjCn6k*hPHYQtu`@N0BR7gD@x(#oKJ*5FJE9` zOlg0zDhVcqm`=ROL<}ONx>#VW&7n!hW)Y{kNz#)&7u zUk-3bMuVp|YjT&?)|DIG`Q0rgzT-4BcNDwiI-;Y`;yo9@&2jUKr+lh4+f%J$#_BDN z$I1g-Qhk+KvmkNgA_TUzo^&QTSZLyIyt*ZJ(9xKzYnW@Yn^fEEqYLjGjhK}AA*!ck z((J05h+_X8_goJaXJt;YHq$|*9Af(C!kiVLU_HEhWt*1=?NyacrVpi|fGJl%`YH@e zo#7a>Vc0obz4EPeXJ_yJyI8-3$&V`!{``3s0e96X@0X->N{P9+)p3vSp zlkk0Mb#ttJs5!Yrc_uK8OrbR4hkQlutZQsLcL1*XBd!>(Kt&PGfIKUL(-8*?DCHV} z{Gn@RVL`vjUIKznlcCo9iC$&Ar)EWRrT)wD!ZL8i%zY@Mve3V~$>C;1{=XXJSKJ9@ zij~c6_lU^g$@q2Q?Nyu6)roA4y0J-lNwM`Iu5_a~wh<2W_eZkrue^tjuzk=eF?Y<8 zh_>y}4&0|t;;ooXx*+dnG~4%N?Uq|;aa=&n{_Ga#q!A?mZ&VGRdqN?={0n7rqv!4;oBC2j_GjEr##N2oY_w?@ z(nD$;+q8)d7J^Pn4{HPmsPwtqL))s7i6VE*?V+I-z05LX#??)ZT9uN>uU$pW$K_Qh zu>_IvozKKp1rz4Sg$9^+^V}v<1{kL@_!q(j)-4asC8FYq(LMllXtR4o0JpT87ZMo!_PAaxE&MLQz$|f z2rD-?k#!^Ofvz)SV^m0gJr9&e?gd>$8Why4OrGyvI^Wylpzko7&ksNlOl#u3I;{GV zAnQJJfjYy*$OPZ@@%sM0d>W0V3O)3#xi*V{S<#47Q_;BZ9r8!g-Spa`xsODvu(`}c zF#5d<7amSc(cN+ufm)J4`Ztx-Ttx{U&)u9*Q&zZ1!G$*}rH;!;svIHDrw59LRFpHPY3ehzOs zZbkeOh-hUBa*6t@(Fa9vt%n^MrTgKJxrWX<9p=TB5+?izoVHZQ<;4ch>+ZLz#T#q~#mfkaY-!j@4*@s@m zz2&1t{Q=Bmf-~l+Q|9mG>JSI$vx6|-3>o86LFC35fw6(DvUY;gxPupsY`0r<>CR;( zJ1g-YQ6DTW2=p;7Uv~Un`!-hu#afl$7h+po;m_TTap=-=cB*caWsi%k&f-7+{&F&s z+2A`}AP)%j@B2fC%L4jVzg2>=g`|{|h&Vg*XWs+^quk#8(y-+*ho-^kZ$$-^!ZvBJ$?5;$};RuxvA zTAJIq9_}zUBSTI4B&-OtG#fa-9^Im|BrYQHKHW66u^{773RuBlIkwUQ(-=Fy_u9Pp zY2SD05Nm5abWA{Xsp-2cTH)2#hA%|1OD1(;BQ1c!#+Xk$U^HL{q@WK$&2S6yobqck6+{}>l?kRP2P#8XQ*MPJIiLiBv5uMc1 zCR~I!n`&|ki$;qd=iek)>G?f^!cCHgR@dr1D^7L^pStdU@bY%9gHb%oOycM8wFeV` zYiYFV5jB}bN@t}zyxwkeYgLXtaq@8(wEynVXzWS8MVG(eaPtpsY*tw+q-X-ov^&_$ z4r>LoP6qdfc9hi)bvg7{j;OP)75(nx7*;K}RYo478*qFMG=&(g=HfV(SB9x$KISy- z6y&hM1b-Am`)jUT6pNsym{Gl7ifruvddn*up!lukdrQ4}zra9vj zyvasC(Q1-;j}V}u3o8m!kHky2w;UNJ-C!@+cZ;qC|TvGXncaP@R0pFq2)SSs#1g4Jg!=A}{ zl9KT|eeao7hc#Em;}i3|Z0XuXzi2maSF<9b8Rm4_+<{hQgAe?{{Yr`{T7@h4I3Zg;B$bX=Z*41l^p4Z`3dS#=G5CCn^E2rpWvKDAc7%5T~wSDsmu*DWQD0e4@4pY~nDI6{MRAL=cA+ z)&^Jes*^;Yi5*$T_y5F|8&)|#`Ws&BGVknuJ-S%!kfFmi`;k&l_4gR=T*6s?N~5Cs zU>#w-OSVCy0*_~-|7799c60_qmVN}ySLmE72@ANcLkEiAJATgMaENEYaQaGO4g?h4U zUo37u9JjErfCvK$ktJVXaZ&Dg;Ti3U?Y3vy&(z$mmrLvkz{<_W&+6N}<-FAn*Jp}J z+_AL}&d>(Slyu8bo0@K6Ml_Y!2GEq4@6NhqTd?Ie8`_ZJsNdKs%y9@J3k3Byw87G^ zSuxlMml3S9*Pcw65HimOo^H{QQ)T64^90}peujSc0n??WYd7T4(v{Yr*qd*}$30H$ ztJJkKK=F6#Cp`XU8}W<)=%i^H29=>w7yFp#Gi#Pyejh%- z59msGdL9yw@b8s*A&PK^(xzaLCP9bitldxid9Ea)*Pn#col7GGmPIirW&|g55J^d` z7&Lh9w|?0)0;7W)bEouiiWJ%@LEElJTG*fa6&8w@(-^|0yAkEipokn+Dl0tOiT2$X zpT@-=3YxQ9*JE6c1#HK}b3cR$rQ`1DC5<2Mp6ewQBC>!{FX%$iTOMuQd4E^duvXoA zCjGD+)65`^@8L>t!!TI}K&JV5tYiwDix&I7A`K~0Lx>H-Jqe)$@yE9t)9Cd>FLupg z@`9n&jcGErohQ?owc0YIQypNejL@?C2K3^Sp3%L)jSG?iC)1*CVJI2bB{$J+9tK5U z3*pZfq$iuc3bc0R9QjpbM1134M(^R`&^0m1bci|_Rr(+aqO4&Yl6DG-7n*X>C|k{T5Vfzc48`%XG7N>i*YAST1spfN-;w>u?QJ`quwil+N-|Rnh4(U=Js_C@*jfmoaprT<@zyR0M9*}RpyKJ7R%5fK<-PLdc2cv8<4q>evtyaY0Kv zTZlY2+U=xOI%Z*RREF&@+paS+R=d9$_Q&pgO?FQmZMPbX?$FOSt5a6pvFFB0-AwDE zNY-clek zRM=sh3X##@=xZJCU}FbdytSMaO#?u`R_0%Tkh;_pb=9T&({jGOj4f#Bq{$L`8{A-I zP8H<-8Ci?ShP0eHTUE|!DQjQ8b=(;J?rVCgt^16g-0W%%y#}h^AbdWj=pNm>Lk+!Q zwehA1vYooP>Iy~cCuSa=$>v7*kps0Le7H)=!`yl;CD>(=$x}KISs(W%3T66GR<&{5#P6}fTiRnOU~4yJ6%)6U;n`&tur z*0IcdGR7n`yfrVEXZXFx4wHQ{j;YbHe{z>>2m=ac?llTceA|q6i#35QXk*g7AzQqB z5A3lc4b)}WKdIIn*XEoQR+PZu0gF(gXIqYA{*EK|T7GGj?Epmwbe>gXA&te|f@zVp z|3L9U@;2!OgPTZ7wC+uGaqr&Rtl=Jrz4SmeZPl1`ARjbfp833X+UU%4`Q2CrTNo0J z;w*DH;YVLs_A`p);tqss8Hnbc&x&sE$bN?l1xi!axi0V)}zU6ZiT&fguna7uZjj zMESvNj37Qf39GY`F#U*!+V%0-)k+D9_H;!VQR%%Q2h4X^n0|;=$Q{2|2P>*HJM{z+ zffmUt1*;mCNGe}h_xvmUCwRX=`$Axnie1J1ciJw-B;`2`i{d<=2onZiW;F;7GB~Gr=i2GvyMP3QM--)pYjMrzdTX zRu&-w=q?A?Go2QBJ%)xvlFINfNeot|=l7miaOLA{E?ylEWOhj+OSU8BDgth7{L>94 zD^1%cs^vxgT)JLfnMlxPm#qPn)GdtPSSQhozbpMHUHBVsX!VPcJndEwUa55#P7QUu z6dxKyl}-7@3P z_pWmTGGU>(P=`}gYsnD#w`y{kVc=qD=F@%YVX<7ItFhqt3{{)G$@xM9v@_1!WZSyD zswnd4cqbZqLZ&}v(N!(J+Lw%m%YRkhHK_ABiY>%)qf*b4r?b{Za$;jC&-t&It)`g% zOQQdGxO&^F7)#kwlVVl_vjNl0G4~p2%+ii&CCU1wleqJ0&aX>fp!NE$9Mt`Aw;n9{7(ZU67k{p%8`zQ2hS_Boa%ByaC(Y=VM_8eN{we~ z$xv3QUrzmPNi7W^V4)%He28juV!5OAEj{S&&&&`7Yn6PQ?H3z2A7yVcyHlKUXqyZv z)W^#F275!>09QqHz}e;AZSSAQcG5ru778rNXmH6O+p6mXqp*vVrIgqHXKu=A@Qno1-_ER+h}y2on2$s*8%>F(GfI(<=D7%AF8@ z2*eDtsem-aw#pS&8viv?|2@t(aBzU8P$F>V^9cEhZN0s35w#SMvDTiHsGVN;Z9W-R z@T$1{X@KM;*fc_Mc!F;uCw5kWbkuAlQBls`)7z4#W|qaDX5*=aAuswg{DmTGI9HmJ zF@&dOQ-ykjK$Kki9}+LoF6@T}=uf)RAi{r$SD_QXn-dEmQ2rfM5RK z24!&7BPmdf_+VqC>?moYTDYcpxohyd?8-3sFz$&7`Qq&_b0YI^Yx7E^vyZh6QI!-5 zhuvQ(Wl+nT(jU{6?;~Uj4Z(vWtzAK;bRjf%b!2-#Uu*DA(!7n0!Z}n=rgLk5fRJsp6FgNuWU=ieGo5w5qGK5Db5TsCz!y9>V* zYWbg(iv#(3wQCF)HE;`t)qUoIN<}cUwQ3B;*F2?-pn(Z*n=*YtNShU_IoMe6#p-(d z&i|Dh-)e^c+Pr(BGwV=s3Wiih9vnb(XXyt+R8`+68|a{U>Njm^k1AF5qE4mr$k^9w z5(kMZr5=)QLrqPOzAk-gIaxnpqaX$0r*?p_)7Rfg(SkVS8H{9F*8h1sW% zd@<5@+D4sQ+EMq8a%iL;2OwMaTJdOlN^U6|k}R zfV=*U9$MU=AM*=(bt6pQNB-~%gRP>+^P@K&g2pEYC1+*uS30RM##(FnX<*^ueUgWK z)owsowbvzLN;`>+h9=Y~L|4>kn(db1;Ok1}L^|$8+JOP+0kwZTmC&RfgJ2}VVxfSg z&k2xYtuh89_Ac}13P;BBdz8nvq`hPf;c=$(LjJ6g!}p^Ixh#yWZuPKTcx+^KSeRaD zEJ7$d0*is=JEic3^S46(gWA22(i!^GZT=!Lcn^366)ZS?vBzfgtd;nGu}S{Jd*|V| zi8+kIt+c7m(vjP#Ni%!Fp7lSkSmZXwbFI?J=TBkr^5|G3RZnu-s?19@OaI}>?(Y#K zc7n7%y`fZP(1o_yH)}lZ(@||XT*e)P%4B%;gG;~S3bDMqKV0btanxz1IVzMB|5DBU(CY(aTt0!Bw?ThMWTaW%el$Z=||ktIZ&mwL^vZDFoD(Nykgx|fKrYuUPfgGrNZd`%qs zShjq?`;c@}J#RMn)wuRjmONKK*(8m8=I^u1#F?q-Bg7SO> zc!b*K&aytt>$KyWuOXFHXaIB;2ikq>Y+V}#CU_2@r1f0~r z9wte^TLpa`5y?%do=;wed%-#npQHif!nl>=Ljq)yygMAK!jwBE&)3h%@$R3T(n%?F z(d6OV1a?b*hmtfP4@m@6%#!1>UX^6NKY+b^$b*7wB-`;)8E@k zJ2Ox4;j{1@+gz@l2wBt8K~b!nE#6<6VRczn#<)IcshJyDZOpu>>Y*wY2~$57Kp2G9 z4ha(MWIFVI4MFU&0Y}D1>jZyOgJZ!cs3@E+JoIW%hIfhKmNvg23yUOA?aSQouWbNS zNIGycXPH^838QG={buqEYH9GSUSb~J%hxfKTlL7jcpF~NX5N03&I{t;56|Y)vyf!` z)DqLG$W*@l#haQVsfC<20s`B`Gez7ap1|uWyP8la_K$dVRk? zawE2BZU1~)VF}PrE6UvB2LQ}Hy~}Iy_?(d_(8=q^nS+l^9T!J!&zSzuTa{QBL0fhS zHUIc)m^b;9v0(osjmxdnr>1hT5aj2#Y_w(_4T5CZP2)?Fp!{mw*4>YOeaQdIeG#%a zOmj-6EelX71ehj$lF}ck9cn0_3(3yDi88X8*EKOm9Qv!>MKntIHoqkC8>T0~R6V{g zjZ{1$8qcHr^BD^apm>Db3ppw*mlawk0`oZ@Nu*sh&n6Rp^heC6AIN?a$h@npUoRXb zpg>)d_n*~-r*PiYNfxVy^5Xsf=06nHo_wFSv|-7_&DX*%C3fE|l8wHZM9???!Q$xB zREQH>5=Q-SmbGT^>xUJC^>h{8$Vh0zvv#GZ)rW^$77)YBt$=c^MWp|m-xNRPWwv~o zzVFSOm#M{1{kj}!P4+w=&sxP3YyJHYsoGsSk4HEz>9JwkdLm*q-siB_3-jtIaDNVC zYfmezGoi^D`(-QXpJYO8>So^GunwDiqR`G4I2I+|Z~2PiR3!>(#CTZ*Bd+q_O>%ID ztuEiIvqLg#rUJU<`%)g?eHPDL)B4w{W;#dR3R@LErRI-HSPbM>h8v|27LrN*dR!A& zD^Dt_lu!5AV=DJ{`4(mu;UZwek}*gXN4ZkDRK7n&9;4QjR0+#8)qb!G2Lc#$cKxFZns_g`5kkL{p(tusi4 zq%sAr3o9X&WAVghUf^F0GqR)skWhF=>3m?^iRd_B_$kpY0LdRIzmvgS_$oJ9FcSnmrH99PnY5_Gs-6xmi5s#E(__n#N~Dm0n}xiRUCSRp1BCS2dK!QW3`w1qRz~ z_`?B3=)@&s>VK`;{2iYdY6r+O%_4ZK#mEhzcF3i8{BhpRLD%@xJnXJPa3l09n(8(= z?c^T{cH-RN1d#R&)|)%_&h0=nR*y@43H^@))_$uhyfcqa0uSu8WE3v3nzG&&<1p;) zSvF8c68&Q>Z+y{pPy45W5uq#S=o04!s5$OE`wS(P%Z}e5$X2-@DgSCH40dJAE+%dy zWr`_^4XQPOJkp0i3=smvVOSIcW1{I0V=;0DpNK-O9K6lK+drb6I;}RT_nw-Jb<|tX zdp_%q7rfF!7pXrPP$=6LD25{_N7_u=6T;@Uh_^}bIgWBXtL@ALP~c{_0@REC$&s@) zM}%u)2z(}tE)u*ZGWIacH@o(xvUVGuYRFCtPMO(5{^e8s>MMGXs^scRe|XdM3CX=X zE7{W!t&;eZoT`WL%tfKEsdMYf8HzKf8ZAOLy^9*~mgERn%#1KpK3uMW9Ngbmj-)(a zb4yqmRx^jaP3gyP{PJ(Q0>GLoDukb;9xf_m$06$aSKiaN85a!*v9a0Le-bLyo6E?b zYtK&e^g2=8^>D_n7ZC@YIfyxf3pt%@{iKGApo_zuQ9vh}??@bPyz;0T;nUXj?JCU2pF zvIzn{KLKx?vQ-TlYd71b+PmuRvEn*8IsyqO=@R0E3&P3G!TC;o45Z!OKl9vZDLk^< z+G>!De~;Vc&g))~o!1<;&WGOL;P|ru!WVCqRDMGkxFiFQd(HiMYWr%V=;i+LaYY(dkZ2bMrWe8P`#ClW%ohMe4o&ekT3Kr%Ke-KDZxptcCJ#@2@Sw39~U14#cPDx+5T4rI#vC z4jnaIqR0TfV@}_E9{q1C4ua0@UA`H?q;&$K^Xwi3jSAHCXy)Ebyx<7+#4jkGIKq$R z1Jj?ad&dMv(IVwa|Apu+1X4v-;I-}ZOH6W&F|xtZ3I`xI)Nuk%T4^2t8)5?Hv~clt zMQ!}a%oDrA#}$adrZ;ZOQgbW;roY_t@9AS}w8V7C2Y_=n?^ho2O}t=EpI0osK{G)6M{{vIa>_bZ3|>-UL?Xg?$SY{@SIr@@RQ!(Pfs zBGf8_sOd5c*y>rY@3?LfnepZ3ZZEf2XEQAeT53Ru1J9OeT6|?t0ffYekdt(p{A`$S zO%Ije-TVBN@E<6kAoo;UK)Aq)4lOamkv{`O_EnxTBn#1uAjbz>ICgXR$ zl?e)!v9WZ!KC8;yZ2qKkP=iCAFlI_BMf|e7g{}0 z`BLppxLkY7b6TDZV*+)cRQel90SfMikr@z62>FOdPpI;nnUAF40mkRd*K^0kY{^$|^2b!uLXI=%t}AdLLPJB> zEna}>noaZW(FWAUUhcC_whbA?n|)P+KRymtI% zVO{xM1zp8R^5t$aFvz%q(ySmZsj=IbRcIk)bXEKnk4Q}9picVbmZH6T7W;h(Ck*GW&V%q==B^x2 zhg6}dBFUJFO7@!NP80i)NA_)B#X@eJK7U2QeqZc%AiFJ2Q(hw}6bE=)*kt8SKtepmlN*l4$7Dey+LzKYnKn4@W|9Uol(_unojQ_3B zl!gBO^#g-alAe*12TJFlW#i_ehtfL$Tu>E*otG2H$Hm0S$_0gX>;ZV7F%epRo(&p0 z1`bXR1|CjMHV!VRxB*~*3L*cNCWoPX&&7JED`tOgPN8&=cp!}#F+&M*h8JAuMr^z8 z`h_VuSOkXydKdAA$toguY=~^4!Td+$>X{OS z9?(yeCs?Rky%!({@BHp?CKXo(IPM0Nk68OPZ6|?Ox2i{RDL8?-Xz~#E>oP{l&Yl@L z`o@pEO6~5-S6WeZl{nfmZ};ob?+2b{0&7R^$IjOp^}$l|GcXwp#5JDj=-vsEAyiGQ zU@x>j&D|#J4298iZ=DIvr5!Z|6V9jZd{DE2;YD{R9(2>SbyX6o=~z)2YTqAGdRoXs zetecTfiZJHmN>>)l!4_vfR!i^Uki#GzUp!{QZz+lfd=#Qhki|p!hkYik!j$=6^_PM z*M2YS3XP2M*;u@Es5cN)kbYEyM9$9QYAo=o;o%Cps9w?DR?XB$^+s+{RL?9fj-ba1 zj6b~@-0lGL-z)IPLXhQEqkb|BV_lRf=E)P?1{Ttlg2Z}V;Fbz)=&#Q{C=<#!q&YQy z@z@%1IZk!by}m!MLX-!S4$UI8b>wGod{wdVXm@@@Y6{ics&yY=^dzmLtIh}CZxj+? z@0Hh8(OSnHV9TrOT{6g_?ug18YGNl%FRHp*ekU1K(x1j@DFy?ZEl+nAdWsT-hB9Dt{Le|WmnfS&zt@qq}dq4{&qn984UZ28w{upzV_|bx)e*JKK`D=_t5{#?~~UEUpu!~Mi2BsI3Rs1ZB06& zxuS2?N;?|UPlAJYQPo`~K$F<)B|E>db5DLK7eY1xf!4N7(=JF*S01~2rv1l5owB7= z;c^g@Gjn@`2YtVj8DX5Kuvqdgo~JVS-IWAtp_H8stgb4U|HM+QI1sAz$kqK#-o2Qj|MtfKHK;;}5DEbh7y+6zo)mi#4+k3i#Y;B6F zx7MRuJW*waY4&}inD<&+*@)8Nz|H;BvOB80GVk{T39GyZdKvHtS$1n5@XsUE=iqp?y~9>nL|Q$IBHFbcH%5`4zT?;)Gd_nzdhv2WmO zux`!toQEMifsn2^1M_Nha+F44r1IB%VaY^tA;@}_H5CipgZ}tlCfh~IPRJFojaT*h zAZiE?HSinXSRo^HEel8_A$Y2Sjj-W|PS@m)1}-#PpZXGq?PEm2{bWFJ?ANJju|p)K z!asW~7nOr!I!cLEX46g0$|XN_OsNtdzO8Px6&y~yi%03aRYM1aA^tGh)UU=a1sWyO zlkdG~BeXQ=Q7xTJmSM5(vg66QLy~Rrs7?#7TIc75NA%-F&LAm5iE&us2lm|WaDOri+pI?+T0~B`^q~T6EE<-afpD;&HT* z|B(Kf)|n8?c9(e^hvtaox}y@Eq|~ws-|wpsg*cHS9%i_>X=^0EMGg}bq9XxiD1R{^ z%PtyZrV1}5qL~w^E!LA8K2e(q`(|ui#FZ#N<1aX&yQK7Rxi%d(Df(8C4*NlUj;uyt zY>bD@r_gZsW*s^-ce+>ROFjsSVWC2^#z!?a*;nU;cMafL=@+5*7yoBkMCgq8yEOFp zRpE9x?Sm9ghg!5bTsOoR1gqgk?kX*cbm+oJwZe+9xHPM_;>UEM|O;nIdHk zg!c8)ObG{!28Uw`eBUaM0gTYTCJCrjJ7WyOtdYjDq|?=yY2#d3`4~Sdg?;RWEVREk zmnbCxfViic3bFKHa#mNyLwqn*4%HaGT*7_#INX62$|5j58?XC#y$Dk#s!zryxk z2TLTA+O0ZF#0FumV|P$MgYecB%dVc(9JZ79gO3$&<#zGkl|=u)=Io&#k>JG+>Dvgn zX~fSZWJmr0UUy0celI_8e|NqNhug;STg0UKFeypkFD@voNK6O8l^WaJ;Q-_wkr|@) zD?CM_>;OWm%HOro?yfkEE#;LnCiX*RzRlDsYLInUO$)lOrW&WkOr51RYJ73BbK;N< z{tTn0Y&?31{J}T!l#44y&}5rV0c(dpb3uE15I=Q=!6X@VOf~cYi5WppRdAYF&g){% z8mV&98t87gt(VU;2%lH4`3!C7xJnl;6!lFw zomS*Cc%Rp+hBL`$76FUez0xp}%D;EG=K`K!00;vLNRDlDE+Lu7wQ{PJC0$YuObY}7 z0K+sV*_os2U$h_(JN|t8GG@dN&}&XYX(*rfWq|-q3hs$lbFIF$fV*AsPD5G6go;2y z_ga%CBe``ntA)FP@|0Ewv`9zo^&qt9X}%r#2h+d7R+g?@jFp+M+~AoVDSXtl4oLS} zqfGyIXLnc_;`}kWCYBgX+Iq6n)*vXKMJ@p|J~w%a zN^#nGZx0P?FxMCm$SYBWmqStRA~$Y1MiT{0vF}^N?LS}1QiK@TlD0YwFP2_eN6upY zw=bU$F4z#Ky{9iCfQ0RT?il~dJ(HC>vXs?Yt?|b7SveVnOEx{44n3%0X=t-Aaf^*l zhvDu=#j)9fMA<2K?pq@R9+0tkj}NwXA{$9;3Y-MKEU5FQXZH?q2~x9dy+-YVyitA_M!PrLrXm z+3B%uKrOHH>OH;70Ao9|*dxoXGv)DebR}xAr=W3RsKa9Wiv--ZHv_n8f|C7K4kujQ z;g4KXK_yO^ER8QOk8d09@*L5o)Oc^b|L_V6{=2f{#T5y=QTE}g9R|3Al^(Na%Al2n zGiXoTYGg48f!sfL}=Mrg4hv>7hRde^AHWYp4}%@;OqLDpCS3 z&9MqoGwyp(GD6+6M_h6@i10Q@-|xOVkBa=+b2y?~Q5Ua9&}C*={9IUR=4}!wyPtmd zM|10_F(=;{!TGa{xgy4gt1I5=n7i>J`A8-y9Kqbv;wgg%8$NvFKM_ninxL1fKftQc zH);%(-?d|<&)mBGxEzJ|a$3!-Nn-BB$yz~1d_jR|%@lA^@oX47JXHM1ITZ^8Urgcg zaUThg0!otp$6Cn{p}vA2`+R8wuqV2F9nIzx+8d(<-Fuu18Lu9)khpQ#??;Br216AJ z_N43CmfhXDkJYe0|CGWWwL2Mh4@N=F(vqxcU?jioU&vyb`9x4oT~B_8k&gcGNm(*H zmFYFOBJ(LJO7Anz?W*G%0inPSiFzzjZ546OOMM=waL$s`rg=2N#QMDq@6aI!$YW)H zudE2+E|%v}iZac;)~u6<{C3teWk&oq1@D&Ig9LP?zm(yItjC0dM2SmNhw{!!oUV_! zhjcMMXzHC5Vkv*p-Cu>)7?ZF{lJ*% zHDfw(=0Wagyi}F{wNccH$QbhGtwXCIbab8efX~Fvvl&J>QqLG(HPNZWAnuXLisqD zvVP+2lLX-*X2#P!64=lGMeA?bK&fp;O2XUu{PY(zt4!y}FJuxwZOA_r!9|je0a{7n zdgK-{1EMG*u-265#gT$3l~Mn7p#!|W@f5|Yn!Qo3^Yc!m_`a`MGFn7%Hu5c}XQvQP zM=&su_40z2b_czbX5Pl%%|y3 zIbBydiTRjuiwK~GQ1$pxT=iAGtu=>T->+}uY%dO8LH zu7lZ)SFgp`z|(h_GdW@zfw)eHFwGSgfKeIdhylJjm*WFtPmh9a zgd7&CHVi1A4hsw$3@>xnSJ%Cc+E3j)Wj(613fJ;;;(yyf76dB?&3sHWRC57AOU^0@ zmCIvE<&EhP>M3bstuO?X#EBTQ^U^V$LUtA)Vo`Epzi~M?^5N-keb|e2T4!ti*j+4) z+E#I8D%={IIcb!_C?fq$3um|qisjZ3y$-Yqs+Z^(OPLOg3Xx+%P~ z8zig#lskI=-790(rtkxfZ=BElWxL1t`lya5RC8$ZE0prXa7&T{sZXn{yI-HTCY9B< zek+>TJ~>E7M5Ol@>{p1JSQ8c+oRRgCN+7eJFkEjdf-ZU;R`M3TsPWsp+A>zrdprmV z%1Dd{Z_8P*Rl^)o2$a;^>UY9WX~U#MqHj}=mIrqB&q1%vT2rso8)uoqCMGZn1R8T! z@o6!Dw#8}#?e}nvLKPUFmTZsB#(a6ek-{L}B~b5W@E;jcl6!A;nw z)Fxd|&E8|xeUa_iLRW@Dzd7w(2wJvy{x0XX_LDNAGFgY`{+dSXHPNRHWu}&|2=3H+_TC3PB|3j?H_mVt(1mUZ#jNQ)e&*YI{Gs%+^by7j~^#U0W8fYB*;|Q zq{vMlM>Co{!?^&POb^>1TUtV(I zx&Xf2ODz_$u>*&-1;$JnbY2*pE=3{X);qu7WTudt89EF=++sKHn;w$1byJneor}?n zQf{l-&$5UYM=wuQXS~KOfQ7~%$B)h+Nor3Pw=r?kXL*OMcJlME?;aIno9}l|s&zyk z=+lT=n^-JQBARI0*A>6Nl2$R=&LEXw8k;8;7bmCEKv!hA^QGF0Q~MBj9`@l;ToI5r zCV|BPKM)BVU(9%VM?HOSfBiZ)uPP(04Grf&xk+H)W>le_ReHVjH(Y07jqB-d>fBas z7u#EWb~Csyw7=N8O@4Xa;Ai^4xqLvakjeA+ddM=f^2bg!mU`!w+59NExMXG3ZeEL6 z&Ba}~_GX40xLynAJTc?#9t}UwxDIB-2Tx}))(-$PQ_e_L{ z&+@j|d^zc3Z*V~;M)uz?4HfH3rQV0aBO%B_tG(+Tbuw z-ieY7{Zjrkv#bnN;)RKxzs`XsjS7v^9)?aF(LdNd-JCj>9wh@OujoV?scmWK5?jVV z`}x>nP=hKZ_(1-17tZY?)th#Es?{LO?PUIwTb9u3sq7x@eZ?z)EaQZjP^adaMO3X~ z-b&CS*OdaVd+;znVpls0}dh#a%!~@ykn0olc8OU3hPb$s8^){ zExeD@e6zgktxwk~s*Hd`Rae>gcY|c>fGt6q7s9i-$pvX%ukO{iTKc$2(K_(pNt-2h8O$*Yd(>>Bj!C3}zKBiJLedRia%jPw>wY99*$RwLfY)-HMS){SKJKQlxRH|eQ>UZrRVIal zPvif--(Qw*{*~n{g$>OEk6_N++$D?znaIJa4gytz6zz>Y>drQc20h^hRS^@|5@&k-d>b5a$!aeofl(egR#S;jVPjX{oH4y`vl<&+CH-zA00~yi8NOK%s6S6+ zkhZMkT3*ofT0L* z5Y=%TKcl0BD(K?N5pq}_uOMPHd+^c5v`j?nSlf%*(pQ9azO!Bxh4n0?PvjHtDmF*< zilV7>;(<4+>DM_f8XgfAEMT5OKeuBmozSAy^klR7N=sNVQS@L))R9REGE*3V4MWcy zpYf3PDU7gkKe~hGUCy}q)noP4=K$MMK5K@i;7%@*XbWb^L>pTZ8hQ?XEVKyeGwqnr zDG=5TK0ZOj9(uPE!~Acw&W_kxb80 zc&TwXK-We5jAS%i6hEoBDICL-HR-o8x4F((wTpJ9txw-s$Y{;-Bd#~)LeoSZw`>t8 zjcUpxh^;#jfKey5ln2wlCrPUjf}dD>+Z|Ze%of?0!Htj#3J6z$yD#A0(+?xoJ$zkM zLJ9r{umW}GrQtz4&n#snhoPWWQn0*|lp5yLg}$b#N0-?fsm=@vFT1H5FXb#0ZfY)Oj{1Oi%4H2a)F&_RC?>chA5S3CQUcsBCGgp5TO$_)k@M@`dbQ@=#C6XwQ$weEZwp}&` zj&%v52d}wG!wLc&*2?eoK0p2OmOu1iYACPlBwuPWWcy$Z22! z1zfd5&CRhJe>OA}DHx1ou~$Q6k#XU#5K;co6(S+P3Bo=5Y4%R2#2REkoZPtFed&ia z-1(D9sPLpgl8mZC#&4_d=8w#JAMA*A&_HG2t8Lf4vv#KT<@(V^fvlQ~*b5)^y{EDV zV=lqq7uK7ZsgAs4O;g#Ew6ii>jc4)KN61fVh-sYO$*8VaqL+M+flQNVsr3qqvhtx} z*33Vhq(5A9!CvQ7-;;-_Q(?VIj91So)+kf-!-iZ^UogSy=omWG*-Y+*+k99_hjwJ{ z)0XW`4jEr-F0Qi_d9LKCNzpt$auTEcMr6A%(sUKSjPSd!@{l1u5e$uD#Dgh$QW$yF zO$zasOjTGz^OuNe#Duk$WYt1)FR_nrUN*TP$!Cd2zVo7}oHvCJOJQeS%LbHETi`w6 zvm6Z|xtq#sVnjwsMQJ(qRJ}%plUvgO$B0vSV?{avr?OIRd+eTS+~?KlvwecyVa~)q=^Bw zJ^guJLd=E=10jJdCccy!EOdE>Wb$00Va!Vg04*CI7XZk>%6T}wvBts1 z%F4;Q3uNQqq=WsEmW_*@la>8!D#wfa3!D$!pIR~ezW>nSrS*9KJ$GuV)i*n7q6efg zedc=2agD8q2D*b7Nyuo>H z24SAz`#s>9`PfQM)S{FEfWsGkh3)? z3RHh5Bc*hXXp%Mv$b{O7II zoXp6bHo3bhWt{X&Dy0yqfM8OQDM4 znSRB#)n*wjfyLV+iHqH;!1wRHOZTf!_qxk?{qLi{&6rHGB!sDeh98u9Fqi`6m*Z19 z@3|H9V)nCKahHW3h5R=;(8k_gJ)D5FM_U*T^h0O9MsF#23Syw_c2np~x=H zppl|Tx!cfay)ogIymiEI>jxBGU8QA*ASAfPV!KA-h}~J8n{vrt%%c^Q+I-rl*qYsZ zeF0sf#P@iVF3^8g+VT;aWXe+EBspxUO$G~Eri4*+iT=wxk zQYZ|DKvxOofB>!3FI#I#eqTiPx6r`qvANPL=X+e~8X70N8dSZQtmO@KZ)+W|i7zXr zf^XDZAoSo#Rlv{eT?2aRK2^Z5>UOdPJHLMBFTKbFb*+)4^83T}hxv%wdlZu4g57C& zp;@MP(=J%>Pkvp5cw~_2H0x|nqu*JW%eALlkrq=YvE`|AbOErybAs8pTK>e#zMQu< zRbyoRgqGj}s!_db7q=NJg-=Y>iOO;y?1GeFI*X5JcExe7|A9fa~Jrt(^djdzFBfw)RT?xe%rMlSisQJN| zC5Ui2bn-L4K3-;k3Pq2jzhCvtbESz)kgJ!<&b3G&APP)*rB8i_=s3Rqi7EQ%P?K^H zKe`;PwO{XUH`MGSrH|TOd+=A-{Q?WTun@l`T2srRtYSG|F^paOrI0b+U4y5KOTpAM zah-F*)wa>CV^zbry+KY7pwfU11U2CLz=^9``j;T`3S~4Flsg`G?K`|nT;Wa(J&kbH z8=qTZlZQ6YByy3-W?XMRI;E3xflS~g@s$7i?I}rTW>6iUQ3A{<1y(=Gz_!DYF@FR~ zmL@n%tx~biFH)TJM{0kQXz9U-F`ssaY=)50)--j{rlZ>fhR| zKI=9Fk1bexB|~05B)_^P)_=UDz3qN@eH3aS{RAst$x)9akpxkSaIgduq3dyjmv96g zk4~X2G$Cc3ly<^Tn-HeP3{i!**5)Q+N|+%^U`Q<^+#o0>Yo{@jO;1Yf^rD*_l&OxWRUw~a;A<3cy} zD-ABTa6GE-(l%7qLM58x(VyP#275CTV{Eg`!6xIf!aP+%WDj~7Q+RrAGpp_{kE^?j zzo3hJ5)viC#jB$GE!gGt2A0c31qO%WJ`l%z)vjNB=#jthWoWD1G8Sqh=?rB_UF)af zwaAYb@UfL&8y>~Hy-lhlgOS?kwPR};ZBP8mB~Q>!IBKEU_0exOV@fpRANmDsDVqN| zZOqZzWW*(XFT$&c)~hZgmXJ;6GKY^8WogBhPNl$g#Qyf_6EQpB9BmWPNjL#cMDI2c z!7l(|O`{@#Kpi;q<*=V{Ck-zp3-I>#nYeUuVk->>)9Pu+fFf#oY`#u7;VWwRy z!WA-#m1*rH8}0^L-o#;l05fLDEc8v(Sf{1(JC7n$km1|hx2CGlS;82&RZet zoau2f2hAi(*m@ZUOKVbIE9pNAWvRbr$8|dcRxx7qP6@rIV6JetT$_CNOqCfmqJK6m+u-wH4aM3VmwXj4 zzjo%lNK3tD;=Jad+xD5BK3y9J?N-&_9*l6PMRso`2`HKTN_v`DKpuriDshjCjVVZJ zDA*98p-=`R68)zcUkOAvq$T(&k;lu%W*}O7{^Vfu_urab|Fi7h9-h?2N==EuPtL1C zsvHD_ZzH904Wf|S?&`+_LD@&&_O16db2ngbcaJL8A@Ckz>S$G*l91qjar;>=sxYXh zZjVRzfw*mQ)Pz7IBN9;%jg(tR75}Wv$@U6Or*Zaot;{x2ITus74cfv>0s+6|tv22cYF}!p-ggY`NY8Lb2HuB=t42nx{>-Mgp%@&yoXRNDp z^(X+@kgHg;uN0zR2=lK~zbs#P{{$6lJh0%o_1k5ev?|b&{5{y%Y@Nn&u=8c^?UHyp zC1V0Xb`|h29&+4@rRgwfZBx@`ia8`YgI_8#(wtw(Em56(HAqe8eN%^C7UY&VI3h#T zF)@+OZ)S3In*-EWDU0TjcOIV};(_&Jd}e0N6w<$&PJ~WL-ji?)q>4qN7$>#wO^-Ky z)PJ0Nig?PQ2eBS+F1>n>Ub%`oId`o|Nt#yKcz13n@@%*XP*4*zz0yD=CZieO_p+9_ zY3Sc+&<5ViC(8Re1^;_?tJmHbv((a8tK4(oT~|f$rLsHdtE34nb475Ol~S;<<@0At zrA)tXNshl3LvGP(Y@F;XD$d^GIPY!KX9>=*Hi$9BkLeGO7@k{Cc?LdX`z-hy9=dQ< z0alSn9de7t;1yKmDB#T0`u=E|_x3t5YNCWJEYF`m9Rcz!z)ky2$i++we?Dk69+XD2 z)5BsO(VsC6ZCleK`ww*OSD0+6A7&OPz*%>KAM`cYYqPXcY92*j*!E)?pKCvIW5}xo zC=ehMcUeL#aM~F$Hr3{1m#5qKWyl*_z&1f~Uh=$-Dx~y%umoMq z$>BQ;YpLE%mfQTNLhg0mi$(s)Vz%`+ z<}Un^d=m2NQpizQa(>34r(yWe%6H>b2&b>oW=a?`Z`f>m**p+EmE)eB${-kfZlfpd z+gUg=b8{gfcqk8Zgz_($p4c>6LsfgWkYQuH@KW@M_H!)}cD|xDt{Xonf%}?ZhhZJp zEYW_6`+0XsYp4CeueV172j&nyd{i!3diUhPbD;&CYxjaaz<%f9XOzmxTtWzeD%;U; zTn?9(mt>;;h0%MGv{#?3hVRSYV5f{P-xmg{w%kv{sD8Y3eFT+pMq^PcR;Tf8r|cU7 zWNLiRaz{RD3{LgdJdQ8QNvH&Tg{jlFj@=FJayZi!q-Mt71kXtwU}j11;J9P>s_(SN zNT_f9?7t<0l_3Q^b}vs!BqS&*oKZ1hB3$wZ!kz0ROVdhjq3nw=wbhTTp(Vhu@Rb&m z@c0&G`JmXmv$y3OAZxBQrl3Zu_0+-Z(?0F<;jeB}pZlc0GQchoV?K%r`>-&#wV+KZ zEcBF2^r&f_hKZ8|@{vkc3;aL>i%Bzl3c!3vT1vNqE|^DjA zA-%;K8X;8=o;1*HtAxc;Tw0p^+Vr{ptw{nXZ}MO6R)?(C2QuviH~eqDEpL@~HVIa(gx442&29v; zXOr-7wVtDfWmpZekK7y`5y>((gz_;@MqAtr|JE!e(Wz5!HsI~l1v(ex)ns~E%6JFx zg%O1e|Ip9$4H#OUdPifBSaRfcW5isW=+yWaoWS*MxyVCLsy!ZlPK>1p&sb5*vpUeH zkyxaS0k|N<8Z0JvR4E_Owu&Z_w6M1Oyw2 zAe#JQfAgkiEnmyuzC0I4FrGK)Q?KRo%k7($0uUq0!J#(8+Y9Mv`YQaag{HJRd2$=P=6+P0qCA~Mk8 zJKwE}rZm@H=ia40ZO*5+=(wu5de+CbcMEN@X)ow|NfXM0(<>E?eOL(8ss^X{#of0; z1jzNXIq9=V$>^L5Bdijn;x+~u)dXa2UzB*@L#;;t-3nkOdg6wqAKc;Umx8m%2%i&Z zJQkL~K?X_|z{a~$uG2TB%`%Ayoi`0&tHQ5cIR_Cz^@@?n3r78AzJXLOAY}5~0;`1a zG&3e}r%co^c@$r%3Xc3=fEk}9pOAvAyNVk5AH$Dn)#1tbLoNqtzo{0mWvkd5CyM6j zTu7ssj2u{Tq_Bh(f&+4C(T1!`4dWLotb$Au=SKIKJ2m=urH=V}&cznyRC3kekzq@r zd3p@AHYK{&W>qCxgZ10E7yn+vJppOv8;??Q#@fatr_1O>8F&flUaDz!qMh?S_XZcu z!6`w4bno2_HMLW<)tm3n?X9VIfcE1=V~c-Am(wF}KCUoF5TS&U+zb$`vR<;8$)sE$ z%M`g8t)S4E5;gK+9680rF#Fm+wEkFr+o3mKe57RSY~V*ph&308R96Wo;Ke%wD z+BTXvLbbd+?g^Hdi`uz-5%uE4{QPsKy^3YLO2ywa+l`q^Isq4i2S3yD7OePr?X2^~ zRQfz13oB*CM?cUmx4TpH=D@5_nBUPGBH`r>zFKS4$b)x&z^n(Dao6$MypCF;$mB84 z@YvK`+SD%>x!o8v3q>+y>_{mpASnfYV#8#(Lf`3M&- z*fu&_F){3xnp;90@~HcJ5BC>eROgLw|Mnw7nHFV4uveV4N(n;%xF$07dHyK2=c zlo~By^`)ramY0`XvFx-T*sx*!ZJB`uq*U@AkqvTc6Etf@R;b5wf;R>KEv_oBq@><9 zYvwCU#Kn^D8VlDGFF`SEWDtWpo9KI{e30}IO)kFz&KYK)Eqlbz+#o@1vwwTzx$tb% z8IR{*@KHIPyKEysgd78i5hPGazb7bR;|3^x>Oa2TlyE}QfbbhUU?C{4>4+TH7K<>_wPhFq47PDz6g ziS!-TOO%-|#GMJzaG63dvA(q}q7IaQ+HquRhVy$&#thhj>thZf4S;ip zYpa1@`7sr*J24vkVnd;&Qkw8dJr4>H@tjLAz)H_uBHkAEl@$0$Bua0GbWWEof{l_R zTYMizR3A|rtmFwU!t14WTdPPn(Xi|`Zmpry%V#8BLL>3HyL|)C1O76LG1DfTynZZk zOO(Lf`xnI~wvrIr1`cu8nj^j|UmcStO;HidsJ>!OD>u^ToD?M@6d)pQsM40;jtR2C z#a82y#1X8*^rf*M)+dwD=LJPg<%yFfl~9@FoIN~T8-R57%s_C}OlQ@BrI1WXT$2@)9u6K2k7<#DU zq3>F;ULjAK;=O1P2VgYrZjStKc8$|?de_IhQRgH$Qnp&b$U zo$EgNIA+@HWD^dmH)P$OY0@x5hy3V|RY>D$sFV}V3e%ZS^b5-8+3#>6t4oPShYR-$Ot4YA|FcwQ7L+amn|B^1d4&NNA zr50(m76WS0nTxH{boR6QIVwS96n1!%pGImvmke1&q$@gq-p#%LDjc#_N&b~uHjyzw zBJdh4;I_Y=0!f#l)0m4VK3#q^uEvkOn}^UVj(SpIChv8=`hT&g9q9PeATwMr7-KK^ zi=abkXpf&^ZB0}yi8w+t#)*To#i4Y_>w3)0V)zGiGFn)#eInXFyHd7pzF=>{HfHLf z;)B~B(&zV#eJILoFia(VUs5o9Tj6Yz*l1D3s-=Z9ZBL|fw8hv|_iA&4#R9jpNE19P zz?2Fipxr?nt*}Ai(=Xk({6L%4G_cPTIcR;AM%95^pNjPx4pj)s2T*D38N53U#mlZ{ znNCxruF91YC^Rq#m-*Rn(0*9l1p2(3vK|*(TW5A;$)FCJjI2b@v@4m87bMFt@AzAm zQ|c{XAltDe5{fCzV5Qrv|L;v}wAX?h8|1 z;GtlXDEY2Q8=t)}!=;NzYPp@`haeIG0V)-ShPPHRmy53LpOXwA->egnlKRygqM!uD zlclk9KsFIrF1C&H3-z33hYM*3Shs@OqKv8;Ep!VfJs014XH+7JTsZY0%!_8e4TA}= zbHl~QPbH5K()6$(D;7MnU?(wAUq@Q?IkoQX!-ot@vCSTj`ez;KoT`#+7hMZ~WyWV? zNzGCa#)d#fw?^I6zD{U_@2be*e5E?ZH;NYW{;>)?oT{A9XtBg!WQGI8!xDr-Ddhi? zdjN=h@xvzW&}1iX8@hhYyS1eM{xzfoaR>SR*L6gO^2J` z)YfKA&r3%b+K}Wy>Hn-?r4Zfw$A*)qX$3N+k?==TeJc+pB92AU>+=YWI5=zxHMy%y zdaUzqgJ_6V8j7kk$L*QofMiIP*gN#J?$;EOTSN15{VEkWGnH?Ci%5}_!=d3nsTSz^ zU(+2@j1H=BdCR+g2{EHq*BB?S>aVZpfDiHzHHeem+SXV#R7NL1elkzAIM3qr#_wgzk+;P`RA-Sv1j zsBuhcX0Ao9$Hpm*`n%}ZiKAlDCy9pg(n7!bF$E?z2N5@#M@a9yPR=hcTH9@m5S zMw%%y`AZ+!pVVW_2!v#Lpfq5$wU_7p9-VNib1w$UDdKjFHR3q~Y<&$K(uX3q+WB<0 z!{ZBH^)f>aytf?KY7Y-R2RQM|J5?nE?q{8SGY&N6qNGWftInRT0hB}w?WKR#ec?mn zh65;J7C`ZeXHfG_)a0IfJ<68Hh9|W?Fyt`AZVO#DCKS|~3(|+djx_7^{LKV3h+wa_g|fMh0I2;h8ry6 zt3FsPn^rANd9OWQI5pE`Omeu|R{SJCyl*yoYHE+wlY!@wCirt8WA?`&w`4*+kBAWq zJEEz$IW{xPtbvZ{+}2e#CR;6y>E$Xhvog2M3^tdNH;bdy7{b}Uy_==q`KEB)Y&QPQ zXq~^8g#0XXPl^JnljDM}0t4Yt$5=+tG=M1+`zAWliqhXI=u4Gyb!J|2aK6r0kr?=J=kE?4H{b5Oo5%_WEa5A$-W8% z0BHeqG#ng!KzbgYJq89Ec3#eHCJ-Yal(xkB{@-p{bsnw_>A=3Y2I}S5VS9)k-(`u( z`qB<(1Og0j{Hd?JeCRZ1&{$s8>_rFjEusaFd4s3*fb7X>Ua)_{9~4zcp|A4S;+8)(S0A?VV$ zYvL2I9@24&wkfHg>T(eR>P)DG@8hW~{*I^|I ztoy62PcG8gsbRWLQb=Ys|1FHAF(qHiXiEDibsOb5Oaj;OfD{ejaY97zngA97*pILP zj=rpWY2r&Ch1Gnyc&$YybQuJ@=2B5;mH9K+?^q8pnl;eCCwCv8j)x{~+jEVG)Nlj@ z593_6R|1Kyu%iD$$~x>DS0lsJ8y8_Hyn2I(LNN$-G)I0w_}WQTyXJhOYc^&g9WX?e z^t#vLbKY$Dp;%0z;tLyCIHWNUTie~O2fsCJ_4x(OIj88`l1OyXCzxAchPhQ8Hz$uW4Sh*2h12>kS%k z>p84XNo^BD`)v}%l;Nh+>2}bn18VWZP~YL8lM1PosSpgIw>7Jf424%ca%LwvNGc3~ zP4wanK0X>`kX#B;()D38$r3cnCQ2RS#IqeU2C6=`IuNSqwTM@Rohw`7f;zzm=fWI9 z7l&2V`P&!ET|R;+1k$L}I!q~(p1Ip2&GIN#{abeUmw{@ftKf?sE@ArprB!A-o2jZY z*-4&<3cIW|$B=ziK_O}SFG<1FJvipI?hR{kN_L86c%!JYToguTEyL!Iz?@ z?h~pN{M7!zTFGz_^yYFv8N~zxT#sUz9G1ag%(pEB+MNe%2mhR#I?CQk`cmolVeV(a zziTLn5*0C$!^xj|4{RSQ8zegqd}E(-&lA^;O@(byCvT6r3ZTAjyas&uJPC}4UZInY z`j$yv9hADs8#&JkhP#8M&J-RPbvJ~Z(CvLAwETz47Q=S0^3UiPLxt1=J({D@SAwWX zn&J&awn{}_EGxNO^wpS`QJgdf&bfV2S!e}1?=4$XBEtXjGl`|0SH+CK|6&brwr{i+ z3m#Qf6Yk8{=40q=cZDSd;K=0j&`XFBvujXTW*IQWIpFRd27eUophV_T86K_LKjlKtHMWzY<%`Mp5ZFVU}ry&?d_Eq#S~)^^YI4j zU~crwMaFWe(q^|{Yi*qBp5B3}gY^Q#G+=r%h}e*)%vBk!ms;`1;;=coI4X>YZ(-Ne zu$skt+Tyk0YZ$fE0l%3}{vxURff@TloR!kaVa$w}a^^pb+{)t}YJyAtQ$ibG>dO|$ zKg0~`imOVSsF1)#fdt^$)uD1Tn02jR=BIyGV>4FJ}N^0Ssr6Y5h(BSwF*5m1?Ay&2Q!2V)s3Ab?T zJ`BAt?RI|F>s2g6L1F@ZFSJ0HTzMm&HlWKOC>k^{(&aj9SLIEtVo+MV`$zjTLtoYj zRvym-F9ertH3%>wi3f*v)J)tEkiHLMIovF1P9yMoHa_0_IoG81I+J+W`}X#RD51nm zT3Er&JTaXe0Q%RLnb^Sp4}AxXi7ZM&b7xjs(%pF*!K37NzO~N`udniR{s`*s z#T!l7z7o=bJp^{1c$KqTvU}DFVIZ=W6&LQYo5u!Ko_!Q<{NVj}0udI^2q=Rp*74)! z51K`JU;HtfC1K&_g#zrD!7`JpH|H;*lm{HqE;VK~+8h(!3(ObCYyY`s2MNsIwcRFd ztX4D1YCBK5d^D|3*)3Nyl4U*Zwv<>_=| zKyt%k(hqxt1jYgg_(q7#s+>IMm_Y-ZM{iXlRuwXz?kP$+;MMohvP zFygn#M@I|1CQi;?7FBvlsjV^vZzHx?{qUg~v><7vgHOi)EtvY|f=B##$uVacDjXPE zo#T2#imWPiI5fsm+`whu_c`;T3th*uCvWW}T6fXjOHQ=1VzrLE znq6l0Z{_mW8X(~P`spObqwLTR>K#Nd+VFajNhthZcx0jN<)yt}eJfSOw|6TNzxyPX zcWP1qc#_4*F3^$QYZuVXBN=7MWZo3pr)d0 z0c6#}_apC8pD`?2#nQ*r_+j^8)mYYA)2I4`#|BjIhWHmG7jW6~tl#5~-I33`KN*wJ zEF5jK7OkH(7Hj0F4P{hgCFam(ZCrOV{=`!h6TsDeGX-`aLg6SrAj0wJrXb*^Fuw>3Sujlb-wG>UoN9vFKkcLwztR;E^AKh zHa3R9xCosh-(cNCU|P(v)L`%wb*lZxW3ZKXuFXf``Sj}*RDE-uQM5TytLcQ^5Zc9Z zz50At+X)oM;RS~+=pPS{nm^^h6LRvwW8$JUH`=|DU#e_QBi}|UOjGRsx*sF=OVgIT zH)3=8erMeZ^qDr|mt&ZhM+;BaS!KcdJbhi|PP?yNze2~Obz0I?KiVPvl^>3--o@_U zr@DN^roR;Nu*(B+V>vX`v8~;yRZRJ|_l!~%Xh|Sd`|n*1mxw(f6aN4MioC*Im?ac9 zUQd*PMk_s821KG`R57nf=(Q+l@4$oYK4s!im0{EK(6T3w4?1|buW0GfguQxrR7&cE z{ZGGAteF~=E$@X=hw__3rautOS3Wh~Ko52PRXrpQjh#6PZFX0$`b_(C{RcXrmEGO( zZt;>bQLXFdcZu3Hz=H0q95|-w9$M^F>Kom8jr~8O&N8a4Hrm#~-Q5b5;O{+3GvBo~6(Hl%;8#K(Yg!eh^YtKA?RdXw8Qo}`lY?1l@Q5~b3L}1O4Nc6kF9jTouZUyj3X52! z5m(wv_{~r~Ll*ak2F5rxWn^;-`_Ab0&DzAvGHa$*gM2JNY*#m;>*p$G-j;FXZ%Uft z|6GV8%X*+ZaFd{EXw{Ns7w27S_A%RS|M8^gBDyE5q^vwT>hk#FThy*M47%tcZXd3sC@hBTE8*` zdRb+!xA?msBHEG5NYh)}I|x(waBMK9hbOPzZN4%bTMO4Q>v1(n_Fo``{{)BLzqjz%9}aIS?Y}JU9pPZ;^-yzYBW&%Z=GSqXz;KK(B@58j+K%dd1i{}sK&N*uplfQ|L&?ZdsG%ff%aOqNk=6DezACe&8S~LPt_gF#tQcbu-JGh5 z5j?by1(y(%QnIqMdpI7;7H#u#p6OT-q10XOh{e9LH1Qtxuu_JHi@^f+`gz0vd*Q$P zPm>b9ih8SP=c22kVRdzbJWk+9{(g;e_5A&i1A0Ky3?GB^A@&G$9PY0*w6dfd&YtFt zwgZkXO`zgLGamZ}#c*?X>tVNR{8c+CToTd|t|ufOH67CQa$1;xpyY`|1Iq6Uq4sjf zWr9Zz^YVrA*G6`pT$2Yg9&85fZXOWMNj8JSTvj_59$cS6SoEKA((~ATEsO}nFi)@; zpTsD`BOd*o#b%==eMKo;Y>04h+L1Tn;6r6m)uRhOiQWlMK0MjDo`{8c;MZzBzw|dr z9S~6VTGNLniO?OTm~|M8f0~%m#5yuo!wjdZWG$g$+0IUcFVzTLG!}P?$Isw1{kS+y zU9NqYp{T)BOB9FQWK8cM>EfQVOjqR9r`U{Kc|jIAX0)-Aq;JT6c(iRbzai)TV=aHu znEs@+Pa>y;{{f=aaULk$LFH((DorEIYYmBDP9@52ur?iGln{O{{2`4f&dtCWsZzuX zeN{kKpU40B4}eZ%-J7y6IE2^TbbVnwBM=V^eY%;-= z#w_jjWOKP{`=we`SRPOr*jcL7RqPYRX-=kf-Hm>Lp;N7mx=y3Z(eY=@D3Q=HmUAO4 zk@J9u@ouH*X+qzpGvY9`lK;aZrb@Kb znEu5rOu~1(WF_FcQS?~P&2$v{=~z4JvG@rMlPWDLKPfzSz_!*7<(J_^QPM)x0+;1JesN}RQwqzxVV zL9`1i;2aFvMX3}{m|^5FkWRi3CCf(=f>g+DUNO-#LgkNBdM+*w zj;;Owfn;**($X=r^X^XkVWgv_19E)g+8CW&TpT7>AVk*Aj^$|WF@6ddgpsu0d=p9NTH>;ksf7fhvtMaB}IfGEPQ;JYr~iDh5sa?7%KF7J(SubRUD7oT{M@ z21lwNe?v>IDnj@`Q@vPUNuS8!yB%y^rs6tK+=RfPKFcIKO@_4;39m*kC#Bar#@mLM zD&r2f?;g;GJ+APQl4g|c@wHD{TwtE*?(}a?-rC#gzpe~1?0t>8Dhk?Vw|kuFD3aUX zW4c7tQQA>7;1O?OT!R8{%86rt2xqDRK5bvCP!2N0Sfm;IX(xdL&A-VS1*I}5Us+Nb zHg=SZ8l9AZ5-+87+P;h1!ccQ?4rW zj&hd=ZQG)bW2|)%fsQA)hr(AXI)fqm&n|CLI-@Ek4MaCO$h%LI8dAK)?!L{WZG6QnDw@EPRESb15Lz~H$94~do0)6NlTFH zC|tc&d3m^1L$#oK`p(EixQwB}&etWo2VIa==!xb}YklF-7R((#Gh$2@`v`%GAUW6i zG&=XB;#WyiL|pcd{C)%4H>7+|=~-&4p@m$s+PjE@GA!+UTo{IBi;td`(HrgL|M0({ zNV3-pMl(&-MeA=`yRxCH{GlBqj5FF0Xz|&x9b?xXGs#_rkMFh}1d~XXD{_H8*QcWs z*Bj&VfV3piSwxVWh=Mf4kT?#Kwidc~J*zg-3VU{l_A=U6>Jkk4KEv^VU|UPee%S}b98Vm)nh)UI8&iY{Rsx4mPzoVR;j;CTL^SB9vs@<%A9k8wR9ftvRI z#L6j=MdM6i{hqFwtY&o1x>#QPU#*2K1|8)FGk2GQT{N_ngH?8RKIo4~yAX+P9v)x! z39;8hUTyMzW{u3eOqSYF$C=}(qNV%UVai!y+^LrjqXqzB9~1qrmb`ZmjK|lICC{^? zSV{AR+J`-ITjjj?W8*o_nN%sk>;3n*Lx-dMJkj&Sv`_WlmnD)x=I3%#Q=ZAolgkRp z+D&dt*x;Y_911O5j}$Kh11WjKZfhe&s)vGt@yvaiDHe_{yYK(}Iv&o=Y_-aYs$IkI zKaMt4Q&F$oZ%5pTYUpC;Qm#)4h@ifekx)2pV58>kft@Q==^k^yj0q;^K4L_$)W7XI z9~*5js10+dOqtA#BCCvs-w5foqD3x}^#dG}VR#XPNn2-RFeT`}kRf2F06e^D3ww9q zg6=sh0H~1^>R$rI=;w(JM41g^r+oAoKd{+KM&{c_(QB(W=wu>H(V6as(@W0Qy7)OREdQsZHWC6 zSidB`h}?VrHYr7WALM?{u3;>l3=TPjO=)81Y)njpsjDDj(uJ7G68wP9M=Z?+8M{zU zdg?ARDM1F)TWiB_Q`*(BMLv}6Q)@luw)tsaZ}+H z!TQN1C<(1=8fYsY*+N(r(lYY&3&pZ$Wlrgon6t6mYws_VNlFzZ9dojXo(&$D zs#zOIq*H^R<2B&AL9{TOy|4hk2ruI^dD{5#MF&la4ZEX05f=pX;4#?AiaYFta+?AuphV3E=mMZKVQE%Y|EY2j-eJuEpjl;;yn)+f2# z%)Ma(o2pPKd5bJhPIWUFvHqK@7A+NxES5<$_nhQ{D4)F~9uTd}@= z@y}u{6I%$>=*}A49tTOeO-~BxYwe}eyz}|dGA5!!H7(!%Y+Bm8Ng0NPmG?Ws)5+8% z2EyWUTh*)~B4YkOv+MOt$F<@P^J3%D3GS5Svc75`K<0xN11al}3F7a?TqWr|u_hAP zCMjxvKwU2_O>@P0pbVK3T#5#_KR&i8C%J)W&^`m?*b#peEUK(p+%amIMot}=mu}ey z$s6XMhXtew#4e&0Hg|fBbMg`Cs*&&S)5miejmoNH?lraol#>xela;pq_=mbF%`xjE z;}jT~{Pgz89!ulWVBZYo`oBybO6x_LRxU0s`HtJ;;k;(vZGWd9$_Fj8`M5``>Vn&= zanW&DET8-A`()?rs`y_$8uwXn-eWf_+v{rcEP$Ffi+Z^t8>dwWh`e~ws8M!phI!PT zpSv{Vr>kk+cGz34j;3pA__bbm0>EsYYhw$o=p2g|F25a*rkzkHWzkP&hR6d*i!(z` z;S~Q${KWr4_2GNaQJ6VBU_H@_apvrOvPE`MJe{Di7s1rPg>rO8{x_Tv$ zB(f?O-p4VKb$9jBy0-sako-d)JE(wM2t)`h`M9s1D29N2t)4CQ(PN=z#voB6ft60M zHjZS|$;7&W9g^mVw)#k9o_3{KxCQ!nBrrrisu#B!+ZE%Zp{=b<5)p>F+Zb=2Qtt+X zn;nx>#+Rhr`8Ql4V4a&7w_UwD$sNT>!>fvJ!Le05Vxt1@C>5?LbOy-x2m~RYAW@(| zc{Bs~vh)mK?EK4!0NR_nb>{%C?w`&JOj-%<1)2bA6><6l%d_{I6+~sV>MoK~g_eTEg|+L!s<%Z+3eGHq=d0cF$d<7xlz)7e-kjAvj+65P;|JO zlF31yXKVT{+o8**;#upKt%6@j0bP``)#s=8>ChQr$db81V)v zGYA&SET}UBDcjyOXQ(dvNt*2Q{Xw)P6s&B_Q!sZl8^_Sr+IS4 zHQ)GNk=9<#=Bjb!9DJTPBBA7%B9YTcT@ukmt+E*?Mt*bc#g_xQ@GtfEIU}1?sRvp#t2Ix-WTOlw z_V2);N_HwTz>!lKLjMpsSmskE0WO(Geg|=$%uoJK>JmF&1fK)xy&<)J>_Thv$wLV- zHRtrpnuyO6tSn}HVm$a9QjAPF>P7UtFIJT&s)qZknndGPTs7!{A)=;0AiHB-;;y<=0SL&BlqQ}NPmKq_!0nY0K@=&@2Y1zy4o4L;PxC`1j=|IRp`Ji?(A3IC@ z3Wb)TnC)@AJ~{^R?$&-!ynOG+_hzED)CR5+@-G72uQIo=(WpmDk|H5jeeo-1AUu)WqI+J3{eLsj4eTsc{y$mu;tg(J<`Rwh&Ge2|CFa1|WCRG20t+eH3j{y)&V0$lhzg8hi($ZR5Ziua~NXPy9%=bZ1?&jofk+v%} zKW@Hy1L8)%cgX317}K$@oo2)B(Oa{IgTF7%YR3K2Uj0`0GVpwPwN0Es(aM z*`300Z7A63dzMt|UmYj;w8KB0OJ+R?;*xnLRG`+L-}}O3^O0ZLTfRsIO0#lak}>`z z8H13LWVjbHb&A(cGs0m%R<=n0`e)xiWQX7KmxNzC8C$X&-Oi)Ds<1_o!g8x!eXXE= zO|Xjbq8)zj^HdkiTeN#@$V`C@?AlxzbYqSfbd(&#TKr?yitE{t=u)*@i%g+m-|sT6 z@=+G=Xg|_U7o4AGWleJAWkfb-IN&h|?Xp#C%u>2SrLyl~t z(r7&O=ewC&mb^4ahS?AMHM)B?9u({>LiYeMi{%pyEeQ5uHql7KMf^4`07XovELY41 z#8UfcFT#tA^k@3GJv%SlP@mo<&0J-axA~gN{ln9CTe1ltMF6c5rLXD62!-nkP&9Ss zoXPe7Wsu(T|C2$KpfX6WZdEDUx&Y_JJ{=QO@ZjX&V1RNx8R!}Lcy^cO1|}A^pv9@Y zTq{5zJv}Wg9iQOdJcN-VF%9_#ybJr!K*8v z$^=VL@Vczvo^0K@r8q%PXmfBvo|tPC zNTFbq-MJ>d$hYrA=VrN&ej}YJRQ+L&#G`yDa%j!PyWxvB?IvxZ*t+FqRK6?cCzD*` z8ZQoE!ma)Jk&`hh5_4QJ{gc$Csbz9<-en&t;L|8PnnFVmFejc9bwO6FEl^N2bJk6v z3!fspfUuS@hfPvgiz&&XCmuu~aW<(?PrfEd3*XzQ{TU|E5+C_9HXcAU5CAap1t)ya z3qxg$J41O6Rg;oX@V>FLoW2)XFM4CrEbs{B=JR&{6`|Vg|7W}Pb6@S%jcJa(ZR4Pz zn$n8%WOY4r)gfI6o&7+2+_{D??&9P~R7RiBJwc?JaFlunN6^XH>Nl?xCLF0VJvefDWIVbzeOI<(;66)M71eiS zW~Lw#LW_qH1wO-W15*Lm*l0mJH=9~)u08}Q-G-TBUBaZBX+8>TOhSy`6zNvQEd7rT z&hr+|6m#AD6g!DdMdp`_=#HXCi$N1~n;Bx!_lZ44&Z$=}cLJaG&L%i-WS+|KcRttt zZXOuoO8Olo5hosoUmf*B#a}#OR2EV97S1r7c6<;w1rj3 za%UNI(1Yea>pPolD9N@=rPnzj;!1%tZ_81Tx6Ih_7k`G&uf|iw?PiQS>uuOx=`AZH z{83hncEW@7`wg z#as_!nkj!bT>5s$w~kf^b8LQdEhAkqM>iRU4}Cj%sW`QL++!lEA)6oMSm}%oXci0j z!~;T>Zv@Kt|MXTeoBN)4bnNXt=sxB~wK;iPHJh~!UTd3p^RwgeF~Sf-W3^}_R|lW= zwq}1rUB6EepIZig_;IJ6zv?6}37IlpvkJUDjf`I}RY1Tchl=kb`%&V4^T${^cdct{ zzHSycd}gz9hlO31ul)MCjRMjO88W7`3uF(9;IWy8y`COHBpb zq{trvq)xm*_aCO}9Waj*%UkKq>->$*G5jjqlwgoPsSqa?qd2;H`BzikDyH*#yW6I^ zV3YanEkDhjt$W>-d(9q`sA533QeM(26(=14={ZV0+=YT&Eut)1GBSU;#gfAE6g;gy z#SJsm0eDPkD2jYE8Fc{Z%dFWp${$@0&$im_a_J7HCimUcQ2>`%LbtFrP-B0Mp4BJKb+q3DJs@BC}okAUjBmU<=g9B1z`qS5=+$yW8rN@0n*f zjMn&~t7Z4vwB0%k9x#B`gl=Dw3JVLwQuwYudT}J|)4WmL|2V25?2+)X@!1U9VHI5t z1WK(>X%rjaj(fCB6?hfk74I)?ga;AK5vj-NsQKahe44!J*WIIj~qk zA4t#F`Z|UY{e#ul;xzqL$NE`qHf?8|?PL8vu03v?Qw`J}n~T97(4B?~!nI6p37&`f zlbdXk6`$?$S9jt!?AUQqY!Tx$RX8NcQgnc*0vH#r9j;hH?`Z)55DH%U zxDWhDw>>a0-hY6#ep<1Yx6SY2eS$|nP%`IXjHmF>#z`5!ofDtC!Y8V%%-1MV47&bg z>+?(DkWq>>@whMC>Dn^vTMTd1yUJiSL`$ye*(Nlj9Yv7HdYMr%0T=1BY2tfY@%m%R z;CaR15f8n`vzhf)zwT)h^gMV!{(~F+uz4Jy>%p+Mibjsu;Q$no}!|MYyCpXeof7=*W38A=f|Bv=d3ZNS`EjfsTvhJ5BlR2#96&JwoL&z5>*H{xsk@vD1 z*o^D19mw+@7W3oc4?l&_HVC{vB2b$bp4V{ml7c4`Ydq)ARrHYM5SXi+Ors?GEl7i> zx{n&Zw9xsZ*$_dwpjr7rv;@VV6>%eHeN%35mpuo*1&;)uqS6{U4he=}?nV9)o(pGA z+ov<0Rqjs1OZ&~GYYVk}u}P!coL)Vk5kK{xN0@w6Uf7UCVK{_Nm9lWa0+Dv`bUkkZ;}=01%Xf-v$#~xk z({---b=T5dEQ{eE?$Z~UU%tS#30n_`>a1#$TSz8rb!)T>{b%oESzPKH1rAK z$#u=nHNsR^v4C0hV#EdHm3z5c6Y(G*+F-yf4BbD`0&F$d&0uOk&1E+wb9Bn}A9IQRKo@4SwvRAktJ)T#+nF%lUm7W;5K!M$ZG~vMNT_ zs6SnF0=3?KI`Pb!r%&_~B^{|t)H1UiZICA31`@3>bKrp3g&XH<{}x|Si0R$MJoZX- zV`mZ%EhLmCe7yB~VXy{{qTwq#`gfYmFF}~ZSa35CGXye#q5@3cF$#=`zGIpPyLsCP{jhrnhKoR_A%}(CB1TAbDWCqR-w}B>+xlV7(!}57 z!UJ>eGpHD^P3r?IaJg!uNvv4LUF?b#XLQMfgTO0LlVCaQKb!*I8b2=s#m&z^guCn^ zhc5vVcd+W<+^6Ou+AW6!Oxm?v<`TRF6`%G!2pQP-A@OyeOl^`}lS#0LCVYz86ytrc z?GMQwY zdTPUxw#6fPc;2wH__#iILgb~)d^+}O;+o#HkoNF=3StGz`m)QHBH8j=yMRIvv5Fd$ zgg;nb8My#&wl-3bl8&=OXUokBT@Da67B+uNsf!#F7^UhsR`~7HiFt3FH-08gMl(Lx z^4i(`@Qsyj5=+GBHDK@s;$9&O|75`7P)DUW9pn{wHFmC8nm*06uY7ofa#@b6& zOeJi1Yc2gEQ|t)qvSJVi2!z5;ndCEQ3D%ys=`Ym2{qV6z8dNlr(zD{Vr(ttaRv%Tq zv&t7Fg*Q`{yRyNJtG)N7u7o7kiMOyPJZyjTK0iDdlIbj0f0@I91w-GGz?k#%l0;jK zX|r-)cyEO#-DUbLVgiBMi0x-ti|euwPjXa!aD0S~HF5p%9YY0w^}K;ws7RU|MHU@4 z5gE|4)`->8X0#~?76@`P8BLD;Mfv@6Ue_@&dQ%{e8Wk7TGQ59Bz)6;7%F}nXQaPIw zl#IS7(D~~2u-fO@r3$02z}I>h#khYU+BM9Aua&L%+Wo*~@{>Mi0hPA$@-j8=hVS8C z=p*<7Z522G2U>F;QyesTtoH+~2@WR0d3`4T{p`mzwBrN^-+TA!<9Qu6fRC0WB70ypV-*|vi_2R{$p9ypS!hZxw`ugyOC^S61jBgpn-n-X%(M-g5dqf{ zX9SGwdNy`u_OoU@nQxYb%dwd#P;!ds$52NY6c;9<@XseuOSnp0JB?QZt;FflnX~1b ztekI-`)$*Zt9jlCj-utyeCgRogw%UjQBCYAb>CkPk$v^1J*>lo51Cd#<)F{lv2;OcyAAub01?9pG_Cpes4N^ z&w;4N)~$owyXB#`PnV)im}CZaTudU?#J~XXNjM(LDob209SiG6V^5Zu$Gry)IoN@I zB}H;z8!t^rA#PPT`%BF*JwbY*_^)y9tZ|v=I9SHtlyJ zz2)*ycNt{C>A;Mk_%9TkTQY!N)cF2j+iMuQuWC9dn;TiZnb9o#D_y9NrzW~Gagy|g05-hDBf~Lx`6vLUsZqyQW7}V$=@h;wdxAr-W zuGj3g%}WyRsup!U_lI|i>(3@OPlJ;RtXmRRtJ$Ynl8^cu!M@RzcRGsY5;qu9Usdr~ zX20?%VJw7>;oFwEOA!8M8ck$QMnJ!_mo<*@BVaFwzge5e3%G6hdbbUX9}~7;#fv{xJ2(PJgHD zaq76`#D>1uWPjb;+)xOe7^!2Aj_K>f#G+$^)in#~z;C^tM4&YRP7lM|zNUJGn-Dxw z7;*(g@$tFeby!rD-D1H*uUd$8%qY57qot2t-VL6519J^1G7-O^6iC1qUWB5Jah+

    FB1+J$-a!`AD`eeQ`9VOQnkuG3RppWeH@;M8f~CXs?73(@nW16SG%hcJqK$p(*D2ZhO3w4mDiV^;jRM zWk+ATU=AU581qAd`e3U7V7#1N$6Y(ofqe7eNbr%W?F#krmCH&sE0{B@L@B^qImP^U zT1QlE@!8^%;^ZX~k3wh=7+32Cj(854{UgF&Lx+d#{PfZQ)w`w;e=SMdT!LK%hIz7)fK0AkJ*n+e`bkWvm%%q7c#^$SMN90rGv9C|OCSUs`r5 zT$dAx(59_-N!`ADy63@Yh_o_4MERRUR-`(GbAryu-B`@cHPKmf3+rDH&W8soM%vEd zVC!E*Y%+5WhD7wsh4>#6xBy3C$_;QNuz$9^ViTXF@m)hnOLF*_j z!t{Q}W;19`?|t1^I5GREq9tq-jD=bhjII!2w_97ooDTU*_dP8MPdmogmp#wJc?eA! z)Jz?+KrZf(I_TrAS?i3J(df~eIeyo=g%3s|bTsf~+}ZqU#Du}9z@w|71+TVQeykQ} z@~>)HaC+c+Fn8T3=Zgd+mJtN!I^~@BIR}Xr0ZwKu+PM{ROCF3HoQU7%N;$yd`Ls+AFQW3vZ&hF;@^q#olO7Q{3R9wEXP}S8);NMsHt(5FiGj-h-)6h6K z)EP19=|rZzwDJ2?HWB{$)uhu%zwX-c^(xIGLH8|3mW}5FftfrE(TsaZ-_xI&Z{fJ< zy*g^}Q1gCr(8MPy{&256RXXgi4&Q@LJD!=wX9o%evrUKoDl!8vlC*&pR=-l}Mkz5- zeJ_^XAC>rh_Ku(tzgtcAI<3BYh|}K&a=s5u6b4h)aoO{SN@pIsj}F}jB`It5BHelSiRQlEhE6QfB5X@c)?^xCvZ)o+-h~H%x875w)h>6sjNby_CFfc zlg;sOlEYUijDP%esI^&lprm_wj4r^DsbtNH9gb{9_JYi$y^GnssC$&)#`@F^eWUw| z0JxKWe!(W(V)mj!5EMAvN0poXjjNTCpU9pIZFI<8 zM^fVwL6&wn>d<0MllO|^VhDvij~f8pKST96*w*cg0vA9^cDVT^NA6p0WcE_M#)mJt zMr0(MNmAGVeQ^I!*=YAa7<^1VaBp&@Qo7eG@OVGuN0E|28S5n54;ss((vEp|^ZS6< z*r)fv1uiLt`(M__l=a7Gagsgp(IJMtipjOm)s>j+o)zs2AL(+k`|0!UVL(sU@<9*G z6G<^H-V990U!ej;2~=__K)`l?`@P}$ziWESu3HZFr&V0*O(Gb{FQ`m%GH-#ynW^pD z-9xHd3vc)>LoAQOXWEW2GM)5=&+9(Kz)QkCxz4-qWBR6fa0+98lY#sRbaFq-@q&R< zZ2Y_ACaH`))&B0RE^Il-C|MF$2QEJdnvf36Gy?#smi2XId!qYAm;6s>o>84 z{B6p6X;XK;($mA6vZt_tov|n<`uIm{JI?G|x(>1%w%GF&Zr_?88)W}~l=^-IR$VSZVv#w*YhTAdOr5b1%Fpr?J`a%C;oRabfe+pIh)8U|@ zaYM4y15u0o(v$m}-*`Y!hJI}fsbOqg^HdNOTx!;j&`k(QKaW3D;9P;AMd}WKJNpdBj?V;w&m_zI zEePT9;$cF0d{<-HO9uJzv*y5bN*MERSkCj(Tj!0oBjB7~ton<~gij-gGCF z&npO&t_Wejf2jBxvQ|vXQlOuw0%%&L`uf6@!53nd^V{AdPfv^Pw1GOf$Ud5ci^}PA zTIih24$F6nC6BD%Zhy#t*QV?yc|7%gY2L&(oM>~bm}|EwrsfOZ`VFt;-=ozf%q5q< zS-&$jNiuBOQYCIi=_GrTRsbhTZ{(p0h`-OUQS{;Xq6a_2zI;zZcvEJELyy3kLFhd? za@Js%{plYE?HgBV+j2lNGpnyh$oo<3m+UmW^L9I?H~)N`(0-Xx#j3V|b;s&!6}@;i zX16tGOKGw)0=59B+hY-!ZFB1Wz$UZbn$HYrtNJTPpuFG+q)sWhs9oc6vMFBF)D~SY z|3SC_`>m*ZOqNqFe*OL>S$nX-4(Vr0QDnu0(ORdVZ&SU1?{W9L%=VHmXSYXK!Wk+} zReX+6qpp2kpjS=42t&)lPbAB9MUhk68V1+yNxIW*E`f}HxyWA;1khk+NE2bmSrl+N z^MRNnIq}9|q%qy(mW&}xdV?H-sN%sh{nyd^9>J*J=y;zLaPXAXkiWhU?uk;2eqWQU z?Ff|ZiJ&kB4Zhh_m7PospDF4ZL&dAzcqaKyZ>+n>_>INGBZqeNmyMLXFVlQFRt97i zOUf@*h|rUXMFm$jy-XBSEGVj7rY}2Am~N6#Q;x1Ev=(tQ7LqbTT95}RGgqd*bWxhaGv zSo$XvZT%CTsr&%RCo`Gv?d>JR63QM>8kB{Bi=k{P&Y+vcDCj zfV2Ow6RX(Hxrie(46b;PL|6mHIbK>AJ1_^$%akZY>77QJvGi@L;uCN=j3_SV^5CFA z(aqN&ksr@L3b~=jse=Zy1uy2z{AfCq@ktdV&h=s=H+5w z=V1FiyTzlB$_3pIict1`{c{fbd*L+v0*jLkWug_G=6IwC6-536lfSQpm8Y`^xc`?} z$~_vTbEc1v*2HwvOmt-zIV~(f0FCwy1i&vZjB~P26UaM3SyDsu-#9ya4j2%6E45ieTj4TX?yP2QQ1SR7{3F+nRTox>#3NkvQ+hRcxOboq;dgB4|MybROcjZ4lgg1S(`9`U>xh;$U9 z00eb;3%qOR+{*Q94w&d?o7cVt2D!Z;2%_sN0509&O|+QjHag?ljt)%~ zRO60QFjU~uvw-VZF}6MLZET*tSpRL({ijN!kY2jFtIXsz;DviidR!3`Jj&f`tDEX%6%IkhhTKJpdFfLu~=XY%fs zHSO{Kso+7VgPh5=F6*xsRzwc zLHi%=lN*;`RHGgglla(%X4f+Uu(0m%+nD0C=P4sQs#6ruUpdwyN@73Y#D0)PHEGb3 z&||BE#vVUh27?{{2g@G1@AhefB;XT>_?smt#PnT<&{Q&!*12X+m(=IH+C&HPwL&)V znKZ>;Q)M0%`mpQ;tKnY1I)1Vt;KE<5Bx&Y}iQ$jZCFgl*9F1ZgGrDZUg;uD$%*c~9|sm2n|=W5(OZBo9xxzHq{Zw#P@R+j$W0fNDmCMsp5MNa zklbmK2<=RtG#cN1DiG@@z=e_0FbPtCE{L%JEXUkIUu*nvGID8SbkVEqVHsbTp5jRt zOZZA3_hDgp6wF+pJfn;AJA*%|+SYUFI#|utuB3PL8ngCm|Jd4=X(h5tj^im(=9@rt zpdo50K5TsyMP-#BE0m~pGv-@O%lG-B^lR#7S5l=0vT)#DybZdmz89I6mgX?+s8Y5~ zqPgUgV12_+94Q5>iAMMh2Op7&rPU&&0+GWC$rdLKen!K~TZc=b?RO*_-D?PyX}E`* zXJhr&4Q=%RG!8SeIxmIjeJ4*yu{u-Gz5Ul56orQ{dGKgXlpg*{U@10+A}b6~l!ZVJ zM@k^~ylbemvEWkr$K#Ov%Nyltb&W#p?fnyv%Cq}PkEi+xHrJ_xM}c+^=nWs_(*)nz zBPp%ZMEs-i@uD!m&2Q9Ven8OEL(O_V`88WdjHVwKWIJALFsM^WcugQgq5+ETheH(i zO8OEu5VZ9jW_dcp@#ZZrUzn8n0n7iy?+1gc4?YYubd;J}#B5=9p8(de9bIPGzR7>2 z?>X@|grv@N6v@amhs0VTM(_WqHy-h^T;I?9!&my8Jl&|Rx}AA2&yt>T%BuJA>X%LJ zJQ3?n!<@_!{sJuSdii5$n-(51#(rUvo72*Wk05||ASo-ncUPibENe6QZwI&Os!5+z z?iEu(ce~D|qFv+L*jUZtT*Z*keDl1Z^RA%=n{$BbNKm#YZ+Ny^0p9x-(@xbVDym+% zNYddoz|td-c<>5A1_o;8hl^H4YJwFNdo?k<_{mJvY`0ymh;Qq%Bi=kAK89QwJa(}9 zE_>Ln&}LW(nW)V;Tm*pvNO3$3i9A0!`lw8u%zoQU0^%{z6a9SLR1-2fJj)%Pa(&(+ zI!~-fN>q>H*+oz4+P%vKy4x@o#j}QL-DnDf_6!C*vw30P)d)hxfLBQ8{M=v` zi_+p3SiC`{I^1=C?5i)`plBb-pX`mX9Fs2(ln zGm{0*@6bxGLnKYchurwC-Lac{dbWVb>fo-)@+jZVJW<*ZxBj^zf?|<_Vp-HEKE=6( z6vu)N$H2v&h`T`r*OtvR258irxQaT9^Di8FQr$D#=b_N_`p_!`c2Xqwb+gN%$&<0F z&1n*$_ol*eD?X7|hgY)@F-j=~rFw?)xN~zwT$a>Z4RKHY4q)`|Y_7czqSCdY?Yh=a{`UmLj@i?dkH=FPz{_ObxyEt(wUxjS>4Q zhG4``3RD$`QKh#s-cR``S=l9~8Px`zV+v_YsBh|gvKN_6T(O43x+n~aD&!%I@&n#p zLhf;9BLmq2_YIY~n;+t3)O6FFYF4z;2RQ``p${bDBA|6p@7r>M-s1h#+02MX&vmJF z{Py--74s9${I24hGYRR{?;qqCtzhQ>1us*A{noch}&-io3g0+$rvE z#VPKbd~?ps$)9B2$>dLF9@%^M+OA2lsMUn%NNSz#d#I7Y56=9-p*`2Oat;%sEW$Cf5 zxpA>}gu_DKB-;d~N^PFl5!n_i-K#s>lZF6FDu`F=n5Mh^-3_phO30K0n40KN2G2N9 zV)$PywuybMVt%E6gPyKKBZa4qB3E4g*Z?)u)lJ;V=vGV%m)2#lR~xv^sp~sde$@oC zD!OBE4;5?ThyB)=7BJucBd}z9vE)2;zdpT>knb5NwmG4ssu!a< z*`S({nxvr!d6*GA(v*V480Lt-ij(_v=cenAzjWVR?^}4>z1jGEz>e-~c>>0$LLNVo z8o0YGU&csJ8yEcfbU$%q;{Q428mjks-LV)YJ``YbCzt|-?g4a^7;%IZR-3m?;K%V* z*1Q(zl|ooof7XH3zH=sdWicREsQ=7>-sW1c#CnH+H^PAU!+SDyWpHzU?3aF2Jby-( zD^o*ikgG86G4fAMKVYs#Ll#k-lHtb7lCa9GysJ1&9ruJauHNOov-b9AbG7bN`bhC` zv&oVj`QdaY>)XCc%>~DbY*nngBMSk^$g8JO7YDq|DDBIVXSSO7GC*4kHOFl>+>zty@ZuE zwV`>oE{yJMoq9nT($P|6443#g=kH;8;C2sAIRpREa^ez#4LdPK*UZv}q`AVwWtx6= zGxRU*F;zAG2WJx;|G{t~tdOhLyUQI_l4a-bE;|fm2+{nB&s}w$K{O>pdZ$uJX0k(# zmSB0ip}3fFcq+(s?%Uig+%G%33GxPXkx^Rw3ib1vR*+eQ;4nkv)N3UZaxe^|9BRNZ zGP!;i9|fS!pT0g;{J_`PLv>t@P=p(TS5a0Kh0K$P7?hKitwbDISwNz$WS46m`s6F> ziMmgECi5>_K{Y7hq5sY5q7Ez_db`S;l!yY<@0^J)uoJ=Y+4mBmCq=q7;eVZR52OX< z6v?^de8+*h>2Sxj`ow3|^A@_wNG*o(qzz~*og-$OhjSTk*)EY8?KOG!mm32R@DO(w z{TQ={`dV8O{VAWPk%aCaQd{(u`DSx>SMHNHmfz#-ey@)@Rd#+fNswbo)^GDj0T&N` zHX>93^KblBOI3G;*?h8LsB5;3pRF5K?YmnIfoqI}lOGINN9d4t+JYQ9wBv=G5t$R` ziju_1vPDr>tF$)0)-|@zR=%g}&YuMsZIJ)~pm+YL%Km*0!x+1`f|X51^YuZpQ4KD) zPwXkh6d}0USNOrV@+ZwGub2Awq~~c`B1mdph7L^qYaiI@;msQ#p2wX5#>41&jvzJQ z9H?)Qyb*?veq0?RU<6WEF^?`USG1(nbecl;lLQN7B@fR%l2O(?r1-g`_x@%nC+Txp z+x6ju;1`w{!eQ07Cy|j;6mJ1vlV=l%545?z47qo;5hS|!r0>J!$6quwx_E{?6<#cO z(==aZ=07ac{Ur{%=Axo!;ZC$zk?UTA=wV%}D<#B_=?0wDOwi;nu9Y_og zuFWz+-s*`gj|799BXr~!c=4h9CZ^PYWPwG)UbuZC;fI{~Y@X9Xl7HySE4RSSMof`D z_VcFOPvy=X8F;>OJ>RQV>t^GG!01(N;{vmm;Rtj}=By;-Dg-u$K)BffkVPK~NRK){ ztaVet(GdOQ!B0MZJLIc^LzYvZ*nk8v^5|#{+R2sNHwNy(Xoy+(-6614e%>gZsnnam zg)s*p%;ttyVaPJZ)4t$L!-as@_S@O}QaHI6SYXDT=-HVfE6qZ>*2mb7?=JQe=AB9|Sg5vGRbNJNKXm5uztpSqkbh4(kGZXZ+F_YA4>ON&@p-&#@Ex@w?bxW~JKPB;DQ>-))I~q@~6`NrSr~0?8 zUuGG02oGy8hS^$~o_X?V6fHI>-@j%6!t2cbq8W_P^I3i>mpgbq({`sF7zBBk2YXEM z{^Eh7PTY0C3P4S8g>riWK*791!LQF2B?3Ne1X991u3U~;$vxHX={OhZHOz$kbE6?g z)Rj}qH@e>6D&{)3QxJIL#xTz%TYAh?{#rZUH8J{fm`F-QaU61%-nAGsp^7o-Yrggi zef~!31*5!DmgKvFm3AtSvFfP&PuZza^Q#hCv3g@8)DD!`%vj_wG%q|LBCJ zQGWBM(|jhUIv1NSzujc3R1jJPY_MQO-q~2u{?CtL{{JF}GDPIK_#-UKPs1d@!u6Mi zmYR-*bDfrshMta#i-U%mmW7RthL)2PQenczzBxCuN=M7i#zDi*3VBKm@oTIN&Pk}! zN#YFd@MaO+osE>+zN{K1kWR3d*ot>qSh{>X=iISmQJ_Hysz(1Qij>%YFMOi>zKx{s zmMW0tKn<)sT-zFR_Gf9yDyiqsDZli?z;Gx=kx&fwRs;51dP7lKQK5FW)JR(+hmpm16`q;&Q#r{hH zaQtfU;a(W2c!yq!pGisT4`TUL6%%KY7wo0OVrJ~ds;Q2hu*td721(v|d-T#PJqM_PM6CGEn_ zzIpkRL!lOLeB%PiMkY3raAq@zN7*+L-oMxUkcZzp55)@YDSRkrl7FPZ$exC$VK--a zJ14!d;}qD@C5Z>TMFan&x);CbY#Y{Hj<2xkIymFuTxcp8T<6{*~VRhX_o3Z!ZGTH4sCC!gouxEV(gud2XdC>1)FqKV}X$MT}i11U~Ze<91K zK~=2ZR!605`JP6cIilm$Wu)}k%q?7~VaL@*@({O&!-*Ih-@aLfY7B>wvmFOpcXDt6 zn&l^=Fv4-L=#t0pFbM$@&^hqnRRo?2$Oa7I-E~9O81fA4MPpSItG;i7i#T3WVrcH% zLB@Iqzs1ThbHmXy#hD2YRui|8S5$g$>^QB|cO_B|_g3Ny{SFuh-SXCgQ0ZteIRES- zWjT-0;Rq^D;{sFF2p`^Gs?7U_jrX8G*?tir7}IA8cg0pi1zO>db@| zgKHK`;bmv($Y0mgBWgv9EXcPqsnd#KJZYge{>U`{=)rj9l1IzvRvcL&x=&59pYXar zXNy(($_XQ=Y^D}dEP?-D_=2H#E{^c^T}yd%DGQXBJ_jIm^C>s?;~eG6f)!NG3OI-p<8XF{ul--FeWo14VvqBR>+_8s+NQHkzeO``R)EwA=M=T`3URXW$lku5%iAmkEY zitOyzI-`w4?-W3jIYov1FJx=vr^KlRZltcc8;KeJ@J~y#u#BI~GVv@5uZjYUav`Lw+S5uMz0rs$4%^&s;vrTXeP=QLf(C0EOB2ykAQMav-8W` zlZsb)ZRo)fo5YvgB>Kt9urMa7yGQCcS8aU4Fj{vvYsUln8JZx@C089O?3)xHol+tZ z93yKB2uUqH*#h}$*=I=>7v9@RuY+Up`@+TAymhp}yzhB&Ymd+va4JdOJVm|Rf9s=4 zP*t(J&XfJ-{POW%KqElqNhQWs-kC{aqQ*jEHYYPMzr`>4J=UAUy0I;EC3I|^kyA1A zAhQ^zOZ@Ga&aE&o2+fp7wSJFB?sC}Ezl0K)DYn_kUk^5G-YXOy&wt$wWROs%v$~O> zzsZRU%m1dlq5Zm~B)z9s==fQ}*|})py34gXRptk}nxci+9UO|yvmC{&xqBTRc)dJb zPe%VZYANK{0;fRJ`F!dJM1_QO3d=4GbZtDBj{HDNX4Dh6t@$ukQRQ2489Cnv+}Za$ zk4)aB{v?ppuTN^Qq{7nFLWh%=fzn6{8Qo~ci#R!(myBI9mQrowc{uB0``~aE%sN+eg4?A7`^xtPXTTjlg{MNCsEp-Z088Z6?l1!^( zJPquduc0T?>QywRXq-TgD@dN`jmUs>m)uARcLywIgS`X)z-d|O*_PYoYdHS{&_hlK zkt_r$r?HeAdCN7!ZCj$OGA}hd!wZmd)XLZ&?;q0q?M~>*hRC5fRS9km=s}Or@B z-(Hk6N{+1AI{}f`Yz48}yQUWT?`HjPA6Ak~597e`(=mPslaJRj6XfY|WZD!VEe<%V z`PcKsqNUj>!FOE$tQ#k8zvJ$-uB?XN?JsLr*9MzOyls2N_W+b<;sk{vO^Iw_0` zO@D0O^L2(F^Os#L!ZI^N3+iV`Q(Z>t&MEl%%eF1(dpgQ`hWTUMhS?|2C5bHK8rmnn zSB6AUoUT7F&D76GI1zE`mL(v!j~dZ|&$KM3r2e^aZ9ebWFfFptjfvETlt&$nds(}I z6|nKCM$bw#a%J5MCr(N;_?uXg&MDA883&YeCMD6?0d-QWqT33#u&;(MnHd1`06hjFQD_VGXgeuI}vDIX3#GTz? zTB7{2S~;4Z^<74QC_Xp_S-U-J^lissiNY309o*G31M*O%=0l|TRb9c_6R$-jge}^X z{fi26rzyjnXzXiy^HQLC&kAnjQv_s%1e(oRyr)#)MTXSmZAf>)XbuhWR?9LeHdCpczbASNYcR$hAnQ4Z(o^d@pYq#h|SbUu#jR;AaC20;tN<*+pWSD zMk#`VI{SroC7Xx!trr8zCvGyuMP(|d_Txwq1I$a#!q~z^l$*ZsSs*?VFLz>Edw5+8 zoY6>^w2@8Y&X_@aBWZQQilMDAu4SOZaW1LO+M#ySy0iZK)IEATOyo#*2Bc5KAuSKm z+vYE$UW=Cg9hsM+CrGhwV%#|UM>ba)u=}utUv*Lc#?WqDcc2uBmSdQm*ihx@t|FN zSX}+{)<)kUPcpU^q0!gbf1gn&>rkbP3*5osLT>UOutV~UE z;!jjS83LdY!a$BMXwcJYNIRRij;Qn|(zcTK#Y$xsTNXG9%)`Z&ctFPLgjnRE2suI3 z^zmZLgkHa~hnj(e0Cn-8>ZRcq`DgXVVvGCPTcJu#+}J#UFA~bu-(qqW10E%(M;K(` zEt{JRgeS7F!U3T)>X=}FI+o0uX>(=&BrmFr#^4IYQznswGWI}PNkK2hoiYWbQ2l4qDA4Bgq;a=2Ki{G$G&&jNBdr~Iajjks?n5{30$rN$B9+A;du z$?0^ci)X++{&~XB_`HAuN>4Rz3zv(3weeXyB`OnE^`Bmked#QBB{PkXYs;uqQmM>3 zW8yNOl~1#!siEmlDdd3r_eoeRa$Ub;|^~XH=eU_->crt z4qaO7*c5>XOHc-lCZE=C*UF@ggtb`X4@i_FdGS}Boj>_M9&V+%x(kaYL*g_D1VX@b zQV}TD3Tv2KYvD}iHB|NKJ-J}F2tKQRXUDnd^b%ZnfSlE&1xQW3XY2A>`kTsH&OoyO zjiI`~PDdP2SC~14zA2JR7Pcd0z^XBRLt_}bL%@4zd-f3o45!eeV55hwT3YFkZ1STeyRID^Wd z%nAHlcsz=?`jE*2qfI$-tREX!y~JXO3*L{H7@zN`czE?!y}X#s(722cbV-%s!wKKbvm8D#CaY9Yp%Wcdd{=cUJ7?Lb(Y_~G*Sgj2 zwfch=$shPG&Di3daY(Z#M;yy>DH|u2r(_3a2z}4uw#_UJ)=q*|)F*^jXF!tsWn@A_v;bjH;3sqZ3miS@*`NNOgr32-62;CkIRRA>CxQ53! zFn*JlEQ|qvN&xga)K!UO*Doj@C_(!~_#d;}g~@+E{6*s6f2x{bH6sdIl@DfR;i(nG z?91vf`*n0>)X4}iwP~)VU{iGn$}Xwf`X}Ehrvw3ggRx~S1_^D|g;Zz@t7XtfI|$wv z=s89xm8G+#7tvYq)L`0Tzj?0_flZ$%L*(m!kYuKc0&ci^);~z^oi&aSrcpUmqTK$) z>And}8`HfT&@LICU>n$DAlN4(JOJmBq7gH~0x5bOCwq|_(tnUtWGCRXBTLF`qTCUQ z*QxpiT5ZxLv!gJ$AvgydErS#iB_j4eUOYK<2#ej)9XwyA+(eE{r_2t>Kdq#$m5esl=q3k$~h~WF)YDQ=Bq)*h##Wi|xwLNH^{>(UXTZs#Q`youN?LB^F*(MbnmS zmNRO-0F!J_oW~3PLdr`e7CLt`ugE31amRazB80R`)HES{M~(y07OwA3*+G8|H5R9} zV@EEidsC6OM2b&L{kv{)Q=fG_V+V5^1hjSEDkoSgv5fW+VSj7E!t3=;2Zlja))M@$ z&=64Z|3ZTbL}-BVhr4E&o19yp-hwC#09KBJRa!1KHrAcltu4C$1O{drItbE&nRAM@oB(iRDNUz1HYuosl&5*TLDbQEQNxnW*)oed}` z#x~YHj9RyIJ&r@(vjqr9=8L0)yYLeM?dqO-8)CEy%= zV-AvbQ?gLhFe0<`8aNX}7&~ai4%eg&py!w`kyzU;v}MV-t7~5eSI1^^TgpofaxfXD zyGgw}G!w7d3o0E~z3GURX)#tl?)wIElcKhhy%6)MJfQ`4R4&B65rj6yoQaY9Mg#<~ zjb$qz5kloeEd)U7=4}J+IZvSAc%iO5!L@zM2n?Y(<{y{O{H1G|mO7lsr!$A)&BF&S zMt1z;glJadrUX=0nYyRcZHD0r4g z|IjGM3-=q;dr%Pc7K90j@Q8*b>9g5^)#wGij6jW+eDvY}?;*qb%VeYYa48c$m%W;r zdm^YKFSy=7DKowppNB6|WaB9$F5h*kj&_4Pqn?m|c&hG;S%WfeMg#AR`oWnLCv=>J zyv=!p#=cJPEY|6X#XuD`JH3`z_dzY}j8aHK944dQwe3@>P0&|nxfNrBsb&O}pF&H| zMwNn;P*EfQiUktUs3k!xL0VRDv@x}t;81*%X9gc*Zi(Stg>s;^w3%Kq z@%69&x^FJnk#|7ca^Xi7h1z7eONQejbLiF0)))!Q#8}|(b+)1R08kHVU+}(ed6oBP z`P@u^Qp|Z{Oz~)#vNvQ7mvm6T~oyehY@oFI#a}339)Bz#y54!PMtYdbB9QC z<104?7xA8iL?Bk4Mv-hdRS%D8T>3^C^nAK=jj9JaZ5;dEY16 zpI-gO;;mH~*FAMw8e3A=c56hgoBYPQjMy0J+T@Q6VgI@rh(|v6S9YDOOgwI6#vbT7 z1xSS3;d9W~{V2igQK0t4$0 zi$ZGb8nieJpRX{i~kX z4UetW(T6>|$pofjTg68`^ZSc8q^eLsEo~o;?ou;8j57@)OFR&iQP2t*EWvfNskP4IV$QL!;(;HJW|N{5Gf%bQ<2c3DwVG>D6b zRPp<}p5A)jc>bW+45-vk!+YD^`_wu3`9f?UFLRps{} zCJtq!>V4WZ;NU@hhN)u@f)LuS_(Dvs!x8upvv*UWX7nzP8*>%PzU zEnPZQ5(?|sMpNoUD!X%L(6-n1Zifm%__S=z*)2@8U$bCS-}ptK+>nbRpsev3LM1vU z=wOi&5a|f?w@wD7+AcB9oo~cV)$h$h2%3{YU(IRv``y7)^8eU##C27_^tjEhFKhnU zz+teM&*-RTUD4sBcyQs)rpDHYx8&is2^9|dG#?3|X-SkK@YK+AbVpac+G2e4fUfY@8*0rPp-jhZ{C#qrvIGpW7xMQ2Sl(~2hQ-+8@Y?~ry(dT4JHT54 z!x=l~crg;(;g@;vw0C5(vo3p?a%BC{`^)m_^o7k4qzV>!iG_B>Q&5~?U`-yP&)p7~ z{A}h|Svi04$j-rcl(yIBi{o}eAJlM)(@$p-d0y}5BW^P1OPm+{+`rD<(a-L(aqgb5 z)r9w%2yrDE$r8&+vK8gJZ-y~3a6hjr-EkCxg1kQ9Ogq-VERLY|oSbbF-c$CfQ-J1oiYn zz9D<)>Nt(63em7jxok&Kn~L;(FhhMY_0j3gNLetpdXH*v!l)=kB7X=vv>(wO0D20& z^h%`!`SbQV9n>^i6D2PFRQ?-W8%~Y&+ zm;SPlVYEvppYLgzbvu?RdvNNEqi=ez%`E5Hp?E$LX1FKf7^?oH`D8sZep(WX6>U({ zdo)YVU(Q?mHSLuYsMQ#<@#F5awc6xaL?-LjShHb$E5fsWbQ<=|0RgpGei_~zY=`xY z63?QyHf{^njZi%h>J{3#{?JwIa}mySKo|VpGbx&}=7nU{wdD=OeHa$?ry%112zk1sCJX_*^{Gs&c(Jg~|OYN1nM^87hIa%oL*m^i~85cDQ|Dub0zy97)!xmYLkMw&8it{-5y_I?@O*94n_17_O3 zWa>0G-s=uGt6yR=V5qiZkBlFdn!Hgo{##UUZpn5t3_hcDC0a|R>%ZTu)7;r}|JvAY zb4y!X1r-Fq`l6h*^AG;F!*W2GB_cW_(5oEMTJKe2LwYYLk(w;m!E8UTn?heqiqAo{ zP>{b>G35}nwgd6ieTExXr8q={($Gg{Ev&qyYZ*(ah{@u4j>Xhxa2+;#IOB1il>aXX zATvLJ+}Sb9n1FejeVLO=;mRwemnZF}b9ArW@7P&mWlYwB0l9E@l#Uj!x%@GfZhy~S z0F!s*n^`pGQSXfv&_b4~zPY3gm*Mice5vZ%Ggrjj z5d+_SE~8zyl`Q7$&FOHfaYFm2vbeXJ_ruN;Wh;1jxq$6CI4y(8Ia_f$oRjR0%Kp12 zBb5Z*^KdcITn)u9m+F&xGVxvhEQBc;)@rKj4OUk3SELU*gkm(x9lmTNcM-M;Ma_aE zg(qpglI4$X=(+F!_BK(eG4NSb zr^{6jFXff`-TswwimJVvzdfs;3z}0VIo%A|+1WpXls%EUt6%75ULa>M z6N-Dy7m5Yb33X+z@)-WWb8AW__Csxpoe#6d}3 z`YgWqt785)&L?K+liw+3!I*O0HcZydf0vpmDi*;*sB`g-!VKnkYvrExIzq5Z9HC-% z#$zVg|JKP*#;x8fsYb2o_DVcT8Ona2+vD$7EEoQjYMCIm?;Yd!(8lob@246kYXCWB zk-=fr;i6Dbc+!pLib7ihEdJYQU0RD}R`;)($S^*S6b^m!y4=3np>C5E(y_e6zO$WQ z{F641iiRf$j7;Zw<}d8-)NbH5Z#R$-}&q{iBB2<#i$5} zAdZDSiSg?~mpKATpYfK*NNZkw<>w#39GI=Z#|TEGvwW( z=qZk{>(oQr=nCnIy1M;1cvQ{vZto_;a4iC*s*a(qrJx?O&zX=61L~7#&DRjMD_MW5 z0w7~o$p1C(>wK5#)@UNL4R*Ikosp|Kl~gHHR90q~JR5ilk2{~}yg02J-Is6tV%`W` zDU*hH{&21bRlXm4bDn#}rQ_H*VILL86`at+4i!=upwC^!W7{@)AK0c`m~MQ~DATF| zp=Rd?_&n|o7r3$c$}EEpzw8kyPWwE|V>0|IiewTVHfEllB@rpGTQl2+&5R{XNvFjY8&ZEQ z$vC1$_j&@5BiBNjCH9kGNu=F=sO~<~`+MT|pC}rXwRoS_FLv`YR5)>uu?N^XsN@IH zKE;ddwEO6LpWXRU$bo;YcHMYt_=-nm)!DrF4VdB?br$@@|B|&vvPLn@k8Te91V{w` zB1l4Zdm&6`^8Cs%tRvybrhGV{!UPh`lX24H>mnkUul)SkFNRIQ>68ZOiyjJJ{CsfbSLyAV zbW*;!!vfxM`yUcmi0JzHJl$kgVm0LuiN)&Pu%KCxQ5Q`_^5 z8C{NIKHwcWF*Kd<^PqmRAMexDt1n4N%!=&V?;BztDU*EpdGpZm$s(}9#5^dTVs&po$fDDTCxeyAP@z>9;JOzZ$NOejf2pYr5pg8GK(Ei>(9&T;! zH?Oqlna1-D0$uKoPaHg>v)NJ%=gTf$7p3Wx6_rBT|n3T1gg z?eG7j8x7= zTQZfwt~A@*vc-e~pdj?uc-9{rp*doA`-D%L8=6%3LVhcD z=zVrGUdIjno|jC*u6@e&CNrZ+bMDh|?cUF;pGR#5T)5Y0fKCa=`v>{s`@~N))ggeG za1H9pA{buduM$a3d*MV~jhKm1w#X|I%mUNH8&*xJh9(8*v3qqA!Z(SpIc4W#Nk(_3 zYiA9-9Rmm!<}E$^!)iYc7Cw)o>`q1Rs07l5TWs{QHTDZ7;>)>BsX4>(^D3d+kA_0tknTcu+P%;9I~CAHS*CB43^?PJxv{ zoSVbZ0x?j+EM62qP$g&L?MwYQo7~MpCBy?+t*_n^lzq#)#lP2gmhc5X8)7bU%h@_O zYjxx$jk`YOdm*#6v(0>@lf-rMMYe(4^-+QKaawUa(b>VyWnudq7x^8C*_2)>@KTt* z#egEmMCNR2^_i=pGRDM!7@aHK$P7t*_%dAmKYoc6ds@ zkQKL+ZM#fkq7KgJ-iyfd^_sCWGi}SdvT}hWw3;Gy#Bn6alLC6Np!e z3VVzt7wNCgeydP9QI52d3=H(E)ka&_xgPha-i0^rS)cZB^OwOFyL3WU;jg(H2lx7J z!Fr6DJv>E^g;9~Uv-~I=XOlKvsaAbyJh!zMI25_*yid`rgjY!kNG`HuoDrX)x`|wa z{u>q)$xS9tT@>jC|vEh>pIF@t;Lxl z$$2yTtb+?0H!#6B2GOpej}hKJyU1}Rw_UAV63b?DQlV6s4Q{1kmJupMY6@E)*2spD zV~h7VaxpqAtD72eO&CLZoP{q(C4%DxwcXgt`cfSmTbDVkMeT4tu5;C_%{r{$#&c@137_7ok zSL_R+C^e9egbRK0-+X`Q`CKJD9KMBX1hsOtEPqCX)INM%&76!J6iooWDa+-OhT|T` z_+9A16%CKWI9FO;ZPZ%wHOthCy7~uKJJ*y7=~^0BW`)^Hn$`0W6O)?LTE*%a+KFcJ zhepAIlNm47L8UoV3sat%7~MV6Xo80DQK*I+a|IH_c{IWrEjDcb%qyEPkKI}rHK%OZ z9BIpLHic^YmeD0a%xa?AdCCcoL|Sb~yacTQyyjRWcPDEu)73$4X?%S<3S0jr-6jE} zr`$P$J7`U27yp%TfIO0gSwQ5{8_(UM<_LXovHpnI_hD=$@^YdK29kNmrz;aZdpzBv zELZ@_YL$GLe&lw9v$gORrYwl_`J55>7q~A)3W>=PH;nc;`6%P?0%UL~$7d<~5S2hb z?BPA$0zB7Vs{UEmMT&7)el63JBC6%9PayL0-dHkD>VEf$*HXnH`EE*?X^fiSZLPKe z+0}H*{kUrvfhpyy%5UEb*V;0iTXuwV?VP)Wz2_hMh9Q12qhz{K^iIP|<8xFRS0>+h z1;;j-HPC?ev|=0!cz)>pb&}Ua%kp9Jxr?>YMgaIsI0(XWfbGR6q{f8XM|(!d+fwZI zxtI04e%!4lCS#YCS~6A|&7)%yvJIA!jf^@Ac{{q%k6PmJ*`T&p>+?{1({PdV!tbv~XI`)9aCyCYfSCy)=czq^r+Qk(O30#nS&^=GI}Wg6u>dPvJa2NoqivJxw*PXTrx?w z4i`GiE^NWKU5rq6l-{=@@<0g7@JseDjuDQb_pMg;`q73t)%A`fcl&1Cj14y3_x<|0 zU^}qRdfko~=kUPBn)5}Jmf?wyTXsZtGq;Ov*C_iRq&pkX&+NanCh*@*_5!BTv8*wm zxYQLW#G?wGphzTUS9l2IHm>NM? zX^RP_BSCe8ti)VcP>fKIvbpGv+wurlk0cep02pIb!fCJ5H~)mH?GJLzUYZB{$BpYf zKbN>0itp9>UdP#vTM~sM^-t_7r(AMU+yQHrnYdLVv#8^k)il~3i`Hzwlg;YZ|85vW zL<4gbIb$dEL0agnWQe95t+f&R+Ja_3Lv|DomNaOw(&>wD1`$XXAHzuBg zww$*T`^u8LgVg8D8lUsKEK-5k&vSJ?Kq0eE^`M)X!pZksLwVpXe9TM3 z$sXa;w$rB}!@aLGwa_XK3NUW;-va=sWDKQ;K*`UdLEG>Frw}QdqMqzdW={3%O723* zVI3vq*il*-H{#I*>W@b|C0wSKiqJYq;gFRvz zA4zzVi}RxnxYUlQq0*_`1ZJr)Q$L@amcq)9`B@!aC28I}m)`#`TgRP$6N=+^4t$@% zA|F(j^jUKJ*=^PK@@&(VGF$M|rKxV1f^~t$!dj#9U96Y7uW`kRZ5}hfxKV5lHn%;fEY?0cK5+k%Ql z-g6vEj*pv7ZK7cH+8esMW7Q8dVvQt=+v>gc)d4#8;z<5?Qig{JgN&MO+ye-ygKpv$ zZiIBcSmKNzl4Oos3r$`5WQ1kotx9mHa`LBOTKN%-1VHv%DhHq%&(mj+TKucG zt(sf@+hH5{&*~O+zHw|5`%R-}!?~?v#y{K|0w?4Hf`QM77BD;UK2A^+te<#;9DK)T z#AoajYx*sA=aooT4Le%w)@F^Y`Mn_H_?4BO(HHcG^lF-kl`O8|Nm}Hl-R^fH-R+&9 zzjiM=I;^EeCzD!*uu9sG|FI|4oXD*&bVTRn0L~q+W$_X)5dmVQPjfcyj6xctV;5BL`wk!+{` z&ahC(^|x0|yKlMY$41q0GHUMJCko@%+nLr|6*d<~VXIOl=^=YcurQH#A1NMI2pg)H z3jxD=6W_q$!~T+aPMjX=@a zA1NK6j$f7GxUO9P@6DuaFW;a|*9ubV5Xy@qDCdn;LW5kZ8>>c>p|!2YrT05qy|7oG z?IEfy!>X9N*=*4W7NXW>?jsxDzB`}0Nh!@rtaT0uxbhl;_-*Oj)KKU)Y09Rg+V9A` zwLm{dC}X)#Iy|m!An=+ngksvMF@k)4qu{g7G{mL-X|A`wo$=-fyTKQnJYlbmdk3BF7=QDN*rS_6!UvD@w!kaC zzD{=h1(n#pMgyr5a0|IL)d8Vt?cMK5*b~uChiYY2ad?z$&ncxx09tXD*zevCjsN&5 zC4t09mVG`e<-&EHg#`6O<+=Y30xz2mo{aJZRE_J(LpN6(YfLI+x`X1aSw$|2-k*(Y zaTxr65_#E}N|!}EtJjQ`F}|wf2XSMf~Y^r`-Svb0B%rzKOUW%@FomNZTbX0e}6t+z) z--;Ie_%4^vcaX4*sn&JLT3&j{Le5s5YSx5nTwm9YRyY=KT!CemAPv$|$#aU6K`}A+ z;e-Sr`PBNZ$%=uP6`=cNzg_Rm98=y{^?&ziD5GO6wc|}e1#*KOPotT}Y4qfH(HJr> zeoNhaOzcVy{SA&Ab)rswh_@8*DdfytyCGC^P@G7xNU*|Y=F~PGVM7;6?RM5_3C2dV8^DCU(S5IeN`W&26Xj8sBF@)ydOLHrI5;&M z)f8oX6IF6KVwFcxxD(~?ZXmD(mMc|4sDp(@D9Szp`q9Zm_J(3>mPgOg=$z}n+^Cw@ zRJJ_t?9SDP5+lROy4I-!GdB&q<~!eogT+zD!Mmr-d;6+RHcjy=bVG+97JogTa}rqXuS$AbxwEePTMTVySe;aZ>TzNjqR7LQJBn)OOcl3%eXv~1kw zrmArrTWD8ef0{>iN&R^D!{)OZATGmS*itk{QO>+M3C#6Uny$@b{Bi29UY}|TD zTkFr3Hr0kUQPhRiRGImgk|KL4I@qw{{k(MI-YR(3)ZNJEwb=Lt&oBD-*s@D{zx?2` zBcU0%dkGFsO;Icms7N_-E-_Y~s8tsW%+~wzuqs(tlQ8y|>`9$rY^pOUn-8We8{T5baqoqwM`E-zHlvT1mOf zb6TVlxHrq!{pWK>@l7emV)exog)<3zLvSV~CBIp*NGx7$S%7*%+a~ZpfrC+^mNmZ_0P##?t>G>a3#Liq@`;yA^i| z4ek)!DFp%qcP$Xyy*S0)U5h&ucPZ`^cemoji~l+Qcg8qZ*%!%0b~5%_Yrb>N=Sf;Z zLtBUxYr;nOr|Xp}9u}XxX+urSvQ+7_T}S5`;Dfvy*6{IDXnTqSi7LmMqY3?zhfQZ^ zC^*uPK6WlQ+GbI|JO(MNp~SuEJIE99GebXU?hK$yD@L|hUmu8N2*A^_n39_*-6(~Q zvLj}iSXrx>=26(AayEVBOXyuo_oI}^nB)5Yu-yUBP6>0nuK@i8Eu2XA z@Z#tXEr#ij9FF%RMgt%F{>`}F0_jR6)+VL-!ps37vNUZZ6krB%>d3oRS;Z`@7zi?3 zfBGu=d@wK%fgUgd0+Z`7g?-`Dpi6`#0(ULA+oq}GNxNb90geZgiNB_O9Bi&^ce&Tf zO{U|_6qkCCNZCcgzo4z?>X|a3@>;v38H|og4>+{Eq;srxFShNJpqFbNZ6~Q-EE6Bt zH)v|OS-Uk6$0kc4q%sc1!;DK{V@-haZ zphwx<(G#uqg?!F(nXvsz3bC>WI{w<2myy^}@@6mJR8ux!D~+MPI`bUDycWuD-bh^w zj+^Hf-w*`$yA?zd+hPO2GqtMH4tlbuwlqm=F0yj)2TuL@NkWcpM{>_*>#KG zuC_VsMTVn^g5Q>Em)uIo?9$xl+}=(~d7+Srk3&o#z^zwP6Ag%QnYVlP+w;kayAh+h z;?(Kv$l{dE+sxr}_TkL58r@c|5Uel=Yp!$@_MUQ+A3H&y@vFR$79;D5aHO3YNm`YF z1+M&4t)dpRT-J@JiAtol6H!VH_k#*P%GqKZmp78eoUK*1mP~vF&rN$GP0w{8Att{7 z4|GWOF}V~q$VCij0Z~;Srmb=PWT$YOI8jaF|Edr?NsK2?kEI}wV%;Ex+HIt;DP6{} z{PTR=Jztq81W98)&%6tqJKR#dFnK&}@L;yqUvo<$WmYYv%f+n^8!D0xntN}RK z>-3uEon=))>|WAX$A``$uMg15PTSY4PFx-M21b~6latG4V#{Il&$cE{_jJ0sj>HJ?EMFVQQ-lw`YJHa1c*{w z3?~WPvTmfAZdj9RO?8c~s`fYjwePc(ymaIW@-V$g1GHx8t@+Yhxmu&RI7;WjW%#a#7qz6uIf9Wa}M3g~~6tPviu~L#M*`kliC}!{&Y*B3Reox6L5|+qj z0enyM2!Yb@NZ;7LE-tECt54ojMs%5V+bI5bBDw@w)MGZD6{}i(5l^i$j>g%`fS2d zU(JBhFdT+xDbPe4)HTNl<$Q%xFl>9CUfjmRFQz8qN=BZ&M;ZEwwC6A82xhmVrwz>< zSLJ^O%UPZY7`HhJ9v-i2bM17?6}VBgoR;*rPm31O)gHD=~WOny_o$C)05=%iQH^(5ydyS&)A~_B)%5 z(xIp~lTeSm&Yt35VzAs$YYX$1txY61xbM@^lTfbuuPEa7KT$*jDvGRtLg#4c>7ebG zEF6NIC-gLQ00vqvUao_cwUyDy?YYI}si~>S8GRKyI5m8}Kbt9gs6Xo!ckBzx?1BqM zuvdjs9K7|#czTX@|5Sa3#-S)J2?*$`DQu~Wx)q2gTKWSFYX`?L!mY!ch)p`BtSbYY zpsj@9Z@s6Cs$Ko%$KQ*pCgnH(P@gfsH>74Hy`0cJ>G~o6N>GMAPWOO_AG@txRHO<{ zc9h(hrLxu9;M$n6pKI;y5;T~o$<>u&1DNE5z4)gNRk`9#yzg{iDR@DqS`u@A)%#-P zZhB7bcz_Bj#?hq_pYP$-6aG}dKX(hrB~hy`oRTHu>rt6t*s_(sz4Jkcx#(zugW(jE z+^v!k@O!8-qa=~iOG4ipbY5FP9%QMiHChDMU0!_6Rt*?j!;E`e){yNzVW<(RKa}y9 z)9hixlJ__=m-b}R%TCpzV?bfGVsh~0q$u6Qtohg?#f&`dOCm4c11tD~>WGWGECvx* zL0)`i0YE7{;8?-Jg$e4TY)@l6hl-eYzjQ3;q9Xh};)|W^7r%lsZ^<7P>Wg`)aG#2Z zXN-{p$Q}U#2#zq@kB^g&gPM642c25eSPcb+MJgXS6S(#*P4yP8G0N4Wu=7XXku2Sd!zju4$=ON|7fKw$R+*JRb52OU!o;Gl{6RU z3W*u9>jjl*@ct2=fPy##0RvKsBnp(rXoW;b*uU?UvC4CmdtVf$@gvn86dUgP$2JTb z&ip(1svrw3AyrEM`v(>NC!w$GUHoD2_lf}0Fu4-U{Z4^<$~8(f{%9u!@cs7_RN_|C zCKlJ;0n(b4b^rNwL!cKx*E4#e=g_#}29!pQ3H=iVpP;hZ3R=X^A6Z1!tNln%n$mfs z7s6-Rh+ds#8?PaNaz_wwz<7s$ea*V5C~&n^@mQ@uaZ|E!fmW@d(X_i7`n<{YSIH>| zQu4A;)emL!X}E&XjKD*{bFoEtR3JhrQ-9x3g9ZKVjWwi*Qe7?fjOW0o>-8`ig^59> z1USuo+FYHIq(8Fsr5lgl?UU7-?&_w$U6?D0@3*cV03Mb)7#l+!j0SNygCw_ctLiej zWVQ&2SV4T1PMVHVz~(++Un@g}lniI*i}YrzVc(Pc8&h{whz3Q19&i{^yZ3-iqiQmmL9m)ONym8x@_!%3CIVCAGIx6}8Du)aqE_|_aH43u7luYpI)nPFUz+_U$iX+_a4w#W?!%B+T~iL9IqGU#2i zuUt2au2t?I(T911E6Ft2k{q=*h$?vl=KZ9J!b!~7GVYl7;yE6n? zWBQ^(Y^0cOy(XU3+m5jr;=9%{oxMM?T-H`bFUK@m<-_J7?>m*uY+S}{aOFvG^JwIV zhlRk55%}Fe2VWPqTaWf36}gE07L^*-fQX~_j8nWBaQ+bJsIT!BW7&}<8+Q#AVVWn{b#Hjabu%{o}n?k7E(L+)k}M;MB;4j zMc>0a(U{{2(5&s~D;d5ga^#S*<)p@PIZ%f8%b4@VRs16am_)^xhTf*{#%p)xEm>{B zgxa|CW3`!aS~26mqET0FlmS&1fCU5HQQ^RlBgB(jNvFV3<3O)4Vl{{(V{<>G`o6rr zj^dHEsZA}8j)#mq+xjG1@E$A+XIPjd2^1YSa%-Ev_I7?qOxKRDVA5|aiQlaHkT%+(n1MA zt=%>&7pa|k@FDK4fX8A64wPwUnp-nvN8l$&a782dM5 zA3@ZvhnqFa-nB5DQN;*Nku|9S$M(LUA{mJ>JJ>ftRya6vxB&LMV@3o8WUGMF<-pIF zzi!@pmh7qQh3tB5ZF$SX(oKG*fKwyvMyt+QOnlN6*;x$UAmNZ~>O#{5g9R05Bp|hF zhiX;e7BZO-VMY0sQ9_nvc5xUT5BbgSP-%PdET!M+(tFFYYi-mwAz|O$!!ZuN+e(gH zagtKpeJ@y5t-2!2z8W0rYCUWHCGT1MN#~0FQ+YO7WW=?Z*umt-wL5Q#x8wJ}EHTvu zQCgNNSv+{CBpC#WLKkp9f~C-YoWtdYzgc^0qLK!`k5=q{efNs_MA3bi#_;uz*gtvWCSs$#Z9g;ovJ(X`I$V{Fnri& z?(!^vvCudH&gX8LM{;!tTs&`e846(m#i|b+HQzT7&D1b~Kz?RRAh{}P$J3ssl)|;y zu8l)Re$*V$4$Zr&xxzoCs^`T>1G0PaK%+)8NyZ~}bW-?-xks3#XWAC>m5Y!# zkt|9WaIwWZ_)sQ?d;O07?(#ZXoHH3$zc%zh)YUTA=N#3+?=7J7aj3y_M)A^X=y}O% z%F6RY=*>+$+m$VC%+0HS<4Hajc1Qj!(BO08z4cBJ37t^i7MdLC2*i4Qgk?Hbqu!4q zmZc*NK;O32*oU-`b_)~E9Ff$B^Lz%nZ36c-@w_~Lx5kuftL?o0_wA0eo15$^h&`dI zd=N_=GGd2R6CjptS-$`$hM&^v?2KuJSOCohz#xi?E5iNq+GX&Ec`HYNfj0@{BKcLO zs*G}i&H&?~J)4Tl6MTXv`BoXVV7~GMLMi22B1-y9Rl3$ydS{vA7V0aK0!B`g3Rwst zb_lyOW3_jYRh(f#`>Z~eF&eM`T=bV{5E6i%c}~KbnMGSZ?Pk{?)TmlcPCME;FDx<8 z_`yLZk-3QThoTu}hHXwbx`R=EJYECn?Ru(fwZXu=e*6S|@WK65=QO?FLr5)@&Baus zrCvLkb;|toLFTs-3f{`rUwSf7N{mxThK`odw~^nlCvofMFekj^C|DZk<@+$Xqy!jn zenDKl;2bp2uSTNL+#=2H+(>Y1?IaF*oq8+A<3qiCLr_-^O@oJ?`ZC#Du3&@lhSdWQM$?xs-45 za6f>)6_@ew*sMQ%d8CmM*rHI&yR34q6KWx` z76PuqIli(ot^V%+mw>?9b4c)g>1TOyD8sZ78&P8Ge12{VVR8{n)ePyBMxAu4x@@}l z&JS2o?*-k@e7Gl|pAB0#|cWB@RSGW&KlG+d`t z{t`JSe9F4YI;%J<+x&tw$JT1e%7Xo8NGV?(CDta#5eu0W_StgmJ4m5FGiE)y=K(wd z`)19P2=@kq=u@j!Nb=hq#*#v>tY|;sjOD>U{Z0z#H~h8GN?(3a5j{25`I`NlG>Yt) z<67oWqv!^Q>qTe`dc49QoDu`P@L)T=f_ibLK}qe^HYQ4ZBNLeuZql7n^YK ztNMrgB%~KpZH1yo8yd!JmMdq)pum)d1HT3jNdk?g z@O@098_~?(2v4)^9Lqmlc3d2G`o-GLdcEAVUqBh zq;8o3ILO4?>>;FM5~Ka%@OgV>%8ViS`>4-x!#S^C^iAV!qrEyzBSMHRA4}7U>Nuhh z+k31dn?~H5%Zc-7LF(yKwK~zUG^zr%Yt6^Xc~g#|D2$>*ObH{-1Q`UAva1}{vESsG zs=tKLeR$X9CM3R7wU3zT%R^73`z{Ml9aR4B(Wnju{yha*h zUj=Xy@9M?Kg-ZA$H+(-@R+XisPC9!ZZs2PZ<^&Iy2to?zdPINi1C#dI#S{Tiu?G|v zU~MOA_L%TGR4Dv!Bm__mG*wZvu@2#b95UB`&1WLSBH02j{a%f+Jo~x!2S>&7gl=J) z*mWff0PH>YYxt&flpiL9$9si-*=G z_8`(>Qc%yt1-Y0_y1}28szyAYSxYPOI1}x=XY1TN#l^>;3cAk?VKRRrO!N%29Bf>)%(QesXw3vK z7Y`RSHbTe22?Xvyv82o#+`v_CZcZR4H$C5`TuP?oAs_5yv;$8CB0{+k?4$|Qe+j*1 zI-b1GN`myJ`i#d3wmj;1V^AB%I4i__MSgK(`1d;71Nw0|&ZxPd+mi7{uHx$$pA*_r zA9x6t{)G8P^VTIRKnomw716$pmsFwcx!VhnPNE9b^zL}i#F-r$cAtZKnUGVuX6*;r zm^QvHTs0KF4h|ZVOc12?-9+4KeKN19`k8$xdEEh&?N*re-;wUREq|edG({^6k!n2g z)k9z(xc9f_AoCdSG5Ed<7J}YgT#QHTRpUmwr%02HsM7c_&7NOiAk5SZWG^{dG5>5? z5v&@9FTEe*!*+hs7^xOYA$9Uq6DW)N#-Qid9viG;Sl}m|XgZ-muX@=VXWpC#YHJgI~!d6O?AuQP5=Fpnr>x0jB^ib83_d zT$vu0%&@f79ky2uNzRq%@m+UckFS}|p490jfzC(0KIhV-ZQupaomRkC@`=z#+NDbe z(ekwXTGjY+(w_m8mzSpAhAJ2|^JO3mw=9ROh5%*NP}DNWQrjQ1yObrp9je1h+!DqzKy2{IGi6b7Oy=hs&gnX!|*zE#fVQi6ciIu(dCYc<2>J>3XmSgKXKb5^7= z018T>tinp>ffuJ86SzSYHSuS7Pl>I6-|8qGX3=!CY)?$t^Ng#=(SS;si8FZO4ekvT zy%l7l6NOG@#_X$xTlhzX#mnvc8XsDFLp*c8WpXjM#(Ja@hG4-Z+* z=6JEg+8d}qOHxPAZS_0#Yw7D%Pa4>^4pi2RHsviT2ns^A39m0&3DOi`AJ4WUd)rcii!Le ziiY!6bSl2z*O@IT#F*6WD=%tN&8S^43Mw}%M;t=oC$Tgba^oto^$B2SGMgv6XnMKs;o@Bo{qt`jbeSFusWjD7|t% zrsv({mDRrp7wWzh|AiL<=MR&iO^+(|wzErU5VUYzt3{79-h9&~^gzF&b%@Q3h6c4m z!GrOXws-!iM01UhxAPw4I&7npmKC?I{PXj>c8o(W*epYk#a9ZBjstw>@C!h#{xf|6 zD?Cl|kVS!tDuhXP=;R%q8&M)(D2UO(+#e501PQEh3j|rD>Lda{!td2crZ7_Syn)tM z_|0}QWglD3ccA;#Aj*GHBPDBPJV24$xn-7Rm+a4`Wfi4>E)yAZ8T0F(7~mvwg3tdM zXj#nzNIHAwy=CbJ&Q>=olL~6ivB|M6j+UEUITkrH`sW)q9v%%02jd(rTA&FAg!E}V zrTY#qea@nZ`iq6{-0z;F)bU=LNQ z(fR{480Z) zHxrW~z$+-pPTlSYw@#C%Fk%K3t&B$=z55J1wr*BAEY%p|cP>|MJ527n5f5-+3agR+ z8&Ar;&2bgu1@uT*uA|N7FN;JN= z2LQIhizD_E-xI&eD~*N0C^1Zcj2Vu+D(wF2D0G1qEy|cO&kD}akZCwu-0<|o5~$`= zjgg&lx)3g=JB~?=?pqe20+(Je|NqN?EhzwBd>xs`)Qgv9&tp zc$F?}iC!G434&6m?u~A(jb-tnTJ%oCz=!S*UYY}(U%CHITRm!Hcc+eB^C;yPZuweT zIb|M~*FVJ;KJi^BQG5N}gOLKMeJ?0fl(gAcvy#N|KC3g{MXJ+(Mep;nD9-A?`sUp! z0L&KUOiGi#-E*Mkt zUM6t8a>G;)e99{0+=_D>f>Rh@VEmSdDZb)*#+@I$VU(fBMM0Pk%uCz*=EG9Hw{tOX z-`t-Va+}@U&mmOuK;+Aejg1JDC!@(Mh9g=<70uEGE*ad2WyqtkDs@9c*Pv8@gAP z5D9QdDWTC$RySy?a@3t`I!rT(f$v=$~RiX%I{&!eC##XD^}p zXau@hZ%7l1z@URlzGE8M3WQZiShr?1+kU_p2B1=r%nSb3|9W+GfD0rjil=Ynta^`E z!wQo;e5ov;(h^=TWq`s7tAJ!eTxK=T%KS!>_slHZx%BV*BM2HN8lBu(3jfvN%-49+?!zCl?*F|rLkCUd=LwK!R$okmcw)obDnhVPw z?N_`Di4I}ZO^#uR$#x$Z`1di_|LNEA&J4H3=WgD{IB#aHnmRcXwDSEo z|K^KLh{t3@kyE91>l(kh?sS}!)8d;+&P6Vzd0Gzp3Qq&8hyH#6zTXNM-pLXdWlB;g z%x zvJcR9zK1Nkm9b}x{IoP`M;V_X0?xmarYeV@)b1!0Ek}Fwhj93LS6Tk#uT_)#g;Oa?08OT}{inF*W!CBczl3vyR ziQcT)gm-AXWBBx&w{UNT8o0QNV>&uzo&R&xu98N|5(O1Bzj;cW(icJt!d*wPz;FNr zIo_m7OR6r}d8>kY=laGq-n8$xqKab#`<}X8{%u-eVi@$~Zl34AX0&9d>3t!3^dI6y zBtIol$p3q~sI(j=;90jnvL%8a71d3*smc+^m_RD9os6_tKyoMvZHvCQ01ke5gVpBA z#J$Ip7cP&MtC80$UdnJ8f)vOL?G;o7i^8)gG07FuW8Ut}l*X~BS3Hc2k*LTNS&d)u zAzRGb3BK{M5mqNtps|30;8Tmjzhi%7e#ZHL<8;=>*uQpbm{6b&NBEMMAy%U-c6Moz zwq<7tZQNk^3$0=4bT}&H5=zoGt(?PpY8SARbXhA@IL#gWT0Pawvf(Mi+VGg{zaaC9 z43Kxd8^--I`5aX#(ZSyqQ!%FQ~%ntEv> zi6mce;Lc$Ff+ayP0n1QwVE6SSHFsRD#Y(mlHJ2M{9|bH@*jU-W_cYxtt8R~0uhn*v zVJ)QV1qWI7SYhQ>%KS0xXk5~z&;)zJo7_7(&6O_7#U)X4!)yaU(f8l=J_zSLJO`{z zvi2GcRbYdqC;+(xm_9q8kkGgYQYH0fG7UaYT193tm9$1Z9!gO@I(;vkd@=|Ai?Tk@ zm{71byQ`;*Ia%9A`|MD3QeCPi^PuHg`J!=fSzOP3QigAmq4BbME=eLhCN3~U|MfR6 z^29$_9`IBMAv92$FhI*>@&J#|(02@TlH6+5o4vT7A>cMA%@fiLo-Ot|!JSNRw4UR6 zaO46*&zw_m08rCFY9ZkEQj47_ESv+O4ixR;9rshuX1S_`EXI`jJjTxVVA;WVOSICC zeeIb~6$=R<6M~lbNpKrmx%Bq~CWgwX!91sxkEtEMO!lmFxTF73;WNvnbIZe9mfw&x z`;?jw6m++ZkBG9Rb#3`Y^&lAYQD^llnvI&R?rc%@Vp7nairYR*#K~l5gH9&D*Q(`O zUQa!Yx>~>l5D{km;Vv3Q=SPhg`a7Vw_K_|`YNG_YP3Cr_U>b5)5FFO++7j;hL%+WX zCG}u+99hM`A(xq%YjJ&jKb+TE$YXHk!@}ei$;jF-QEE`So6^vj^H@0@KGHmBi}?rr zh%hw>FK5Kh=grY@B4MFnk%xrB=*_%_t@QYEw)lb_L~VkJ04Jq_OE-;&vJIcE;-D#u z)>6qUsEvO7J zk=`XPzzLxJPs=3_aD$$nfq{tw3I~M(Ha>B3uPl!4adI5auF`XIa(K7;hI2h>w zO!Qpbyc`S+5G8X)X!*kSx#EFhD3h_Rz6s`$kvh~E&{#h%BcCN8Qy zb8cY;jTpcT;F}Rq?l!A9Q2abex;5$t4Gc@L2t8>*8og?j75W&^^i_KQ-U1@E&vOGb zF83S|HY{1Wi8L4R(_+phW#6Br*3LNmpyvh{ae_gSW%tn(kS|HzZsqxH$Ox>RR$^=T z(TWCdbS;iU$`d)9loHI!JVM#J81`L!vcSrw;du|!pk!GY+UWUc6a8A*ikUlaxj@Y4 zdX`BJj8V@Ts-%8Zcy*;_%VY$pt%Xt!qOJ=D?`XpBT0JReAd(b>1Gx7u=1Xm6^rllbnO?WQA@F~ ziqPT9=hHAKUMN5wijeBQ8=@phMzhX5^z;4Ax=67P?6y)3m>(rd;xw@1@^7`{cGa;a zE_m}*WBdm*%NUXjGXO2HX3InP2qPvAyX3*bX5w1=)=D8=c&K&&Z5iZU3MiqMx)wHm zPjY`1bw2gGczz%pUK&I=1vZgUv^tjgIj?0_4C!i|YW&jFwTaY7%BD-aP3B$T1r_g` z()P^o*Y5rJFssAuH11%WTw*TGirD&RGoZ{SFOAu$!!#xSGhn@*GPUIWA=a~2ZALur zrM>QKxkTMztHjI~V_w`~GMl)UILUhI$Cj8Uca^_fdHvw-*DkY+dH>W|?XwlgfSHn< zi1}pr4}FG5J~Z5~GsYOC2;^k}1j0&XDs#cVT9Zm-V0ECy&9T(8a?~MxmIGOqh8qm8 zv4xf0$W!0pfbv)E4cuZ>5AA{`yr#806x615`*nr@alSPPirP~zxYYzrQ+t#Ihe55#}{T%<}p(Q8juw@IcT@CTJFaLhsent9mnW?yG5%TI~$F-7MkaJ~elVQ?^)T$D84! zV||N&eqN~*yp)o-!aT$Vx@-F3xQX=bp(WR%SQU^DRw(^>@?jGExnGAB+>-X#a5e6s z;c&TxzSj(0`d}b)1E`O%p|T_1uc4=A5flL09F1F=teP33-`BoJvcP@OjKet*Emle}=yHWzm5o8yTSs$qE zvYk#%D;zt)d=JrCPRqcNy3-btjxn|t#|sG_LJ(+*%l23-`7IUf#hVT2zzk4+zbuqD zs9xQ)^C0V_cgxF&xX!8iHIO8VXqTC}C12Bg7FY^aU-->_djBF|{+*a5k%d*Df{i%{ z=>>*d`TOs1*#3~vmE@U}50t`6=^cN{VYlBrY`?fiR?#QZK1VlNG%m5*^sh;o$ioSB zeK7Ikz?4#=jy^(_a^5SM!Rk%SJWDrUt(z)OtLDXZRA@Mcgk*T zWILasLREQjVnGB8?lCb==A@uGuIpY;esD+t2Qv3V;toT7-2^OUBK!G<5fpo1qOZaA zti4EMM`}~q@V?Wg$NxI!DJuOMa;r+-gs-4f9iXOG*;}oJoiWn@K<#LJW_sI^a@p_G zn3-K(*_<{brnxGs$Y`5wv=goPCKlELn~4hj#k9rYh49c|;P`uCmiXc-JWS*6l1$97 zmNc2^@nTiVoC9Cp6W{hT9m(kWun+JY)*bWI(VuM+7*&s~`yXHFH63-Qb`)98emXZ= z)&sEeWy;-XecMjcjgPIc`W40y#cLmTyc>5rJwXuiCMgd!>WYr9zZ-)-8%r^<&kbhR zeQS_pN!mTsZ=9WESSO z3u5o$ZJE?y(!QAbXDMT2b%KbyZ_SkS&X<|7JFPj=b>r3RUzAug|NWpSbTbv?;q3b@ z0NHBZ*l6madJ-O|<*D)(p3)rm$MjRq#9bRH;URm$xB96sCQBVrhLYh#m!j*;7GFkZ zBeEuBZyx{A30Znq&(#MxNpy-$uUmEI(|CGoU`rE;!J-SUS<_O~oM3AuTlJ5puk4^l z0|JX_1fhoc`%j-N zY0T~RvfCPG*U>je%IVY3r3#s|)8q?Ar!lOt4Exd(?oEh!4w-s2C*kWHy&p7~7|BP= z=gjwVc#HBAT;hF`q!CbIbS1HFb?Z>_*ZJ?XJZ-csgj*8}^Ah$7 z!e=Z~GF^)AR^El3XrswU24Gi8=Pb7he4|1J=Ir@+vxN$;!`@#VgP|#bSAkM^Z1#Ft zJa;+>fL~f!j|FoWzDu=)X&#?CBqZE^+Ql$Yt{T%Xk@cp@mX!e)r2`y3bK_8>G&0A> zLZzAyKH%By_3q;r8kz%u$ri;>6SQ-^#|mror-cx}+PB9$2YbA~-nE~C$$#r@3aS~7 zY$PMtR=dye0YcLfeAK+Fv(n8w1oG?(aOCqV%Q_ng)G0u3{X^rch9gLafupfVO|7UI;Yos!|K^3SX z)gJLkxkla`oE}3u%os^Pg#;1~QZuh5n&;Rgb9dj1^=`qII4NvU&S=puQ0la75qJ)z zpL3%mSgw{gAzW^8Qh1?mRb7whAgZSRD-je}C^oJw!lt!~nYyj6F&HS=Z-&9lCGd6e z*TmoE(R#=IpDy?f=ZU<}_oxl%TP3eKPB_X=j92^FR4$_YyK4?q>dI);p$f@9f2YuqtzhqUB`t$u{)J zp9Fcg-x>pp!y@gd#M7#z2H{{%40%G) zR0*=sv#W>CeywAgZV(etU8(oqJi>$n-&`WDNPBr*x6=2^@d=)S(fi4a25{GWW4PH3 zIBTdE3W_?%7F`>~R+n#XC?8d6rqb-ty-mjyS!PsQaG36SX<8_xv@pb5iIjddta(}j2B2|lPvo0U>T}?VUKR%RHVQw%r*J~+vFeAyr;;F*Y z84{SzXcd@5mI7POHXvx%+}Rfaei7p5`ngjuTQ0Y5@@57(xG<%2Q?ySkUTT3~l@?+J zTJSlc-@yhNJh5wEFF+^{+9IP7z@geum_ zrV)yeb4wS?V!UUa`}J=Rc*(-Kp0tVjwxm?^zYo0rY&om=e_L+ycq#tNy#;mShNLU0 zQ5|^iMRj2%{HkcmF}m(^C}Tam{7`q%Q{MD)?tSRR$^eunMA1pTyuO zkmYHZAN~Xgae=R0>h}_*ll;%Dx+|c%c-P3Ea_TO;p?>lF;I2o$yk$9+qYfh$%|Spl z{`=P9lHrU!psuLA*{!9jP7{$uJ_IhSB>ej`&t+7&YzXK%%O(f+4v$IzQ&b;|UGo(> zH#0NE4O4+pP($ahV0s=f4@{nKAj>jgN}jXS0eEf1VP>_fTp6TUyfDL+zyg)L_vbkg*Ag4vbW?QeMU#9`pg}bhNdiQ<&Lk6CtPCQ-(j_iRGd>`& z?OWyqr$?7?PI3xJfc5X_2RjVtv401D5LFl`!rUOwI^Qz2VxSty?nqcYbu!rLHBsVr zWwf}A3Z>P-_LZUz`lyw%c`+$lPMF3S?R~8l*x*OCi7T9H zC&n@G3gG6i^AOXmw_ouHWE7S;Rt8g)S;Tk^>%U<2a-7#)+3Ysl=Wi&LR&MkSDa{@g z6;!aA7{`9S=ITyTr%5uk^yM)hczgi4%$9sH?_qt|%k^BXT0(Whlv08Df^SCFI$af& zkJ4L|d)O3Pk{|>jBH{xw1=W4~$(r@8 z6A$&0W)ziK5oa4iOy;u8+^Q(g4c|py(gwMz8iz8lxEZgBMPcemXklSaVC9gFN|F&! z{!l6R9vz*$&e(Yy5{A?hRqCocn^;8CMu)OgsTN3Pnxs0di-Btd_Od$wRz`l@hiM9S zdlI)iQ`($D(_VAGo_me?fmFqagS+4ljo|e}o=K$})!s5;5CdWHn7nG#$4?s}Eel55 zzP^ZeDR>e8kmw{8n~pYc621W@8LbkFzI=)?2!R7R)1<6hzrGJKH&c(XjhzoDM`m+> zA0sewI&fgAC0u~*eOsKy{Ig>MsZcWazsPUVqZ64m;~KlQdU|Vx4gL_o{H7>XY>rX7Qu07%5ijUAac@~k zF*MBmULz~i%y$vZb){v=BL58SLFcWim;O+v!6yCzi^6O}jCr*W7#I$HwH zwvT=%$&@*QuO~so|3KyhkLi=3lnXC@2IJ`KFR)gZRVp*x*x)%WGLy-(EGZ{wHBrAJ zHno(vXs-D!<8b5e!}bIs7|Hrt8*c>c%= zmO~X^P+(tX=PoIl3Q$=D^wHYpB$a|?`)4CHS0XSqPoL*o7%&eZvI#$8^fk=Q!- zA)0j7wgEO3G*fbZ@P$5~co8G^*Uv);IM{(=c|5{Ovt=`Q;cxd5_r~&HniQSpweid8 z4tBHGcwbh$D_Qo3z{n;CP``!##4*US|G85F(p)BZK%4h`y?}X8Tf@kAAXdL*1U_VoFmWT6xk2` zYP)QhIsdvgYmXOZ?EvM9b(ddHd-iy}I=C}icCs}X|wsChcp_0-lj*FmJz z=FHCXxG|Y*H{@Dm?&pCOP|fJA*+p!l#NTXpO`mL0^>7J{F7Kg>0{q<1pL2T zfl*uP%BiH<+9PtTQn2n@lQql2jbV@8%Owq=4}+8v!x%Jzv~g9H2%)=6L@rJ_1Kwx^ zJEd-hc2$^e8Rm6+pkP5CJ3$buuf3?^D!%tP{KQUGl$UJNl!Mv!yK9}wB)SZGQ6~ky z)ubPx1)U7r^8=jAKC>m|emS{V88k^~{C^Zp+`9i?0KN@D@?vXc=&3Fq6dZvDJWUvr zs0o1BAI9fB3{-Y6`Ixk0?roGruh&JshD(CwDoQ|EOwqI6qHBdxPHo)kqSMUeuJ=j$USiMIe z(}F-!a;s~xbxhKBuf7%4m>oISJm7Zw>#w54l2?=fJV_YrDao+#c9*m#+7M4@DK=2@ z$?lG%X&vJeIt-m1+a8%to=fJCH2c1&<+!Tq4e|+P0^o1}0^z%SVn_fS0Jy$;jX!Fg z5A!nWZABbpYbCaps6mHb|Np!=4aQr~`De+~NHkI=`R%54y~cLq>2-G&uD$5ewa)Ec zHYdi1^TUmBSg*6WTMpg-q+^jLlJmyaiMp=j!tF0nBSfy2kaoX9)W={$x?3-&v`P$G zKNYBfK5LBVCAT`C7RSd%9kt|K(aK47MQ!3IYhlr^IaNtZizPeuvPg=lXImo2eCf^2 ze%5)uRb+FKyG_*S>p<-4)eH40*GDmb*B9ptUo5Y|9k@~&0N^ulhsr(N13XU{z-9>p z@FpGFZ2_$6-LzBR*bHZSoS4)jvozJ)@1KsO3w;1YPbh5kgn;g^SF7_73XvwUsd)5v z->cFJnx=RtNOi9xw=iu3ssL0`;=*eRE8p|_FsG%+x{iB-r_;9LMO7cSfhRxm-d4Bq z(dE>Na!gU2lWNK|<$LOJDOi$XjoSsEbTU%@l{SMB)nWg_+^>?DBLGBEDCiW`Alyu* zqFVjLm$qmcY2~;HCl16F(Xv^L|48 zOV)LsYtcvli652vLly^2QOX`o6Hu|AdbQlWoX#O3_Ew{2{o6k(Lz>f}t+th%O`?M_ znU&Z)Z0_1`9r^nIUjaN#C`hy<;<*3mQ3-=ugI!*7#=l>~2_2fIr(Ua3kq`7-e3iTvX=g}mc zlx8wrD$<;(Uv>33(^MkKKmtrnT;eFIVfx;9Fg9r<3c<0!|ahv`Hy6&xw2q~X9Gr^LSuNyeE;fBG z(FiO}44`A_0Knl-`}}$&EQ?vqUe+xi*!WJR+Pp>QZU2w44Qm7+JWJrnW{GEDGdC01 z0L`8@I<}?IogIp;G0_^OX$frq#u0Z^gth@RP0|3DCTU>ztIsPtV069efwBiFUay=! z*v$J!GP}r-%rV2?fuR8mPwG^dEU5yt3y`6Oz9*6@7pYpfJy>n>rbSEQeP#}6mS{R@ z=Si}otqBc6paDEb0l=wAQnGE=sYkGv@n>7#iN;bLwo@GEnVvmRbL{`m@VndA*4Hh+ zW=H=&ngcXR6WE@mHLUyqU^A&X3HJ5Or7vikn8THHHQ((v$@P+a{$Bl~xVLU0ZsGO( zSMvdqN#(GBD{d4}pKlY2B*m{dXrPwQ_o3Y$vdEaSH@An09JK=4Y(q-@+%9YQ$UeBl3>ZWMM*f7>$lI>)o(h>(Fp2Rc%ug&QfKEEG>ah zE5uoKmV+Z&iHRAhtL$AUs*?*>O)h3>e_S1<1VIEhFz_GYhK z#t3u$`Yi-OK>$2W8zVkT6yx5<#mXUpR6HSXZ$Wyne_vCo|a%$BWZ7v`v4Sbze0Z;$| z;Q1*drYoy>6s2fg?L}pBM3$684oSENK$_`<5M(m@@t!iWe)luS_V=3PA=~*D^F578 z+%3c=yI5VLaae;iP-NY64xM)$tn1=ZFCpiwZK7tm5@@P3V+DtVvqFb&Mb3M|Jf<_M zsWJg$RRl3%tT)5cH0U*{w?bB8ZV?b<jD)YxXfsSW zy~jd9to0dRXESw~3oBl;2=KdFrLgFk+ONDRi9DNo)&Zr*C^q(}K_74w92|j_tXHB@ z08CFH@~0`1b}Ri+L4Z}UudjBeWMbfA&Ni@0Z-?IIgCzkgb8XCnEFgLyfNdVlO>OxL5_#|YY_%${KvqB3QC z?ENhzEiJZQ_W#?oIdwxOHZsaLYGl;N(2(U|z<+0Oz?*0002W$;7A;+9oS8GBPkTC^j`PCnqH}G`8sk00J}s zxQ|X!B>>TY0uPYc8m_ zR`x1z_SSvIV~o-6-ep;{ykIf4-u z;3~&PmReXapu9b_rxX(!S6~;!BvdLDp^6Ym3_^0*_Z*)Y$-U)bD;F)V=J|ea+Xklj z`TcA0iUMo1mWP=%&~gq#DU_qK+ZL}cKoE<&cv1j*s&$||*w_W)N3M@?)Ox`S+F~}}J zQE@GSgge89t5ey!jH@cG6w*ZPnYI7bYBx`+d~SsTOiewgsmX@F>E34`h`E@(4Q8pw zdK5`fQzdDgjupv;cctn&tA}ezELoLXRbMpf0wl=-f+WX;L*Bd3SJ}05roo2Q=XnH4 zbKIt!!ohHIFi1_Z=ze+5L)JE5O~glUS*id$OAUd|QgHH}DlhjCnFAEe)$BD{wS`$McAaha^2Lw zqQ*wzLu{Zx!VLL{B^fQ4COz?b2#J_Qb_iFK%@l0S-J-A&O|q zHgNAwlMz&^?Q-7j5W}fu>9pe%p?{m&FY|vn+Rp`rG9*oUK+O}z;J)_Tml2YzHsfd| z&_)y@>#vPK!=l0d746f*zyU;0l4DgAf98AE$(T%FtIm!$mt7Q3Yc}ic#%>E|Rn!;v z8M<_sl8m99yq$-B?6|#E%ohhNOGv`gWDmY_>XE Date: Mon, 18 Aug 2025 18:51:08 -0400 Subject: [PATCH 470/512] Make bulk cooking in cooking vessels faster --- code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm index 6b2f8917a820..0efd5985f304 100644 --- a/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm +++ b/code/modules/food/cooking/cooking_vessels/_cooking_vessel.dm @@ -125,7 +125,7 @@ if(recipe && recipe == last_recipe && recipe.can_bulk_cook) // Bulk cooking has benefits like reduced cook time // we don't just do it instantly because there's messages each time - started_cooking = world.time + (recipe.cooking_time / 2) + started_cooking = world.time + (recipe.cooking_time / 5) else started_cooking = null last_recipe = null From 1e3b0116d478666e4d7e7a95a8cbbc6a847b8ed6 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Sat, 28 Jun 2025 19:22:36 -0400 Subject: [PATCH 471/512] Add noise texture to stone walls --- .../solids/materials_solid_stone.dm | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/code/modules/materials/definitions/solids/materials_solid_stone.dm b/code/modules/materials/definitions/solids/materials_solid_stone.dm index dc692ddb16f7..5cdac448041c 100644 --- a/code/modules/materials/definitions/solids/materials_solid_stone.dm +++ b/code/modules/materials/definitions/solids/materials_solid_stone.dm @@ -25,6 +25,15 @@ ore_result_amount = 4 sound_manipulate = 'sound/foley/rockscrape.ogg' sound_dropped = 'sound/foley/rockscrape.ogg' + var/image/texture + +/decl/material/solid/stone/Initialize() + . = ..() + texture = image('icons/turf/wall_texture.dmi', "concrete") + texture.blend_mode = BLEND_MULTIPLY + +/decl/material/solid/stone/get_wall_texture() + return texture /decl/material/solid/stone/sandstone name = "sandstone" @@ -114,12 +123,3 @@ melting_point = T0C + 1200 exoplanet_rarity_plant = MAT_RARITY_NOWHERE exoplanet_rarity_gas = MAT_RARITY_NOWHERE - var/image/texture - -/decl/material/solid/stone/concrete/Initialize() - . = ..() - texture = image('icons/turf/wall_texture.dmi', "concrete") - texture.blend_mode = BLEND_MULTIPLY - -/decl/material/solid/stone/concrete/get_wall_texture() - return texture From 50a030985936811da104355a9ba994d2709ace33 Mon Sep 17 00:00:00 2001 From: Noelle Lavenza Date: Fri, 20 Jun 2025 21:22:16 -0400 Subject: [PATCH 472/512] Add basic wall cabinets --- code/game/objects/structures/wall_cabinet.dm | 35 ++++++++++++++++++ .../obj/structures/furniture/cabinet_duo.dmi | Bin 0 -> 558 bytes maps/shaded_hills/shaded_hills-inn.dmm | 24 ++++++++++++ maps/shaded_hills/shaded_hills-woods.dmm | 9 ++++- .../woods/chemistry_shack/chemistry_shack.dmm | 12 ++++++ .../suspicious_cabin/suspicious_cabin.dmm | 20 ++++++++++ nebula.dme | 1 + 7 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 code/game/objects/structures/wall_cabinet.dm create mode 100644 icons/obj/structures/furniture/cabinet_duo.dmi diff --git a/code/game/objects/structures/wall_cabinet.dm b/code/game/objects/structures/wall_cabinet.dm new file mode 100644 index 000000000000..3cc7b07bcc55 --- /dev/null +++ b/code/game/objects/structures/wall_cabinet.dm @@ -0,0 +1,35 @@ +// A wall-mounted storage object. +/obj/structure/wall_cabinet + name = "cabinet" + desc = "A wall-mounted cabinet used to store various goods and sundries, and also make use of all that wasted wall-space." + icon = 'icons/obj/structures/furniture/cabinet_duo.dmi' + icon_state = ICON_STATE_WORLD + anchored = TRUE + obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED + layer = ABOVE_HUMAN_LAYER + material_alteration = MAT_FLAG_ALTERATION_ALL + directional_offset = @'{"NORTH":{"y":-1},"SOUTH":{"y":24}}' + storage = /datum/storage/wall_cabinet + +/obj/structure/wall_cabinet/on_update_icon() + . = ..() + if(storage?.opened) + // todo: door material? glass cabinet doors could be interesting if we add a 'full' sprite + var/image/open_overlay = overlay_image(icon, "[icon_state]_open", get_color(), RESET_COLOR|KEEP_APART) + open_overlay.layer = ABOVE_HUMAN_LAYER + 0.005 + add_overlay(open_overlay) + +/datum/storage/wall_cabinet + max_storage_space = BASE_STORAGE_CAPACITY(ITEM_SIZE_GARGANTUAN) // smaller than structure fwiw + open_sound = 'sound/foley/drawer-open.ogg' + close_sound = 'sound/foley/drawer-close.ogg' + +/obj/structure/wall_cabinet/walnut + color = /decl/material/solid/organic/wood/walnut::color + material = /decl/material/solid/organic/wood/walnut + reinf_material = /decl/material/solid/organic/wood/walnut + +/obj/structure/wall_cabinet/ebony + color = /decl/material/solid/organic/wood/ebony::color + material = /decl/material/solid/organic/wood/ebony + reinf_material = /decl/material/solid/organic/wood/ebony \ No newline at end of file diff --git a/icons/obj/structures/furniture/cabinet_duo.dmi b/icons/obj/structures/furniture/cabinet_duo.dmi new file mode 100644 index 0000000000000000000000000000000000000000..adc99dcb2055e32ee3637eefb1ad93ae140ed2a0 GIT binary patch literal 558 zcmV+}0@3}6P)t<7!okUkik`s0z!IMZ-T(jq0d!JMQvg8b*k%9#0CIX%Sad{Xb7OL8aCB*J zZU6vyoKseCa&`CgQ*iP1C^0t`#5P1z6`x;_nuklNvVyCh3)lq!`~N2p zkA-e)0003=NklKq2k@uhMZ+jMXCXSw!u^ zZxJbCo_~n#nJoK{ Date: Sat, 28 Jun 2025 20:57:10 -0400 Subject: [PATCH 473/512] Improve amanita and coffee plant sprites --- .../hydroponics/plant_types/seeds_misc.dm | 6 ++++-- icons/obj/hydroponics/hydroponics_growing.dmi | Bin 45299 -> 45415 bytes 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/hydroponics/plant_types/seeds_misc.dm b/code/modules/hydroponics/plant_types/seeds_misc.dm index ea29e6249413..a36f8486b7f3 100644 --- a/code/modules/hydroponics/plant_types/seeds_misc.dm +++ b/code/modules/hydroponics/plant_types/seeds_misc.dm @@ -560,6 +560,7 @@ set_trait(TRAIT_POTENCY,10) set_trait(TRAIT_PRODUCT_ICON,"mushroom") set_trait(TRAIT_PRODUCT_COLOUR,"#ff4545") + set_trait(TRAIT_LEAVES_COLOUR,"#ff4545") // to make it so they aren't pale while immature set_trait(TRAIT_PLANT_COLOUR,"#e0ddba") set_trait(TRAIT_PLANT_ICON,"mushroom4") @@ -579,6 +580,7 @@ set_trait(TRAIT_PRODUCT_COLOUR,"#ede8ea") set_trait(TRAIT_PLANT_COLOUR,"#e6d8dd") set_trait(TRAIT_PLANT_ICON,"mushroom5") + set_trait(TRAIT_LEAVES_COLOUR,null) /datum/seed/mushroom/towercap name = "towercap" @@ -1528,8 +1530,8 @@ set_trait(TRAIT_YIELD,5) set_trait(TRAIT_PRODUCT_ICON,"treefruit") set_trait(TRAIT_PRODUCT_COLOUR,"#a80000") - set_trait(TRAIT_PLANT_COLOUR,"#749733") - set_trait(TRAIT_PLANT_ICON,"vine2") + set_trait(TRAIT_PLANT_COLOUR,"#7acf3c") + set_trait(TRAIT_PLANT_ICON,"tree2") set_trait(TRAIT_IDEAL_HEAT, 299) set_trait(TRAIT_IDEAL_LIGHT, 6) set_trait(TRAIT_WATER_CONSUMPTION, 6) diff --git a/icons/obj/hydroponics/hydroponics_growing.dmi b/icons/obj/hydroponics/hydroponics_growing.dmi index 4cfbff45b529dae210a160e1d331386f480fea4c..9e4f944856b03f9cbd726054436a0e6396f5e42e 100644 GIT binary patch delta 19524 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

    ZH_m(dG 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 delta 19407 zcmcF~cRbbM`}c>#AtMUeyP}g#$d*;IPPSyvlE@zU99czXR+*8NWG8!tkj%2TV`Oh9 z2hZ*M{r&$uujhF^ub0>Hai5RRxbEw|uJ`r6-uKcR;qEM9%vCtlSI@{@+1Abaxuc7_ z<1=Rn@=i^7-=j4zM5{WyuB%*PH-z7}@24b;G-{H*T2#P2;B6y~-M4pLM@EY6Y+wAy z?b}PgG&YPa^$s{WIY8IdH5NVVs%h3}D|HBX`loPncFn_;@9*RKfydt*1REu%ee_u( z!kk%#^yCt#R)51jC0``3V14%;YYXEt&WLZ4{h@W@^){G%S4y{Ekgu)s0`*td_GoA* zFIVo?enEkD+U%fCM(97Wp}Y@rJ-YXs`H7A13{NphxL?hF^)jA|?0GovT~roF;j5Pw zT;V%^?ei23PS(VJ6lA0!8TZQvIWht~nQR7owSr9ljXI`ZfE{19l=(^v9ZN*(S>&_$`}wmLj!pj_(#gN{AtgVtA~RFuZbT=^jCV4YE6msYk^P!LQZ~ zV?S!y^oHBioGHf<+pZ};5b@-?#3&u>|0eCOWV_bSIXAKCF2ZOiSCcT=^FRO2C})FH zjbn<%GIzdt(Am!uSE2VD|N1Iw-%5H(;X_MKH*FLw=95kk%&wJg2Mv;oVSX%0Nk5IO zCd`(8?^%=WSSbBo-?_Sz_uB+)6L0D)5-uR&WBWFwyrj;d%>Rmbq0IpGmBb{C_bn}U z2^x0sA=qngjcqN<)vuSgw(P`pQk0e$Uwd1A_MhXDk`?D~CC0usY(_?3)D~ZcV0~TW zULDCPJyQRq6!H&k_g)rclIWdj>Z+)`}j? z-1aM^_3oNNwTW^H2D`~$ua|y? zUO1WG%*_dCvLF+hm#o!AUdRnmcxlWTW8q1D^*HYFT5j>xEBo>@rQRprH_WD{|G)&M zHHBAX{1p$%TM@ao@U`Jtd9M_r+Lx3;%7N{b5AR;BtaRK((4|tlkURFH z)~tB*P*Kh>EW7&f*F;9Vw;V=cd+Ob7H`wLZJ5hT(rpVB*m-FEESL$YH9Kw6mdDs|A zc9dab&i|o@>Rb1W^sHr7$8nco6!di*b+OUbcTu=DlKjifg2)t`a$`h7W0cc^^fd0G z|6%R)?@mGpI@_W;o7roaoR}18IH)XUG(R32ek1L*(d5;z%lgf2DQb{>n4p`Ku;(G) zl@A7m&4K~jrh{{Gt}RthR=ag{7C+=!yBDq#^yU}W z(bQoB35-jEFUaF(sb>4L)wV(e{S}|AQPE+KHyewK@Q!0Jz5@Zquw8Tr$B`37v9ieW<` z!Q~MDG4f%RM8m2&=c*_1-L@ku`z-X{wUY)00T7RXf0eK|9WGK8p)pu-7^b8aAeUh% z@Z_w`h1~Y(Q_Y8Rf8cDhu!P_G*e4@@-80A6nV9!$1{VddkeRH@r=hcG1%FFDbB<5m2_oJ?3=~abntozTx5<_B|9mhNke2oQ91%qx0IsHSeg4Ov`ct7Y z0IxIXTKkp8bl*PHRmn<$4LvnN zLg-zoq30ogle~cYt$X_2X&@^y=tfGe2wSK7%WdLA_1|D*E&q@}O^b`UU;S-tJ@l(7 zg*68gJCj&<35S)T7;T@!E}r&BZ#t}7`On^QVhjpxfw@bDH(Tc-s=w{Qg7;nWhTR0x z6HA9TZ&sU6{8i}QD@4dOWx^h>{{6d@wn_pWt!Tqimxw&w-HG6RLpVpTeHxf!JW0?z zv=Num7$`C2t#q^4sNJja_|XwC&#J;s&_Wv?g3iy7$Gw#ggwGD)u66Ln zeZH{8oE-v%!qb`^bNIyL*l+rn&9pIqHQ=a~9hnHP4CFk6pFVqrfbg%7v8-%tr^Hax z&W?ybe!FA9jJK2Au-NS6lGYn40-B-7d2u{G9h#Pw*0|LrFClSQWPZAnB>!);H$YsN$ZKWb8hA3a?}3|}+qCa$ zQB^>EqCdRmQ+ui6L2yY2%DUI3jpdfwDP6zFmGO04&shgYUd^&b752I-DM4*B z$a%_db+rUt?6;WE4$a)ZE2!E*9BjLc3JA~tK~QHNP+V8zktD0}XjGAcozeW?K+;;C zb_No~?O>)i1M!5CoJ`+;jc&WQ`N!Qe7Xd;R5hMFg`knqQ5<|2p8$xlSfT(I%$(Q0C9NCtP{ZnwW6uBTJ}das`MoYrwt` z1T5V8pn%rr*tTx>moz%5Q)uklji=!mgoZbia?Vc``_RSyx|KBf0zyHLBGI!T?A&T31%eB zd}>rXdEj)M+XDTt5&4=j=ha$-wlmzqUGIYA`0n2l%&p>EeZ$$c+39{cq14+9D@vcl zp@=Cv80;p!`+}6?)$x_xPSXx4TcgArSU-<9t3R(k_HMc2u5W;pfL|#~Lfz0q2>QhX zDad6U^0$g<)=oMjAcbnv^nXkKm$rO=-K*`wa4O^KtY+s5Vkup1f}TFS5?FlJQj zkOeFm>?D3uHmQb$BcA}`V3&^KZXDtM{QI#^fu2l4VAO;or+Uz}yNIh#6kL;G)!&dy zEs~B{%Qjo2gPq>DV1kgkZBN5RZz@ev_63UUma}$t_@R2<#lf*fjhm=6g(`d6gzam) zQ2ySQaE7gM$?p|!-;1X7gd&=Q?TwlAnRl23b8U@jo{PSFqe*u$zvH2ynh)~0|q>@uzr&d@flx@X(gzZe7G;jer!># z-@psXagUyrZAyLq`~{UW&VDfm7v7fjjM1I~s-ibLRQtR;-w~?6A3{eb3G;UpQpl(w z&NK$y=cu;us`VFvYitx1D^;6@T9uNvS-EBfh!6{;IKRqR_Z+`L17(^Nsdr0m9#wC9 zbSoh==>6qiE|Ne?)rEhUZF4?U=-9=F)~Xxd6AK>9f(E{?{wqC+YeR?loE5B9qz4Wk zV}CndcxbqGH*;Xqvo`c0to@z|DYazNSM$t6YQVQ&XFquv>>owSizF8VynRsY^SVu*JgbtqDk};ea zf-)>q`@N!2JBjQryKZ_s#EelQSodUpT*(Adn&Fd@NoQ$! z8Fy~$+m$9g)kzQ2E`Ba5s{V6Rg9@cF1-vFRiR*`Cp2J-W1yk{qTkh>0E9K;a5&a%P z1OMnFR61VmzR!6{5H$3V_WO)mYhg3pw5uyGcO2QbOkKFa`H^1TOR3g7pEk=Rzc7a| z%YODRy;wFKH2h3Co_)cK60(nf_t}fN(p4d&^m9*S;UT5aZRtoRLg$D*j-xuEXMKK( z>%4pn|_^TF?3x1dh@NxaFEa`~&o-$XcXxSam^Z3t4cL}=7# zAN+e^#0S&*^GiKuwUQI#tC{=~3#Ni^xR5XH-!YavMgAvkT_&zI@luFCUq|<9@bj_t zuhwf8Z2n8FpKo!>QB^(Zv=I^S`fwJef|dJf!e47r)M6oo>FLol;-j^&_1M>d;vD~x zJO^Jf*FV{-Ld>xFN9;tjaSc7b)pQ1c6vikD9!oQp)qp{@K|Q+R_v2CEFl&3h z;-~ET{ujhW5^d9jozVwYAD|vPn5GL`Hb{CaMRR2JFwGscu?oD_jF0yE4jLB`((-OK zYiE32oDX0r;GRVWZt>ZYrc0jewz8^dIY=^HCO&Kj{pZw$w8u`g#Q$G|HHJPRS}DP7 z$9DLc@s)*LpQqU9Lw_*unu8Ukri{*0g!)1p%+m3DKDyXObn*RZ*j2)?o_#O<{5`>) zuXOaTchOH4bL-~p9_5svhv+1KZTr>`t?Z#UmbW?5-$fk9yu znlCX@J-Lg1wE!NtnOzSPVT+53nonJp{X3*GFUNG|;regR?E7Wf`gEEDSK>@^t7FZY zxQexI)n>+J?$lF*r9h$K_Uy$Z+FNm)A2aBs;$Jm6<%(j5DpoO#w|+(|ReEda{iwLO zH6wYJ8=P5rwe~W95BmfK~a`mPnHXupcwIGz1x;dKZ81k|NLPIS@)#U#}1aM zD8pFhDm+-d3=~M3cC-!-O?~i4W%AMxhC1?Y8s7U%C0kvbV!;;kZC2t99}`EwP66Lz z_mv+>OwisP7e4LEOOz?Yt1_56f|$-E<2L~wcON#q5t^@7+zp>EsW}w9YxY~DuIrLt z(A?Rl{lmAL23pBA<~Ca|9yq?SWsBxbuZKT9c>Y!pWnG*Ov+StYv@6mM%Ts1@Y0X#7 zd7kz2D&nVZCEI{_oKei8#a%YRO=Sv_xPm!I2&H z|H(iu!^FvrB0LPP^|LL65_5z2kh>}JM%=GnaCuXw5h(eNNztG0cFHyCGEM>D`ipa| z$fkHji3eH0R}IGsInGCuKY|c+;2^fcTK4_v%gLzjE`~_eiH+(eWD_kX>e)o-pEACY z{NbGA4{Gl+04gKXS^2~}t#RENWV@IiyT}~)LFakkG;RRS&qjf?e}e&EQXvuNgM8K? zC%w~XZ?{&AgsN)t7b)We@0~vwNDD@Z#327c(EFan?`*xUOZE(*{pdO9ZT+s3_>;_? z{cZ`i=twZHOUDliY%Bu)G8&;0-uTPGcK0{7y`8|q%(MkXytNR_AXz(Y>EpnVZ`$i1 zR(AOB1y8X$+j~Qv7baWI7+vJSoWx%bduiL6qOz{UF3TO!rIf=dzuqr;sI3Td{L2i{ z?8t8+k|?tTe-LB%7M^3&VKJr~jF8!mes@f#SK%?ZsBI__@$M(HM!si-zsrF8DIBt0 zeVqq9#%9e5E+vH^=KX)wBlrJt%`D~`>Q7nj>Vmo&Kp>C}*6hkVk;-q@Ha5m2o=u5u ziQZ*&fGSM*n|jBqp508?-{}?{&+y-Q9hjlGz%5w67k7fkxgq3Rw1KMFG3KA?vNy_nqjA4S4WvU*4hMq zgUH;`Pmq7v9<0SC4ENQ!azEt+;VLC6kE7g<=wo%vuR8)Hz_vz-SfbsP5_uMo;z;8g z9~3ZDno#zU>adC;lK15L*gtqj#qNS)eW_fBcLahWA|k{g$>|gCQ~d3TYB!RAtswR$ zz#Gf}UO=~D^Xq#0UgfZvt^gc%aBA+maxGxvLbh~3G(a0cQ9jw1JEp4DA7T`}Kn8lF z%FW!dS0%-I?V47{8T#uNe6z(&MWED9eb>;v=))Id`#D39k?|wqv19t)9zrzVcbdi7 zO{%b8ZZ3XT%z#UP*hBykV)K^wPW!z;jwjbJTBwxcE$Kp?}If) z|J{`7;HoKK@&;VbGpY7K`l@Hs;-@Par=9nXaZ4Eps0oj+Tem0m-|6IOKR6KQ6BNw2 z%_E&l&P?b_q(2AwDte2Q3`eN5WbaM-_GVf2*p;`Rx=4PI1SLX(-}L>Qf#A!BZw2Fe z>?oP2GHi#!OvRWo5l4@Wj60*pyiC zT7w>n(adcNa4PTSv-}?oOY6@mPAo6ilX9`olUyMuUN?rU9_8I8?emCnDbN$i-$7Fn z(pr;rVRx$EU7l?-Yb=fz_@sZ-w?j8-XL0fgbvPKP!8 z59feSlnb+-m_B+G;#ph7LO}|Z)YZvs|H|V0K)AjlC@467|Ni~0-HbC9Nrpb=(Ns76 zYixF3q?;UR>opoO$j!t(1uvcvtLV+$<3z1PFQ8Sl9-W!V`j7hWRQZLj2Iv}Bx&W+>(j1{V8c zZ}zRYvvA)D>y?zFlB=fyFbdbK}%Fl?hk&h^~t9FCc{Q+xLJ0H@; z+EG;6qt>cy*x=1yGX-OWbhq-4%_NF78lpHAZPU9Mpzl2h4z31=u*g}$}1^l|+P#ARv|69p}w+8MDj*4s&lMvP@(OpG7 zlFHG{OKrBGMjN&FX$OIgE@r zM*K+8RH2MRChdj|+Bt+-*@yTRoATBa@p^Oic7iGebY95=3e!5no~mhMxj22tk9$MHE>bv`>^p0Mv;KFk)%sUDS7+=OmZeUBBK-DX2pBxk(@55 zKcgrMB}+KSw)k?ibWtfWTzi8fywk5u=aAmos&oWc&Zi6) z!x{oH=UGTBMu-0A?%s;7H=yp;HLfGV!otP^F(XHR#q!Zi6qa*IAQ9MN0|VV*y-_<6 zMn70mrd+&%Pab9N-kj|}ah2x=4(C6$LcKv1MuR0rpF*?oKD6Pte)2)T{hiaFPev6# zHc@^;imCbCjV;r=omJKm%HG{4OxW_K8PTLnZN@<+MF}O7&gpv0TC?%3?)J)SE8_isYVw+F&14`9Zpk}W#b=PQesc0+{;UD*6}S{78=?sdE9mhIK0-~mtlsm}Jt;?!za-f|boU9Ss|gpnK+ zs7>LomCjO^Gp;rCmbuRzUk^xPET=(YB*V;2DP9G1z?0Y*)$Cb5^P9Po`NNjQ(_w9Q z6h}Xii#k!a5sKwH)-Z{>E~;d`YKeY)MWL^{P7%8auuy*84Mm9`{XG%t%zmdwk4X9< zoqeu}h8N>aGWjwqJ52$v!s+GVlU4JZo$x8XT9_@m%^HHXas*#=9?DX$etNJZc|rOL z%O3kaJl(M#bS-zx&#=K51GIPt&x zuX}9qJMVKHvsaCIig^J|qgZO>-lael7LJEGJm@dULQ=?BkY^>y6^1j_bx(UzBqCEJ zo-u*hBf`8*uZtq=s2e#RzQy7^-SCu!jjctE{RI)|HvyN;<7eNU%lpM8!^=Lol=0$# zQO0M7NbYz|bo%)zXh-!mRU{i4p6)L7MuI+1pX;H#-vLFs+zYbablF{xd3ith;HUS$ zy&Ezw{tY$NS&mFhXj~I)x~EiAUCqcF%Ijoi%!sn}!RqTbi1nH^vKuudOFYG)$_C@2 zpBAx;WM8I}{%bH)>C6U6O$e2;3ZYPFpTW!;kU%0rUJhn=yzIt`0J6d8;X^l%7nW@D z!(>x@D7D|L<-nnn)g+3Ikg!VS6mOMD(Vg;9_rD+JU!POJ04aj-(9{d4;9vEJpGc63 zfJ7`QtC13p%5$R{j6chR|K)v=Ps}*OFQwZCcXsdODal=KOJ7s0vdZzRF+|Z7JmY-T=Kx*WWiGe2Ag+NUNb+- z{a8M#&Wh2B`h66h!$&0qYY?gt8v-6nn>x~&YdXe$J^pcnYD5yd$ z1+F{6(0MiYlcEI)o!50gIh_8F2HcRvn(oWDh0~mFPH`~rSg^h0`?un$;i*MZoKsl; zRWphIByGWSnIao;&gI`l>!*r6iciV^K`X2Bb)KCqB8v?bemwQ>pE6tn=(E0@L4se- zpW1~63C~YYRn*ILu6JyF>J{YNai8w?iTP)e^zNlydkSKiE6M>??+IuE zdCZsTipj|0}Wa2&4_K5>=I5Ds^hl01zM|QsMgB(l%FTUp|dZ=@ht! zsbcLTmiyBVI`OlXB6Y_BS`M`jJRektfR()-S^-)T^&piv$OIQ4L?>Sn$i==FEo zea}>sVxZu7+c`2MT6jKhQ0jVG_5;I}N^7S6CmfP46CV-5_v^LXGk7w+>f(9I3V#7C2XgNA*nji!&}ls(Xb9CQ=#6nXtD7Yb z^YaJ%H7O{+c!KV3ueX)|$D80fwi9$&KS+bw7jN$Qlb_1%^pfA)Q9y+A;kPg%Wo%y0(X9o(jwnBqp zp9tpc7?Qik-OhJvn6-ml#%jwnS6&fk%_48of_68tO|}{AvhFb zQ@a-3QNYYjSD#EG3(dI}XEuMMtu)W%60QF+b)oSvn6hD%qjO1v&L6lRU-wHV@j_Og zVzPt3BtZnAC6T`EzD^Ye0vZ|4AD${0cMy9na|v}AN{OM*d_cRDAJO$7?+}%{FGBjA z*T0l)#4m~X&uc0Z5Ydtz1&s`E- z?Zw>svX{K((?J*0ra=M-l#724E|Pz3V*rgJ*8CQFYwD7s$-nNYzI{g!{M)ybV2jYT zpQ)dtX;XwaWJ%{zP0qdun=&pSV&%t`xl5CKM=h^*_iTe-6SyexAe+b^g|HbuGxykd z5$A@rryQ-fwUze+bu;%G9~EnfJtd@7Jk9@TsLauYU8}dvlaZ1DPwC_#MZ-oQ57zZ7 zF3Fo3j8;@edUYt>u?bqZA!(ahPwoXyWnSTPv^s#=445JcOyU^)YsTHD{nq1u)AAjLzF{w1Mo?c9xvltyu;OTi zQ1nwr@`8o7LfOX;ZwhXvo;JKq4&V`py2U`j5>#O-(6Mv++LeU7I@Ov8N<|_z0IjS= zY>G;tcuIwFI$0HKLNc-E13HPv7$eIB zNB$?>gH{MCfp8eSKwr-4pZRI_i>%GgD?*XuUi}K0->PdS2|Hah-p^erS-djSzLTfc zKwlQxe!r84ku{ab@leY6bZ_t94M%~3p6x3uWxx#pBOeiRC;#~`Z>U6}v`Wj6BWnfv zb+Fej*(76hWii3HYfem5@5%@Qri;$D%JS%N%TN6-BYA~imyJ*U5w0fKRsL6tPP0lF zJ)t`MaJ}Mik6JqU9@qE>!FxJY8~eu}x^B-C=+J32lLRIx&NqRA)z9@isfXT`e24Gz zw39Ms=q)~ZR-Bb!MgV=-Wt)|gE}h%IQrYpondN;-ku5P7$poa{CK7%ehn4dk~(VYR$kDATr1Kd0gcyI)q1&7 z$~^Fpw#K5RNLf*49pdOhuTQ)uVpYqwd!$bx8xcn4!?4Bn=<57eexx%~j6eVY63xxR z!e7G9(7OnQ5jMHAi@6yJN>GKcGFFhyK6$qb*cbF*KvOz0(xTKT7~Ctojf*w{Rsr<% zhe>B8FqZK9_v^`KkQ`j^uYHqvGCR#ea|eM=k{L##jq1pJ- zpZR}7K{Lv;d^A4YIvM6r-Umq&vm01O0wqXoAR_%L=FdPLz84XyFqDwPm!KZ1p$ZVg zD8sj8z#utPnj9G9iI%=7b$lPoNaPMb)%)9KbxB-8f?&pm%CozSCC9wTz!E5?00;-f z91M88-IRQT!ayeF(OQjeV-Tt8c#_S|!r$$Z9t^C&=CoMP+DActo8>{p1ekEP1S$O^ zZ!J~5ZKwiG!`uqU@|jYA%Fb~)IR03D>pG1r2s*!PL_C4X9#@h5y~W&K*2L+Z}>GfBsyji1w_d1nQSN+5H&MQXk>&;J?#PN?P_*xS<=)pDFx} z0yP38xxOutq6wZ9$P_5>J*Av3uGJvePg-ZzKc}cbNa_Q*T30e^i9@jfOp8xg`@FDG zqV3>}+}cTYT*t|`ZCLsbO``-8W!_rJA!%`*Nzqu3-5_B1kxj4BTX)jkH1NN^2l1)P zT`+bX0GdEan|Ha6Y97(5*|BLocDTtXNSjIlB>64XLAFMXm5xr(+XTQxm?_e!|8Hx0 z<9G~2BRfQ+Tlibyz%&c#cL+2D7upe$w@CX`qQ4w*u))0V?E&yQn)+}bc5@rNaG->3 ztgc?+Jq2A{V2hHkUy*?M0vG}SZNOnF2&2y3tJ1_1(Dd8hYu=+?#p@#^YAbwf*CBLC)A16PPDJV6%q2VGArd z*FYjnga_bK9T%I)hvr_VYV!!c`IM9t9lk4R(@MZ9iR#zZ)9FxNd%QXl@@#p-_bCx9 zQWn{g0lD`^AG{p8`RmDRcz|4C)=Ne*9SKD)=gGc!Ok{yjj`nFoE@SF_SynsJ1Hg5J zq#lafbt`LwWdI6FpvKZ7!UH9o=#`A#rC#M0H3B9&hF4+MtN)d1{Tjj7?|bA4JWSKN ziryYVU}Vog2m8FeyA40~7faF1lLJd~2ZvXl2l4mFvX`y9!%vY;`j+p*qQpp5!hIH^ zM#LKme;|2#`x-?W#OP}8f6n8f{E!kQ5I{L5EvSay|KZ9{132{c$2#OoU1;V6iGQB_``Bk zekXDO6cVOSPfWPaL0L>^xr(`948-`?r6&OA3CmKSsXc1~Z4bP_z(~@0e;RZfFmIn^ zuU?!H-h)bZqS^K0C4VA>>eC_CxtdU3d-}d3wjne+-fybYt~_*O>(w&~=;Wgkv?sb@ z1Q{d3DP>eo2i?SyBVNN%U{wQwC(n;alpN-*nJFuBe&K{yH{ zgPIvzIUaLEVNCc?mhaQ%da}-RI8b=LT0JbDAJclwS>vcmVRumDrGArOPN->YY)rYA zy<@uV24+Z?nr;Mfxt?II?WuSv$EduznK_Sh?*~cpm=N;cSL?o{~Ck*w)n_dsxf6hDt`i|K=NRS`rqifk5 z&{rZ<>{(c5zVn+G{?6=oxaujGA0Zt%wE=>D|E_Sv&L9!}%jQGjg2}t+6R4Md7%wP5DE7o6D8;=4 zF|&7~HsG+=wyOPDUrPdaZxXTR^jcM63<-7R9&%}BE9}b=ja_8mc!7-;yfe_nKI6{E zB;kK=2PVj_vduR0T5O*etNWO)1j_Seic9IPu`+9mGS^m+i4AA>J_nTn>`a`}U$B8P^%aK|qv!8T zGBHTtocp6)#q=E2K9u_>X5{)q;t)Wz-HoKdA`tIABdO&@`e8+Fb-8n5&6M_zCc@@i zC$Z>%S&B5~KR|Yugc<&S(Z0F_0=0wq$^H8Q*Wcb#0r%;&e1H9{z4x{g^!;vJ7lZB0 zhAGZpu7BO6?WEXsF!$qvD8*ZreEhsPp-EBV`qy%^F&KGwY$to>4l{J`hJ|r2Gac9I zwGR|4e^Nn;IS6Z2t|x4>>W_^a?lmI_z1;}3tAKcmR^>KSVW9^o%vp>HAOz2L>bqT# zBETe?hfViP0!+^(w#tF|MkR+gc)uHY3cURhyYV2Q$Bz5$lIO*Q^Lb!k^G;o)a%10u z#~j`X(#jeo-g1=(juYFv}K+H2qY=TgzX9 zR>f5Yh1bfi-SQ>k>waDrd9N$4CbSE%@4f5J6|s~AbtN&ES-n)NL6MBhZdZ7)@eE}x z#BeT_6;jS(K*mIFb4wni19=eGPSByE65;c5NJ*@M8qfJ-0fDjRfPu;_PfmumDb*0D z4j$s~XS0n=edJ`XCv@ao-MUKf`&NM-2a+q2K!G^b9gz`Cco3(Fg;IIzpI5IrrV<4% z=3&DHZK_R?YpxMXtwTVC%lsccu^)g%=c=0t(e*?!VWA2mQbHOg0QDb$7~3QdVa^G@ zip!v(1FxOT_AzeU?0uYDTt66 zU1!E-Q3xLT8g;u0F{GlGt#FC9fwso>pBM7^3nZ_jJ?)zAF;8o;Fmur05a^x?gT%7(@pB4+Z5Dnk=60~`)p0@ z4Ff50wriiP4}lBrH}GH^p1;lbdK_c~2jg$p)Sc#ISBW-oom7{J7;<3z?mufw zt-Ee`=8pQeF`L&BekXg!plX6<_LObY19^>pU|Eb`9kD6~T~)_%0d!f445%{UPtmGw zz42Nv0AP(?-PtI=ZPN#D%>|M^z~k$=*E6b(fXbuRR6v_|CenA(43&_ol9%=PjcZ-wq;o5% zsRa|%Rcj}|PMY?NAUZw-o;N1W&~v$KD(6ZS2J(Yb7Y4}(lR(nGW;uV@c8BwBtjWyY zoM-Jih0n|x#Iva~Q4X0g5dK;#JRiFa*3NOA=VPuEy(9!d#9snfAIVXEZ3-&L>eNN&$3muccbmn*3Oo(WDk7TOc zN?|^ty_S)w9#zs^)b!pBA*U7bTteoH)`D{Am4 zQ`Vbh`Yh}iTec-kRPy!RcxR#)zxurR=PR4<%-{Ged?O}(V=R*Ky^HO$(o6xG(!D> z?o)KZs~zQ#m$HNT9d%y5vS5lbE6CBOHz%9 z3|FciKxZ((Ac20la1PNW5hQKr>Nty19ZY=y%%y4i1n~-)E-6D(NswQ&?-C>V%7_B0 zXnNmc$I^D()dpR{r^iQ-!O5VQLk0zkn$cDHk9y3-HQoChqk_$zrOEM^im+i?9G@e+ z>Gm@dOs6xr54ki*d+Pt;n;Hp@Ti~zEk93pw?@tt zS-Z;Xm8Q^h9v_KZ217w~zM2z^-q0$R;AC&?;AhXf@IeNz_?@4}>aCku z%6fmTn#}tk1x&I5p-poB7HmR$jlV?8@ej|s)W;K3yGL?=IG4#_OGTBpf9@!L8*?ll z4X&)L{9aG(Ua5~+uuDY~10e;aU`X*CP9!K=)pz8barrb&dYq$J0O~IIN zS6wd8*eT@WnIlzEO4I=Hm@PydY_(n6u)ROEdJ$1V@;^$|ga6C^=l`~4`tx>9(wy9R zGZP+xERr!YzI(iAVhy^0;^Fe*09>~dkq`w9gE#~;sK$PzYxwb75WcOs4RE4RLyRXe zLnu0Lcy%=A#uyV0Y_vQ8ikIA6xu0zoK0ZDzBU4jTi(Y)l^XrngWCtOR$M#oW--@p{ z>uvDefBaxBnGu6Jt*)+qJujsSF;hR@qK4eQI98g7-bRAd@}{*TT5%8g@e)mwE2#!- zl$ezCRBuf0IqThg2%=a!7ZYqpIO=u3Pf0=GX}ayT&SkwEBS)vTn+?o06g->FfklOP zk53wQ;mhhqbq%270VDxZs-(<>8r0v-&bGHpv%f`0N2j?{vB~J5?%OGpaB_rELW>gv zk1N;Ib3|yq$m)HOnm_wQ2Hp);YiJJ}_jw#_Vf<;|nj!e$Puu(uX&=GvYt^<0Ykc~7 zV-d*BhQB-#t&2CLZp(eUw6$#=qq*9;IY$9WglPE9qqS%#ME^{$?mLN7Ffdj~2%y$V zzA@4|D^ZmH7-EJ1gL)(pvGa~bul-+k6iFZ2#8tUfUP@9Y5#H}MheLrm5S_PWWP*Xb zDOCK*7qfaYpcb+Wx3Hs5Vv}NFXKw{EM;Y%eh)u>Ds&by(i9}@LzE)N7ydk?vHb0jo zw2y>BP?l9^E2a5#USm7<@4!m+zHt;G$KrByv>p7CK8z6bnWWD+rT)b;8 z#Eg8y3^o$N_P!?_9UU~*r{L1>89L}69f9qE2dl-6&e@!u2q<#_y5nJz=F?T<%rL~6nYzz&t&qaP`Oz22W#nXJ+@@|8(~I=p0r_L zt@K552x4&YtVL~3zKI$SayB{tSA)o>8dVh)3m;o|gs7MZ4>za7=I7@N{0x^C7uOzEITM@`&+ZSK zSFOD8o4xINi-?dB%G&XA3naPmkoesL58VpaZ?kXXwRiJoZFR1FCQPb6I+-|Kx>RLE z@NP$cMYA?1wulB(f0kKFs7Rd$lZm`}gTwhCW-7w8{Z{h7fty(P`7uMkv@U$KK1pU9 zoS{bWKN(Zt4*j#+=7l}b)~KzkTl=n+$;q*}eGAIpxsc`Fa)7ZF@GhOm_Z{Uj8%_!K z=Sw-YOv6(|U8M}J@Po~E-U@L{EUZ$Hb13G{S9cz|jq0{AJPbI@NRWrK2|a$xdv96H z9lH7Zukref`a;su()R7gjwbKVvVsU=9QY<1VfKybMnTQO1%fTNC-YvPQYUD=bR3MG z$+Qf5GxxWc$3W<3b|AXC?(uFh{mAMAhb&u&WmeYr$%Wck4?&fjlMS#1b^B4SM*V_r z5W%i5BT_NFd}Ckq4F#+>0G27#T?Wl89D2F9K)~Ey@zu7*7RHJ5w-me@Y>l^Onh|Q- zmQolRrJ2){V;2{f7<`E1OSTw^Y5&23Ml#^O?J3V1R`!loUcAr9kg#cG3$%umLs%+O zGeuP9#N_m-vGb)LLpkPZ0`y1~{a)4hy!5Wc;S=t z2GaiV7o1Aa?Dl-e16%+A#*R3%oxuYN;iU*5)SU;9U;%b?)%($#`K{jq3ebQPsfFja z)jnXs2aX%)c_kd)Ys=w?Hm2&yy*8&puvlBQ*wgMteD}M$K?wB>@3vZc4EAh4vxq+1 zfG2B#Qd4H|mc`9UDl>80T6d@ zjm0TYiJ2@$MG)p@STU8p0X)$$Bf0ZV=^QAEb2}V;Kuef^DlC5iG{Xi~2NE`Kus~l- ztF72sS#Q+08h$Y?6+TJ0X=u7T1N#(_R1HZeq;b^ zg11=phu15IXJ%%g^Eb}pIR+a0mCYmE?hJ5l>?hetmuY^^=LIsjqF; zWp1bp5MI)UqxY3sRa63N6O=YT&s8g*{E4mFe7=^wqjQ2^o#@Q#ZCEIwKG=fPeZD)1>rZJI8C0T&^6AQJ zCrPXv-qbd&O~TWkjr*N6xUoCDGcseqS(%{a^k&BklDV4

    iVgB|hhs};qj)pIPZbtEJtE+_vyQW81e!r=E3L(R_>;s2gyZ2Zop z6y9nkq47CcsO5ais+JBmi66H|GHcZnz>xFAHv&k=_2>Eo3A_IcOZN0OK9X4i#DH-# zGqZ!b(+vCqPy2a127+^i&4%MI>vns=Dx(m!U)3k;8E@07q%VbdTifi3d}|25&|yp3 z_xyiVa;-s4Tv2#I9+ijKA`=Ay9T?;#gh3RgD9A(^3mCKkJ4GWPh-k~BL?k55Qjut( z3MmAkwZ-yKph~6+4VnjN$}6Zr3sNiz0&Y@C112B{80cAkI{jhy=RWSvIeX7{?wdnkw_c@AB68V1&hHZ=WT`7 zcEm9^XXa?L2%OTIIo=5=hrv~5mr|HqZ*Ok|*>}4e>%DX#A65!rbOt7~bC|An(feo6 z`BkW_D*(2rmf(Ud*3b2EY`ot~mJ(;MPEPvX zm&>Jr5}kFs}-&DoHfVHBP5n;U8*w|--ZA)8V zygmtI`s!n$L?}d0h5%tuqPvj(TD3*VP!r|%hI0pIS~mrOEHXhclQwTKUY9EQ@Km(V zkzjsMeyG67f1b9(;K2!}I%GClo$)%H*FzJoNwc5~c#j?%K940bXq_c-_JW1z{9T;u zU8IQdV@UUe%B{*PoxkX1&jMog;B;umMe)JGq5%YDO4+j0PoWlb0G}0c)ZmJ9vhH$iXef>s&c|K1FIXPv@sbbRDPA}m5?o3Bhbt> zwvD{%)i2m1$b>J8Pv6BHs~{}TS(?mPl+>7PF@9V!6|>dWCQZ7!dVjv}7Zd1HXa~^y zuqavBV_tEn%-whX=Fv=9%KD9rvL{C8!*sukU1-!7*J5^hFDErny*Phrc#ME(?*0PR zwc#Xn$4$laqAoJ#z+>gzQgZ5{zPFi3zC#EtY2U8U*Lb)_#>aoJuN>;Up}t&u??RYl z{j(mw$RH1EquQuXNoN}^QS>uxvlSwIxPkLcc~-&-_s`1KhnsGGe}xw~BYm3}_`z|{ zcwi2i;j#Khld;s#^R5$uvk5DA!GaXup5JiR`rS{UZ$Fdc7RuS4a_A1dXNa~iUL2y* ze!YRS+JyQ4HD>bEJXlISq}RZT=EjRX33`8E3|QHcn#|gvZ-ZDQ0$zL<+SP^Ux40PY zQ6=05=>%Pt><9^w??I$wL~ejDVNu3GApPhtl0|>M;y*$ zWMVk~6`fvN78@=(Q5lpfcg2MjI+FH|pH&tcBo9i~bX3mtgTNL`g;JUQtr>CrZgEWw z>WZ0B+;5yCmXvg7;RqWye|0bJ`;(ZI6-0`j#*K}`sDC}zDD#)79*p!OJ^W{~uJj!1t8RReoj=j70k( Date: Tue, 19 Aug 2025 23:16:19 -0400 Subject: [PATCH 474/512] Fix staging branch dreamchecker errors --- .../reagent_containers/condiments/_condiment_large.dm | 6 ------ .../reagent_containers/condiments/_condiment_small.dm | 9 --------- 2 files changed, 15 deletions(-) diff --git a/code/modules/reagents/reagent_containers/condiments/_condiment_large.dm b/code/modules/reagents/reagent_containers/condiments/_condiment_large.dm index 453aebbcc9a1..877b64b928bd 100644 --- a/code/modules/reagents/reagent_containers/condiments/_condiment_large.dm +++ b/code/modules/reagents/reagent_containers/condiments/_condiment_large.dm @@ -4,9 +4,3 @@ volume = 500 w_class = ITEM_SIZE_LARGE use_condiment_name = FALSE - -/obj/item/chems/condiment/large/salt/update_container_desc() - return - -/obj/item/chems/condiment/large/salt/on_update_icon() - return diff --git a/code/modules/reagents/reagent_containers/condiments/_condiment_small.dm b/code/modules/reagents/reagent_containers/condiments/_condiment_small.dm index 0ad0fd5fc498..9c92a450df16 100644 --- a/code/modules/reagents/reagent_containers/condiments/_condiment_small.dm +++ b/code/modules/reagents/reagent_containers/condiments/_condiment_small.dm @@ -5,12 +5,3 @@ amount_per_transfer_from_this = 1 volume = 20 use_condiment_name = FALSE - -/obj/item/chems/condiment/small/update_center_of_mass() - return - -/obj/item/chems/condiment/small/update_container_desc() - return - -/obj/item/chems/condiment/small/on_update_icon() - return From 9438200c681e250497c3cc37c0ead679b18deddf Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 21 Aug 2025 20:12:58 +1000 Subject: [PATCH 475/512] Automatic changelog generation for PR #5105 [ci skip] --- html/changelogs/AutoChangeLog-pr-5105.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5105.yml diff --git a/html/changelogs/AutoChangeLog-pr-5105.yml b/html/changelogs/AutoChangeLog-pr-5105.yml new file mode 100644 index 000000000000..f729008ff764 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5105.yml @@ -0,0 +1,5 @@ +author: Sutures +changes: + - {soundadd: added ambience to Shaded Hills river and swamp areas} + - {tweak: ambience should be louder and more frequent overall} +delete-after: true From 15e0092556b100c7d9a2828504e8c6ee73dacfa9 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 21 Aug 2025 20:15:16 +1000 Subject: [PATCH 476/512] Automatic changelog generation for PR #5110 [ci skip] --- html/changelogs/AutoChangeLog-pr-5110.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5110.yml diff --git a/html/changelogs/AutoChangeLog-pr-5110.yml b/html/changelogs/AutoChangeLog-pr-5110.yml new file mode 100644 index 000000000000..c20f99b900fa --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5110.yml @@ -0,0 +1,5 @@ +author: Sutures +changes: + - {imageadd: added new amanita mushroom plant growth states} + - {tweak: changed coffee plant growth states} +delete-after: true From 9b2bc9540adc61a3153b23377efae8f8d7691601 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 21 Aug 2025 20:15:40 +1000 Subject: [PATCH 477/512] Automatic changelog generation for PR #5108 [ci skip] --- html/changelogs/AutoChangeLog-pr-5108.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5108.yml diff --git a/html/changelogs/AutoChangeLog-pr-5108.yml b/html/changelogs/AutoChangeLog-pr-5108.yml new file mode 100644 index 000000000000..f3809a3b2716 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5108.yml @@ -0,0 +1,4 @@ +author: Sutures +changes: + - {tweak: stone walls now have a slight noise effect on their sprite} +delete-after: true From 61578f888f08a992cbc0532f92f08c8b28f00b75 Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 21 Aug 2025 20:17:58 +1000 Subject: [PATCH 478/512] Automatic changelog generation for PR #5107 [ci skip] --- html/changelogs/AutoChangeLog-pr-5107.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5107.yml diff --git a/html/changelogs/AutoChangeLog-pr-5107.yml b/html/changelogs/AutoChangeLog-pr-5107.yml new file mode 100644 index 000000000000..2f1151c46a2c --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5107.yml @@ -0,0 +1,4 @@ +author: Sutures +changes: + - {soundadd: added a boiling-water sound to cooking pots on Shaded Hills} +delete-after: true From 22c8dfd3bf43ec9f3acad1e2373d9c5c72d24d3b Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Fri, 22 Aug 2025 00:58:47 +0000 Subject: [PATCH 479/512] Automatic changelog generation [ci skip] --- html/changelog.html | 11 +++++++++++ html/changelogs/.all_changelog.yml | 8 ++++++++ html/changelogs/AutoChangeLog-pr-5105.yml | 5 ----- html/changelogs/AutoChangeLog-pr-5107.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5108.yml | 4 ---- html/changelogs/AutoChangeLog-pr-5110.yml | 5 ----- 6 files changed, 19 insertions(+), 18 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-5105.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5107.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5108.yml delete mode 100644 html/changelogs/AutoChangeLog-pr-5110.yml diff --git a/html/changelog.html b/html/changelog.html index 2aecab0a3e31..581a7cf42779 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -51,6 +51,17 @@ -->

    + +

    22 August 2025

    +

    Sutures updated:

    +
      +
    • added new amanita mushroom plant growth states
    • +
    • changed coffee plant growth states
    • +
    • added ambience to Shaded Hills river and swamp areas
    • +
    • ambience should be louder and more frequent overall
    • +
    • stone walls now have a slight noise effect on their sprite
    • +
    • added a boiling-water sound to cooking pots on Shaded Hills
    • +
    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 6358b713724c..b60666410e5c 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -15030,3 +15030,11 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2025-04-14: Zandario: - admin: Added a "Toggle Browser Inspect" debug verb for debugging UIs +2025-08-22: + Sutures: + - imageadd: added new amanita mushroom plant growth states + - tweak: changed coffee plant growth states + - soundadd: added ambience to Shaded Hills river and swamp areas + - tweak: ambience should be louder and more frequent overall + - tweak: stone walls now have a slight noise effect on their sprite + - soundadd: added a boiling-water sound to cooking pots on Shaded Hills diff --git a/html/changelogs/AutoChangeLog-pr-5105.yml b/html/changelogs/AutoChangeLog-pr-5105.yml deleted file mode 100644 index f729008ff764..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5105.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Sutures -changes: - - {soundadd: added ambience to Shaded Hills river and swamp areas} - - {tweak: ambience should be louder and more frequent overall} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-pr-5107.yml b/html/changelogs/AutoChangeLog-pr-5107.yml deleted file mode 100644 index 2f1151c46a2c..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5107.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Sutures -changes: - - {soundadd: added a boiling-water sound to cooking pots on Shaded Hills} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-pr-5108.yml b/html/changelogs/AutoChangeLog-pr-5108.yml deleted file mode 100644 index f3809a3b2716..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5108.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: Sutures -changes: - - {tweak: stone walls now have a slight noise effect on their sprite} -delete-after: true diff --git a/html/changelogs/AutoChangeLog-pr-5110.yml b/html/changelogs/AutoChangeLog-pr-5110.yml deleted file mode 100644 index c20f99b900fa..000000000000 --- a/html/changelogs/AutoChangeLog-pr-5110.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: Sutures -changes: - - {imageadd: added new amanita mushroom plant growth states} - - {tweak: changed coffee plant growth states} -delete-after: true From 998f944bb89ce45d66509b3f1e9c5fce7af21495 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 24 Aug 2025 09:25:11 -0400 Subject: [PATCH 480/512] Fix missing parent call in nugget box icon code --- code/game/objects/items/weapons/storage/nuggets.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/items/weapons/storage/nuggets.dm b/code/game/objects/items/weapons/storage/nuggets.dm index 3ecc72ce2270..c8a8b1602fc2 100644 --- a/code/game/objects/items/weapons/storage/nuggets.dm +++ b/code/game/objects/items/weapons/storage/nuggets.dm @@ -32,6 +32,7 @@ . += /obj/item/food/nugget /obj/item/box/nuggets/on_update_icon() + . = ..() var/datum/storage/box/nuggets/nugget_box = storage if(length(contents) == 0 || !istype(nugget_box)) icon_state = "[initial(icon_state)]_empty" From c4748d3f62e9d9cd78d23a02276f74d4d8429b08 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 24 Aug 2025 09:16:31 -0400 Subject: [PATCH 481/512] Fix chat filters being broken --- code/modules/chat_filter/_chat_filter.dm | 44 +++++++++++++++--------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/code/modules/chat_filter/_chat_filter.dm b/code/modules/chat_filter/_chat_filter.dm index 7e9ce18e77a0..ea96abac60af 100644 --- a/code/modules/chat_filter/_chat_filter.dm +++ b/code/modules/chat_filter/_chat_filter.dm @@ -1,21 +1,29 @@ var/global/list/chat_blockers_in_use var/global/list/chat_modifiers_in_use -/proc/build_filter_lists() +/proc/_get_chat_filters_in_use() global.chat_blockers_in_use = list() global.chat_modifiers_in_use = list() - var/list/all_filters = decls_repository.get_decls_of_type(/decl/chat_filter) - for(var/filtertype in all_filters) - var/decl/chat_filter/chat_filter = all_filters[filtertype] - if(!chat_filter.disabled) - if(chat_filter.can_deny_message) - global.chat_blockers_in_use += chat_filter - if(chat_filter.can_modify_message) - global.chat_modifiers_in_use += chat_filter - return TRUE + for(var/decl/chat_filter/chat_filter in decls_repository.get_decls_of_type_unassociated(/decl/chat_filter)) + if(chat_filter.disabled) + continue + if(chat_filter.can_deny_message) + global.chat_blockers_in_use += chat_filter + if(chat_filter.can_modify_message) + global.chat_modifiers_in_use += chat_filter + +/proc/get_chat_blockers_in_use() + if(!global.chat_blockers_in_use) + _get_chat_filters_in_use() + return global.chat_blockers_in_use + +/proc/get_chat_modifiers_in_use() + if(!global.chat_modifiers_in_use) + _get_chat_filters_in_use() + return global.chat_modifiers_in_use /proc/filter_block_message(var/mob/speaker, var/msg) - for(var/decl/chat_filter/chat_filter in global.chat_blockers_in_use) + for(var/decl/chat_filter/chat_filter in get_chat_blockers_in_use()) var/match = chat_filter.match(msg) if(match) var/deny_msg = chat_filter.deny(speaker, match) @@ -25,7 +33,7 @@ var/global/list/chat_modifiers_in_use /proc/filter_modify_message(var/msg) . = msg - for(var/decl/chat_filter/chat_filter in global.chat_modifiers_in_use) + for(var/decl/chat_filter/chat_filter in get_chat_modifiers_in_use()) var/match = chat_filter.match(.) if(match) . = chat_filter.replace(., match) @@ -50,9 +58,10 @@ var/global/list/chat_modifiers_in_use /client/verb/check_message_filters() set name = "Check Message Filters" set category = "OOC" - if(length(global.chat_blockers_in_use)) + var/list/blockers_in_use = get_chat_blockers_in_use() + if(length(blockers_in_use)) to_chat(usr, "The following filters are being used to block messages:
    ") - for(var/decl/chat_filter/chat_filter in global.chat_blockers_in_use) + for(var/decl/chat_filter/chat_filter in blockers_in_use) to_chat(usr, "[chat_filter.name]
    [chat_filter.summary]
    ") else to_chat(usr, "There are no filters being used to block messages currently.") @@ -60,9 +69,10 @@ var/global/list/chat_modifiers_in_use /client/verb/check_message_modifiers() set name = "Check Message Modifiers" set category = "OOC" - if(length(global.chat_modifiers_in_use)) + var/list/modifiers_in_use = get_chat_modifiers_in_use() + if(length(modifiers_in_use)) to_chat(usr, "The following filters can be used to modify messages:
    ") - for(var/decl/chat_filter/chat_filter in global.chat_modifiers_in_use) + for(var/decl/chat_filter/chat_filter in modifiers_in_use) to_chat(usr, "[chat_filter.name]
    [chat_filter.summary]
    ") else - to_chat(usr, "There are no avaiable filters for modifying messages currently.") + to_chat(usr, "There are no available filters for modifying messages currently.") From cf4dee71d18086d8536c12f94c286cbab5ddae1e Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Thu, 28 Aug 2025 20:25:25 +1000 Subject: [PATCH 482/512] Automatic changelog generation for PR #5102 [ci skip] --- html/changelogs/AutoChangeLog-pr-5102.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 html/changelogs/AutoChangeLog-pr-5102.yml diff --git a/html/changelogs/AutoChangeLog-pr-5102.yml b/html/changelogs/AutoChangeLog-pr-5102.yml new file mode 100644 index 000000000000..845674f28c76 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-5102.yml @@ -0,0 +1,4 @@ +author: Elizabeth +changes: + - {imageadd: added some variant sprites for cobblestone and running bond paths} +delete-after: true From 4b5945f733a464986193572fa4e64947513dfccd Mon Sep 17 00:00:00 2001 From: NebulaSS13Bot Date: Fri, 29 Aug 2025 00:55:12 +0000 Subject: [PATCH 483/512] Automatic changelog generation [ci skip] --- html/changelog.html | 6 ++++++ html/changelogs/.all_changelog.yml | 3 +++ html/changelogs/AutoChangeLog-pr-5102.yml | 4 ---- 3 files changed, 9 insertions(+), 4 deletions(-) delete mode 100644 html/changelogs/AutoChangeLog-pr-5102.yml diff --git a/html/changelog.html b/html/changelog.html index 581a7cf42779..02e47675ee10 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,6 +52,12 @@ -->
    +

    29 August 2025

    +

    Elizabeth updated:

    +
      +
    • added some variant sprites for cobblestone and running bond paths
    • +
    +

    22 August 2025

    Sutures updated: