another batch. MAJOR: ccpodlauncher, cargo/console.dm, smartfrige, holodeck/computer.dm, biogenerator

This commit is contained in:
Letter N
2020-07-29 15:10:01 +08:00
parent 8e177bf01e
commit 5d4bb48628
20 changed files with 517 additions and 456 deletions

View File

@@ -237,11 +237,10 @@
return ..() return ..()
return UI_CLOSE return UI_CLOSE
/obj/machinery/airalarm/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/airalarm/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "AirAlarm", name, 440, 650, master_ui, state) ui = new(user, src, "AirAlarm", name)
ui.open() ui.open()
/obj/machinery/airalarm/ui_data(mob/user) /obj/machinery/airalarm/ui_data(mob/user)

View File

@@ -26,9 +26,6 @@ Passive gate is similar to the regular pump except:
construction_type = /obj/item/pipe/directional construction_type = /obj/item/pipe/directional
pipe_state = "passivegate" pipe_state = "passivegate"
ui_x = 335
ui_y = 115
/obj/machinery/atmospherics/components/binary/passive_gate/CtrlClick(mob/user) /obj/machinery/atmospherics/components/binary/passive_gate/CtrlClick(mob/user)
if(can_interact(user)) if(can_interact(user))
on = !on on = !on
@@ -102,11 +99,10 @@ Passive gate is similar to the regular pump except:
)) ))
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
/obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/binary/passive_gate/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "AtmosPump", name)
ui.open() ui.open()
/obj/machinery/atmospherics/components/binary/passive_gate/ui_data() /obj/machinery/atmospherics/components/binary/passive_gate/ui_data()

View File

@@ -107,11 +107,10 @@
)) ))
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA) radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
/obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/binary/pump/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "AtmosPump", name, 335, 115, master_ui, state) ui = new(user, src, "AtmosPump", name)
ui.open() ui.open()
/obj/machinery/atmospherics/components/binary/pump/ui_data() /obj/machinery/atmospherics/components/binary/pump/ui_data()

View File

@@ -133,11 +133,10 @@
set_frequency(frequency) set_frequency(frequency)
return ..() return ..()
/obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/trinary/filter/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "AtmosFilter", name, 475, 185, master_ui, state) ui = new(user, src, "AtmosFilter", name)
ui.open() ui.open()
/obj/machinery/atmospherics/components/trinary/filter/ui_data() /obj/machinery/atmospherics/components/trinary/filter/ui_data()

View File

@@ -14,9 +14,6 @@
construction_type = /obj/item/pipe/trinary/flippable construction_type = /obj/item/pipe/trinary/flippable
pipe_state = "mixer" pipe_state = "mixer"
ui_x = 370
ui_y = 165
//node 3 is the outlet, nodes 1 & 2 are intakes //node 3 is the outlet, nodes 1 & 2 are intakes
/obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user) /obj/machinery/atmospherics/components/trinary/mixer/CtrlClick(mob/user)
@@ -127,11 +124,10 @@
var/datum/pipeline/parent3 = parents[3] var/datum/pipeline/parent3 = parents[3]
parent3.update = TRUE parent3.update = TRUE
/obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/trinary/mixer/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "AtmosMixer", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "AtmosMixer", name)
ui.open() ui.open()
/obj/machinery/atmospherics/components/trinary/mixer/ui_data() /obj/machinery/atmospherics/components/trinary/mixer/ui_data()

View File

@@ -320,11 +320,13 @@
return return
return ..() return ..()
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/unary/cryo_cell/ui_state(mob/user)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) return GLOB.notcontained_state
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "Cryo", name, 400, 550, master_ui, state) ui = new(user, src, "Cryo", name)
ui.open() ui.open()
/obj/machinery/atmospherics/components/unary/cryo_cell/ui_data() /obj/machinery/atmospherics/components/unary/cryo_cell/ui_data()

View File

@@ -20,9 +20,6 @@
pipe_state = "injector" pipe_state = "injector"
ui_x = 310
ui_y = 115
/obj/machinery/atmospherics/components/unary/outlet_injector/CtrlClick(mob/user) /obj/machinery/atmospherics/components/unary/outlet_injector/CtrlClick(mob/user)
if(can_interact(user)) if(can_interact(user))
on = !on on = !on
@@ -132,7 +129,7 @@
on = !on on = !on
if("inject" in signal.data) if("inject" in signal.data)
spawn inject() INVOKE_ASYNC(src, .proc/inject)
return return
if("set_volume_rate" in signal.data) if("set_volume_rate" in signal.data)
@@ -140,22 +137,16 @@
var/datum/gas_mixture/air_contents = airs[1] var/datum/gas_mixture/air_contents = airs[1]
volume_rate = clamp(number, 0, air_contents.return_volume()) volume_rate = clamp(number, 0, air_contents.return_volume())
if("status" in signal.data) addtimer(CALLBACK(src, .proc/broadcast_status), 2)
spawn(2)
broadcast_status()
return //do not update_icon
spawn(2)
broadcast_status()
if(!("status" in signal.data)) //do not update_icon
update_icon() update_icon()
/obj/machinery/atmospherics/components/unary/outlet_injector/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/unary/outlet_injector/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "AtmosPump", name)
ui.open() ui.open()
/obj/machinery/atmospherics/components/unary/outlet_injector/ui_data() /obj/machinery/atmospherics/components/unary/outlet_injector/ui_data()

View File

@@ -11,8 +11,6 @@
layer = OBJ_LAYER layer = OBJ_LAYER
plane = GAME_PLANE plane = GAME_PLANE
circuit = /obj/item/circuitboard/machine/thermomachine circuit = /obj/item/circuitboard/machine/thermomachine
ui_x = 300
ui_y = 230
pipe_flags = PIPING_ONE_PER_TURF pipe_flags = PIPING_ONE_PER_TURF
@@ -125,11 +123,10 @@
return ..() return ..()
return UI_CLOSE return UI_CLOSE
/obj/machinery/atmospherics/components/unary/thermomachine/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/atmospherics/components/unary/thermomachine/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "ThermoMachine", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "ThermoMachine", name)
ui.open() ui.open()
/obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user) /obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user)

View File

@@ -5,8 +5,6 @@
desc = "A canister for the storage of gas." desc = "A canister for the storage of gas."
icon_state = "yellow" icon_state = "yellow"
density = TRUE density = TRUE
ui_x = 300
ui_y = 232
var/valve_open = FALSE var/valve_open = FALSE
var/obj/machinery/atmospherics/components/binary/passive_gate/pump var/obj/machinery/atmospherics/components/binary/passive_gate/pump
@@ -319,11 +317,13 @@ obj/machinery/portable_atmospherics/canister/welder_act(mob/living/user, obj/ite
air_update_turf() // Update the environment if needed. air_update_turf() // Update the environment if needed.
update_icon() update_icon()
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/portable_atmospherics/canister/ui_state(mob/user)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) return GLOB.physical_state
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
/obj/machinery/portable_atmospherics/canister/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "Canister", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "Canister", name)
ui.open() ui.open()
/obj/machinery/portable_atmospherics/canister/ui_data() /obj/machinery/portable_atmospherics/canister/ui_data()

View File

@@ -8,8 +8,6 @@
name = "portable air pump" name = "portable air pump"
icon_state = "psiphon:0" icon_state = "psiphon:0"
density = TRUE density = TRUE
ui_x = 300
ui_y = 315
var/on = FALSE var/on = FALSE
var/direction = PUMP_OUT var/direction = PUMP_OUT
@@ -83,11 +81,10 @@
investigate_log("[key_name(user)] started a transfer into [holding].", INVESTIGATE_ATMOS) investigate_log("[key_name(user)] started a transfer into [holding].", INVESTIGATE_ATMOS)
/obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/portable_atmospherics/pump/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "PortablePump", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "PortablePump", name)
ui.open() ui.open()
/obj/machinery/portable_atmospherics/pump/ui_data() /obj/machinery/portable_atmospherics/pump/ui_data()

View File

@@ -62,11 +62,10 @@
on = !on on = !on
update_icon() update_icon()
/obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/portable_atmospherics/scrubber/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "PortableScrubber", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "PortableScrubber", name)
ui.open() ui.open()
/obj/machinery/portable_atmospherics/scrubber/ui_data() /obj/machinery/portable_atmospherics/scrubber/ui_data()

View File

@@ -277,11 +277,10 @@ GLOBAL_LIST_EMPTY(gateway_destinations)
. = ..() . = ..()
try_to_linkup() try_to_linkup()
/obj/machinery/computer/gateway_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state) /obj/machinery/computer/gateway_control/ui_interact(mob/user, datum/tgui/ui)
. = ..() ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "Gateway", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "Gateway", name)
ui.open() ui.open()
/obj/machinery/computer/gateway_control/ui_data(mob/user) /obj/machinery/computer/gateway_control/ui_data(mob/user)

View File

