Update to Sandbox Panel

The panel itself has been updated with subcategories and additional options.  The "air regulator" option was removed because what even does that mean.  The Suit Up option has been fixed, and should work properly now.  Additional items include an all-access ID, RCD, flashlight, light replacer, plasteel, cable, floorbot, medbot, gas mask, and emergency air tank.

The hrefs var was moved out of global scope because that's a terrible place for something so generically named.

The Spawn Item and Spawn Canister dialogs now use a browser window instead of a pick list.  This window is cached per user.

Sandbox's Spawn Airlock option gets a new interface.  It allows you to pick the accesses of the new airlock, as well as its paintjob, name, glass inserts where appropriate, and an option to make the access list "require one" instead of "require all."  It adds an airlock frame which can be repositioned; attack-hand-ing the airlock frame (if it has the airlock builder datum attached) will now open the window.

An administrative option has been added to the sandbox panel, which is configurable through game_options.txt.  Because the item spawning uses a persistent browser window, it is susceptible to spamming.  The added option forces the window closed after each item is spawned.  This only affects the item and canister selection windows, and not the whole sandbox panel.
This commit is contained in:
supersayu
2013-05-08 15:13:12 -04:00
parent 17e4358d4c
commit 86d82ce51e
5 changed files with 318 additions and 86 deletions

View File

@@ -108,6 +108,8 @@
var/silent_ai = 0 var/silent_ai = 0
var/silent_borg = 0 var/silent_borg = 0
var/sandbox_autoclose = 0 // close the sandbox panel after spawning an item, potentially reducing griff
/datum/configuration/New() /datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode var/list/L = typesof(/datum/game_mode) - /datum/game_mode
@@ -340,6 +342,8 @@
config.silent_ai = 1 config.silent_ai = 1
if("silent_borg") if("silent_borg")
config.silent_borg = 1 config.silent_borg = 1
if("sandbox_autoclose")
config.sandbox_autoclose = 1
else else
diary << "Unknown setting in configuration: '[name]'" diary << "Unknown setting in configuration: '[name]'"

View File

@@ -0,0 +1,138 @@
/*
This is for the sandbox for now,
maybe useful later for an actual thing?
-Sayu
*/
obj/structure/door_assembly
var/datum/airlock_maker/maker = null
attack_hand()
..()
if(maker)
maker.interact()
datum/airlock_maker
var/obj/structure/door_assembly/linked = null
var/list/access_used = null
var/require_all = 1
var/paintjob = "none"
var/glassdoor = 0
var/doorname = "Airlock"
New(var/atom/target_loc)
linked = new(target_loc)
linked.maker = src
linked.anchored = 0
access_used = list()
interact()
proc/linkpretty(href,desc,active)
if(!desc)
var/static/list/defaults = list("No","Yes")
desc = defaults[active+1]
if(active)
return "<a href='?src=\ref[src];[href]'><b>[desc]</b></a>"
return "<a href='?src=\ref[src];[href]'><i>[desc]</i></a>"
proc/interact()
var/list/leftcolumn = list()
var/list/rightcolumn = list()
leftcolumn += "<u><b>Required Access</b></u>"
for(var/access in get_all_accesses())
leftcolumn += linkpretty("access=[access]",get_access_desc(access),access in access_used)
leftcolumn += "Require all listed accesses: [linkpretty("reqall",null,require_all)]"
rightcolumn += "<u><b>Paintjob</b></u>"
for(var/option in list("none","engineering","atmos","security","command","medical","research","mining","maintenance","external","highsecurity"))
rightcolumn += linkpretty("paint=[option]",option,option == paintjob)
rightcolumn += "Glass door: " + linkpretty("glass",null,glassdoor) + "<br><br>"
var/length = max(leftcolumn.len,rightcolumn.len)
var/dat = "You may move the model airlock around. A new airlock will be built in its space when you click done, below.<hr><br>"
dat += "<a href='?src=\ref[src];rename'>Door name</a>: \"[doorname]\""
dat += "<table>"
for(var/i=1; i<=length; i++)
dat += "<tr><td>"
if(i<=leftcolumn.len)
dat += leftcolumn[i]
dat += "</td><td>"
if(i<=rightcolumn.len)
dat += rightcolumn[i]
dat += "</td></tr>"
dat += "</table><hr><a href='?src=\ref[src];done'>Finalize Airlock Construction</a> | <a href='?src=\ref[src];cancel'>Cancel and Destroy Airlock</a>"
usr << browse(dat,"window=airlockmaker")
Topic(var/href,var/list/href_list)
if(!usr) return
if(!src || !linked || !linked.loc)
usr << browse(null,"window=airlockmaker")
return
if("rename" in href_list)
var/newname = input(usr,"New airlock name:","Name the airlock",doorname) as null|text
if(newname)
doorname = newname
if("access" in href_list)
var/value = text2num(href_list["access"])
access_used ^= value
if("reqall" in href_list)
require_all = !require_all
if("paint" in href_list)
paintjob = href_list["paint"]
if("glass" in href_list)
glassdoor = !glassdoor
if("cancel" in href_list)
usr << browse(null,"window=airlockmaker")
del linked
del src
return
if("done" in href_list)
usr << browse(null,"window=airlockmaker")
var/turf/t_loc = linked.loc
del linked
if(!istype(t_loc))
return
var/target_type = "/obj/machinery/door/airlock"
if(glassdoor)
if(paintjob != "none")
if(paintjob in list("external","highsecurity")) // no glass version
target_type += "/[paintjob]"
else
target_type += "/glass_[paintjob]"
else
target_type += "/glass"
else if(paintjob != "none")
target_type += "/[paintjob]"
var/final = target_type
target_type = text2path(final)
if(!target_type)
usr << "Didn't work, contact Sayu with this: [final]"
usr << browse(null,"window=airlockmaker")
return
var/obj/machinery/door/D = new target_type(t_loc)
D.name = doorname
if(access_used.len == 0)
D.req_access = null
D.req_one_access = null
else if(require_all)
D.req_access = access_used.Copy()
D.req_one_access = null
else
D.req_access = null
D.req_one_access = access_used.Copy()
return
interact()

