From 1c80ef4d357bad4c14ff4a5d1945f144ea312347 Mon Sep 17 00:00:00 2001 From: Kashargul <144968721+Kashargul@users.noreply.github.com> Date: Mon, 6 Apr 2026 07:26:31 +0200 Subject: [PATCH] plane holder hard dels (#19374) * plane holder hard dels * . * . * . * vac hard del * this * . * . --------- Co-authored-by: Cameron Lennox --- code/_onclick/hud/map_view.dm | 1 + code/datums/chat_message.dm | 2 +- .../items/devices/communicator/UI_tgui.dm | 9 +++ code/game/objects/items/devices/vacpack.dm | 79 ++++++++++--------- code/game/objects/mail.dm | 4 + code/modules/admin/admin.dm | 2 +- code/modules/mining/mine_turfs.dm | 8 +- code/modules/overmap/overmap_object.dm | 3 +- .../tgui/modules/appearance_changer.dm | 1 + .../xenoarcheaology/finds/find_spawning.dm | 2 +- 10 files changed, 65 insertions(+), 46 deletions(-) diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/map_view.dm index 6457181a5c..e5c0e8ac05 100644 --- a/code/_onclick/hud/map_view.dm +++ b/code/_onclick/hud/map_view.dm @@ -18,6 +18,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view_tg) /atom/movable/screen/map_view_tg/Destroy() for(var/datum/weakref/client_ref in viewing_clients) hide_from_client(client_ref.resolve()) + QDEL_LIST_NULL(popup_plane_masters) return ..() diff --git a/code/datums/chat_message.dm b/code/datums/chat_message.dm index e8c658107e..a37048b08b 100644 --- a/code/datums/chat_message.dm +++ b/code/datums/chat_message.dm @@ -155,7 +155,7 @@ GLOBAL_LIST_EMPTY(runechat_image_cache) for(var/word in names) if(length(word) > 3) - parts += word + parts += REGEX_QUOTE(word) var/regex/message_regex = new("\\b(" + parts.Join("|") + ")\\b(?!\[^<]*>)", "gi") diff --git a/code/game/objects/items/devices/communicator/UI_tgui.dm b/code/game/objects/items/devices/communicator/UI_tgui.dm index f1f091afcc..0e32a8b05d 100644 --- a/code/game/objects/items/devices/communicator/UI_tgui.dm +++ b/code/game/objects/items/devices/communicator/UI_tgui.dm @@ -9,6 +9,15 @@ var/atom/movable/screen/background/cam_background var/atom/movable/screen/skybox/local_skybox +/obj/item/communicator/Destroy() + if(cam_screen) + QDEL_NULL(cam_screen) + QDEL_LIST_NULL(cam_plane_masters) + if(cam_background) + QDEL_NULL(cam_background) + local_skybox = null + . = ..() + // Proc: setup_tgui_camera() // Parameters: None // Description: This sets up all of the variables above to handle in-UI map windows. diff --git a/code/game/objects/items/devices/vacpack.dm b/code/game/objects/items/devices/vacpack.dm index 490012ed61..3493189f62 100644 --- a/code/game/objects/items/devices/vacpack.dm +++ b/code/game/objects/items/devices/vacpack.dm @@ -8,7 +8,7 @@ item_state = "sucker" slot_flags = SLOT_BELT | SLOT_BACK var/vac_power = 0 - var/output_dest = null + var/datum/weakref/output_dest var/list/vac_settings = list( "power off" = 0, "dust and grime" = 1, @@ -29,12 +29,16 @@ var/max_items = 20 flags = NOBLUDGEON +/obj/item/vac_attachment/Destroy() + output_dest = null + . = ..() + /obj/item/vac_attachment/attack_self(mob/user) . = ..(user) if(.) return TRUE var/set_input = null - if(!output_dest) + if(!output_dest?.resolve()) set_input = "output destination" if(!set_input) set_input = tgui_input_list(user, "Set your [suckverb] attachment's power level or output mode.", "Vac Settings", vac_settings) @@ -54,7 +58,7 @@ var/obj/item/robot_module/M = R.module for(var/obj/item/dogborg/sleeper/S in M.modules) if(istype(S)) - output_dest = S + output_dest = WEAKREF(S) return to_chat(user, span_warning("Borg belly not found.")) if("Trash Bag") @@ -63,16 +67,16 @@ var/obj/item/robot_module/M = R.module for(var/obj/item/storage/bag/trash/T in M.modules) if(istype(T)) - output_dest = T + output_dest = WEAKREF(T) return for(var/obj/item/storage/bag/trash/T in user.contents) if(istype(T)) - output_dest = T + output_dest = WEAKREF(T) return to_chat(user, span_warning("Trash bag not found.")) if("Vore Belly") if(user.vore_selected) - output_dest = user.vore_selected + output_dest = WEAKREF(user.vore_selected) return else vac_power = vac_settings[set_input] @@ -83,24 +87,25 @@ return if(!proximity) return - if(!output_dest) + var/atom/movable/output_atom = output_dest?.resolve() + if(!output_atom) return - if(istype(output_dest,/obj/item/storage/bag/trash)) - if(get_turf(output_dest) != get_turf(user)) + if(istype(output_atom, /obj/item/storage/bag/trash)) + if(get_turf(output_atom) != get_turf(user)) vac_power = 0 icon_state = "sucker-0" output_dest = null to_chat(user, span_warning("Trash bag not found. Shutting down.")) return - var/obj/item/storage/bag/trash/B = output_dest + var/obj/item/storage/bag/trash/B = output_atom var/total_storage_space = 0 for(var/obj/item/thing in B.contents)//no more leniency on this one. We check it all. B total_storage_space += thing.get_storage_cost() if(total_storage_space >= B.max_storage_space) to_chat(user, span_warning("Trash bag full. Empty trash bag contents to continue.")) return - if(istype(output_dest,/obj/item/dogborg/sleeper)) - var/obj/item/dogborg/sleeper/B = output_dest + if(istype(output_atom, /obj/item/dogborg/sleeper)) + var/obj/item/dogborg/sleeper/B = output_atom if(LAZYLEN(B.contents) >= B.max_item_count) to_chat(user, span_warning("[B.name] full. Empty or process contents to continue.")) return @@ -108,8 +113,8 @@ if(B.current_capacity >= B.max_ore_storage) to_chat(user, span_warning("Ore storage full. Deposit ore contents to a box continue.")) return - if(isbelly(output_dest)) - var/turf/T = get_turf(output_dest) + if(isbelly(output_atom)) + var/turf/T = get_turf(output_atom) if(!T.Adjacent(user)) //Can still be used as a feeding tube by another adjacent player. if(vac_owner && user != vac_owner) return @@ -131,7 +136,7 @@ if(vac_power == 8) playsound(src, 'sound/machines/hiss.ogg', 100, 1, -1) for(var/obj/item/I in oview(pull_range, target)) - if(I.anchored || !is_allowed_suck(I, user)) + if(I.anchored || !is_allowed_suck(I, user, output_atom)) continue I.singularity_pull(target, STAGE_THREE) suckables += I @@ -184,13 +189,13 @@ if(is_type_in_list(F, GLOB.item_vore_blacklist)) continue if(istype(F,/obj/effect/decal/cleanable)) - if(isbelly(output_dest)) - var/obj/belly/B = output_dest + if(isbelly(output_atom)) + var/obj/belly/B = output_atom B.owner_adjust_nutrition(1) qdel(F) continue - if(istype(output_dest,/obj/item/storage/bag/trash)) - var/obj/item/storage/bag/trash/B = output_dest + if(istype(output_atom,/obj/item/storage/bag/trash)) + var/obj/item/storage/bag/trash/B = output_atom if(LAZYLEN(B.contents) >= B.max_storage_space) to_chat(user, span_warning("Trash bag full. Empty trash bag contents to continue.")) break @@ -199,15 +204,15 @@ if(vac_conga < 100) vac_conga += 3 addtimer(CALLBACK(src, PROC_REF(prepare_sucking), F, user, auto_setting, target), 0.3 SECONDS + vac_conga) - else if(is_allowed_suck(target, user)) + else if(is_allowed_suck(target, user, output_atom)) handle_consumption(F, user, auto_setting) if(vac_conga > 0) var/obj/effect/vac_visual/V = new(target) V.ready(0.5 SECONDS + vac_conga) if(istype(target, /turf/simulated)) var/turf/simulated/T = target - if(isbelly(output_dest) && T.dirt > 50) - var/obj/belly/B = output_dest + if(isbelly(output_atom) && T.dirt > 50) + var/obj/belly/B = output_atom B.owner_adjust_nutrition((T.dirt - 50) / 10) //Max tile dirt is 101. so about 5 nutrition from a disgusting floor, I think that's okay. T.dirt = 0 T.wash(CLEAN_WASH) @@ -220,7 +225,7 @@ var/obj/item/I = target if(is_type_in_list(I, GLOB.item_vore_blacklist) || I.w_class >= ITEMSIZE_HUGE) return - if(!is_allowed_suck(target, user)) //cancel if you're not allowed + if(!is_allowed_suck(target, user, output_atom)) //cancel if you're not allowed return if(vac_power > I.w_class) if(vac_power == 7) @@ -252,7 +257,7 @@ if(vac_power >= 6) valid_to_suck = TRUE auto_setting = 6 - if(valid_to_suck && is_allowed_suck(target, user)) + if(valid_to_suck && is_allowed_suck(target, user, output_atom)) playsound(src, sucksound, auto_setting * 20, 1, -1) user.visible_message(span_filter_notice("[user] [suckverb]s up \the [target.name]."), span_notice("You [suckverb] up \the [target.name]...")) if(suckanim) @@ -260,9 +265,10 @@ addtimer(CALLBACK(src, PROC_REF(handle_consumption), L, user, auto_setting), 0.5 SECONDS) /obj/item/vac_attachment/proc/prepare_sucking(atom/movable/target, mob/user, turf/target_turf) - if(!target.Adjacent(user) || src.loc != user || vac_power < 2 || !output_dest) //Cancel if moved/unpowered/dropped + var/atom/movable/output_atom = output_dest?.resolve() + if(!target.Adjacent(user) || src.loc != user || vac_power < 2 || !output_atom) //Cancel if moved/unpowered/dropped return - if(!is_allowed_suck(target, user)) //cancel if you're not allowed + if(!is_allowed_suck(target, user, output_atom)) //cancel if you're not allowed return target.SpinAnimation(5,1) addtimer(CALLBACK(src, PROC_REF(handle_consumption), target, user, target_turf), 0.5 SECONDS) @@ -270,26 +276,27 @@ /obj/item/vac_attachment/proc/handle_consumption(atom/movable/target, mob/user, auto_setting, turf/target_turf) if(target_turf && target.loc != target_turf) return - if(!target.Adjacent(user) || src.loc != user || vac_power < 2 || !output_dest) //Cancel if moved/unpowered/dropped + var/atom/movable/output_atom = output_dest?.resolve() + if(!target.Adjacent(user) || src.loc != user || vac_power < 2 || !output_atom) //Cancel if moved/unpowered/dropped return - if(!is_allowed_suck(target, user)) //Does it obey restrictions on what the target could otherwise consume? + if(!is_allowed_suck(target, user, output_atom)) //Does it obey restrictions on what the target could otherwise consume? return if(isitem(target)) var/obj/item/target_item = target if(target_item.drop_sound) playsound(src, target_item.drop_sound, vac_power * 5, 1, -1) playsound(src, 'sound/rakshasa/corrosion3.ogg', auto_setting * 15, 1, -1) - if(isbelly(output_dest)) - var/obj/belly/output_belly = output_dest + if(isbelly(output_atom)) + var/obj/belly/output_belly = output_atom output_belly.nom_atom(target) return - target.forceMove(output_dest) + target.forceMove(output_atom) -/obj/item/vac_attachment/proc/is_allowed_suck(atom/movable/target, mob/user) //a ray of light in this inscrutible file. Check if we *can* fit what we want to fit, where we want to fit it. This does NOT check all the sanity checks n stuff +/obj/item/vac_attachment/proc/is_allowed_suck(atom/movable/target, mob/user, atom/movable/output_atom) //a ray of light in this inscrutible file. Check if we *can* fit what we want to fit, where we want to fit it. This does NOT check all the sanity checks n stuff if(isitem(target)) var/obj/item/target_item = target - if(istype(output_dest, /obj/item/storage))//if it's storage, does it fit? - var/obj/item/storage/target_storage = output_dest + if(istype(output_atom, /obj/item/storage))//if it's storage, does it fit? + var/obj/item/storage/target_storage = output_atom if(target_storage.can_be_inserted(target_item, TRUE)) return TRUE else//if it's not a trash bag, it's a vorebelly or borg belly. Check trash eat @@ -302,8 +309,8 @@ if(isliving(target)) //quick prefs test. Better safe than sorry var/mob/living/caneat = target if(caneat.devourable && caneat.can_be_drop_prey) - if(istype(output_dest, /obj/item/storage))//check if a mob holder's gonna fit there! - var/obj/item/storage/target_storage = output_dest + if(istype(output_atom, /obj/item/storage))//check if a mob holder's gonna fit there! + var/obj/item/storage/target_storage = output_atom var/total_storage_space = ITEMSIZE_COST_SMALL for(var/obj/item/thing in target_storage.contents) total_storage_space += thing.get_storage_cost() diff --git a/code/game/objects/mail.dm b/code/game/objects/mail.dm index f040e7f26b..79c769a162 100644 --- a/code/game/objects/mail.dm +++ b/code/game/objects/mail.dm @@ -78,6 +78,10 @@ for(var/i = 1, i <= stamp_count, i++) stamps += list("stamp_[rand(2, 8)]") +/obj/item/mail/Destroy() + recipient_ref = null + . = ..() + /obj/item/mail/blank desc = "A blank envelope." description_info = "An object can be placed into the envelope, click on it with an empty hand to seal it. Alt-Click to retrieve the items from inside before sealing." diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 1eab3e10b6..07e5436aa2 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -1062,7 +1062,7 @@ ADMIN_VERB(spawn_atom, R_SPAWN, "Spawn", "(atom path) Spawn an atom", ADMIN_CATE log_and_message_admins("spawned [amount] x [chosen_path] at [AREACOORD(user.mob)]", user) feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! -ADMIN_VERB(show_traitor_panel, R_ADMIN|R_FUN|R_EVENT, "Show Traitor Panel", "Edit mobs's memory and role", ADMIN_CATEGORY_EVENTS, mob/M in GLOB.mob_list) +ADMIN_VERB_AND_CONTEXT_MENU(show_traitor_panel, R_ADMIN|R_FUN|R_EVENT, "Show Traitor Panel", "Edit mobs's memory and role", ADMIN_CATEGORY_EVENTS, mob/M in GLOB.mob_list) if(!istype(M)) to_chat(user, "This can only be used on instances of type /mob") return diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index fceb66f33c..6742963b73 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -48,7 +48,7 @@ GLOBAL_LIST_EMPTY(mining_overlay_cache) var/next_rock = 0 var/archaeo_overlay = "" var/excav_overlay = "" - var/obj/item/last_find + var/last_find_name var/datum/artifact_find/artifact_find var/ignore_mapgen @@ -692,10 +692,8 @@ GLOBAL_LIST_EMPTY(mining_overlay_cache) //some find types delete the /obj/item/archaeological_find and replace it with something else, this handles when that happens //yuck var/display_name = "Something" - if(!X) - X = last_find - if(X) - display_name = X.name + if(last_find_name) + display_name = last_find_name //This is affected by 'prob_delicate' in finds.dm. As of writing, this has been set to 0 because the suspension field is just one extra piece that makes //Xenoarch that much more confusing, and the intent of this PR is to make it more friendly to get into. diff --git a/code/modules/overmap/overmap_object.dm b/code/modules/overmap/overmap_object.dm index 30489e83fb..ea718004c6 100644 --- a/code/modules/overmap/overmap_object.dm +++ b/code/modules/overmap/overmap_object.dm @@ -66,8 +66,7 @@ if(cam_screen) QDEL_NULL(cam_screen) - if(cam_plane_masters) - QDEL_LIST(cam_plane_masters) + QDEL_LIST_NULL(cam_plane_masters) if(cam_background) QDEL_NULL(cam_background) diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index af1366a728..7aebff0381 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -105,6 +105,7 @@ QDEL_NULL(cam_screen) QDEL_LIST(cam_plane_masters) QDEL_NULL(cam_background) + local_skybox = null return ..() /datum/tgui_module/appearance_changer/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state) diff --git a/code/modules/xenoarcheaology/finds/find_spawning.dm b/code/modules/xenoarcheaology/finds/find_spawning.dm index b6c39449a2..c83ab81ec1 100644 --- a/code/modules/xenoarcheaology/finds/find_spawning.dm +++ b/code/modules/xenoarcheaology/finds/find_spawning.dm @@ -879,7 +879,7 @@ var/turf/simulated/mineral/T = get_turf(new_item) if(istype(T)) - T.last_find = new_item + T.last_find_name = new_item.name if(secondary_item) //Is this part of a set? if(talkative) secondary_item.talking_atom = new(secondary_item)