@@ -1,18 +1,18 @@
#define PRINTER_TIMEOUT 10 #define PRINTER_TIMEOUT 10
/obj/machinery/computer/bounty /obj/machinery/computer/bounty
name = "Nanotrasen bounty console" name = "\improper Nanotrasen bounty console"
desc = "Used to check and claim bounties offered by Nanotrasen" desc = "Used to check and claim bounties offered by Nanotrasen"
icon_screen = "bounty" icon_screen = "bounty"
circuit = /obj/item/circuitboard/computer/bounty circuit = /obj/item/circuitboard/computer/bounty
light_color = "#E2853D"//orange light_color = "#E2853D"//orange
var/printer_ready = 0 //cooldown var var/printer_ready = 0 //cooldown var
var/static/datum/bank_account/cargocash
/obj/machinery/computer/bounty/Initialize() /obj/machinery/computer/bounty/Initialize()
. = ..() . = ..()
printer_ready = world.time + PRINTER_TIMEOUT printer_ready = world.time + PRINTER_TIMEOUT
cargocash = SSeconomy.get_dep_account(ACCOUNT_CAR)
/obj/machinery/computer/bounty/proc/print_paper() /obj/machinery/computer/bounty/proc/print_paper()
new /obj/item/paper/bounty_printout(loc) new /obj/item/paper/bounty_printout(loc)
@@ -23,6 +23,8 @@
/obj/item/paper/bounty_printout/Initialize() /obj/item/paper/bounty_printout/Initialize()
. = ..() . = ..()
info = "<h2>Nanotrasen Cargo Bounties</h2></br>" info = "<h2>Nanotrasen Cargo Bounties</h2></br>"
update_icon()
for(var/datum/bounty/B in GLOB.bounties_list) for(var/datum/bounty/B in GLOB.bounties_list)
if(B.claimed) if(B.claimed)
continue continue
@@ -30,63 +32,34 @@
<ul><li>Reward: [B.reward_string()]</li> <ul><li>Reward: [B.reward_string()]</li>
<li>Completed: [B.completion_string()]</li></ul>"} <li>Completed: [B.completion_string()]</li></ul>"}
/obj/machinery/computer/bounty/ui_interact(mob/user) /obj/machinery/computer/bounty/ui_interact(mob/user, datum/tgui/ui)
. = ..()
if(!GLOB.bounties_list.len) if(!GLOB.bounties_list.len)
setup_bounties() setup_bounties()
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR) ui = SStgui.try_update_ui(user, src, ui)
var/list/dat = list({"<a href='?src=[REF(src)];refresh=1'>Refresh</a> if(!ui)
<a href='?src=[REF(src)];refresh=1;choice=Print'>Print Paper</a> ui = new(user, src, "CargoBountyConsole", name)
<p>Credits: <b>[D.account_balance]</b></p> ui.open()
<table style="text-align:center;" border="1" cellspacing="0" width="100%">
<tr><th>Name</th><th>Description</th><th>Reward</th><th>Completion</th><th>Status</th></tr>"})
for(var/datum/bounty/B in GLOB.bounties_list)
if(B.claimed)
dat += "<tr style='background-color:#294675;'>"
else if(B.can_claim())
dat += "<tr style='background-color:#4F7529;'>"
else
dat += "<tr style='background-color:#990000;'>"
if(B.high_priority)
dat += {"<td><b>[B.name]</b></td>
<td><b>High Priority:</b> [B.description]</td>
<td><b>[B.reward_string()]</b></td>"}
else
dat += {"<td>[B.name]</td>
<td>[B.description]</td>
<td>[B.reward_string()]</td>"}
dat += "<td>[B.completion_string()]</td>"
if(B.claimed)
dat += "<td>Claimed</td>"
else if(B.can_claim())
dat += "<td><A href='?src=[REF(src)];refresh=1;choice=Claim;d_rec=[REF(B)]'>Claim</a></td>"
else
dat += "<td>Unclaimed</td>"
dat += "</tr>"
dat += "</table>"
dat = dat.Join()
var/datum/browser/popup = new(user, "bounties", "Nanotrasen Bounties", 700, 600)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
/obj/machinery/computer/bounty/Topic(href, href_list) /obj/machinery/computer/bounty/ui_data(mob/user)
var/list/data = list()
var/list/bountyinfo = list()
for(var/datum/bounty/B in GLOB.bounties_list)
bountyinfo += list(list("name" = B.name, "description" = B.description, "reward_string" = B.reward_string(), "completion_string" = B.completion_string() , "claimed" = B.claimed, "can_claim" = B.can_claim(), "priority" = B.high_priority, "bounty_ref" = REF(B)))
data["stored_cash"] = cargocash.account_balance
data["bountydata"] = bountyinfo
return data
/obj/machinery/computer/bounty/ui_act(action,params)
if(..()) if(..())
return return
switch(action)
switch(href_list["choice"]) if("ClaimBounty")
var/datum/bounty/cashmoney = locate(params["bounty"]) in GLOB.bounties_list
if(cashmoney)
cashmoney.claim()
return TRUE
if("Print") if("Print")
if(printer_ready < world.time) if(printer_ready < world.time)
printer_ready = world.time + PRINTER_TIMEOUT printer_ready = world.time + PRINTER_TIMEOUT
print_paper() print_paper()
return
if("Claim")
var/datum/bounty/B = locate(href_list["d_rec"])
if(B in GLOB.bounties_list)
B.claim()
if(href_list["refresh"])
playsound(src, "terminal_type", 25, 0)
updateUsrDialog()

View File

@@ -11,7 +11,7 @@
/client/proc/centcom_podlauncher() //Creates a verb for admins to open up the ui /client/proc/centcom_podlauncher() //Creates a verb for admins to open up the ui
set name = "Config/Launch Supplypod" set name = "Config/Launch Supplypod"
set desc = "Configure and launch a Centcom supplypod full of whatever your heart desires!" set desc = "Configure and launch a CentCom supplypod full of whatever your heart desires!"
set category = "Admin" set category = "Admin"
var/datum/centcom_podlauncher/plaunch = new(usr)//create the datum var/datum/centcom_podlauncher/plaunch = new(usr)//create the datum
plaunch.ui_interact(usr)//datum has a tgui component, here we open the window plaunch.ui_interact(usr)//datum has a tgui component, here we open the window
@@ -23,7 +23,10 @@
var/turf/oldTurf //Keeps track of where the user was at if they use the "teleport to centcom" button, so they can go back var/turf/oldTurf //Keeps track of where the user was at if they use the "teleport to centcom" button, so they can go back
var/client/holder //client of whoever is using this datum var/client/holder //client of whoever is using this datum
var/area/bay //What bay we're using to launch shit from. var/area/bay //What bay we're using to launch shit from.
var/turf/dropoff_turf //If we're reversing, where the reverse pods go
var/picking_dropoff_turf
var/launchClone = FALSE //If true, then we don't actually launch the thing in the bay. Instead we call duplicateObject() and send the result var/launchClone = FALSE //If true, then we don't actually launch the thing in the bay. Instead we call duplicateObject() and send the result
var/launchRandomItem = FALSE //If true, lauches a single random item instead of everything on a turf.
var/launchChoice = 1 //Determines if we launch all at once (0) , in order (1), or at random(2) var/launchChoice = 1 //Determines if we launch all at once (0) , in order (1), or at random(2)
var/explosionChoice = 0 //Determines if there is no explosion (0), custom explosion (1), or just do a maxcap (2) var/explosionChoice = 0 //Determines if there is no explosion (0), custom explosion (1), or just do a maxcap (2)
var/damageChoice = 0 //Determines if we do no damage (0), custom amnt of damage (1), or gib + 5000dmg (2) var/damageChoice = 0 //Determines if we do no damage (0), custom amnt of damage (1), or gib + 5000dmg (2)
@@ -47,23 +50,28 @@
var/mob/M = H var/mob/M = H
holder = M.client //if its a mob, assign the mob's client to holder holder = M.client //if its a mob, assign the mob's client to holder
bay = locate(/area/centcom/supplypod/loading/one) in GLOB.sortedAreas //Locate the default bay (one) from the centcom map bay = locate(/area/centcom/supplypod/loading/one) in GLOB.sortedAreas //Locate the default bay (one) from the centcom map
temp_pod = new(locate(/area/centcom/supplypod/podStorage) in GLOB.sortedAreas) //Create a new temp_pod in the podStorage area on centcom (so users are free to look at it and change other variables if needed) temp_pod = new(locate(/area/centcom/supplypod/pod_storage) in GLOB.sortedAreas) //Create a new temp_pod in the podStorage area on centcom (so users are free to look at it and change other variables if needed)
orderedArea = createOrderedArea(bay) //Order all the turfs in the selected bay (top left to bottom right) to a single list. Used for the "ordered" mode (launchChoice = 1) orderedArea = createOrderedArea(bay) //Order all the turfs in the selected bay (top left to bottom right) to a single list. Used for the "ordered" mode (launchChoice = 1)
/datum/centcom_podlauncher/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, \ /datum/centcom_podlauncher/ui_state(mob/user)
force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state)//ui_interact is called when the client verb is called. return GLOB.admin_state
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) /datum/centcom_podlauncher/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "CentcomPodLauncher", "Config/Launch Supplypod", 700, 700, master_ui, state) ui = new(user, src, "CentcomPodLauncher")
ui.open() ui.open()
/datum/centcom_podlauncher/ui_data(mob/user) //Sends info about the pod to the UI. /datum/centcom_podlauncher/ui_data(mob/user) //Sends info about the pod to the UI.
var/list/data = list() //*****NOTE*****: Many of these comments are similarly described in supplypod.dm. If you change them here, please consider doing so in the supplypod code as well! var/list/data = list() //*****NOTE*****: Many of these comments are similarly described in supplypod.dm. If you change them here, please consider doing so in the supplypod code as well!
var/B = (istype(bay, /area/centcom/supplypod/loading/one)) ? 1 : (istype(bay, /area/centcom/supplypod/loading/two)) ? 2 : (istype(bay, /area/centcom/supplypod/loading/three)) ? 3 : (istype(bay, /area/centcom/supplypod/loading/four)) ? 4 : 0 //top ten THICCEST FUCKING TERNARY CONDITIONALS OF 2036 var/B = (istype(bay, /area/centcom/supplypod/loading/one)) ? 1 : (istype(bay, /area/centcom/supplypod/loading/two)) ? 2 : (istype(bay, /area/centcom/supplypod/loading/three)) ? 3 : (istype(bay, /area/centcom/supplypod/loading/four)) ? 4 : (istype(bay, /area/centcom/supplypod/loading/ert)) ? 5 : 0 //top ten THICCEST FUCKING TERNARY CONDITIONALS OF 2036
data["bay"] = B //Holds the current bay the user is launching objects from. Bays are specific rooms on the centcom map. data["bay"] = bay //Holds the current bay the user is launching objects from. Bays are specific rooms on the centcom map.
data["bayNumber"] = B //Holds the bay as a number. Useful for comparisons in centcom_podlauncher.ract
data["oldArea"] = (oldTurf ? get_area(oldTurf) : null) //Holds the name of the area that the user was in before using the teleportCentcom action data["oldArea"] = (oldTurf ? get_area(oldTurf) : null) //Holds the name of the area that the user was in before using the teleportCentcom action
data["picking_dropoff_turf"] = picking_dropoff_turf //If we're picking or have picked a dropoff turf. Only works when pod is in reverse mode
data["dropoff_turf"] = dropoff_turf //The turf that reverse pods will drop their newly acquired cargo off at
data["launchClone"] = launchClone //Do we launch the actual items in the bay or just launch clones of them? data["launchClone"] = launchClone //Do we launch the actual items in the bay or just launch clones of them?
data["launchRandomItem"] = launchRandomItem //Do we launch a single random item instead of everything on the turf?
data["launchChoice"] = launchChoice //Launch turfs all at once (0), ordered (1), or randomly(1) data["launchChoice"] = launchChoice //Launch turfs all at once (0), ordered (1), or randomly(1)
data["explosionChoice"] = explosionChoice //An explosion that occurs when landing. Can be no explosion (0), custom explosion (1), or maxcap (2) data["explosionChoice"] = explosionChoice //An explosion that occurs when landing. Can be no explosion (0), custom explosion (1), or maxcap (2)
data["damageChoice"] = damageChoice //Damage that occurs to any mob under the pod when it lands. Can be no damage (0), custom damage (1), or gib+5000dmg (2) data["damageChoice"] = damageChoice //Damage that occurs to any mob under the pod when it lands. Can be no damage (0), custom damage (1), or gib+5000dmg (2)
@@ -72,11 +80,12 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
data["openingDelay"] = temp_pod.openingDelay //How long the pod takes to open after landing data["openingDelay"] = temp_pod.openingDelay //How long the pod takes to open after landing
data["departureDelay"] = temp_pod.departureDelay //How long the pod takes to leave after opening (if bluespace=true, it deletes. if reversing=true, it flies back to centcom) data["departureDelay"] = temp_pod.departureDelay //How long the pod takes to leave after opening (if bluespace=true, it deletes. if reversing=true, it flies back to centcom)
data["styleChoice"] = temp_pod.style //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod. data["styleChoice"] = temp_pod.style //Style is a variable that keeps track of what the pod is supposed to look like. It acts as an index to the POD_STYLES list in cargo.dm defines to get the proper icon/name/desc for the pod.
data["effectShrapnel"] = temp_pod.effectShrapnel //If true, creates a cloud of shrapnel of a decided type and magnitude on landing
data["effectStun"] = temp_pod.effectStun //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish! data["effectStun"] = temp_pod.effectStun //If true, stuns anyone under the pod when it launches until it lands, forcing them to get hit by the pod. Devilish!
data["effectLimb"] = temp_pod.effectLimb //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands data["effectLimb"] = temp_pod.effectLimb //If true, pops off a limb (if applicable) from anyone caught under the pod when it lands
data["effectOrgans"] = temp_pod.effectOrgans //If true, yeets the organs out of any bodies caught under the pod when it lands data["effectOrgans"] = temp_pod.effectOrgans //If true, yeets the organs out of any bodies caught under the pod when it lands
data["effectBluespace"] = temp_pod.bluespace //If true, the pod deletes (in a shower of sparks) after landing data["effectBluespace"] = temp_pod.bluespace //If true, the pod deletes (in a shower of sparks) after landing
data["effectStealth"] = temp_pod.effectStealth //If true, a target icon isnt displayed on the turf where the pod will land data["effectStealth"] = temp_pod.effectStealth //If true, a target icon isn't displayed on the turf where the pod will land
data["effectQuiet"] = temp_pod.effectQuiet //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc) data["effectQuiet"] = temp_pod.effectQuiet //The female sniper. If true, the pod makes no noise (including related explosions, opening sounds, etc)
data["effectMissile"] = temp_pod.effectMissile //If true, the pod deletes the second it lands. If you give it an explosion, it will act like a missile exploding as it hits the ground data["effectMissile"] = temp_pod.effectMissile //If true, the pod deletes the second it lands. If you give it an explosion, it will act like a missile exploding as it hits the ground
data["effectCircle"] = temp_pod.effectCircle //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here data["effectCircle"] = temp_pod.effectCircle //If true, allows the pod to come in at any angle. Bit of a weird feature but whatever its here
@@ -115,20 +124,39 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
bay = locate(/area/centcom/supplypod/loading/four) in GLOB.sortedAreas bay = locate(/area/centcom/supplypod/loading/four) in GLOB.sortedAreas
refreshBay() refreshBay()
. = TRUE . = TRUE
if("bay5")
bay = locate(/area/centcom/supplypod/loading/ert) in GLOB.sortedAreas
refreshBay()
. = TRUE
if("pickDropoffTurf") //Enters a mode that lets you pick the dropoff location for reverse pods
if (picking_dropoff_turf)
picking_dropoff_turf = FALSE
updateCursor(FALSE, FALSE) //Update the cursor of the user to a cool looking target icon
return
if (launcherActivated)
launcherActivated = FALSE //We don't want to have launch mode enabled while we're picking a turf
picking_dropoff_turf = TRUE
updateCursor(FALSE, TRUE) //Update the cursor of the user to a cool looking target icon
. = TRUE
if("clearDropoffTurf")
picking_dropoff_turf = FALSE
dropoff_turf = null
updateCursor(FALSE, FALSE)
. = TRUE
if("teleportCentcom") //Teleports the user to the centcom supply loading facility. if("teleportCentcom") //Teleports the user to the centcom supply loading facility.
var/mob/M = holder.mob //We teleport whatever mob the client is attached to at the point of clicking var/mob/M = holder.mob //We teleport whatever mob the client is attached to at the point of clicking
oldTurf = get_turf(M) //Used for the "teleportBack" action oldTurf = get_turf(M) //Used for the "teleportBack" action
var/area/A = locate(/area/centcom/supplypod/loading) in GLOB.sortedAreas var/area/A = locate(bay) in GLOB.sortedAreas
var/list/turfs = list() var/list/turfs = list()
for(var/turf/T in A) for(var/turf/T in A)
turfs.Add(T) //Fill a list with turfs in the area turfs.Add(T) //Fill a list with turfs in the area
var/turf/T = safepick(turfs) //Only teleport if the list isn't empty if (!length(turfs)) //If the list is empty, error and cancel
if(!T) //If the list is empty, error and cancel
to_chat(M, "Nowhere to jump to!") to_chat(M, "Nowhere to jump to!")
return return //Only teleport if the list isn't empty
var/turf/T = pick(turfs)
M.forceMove(T) //Perform the actual teleport M.forceMove(T) //Perform the actual teleport
log_admin("[key_name(usr)] jumped to [AREACOORD(A)]") log_admin("[key_name(usr)] jumped to [AREACOORD(T)]")
message_admins("[key_name_admin(usr)] jumped to [AREACOORD(A)]") message_admins("[key_name_admin(usr)] jumped to [AREACOORD(T)]")
. = TRUE . = TRUE
if("teleportBack") //After teleporting to centcom, this button allows the user to teleport to the last spot they were at. if("teleportBack") //After teleporting to centcom, this button allows the user to teleport to the last spot they were at.
var/mob/M = holder.mob var/mob/M = holder.mob
@@ -144,6 +172,9 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if("launchClone") //Toggles the launchClone var. See variable declarations above for what this specifically means if("launchClone") //Toggles the launchClone var. See variable declarations above for what this specifically means
launchClone = !launchClone launchClone = !launchClone
. = TRUE . = TRUE
if("launchRandomItem") //Pick random turfs from the supplypod bay at centcom to launch
launchRandomItem = !launchRandomItem
. = TRUE
if("launchOrdered") //Launch turfs (from the orderedArea list) one at a time in order, from the supplypod bay at centcom if("launchOrdered") //Launch turfs (from the orderedArea list) one at a time in order, from the supplypod bay at centcom
if (launchChoice == 1) //launchChoice 1 represents ordered. If we push "ordered" and it already is, then we go to default value if (launchChoice == 1) //launchChoice 1 represents ordered. If we push "ordered" and it already is, then we go to default value
launchChoice = 0 launchChoice = 0
@@ -152,7 +183,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
launchChoice = 1 launchChoice = 1
updateSelector() updateSelector()
. = TRUE . = TRUE
if("launchRandom") //Pick random turfs from the supplypod bay at centcom to launch if("launchRandomTurf") //Pick random turfs from the supplypod bay at centcom to launch
if (launchChoice == 2) if (launchChoice == 2)
launchChoice = 0 launchChoice = 0
updateSelector() updateSelector()
@@ -170,11 +201,11 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
var/list/expNames = list("Devastation", "Heavy Damage", "Light Damage", "Flame") //Explosions have a range of different types of damage var/list/expNames = list("Devastation", "Heavy Damage", "Light Damage", "Flame") //Explosions have a range of different types of damage
var/list/boomInput = list() var/list/boomInput = list()
for (var/i=1 to expNames.len) //Gather input from the user for the value of each type of damage for (var/i=1 to expNames.len) //Gather input from the user for the value of each type of damage
boomInput.Add(input("[expNames[i]] Range", "Enter the [expNames[i]] range of the explosion. WARNING: This ignores the bomb cap!", 0) as null|num) boomInput.Add(input("Enter the [expNames[i]] range of the explosion. WARNING: This ignores the bomb cap!", "[expNames[i]] Range", 0) as null|num)
if (isnull(boomInput[i])) if (isnull(boomInput[i]))
return return
if (!isnum(boomInput[i])) //If the user doesn't input a number, set that specific explosion value to zero if (!isnum(boomInput[i])) //If the user doesn't input a number, set that specific explosion value to zero
alert(usr, "That wasnt a number! Value set to default (zero) instead.") alert(usr, "That wasn't a number! Value set to default (zero) instead.")
boomInput = 0 boomInput = 0
explosionChoice = 1 explosionChoice = 1
temp_pod.explosionSize = boomInput temp_pod.explosionSize = boomInput
@@ -192,11 +223,11 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
damageChoice = 0 damageChoice = 0
temp_pod.damage = 0 temp_pod.damage = 0
return return
var/damageInput = input("How much damage to deal", "Enter the amount of brute damage dealt by getting hit", 0) as null|num var/damageInput = input("Enter the amount of brute damage dealt by getting hit","How much damage to deal", 0) as null|num
if (isnull(damageInput)) if (isnull(damageInput))
return return
if (!isnum(damageInput)) //Sanitize the input for damage to deal.s if (!isnum(damageInput)) //Sanitize the input for damage to deal.s
alert(usr, "That wasnt a number! Value set to default (zero) instead.") alert(usr, "That wasn't a number! Value set to default (zero) instead.")
damageInput = 0 damageInput = 0
damageChoice = 1 damageChoice = 1
temp_pod.damage = damageInput temp_pod.damage = damageInput
@@ -226,13 +257,30 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
temp_pod.desc = descInput temp_pod.desc = descInput
temp_pod.adminNamed = TRUE //This variable is checked in the supplypod/setStyle() proc temp_pod.adminNamed = TRUE //This variable is checked in the supplypod/setStyle() proc
. = TRUE . = TRUE
if("effectShrapnel") //Creates a cloud of shrapnel on landing
if (temp_pod.effectShrapnel == TRUE) //If already doing custom damage, set back to default (no shrapnel)
temp_pod.effectShrapnel = FALSE
return
var/shrapnelInput = input("Please enter the type of pellet cloud you'd like to create on landing (Can be any projectile!)", "Projectile Typepath", 0) in sortList(subtypesof(/obj/projectile), /proc/cmp_typepaths_asc)
if (isnull(shrapnelInput))
return
var/shrapnelMagnitude = input("Enter the magnitude of the pellet cloud. This is usually a value around 1-5. Please note that Ryll-Ryll has asked me to tell you that if you go too crazy with the projectiles you might crash the server. So uh, be gentle!", "Shrapnel Magnitude", 0) as null|num
if (isnull(shrapnelMagnitude))
return
if (!isnum(shrapnelMagnitude))
alert(usr, "That wasn't a number! Value set to 3 instead.")
shrapnelMagnitude = 3
temp_pod.shrapnel_type = shrapnelInput
temp_pod.shrapnel_magnitude = shrapnelMagnitude
temp_pod.effectShrapnel = TRUE
. = TRUE
if("effectStun") //Toggle: Any mob under the pod is stunned (cant move) until the pod lands, hitting them! if("effectStun") //Toggle: Any mob under the pod is stunned (cant move) until the pod lands, hitting them!
temp_pod.effectStun = !temp_pod.effectStun temp_pod.effectStun = !temp_pod.effectStun
. = TRUE . = TRUE
if("effectLimb") //Toggle: Anyone carbon mob under the pod loses a limb when it lands if("effectLimb") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
temp_pod.effectLimb = !temp_pod.effectLimb temp_pod.effectLimb = !temp_pod.effectLimb
. = TRUE . = TRUE
if("effectOrgans") //Toggle: Any carbon mob under the pod loses every limb and organ if("effectOrgans") //Toggle: Anyone carbon mob under the pod loses a limb when it lands
temp_pod.effectOrgans = !temp_pod.effectOrgans temp_pod.effectOrgans = !temp_pod.effectOrgans
. = TRUE . = TRUE
if("effectBluespace") //Toggle: Deletes the pod after landing if("effectBluespace") //Toggle: Deletes the pod after landing
@@ -253,7 +301,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if("effectBurst") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target if("effectBurst") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
effectBurst = !effectBurst effectBurst = !effectBurst
. = TRUE . = TRUE
if("effectAnnounce") //Toggle: Sends a ghost announcement. if("effectAnnounce") //Toggle: Launch 5 pods (with a very slight delay between) in a 3x3 area centered around the target
effectAnnounce = !effectAnnounce effectAnnounce = !effectAnnounce
. = TRUE . = TRUE
if("effectReverse") //Toggle: Don't send any items. Instead, after landing, close (taking any objects inside) and go back to the centcom bay it came from if("effectReverse") //Toggle: Don't send any items. Instead, after landing, close (taking any objects inside) and go back to the centcom bay it came from
@@ -272,15 +320,15 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
. = TRUE . = TRUE
////////////////////////////TIMER DELAYS////////////////// ////////////////////////////TIMER DELAYS//////////////////
if("fallDuration") //Change the falling animation duration if("fallDuration") //Change the time it takes the pod to land, after firing
if (temp_pod.fallDuration != initial(temp_pod.fallDuration)) //If the fall duration has already been changed when we push the "change value" button, then set it to default if (temp_pod.fallDuration != initial(temp_pod.fallDuration)) //If the landing delay has already been changed when we push the "change value" button, then set it to default
temp_pod.fallDuration = initial(temp_pod.fallDuration) temp_pod.fallDuration = initial(temp_pod.fallDuration)
return return
var/timeInput = input("Enter the duration of the pod's falling animation, in seconds", "Delay Time", initial(temp_pod.fallDuration) * 0.1) as null|num var/timeInput = input("Enter the duration of the pod's falling animation, in seconds", "Delay Time", initial(temp_pod.fallDuration) * 0.1) as null|num
if (isnull(timeInput)) if (isnull(timeInput))
return return
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallDuration)*0.1]) instead.") alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.fallDuration)*0.1]) instead.")
timeInput = initial(temp_pod.fallDuration) timeInput = initial(temp_pod.fallDuration)
temp_pod.fallDuration = 10 * timeInput temp_pod.fallDuration = 10 * timeInput
. = TRUE . = TRUE
@@ -292,7 +340,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if (isnull(timeInput)) if (isnull(timeInput))
return return
if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default if (!isnum(timeInput)) //Sanitize input, if it doesnt check out, error and set to default
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.landingDelay)*0.1]) instead.") alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.landingDelay)*0.1]) instead.")
timeInput = initial(temp_pod.landingDelay) timeInput = initial(temp_pod.landingDelay)
temp_pod.landingDelay = 10 * timeInput temp_pod.landingDelay = 10 * timeInput
. = TRUE . = TRUE
@@ -304,7 +352,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if (isnull(timeInput)) if (isnull(timeInput))
return return
if (!isnum(timeInput)) //Sanitize input if (!isnum(timeInput)) //Sanitize input
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.openingDelay)*0.1]) instead.") alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.openingDelay)*0.1]) instead.")
timeInput = initial(temp_pod.openingDelay) timeInput = initial(temp_pod.openingDelay)
temp_pod.openingDelay = 10 * timeInput temp_pod.openingDelay = 10 * timeInput
. = TRUE . = TRUE
@@ -316,13 +364,13 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if (isnull(timeInput)) if (isnull(timeInput))
return return
if (!isnum(timeInput)) if (!isnum(timeInput))
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.departureDelay)*0.1]) instead.") alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.departureDelay)*0.1]) instead.")
timeInput = initial(temp_pod.departureDelay) timeInput = initial(temp_pod.departureDelay)
temp_pod.departureDelay = 10 * timeInput temp_pod.departureDelay = 10 * timeInput
. = TRUE . = TRUE
////////////////////////////ADMIN SOUNDS////////////////// ////////////////////////////ADMIN SOUNDS//////////////////
if("fallingSound") //Admin sound from a local file that plays when the pod falls if("fallSound") //Admin sound from a local file that plays when the pod lands
if ((temp_pod.fallingSound) != initial(temp_pod.fallingSound)) if ((temp_pod.fallingSound) != initial(temp_pod.fallingSound))
temp_pod.fallingSound = initial(temp_pod.fallingSound) temp_pod.fallingSound = initial(temp_pod.fallingSound)
temp_pod.fallingSoundLength = initial(temp_pod.fallingSoundLength) temp_pod.fallingSoundLength = initial(temp_pod.fallingSoundLength)
@@ -334,7 +382,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if (isnull(timeInput)) if (isnull(timeInput))
return return
if (!isnum(timeInput)) if (!isnum(timeInput))
alert(usr, "That wasnt a number! Value set to default ([initial(temp_pod.fallingSoundLength)*0.1]) instead.") alert(usr, "That wasn't a number! Value set to default ([initial(temp_pod.fallingSoundLength)*0.1]) instead.")
temp_pod.fallingSound = soundInput temp_pod.fallingSound = soundInput
temp_pod.fallingSoundLength = 10 * timeInput temp_pod.fallingSoundLength = 10 * timeInput
. = TRUE . = TRUE
@@ -369,7 +417,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if (temp_pod.soundVolume != initial(temp_pod.soundVolume)) if (temp_pod.soundVolume != initial(temp_pod.soundVolume))
temp_pod.soundVolume = initial(temp_pod.soundVolume) temp_pod.soundVolume = initial(temp_pod.soundVolume)
return return
var/soundInput = input(holder, "Please pick a volume. Default is between 1 and 100 with 80 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num var/soundInput = input(holder, "Please pick a volume. Default is between 1 and 100 with 50 being average, but pick whatever. I'm a notification, not a cop. If you still cant hear your sound, consider turning on the Quiet effect. It will silence all pod sounds except for the custom admin ones set by the previous three buttons.", "Pick Admin Sound Volume") as null|num
if (isnull(soundInput)) if (isnull(soundInput))
return return
temp_pod.soundVolume = soundInput temp_pod.soundVolume = soundInput
@@ -421,17 +469,27 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
. = TRUE . = TRUE
if("giveLauncher") //Enters the "Launch Mode". When the launcher is activated, temp_pod is cloned, and the result it filled and launched anywhere the user clicks (unless specificTarget is true) if("giveLauncher") //Enters the "Launch Mode". When the launcher is activated, temp_pod is cloned, and the result it filled and launched anywhere the user clicks (unless specificTarget is true)
launcherActivated = !launcherActivated launcherActivated = !launcherActivated
updateCursor(launcherActivated) //Update the cursor of the user to a cool looking target icon updateCursor(launcherActivated, FALSE) //Update the cursor of the user to a cool looking target icon
. = TRUE
if("clearBay") //Delete all mobs and objs in the selected bay
if(alert(usr, "This will delete all objs and mobs in [bay]. Are you sure?", "Confirmation", "Delete that shit", "No") == "Delete that shit")
clearBay()
refreshBay()
. = TRUE . = TRUE
/datum/centcom_podlauncher/ui_close() //Uses the destroy() proc. When the user closes the UI, we clean up the temp_pod and supplypod_selector variables. /datum/centcom_podlauncher/ui_close() //Uses the destroy() proc. When the user closes the UI, we clean up the temp_pod and supplypod_selector variables.
qdel(src) qdel(src)
/datum/centcom_podlauncher/proc/updateCursor(var/launching) //Update the moues of the user /datum/centcom_podlauncher/proc/updateCursor(var/launching, var/turf_picking) //Update the mouse of the user
if (holder) //Check to see if we have a client if (!holder) //Can't update the mouse icon if the client doesnt exist!
if (launching) //If the launching param is true, we give the user new mouse icons. return
holder.mouse_up_icon = 'icons/effects/supplypod_target.dmi' //Icon for when mouse is released if (launching || turf_picking) //If the launching param is true, we give the user new mouse icons.
holder.mouse_down_icon = 'icons/effects/supplypod_down_target.dmi' //Icon for when mouse is pressed if(launching)
holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_target.dmi' //Icon for when mouse is released
holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_down_target.dmi' //Icon for when mouse is pressed
if(turf_picking)
holder.mouse_up_icon = 'icons/effects/mouse_pointers/supplypod_pickturf.dmi' //Icon for when mouse is released
holder.mouse_down_icon = 'icons/effects/mouse_pointers/supplypod_pickturf_down.dmi' //Icon for when mouse is pressed
holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released) holder.mouse_pointer_icon = holder.mouse_up_icon //Icon for idle mouse (same as icon for when released)
holder.click_intercept = src //Create a click_intercept so we know where the user is clicking holder.click_intercept = src //Create a click_intercept so we know where the user is clicking
else else
@@ -461,7 +519,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
else else
return //if target is null and we don't have a specific target, cancel return //if target is null and we don't have a specific target, cancel
if (effectAnnounce) if (effectAnnounce)
deadchat_broadcast("<span class='deadsay'>A special package is being launched at the station!</span>", turf_target = target) deadchat_broadcast("A special package is being launched at the station!", turf_target = target, message_type=DEADCHAT_ANNOUNCEMENT)
var/list/bouttaDie = list() var/list/bouttaDie = list()
for (var/mob/living/M in target) for (var/mob/living/M in target)
bouttaDie.Add(M) bouttaDie.Add(M)
@@ -479,6 +537,15 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
else else
launch(target) //If we couldn't locate an adjacent turf, just launch at the normal target launch(target) //If we couldn't locate an adjacent turf, just launch at the normal target
sleep(rand()*2) //looks cooler than them all appearing at once. Gives the impression of burst fire. sleep(rand()*2) //looks cooler than them all appearing at once. Gives the impression of burst fire.
else if (picking_dropoff_turf)
//Clicking on UI elements shouldn't pick a dropoff turf
if(istype(target,/obj/screen))
return FALSE
. = TRUE
if(left_click) //When we left click:
dropoff_turf = get_turf(target)
to_chat(user, "<span class = 'notice'> You've selected [dropoff_turf] at [COORD(dropoff_turf)] as your dropoff location.</span>")
/datum/centcom_podlauncher/proc/refreshBay() //Called whenever the bay is switched, as well as wheneber a pod is launched /datum/centcom_podlauncher/proc/refreshBay() //Called whenever the bay is switched, as well as wheneber a pod is launched
orderedArea = createOrderedArea(bay) //Create an ordered list full of turfs form the bay orderedArea = createOrderedArea(bay) //Create an ordered list full of turfs form the bay
@@ -489,7 +556,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
to_chat(holder.mob, "No /area/centcom/supplypod/loading/one (or /two or /three or /four) in the world! You can make one yourself (then refresh) for now, but yell at a mapper to fix this, today!") to_chat(holder.mob, "No /area/centcom/supplypod/loading/one (or /two or /three or /four) in the world! You can make one yourself (then refresh) for now, but yell at a mapper to fix this, today!")
CRASH("No /area/centcom/supplypod/loading/one (or /two or /three or /four) has been mapped into the centcom z-level!") CRASH("No /area/centcom/supplypod/loading/one (or /two or /three or /four) has been mapped into the centcom z-level!")
orderedArea = list() orderedArea = list()
if (!isemptylist(A.contents)) //Go through the area passed into the proc, and figure out the top left and bottom right corners by calculating max and min values if (length(A.contents)) //Go through the area passed into the proc, and figure out the top left and bottom right corners by calculating max and min values
var/startX = A.contents[1].x //Create the four values (we do it off a.contents[1] so they have some sort of arbitrary initial value. They should be overwritten in a few moments) var/startX = A.contents[1].x //Create the four values (we do it off a.contents[1] so they have some sort of arbitrary initial value. They should be overwritten in a few moments)
var/endX = A.contents[1].x var/endX = A.contents[1].x
var/startY = A.contents[1].y var/startY = A.contents[1].y
@@ -512,12 +579,12 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
numTurfs = 0 //Counts the number of turfs that can be launched (remember, supplypods either launch all at once or one turf-worth of items at a time) numTurfs = 0 //Counts the number of turfs that can be launched (remember, supplypods either launch all at once or one turf-worth of items at a time)
acceptableTurfs = list() acceptableTurfs = list()
for (var/turf/T in orderedArea) //Go through the orderedArea list for (var/turf/T in orderedArea) //Go through the orderedArea list
if (typecache_filter_list_reverse(T.contents, ignored_atoms).len != 0) //if there is something in this turf that isnt in the blacklist, we consider this turf "acceptable" and add it to the acceptableTurfs list if (typecache_filter_list_reverse(T.contents, ignored_atoms).len != 0) //if there is something in this turf that isn't in the blacklist, we consider this turf "acceptable" and add it to the acceptableTurfs list
acceptableTurfs.Add(T) //Because orderedArea was an ordered linear list, acceptableTurfs will be as well. acceptableTurfs.Add(T) //Because orderedArea was an ordered linear list, acceptableTurfs will be as well.
numTurfs ++ numTurfs ++
launchList = list() //Anything in launchList will go into the supplypod when it is launched launchList = list() //Anything in launchList will go into the supplypod when it is launched
if (!isemptylist(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We dont fill the supplypod if acceptableTurfs is empty, if the pod is going in reverse (effectReverse=true), or if the pod is acitng like a missile (effectMissile=true) if (length(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We dont fill the supplypod if acceptableTurfs is empty, if the pod is going in reverse (effectReverse=true), or if the pod is acitng like a missile (effectMissile=true)
switch(launchChoice) switch(launchChoice)
if(0) //If we are launching all the turfs at once if(0) //If we are launching all the turfs at once
for (var/turf/T in acceptableTurfs) for (var/turf/T in acceptableTurfs)
@@ -536,22 +603,34 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
if (isnull(A)) if (isnull(A))
return return
var/obj/structure/closet/supplypod/centcompod/toLaunch = DuplicateObject(temp_pod) //Duplicate the temp_pod (which we have been varediting or configuring with the UI) and store the result var/obj/structure/closet/supplypod/centcompod/toLaunch = DuplicateObject(temp_pod) //Duplicate the temp_pod (which we have been varediting or configuring with the UI) and store the result
toLaunch.bay = bay //Bay is currently a nonstatic expression, so it cant go into toLaunch using DuplicateObject if(dropoff_turf)
toLaunch.reverse_dropoff_turf = dropoff_turf
else
toLaunch.reverse_dropoff_turf = bay //Bay is currently a nonstatic expression, so it cant go into toLaunch using DuplicateObject
toLaunch.update_icon()//we update_icon() here so that the door doesnt "flicker on" right after it lands toLaunch.update_icon()//we update_icon() here so that the door doesnt "flicker on" right after it lands
var/shippingLane = GLOB.areas_by_type[/area/centcom/supplypod/fly_me_to_the_moon]
toLaunch.forceMove(shippingLane)
if (launchClone) //We arent launching the actual items from the bay, rather we are creating clones and launching those if (launchClone) //We arent launching the actual items from the bay, rather we are creating clones and launching those
if(launchRandomItem)
var/atom/movable/O = pick_n_take(launchList)
DuplicateObject(O).forceMove(toLaunch) //Duplicate a single atom/movable from launchList and forceMove it into the supplypod
else
for (var/atom/movable/O in launchList) for (var/atom/movable/O in launchList)
DuplicateObject(O).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod DuplicateObject(O).forceMove(toLaunch) //Duplicate each atom/movable in launchList and forceMove them into the supplypod
new /obj/effect/abstract/DPtarget(A, toLaunch) //Create the DPTarget, which will eventually forceMove the temp_pod to it's location else
if(launchRandomItem)
var/atom/movable/O = pick_n_take(launchList)
O.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
else else
for (var/atom/movable/O in launchList) //If we aren't cloning the objects, just go through the launchList for (var/atom/movable/O in launchList) //If we aren't cloning the objects, just go through the launchList
O.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod O.forceMove(toLaunch) //and forceMove any atom/moveable into the supplypod
new /obj/effect/abstract/DPtarget(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location new /obj/effect/pod_landingzone(A, toLaunch) //Then, create the DPTarget effect, which will eventually forceMove the temp_pod to it's location
if (launchClone) if (launchClone)
launchCounter++ //We only need to increment launchCounter if we are cloning objects. launchCounter++ //We only need to increment launchCounter if we are cloning objects.
//If we aren't cloning objects, taking and removing the first item each time from the acceptableTurfs list will inherently iterate through the list in order //If we aren't cloning objects, taking and removing the first item each time from the acceptableTurfs list will inherently iterate through the list in order
/datum/centcom_podlauncher/proc/updateSelector() //Ensures that the selector effect will showcase the next item if needed /datum/centcom_podlauncher/proc/updateSelector() //Ensures that the selector effect will showcase the next item if needed
if (launchChoice == 1 && !isemptylist(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We only show the selector if we are taking items from the bay if (launchChoice == 1 && length(acceptableTurfs) && !temp_pod.reversing && !temp_pod.effectMissile) //We only show the selector if we are taking items from the bay
var/index = launchCounter + 1 //launchCounter acts as an index to the ordered acceptableTurfs list, so adding one will show the next item in the list var/index = launchCounter + 1 //launchCounter acts as an index to the ordered acceptableTurfs list, so adding one will show the next item in the list
if (index > acceptableTurfs.len) //out of bounds check if (index > acceptableTurfs.len) //out of bounds check
index = 1 index = 1
@@ -559,8 +638,14 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
else else
selector.moveToNullspace() //Otherwise, we move the selector to nullspace until it is needed again selector.moveToNullspace() //Otherwise, we move the selector to nullspace until it is needed again
/datum/centcom_podlauncher/proc/clearBay() //Clear all objs and mobs from the selected bay
for (var/obj/O in bay.GetAllContents())
qdel(O)
for (var/mob/M in bay.GetAllContents())
qdel(M)
/datum/centcom_podlauncher/Destroy() //The Destroy() proc. This is called by ui_close proc, or whenever the user leaves the game /datum/centcom_podlauncher/Destroy() //The Destroy() proc. This is called by ui_close proc, or whenever the user leaves the game
updateCursor(FALSE) //Make sure our moues cursor resets to default. False means we are not in launch mode updateCursor(FALSE, FALSE) //Make sure our moues cursor resets to default. False means we are not in launch mode
qdel(temp_pod) //Delete the temp_pod qdel(temp_pod) //Delete the temp_pod
qdel(selector) //Delete the selector effect qdel(selector) //Delete the selector effect
. = ..() . = ..()
@@ -581,8 +666,8 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm
for (var/X in temp_pod.explosionSize) for (var/X in temp_pod.explosionSize)
explosionString += "[X]|" explosionString += "[X]|"
var/msg = "launched [podString][whomString].[delayString][damageString][explosionString]]" var/msg = "launched [podString] towards [whomString] [delayString][damageString][explosionString]"
message_admins("[key_name_admin(usr)] [msg] in [AREACOORD(specificTarget)].") message_admins("[key_name_admin(usr)] [msg] in [ADMIN_VERBOSEJMP(specificTarget)].")
if (!isemptylist(whoDyin)) if (length(whoDyin))
for (var/mob/living/M in whoDyin) for (var/mob/living/M in whoDyin)
admin_ticket_log(M, "[key_name_admin(usr)] [msg]") admin_ticket_log(M, "[key_name_admin(usr)] [msg]")

View File

@@ -3,9 +3,6 @@
desc = "Used to order supplies, approve requests, and control the shuttle." desc = "Used to order supplies, approve requests, and control the shuttle."
icon_screen = "supply" icon_screen = "supply"
circuit = /obj/item/circuitboard/computer/cargo circuit = /obj/item/circuitboard/computer/cargo
req_access = list(ACCESS_CARGO)
ui_x = 780
ui_y = 750
var/requestonly = FALSE var/requestonly = FALSE
var/contraband = FALSE var/contraband = FALSE
@@ -27,7 +24,6 @@
desc = "Used to request supplies from cargo." desc = "Used to request supplies from cargo."
icon_screen = "request" icon_screen = "request"
circuit = /obj/item/circuitboard/computer/cargo/request circuit = /obj/item/circuitboard/computer/cargo/request
req_access = list()
requestonly = TRUE requestonly = TRUE
/obj/machinery/computer/cargo/Initialize() /obj/machinery/computer/cargo/Initialize()
@@ -66,15 +62,12 @@
var/obj/item/circuitboard/computer/cargo/board = circuit var/obj/item/circuitboard/computer/cargo/board = circuit
board.contraband = TRUE board.contraband = TRUE
board.obj_flags |= EMAGGED board.obj_flags |= EMAGGED
req_access = list()
update_static_data(user) update_static_data(user)
return ..()
/obj/machinery/computer/cargo/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/computer/cargo/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "Cargo", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "Cargo", name)
ui.open() ui.open()
/obj/machinery/computer/cargo/ui_data() /obj/machinery/computer/cargo/ui_data()
@@ -120,7 +113,6 @@
var/list/data = list() var/list/data = list()
data["requestonly"] = requestonly data["requestonly"] = requestonly
data["supplies"] = list() data["supplies"] = list()
data["emagged"] = obj_flags & EMAGGED
for(var/pack in SSshuttle.supply_packs) for(var/pack in SSshuttle.supply_packs)
var/datum/supply_pack/P = SSshuttle.supply_packs[pack] var/datum/supply_pack/P = SSshuttle.supply_packs[pack]
if(!data["supplies"][P.group]) if(!data["supplies"][P.group])
@@ -135,8 +127,8 @@
"cost" = P.cost, "cost" = P.cost,
"id" = pack, "id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name. "desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"goody" = P.goody,
"private_goody" = P.goody == PACK_GOODY_PRIVATE, "private_goody" = P.goody == PACK_GOODY_PRIVATE,
"goody" = P.goody == PACK_GOODY_PUBLIC,
"access" = P.access, "access" = P.access,
"can_private_buy" = P.can_private_buy "can_private_buy" = P.can_private_buy
)) ))
@@ -145,9 +137,6 @@
/obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui) /obj/machinery/computer/cargo/ui_act(action, params, datum/tgui/ui)
if(..()) if(..())
return return
if(!allowed(usr))
to_chat(usr, "<span class='notice'>Access denied.</span>")
return
switch(action) switch(action)
if("send") if("send")
if(!SSshuttle.supply.canMove()) if(!SSshuttle.supply.canMove())
@@ -179,6 +168,8 @@
else else
SSshuttle.shuttle_loan.loan_shuttle() SSshuttle.shuttle_loan.loan_shuttle()
say("The supply shuttle has been loaned to CentCom.") say("The supply shuttle has been loaned to CentCom.")
investigate_log("[key_name(usr)] accepted a shuttle loan event.", INVESTIGATE_CARGO)
log_game("[key_name(usr)] accepted a shuttle loan event.")
. = TRUE . = TRUE
if("add") if("add")
var/id = text2path(params["id"]) var/id = text2path(params["id"])
@@ -200,13 +191,15 @@
rank = "Silicon" rank = "Silicon"
var/datum/bank_account/account var/datum/bank_account/account
if(self_paid) if(self_paid && ishuman(usr))
if(!pack.can_private_buy && !(obj_flags & EMAGGED)) var/mob/living/carbon/human/H = usr
return var/obj/item/card/id/id_card = H.get_idcard(TRUE)
var/obj/item/card/id/id_card = usr.get_idcard(TRUE)
if(!istype(id_card)) if(!istype(id_card))
say("No ID card detected.") say("No ID card detected.")
return return
if(istype(id_card, /obj/item/card/id/departmental_budget))
say("The [src] rejects [id_card].")
return
account = id_card.registered_account account = id_card.registered_account
if(!istype(account)) if(!istype(account))
say("Invalid bank account.") say("Invalid bank account.")
@@ -218,9 +211,9 @@
if(isnull(reason) || ..()) if(isnull(reason) || ..())
return return
if(pack.goody == PACK_GOODY_PRIVATE && !self_paid) if(pack.goody && !self_paid)
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE) playsound(src, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
say("ERROR: Private small crates may only be purchased by private accounts.") say("ERROR: Small crates may only be purchased by private accounts.")
return return
var/obj/item/coupon/applied_coupon var/obj/item/coupon/applied_coupon
@@ -241,6 +234,9 @@
SSshuttle.shoppinglist += SO SSshuttle.shoppinglist += SO
if(self_paid) if(self_paid)
say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.") say("Order processed. The price will be charged to [account.account_holder]'s bank account on delivery.")
if(requestonly && message_cooldown < world.time)
radio.talk_into(src, "A new order has been requested.", RADIO_CHANNEL_SUPPLY)
message_cooldown = world.time + 30 SECONDS
. = TRUE . = TRUE
if("remove") if("remove")
var/id = text2num(params["id"]) var/id = text2num(params["id"])

View File

@@ -1,5 +1,5 @@
#define MAX_EMAG_ROCKETS 8 #define MAX_EMAG_ROCKETS 8
#define BEACON_COST 5000 #define BEACON_COST 500
#define SP_LINKED 1 #define SP_LINKED 1
#define SP_READY 2 #define SP_READY 2
#define SP_LAUNCH 3 #define SP_LAUNCH 3
@@ -13,10 +13,9 @@
All sales are near instantaneous - please choose carefully" All sales are near instantaneous - please choose carefully"
icon_screen = "supply_express" icon_screen = "supply_express"
circuit = /obj/item/circuitboard/computer/cargo/express circuit = /obj/item/circuitboard/computer/cargo/express
ui_x = 600
ui_y = 700
blockade_warning = "Bluespace instability detected. Delivery impossible." blockade_warning = "Bluespace instability detected. Delivery impossible."
req_access = list(ACCESS_QM) req_access = list(ACCESS_QM)
var/message var/message
var/printed_beacons = 0 //number of beacons printed. Used to determine beacon names. var/printed_beacons = 0 //number of beacons printed. Used to determine beacon names.
var/list/meme_pack_data var/list/meme_pack_data
@@ -42,7 +41,7 @@
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the interface.</span>") to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] the interface.</span>")
return return
else if(istype(W, /obj/item/disk/cargo/bluespace_pod)) else if(istype(W, /obj/item/disk/cargo/bluespace_pod))
podType = /obj/structure/closet/supplypod/bluespacepod podType = /obj/structure/closet/supplypod/bluespacepod //doesnt effect circuit board, making reversal possible
to_chat(user, "<span class='notice'>You insert the disk into [src], allowing for advanced supply delivery vehicles.</span>") to_chat(user, "<span class='notice'>You insert the disk into [src], allowing for advanced supply delivery vehicles.</span>")
qdel(W) qdel(W)
return TRUE return TRUE
@@ -52,13 +51,13 @@
sb.link_console(src, user) sb.link_console(src, user)
return TRUE return TRUE
else else
to_chat(user, "<span class='notice'>[src] is already linked to [sb].</span>") to_chat(user, "<span class='alert'>[src] is already linked to [sb].</span>")
..() ..()
/obj/machinery/computer/cargo/express/emag_act(mob/living/user) /obj/machinery/computer/cargo/express/emag_act(mob/living/user)
. = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
if(obj_flags & EMAGGED) if(obj_flags & EMAGGED)
return return
if(user)
user.visible_message("<span class='warning'>[user] swipes a suspicious card through [src]!</span>", user.visible_message("<span class='warning'>[user] swipes a suspicious card through [src]!</span>",
"<span class='notice'>You change the routing protocols, allowing the Supply Pod to land anywhere on the station.</span>") "<span class='notice'>You change the routing protocols, allowing the Supply Pod to land anywhere on the station.</span>")
obj_flags |= EMAGGED obj_flags |= EMAGGED
@@ -66,8 +65,6 @@
var/obj/item/circuitboard/computer/cargo/board = circuit var/obj/item/circuitboard/computer/cargo/board = circuit
board.obj_flags |= EMAGGED board.obj_flags |= EMAGGED
packin_up() packin_up()
req_access = list()
return TRUE
/obj/machinery/computer/cargo/express/proc/packin_up() // oh shit, I'm sorry /obj/machinery/computer/cargo/express/proc/packin_up() // oh shit, I'm sorry
meme_pack_data = list() // sorry for what? meme_pack_data = list() // sorry for what?
@@ -89,10 +86,10 @@
"desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name. "desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name.
)) ))
/obj/machinery/computer/cargo/express/ui_interact(mob/living/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state. /obj/machinery/computer/cargo/express/ui_interact(mob/living/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "CargoExpress", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "CargoExpress", name)
ui.open() ui.open()
/obj/machinery/computer/cargo/express/ui_data(mob/user) /obj/machinery/computer/cargo/express/ui_data(mob/user)
@@ -102,7 +99,7 @@
if(D) if(D)
data["points"] = D.account_balance data["points"] = D.account_balance
data["locked"] = locked//swipe an ID to unlock data["locked"] = locked//swipe an ID to unlock
data["siliconUser"] = hasSiliconAccessInArea(user) data["siliconUser"] = user.has_unlimited_silicon_privilege
data["beaconzone"] = beacon ? get_area(beacon) : ""//where is the beacon located? outputs in the tgui data["beaconzone"] = beacon ? get_area(beacon) : ""//where is the beacon located? outputs in the tgui
data["usingBeacon"] = usingBeacon //is the mode set to deliver to the beacon or the cargobay? data["usingBeacon"] = usingBeacon //is the mode set to deliver to the beacon or the cargobay?
data["canBeacon"] = !usingBeacon || canBeacon //is the mode set to beacon delivery, and is the beacon in a valid location? data["canBeacon"] = !usingBeacon || canBeacon //is the mode set to beacon delivery, and is the beacon in a valid location?
@@ -131,9 +128,6 @@
return data return data
/obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui) /obj/machinery/computer/cargo/express/ui_act(action, params, datum/tgui/ui)
if(!allowed(usr))
to_chat(usr, "<span class='notice'>Access denied.</span>")
return
switch(action) switch(action)
if("LZCargo") if("LZCargo")
usingBeacon = FALSE usingBeacon = FALSE
@@ -153,6 +147,7 @@
printed_beacons++//printed_beacons starts at 0, so the first one out will be called beacon # 1 printed_beacons++//printed_beacons starts at 0, so the first one out will be called beacon # 1
beacon.name = "Supply Pod Beacon #[printed_beacons]" beacon.name = "Supply Pod Beacon #[printed_beacons]"
if("add")//Generate Supply Order first if("add")//Generate Supply Order first
var/id = text2path(params["id"]) var/id = text2path(params["id"])
var/datum/supply_pack/pack = SSshuttle.supply_packs[id] var/datum/supply_pack/pack = SSshuttle.supply_packs[id]
@@ -195,7 +190,6 @@
LZ = pick(empty_turfs) LZ = pick(empty_turfs)
if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
D.adjust_money(-SO.pack.cost) D.adjust_money(-SO.pack.cost)
SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]"))
new /obj/effect/abstract/DPtarget(LZ, podType, SO) new /obj/effect/abstract/DPtarget(LZ, podType, SO)
. = TRUE . = TRUE
update_icon() update_icon()
@@ -209,7 +203,7 @@
CHECK_TICK CHECK_TICK
if(empty_turfs && empty_turfs.len) if(empty_turfs && empty_turfs.len)
D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS))) D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS)))
SSblackbox.record_feedback("nested tally", "cargo_imports", MAX_EMAG_ROCKETS, list("[SO.pack.cost * 0.72]", "[SO.pack.name]"))
SO.generateRequisition(get_turf(src)) SO.generateRequisition(get_turf(src))
for(var/i in 1 to MAX_EMAG_ROCKETS) for(var/i in 1 to MAX_EMAG_ROCKETS)
var/LZ = pick(empty_turfs) var/LZ = pick(empty_turfs)

