From 8a4250ddcd2ea3df94f648d5fd20121f250e4c61 Mon Sep 17 00:00:00 2001 From: PsiOmegaDelta Date: Tue, 17 Nov 2015 22:58:10 +0100 Subject: [PATCH] Can now connect cryo pods and computers with each other using the new multitool methodology. Also cleans up Destroys(). --- baystation12.dme | 4 ++ code/_macros.dm | 2 + code/datums/expansions/expansion.dm | 10 +++ .../datums/expansions/multitool/_multitool.dm | 3 + code/datums/expansions/multitool/cloning.dm | 24 +++++++ code/datums/expansions/multitool/multitool.dm | 69 ++++++++++++++++++- code/datums/expansions/multitool/store.dm | 22 ++++++ .../datums/expansions/multitool/~multitool.dm | 3 + code/game/machinery/cloning.dm | 11 +-- code/game/machinery/computer/cloning.dm | 38 +++++++--- code/game/objects/items/devices/multitool.dm | 12 ++-- code/game/objects/objs.dm | 3 +- code/modules/mob/dead/observer/observer.dm | 7 ++ code/modules/mob/living/silicon/ai/ai.dm | 13 +++- code/modules/mob/mob_helpers.dm | 16 +++++ 15 files changed, 214 insertions(+), 23 deletions(-) create mode 100644 code/datums/expansions/multitool/_multitool.dm create mode 100644 code/datums/expansions/multitool/cloning.dm create mode 100644 code/datums/expansions/multitool/store.dm create mode 100644 code/datums/expansions/multitool/~multitool.dm diff --git a/baystation12.dme b/baystation12.dme index 03a30853ba3..93f012236b4 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -196,7 +196,11 @@ #include "code\datums\diseases\advance\symptoms\vomit.dm" #include "code\datums\diseases\advance\symptoms\weight.dm" #include "code\datums\expansions\expansion.dm" +#include "code\datums\expansions\multitool\_multitool.dm" +#include "code\datums\expansions\multitool\cloning.dm" #include "code\datums\expansions\multitool\multitool.dm" +#include "code\datums\expansions\multitool\store.dm" +#include "code\datums\expansions\multitool\~multitool.dm" #include "code\datums\helper_datums\construction_datum.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" diff --git a/code/_macros.dm b/code/_macros.dm index b6ddf4f12ca..69376b6e5e1 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -23,6 +23,8 @@ #define isnewplayer(A) istype(A, /mob/new_player) +#define isobj(A) istype(A, /obj) + #define isobserver(A) istype(A, /mob/dead/observer) #define isorgan(A) istype(A, /obj/item/organ/external) diff --git a/code/datums/expansions/expansion.dm b/code/datums/expansions/expansion.dm index 1235467b37d..81c53b76dd1 100644 --- a/code/datums/expansions/expansion.dm +++ b/code/datums/expansions/expansion.dm @@ -12,3 +12,13 @@ /datum/expansion/Destroy() holder = null return ..() + +/datum/expansion/CanUseTopic(var/mob/user) + return holder && user && !user.incapacitated() ? STATUS_INTERACTIVE : STATUS_CLOSE + +/datum/expansion/Topic() + if(..()) + return 1 + if(CanUseTopic(usr) != STATUS_INTERACTIVE) + return 1 + return 0 diff --git a/code/datums/expansions/multitool/_multitool.dm b/code/datums/expansions/multitool/_multitool.dm new file mode 100644 index 00000000000..6ec2a8657e7 --- /dev/null +++ b/code/datums/expansions/multitool/_multitool.dm @@ -0,0 +1,3 @@ +#define MT_NOACTION 0 +#define MT_REFRESH 1 +#define MT_CLOSE 2 diff --git a/code/datums/expansions/multitool/cloning.dm b/code/datums/expansions/multitool/cloning.dm new file mode 100644 index 00000000000..fcda47aac45 --- /dev/null +++ b/code/datums/expansions/multitool/cloning.dm @@ -0,0 +1,24 @@ +/datum/expansion/multitool/cryo/get_interact_window(var/obj/item/device/multitool/M, var/mob/user) + return buffer(M) + +/datum/expansion/multitool/cryo/receive_buffer(var/obj/item/device/multitool/M, var/atom/buffer, var/mob/user) + var/obj/machinery/clonepod/P = M.get_buffer(/obj/machinery/clonepod) + var/obj/machinery/computer/cloning/C = holder + + if(!P) + user << "No valid connection data in \the [M] buffer." + return MT_NOACTION + + var/is_connected = (P in C.pods) + if(!is_connected) + if(C.connect_pod(P)) + user << "You connect \the [P] to \the [C]." + else + user << "You failed to connect \the [P] to \the [C]." + return MT_REFRESH + + if(C.release_pod(P)) + user << "You disconnect \the [P] from \the [C]." + else + user << "You failed to disconnect \the [P] from \the [C]." + return MT_REFRESH diff --git a/code/datums/expansions/multitool/multitool.dm b/code/datums/expansions/multitool/multitool.dm index e5e1b51599c..b95bb9f1659 100644 --- a/code/datums/expansions/multitool/multitool.dm +++ b/code/datums/expansions/multitool/multitool.dm @@ -1,2 +1,69 @@ -/datum/expansion/multitool/proc/interact() +/datum/expansion/multitool + var/window_x = 370 + var/window_y = 470 + +/datum/expansion/multitool/proc/interact(var/obj/item/device/multitool/M, var/mob/user) + if(!CanUseTopic(user)) + return + + var/html = get_interact_window(M, user) + if(html) + var/datum/browser/popup = new(usr, "multitool", holder.name, window_x, window_y) + popup.set_content(html) + popup.set_title_image(user.browse_rsc_icon(holder.icon, holder.icon_state)) + popup.open() + else + close_window(usr) + +/datum/expansion/multitool/proc/get_interact_window(var/obj/item/device/multitool/M, var/mob/user) + return + +/datum/expansion/multitool/proc/close_window(var/mob/user) + user << browse(null, "window=multitool") + +/datum/expansion/multitool/proc/buffer(var/obj/item/device/multitool/multitool) + . += "Buffer Memory:
" + if(multitool.buffer_name) + . += "[multitool.buffer_name] Send Purge
" + else + . += "No connection stored in the buffer." + +/datum/expansion/multitool/CanUseTopic(var/mob/user) + . = ..() + if(. == STATUS_CLOSE) + return + + return user.get_multitool() && user.Adjacent(holder) ? STATUS_INTERACTIVE : STATUS_CLOSE + +/datum/expansion/multitool/Topic(href, href_list) + if(..()) + close_window(usr) + return 1 + + var/mob/user = usr + var/obj/item/device/multitool/M = user.get_multitool() + if(href_list["send"]) + var/atom/buffer = locate(href_list["send"]) + . = send_buffer(M, buffer, user) + else if(href_list["purge"]) + M.set_buffer(null) + . = MT_REFRESH + else + . = OnTopic(href, href_list, user) + + switch(.) + if(MT_REFRESH) + interact(M, user) + if(MT_CLOSE) + close_window(user) + return 1 + +/datum/expansion/multitool/proc/OnTopic(href, href_list, usr) + return + +/datum/expansion/multitool/proc/send_buffer(var/obj/item/device/multitool/M, var/atom/buffer, var/mob/user) + if(M.buffer_object == buffer) + receive_buffer(M, buffer, user) + +/datum/expansion/multitool/proc/receive_buffer(var/obj/item/device/multitool/M, var/atom/buffer, var/mob/user) return diff --git a/code/datums/expansions/multitool/store.dm b/code/datums/expansions/multitool/store.dm new file mode 100644 index 00000000000..f41a8d9bf2f --- /dev/null +++ b/code/datums/expansions/multitool/store.dm @@ -0,0 +1,22 @@ +/datum/expansion/multitool/store + var/can_load_connection + +/datum/expansion/multitool/store/New(var/atom/holder, var/can_load_connection) + ..() + src.can_load_connection = can_load_connection + +/datum/expansion/multitool/store/CanUseTopic() + if(can_load_connection && !call(src, can_load_connection)()) + return STATUS_CLOSE + return ..() + +/datum/expansion/multitool/store/interact(var/obj/item/device/multitool/M, var/mob/user) + if(!CanUseTopic(user)) + return + + if(M.get_buffer() == holder) + M.set_buffer(null) + user << "You purge the connection data of \the [holder] from \the [M]." + else + M.set_buffer(holder) + user << "You load connection data from \the [holder] to \the [M]." diff --git a/code/datums/expansions/multitool/~multitool.dm b/code/datums/expansions/multitool/~multitool.dm new file mode 100644 index 00000000000..875f0e47cc0 --- /dev/null +++ b/code/datums/expansions/multitool/~multitool.dm @@ -0,0 +1,3 @@ +#undef MT_NOACTION +#undef MT_REFRESH +#undef MT_CLOSE diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 3c5f44ea6e3..1a14c9e59f9 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -57,6 +57,12 @@ RefreshParts() update_icon() + expansions[/datum/expansion/multitool] = new/datum/expansion/multitool/store(src) + +/obj/machinery/clonepod/Destroy() + if(connected) + connected.release_pod(src) + return ..() /obj/machinery/clonepod/attack_ai(mob/user as mob) @@ -239,11 +245,6 @@ user.visible_message("[user] secures [src] to the floor.", "You secure [src] to the floor.") else user.visible_message("[user] unsecures [src] from the floor.", "You unsecure [src] from the floor.") - else if(istype(W, /obj/item/device/multitool)) - var/obj/item/device/multitool/M = W - M.set_buffer(src) - user << "You load connection data from [src] to [M]." - return else ..() diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 872a5ce8a54..97b196df3ad 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -18,11 +18,12 @@ /obj/machinery/computer/cloning/initialize() ..() + expansions[/datum/expansion/multitool] = new/datum/expansion/multitool/cryo(src) updatemodules() /obj/machinery/computer/cloning/Destroy() releasecloner() - ..() + return ..() /obj/machinery/computer/cloning/proc/updatemodules() src.scanner = findscanner() @@ -52,6 +53,33 @@ P.name = initial(P.name) pods.Cut() +/obj/machinery/computer/cloning/proc/connect_pod(var/obj/machinery/clonepod/P) + if(P in pods) + return 0 + + if(P.connected) + P.connected.release_pod(P) + P.connected = src + pods += P + rename_pods() + + return 1 + +/obj/machinery/computer/cloning/proc/release_pod(var/obj/machinery/clonepod/P) + if(!(P in pods)) + return + + P.connected = null + P.name = initial(P.name) + pods -= P + rename_pods() + return 1 + +/obj/machinery/computer/cloning/proc/rename_pods() + for(var/i = 1 to pods.len) + var/atom/P = pods[i] + P.name = "[initial(P.name)] #[i]" + /obj/machinery/computer/cloning/proc/findcloner() var/num = 1 var/area/A = get_area(src) @@ -70,14 +98,6 @@ user << "You insert [W]." src.updateUsrDialog() return - else if(istype(W, /obj/item/device/multitool)) - var/obj/item/device/multitool/M = W - var/obj/machinery/clonepod/P = M.get_buffer() - if(istype(P) && !(P in pods)) - pods += P - P.connected = src - P.name = "[initial(P.name)] #[pods.len]" - user << "You connect [P] to [src]." else ..() return diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm index d53ab1f5bbd..e383bd0d044 100644 --- a/code/game/objects/items/devices/multitool.dm +++ b/code/game/objects/items/devices/multitool.dm @@ -23,18 +23,20 @@ var/buffer_name var/atom/buffer_object -/obj/item/device/multitool/proc/get_buffer() - if(buffer_object) +/obj/item/device/multitool/proc/get_buffer(var/typepath) + // Update the buffer name only when someone fetches the buffer. + // Means you cannot be sure the source hasn't been destroyed until the very moment it's needed. + buffer_name = buffer_object ? buffer_object.name : null + if(buffer_object && (!typepath || istype(buffer_object, typepath))) return buffer_object - buffer_name = null /obj/item/device/multitool/proc/set_buffer(var/atom/buffer) if(!buffer || istype(buffer)) buffer_object = buffer - buffer_name = buffer ? buffer_name : null + buffer_name = buffer ? buffer.name : null /obj/item/device/multitool/resolve_attackby(atom/A, mob/user) - if(!isobject(A)) + if(!isobj(A)) return ..(A, user) var/obj/O = A diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index b40972a11ac..dc9d37a93d5 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -21,7 +21,8 @@ processing_objects -= src for(var/expansion in expansions) qdel(expansions[expansion]) - expansions.Cut() + if(expansions) + expansions.Cut() return ..() /obj/Topic(href, href_list, var/datum/topic_state/state = default_state) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 3a73bffb700..d1b01b6c21e 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -29,6 +29,8 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images var/image/ghostimage = null //this mobs ghost image, for deleting and stuff var/ghostvision = 1 //is the ghost able to see things humans can't? var/seedarkness = 1 + + var/obj/item/device/multitool/ghost_multitool incorporeal_move = 1 /mob/dead/observer/New(mob/body) @@ -79,9 +81,14 @@ var/global/list/image/ghost_sightless_images = list() //this is a list of images if(!name) //To prevent nameless ghosts name = capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names)) real_name = name + + ghost_multitool = new(src) ..() /mob/dead/observer/Destroy() + qdel(ghost_multitool) + ghost_multitool = null + if (ghostimage) ghost_darkness_images -= ghostimage qdel(ghostimage) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5d3cf1a74c7..6bbdc0aae1a 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -83,6 +83,8 @@ var/list/ai_verbs_default = list( var/custom_sprite = 0 // Whether the selected icon is custom var/carded + var/obj/item/device/multitool/ai_multitool + /mob/living/silicon/ai/proc/add_ai_verbs() src.verbs |= ai_verbs_default src.verbs |= silicon_subsystems @@ -173,7 +175,6 @@ var/list/ai_verbs_default = list( ai_list += src ..() - return /mob/living/silicon/ai/proc/on_mob_init() src << "You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras)." @@ -201,9 +202,17 @@ var/list/ai_verbs_default = list( setup_icon() /mob/living/silicon/ai/Destroy() + qdel(aiPDA) + qdel(aiMulti) + qdel(aiRadio) + aiPDA = null + aiMulti = null + aiRadio = null + ai_list -= src qdel(eyeobj) - ..() + eyeobj = null + return ..() /mob/living/silicon/ai/proc/setup_icon() var/file = file2text("config/custom_sprites.txt") diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index fe4d6ed56de..4d2fc208cc0 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -570,3 +570,19 @@ proc/is_blind(A) return threatcount #undef SAFE_PERP + +/mob/proc/get_multitool(var/obj/item/device/multitool/P) + if(istype(P)) + return P + +mob/dead/observer/get_multitool() + return can_admin_interact() && ..(ghost_multitool) + +/mob/living/carbon/human/get_multitool() + return ..(get_active_hand()) + +/mob/living/silicon/robot/get_multitool() + return ..(get_active_hand()) + +/mob/living/silicon/ai/get_multitool() + return ..(aiMulti)