diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm new file mode 100644 index 0000000000..dd9c068a17 --- /dev/null +++ b/code/modules/mining/fulton.dm @@ -0,0 +1,191 @@ +var/global/list/total_extraction_beacons = list() + +/obj/item/extraction_pack + name = "fulton extraction pack" + desc = "A balloon that can be used to extract equipment or personnel to a Fulton Recovery Beacon. Anything not bolted down can be moved. Link the pack to a beacon by using the pack in hand." + icon = 'icons/obj/fulton.dmi' + icon_state = "extraction_pack" + w_class = ITEMSIZE_NORMAL + var/obj/structure/extraction_point/beacon + var/list/beacon_networks = list("station") + var/uses_left = 3 + var/can_use_indoors + var/safe_for_living_creatures = 1 + +/obj/item/extraction_pack/examine() + . = ..() + usr.show_message("It has [uses_left] use\s remaining.", 1) + +/obj/item/extraction_pack/attack_self(mob/user) + var/list/possible_beacons = list() + for(var/B in global.total_extraction_beacons) + var/obj/structure/extraction_point/EP = B + if(EP.beacon_network in beacon_networks) + possible_beacons += EP + + if(!possible_beacons.len) + to_chat(user, "There are no extraction beacons in existence!") + return + + else + var/A + + A = input("Select a beacon to connect to", "Balloon Extraction Pack", A) as null|anything in possible_beacons + + if(!A) + return + beacon = A + to_chat(user, "You link the extraction pack to the beacon system.") + +/obj/item/extraction_pack/afterattack(atom/movable/A, mob/living/carbon/human/user, flag, params) + if(!beacon) + to_chat(user, "[src] is not linked to a beacon, and cannot be used.") + return + if(!can_use_indoors) + var/turf/T = get_turf(A) + if(T && !T.outdoors) + to_chat(user, "[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, "[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) + return + to_chat(user, "You start attaching the pack to [A]...") + if(do_after(user,50,target=A)) + to_chat(user, "You attach the pack to [A] and activate it.") + /* No components, sorry. No convienence for you! + if(loc == user && istype(user.back, /obj/item/storage/backpack)) + var/obj/item/storage/backpack/B = user.back + B.SendSignal(COMSIG_TRY_STORAGE_INSERT, src, user, FALSE, FALSE) + */ + uses_left-- + if(uses_left <= 0) + user.drop_from_inventory(src, A) + var/mutable_appearance/balloon + var/mutable_appearance/balloon2 + var/mutable_appearance/balloon3 + if(isliving(A)) + var/mob/living/M = A + M.AdjustStunned(20) // Keep them from moving during the duration of the extraction + if(M.buckled) + M.buckled.unbuckle_mob(M) + else + A.anchored = TRUE + A.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/obj/fulton_balloon.dmi', "fulton_expand") + balloon2.pixel_y = 10 + balloon2.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + holder_obj.add_overlay(balloon2) + sleep(4) + balloon = mutable_appearance('icons/obj/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/fulext_deploy.wav', 50, 1, -3) + animate(holder_obj, pixel_z = 10, time = 20) + sleep(20) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + playsound(holder_obj.loc, 'sound/items/fultext_launch.wav', 50, 1, -3) + animate(holder_obj, pixel_z = 1000, time = 30) + if(ishuman(A)) + var/mob/living/carbon/human/L = A + L.AdjustStunned(20) + L.drowsyness = 0 + sleep(30) + var/list/flooring_near_beacon = list() + for(var/turf/simulated/floor/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(50) + animate(holder_obj, pixel_z = 15, time = 10) + sleep(10) + animate(holder_obj, pixel_z = 10, time = 10) + sleep(10) + balloon3 = mutable_appearance('icons/obj/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(4) + holder_obj.cut_overlay(balloon3) + A.anchored = FALSE // An item has to be unanchored to be extracted in the first place. + A.density = initial(A.density) + animate(holder_obj, pixel_z = 0, time = 5) + sleep(5) + A.forceMove(holder_obj.loc) + qdel(holder_obj) + if(uses_left <= 0) + qdel(src) + + +/obj/item/fulton_core + name = "extraction beacon signaller" + desc = "Emits a signal which fulton recovery devices can lock onto. Activate in hand to create a beacon." + icon = 'icons/obj/stock_parts.dmi' + icon_state = "subspace_amplifier" + +/obj/item/fulton_core/attack_self(mob/user) + if(do_after(user,15,target = user) && !QDELETED(src)) + new /obj/structure/extraction_point(get_turf(user)) + qdel(src) + +/obj/structure/extraction_point + name = "fulton recovery beacon" + desc = "A beacon for the fulton recovery system. Activate a pack in your hand to link it to a beacon." + icon = 'icons/obj/fulton.dmi' + icon_state = "extraction_point" + anchored = TRUE + density = FALSE + var/beacon_network = "station" + +/obj/structure/extraction_point/initialize() + . = ..() + name += " ([rand(100,999)]) ([get_area_name(src, TRUE)])" + global.total_extraction_beacons += src + +/obj/structure/extraction_point/Destroy() + global.total_extraction_beacons -= src + ..() + +/obj/effect/extraction_holder + name = "extraction holder" + desc = "you shouldnt see this" + var/atom/movable/stored_obj + +/obj/item/extraction_pack/proc/check_for_living_mobs(atom/A) + if(isliving(A)) + var/mob/living/L = A + if(L.stat != DEAD) + return 1 + for(var/thing in A.GetAllContents()) + if(isliving(A)) + var/mob/living/L = A + if(L.stat != DEAD) + return 1 + return 0 + +/obj/effect/extraction_holder/singularity_pull() + return + +/obj/effect/extraction_holder/singularity_pull() + return diff --git a/icons/obj/fulton.dmi b/icons/obj/fulton.dmi new file mode 100644 index 0000000000..c56c275b3b Binary files /dev/null and b/icons/obj/fulton.dmi differ diff --git a/icons/obj/fulton_balloon.dmi b/icons/obj/fulton_balloon.dmi new file mode 100644 index 0000000000..5a1fa98e14 Binary files /dev/null and b/icons/obj/fulton_balloon.dmi differ diff --git a/sound/items/fulext_deploy.wav b/sound/items/fulext_deploy.wav new file mode 100644 index 0000000000..9fbcb7e3f8 Binary files /dev/null and b/sound/items/fulext_deploy.wav differ diff --git a/sound/items/fultext_launch.wav b/sound/items/fultext_launch.wav new file mode 100644 index 0000000000..a623a89ada Binary files /dev/null and b/sound/items/fultext_launch.wav differ diff --git a/vorestation.dme b/vorestation.dme index 07d743c1cc..c94ef9490b 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -1839,6 +1839,7 @@ #include "code\modules\mining\abandonedcrates_vr.dm" #include "code\modules\mining\alloys.dm" #include "code\modules\mining\coins.dm" +#include "code\modules\mining\fulton.dm" #include "code\modules\mining\machine_input_output_plates.dm" #include "code\modules\mining\machine_processing.dm" #include "code\modules\mining\machine_stacking.dm"