From 467355d86ecbb237239f220c70cbe86a0de2fb13 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 4 Nov 2023 00:34:26 +0100 Subject: [PATCH] [MIRROR] Better feedback on fulton extraction [MDB IGNORE] (#24762) * Better feedback on fulton extraction (#79452) ## About The Pull Request Just playing issues roulette when I came across this gem of old code. Granted, it's not fully rewritten to perfection, but it should at least be better. Added feedback for both parties, sounds, documentation, and swapped references for weakrefs. Note: It looked like it was trying to put the target around the beacon, but this didn't seem to be working. Fixed this, so now it places them in an open spot around the beacon (unless its blocked) ## Why It's Good For The Game Fixes #35783 Not cool for someone to just zip you up and send you away with no feedback The original issue might not even apply since most(?) only work indoors, but this fixes any case Might fix a hard del?? ## Changelog :cl: fix: Added feedback for both extractor and extractee while using fulton extraction packs. qol: Extraction packs now have better exam text. /:cl: --------- Co-authored-by: Jacquerel * Better feedback on fulton extraction --------- Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Co-authored-by: Jacquerel --- code/modules/mining/fulton.dm | 273 +++++++++++++++++++--------------- 1 file changed, 156 insertions(+), 117 deletions(-) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index 20a436dc5c6..c8c8cf966ba 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -6,136 +6,179 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) icon = 'icons/obj/fulton.dmi' icon_state = "extraction_pack" w_class = WEIGHT_CLASS_NORMAL - var/obj/structure/extraction_point/beacon + /// Beacon weakref + var/datum/weakref/beacon_ref + /// List of networks var/list/beacon_networks = list("station") + /// Number of uses left var/uses_left = 3 + /// Can be used indoors var/can_use_indoors - var/safe_for_living_creatures = 1 + /// Can be used on living creatures + var/safe_for_living_creatures = TRUE + /// Maximum force that can be used to extract var/max_force_fulton = MOVE_FORCE_STRONG /obj/item/extraction_pack/examine() . = ..() - . += "It has [uses_left] use\s remaining." + . += span_infoplain("It has [uses_left] use\s remaining.") + + var/obj/structure/extraction_point/beacon = beacon_ref?.resolve() + + if(isnull(beacon)) + beacon_ref = null + . += span_infoplain("It is not linked to a beacon.") + return + + . += span_infoplain("It is linked to [beacon.name].") /obj/item/extraction_pack/attack_self(mob/user) var/list/possible_beacons = list() - for(var/obj/structure/extraction_point/extraction_point as anything in GLOB.total_extraction_beacons) + for(var/datum/weakref/point_ref as anything in GLOB.total_extraction_beacons) + var/obj/structure/extraction_point/extraction_point = point_ref.resolve() + if(isnull(extraction_point)) + GLOB.total_extraction_beacons.Remove(point_ref) if(extraction_point.beacon_network in beacon_networks) possible_beacons += extraction_point if(!length(possible_beacons)) - to_chat(user, span_warning("There are no extraction beacons in existence!")) + balloon_alert(user, "no beacons") return - else - var/chosen_beacon = tgui_input_list(user, "Beacon to connect to", "Balloon Extraction Pack", sort_names(possible_beacons)) - if(isnull(chosen_beacon)) - return - beacon = chosen_beacon - to_chat(user, span_notice("You link the extraction pack to the beacon system.")) -/obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params) + var/chosen_beacon = tgui_input_list(user, "Beacon to connect to", "Balloon Extraction Pack", sort_names(possible_beacons)) + if(isnull(chosen_beacon)) + return + + beacon_ref = WEAKREF(chosen_beacon) + balloon_alert(user, "linked!") + +/obj/item/extraction_pack/afterattack(atom/movable/thing, mob/living/carbon/human/user, proximity_flag, params) . = ..() . |= AFTERATTACK_PROCESSED_ITEM - if(!beacon) - to_chat(user, span_warning("[src] is not linked to a beacon, and cannot be used!")) - return - if(!(beacon in GLOB.total_extraction_beacons)) - beacon = null - to_chat(user, span_warning("The connected beacon has been destroyed!")) - return - if(!can_use_indoors) - var/area/area = get_area(A) - if(!area.outdoors) - to_chat(user, span_warning("[src] can only be used on things that are outdoors!")) - return - if(!flag) - return - if(!istype(A)) - return - else - if(!safe_for_living_creatures && check_for_living_mobs(A)) - to_chat(user, span_warning("[src] is not safe for use with living creatures, they wouldn't survive the trip back!")) - return - if(!isturf(A.loc)) // no extracting stuff inside other stuff - return - if(A.anchored || (A.move_resist > max_force_fulton)) - return - to_chat(user, span_notice("You start attaching the pack to [A]...")) - if(do_after(user,50,target=A)) - to_chat(user, span_notice("You attach the pack to [A] and activate it.")) - if(loc == user) - user.back?.atom_storage?.attempt_insert(src, user, force = STORAGE_SOFT_LOCKED) - uses_left-- - if(uses_left <= 0) - user.transferItemToLoc(src, A, TRUE) - var/mutable_appearance/balloon - var/mutable_appearance/balloon2 - var/mutable_appearance/balloon3 - if(isliving(A)) - var/mob/living/M = A - M.Paralyze(320) // Keep them from moving during the duration of the extraction - if(M.buckled) - M.buckled.unbuckle_mob(M, TRUE) // Unbuckle them to prevent anchoring problems - else - A.set_anchored(TRUE) - A.set_density(FALSE) - var/obj/effect/extraction_holder/holder_obj = new(A.loc) - holder_obj.appearance = A.appearance - A.forceMove(holder_obj) - balloon2 = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_expand") - balloon2.pixel_y = 10 - balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.add_overlay(balloon2) - sleep(0.4 SECONDS) - balloon = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_balloon") - balloon.pixel_y = 10 - balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.cut_overlay(balloon2) - holder_obj.add_overlay(balloon) - playsound(holder_obj.loc, 'sound/items/fultext_deploy.ogg', 50, TRUE, -3) - animate(holder_obj, pixel_z = 10, time = 20) - sleep(2 SECONDS) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(1 SECONDS) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(1 SECONDS) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(1 SECONDS) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(1 SECONDS) - playsound(holder_obj.loc, 'sound/items/fultext_launch.ogg', 50, TRUE, -3) - animate(holder_obj, pixel_z = 1000, time = 30) - if(ishuman(A)) - var/mob/living/carbon/human/L = A - L.SetUnconscious(0) - L.remove_status_effect(/datum/status_effect/drowsiness) - L.SetSleeping(0) - sleep(3 SECONDS) - var/list/flooring_near_beacon = list() - for(var/turf/open/floor in orange(1, beacon)) - flooring_near_beacon += floor - holder_obj.forceMove(pick(flooring_near_beacon)) - animate(holder_obj, pixel_z = 10, time = 50) - sleep(5 SECONDS) - animate(holder_obj, pixel_z = 15, time = 10) - sleep(1 SECONDS) - animate(holder_obj, pixel_z = 10, time = 10) - sleep(1 SECONDS) - balloon3 = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_retract") - balloon3.pixel_y = 10 - balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM - holder_obj.cut_overlay(balloon) - holder_obj.add_overlay(balloon3) - sleep(0.4 SECONDS) - holder_obj.cut_overlay(balloon3) - A.set_anchored(FALSE) // An item has to be unanchored to be extracted in the first place. - A.set_density(initial(A.density)) - animate(holder_obj, pixel_z = 0, time = 5) - sleep(0.5 SECONDS) - A.forceMove(holder_obj.loc) - qdel(holder_obj) - if(uses_left <= 0) - qdel(src) + var/obj/structure/extraction_point/beacon = beacon_ref?.resolve() + if(isnull(beacon)) + balloon_alert(user, "not linked") + beacon_ref = null + return + + if(!can_use_indoors) + var/area/area = get_area(thing) + if(!area.outdoors) + balloon_alert(user, "not outdoors") + return + + if(!proximity_flag || !istype(thing)) + return + + if(!safe_for_living_creatures && check_for_living_mobs(thing)) + to_chat(user, span_warning("[src] is not safe for use with living creatures, they wouldn't survive the trip back!")) + balloon_alert(user, "not safe!") + return + + if(!isturf(thing.loc)) // no extracting stuff inside other stuff + return + if(thing.anchored || (thing.move_resist > max_force_fulton)) + return + + balloon_alert_to_viewers("attaching...") + playsound(thing, 'sound/items/zip.ogg', vol = 50, vary = TRUE) + if(isliving(thing)) + var/mob/living/creature = thing + if(creature.mind) + to_chat(thing, span_userdanger("You are being extracted! Stand still to proceed.")) + + if(!do_after(user, 5 SECONDS, target = thing)) + return + + balloon_alert_to_viewers("extracting!") + if(loc == user) + user.back?.atom_storage?.attempt_insert(src, user, force = STORAGE_SOFT_LOCKED) + uses_left-- + + if(uses_left <= 0) + user.transferItemToLoc(src, thing, TRUE) + + var/mutable_appearance/balloon + var/mutable_appearance/balloon2 + var/mutable_appearance/balloon3 + + if(isliving(thing)) + var/mob/living/creature = thing + creature.Paralyze(32 SECONDS) // Keep them from moving during the duration of the extraction + if(creature.buckled) + creature.buckled.unbuckle_mob(creature, TRUE) // Unbuckle them to prevent anchoring problems + else + thing.set_anchored(TRUE) + thing.set_density(FALSE) + + var/obj/effect/extraction_holder/holder_obj = new(get_turf(thing)) + holder_obj.appearance = thing.appearance + thing.forceMove(holder_obj) + balloon2 = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_expand") + balloon2.pixel_y = 10 + balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.add_overlay(balloon2) + + sleep(0.4 SECONDS) + + balloon = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_balloon") + balloon.pixel_y = 10 + balloon.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon2) + holder_obj.add_overlay(balloon) + playsound(holder_obj.loc, 'sound/items/fultext_deploy.ogg', vol = 50, vary = TRUE, extrarange = -3) + + animate(holder_obj, pixel_z = 10, time = 2 SECONDS) + animate(pixel_z = 15, time = 1 SECONDS) + animate(pixel_z = 10, time = 1 SECONDS) + animate(pixel_z = 15, time = 1 SECONDS) + animate(pixel_z = 10, time = 1 SECONDS) + sleep(6 SECONDS) + + playsound(holder_obj.loc, 'sound/items/fultext_launch.ogg', vol = 50, vary = TRUE, extrarange = -3) + animate(holder_obj, pixel_z = 1000, time = 3 SECONDS) + + if(ishuman(thing)) + var/mob/living/carbon/human/creature = thing + creature.SetUnconscious(0) + creature.remove_status_effect(/datum/status_effect/drowsiness) + creature.SetSleeping(0) + + sleep(3 SECONDS) + + var/turf/flooring_near_beacon = list() + var/turf/beacon_turf = get_turf(beacon) + for(var/turf/floor as anything in RANGE_TURFS(1, beacon_turf)) + if(!floor.is_blocked_turf()) + flooring_near_beacon += floor + + if(!length(flooring_near_beacon)) + flooring_near_beacon += beacon_turf + + holder_obj.forceMove(pick(flooring_near_beacon)) + + animate(holder_obj, pixel_z = 10, time = 5 SECONDS) + animate(pixel_z = 15, time = 1 SECONDS) + animate(pixel_z = 10, time = 1 SECONDS) + sleep(7 SECONDS) + + balloon3 = mutable_appearance('icons/effects/fulton_balloon.dmi', "fulton_retract") + balloon3.pixel_y = 10 + balloon3.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.cut_overlay(balloon) + holder_obj.add_overlay(balloon3) + sleep(0.4 SECONDS) + + holder_obj.cut_overlay(balloon3) + thing.set_anchored(FALSE) // An item has to be unanchored to be extracted in the first place. + thing.set_density(initial(thing.density)) + animate(holder_obj, pixel_z = 0, time = 0.5 SECONDS) + sleep(0.5 SECONDS) + + thing.forceMove(holder_obj.loc) + qdel(holder_obj) + if(uses_left <= 0) + qdel(src) /obj/item/fulton_core name = "extraction beacon assembly kit" @@ -162,13 +205,9 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) /obj/structure/extraction_point/Initialize(mapload) . = ..() name += " ([rand(100,999)]) ([get_area_name(src, TRUE)])" - GLOB.total_extraction_beacons += src + GLOB.total_extraction_beacons.Add(WEAKREF(src)) update_appearance(UPDATE_OVERLAYS) -/obj/structure/extraction_point/Destroy() - GLOB.total_extraction_beacons -= src - return ..() - /obj/structure/extraction_point/attack_hand(mob/living/user, list/modifiers) . = ..() balloon_alert_to_viewers("undeploying...")