mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-19 03:55:11 +01:00
[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 🆑 fix: Added feedback for both extractor and extractee while using fulton extraction packs. qol: Extraction packs now have better exam text. /🆑 --------- Co-authored-by: Jacquerel <hnevard@ gmail.com> * Better feedback on fulton extraction --------- Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com> Co-authored-by: Jacquerel <hnevard@ gmail.com>
This commit is contained in:
+156
-117
@@ -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...")
|
||||
|
||||
Reference in New Issue
Block a user