View File

@@ -312,11 +312,10 @@
else else
pad = locate() in range(4,src) pad = locate() in range(4,src)
/obj/machinery/computer/piratepad_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \ /obj/machinery/computer/piratepad_control/ui_interact(mob/user, datum/tgui/ui)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "CargoHoldTerminal", name, ui_x, ui_y, master_ui, state) ui = new(user, src, "CargoHoldTerminal", name)
ui.open() ui.open()
/obj/machinery/computer/piratepad_control/ui_data(mob/user) /obj/machinery/computer/piratepad_control/ui_data(mob/user)

View File

@@ -12,6 +12,7 @@
idle_power_usage = 5 idle_power_usage = 5
active_power_usage = 100 active_power_usage = 100
circuit = /obj/item/circuitboard/machine/smartfridge circuit = /obj/item/circuitboard/machine/smartfridge
var/max_n_of_items = 1500 var/max_n_of_items = 1500
var/allow_ai_retrieve = FALSE var/allow_ai_retrieve = FALSE
var/list/initial_contents var/list/initial_contents
@@ -38,12 +39,10 @@
if(in_range(user, src) || isobserver(user)) if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: This unit can hold a maximum of <b>[max_n_of_items]</b> items.</span>" . += "<span class='notice'>The status display reads: This unit can hold a maximum of <b>[max_n_of_items]</b> items.</span>"
/obj/machinery/smartfridge/power_change()
..()
update_icon()
/obj/machinery/smartfridge/update_icon_state() /obj/machinery/smartfridge/update_icon_state()
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
if(!stat) if(!stat)
SSvis_overlays.add_vis_overlay(src, icon, "smartfridge-light-mask", EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha)
if(visible_contents) if(visible_contents)
switch(contents.len) switch(contents.len)
if(0) if(0)
@@ -66,9 +65,6 @@
********************/ ********************/
/obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params) /obj/machinery/smartfridge/attackby(obj/item/O, mob/user, params)
if(user.a_intent == INTENT_HARM)
return ..()
if(default_deconstruction_screwdriver(user, icon_state, icon_state, O)) if(default_deconstruction_screwdriver(user, icon_state, icon_state, O))
cut_overlays() cut_overlays()
if(panel_open) if(panel_open)
@@ -87,9 +83,7 @@
updateUsrDialog() updateUsrDialog()
return return
if(stat) if(!stat)
updateUsrDialog()
return FALSE
if(contents.len >= max_n_of_items) if(contents.len >= max_n_of_items)
to_chat(user, "<span class='warning'>\The [src] is full!</span>") to_chat(user, "<span class='warning'>\The [src] is full!</span>")
@@ -97,7 +91,7 @@
if(accept_check(O)) if(accept_check(O))
load(O) load(O)
user.visible_message("[user] has added \the [O] to \the [src].", "<span class='notice'>You add \the [O] to \the [src].</span>") user.visible_message("<span class='notice'>[user] adds \the [O] to \the [src].</span>", "<span class='notice'>You add \the [O] to \the [src].</span>")
updateUsrDialog() updateUsrDialog()
if (visible_contents) if (visible_contents)
update_icon() update_icon()
@@ -115,18 +109,27 @@
updateUsrDialog() updateUsrDialog()
if(loaded) if(loaded)
user.visible_message("[user] loads \the [src] with \the [O].", \ if(contents.len >= max_n_of_items)
"<span class='notice'>You [contents.len >= max_n_of_items ? "fill" : "load"] \the [src] with \the [O].</span>") user.visible_message("<span class='notice'>[user] loads \the [src] with \the [O].</span>", \
"<span class='notice'>You fill \the [src] with \the [O].</span>")
else
user.visible_message("<span class='notice'>[user] loads \the [src] with \the [O].</span>", \
"<span class='notice'>You load \the [src] with \the [O].</span>")
if(O.contents.len > 0) if(O.contents.len > 0)
to_chat(user, "<span class='warning'>Some items are refused.</span>") to_chat(user, "<span class='warning'>Some items are refused.</span>")
if (visible_contents)
update_icon()
return TRUE return TRUE
else else
to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>") to_chat(user, "<span class='warning'>There is nothing in [O] to put in [src]!</span>")
return FALSE return FALSE
if(user.a_intent != INTENT_HARM)
to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>") to_chat(user, "<span class='warning'>\The [src] smartly refuses [O].</span>")
updateUsrDialog() updateUsrDialog()
return FALSE return FALSE
else
return ..()
@@ -151,16 +154,16 @@
return TRUE return TRUE
///Really simple proc, just moves the object "O" into the hands of mob "M" if able, done so I could modify the proc a little for the organ fridge ///Really simple proc, just moves the object "O" into the hands of mob "M" if able, done so I could modify the proc a little for the organ fridge
/obj/machinery/smartfridge/proc/dispense(obj/item/O, var/mob/M) /obj/machinery/smartfridge/proc/dispense(obj/item/O, mob/M)
if(!M.put_in_hands(O)) if(!M.put_in_hands(O))
O.forceMove(drop_location()) O.forceMove(drop_location())
adjust_item_drop_location(O) adjust_item_drop_location(O)
/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) /obj/machinery/smartfridge/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "SmartVend", name, 440, 550, master_ui, state) ui = new(user, src, "SmartVend", name)
ui.set_autoupdate(FALSE) ui.set_autoupdate(FALSE)
ui.open() ui.open()
@@ -232,7 +235,7 @@
// ---------------------------- // ----------------------------
/obj/machinery/smartfridge/drying_rack /obj/machinery/smartfridge/drying_rack
name = "drying rack" name = "drying rack"
desc = "A wooden contraption, used to dry plant products, food and leather." desc = "A wooden contraption, used to dry plant products, food and hide."
icon = 'icons/obj/hydroponics/equipment.dmi' icon = 'icons/obj/hydroponics/equipment.dmi'
icon_state = "drying_rack" icon_state = "drying_rack"
use_power = IDLE_POWER_USE use_power = IDLE_POWER_USE
@@ -277,6 +280,11 @@
return TRUE return TRUE
return FALSE return FALSE
// /obj/machinery/smartfridge/drying_rack/powered() do we have this? no.
// if(!anchored)
// return FALSE
// return ..()
/obj/machinery/smartfridge/drying_rack/power_change() /obj/machinery/smartfridge/drying_rack/power_change()
if(powered() && anchored) if(powered() && anchored)
stat &= ~NOPOWER stat &= ~NOPOWER
@@ -285,6 +293,10 @@
toggle_drying(TRUE) toggle_drying(TRUE)
update_icon() update_icon()
// . = ..()
// if(!powered())
// toggle_drying(TRUE)
/obj/machinery/smartfridge/drying_rack/load() //For updating the filled overlay /obj/machinery/smartfridge/drying_rack/load() //For updating the filled overlay
..() ..()
update_icon() update_icon()
@@ -308,7 +320,7 @@
var/obj/item/reagent_containers/food/snacks/S = O var/obj/item/reagent_containers/food/snacks/S = O
if(S.dried_type) if(S.dried_type)
return TRUE return TRUE
if(istype(O, /obj/item/stack/sheet/wetleather/)) if(istype(O, /obj/item/stack/sheet/wetleather/)) //no wethide
return TRUE return TRUE
return FALSE return FALSE
@@ -386,19 +398,19 @@
/obj/machinery/smartfridge/extract/preloaded /obj/machinery/smartfridge/extract/preloaded
initial_contents = list(/obj/item/slime_scanner = 2) initial_contents = list(/obj/item/slime_scanner = 2)
// ------------------------- You think you're better than Chem, huh? // -------------------------
// Organ Surgery Smartfridge // Organ Surgery Smartfridge
// ------------------------- Just wait till Tamiorgans // -------------------------
/obj/machinery/smartfridge/organ /obj/machinery/smartfridge/organ
name = "smart organ storage" name = "smart organ storage"
desc = "A refrigerated storage unit for organ storage." desc = "A refrigerated storage unit for organ storage."
max_n_of_items = 25 //vastly lower to prevent processing too long max_n_of_items = 20 //vastly lower to prevent processing too long
var/repair_rate = 0 var/repair_rate = 0
/obj/machinery/smartfridge/organ/accept_check(obj/item/O) /obj/machinery/smartfridge/organ/accept_check(obj/item/O)
if(istype(O, /obj/item/organ)) if(isorgan(O) || isbodypart(O))
return TRUE return TRUE
if(istype(O, /obj/item/reagent_containers/syringe)) if(istype(O, /obj/item/reagent_containers/syringe)) //other medical things.
return TRUE return TRUE
if(istype(O, /obj/item/reagent_containers/glass/bottle)) if(istype(O, /obj/item/reagent_containers/glass/bottle))
return TRUE return TRUE
@@ -410,7 +422,7 @@
. = ..() . = ..()
if(!.) //if the item loads, clear can_decompose if(!.) //if the item loads, clear can_decompose
return return
if(istype(O, /obj/item/organ)) if(isorgan(O))
var/obj/item/organ/organ = O var/obj/item/organ/organ = O
organ.organ_flags |= ORGAN_FROZEN organ.organ_flags |= ORGAN_FROZEN
@@ -426,12 +438,13 @@
return return
O.applyOrganDamage(-repair_rate) O.applyOrganDamage(-repair_rate)
/obj/machinery/smartfridge/organ/Exited(obj/item/organ/AM, atom/newLoc) /obj/machinery/smartfridge/organ/Exited(atom/movable/AM, atom/newLoc)
. = ..() . = ..()
if(istype(AM)) if(isorgan(AM))
AM.organ_flags &= ~ORGAN_FROZEN var/obj/item/organ/O = AM
O.organ_flags &= ~ORGAN_FROZEN
/obj/machinery/smartfridge/organ/preloaded /obj/machinery/smartfridge/organ/preloaded //cit specific??????
initial_contents = list( initial_contents = list(
/obj/item/reagent_containers/medspray/synthtissue = 1, /obj/item/reagent_containers/medspray/synthtissue = 1,
/obj/item/reagent_containers/medspray/sterilizine = 1) /obj/item/reagent_containers/medspray/sterilizine = 1)
@@ -450,6 +463,15 @@
desc = "A refrigerated storage unit for medicine storage." desc = "A refrigerated storage unit for medicine storage."
/obj/machinery/smartfridge/chemistry/accept_check(obj/item/O) /obj/machinery/smartfridge/chemistry/accept_check(obj/item/O)
var/static/list/chemfridge_typecache = typecacheof(list(
/obj/item/reagent_containers/syringe,
/obj/item/reagent_containers/glass/bottle,
/obj/item/reagent_containers/glass/beaker,
/obj/item/reagent_containers/spray,
/obj/item/reagent_containers/medigel,
/obj/item/reagent_containers/chem_pack
))
if(istype(O, /obj/item/storage/pill_bottle)) if(istype(O, /obj/item/storage/pill_bottle))
if(O.contents.len) if(O.contents.len)
for(var/obj/item/I in O) for(var/obj/item/I in O)
@@ -463,7 +485,7 @@
return TRUE return TRUE
if(!O.reagents || !O.reagents.reagent_list.len) // other empty containers not accepted if(!O.reagents || !O.reagents.reagent_list.len) // other empty containers not accepted
return FALSE return FALSE
if(istype(O, /obj/item/reagent_containers/syringe) || istype(O, /obj/item/reagent_containers/glass/bottle) || istype(O, /obj/item/reagent_containers/glass/beaker) || istype(O, /obj/item/reagent_containers/spray) || istype(O, /obj/item/reagent_containers/medspray) || istype(O, /obj/item/reagent_containers/chem_pack)) if(is_type_in_typecache(O, chemfridge_typecache))
return TRUE return TRUE
return FALSE return FALSE
@@ -487,6 +509,7 @@
/obj/item/reagent_containers/glass/bottle/cold = 1, /obj/item/reagent_containers/glass/bottle/cold = 1,
/obj/item/reagent_containers/glass/bottle/flu_virion = 1, /obj/item/reagent_containers/glass/bottle/flu_virion = 1,
/obj/item/reagent_containers/glass/bottle/mutagen = 1, /obj/item/reagent_containers/glass/bottle/mutagen = 1,
/obj/item/reagent_containers/glass/bottle/sugar = 1,
/obj/item/reagent_containers/glass/bottle/plasma = 1, /obj/item/reagent_containers/glass/bottle/plasma = 1,
/obj/item/reagent_containers/glass/bottle/synaptizine = 1, /obj/item/reagent_containers/glass/bottle/synaptizine = 1,
/obj/item/reagent_containers/glass/bottle/formaldehyde = 1) /obj/item/reagent_containers/glass/bottle/formaldehyde = 1)
@@ -498,8 +521,8 @@
name = "disk compartmentalizer" name = "disk compartmentalizer"
desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)." desc = "A machine capable of storing a variety of disks. Denoted by most as the DSU (disk storage unit)."
icon_state = "disktoaster" icon_state = "disktoaster"
visible_contents = FALSE
pass_flags = PASSTABLE pass_flags = PASSTABLE
visible_contents = FALSE
/obj/machinery/smartfridge/disks/accept_check(obj/item/O) /obj/machinery/smartfridge/disks/accept_check(obj/item/O)
if(istype(O, /obj/item/disk/)) if(istype(O, /obj/item/disk/))