View File

@@ -1,19 +1,6 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31 //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
var/hsboxspawn = 1 var/hsboxspawn = 1
var/list
hrefs = list(
"hsbsuit" = "Suit Up (Space Travel Gear)",
"hsbmetal" = "Spawn 50 Metal",
"hsbglass" = "Spawn 50 Glass",
"hsbairlock" = "Spawn Airlock",
"hsbregulator" = "Spawn Air Regulator",
"hsbfilter" = "Spawn Air Filter",
"hsbcanister" = "Spawn Canister",
"hsbfueltank" = "Spawn Welding Fuel Tank",
"hsbwater tank" = "Spawn Water Tank",
"hsbtoolbox" = "Spawn Toolbox",
"hsbmedkit" = "Spawn Medical Kit")
mob mob
var/datum/hSB/sandbox = null var/datum/hSB/sandbox = null
@@ -26,128 +13,223 @@ mob
sandbox.admin = 1 sandbox.admin = 1
verbs += new/mob/proc/sandbox_panel verbs += new/mob/proc/sandbox_panel
sandbox_panel() sandbox_panel()
set name = "Sandbox Panel"
if(sandbox) if(sandbox)
sandbox.update() sandbox.update()
datum/hSB datum/hSB
var/owner = null var/owner = null
var/admin = 0 var/admin = 0
var/objinfo = null
var/canisterinfo = null
var/hsbinfo = null
var/global/list/spawn_forbidden = list(/obj/item/weapon/grab, /obj/item/tk_grab, /obj/item/weapon/dummy, /obj/item/assembly,/obj/item/device/onetankbomb)
proc proc
update() update()
var/hsbpanel = "<center><b>h_Sandbox Panel</b></center><hr>" var/global/list/hrefs = list(
"Space Gear",
"Suit Up (Space Travel Gear)" = "hsbsuit",
"Spawn Gas Mask" = "hsbspawn&path=[/obj/item/clothing/mask/gas]",
"Spawn Emergency Air Tank" = "hsbspawn&path=[/obj/item/weapon/tank/emergency_oxygen/double]",
"Standard Tools",
"Spawn Flashlight" = "hsbspawn&path=[/obj/item/device/flashlight]",
"Spawn Toolbox" = "hsbspawn&path=[/obj/item/weapon/storage/toolbox/mechanical]",
"Spawn Light Replacer" = "hsbspawn&path=[/obj/item/device/lightreplacer]",
"Spawn Rapid Construction Device" = "hsbrcd",
"Spawn RCD Ammo" = "hsbspawn&path=[/obj/item/weapon/rcd_ammo]",
"Spawn Medical Kit" = "hsbspawn&path=[/obj/item/weapon/storage/firstaid/regular]",
"Spawn All-Access ID" = "hsbaaid",
"Building Supplies",
"Spawn 50 Metal" = "hsbmetal",
"Spawn 50 Plasteel" = "hsbplasteel",
"Spawn 50 Glass" = "hsbglass",
"Spawn Full Cable Coil" = "hsbspawn&path=[/obj/item/weapon/cable_coil]",
"Spawn Hyper Capacity Power Cell" = "hsbspawn&path=[/obj/item/weapon/cell/hyper]",
"Spawn Airlock" = "hsbairlock",
"Miscellaneous",
"Spawn Air Scrubber" = "hsbspawn&path=[/obj/machinery/portable_atmospherics/scrubber]",
"Spawn Canister" = "hsbcanister",
"Spawn Welding Fuel Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/fueltank]",
"Spawn Water Tank" = "hsbspawn&path=[/obj/structure/reagent_dispensers/watertank]",
"Bots",
"Spawn Floorbot" = "hsbspawn&path=[/obj/machinery/bot/floorbot]",
"Spawn Medbot" = "hsbspawn&path=[/obj/machinery/bot/medbot]")
if(!hsbinfo)
hsbinfo = "<center><b>Sandbox Panel</b></center><hr>"
if(admin) if(admin)
hsbpanel += "<b>Administration Tools:</b><br>" hsbinfo += "<b>Administration</b><br>"
hsbpanel += "- <a href=\"?\ref[src];hsb=hsbtobj\">Toggle Object Spawning</a><br><br>" hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtobj'>Toggle Object Spawning</a><br>"
hsbpanel += "<b>Regular Tools:</b><br>" hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtac'>Toggle Item Spawn Panel Auto-close</a><hr>"
for(var/T in hrefs) for(var/T in hrefs)
hsbpanel += "- <a href=\"?\ref[src];hsb=[T]\">[hrefs[T]]</a><br>" var/href = hrefs[T]
if(href)
hsbinfo += "- <a href=\"?\ref[src];hsb=[hrefs[T]]\">[T]</a><br>"
else
hsbinfo += "<br><b>[T]</b><br>"
if(hsboxspawn) if(hsboxspawn)
hsbpanel += "- <a href=\"?\ref[src];hsb=hsbobj\">Spawn Object</a><br><br>" hsbinfo += "<hr>- <a href=\"?\ref[src];hsb=hsbobj\">Spawn Other Item</a><br><br>"
usr << browse(hsbpanel, "window=hsbpanel")
usr << browse(hsbinfo, "window=hsbpanel")
Topic(href, href_list) Topic(href, href_list)
if(!(src.owner == usr.ckey)) return if(!usr || !src || !(src.owner == usr.ckey))
if(!usr) return //I guess this is possible if they log out or die with the panel open? It happened. if(usr)
usr << browse(null,"window=sandbox")
return
if(href_list["hsb"]) if(href_list["hsb"])
switch(href_list["hsb"]) switch(href_list["hsb"])
//
// Admin: toggle spawning
//
if("hsbtobj") if("hsbtobj")
if(!admin) return if(!admin) return
if(hsboxspawn) if(hsboxspawn)
world << "<b>Sandbox: [usr.key] has disabled object spawning!</b>" world << "<b>\red Sandbox: \black[usr.key] has disabled object spawning!</b>"
hsboxspawn = 0 hsboxspawn = 0
return return
if(!hsboxspawn) else
world << "<b>Sandbox: [usr.key] has enabled object spawning!</b>" world << "<b>\blue Sandbox: \black[usr.key] has enabled object spawning!</b>"
hsboxspawn = 1 hsboxspawn = 1
return return
//
// Admin: Toggle auto-close
//
if("hsbtac")
if(!admin) return
if(config.sandbox_autoclose)
world << "<b>\blue Sandbox: \black [usr.key] has removed the object spawn limiter.</b>"
config.sandbox_autoclose = 0
else
world << "<b>\red Sandbox: \black [usr.key] has added a limiter to object spawning. The window will now auto-close after use.</b>"
config.sandbox_autoclose = 1
return
//
// Spacesuit with full air jetpack set as internals
//
if("hsbsuit") if("hsbsuit")
var/mob/living/carbon/human/P = usr var/mob/living/carbon/human/P = usr
if(!istype(P)) return
if(P.wear_suit) if(P.wear_suit)
P.wear_suit.loc = P.loc P.wear_suit.loc = P.loc
P.wear_suit.layer = initial(P.wear_suit.layer) P.wear_suit.layer = initial(P.wear_suit.layer)
P.wear_suit = null P.wear_suit = null
P.wear_suit = new/obj/item/clothing/suit/space(P) P.wear_suit = new/obj/item/clothing/suit/space(P)
P.wear_suit.layer = 20 P.wear_suit.layer = 20
P.update_inv_wear_suit()
if(P.head) if(P.head)
P.head.loc = P.loc P.head.loc = P.loc
P.head.layer = initial(P.head.layer) P.head.layer = initial(P.head.layer)
P.head = null P.head = null
P.head = new/obj/item/clothing/head/helmet/space(P) P.head = new/obj/item/clothing/head/helmet/space(P)
P.head.layer = 20 P.head.layer = 20
P.update_inv_head()
if(P.wear_mask) if(P.wear_mask)
P.wear_mask.loc = P.loc P.wear_mask.loc = P.loc
P.wear_mask.layer = initial(P.wear_mask.layer) P.wear_mask.layer = initial(P.wear_mask.layer)
P.wear_mask = null P.wear_mask = null
P.wear_mask = new/obj/item/clothing/mask/gas(P) P.wear_mask = new/obj/item/clothing/mask/gas(P)
P.wear_mask.layer = 20 P.wear_mask.layer = 20
P.update_inv_wear_mask()
if(P.back) if(P.back)
P.back.loc = P.loc P.back.loc = P.loc
P.back.layer = initial(P.back.layer) P.back.layer = initial(P.back.layer)
P.back = null P.back = null
P.back = new/obj/item/weapon/tank/jetpack(P) P.back = new/obj/item/weapon/tank/jetpack/oxygen(P)
P.back.layer = 20 P.back.layer = 20
P.update_inv_back()
P.internal = P.back P.internal = P.back
if(P.internals)
P.internals.icon_state = "internal1"
if("hsbmetal") if("hsbmetal")
var/obj/item/stack/sheet/hsb = new/obj/item/stack/sheet/metal new/obj/item/stack/sheet/metal{amount=50}(usr.loc)
hsb.amount = 50
hsb.loc = usr.loc if("hsbplasteel")
new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc)
if("hsbglass") if("hsbglass")
var/obj/item/stack/sheet/hsb = new/obj/item/stack/sheet/glass new/obj/item/stack/sheet/glass{amount=50}(usr.loc)
hsb.amount = 50
hsb.loc = usr.loc if("hsbaaid")
var/obj/item/weapon/card/id/gold/ID = new(usr.loc)
ID.registered_name = usr.real_name
ID.assignment = "Sandbox"
ID.access = get_all_accesses()
if("hsbrcd")
new/obj/item/weapon/rcd{matter=30;canRwall=1}(usr.loc)
//
// New sandbox airlock maker
//
if("hsbairlock") if("hsbairlock")
var/obj/machinery/door/hsb = new/obj/machinery/door/airlock new /datum/airlock_maker(usr.loc)
//TODO: DEFERRED make this better, with an HTML window or something instead of 15 popups //
hsb.req_access = list() // Canister select window
var/accesses = get_all_accesses() //
for(var/A in accesses)
if(alert(usr, "Will this airlock require [get_access_desc(A)] access?", "Sandbox:", "Yes", "No") == "Yes")
hsb.req_access += A
hsb.loc = usr.loc
usr << "<b>Sandbox: Created an airlock."
if("hsbcanister") if("hsbcanister")
var/list/hsbcanisters = typesof(/obj/machinery/portable_atmospherics/canister/) - /obj/machinery/portable_atmospherics/canister/ if(!canisterinfo)
var/hsbcanister = input(usr, "Choose a canister to spawn.", "Sandbox:") in hsbcanisters + "Cancel" canisterinfo = "Choose a canister type:<hr>"
if(!(hsbcanister == "Cancel")) for(var/O in (typesof(/obj/machinery/portable_atmospherics/canister/) - /obj/machinery/portable_atmospherics/canister/))
new hsbcanister(usr.loc) canisterinfo += "<a href='?src=\ref[src];hsb=hsbspawn&path=[O]'>[O]</a><br>"
if("hsbfueltank") usr << browse(canisterinfo,"window=sandbox")
//var/obj/hsb = new/obj/weldfueltank
//hsb.loc = usr.loc //
if("hsbwatertank") // Object spawn window
//var/obj/hsb = new/obj/watertank //
//hsb.loc = usr.loc
if("hsbtoolbox")
var/obj/item/weapon/storage/hsb = new/obj/item/weapon/storage/toolbox/mechanical
for(var/obj/item/device/radio/T in hsb)
del(T)
new/obj/item/weapon/crowbar (hsb)
hsb.loc = usr.loc
if("hsbmedkit")
var/obj/item/weapon/storage/firstaid/hsb = new/obj/item/weapon/storage/firstaid/regular
hsb.loc = usr.loc
if("hsbobj") if("hsbobj")
if(!hsboxspawn) return if(!hsboxspawn) return
var/list/selectable = list() if(!objinfo)
for(var/O in typesof(/obj/item/)) objinfo = "Items:<hr><br>"
//Note, these istypes don't work for(var/O in reverselist(typesof(/obj/item/)))
if(istype(O, /obj/item/weapon/gun)) var/allow = 1
for(var/typekey in spawn_forbidden)
if(ispath(O,typekey))
allow = 0
break
if(!allow)
continue continue
if(istype(O, /obj/item/assembly)) objinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
continue
if(istype(O, /obj/item/device/camera))
continue
if(istype(O, /obj/item/weapon/cloaking_device))
continue
if(istype(O, /obj/item/weapon/dummy))
continue
if(istype(O, /obj/item/weapon/melee/energy/sword))
continue
if(istype(O, /obj/structure))
continue
selectable += O
var/hsbitem = input(usr, "Choose an object to spawn.", "Sandbox:") in selectable + "Cancel" usr << browse(objinfo,"window=sandbox")
if(hsbitem != "Cancel")
new hsbitem(usr.loc) //
// For the object spawn specifically, checks to see if it is turned off
//
if("hsb_safespawn")
if(!hsboxspawn)
usr << browse(null,"window=sandbox")
return
var/typepath = text2path(href_list["path"])
if(!typepath)
usr << "Bad path: \"[href_list["path"]]\""
return
new typepath(usr.loc)
if(config.sandbox_autoclose)
usr << browse(null,"window=sandbox")
//
// For everything else in the href list
//
if("hsbspawn")
var/typepath = text2path(href_list["path"])
if(!typepath)
usr << "Bad path: \"[href_list["path"]]\""
return
new typepath(usr.loc)
if(config.sandbox_autoclose)
usr << browse(null,"window=sandbox")

