From 34e3c3570ce2096c351068a996ad7ed97c68338d Mon Sep 17 00:00:00 2001 From: RustingWithYou <63625389+RustingWithYou@users.noreply.github.com> Date: Sun, 14 Apr 2024 04:14:02 +1200 Subject: [PATCH] Ports Baystation Click Handling & Build Mode (#18896) Ports the changes to clicking and build mode made in https://github.com/Baystation12/Baystation12/pull/16292 --- aurorastation.dme | 13 +- code/_onclick/ai.dm | 8 - code/_onclick/click.dm | 115 +++++- code/_onclick/cyborg.dm | 4 - code/_onclick/observer.dm | 6 - code/modules/admin/admin_verbs.dm | 10 +- code/modules/admin/buildmode/advanced.dm | 46 +++ code/modules/admin/buildmode/basic.dm | 70 ++++ code/modules/admin/buildmode/buildmode.dm | 51 +++ code/modules/admin/buildmode/buttons.dm | 78 ++++ code/modules/admin/buildmode/click_handler.dm | 52 +++ code/modules/admin/buildmode/edit.dm | 81 ++++ code/modules/admin/buildmode/ladders.dm | 29 ++ code/modules/admin/buildmode/light_maker.dm | 38 ++ code/modules/admin/buildmode/move_into.dm | 46 +++ code/modules/admin/buildmode/relocate_to.dm | 47 +++ code/modules/admin/buildmode/room_builder.dm | 91 +++++ code/modules/admin/buildmode/throw_at.dm | 46 +++ code/modules/admin/verbs/buildmode.dm | 355 ------------------ code/modules/admin/view_variables/topic.dm | 11 - code/modules/client/client_defines.dm | 1 - code/modules/client/client_procs.dm | 5 - code/unit_tests/create_and_destroy.dm | 1 + html/changelogs/RustingWithYou - click.yml | 41 ++ icons/misc/buildmode.dmi | Bin 1209 -> 1483 bytes 25 files changed, 839 insertions(+), 406 deletions(-) create mode 100644 code/modules/admin/buildmode/advanced.dm create mode 100644 code/modules/admin/buildmode/basic.dm create mode 100644 code/modules/admin/buildmode/buildmode.dm create mode 100644 code/modules/admin/buildmode/buttons.dm create mode 100644 code/modules/admin/buildmode/click_handler.dm create mode 100644 code/modules/admin/buildmode/edit.dm create mode 100644 code/modules/admin/buildmode/ladders.dm create mode 100644 code/modules/admin/buildmode/light_maker.dm create mode 100644 code/modules/admin/buildmode/move_into.dm create mode 100644 code/modules/admin/buildmode/relocate_to.dm create mode 100644 code/modules/admin/buildmode/room_builder.dm create mode 100644 code/modules/admin/buildmode/throw_at.dm delete mode 100644 code/modules/admin/verbs/buildmode.dm create mode 100644 html/changelogs/RustingWithYou - click.yml diff --git a/aurorastation.dme b/aurorastation.dme index 1a80c686e7b..4621ac0b28b 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -1468,6 +1468,18 @@ #include "code\modules\admin\stickyban.dm" #include "code\modules\admin\ticket.dm" #include "code\modules\admin\topic.dm" +#include "code\modules\admin\buildmode\advanced.dm" +#include "code\modules\admin\buildmode\basic.dm" +#include "code\modules\admin\buildmode\buildmode.dm" +#include "code\modules\admin\buildmode\buttons.dm" +#include "code\modules\admin\buildmode\click_handler.dm" +#include "code\modules\admin\buildmode\edit.dm" +#include "code\modules\admin\buildmode\ladders.dm" +#include "code\modules\admin\buildmode\light_maker.dm" +#include "code\modules\admin\buildmode\move_into.dm" +#include "code\modules\admin\buildmode\relocate_to.dm" +#include "code\modules\admin\buildmode\room_builder.dm" +#include "code\modules\admin\buildmode\throw_at.dm" #include "code\modules\admin\callproc\callproc.dm" #include "code\modules\admin\DB ban\ban_mirroring.dm" #include "code\modules\admin\DB ban\functions.dm" @@ -1515,7 +1527,6 @@ #include "code\modules\admin\verbs\atmosdebug.dm" #include "code\modules\admin\verbs\bluespacetech.dm" #include "code\modules\admin\verbs\BrokenInhands.dm" -#include "code\modules\admin\verbs\buildmode.dm" #include "code\modules\admin\verbs\cinematic.dm" #include "code\modules\admin\verbs\clear_toxins.dm" #include "code\modules\admin\verbs\custom_event.dm" diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 39d8d1bcc2b..e523618ddcb 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -10,10 +10,6 @@ Note that AI have no need for the adjacency proc, and so this proc is a lot cleaner. */ /mob/living/silicon/ai/DblClickOn(var/atom/A, params) - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return - if(control_disabled || stat) return if(ismob(A)) @@ -27,10 +23,6 @@ return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return - if(stat) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 33bb17cb4e3..a4849f10210 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -17,12 +17,12 @@ */ /atom/Click(location,control,params) - if(src) - usr.ClickOn(src, params) + var/datum/click_handler/click_handler = usr.GetClickHandler() + click_handler.OnClick(src, params) /atom/DblClick(var/location, var/control, var/params) - if(src) - usr.DblClickOn(src, params) + var/datum/click_handler/click_handler = usr.GetClickHandler() + click_handler.OnDblClick(src, params) /atom/proc/allow_click_through(var/atom/A, var/params, var/mob/user) return FALSE @@ -36,10 +36,6 @@ /mob/proc/OnMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params) if(istype(loc, /atom)) var/atom/A = loc - if(client && client.buildmode) - build_click(src, client.buildmode, params, A) - return - if(A.RelayMouseDrag(src_object, over_object, src_location, over_location, src_control, over_control, params, src)) return @@ -52,7 +48,7 @@ /** * Standard mob ClickOn() - * Handles exceptions: Buildmode, middle click, modified clicks, mech actions + * Handles exceptions: middle click, modified clicks, mech actions * * After that, mostly just check your state, check whether you're holding an item, * check whether you're adjacent to the target, then pass off the click to whoever @@ -82,10 +78,6 @@ return return B.ClickOn(A, params) - if(client && client.buildmode) - build_click(src, client.buildmode, params, A) - return - var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) @@ -422,3 +414,100 @@ var/global/list/click_catchers set hidden = 1 set name = ".mouse" LogMouseMacro(".mouse", params) + +/* + Custom Click Handlinig +*/ + +/mob + var/datum/stack/click_handlers + +/mob/Destroy() + if(click_handlers) + click_handlers.QdelClear() + QDEL_NULL(click_handlers) + . = ..() + +var/const/CLICK_HANDLER_NONE = 0 +var/const/CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT = 1 +var/const/CLICK_HANDLER_ALL = (~0) + +/datum/click_handler + var/mob/user + var/handler_flags = CLICK_HANDLER_NONE + +/datum/click_handler/New(mob/user) + ..() + src.user = user + if(handler_flags & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT) + RegisterSignal(user, COMSIG_MOB_LOGOUT, /datum/click_handler/proc/OnMobLogout, TRUE) + +/datum/click_handler/Destroy() + if(handler_flags & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT) + UnregisterSignal(user, COMSIG_MOB_LOGOUT) + user = null + . = ..() + +/datum/click_handler/proc/Enter() + return + +/datum/click_handler/proc/Exit() + return + + +/datum/click_handler/proc/OnMobLogout() + user.RemoveClickHandler(src) + +/datum/click_handler/proc/OnClick(var/atom/A, var/params) + return + +/datum/click_handler/proc/OnDblClick(var/atom/A, var/params) + return + +/datum/click_handler/default/OnClick(var/atom/A, var/params) + user.ClickOn(A, params) + +/datum/click_handler/default/OnDblClick(var/atom/A, var/params) + user.DblClickOn(A, params) + +/mob/proc/GetClickHandler(var/datum/click_handler/popped_handler) + if(!click_handlers) + click_handlers = new() + if(click_handlers.is_empty()) + PushClickHandler(/datum/click_handler/default) + return click_handlers.Top() + +/mob/proc/RemoveClickHandler(var/datum/click_handler/click_handler) + if(!click_handlers) + return + + var/was_top = click_handlers.Top() == click_handler + + if(was_top) + click_handler.Exit() + click_handlers.Remove(click_handler) + qdel(click_handler) + + if(!was_top) + return + click_handler = click_handlers.Top() + if(click_handler) + click_handler.Enter() + +/mob/proc/PopClickHandler() + if(!click_handlers) + return + RemoveClickHandler(click_handlers.Top()) + +/mob/proc/PushClickHandler(var/datum/click_handler/new_click_handler_type) + if((initial(new_click_handler_type.handler_flags) & CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT) && !client) + return FALSE + if(!click_handlers) + click_handlers = new() + var/datum/click_handler/click_handler = click_handlers.Top() + if(click_handler) + click_handler.Exit() + + click_handler = new new_click_handler_type(src) + click_handler.Enter() + click_handlers.Push(click_handler) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index 5028af39eee..40ecc88f1cf 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -11,10 +11,6 @@ return next_click = world.time + 1 - if(client.buildmode) // comes after object.Click to allow buildmode gui objects to be clicked - build_click(src, client.buildmode, params, A) - return - var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) CtrlShiftClickOn(A) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 0cac821fad8..8abdab43ccc 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -11,9 +11,6 @@ to_chat(src, "You will no longer examine things you click on.") /mob/abstract/observer/DblClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return if(can_reenter_corpse && mind && mind.current) if(A == mind.current || (mind.current in A)) // double click your corpse or whatever holds it reenter_corpse() // (cloning scanner, body bag, closet, mech, etc) @@ -29,9 +26,6 @@ forceMove(get_turf(A)) /mob/abstract/observer/ClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return if(!canClick()) return setClickCooldown(4) // You are responsible for checking config.ghost_interaction when you override this function diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 43b2bf2b46b..c3f1312d73f 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -746,8 +746,14 @@ var/list/admin_verbs_cciaa = list( /client/proc/togglebuildmodeself() set name = "Toggle Build Mode Self" set category = "Special Verbs" - if(src.mob) - togglebuildmode(src.mob) + + if(!check_rights(R_ADMIN)) + return + var/datum/click_handler/handler = mob.GetClickHandler() + if(handler.type == /datum/click_handler/build_mode) + usr.PopClickHandler() + else + usr.PushClickHandler(/datum/click_handler/build_mode) feedback_add_details("admin_verb","TBMS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /client/proc/object_talk(var/msg as text) // -- TLE diff --git a/code/modules/admin/buildmode/advanced.dm b/code/modules/admin/buildmode/advanced.dm new file mode 100644 index 00000000000..2f7b2b47f33 --- /dev/null +++ b/code/modules/admin/buildmode/advanced.dm @@ -0,0 +1,46 @@ +/datum/build_mode/advanced + name = "Advanced" + icon_state = "buildmode2" + var/build_type + +/datum/build_mode/advanced/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Left Click = Create objects")) + to_chat(user, SPAN_NOTICE("Right Click = Delete objects")) + to_chat(user, SPAN_NOTICE("Left Click + Ctrl = Capture object type")) + to_chat(user, SPAN_NOTICE("Middle Click = Capture object type")) + to_chat(user, SPAN_NOTICE("Right Click on Build Mode Button = Select object type")) + to_chat(user, "") + to_chat(user, SPAN_NOTICE("Use the directional button in the upper left corner to")) + to_chat(user, SPAN_NOTICE("change the direction of built objects.")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/advanced/Configurate() + SetBuildType(select_subpath(build_type || /obj/structure/closet)) + +/datum/build_mode/advanced/OnClick(var/atom/A, var/list/parameters) + if(parameters["left"] && !parameters["ctrl"]) + if(ispath(build_type,/turf)) + var/turf/T = get_turf(A) + T.ChangeTurf(build_type) + else if(ispath(build_type)) + var/atom/new_atom = new build_type (get_turf(A)) + new_atom.set_dir(host.dir) + Log("Created - [log_info_line(new_atom)]") + else + to_chat(user, SPAN_NOTICE("Select a type to construct.")) + else if(parameters["right"]) + Log("Deleted - [log_info_line(A)]") + qdel(A) + else if((parameters["left"] && parameters["ctrl"]) || parameters["middle"]) + SetBuildType(A.type) + +/datum/build_mode/advanced/proc/SetBuildType(var/atom_type) + if(!atom_type || atom_type == build_type) + return + + if(ispath(atom_type, /atom)) + build_type = atom_type + to_chat(user, SPAN_NOTICE("Will now construct instances of the type [atom_type].")) + else + to_chat(user, SPAN_WARNING("Cannot construct instances of type [atom_type].")) diff --git a/code/modules/admin/buildmode/basic.dm b/code/modules/admin/buildmode/basic.dm new file mode 100644 index 00000000000..ec257aefa1b --- /dev/null +++ b/code/modules/admin/buildmode/basic.dm @@ -0,0 +1,70 @@ +/datum/build_mode/basic + the_default = TRUE + name = "Basic" + icon_state = "buildmode1" + +/datum/build_mode/basic/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Left Click = Construct / Upgrade")) + to_chat(user, SPAN_NOTICE("Right Click = Deconstruct / Delete / Downgrade")) + to_chat(user, SPAN_NOTICE("Left Click + Ctrl = R-Window")) + to_chat(user, SPAN_NOTICE("Left Click + Alt = Airlock")) + to_chat(user, "") + to_chat(user, SPAN_NOTICE("Use the directional button in the upper left corner to")) + to_chat(user, SPAN_NOTICE("change the direction of built objects.")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/basic/OnClick(var/atom/object, var/list/pa) + if(istype(object,/turf) && pa["left"] && !pa["alt"] && !pa["ctrl"] ) + if(istype(object,/turf/space)) + var/turf/T = object + Log("Upgraded - [log_info_line(object)]") + T.ChangeTurf(/turf/simulated/floor) + return + else if(istype(object,/turf/simulated/floor)) + var/turf/T = object + Log("Upgraded - [log_info_line(object)]") + T.ChangeTurf(/turf/simulated/wall) + return + else if(istype(object,/turf/simulated/wall)) + var/turf/T = object + Log("Upgraded - [log_info_line(object)]") + T.ChangeTurf(/turf/simulated/wall/r_wall) + return + else if(pa["right"]) + if(istype(object,/turf/simulated/wall)) + var/turf/T = object + Log("Downgraded - [log_info_line(object)]") + T.ChangeTurf(/turf/simulated/floor) + return + else if(istype(object,/turf/simulated/floor)) + var/turf/T = object + Log("Downgraded - [log_info_line(object)]") + T.ChangeTurf(/turf/space) + return + else if(istype(object,/turf/simulated/wall/r_wall)) + var/turf/T = object + Log("Downgraded - [log_info_line(object)]") + T.ChangeTurf(/turf/simulated/wall) + return + else if(istype(object,/obj)) + Log("Deleted - [log_info_line(object)]") + qdel(object) + return + else if(istype(object,/turf) && pa["alt"] && pa["left"]) + var/airlock = new/obj/machinery/door/airlock(get_turf(object)) + Log("Created - [log_info_line(airlock)]") + else if(istype(object,/turf) && pa["ctrl"] && pa["left"]) + var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) + Log("Created - [log_info_line(object)]") + switch(host.dir) + if(NORTH) + WIN.set_dir(NORTH) + if(SOUTH) + WIN.set_dir(SOUTH) + if(EAST) + WIN.set_dir(EAST) + if(WEST) + WIN.set_dir(WEST) + if(NORTHWEST) + WIN.set_dir(NORTHWEST) diff --git a/code/modules/admin/buildmode/buildmode.dm b/code/modules/admin/buildmode/buildmode.dm new file mode 100644 index 00000000000..fca84332254 --- /dev/null +++ b/code/modules/admin/buildmode/buildmode.dm @@ -0,0 +1,51 @@ +/datum/build_mode + var/the_default = FALSE + var/name + var/icon_state + var/datum/click_handler/build_mode/host + var/mob/user + +/datum/build_mode/New(var/host) + ..() + src.host = host + user = src.host.user + +/datum/build_mode/Destroy() + host = null + . = ..() + +/datum/build_mode/proc/OnClick(var/atom/A, var/list/parameters) + return + +/datum/build_mode/proc/Configurate() + return + +/datum/build_mode/proc/Help() + return + +/datum/build_mode/proc/Log(message) + log_admin("BUILD MODE - [name] - [key_name(usr)] - [message]") + +/datum/build_mode/proc/Warn(message) + to_chat(user, "BUILD MODE - [name] - [message])") + +/datum/build_mode/proc/select_subpath(given_path) + var/desired_path = input("Enter full or partial typepath.","Typepath","[given_path]") as text|null + if(!desired_path) + return + + var/list/types = typesof(/atom) + var/list/matches = list() + + for(var/path in types) + if(findtext("[path]", desired_path)) + matches += path + + if(!matches.len) + alert("No results found. Sorry.") + return + + if(matches.len==1) + return matches[1] + else + return (input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches) diff --git a/code/modules/admin/buildmode/buttons.dm b/code/modules/admin/buildmode/buttons.dm new file mode 100644 index 00000000000..9748602e8b1 --- /dev/null +++ b/code/modules/admin/buildmode/buttons.dm @@ -0,0 +1,78 @@ +/obj/effect/bmode + name = "Build Mode" + density = 1 + anchored = 1 + layer = HUD_BASE_LAYER + mouse_opacity = MOUSE_OPACITY_OPAQUE + icon = 'icons/misc/buildmode.dmi' + var/datum/click_handler/build_mode/host + +/obj/effect/bmode/New(var/host) + ..() + src.host = host + +/obj/effect/bmode/Destroy() + host = null + . = ..() + +/obj/effect/bmode/proc/OnClick(var/list/params) + return + +/obj/effect/bmode/dir + name = "Modify Dir" + icon_state = "build" + screen_loc = "NORTH,WEST" + +/obj/effect/bmode/dir/New() + ..() + set_dir(host.dir) + +/obj/effect/bmode/dir/OnClick(var/list/parameters) + switch(dir) + if(SOUTH) + set_dir(WEST) + if(WEST) + set_dir(NORTH) + if(NORTH) + set_dir(EAST) + if(EAST) + set_dir(NORTHWEST) + else + set_dir(SOUTH) + host.dir = dir + +/obj/effect/bmode/help + name = "Help" + icon_state = "buildhelp" + screen_loc = "NORTH,WEST+1" + +/obj/effect/bmode/help/OnClick() + host.current_build_mode.Help() + +/obj/effect/bmode/mode + name = "Select Mode" + screen_loc = "NORTH,WEST+2" + +/obj/effect/bmode/mode/New() + ..() + icon_state = host.current_build_mode.icon_state + +/obj/effect/bmode/mode/OnClick(var/list/parameters) + if(parameters["left"]) + var/datum/build_mode/build_mode = input("Select build mode", "Select build mode", host.current_build_mode) as null|anything in host.build_modes + if(build_mode && host && (build_mode in host.build_modes)) + host.current_build_mode = build_mode + icon_state = build_mode.icon_state + to_chat(usr, SPAN_NOTICE("Build mode '[host.current_build_mode]' selected.")) + else if(parameters["right"]) + host.current_build_mode.Configurate() + +/obj/effect/bmode/quit + name = "Quit" + icon_state = "buildquit" + screen_loc = "NORTH,WEST+3" + +/obj/effect/bmode/quit/OnClick() + var/datum/click_handler/handler = usr.GetClickHandler() + if(handler.type == /datum/click_handler/build_mode) + usr.PopClickHandler() diff --git a/code/modules/admin/buildmode/click_handler.dm b/code/modules/admin/buildmode/click_handler.dm new file mode 100644 index 00000000000..dfab1ac97f3 --- /dev/null +++ b/code/modules/admin/buildmode/click_handler.dm @@ -0,0 +1,52 @@ +/datum/click_handler/build_mode + handler_flags = CLICK_HANDLER_REMOVE_ON_MOB_LOGOUT + var/dir + + var/list/build_modes + var/list/build_buttons + + var/datum/build_mode/current_build_mode + +/datum/click_handler/build_mode/New(var/mob/user) + ..() + + build_modes = list() + for(var/mode_type in subtypesof(/datum/build_mode)) + var/datum/build_mode/build_mode = new mode_type(src) + build_modes += build_mode + if(build_mode.the_default) + current_build_mode = build_mode + + build_buttons = list() + for(var/button_type in subtypesof(/obj/effect/bmode)) + var/obj/effect/bmode/build_button = new button_type(src) + build_buttons += build_button + +/datum/click_handler/build_mode/Destroy() + QDEL_NULL(current_build_mode) + + QDEL_LIST(build_modes) + QDEL_LIST(build_buttons) + + . = ..() + +/datum/click_handler/build_mode/Enter() + user.client.show_popup_menus = FALSE + for(var/build_button in build_buttons) + user.client.screen += build_button + +/datum/click_handler/build_mode/Exit() + user.client.show_popup_menus = TRUE + for(var/build_button in build_buttons) + user.client.screen -= build_button + +/datum/click_handler/build_mode/OnDblClick(var/atom/A, var/params) + OnClick(A, params) // We treat double-clicks as normal clicks + +/datum/click_handler/build_mode/OnClick(var/atom/A, var/params) + params = params2list(params) + if(A in build_buttons) + var/obj/effect/bmode/build_button = A + build_button.OnClick(params) + else + current_build_mode.OnClick(A, params) diff --git a/code/modules/admin/buildmode/edit.dm b/code/modules/admin/buildmode/edit.dm new file mode 100644 index 00000000000..edaf59bd2ab --- /dev/null +++ b/code/modules/admin/buildmode/edit.dm @@ -0,0 +1,81 @@ +/datum/build_mode/edit + name = "Edit" + icon_state = "buildmode3" + var/var_to_edit = "name" + var/value_to_set = "derp" + +/datum/build_mode/edit/Destroy() + ClearValue() + . = ..() + +/datum/build_mode/edit/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Right Click on Build Mode Button = Select var & value")) + to_chat(user, SPAN_NOTICE("Left Click = Sets the var's value")) + to_chat(user, SPAN_NOTICE("Right Click = Reset the var's value")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/edit/Configurate() + var/var_name = input("Enter variable name:", "Name", var_to_edit) as text|null + if(!var_name) + return + + var/thetype = input("Select variable type:", "Type") as null|anything in list("text","number","mob-reference","obj-reference","turf-reference") + if(!thetype) return + + var/new_value + switch(thetype) + if("text") + new_value = input(usr,"Enter variable value:" ,"Value", value_to_set) as text|null + if("number") + new_value = input(usr,"Enter variable value:" ,"Value", value_to_set) as num|null + if("mob-reference") + new_value = input(usr,"Enter variable value:" ,"Value", value_to_set) as null|mob in GLOB.mob_list + if("obj-reference") + new_value = input(usr,"Enter variable value:" ,"Value", value_to_set) as null|obj in world + if("turf-reference") + new_value = input(usr,"Enter variable value:" ,"Value", value_to_set) as null|turf in world + + if(var_name && new_value) + var_to_edit = var_name + SetValue(new_value) + +/datum/build_mode/edit/OnClick(var/atom/A, var/list/parameters) + if(var_to_edit in VVlocked) + if(!check_rights(R_DEBUG)) return + if(var_to_edit in VVckey_edit) + if(!check_rights(R_SPAWN|R_DEBUG)) return + if(var_to_edit in VVicon_edit_lock) + if(!check_rights(R_FUN|R_DEBUG)) return + if(!(var_to_edit in A.vars)) + to_chat(user, SPAN_WARNING("\The [A] does not have a var '[var_to_edit]'")) + return + + var/old_value = A.vars[var_to_edit] + var/new_value + if(parameters["left"]) + new_value = value_to_set + if(parameters["right"]) + new_value = initial(A.vars[var_to_edit]) + + if(old_value == new_value) + return + A.vars[var_to_edit] = new_value + to_chat(user, SPAN_NOTICE("Changed the value of [var_to_edit] from '[old_value]' to '[new_value]'.")) + Log("[log_info_line(A)] - [var_to_edit] - [old_value] -> [new_value]") + +/datum/build_mode/edit/proc/SetValue(var/new_value) + if(value_to_set == new_value) + return + ClearValue() + value_to_set = new_value + GLOB.destroyed_event.register(value_to_set, src, /datum/build_mode/edit/proc/ClearValue) + +/datum/build_mode/edit/proc/ClearValue(var/feedback) + if(!istype(value_to_set, /datum)) + return + + GLOB.destroyed_event.unregister(value_to_set, src, /datum/build_mode/edit/proc/ClearValue) + value_to_set = initial(value_to_set) + if(feedback) + Warn("The selected reference value was deleted. Default value restored.") diff --git a/code/modules/admin/buildmode/ladders.dm b/code/modules/admin/buildmode/ladders.dm new file mode 100644 index 00000000000..5bd3e11aa46 --- /dev/null +++ b/code/modules/admin/buildmode/ladders.dm @@ -0,0 +1,29 @@ +/datum/build_mode/ladders + name = "Ladders" + icon_state = "buildmode6" + var/turf/ladder_upper + var/turf/ladder_lower + +/datum/build_mode/ladders/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Left Click on Turf = Set as upper ladder loc")) + to_chat(user, SPAN_NOTICE("Right Click on Turf = Set as lower ladder loc")) + to_chat(user, SPAN_NOTICE("As soon as both points have been selected, the ladder is created.")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/ladders/OnClick(var/atom/A, var/list/parameters) + if(parameters["left"]) + ladder_upper = get_turf(A) + to_chat(user, SPAN_NOTICE("Defined [ladder_upper] ([ladder_upper.type]) as the upper ladder location.")) + if(parameters["right"]) + ladder_lower = get_turf(A) + to_chat(user, SPAN_NOTICE("Defined [ladder_lower] ([ladder_lower.type]) as the lower ladder location.")) + if(ladder_upper && ladder_lower) + to_chat(user, SPAN_NOTICE("Ladder locations set, building ladders.")) + Log("Created a ladder between '[log_info_line(ladder_upper)]' and '[log_info_line(ladder_lower)]'.") + var/obj/structure/ladder/upper = new /obj/structure/ladder(ladder_upper) + var/obj/structure/ladder/lower = new /obj/structure/ladder/up(ladder_lower) + upper.target_down = lower + lower.target_up = upper + ladder_upper = null + ladder_lower = null diff --git a/code/modules/admin/buildmode/light_maker.dm b/code/modules/admin/buildmode/light_maker.dm new file mode 100644 index 00000000000..063a0f0b7d3 --- /dev/null +++ b/code/modules/admin/buildmode/light_maker.dm @@ -0,0 +1,38 @@ +/datum/build_mode/light_maker + name = "Light Maker" + icon_state = "buildmode8" + + var/light_range = 3 + var/light_power = 3 + var/light_color = COLOR_WHITE + +/datum/build_mode/light_maker/Help() + to_chat(usr, SPAN_NOTICE("***********************************************************")) + to_chat(usr, SPAN_NOTICE("Left Click = Make it glow")) + to_chat(usr, SPAN_NOTICE("Right Click = Reset glow")) + to_chat(usr, SPAN_NOTICE("Right Click on Build Mode Button = Change glow properties")) + to_chat(usr, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/light_maker/Configurate() + var/choice = alert("Change the new light range, power, or color?", "Light Maker", "Range", "Power", "Color", "Cancel") + switch(choice) + if("Range") + var/input = input("New light range.", name, light_range) as null|num + if(input) + light_range = input + if("Power") + var/input = input("New light power.", name, light_power) as null|num + if(input) + light_power = input + if("Color") + var/input = input("New light color.", name, light_color) as null|color + if(input) + light_color = input + +/datum/build_mode/light_maker/OnClick(var/atom/A, var/list/parameters) + if(parameters["left"]) + if(A) + A.set_light(light_range, light_power, light_color) + if(parameters["right"]) + if(A) + A.set_light(0, 0, COLOR_WHITE) diff --git a/code/modules/admin/buildmode/move_into.dm b/code/modules/admin/buildmode/move_into.dm new file mode 100644 index 00000000000..8ad6e00a8c6 --- /dev/null +++ b/code/modules/admin/buildmode/move_into.dm @@ -0,0 +1,46 @@ +/datum/build_mode/move_into + name = "Move Into" + icon_state = "buildmode7" + + var/atom/destination + +/datum/build_mode/move_into/Destroy() + ClearDestination() + . = ..() + +/datum/build_mode/move_into/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Left Click = Select destination")) + to_chat(user, SPAN_NOTICE("Right Click on Movable Atom = Move target into destination")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/move_into/OnClick(var/atom/movable/A, var/list/parameters) + if(parameters["left"]) + SetDestination(A) + if(parameters["right"]) + if(!destination) + to_chat(user, SPAN_WARNING("No target destination.")) + else if(!ismovable(A)) + to_chat(user, SPAN_WARNING("\The [A] must be of type /atom/movable.")) + else + to_chat(user, SPAN_NOTICE("Moved \the [A] into \the [destination].")) + Log("Moved '[log_info_line(A)]' into '[log_info_line(destination)]'.") + A.forceMove(destination) + +/datum/build_mode/move_into/proc/SetDestination(var/atom/A) + if(A == destination) + return + ClearDestination() + + destination = A + GLOB.destroyed_event.register(destination, src, /datum/build_mode/move_into/proc/ClearDestination) + to_chat(user, SPAN_NOTICE("Will now move targets into \the [destination].")) + +/datum/build_mode/move_into/proc/ClearDestination(var/feedback) + if(!destination) + return + + GLOB.destroyed_event.unregister(destination, src, /datum/build_mode/move_into/proc/ClearDestination) + destination = null + if(feedback) + Warn("The selected destination was deleted.") diff --git a/code/modules/admin/buildmode/relocate_to.dm b/code/modules/admin/buildmode/relocate_to.dm new file mode 100644 index 00000000000..86e827e1e15 --- /dev/null +++ b/code/modules/admin/buildmode/relocate_to.dm @@ -0,0 +1,47 @@ +/datum/build_mode/relocate_to + name = "Relocate To" + icon_state = "buildmode9" + var/atom/movable/to_relocate + +/datum/build_mode/relocate_to/Destroy() + ClearRelocator() + . = ..() + +/datum/build_mode/relocate_to/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Left Click on Movable Atom = Select object to be relocated")) + to_chat(user, SPAN_NOTICE("Right Click on Turf = Destination to be relocated to")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/relocate_to/OnClick(var/atom/A, var/list/parameters) + if(parameters["left"]) + if(istype(A, /atom/movable)) + SetRelocator(A) + else if(parameters["right"]) + if(to_relocate) + var/destination_turf = get_turf(A) + if(destination_turf) + to_relocate.forceMove(destination_turf) + Log("Relocated '[log_info_line(to_relocate)]' to '[log_info_line(destination_turf)]'") + else + to_chat(user, SPAN_WARNING("Unable to locate destination turf.")) + else + to_chat(user, SPAN_WARNING("You have nothing selected to relocate.")) + +/datum/build_mode/relocate_to/proc/SetRelocator(var/new_relocator) + if(to_relocate == new_relocator) + return + ClearRelocator() + + to_relocate = new_relocator + RegisterSignal(to_relocate, COMSIG_QDELETING, PROC_REF(ClearRelocator)) + to_chat(user, SPAN_NOTICE("Will now be relocating \the [to_relocate].")) + +/datum/build_mode/relocate_to/proc/ClearRelocator(var/feedback) + if(!to_relocate) + return + + UnregisterSignal(to_relocate, COMSIG_QDELETING) + to_relocate = null + if(feedback) + Warn("The selected relocation object was deleted.") diff --git a/code/modules/admin/buildmode/room_builder.dm b/code/modules/admin/buildmode/room_builder.dm new file mode 100644 index 00000000000..c4e3a5f3ade --- /dev/null +++ b/code/modules/admin/buildmode/room_builder.dm @@ -0,0 +1,91 @@ +/datum/build_mode/room_builder + name = "Room Builder" + icon_state = "buildmode5" + + var/turf/coordinate_A + var/turf/coordinate_B + + var/floor_type = /turf/simulated/floor/plating + var/wall_type = /turf/simulated/wall + +/datum/build_mode/room_builder/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Left Click on Turf = Select as point A")) + to_chat(user, SPAN_NOTICE("Right Click on Turf = Select as point B")) + to_chat(user, SPAN_NOTICE("As soon as both points have been selected, the room is created.")) + to_chat(user, "") + to_chat(user, SPAN_NOTICE("Right Click on Build Mode Button = Change floor/wall type")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/room_builder/Configurate() + var/choice = alert("Would you like to set the floor or wall type?", name, "Floor", "Wall", "Cancel") + switch(choice) + if("Floor") + floor_type = select_subpath(floor_type) || floor_type + to_chat(user, SPAN_NOTICE("Floor type set to [floor_type].")) + if("Wall") + wall_type = select_subpath(wall_type) || wall_type + to_chat(user, SPAN_NOTICE("Wall type set to [wall_type].")) + +/datum/build_mode/room_builder/OnClick(var/atom/A, var/list/parameters) + if(parameters["left"]) + coordinate_A = get_turf(A) + to_chat(user, SPAN_NOTICE("Defined [coordinate_A] ([coordinate_A.type]) as point A.")) + if(parameters["right"]) + coordinate_B = get_turf(A) + to_chat(user, SPAN_NOTICE("Defined [coordinate_B] ([coordinate_B.type]) as point B.")) + + if(coordinate_A && coordinate_B) + to_chat(user, SPAN_NOTICE("Room coordinates set. Building room.")) + Log("Created a room with wall type [wall_type] and floor type [floor_type] from [log_info_line(coordinate_A)] to [log_info_line(coordinate_B)]") + make_rectangle(coordinate_A, coordinate_B, wall_type, floor_type) + coordinate_A = null + coordinate_B = null + +/datum/build_mode/room_builder/proc/make_rectangle(var/turf/A, var/turf/B, var/turf/wall_type, var/turf/floor_type) + if(!A || !B) // No coords + return + if(A.z != B.z) // Not same z-level + return + + var/height = A.y - B.y + var/width = A.x - B.x + var/z_level = A.z + + var/turf/lower_left_corner = null + // First, try to find the lowest part + var/desired_y = 0 + if(A.y <= B.y) + desired_y = A.y + else + desired_y = B.y + + //Now for the left-most part. + var/desired_x = 0 + if(A.x <= B.x) + desired_x = A.x + else + desired_x = B.x + + lower_left_corner = locate(desired_x, desired_y, z_level) + + // Now we can begin building the actual room. This defines the boundries for the room. + var/low_bound_x = lower_left_corner.x + var/low_bound_y = lower_left_corner.y + + var/high_bound_x = lower_left_corner.x + abs(width) + var/high_bound_y = lower_left_corner.y + abs(height) + + for(var/i = low_bound_x, i <= high_bound_x, i++) + for(var/j = low_bound_y, j <= high_bound_y, j++) + var/turf/T = locate(i, j, z_level) + if(i == low_bound_x || i == high_bound_x || j == low_bound_y || j == high_bound_y) + if(ispath(wall_type, /turf)) + T.ChangeTurf(wall_type) + else + new wall_type(T) + else + if(ispath(floor_type, /turf)) + T.ChangeTurf(floor_type) + else + new floor_type(T) diff --git a/code/modules/admin/buildmode/throw_at.dm b/code/modules/admin/buildmode/throw_at.dm new file mode 100644 index 00000000000..0e03c4b4bf1 --- /dev/null +++ b/code/modules/admin/buildmode/throw_at.dm @@ -0,0 +1,46 @@ +/datum/build_mode/throw_at + name = "Throw At" + icon_state = "buildmode4" + var/atom/movable/to_throw + +/datum/build_mode/throw_at/Destroy() + ClearThrowable() + . = ..() + +/datum/build_mode/throw_at/Help() + to_chat(user, SPAN_NOTICE("***********************************************************")) + to_chat(user, SPAN_NOTICE("Left Click on Movable Atom = Select object to be thrown")) + to_chat(user, SPAN_NOTICE("Right Click on Atom = Throw at the target")) + to_chat(user, SPAN_NOTICE("***********************************************************")) + +/datum/build_mode/throw_at/OnClick(var/atom/A, var/list/parameters) + if(parameters["left"]) + if(istype(A, /atom/movable)) + SetThrowable(A) + else if(parameters["right"]) + if(to_throw) + if(!isturf(to_throw.loc)) + to_chat(user, SPAN_WARNING("\The [to_throw] is currently not on a turf and cannot be thrown.")) + else + to_throw.throw_at(A, 10, 1) + Log("Threw '[log_info_line(to_throw)]' at '[log_info_line(A)]'") + else + to_chat(user, SPAN_WARNING("You have nothing selected to throw.")) + +/datum/build_mode/throw_at/proc/SetThrowable(var/new_throwable) + if(to_throw == new_throwable) + return + ClearThrowable() + + to_throw = new_throwable + RegisterSignal(to_throw, COMSIG_QDELETING, PROC_REF(ClearThrowable)) + to_chat(user, SPAN_NOTICE("Will now be throwing \the [to_throw].")) + +/datum/build_mode/throw_at/proc/ClearThrowable(var/feedback) + if(!to_throw) + return + + UnregisterSignal(to_throw, COMSIG_QDELETING) + to_throw = null + if(feedback) + Warn("The selected throwing object was deleted.") diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm deleted file mode 100644 index 29bcfc84a22..00000000000 --- a/code/modules/admin/verbs/buildmode.dm +++ /dev/null @@ -1,355 +0,0 @@ -/proc/togglebuildmode(mob/M as mob in GLOB.player_list) - set name = "Toggle Build Mode" - set category = "Special Verbs" - if(M.client) - if(M.client.buildmode) - log_admin("[key_name(usr)] has left build mode.",admin_key=key_name(usr)) - M.client.buildmode = 0 - M.client.show_popup_menus = 1 - remove_verb(M, /verb/load_template_verb) - for(var/obj/effect/bmode/buildholder/H) - if(H.cl == M.client) - qdel(H) - else - log_admin("[key_name(usr)] has entered build mode.",admin_key=key_name(usr)) - M.client.buildmode = 1 - M.client.show_popup_menus = 0 - add_verb(M, /verb/load_template_verb) - var/obj/effect/bmode/buildholder/H = new/obj/effect/bmode/buildholder() - var/obj/effect/bmode/builddir/A = new/obj/effect/bmode/builddir(H) - A.master = H - var/obj/effect/bmode/buildhelp/B = new/obj/effect/bmode/buildhelp(H) - B.master = H - var/obj/effect/bmode/buildmode/C = new/obj/effect/bmode/buildmode(H) - C.master = H - var/obj/effect/bmode/buildquit/D = new/obj/effect/bmode/buildquit(H) - D.master = H - var/obj/effect/bmode/template/E = new/obj/effect/bmode/template(H) - E.master = H - - H.builddir = A - H.buildhelp = B - H.buildmode = C - H.buildquit = D - H.load_template = E - M.client.screen += A - M.client.screen += B - M.client.screen += C - M.client.screen += D - M.client.screen += E - H.cl = M.client - -/obj/effect/bmode//Cleaning up the tree a bit - density = 1 - anchored = 1 - layer = HUD_BASE_LAYER - dir = NORTH - icon = 'icons/misc/buildmode.dmi' - mouse_opacity = MOUSE_OPACITY_OPAQUE - var/obj/effect/bmode/buildholder/master - -/obj/effect/bmode/Destroy() - if(master && master.cl) - master.cl.screen -= src - master = null - return ..() - -/obj/effect/bmode/builddir - icon_state = "build" - screen_loc = "NORTH,WEST" - -/obj/effect/bmode/builddir/Click() - switch(dir) - if(NORTH) - set_dir(EAST) - if(EAST) - set_dir(SOUTH) - if(SOUTH) - set_dir(WEST) - if(WEST) - set_dir(NORTHWEST) - if(NORTHWEST) - set_dir(NORTH) - return 1 - -/obj/effect/bmode/buildhelp - icon = 'icons/misc/buildmode.dmi' - icon_state = "buildhelp" - screen_loc = "NORTH,WEST+1" - -/obj/effect/bmode/buildhelp/Click() - switch(master.cl.buildmode) - if(1) - to_chat(usr, "***********************************************************") - to_chat(usr, "Left Mouse Button = Construct / Upgrade") - to_chat(usr, "Right Mouse Button = Deconstruct / Delete / Downgrade") - to_chat(usr, "Left Mouse Button + ctrl = R-Window") - to_chat(usr, "Left Mouse Button + alt = Airlock") - to_chat(usr, " ") - to_chat(usr, "Use the button in the upper left corner to") - to_chat(usr, "change the direction of built objects.") - to_chat(usr, "***********************************************************") - if(2) - to_chat(usr, "***********************************************************") - to_chat(usr, "Right Mouse Button on buildmode button = Set object type") - to_chat(usr, "Middle Mouse Button on buildmode button= On/Off object type saying") - to_chat(usr, "Middle Mouse Button on turf/obj = Capture object type") - to_chat(usr, "Left Mouse Button on turf/obj = Place objects") - to_chat(usr, "Right Mouse Button = Delete objects") - to_chat(usr, " ") - to_chat(usr, "Use the button in the upper left corner to") - to_chat(usr, "change the direction of built objects.") - to_chat(usr, "***********************************************************") - if(3) - to_chat(usr, "***********************************************************") - to_chat(usr, "Right Mouse Button on buildmode button = Select var(type) & value") - to_chat(usr, "Left Mouse Button on turf/obj/mob = Set var(type) & value") - to_chat(usr, "Right Mouse Button on turf/obj/mob = Reset var's value") - to_chat(usr, "***********************************************************") - if(4) - to_chat(usr, "***********************************************************") - to_chat(usr, "Left Mouse Button on turf/obj/mob = Select") - to_chat(usr, "Right Mouse Button on turf/obj/mob = Throw") - to_chat(usr, "***********************************************************") - return 1 - -/obj/effect/bmode/buildquit - icon_state = "buildquit" - screen_loc = "NORTH,WEST+4" - -/obj/effect/bmode/buildquit/Click() - togglebuildmode(master.cl.mob) - return 1 - -/obj/effect/bmode/buildholder - density = 0 - anchored = 1 - var/client/cl = null - var/obj/effect/bmode/builddir/builddir = null - var/obj/effect/bmode/buildhelp/buildhelp = null - var/obj/effect/bmode/buildmode/buildmode = null - var/obj/effect/bmode/buildquit/buildquit = null - var/obj/effect/bmode/template/load_template = null - var/atom/movable/throw_atom = null - -/obj/effect/bmode/buildholder/Destroy() - qdel(builddir) - builddir = null - qdel(buildhelp) - buildhelp = null - qdel(buildmode) - buildmode = null - qdel(buildquit) - buildquit = null - throw_atom = null - cl = null - return ..() - -/obj/effect/bmode/template - icon_state = "load_template" - screen_loc = "NORTH,WEST+2" - -/obj/effect/bmode/template/Click() - load_template(usr) - return 1 - -/obj/effect/bmode/buildmode - icon_state = "buildmode1" - screen_loc = "NORTH,WEST+3" - var/varholder = "name" - var/valueholder = "derp" - var/objholder = /obj/structure/closet - var/objsay = 1 - -/obj/effect/bmode/buildmode/Click(location, control, params) - var/list/pa = params2list(params) - - if(pa.Find("middle")) - switch(master.cl.buildmode) - if(2) - objsay=!objsay - - - if(pa.Find("left")) - switch(master.cl.buildmode) - if(1) - master.cl.buildmode = 2 - src.icon_state = "buildmode2" - if(2) - master.cl.buildmode = 3 - src.icon_state = "buildmode3" - if(3) - master.cl.buildmode = 4 - src.icon_state = "buildmode4" - if(4) - master.cl.buildmode = 1 - src.icon_state = "buildmode1" - - else if(pa.Find("right")) - switch(master.cl.buildmode) - if(1) - return 1 - if(2) - objholder = text2path(input(usr,"Enter typepath:" ,"Typepath","/obj/structure/closet")) - if(!ispath(objholder)) - objholder = /obj/structure/closet - alert("That path is not allowed.") - else - if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0)) - objholder = /obj/structure/closet - if(3) - var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") - - master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name") - if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0)) - return 1 - var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") - if(!thetype) return 1 - switch(thetype) - if("text") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text - if("number") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num - if("mob-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in GLOB.mob_list - if("obj-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world - if("turf-reference") - master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world - return 1 - -/proc/build_click(var/mob/user, buildmode, params, var/obj/object) - var/obj/effect/bmode/buildholder/holder = null - for(var/obj/effect/bmode/buildholder/H) - if(H.cl == user.client) - holder = H - break - if(!holder) return - var/list/pa = params2list(params) - - switch(buildmode) - if(1) - if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") ) - if(istype(object,/turf/space)) - var/turf/T = object - T.ChangeTurf(/turf/simulated/floor) - return - else if(istype(object,/turf/simulated/floor)) - var/turf/T = object - T.ChangeTurf(/turf/simulated/wall) - return - else if(istype(object,/turf/simulated/wall)) - var/turf/T = object - T.ChangeTurf(/turf/simulated/wall/r_wall) - return - else if(pa.Find("right")) - if(istype(object,/turf/simulated/wall)) - var/turf/T = object - T.ChangeTurf(/turf/simulated/floor) - return - else if(istype(object,/turf/simulated/floor)) - var/turf/T = object - T.ChangeTurf(/turf/space) - return - else if(istype(object,/turf/simulated/wall/r_wall)) - var/turf/T = object - T.ChangeTurf(/turf/simulated/wall) - return - else if(istype(object,/obj)) - qdel(object) - return - else if(istype(object,/turf) && pa.Find("alt") && pa.Find("left")) - new/obj/machinery/door/airlock(get_turf(object)) - else if(istype(object,/turf) && pa.Find("ctrl") && pa.Find("left")) - switch(holder.builddir.dir) - if(NORTH) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.set_dir(NORTH) - if(SOUTH) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.set_dir(SOUTH) - if(EAST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.set_dir(EAST) - if(WEST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.set_dir(WEST) - if(NORTHWEST) - var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) - WIN.set_dir(NORTHWEST) - if(2) - if(pa.Find("left")) - if(ispath(holder.buildmode.objholder,/turf)) - var/turf/T = get_turf(object) - T.ChangeTurf(holder.buildmode.objholder) - else - var/obj/A = new holder.buildmode.objholder (get_turf(object)) - A.set_dir(holder.builddir.dir) - else if(pa.Find("right")) - if(isobj(object)) qdel(object) - if(pa.Find("middle")) - holder.buildmode.objholder = text2path("[object.type]") - if(holder.buildmode.objsay) to_chat(usr, "[object.type]") - - - if(3) - if(pa.Find("left")) //I cant believe this shit actually compiles. - if(object.vars.Find(holder.buildmode.varholder)) - log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]",admin_key=key_name(usr)) - object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder - else - to_chat(usr, "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'") - if(pa.Find("right")) - if(object.vars.Find(holder.buildmode.varholder)) - log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]",admin_key=key_name(usr)) - object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder]) - else - to_chat(usr, "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'") - - if(4) - if(pa.Find("left")) - if(istype(object, /atom/movable)) - holder.throw_atom = object - if(pa.Find("right")) - if(holder.throw_atom) - holder.throw_atom.throw_at(object, 10, 1) - log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]",admin_key=key_name(usr)) - -/verb/load_template_verb() - set name = "Load Template" - set category = "Special Verbs" - if(!usr) - return - load_template(usr) - -/proc/load_template(var/mob/user) - if(!user) - return - - if(!check_rights(R_SPAWN)) - return - - var/list/templates - try - templates = json_decode(return_file_text("config/templates_list.json")) - catch(var/exception/ej) - LOG_DEBUG("Warning: Could not load the templates config as templates_list.json is missing - [ej]") - return - - if(!templates || !templates["templates_list"] || templates["templates_folder"] == "") - return - - var/turf/T = get_turf(user) - var/name = input(user, "Which template would you like to load?", "Load Template", null) as null|anything in templates["templates_list"] - - if (!name || !T) - return - - var/datum/map_template/maploader = new (templates["templates_folder"] + name, name) - if (!maploader) - LOG_DEBUG("Error, unable to load maploader in proc load_template!") - return - - var/centered = input(user, "Do you want template to load as center or Edge?", "Load Template", null) as null|anything in list("Center", "Edge") - maploader.load(T, centered == "Center" ? TRUE : FALSE) - log_and_message_admins("[key_name_admin(user)] has loaded template [name].", user, T) diff --git a/code/modules/admin/view_variables/topic.dm b/code/modules/admin/view_variables/topic.dm index 4ef682386e4..62b554097e4 100644 --- a/code/modules/admin/view_variables/topic.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -123,17 +123,6 @@ src.cmd_admin_dust(M) - else if(href_list["build_mode"]) - if(!check_rights(R_BUILDMODE|R_DEV)) return - - var/mob/M = locate(href_list["build_mode"]) - if(!istype(M)) - to_chat(usr, "This can only be used on instances of type /mob") - return - - togglebuildmode(M) - href_list["datumrefresh"] = href_list["build_mode"] - else if(href_list["drop_everything"]) if(!check_rights(R_DEBUG|R_ADMIN)) return diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 43ca7e43fde..2721e4fde7b 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -8,7 +8,6 @@ // Admin var/datum/admins/holder = null var/datum/admins/deadmin_holder = null - var/buildmode = 0 // Spam Protection var/last_message = "" // Contains the last message sent by this client - used to protect against copy-paste spamming. diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 59025cfe6e3..805b329e170 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -819,11 +819,6 @@ var/list/localhost_addresses = list( autofire_aiming_at[1] = over_object autofire_aiming_at[2] = params var/mob/living/M = mob - if(istype(get_turf(over_object), /atom)) - var/atom/A = get_turf(over_object) - if(src && src.buildmode) - build_click(M, src.buildmode, params, A) - return if(istype(M) && !M.incapacitated()) var/obj/item/I = M.get_active_hand() diff --git a/code/unit_tests/create_and_destroy.dm b/code/unit_tests/create_and_destroy.dm index ed5a17ea6c3..a27655652d1 100644 --- a/code/unit_tests/create_and_destroy.dm +++ b/code/unit_tests/create_and_destroy.dm @@ -159,6 +159,7 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE) ignore += typesof(/mob/living/heavy_vehicle) ignore += typesof(/obj/singularity/narsie) ignore += typesof(/obj/screen/ability) + ignore += typesof(/obj/effect/bmode) // Requires something in icon update or runtimes ignore += typesof(/obj/item/gun/energy/gun/nuclear) diff --git a/html/changelogs/RustingWithYou - click.yml b/html/changelogs/RustingWithYou - click.yml new file mode 100644 index 00000000000..b58f9871730 --- /dev/null +++ b/html/changelogs/RustingWithYou - click.yml @@ -0,0 +1,41 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# maptweak +# spellcheck (typo fixes) +# experiment +# balance +# admin +# backend +# security +# refactor +################################# + +# Your name. +author: RustingWithYou + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries. +# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Ports Baystation click handlers and build mode." diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index 269b266e858fe1402f96d567de2b2c633a630a7f..2550a1a486c633f9e2e9c2ad3a6f8cd601e2b5a0 100644 GIT binary patch delta 1325 zcmV+|1=9Mt3Cjy1iBL{Q4GJ0x0000DNk~Le0001>0001h1Oos70Det>D3KvI0i}^y zeSb%jDLITbh0#&ZkH$SiftPKeD_UUfD-*POf=3|t=Y| zN$b&9orn*gvi9+=7LRXPd*0RJ@l0>-N+V|&OEgoNgouU2t`E**DT$jfS ztpJSG;_)TD!;h!a0J$!Y=Nj~JNMMbGXVU17XS`$3&oAD-7u#q0|=$?YV~>5V{zy z5h{Pa*+i(ll6weMJl|{~lu_z^gaG>p=}h3~Aukdtt4)5saRZTlt`kb2ra5NzWq%}; zQquWa>x8f*sx)5(NZVKOxKT>c`No)pa2B%}A$9SPu-U8K7@ok-^8(>)9NN`MUnCri zL)*+gLi_i72xCmuxrLC{LHqam*hAF<{GVCIO@-_128IHiCy zU9Cmw@8%kFoaQGo*IJbRZmtz(VEl(f%G6qv{%)=j#1S33)}r)xD|$kh`@0pb^B87Y zl>Tl(11d!i7t>6O(%;SXbR6dXZm!c6y4IrfcXM46;z2lM*r(+FZmw;IgMXoi%gYL- z3VAvAcXLe&d1=`BnS?JvYKSpR{M}sRnB#{EGf5d9iGHt_`@02=@shXz1wtZ5Jn+sT z_jfBAqsoDca~;EpKOi9t{%%EU@(DR1&`kHMP3G_B8fS(%P1?)FIL!Usf}YKk+~2L} z$xO-p-HM(N=KgL;`_|2Rm4Abs=@H?(KYaIxZ^j??NB&jatBRyrPL5O4$y^?<9?pG@ zj#E=!FAz$Y6GF1rTi6eSYh6Ock5$6j(elf5^`SJ)zgQ$R7BE?{^BS!Upt(S3FPM04 z>Hf=B^gzhY4s#fIzlRwYJs;Wu(Tn^JMiG0HN730aTKK+GAGaerNF5@L_?3NF)k zB#&4XVRx+JzQicRC9~Bbv~ZD7fwPc-5ZEFw6S^28rJG5-(HasG9*~3S5>mjx^azU> zUhUT8KGakwh{W) za;z^A`nKp`*Rz`0lz;Uu>34tl2K=EY+wHelUGQ!vR2RJK2dfLN%@pX)jOv1mmGoGN zm$4Q`wXT{lUoF}iY-P#smtCXPr$ac|%Sl^N@Xo=zG2X#938@sLOrMY{3J|nMv|gr3 z$T?Pa3E9Jf4%#A0Tc>Fea`o@*=VgXxE~mi(_6WJeaU7GZ)_<-VHwmfCYZMe&jSOF+ z6GDCs&apNKDSlFGpED#^k*sY_2$L9+uzQ0xVc3Uw2g_wH3TZ-^^zxZ{>?R>HNvakF zLN+QnVKGj_H#Ith=)Yh{sNzg<0X_$Wz8?oMEIw6BJ|$}tQVB3r)?2+?d@_ml7W#zf zuC&y0I1Y0{>V9I^>z#4P<-n1<$_ag?sYl5ESPpAj8KE76uA7v jRu|lEMRuE|-FEIDlB3W(Jtz~{00000NkvXXu0mjfQy-CK delta 1049 zcmV+!1m^q83%Lm)iBL{Q4GJ0x0000DNk~Le0001h0001h1Oos705K4J_>mzu0iuyv zeScL`Mruw0sd@@aGfPO&larsA5?_*Xou00W*$ zL_t(&f$dpavfCgGb$8IF?E>5#bP1iw4B!1}SJ1Elind=p00A~Oiu?Kq$-UQSoQn>U zIFiZo=3O)1TJduG)Qr`Nm)lxTcw4P_xqrRCSL5?)#mnvEw?`R2zOD)T*y8?v!OQJK zJ>!=(VSpC*_X|b_k7|$wCIAp?+}~F`V&K9x2FV962LB-gFE~EKzyXawI9+xOdW##( z{{@8QDs~Lc)@)|5>-8faOnZG4h3UAD^5DgQ!W^Dvz$yzszb909q{-e3Je&csxWOQy|Z$wb-+4m8sYn0KR>w2FDRSuit@eQS2jRu_aK)Q2{^EA$RkoH%J z^EA#3q%x_6X}r`uPu~O0VA_o?&lqI4nJ_C-%o8TXv0zrDw7)`D919jzCW-Z+s%yZ5 z4rLy{`h!=0aCCk!jYm&y)0h+q1=f3DrDetGaGiO(-8yP);5YUhtT-J$XMcbSk3VS9 zC(Uc|IRnTRlje2!FEGFw)A*pn=L`U=y{A`-LWduG1(8}qxsUwtGguqrTplnNrVVGC;NY6>vTi<0IBlILV8i!D%L*F|b+u6Ab>jD!=*z^8`yj%#=41Se>?+z}gRN zCP*h))0wxKAa$O4lI8T-SZiZB>Dpny1msCHSEe*nAN2c%eFjbxFn{Gb}*#o3IzwHQo%iaV8DQDQ?kGq5`i5?gD9{C-S6$G4U{pC zLd$@!+3k#VfiVK3c$t T&wn$a00000NkvXXu0mjfZlvIo
iVK3c$t T&wn$a00000NkvXXu0mjfZlvIo