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_borg = 0
var/sandbox_autoclose = 0 // close the sandbox panel after spawning an item, potentially reducing griff
/datum/configuration/New()
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
@@ -340,6 +342,8 @@
config.silent_ai = 1
if("silent_borg")
config.silent_borg = 1
if("sandbox_autoclose")
config.sandbox_autoclose = 1
else
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
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
var/datum/hSB/sandbox = null
@@ -26,128 +13,223 @@ mob
sandbox.admin = 1
verbs += new/mob/proc/sandbox_panel
sandbox_panel()
set name = "Sandbox Panel"
if(sandbox)
sandbox.update()
datum/hSB
var/owner = null
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
update()
var/hsbpanel = "<center><b>h_Sandbox Panel</b></center><hr>"
if(admin)
hsbpanel += "<b>Administration Tools:</b><br>"
hsbpanel += "- <a href=\"?\ref[src];hsb=hsbtobj\">Toggle Object Spawning</a><br><br>"
hsbpanel += "<b>Regular Tools:</b><br>"
for(var/T in hrefs)
hsbpanel += "- <a href=\"?\ref[src];hsb=[T]\">[hrefs[T]]</a><br>"
if(hsboxspawn)
hsbpanel += "- <a href=\"?\ref[src];hsb=hsbobj\">Spawn Object</a><br><br>"
usr << browse(hsbpanel, "window=hsbpanel")
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)
hsbinfo += "<b>Administration</b><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtobj'>Toggle Object Spawning</a><br>"
hsbinfo += "- <a href='?src=\ref[src];hsb=hsbtac'>Toggle Item Spawn Panel Auto-close</a><hr>"
for(var/T in hrefs)
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)
hsbinfo += "<hr>- <a href=\"?\ref[src];hsb=hsbobj\">Spawn Other Item</a><br><br>"
usr << browse(hsbinfo, "window=hsbpanel")
Topic(href, href_list)
if(!(src.owner == usr.ckey)) return
if(!usr) return //I guess this is possible if they log out or die with the panel open? It happened.
if(!usr || !src || !(src.owner == usr.ckey))
if(usr)
usr << browse(null,"window=sandbox")
return
if(href_list["hsb"])
switch(href_list["hsb"])
//
// Admin: toggle spawning
//
if("hsbtobj")
if(!admin) return
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
return
if(!hsboxspawn)
world << "<b>Sandbox: [usr.key] has enabled object spawning!</b>"
else
world << "<b>\blue Sandbox: \black[usr.key] has enabled object spawning!</b>"
hsboxspawn = 1
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")
var/mob/living/carbon/human/P = usr
if(!istype(P)) return
if(P.wear_suit)
P.wear_suit.loc = P.loc
P.wear_suit.layer = initial(P.wear_suit.layer)
P.wear_suit = null
P.wear_suit = new/obj/item/clothing/suit/space(P)
P.wear_suit.layer = 20
P.update_inv_wear_suit()
if(P.head)
P.head.loc = P.loc
P.head.layer = initial(P.head.layer)
P.head = null
P.head = new/obj/item/clothing/head/helmet/space(P)
P.head.layer = 20
P.update_inv_head()
if(P.wear_mask)
P.wear_mask.loc = P.loc
P.wear_mask.layer = initial(P.wear_mask.layer)
P.wear_mask = null
P.wear_mask = new/obj/item/clothing/mask/gas(P)
P.wear_mask.layer = 20
P.update_inv_wear_mask()
if(P.back)
P.back.loc = P.loc
P.back.layer = initial(P.back.layer)
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.update_inv_back()
P.internal = P.back
if(P.internals)
P.internals.icon_state = "internal1"
if("hsbmetal")
var/obj/item/stack/sheet/hsb = new/obj/item/stack/sheet/metal
hsb.amount = 50
hsb.loc = usr.loc
new/obj/item/stack/sheet/metal{amount=50}(usr.loc)
if("hsbplasteel")
new/obj/item/stack/sheet/plasteel{amount=50}(usr.loc)
if("hsbglass")
var/obj/item/stack/sheet/hsb = new/obj/item/stack/sheet/glass
hsb.amount = 50
hsb.loc = usr.loc
new/obj/item/stack/sheet/glass{amount=50}(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")
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()
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."
//
// Canister select window
//
if("hsbcanister")
var/list/hsbcanisters = typesof(/obj/machinery/portable_atmospherics/canister/) - /obj/machinery/portable_atmospherics/canister/
var/hsbcanister = input(usr, "Choose a canister to spawn.", "Sandbox:") in hsbcanisters + "Cancel"
if(!(hsbcanister == "Cancel"))
new hsbcanister(usr.loc)
if("hsbfueltank")
//var/obj/hsb = new/obj/weldfueltank
//hsb.loc = usr.loc
if("hsbwatertank")
//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(!canisterinfo)
canisterinfo = "Choose a canister type:<hr>"
for(var/O in (typesof(/obj/machinery/portable_atmospherics/canister/) - /obj/machinery/portable_atmospherics/canister/))
canisterinfo += "<a href='?src=\ref[src];hsb=hsbspawn&path=[O]'>[O]</a><br>"
usr << browse(canisterinfo,"window=sandbox")
//
// Object spawn window
//
if("hsbobj")
if(!hsboxspawn) return
var/list/selectable = list()
for(var/O in typesof(/obj/item/))
//Note, these istypes don't work
if(istype(O, /obj/item/weapon/gun))
continue
if(istype(O, /obj/item/assembly))
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
if(!objinfo)
objinfo = "Items:<hr><br>"
for(var/O in reverselist(typesof(/obj/item/)))
var/allow = 1
for(var/typekey in spawn_forbidden)
if(ispath(O,typekey))
allow = 0
break
if(!allow)
continue
objinfo += "<a href='?src=\ref[src];hsb=hsb_safespawn&path=[O]'>[O]</a><br>"
var/hsbitem = input(usr, "Choose an object to spawn.", "Sandbox:") in selectable + "Cancel"
if(hsbitem != "Cancel")
new hsbitem(usr.loc)
usr << browse(objinfo,"window=sandbox")
//
// 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

@@ -141,4 +141,11 @@ JOBS_HAVE_MINIMAL_ACCESS
### NON-VOCAL SILICONS ###
## Uncomment to stop the AI, or cyborgs, from having vocal communication.
#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\pinpointer.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\sandbox.dm"
#include "code\game\gamemodes\traitor\traitor.dm"