View File

@@ -2,10 +2,7 @@
Holodeck Update Holodeck Update
The on-station holodeck area is of type [holodeck_type]. The on-station holodeck area is of type [holodeck_type].
All types found in GLOB.holodeck_areas_per_comp_type[src.type], generated on make_datum_references_lists(), All subtypes of [program_type] are loaded into the program cache or emag programs list.
are loaded into the program cache or emag programs list.
Paths with their abstract_type variable equal to themselves will be skipped.
If init_program is null, a random program will be loaded on startup. If init_program is null, a random program will be loaded on startup.
If you don't wish this, set it to the offline program or another of your choosing. If you don't wish this, set it to the offline program or another of your choosing.
@@ -15,6 +12,7 @@
3) Create a new control console that uses those areas 3) Create a new control console that uses those areas
Non-mapped areas should be skipped but you should probably comment them out anyway. Non-mapped areas should be skipped but you should probably comment them out anyway.
The base of program_type will always be ignored; only subtypes will be loaded.
*/ */
#define HOLODECK_CD 25 #define HOLODECK_CD 25
@@ -26,18 +24,20 @@
icon_screen = "holocontrol" icon_screen = "holocontrol"
idle_power_usage = 10 idle_power_usage = 10
active_power_usage = 50 active_power_usage = 50
var/area/holodeck/linked var/area/holodeck/linked
var/area/holodeck/program var/area/holodeck/program
var/area/holodeck/last_program var/area/holodeck/last_program
var/area/offline_program = /area/holodeck/rec_center/offline var/area/offline_program = /area/holodeck/rec_center/offline
// Splitting this up allows two holodecks of the same size
// to use the same source patterns. Y'know, if you want to.
var/holodeck_type = /area/holodeck/rec_center
var/list/program_cache var/list/program_cache
var/list/emag_programs var/list/emag_programs
// Splitting this up allows two holodecks of the same size
// to use the same source patterns. Y'know, if you want to.
var/holodeck_type = /area/holodeck/rec_center // locate(this) to get the target holodeck
var/program_type = /area/holodeck/rec_center // subtypes of this (but not this itself) are loadable programs
var/active = FALSE var/active = FALSE
var/damaged = FALSE var/damaged = FALSE
var/list/spawned = list() var/list/spawned = list()
@@ -49,41 +49,46 @@
return INITIALIZE_HINT_LATELOAD return INITIALIZE_HINT_LATELOAD
/obj/machinery/computer/holodeck/LateInitialize() /obj/machinery/computer/holodeck/LateInitialize()
linked = SSholodeck.target_holodeck_area[type] if(ispath(holodeck_type, /area))
offline_program = SSholodeck.offline_programs[type] linked = pop(get_areas(holodeck_type, FALSE))
if(ispath(offline_program, /area))
offline_program = pop(get_areas(offline_program), FALSE)
// the following is necessary for power reasons
if(!linked || !offline_program) if(!linked || !offline_program)
log_world("No matching holodeck area found") log_world("No matching holodeck area found")
qdel(src) qdel(src)
return return
var/area/AS = get_area(src)
program_cache = SSholodeck.program_cache[type]
emag_programs = SSholodeck.emag_program_cache[type]
// the following is necessary for power reasons
var/area/AS = get_base_area(src)
if(istype(AS, /area/holodeck)) if(istype(AS, /area/holodeck))
log_mapping("Holodeck computer cannot be in a holodeck, This would cause circular power dependency.") log_mapping("Holodeck computer cannot be in a holodeck, This would cause circular power dependency.")
qdel(src) qdel(src)
return return
else else
linked.linked = src linked.linked = src
var/area/my_area = get_area(src)
if(my_area)
linked.power_usage = my_area.power_usage
else
linked.power_usage = new /list(AREA_USAGE_LEN)
generate_program_list()
load_program(offline_program, FALSE, FALSE) load_program(offline_program, FALSE, FALSE)
/obj/machinery/computer/holodeck/Destroy() /obj/machinery/computer/holodeck/Destroy()
emergency_shutdown() emergency_shutdown()
if(linked) if(linked)
linked.linked = null linked.linked = null
linked.power_usage = new /list(AREA_USAGE_LEN)
return ..() return ..()
/obj/machinery/computer/holodeck/power_change() /obj/machinery/computer/holodeck/power_change()
. = ..() . = ..()
toggle_power(!stat) toggle_power(!stat)
/obj/machinery/computer/holodeck/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) /obj/machinery/computer/holodeck/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) ui = SStgui.try_update_ui(user, src, ui)
if(!ui) if(!ui)
ui = new(user, src, ui_key, "Holodeck", name, 400, 500, master_ui, state) ui = new(user, src, "Holodeck", name)
ui.open() ui.open()
/obj/machinery/computer/holodeck/ui_data(mob/user) /obj/machinery/computer/holodeck/ui_data(mob/user)
@@ -107,19 +112,27 @@
var/program_to_load = text2path(params["type"]) var/program_to_load = text2path(params["type"])
if(!ispath(program_to_load)) if(!ispath(program_to_load))
return FALSE return FALSE
var/valid = FALSE
var/list/checked = program_cache.Copy()
if(obj_flags & EMAGGED)
checked |= emag_programs
for(var/prog in checked)
var/list/P = prog
if(P["type"] == program_to_load)
valid = TRUE
break
if(!valid)
return FALSE
var/area/A = locate(program_to_load) in GLOB.sortedAreas var/area/A = locate(program_to_load) in GLOB.sortedAreas
if(A) if(A)
load_program(A) load_program(A)
if("safety") if("safety")
if(!hasSiliconAccessInArea(usr) && !IsAdminGhost(usr)) if((obj_flags & EMAGGED) && program)
var/msg = "[key_name(usr)] attempted to emag the holodeck using a href they shouldn't have!"
message_admins(msg)
log_admin(msg)
return
obj_flags ^= EMAGGED
if((obj_flags & EMAGGED) && program && emag_programs[program.name])
emergency_shutdown() emergency_shutdown()
nerf(obj_flags & EMAGGED) nerf(obj_flags & EMAGGED)
obj_flags ^= EMAGGED
say("Safeties restored. Restarting...")
/obj/machinery/computer/holodeck/process() /obj/machinery/computer/holodeck/process()
if(damaged && prob(10)) if(damaged && prob(10))
@@ -160,13 +173,12 @@
if(!LAZYLEN(emag_programs)) if(!LAZYLEN(emag_programs))
to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.") to_chat(user, "[src] does not seem to have a card swipe port. It must be an inferior model.")
return return
playsound(src, "sparks", 75, 1) playsound(src, "sparks", 75, TRUE)
obj_flags |= EMAGGED obj_flags |= EMAGGED
to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>") to_chat(user, "<span class='warning'>You vastly increase projector power and override the safety and security protocols.</span>")
to_chat(user, "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.") say("Warning. Automatic shutoff and derezzing protocols have been corrupted. Please call Nanotrasen maintenance and do not use the simulator.")
log_game("[key_name(user)] emagged the Holodeck Control Console") log_game("[key_name(user)] emagged the Holodeck Control Console")
nerf(!(obj_flags & EMAGGED)) nerf(!(obj_flags & EMAGGED))
return TRUE
/obj/machinery/computer/holodeck/emp_act(severity) /obj/machinery/computer/holodeck/emp_act(severity)
. = ..() . = ..()
@@ -182,6 +194,19 @@
emergency_shutdown() emergency_shutdown()
return ..() return ..()
/obj/machinery/computer/holodeck/proc/generate_program_list()
for(var/typekey in subtypesof(program_type))
var/area/holodeck/A = GLOB.areas_by_type[typekey]
if(!A || !A.contents.len)
continue
var/list/info_this = list()
info_this["name"] = A.name
info_this["type"] = A.type
if(A.restricted)
LAZYADD(emag_programs, list(info_this))
else
LAZYADD(program_cache, list(info_this))
/obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE) /obj/machinery/computer/holodeck/proc/toggle_power(toggleOn = FALSE)
if(active == toggleOn) if(active == toggleOn)
return return
@@ -281,7 +306,7 @@
silent = FALSE // otherwise make sure they are dropped silent = FALSE // otherwise make sure they are dropped
if(!silent) if(!silent)
visible_message("[O] fades away!") visible_message("<span class='notice'>[O] fades away!</span>")
qdel(O) qdel(O)
#undef HOLODECK_CD #undef HOLODECK_CD

