fixes merge conflict
@@ -1,94 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Omni device port types
|
||||
//--------------------------------------------
|
||||
#define ATM_NONE 0
|
||||
#define ATM_INPUT 1
|
||||
#define ATM_OUTPUT 2
|
||||
|
||||
#define ATM_O2 3
|
||||
#define ATM_N2 4
|
||||
#define ATM_CO2 5
|
||||
#define ATM_P 6 //Plasma
|
||||
#define ATM_N2O 7
|
||||
|
||||
//--------------------------------------------
|
||||
// Omni port datum
|
||||
//
|
||||
// Used by omni devices to manage connections
|
||||
// to other atmospheric objects.
|
||||
//--------------------------------------------
|
||||
/datum/omni_port
|
||||
var/obj/machinery/atmospherics/omni/master
|
||||
var/dir
|
||||
var/update = 1
|
||||
var/mode = 0
|
||||
var/concentration = 0
|
||||
var/con_lock = 0
|
||||
var/transfer_moles = 0
|
||||
var/datum/gas_mixture/air
|
||||
var/obj/machinery/atmospherics/node
|
||||
var/datum/pipeline/parent
|
||||
|
||||
/datum/omni_port/New(var/obj/machinery/atmospherics/omni/M, var/direction = NORTH)
|
||||
..()
|
||||
dir = direction
|
||||
if(istype(M))
|
||||
master = M
|
||||
air = new
|
||||
air.volume = 200
|
||||
|
||||
/datum/omni_port/proc/connect()
|
||||
if(node)
|
||||
return
|
||||
master.atmos_init()
|
||||
if(node)
|
||||
node.atmos_init()
|
||||
node.addMember(master)
|
||||
master.build_network()
|
||||
|
||||
/datum/omni_port/proc/disconnect()
|
||||
if(node)
|
||||
node.disconnect(master)
|
||||
node = null
|
||||
master.nullifyPipenet(parent)
|
||||
|
||||
//--------------------------------------------
|
||||
// Need to find somewhere else for these
|
||||
//--------------------------------------------
|
||||
|
||||
//returns a text string based on the direction flag input
|
||||
// if capitalize is true, it will return the string capitalized
|
||||
// otherwise it will return the direction string in lower case
|
||||
/proc/dir_name(var/dir, var/capitalize = 0)
|
||||
var/string = null
|
||||
switch(dir)
|
||||
if(NORTH)
|
||||
string = "North"
|
||||
if(SOUTH)
|
||||
string = "South"
|
||||
if(EAST)
|
||||
string = "East"
|
||||
if(WEST)
|
||||
string = "West"
|
||||
|
||||
if(!capitalize && string)
|
||||
string = lowertext(string)
|
||||
|
||||
return string
|
||||
|
||||
//returns a direction flag based on the string passed to it
|
||||
// case insensitive
|
||||
/proc/dir_flag(var/dir)
|
||||
dir = lowertext(dir)
|
||||
switch(dir)
|
||||
if("north")
|
||||
return NORTH
|
||||
if("south")
|
||||
return SOUTH
|
||||
if("east")
|
||||
return EAST
|
||||
if("west")
|
||||
return WEST
|
||||
else
|
||||
return 0
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Gas filter - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
name = "omni gas filter"
|
||||
icon_state = "map_filter"
|
||||
|
||||
var/list/o_filters = new()
|
||||
var/datum/omni_port/input
|
||||
var/datum/omni_port/output
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Destroy()
|
||||
input = null
|
||||
output = null
|
||||
o_filters.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(input == P)
|
||||
input = null
|
||||
if(o_filters.Find(P))
|
||||
o_filters -= P
|
||||
|
||||
P.air.volume = 200
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
o_filters += P
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/error_check()
|
||||
if(!input || !output || !o_filters)
|
||||
return 1
|
||||
if(o_filters.len < 1 || o_filters.len > 2) //requires 1 or 2 o_filters ~otherwise why are you using a filter?
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
if(!input || !output)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/output_air = output.air //BYOND doesn't like referencing "output.air.return_pressure()" so we need to make a direct reference
|
||||
var/datum/gas_mixture/input_air = input.air // it's completely happy with them if they're in a loop though i.e. "P.air.return_pressure()"... *shrug*
|
||||
|
||||
var/output_pressure = output_air.return_pressure()
|
||||
|
||||
if(output_pressure >= target_pressure)
|
||||
return 1
|
||||
for(var/datum/omni_port/P in o_filters)
|
||||
if(P.air.return_pressure() >= target_pressure)
|
||||
return 1
|
||||
|
||||
var/pressure_delta = target_pressure - output_pressure
|
||||
|
||||
if(input_air.return_temperature() > 0)
|
||||
input.transfer_moles = pressure_delta * output_air.volume / (input_air.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
if(input.transfer_moles > 0)
|
||||
var/datum/gas_mixture/removed = input_air.remove(input.transfer_moles)
|
||||
|
||||
if(!removed)
|
||||
return 1
|
||||
|
||||
for(var/datum/omni_port/P in o_filters)
|
||||
var/datum/gas_mixture/filtered_out = new
|
||||
filtered_out.temperature = removed.return_temperature()
|
||||
|
||||
switch(P.mode)
|
||||
if(ATM_O2)
|
||||
filtered_out.oxygen = removed.oxygen
|
||||
removed.oxygen = 0
|
||||
if(ATM_N2)
|
||||
filtered_out.nitrogen = removed.nitrogen
|
||||
removed.nitrogen = 0
|
||||
if(ATM_CO2)
|
||||
filtered_out.carbon_dioxide = removed.carbon_dioxide
|
||||
removed.carbon_dioxide = 0
|
||||
if(ATM_P)
|
||||
filtered_out.toxins = removed.toxins
|
||||
removed.toxins = 0
|
||||
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
if(ATM_N2O)
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
else
|
||||
filtered_out = null
|
||||
|
||||
P.air.merge(filtered_out)
|
||||
P.parent.update = 1
|
||||
|
||||
output_air.merge(removed)
|
||||
output.parent.update = 1
|
||||
|
||||
input.transfer_moles = 0
|
||||
input.parent.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
usr.set_machine(src)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "omni_filter.tmpl", "Omni Filter Control", 330, 330)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
var/filter = 1
|
||||
var/f_type = null
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
filter = 0
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
filter = 0
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
f_type = mode_send_switch(P.mode)
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"filter" = filter, \
|
||||
"f_type" = f_type)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["pressure"] = target_pressure
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_send_switch(var/mode = ATM_NONE)
|
||||
switch(mode)
|
||||
if(ATM_O2)
|
||||
return "Oxygen"
|
||||
if(ATM_N2)
|
||||
return "Nitrogen"
|
||||
if(ATM_CO2)
|
||||
return "Carbon Dioxide"
|
||||
if(ATM_P)
|
||||
return "Plasma" //*cough* Plasma *cough*
|
||||
if(ATM_N2O)
|
||||
return "Nitrous Oxide"
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
on = !on
|
||||
else
|
||||
on = 0
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
on = 0
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !on)
|
||||
switch(href_list["command"])
|
||||
if("set_pressure")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
|
||||
target_pressure = between(0, new_pressure, 4500)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), mode_return_switch(href_list["mode"]))
|
||||
if("switch_filter")
|
||||
var/new_filter = input(usr,"Select filter mode:","Change filter",href_list["mode"]) in list("None", "Oxygen", "Nitrogen", "Carbon Dioxide", "Plasma", "Nitrous Oxide")
|
||||
switch_filter(dir_flag(href_list["dir"]), mode_return_switch(new_filter))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/mode_return_switch(var/mode)
|
||||
switch(mode)
|
||||
if("Oxygen")
|
||||
return ATM_O2
|
||||
if("Nitrogen")
|
||||
return ATM_N2
|
||||
if("Carbon Dioxide")
|
||||
return ATM_CO2
|
||||
if("Plasma")
|
||||
return ATM_P
|
||||
if("Nitrous Oxide")
|
||||
return ATM_N2O
|
||||
if("in")
|
||||
return ATM_INPUT
|
||||
if("out")
|
||||
return ATM_OUTPUT
|
||||
if("None")
|
||||
return ATM_NONE
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_filter(var/dir, var/mode)
|
||||
//check they aren't trying to disable the input or output ~this can only happen if they hack the cached tmpl file
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == dir)
|
||||
if(P.mode == ATM_INPUT || P.mode == ATM_OUTPUT)
|
||||
return
|
||||
|
||||
switch_mode(dir, mode)
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/switch_mode(var/port, var/mode)
|
||||
if(mode == null || !port)
|
||||
return
|
||||
var/datum/omni_port/target_port = null
|
||||
var/list/other_ports = new()
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.dir == port)
|
||||
target_port = P
|
||||
else
|
||||
other_ports += P
|
||||
|
||||
var/previous_mode = null
|
||||
if(target_port)
|
||||
previous_mode = target_port.mode
|
||||
target_port.mode = mode
|
||||
if(target_port.mode != previous_mode)
|
||||
handle_port_change(target_port)
|
||||
else
|
||||
return
|
||||
else
|
||||
return
|
||||
|
||||
for(var/datum/omni_port/P in other_ports)
|
||||
if(P.mode == mode)
|
||||
var/old_mode = P.mode
|
||||
P.mode = previous_mode
|
||||
if(P.mode != old_mode)
|
||||
handle_port_change(P)
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/filter/proc/handle_port_change(var/datum/omni_port/P)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
@@ -1,291 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Gas mixer - omni variant
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
name = "omni gas mixer"
|
||||
icon_state = "map_mixer"
|
||||
|
||||
var/list/inputs = new()
|
||||
var/datum/omni_port/output
|
||||
|
||||
//setup tags for initial concentration values (must be decimal)
|
||||
var/tag_north_con
|
||||
var/tag_south_con
|
||||
var/tag_east_con
|
||||
var/tag_west_con
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/New()
|
||||
..()
|
||||
if(mapper_set())
|
||||
var/con = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
if(tag_north_con && tag_north == 1)
|
||||
P.concentration = tag_north_con
|
||||
con += max(0, tag_north_con)
|
||||
if(SOUTH)
|
||||
if(tag_south_con && tag_south == 1)
|
||||
P.concentration = tag_south_con
|
||||
con += max(0, tag_south_con)
|
||||
if(EAST)
|
||||
if(tag_east_con && tag_east == 1)
|
||||
P.concentration = tag_east_con
|
||||
con += max(0, tag_east_con)
|
||||
if(WEST)
|
||||
if(tag_west_con && tag_west == 1)
|
||||
P.concentration = tag_west_con
|
||||
con += max(0, tag_west_con)
|
||||
|
||||
//mappers who are bad at maths will be punished (total concentration must be 100%)
|
||||
if(con != 1)
|
||||
tag_north_con = null
|
||||
tag_south_con = null
|
||||
tag_east_con = null
|
||||
tag_west_con = null
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Destroy()
|
||||
inputs.Cut()
|
||||
output = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/sort_ports()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
if(output == P)
|
||||
output = null
|
||||
if(inputs.Find(P))
|
||||
inputs -= P
|
||||
|
||||
P.air.volume = 200
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
inputs += P
|
||||
if(ATM_OUTPUT)
|
||||
output = P
|
||||
|
||||
if(!mapper_set())
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
P.concentration = 1 / max(1, inputs.len)
|
||||
|
||||
if(output)
|
||||
output.air.volume *= 0.75 * inputs.len
|
||||
output.concentration = 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/mapper_set()
|
||||
return (tag_north_con || tag_south_con || tag_east_con || tag_west_con)
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/error_check()
|
||||
if(!output || !inputs)
|
||||
return 1
|
||||
if(inputs.len < 2 || inputs.len > 3) //requires 2 or 3 inputs ~otherwise why are you using a mixer?
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/process_atmos()
|
||||
..()
|
||||
if(!on)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/output_air = output.air
|
||||
var/output_pressure = output_air.return_pressure()
|
||||
|
||||
|
||||
if(output_pressure >= target_pressure * 0.999)
|
||||
//No need to mix if target is already full! - 0.1% margin of error so we minimize processing minor gas volumes
|
||||
return 1
|
||||
|
||||
//Calculate necessary moles to transfer using PV=nRT
|
||||
|
||||
var/pressure_delta = target_pressure - output_pressure
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.air.return_temperature() > 0)
|
||||
P.transfer_moles = (P.concentration * pressure_delta) * output_air.return_volume() / (P.air.return_temperature() * R_IDEAL_GAS_EQUATION)
|
||||
|
||||
var/ratio_check = null
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(!P.transfer_moles)
|
||||
return 1
|
||||
if(P.air.total_moles() < P.transfer_moles)
|
||||
ratio_check = 1
|
||||
continue
|
||||
|
||||
if(ratio_check)
|
||||
var/list/ratio_list = new()
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
ratio_list.Add(P.air.total_moles() / P.transfer_moles)
|
||||
|
||||
var/ratio = min(ratio_list)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
P.transfer_moles *= ratio
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.transfer_moles > 0)
|
||||
output_air.merge(P.air.remove(P.transfer_moles))
|
||||
P.parent.update = 1
|
||||
P.transfer_moles = 0
|
||||
|
||||
output.parent.update = 1
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, force_open = 0)
|
||||
usr.set_machine(src)
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "omni_mixer.tmpl", "Omni Mixer Control", 360, 330)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/ui_data(mob/user, datum/topic_state/state)
|
||||
var/data[0]
|
||||
|
||||
data["power"] = on
|
||||
data["config"] = configuring
|
||||
|
||||
var/portData[0]
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!configuring && P.mode == 0)
|
||||
continue
|
||||
|
||||
var/input = 0
|
||||
var/output = 0
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
input = 1
|
||||
if(ATM_OUTPUT)
|
||||
output = 1
|
||||
|
||||
portData[++portData.len] = list("dir" = dir_name(P.dir, capitalize = 1), \
|
||||
"concentration" = P.concentration, \
|
||||
"input" = input, \
|
||||
"output" = output, \
|
||||
"con_lock" = P.con_lock)
|
||||
|
||||
if(portData.len)
|
||||
data["ports"] = portData
|
||||
if(output)
|
||||
data["pressure"] = target_pressure
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
switch(href_list["command"])
|
||||
if("power")
|
||||
if(!configuring)
|
||||
on = !on
|
||||
else
|
||||
on = 0
|
||||
if("configure")
|
||||
configuring = !configuring
|
||||
if(configuring)
|
||||
on = 0
|
||||
|
||||
//only allows config changes when in configuring mode ~otherwise you'll get weird pressure stuff going on
|
||||
if(configuring && !on)
|
||||
switch(href_list["command"])
|
||||
if("set_pressure")
|
||||
var/new_pressure = input(usr,"Enter new output pressure (0-4500kPa)","Pressure control",target_pressure) as num
|
||||
target_pressure = between(0, new_pressure, 4500)
|
||||
if("switch_mode")
|
||||
switch_mode(dir_flag(href_list["dir"]), href_list["mode"])
|
||||
if("switch_con")
|
||||
change_concentration(dir_flag(href_list["dir"]))
|
||||
if("switch_conlock")
|
||||
con_lock(dir_flag(href_list["dir"]))
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/switch_mode(var/port = NORTH, var/mode = ATM_NONE)
|
||||
if(mode != ATM_INPUT && mode != ATM_OUTPUT)
|
||||
switch(mode)
|
||||
if("in")
|
||||
mode = ATM_INPUT
|
||||
if("out")
|
||||
mode = ATM_OUTPUT
|
||||
else
|
||||
mode = ATM_NONE
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
var/old_mode = P.mode
|
||||
if(P.dir == port)
|
||||
switch(mode)
|
||||
if(ATM_INPUT)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
P.mode = mode
|
||||
if(ATM_OUTPUT)
|
||||
P.mode = mode
|
||||
if(ATM_NONE)
|
||||
if(P.mode == ATM_OUTPUT)
|
||||
return
|
||||
if(P.mode == ATM_INPUT && inputs.len > 2)
|
||||
P.mode = mode
|
||||
else if(P.mode == ATM_OUTPUT && mode == ATM_OUTPUT)
|
||||
P.mode = ATM_INPUT
|
||||
if(P.mode != old_mode)
|
||||
switch(P.mode)
|
||||
if(ATM_NONE)
|
||||
initialize_directions &= ~P.dir
|
||||
P.disconnect()
|
||||
else
|
||||
initialize_directions |= P.dir
|
||||
P.connect()
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/change_concentration(var/port = NORTH)
|
||||
tag_north_con = null
|
||||
tag_south_con = null
|
||||
tag_east_con = null
|
||||
tag_west_con = null
|
||||
|
||||
var/old_con = 0
|
||||
var/non_locked = 0
|
||||
var/remain_con = 1
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
old_con = P.concentration
|
||||
else if(!P.con_lock)
|
||||
non_locked++
|
||||
else
|
||||
remain_con -= P.concentration
|
||||
|
||||
//return if no adjustable ports
|
||||
if(non_locked < 1)
|
||||
return
|
||||
|
||||
var/new_con = (input(usr,"Enter a new concentration (0-[round(remain_con * 100, 0.5)])%","Concentration control", min(remain_con, old_con)*100) as num) / 100
|
||||
|
||||
//cap it between 0 and the max remaining concentration
|
||||
new_con = between(0, new_con, remain_con)
|
||||
|
||||
//new_con = min(remain_con, new_con)
|
||||
|
||||
//clamp remaining concentration so we don't go into negatives
|
||||
remain_con = max(0, remain_con - new_con)
|
||||
|
||||
//distribute remaining concentration between unlocked ports evenly
|
||||
remain_con /= max(1, non_locked)
|
||||
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.concentration = new_con
|
||||
else if(!P.con_lock)
|
||||
P.concentration = remain_con
|
||||
|
||||
/obj/machinery/atmospherics/omni/mixer/proc/con_lock(var/port = NORTH)
|
||||
for(var/datum/omni_port/P in inputs)
|
||||
if(P.dir == port)
|
||||
P.con_lock = !P.con_lock
|
||||
@@ -1,302 +0,0 @@
|
||||
//--------------------------------------------
|
||||
// Base omni device
|
||||
//--------------------------------------------
|
||||
/obj/machinery/atmospherics/omni
|
||||
name = "omni device"
|
||||
icon = 'icons/atmos/omni_devices.dmi'
|
||||
icon_state = "base"
|
||||
use_power = IDLE_POWER_USE
|
||||
initialize_directions = 0
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
var/on = 0
|
||||
var/configuring = 0
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/tag_north = ATM_NONE
|
||||
var/tag_south = ATM_NONE
|
||||
var/tag_east = ATM_NONE
|
||||
var/tag_west = ATM_NONE
|
||||
|
||||
var/overlays_on[5]
|
||||
var/overlays_off[5]
|
||||
var/overlays_error[2]
|
||||
var/underlays_current[4]
|
||||
|
||||
var/list/ports = new()
|
||||
|
||||
/obj/machinery/atmospherics/omni/New()
|
||||
..()
|
||||
icon_state = "base"
|
||||
|
||||
ports = new()
|
||||
for(var/d in GLOB.cardinal)
|
||||
var/datum/omni_port/new_port = new(src, d)
|
||||
switch(d)
|
||||
if(NORTH)
|
||||
new_port.mode = tag_north
|
||||
if(SOUTH)
|
||||
new_port.mode = tag_south
|
||||
if(EAST)
|
||||
new_port.mode = tag_east
|
||||
if(WEST)
|
||||
new_port.mode = tag_west
|
||||
if(new_port.mode > 0)
|
||||
initialize_directions |= d
|
||||
ports += new_port
|
||||
|
||||
build_icons()
|
||||
|
||||
/obj/machinery/atmospherics/omni/Destroy()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node)
|
||||
P.node.disconnect(src)
|
||||
P.node = null
|
||||
nullifyPipenet(P.parent)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/atmos_init()
|
||||
..()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.node || P.mode == 0)
|
||||
continue
|
||||
for(var/obj/machinery/atmospherics/target in get_step(src, P.dir))
|
||||
if(target.initialize_directions & get_dir(target,src))
|
||||
P.node = target
|
||||
break
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_icon()
|
||||
..()
|
||||
|
||||
if(stat & NOPOWER)
|
||||
overlays = overlays_off
|
||||
on = 0
|
||||
else if(error_check())
|
||||
overlays = overlays_error
|
||||
on = 0
|
||||
else
|
||||
overlays = on ? (overlays_on) : (overlays_off)
|
||||
|
||||
underlays = underlays_current
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/error_check()
|
||||
return
|
||||
|
||||
/obj/machinery/atmospherics/omni/power_change()
|
||||
var/old_stat = stat
|
||||
..()
|
||||
if(old_stat != stat)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/omni/attackby(var/obj/item/W as obj, var/mob/user as mob, params)
|
||||
if(!istype(W, /obj/item/wrench))
|
||||
return ..()
|
||||
|
||||
if(can_unwrench)
|
||||
var/int_pressure = 0
|
||||
for(var/datum/omni_port/P in ports)
|
||||
int_pressure += P.air.return_pressure()
|
||||
var/datum/gas_mixture/env_air = loc.return_air()
|
||||
if((int_pressure - env_air.return_pressure()) > 2*ONE_ATMOSPHERE)
|
||||
to_chat(user, "<span class='danger'>You cannot unwrench [src], it is too exerted due to internal pressure.</span>")
|
||||
add_fingerprint(user)
|
||||
return 1
|
||||
playsound(loc, W.usesound, 50, 1)
|
||||
to_chat(user, "<span class='notice'>You begin to unfasten \the [src]...</span>")
|
||||
if(do_after(user, 40 * W.toolspeed, target = src))
|
||||
user.visible_message( \
|
||||
"[user] unfastens \the [src].", \
|
||||
"<span class='notice'>You have unfastened \the [src].</span>", \
|
||||
"You hear a ratchet.")
|
||||
new /obj/item/pipe(loc, make_from=src)
|
||||
qdel(src)
|
||||
else
|
||||
return ..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
|
||||
add_fingerprint(usr)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/omni/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/build_icons()
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
var/core_icon = null
|
||||
if(istype(src, /obj/machinery/atmospherics/omni/mixer))
|
||||
core_icon = "mixer"
|
||||
else if(istype(src, /obj/machinery/atmospherics/omni/filter))
|
||||
core_icon = "filter"
|
||||
else
|
||||
return
|
||||
|
||||
//directional icons are layers 1-4, with the core icon on layer 5
|
||||
if(core_icon)
|
||||
overlays_off[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
|
||||
overlays_on[5] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon + "_glow")
|
||||
|
||||
overlays_error[1] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , core_icon)
|
||||
overlays_error[2] = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , "error")
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_port_icons()
|
||||
if(!check_icon_cache())
|
||||
return
|
||||
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(P.update)
|
||||
var/ref_layer = 0
|
||||
switch(P.dir)
|
||||
if(NORTH)
|
||||
ref_layer = 1
|
||||
if(SOUTH)
|
||||
ref_layer = 2
|
||||
if(EAST)
|
||||
ref_layer = 3
|
||||
if(WEST)
|
||||
ref_layer = 4
|
||||
|
||||
if(!ref_layer)
|
||||
continue
|
||||
|
||||
var/list/port_icons = select_port_icons(P)
|
||||
if(port_icons)
|
||||
if(P.node)
|
||||
underlays_current[ref_layer] = port_icons["pipe_icon"]
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
overlays_off[ref_layer] = port_icons["off_icon"]
|
||||
overlays_on[ref_layer] = port_icons["on_icon"]
|
||||
else
|
||||
underlays_current[ref_layer] = null
|
||||
overlays_off[ref_layer] = null
|
||||
overlays_on[ref_layer] = null
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/select_port_icons(var/datum/omni_port/P)
|
||||
if(!istype(P))
|
||||
return
|
||||
|
||||
if(P.mode > 0)
|
||||
var/ic_dir = dir_name(P.dir)
|
||||
var/ic_on = ic_dir
|
||||
var/ic_off = ic_dir
|
||||
switch(P.mode)
|
||||
if(ATM_INPUT)
|
||||
ic_on += "_in_glow"
|
||||
ic_off += "_in"
|
||||
if(ATM_OUTPUT)
|
||||
ic_on += "_out_glow"
|
||||
ic_off += "_out"
|
||||
if(ATM_O2 to ATM_N2O)
|
||||
ic_on += "_filter"
|
||||
ic_off += "_out"
|
||||
|
||||
ic_on = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_on)
|
||||
ic_off = GLOB.pipe_icon_manager.get_atmos_icon("omni", , , ic_off)
|
||||
|
||||
var/pipe_state
|
||||
var/turf/T = get_turf(src)
|
||||
if(!istype(T))
|
||||
return
|
||||
if(T.intact && istype(P.node, /obj/machinery/atmospherics/pipe) && P.node.level == 1 )
|
||||
//pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_down", P.dir, color_cache_name(P.node))
|
||||
pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "down")
|
||||
else
|
||||
//pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay_intact", P.dir, color_cache_name(P.node))
|
||||
pipe_state = GLOB.pipe_icon_manager.get_atmos_icon("underlay", P.dir, color_cache_name(P.node), "intact")
|
||||
|
||||
return list("on_icon" = ic_on, "off_icon" = ic_off, "pipe_icon" = pipe_state)
|
||||
|
||||
/obj/machinery/atmospherics/omni/update_underlays()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 1
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/hide(var/i)
|
||||
update_underlays()
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/update_ports()
|
||||
sort_ports()
|
||||
update_port_icons()
|
||||
for(var/datum/omni_port/P in ports)
|
||||
P.update = 0
|
||||
|
||||
/obj/machinery/atmospherics/omni/proc/sort_ports()
|
||||
return
|
||||
|
||||
// Pipenet procs
|
||||
/obj/machinery/atmospherics/omni/build_network(remove_deferral = FALSE)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(!P.parent)
|
||||
P.parent = new /datum/pipeline()
|
||||
P.parent.build_pipeline(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/omni/disconnect(obj/machinery/atmospherics/reference)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(reference == P.node)
|
||||
if(istype(P.node, /obj/machinery/atmospherics/pipe))
|
||||
qdel(P.parent)
|
||||
P.node = null
|
||||
update_ports()
|
||||
|
||||
/obj/machinery/atmospherics/omni/nullifyPipenet(datum/pipeline/P)
|
||||
..()
|
||||
if(!P)
|
||||
return
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(P == PO.parent)
|
||||
PO.parent.other_airs -= PO.air
|
||||
PO.parent = null
|
||||
|
||||
/obj/machinery/atmospherics/omni/returnPipenetAir(datum/pipeline/P)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(P == PO.parent)
|
||||
return PO.air
|
||||
|
||||
/obj/machinery/atmospherics/omni/pipeline_expansion(datum/pipeline/P)
|
||||
if(P)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(PO.parent == P)
|
||||
return list(PO.node)
|
||||
else
|
||||
var/list/nodes = list()
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
nodes += PO.node
|
||||
|
||||
return nodes
|
||||
|
||||
/obj/machinery/atmospherics/omni/setPipenet(datum/pipeline/P, obj/machinery/atmospherics/A)
|
||||
for(var/datum/omni_port/PO in ports)
|
||||
if(A == PO.node)
|
||||
PO.parent = P
|
||||
|
||||
/obj/machinery/atmospherics/omni/returnPipenet(obj/machinery/atmospherics/A)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(A == P.node)
|
||||
return P.parent
|
||||
|
||||
/obj/machinery/atmospherics/omni/replacePipenet(datum/pipeline/Old, datum/pipeline/New)
|
||||
for(var/datum/omni_port/P in ports)
|
||||
if(Old == P.parent)
|
||||
P.parent = New
|
||||
|
||||
|
||||
/obj/machinery/atmospherics/omni/process_atmos()
|
||||
..()
|
||||
for(var/datum/omni_port/port in ports)
|
||||
if(!port.parent)
|
||||
return 0
|
||||
return 1
|
||||
@@ -1,26 +1,39 @@
|
||||
|
||||
/// Nothing will be filtered.
|
||||
#define FILTER_NOTHING -1
|
||||
/// Plasma, and Oxygen Agent B.
|
||||
#define FILTER_TOXINS 0
|
||||
/// Oxygen only.
|
||||
#define FILTER_OXYGEN 1
|
||||
/// Nitrogen only.
|
||||
#define FILTER_NITROGEN 2
|
||||
/// Carbon dioxide only.
|
||||
#define FILTER_CO2 3
|
||||
/// Nitrous oxide only.
|
||||
#define FILTER_N2O 4
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter
|
||||
name = "gas filter"
|
||||
icon = 'icons/atmos/filter.dmi'
|
||||
icon_state = "map"
|
||||
|
||||
can_unwrench = 1
|
||||
|
||||
name = "gas filter"
|
||||
|
||||
can_unwrench = TRUE
|
||||
/// The amount of pressure the filter wants to operate at.
|
||||
var/target_pressure = ONE_ATMOSPHERE
|
||||
|
||||
var/filter_type = 0
|
||||
/*
|
||||
Filter types:
|
||||
-1: Nothing
|
||||
0: Toxins: Toxins, Oxygen Agent B
|
||||
1: Oxygen: Oxygen ONLY
|
||||
2: Nitrogen: Nitrogen ONLY
|
||||
3: Carbon Dioxide: Carbon Dioxide ONLY
|
||||
4: Sleeping Agent (N2O)
|
||||
*/
|
||||
|
||||
var/frequency = 0
|
||||
/// The type of gas we want to filter. Valid values that go here are from the `FILTER` defines at the top of the file.
|
||||
var/filter_type = FILTER_NOTHING
|
||||
/// The frequency of the filter. Used with `radio_connection`.
|
||||
var/frequency = NONE
|
||||
/// A reference to the filter's `datum/radio_frequency`.
|
||||
var/datum/radio_frequency/radio_connection
|
||||
/// A list of available filter options. Used with `tgui_data`.
|
||||
var/list/filter_list = list(
|
||||
"Nothing" = FILTER_NOTHING,
|
||||
"Plasma" = FILTER_TOXINS,
|
||||
"O2" = FILTER_OXYGEN,
|
||||
"N2" = FILTER_NITROGEN,
|
||||
"CO2" = FILTER_CO2,
|
||||
"N2O" = FILTER_N2O
|
||||
)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user)
|
||||
if(!istype(user) || user.incapacitated())
|
||||
@@ -146,26 +159,26 @@ Filter types:
|
||||
filtered_out.temperature = removed.temperature
|
||||
|
||||
switch(filter_type)
|
||||
if(0) //removing hydrocarbons
|
||||
if(FILTER_TOXINS)
|
||||
filtered_out.toxins = removed.toxins
|
||||
removed.toxins = 0
|
||||
|
||||
filtered_out.agent_b = removed.agent_b
|
||||
removed.agent_b = 0
|
||||
|
||||
if(1) //removing O2
|
||||
if(FILTER_OXYGEN)
|
||||
filtered_out.oxygen = removed.oxygen
|
||||
removed.oxygen = 0
|
||||
|
||||
if(2) //removing N2
|
||||
if(FILTER_NITROGEN)
|
||||
filtered_out.nitrogen = removed.nitrogen
|
||||
removed.nitrogen = 0
|
||||
|
||||
if(3) //removing CO2
|
||||
if(FILTER_CO2)
|
||||
filtered_out.carbon_dioxide = removed.carbon_dioxide
|
||||
removed.carbon_dioxide = 0
|
||||
|
||||
if(4)//removing N2O
|
||||
if(FILTER_N2O)
|
||||
filtered_out.sleeping_agent = removed.sleeping_agent
|
||||
removed.sleeping_agent = 0
|
||||
else
|
||||
@@ -188,7 +201,7 @@ Filter types:
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attack_hand(mob/user)
|
||||
if(..())
|
||||
@@ -199,53 +212,56 @@ Filter types:
|
||||
return
|
||||
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = GLOB.default_state)
|
||||
/obj/machinery/atmospherics/trinary/filter/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
user.set_machine(src)
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_filter.tmpl", name, 475, 155, state = state)
|
||||
ui = new(user, src, ui_key, "AtmosFilter", name, 380, 140, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["pressure"] = round(target_pressure)
|
||||
data["max_pressure"] = round(MAX_OUTPUT_PRESSURE)
|
||||
data["filter_type"] = filter_type
|
||||
/obj/machinery/atmospherics/trinary/filter/tgui_data(mob/user)
|
||||
var/list/data = list(
|
||||
"on" = on,
|
||||
"pressure" = round(target_pressure),
|
||||
"max_pressure" = round(MAX_OUTPUT_PRESSURE),
|
||||
"filter_type" = filter_type
|
||||
)
|
||||
data["filter_type_list"] = list()
|
||||
for(var/label in filter_list)
|
||||
data["filter_type_list"] += list(list("label" = label, "gas_type" = filter_list[label]))
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/Topic(href, href_list) // -- TLE
|
||||
/obj/machinery/atmospherics/trinary/filter/tgui_act(action, list/params)
|
||||
if(..())
|
||||
return 1
|
||||
return
|
||||
|
||||
if(href_list["power"])
|
||||
on = !on
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
if(href_list["pressure"])
|
||||
var/pressure = href_list["pressure"]
|
||||
if(pressure == "max")
|
||||
pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
else if(pressure == "input")
|
||||
pressure = input("New output pressure (0-[MAX_OUTPUT_PRESSURE] kPa):", name, target_pressure) as num|null
|
||||
if(!isnull(pressure) && !..())
|
||||
. = TRUE
|
||||
else if(text2num(pressure) != null)
|
||||
pressure = text2num(pressure)
|
||||
. = TRUE
|
||||
if(.)
|
||||
target_pressure = clamp(pressure, 0, MAX_OUTPUT_PRESSURE)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
if(href_list["filter"])
|
||||
filter_type = text2num(href_list["filter"])
|
||||
investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos")
|
||||
. = TRUE
|
||||
switch(action)
|
||||
if("power")
|
||||
toggle()
|
||||
investigate_log("was turned [on ? "on" : "off"] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
update_icon()
|
||||
SSnanoui.update_uis(src)
|
||||
if("set_filter")
|
||||
filter_type = text2num(params["filter"])
|
||||
investigate_log("was set to filter [filter_type] by [key_name(usr)]", "atmos")
|
||||
return TRUE
|
||||
|
||||
if("max_pressure")
|
||||
target_pressure = MAX_OUTPUT_PRESSURE
|
||||
. = TRUE
|
||||
|
||||
if("min_pressure")
|
||||
target_pressure = 0
|
||||
. = TRUE
|
||||
|
||||
if("custom_pressure")
|
||||
target_pressure = clamp(text2num(params["pressure"]), 0, MAX_OUTPUT_PRESSURE)
|
||||
. = TRUE
|
||||
if(.)
|
||||
investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos")
|
||||
|
||||
/obj/machinery/atmospherics/trinary/filter/attackby(obj/item/W, mob/user, params)
|
||||
if(istype(W, /obj/item/pen))
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
//var/list/underlays_intact[]
|
||||
//var/list/pipe_underlays_exposed[]
|
||||
//var/list/pipe_underlays_intact[]
|
||||
var/list/omni_icons[]
|
||||
|
||||
/datum/pipe_icon_manager/New()
|
||||
check_icons()
|
||||
@@ -53,8 +52,6 @@
|
||||
return manifold_icons[state + color]
|
||||
if("device")
|
||||
return device_icons[state]
|
||||
if("omni")
|
||||
return omni_icons[state]
|
||||
if("underlay")
|
||||
return underlays[state + dir + color]
|
||||
//if("underlay_intact")
|
||||
@@ -75,8 +72,6 @@
|
||||
gen_manifold_icons()
|
||||
if(!device_icons)
|
||||
gen_device_icons()
|
||||
if(!omni_icons)
|
||||
gen_omni_icons()
|
||||
//if(!underlays_intact || !underlays_down || !underlays_exposed || !pipe_underlays_exposed || !pipe_underlays_intact)
|
||||
if(!underlays)
|
||||
gen_underlay_icons()
|
||||
@@ -150,18 +145,6 @@
|
||||
continue
|
||||
device_icons["scrubber" + state] = image('icons/atmos/vent_scrubber.dmi', icon_state = state)
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_omni_icons()
|
||||
if(!omni_icons)
|
||||
omni_icons = new()
|
||||
|
||||
var/icon/omni = new('icons/atmos/omni_devices.dmi')
|
||||
|
||||
for(var/state in omni.IconStates())
|
||||
if(!state || findtext(state, "map"))
|
||||
continue
|
||||
omni_icons[state] = image('icons/atmos/omni_devices.dmi', icon_state = state)
|
||||
|
||||
|
||||
/datum/pipe_icon_manager/proc/gen_underlay_icons()
|
||||
|
||||
if(!underlays)
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#define PIPE_TVALVE 18
|
||||
#define PIPE_MANIFOLD4W 19
|
||||
#define PIPE_CAP 20
|
||||
#define PIPE_OMNI_MIXER 21
|
||||
#define PIPE_OMNI_FILTER 22
|
||||
#define PIPE_UNIVERSAL 23
|
||||
#define PIPE_SUPPLY_STRAIGHT 24
|
||||
#define PIPE_SUPPLY_BENT 25
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#define INIT_ORDER_GARBAGE 21
|
||||
#define INIT_ORDER_DBCORE 20
|
||||
#define INIT_ORDER_BLACKBOX 19
|
||||
#define INIT_ORDER_SERVER_MAINT 18
|
||||
#define INIT_ORDER_CLEANUP 18
|
||||
#define INIT_ORDER_INPUT 17
|
||||
#define INIT_ORDER_SOUNDS 16
|
||||
#define INIT_ORDER_INSTRUMENTS 15
|
||||
@@ -90,7 +90,7 @@
|
||||
#define FIRE_PRIORITY_NANOMOB 10
|
||||
#define FIRE_PRIORITY_NIGHTSHIFT 10
|
||||
#define FIRE_PRIORITY_IDLE_NPC 10
|
||||
#define FIRE_PRIORITY_SERVER_MAINT 10
|
||||
#define FIRE_PRIORITY_CLEANUP 10
|
||||
#define FIRE_PRIORITY_TICKETS 10
|
||||
#define FIRE_PRIORITY_RESEARCH 10
|
||||
#define FIRE_PRIORITY_GARBAGE 15
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* # Cleanup Subsystem
|
||||
*
|
||||
* For now, all it does is periodically clean the supplied global lists of any null values they may contain.
|
||||
*
|
||||
* Why is this important?
|
||||
*
|
||||
* Sometimes, these lists can gain nulls due to errors.
|
||||
* For example, when a dead player trasitions from the `dead_mob_list` to the `alive_mob_list`, a null value may get stuck in the dead mob list.
|
||||
* This can cause issues when other code tries to do things with the values in the list, but are instead met with null values.
|
||||
* These problems are incredibly hard to track down and fix, so this subsystem is a solution to that.
|
||||
*/
|
||||
SUBSYSTEM_DEF(cleanup)
|
||||
name = "Null cleanup"
|
||||
wait = 30 SECONDS
|
||||
flags = SS_POST_FIRE_TIMING
|
||||
priority = FIRE_PRIORITY_CLEANUP
|
||||
init_order = INIT_ORDER_CLEANUP
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
|
||||
offline_implications = "Certain global lists will no longer be cleared of nulls, which may result in runtimes. No immediate action is needed."
|
||||
/// A list of global lists we want the subsystem to clean.
|
||||
var/list/lists_to_clean
|
||||
|
||||
/datum/controller/subsystem/cleanup/Initialize(start_timeofday)
|
||||
// If you want this subsystem to clean out nulls from a specific list, add it here.
|
||||
lists_to_clean = list(
|
||||
GLOB.clients = "clients",
|
||||
GLOB.player_list = "player_list",
|
||||
GLOB.mob_list = "mob_list",
|
||||
GLOB.alive_mob_list = "alive_mob_list",
|
||||
GLOB.dead_mob_list = "dead_mob_list",
|
||||
GLOB.human_list = "human_list",
|
||||
GLOB.carbon_list = "carbon_list"
|
||||
)
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/cleanup/fire(resumed)
|
||||
for(var/L in lists_to_clean)
|
||||
var/list/_list = L
|
||||
var/prev_length = length(_list)
|
||||
listclearnulls(_list)
|
||||
|
||||
if(length(_list) < prev_length)
|
||||
stack_trace("Found a null value in GLOB.[lists_to_clean[_list]]!")
|
||||
@@ -191,6 +191,10 @@
|
||||
..()
|
||||
desc = "That's Definitely Not [M.real_name]."
|
||||
|
||||
/datum/dog_fashion/head/cone
|
||||
name = "REAL_NAME"
|
||||
desc = "Omnicone's Chosen Champion"
|
||||
|
||||
/datum/dog_fashion/back/hardsuit
|
||||
name = "Space Explorer REAL_NAME"
|
||||
desc = "That's one small step for a corgi. One giant yap for corgikind."
|
||||
|
||||
@@ -351,16 +351,6 @@ GLOBAL_LIST_EMPTY(rpd_pipe_list) //Some pipes we don't want to be dispensable
|
||||
pipe_id = PIPE_CIRCULATOR
|
||||
pipe_icon = "circ"
|
||||
|
||||
/datum/pipes/atmospheric/omni_filter
|
||||
pipe_name = "omni filter"
|
||||
pipe_id = PIPE_OMNI_FILTER
|
||||
pipe_icon = "omni_filter"
|
||||
|
||||
/datum/pipes/atmospheric/omni_mixer
|
||||
pipe_name = "omni mixer"
|
||||
pipe_id = PIPE_OMNI_MIXER
|
||||
pipe_icon = "omni_mixer"
|
||||
|
||||
/datum/pipes/atmospheric/insulated
|
||||
pipe_name = "insulated pipe"
|
||||
pipe_id = PIPE_INSULATED_STRAIGHT
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
action_background_icon_state = "bg_demon"
|
||||
|
||||
/obj/effect/proc_holder/spell/fireball/hellish/cast(list/targets, mob/living/user = usr)
|
||||
msg_admin_attack("[key_name_admin(usr)] has fired a fireball.", ATKLOG_FEW)
|
||||
add_attack_logs(user, targets, "has fired a Hellfire ball", ATKLOG_FEW)
|
||||
.=..()
|
||||
|
||||
|
||||
|
||||
@@ -106,10 +106,6 @@
|
||||
else if(istype(make_from, /obj/machinery/atmospherics/unary/passive_vent))
|
||||
src.pipe_type = PIPE_PASV_VENT
|
||||
|
||||
else if(istype(make_from, /obj/machinery/atmospherics/omni/mixer))
|
||||
src.pipe_type = PIPE_OMNI_MIXER
|
||||
else if(istype(make_from, /obj/machinery/atmospherics/omni/filter))
|
||||
src.pipe_type = PIPE_OMNI_FILTER
|
||||
else if(istype(make_from, /obj/machinery/atmospherics/binary/circulator))
|
||||
src.pipe_type = PIPE_CIRCULATOR
|
||||
|
||||
@@ -259,7 +255,7 @@
|
||||
return dir //dir|acw
|
||||
if(PIPE_CONNECTOR, PIPE_UVENT, PIPE_PASV_VENT, PIPE_SCRUBBER, PIPE_HEAT_EXCHANGE, PIPE_INJECTOR)
|
||||
return dir|flip
|
||||
if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER)
|
||||
if(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W)
|
||||
return dir|flip|cw|acw
|
||||
if(PIPE_MANIFOLD, PIPE_SUPPLY_MANIFOLD, PIPE_SCRUBBERS_MANIFOLD)
|
||||
return flip|cw|acw
|
||||
@@ -317,7 +313,7 @@
|
||||
dir = 1
|
||||
else if(dir==8)
|
||||
dir = 4
|
||||
else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W, PIPE_OMNI_MIXER, PIPE_OMNI_FILTER))
|
||||
else if(pipe_type in list(PIPE_MANIFOLD4W, PIPE_SUPPLY_MANIFOLD4W, PIPE_SCRUBBERS_MANIFOLD4W))
|
||||
dir = 2
|
||||
|
||||
/obj/item/pipe/attack_self(mob/user as mob)
|
||||
@@ -499,14 +495,6 @@
|
||||
P.name = pipename
|
||||
P.on_construction(dir, pipe_dir, color)
|
||||
|
||||
if(PIPE_OMNI_MIXER)
|
||||
var/obj/machinery/atmospherics/omni/mixer/P = new(loc)
|
||||
P.on_construction(dir, pipe_dir, color)
|
||||
|
||||
if(PIPE_OMNI_FILTER)
|
||||
var/obj/machinery/atmospherics/omni/filter/P = new(loc)
|
||||
P.on_construction(dir, pipe_dir, color)
|
||||
|
||||
user.visible_message( \
|
||||
"[user] fastens the [src].", \
|
||||
"<span class='notice'>You have fastened the [src].</span>", \
|
||||
|
||||
@@ -260,9 +260,9 @@
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
if(payload && !istype(payload, /obj/item/bombcore/training))
|
||||
msg_admin_attack("[key_name_admin(user)] has primed a [name] ([payload]) for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.", ATKLOG_FEW)
|
||||
log_game("[key_name(user)] has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]")
|
||||
investigate_log("[key_name(user)] has has primed a [name] ([payload]) for detonation at [A.name] [COORD(bombturf)]", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has primed a [name] ([payload]) for detonation", ATKLOG_FEW)
|
||||
payload.adminlog = "\The [src] that [key_name(user)] had primed detonated!"
|
||||
|
||||
///Bomb Subtypes///
|
||||
@@ -652,8 +652,8 @@
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(T)
|
||||
detonated--
|
||||
message_admins("[key_name_admin(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[T.x];Y=[T.y];Z=[T.z]'>[A.name] (JMP)</a>.")
|
||||
investigate_log("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using", ATKLOG_FEW)
|
||||
log_game("[key_name(user)] has remotely detonated [detonated ? "syndicate bombs" : "a syndicate bomb"] using a [name] at [A.name] ([T.x],[T.y],[T.z])")
|
||||
detonated = 0
|
||||
existant = 0
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
#define REGIME_TELEPORT 0
|
||||
#define REGIME_GATE 1
|
||||
#define REGIME_GPS 2
|
||||
|
||||
/obj/machinery/computer/teleporter
|
||||
name = "teleporter control console"
|
||||
desc = "Used to control a linked teleportation Hub and Station."
|
||||
icon_screen = "teleport"
|
||||
icon_keyboard = "teleport_key"
|
||||
circuit = /obj/item/circuitboard/teleporter
|
||||
var/obj/item/gps/locked = null
|
||||
var/regime_set = "Teleporter"
|
||||
var/obj/item/gps/locked = null /// A GPS with a locked destination
|
||||
var/regime = REGIME_TELEPORT /// Switches mode between teleporter, gate and gps
|
||||
var/id = null
|
||||
var/obj/machinery/teleport/station/power_station
|
||||
var/calibrating
|
||||
var/turf/target //Used for one-time-use teleport cards (such as clown planet coordinates.)
|
||||
//Setting this to 1 will set src.locked to null after a player enters the portal and will not allow hand-teles to open portals to that location.
|
||||
var/obj/machinery/teleport/station/power_station /// The power station that's connected to the console
|
||||
var/calibrating = FALSE /// Whether calibration is in progress or not. Calibration prevents changes.
|
||||
var/turf/target ///The target turf of the teleporter
|
||||
var/target_list ///lists of suitable teleport targets, dependent on regime. Used in the UI
|
||||
|
||||
/* var/area_bypass is for one-time-use teleport cards (such as clown planet coordinates.)
|
||||
Setting this to TRUE will set var/obj/item/gps/locked to null after a player enters the portal and will not allow hand-teles to open portals to that location.
|
||||
*/
|
||||
var/area_bypass = FALSE
|
||||
var/cc_beacon = FALSE
|
||||
|
||||
@@ -24,6 +32,7 @@
|
||||
..()
|
||||
link_power_station()
|
||||
update_icon()
|
||||
target_list = targets_teleport()
|
||||
|
||||
/obj/machinery/computer/teleporter/Destroy()
|
||||
if(power_station)
|
||||
@@ -55,202 +64,238 @@
|
||||
|
||||
/obj/machinery/computer/teleporter/emag_act(mob/user)
|
||||
if(!emagged)
|
||||
emagged = 1
|
||||
emagged = TRUE
|
||||
to_chat(user, "<span class='notice'>The teleporter can now lock on to Syndicate beacons!</span>")
|
||||
else
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/teleporter/attack_ai(mob/user)
|
||||
src.attack_hand(user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/machinery/computer/teleporter/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
|
||||
/obj/machinery/computer/teleporter/tgui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
// Set up the Nano UI
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "teleporter_console.tmpl", "Teleporter Console UI", 400, 400)
|
||||
ui = new(user, src, ui_key, "Teleporter", "Teleporter Console", 380, 260)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/teleporter/ui_data(mob/user, ui_key = "main", datum/topic_state/state = GLOB.default_state)
|
||||
var/data[0]
|
||||
/obj/machinery/computer/teleporter/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["powerstation"] = power_station
|
||||
if(power_station?.teleporter_hub)
|
||||
data["teleporterhub"] = power_station.teleporter_hub
|
||||
data["calibrated"] = power_station.teleporter_hub.calibrated
|
||||
data["accurate"] = power_station.teleporter_hub.accurate
|
||||
else
|
||||
data["teleporterhub"] = null
|
||||
data["calibrated"] = null
|
||||
data["accurate"] = null
|
||||
data["regime"] = regime_set
|
||||
data["regime"] = regime
|
||||
var/area/targetarea = get_area(target)
|
||||
data["target"] = (!target || !targetarea) ? "None" : sanitize(targetarea.name)
|
||||
data["calibrating"] = calibrating
|
||||
data["locked"] = locked
|
||||
data["locked"] = locked ? TRUE : FALSE
|
||||
data["targetsTeleport"] = target_list
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/teleporter/Topic(href, href_list)
|
||||
/obj/machinery/computer/teleporter/tgui_act(action, params)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["eject"])
|
||||
eject()
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
|
||||
if(!check_hub_connection())
|
||||
to_chat(usr, "<span class='warning'>Error: Unable to detect hub.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
atom_say("Error: Unable to detect hub.")
|
||||
return
|
||||
if(calibrating)
|
||||
to_chat(usr, "<span class='warning'>Error: Calibration in progress. Stand by.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
atom_say("Error: Calibration in progress. Stand by.")
|
||||
return
|
||||
|
||||
if(href_list["regimeset"])
|
||||
power_station.engaged = 0
|
||||
power_station.teleporter_hub.update_icon()
|
||||
power_station.teleporter_hub.calibrated = 0
|
||||
reset_regime()
|
||||
SSnanoui.update_uis(src)
|
||||
if(href_list["settarget"])
|
||||
power_station.engaged = 0
|
||||
power_station.teleporter_hub.update_icon()
|
||||
power_station.teleporter_hub.calibrated = 0
|
||||
set_target(usr)
|
||||
SSnanoui.update_uis(src)
|
||||
if(href_list["lock"])
|
||||
power_station.engaged = 0
|
||||
power_station.teleporter_hub.update_icon()
|
||||
power_station.teleporter_hub.calibrated = 0
|
||||
target = get_turf(locked.locked_location)
|
||||
SSnanoui.update_uis(src)
|
||||
if(href_list["calibrate"])
|
||||
if(!target)
|
||||
to_chat(usr, "<span class='warning'>Error: No target set to calibrate to.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3)
|
||||
to_chat(usr, "<span class='notice'>Hub is already calibrated.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
return
|
||||
src.visible_message("<span class='notice'>Processing hub calibration to target...</span>")
|
||||
. = TRUE
|
||||
|
||||
calibrating = 1
|
||||
SSnanoui.update_uis(src)
|
||||
spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration
|
||||
calibrating = 0
|
||||
if(check_hub_connection())
|
||||
power_station.teleporter_hub.calibrated = 1
|
||||
src.visible_message("<span class='notice'>Calibration complete.</span>")
|
||||
else
|
||||
src.visible_message("<span class='warning'>Error: Unable to detect hub.</span>")
|
||||
SSnanoui.update_uis(src)
|
||||
switch(action)
|
||||
if("eject") //eject gps device
|
||||
eject()
|
||||
if("load") //load gps coordinates
|
||||
target = locate(locked.locked_location.x,locked.locked_location.y,locked.locked_location.z)
|
||||
if("setregime")
|
||||
regime = text2num(params["regime"])
|
||||
if(regime == REGIME_TELEPORT)
|
||||
target_list = targets_teleport()
|
||||
if(regime == REGIME_GATE)
|
||||
target_list = targets_gate()
|
||||
if(regime == REGIME_GPS)
|
||||
target_list = null //clears existing entries, target is added by load action
|
||||
resetPowerstation()
|
||||
target = null
|
||||
if("settarget")
|
||||
resetPowerstation()
|
||||
var/turf/tmpTarget = locate(text2num(params["x"]),text2num(params["y"]),text2num(params["z"]))
|
||||
if(!istype(tmpTarget, /turf))
|
||||
atom_say("No valid targets available.")
|
||||
return
|
||||
target = tmpTarget
|
||||
if(regime == REGIME_TELEPORT)
|
||||
teleport_helper()
|
||||
if(regime == REGIME_GATE)
|
||||
gate_helper()
|
||||
if("calibrate")
|
||||
if(!target)
|
||||
atom_say("Error: No target set to calibrate to.")
|
||||
return
|
||||
if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accurate >= 3)
|
||||
atom_say("Hub is already calibrated.")
|
||||
return
|
||||
|
||||
SSnanoui.update_uis(src)
|
||||
atom_say("Processing hub calibration to target...")
|
||||
calibrating = TRUE
|
||||
addtimer(CALLBACK(src, .proc/calibrateCallback), 50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration
|
||||
|
||||
/**
|
||||
* Resets the connected powerstation to initial values. Helper function of tgui_act
|
||||
*/
|
||||
/obj/machinery/computer/teleporter/proc/resetPowerstation()
|
||||
power_station.engaged = FALSE
|
||||
power_station.teleporter_hub.calibrated = FALSE
|
||||
power_station.teleporter_hub.update_icon()
|
||||
|
||||
/**
|
||||
* Calibrates the hub. Helper function of tgui_act
|
||||
*/
|
||||
/obj/machinery/computer/teleporter/proc/calibrateCallback()
|
||||
calibrating = FALSE
|
||||
if(check_hub_connection())
|
||||
power_station.teleporter_hub.calibrated = TRUE
|
||||
atom_say("Calibration complete.")
|
||||
else
|
||||
atom_say("Error: Unable to detect hub.")
|
||||
|
||||
/obj/machinery/computer/teleporter/proc/check_hub_connection()
|
||||
if(!power_station)
|
||||
return
|
||||
if(!power_station.teleporter_hub)
|
||||
return
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/teleporter/proc/reset_regime()
|
||||
target = null
|
||||
if(regime_set == "Teleporter")
|
||||
regime_set = "Gate"
|
||||
else
|
||||
regime_set = "Teleporter"
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Helper function of tgui_act
|
||||
*
|
||||
* Triggered when ejecting a gps device. Sets the gps to the ground and resets the console
|
||||
*/
|
||||
/obj/machinery/computer/teleporter/proc/eject()
|
||||
if(locked)
|
||||
locked.loc = loc
|
||||
locked = null
|
||||
regime = REGIME_TELEPORT
|
||||
target_list = targets_teleport()
|
||||
|
||||
/obj/machinery/computer/teleporter/proc/set_target(mob/user)
|
||||
area_bypass = FALSE
|
||||
if(regime_set == "Teleporter")
|
||||
var/list/L = list()
|
||||
var/list/areaindex = list()
|
||||
/**
|
||||
* Creates a list of viable targets for the teleport. Helper function of tgui_data
|
||||
*/
|
||||
/obj/machinery/computer/teleporter/proc/targets_teleport()
|
||||
var/list/L = list()
|
||||
var/list/areaindex = list()
|
||||
|
||||
for(var/obj/item/radio/beacon/R in GLOB.beacons)
|
||||
var/turf/T = get_turf(R)
|
||||
if(!T)
|
||||
continue
|
||||
if(!is_teleport_allowed(T.z) && !R.cc_beacon)
|
||||
continue
|
||||
if(R.syndicate == 1 && emagged == 0)
|
||||
continue
|
||||
var/tmpname = T.loc.name
|
||||
for(var/obj/item/radio/beacon/R in GLOB.beacons)
|
||||
var/turf/T = get_turf(R)
|
||||
if(!T)
|
||||
continue
|
||||
if(!is_teleport_allowed(T.z) && !R.cc_beacon)
|
||||
continue
|
||||
if(R.syndicate && !emagged)
|
||||
continue
|
||||
var/tmpname = T.loc.name
|
||||
if(areaindex[tmpname])
|
||||
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
||||
else
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = list(
|
||||
"name" = tmpname,
|
||||
"x" = T.x,
|
||||
"y" = T.y,
|
||||
"z" = T.z)
|
||||
|
||||
for(var/obj/item/implant/tracking/I in GLOB.tracked_implants)
|
||||
if(!I.implanted || !ismob(I.loc))
|
||||
continue
|
||||
else
|
||||
var/mob/M = I.loc
|
||||
if(M.stat == DEAD)
|
||||
if(M.timeofdeath + 6000 < world.time)
|
||||
continue
|
||||
var/turf/T = get_turf(M)
|
||||
if(!T) continue
|
||||
if(!is_teleport_allowed(T.z)) continue
|
||||
var/tmpname = M.real_name
|
||||
if(areaindex[tmpname])
|
||||
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
||||
else
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = R
|
||||
L[tmpname] = list(
|
||||
"name" = tmpname,
|
||||
"x" = T.x,
|
||||
"y" = T.y,
|
||||
"z" = T.z)
|
||||
return L
|
||||
|
||||
for(var/obj/item/implant/tracking/I in GLOB.tracked_implants)
|
||||
if(!I.implanted || !ismob(I.loc))
|
||||
continue
|
||||
else
|
||||
var/mob/M = I.loc
|
||||
if(M.stat == DEAD)
|
||||
if(M.timeofdeath + 6000 < world.time)
|
||||
continue
|
||||
var/turf/T = get_turf(M)
|
||||
if(!T) continue
|
||||
if(!is_teleport_allowed(T.z)) continue
|
||||
var/tmpname = M.real_name
|
||||
if(areaindex[tmpname])
|
||||
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
||||
else
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = I
|
||||
/**
|
||||
* Creates a list of viable targets for the gate. Helper function of tgui_data
|
||||
*/
|
||||
/obj/machinery/computer/teleporter/proc/targets_gate(mob/users)
|
||||
var/list/L = list()
|
||||
var/list/areaindex = list()
|
||||
var/list/S = power_station.linked_stations
|
||||
if(!S.len)
|
||||
return L
|
||||
for(var/obj/machinery/teleport/station/R in S)
|
||||
var/turf/T = get_turf(R)
|
||||
if(!T || !R.teleporter_hub || !R.teleporter_console)
|
||||
continue
|
||||
if(!is_teleport_allowed(T.z))
|
||||
continue
|
||||
var/tmpname = T.loc.name
|
||||
if(areaindex[tmpname])
|
||||
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
||||
else
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = list(
|
||||
"name" = tmpname,
|
||||
"x" = T.x,
|
||||
"y" = T.y,
|
||||
"z" = T.z)
|
||||
return L
|
||||
|
||||
var/desc = input("Please select a location to lock in.", "Locking Computer") in L
|
||||
target = L[desc]
|
||||
if(istype(target, /obj/item/radio/beacon))
|
||||
var/obj/item/radio/beacon/B = target
|
||||
/**
|
||||
* Helper function of tgui_act.
|
||||
*
|
||||
* Called after selecting a target for the gate in the UI. Sets area_bypass and cc_beacon.
|
||||
*/
|
||||
/obj/machinery/computer/teleporter/proc/teleport_helper()
|
||||
area_bypass = FALSE
|
||||
for(var/item in target.contents)
|
||||
if(istype(item, /obj/item/radio/beacon))
|
||||
var/obj/item/radio/beacon/B = item
|
||||
if(B.area_bypass)
|
||||
area_bypass = TRUE
|
||||
cc_beacon = B.cc_beacon
|
||||
else
|
||||
var/list/L = list()
|
||||
var/list/areaindex = list()
|
||||
var/list/S = power_station.linked_stations
|
||||
if(!S.len)
|
||||
to_chat(user, "<span class='alert'>No connected stations located.</span>")
|
||||
return
|
||||
for(var/obj/machinery/teleport/station/R in S)
|
||||
var/turf/T = get_turf(R)
|
||||
if(!T || !R.teleporter_hub || !R.teleporter_console)
|
||||
continue
|
||||
if(!is_teleport_allowed(T.z))
|
||||
continue
|
||||
var/tmpname = T.loc.name
|
||||
if(areaindex[tmpname])
|
||||
tmpname = "[tmpname] ([++areaindex[tmpname]])"
|
||||
else
|
||||
areaindex[tmpname] = 1
|
||||
L[tmpname] = R
|
||||
var/desc = input("Please select a station to lock in.", "Locking Computer") in L
|
||||
target = L[desc]
|
||||
if(target)
|
||||
var/obj/machinery/teleport/station/trg = target
|
||||
trg.linked_stations |= power_station
|
||||
trg.stat &= ~NOPOWER
|
||||
if(trg.teleporter_hub)
|
||||
trg.teleporter_hub.stat &= ~NOPOWER
|
||||
trg.teleporter_hub.update_icon()
|
||||
if(trg.teleporter_console)
|
||||
trg.teleporter_console.stat &= ~NOPOWER
|
||||
trg.teleporter_console.update_icon()
|
||||
return
|
||||
|
||||
/**
|
||||
* Helper function of tgui_act.
|
||||
*
|
||||
* Called after selecting a target for the teleporter in the UI.
|
||||
*/
|
||||
/obj/machinery/computer/teleporter/proc/gate_helper()
|
||||
area_bypass = FALSE
|
||||
var/obj/machinery/teleport/station/trg = target
|
||||
trg.linked_stations |= power_station
|
||||
trg.stat &= ~NOPOWER
|
||||
if(trg.teleporter_hub)
|
||||
trg.teleporter_hub.stat &= ~NOPOWER
|
||||
trg.teleporter_hub.update_icon()
|
||||
if(trg.teleporter_console)
|
||||
trg.teleporter_console.stat &= ~NOPOWER
|
||||
trg.teleporter_console.update_icon()
|
||||
|
||||
/proc/find_loc(obj/R as obj)
|
||||
if(!R) return null
|
||||
@@ -263,20 +308,20 @@
|
||||
/obj/machinery/teleport
|
||||
name = "teleport"
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
|
||||
/obj/machinery/teleport/hub
|
||||
name = "teleporter hub"
|
||||
desc = "It's the hub of a teleporting machine."
|
||||
icon_state = "tele0"
|
||||
var/accurate = 0
|
||||
var/accurate = FALSE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 2000
|
||||
var/obj/machinery/teleport/station/power_station
|
||||
var/calibrated //Calibration prevents mutation
|
||||
var/admin_usage = 0 // if 1, works on z2. If 0, doesn't. Used for admin room teleport.
|
||||
var/admin_usage = FALSE // if 1, works on z2. If 0, doesn't. Used for admin room teleport.
|
||||
|
||||
/obj/machinery/teleport/hub/New()
|
||||
..()
|
||||
@@ -317,6 +362,7 @@
|
||||
for(dir in list(NORTH,EAST,SOUTH,WEST))
|
||||
power_station = locate(/obj/machinery/teleport/station, get_step(src, dir))
|
||||
if(power_station)
|
||||
power_station.link_console_and_hub()
|
||||
break
|
||||
return power_station
|
||||
|
||||
@@ -324,27 +370,12 @@
|
||||
if(!is_teleport_allowed(z) && !admin_usage)
|
||||
to_chat(M, "You can't use this here.")
|
||||
return
|
||||
if(power_station && power_station.engaged && !panel_open)
|
||||
//--FalseIncarnate
|
||||
//Prevents AI cores from using the teleporter, prints out failure messages for clarity
|
||||
if(istype(M, /mob/living/silicon/ai) || istype(M, /obj/structure/AIcore))
|
||||
visible_message("<span class='warning'>The teleporter rejects the AI unit.</span>")
|
||||
if(istype(M, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/T = M
|
||||
var/list/TPError = list("<span class='warning'>Firmware instructions dictate you must remain on your assigned station!</span>",
|
||||
"<span class='warning'>You cannot interface with this technology and get rejected!</span>",
|
||||
"<span class='warning'>External firewalls prevent you from utilizing this machine!</span>",
|
||||
"<span class='warning'>Your AI core's anti-bluespace failsafes trigger and prevent teleportation!</span>")
|
||||
to_chat(T, "[pick(TPError)]")
|
||||
return
|
||||
else
|
||||
if(!teleport(M) && isliving(M)) // the isliving(M) is needed to avoid triggering errors if a spark bumps the telehub
|
||||
visible_message("<span class='warning'>[src] emits a loud buzz, as its teleport portal flickers and fails!</span>")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
|
||||
power_station.toggle() // turn off the portal.
|
||||
|
||||
use_power(5000)
|
||||
//--FalseIncarnate
|
||||
if(power_station && power_station.engaged && !panel_open && !blockAI(M) && !istype(M, /obj/spacepod))
|
||||
if(!teleport(M) && isliving(M)) // the isliving(M) is needed to avoid triggering errors if a spark bumps the telehub
|
||||
visible_message("<span class='warning'>[src] emits a loud buzz, as its teleport portal flickers and fails!</span>")
|
||||
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
|
||||
power_station.toggle() // turn off the portal.
|
||||
use_power(5000)
|
||||
return
|
||||
|
||||
/obj/machinery/teleport/hub/attackby(obj/item/I, mob/user, params)
|
||||
@@ -375,7 +406,7 @@
|
||||
. = do_teleport(M, locate(rand((2*TRANSITIONEDGE), world.maxx - (2*TRANSITIONEDGE)), rand((2*TRANSITIONEDGE), world.maxy - (2*TRANSITIONEDGE)), 3), 2, bypass_area_flag = com.area_bypass)
|
||||
else
|
||||
. = do_teleport(M, com.target, bypass_area_flag = com.area_bypass)
|
||||
calibrated = 0
|
||||
calibrated = FALSE
|
||||
|
||||
/obj/machinery/teleport/hub/update_icon()
|
||||
if(panel_open)
|
||||
@@ -389,7 +420,7 @@
|
||||
name = "permanent teleporter"
|
||||
desc = "A teleporter with the target pre-set on the circuit board."
|
||||
icon_state = "tele0"
|
||||
var/recalibrating = 0
|
||||
var/recalibrating = FALSE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 2000
|
||||
@@ -406,37 +437,42 @@
|
||||
tele_delay = max(A, 0)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/teleport/perma/Bumped(M as mob|obj)
|
||||
/**
|
||||
Internal helper function
|
||||
|
||||
Prevents AI from using the teleporter, prints out failure messages for clarity
|
||||
*/
|
||||
/obj/machinery/teleport/proc/blockAI(atom/A)
|
||||
if(istype(A, /mob/living/silicon/ai) || istype(A, /obj/structure/AIcore))
|
||||
visible_message("<span class='warning'>The teleporter rejects the AI unit.</span>")
|
||||
if(istype(A, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/T = A
|
||||
var/list/TPError = list("<span class='warning'>Firmware instructions dictate you must remain on your assigned station!</span>",
|
||||
"<span class='warning'>You cannot interface with this technology and get rejected!</span>",
|
||||
"<span class='warning'>External firewalls prevent you from utilizing this machine!</span>",
|
||||
"<span class='warning'>Your AI core's anti-bluespace failsafes trigger and prevent teleportation!</span>")
|
||||
to_chat(T, "[pick(TPError)]")
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/teleport/perma/Bumped(atom/A)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
if(!is_teleport_allowed(z))
|
||||
to_chat(M, "You can't use this here.")
|
||||
to_chat(A, "You can't use this here.")
|
||||
return
|
||||
if(target && !recalibrating && !panel_open)
|
||||
//--FalseIncarnate
|
||||
//Prevents AI cores from using the teleporter, prints out failure messages for clarity
|
||||
if(istype(M, /mob/living/silicon/ai) || istype(M, /obj/structure/AIcore))
|
||||
visible_message("<span class='warning'>The teleporter rejects the AI unit.</span>")
|
||||
if(istype(M, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/T = M
|
||||
var/list/TPError = list("<span class='warning'>Firmware instructions dictate you must remain on your assigned station!</span>",
|
||||
"<span class='warning'>You cannot interface with this technology and get rejected!</span>",
|
||||
"<span class='warning'>External firewalls prevent you from utilizing this machine!</span>",
|
||||
"<span class='warning'>Your AI core's anti-bluespace failsafes trigger and prevent teleportation!</span>")
|
||||
to_chat(T, "[pick(TPError)]")
|
||||
return
|
||||
else
|
||||
do_teleport(M, target)
|
||||
use_power(5000)
|
||||
|
||||
if(tele_delay)
|
||||
recalibrating = 1
|
||||
update_icon()
|
||||
spawn(tele_delay)
|
||||
recalibrating = 0
|
||||
update_icon()
|
||||
//--FalseIncarnate
|
||||
return
|
||||
if(target && !recalibrating && !panel_open && !blockAI(A))
|
||||
do_teleport(A, target)
|
||||
use_power(5000)
|
||||
if(tele_delay)
|
||||
recalibrating = TRUE
|
||||
update_icon()
|
||||
addtimer(CALLBACK(src, .proc/BumpedCallback), tele_delay)
|
||||
|
||||
/obj/machinery/teleport/perma/proc/BumpedCallback()
|
||||
recalibrating = FALSE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/teleport/perma/power_change()
|
||||
..()
|
||||
@@ -467,7 +503,7 @@
|
||||
name = "station"
|
||||
desc = "The power control station for a bluespace teleporter."
|
||||
icon_state = "controller"
|
||||
var/engaged = 0
|
||||
var/engaged = FALSE
|
||||
use_power = IDLE_POWER_USE
|
||||
idle_power_usage = 10
|
||||
active_power_usage = 2000
|
||||
@@ -568,7 +604,7 @@
|
||||
|
||||
|
||||
/obj/machinery/teleport/station/attack_ai()
|
||||
src.attack_hand()
|
||||
attack_hand()
|
||||
|
||||
/obj/machinery/teleport/station/attack_hand(mob/user)
|
||||
if(!panel_open)
|
||||
@@ -583,12 +619,12 @@
|
||||
to_chat(user, "<span class='notice'>Close the hub's maintenance panel first.</span>")
|
||||
return
|
||||
if(teleporter_console.target)
|
||||
src.engaged = !src.engaged
|
||||
engaged = !engaged
|
||||
use_power(5000)
|
||||
visible_message("<span class='notice'>Teleporter [engaged ? "" : "dis"]engaged!</span>")
|
||||
else
|
||||
visible_message("<span class='alert'>No target detected.</span>")
|
||||
src.engaged = 0
|
||||
engaged = FALSE
|
||||
teleporter_hub.update_icon()
|
||||
if(istype(user))
|
||||
add_fingerprint(user)
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
set_ready_state(0)
|
||||
log_message("Fired from [name], targeting [target].")
|
||||
var/turf/T = get_turf(src)
|
||||
msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])")
|
||||
add_attack_logs(chassis.occupant, target, "fired a [src]", ATKLOG_FEW)
|
||||
log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]")
|
||||
do_after_cooldown()
|
||||
return
|
||||
@@ -238,7 +238,7 @@
|
||||
chassis.use_power(energy_drain)
|
||||
log_message("Honked from [name]. HONK!")
|
||||
var/turf/T = get_turf(src)
|
||||
msg_admin_attack("[key_name_admin(chassis.occupant)] used a Mecha Honker in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])")
|
||||
add_attack_logs(chassis.occupant, target, "used a Mecha Honker", ATKLOG_MOST)
|
||||
log_game("[key_name(chassis.occupant)] used a Mecha Honker in [T.x], [T.y], [T.z]")
|
||||
do_after_cooldown()
|
||||
return
|
||||
@@ -357,7 +357,7 @@
|
||||
projectiles--
|
||||
log_message("Fired from [name], targeting [target].")
|
||||
var/turf/T = get_turf(src)
|
||||
msg_admin_attack("[key_name_admin(chassis.occupant)] fired a [src] in ([T.x], [T.y], [T.z] - [ADMIN_JMP(T)])")
|
||||
add_attack_logs(chassis.occupant, target, "fired a [src]", ATKLOG_FEW)
|
||||
log_game("[key_name(chassis.occupant)] fired a [src] in [T.x], [T.y], [T.z]")
|
||||
do_after_cooldown()
|
||||
return
|
||||
|
||||
@@ -481,7 +481,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
|
||||
var/more = ""
|
||||
if(M)
|
||||
more = " "
|
||||
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1)
|
||||
add_attack_logs(M, location, "Caused a chemical smoke reaction containing [contained]. Last associated key is [carry.my_atom.fingerprintslast][more]", ATKLOG_FEW)
|
||||
log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].")
|
||||
else
|
||||
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1)
|
||||
|
||||
@@ -83,13 +83,13 @@
|
||||
var/more = ""
|
||||
if(M)
|
||||
more = " "
|
||||
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", ATKLOG_FEW)
|
||||
add_attack_logs(M, location, "Caused a chemical smoke reaction containing [contained]. Last associated key is [carry.my_atom.fingerprintslast][more]", ATKLOG_FEW)
|
||||
log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].")
|
||||
else
|
||||
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", ATKLOG_FEW)
|
||||
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. No associated key.", ATKLOG_FEW)
|
||||
log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.")
|
||||
else
|
||||
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink]). No associated key. CODERS: carry.my_atom may be null.", ATKLOG_FEW)
|
||||
msg_admin_attack("A chemical smoke reaction has taken place in ([whereLink])[contained]. No associated key. CODERS: carry.my_atom may be null.", ATKLOG_FEW)
|
||||
log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key. CODERS: carry.my_atom may be null.")
|
||||
|
||||
|
||||
|
||||
@@ -83,8 +83,7 @@
|
||||
if(href_list["wipe"])
|
||||
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", "Confirm Wipe", "Yes", "No")
|
||||
if(confirm == "Yes" && (CanUseTopic(user, state) == STATUS_INTERACTIVE))
|
||||
msg_admin_attack("[key_name_admin(user)] wiped [key_name_admin(AI)] with \the [src].", ATKLOG_FEW)
|
||||
add_attack_logs(user, AI, "Wiped with [src].")
|
||||
add_attack_logs(user, AI, "Wiped with [src].", ATKLOG_FEW)
|
||||
flush = 1
|
||||
AI.suiciding = 1
|
||||
to_chat(AI, "Your core files are being wiped!")
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
|
||||
|
||||
investigate_log("[key_name(user)] attached a [A] to a transfer valve.", INVESTIGATE_BOMB)
|
||||
msg_admin_attack("[key_name_admin(user)]attached [A] to a transfer valve.", ATKLOG_FEW)
|
||||
add_attack_logs(user, src, "attached [A] to a transfer valve", ATKLOG_FEW)
|
||||
log_game("[key_name_admin(user)] attached [A] to a transfer valve.")
|
||||
attacher = user
|
||||
SSnanoui.update_uis(src) // update all UIs attached to src
|
||||
@@ -128,7 +128,7 @@
|
||||
if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
if("toggle")
|
||||
toggle_valve()
|
||||
toggle_valve(usr)
|
||||
if("device")
|
||||
if(attached_device)
|
||||
attached_device.attack_self(usr)
|
||||
@@ -190,7 +190,7 @@
|
||||
it explodes properly when it gets a signal (and it does).
|
||||
*/
|
||||
|
||||
/obj/item/transfer_valve/proc/toggle_valve()
|
||||
/obj/item/transfer_valve/proc/toggle_valve(mob/user)
|
||||
if(!valve_open && tank_one && tank_two)
|
||||
valve_open = 1
|
||||
var/turf/bombturf = get_turf(src)
|
||||
@@ -207,6 +207,8 @@
|
||||
investigate_log("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", INVESTIGATE_BOMB)
|
||||
message_admins("Bomb valve opened at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name_admin(mob)]")
|
||||
log_game("Bomb valve opened at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]")
|
||||
if(user)
|
||||
add_attack_logs(user, src, "Bomb valve opened with [attached_device ? attached_device : "no device"], attached by [attacher_name]. Last touched by: [key_name(mob)]", ATKLOG_FEW)
|
||||
merge_gases()
|
||||
spawn(20) // In case one tank bursts
|
||||
for(var/i in 1 to 5)
|
||||
|
||||
@@ -242,15 +242,15 @@
|
||||
to_chat(user, "<span class='notice'>You hide [I] in the [src]. It will detonate some time after the flag is lit on fire.</span>")
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
message_admins("[key_name_admin(user)] has hidden [I] in the [src] ready for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
log_game("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
|
||||
investigate_log("[key_name(user)] has hidden [I] in the [src] ready for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has hidden [I] ready for detonation in", ATKLOG_MOST)
|
||||
else if(is_hot(I) && !(resistance_flags & ON_FIRE) && boobytrap && trapper)
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
message_admins("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>.")
|
||||
log_game("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).")
|
||||
investigate_log("[key_name_admin(user)] has lit the [src] trapped with [boobytrap] by [key_name_admin(trapper)] at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]).", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has lit (booby trapped with [boobytrap]", ATKLOG_FEW)
|
||||
burn()
|
||||
else
|
||||
return ..()
|
||||
|
||||
@@ -189,8 +189,8 @@
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
investigate_log("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]", INVESTIGATE_BOMB)
|
||||
message_admins("E20 detonated at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> with a roll of [result]. Triggered by: [key_name_admin(user)]")
|
||||
log_game("E20 detonated at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) with a roll of [result]. Triggered by: [key_name(user)]")
|
||||
add_attack_logs(user, src, "detonated with a roll of [result]", ATKLOG_FEW)
|
||||
|
||||
|
||||
/obj/item/dice/update_icon()
|
||||
|
||||
@@ -101,9 +101,9 @@
|
||||
update_icon()
|
||||
else if(clown_check(user))
|
||||
// This used to go before the assembly check, but that has absolutely zero to do with priming the damn thing. You could spam the admins with it.
|
||||
message_admins("[key_name_admin(usr)] has primed a [name] for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> [contained].")
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z]) [contained].")
|
||||
investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])[contained].", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has primed (contained [contained])", ATKLOG_FEW)
|
||||
to_chat(user, "<span class='warning'>You prime the [name]! [det_time / 10] second\s!</span>")
|
||||
playsound(user.loc, 'sound/weapons/armbomb.ogg', 60, 1)
|
||||
active = 1
|
||||
@@ -120,7 +120,7 @@
|
||||
owner.visible_message("<span class='danger'>[attack_text] hits [owner]'s [src], setting it off! What a shot!</span>")
|
||||
var/turf/T = get_turf(src)
|
||||
log_game("A projectile ([hitby]) detonated a grenade held by [key_name(owner)] at [COORD(T)]")
|
||||
message_admins("A projectile ([hitby]) detonated a grenade held by [key_name_admin(owner)] at [ADMIN_COORDJMP(T)]")
|
||||
add_attack_logs(P.firer, owner, "A projectile ([hitby]) detonated a grenade held", ATKLOG_FEW)
|
||||
prime()
|
||||
return 1 //It hit the grenade, not them
|
||||
|
||||
@@ -149,16 +149,16 @@
|
||||
if(!O.reagents) continue
|
||||
if(istype(O,/obj/item/slime_extract))
|
||||
cores += " [O]"
|
||||
for(var/reagent in O.reagents.reagent_list)
|
||||
contained += " [reagent] "
|
||||
for(var/R in O.reagents.reagent_list)
|
||||
var/datum/reagent/reagent = R
|
||||
contained += "[reagent.volume] [reagent], "
|
||||
if(contained)
|
||||
if(cores)
|
||||
contained = "\[[cores];[contained]\]"
|
||||
contained = "\[[cores]; [contained]\]"
|
||||
else
|
||||
contained = "\[[contained]\]"
|
||||
contained = "\[ [contained]\]"
|
||||
var/turf/bombturf = get_turf(loc)
|
||||
var/area/A = bombturf.loc
|
||||
message_admins("[key_name_admin(usr)] has completed [name] at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a> [contained].")
|
||||
add_attack_logs(user, src, "has completed with [contained]", ATKLOG_MOST)
|
||||
log_game("[key_name(usr)] has completed [name] at [bombturf.x], [bombturf.y], [bombturf.z]. [contained]")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You need to add at least one beaker before locking the assembly.</span>")
|
||||
|
||||
@@ -48,9 +48,9 @@
|
||||
var/turf/bombturf = get_turf(src)
|
||||
var/area/A = get_area(bombturf)
|
||||
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] has primed a [name] for detonation at [ADMIN_COORDJMP(bombturf)].")
|
||||
log_game("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)].")
|
||||
investigate_log("[key_name(user)] has primed a [name] for detonation at [A.name] [COORD(bombturf)])", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
message_admins("[key_name_admin(usr)] has primed a [name] for detonation at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[bombturf.x];Y=[bombturf.y];Z=[bombturf.z]'>[A.name] (JMP)</a>")
|
||||
log_game("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])")
|
||||
investigate_log("[key_name(usr)] has primed a [name] for detonation at [A.name] ([bombturf.x],[bombturf.y],[bombturf.z])", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has primed for detonation", ATKLOG_FEW)
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
C.throw_mode_on()
|
||||
|
||||
@@ -310,6 +310,18 @@
|
||||
item_state = "utility"
|
||||
use_item_overlays = 1 // So it will still show tools in it in case sec get lazy and just glance at it.
|
||||
|
||||
/obj/item/storage/belt/military/traitor/hacker
|
||||
|
||||
/obj/item/storage/belt/military/traitor/hacker/New()
|
||||
..()
|
||||
new /obj/item/screwdriver(src, "red")
|
||||
new /obj/item/wrench(src)
|
||||
new /obj/item/weldingtool/largetank(src)
|
||||
new /obj/item/crowbar/red(src)
|
||||
new /obj/item/wirecutters(src, "red")
|
||||
new /obj/item/stack/cable_coil(src, 30, COLOR_RED)
|
||||
update_icon()
|
||||
|
||||
/obj/item/storage/belt/grenade
|
||||
name = "grenadier belt"
|
||||
desc = "A belt for holding grenades."
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/obj/item/storage/box/syndicate/New()
|
||||
..()
|
||||
switch(pickweight(list("bloodyspai" = 1, "thief" = 1, "bond" = 1, "sabotage" = 1, "payday" = 1, "implant" = 1, "hacker" = 1, "darklord" = 1, "professional" = 1)))
|
||||
if("bloodyspai") // 35TC + one 0TC
|
||||
if("bloodyspai") // 37TC + one 0TC
|
||||
new /obj/item/clothing/under/chameleon(src) // 2TC
|
||||
new /obj/item/clothing/mask/chameleon(src) // 0TC
|
||||
new /obj/item/card/id/syndicate(src) // 2TC
|
||||
@@ -14,12 +14,12 @@
|
||||
new /obj/item/storage/fancy/cigarettes/cigpack_syndicate(src) // 2TC
|
||||
new /obj/item/flashlight/emp(src) // 2TC
|
||||
new /obj/item/clothing/glasses/hud/security/chameleon(src) // 2TC
|
||||
new /obj/item/chameleon(src) // 8TC
|
||||
new /obj/item/chameleon(src) // 7TC
|
||||
return
|
||||
|
||||
if("thief") // 40TC
|
||||
if("thief") // 39TC
|
||||
new /obj/item/gun/energy/kinetic_accelerator/crossbow(src) // 12TC
|
||||
new /obj/item/chameleon(src) // 8TC
|
||||
new /obj/item/chameleon(src) // 7TC
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
|
||||
new /obj/item/clothing/gloves/color/black/thief(src) // 6TC
|
||||
new /obj/item/card/id/syndicate(src) // 2TC
|
||||
@@ -43,7 +43,7 @@
|
||||
new /obj/item/CQC_manual(src) // 13TC
|
||||
return
|
||||
|
||||
if("sabotage") // 47TC + three 0TC
|
||||
if("sabotage") // 41TC + two 0TC
|
||||
new /obj/item/grenade/plastic/c4(src) // 1TC
|
||||
new /obj/item/grenade/plastic/c4(src) // 1TC
|
||||
new /obj/item/camera_bug(src) // 1TC
|
||||
@@ -53,23 +53,23 @@
|
||||
new /obj/item/card/emag(src) // 6TC
|
||||
new /obj/item/clothing/gloves/color/yellow(src) // 0TC
|
||||
new /obj/item/grenade/syndieminibomb(src) // 6TC
|
||||
new /obj/item/grenade/clusterbuster/n2o(src) // 0TC
|
||||
new /obj/item/grenade/clusterbuster/n2o(src) // 4TC
|
||||
new /obj/item/storage/box/syndie_kit/space(src) // 4TC
|
||||
new /obj/item/encryptionkey/syndicate(src) // 2TC
|
||||
return
|
||||
|
||||
if("payday") // 33TC + four 0TC
|
||||
if("payday") // 35TC + four 0TC
|
||||
new /obj/item/gun/projectile/revolver(src) // 13TC
|
||||
new /obj/item/ammo_box/a357(src) // 3TC
|
||||
new /obj/item/ammo_box/a357(src) // 3TC
|
||||
new /obj/item/card/emag(src) // 6TC
|
||||
new /obj/item/grenade/plastic/c4(src) // 1TC
|
||||
new /obj/item/jammer(src) // 5TC
|
||||
new /obj/item/card/id/syndicate(src) // 2TC
|
||||
new /obj/item/clothing/under/suit_jacket/really_black(src) //0TC
|
||||
new /obj/item/clothing/suit/storage/lawyer/blackjacket/armored(src) //0TC
|
||||
new /obj/item/clothing/gloves/color/latex/nitrile(src) //0 TC
|
||||
new /obj/item/clothing/mask/gas/clown_hat(src) // 0TC
|
||||
new /obj/item/thermal_drill(src) // 3TC
|
||||
new /obj/item/thermal_drill/diamond_drill(src) // 1TC
|
||||
new /obj/item/encryptionkey/syndicate(src) // 2TC
|
||||
return
|
||||
|
||||
@@ -83,17 +83,20 @@
|
||||
new /obj/item/encryptionkey/syndicate(src) // 2TC
|
||||
return
|
||||
|
||||
if("hacker") // 30TC + one 0TC
|
||||
if("hacker") // 37TC + two 0TC
|
||||
new /obj/item/aiModule/syndicate(src) // 12TC
|
||||
new /obj/item/card/emag(src) // 6TC
|
||||
new /obj/item/encryptionkey/syndicate(src) // 2TC
|
||||
new /obj/item/encryptionkey/binary(src) // 5TC
|
||||
new /obj/item/aiModule/toyAI(src) // 0TC
|
||||
new /obj/item/clothing/glasses/chameleon/thermal(src) // 6TC
|
||||
new /obj/item/storage/belt/military/traitor/hacker(src) // 3TC
|
||||
new /obj/item/clothing/gloves/combat(src) // 0TC
|
||||
new /obj/item/multitool/ai_detect(src) // 1TC
|
||||
new /obj/item/storage/box/syndie_kit/c4 // 4TC
|
||||
new /obj/item/flashlight/emp(src) // 2TC
|
||||
return
|
||||
|
||||
if("darklord") // 22TC + two 0TC
|
||||
if("darklord") // 24TC + two 0TC
|
||||
new /obj/item/melee/energy/sword/saber/red(src) // 8TC
|
||||
new /obj/item/melee/energy/sword/saber/red(src) // 8TC
|
||||
new /obj/item/dnainjector/telemut/darkbundle(src) // 0TC
|
||||
@@ -104,7 +107,7 @@
|
||||
new /obj/item/encryptionkey/syndicate(src) // 2TC
|
||||
return
|
||||
|
||||
if("professional") // 32 TC + two 0TC
|
||||
if("professional") // 34TC + two 0TC
|
||||
new /obj/item/gun/projectile/automatic/sniper_rifle/syndicate/penetrator(src) // 16TC
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/penetrator(src) // 5TC
|
||||
new /obj/item/ammo_box/magazine/sniper_rounds/soporific(src) // 3TC
|
||||
|
||||
@@ -187,6 +187,7 @@
|
||||
if(user)
|
||||
to_chat(user, "<span class='danger'>The crate's anti-tamper system activates!</span>")
|
||||
investigate_log("[key_name(user)] has detonated a [src]", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "has detonated", ATKLOG_MOST)
|
||||
for(var/atom/movable/AM in src)
|
||||
qdel(AM)
|
||||
explosion(get_turf(src), 0, 1, 5, 5)
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
anchored = TRUE
|
||||
resistance_flags = FIRE_PROOF | LAVA_PROOF
|
||||
|
||||
var/gps = null
|
||||
var/obj/effect/light_emitter/tendril/emitted_light
|
||||
|
||||
/obj/structure/spawner/lavaland/goliath
|
||||
@@ -29,7 +28,6 @@ GLOBAL_LIST_INIT(tendrils, list())
|
||||
/obj/structure/spawner/lavaland/Initialize(mapload)
|
||||
. = ..()
|
||||
emitted_light = new(loc)
|
||||
gps = new /obj/item/gps/internal(src)
|
||||
GLOB.tendrils += src
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
@@ -59,7 +57,6 @@ GLOBAL_LIST_INIT(tendrils, list())
|
||||
SSmedals.SetScore(TENDRIL_CLEAR_SCORE, L.client, 1)
|
||||
GLOB.tendrils -= src
|
||||
QDEL_NULL(emitted_light)
|
||||
QDEL_NULL(gps)
|
||||
return ..()
|
||||
|
||||
/obj/effect/light_emitter/tendril
|
||||
|
||||
@@ -52,12 +52,13 @@
|
||||
if(!status)
|
||||
status = TRUE
|
||||
investigate_log("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB)
|
||||
msg_admin_attack("[key_name_admin(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW)
|
||||
log_game("[key_name(user)] welded a single tank bomb. Temperature: [bombtank.air_contents.temperature - T0C]")
|
||||
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. [bombtank] can now be ignited.</span>")
|
||||
add_attack_logs(user, src, "welded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_FEW)
|
||||
else
|
||||
status = FALSE
|
||||
investigate_log("[key_name(user)] unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", INVESTIGATE_BOMB)
|
||||
add_attack_logs(user, src, "unwelded a single tank bomb. Temperature: [bombtank.air_contents.temperature-T0C]", ATKLOG_ALMOSTALL)
|
||||
to_chat(user, "<span class='notice'>The hole has been closed.</span>")
|
||||
|
||||
|
||||
|
||||
@@ -101,8 +101,8 @@
|
||||
if(href_list["time"])
|
||||
timing = !timing
|
||||
if(timing && istype(holder, /obj/item/transfer_valve))
|
||||
message_admins("[key_name_admin(usr)] activated [src] attachment on [holder].")
|
||||
investigate_log("[key_name(usr)] activated [src] attachment for [loc]", INVESTIGATE_BOMB)
|
||||
add_attack_logs(usr, holder, "activated [src] attachment on", ATKLOG_FEW)
|
||||
log_game("[key_name(usr)] activated [src] attachment for [loc]")
|
||||
update_icon()
|
||||
if(href_list["reset"])
|
||||
|
||||
@@ -401,6 +401,7 @@
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
attack_verb = list("warned", "cautioned", "smashed")
|
||||
resistance_flags = NONE
|
||||
dog_fashion = /datum/dog_fashion/head/cone
|
||||
|
||||
/obj/item/clothing/head/jester
|
||||
name = "jester hat"
|
||||
|
||||
@@ -272,15 +272,6 @@
|
||||
new /obj/item/reagent_containers/food/drinks/cans/cola(src)
|
||||
|
||||
|
||||
/obj/item/instrument/guitar/jello_guitar //Pineapple Salad: Dan Jello
|
||||
name = "Dan Jello's Pink Guitar"
|
||||
desc = "Dan Jello's special pink guitar."
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "jello_guitar"
|
||||
item_state = "jello_guitar"
|
||||
righthand_file = 'icons/mob/inhands/fluff_righthand.dmi'
|
||||
lefthand_file = 'icons/mob/inhands/fluff_lefthand.dmi'
|
||||
|
||||
/obj/item/fluff/wingler_comb
|
||||
name = "blue comb"
|
||||
desc = "A blue comb, it looks like it was made to groom a Tajaran's fur."
|
||||
@@ -1592,13 +1583,17 @@
|
||||
item_state = "asmer_accordion"
|
||||
|
||||
|
||||
/obj/item/clothing/head/rabbitears/fluff/pinesalad_bunny // Pineapple Salad : Dan Jello
|
||||
name = "Bluespace rabbit ears"
|
||||
desc = "A pair of sparkly bluespace rabbit ears, with a small tag on them that reads, 'Dan Jello~'. Yuck, \
|
||||
there's some pink slime on the part that goes on your head!"
|
||||
/obj/item/clothing/head/fluff/pinesalad_horns //Pineapple Salad: Dan Jello
|
||||
name = "Bluespace Horns"
|
||||
desc = "A pair of fake horns. Now with added bluespace!"
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "ps_bunny"
|
||||
icon_state = "ps_horns"
|
||||
|
||||
/obj/item/storage/backpack/fluff/hiking //Pineapple Salad: Dan Jello
|
||||
name = "\improper Fancy Hiking Pack"
|
||||
desc = "A black and red hiking pack with some nice little accessories."
|
||||
icon = 'icons/obj/custom_items.dmi'
|
||||
icon_state = "danpack"
|
||||
|
||||
/obj/item/clothing/under/fluff/kiaoutfit //FullOfSkittles: Kiachi
|
||||
name = "Suspicious Outfit"
|
||||
|
||||
@@ -127,15 +127,6 @@
|
||||
description_info = "This filters the atmosphere of harmful gas. Filtered gas goes to the pipes connected to it, typically a scrubber pipe. \
|
||||
It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm."
|
||||
|
||||
//Omni filters
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
description_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \
|
||||
output. The filtered output's arrows glow orange."
|
||||
|
||||
//Omni mixers
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
description_info = "Combines gas from custom input and output directions. The percentage of combined gas can be defined."
|
||||
|
||||
//Canisters
|
||||
/obj/machinery/portable_atmospherics/canister
|
||||
description_info = "The canister can be connected to a connector port with a wrench. Tanks of gas (the kind you can hold in your hand) \
|
||||
|
||||
@@ -432,6 +432,29 @@
|
||||
icon_state = "jdonut1"
|
||||
extra_reagent = "cherryjelly"
|
||||
|
||||
//////////////////////
|
||||
// Pancakes //
|
||||
//////////////////////
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pancake
|
||||
name = "pancake"
|
||||
desc = "A plain pancake."
|
||||
icon_state = "pancake"
|
||||
filling_color = "#E7D8AB"
|
||||
bitesize = 2
|
||||
list_reagents = list("nutriment" = 3, "sugar" = 3)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pancake/berry_pancake
|
||||
name = "berry pancake"
|
||||
desc = "A pancake loaded with berries."
|
||||
icon_state = "berry_pancake"
|
||||
list_reagents = list("nutriment" = 3, "sugar" = 3, "berryjuice" = 3)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake
|
||||
name = "choc-chip pancake"
|
||||
desc = "A pancake loaded with chocolate chips."
|
||||
icon_state = "choc_chip_pancake"
|
||||
list_reagents = list("nutriment" = 3, "sugar" = 3, "cocoa" = 3)
|
||||
|
||||
//////////////////////
|
||||
// Misc //
|
||||
|
||||
@@ -234,7 +234,7 @@
|
||||
return
|
||||
|
||||
if(UserOverride)
|
||||
msg_admin_attack("[key_name_admin(occupant)] was gibbed by an autogibber (\the [src]) [ADMIN_JMP(src)]")
|
||||
add_attack_logs(user, occupant, "gibbed by an autogibber ([src])")
|
||||
log_game("[key_name(occupant)] was gibbed by an autogibber ([src]) (X:[x] Y:[y] Z:[z])")
|
||||
|
||||
if(operating)
|
||||
|
||||
@@ -249,3 +249,23 @@
|
||||
/obj/item/stack/rods,
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/fish_skewer
|
||||
|
||||
/datum/recipe/grill/pancake
|
||||
items = list(
|
||||
/obj/item/reagent_containers/food/snacks/cookiedough
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/pancake
|
||||
|
||||
/datum/recipe/grill/berry_pancake
|
||||
items = list(
|
||||
/obj/item/reagent_containers/food/snacks/cookiedough,
|
||||
/obj/item/reagent_containers/food/snacks/grown/berries
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/pancake/berry_pancake
|
||||
|
||||
/datum/recipe/grill/choc_chip_pancake
|
||||
items = list(
|
||||
/obj/item/reagent_containers/food/snacks/cookiedough,
|
||||
/obj/item/reagent_containers/food/snacks/choc_pile
|
||||
)
|
||||
result = /obj/item/reagent_containers/food/snacks/pancake/choc_chip_pancake
|
||||
|
||||
@@ -116,9 +116,8 @@
|
||||
/obj/item/reagent_containers/food/snacks/grown/firelemon/attack_self(mob/living/user)
|
||||
var/area/A = get_area(user)
|
||||
user.visible_message("<span class='warning'>[user] primes the [src]!</span>", "<span class='userdanger'>You prime the [src]!</span>")
|
||||
var/message = "[ADMIN_LOOKUPFLW(user)] primed a combustible lemon for detonation at [A] [ADMIN_COORDJMP(user)]"
|
||||
investigate_log("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].", INVESTIGATE_BOMB)
|
||||
message_admins(message)
|
||||
add_attack_logs(user, src, "primed a combustible lemon for detonation", ATKLOG_FEW)
|
||||
log_game("[key_name(user)] primed a combustible lemon for detonation at [A] [COORD(user)].")
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/C = user
|
||||
|
||||
@@ -167,6 +167,8 @@
|
||||
hearing_mobs.len = 0
|
||||
var/turf/source = get_turf(parent)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.z != source.z) // Z-level check
|
||||
continue
|
||||
var/dist = get_dist(M, source)
|
||||
if(dist > instrument_range) // Distance check
|
||||
continue
|
||||
@@ -253,16 +255,20 @@
|
||||
* Processes our song.
|
||||
*/
|
||||
/datum/song/proc/process_song(wait)
|
||||
if(!length(compiled_chords) || current_chord > length(compiled_chords) || should_stop_playing(user_playing))
|
||||
if(!length(compiled_chords) || should_stop_playing(user_playing))
|
||||
stop_playing()
|
||||
return
|
||||
var/list/chord = compiled_chords[current_chord]
|
||||
if(++elapsed_delay >= delay_by)
|
||||
// We were sustaining the final note but not anymore
|
||||
if(current_chord > length(compiled_chords))
|
||||
stop_playing()
|
||||
return
|
||||
var/list/chord = compiled_chords[current_chord]
|
||||
play_chord(chord)
|
||||
elapsed_delay = 0
|
||||
delay_by = tempodiv_to_delay(chord[length(chord)])
|
||||
current_chord++
|
||||
if(current_chord > length(compiled_chords))
|
||||
if(current_chord > length(compiled_chords) + 1)
|
||||
if(repeat)
|
||||
repeat--
|
||||
current_chord = 1
|
||||
@@ -284,6 +290,8 @@
|
||||
*/
|
||||
/datum/song/proc/compile_chords()
|
||||
legacy ? compile_legacy() : compile_synthesized()
|
||||
// Some chords may be null for some reason - exclude them.
|
||||
listclearnulls(compiled_chords)
|
||||
|
||||
/**
|
||||
* Plays a chord.
|
||||
|
||||
@@ -927,6 +927,8 @@
|
||||
. += T.slowdown
|
||||
if(slowed)
|
||||
. += 10
|
||||
if(forced_look)
|
||||
. += 3
|
||||
if(ignorewalk)
|
||||
. += config.run_speed
|
||||
else
|
||||
|
||||
@@ -319,10 +319,9 @@
|
||||
return verb
|
||||
|
||||
/mob/living/simple_animal/movement_delay()
|
||||
. = ..()
|
||||
|
||||
. = speed
|
||||
|
||||
if(forced_look)
|
||||
. += 3
|
||||
. += config.animal_delay
|
||||
|
||||
/mob/living/simple_animal/Stat()
|
||||
|
||||
@@ -235,6 +235,7 @@
|
||||
investigate_log("turned [active?"<font color='red'>ON</font>":"<font color='green'>OFF</font>"] by [usr ? usr.key : "outside forces"]","singulo")
|
||||
if(active)
|
||||
msg_admin_attack("PA Control Computer turned ON by [key_name_admin(usr)]", ATKLOG_FEW)
|
||||
usr.create_log(MISC_LOG, "PA Control Computer turned ON", src)
|
||||
log_game("PA Control Computer turned ON by [key_name(usr)] in ([x],[y],[z])")
|
||||
use_log += text("\[[time_stamp()]\] <font color='red'>[key_name(usr)] has turned on the PA Control Computer.</font>")
|
||||
if(active)
|
||||
|
||||
@@ -849,7 +849,7 @@
|
||||
/datum/reagent/medicine/stimulants
|
||||
name = "Stimulants"
|
||||
id = "stimulants"
|
||||
description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and stun."
|
||||
description = "An illegal compound that dramatically enhances the body's performance and healing capabilities."
|
||||
color = "#C8A5DC"
|
||||
harmless = FALSE
|
||||
can_synth = FALSE
|
||||
@@ -886,7 +886,7 @@
|
||||
/datum/reagent/medicine/stimulative_agent
|
||||
name = "Stimulative Agent"
|
||||
id = "stimulative_agent"
|
||||
description = "An illegal compound that dramatically enhances the body's performance and healing capabilities."
|
||||
description = "Increases run speed and eliminates stuns, can heal minor damage. If overdosed it will deal toxin damage and be less effective for healing stamina."
|
||||
color = "#C8A5DC"
|
||||
metabolization_rate = 0.5 * REAGENTS_METABOLISM
|
||||
overdose_threshold = 60
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
var/attack_log_type = ATKLOG_MOST
|
||||
if(reagents.has_reagent("sacid") || reagents.has_reagent("facid") || reagents.has_reagent("lube"))
|
||||
attack_log_type = ATKLOG_FEW
|
||||
msg_admin_attack("[key_name_admin(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K", attack_log_type)
|
||||
add_attack_logs(user, A, "sprayed [contents_log] at [reagents.chem_temp]K using [src]", attack_log_type)
|
||||
log_game("[key_name(user)] used a spray bottle at [COORD(user)] - Contents: [contents_log] - Temperature: [reagents.chem_temp]K")
|
||||
return
|
||||
|
||||
|
||||
@@ -84,17 +84,15 @@
|
||||
..()
|
||||
if(!QDELETED(src)) //wasn't deleted by the projectile's effects.
|
||||
if(!P.nodamage && ((P.damage_type == BURN) || (P.damage_type == BRUTE)))
|
||||
message_admins("[key_name_admin(P.firer)] triggered a fueltank explosion with [P.name] at [COORD(loc)] ")
|
||||
add_attack_logs(P.firer, src, "shot with [P.name]")
|
||||
add_attack_logs(P.firer, src, "shot with [P.name]", ATKLOG_FEW)
|
||||
log_game("[key_name(P.firer)] triggered a fueltank explosion with [P.name] at [COORD(loc)]")
|
||||
investigate_log("[key_name(P.firer)] triggered a fueltank explosion with [P.name] at [COORD(loc)]", INVESTIGATE_BOMB)
|
||||
boom()
|
||||
|
||||
/obj/structure/reagent_dispensers/fueltank/boom(rigtrigger = FALSE, log_attack = FALSE) // Prevent case where someone who rigged the tank is blamed for the explosion when the rig isn't what triggered the explosion
|
||||
if(rigtrigger) // If the explosion is triggered by an assembly holder
|
||||
message_admins("A fueltank, last rigged by [lastrigger], was triggered at [COORD(loc)]") // Then admin is informed of the last person who rigged the fuel tank
|
||||
log_game("A fueltank, last rigged by [lastrigger], triggered at [COORD(loc)]")
|
||||
add_attack_logs(lastrigger, src, "rigged fuel tank exploded")
|
||||
add_attack_logs(lastrigger, src, "rigged fuel tank exploded", ATKLOG_FEW)
|
||||
investigate_log("A fueltank, last rigged by [lastrigger], triggered at [COORD(loc)]", INVESTIGATE_BOMB)
|
||||
if(log_attack)
|
||||
add_attack_logs(usr, src, "blew up", ATKLOG_FEW)
|
||||
@@ -142,9 +140,8 @@
|
||||
|
||||
var/obj/item/assembly_holder/H = I
|
||||
if(istype(H.a_left, /obj/item/assembly/igniter) || istype(H.a_right, /obj/item/assembly/igniter))
|
||||
msg_admin_attack("[key_name_admin(user)] rigged [src.name] with [I.name] for explosion (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[x];Y=[y];Z=[z]'>JMP</a>)", ATKLOG_FEW)
|
||||
log_game("[key_name(user)] rigged [src.name] with [I.name] for explosion at [COORD(loc)]")
|
||||
add_attack_logs(user, src, "rigged fuel tank")
|
||||
add_attack_logs(user, src, "rigged fuel tank with [I.name] for explosion", ATKLOG_FEW)
|
||||
investigate_log("[key_name(user)] rigged [src.name] with [I.name] for explosion at [COORD(loc)]", INVESTIGATE_BOMB)
|
||||
|
||||
lastrigger = "[key_name(user)]"
|
||||
|
||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 240 KiB After Width: | Height: | Size: 240 KiB |
|
Before Width: | Height: | Size: 972 B After Width: | Height: | Size: 964 B |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 253 KiB After Width: | Height: | Size: 253 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 99 KiB |
@@ -1,24 +0,0 @@
|
||||
<div class="item">
|
||||
<div class="itemLabel">Power:</div>
|
||||
<div class="itemContent">{{:helper.link(data.on ? 'On' : 'Off', data.on ? 'power-off' : 'times', {'power' : 1}, null, data.on ? 'selected' : null)}}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">Output Pressure:</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Set', 'pencil', {'pressure' : 'input'})}}
|
||||
{{:helper.link('Max', 'plus', {'pressure' : 'max'}, data.pressure == data.max_pressure ? 'disabled' : null)}}
|
||||
{{:helper.smoothRound(data.pressure)}} kPa
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">Filter:</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Nothing', null, {'filter' : -1}, data.filter_type == -1 ? 'selected' : null)}}
|
||||
{{:helper.link('Plasma', null, {'filter' : 0}, data.filter_type == 0 ? 'selected' : null)}}
|
||||
{{:helper.link('O2', null, {'filter' : 1}, data.filter_type == 1 ? 'selected' : null)}}
|
||||
{{:helper.link('N2', null, {'filter' : 2}, data.filter_type == 2 ? 'selected' : null)}}
|
||||
{{:helper.link('CO2', null, {'filter' : 3}, data.filter_type == 3 ? 'selected' : null)}}
|
||||
{{:helper.link('N2O', null, {'filter' : 4}, data.filter_type == 4 ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
<div class="item">
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
{{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}}
|
||||
</div>
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
{{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}}
|
||||
</div>
|
||||
|
||||
{{if data.config}}
|
||||
|
||||
<div style="width: 315px; text-align: center">
|
||||
<div style="float: left">
|
||||
<div class="white" style="height: 26">Port</div>
|
||||
{{for data.ports}}
|
||||
<div class="average" style="height: 26">{{:value.dir}} Port</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Input</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, null, value.input ? 'selected' : null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Output</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{:helper.link(' ', null, {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Filter</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{:helper.link(value.f_type ? value.f_type : 'None', null, {'command' : 'switch_filter', 'mode' : value.f_type, 'dir' : value.dir}, value.filter ? null : 'disabled', value.f_type ? 'selected' : null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s
|
||||
</div>
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
{{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}}
|
||||
</div>
|
||||
|
||||
{{else}}
|
||||
|
||||
<div style="width: 315px; text-align: center">
|
||||
<div style="float: left">
|
||||
<div class="white" style="height: 26">Port</div>
|
||||
{{for data.ports}}
|
||||
<div class="average" style="height: 26">{{:value.dir}} Port</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Mode</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{if value.input}}
|
||||
Input
|
||||
{{else value.output}}
|
||||
Output
|
||||
{{else value.f_type}}
|
||||
{{:value.f_type}}
|
||||
{{else}}
|
||||
Disabled
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s
|
||||
</div>
|
||||
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
Flow Rate: {{:(data.last_flow_rate/10)}} L/s
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
@@ -1,101 +0,0 @@
|
||||
<div class="item">
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
{{:helper.link(data.power ? 'On' : 'Off', null, {'command' : 'power'}, data.config ? 'disabled' : null)}}
|
||||
</div>
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
{{:helper.link('Configure', null, {'command' : 'configure'}, null, data.config ? 'selected' : null)}}
|
||||
</div>
|
||||
|
||||
{{if data.config}}
|
||||
|
||||
<div style="width: 315px; text-align: center">
|
||||
<div style="float: left">
|
||||
<div class="white" style="height: 26">Port</div>
|
||||
{{for data.ports}}
|
||||
<div class="average" style="height: 26">{{:value.dir}} Port</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Input</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{:helper.link(' ', null, value.input ? {'command' : 'switch_mode', 'mode' : 'none', 'dir' : value.dir} : {'command' : 'switch_mode', 'mode' : 'in', 'dir' : value.dir}, value.output ? 'disabled' : null, value.input ? 'selected' : null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Output</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{:helper.link(' ', null, value.output ? null : {'command' : 'switch_mode', 'mode' : 'out', 'dir' : value.dir}, null, value.output ? 'selected' : null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Concentration</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{:helper.link( value.input ? helper.round(value.concentration*100)+' %' : '-', null, {'command' : 'switch_con', 'dir' : value.dir}, value.input ? null : 'disabled')}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Lock</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{:helper.link(' ', value.con_lock ? 'lock' : 'unlock', {'command' : 'switch_conlock', 'dir' : value.dir}, value.input ? null : 'disabled', value.con_lock ? 'selected' : null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
Set Flow Rate Limit: {{:(data.set_flow_rate/10)}} L/s
|
||||
</div>
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
{{:helper.link('Set Flow Rate Limit', null, {'command' : 'set_flow_rate'})}}
|
||||
</div>
|
||||
|
||||
{{else}}
|
||||
|
||||
<div style="width: 315px; text-align: center">
|
||||
<div style="float: left">
|
||||
<div class="white" style="height: 26">Port</div>
|
||||
{{for data.ports}}
|
||||
<div class="average" style="height: 26">{{:value.dir}} Port</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Mode</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{if value.input}}
|
||||
Input
|
||||
{{else value.output}}
|
||||
Output
|
||||
{{else}}
|
||||
Disabled
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
<div style="float: left; margin-left: 10">
|
||||
<div class="white" style="height: 26">Concentration</div>
|
||||
{{for data.ports}}
|
||||
<div style="height: 26">
|
||||
{{if value.input}}
|
||||
{{:helper.round(value.concentration*100)}} %
|
||||
{{else}}
|
||||
-
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="itemContent" style="padding: 5px">
|
||||
Flow Rate: {{:(data.last_flow_rate/10)}} L/s
|
||||
</div>
|
||||
|
||||
{{/if}}
|
||||
</div>
|
||||
@@ -1,36 +0,0 @@
|
||||
<!--
|
||||
Title: Teleporter Console UI
|
||||
Used In File(s): \code\game\machinery\teleporter.dm
|
||||
-->
|
||||
<h1>Teleporter Status</h1>
|
||||
{{if !data.powerstation}}
|
||||
<div class="bad">No power station linked.</div>
|
||||
{{else !data.teleporterhub}}
|
||||
<div class="bad">No hub linked.</div>
|
||||
{{else}}
|
||||
<div class="block">
|
||||
<div class="item">
|
||||
<div class="itemLabel">Current Regime</div>
|
||||
<div class="itemContent">{{:data.regime}}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">Current Target</div>
|
||||
<div class="itemContent">{{:data.target}}{{if data.target != "None"}}{{if data.regime == "Gate"}} Teleporter{{/if}}{{/if}}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">Calibration</div>
|
||||
<div class="itemContent">{{if data.calibrating}}<span class="average">In Progress</span>{{else data.calibrated}}<span class="good">Optimal</span>{{else data.accurate > 2}}<span class="good">Optimal</span>{{else}}<span class="bad">Sub-Optimal</span>{{/if}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top:10px;" class="item">
|
||||
<div class="item">{{:helper.link('Change regime', 'gear', {'regimeset': 1})}}</div>
|
||||
<div class="item">{{:helper.link('Set target', 'gear', {'settarget': 1})}}</div>
|
||||
</div>
|
||||
<div style="margin-top:10px;" class="item">
|
||||
<div class="item">{{:helper.link('Get target from memory', 'arrow-circle-down', {'lock': 1}, data.locked ? '' : 'disabled')}}</div>
|
||||
<div class="item">{{:helper.link('Eject GPS device', 'eject', {'eject': 1}, data.locked ? '' : 'disabled')}}</div>
|
||||
</div>
|
||||
<div style="margin-top:10px;" class="item">
|
||||
<div class="item">{{:helper.link('Calibrate hub', 'arrows-alt', {'calibrate': 1}, data.target == 'None' ? 'disabled' : '')}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -174,10 +174,6 @@
|
||||
#include "code\ATMOSPHERICS\components\binary_devices\pump.dm"
|
||||
#include "code\ATMOSPHERICS\components\binary_devices\valve.dm"
|
||||
#include "code\ATMOSPHERICS\components\binary_devices\volume_pump.dm"
|
||||
#include "code\ATMOSPHERICS\components\omni_devices\_omni_extras.dm"
|
||||
#include "code\ATMOSPHERICS\components\omni_devices\filter.dm"
|
||||
#include "code\ATMOSPHERICS\components\omni_devices\mixer.dm"
|
||||
#include "code\ATMOSPHERICS\components\omni_devices\omni_base.dm"
|
||||
#include "code\ATMOSPHERICS\components\trinary_devices\filter.dm"
|
||||
#include "code\ATMOSPHERICS\components\trinary_devices\mixer.dm"
|
||||
#include "code\ATMOSPHERICS\components\trinary_devices\trinary_base.dm"
|
||||
@@ -218,6 +214,7 @@
|
||||
#include "code\controllers\subsystem\assets.dm"
|
||||
#include "code\controllers\subsystem\atoms.dm"
|
||||
#include "code\controllers\subsystem\changelog.dm"
|
||||
#include "code\controllers\subsystem\cleanup.dm"
|
||||
#include "code\controllers\subsystem\events.dm"
|
||||
#include "code\controllers\subsystem\fires.dm"
|
||||
#include "code\controllers\subsystem\garbage.dm"
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { useBackend } from "../backend";
|
||||
import { Button, Section, NumberInput, LabeledList } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
|
||||
export const AtmosFilter = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
on,
|
||||
pressure,
|
||||
max_pressure,
|
||||
filter_type,
|
||||
filter_type_list,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
<Section>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Power">
|
||||
<Button
|
||||
icon={on ? "power-off" : "power-off"}
|
||||
content={on ? "On" : "Off"}
|
||||
color={on ? null : "red"}
|
||||
selected={on}
|
||||
onClick={() => act('power')} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Rate">
|
||||
<Button
|
||||
icon="fast-backward"
|
||||
textAlign="center"
|
||||
disabled={pressure === 0}
|
||||
width={2.2}
|
||||
onClick={() => act('min_pressure')} />
|
||||
<NumberInput
|
||||
animated
|
||||
unit="kPa"
|
||||
width={6.1}
|
||||
lineHeight={1.5}
|
||||
step={10}
|
||||
minValue={0}
|
||||
maxValue={max_pressure}
|
||||
value={pressure}
|
||||
onDrag={(e, value) => act('custom_pressure', {
|
||||
pressure: value,
|
||||
})} />
|
||||
<Button
|
||||
icon="fast-forward"
|
||||
textAlign="center"
|
||||
disabled={pressure === max_pressure}
|
||||
width={2.2}
|
||||
onClick={() => act('max_pressure')} />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Filter">
|
||||
{filter_type_list.map(filter => (
|
||||
<Button
|
||||
key={filter.label}
|
||||
selected={filter.gas_type === filter_type}
|
||||
content={filter.label}
|
||||
onClick={() => act('set_filter', {
|
||||
filter: filter.gas_type,
|
||||
})} />
|
||||
))}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,167 @@
|
||||
import { useBackend } from '../backend';
|
||||
import { Box, Button, LabeledList, Section, Grid, Dropdown, Flex } from '../components';
|
||||
import { Window } from '../layouts';
|
||||
import { GridColumn } from '../components/Grid';
|
||||
|
||||
export const Teleporter = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
let targetsTeleport = data.targetsTeleport ? data.targetsTeleport : {};
|
||||
const REGIME_TELEPORT = 0;
|
||||
const REGIME_GATE = 1;
|
||||
const REGIME_GPS = 2;
|
||||
const {
|
||||
calibrated,
|
||||
calibrating,
|
||||
powerstation,
|
||||
regime,
|
||||
teleporterhub,
|
||||
target,
|
||||
locked,
|
||||
} = data;
|
||||
return (
|
||||
<Window>
|
||||
<Window.Content>
|
||||
{(!powerstation || !teleporterhub)
|
||||
&& (
|
||||
<Section
|
||||
title="Error">
|
||||
{teleporterhub}
|
||||
{!powerstation
|
||||
&& (
|
||||
<Box color="bad"> Powerstation not linked </Box>
|
||||
)}
|
||||
{powerstation && !teleporterhub
|
||||
&& (
|
||||
<Box color="bad"> Teleporter hub not linked </Box>
|
||||
)}
|
||||
</Section>
|
||||
)}
|
||||
{(powerstation && teleporterhub)
|
||||
&& (
|
||||
<Section title="Status">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Regime">
|
||||
<Button
|
||||
tooltip="Teleport to another teleport hub. "
|
||||
color={regime === REGIME_GATE ? 'good' : null}
|
||||
onClick={() =>
|
||||
act('setregime', { regime: REGIME_GATE })}>
|
||||
Gate
|
||||
</Button>
|
||||
<Button
|
||||
tooltip="One-way teleport. "
|
||||
color={regime === REGIME_TELEPORT ? 'good' : null}
|
||||
onClick={() =>
|
||||
act('setregime', { regime: REGIME_TELEPORT })}>
|
||||
Teleporter
|
||||
</Button>
|
||||
<Button
|
||||
tooltip="Teleport to a location stored in a GPS device. "
|
||||
color={regime === REGIME_GPS ? 'good' : null}
|
||||
disabled={locked ? false : true}
|
||||
onClick={() =>
|
||||
act('setregime', { regime: REGIME_GPS })}>
|
||||
GPS
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Teleport target">
|
||||
{/* The duplication of the dropdowns is due to the
|
||||
updates of selected not affecting the state
|
||||
of the dropdown */}
|
||||
{regime === REGIME_TELEPORT && (
|
||||
<Dropdown
|
||||
width="220px"
|
||||
selected={target}
|
||||
options={Object.keys(targetsTeleport)}
|
||||
color={target !== "None" ? "default" : "bad"}
|
||||
onSelected={val => act('settarget',
|
||||
{
|
||||
x: targetsTeleport[val]["x"],
|
||||
y: targetsTeleport[val]["y"],
|
||||
z: targetsTeleport[val]["z"],
|
||||
})} />
|
||||
)}
|
||||
{regime === REGIME_GATE && (
|
||||
<Dropdown
|
||||
width="220px"
|
||||
selected={target}
|
||||
options={Object.keys(targetsTeleport)}
|
||||
color={target !== "None" ? "default" : "bad"}
|
||||
onSelected={val => act('settarget',
|
||||
{
|
||||
x: targetsTeleport[val]["x"],
|
||||
y: targetsTeleport[val]["y"],
|
||||
z: targetsTeleport[val]["z"],
|
||||
})} />
|
||||
)}
|
||||
{regime === REGIME_GPS && (
|
||||
<Box>
|
||||
{target}
|
||||
</Box>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Calibration">
|
||||
{target !== 'None'
|
||||
&& (
|
||||
<Grid>
|
||||
<GridColumn size="2">
|
||||
{calibrating
|
||||
&& (
|
||||
<Box color="average">
|
||||
In Progress
|
||||
</Box>
|
||||
) || (calibrated
|
||||
&& (
|
||||
<Box color="good">
|
||||
Optimal
|
||||
</Box>
|
||||
) || (
|
||||
<Box color="bad">
|
||||
Sub-Optimal
|
||||
</Box>
|
||||
))}
|
||||
</GridColumn>
|
||||
<GridColumn size="3">
|
||||
<Box class="ml-1">
|
||||
<Button
|
||||
icon="sync-alt"
|
||||
tooltip="Calibrates the hub. \
|
||||
Accidents may occur when the \
|
||||
calibration is not optimal."
|
||||
disabled={(calibrated || calibrating) ? true : false}
|
||||
onClick={() => act('calibrate')} />
|
||||
</Box>
|
||||
</GridColumn>
|
||||
</Grid>
|
||||
)}
|
||||
{target === 'None'
|
||||
&& (
|
||||
<Box lineHeight="21px">
|
||||
No target set
|
||||
</Box>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
)}
|
||||
{!!(locked && powerstation && teleporterhub && regime === REGIME_GPS)
|
||||
&& (
|
||||
<Section title="GPS">
|
||||
<Flex direction="row" justify="space-around">
|
||||
<Button
|
||||
content="Upload GPS data"
|
||||
tooltip="Loads the GPS data from the device."
|
||||
icon="upload"
|
||||
onClick={() => act('load')} />
|
||||
<Button
|
||||
content="Eject"
|
||||
tooltip="Ejects the GPS device"
|
||||
icon="eject"
|
||||
onClick={() => act('eject')} />
|
||||
</Flex>
|
||||
</Section>
|
||||
)}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||