From 5be7f11d03cb51bbd5b53f75784688c4c310b781 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 23 Sep 2023 07:22:02 +1000 Subject: [PATCH 01/33] Fixes AI joining and HUD creation. --- code/_onclick/hud/ai.dm | 3 ++- maps/exodus/exodus-2.dmm | 30 ++++++++++++------------------ maps/ministation/ministation.dmm | 4 +--- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm index 1c99ce6d77d..707b08b14d0 100644 --- a/code/_onclick/hud/ai.dm +++ b/code/_onclick/hud/ai.dm @@ -2,6 +2,7 @@ hud_type = /datum/hud/ai /datum/hud/ai/FinalizeInstantiation() + adding = list() var/list/ai_hud_data = decls_repository.get_decls_of_subtype(/decl/ai_hud) for(var/elem_type in ai_hud_data) var/decl/ai_hud/ai_hud = ai_hud_data[elem_type] @@ -14,4 +15,4 @@ ai_hud.input_args ) if(mymob?.client) - mymob.client.screen = list(adding) + mymob.client.screen += adding diff --git a/maps/exodus/exodus-2.dmm b/maps/exodus/exodus-2.dmm index 5f8bc0090d1..0d2a591401e 100644 --- a/maps/exodus/exodus-2.dmm +++ b/maps/exodus/exodus-2.dmm @@ -7059,7 +7059,7 @@ /area/exodus/maintenance/auxsolarstarboard) "aoK" = ( /obj/machinery/faxmachine{ - anchored = 0; + anchored = 0 }, /obj/structure/table/reinforced, /obj/machinery/newscaster{ @@ -28776,9 +28776,6 @@ /turf/simulated/floor/tiled/steel_grid, /area/exodus/hallway/primary/central_one) "bjc" = ( -/obj/abstract/landmark/start{ - name = "AI" - }, /obj/machinery/newscaster{ pixel_x = 32; pixel_y = 32 @@ -28809,7 +28806,7 @@ /obj/item/radio/intercom{ pixel_y = 22 }, -/obj/structure/aicore/deactivated, +/obj/abstract/landmark/start/ai, /turf/simulated/floor/bluegrid, /area/exodus/turret_protected/ai) "bjd" = ( @@ -32793,10 +32790,10 @@ /obj/machinery/portable_atmospherics/powered/scrubber/huge, /obj/effect/floor_decal/industrial/outline/yellow, /obj/structure/window/borosilicate_reinforced{ - dir = 4; + dir = 4 }, /obj/structure/window/borosilicate_reinforced{ - dir = 1; + dir = 1 }, /turf/simulated/floor/plating, /area/exodus/research/mixing) @@ -33587,10 +33584,10 @@ /obj/machinery/portable_atmospherics/powered/scrubber/huge, /obj/effect/floor_decal/industrial/outline/yellow, /obj/structure/window/borosilicate_reinforced{ - dir = 8; + dir = 8 }, /obj/structure/window/borosilicate_reinforced{ - dir = 1; + dir = 1 }, /turf/simulated/floor/plating, /area/exodus/research/mixing) @@ -36718,7 +36715,7 @@ /obj/machinery/portable_atmospherics/powered/scrubber/huge, /obj/effect/floor_decal/industrial/outline/yellow, /obj/structure/window/borosilicate_reinforced{ - dir = 1; + dir = 1 }, /turf/simulated/floor/plating, /area/exodus/research/mixing) @@ -36946,7 +36943,7 @@ dir = 4 }, /obj/structure/window/borosilicate_reinforced{ - dir = 4; + dir = 4 }, /turf/simulated/floor/tiled/white, /area/exodus/research/mixing) @@ -36954,7 +36951,7 @@ /obj/machinery/portable_atmospherics/canister, /obj/effect/floor_decal/corner/purple/three_quarters, /obj/structure/window/borosilicate_reinforced{ - dir = 8; + dir = 8 }, /turf/simulated/floor/tiled/white, /area/exodus/research/mixing) @@ -63356,8 +63353,8 @@ /area/ship/exodus_pod_mining) "doN" = ( /obj/abstract/level_data_spawner/main_level{ - name = "Exodus Operations Deck"; -}, + name = "Exodus Operations Deck" + }, /turf/space, /area/space) "drB" = ( @@ -64950,9 +64947,6 @@ /obj/structure/table, /turf/simulated/floor/tiled/white, /area/exodus/research/robotics) -"wTf" = ( -/turf/simulated/floor/airless, -/area/exodus/turret_protected/ai) "wTp" = ( /obj/machinery/atmospherics/pipe/simple/hidden/supply{ dir = 6 @@ -93985,7 +93979,7 @@ auR avS avU fPF -wTf +eEn beb bgW aoi diff --git a/maps/ministation/ministation.dmm b/maps/ministation/ministation.dmm index e7fa179769a..6763dee4256 100644 --- a/maps/ministation/ministation.dmm +++ b/maps/ministation/ministation.dmm @@ -13927,9 +13927,7 @@ pixel_x = 27; pixel_y = 5 }, -/obj/abstract/landmark/start{ - name = "AI" - }, +/obj/abstract/landmark/start/ai, /obj/machinery/network/requests_console{ department = "AI"; pixel_x = 32; From a92444860c7932972613dff64c835712d40a287b Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 23 Sep 2023 10:56:39 +1000 Subject: [PATCH 02/33] QDELETED checks on thrownthing after scav runtimes. --- code/controllers/subsystems/throwing.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystems/throwing.dm b/code/controllers/subsystems/throwing.dm index 4c6dfbb6ccd..dfadbd42bdd 100644 --- a/code/controllers/subsystems/throwing.dm +++ b/code/controllers/subsystems/throwing.dm @@ -182,9 +182,10 @@ SUBSYSTEM_DEF(throwing) if(!hit) thrownthing.throw_impact(get_turf(thrownthing), src) // we haven't hit something yet and we still must, let's hit the ground. - thrownthing.space_drift(init_dir) + if(!QDELETED(thrownthing)) + thrownthing.space_drift(init_dir) - if(t_target) + if(t_target && !QDELETED(thrownthing)) thrownthing.throw_impact(t_target, src) if (callback) From 2a060488d46b8ba908b26cfa1f8a563cd35c5e06 Mon Sep 17 00:00:00 2001 From: "natakilar@gmail.com" Date: Sat, 23 Sep 2023 13:36:44 -0400 Subject: [PATCH 03/33] Network camera fixes --- code/game/machinery/camera/_camera_device.dm | 3 ++- code/game/machinery/camera/camera.dm | 4 ++-- code/game/machinery/camera/presets.dm | 15 +++++++-------- maps/exodus/exodus_cameras.dm | 14 +++++++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/code/game/machinery/camera/_camera_device.dm b/code/game/machinery/camera/_camera_device.dm index aba5e522a61..6fa7a539f25 100644 --- a/code/game/machinery/camera/_camera_device.dm +++ b/code/game/machinery/camera/_camera_device.dm @@ -12,7 +12,7 @@ var/xray_enabled = FALSE has_commands = TRUE -/datum/extension/network_device/camera/New(datum/holder, n_id, n_key, c_type, autojoin, list/preset_channels, camera_name, camnet_enabled = TRUE, req_connection = TRUE) +/datum/extension/network_device/camera/New(datum/holder, n_id, n_key, r_type, autojoin, list/preset_channels, camera_name, camnet_enabled = TRUE, req_connection = TRUE) if(length(preset_channels)) channels = preset_channels.Copy() . = ..() @@ -22,6 +22,7 @@ display_name = camera_name /datum/extension/network_device/camera/post_construction() + . = ..() if(cameranet_enabled) cameranet.add_source(holder) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 1c568833574..70bda310465 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -192,7 +192,7 @@ if (istype(AM, /obj)) var/obj/O = AM if (O.throwforce >= src.toughness) - visible_message("[src] was hit by [O].") + visible_message(SPAN_WARNING("[src] was hit by [O]!")) take_damage(O.throwforce) /obj/machinery/camera/physical_attack_hand(mob/living/carbon/human/user) @@ -200,7 +200,7 @@ return if(user.species.can_shred(user)) user.do_attack_animation(src) - visible_message("\The [user] slashes at [src]!") + visible_message(SPAN_WARNING("\The [user] slashes at [src]!")) playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) add_hiddenprint(user) take_damage(25) diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm index 62bf538ecfe..30ee583beec 100644 --- a/code/game/machinery/camera/presets.dm +++ b/code/game/machinery/camera/presets.dm @@ -1,32 +1,31 @@ /obj/machinery/camera/network/engineering preset_channels = list(CAMERA_CAMERA_CHANNEL_ENGINEERING) - initial_access = list(access_engine) + req_access = list(access_engine) /obj/machinery/camera/network/ert preset_channels = list(CAMERA_CHANNEL_ERT) cameranet_enabled = FALSE - initial_access = list(access_engine) + req_access = list(access_engine) /obj/machinery/camera/network/medbay preset_channels = list(CAMERA_CHANNEL_MEDICAL) - initial_access = list(access_medical) - + req_access = list(access_medical) /obj/machinery/camera/network/mercenary preset_channels = list(CAMERA_CHANNEL_MERCENARY) cameranet_enabled = FALSE - initial_access = list(access_mercenary) + req_access = list(access_mercenary) /obj/machinery/camera/network/mining preset_channels = list(CAMERA_CHANNEL_MINE) - initial_access = list(access_mining) + req_access = list(access_mining) /obj/machinery/camera/network/research preset_channels = list(CAMERA_CHANNEL_RESEARCH) - initial_access = list(access_research) + req_access = list(access_research) /obj/machinery/camera/network/security preset_channels = list(CAMERA_CHANNEL_SECURITY) - initial_access = list(access_security) + req_access = list(access_security) /obj/machinery/camera/network/television preset_channels = list(CAMERA_CHANNEL_TELEVISION) diff --git a/maps/exodus/exodus_cameras.dm b/maps/exodus/exodus_cameras.dm index 8164f3995c9..1f5d4b51ee3 100644 --- a/maps/exodus/exodus_cameras.dm +++ b/maps/exodus/exodus_cameras.dm @@ -8,37 +8,37 @@ var/global/const/CAMERA_CHANNEL_ENGINEERING_OUTPOST = "Engineering Outpost" // Networks /obj/machinery/camera/network/command preset_channels = list(CAMERA_CHANNEL_COMMAND) - initial_access = list(access_heads) + req_access = list(access_heads) /obj/machinery/camera/network/crescent preset_channels = list(CAMERA_CHANNEL_CRESCENT) /obj/machinery/camera/network/engine preset_channels = list(CAMERA_CHANNEL_ENGINE) - initial_access = list(access_engine) + req_access = list(access_engine) /obj/machinery/camera/network/engineering_outpost preset_channels = list(CAMERA_CHANNEL_ENGINEERING_OUTPOST) - initial_access = list(access_engine) + req_access = list(access_engine) // Motion /obj/machinery/camera/motion/engineering_outpost preset_channels = list(CAMERA_CHANNEL_ENGINEERING_OUTPOST) - initial_access = list(access_engine) + req_access = list(access_engine) // All Upgrades /obj/machinery/camera/all/command preset_channels = list(CAMERA_CHANNEL_COMMAND) - initial_access = list(access_heads) + req_access = list(access_heads) // Compile stubs. /obj/machinery/camera/motion/command preset_channels = list(CAMERA_CHANNEL_COMMAND) - initial_access = list(access_heads) + req_access = list(access_heads) /obj/machinery/camera/network/maintenance preset_channels = list(CAMERA_CAMERA_CHANNEL_ENGINEERING) - initial_access = list(access_engine) + req_access = list(access_engine) /obj/machinery/camera/xray/security preset_channels = list(CAMERA_CHANNEL_SECURITY) From 88ae4d3c8e33b4f51fbef970a1890596fd020a10 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 23 Sep 2023 09:54:16 +1000 Subject: [PATCH 04/33] Adding qdeleted checks to blood_splatter() returns. --- code/modules/mob/living/carbon/human/human.dm | 8 ++++---- .../modules/mob/living/simple_animal/simple_animal.dm | 11 ++++++----- code/modules/reagents/chems/chems_blood.dm | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index af5a1748500..1343b119a91 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1189,10 +1189,10 @@ if(damage && P.damtype == BRUTE) var/hit_dir = get_dir(P.starting, src) var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir) - B.icon_state = pick("dir_splatter_1","dir_splatter_2") - var/scale = min(1, round(P.damage / 50, 0.2)) - B.set_scale(scale) - + if(!QDELETED(B)) + B.icon_state = pick("dir_splatter_1","dir_splatter_2") + var/scale = min(1, round(P.damage / 50, 0.2)) + B.set_scale(scale) new /obj/effect/temp_visual/bloodsplatter(loc, hit_dir, species.get_blood_color(src)) /mob/living/carbon/human/has_dexterity(var/dex_level) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 84d4b22a078..c3472b61060 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -521,11 +521,12 @@ if(P.damtype == BRUTE) var/hit_dir = get_dir(P.starting, src) var/obj/effect/decal/cleanable/blood/B = blood_splatter(get_step(src, hit_dir), src, 1, hit_dir) - B.icon_state = pick("dir_splatter_1","dir_splatter_2") - B.basecolor = bleed_colour - var/scale = min(1, round(mob_size / MOB_SIZE_MEDIUM, 0.1)) - B.set_scale(scale) - B.update_icon() + if(!QDELETED(B)) + B.icon_state = pick("dir_splatter_1","dir_splatter_2") + B.basecolor = bleed_colour + var/scale = min(1, round(mob_size / MOB_SIZE_MEDIUM, 0.1)) + B.set_scale(scale) + B.update_icon() /mob/living/simple_animal/handle_fire() return diff --git a/code/modules/reagents/chems/chems_blood.dm b/code/modules/reagents/chems/chems_blood.dm index e11c484fd78..25b5429a763 100644 --- a/code/modules/reagents/chems/chems_blood.dm +++ b/code/modules/reagents/chems/chems_blood.dm @@ -59,7 +59,7 @@ blood_splatter(T, src, 1) else if(isalien(W)) var/obj/effect/decal/cleanable/blood/B = blood_splatter(T, holder.my_atom, 1) - if(B) + if(!QDELETED(B)) B.blood_DNA["UNKNOWN DNA STRUCTURE"] = "X*" /decl/material/liquid/blood/affect_ingest(var/mob/living/M, var/removed, var/datum/reagents/holder) From c8348c2c7ac98010f93d91d085083581abe27709 Mon Sep 17 00:00:00 2001 From: Knighted Illithid Date: Mon, 25 Sep 2023 16:14:18 +0300 Subject: [PATCH 05/33] Multi-item recipes fix #3382 (fixed) --- code/datums/recipe.dm | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm index 061b47ed3fc..3a74896845c 100644 --- a/code/datums/recipe.dm +++ b/code/datums/recipe.dm @@ -95,7 +95,7 @@ needed_items -= itype else needed_items -= itype - break + // break if(!length(container_contents)) break return !length(needed_items) @@ -128,10 +128,15 @@ //Find items we need if (LAZYLEN(items)) for (var/i in items) - var/obj/item/I = locate(i) in container_contents - if (I && I.reagents) - I.reagents.trans_to_holder(buffer,I.reagents.total_volume) - qdel(I) + var/cnt = 1 + if (isnum(items[i])) + cnt = items[i] + for (cnt, cnt > 0, cnt--) + var/obj/item/I = locate(i) in container_contents + if (I && I.reagents) + container_contents -= I + I.reagents.trans_to_holder(buffer,I.reagents.total_volume) + qdel(I) //Find fruits if (LAZYLEN(fruit)) From 883ecbbf929035170d3766ca3e016e919e6de97d Mon Sep 17 00:00:00 2001 From: Knighted Illithid <37145478+cyberillithid@users.noreply.github.com> Date: Mon, 25 Sep 2023 21:53:59 +0300 Subject: [PATCH 06/33] Update code/datums/recipe.dm per @out-of-phaze suggestion Co-authored-by: Penelope Haze --- code/datums/recipe.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/datums/recipe.dm b/code/datums/recipe.dm index 3a74896845c..b79198b50c3 100644 --- a/code/datums/recipe.dm +++ b/code/datums/recipe.dm @@ -93,8 +93,10 @@ --needed_items[itype] if(needed_items[itype] <= 0) needed_items -= itype + break else needed_items -= itype + break // break if(!length(container_contents)) break From 973d5b87b47989f898aaaa9a7deee4b5c64acb34 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 24 Sep 2023 22:36:19 +1000 Subject: [PATCH 07/33] Adding icon updates to hydrotray. --- code/modules/hydroponics/trays/tray.dm | 4 +++- code/modules/hydroponics/trays/tray_process.dm | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 171cd6d959b..f313d123fbd 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -466,11 +466,12 @@ if(weedlevel > 0) user.visible_message("[user] starts uprooting the weeds.", "You remove the weeds from the [src].") weedlevel = 0 + update_icon() if(seed) var/needed_skill = seed.mysterious ? SKILL_ADEPT : SKILL_BASIC if(!user.skill_check(SKILL_BOTANY, needed_skill)) plant_health -= rand(40,60) - check_plant_health(1) + check_plant_health() else to_chat(user, "This plot is completely devoid of weeds. It doesn't need uprooting.") @@ -489,6 +490,7 @@ toxins += spray.toxicity pestlevel -= spray.pest_kill_str weedlevel -= spray.weed_kill_str + update_icon() to_chat(user, "You spray [src] with [O].") playsound(loc, 'sound/effects/spray3.ogg', 50, 1, -6) qdel(O) diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm index 034e2c54abd..fa797f11ee1 100644 --- a/code/modules/hydroponics/trays/tray_process.dm +++ b/code/modules/hydroponics/trays/tray_process.dm @@ -119,7 +119,7 @@ // Handle life and death. // When the plant dies, weeds thrive and pests die off. - check_plant_health(0) + check_plant_health(FALSE) // If enough time (in cycles, not ticks) has passed since the plant was harvested, we're ready to harvest again. if((age > seed.get_trait(TRAIT_MATURATION)) && \ From 90d32578e903449d0fc47b0b7355b81e0adeffae Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sun, 24 Sep 2023 22:38:29 +1000 Subject: [PATCH 08/33] Tweaking the ZAS checks in playsound volume code. --- code/game/sound.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/sound.dm b/code/game/sound.dm index ff66f17de2d..e26f2cabdb6 100644 --- a/code/game/sound.dm +++ b/code/game/sound.dm @@ -55,8 +55,8 @@ var/global/const/FALLOFF_SOUNDS = 0.5 volume *= pressure_factor - if(!turf_source.blocks_air && (T.zone || turf_source.zone) && T.zone != turf_source.zone) - volume -= 30 + if(!turf_source.blocks_air && T.zone != turf_source.zone) + volume = round(volume * 0.7) // quick and dirty volume reduction from ZAS flood fill return volume /mob/proc/playsound_local(var/turf/turf_source, soundin, vol as num, vary, frequency, falloff, is_global, extrarange, override_env, envdry, envwet) From 4b1ff2b5b1f610ee0372d67b9e60eb7be32e26cb Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 28 Sep 2023 22:00:24 +1000 Subject: [PATCH 09/33] Expands Bee area to cover all tiles. --- maps/tradeship/tradeship-2.dmm | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/maps/tradeship/tradeship-2.dmm b/maps/tradeship/tradeship-2.dmm index a0b7d886d5a..03a22389ba0 100644 --- a/maps/tradeship/tradeship-2.dmm +++ b/maps/tradeship/tradeship-2.dmm @@ -4749,7 +4749,7 @@ dir = 1 }, /turf/space, -/area/space) +/area/ship/trade/shuttle/outgoing/general) "oi" = ( /obj/machinery/vending/snack{ dir = 4 @@ -6994,7 +6994,7 @@ dir = 1 }, /turf/space, -/area/space) +/area/ship/trade/shuttle/outgoing/general) "Nc" = ( /obj/structure/disposalpipe/segment{ dir = 4; @@ -7175,16 +7175,6 @@ /obj/machinery/power/terminal, /turf/simulated/floor/plating, /area/ship/trade/maintenance/engine/aft) -"OD" = ( -/obj/structure/catwalk, -/obj/structure/railing/mapped{ - dir = 1 - }, -/obj/structure/railing/mapped{ - dir = 4 - }, -/turf/space, -/area/space) "OP" = ( /obj/machinery/alarm{ dir = 8; @@ -7525,16 +7515,6 @@ }, /turf/simulated/floor/plating, /area/ship/trade/shuttle/outgoing/general) -"Sk" = ( -/obj/structure/catwalk, -/obj/structure/railing/mapped{ - dir = 1 - }, -/obj/structure/railing/mapped{ - dir = 8 - }, -/turf/space, -/area/space) "Sr" = ( /turf/simulated/floor/plating, /area/ship/trade/maintenance/hallway) @@ -9834,7 +9814,7 @@ aa aa aa aa -Sk +WM gN qv Sj @@ -10572,7 +10552,7 @@ aa aa aa aa -OD +Bi Tb CV Wb From adf231a311f453c76343c92f7d16dd7d3ea8e76c Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 28 Sep 2023 22:12:59 +1000 Subject: [PATCH 10/33] Tweaked get_reaction_loc() to take a flag that returns the turf if the atom is an open container, for grenade reactions. --- code/__defines/chemistry.dm | 2 ++ code/game/objects/effects/chem/chemsmoke.dm | 2 +- .../liquids/materials_liquid_chemistry.dm | 2 +- code/modules/reagents/Chemistry-Holder.dm | 4 +++- code/modules/reagents/reactions/_reaction.dm | 14 ++++++++------ .../reactions/reaction_grenade_reaction.dm | 19 ++++++++++--------- .../reagents/reactions/reaction_other.dm | 4 ++-- .../reactions/reaction_recipe_food.dm | 2 +- .../reagents/reactions/reaction_synthesis.dm | 10 +++++----- mods/content/psionics/datum/chems.dm | 4 ++-- 10 files changed, 35 insertions(+), 28 deletions(-) diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 721851ffaf3..3d24c1a3306 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -68,3 +68,5 @@ #define DEFAULT_GAS_ACCELERANT /decl/material/gas/hydrogen #define DEFAULT_GAS_OXIDIZER /decl/material/gas/oxygen + +#define CHEM_REACTION_FLAG_OVERFLOW_CONTAINER BITFLAG(0) diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm index 793495489c4..d5de273a4ee 100644 --- a/code/game/objects/effects/chem/chemsmoke.dm +++ b/code/game/objects/effects/chem/chemsmoke.dm @@ -138,7 +138,7 @@ var/whereLink = "[where]" if(show_log) - var/atom/location = carry?.get_reaction_loc() + var/atom/location = carry?.get_reaction_loc(CHEM_REACTION_FLAG_OVERFLOW_CONTAINER) if(location?.fingerprintslast) var/mob/M = get_mob_by_key(location.fingerprintslast) var/more = "" diff --git a/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm b/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm index a0f46f458de..8dff6110d27 100644 --- a/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm +++ b/code/modules/materials/definitions/liquids/materials_liquid_chemistry.dm @@ -1,5 +1,5 @@ /decl/material/liquid/surfactant // Foam precursor - name = "surfacant" + name = "surfactant" uid = "liquid_surfacant" lore_text = "A isocyanate liquid that forms a foam when mixed with water." taste_description = "metal" diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index b81a7ddc576..4429de2ad36 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -39,7 +39,9 @@ var/global/obj/temp_reagents_holder = new clone.cached_color = cached_color return clone -/datum/reagents/proc/get_reaction_loc() +/datum/reagents/proc/get_reaction_loc(chemical_reaction_flags) + if((chemical_reaction_flags & CHEM_REACTION_FLAG_OVERFLOW_CONTAINER) && ATOM_IS_OPEN_CONTAINER(my_atom)) + return get_turf(my_atom) return my_atom /datum/reagents/proc/get_primary_reagent_name(var/codex = FALSE) // Returns the name of the reagent with the biggest volume. diff --git a/code/modules/reagents/reactions/_reaction.dm b/code/modules/reagents/reactions/_reaction.dm index 16756785735..caed59766bf 100644 --- a/code/modules/reagents/reactions/_reaction.dm +++ b/code/modules/reagents/reactions/_reaction.dm @@ -15,6 +15,8 @@ var/log_is_important = 0 // If this reaction should be considered important for logging. Important recipes message admins when mixed, non-important ones just log to file. var/lore_text var/mechanics_text + /// Flags used when reaction processing. + var/chemical_reaction_flags = 0 /decl/chemical_reaction/proc/can_happen(var/datum/reagents/holder) //check that all the required reagents are present @@ -29,7 +31,7 @@ if(holder.has_any_reagent(inhibitors)) return 0 - var/atom/location = holder.get_reaction_loc() + var/atom/location = holder.get_reaction_loc(chemical_reaction_flags) var/temperature = location?.temperature || T20C if(temperature < minimum_temperature || temperature > maximum_temperature) return 0 @@ -37,7 +39,7 @@ return 1 /decl/chemical_reaction/proc/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) - var/atom/location = holder.get_reaction_loc() + var/atom/location = holder.get_reaction_loc(chemical_reaction_flags) if(thermal_product && location && ATOM_SHOULD_TEMPERATURE_ENQUEUE(location)) ADJUST_ATOM_TEMPERATURE(location, thermal_product) @@ -47,7 +49,7 @@ for(var/reagent in required_reagents) . += reagent -/decl/chemical_reaction/proc/get_reaction_flags(var/datum/reagents/holder) +/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) @@ -59,7 +61,7 @@ if(reaction_volume > A) reaction_volume = A - var/reaction_flags = get_reaction_flags(holder) + var/alt_reaction_indicator = get_alternate_reaction_indicator(holder) for(var/reactant in required_reagents) holder.remove_reagent(reactant, reaction_volume * required_reagents[reactant], safety = 1) @@ -69,11 +71,11 @@ if(result) holder.add_reagent(result, amt_produced, data, safety = 1) - on_reaction(holder, amt_produced, reaction_flags) + on_reaction(holder, amt_produced, alt_reaction_indicator) //called after processing reactions, if they occurred /decl/chemical_reaction/proc/post_reaction(var/datum/reagents/holder) - var/atom/container = holder.get_reaction_loc() + var/atom/container = holder.get_reaction_loc(chemical_reaction_flags) if(mix_message && container && !ismob(container)) var/turf/T = get_turf(container) if(istype(T)) diff --git a/code/modules/reagents/reactions/reaction_grenade_reaction.dm b/code/modules/reagents/reactions/reaction_grenade_reaction.dm index 1bc2f9aa9ec..74b713dfc4f 100644 --- a/code/modules/reagents/reactions/reaction_grenade_reaction.dm +++ b/code/modules/reagents/reactions/reaction_grenade_reaction.dm @@ -2,6 +2,7 @@ result = null abstract_type = /decl/chemical_reaction/grenade_reaction result_amount = 1 + chemical_reaction_flags = CHEM_REACTION_FLAG_OVERFLOW_CONTAINER /decl/chemical_reaction/grenade_reaction/explosion_potassium name = "Explosion" @@ -11,10 +12,10 @@ /decl/chemical_reaction/grenade_reaction/explosion_potassium/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/atom/location = holder.get_reaction_loc() + var/atom/location = holder.get_reaction_loc(chemical_reaction_flags) if(location) var/datum/effect/effect/system/reagents_explosion/e = new() - e.set_up(round (created_volume/10, 1), location, 0, 0) + e.set_up(round(created_volume/10, 1), location, 0, 0) if(isliving(location)) e.amount *= 0.5 var/mob/living/L = location @@ -32,7 +33,7 @@ /decl/chemical_reaction/grenade_reaction/flash_powder/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/turf/location = get_turf(holder.get_reaction_loc()) + var/turf/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) spark_at(location, amount=2, cardinal_only = TRUE) for(var/mob/living/carbon/M in viewers(world.view, location)) @@ -58,7 +59,7 @@ /decl/chemical_reaction/grenade_reaction/emp_pulse/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/turf/location = holder.get_reaction_loc() + var/turf/location = holder.get_reaction_loc(chemical_reaction_flags) if(location) // 100 created volume = 4 heavy range & 7 light range. A few tiles smaller than traitor EMP grandes. // 200 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. @@ -79,7 +80,7 @@ /decl/chemical_reaction/grenade_reaction/flash_fire/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/turf/location = get_turf(holder.get_reaction_loc()) + var/turf/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(istype(location)) location.assume_gas(/decl/material/gas/hydrogen, created_volume, FLAMMABLE_GAS_FLASHPOINT + 10) spark_at(location, amount=1, cardinal_only = TRUE) @@ -93,7 +94,7 @@ /decl/chemical_reaction/grenade_reaction/chemsmoke/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/location = get_turf(holder.get_reaction_loc()) + var/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) var/datum/effect/effect/system/smoke_spread/chem/S = new /datum/effect/effect/system/smoke_spread/chem S.attach(location) @@ -112,7 +113,7 @@ /decl/chemical_reaction/grenade_reaction/foam/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/turf/location = get_turf(holder.get_reaction_loc()) + var/turf/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) location.visible_message(SPAN_WARNING("The solution spews out foam!"), range = 5) var/datum/effect/effect/system/foam_spread/s = new() @@ -129,7 +130,7 @@ /decl/chemical_reaction/grenade_reaction/metalfoam/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/atom/location = holder.get_reaction_loc() + var/atom/location = holder.get_reaction_loc(chemical_reaction_flags) if(location) if(istype(location, /obj/item/sealant_tank)) var/obj/item/sealant_tank/foam = location @@ -151,7 +152,7 @@ /decl/chemical_reaction/grenade_reaction/ironfoam/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/turf/location = get_turf(holder.get_reaction_loc()) + var/turf/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) location.visible_message(SPAN_WARNING("The solution spews out a metallic foam!"), range = 5) var/datum/effect/effect/system/foam_spread/s = new() diff --git a/code/modules/reagents/reactions/reaction_other.dm b/code/modules/reagents/reactions/reaction_other.dm index 680e3564aa1..6088fb606f1 100644 --- a/code/modules/reagents/reactions/reaction_other.dm +++ b/code/modules/reagents/reactions/reaction_other.dm @@ -6,12 +6,12 @@ var/strength = 3 /decl/chemical_reaction/soap_key/can_happen(var/datum/reagents/holder) - if(istype(holder.get_reaction_loc(), /obj/item/soap)) + if(istype(holder.get_reaction_loc(chemical_reaction_flags), /obj/item/soap)) return ..() return 0 /decl/chemical_reaction/soap_key/on_reaction(var/datum/reagents/holder) - var/obj/item/soap/S = holder.get_reaction_loc() + var/obj/item/soap/S = holder.get_reaction_loc(chemical_reaction_flags) if(istype(S) && S.key_data) var/obj/item/key/soap/key = new(get_turf(S), S.key_data) key.uses = strength diff --git a/code/modules/reagents/reactions/reaction_recipe_food.dm b/code/modules/reagents/reactions/reaction_recipe_food.dm index 7bc273ca6a5..6a63aa7f0c5 100644 --- a/code/modules/reagents/reactions/reaction_recipe_food.dm +++ b/code/modules/reagents/reactions/reaction_recipe_food.dm @@ -6,7 +6,7 @@ /decl/chemical_reaction/recipe/food/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/location = get_turf(holder.get_reaction_loc()) + var/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(obj_result && isturf(location)) for(var/i = 1, i <= created_volume, i++) new obj_result(location) diff --git a/code/modules/reagents/reactions/reaction_synthesis.dm b/code/modules/reagents/reactions/reaction_synthesis.dm index 511219aa387..f541c2f5072 100644 --- a/code/modules/reagents/reactions/reaction_synthesis.dm +++ b/code/modules/reagents/reactions/reaction_synthesis.dm @@ -20,7 +20,7 @@ /decl/chemical_reaction/synthesis/fiberglass/on_reaction(datum/reagents/holder, created_volume, reaction_flags) ..() - var/location = get_turf(holder.get_reaction_loc()) + var/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) created_volume = CEILING(created_volume) if(created_volume > 0) @@ -47,7 +47,7 @@ return TRUE /decl/chemical_reaction/synthesis/crystalization/on_reaction(datum/reagents/holder, created_volume, reaction_flags) - var/location = get_turf(holder.get_reaction_loc()) + 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) @@ -81,7 +81,7 @@ return TRUE /decl/chemical_reaction/synthesis/aerogel/on_reaction(datum/reagents/holder, created_volume, reaction_flags) - var/location = get_turf(holder.get_reaction_loc()) + 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) @@ -101,7 +101,7 @@ /decl/chemical_reaction/synthesis/plastication/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/location = get_turf(holder.get_reaction_loc()) + var/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(location) SSmaterials.create_object(/decl/material/solid/plastic, location, created_volume) @@ -116,7 +116,7 @@ /decl/chemical_reaction/synthesis/resin_pack/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) ..() - var/turf/T = get_turf(holder.get_reaction_loc()) + var/turf/T = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(istype(T)) var/create_stacks = FLOOR(created_volume) if(create_stacks > 0) diff --git a/mods/content/psionics/datum/chems.dm b/mods/content/psionics/datum/chems.dm index 4cbc86e54ad..119cfbc1c2e 100644 --- a/mods/content/psionics/datum/chems.dm +++ b/mods/content/psionics/datum/chems.dm @@ -13,7 +13,7 @@ required_reagents = list(/decl/material/liquid/blood = 15, /decl/material/liquid/crystal_agent = 1) result_amount = 1 -/decl/chemical_reaction/synthesis/nullglass/get_reaction_flags(var/datum/reagents/holder) +/decl/chemical_reaction/synthesis/nullglass/get_alternate_reaction_indicator(var/datum/reagents/holder) var/list/blood_data = REAGENT_DATA(holder, /decl/material/liquid/blood) var/weakref/donor_ref = LAZYACCESS(blood_data, "donor") var/mob/living/donor = donor_ref?.resolve() @@ -21,7 +21,7 @@ . = (istype(donor) && (donor.psi || (donor.mind && wizards.is_antagonist(donor.mind)))) /decl/chemical_reaction/synthesis/nullglass/on_reaction(var/datum/reagents/holder, var/created_volume, var/reaction_flags) - var/location = get_turf(holder.get_reaction_loc()) + var/location = get_turf(holder.get_reaction_loc(chemical_reaction_flags)) if(reaction_flags) for(var/i = 1, i <= created_volume, i++) new /obj/item/soulstone(location) From faf98a65b7db06b088f5f8b9d6ce4e15746514a5 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Thu, 28 Sep 2023 22:30:03 +1000 Subject: [PATCH 11/33] Fixing potassium-water bombs. --- code/modules/reagents/reactions/reaction_grenade_reaction.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/reactions/reaction_grenade_reaction.dm b/code/modules/reagents/reactions/reaction_grenade_reaction.dm index 74b713dfc4f..f32859c611c 100644 --- a/code/modules/reagents/reactions/reaction_grenade_reaction.dm +++ b/code/modules/reagents/reactions/reaction_grenade_reaction.dm @@ -15,7 +15,7 @@ var/atom/location = holder.get_reaction_loc(chemical_reaction_flags) if(location) var/datum/effect/effect/system/reagents_explosion/e = new() - e.set_up(round(created_volume/10, 1), location, 0, 0) + e.set_up(round(created_volume/3, 1), location, 0, 0) if(isliving(location)) e.amount *= 0.5 var/mob/living/L = location From 1b7ea5c8c9bd1fd9cb2007563838e8a4b7f7e4ec Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Fri, 29 Sep 2023 09:53:44 +1000 Subject: [PATCH 12/33] Removing turf/hitby parent call to avoid maneuvers always causing mild damage. --- code/controllers/subsystems/throwing.dm | 7 +++---- code/game/turfs/turf.dm | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/code/controllers/subsystems/throwing.dm b/code/controllers/subsystems/throwing.dm index dfadbd42bdd..f10c02c06cf 100644 --- a/code/controllers/subsystems/throwing.dm +++ b/code/controllers/subsystems/throwing.dm @@ -170,11 +170,10 @@ SUBSYSTEM_DEF(throwing) thrownthing.throwing = null if (!hit) - for (var/thing in get_turf(thrownthing)) //looking for our target on the turf we land on. - var/atom/A = thing - if (A == target) + for (var/atom/thing as anything in get_turf(thrownthing)) //looking for our target on the turf we land on. + if (thing == target) hit = TRUE - thrownthing.throw_impact(A, src) + thrownthing.throw_impact(thing, src) break if(QDELETED(thrownthing)) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 3ed31a7098e..29d2675703d 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -330,7 +330,7 @@ // Called when turf is hit by a thrown object /turf/hitby(atom/movable/AM, var/datum/thrownthing/TT) - ..() + SHOULD_CALL_PARENT(FALSE) // /atom/hitby() applies damage to AM if it's a living mob. if(density) if(isliving(AM)) var/mob/living/M = AM From 4b1b8ec9a19542a5edfcc4ee0668675bf1474092 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 15:52:30 +1000 Subject: [PATCH 13/33] Making machine frames rotatable. --- .../game/machinery/computer/buildandrepair.dm | 1 - code/game/machinery/constructable_frame.dm | 9 ++++----- icons/obj/items/stock_parts/stock_parts.dmi | Bin 20489 -> 21404 bytes 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/code/game/machinery/computer/buildandrepair.dm b/code/game/machinery/computer/buildandrepair.dm index 4745a0ca0cb..5a6e4780c71 100644 --- a/code/game/machinery/computer/buildandrepair.dm +++ b/code/game/machinery/computer/buildandrepair.dm @@ -4,7 +4,6 @@ name = "computer frame" icon = 'icons/obj/items/stock_parts/stock_parts.dmi' icon_state = "unwired" - obj_flags = OBJ_FLAG_ROTATABLE expected_machine_type = "computer" /obj/machinery/constructable_frame/computerframe/on_update_icon() diff --git a/code/game/machinery/constructable_frame.dm b/code/game/machinery/constructable_frame.dm index 0ab6191ec8c..e58b243c5dc 100644 --- a/code/game/machinery/constructable_frame.dm +++ b/code/game/machinery/constructable_frame.dm @@ -1,8 +1,6 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 - //Circuit boards are in /code/game/objects/items/weapons/circuitboards/machinery/ - -/obj/machinery/constructable_frame //Made into a seperate type to make future revisions easier. +///Made into a seperate type to make future revisions easier. +/obj/machinery/constructable_frame name = "machine frame" icon = 'icons/obj/items/stock_parts/stock_parts.dmi' icon_state = "box_0" @@ -11,9 +9,10 @@ use_power = POWER_USE_OFF uncreated_component_parts = null construct_state = /decl/machine_construction/frame/unwrenched + obj_flags = OBJ_FLAG_ROTATABLE + atom_flags = ATOM_FLAG_NO_TEMP_CHANGE | ATOM_FLAG_CLIMBABLE var/obj/item/stock_parts/circuitboard/circuit = null var/expected_machine_type - atom_flags = ATOM_FLAG_NO_TEMP_CHANGE | ATOM_FLAG_CLIMBABLE /obj/machinery/constructable_frame/state_transition(decl/machine_construction/new_state) . = ..() diff --git a/icons/obj/items/stock_parts/stock_parts.dmi b/icons/obj/items/stock_parts/stock_parts.dmi index c5232faf88df2309acae390d1392b47a8d434739..24e82a36ceac9176477aa976b0881f4ce9af1cb1 100644 GIT binary patch literal 21404 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

CTFgS*BkQ-cw1MIj~WY3AwK#F!fNr8xU?@RGRI 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 YRMdxIyYhuZ;JOJhF|;&zujdr=AL*d9_W%F@ literal 20489 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 From b755532257565f62d0a5d87c29ffa4d75a078db4 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 22:16:59 +1000 Subject: [PATCH 14/33] Simplifies paper bundle icon updates, fixes runtime in overlay copy. --- code/controllers/subsystems/overlays.dm | 2 +- code/game/objects/item_materials.dm | 6 +++--- code/modules/paperwork/paper_bundle.dm | 26 ++++++++----------------- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 61d8f7f626f..689c5f1bd68 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -179,7 +179,7 @@ SUBSYSTEM_DEF(overlays) if(NOT_QUEUED_ALREADY) QUEUE_FOR_COMPILE -/atom/proc/set_overlays(list/overlays_list, priority = FALSE) // Sets overlays to a list, equivalent to cut_overlays() + add_overlays(). +/atom/proc/set_overlays(list/overlays_list, priority = FALSE) // Sets overlays to a list, equivalent to cut_overlays() + add_overlay(). if (!overlays_list) return diff --git a/code/game/objects/item_materials.dm b/code/game/objects/item_materials.dm index 569e4504203..59def6f2a16 100644 --- a/code/game/objects/item_materials.dm +++ b/code/game/objects/item_materials.dm @@ -8,7 +8,7 @@ if(blood_overlay) add_overlay(blood_overlay) if(global.contamination_overlay && contaminated) - overlays += global.contamination_overlay + add_overlay(global.contamination_overlay) /obj/item/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone) . = ..() @@ -108,10 +108,10 @@ if(max_health < 1) //Make sure to warn us if the values we set make the max_health be under 1 log_warning("The 'max_health' of '[src]'([type]) made out of '[material]' was calculated as [material_health_multiplier] * [material.integrity] == [max_health], which is smaller than 1.") - + if(isnull(health)) //only set health if we didn't specify one already, so damaged objects on spawn and etc can be a thing health = max_health - + if(material.products_need_process()) START_PROCESSING(SSobj, src) if(material.conductive) diff --git a/code/modules/paperwork/paper_bundle.dm b/code/modules/paperwork/paper_bundle.dm index f7e295a7056..d1f5dd9250b 100644 --- a/code/modules/paperwork/paper_bundle.dm +++ b/code/modules/paperwork/paper_bundle.dm @@ -24,16 +24,6 @@ var/tmp/cur_page = 1 // current page var/tmp/max_pages = 100 //Maximum number of papers that can be in the bundle var/list/pages // Ordered list of pages as they are to be displayed. Can be different order than src.contents. - var/static/list/cached_overlays //Cached images used by all paper bundles for generating the overlays and underlays - -/**Creates frequently used images globally, so we can re-use them. */ -/obj/item/paper_bundle/proc/cache_overlays() - if(LAZYLEN(cached_overlays)) - return - LAZYSET(cached_overlays, "clip", image('icons/obj/bureaucracy.dmi', "clip")) - LAZYSET(cached_overlays, "paper", image('icons/obj/bureaucracy.dmi', "paper")) - LAZYSET(cached_overlays, "photo", image('icons/obj/bureaucracy.dmi', "photo")) - LAZYSET(cached_overlays, "refill", image('icons/obj/bureaucracy.dmi', "paper_refill_label")) /obj/item/paper_bundle/Destroy() LAZYCLEARLIST(pages) //Get rid of refs @@ -306,14 +296,14 @@ /obj/item/paper_bundle/on_update_icon() . = ..() - if(!LAZYLEN(cached_overlays)) - cache_overlays() - underlays.Cut() + underlays.Cut() var/obj/item/paper/P = pages[1] icon = P.icon icon_state = P.icon_state - set_overlays(P.overlays) + + for(var/overlay in P.overlays) + add_overlay(overlay) var/paper_count = 0 var/photo_count = 0 @@ -321,7 +311,7 @@ for(var/obj/O in pages) if(istype(O, /obj/item/paper) && (paper_count < MAX_PAPER_UNDERLAYS)) //We can't even see them, so don't bother create appearences form each paper's icon, and use a generic one - var/mutable_appearance/img = new(cached_overlays["paper"]) + var/mutable_appearance/img = mutable_appearance('icons/obj/bureaucracy.dmi', "paper") img.color = O.color img.pixel_x -= min(paper_count, 2) img.pixel_y -= min(paper_count, 2) @@ -336,7 +326,7 @@ if(photo_count < 1) add_overlay(Ph.tiny) else - add_overlay(cached_overlays["photo"]) //We can't even see them, so don't bother create new unique appearences + add_overlay("photo") //We can't even see them, so don't bother create new unique appearences photo_count++ //Break if we have nothing else to do @@ -353,7 +343,7 @@ else if(photo_count > 0) desc += "\nThere is a photo attached to it." - add_overlay(cached_overlays["clip"]) + add_overlay("clip") /** * Merge another bundle or paper into us. @@ -518,7 +508,7 @@ /obj/item/paper_bundle/refill/on_update_icon() . = ..() - add_overlay(cached_overlays["refill"]) + add_overlay("refill") /////////////////////////////////////////////////////////////////////////// // Interaction Rename From cef198a53c0314ccd2948ec63a73f74a7c5d9f7e Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 22:19:19 +1000 Subject: [PATCH 15/33] Adding a continue to file perm helper. --- code/modules/modular_computers/file_system/directory.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/modular_computers/file_system/directory.dm b/code/modules/modular_computers/file_system/directory.dm index efafd3b0365..af81828a81c 100644 --- a/code/modules/modular_computers/file_system/directory.dm +++ b/code/modules/modular_computers/file_system/directory.dm @@ -58,6 +58,7 @@ var/datum/computer_file/held_file = file_ref.resolve() if(!held_file) held_files -= file_ref + continue if(istype(held_file, /datum/computer_file/directory)) var/datum/computer_file/directory/dir = held_file From 6efcd12bb56b9ab548886bf6b98127717aa958f7 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 22:21:06 +1000 Subject: [PATCH 16/33] Swap .len for length() in autopsy update to avoid runtime. --- code/game/objects/items/weapons/autopsy.dm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm index 2d6b5e790f2..9d9f4061d46 100644 --- a/code/game/objects/items/weapons/autopsy.dm +++ b/code/game/objects/items/weapons/autopsy.dm @@ -48,17 +48,17 @@ playsound(src, 'sound/effects/fastbeep.ogg', 10) /obj/item/scanner/autopsy/proc/add_data(var/obj/item/organ/external/O) - if(!O.autopsy_data.len) return + if(!length(O.autopsy_data)) + return for(var/V in O.autopsy_data) var/datum/autopsy_data/W = O.autopsy_data[V] - if(!weapon_data[V]) - weapon_data[V] = list("data" = W.copy(), "organs" = list(O.name)) - else + if(weapon_data[V]) var/datum/autopsy_data/data = weapon_data[V]["data"] data.merge_with(W) - var/list/organs = weapon_data[V]["organs"] - organs |= O.name + weapon_data[V]["organs"] |= O.name + else + weapon_data[V] = list("data" = W.copy(), "organs" = list(O.name)) /obj/item/scanner/autopsy/proc/get_formatted_data() var/list/scan_data = list("Subject: [target_name]") From 3adc2c307c1e31739af9fdbd9c9794e3961c340f Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 22:34:49 +1000 Subject: [PATCH 17/33] Overhead text can now be offset for large atoms. --- code/game/atoms.dm | 6 ++++++ code/modules/mob/floating_message.dm | 3 ++- code/modules/mob/living/living.dm | 8 ++++++++ code/modules/mob/living/simple_animal/hostile/pike.dm | 1 + code/modules/mob/mob.dm | 6 ++++++ code/modules/mob/mob_defines.dm | 4 ++++ 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 4d78a75bd74..3b1c3d3dc6b 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -855,3 +855,9 @@ /atom/proc/on_defilement() return + +/atom/proc/get_overhead_text_x_offset() + return 0 + +/atom/proc/get_overhead_text_y_offset() + return 0 diff --git a/code/modules/mob/floating_message.dm b/code/modules/mob/floating_message.dm index 08b66bd25c6..1a37abc46d3 100644 --- a/code/modules/mob/floating_message.dm +++ b/code/modules/mob/floating_message.dm @@ -64,7 +64,8 @@ var/global/list/floating_chat_colors = list() I.maptext_width = CHAT_MESSAGE_WIDTH I.maptext_height = CHAT_MESSAGE_HEIGHT I.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART - I.pixel_w = -round(I.maptext_width/2) + 16 + I.pixel_w = -round(I.maptext_width/2) + 16 + holder.get_overhead_text_x_offset() + I.pixel_z = holder.get_overhead_text_y_offset() style = "font-family: 'Small Fonts'; -dm-text-outline: 1px black; font-size: [size]px; line-height: 1.1; [style]" I.maptext = "

[message]
" diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 87839a002f2..eb255360560 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1121,3 +1121,11 @@ default behaviour is: /mob/living/proc/get_mob_footstep(var/footstep_type) var/decl/species/my_species = get_species() return my_species?.get_footstep(src, footstep_type) + +/mob/living/get_overhead_text_x_offset() + var/decl/bodytype/bodytype = get_bodytype() + return ..() + bodytype?.antaghud_offset_x + +/mob/living/get_overhead_text_y_offset() + var/decl/bodytype/bodytype = get_bodytype() + return ..() + bodytype?.antaghud_offset_y diff --git a/code/modules/mob/living/simple_animal/hostile/pike.dm b/code/modules/mob/living/simple_animal/hostile/pike.dm index 75e70b201da..33494af88e4 100644 --- a/code/modules/mob/living/simple_animal/hostile/pike.dm +++ b/code/modules/mob/living/simple_animal/hostile/pike.dm @@ -8,6 +8,7 @@ speed = 1 mob_size = MOB_SIZE_LARGE + offset_overhead_text_x = 16 pixel_x = -16 health = 150 diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 1c839b159ce..f91a9fdc7bf 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1317,3 +1317,9 @@ /mob/proc/get_target_zone() return zone_sel?.selecting + +/mob/get_overhead_text_x_offset() + return offset_overhead_text_x + +/mob/get_overhead_text_y_offset() + return offset_overhead_text_y diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 245f6991ecd..5d1c5e884f4 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -177,3 +177,7 @@ /// Used for darksight, required on all mobs to ensure lighting renders properly. var/obj/screen/lighting_plane_master/lighting_master + + // Offset the overhead text if necessary. + var/offset_overhead_text_x = 0 + var/offset_overhead_text_y = 0 \ No newline at end of file From 3fef4a7d5a2a138171f16fb0238efbb8313177d1 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 22:43:05 +1000 Subject: [PATCH 18/33] Poster dir set in Initialize. --- code/game/objects/effects/decals/contraband.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/objects/effects/decals/contraband.dm b/code/game/objects/effects/decals/contraband.dm index 8c622bdd765..3c174fdba94 100644 --- a/code/game/objects/effects/decals/contraband.dm +++ b/code/game/objects/effects/decals/contraband.dm @@ -100,6 +100,8 @@ poster_type = give_poster_type else poster_type = pick(decls_repository.get_decl_paths_of_subtype(/decl/poster)) + if(placement_dir && dir != placement_dir) + set_dir(placement_dir) set_poster(poster_type) /obj/structure/sign/poster/proc/set_poster(var/poster_type) From 8d382c3719ae1a0cb02c6178e35c51943407a8bd Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 22:48:16 +1000 Subject: [PATCH 19/33] Removed default hair hiding from head items, added to hoods. --- code/game/gamemodes/cult/cult_items.dm | 3 +-- code/modules/clothing/head/_head.dm | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm index 1c21c09ee7a..28daf9435d2 100644 --- a/code/game/gamemodes/cult/cult_items.dm +++ b/code/game/gamemodes/cult/cult_items.dm @@ -42,9 +42,8 @@ /obj/item/clothing/head/culthood name = "cult hood" desc = "A hood worn by the followers of Nar-Sie." - icon = 'icons/clothing/head/cult.dmi' - flags_inv = HIDEFACE + flags_inv = HIDEFACE | BLOCK_HEAD_HAIR body_parts_covered = SLOT_HEAD armor = list( ARMOR_MELEE = ARMOR_MELEE_RESISTANT, diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm index dbe3c1f36f3..72889714885 100644 --- a/code/modules/clothing/head/_head.dm +++ b/code/modules/clothing/head/_head.dm @@ -4,7 +4,6 @@ icon = 'icons/clothing/head/softcap.dmi' blood_overlay_type = "helmetblood" w_class = ITEM_SIZE_SMALL - flags_inv = BLOCK_HEAD_HAIR slot_flags = SLOT_HEAD body_parts_covered = SLOT_HEAD From b0e5e82b59e377d9e7f706f02b82f17ee3933816 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Wed, 13 Sep 2023 13:03:16 -0500 Subject: [PATCH 20/33] Fix hydrate automatic UID --- .../definitions/solids/materials_solid_ice.dm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/code/modules/materials/definitions/solids/materials_solid_ice.dm b/code/modules/materials/definitions/solids/materials_solid_ice.dm index 6e02c04bf18..7dc9a2cadac 100644 --- a/code/modules/materials/definitions/solids/materials_solid_ice.dm +++ b/code/modules/materials/definitions/solids/materials_solid_ice.dm @@ -124,13 +124,13 @@ //Little helper macro, since hydrates are all basically the same // DISPLAY_NAME is needed because of compounds with white spaces in their names -#define DECLARE_HYDRATE_DNAME_PATH(PATH, NAME, DISPLAY_NAME) \ -/decl/material/solid/ice/hydrate/##NAME/uid = "solid_hydrate_##NAME"; \ -/decl/material/solid/ice/hydrate/##NAME/Initialize(){ \ - name = "[##DISPLAY_NAME] hydrate"; \ - heating_products = list(PATH = 0.2, /decl/material/liquid/water = 0.8); \ - . = ..(); \ -} \ +#define DECLARE_HYDRATE_DNAME_PATH(PATH, NAME, DISPLAY_NAME) \ +/decl/material/solid/ice/hydrate/##NAME/uid = "solid_hydrate_" + #NAME; \ +/decl/material/solid/ice/hydrate/##NAME/name = #DISPLAY_NAME + " hydrate"; \ +/decl/material/solid/ice/hydrate/##NAME/heating_products = list( \ + PATH = 0.2, \ + /decl/material/liquid/water = 0.8 \ +); \ /decl/material/solid/ice/hydrate/##NAME #define DECLARE_HYDRATE_DNAME(NAME, DISPLAY_NAME) DECLARE_HYDRATE_DNAME_PATH(/decl/material/gas/##NAME, NAME, DISPLAY_NAME) From 98eeb70568f87cdd813712278d2ea73e6ba984bf Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 23 Sep 2023 18:34:11 -0500 Subject: [PATCH 21/33] Add exceptions to disposals tag map test --- code/unit_tests/map_tests.dm | 2 ++ maps/~mapsystem/maps_unit_testing.dm | 3 +++ 2 files changed, 5 insertions(+) diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index f66fbfcd12c..081c772d5d3 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -686,6 +686,8 @@ continue if(is_type_in_list(sort, exempt_junctions)) continue + if(sort.sort_type in global.using_map.disconnected_disposals_tags) + continue var/obj/machinery/disposal/bin = get_bin_from_junction(sort) if(!bin) log_bad("Junction with tag [sort.sort_type] at ([sort.x], [sort.y], [sort.z]) could not find disposal.") diff --git a/maps/~mapsystem/maps_unit_testing.dm b/maps/~mapsystem/maps_unit_testing.dm index 35696dde5c0..bbdb5c6e6d3 100644 --- a/maps/~mapsystem/maps_unit_testing.dm +++ b/maps/~mapsystem/maps_unit_testing.dm @@ -37,3 +37,6 @@ ) var/list/area_purity_test_exempt_areas = list() + + /// A list of disposals tags (sort_type var) that aren't expected to have outputs. + var/list/disconnected_disposals_tags = list() From 649943bfdd0b573dd6c607a028d9fd576fbf82cb Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 23 Sep 2023 21:21:10 -0500 Subject: [PATCH 22/33] Prevent unit test disposalholders from merging --- code/unit_tests/map_tests.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index 081c772d5d3..bef6df2ff81 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -719,6 +719,9 @@ var/datum/unit_test/networked_disposals_shall_deliver_tagged_packages/test speed = 100 +/obj/structure/disposalholder/unit_test/merge() + return FALSE + /obj/structure/disposalholder/unit_test/Destroy() test.package_delivered(src) . = ..() From 9326ec494a8ce8556193f027b72f03972e8441a9 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 23 Sep 2023 21:21:22 -0500 Subject: [PATCH 23/33] Double disposalholder step limit --- code/modules/recycling/disposalholder.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/recycling/disposalholder.dm b/code/modules/recycling/disposalholder.dm index 6fdcc5da167..b2c2d3d96b8 100644 --- a/code/modules/recycling/disposalholder.dm +++ b/code/modules/recycling/disposalholder.dm @@ -9,7 +9,7 @@ var/datum/gas_mixture/gas = null // gas used to flush, will appear at exit point var/active = 0 // true if the holder is moving, otherwise inactive dir = 0 - var/count = 2048 //*** can travel 2048 steps before going inactive (in case of loops) + var/count = 4096 //*** can travel 4096 steps before going inactive (in case of loops) var/destinationTag = "" // changes if contains a delivery container var/tomail = 0 //changes if contains wrapped package var/hasmob = 0 //If it contains a mob From 0df1cbe858d35dc2a547ddb953753e32b7acb0b5 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sat, 23 Sep 2023 21:22:52 -0500 Subject: [PATCH 24/33] Stop cash freezer from overflowing --- .../objects/structures/crates_lockers/closets/secure/freezer.dm | 2 +- code/modules/economy/worth_cash.dm | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm index a2c234cb532..39f01e28bbc 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm @@ -47,7 +47,7 @@ var/created_size = 0 for(var/i = 1 to 200) //sanity loop limit var/obj/item/cash_type = pick(3; /obj/item/cash/c1000, 4; /obj/item/cash/c500, 5; /obj/item/cash/c200) - var/bundle_size = initial(cash_type.w_class) / 2 + var/bundle_size = initial(cash_type.w_class) if(created_size + bundle_size <= storage_capacity) created_size += bundle_size . += cash_type diff --git a/code/modules/economy/worth_cash.dm b/code/modules/economy/worth_cash.dm index dd94cbbf3c8..636b1f9d3f9 100644 --- a/code/modules/economy/worth_cash.dm +++ b/code/modules/economy/worth_cash.dm @@ -152,6 +152,7 @@ /obj/item/cash/c200 absolute_worth = 200 + w_class = ITEM_SIZE_SMALL // so that the money freezer doesn't overflow bc this is a pile instead of single bill /obj/item/cash/c500 absolute_worth = 500 From 0682ab2c87acd792151ad5534fb2bbecddb82ee9 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 24 Sep 2023 20:03:55 -0500 Subject: [PATCH 25/33] Add diagnostics to air alarm connectivity test --- code/unit_tests/map_tests.dm | 40 ++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index bef6df2ff81..a5fa114003f 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -78,10 +78,14 @@ continue if(!isPlayerLevel(A.z)) continue - var/obj/machinery/alarm/alarm = locate() in A // Only test areas with functional alarms - if(!alarm) - continue - if(alarm.stat & (NOPOWER | BROKEN)) + // Only test areas with functional alarms + var/obj/machinery/alarm/found_alarm + for (var/obj/machinery/alarm/alarm in A) + if(alarm.inoperable()) // must have at least one functional alarm + continue + found_alarm = alarm + + if(!found_alarm) continue //Make a list of devices that are being controlled by their air alarms @@ -97,17 +101,37 @@ for(var/tag in vents_in_area) // The point of this test is that while the names list is registered at init, the info is transmitted by radio. if(!A.air_vent_info[tag]) var/obj/machinery/atmospherics/unary/vent_pump/V = vents_in_area[tag] - var/logtext = "Vent [A.air_vent_names[tag]] ([V.x], [V.y], [V.z]) with id_tag [tag] did not update the air alarm in area [A]." - if(!V.operable()) + var/logtext = "Vent [A.air_vent_names[tag]] ([V.x], [V.y], [V.z]) with id_tag [tag] did not update [log_info_line(found_alarm)] in area [A]." + if(V.inoperable()) logtext = "[logtext] The vent was not functional." + var/alarm_dist = get_dist(found_alarm, V) + if(alarm_dist > 60) + logtext += " The vent may be out of transmission range (max 60, was [alarm_dist])." + var/V_freq + for(var/obj/item/stock_parts/radio/radio_component in V.component_parts) + V_freq ||= radio_component.frequency + if(isnull(V_freq)) + logtext += " The vent had no frequency set." + else if(V_freq != found_alarm.frequency) + logtext += " Frequencies did not match (alarm: [found_alarm.frequency], vent: [V_freq])." log_bad(logtext) failed = TRUE for(var/tag in scrubbers_in_area) if(!A.air_scrub_info[tag]) var/obj/machinery/atmospherics/unary/vent_scrubber/V = scrubbers_in_area[tag] - var/logtext = "Scrubber [A.air_scrub_names[tag]] ([V.x], [V.y], [V.z]) with id_tag [tag] did not update the air alarm in area [A]." - if(!V.operable()) + var/logtext = "Scrubber [A.air_scrub_names[tag]] ([V.x], [V.y], [V.z]) with id_tag [tag] did not update [log_info_line(found_alarm)] in area [A]." + if(V.inoperable()) logtext = "[logtext] The scrubber was not functional." + var/alarm_dist = get_dist(found_alarm, V) + if(alarm_dist > 60) + logtext += " The scrubber may be out of transmission range (max 60, was [alarm_dist])." + var/V_freq + for(var/obj/item/stock_parts/radio/radio_component in V.component_parts) + V_freq ||= radio_component.frequency + if(isnull(V_freq)) + logtext += " The scrubber had no frequency set." + else if(V_freq != found_alarm.frequency) + logtext += " Frequencies did not match (alarm: [found_alarm.frequency], scrubber: [V_freq])." log_bad(logtext) failed = TRUE From 6fbe76bef36e67778e93e69444ba941b01222058 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 24 Sep 2023 20:04:53 -0500 Subject: [PATCH 26/33] Disable transmitter latency for unit testing --- .../_machines_base/stock_parts/radio/transmitter.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm b/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm index 67d06b18aec..3ea9f96f1fa 100644 --- a/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm +++ b/code/game/machinery/_machines_base/stock_parts/radio/transmitter.dm @@ -4,6 +4,9 @@ icon_state = "transmitter" var/range = 60 // Limits transmit range var/latency = 2 // Delay between event and transmission; doesn't apply to transmit on tick + #ifdef UNIT_TEST + latency = 0 // this can slow down testing and cause random inconsistent failures + #endif var/buffer /obj/item/stock_parts/radio/transmitter/proc/queue_transmit(list/data) @@ -11,7 +14,10 @@ return if(!buffer) buffer = data - addtimer(CALLBACK(src, .proc/transmit), latency) + if(latency) + addtimer(CALLBACK(src, .proc/transmit), latency) + else + transmit() else buffer |= data From 0cc1942f5ac7856cff9f21374135e73140f2b19e Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 24 Sep 2023 20:11:55 -0500 Subject: [PATCH 27/33] Update camera tag auto-setting --- code/game/machinery/camera/camera.dm | 13 ++++++------- code/unit_tests/map_tests.dm | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 70bda310465..8556e5f5775 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -86,13 +86,12 @@ if(!c_tag) var/area/A = get_area(src) if(isturf(loc) && A) - for(var/obj/machinery/camera/C in A) - if(C == src) continue - if(C.number) - number = max(number, C.number+1) - c_tag = "[A.proper_name][number == 1 ? "" : " #[number]"]" - if(!c_tag) // Add a default c_tag in case the camera has been placed in an invalid location or inside another object. - c_tag = "Security Camera - [random_id(/obj/machinery/camera, 100,999)]" + var/suffix = uniqueness_repository.Generate(/datum/uniqueness_generator/id_sequential, "c_tag [A.proper_name]", 1) // unlike sequential_id, starts at 1 instead of 100 + if(suffix == 1) + suffix = null + c_tag = "[A.proper_name][suffix ? " [suffix]" : null]" + // Add a default c_tag in case the camera has been placed in an invalid location or inside another object. + c_tag ||= "Security Camera - [random_id(/obj/machinery/camera, 100,999)]" invalidateCameraCache() set_extension(src, /datum/extension/network_device/camera, null, null, null, TRUE, preset_channels, c_tag, cameranet_enabled, requires_connection) diff --git a/code/unit_tests/map_tests.dm b/code/unit_tests/map_tests.dm index a5fa114003f..99be12eb684 100644 --- a/code/unit_tests/map_tests.dm +++ b/code/unit_tests/map_tests.dm @@ -419,7 +419,7 @@ pass = FALSE if(pass) - pass("Have cameras have the c_tag set.") + pass("All cameras have the c_tag set.") else fail("One or more cameras do not have the c_tag set.") From 4d0356dce95093be3567f6a2daad460ca5dd0359 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 25 Sep 2023 09:53:03 -0500 Subject: [PATCH 28/33] Expand multi-holodeck support --- .../circuitboards/computer/holodeckcontrol.dm | 3 +++ code/game/objects/structures/tables.dm | 6 +++--- code/modules/holodeck/HolodeckObjects.dm | 12 +++++++++--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm b/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm index c0713c1e57c..c6a553dfe5c 100644 --- a/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm +++ b/code/game/objects/items/weapons/circuitboards/computer/holodeckcontrol.dm @@ -7,6 +7,9 @@ var/list/supported_programs var/list/restricted_programs +/obj/item/stock_parts/circuitboard/holodeckcontrol/get_buildable_types() + return typesof(/obj/machinery/computer/HolodeckControl) + /obj/item/stock_parts/circuitboard/holodeckcontrol/construct(var/obj/machinery/computer/HolodeckControl/HC) if (..(HC)) HC.supported_programs = supported_programs.Copy() diff --git a/code/game/objects/structures/tables.dm b/code/game/objects/structures/tables.dm index 0c9137a305c..dd9e2576f61 100644 --- a/code/game/objects/structures/tables.dm +++ b/code/game/objects/structures/tables.dm @@ -667,23 +667,23 @@ /obj/structure/table/holotable icon_state = "holo_preview" + holographic = TRUE color = COLOR_OFF_WHITE material = /decl/material/solid/metal/aluminium/holographic reinf_material = /decl/material/solid/metal/aluminium/holographic /obj/structure/table/holo_plastictable icon_state = "holo_preview" + holographic = TRUE color = COLOR_OFF_WHITE material = /decl/material/solid/plastic/holographic reinf_material = /decl/material/solid/plastic/holographic /obj/structure/table/holo_woodentable + holographic = TRUE icon_state = "holo_preview" - -/obj/structure/table/holo_woodentable/Initialize() material = /decl/material/solid/wood/holographic reinf_material = /decl/material/solid/wood/holographic - . = ..() //wood wood wood /obj/structure/table/woodentable diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index b8ad98f75d2..7af49cc096c 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -206,9 +206,15 @@ visible_message("[src] fades away as it shatters!") qdel(src) -/obj/structure/bed/chair/holochair/attackby(obj/item/W, mob/user) - if(IS_WRENCH(W)) - to_chat(user, ("It's a holochair, you can't dismantle it!")) +/obj/structure/bed/holobed + tool_interaction_flags = 0 + holographic = TRUE + material = /decl/material/solid/metal/aluminium/holographic + +/obj/structure/bed/chair/holochair + tool_interaction_flags = 0 + holographic = TRUE + material = /decl/material/solid/metal/aluminium/holographic /obj/item/holo damtype = PAIN From 3b773f1bc7129ecd67027a9b0dafdba6b2e0f80a Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 25 Sep 2023 09:53:31 -0500 Subject: [PATCH 29/33] Fix heat exchanging pipe set_dir return value --- code/modules/atmospherics/he_pipes.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/atmospherics/he_pipes.dm b/code/modules/atmospherics/he_pipes.dm index af07739ae96..5e19838b376 100644 --- a/code/modules/atmospherics/he_pipes.dm +++ b/code/modules/atmospherics/he_pipes.dm @@ -28,8 +28,8 @@ add_filter("glow",1, list(type="drop_shadow", x = 0, y = 0, offset = 0, size = 4)) /obj/machinery/atmospherics/pipe/simple/heat_exchanging/set_dir(new_dir) - ..() - initialize_directions_he = initialize_directions // all directions are HE + . = ..() + initialize_directions_he = get_initialize_directions() // all directions are HE /obj/machinery/atmospherics/pipe/simple/heat_exchanging/atmos_init() atmos_initalized = TRUE From 530a77b036cacbaa95399e7330d35dbb59755260 Mon Sep 17 00:00:00 2001 From: MistakeNot4892 Date: Sat, 30 Sep 2023 22:06:06 +1000 Subject: [PATCH 30/33] Buckled offsets now handle diagonals with no diagonal offset supplied. --- code/modules/mob/mob_layering.dm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/mob_layering.dm b/code/modules/mob/mob_layering.dm index 33f8325c27a..e3143c6d1dc 100644 --- a/code/modules/mob/mob_layering.dm +++ b/code/modules/mob/mob_layering.dm @@ -90,7 +90,13 @@ if(istext(pixel_shift)) pixel_shift = cached_json_decode(pixel_shift) if(islist(pixel_shift)) - var/list/directional_offset = LAZYACCESS(pixel_shift, "[dir]") + var/list/directional_offset = LAZYACCESS(pixel_shift, num2text(dir)) + // Unset diagonals should be substituted with the appropriate NSEW value. + if(!directional_offset) + if(dir & EAST) + directional_offset = LAZYACCESS(pixel_shift, num2text(EAST)) + else if(dir & WEST) + directional_offset = LAZYACCESS(pixel_shift, num2text(WEST)) if(islist(directional_offset)) pixel_shift = directional_offset new_pixel_x += pixel_shift["x"] || 0 From 6b139beb7d602024de2682868bafa406882c1a88 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 25 Sep 2023 14:28:19 -0500 Subject: [PATCH 31/33] Fix slime scanner and slime messages --- mods/content/xenobiology/slime/_slime.dm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/mods/content/xenobiology/slime/_slime.dm b/mods/content/xenobiology/slime/_slime.dm index 196cbce3528..544f92787c1 100644 --- a/mods/content/xenobiology/slime/_slime.dm +++ b/mods/content/xenobiology/slime/_slime.dm @@ -213,9 +213,9 @@ adjust_friendship(user, rand(2,3)) return TRUE - if(feeding_on) - var/prey = feeding_on - if(feeding_on == user) + var/prey = feeding_on?.resolve() + if(prey) + if(prey == user) if(prob(60)) visible_message(SPAN_DANGER("\The [user] fails to escape \the [src]!")) else @@ -223,12 +223,12 @@ set_feeding_on() else if(prob(30)) - visible_message(SPAN_DANGER("\The [user] attempts to wrestle \the [src] off \the [feeding_on]!")) + visible_message(SPAN_DANGER("\The [user] attempts to wrestle \the [src] off \the [prey]!")) else - visible_message(SPAN_DANGER("\The [user] manages to wrestle \the [src] off \the [feeding_on]!")) + visible_message(SPAN_DANGER("\The [user] manages to wrestle \the [src] off \the [prey]!")) set_feeding_on() - if(prey != feeding_on) + if(prey != feeding_on?.resolve()) playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) SET_STATUS_MAX(src, STAT_CONFUSE, 2) step_away(src, user) @@ -335,6 +335,7 @@ /mob/living/slime/xenobio_scan_results() var/decl/slime_colour/slime_data = GET_DECL(slime_type) + . = list() . += "Slime scan result for \the [src]:" . += "[slime_data.name] [is_adult ? "adult" : "baby"] slime" . += "Nutrition:\t[nutrition]/[get_max_nutrition()]" @@ -360,7 +361,7 @@ var/list/mutationTexts = list("[slime_data.name] ([100 - mutation_chance]%)") for(var/i in mutationChances) - mutationTexts += "[i] ([mutationChances[i]]%)" + mutationTexts += "[GET_DECL(i)] ([mutationChances[i]]%)" . += "Possible colours on splitting:\t[english_list(mutationTexts)]" From 3b8bdb23d80178d4d18b8afa2e87b48f2467b2c3 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Mon, 25 Sep 2023 14:28:53 -0500 Subject: [PATCH 32/33] Fix doubled air overlay on mimic edge turfs --- code/modules/multiz/turf_mimic_edge.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/multiz/turf_mimic_edge.dm b/code/modules/multiz/turf_mimic_edge.dm index 83d8017f38a..c1bdfdcab29 100644 --- a/code/modules/multiz/turf_mimic_edge.dm +++ b/code/modules/multiz/turf_mimic_edge.dm @@ -69,7 +69,7 @@ return /turf/simulated/mimic_edge/get_vis_contents_to_add() - . = shared_mimic_edge_get_add_vis_contents(src, get_mimic_turf(), ..()) + . = shared_mimic_edge_get_add_vis_contents(src, get_mimic_turf(), list()) /turf/simulated/mimic_edge/proc/get_mimic_turf() return mimic_x && mimic_y && mimic_z && locate(mimic_x, mimic_y, mimic_z) @@ -135,7 +135,7 @@ return /turf/unsimulated/mimic_edge/get_vis_contents_to_add() - . = shared_mimic_edge_get_add_vis_contents(src, get_mimic_turf(), ..()) + . = shared_mimic_edge_get_add_vis_contents(src, get_mimic_turf(), list()) /turf/unsimulated/mimic_edge/proc/get_mimic_turf() return mimic_x && mimic_y && mimic_z && locate(mimic_x, mimic_y, mimic_z) @@ -201,7 +201,7 @@ return /turf/exterior/mimic_edge/get_vis_contents_to_add() - . = shared_mimic_edge_get_add_vis_contents(src, get_mimic_turf(), ..()) + . = shared_mimic_edge_get_add_vis_contents(src, get_mimic_turf(), list()) /turf/exterior/mimic_edge/proc/get_mimic_turf() return mimic_x && mimic_y && mimic_z && locate(mimic_x, mimic_y, mimic_z) From fe7b4baed6915059e5042dbbf311ac7ac879ab00 Mon Sep 17 00:00:00 2001 From: Penelope Haze Date: Sun, 6 Aug 2023 11:23:24 -0500 Subject: [PATCH 33/33] Fix belt slot logic --- code/datums/inventory_slots/slots/slot_belt.dm | 15 +++++++++------ code/unit_tests/equipment_tests.dm | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/code/datums/inventory_slots/slots/slot_belt.dm b/code/datums/inventory_slots/slots/slot_belt.dm index f252f5a4007..4837fe592ae 100644 --- a/code/datums/inventory_slots/slots/slot_belt.dm +++ b/code/datums/inventory_slots/slots/slot_belt.dm @@ -12,13 +12,16 @@ /datum/inventory_slot/belt/can_equip_to_slot(var/mob/user, var/obj/item/prop, var/disable_warning) . = ..() if(.) - // If they have a uniform slot, they need a uniform to wear a belt. + // Things with this flag can be worn on the belt slot without a uniform. + if(prop.item_flags & ITEM_FLAG_IS_BELT) + return TRUE + // Otherwise, if they have a uniform slot, they need a uniform to wear a belt. var/datum/inventory_slot/check_slot = user.get_inventory_slot_datum(slot_w_uniform_str) - if(check_slot && !check_slot.get_equipped_item()) - if(!disable_warning) - to_chat(user, SPAN_WARNING("You need to be wearing something on your body before you can wear \the [prop].")) - return FALSE - return (prop.item_flags & ITEM_FLAG_IS_BELT) + if(check_slot?.get_equipped_item()) + return TRUE + if(!disable_warning) + to_chat(user, SPAN_WARNING("You need to be wearing something on your body before you can wear \the [prop].")) + return FALSE /datum/inventory_slot/belt/get_examined_string(mob/owner, mob/user, distance, hideflags, decl/pronouns/pronouns) if(_holding) diff --git a/code/unit_tests/equipment_tests.dm b/code/unit_tests/equipment_tests.dm index 632ff5592df..e15fa9dbad6 100644 --- a/code/unit_tests/equipment_tests.dm +++ b/code/unit_tests/equipment_tests.dm @@ -116,7 +116,7 @@ "[slot_gloves_str]" = /obj/item/clothing/gloves/rainbow, "[slot_l_ear_str]" = /obj/item/clothing/head/hairflower, "[slot_r_ear_str]" = /obj/item/clothing/head/hairflower, - "[slot_belt_str]" = /obj/item/storage/belt/utility, + "[slot_belt_str]" = /obj/item/storage/ore, // note: this should be an item without ITEM_FLAG_IS_BELT "[slot_wear_suit_str]" = /obj/item/clothing/suit/chickensuit )