From a8f890bad1776c4ae6744c5288dcea7d4e1bd81b Mon Sep 17 00:00:00 2001 From: Crazylemon64 Date: Wed, 24 Feb 2016 20:09:07 -0800 Subject: [PATCH] Updates the buildmode tool to allow for better area generator testing --- code/__DEFINES/is_helpers.dm | 1 + code/__HELPERS/unsorted.dm | 77 ++- code/_onclick/ai.dm | 12 +- code/_onclick/click.dm | 8 +- code/_onclick/cyborg.dm | 6 +- code/_onclick/observer.dm | 12 +- .../gamemodes/miniantags/revenant/revenant.dm | 8 +- code/modules/admin/buildmode.dm | 579 ++++++++++-------- code/modules/client/client defines.dm | 5 +- icons/misc/buildmode.dmi | Bin 2550 -> 1284 bytes paradise.dme | 2 + 11 files changed, 413 insertions(+), 297 deletions(-) create mode 100644 code/__DEFINES/is_helpers.dm diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm new file mode 100644 index 00000000000..14161a5775f --- /dev/null +++ b/code/__DEFINES/is_helpers.dm @@ -0,0 +1 @@ +#define ismovableatom(A) istype(A, /atom/movable) \ No newline at end of file diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 773572cc0fc..899e8caa98a 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -896,7 +896,7 @@ proc/anim(turf/location as turf,target as mob|obj,a_icon,a_icon_state as text,fl -proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) +/proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0, var/atom/newloc = null) if(!original) return null @@ -905,15 +905,23 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) if(sameloc) O=new original.type(original.loc) else - O=new original.type(locate(0,0,0)) + O=new original.type(newloc) if(perfectcopy) if((O) && (original)) - for(var/V in original.vars) - if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key"))) - O.vars[V] = original.vars[V] - return O + var/static/list/forbidden_vars = list("type","loc","locs","vars", "parent","parent_type", "verbs","ckey","key","power_supply","contents","reagents","stat","x","y","z","group") + for(var/V in original.vars - forbidden_vars) + if(istype(original.vars[V],/list)) + var/list/L = original.vars[V] + O.vars[V] = L.Copy() + else if(istype(original.vars[V],/datum)) + continue // this would reference the original's object, that will break when it is used or deleted. + else + O.vars[V] = original.vars[V] + if(istype(O)) + O.update_icon() + return O /area/proc/copy_contents_to(var/area/A , var/platingRequired = 0 ) //Takes: Area. Optional: If it should copy to areas that don't have plating @@ -1019,7 +1027,7 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) for(var/V in T.vars) - if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity"))) + if(!(V in list("type","loc","locs","vars", "parent", "parent_type","verbs","ckey","key","x","y","z","contents", "luminosity", "group"))) X.vars[V] = T.vars[V] // var/area/AR = X.loc @@ -1673,3 +1681,58 @@ var/mob/dview/dview_mob = new tY = max(1, min(world.maxy, origin.y + (text2num(tY) - (world.view + 1)))) return locate(tX, tY, tZ) +/proc/pick_closest_path(value) + var/list/matches = get_fancy_list_of_types() + if (!isnull(value) && value!="") + matches = filter_fancy_list(matches, value) + + if(matches.len==0) + return + + var/chosen + if(matches.len==1) + chosen = matches[1] + else + chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches + if(!chosen) + return + chosen = matches[chosen] + return chosen + + +var/list/TYPES_SHORTCUTS = list( + /obj/effect/decal/cleanable = "CLEANABLE", + /obj/item/device/radio/headset = "HEADSET", + /obj/item/clothing/head/helmet/space = "SPESSHELMET", + /obj/item/weapon/book/manual = "MANUAL", + /obj/item/weapon/reagent_containers/food/drinks = "DRINK", //longest paths comes first + /obj/item/weapon/reagent_containers/food = "FOOD", + /obj/item/weapon/reagent_containers = "REAGENT_CONTAINERS", + /obj/machinery/atmospherics = "ATMOS", + /obj/machinery/portable_atmospherics = "PORT_ATMOS", +// /obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack = "MECHA_MISSILE_RACK", + /obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP", +// /obj/item/organ/internal = "ORGAN_INT", +) + +var/global/list/g_fancy_list_of_types = null +/proc/get_fancy_list_of_types() + if (isnull(g_fancy_list_of_types)) //init + var/list/temp = sortList(subtypesof(/atom) - typesof(/area) - /atom/movable) + g_fancy_list_of_types = new(temp.len) + for(var/type in temp) + var/typename = "[type]" + for (var/tn in TYPES_SHORTCUTS) + if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ ) + typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/")) + break + g_fancy_list_of_types[typename] = type + return g_fancy_list_of_types + +/proc/filter_fancy_list(list/L, filter as text) + var/list/matches = new + for(var/key in L) + var/value = L[key] + if(findtext("[key]", filter) || findtext("[value]", filter)) + matches[key] = value + return matches \ No newline at end of file diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 5b9dd3bc6c7..6e21012259b 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -10,9 +10,9 @@ 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(client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) + return if(control_disabled || stat) return @@ -27,9 +27,9 @@ 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(client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) + return if(control_disabled || stat) return diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 5c13314833c..e16fc5af6c1 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -38,9 +38,11 @@ return next_click = world.time + 1 - if(client && client.buildmode) - build_click(src, client.buildmode, params, A) - return + if(client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) + return + else + log_to_dd("Some twerp set a click_intercept without a viable \"InterceptClickOn\" variable, go yell at them. Mob: [src]") var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index fd54407f19e..bc46ae1b514 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -11,9 +11,9 @@ 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(client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) + return var/list/modifiers = params2list(params) if(modifiers["shift"] && modifiers["ctrl"]) diff --git a/code/_onclick/observer.dm b/code/_onclick/observer.dm index 09e205a3316..e4f9fef933a 100644 --- a/code/_onclick/observer.dm +++ b/code/_onclick/observer.dm @@ -1,7 +1,7 @@ /mob/dead/observer/DblClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return + if(client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, 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) @@ -17,9 +17,9 @@ forceMove(get_turf(A)) /mob/dead/observer/ClickOn(var/atom/A, var/params) - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return + if(client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) + return if(world.time <= next_move) return diff --git a/code/game/gamemodes/miniantags/revenant/revenant.dm b/code/game/gamemodes/miniantags/revenant/revenant.dm index eea1bfcc586..4c7277cfdaf 100644 --- a/code/game/gamemodes/miniantags/revenant/revenant.dm +++ b/code/game/gamemodes/miniantags/revenant/revenant.dm @@ -86,10 +86,10 @@ if(essence == 0) src << "You feel your essence fraying!" -/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly. - if(client.buildmode) - build_click(src, client.buildmode, params, A) - return +/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.if(client.click_intercept) + if(client.click_intercept) + if(call(client.click_intercept, "InterceptClickOn")(src, params, A)) + return var/list/modifiers = params2list(params) if(modifiers["middle"]) diff --git a/code/modules/admin/buildmode.dm b/code/modules/admin/buildmode.dm index 31e1842186e..c7a2e331c44 100644 --- a/code/modules/admin/buildmode.dm +++ b/code/modules/admin/buildmode.dm @@ -3,225 +3,274 @@ #define VAR_BUILDMODE 3 #define THROW_BUILDMODE 4 #define AREA_BUILDMODE 5 -#define NUM_BUILDMODES 5 +#define COPY_BUILDMODE 6 +#define NUM_BUILDMODES 6 -/proc/togglebuildmode(mob/M as mob in 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.") - M.client.buildmode = 0 - M.client.show_popup_menus = 1 - for(var/obj/effect/bmode/buildholder/H) - if(H.cl == M.client) - qdel(H) - else - message_admins("[key_name_admin(usr)] has entered build mode.") - log_admin("[key_name(usr)] has entered build mode.") - M.client.buildmode = 1 - M.client.show_popup_menus = 0 - - 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 - - H.builddir = A - H.buildhelp = B - H.buildmode = C - H.buildquit = D - M.client.screen += A - M.client.screen += B - M.client.screen += C - M.client.screen += D - H.cl = M.client - -/obj/effect/bmode //Cleaning up the tree a bit - density = 1 - anchored = 1 - layer = 20 - dir = NORTH +/obj/screen/buildmode icon = 'icons/misc/buildmode.dmi' - var/obj/effect/bmode/buildholder/master = null + var/datum/buildmode/bd -/obj/effect/bmode/Destroy() - if(master && master.cl) - master.cl.screen -= src - master = null - return ..() +/obj/screen/buildmode/New(bld) + ..() + bd = bld -/obj/effect/bmode/builddir - icon_state = "build" +/obj/screen/buildmode/mode + name = "Toggle Mode" + icon_state = "buildmode1" screen_loc = "NORTH,WEST" -/obj/effect/bmode/Click() - switch(dir) - if(NORTH) - dir = EAST - if(EAST) - dir = SOUTH - if(SOUTH) - dir = WEST - if(WEST) - dir = SOUTHWEST - if(SOUTHWEST) - 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(BASIC_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button = Construct / Upgrade" - usr << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade" - usr << "\blue Left Mouse Button + ctrl = R-Window" - usr << "\blue Left Mouse Button + alt = Airlock" - usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(ADV_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Set object type" - usr << "\blue Left Mouse Button on turf/obj = Place objects" - usr << "\blue Right Mouse Button = Delete objects" - usr << "" - usr << "\blue Use the button in the upper left corner to" - usr << "\blue change the direction of built objects." - usr << "\blue ***********************************************************" - if(VAR_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Right Mouse Button on buildmode button = Select var(type) & value" - usr << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value" - usr << "\blue Right Mouse Button on turf/obj/mob = Reset var's value" - usr << "\blue ***********************************************************" - if(THROW_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button on turf/obj/mob = Select" - usr << "\blue Right Mouse Button on turf/obj/mob = Throw" - usr << "\blue ***********************************************************" - if(AREA_BUILDMODE) - usr << "\blue ***********************************************************" - usr << "\blue Left Mouse Button on turf/obj/mob = Select corner" - usr << "\blue Right Mouse Button on buildmode button = Select generator" - usr << "\blue ***********************************************************" - return 1 - -/obj/effect/bmode/buildquit - icon_state = "buildquit" - screen_loc = "NORTH,WEST+3" - -/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/atom/movable/throw_atom = null - var/turf/cornerA = null - var/turf/cornerB = null - var/generator_path = 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/buildmode - icon_state = "buildmode1" - screen_loc = "NORTH,WEST+2" - var/varholder = "name" - var/valueholder = "derp" - var/objholder = /obj/structure/closet - -/obj/effect/bmode/buildmode/Click(location, control, params) +/obj/screen/buildmode/mode/Click(location, control, params) var/list/pa = params2list(params) if(pa.Find("left")) - master.cl.buildmode = (master.cl.buildmode % NUM_BUILDMODES) +1 - src.icon_state = "buildmode[master.cl.buildmode]" - + bd.toggle_modes() else if(pa.Find("right")) - switch(master.cl.buildmode) - if(BASIC_BUILDMODE) - return 1 - if(ADV_BUILDMODE) - 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(VAR_BUILDMODE) - var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "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 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 - if(AREA_BUILDMODE) - var/list/gen_paths = subtypesof(/datum/mapGenerator) - - var/type = input(usr,"Select Generator Type","Type") as null|anything in gen_paths - if(!type) return - - master.generator_path = type + bd.change_settings(usr) + update_icon() return 1 +/obj/screen/buildmode/mode/update_icon() + icon_state = "buildmode[bd.mode]" + return -/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) +/obj/screen/buildmode/help + icon_state = "buildhelp" + screen_loc = "NORTH,WEST+1" + name = "Buildmode Help" - if(istype(object,/obj/effect/bmode)) - return +/obj/screen/buildmode/help/Click() + bd.show_help(usr) + return 1 - switch(buildmode) +/obj/screen/buildmode/bdir + icon_state = "build" + screen_loc = "NORTH,WEST+2" + name = "Change Dir" + +/obj/screen/buildmode/bdir/update_icon() + dir = bd.build_dir + return + +/obj/screen/buildmode/bdir/Click() + bd.change_dir() + update_icon() + return 1 + +/obj/screen/buildmode/quit + icon_state = "buildquit" + screen_loc = "NORTH,WEST+3" + name = "Quit Buildmode" + +/obj/screen/buildmode/quit/Click() + bd.quit() + return 1 + +/obj/screen/buildmode/dir/Click() + bd.change_dir() + update_icon() + return 1 + +/obj/effect/buildmode_reticule + var/image/I + var/client/cl + +/obj/effect/buildmode_reticule/New(var/turf/t, var/client/c) + loc = t + I = image('icons/mob/blob.dmi', t, "marker",19.0,2) // Sprite reuse wooo + cl = c + cl.images += I + +/obj/effect/buildmode_reticule/proc/deselect() + qdel(src) + +/obj/effect/buildmode_reticule/Destroy() + cl.images -= I + cl = null + qdel(I) + +/datum/buildmode + var/mode = BASIC_BUILDMODE + var/client/holder = null + var/list/obj/screen/buttons = list() + var/build_dir = SOUTH + var/atom/movable/throw_atom = null + var/obj/effect/buildmode_reticule/cornerA = null + var/obj/effect/buildmode_reticule/cornerB = null + var/generator_path = null + var/varholder = "name" + var/valueholder = "derp" + var/objholder = /obj/structure/closet + var/atom/movable/stored = null + +/datum/buildmode/New(client/c) + create_buttons() + holder = c + holder.click_intercept = src + holder.show_popup_menus = 0 + holder.screen += buttons + +/datum/buildmode/proc/quit() + holder.screen -= buttons + holder.click_intercept = null + holder.show_popup_menus = 1 + qdel(src) + +/datum/buildmode/Destroy() + stored = null + Reset() + for(var/button in buttons) + qdel(button) + +/datum/buildmode/proc/create_buttons() + buttons += new /obj/screen/buildmode/mode(src) + buttons += new /obj/screen/buildmode/help(src) + buttons += new /obj/screen/buildmode/bdir(src) + buttons += new /obj/screen/buildmode/quit(src) + +/datum/buildmode/proc/toggle_modes() + mode = (mode % NUM_BUILDMODES) +1 + Reset() + return + +/datum/buildmode/proc/show_help(mob/user) + switch(mode) if(BASIC_BUILDMODE) - if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") ) + user << "***********************************************************" + user << "Left Mouse Button = Construct / Upgrade" + user << "Right Mouse Button = Deconstruct / Delete / Downgrade" + user << "Left Mouse Button + ctrl = R-Window" + user << "Left Mouse Button + alt = Airlock" + user << "" + user << "Use the button in the upper left corner to" + user << "change the direction of built objects." + user << "***********************************************************" + if(ADV_BUILDMODE) + user << "***********************************************************" + user << "Right Mouse Button on buildmode button = Set object type" + user << "Left Mouse Button on turf/obj = Place objects" + user << "Right Mouse Button = Delete objects" + user << "" + user << "Use the button in the upper left corner to" + user << "change the direction of built objects." + user << "***********************************************************" + if(VAR_BUILDMODE) + user << "***********************************************************" + user << "Right Mouse Button on buildmode button = Select var(type) & value" + user << "Left Mouse Button on turf/obj/mob = Set var(type) & value" + user << "Right Mouse Button on turf/obj/mob = Reset var's value" + user << "***********************************************************" + if(THROW_BUILDMODE) + user << "***********************************************************" + user << "Left Mouse Button on turf/obj/mob = Select" + user << "Right Mouse Button on turf/obj/mob = Throw" + user << "***********************************************************" + if(AREA_BUILDMODE) + user << "***********************************************************" + user << "Left Mouse Button on turf/obj/mob = Select corner" + user << "Right Mouse Button on buildmode button = Select generator" + user << "***********************************************************" + if(COPY_BUILDMODE) + user << "***********************************************************" + user << "Left Mouse Button on obj/turf/mob = Spawn a Copy of selected target" + user << "Right Mouse Button on obj/mob = Select target to copy" + user << "***********************************************************" + +/datum/buildmode/proc/change_settings(mob/user) + switch(mode) + if(BASIC_BUILDMODE) + + return 1 + if(ADV_BUILDMODE) + var/target_path = input(user,"Enter typepath:" ,"Typepath","/obj/structure/closet") + objholder = text2path(target_path) + if(!ispath(objholder)) + objholder = pick_closest_path(target_path) + if(!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(VAR_BUILDMODE) + var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine") + + varholder = input(user,"Enter variable name:" ,"Name", "name") + if(varholder in locked && !check_rights(R_DEBUG,0)) + + return 1 + var/thetype = input(user,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference") + if(!thetype) return 1 + switch(thetype) + if("text") + valueholder = input(user,"Enter variable value:" ,"Value", "value") as text + if("number") + valueholder = input(user,"Enter variable value:" ,"Value", 123) as num + if("mob-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as mob in mob_list + if("obj-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as obj in world + if("turf-reference") + valueholder = input(user,"Enter variable value:" ,"Value") as turf in world + if(AREA_BUILDMODE) + var/list/gen_paths = subtypesof(/datum/mapGenerator) + + var/type = input(user,"Select Generator Type","Type") as null|anything in gen_paths + if(!type) return + + generator_path = type + cornerA = null + cornerB = null + +/datum/buildmode/proc/change_dir() + switch(build_dir) + if(NORTH) + build_dir = EAST + if(EAST) + build_dir = SOUTH + if(SOUTH) + build_dir = WEST + if(WEST) + build_dir = NORTHWEST + if(NORTHWEST) + build_dir = NORTH + return 1 + +/datum/buildmode/proc/deselect_region() + qdel(cornerA) + cornerA = null + qdel(cornerB) + cornerB = null + +/datum/buildmode/proc/Reset()//Reset temporary variables + deselect_region() + +/datum/buildmode/proc/select_tile(var/turf/T) + return new /obj/effect/buildmode_reticule(T, holder) + +/proc/togglebuildmode(mob/M in player_list) + set name = "Toggle Build Mode" + set category = "Special Verbs" + if(M.client) + if(istype(M.client.click_intercept,/datum/buildmode)) + var/datum/buildmode/B = M.client.click_intercept + B.quit() + log_admin("[key_name(usr)] has left build mode.") + else + new/datum/buildmode(M.client) + message_admins("[key_name(usr)] has entered build mode.") + log_admin("[key_name(usr)] has entered build mode.") + +/datum/buildmode/proc/InterceptClickOn(user,params,atom/object) //Click Intercept + var/list/pa = params2list(params) + var/right_click = pa.Find("right") + var/left_click = pa.Find("left") + var/alt_click = pa.Find("alt") + var/ctrl_click = pa.Find("ctrl") + + . = 1 + switch(mode) + if(BASIC_BUILDMODE) + if(istype(object,/turf) && left_click && !alt_click && !ctrl_click) var/turf/T = object if(istype(object,/turf/space)) T.ChangeTurf(/turf/simulated/floor/plasteel) @@ -229,10 +278,10 @@ T.ChangeTurf(/turf/simulated/wall) else if(istype(object,/turf/simulated/wall)) T.ChangeTurf(/turf/simulated/wall/r_wall) - log_admin("Build Mode: [key_name(usr)] built [T] at ([T.x],[T.y],[T.z])") + log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])") return - else if(pa.Find("right")) - log_admin("Build Mode: [key_name(usr)] deleted [object] at ([object.x],[object.y],[object.z])") + else if(right_click) + log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") if(istype(object,/turf/simulated/wall)) var/turf/T = object T.ChangeTurf(/turf/simulated/floor/plasteel) @@ -245,11 +294,11 @@ else if(istype(object,/obj)) qdel(object) return - else if(istype(object,/turf) && pa.Find("alt") && pa.Find("left")) - log_admin("Build Mode: [key_name(usr)] built an airlock at ([object.x],[object.y],[object.z])") + else if(istype(object,/turf) && alt_click && left_click) + log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])") new/obj/machinery/door/airlock(get_turf(object)) - else if(istype(object,/turf) && pa.Find("ctrl") && pa.Find("left")) - switch(holder.builddir.dir) + else if(istype(object,/turf) && ctrl_click && left_click) + switch(build_dir) if(NORTH) var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) WIN.dir = NORTH @@ -262,76 +311,74 @@ if(WEST) var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) WIN.dir = WEST - if(SOUTHWEST) - new/obj/structure/window/full/reinforced(get_turf(object)) - log_admin("Build Mode: [key_name(usr)] built a window at ([object.x],[object.y],[object.z])") + if(NORTHWEST) + var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object)) + WIN.dir = NORTHWEST + log_admin("Build Mode: [key_name(user)] built a window at ([object.x],[object.y],[object.z])") + if(ADV_BUILDMODE) - if(pa.Find("left")) - if(ispath(holder.buildmode.objholder,/turf)) + if(left_click) + if(ispath(objholder,/turf)) var/turf/T = get_turf(object) - log_admin("Build Mode: [key_name(usr)] modified [T] ([T.x],[T.y],[T.z]) to [holder.buildmode.objholder]") - T.ChangeTurf(holder.buildmode.objholder) + log_admin("Build Mode: [key_name(user)] modified [T] ([T.x],[T.y],[T.z]) to [objholder]") + T.ChangeTurf(objholder) else - var/obj/A = new holder.buildmode.objholder (get_turf(object)) - A.dir = holder.builddir.dir - log_admin("Build Mode: [key_name(usr)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [holder.builddir.dir]") - else if(pa.Find("right")) + var/obj/A = new objholder (get_turf(object)) + A.dir = build_dir + log_admin("Build Mode: [key_name(user)] modified [A]'s ([A.x],[A.y],[A.z]) dir to [build_dir]") + else if(right_click) if(isobj(object)) - log_admin("Build Mode: [key_name(usr)] deleted [object] at ([object.x],[object.y],[object.z])") + log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])") qdel(object) if(VAR_BUILDMODE) - 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]") - object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder + if(left_click) //I cant believe this shit actually compiles. + if(object.vars.Find(varholder)) + log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]") + object.vars[varholder] = valueholder else - 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]") - object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder]) + user << "[initial(object.name)] does not have a var called '[varholder]'" + if(right_click) + if(object.vars.Find(varholder)) + log_admin("Build Mode: [key_name(user)] modified [object.name]'s [varholder] to [valueholder]") + object.vars[varholder] = initial(object.vars[varholder]) else - usr << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'" + user << "[initial(object.name)] does not have a var called '[varholder]'" if(THROW_BUILDMODE) - if(pa.Find("left")) + if(left_click) if(isturf(object)) return - holder.throw_atom = object - if(pa.Find("right")) - if(holder.throw_atom) - holder.throw_atom.throw_at(object, 10, 1) - log_admin("Build Mode: [key_name(usr)] threw [holder.throw_atom] at [object] ([object.x],[object.y],[object.z])") + throw_atom = object + if(right_click) + if(throw_atom) + throw_atom.throw_at(object, 10, 1,user) + log_admin("Build Mode: [key_name(user)] threw [throw_atom] at [object] ([object.x],[object.y],[object.z])") if(AREA_BUILDMODE) - if(!holder.cornerA) - holder.cornerA = get_turf(object) + if(!cornerA) + cornerA = select_tile(get_turf(object)) return - if(holder.cornerA && !holder.cornerB) - holder.cornerB = get_turf(object) + if(cornerA && !cornerB) + cornerB = select_tile(get_turf(object)) + if(left_click) //rectangular + if(cornerA && cornerB) + if(!generator_path) + user << "Select generator type first." + else + var/datum/mapGenerator/G = new generator_path + G.defineRegion(cornerA.loc,cornerB.loc,1) + G.generate() + deselect_region() + return - if(pa.Find("left")) //rectangular - if(holder.cornerA && holder.cornerB) - if(!holder.generator_path) - usr << "Select generator type first." - var/datum/mapGenerator/G = new holder.generator_path - G.defineRegion(holder.cornerA,holder.cornerB,1) - G.generate() - holder.cornerA = null - holder.cornerB = null - return - /* Something wrong with this, will check later - if(pa.Find("right")) // circular - if(holder.cornerA && holder.cornerB) - if(!holder.generator_path) - usr << "Select generator type first." - var/datum/mapGenerator/G = new holder.generator_path - G.defineCircularRegion(holder.cornerA,holder.cornerB,1) - G.generate() - holder.cornerA = null - holder.cornerB = null - return - */ //Something wrong - Reset - holder.cornerA = null - holder.cornerB = null \ No newline at end of file + deselect_region() + if(COPY_BUILDMODE) + if(left_click) + var/turf/T = get_turf(object) + if(stored) + DuplicateObject(stored, perfectcopy=1, sameloc=0,newloc=T) + else if(right_click) + if(ismovableatom(object)) // No copying turfs for now. + user << "[object] set as template." + stored = object diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm index 4d9237bd11c..3f19442f94b 100644 --- a/code/modules/client/client defines.dm +++ b/code/modules/client/client defines.dm @@ -3,7 +3,6 @@ //ADMIN THINGS// //////////////// var/datum/admins/holder = null - var/buildmode = 0 var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming. var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent. @@ -80,4 +79,6 @@ var/topic_debugging = 0 //if set to true, allows client to see nanoUI errors -- yes i realize this is messy but it'll make live testing infinitely easier - control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS \ No newline at end of file + control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS + + var/datum/click_intercept = null // To use this, implement "InterceptClickOn" in your datum, then set your desired client's click_intercept to that datum \ No newline at end of file diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi index beed381e391ca3562db296f52f13f28ab47751e2..ca9d1fd05ccad5c5e5804d31f60fddc673455e70 100644 GIT binary patch delta 1136 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 e=YLyQ0R9Ku>#Mza7XSMI0000