View File

@@ -10,13 +10,13 @@
var/processing = FALSE var/processing = FALSE
var/obj/item/reagent_containers/glass/beaker = null var/obj/item/reagent_containers/glass/beaker = null
var/points = 0 var/points = 0
var/menustat = "menu"
var/efficiency = 0 var/efficiency = 0
var/productivity = 0 var/productivity = 0
var/max_items = 40 var/max_items = 40
var/datum/techweb/stored_research var/datum/techweb/stored_research
var/list/show_categories = list("Food", "Botany Chemicals", "Organic Materials") var/list/show_categories = list("Food", "Botany Chemicals", "Organic Materials")
var/list/timesFiveCategories = list("Food", "Botany Chemicals") /// Currently selected category in the UI
var/selected_cat
/obj/machinery/biogenerator/Initialize() /obj/machinery/biogenerator/Initialize()
. = ..() . = ..()
@@ -37,22 +37,20 @@
if(A == beaker) if(A == beaker)
beaker = null beaker = null
update_icon() update_icon()
updateUsrDialog()
/obj/machinery/biogenerator/RefreshParts() /obj/machinery/biogenerator/RefreshParts()
var/E = 0.5 var/E = 0
var/P = 0.5 var/P = 0
var/max_storage = 20 var/max_storage = 40
for(var/obj/item/stock_parts/matter_bin/B in component_parts) for(var/obj/item/stock_parts/matter_bin/B in component_parts)
P += B.rating * 0.5 P += B.rating
max_storage = max(20 * B.rating, max_storage) max_storage = 40 * B.rating
for(var/obj/item/stock_parts/manipulator/M in component_parts) for(var/obj/item/stock_parts/manipulator/M in component_parts)
E += M.rating * 0.5 E += M.rating
efficiency = E efficiency = E
productivity = P productivity = P
max_items = max_storage max_items = max_storage
/obj/machinery/biogenerator/examine(mob/user) /obj/machinery/biogenerator/examine(mob/user)
. = ..() . = ..()
if(in_range(user, src) || isobserver(user)) if(in_range(user, src) || isobserver(user))
@@ -70,7 +68,6 @@
icon_state = "biogen-stand" icon_state = "biogen-stand"
else else
icon_state = "biogen-work" icon_state = "biogen-work"
return
/obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params) /obj/machinery/biogenerator/attackby(obj/item/O, mob/user, params)
if(user.a_intent == INTENT_HARM) if(user.a_intent == INTENT_HARM)
@@ -102,7 +99,6 @@
beaker = O beaker = O
to_chat(user, "<span class='notice'>You add the container to the machine.</span>") to_chat(user, "<span class='notice'>You add the container to the machine.</span>")
update_icon() update_icon()
updateUsrDialog()
else else
to_chat(user, "<span class='warning'>Close the maintenance panel first.</span>") to_chat(user, "<span class='warning'>Close the maintenance panel first.</span>")
return return
@@ -139,9 +135,9 @@
to_chat(user, "<span class='info'>You put [O.name] in [src.name]</span>") to_chat(user, "<span class='info'>You put [O.name] in [src.name]</span>")
return TRUE //no afterattack return TRUE //no afterattack
else if (istype(O, /obj/item/disk/design_disk)) else if (istype(O, /obj/item/disk/design_disk))
user.visible_message("[user] begins to load \the [O] in \the [src]...", user.visible_message("<span class='notice'>[user] begins to load \the [O] in \the [src]...</span>",
"You begin to load a design from \the [O]...", "<span class='notice'>You begin to load a design from \the [O]...</span>",
"You hear the chatter of a floppy drive.") "<span class='hear'>You hear the chatter of a floppy drive.</span>")
processing = TRUE processing = TRUE
var/obj/item/disk/design_disk/D = O var/obj/item/disk/design_disk/D = O
if(do_after(user, 10, target = src)) if(do_after(user, 10, target = src))
@@ -153,106 +149,53 @@
else else
to_chat(user, "<span class='warning'>You cannot put this in [src.name]!</span>") to_chat(user, "<span class='warning'>You cannot put this in [src.name]!</span>")
/obj/machinery/biogenerator/ui_interact(mob/user)
if(stat & BROKEN || panel_open)
return
. = ..()
var/dat
if(processing)
dat += "<div class='statusDisplay'>Biogenerator is processing! Please wait...</div><BR>"
else
switch(menustat)
if("nopoints")
dat += "<div class='statusDisplay'>You do not have enough biomass to create products.<BR>Please, put growns into reactor and activate it.</div>"
menustat = "menu"
if("complete")
dat += "<div class='statusDisplay'>Operation complete.</div>"
menustat = "menu"
if("void")
dat += "<div class='statusDisplay'>Error: No growns inside.<BR>Please, put growns into reactor.</div>"
menustat = "menu"
if("nobeakerspace")
dat += "<div class='statusDisplay'>Not enough space left in container. Unable to create product.</div>"
menustat = "menu"
if(beaker)
var/categories = show_categories.Copy()
for(var/V in categories)
categories[V] = list()
for(var/V in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(V)
for(var/C in categories)
if(C in D.category)
categories[C] += D
dat += "<div class='statusDisplay'>Biomass: [points] units.</div><BR>"
dat += "<A href='?src=[REF(src)];activate=1'>Activate</A><A href='?src=[REF(src)];detach=1'>Detach Container</A>"
for(var/cat in categories)
dat += "<h3>[cat]:</h3>"
dat += "<div class='statusDisplay'>"
for(var/V in categories[cat])
var/datum/design/D = V
dat += "[D.name]: <A href='?src=[REF(src)];create=[D.id];amount=1'>Make</A>"
if(cat in timesFiveCategories)
dat += "<A href='?src=[REF(src)];create=[D.id];amount=5'>x5</A>"
if(ispath(D.build_path, /obj/item/stack))
dat += "<A href='?src=[REF(src)];create=[D.id];amount=10'>x10</A>"
dat += "([CEILING(D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency, 1)])<br>"
dat += "</div>"
else
dat += "<div class='statusDisplay'>No container inside, please insert container.</div>"
var/datum/browser/popup = new(user, "biogen", name, 350, 520)
popup.set_content(dat)
popup.open()
/obj/machinery/biogenerator/AltClick(mob/living/user) /obj/machinery/biogenerator/AltClick(mob/living/user)
. = ..() . = ..()
if(istype(user) && user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK)) if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && can_interact(user))
detach(user) detach(user)
/obj/machinery/biogenerator/proc/activate() /**
if (usr.stat != CONSCIOUS) * activate: Activates biomass processing and converts all inserted grown products into biomass
*
* Arguments:
* * user The mob starting the biomass processing
*/
/obj/machinery/biogenerator/proc/activate(mob/user)
if(user.stat != CONSCIOUS)
return return
if (src.stat != NONE) //NOPOWER etc if(stat != NONE)
return return
if(processing) if(processing)
to_chat(usr, "<span class='warning'>The biogenerator is in the process of working.</span>") to_chat(user, "<span class='warning'>The biogenerator is in the process of working.</span>")
return return
var/S = 0 var/S = 0
var/total = 0
for(var/obj/item/reagent_containers/food/snacks/grown/I in contents) for(var/obj/item/reagent_containers/food/snacks/grown/I in contents)
S += 5 S += 5
var/nutri_amount = I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) if(I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) < 0.1)
if(nutri_amount < 0.1) points += 1 * productivity
total += 1*productivity
else else
total += nutri_amount*10*productivity points += I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) * 10 * productivity
qdel(I) qdel(I)
points += round(total)
if(S) if(S)
processing = TRUE processing = TRUE
update_icon() update_icon()
updateUsrDialog() playsound(loc, 'sound/machines/blender.ogg', 50, TRUE)
playsound(src.loc, 'sound/machines/blender.ogg', 50, 1)
use_power(S * 30) use_power(S * 30)
sleep(S + 15 / productivity) sleep(S + 15 / productivity)
if(QDELETED(src)) //let's not.
return
processing = FALSE processing = FALSE
update_icon() update_icon()
else
menustat = "void"
/obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = TRUE) /obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = TRUE)
if(materials.len != 1 || materials[1] != SSmaterials.GetMaterialRef(/datum/material/biomass)) if(materials.len != 1 || materials[1] != SSmaterials.GetMaterialRef(/datum/material/biomass))
return FALSE return FALSE
var/cost = CEILING(materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency, 1) if (materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency > points)
if (cost > points)
menustat = "nopoints"
return FALSE return FALSE
else else
if(remove_points) if(remove_points)
points -= cost points -= materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency
update_icon() update_icon()
updateUsrDialog()
return TRUE return TRUE
/obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1) /obj/machinery/biogenerator/proc/check_container_volume(list/reagents, multiplier = 1)
@@ -262,7 +205,6 @@
sum_reagents *= multiplier sum_reagents *= multiplier
if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume) if(beaker.reagents.total_volume + sum_reagents > beaker.reagents.maximum_volume)
menustat = "nobeakerspace"
return FALSE return FALSE
return TRUE return TRUE
@@ -284,6 +226,7 @@
var/i = amount var/i = amount
while(i > 0) while(i > 0)
if(!check_container_volume(D.make_reagents)) if(!check_container_volume(D.make_reagents))
say("Warning: Attached container does not have enough free capacity!")
return . return .
if(!check_cost(D.materials)) if(!check_cost(D.materials))
return . return .
@@ -293,51 +236,100 @@
beaker.reagents.add_reagent(R, D.make_reagents[R]) beaker.reagents.add_reagent(R, D.make_reagents[R])
. = 1 . = 1
--i --i
menustat = "complete"
update_icon() update_icon()
return . return .
/obj/machinery/biogenerator/proc/detach(mob/living/user) /obj/machinery/biogenerator/proc/detach(mob/living/user)
if(beaker) if(beaker)
if(can_interact(user))
user.put_in_hands(beaker) user.put_in_hands(beaker)
else
beaker.drop_location(get_turf(src))
beaker = null beaker = null
update_icon() update_icon()
/obj/machinery/biogenerator/Topic(href, href_list) /obj/machinery/biogenerator/ui_status(mob/user)
if(..() || panel_open) if(stat & BROKEN || panel_open)
return UI_CLOSE
return ..()
/obj/machinery/biogenerator/ui_assets(mob/user)
return list(
get_asset_datum(/datum/asset/spritesheet/research_designs),
)
/obj/machinery/biogenerator/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Biogenerator", name)
ui.open()
/obj/machinery/biogenerator/ui_data(mob/user)
var/list/data = list()
data["beaker"] = beaker ? TRUE : FALSE
data["biomass"] = points
data["processing"] = processing
if(locate(/obj/item/reagent_containers/food/snacks/grown) in contents)
data["can_process"] = TRUE
else
data["can_process"] = FALSE
return data
/obj/machinery/biogenerator/ui_static_data(mob/user)
var/list/data = list()
data["categories"] = list()
var/categories = show_categories.Copy()
for(var/V in categories)
categories[V] = list()
for(var/V in stored_research.researched_designs)
var/datum/design/D = SSresearch.techweb_design_by_id(V)
for(var/C in categories)
if(C in D.category)
categories[C] += D
for(var/category in categories)
var/list/cat = list(
"name" = category,
"items" = (category == selected_cat ? list() : null))
for(var/item in categories[category])
var/datum/design/D = item
cat["items"] += list(list(
"id" = D.id,
"name" = D.name,
"cost" = D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency,
))
data["categories"] += list(cat)
return data
/obj/machinery/biogenerator/ui_act(action, list/params)
if(..())
return return
usr.set_machine(src) switch(action)
if("activate")
if(href_list["activate"]) activate(usr)
activate() return TRUE
updateUsrDialog() if("detach")
else if(href_list["detach"])
detach(usr) detach(usr)
updateUsrDialog() return TRUE
if("create")
else if(href_list["create"]) var/amount = text2num(params["amount"])
var/amount = (text2num(href_list["amount"])) amount = clamp(amount, 1, 10)
//Can't be outside these (if you change this keep a sane limit) if(!amount)
amount = clamp(amount, 1, 50) return
var/id = href_list["create"] var/id = params["id"]
if(!stored_research.researched_designs.Find(id)) if(!stored_research.researched_designs.Find(id))
//naughty naughty
stack_trace("ID did not map to a researched datum [id]") stack_trace("ID did not map to a researched datum [id]")
return return
//Get design by id (or may return error design)
var/datum/design/D = SSresearch.techweb_design_by_id(id) var/datum/design/D = SSresearch.techweb_design_by_id(id)
//Valid design datum, amount and the datum is not the error design, lets proceed if(D && !istype(D, /datum/design/error_design))
if(D && amount && !istype(D, /datum/design/error_design))
create_product(D, amount) create_product(D, amount)
//This shouldnt happen normally but href forgery is real
else else
stack_trace("ID could not be turned into a valid techweb design datum [id]") stack_trace("ID could not be turned into a valid techweb design datum [id]")
updateUsrDialog() return
return TRUE
else if(href_list["menu"]) if("select")
menustat = "menu" selected_cat = params["category"]
updateUsrDialog() return TRUE