View File

@@ -142,3 +142,10 @@ JOBS_HAVE_MINIMAL_ACCESS
## Uncomment to stop the AI, or cyborgs, from having vocal communication. ## Uncomment to stop the AI, or cyborgs, from having vocal communication.
#SILENT_AI #SILENT_AI
#SILENT_BORG #SILENT_BORG
### SANDBOX PANEL AUTOCLOSE ###
## The sandbox panel's item spawning dialog now stays open even after you click an option.
## If you find that your players are abusing the sandbox panel, this option may slow them down
## without preventing people from using it properly.
## Only functions in sandbox game mode.
#SANDBOX_AUTOCLOSE

View File

@@ -220,6 +220,7 @@
#include "code\game\gamemodes\nuclear\nuclearbomb.dm" #include "code\game\gamemodes\nuclear\nuclearbomb.dm"
#include "code\game\gamemodes\nuclear\pinpointer.dm" #include "code\game\gamemodes\nuclear\pinpointer.dm"
#include "code\game\gamemodes\revolution\revolution.dm" #include "code\game\gamemodes\revolution\revolution.dm"
#include "code\game\gamemodes\sandbox\airlock_maker.dm"
#include "code\game\gamemodes\sandbox\h_sandbox.dm" #include "code\game\gamemodes\sandbox\h_sandbox.dm"
#include "code\game\gamemodes\sandbox\sandbox.dm" #include "code\game\gamemodes\sandbox\sandbox.dm"
#include "code\game\gamemodes\traitor\traitor.dm" #include "code\game\gamemodes\traitor\traitor.dm"