diff --git a/baystation12.dme b/baystation12.dme
index cc0918516d7..9de1e153ca6 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -324,7 +324,6 @@
#include "code\game\machinery\turrets.dm"
#include "code\game\machinery\vending.dm"
#include "code\game\machinery\washing_machine.dm"
-#include "code\game\machinery\wishgranter.dm"
#include "code\game\machinery\atmoalter\area_atmos_computer.dm"
#include "code\game\machinery\atmoalter\canister.dm"
#include "code\game\machinery\atmoalter\meter.dm"
@@ -1153,6 +1152,7 @@
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\SuperMatter.dm"
#include "code\WorkInProgress\Cael_Aislinn\Supermatter\ZeroPointLaser.dm"
#include "code\WorkInProgress\Chinsky\ashtray.dm"
+#include "code\WorkInProgress\Mini\atmos_control.dm"
#include "code\WorkInProgress\Ported\policetape.dm"
#include "code\WorkInProgress\SkyMarshal\Ultralight_procs.dm"
#include "code\WorkInProgress\Susan\susan_desert_turfs.dm"
diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm
index 7b9444d8902..9aae6910c7c 100644
--- a/code/ATMOSPHERICS/components/unary/vent_pump.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm
@@ -5,13 +5,14 @@
name = "Air Vent"
desc = "Has a valve and pump attached to it"
- var/area/initial_loc
level = 1
var/area_uid
- var/id_tag = null
+ var/id_tag
+ power_channel = ENVIRON
var/on = 0
var/pump_direction = 1 //0 = siphoning, 1 = releasing
+ var/pump_speed = 1 //Used to adjust speed for siphons
var/external_pressure_bound = ONE_ATMOSPHERE
var/internal_pressure_bound = 0
@@ -42,25 +43,27 @@
icon_state = "in"
New()
- initial_loc = get_area(loc)
- if (initial_loc.master)
- initial_loc = initial_loc.master
- area_uid = initial_loc.uid
+ var/area/A = get_area(loc)
+ if (A.master)
+ A = A.master
+ area_uid = A.uid
if (!id_tag)
assign_uid()
id_tag = num2text(uid)
if(ticker && ticker.current_state == 3)//if the game is running
- src.initialize()
- src.broadcast_status()
+ initialize()
+ broadcast_status()
..()
high_volume
name = "Large Air Vent"
power_channel = EQUIP
+
New()
..()
air_contents.volume = 1000
+
update_icon()
if(welded)
icon_state = "[level == 1 && istype(loc, /turf/simulated) ? "h" : "" ]weld"
@@ -77,11 +80,12 @@
process()
..()
+// broadcast_status()
if(stat & (NOPOWER|BROKEN))
return
if (!node)
on = 0
- //broadcast_status() // from now air alarm/control computer should request update purposely --rastaf0
+
if(!on)
return 0
@@ -101,7 +105,7 @@
if(pressure_delta > 0)
if(air_contents.temperature > 0)
- var/transfer_moles = pressure_delta*environment.volume/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
+ var/transfer_moles = pressure_delta*environment.volume*environment.group_multiplier*pump_speed/(air_contents.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = air_contents.remove(transfer_moles)
@@ -119,7 +123,7 @@
if(pressure_delta > 0)
if(environment.temperature > 0)
- var/transfer_moles = pressure_delta*air_contents.volume/(environment.temperature * R_IDEAL_GAS_EQUATION)
+ var/transfer_moles = pressure_delta*air_contents.volume*air_contents.group_multiplier*pump_speed/(environment.temperature * R_IDEAL_GAS_EQUATION)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
if (isnull(removed)) //in space
@@ -132,39 +136,42 @@
return 1
+
+
+
//Radio remote control
- proc
- set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- frequency = new_frequency
- if(frequency)
- radio_connection = radio_controller.add_object(src, frequency,radio_filter_in)
+ proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ frequency = new_frequency
+ if(frequency)
+ radio_connection = radio_controller.add_object(src, frequency,radio_filter_in)
- broadcast_status()
- if(!radio_connection)
- return 0
+ proc/broadcast_status()
+ if(!radio_connection)
+ return 0
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.source = src
- signal.data = list(
- "area" = src.area_uid,
- "tag" = src.id_tag,
- "device" = "AVP",
- "power" = on,
- "direction" = pump_direction?("release"):("siphon"),
- "checks" = pressure_checks,
- "internal" = internal_pressure_bound,
- "external" = external_pressure_bound,
- "timestamp" = world.time,
- "sigtype" = "status"
- )
+ signal.data = list(
+ "area" = src.area_uid,
+ "tag" = src.id_tag,
+ "device" = "AVP",
+ "power" = on,
+ "direction" = pump_direction?("release"):("siphon"),
+ "checks" = pressure_checks,
+ "internal" = internal_pressure_bound,
+ "external" = external_pressure_bound,
+ "timestamp" = world.time,
+ "sigtype" = "status",
+ "setting" = pump_speed
+ )
- radio_connection.post_signal(src, signal, radio_filter_out)
+ radio_connection.post_signal(src, signal, radio_filter_out)
- return 1
+ return 1
initialize()
@@ -176,6 +183,7 @@
if(frequency)
set_frequency(frequency)
+
receive_signal(datum/signal/signal)
if(stat & (NOPOWER|BROKEN))
return
@@ -203,47 +211,29 @@
if("checks_toggle" in signal.data)
pressure_checks = (pressure_checks?0:3)
- if("direction" in signal.data)
+ if("direction" in signal)
pump_direction = text2num(signal.data["direction"])
if("set_internal_pressure" in signal.data)
- internal_pressure_bound = between(
- 0,
- text2num(signal.data["set_internal_pressure"]),
- ONE_ATMOSPHERE*50
- )
+ internal_pressure_bound = between(0, text2num(signal.data["set_internal_pressure"]), ONE_ATMOSPHERE*50)
if("set_external_pressure" in signal.data)
- external_pressure_bound = between(
- 0,
- text2num(signal.data["set_external_pressure"]),
- ONE_ATMOSPHERE*50
- )
+ external_pressure_bound = between(0, text2num(signal.data["set_external_pressure"]), ONE_ATMOSPHERE*50)
if("adjust_internal_pressure" in signal.data)
- internal_pressure_bound = between(
- 0,
- internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]),
- ONE_ATMOSPHERE*50
- )
+ internal_pressure_bound = between(0, internal_pressure_bound + text2num(signal.data["adjust_internal_pressure"]), ONE_ATMOSPHERE*50)
if("adjust_external_pressure" in signal.data)
- external_pressure_bound = between(
- 0,
- external_pressure_bound + text2num(signal.data["adjust_external_pressure"]),
- ONE_ATMOSPHERE*50
- )
+ external_pressure_bound = between(0, external_pressure_bound + text2num(signal.data["adjust_external_pressure"]), ONE_ATMOSPHERE*50)
if("init" in signal.data)
name = signal.data["init"]
return
- if("status" in signal.data)
- spawn(2)
- broadcast_status()
- return //do not update_icon
+ if("setting" in signal.data)
+ pump_speed = text2num(signal.data["setting"])
- //log_admin("DEBUG \[[world.timeofday]\]: vent_pump/receive_signal: unknown command \"[signal.data["command"]]\"\n[signal.debug_print()]")
+ //log_admin("DEBUG \[[world.timeofday]\]: vent_pump/receive_signal: unknown command \"[signal["command"]]\"\n[signal.debug_print()]")
spawn(2)
broadcast_status()
update_icon()
@@ -284,6 +274,7 @@
else
user << "\blue You need more welding fuel to complete this task."
return 1
+
examine()
set src in oview(1)
..()
@@ -321,10 +312,4 @@
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/pipe(loc, make_from=src)
- del(src)
-
- /obj/machinery/atmospherics/unary/vent_pump/Del()
- if (initial_loc.air_scrub_info)
- initial_loc.air_scrub_info -= id_tag
- ..()
- return
+ del(src)
\ No newline at end of file
diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
index 84378df3d14..b9c26d32511 100644
--- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
+++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm
@@ -7,34 +7,36 @@
level = 1
- var/area/initial_loc
var/id_tag = null
- var/frequency = 1439
- var/datum/radio_frequency/radio_connection
var/on = 0
var/scrubbing = 1 //0 = siphoning, 1 = scrubbing
var/scrub_CO2 = 1
var/scrub_Toxins = 0
var/scrub_N2O = 0
+ var/scrub_rate = 1
var/volume_rate = 120
var/panic = 0 //is this scrubber panicked?
var/area_uid
+
+ var/frequency = 1439
+ var/datum/radio_frequency/radio_connection
var/radio_filter_out
var/radio_filter_in
+
New()
- initial_loc = get_area(loc)
- if (initial_loc.master)
- initial_loc = initial_loc.master
- area_uid = initial_loc.uid
+ var/area/A = get_area(loc)
+ if (A.master)
+ A = A.master
+ area_uid = A.uid
if (!id_tag)
assign_uid()
id_tag = num2text(uid)
if(ticker && ticker.current_state == 3)//if the game is running
- src.initialize()
- src.broadcast_status()
+ initialize()
+ broadcast_status()
..()
update_icon()
@@ -86,20 +88,20 @@
process()
..()
+// broadcast_status()
if(stat & (NOPOWER|BROKEN))
return
if (!node)
on = 0
- //broadcast_status()
+
if(!on)
return 0
-
var/datum/gas_mixture/environment = loc.return_air()
if(scrubbing)
if((environment.toxins>0) || (environment.carbon_dioxide>0) || (environment.trace_gases.len>0))
- var/transfer_moles = min(1, volume_rate/environment.volume)*environment.total_moles()
+ var/transfer_moles = min(1, volume_rate*scrub_rate/environment.volume)*environment.total_moles
//Take a gas sample
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
@@ -118,15 +120,14 @@
if(removed.trace_gases.len>0)
for(var/datum/gas/trace_gas in removed.trace_gases)
- if(istype(trace_gas, /datum/gas/oxygen_agent_b))
- removed.trace_gases -= trace_gas
- filtered_out.trace_gases += trace_gas
- else if(istype(trace_gas, /datum/gas/sleeping_agent) && scrub_N2O)
+ if(istype(trace_gas, /datum/gas/sleeping_agent) && scrub_N2O)
removed.trace_gases -= trace_gas
filtered_out.trace_gases += trace_gas
//Remix the resulting gases
+ filtered_out.update_values()
+ removed.update_values()
air_contents.merge(filtered_out)
loc.assume_air(removed)
@@ -138,7 +139,7 @@
if (air_contents.return_pressure()>=50*ONE_ATMOSPHERE)
return
- var/transfer_moles = environment.total_moles()*(volume_rate/environment.volume)
+ var/transfer_moles = environment.total_moles*(volume_rate*scrub_rate/environment.volume)
var/datum/gas_mixture/removed = loc.remove_air(transfer_moles)
@@ -220,6 +221,9 @@
broadcast_status()
return //do not update_icon
+ if("setting" in signal.data)
+ scrub_rate = text2num(signal.data["setting"])
+
// log_admin("DEBUG \[[world.timeofday]\]: vent_scrubber/receive_signal: unknown command \"[signal.data["command"]]\"\n[signal.debug_print()]")
spawn(2)
broadcast_status()
@@ -227,7 +231,7 @@
return
power_change()
- if(powered(power_channel))
+ if(powered(ENVIRON))
stat &= ~NOPOWER
else
stat |= NOPOWER
@@ -257,10 +261,4 @@
"\blue You have unfastened \the [src].", \
"You hear ratchet.")
new /obj/item/pipe(loc, make_from=src)
- del(src)
-
- /obj/machinery/atmospherics/unary/vent_scrubber/Del()
- if (initial_loc.air_scrub_info)
- initial_loc.air_scrub_info -= id_tag
- ..()
- return
+ del(src)
\ No newline at end of file
diff --git a/code/WorkInProgress/Mini/atmos_control.dm b/code/WorkInProgress/Mini/atmos_control.dm
index 6c06a16b799..506258cdf9b 100644
--- a/code/WorkInProgress/Mini/atmos_control.dm
+++ b/code/WorkInProgress/Mini/atmos_control.dm
@@ -16,7 +16,7 @@
/obj/machinery/computer/atmoscontrol/attack_hand(mob/user)
if(..())
return
- user.machine = src
+ user.set_machine(src)
if(allowed(user))
overridden = 1
else if(!emagged)
@@ -139,6 +139,12 @@
src.updateUsrDialog()
return
+ if(href_list["atmos_unlock"])
+ switch(href_list["atmos_unlock"])
+ if("0")
+ current.air_doors_close(1)
+ if("1")
+ current.air_doors_open(1)
if(href_list["atmos_alarm"])
if (current.alarm_area.atmosalert(2))
@@ -187,6 +193,8 @@
output += "PANIC SYPHON ACTIVE
turn syphoning off"
else
output += "ACTIVATE PANIC SYPHON IN AREA"
+
+ output += "
Atmospheric Lockdown: [current.alarm_area.air_doors_activated ? "ENABLED" : "Disabled"]"
if (AALARM_SCREEN_VENT)
var/sensor_data = ""
if(current.alarm_area.air_vent_names.len)
diff --git a/code/defines/obj/vending.dm b/code/defines/obj/vending.dm
index ac89893befe..efd1d0b5bd6 100755
--- a/code/defines/obj/vending.dm
+++ b/code/defines/obj/vending.dm
@@ -214,8 +214,8 @@
desc = "A plant nutrients vendor"
icon_state = "nutri"
icon_deny = "nutri-deny"
- product_paths = "/obj/item/nutrient/ez;/obj/item/nutrient/l4z;/obj/item/nutrient/rh;/obj/item/weapon/pestspray;/obj/item/weapon/reagent_containers/syringe;/obj/item/weapon/plantbag"
- product_amounts = "35;25;15;20;5;5"
+ product_paths = "/obj/item/nutrient/ez;/obj/item/nutrient/l4z;/obj/item/nutrient/rh;/obj/item/weapon/pestspray;/obj/item/weapon/reagent_containers/syringe;/obj/item/weapon/plantbag;/obj/item/weapon/seedbag"
+ product_amounts = "35;25;15;20;5;5;5"
product_slogans = "Aren't you glad you don't have to fertilize the natural way?;Now with 50% less stink!;Plants are people too!"
product_hidden = "/obj/item/weapon/reagent_containers/glass/bottle/ammonia;/obj/item/weapon/reagent_containers/glass/bottle/diethylamine"
product_hideamt = "10;5"
diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 8bb76ec226f..6d41985202e 100755
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -49,6 +49,8 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
// (original area before splitting due to sd_DAL)
var/list/related // the other areas of the same type as this
// var/list/lights // list of all lights on this area
+ var/list/all_doors = list() //Added by Strumpetplaya - Alarm Change - Contains a list of doors adjacent to this area
+ var/air_doors_activated = 0
/*Adding a wizard area teleport list because motherfucking lag -- Urist*/
/*I am far too lazy to make it a proper list of areas so I'll just make it run the usual telepot routine at the start of the game*/
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index e0e15c0ecd3..3d59d9016da 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -10,7 +10,7 @@
/area/New()
icon_state = ""
layer = 10
- master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references src.loc.loc.master ~Carn
+ master = src //moved outside the spawn(1) to avoid runtimes in lighting.dm when it references loc.loc.master ~Carn
uid = ++global_uid
related = list(src)
@@ -62,44 +62,44 @@
return
/area/proc/atmosalert(danger_level)
-// if(src.type==/area) //No atmos alarms in space
+// if(type==/area) //No atmos alarms in space
// return 0 //redudant
- if(danger_level != src.atmosalm)
- //src.updateicon()
- //src.mouse_opacity = 0
+ if(danger_level != atmosalm)
+ //updateicon()
+ //mouse_opacity = 0
if (danger_level==2)
var/list/cameras = list()
- for(var/area/RA in src.related)
- //src.updateicon()
+ for(var/area/RA in related)
+ //updateicon()
for(var/obj/machinery/camera/C in RA)
cameras += C
for(var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.triggerAlarm("Atmosphere", src, cameras, src)
for(var/obj/machinery/computer/station_alert/a in world)
a.triggerAlarm("Atmosphere", src, cameras, src)
- else if (src.atmosalm == 2)
+ else if (atmosalm == 2)
for(var/mob/living/silicon/aiPlayer in player_list)
aiPlayer.cancelAlarm("Atmosphere", src, src)
for(var/obj/machinery/computer/station_alert/a in world)
a.cancelAlarm("Atmosphere", src, src)
- src.atmosalm = danger_level
+ atmosalm = danger_level
return 1
return 0
/area/proc/firealert()
- if(src.name == "Space") //no fire alarms in space
+ if(name == "Space") //no fire alarms in space
return
- if (!( src.fire ))
- src.fire = 1
- src.updateicon()
- src.mouse_opacity = 0
- for(var/obj/machinery/door/firedoor/D in src)
+ if( !fire )
+ fire = 1
+ updateicon()
+ mouse_opacity = 0
+ for(var/obj/machinery/door/firedoor/D in all_doors)
if(!D.blocked)
if(D.operating)
D.nextstate = CLOSED
else if(!D.density)
- spawn(0)
- D.close()
+ spawn()
+ D.close()
var/list/cameras = list()
for (var/obj/machinery/camera/C in src)
cameras += C
@@ -107,14 +107,13 @@
aiPlayer.triggerAlarm("Fire", src, cameras, src)
for (var/obj/machinery/computer/station_alert/a in world)
a.triggerAlarm("Fire", src, cameras, src)
- return
/area/proc/firereset()
- if (src.fire)
- src.fire = 0
- src.mouse_opacity = 0
- src.updateicon()
- for(var/obj/machinery/door/firedoor/D in src)
+ if (fire)
+ fire = 0
+ mouse_opacity = 0
+ updateicon()
+ for(var/obj/machinery/door/firedoor/D in all_doors)
if(!D.blocked)
if(D.operating)
D.nextstate = OPEN
@@ -125,7 +124,6 @@
aiPlayer.cancelAlarm("Fire", src, src)
for (var/obj/machinery/computer/station_alert/a in world)
a.cancelAlarm("Fire", src, src)
- return
/area/proc/readyalert()
if(name == "Space")
@@ -142,19 +140,19 @@
return
/area/proc/partyalert()
- if(src.name == "Space") //no parties in space!!!
+ if(name == "Space") //no parties in space!!!
return
- if (!( src.party ))
- src.party = 1
- src.updateicon()
- src.mouse_opacity = 0
+ if (!( party ))
+ party = 1
+ updateicon()
+ mouse_opacity = 0
return
/area/proc/partyreset()
- if (src.party)
- src.party = 0
- src.mouse_opacity = 0
- src.updateicon()
+ if (party)
+ party = 0
+ mouse_opacity = 0
+ updateicon()
for(var/obj/machinery/door/firedoor/D in src)
if(!D.blocked)
if(D.operating)
@@ -273,7 +271,7 @@
A:client:ambience_playing = 1
A << sound('sound/ambience/shipambience.ogg', repeat = 1, wait = 0, volume = 35, channel = 2)
- switch(src.name)
+ switch(name)
if ("Chapel") sound = pick('sound/ambience/ambicha1.ogg','sound/ambience/ambicha2.ogg','sound/ambience/ambicha3.ogg','sound/ambience/ambicha4.ogg')
if ("Morgue") sound = pick('sound/ambience/ambimo1.ogg','sound/ambience/ambimo2.ogg','sound/music/title2.ogg')
if ("Space") sound = pick('sound/ambience/ambispace.ogg','sound/music/title2.ogg',)
diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index a465147daa7..b83774e381d 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -517,3 +517,32 @@
return jobName
return "Unknown"
+
+proc/FindNameFromID(var/mob/living/carbon/human/H)
+ ASSERT(istype(H))
+ var/obj/item/weapon/card/id/C = H.get_active_hand()
+ if( istype(C) || istype(C, /obj/item/device/pda) )
+ var/obj/item/weapon/card/id/ID = C
+
+ if( istype(C, /obj/item/device/pda) )
+ var/obj/item/device/pda/pda = C
+ ID = pda.id
+ if(!istype(ID))
+ ID = null
+
+ if(ID)
+ return ID.registered_name
+
+ C = H.wear_id
+
+ if( istype(C) || istype(C, /obj/item/device/pda) )
+ var/obj/item/weapon/card/id/ID = C
+
+ if( istype(C, /obj/item/device/pda) )
+ var/obj/item/device/pda/pda = C
+ ID = pda.id
+ if(!istype(ID))
+ ID = null
+
+ if(ID)
+ return ID.registered_name
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index 2f586ef0e99..85843cca50f 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -1,5 +1,6 @@
-//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
-
+////////////////////////////////////////
+//CONTAINS: Air Alarms and Fire Alarms//
+////////////////////////////////////////
/proc/RandomAAlarmWires()
//to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else).
@@ -21,119 +22,29 @@
flagIndex+=1
return AAlarmwires
+#define AALARM_WIRE_IDSCAN 1 //Added wires
+#define AALARM_WIRE_POWER 2
+#define AALARM_WIRE_SYPHON 3
+#define AALARM_WIRE_AI_CONTROL 4
+#define AALARM_WIRE_AALARM 5
+#define AALARM_MODE_SCRUBBING 1
+#define AALARM_MODE_REPLACEMENT 2 //like scrubbing, but faster.
+#define AALARM_MODE_PANIC 3 //constantly sucks all air
+#define AALARM_MODE_CYCLE 4 //sucks off all air, then refill and swithes to scrubbing
+#define AALARM_MODE_FILL 5 //emergency fill
-// A datum for dealing with threshold limit values
-// used in /obj/machinery/alarm
-/datum/tlv
- var/min2
- var/min1
- var/max1
- var/max2
- New(_min2 as num, _min1 as num, _max1 as num, _max2 as num)
- min2 = _min2
- min1 = _min1
- max1 = _max1
- max2 = _max2
- proc/get_danger_level(curval as num)
- if (max2 >=0 && curval>=max2)
- return 2
- if (min2 >=0 && curval<=min2)
- return 2
- if (max1 >=0 && curval>=max1)
- return 1
- if (min1 >=0 && curval<=min1)
- return 1
- return 0
- proc/CopyFrom(datum/tlv/other)
- min2 = other.min2
- min1 = other.min1
- max1 = other.max1
- max2 = other.max2
+#define AALARM_SCREEN_MAIN 1
+#define AALARM_SCREEN_VENT 2
+#define AALARM_SCREEN_SCRUB 3
+#define AALARM_SCREEN_MODE 4
+#define AALARM_SCREEN_SENSORS 5
-/obj/machinery/alarm
- name = "alarm"
- icon = 'icons/obj/monitors.dmi'
- icon_state = "alarm0"
- anchored = 1
- use_power = 1
- idle_power_usage = 4
- active_power_usage = 8
- power_channel = ENVIRON
- req_access = list(access_atmospherics)
- var/frequency = 1439
- //var/skipprocess = 0 //Experimenting
- var/alarm_frequency = 1437
#define AALARM_REPORT_TIMEOUT 100
- var/datum/radio_frequency/radio_connection
- var/locked = 1
- var/wiresexposed = 0 // If it's been screwdrivered open.
- var/aidisabled = 0
- var/AAlarmwires = 31
- var/shorted = 0
- var/remote_control = 0
- // Uses code from apc.dm
-
-#define AALARM_WIRE_IDSCAN 1 //Added wires
-#define AALARM_WIRE_POWER 2
-#define AALARM_WIRE_SYPHON 3
-#define AALARM_WIRE_AI_CONTROL 4
-#define AALARM_WIRE_AALARM 5
-
-
-#define AALARM_MODE_SCRUBBING 1
-#define AALARM_MODE_VENTING 2 //makes draught
-#define AALARM_MODE_PANIC 3 //constantly sucks all air
-#define AALARM_MODE_REPLACEMENT 4 //sucks off all air, then refill and swithes to scrubbing
-#define AALARM_MODE_OFF 5
- var/mode = AALARM_MODE_SCRUBBING
-
-#define AALARM_SCREEN_MAIN 1
-#define AALARM_SCREEN_VENT 2
-#define AALARM_SCREEN_SCRUB 3
-#define AALARM_SCREEN_MODE 4
-#define AALARM_SCREEN_SENSORS 5
- var/screen = AALARM_SCREEN_MAIN
- var/area_uid
- var/area/alarm_area
- var/danger_level = 0
-
- // breathable air according to human/Life()
- var/list/TLV = list(
- "oxygen" = new/datum/tlv( 16, 19, 135, 140), // Partial pressure, kpa
- "carbon dioxide" = new/datum/tlv(-1.0, -1.0, 5, 10), // Partial pressure, kpa
- "plasma" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
- "other" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // Partial pressure, kpa
- "pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20), /* kpa */
- "temperature" = new/datum/tlv(T0C, T0C+10, T0C+40, T0C+66), // K
- )
-
-/*
- // breathable air according to wikipedia
- "oxygen" = new/datum/tlv( 9, 12, 158, 296), // Partial pressure, kpa
- "carbon dioxide" = new/datum/tlv(-1.0,-1.0, 0.5, 1), // Partial pressure, kpa
-*/
-/obj/machinery/alarm/server
- //req_access = list(access_rd) //no, let departaments to work together
- TLV = list(
- "oxygen" = new/datum/tlv(-1.0, -1.0,-1.0,-1.0), // Partial pressure, kpa
- "carbon dioxide" = new/datum/tlv(-1.0, -1.0, 5, 10), // Partial pressure, kpa
- "plasma" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
- "other" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // Partial pressure, kpa
- "pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.40,ONE_ATMOSPHERE*1.60), /* kpa */
- "temperature" = new/datum/tlv(40, 60, 100, 120), // K
- )
-
-/obj/machinery/alarm/kitchen_cold_room
- TLV = list(
- "oxygen" = new/datum/tlv( 16, 19, 135, 140), // Partial pressure, kpa
- "carbon dioxide" = new/datum/tlv(-1.0, -1.0, 5, 10), // Partial pressure, kpa
- "plasma" = new/datum/tlv(-1.0, -1.0, 0.2, 0.5), // Partial pressure, kpa
- "other" = new/datum/tlv(-1.0, -1.0, 0.5, 1.0), // Partial pressure, kpa
- "pressure" = new/datum/tlv(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.50,ONE_ATMOSPHERE*1.60), /* kpa */
- "temperature" = new/datum/tlv(200, 210, 273.15, 283.15), // K
- )
+#define RCON_NO 1
+#define RCON_AUTO 2
+#define RCON_YES 3
//all air alarms in area are connected via magic
/area
@@ -143,508 +54,737 @@
var/list/air_vent_info
var/list/air_scrub_info
-/obj/machinery/alarm/New()
- ..()
- alarm_area = get_area(loc)
- if (alarm_area.master)
- alarm_area = alarm_area.master
- area_uid = alarm_area.uid
- if (name == "alarm")
- name = "[alarm_area.name] Air Alarm"
+/obj/machinery/alarm
+ name = "alarm"
+ icon = 'monitors.dmi'
+ icon_state = "alarm0"
+ anchored = 1
+ use_power = 1
+ idle_power_usage = 4
+ active_power_usage = 8
+ power_channel = ENVIRON
+ req_access = list(access_atmospherics, access_engine_equip)
+ var/frequency = 1439
+ //var/skipprocess = 0 //Experimenting
+ var/alarm_frequency = 1437
+ var/remote_control = 0
+ var/rcon_setting = 2
+ var/rcon_time = 0
+ var/locked = 1
+ var/wiresexposed = 0 // If it's been screwdrivered open.
+ var/aidisabled = 0
+ var/AAlarmwires = 31
+ var/shorted = 0
-/obj/machinery/alarm/initialize()
- set_frequency(frequency)
- if (!master_is_operating())
- elect_master()
+ var/mode = AALARM_MODE_SCRUBBING
+ var/screen = AALARM_SCREEN_MAIN
+ var/area_uid
+ var/area/alarm_area
+ var/danger_level = 0
-/obj/machinery/alarm/proc/master_is_operating()
- return alarm_area.master_air_alarm && !(alarm_area.master_air_alarm.stat & (NOPOWER|BROKEN))
+ var/datum/radio_frequency/radio_connection
-/obj/machinery/alarm/proc/elect_master()
- for (var/area/A in alarm_area.related)
- for (var/obj/machinery/alarm/AA in A)
- if (!(AA.stat & (NOPOWER|BROKEN)))
- alarm_area.master_air_alarm = AA
- if (!alarm_area.air_vent_names)
- alarm_area.air_vent_names = new
- alarm_area.air_scrub_names = new
- alarm_area.air_vent_info = new
- alarm_area.air_scrub_info = new
- return 1
- return 0
+ var/list/TLV = list()
-/obj/machinery/alarm/attack_hand(mob/user)
- . = ..()
- if (.)
- return
- user.set_machine(src)
+ server/New()
+ ..()
+ req_access = list(access_rd, access_atmospherics, access_engine_equip)
+ TLV["oxygen"] = list(-1.0, -1.0,-1.0,-1.0) // Partial pressure, kpa
+ TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
+ TLV["plasma"] = list(-1.0, -1.0, 0.2, 0.5) // Partial pressure, kpa
+ TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa
+ TLV["pressure"] = list(0,ONE_ATMOSPHERE*0.10,ONE_ATMOSPHERE*1.40,ONE_ATMOSPHERE*1.60) /* kpa */
+ TLV["temperature"] = list(20, 40, 140, 160) // K
- if ( (get_dist(src, user) > 1 ))
- if (!istype(user, /mob/living/silicon))
- user.unset_machine()
- user << browse(null, "window=air_alarm")
- user << browse(null, "window=AAlarmwires")
+ New()
+ ..()
+ alarm_area = get_area(src)
+ if (alarm_area.master)
+ alarm_area = alarm_area.master
+ area_uid = alarm_area.uid
+ if (name == "alarm")
+ name = "[alarm_area.name] Air Alarm"
+
+ // breathable air according to human/Life()
+ TLV["oxygen"] = list(16, 19, 135, 140) // Partial pressure, kpa
+ TLV["carbon dioxide"] = list(-1.0, -1.0, 5, 10) // Partial pressure, kpa
+ TLV["plasma"] = list(-1.0, -1.0, 0.2, 0.5) // Partial pressure, kpa
+ TLV["other"] = list(-1.0, -1.0, 0.5, 1.0) // Partial pressure, kpa
+ TLV["pressure"] = list(ONE_ATMOSPHERE*0.80,ONE_ATMOSPHERE*0.90,ONE_ATMOSPHERE*1.10,ONE_ATMOSPHERE*1.20) /* kpa */
+ TLV["temperature"] = list(T0C, T0C+10, T0C+40, T0C+66) // K
+
+ initialize()
+ set_frequency(frequency)
+ if (!master_is_operating())
+ elect_master()
+
+
+ process()
+ if((stat & (NOPOWER|BROKEN)) || shorted)
return
+ var/turf/simulated/location = loc
+ ASSERT(istype(location))
- else if (istype(user, /mob/living/silicon) && src.aidisabled)
- user << "AI control for this Air Alarm interface has been disabled."
- user << browse(null, "window=air_alarm")
- return
+ var/datum/gas_mixture/environment = location.return_air()
+ var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
- if(wiresexposed && (!istype(user, /mob/living/silicon)))
- var/t1 = text("
[alarm_area.name] Air Alarm WiresAccess Panel
\n")
- var/list/AAlarmwires = list(
- "Orange" = 1,
- "Dark red" = 2,
- "White" = 3,
- "Yellow" = 4,
- "Black" = 5,
- )
- for(var/wiredesc in AAlarmwires)
- var/is_uncut = src.AAlarmwires & AAlarmWireColorToFlag[AAlarmwires[wiredesc]]
- t1 += "[wiredesc] wire: "
- if(!is_uncut)
- t1 += "Mend"
+ var/list/current_settings = TLV["pressure"]
+ var/environment_pressure = environment.return_pressure()
+ var/pressure_dangerlevel = get_danger_level(environment_pressure, current_settings)
- else
- t1 += "Cut "
- t1 += "Pulse "
+ current_settings = TLV["oxygen"]
+ var/oxygen_dangerlevel = get_danger_level(environment.oxygen*partial_pressure, current_settings)
- t1 += "
"
- t1 += text("
\n[(src.locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")]
\n[((src.shorted || (stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")]
\n[(src.aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
- t1 += text("Close
")
- user << browse(t1, "window=AAlarmwires")
- onclose(user, "AAlarmwires")
+ current_settings = TLV["carbon dioxide"]
+ var/co2_dangerlevel = get_danger_level(environment.carbon_dioxide*partial_pressure, current_settings)
- if(!shorted)
- user << browse(return_text(),"window=air_alarm")
- onclose(user, "air_alarm")
- refresh_all()
+ current_settings = TLV["plasma"]
+ var/plasma_dangerlevel = get_danger_level(environment.toxins*partial_pressure, current_settings)
- return
+ current_settings = TLV["other"]
+ var/other_moles = 0.0
+ for(var/datum/gas/G in environment.trace_gases)
+ other_moles+=G.moles
+ var/other_dangerlevel = get_danger_level(other_moles*partial_pressure, current_settings)
+ current_settings = TLV["temperature"]
+ var/temperature_dangerlevel = get_danger_level(environment.temperature, current_settings)
-/obj/machinery/alarm/proc/isWireColorCut(var/wireColor)
- var/wireFlag = AAlarmWireColorToFlag[wireColor]
- return ((src.AAlarmwires & wireFlag) == 0)
+ var/old_danger_level = danger_level
+ danger_level = max(pressure_dangerlevel,
+ oxygen_dangerlevel,
+ co2_dangerlevel,
+ plasma_dangerlevel,
+ other_dangerlevel,
+ temperature_dangerlevel)
-/obj/machinery/alarm/proc/isWireCut(var/wireIndex)
- var/wireFlag = AAlarmIndexToFlag[wireIndex]
- return ((src.AAlarmwires & wireFlag) == 0)
+ if (old_danger_level != danger_level)
+ apply_danger_level(danger_level)
-/obj/machinery/alarm/proc/cut(var/wireColor)
- var/wireFlag = AAlarmWireColorToFlag[wireColor]
- var/wireIndex = AAlarmWireColorToIndex[wireColor]
- AAlarmwires &= ~wireFlag
- switch(wireIndex)
- if(AALARM_WIRE_IDSCAN)
- src.locked = 1
- //world << "Idscan wire cut"
-
- if(AALARM_WIRE_POWER)
- src.shock(usr, 50)
- src.shorted = 1
- update_icon()
- //world << "Power wire cut"
-
- if (AALARM_WIRE_AI_CONTROL)
- if (src.aidisabled == 0)
- src.aidisabled = 1
- //world << "AI Control Wire Cut"
-
- if(AALARM_WIRE_SYPHON)
- mode = AALARM_MODE_PANIC
+ if (mode==AALARM_MODE_CYCLE && environment_pressure= danger_levels[4] || current_value <= danger_levels[1])
+ return 2
+ if(current_value >= danger_levels[3] || current_value <= danger_levels[2])
+ return 1
+ return 0
+
+ update_icon()
+ if(wiresexposed)
+ icon_state = "alarmx"
+ return
+ if((stat & (NOPOWER|BROKEN)) || shorted)
+ icon_state = "alarmp"
+ return
+ switch(max(danger_level, alarm_area.atmosalm))
+ if (0)
+ icon_state = "alarm0"
+ if (1)
+ icon_state = "alarm2" //yes, alarm2 is yellow alarm
+ if (2)
+ icon_state = "alarm1"
+
+ receive_signal(datum/signal/signal)
+ if(stat & (NOPOWER|BROKEN))
+ return
+ if (alarm_area.master_air_alarm != src)
+ if (master_is_operating())
+ return
+ elect_master()
+ if (alarm_area.master_air_alarm != src)
+ return
+ if(!signal || signal.encryption)
+ return
+ var/id_tag = signal.data["tag"]
+ if (!id_tag)
+ return
+ if (signal.data["area"] != area_uid)
+ return
+ if (signal.data["sigtype"] != "status")
+ return
+
+ var/dev_type = signal.data["device"]
+ if(!(id_tag in alarm_area.air_scrub_names) && !(id_tag in alarm_area.air_vent_names))
+ register_env_machine(id_tag, dev_type)
+ if(dev_type == "AScr")
+ alarm_area.air_scrub_info[id_tag] = signal.data
+ else if(dev_type == "AVP")
+ alarm_area.air_vent_info[id_tag] = signal.data
+
+ proc/register_env_machine(var/m_id, var/device_type)
+ var/new_name
+ if (device_type=="AVP")
+ new_name = "[alarm_area.name] Vent Pump #[alarm_area.air_vent_names.len+1]"
+ alarm_area.air_vent_names[m_id] = new_name
+ else if (device_type=="AScr")
+ new_name = "[alarm_area.name] Air Scrubber #[alarm_area.air_scrub_names.len+1]"
+ alarm_area.air_scrub_names[m_id] = new_name
+ else
+ return
+ spawn (10)
+ send_signal(m_id, list("init" = new_name) )
+
+ proc/refresh_all()
+ for(var/id_tag in alarm_area.air_vent_names)
+ var/list/I = alarm_area.air_vent_info[id_tag]
+ if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
+ continue
+ send_signal(id_tag, list("status") )
+ for(var/id_tag in alarm_area.air_scrub_names)
+ var/list/I = alarm_area.air_scrub_info[id_tag]
+ if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
+ continue
+ send_signal(id_tag, list("status") )
+
+ proc/set_frequency(new_frequency)
+ radio_controller.remove_object(src, frequency)
+ frequency = new_frequency
+ radio_connection = radio_controller.add_object(src, frequency, RADIO_TO_AIRALARM)
+
+ proc/send_signal(var/target, var/list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise
+ if(!radio_connection)
+ return 0
+
+ var/datum/signal/signal = new
+ signal.transmission_method = 1 //radio signal
+ signal.source = src
+
+ signal.data = command
+ signal.data["tag"] = target
+ signal.data["sigtype"] = "command"
+
+ radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM)
+ // world << text("Signal [] Broadcasted to []", command, target)
+
+ return 1
+
+ proc/apply_mode()
+ var/current_pressures = TLV["pressure"]
+ var/target_pressure = (current_pressures[2] + current_pressures[3])/2
+ switch(mode)
+ if(AALARM_MODE_SCRUBBING)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 1, "co2_scrub"= 1, "setting"= 1, "scrubbing"= 1, "panic_siphon"= 0) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 1, "checks"= 1, "setting"= 1, "set_external_pressure"= target_pressure) )
+
+ if(AALARM_MODE_PANIC, AALARM_MODE_CYCLE)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 1, "panic_siphon"= 1) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 0) )
+
+ if(AALARM_MODE_REPLACEMENT)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 1, "co2_scrub"= 1, "setting"= 3, "scrubbing"= 1, "panic_siphon"= 0) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 1, "checks"= 1, "setting"= 3, "set_external_pressure"= target_pressure) )
+
+ if(AALARM_MODE_FILL)
+ for(var/device_id in alarm_area.air_scrub_names)
+ send_signal(device_id, list("power"= 0) )
+ for(var/device_id in alarm_area.air_vent_names)
+ send_signal(device_id, list("power"= 1, "checks"= 1, "setting"= 3, "set_external_pressure"= target_pressure) )
+
+ proc/apply_danger_level(var/new_danger_level)
+ alarm_area.atmosalm = new_danger_level
+
+ for (var/area/A in alarm_area.related)
+ for (var/obj/machinery/alarm/AA in A)
+ if ( !(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.danger_level != new_danger_level)
+ AA.update_icon()
+
+ if(danger_level > 1)
+ air_doors_close(0)
+ else
+ air_doors_open(0)
+
+ update_icon()
+
+ proc/air_doors_close(manual)
+ var/area/A = get_area(src)
+ if(!A.master.air_doors_activated)
+ A.master.air_doors_activated = 1
+ for(var/obj/machinery/door/E in A.master.all_doors)
+ if(istype(E,/obj/machinery/door/firedoor))
+ if(!E:blocked)
+ if(E.operating)
+ E:nextstate = CLOSED
+ else if(!E.density)
+ spawn(0)
+ E.close()
+ continue
+
+/* if(istype(E, /obj/machinery/door/airlock))
+ if((!E:arePowerSystemsOn()) || (E.stat & NOPOWER) || E:air_locked) continue
+ if(!E.density)
+ spawn(0)
+ E.close()
+ spawn(10)
+ if(E.density)
+ E:air_locked = E.req_access
+ E:req_access = list(ACCESS_ENGINE, ACCESS_ATMOSPHERICS)
+ E.update_icon()
+ else if(E.operating)
+ spawn(10)
+ E.close()
+ if(E.density)
+ E:air_locked = E.req_access
+ E:req_access = list(ACCESS_ENGINE, ACCESS_ATMOSPHERICS)
+ E.update_icon()
+ else if(!E:locked) //Don't lock already bolted doors.
+ E:air_locked = E.req_access
+ E:req_access = list(ACCESS_ENGINE, ACCESS_ATMOSPHERICS)
+ E.update_icon()*/
+
+ proc/air_doors_open(manual)
+ var/area/A = get_area(loc)
+ if(A.master.air_doors_activated)
+ A.master.air_doors_activated = 0
+ for(var/obj/machinery/door/E in A.master.all_doors)
+ if(istype(E, /obj/machinery/door/firedoor))
+ if(!E:blocked)
+ if(E.operating)
+ E:nextstate = OPEN
+ else if(E.density)
+ spawn(0)
+ E.open()
+ continue
+
+/* if(istype(E, /obj/machinery/door/airlock))
+ if((!E:arePowerSystemsOn()) || (E.stat & NOPOWER)) continue
+ if(!isnull(E:air_locked)) //Don't mess with doors locked for other reasons.
+ E:req_access = E:air_locked
+ E:air_locked = null
+ E.update_icon()*/
+
+///////////
+//HACKING//
+///////////
+ proc/isWireColorCut(var/wireColor)
+ var/wireFlag = AAlarmWireColorToFlag[wireColor]
+ return ((AAlarmwires & wireFlag) == 0)
+
+ proc/isWireCut(var/wireIndex)
+ var/wireFlag = AAlarmIndexToFlag[wireIndex]
+ return ((AAlarmwires & wireFlag) == 0)
+
+ proc/cut(var/wireColor)
+ var/wireFlag = AAlarmWireColorToFlag[wireColor]
+ var/wireIndex = AAlarmWireColorToIndex[wireColor]
+ AAlarmwires &= ~wireFlag
+ switch(wireIndex)
+ if(AALARM_WIRE_IDSCAN)
+ locked = 1
+
+ if(AALARM_WIRE_POWER)
+ shock(usr, 50)
shorted = 1
update_icon()
- spawn(1200)
- if(shorted == 1)
- shorted = 0
+ if (AALARM_WIRE_AI_CONTROL)
+ if (aidisabled == 0)
+ aidisabled = 1
+
+ if(AALARM_WIRE_SYPHON)
+ mode = AALARM_MODE_PANIC
+ apply_mode()
+
+ if(AALARM_WIRE_AALARM)
+
+ if (alarm_area.atmosalert(2))
+ apply_danger_level(2)
+ spawn(1)
+ updateUsrDialog()
+ update_icon()
+
+ updateDialog()
+
+ return
+
+ proc/mend(var/wireColor)
+ var/wireFlag = AAlarmWireColorToFlag[wireColor]
+ var/wireIndex = AAlarmWireColorToIndex[wireColor] //not used in this function
+ AAlarmwires |= wireFlag
+ switch(wireIndex)
+ if(AALARM_WIRE_IDSCAN)
+
+ if(AALARM_WIRE_POWER)
+ shorted = 0
+ shock(usr, 50)
+ update_icon()
+
+ if(AALARM_WIRE_AI_CONTROL)
+ if (aidisabled == 1)
+ aidisabled = 0
+
+ updateDialog()
+ return
+
+ proc/pulse(var/wireColor)
+ //var/wireFlag = AAlarmWireColorToFlag[wireColor] //not used in this function
+ var/wireIndex = AAlarmWireColorToIndex[wireColor]
+ switch(wireIndex)
+ if(AALARM_WIRE_IDSCAN) //unlocks for 30 seconds, if you have a better way to hack I'm all ears
+ locked = 0
+ spawn(300)
+ locked = 1
+
+ if (AALARM_WIRE_POWER)
+ if(shorted == 0)
+ shorted = 1
update_icon()
+ spawn(1200)
+ if(shorted == 1)
+ shorted = 0
+ update_icon()
- if (AALARM_WIRE_AI_CONTROL)
- // world << "AI Control wire pulsed"
- if (src.aidisabled == 0)
- src.aidisabled = 1
- src.updateDialog()
- spawn(10)
- if (src.aidisabled == 1)
- src.aidisabled = 0
- src.updateDialog()
- if(AALARM_WIRE_SYPHON)
- // world << "Syphon wire pulsed"
- mode = AALARM_MODE_REPLACEMENT
- apply_mode()
+ if (AALARM_WIRE_AI_CONTROL)
+ if (aidisabled == 0)
+ aidisabled = 1
+ updateDialog()
+ spawn(10)
+ if (aidisabled == 1)
+ aidisabled = 0
+ updateDialog()
- if(AALARM_WIRE_AALARM)
- // world << "Aalarm wire pulsed"
- if (alarm_area.atmosalert(0))
- post_alert(0)
- spawn(1)
- src.updateUsrDialog()
- update_icon()
+ if(AALARM_WIRE_SYPHON)
+ mode = AALARM_MODE_REPLACEMENT
+ apply_mode()
- src.updateDialog()
- return
+ if(AALARM_WIRE_AALARM)
+ if (alarm_area.atmosalert(0))
+ apply_danger_level(0)
+ spawn(1)
+ updateUsrDialog()
+ update_icon()
-/obj/machinery/alarm/proc/shock(mob/user, prb)
- if((stat & (NOPOWER))) // unpowered, no shock
- return 0
- if(!prob(prb))
- return 0 //you lucked out, no shock for you
- var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
- s.set_up(5, 1, src)
- s.start() //sparks always.
- if (electrocute_mob(user, get_area(src), src))
- return 1
- else
- return 0
-
-/obj/machinery/alarm/receive_signal(datum/signal/signal)
- if(stat & (NOPOWER|BROKEN))
+ updateDialog()
return
- if (alarm_area.master_air_alarm != src)
- if (master_is_operating())
+
+ proc/shock(mob/user, prb)
+ if((stat & (NOPOWER))) // unpowered, no shock
+ return 0
+ if(!prob(prb))
+ return 0 //you lucked out, no shock for you
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(5, 1, src)
+ s.start() //sparks always.
+ if (electrocute_mob(user, get_area(src), src))
+ return 1
+ else
+ return 0
+///////////////
+//END HACKING//
+///////////////
+
+
+ attack_hand(mob/user)
+ . = ..()
+ if (.)
return
- elect_master()
- if (alarm_area.master_air_alarm != src)
- return
- if(!signal || signal.encryption)
- return
- var/id_tag = signal.data["tag"]
- if (!id_tag)
- return
- if (signal.data["area"] != area_uid)
- return
- if (signal.data["sigtype"] != "status")
+ user.set_machine(src)
+
+ if ( (get_dist(src, user) > 1 ))
+ if (!istype(user, /mob/living/silicon))
+ user.machine = null
+ user << browse(null, "window=air_alarm")
+ user << browse(null, "window=AAlarmwires")
+ return
+
+
+ else if (istype(user, /mob/living/silicon) && aidisabled)
+ user << "AI control for this Air Alarm interface has been disabled."
+ user << browse(null, "window=air_alarm")
+ return
+
+ if(wiresexposed && (!istype(user, /mob/living/silicon)))
+ var/t1 = text("[alarm_area.name] Air Alarm WiresAccess Panel
\n")
+ var/list/AAlarmwires = list(
+ "Orange" = 1,
+ "Dark red" = 2,
+ "White" = 3,
+ "Yellow" = 4,
+ "Black" = 5,
+ )
+ for(var/wiredesc in AAlarmwires)
+ var/is_uncut = AAlarmwires & AAlarmWireColorToFlag[AAlarmwires[wiredesc]]
+ t1 += "[wiredesc] wire: "
+ if(!is_uncut)
+ t1 += "Mend"
+
+ else
+ t1 += "Cut "
+ t1 += "Pulse "
+
+ t1 += "
"
+ t1 += text("
\n[(locked ? "The Air Alarm is locked." : "The Air Alarm is unlocked.")]
\n[((shorted || (stat & (NOPOWER|BROKEN))) ? "The Air Alarm is offline." : "The Air Alarm is working properly!")]
\n[(aidisabled ? "The 'AI control allowed' light is off." : "The 'AI control allowed' light is on.")]")
+ t1 += text("Close
")
+ user << browse(t1, "window=AAlarmwires")
+ onclose(user, "AAlarmwires")
+
+ if(!shorted)
+ user << browse(return_text(user),"window=air_alarm")
+ onclose(user, "air_alarm")
+
return
- var/dev_type = signal.data["device"]
- if(!(id_tag in alarm_area.air_scrub_names) && !(id_tag in alarm_area.air_vent_names))
- register_env_machine(id_tag, dev_type)
- if(dev_type == "AScr")
- alarm_area.air_scrub_info[id_tag] = signal.data
- else if(dev_type == "AVP")
- alarm_area.air_vent_info[id_tag] = signal.data
+ proc/return_text(mob/user)
+ if(!(istype(user, /mob/living/silicon)) && locked)
+ return "\The [src][return_status()]
[rcon_text()]
(Swipe ID card to unlock interface)"
+ else
+ return "\The [src][return_status()]
[rcon_text()]
[return_controls()]"
-/obj/machinery/alarm/proc/register_env_machine(var/m_id, var/device_type)
- var/new_name
- if (device_type=="AVP")
- new_name = "[alarm_area.name] Vent Pump #[alarm_area.air_vent_names.len+1]"
- alarm_area.air_vent_names[m_id] = new_name
- else if (device_type=="AScr")
- new_name = "[alarm_area.name] Air Scrubber #[alarm_area.air_scrub_names.len+1]"
- alarm_area.air_scrub_names[m_id] = new_name
- else
- return
- spawn (10)
- send_signal(m_id, list("init" = new_name) )
+ proc/return_status()
+ var/turf/location = get_turf(src)
+ var/datum/gas_mixture/environment = location.return_air()
+ var/total = environment.oxygen + environment.carbon_dioxide + environment.toxins + environment.nitrogen
+ var/output = "Air Status:
"
-/obj/machinery/alarm/proc/refresh_all()
- for(var/id_tag in alarm_area.air_vent_names)
- var/list/I = alarm_area.air_vent_info[id_tag]
- if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
- continue
- send_signal(id_tag, list("status") )
- for(var/id_tag in alarm_area.air_scrub_names)
- var/list/I = alarm_area.air_scrub_info[id_tag]
- if (I && I["timestamp"]+AALARM_REPORT_TIMEOUT/2 > world.time)
- continue
- send_signal(id_tag, list("status") )
+ if(total == 0)
+ output += "Warning: Cannot obtain air sample for analysis."
+ return output
-/obj/machinery/alarm/proc/set_frequency(new_frequency)
- radio_controller.remove_object(src, frequency)
- frequency = new_frequency
- radio_connection = radio_controller.add_object(src, frequency, RADIO_TO_AIRALARM)
-
-/obj/machinery/alarm/proc/send_signal(var/target, var/list/command)//sends signal 'command' to 'target'. Returns 0 if no radio connection, 1 otherwise
- if(!radio_connection)
- return 0
-
- var/datum/signal/signal = new
- signal.transmission_method = 1 //radio signal
- signal.source = src
-
- signal.data = command
- signal.data["tag"] = target
- signal.data["sigtype"] = "command"
-
- radio_connection.post_signal(src, signal, RADIO_FROM_AIRALARM)
-// world << text("Signal [] Broadcasted to []", command, target)
-
- return 1
-
-/obj/machinery/alarm/proc/return_text()
- if(!(istype(usr, /mob/living/silicon)) && locked)
- return "[src][return_status()]
(Swipe ID card to unlock interface)"
- else
- return "[src][return_status()]
[return_controls()]"
-
-/obj/machinery/alarm/proc/return_status()
- var/turf/location = src.loc
- var/datum/gas_mixture/environment = location.return_air()
- var/total = environment.oxygen + environment.carbon_dioxide + environment.toxins + environment.nitrogen
- var/output = "Air Status:
"
-
- if(total == 0)
- output +={"Warning: Cannot obtain air sample for analysis."}
- return output
-
- output += {"
+ output += {"
"}
- var/datum/tlv/cur_tlv
- var/GET_PP = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
- cur_tlv = TLV["pressure"]
- var/environment_pressure = environment.return_pressure()
- var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure)
+ var/partial_pressure = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
- cur_tlv = TLV["oxygen"]
- var/oxygen_dangerlevel = cur_tlv.get_danger_level(environment.oxygen*GET_PP)
- var/oxygen_percent = round(environment.oxygen / total * 100, 2)
+ var/list/current_settings = TLV["pressure"]
+ var/environment_pressure = environment.return_pressure()
+ var/pressure_dangerlevel = get_danger_level(environment_pressure, current_settings)
- cur_tlv = TLV["carbon dioxide"]
- var/co2_dangerlevel = cur_tlv.get_danger_level(environment.carbon_dioxide*GET_PP)
- var/co2_percent = round(environment.carbon_dioxide / total * 100, 2)
+ current_settings = TLV["oxygen"]
+ var/oxygen_dangerlevel = get_danger_level(environment.oxygen*partial_pressure, current_settings)
+ var/oxygen_percent = round(environment.oxygen / total * 100, 2)
- cur_tlv = TLV["plasma"]
- var/plasma_dangerlevel = cur_tlv.get_danger_level(environment.toxins*GET_PP)
- var/plasma_percent = round(environment.toxins / total * 100, 2)
+ current_settings = TLV["carbon dioxide"]
+ var/co2_dangerlevel = get_danger_level(environment.carbon_dioxide*partial_pressure, current_settings)
+ var/co2_percent = round(environment.carbon_dioxide / total * 100, 2)
- cur_tlv = TLV["other"]
- var/other_moles = 0.0
- for(var/datum/gas/G in environment.trace_gases)
- other_moles+=G.moles
- var/other_dangerlevel = cur_tlv.get_danger_level(other_moles*GET_PP)
+ current_settings = TLV["plasma"]
+ var/plasma_dangerlevel = get_danger_level(environment.toxins*partial_pressure, current_settings)
+ var/plasma_percent = round(environment.toxins / total * 100, 2)
- cur_tlv = TLV["temperature"]
- var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature)
+ current_settings = TLV["other"]
+ var/other_moles = 0.0
+ for(var/datum/gas/G in environment.trace_gases)
+ other_moles+=G.moles
+ var/other_dangerlevel = get_danger_level(other_moles*partial_pressure, current_settings)
- output += {"
+ current_settings = TLV["temperature"]
+ var/temperature_dangerlevel = get_danger_level(environment.temperature, current_settings)
+
+ output += {"
Pressure: [environment_pressure]kPa
Oxygen: [oxygen_percent]%
Carbon dioxide: [co2_percent]%
Toxins: [plasma_percent]%
"}
- if (other_dangerlevel==2)
- output += {"Notice: High Concentration of Unknown Particles Detected
"}
- else if (other_dangerlevel==1)
- output += {"Notice: Low Concentration of Unknown Particles Detected
"}
+ if (other_dangerlevel==2)
+ output += "Notice: High Concentration of Unknown Particles Detected
"
+ else if (other_dangerlevel==1)
+ output += "Notice: Low Concentration of Unknown Particles Detected
"
- output += {"
-Temperature: [environment.temperature]K
-"}
+ output += "Temperature: [environment.temperature]K
"
- var/display_danger_level = max(
- pressure_dangerlevel,
- oxygen_dangerlevel,
- co2_dangerlevel,
- plasma_dangerlevel,
- other_dangerlevel,
- temperature_dangerlevel
- )
+ //Overall status
+ output += "Local Status: "
+ switch(max(pressure_dangerlevel,oxygen_dangerlevel,co2_dangerlevel,plasma_dangerlevel,other_dangerlevel,temperature_dangerlevel))
+ if(2)
+ output += "DANGER: Internals Required"
+ if(1)
+ output += "Caution"
+ if(0)
+ if(alarm_area.atmosalm)
+ output += {"Caution: Atmos alert in area"}
+ else
+ output += {"Optimal"}
- //Overall status
- output += {"Local Status: "}
- if(display_danger_level == 2)
- output += {"DANGER: Internals Required"}
- else if(display_danger_level == 1)
- output += {"Caution"}
- else if (alarm_area.atmosalm)
- output += {"Caution: Atmos alert in area"}
- else
- output += {"Optimal"}
+ return output
- return output
+ proc/rcon_text()
+ var/dat = "Remote Control:
"
+ if(rcon_setting == RCON_NO)
+ dat += "Off"
+ else
+ dat += "Off"
+ dat += " | "
+ if(rcon_setting == RCON_AUTO)
+ dat += "Auto"
+ else
+ dat += "Auto"
+ dat += " | "
+ if(rcon_setting == RCON_YES)
+ dat += "On"
+ else
+ dat += "On"
+ return dat
-/obj/machinery/alarm/proc/return_controls()
- var/output = ""//"[alarm_zone] Air [name]
"
+ proc/return_controls()
+ var/output = ""//"[alarm_zone] Air [name]
"
- switch(screen)
- if (AALARM_SCREEN_MAIN)
- if(alarm_area.atmosalm)
- output += {"Reset - Atmospheric Alarm
"}
- else
- output += {"Activate - Atmospheric Alarm
"}
+ switch(screen)
+ if (AALARM_SCREEN_MAIN)
+ if(alarm_area.atmosalm)
+ output += "Reset - Atmospheric Alarm
"
+ else
+ output += "Activate - Atmospheric Alarm
"
- output += {"
+ output += {"
Scrubbers Control
Vents Control
Set environmentals mode
Sensor Settings
"}
- if (mode==AALARM_MODE_PANIC)
- output += "PANIC SYPHON ACTIVE
Turn syphoning off"
- else
- output += "ACTIVATE PANIC SYPHON IN AREA"
- if (AALARM_SCREEN_VENT)
- var/sensor_data = ""
- if(alarm_area.air_vent_names.len)
- for(var/id_tag in alarm_area.air_vent_names)
- var/long_name = alarm_area.air_vent_names[id_tag]
- var/list/data = alarm_area.air_vent_info[id_tag]
- if(!data)
- continue;
- var/state = ""
-
- sensor_data += {"
-[long_name][state]
-Operating:
-[data["power"]?"on":"off"]
-
-Pressure checks:
-external
-internal
-
-External pressure bound:
--
--
--
--
-[data["external"]]
-+
-+
-+
-+
- (reset)
-
-"}
- if (data["direction"] == "siphon")
- sensor_data += {"
-Direction:
-siphoning
-
-"}
- sensor_data += {"
"}
- else
- sensor_data = "No vents connected.
"
- output = {"Main menu
[sensor_data]"}
- if (AALARM_SCREEN_SCRUB)
- var/sensor_data = ""
- if(alarm_area.air_scrub_names.len)
- for(var/id_tag in alarm_area.air_scrub_names)
- var/long_name = alarm_area.air_scrub_names[id_tag]
- var/list/data = alarm_area.air_scrub_info[id_tag]
- if(!data)
- continue;
- var/state = ""
-
- sensor_data += {"
-[long_name][state]
-Operating:
-[data["power"]?"on":"off"]
-Type:
-[data["scrubbing"]?"scrubbing":"syphoning"]
-"}
-
- if(data["scrubbing"])
- sensor_data += {"
-Filtering:
-Carbon Dioxide
-[data["filter_co2"]?"on":"off"];
-Toxins
-[data["filter_toxins"]?"on":"off"];
-Nitrous Oxide
-[data["filter_n2o"]?"on":"off"]
-
-"}
- sensor_data += {"
-Panic syphon: [data["panic"]?"PANIC SYPHON ACTIVATED":""]
-Dea":"red'>A")]ctivate
-
-"}
- else
- sensor_data = "No scrubbers connected.
"
- output = {"Main menu
[sensor_data]"}
-
- if (AALARM_SCREEN_MODE)
- output += {"
-Main menu
-Air machinery mode for the area:"}
- var/list/modes = list(
- AALARM_MODE_SCRUBBING = "Filtering",
- AALARM_MODE_VENTING = "Draught",
- AALARM_MODE_PANIC = "PANIC",
- AALARM_MODE_REPLACEMENT = "REPLACE AIR",
- AALARM_MODE_OFF = "Off",
- )
- for (var/m=1,m<=modes.len,m++)
- if (mode==m)
- output += {"- [modes[m]] (selected)
"}
+ if (mode==AALARM_MODE_PANIC)
+ output += "PANIC SYPHON ACTIVE
Turn syphoning off"
else
- output += {"- [modes[m]]
"}
- output += "
"
- if (AALARM_SCREEN_SENSORS)
- output += {"
+ output += "ACTIVATE PANIC SYPHON IN AREA"
+
+
+ if (AALARM_SCREEN_VENT)
+ var/sensor_data = ""
+ if(alarm_area.air_vent_names.len)
+ for(var/id_tag in alarm_area.air_vent_names)
+ var/long_name = alarm_area.air_vent_names[id_tag]
+ var/list/data = alarm_area.air_vent_info[id_tag]
+ if(!data)
+ continue;
+ var/state = ""
+
+ sensor_data += {"
+ [long_name][state]
+ Operating:
+ [data["power"]?"on":"off"]
+
+ Pressure checks:
+ external
+ internal
+
+ External pressure bound:
+ -
+ -
+ -
+ -
+ [data["external"]]
+ +
+ +
+ +
+ +
+ (reset)
+
+ "}
+ if (data["direction"] == "siphon")
+ sensor_data += {"
+ Direction:
+ siphoning
+
+ "}
+ sensor_data += {"
"}
+ else
+ sensor_data = "No vents connected.
"
+ output = {"Main menu
[sensor_data]"}
+ if (AALARM_SCREEN_SCRUB)
+ var/sensor_data = ""
+ if(alarm_area.air_scrub_names.len)
+ for(var/id_tag in alarm_area.air_scrub_names)
+ var/long_name = alarm_area.air_scrub_names[id_tag]
+ var/list/data = alarm_area.air_scrub_info[id_tag]
+ if(!data)
+ continue;
+ var/state = ""
+
+ sensor_data += {"
+ [long_name][state]
+ Operating:
+ [data["power"]?"on":"off"]
+ Type:
+ [data["scrubbing"]?"scrubbing":"syphoning"]
+ "}
+
+ if(data["scrubbing"])
+ sensor_data += {"
+ Filtering:
+ Carbon Dioxide
+ [data["filter_co2"]?"on":"off"];
+ Toxins
+ [data["filter_toxins"]?"on":"off"];
+ Nitrous Oxide
+ [data["filter_n2o"]?"on":"off"]
+
+ "}
+ sensor_data += {"
+ Panic syphon: [data["panic"]?"PANIC SYPHON ACTIVATED":""]
+ Dea":"red'>A")]ctivate
+
+ "}
+ else
+ sensor_data = "No scrubbers connected.
"
+ output = {"Main menu
[sensor_data]"}
+
+ if (AALARM_SCREEN_MODE)
+ output += "Main menu
Air machinery mode for the area:"
+ var/list/modes = list(AALARM_MODE_SCRUBBING = "Filtering",\
+ AALARM_MODE_REPLACEMENT = "REPLACE AIR",\
+ AALARM_MODE_PANIC = "PANIC",\
+ AALARM_MODE_CYCLE = "CYCLE",\
+ AALARM_MODE_FILL = "FILL",)
+ for (var/m=1,m<=modes.len,m++)
+ if (mode==m)
+ output += "- [modes[m]] (selected)
"
+ else
+ output += "- [modes[m]]
"
+ output += "
"
+
+ if (AALARM_SCREEN_SENSORS)
+ output += {"
Main menu
Alarm thresholds:
Partial pressure for gases
@@ -660,318 +800,165 @@ table tr:first-child th:first-child { border: none;}
| min2 | min1 | max1 | max2 |
"}
- var/list/gases = list(
- "oxygen" = "O2",
- "carbon dioxide" = "CO2",
- "plasma" = "Toxin",
- "other" = "Other",
- )
- var/list/thresholds = list("min2", "min1", "max1", "max2")
- var/datum/tlv/tlv
- for (var/g in gases)
- output += {"
-| [gases[g]] |
-"}
- tlv = TLV[g]
- for (var/v in thresholds)
- output += {"
-
-[tlv.vars[v]>=0?tlv.vars[v]:"OFF"]
- |
-"}
- output += {"
-
-"}
- tlv = TLV["pressure"]
- output += {"
-| Pressure |
-"}
- for (var/v in thresholds)
- output += {"
-
-[tlv.vars[v]>=0?tlv.vars[v]:"OFF"]
- |
-"}
- output += {"
-
-"}
- tlv = TLV["temperature"]
- output += {"
-| Temperature |
-"}
- for (var/v in thresholds)
- output += {"
-
-[tlv.vars[v]>=0?tlv.vars[v]:"OFF"]
- |
-"}
- output += {"
-
-"}
- output += {"
"}
+ var/list/gases = list(
+ "oxygen" = "O2",
+ "carbon dioxide" = "CO2",
+ "plasma" = "Toxin",
+ "other" = "Other",)
- return output
+ var/list/selected
+ for (var/g in gases)
+ output += "| [gases[g]] | "
+ selected = TLV[g]
+ for(var/i = 1, i <= 4, i++)
+ output += "[selected[i] >= 0 ? selected[i] :"OFF"] | "
+ output += "
"
-/obj/machinery/alarm/Topic(href, href_list)
- if(..())
- return
- src.add_fingerprint(usr)
- usr.set_machine(src)
+ selected = TLV["pressure"]
+ output += " | Pressure | "
+ for(var/i = 1, i <= 4, i++)
+ output += "[selected[i] >= 0 ? selected[i] :"OFF"] | "
+ output += "
"
- if ( (get_dist(src, usr) > 1 ))
- if (!istype(usr, /mob/living/silicon))
- usr.unset_machine()
- usr << browse(null, "window=air_alarm")
- usr << browse(null, "window=AAlarmwires")
- return
+ selected = TLV["temperature"]
+ output += "| Temperature | "
+ for(var/i = 1, i <= 4, i++)
+ output += "[selected[i] >= 0 ? selected[i] :"OFF"] | "
+ output += "
"
- if (href_list["AAlarmwires"])
- var/t1 = text2num(href_list["AAlarmwires"])
- if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) ))
- usr << "You need wirecutters!"
- return
- if (src.isWireColorCut(t1))
- src.mend(t1)
- else
- src.cut(t1)
- else if (href_list["pulse"])
- var/t1 = text2num(href_list["pulse"])
- if (!istype(usr.get_active_hand(), /obj/item/device/multitool))
- usr << "You need a multitool!"
- return
- if (src.isWireColorCut(t1))
- usr << "You can't pulse a cut wire."
- return
- else
- src.pulse(t1)
+ return output
+ Topic(href, href_list)
+ if(href_list["rcon"])
+ rcon_setting = text2num(href_list["rcon"])
- if(href_list["command"])
- var/device_id = href_list["id_tag"]
- switch(href_list["command"])
- if(
- "power",
- "adjust_external_pressure",
- "set_external_pressure",
- "checks",
- "co2_scrub",
- "tox_scrub",
- "n2o_scrub",
- "panic_siphon",
- "scrubbing"
- )
- send_signal(device_id, list (href_list["command"] = text2num(href_list["val"])))
- spawn(3)
- src.updateUsrDialog()
+ if ( (get_dist(src, usr) > 1 ))
+ if (!istype(usr, /mob/living/silicon))
+ usr.machine = null
+ usr << browse(null, "window=air_alarm")
+ usr << browse(null, "window=AAlarmwires")
+ return
- //if("adjust_threshold") //was a good idea but required very wide window
- if("set_threshold")
- var/env = href_list["env"]
- var/varname = href_list["var"]
- var/datum/tlv/tlv = TLV[env]
- var/newval = input("Enter [varname] for env", "Alarm triggers", tlv.vars[varname]) as num|null
+ add_fingerprint(usr)
+ usr.machine = src
- if (isnull(newval) || ..() || (locked && !issilicon(usr)))
- return
- if (newval<0)
- tlv.vars[varname] = -1.0
- else if (env=="temperature" && newval>5000)
- tlv.vars[varname] = 5000
- else if (env=="pressure" && newval>50*ONE_ATMOSPHERE)
- tlv.vars[varname] = 50*ONE_ATMOSPHERE
- else if (env!="temperature" && env!="pressure" && newval>200)
- tlv.vars[varname] = 200
- else
- newval = round(newval,0.01)
- tlv.vars[varname] = newval
- spawn(1)
- src.updateUsrDialog()
+ if(href_list["command"])
+ var/device_id = href_list["id_tag"]
+ switch(href_list["command"])
+ if( "power",
+ "adjust_external_pressure",
+ "set_external_pressure",
+ "checks",
+ "co2_scrub",
+ "tox_scrub",
+ "n2o_scrub",
+ "panic_siphon",
+ "scrubbing")
- if(href_list["screen"])
- screen = text2num(href_list["screen"])
- spawn(1)
- src.updateUsrDialog()
+ send_signal(device_id, list(href_list["command"] = text2num(href_list["val"]) ) )
+ if("set_threshold")
+ var/env = href_list["env"]
+ var/threshold = text2num(href_list["var"])
+ var/list/selected = TLV[env]
+ var/list/thresholds = list("lower bound", "low warning", "high warning", "upper bound")
+ var/newval = input("Enter [thresholds[threshold]] for [env]", "Alarm triggers", selected[threshold]) as null|num
+ if (isnull(newval) || ..() || (locked && issilicon(usr)))
+ return
+ if (newval<0)
+ selected[threshold] = -1.0
+ else if (env=="temperature" && newval>5000)
+ selected[threshold] = 5000
+ else if (env=="pressure" && newval>50*ONE_ATMOSPHERE)
+ selected[threshold] = 50*ONE_ATMOSPHERE
+ else if (env!="temperature" && env!="pressure" && newval>200)
+ selected[threshold] = 200
+ else
+ newval = round(newval,0.01)
+ selected[threshold] = newval
+ if(threshold == 1)
+ if(selected[1] > selected[2])
+ selected[2] = selected[1]
+ if(selected[1] > selected[3])
+ selected[3] = selected[1]
+ if(selected[1] > selected[4])
+ selected[4] = selected[1]
+ if(threshold == 2)
+ if(selected[1] > selected[2])
+ selected[1] = selected[2]
+ if(selected[2] > selected[3])
+ selected[3] = selected[2]
+ if(selected[2] > selected[4])
+ selected[4] = selected[2]
+ if(threshold == 3)
+ if(selected[1] > selected[3])
+ selected[1] = selected[3]
+ if(selected[2] > selected[3])
+ selected[2] = selected[3]
+ if(selected[3] > selected[4])
+ selected[4] = selected[3]
+ if(threshold == 4)
+ if(selected[1] > selected[4])
+ selected[1] = selected[4]
+ if(selected[2] > selected[4])
+ selected[2] = selected[4]
+ if(selected[3] > selected[4])
+ selected[3] = selected[4]
+ apply_mode()
- if(href_list["atmos_alarm"])
- if (alarm_area.atmosalert(2))
- post_alert(2)
- spawn(1)
- src.updateUsrDialog()
- update_icon()
- if(href_list["atmos_reset"])
- if (alarm_area.atmosalert(0))
- post_alert(0)
- spawn(1)
- src.updateUsrDialog()
- update_icon()
+ if(href_list["screen"])
+ screen = text2num(href_list["screen"])
- if(href_list["mode"])
- mode = text2num(href_list["mode"])
- apply_mode()
- spawn(5)
- src.updateUsrDialog()
+ if(href_list["atmos_unlock"])
+ switch(href_list["atmos_unlock"])
+ if("0")
+ air_doors_close(1)
+ if("1")
+ air_doors_open(1)
- return
+ if(href_list["atmos_alarm"])
+ if (alarm_area.atmosalert(2))
+ apply_danger_level(2)
+ update_icon()
-/obj/machinery/alarm/proc/apply_mode()
- switch(mode)
- if(AALARM_MODE_SCRUBBING)
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "power"= 1,
- "co2_scrub"= 1,
- "scrubbing"= 1,
- "panic_siphon"= 0,
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 1,
- "checks"= 1,
- "set_external_pressure"= ONE_ATMOSPHERE
- ))
+ if(href_list["atmos_reset"])
+ if (alarm_area.atmosalert(0))
+ apply_danger_level(0)
+ update_icon()
- if(AALARM_MODE_VENTING)
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "power"= 1,
- "panic_siphon"= 0,
- "scrubbing"= 0
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 1,
- "checks"= 1,
- "set_external_pressure"= ONE_ATMOSPHERE
- ))
- if(
- AALARM_MODE_PANIC,
- AALARM_MODE_REPLACEMENT
- )
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "power"= 1,
- "panic_siphon"= 1
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 0
- ))
- /*if(AALARM_MODE_OFF) Commented out cause the "turn off panic" uses scrubbing mode now instead.
- for(var/device_id in alarm_area.air_scrub_names)
- send_signal(device_id, list(
- "panic_siphon" = 0
- ))
- for(var/device_id in alarm_area.air_vent_names)
- send_signal(device_id, list(
- "power"= 1
- ))*/
+ if(href_list["mode"])
+ mode = text2num(href_list["mode"])
+ apply_mode()
-/obj/machinery/alarm/update_icon()
- if(wiresexposed)
- icon_state = "alarmx"
- return
- if((stat & (NOPOWER|BROKEN)) || shorted)
- icon_state = "alarmp"
- return
- switch(max(danger_level, alarm_area.atmosalm))
- if (0)
- src.icon_state = "alarm0"
- if (1)
- src.icon_state = "alarm2" //yes, alarm2 is yellow alarm
- if (2)
- src.icon_state = "alarm1"
+ if (href_list["AAlarmwires"])
+ var/t1 = text2num(href_list["AAlarmwires"])
+ if (!( istype(usr.equipped(), /obj/item/weapon/wirecutters) ))
+ usr << "You need wirecutters!"
+ return
+ if (isWireColorCut(t1))
+ mend(t1)
+ else
+ cut(t1)
-/obj/machinery/alarm/process()
- if((stat & (NOPOWER|BROKEN)) || shorted)
- return
+ else if (href_list["pulse"])
+ var/t1 = text2num(href_list["pulse"])
+ if (!istype(usr.equipped(), /obj/item/device/multitool))
+ usr << "You need a multitool!"
+ return
+ if (isWireColorCut(t1))
+ usr << "You can't pulse a cut wire."
+ return
+ else
+ pulse(t1)
- var/turf/simulated/location = src.loc
- if (!istype(location))
- return 0
+ updateUsrDialog()
- var/datum/gas_mixture/environment = location.return_air()
-
- var/datum/tlv/cur_tlv
- var/GET_PP = R_IDEAL_GAS_EQUATION*environment.temperature/environment.volume
-
- cur_tlv = TLV["pressure"]
- var/environment_pressure = environment.return_pressure()
- var/pressure_dangerlevel = cur_tlv.get_danger_level(environment_pressure)
-
- cur_tlv = TLV["oxygen"]
- var/oxygen_dangerlevel = cur_tlv.get_danger_level(environment.oxygen*GET_PP)
-
- cur_tlv = TLV["carbon dioxide"]
- var/co2_dangerlevel = cur_tlv.get_danger_level(environment.carbon_dioxide*GET_PP)
-
- cur_tlv = TLV["plasma"]
- var/plasma_dangerlevel = cur_tlv.get_danger_level(environment.toxins*GET_PP)
-
- cur_tlv = TLV["other"]
- var/other_moles = 0.0
- for(var/datum/gas/G in environment.trace_gases)
- other_moles+=G.moles
- var/other_dangerlevel = cur_tlv.get_danger_level(other_moles*GET_PP)
-
- cur_tlv = TLV["temperature"]
- var/temperature_dangerlevel = cur_tlv.get_danger_level(environment.temperature)
-
- var/old_danger_level = danger_level
- danger_level = max(
- pressure_dangerlevel,
- oxygen_dangerlevel,
- co2_dangerlevel,
- plasma_dangerlevel,
- other_dangerlevel,
- temperature_dangerlevel
- )
- if (old_danger_level!=danger_level)
- apply_danger_level()
-
- if (mode==AALARM_MODE_REPLACEMENT && environment_pressure T0C+200)
- src.alarm() // added check of detector status here
+ alarm() // added check of detector status here
return
/obj/machinery/firealarm/attack_ai(mob/user as mob)
- return src.attack_hand(user)
+ return attack_hand(user)
/obj/machinery/firealarm/bullet_act(BLAH)
- return src.alarm()
+ return alarm()
/obj/machinery/firealarm/attack_paw(mob/user as mob)
- return src.attack_hand(user)
+ return attack_hand(user)
/obj/machinery/firealarm/emp_act(severity)
if(prob(50/severity)) alarm()
@@ -1033,38 +1017,36 @@ table tr:first-child th:first-child { border: none;}
/obj/machinery/firealarm/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/wirecutters))
- src.detecting = !( src.detecting )
- if (src.detecting)
- user.visible_message("\red [user] has reconnected [src]'s detecting unit!", "You have reconnected [src]'s detecting unit.")
- else
- user.visible_message("\red [user] has disconnected [src]'s detecting unit!", "You have disconnected [src]'s detecting unit.")
+ detecting = !detecting
+ user.visible_message("\red \The [user] has [detecting ? "re" : "dis" ]connected \the [src]'s detecting unit!",\
+ "You have [detecting ? "re" : "dis" ]connected \the [src]'s detecting unit.")
else
- src.alarm()
- src.add_fingerprint(user)
+ alarm()
+ add_fingerprint(user)
return
-/obj/machinery/firealarm/process()//Note: this processing was mostly phased out due to other code, and only runs when needed
+/obj/machinery/firealarm/process()
if(stat & (NOPOWER|BROKEN))
return
-// var/area/A = src.loc
-// A = A.loc
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
-// if(A.fire)
-// src.icon_state = "fire1"
-// else
-// src.icon_state = "fire0"
+ if(A.fire)
+ icon_state = "fire1"
+ else
+ icon_state = "fire0"
- if(src.timing)
- if(src.time > 0)
- src.time = src.time - ((world.timeofday - last_process)/10)
+ if (timing)
+ if (time > 0)
+ time = round(time) - 1
else
- src.alarm()
- src.time = 0
- src.timing = 0
- processing_objects.Remove(src)
- src.updateDialog()
- last_process = world.timeofday
+ alarm()
+ time = 0
+ timing = 0
+ updateDialog()
return
/obj/machinery/firealarm/power_change()
@@ -1080,38 +1062,39 @@ table tr:first-child th:first-child { border: none;}
if(user.stat || stat & (NOPOWER|BROKEN))
return
- user.set_machine(src)
- var/area/A = src.loc
+ user.machine = src
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
var/d1
var/d2
if (istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon))
- A = A.loc
if (A.fire)
d1 = text("Reset - Lockdown", src)
else
d1 = text("Alarm - Lockdown", src)
- if (src.timing)
+ if (timing)
d2 = text("Stop Time Lock", src)
else
d2 = text("Initiate Time Lock", src)
- var/second = round(src.time) % 60
- var/minute = (round(src.time) - second) / 60
+ var/second = time % 60
+ var/minute = (time - second) / 60
var/dat = "Fire alarm [d1]\n
The current alert level is: [get_security_level()]
\nTimer System: [d2]
\nTime Left: [(minute ? "[minute]:" : null)][second] - - + +\n"
user << browse(dat, "window=firealarm")
onclose(user, "firealarm")
else
- A = A.loc
if (A.fire)
d1 = text("[]", src, stars("Reset - Lockdown"))
else
d1 = text("[]", src, stars("Alarm - Lockdown"))
- if (src.timing)
+ if (timing)
d2 = text("[]", src, stars("Stop Time Lock"))
else
d2 = text("[]", src, stars("Initiate Time Lock"))
- var/second = round(src.time) % 60
- var/minute = (round(src.time) - second) / 60
+ var/second = time % 60
+ var/minute = (time - second) / 60
var/dat = "[stars("Fire alarm")] [d1]\n
The current alert level is: [stars(get_security_level())]
\nTimer System: [d2]
\nTime Left: [(minute ? text("[]:", minute) : null)][second] - - + +\n"
user << browse(dat, "window=firealarm")
onclose(user, "firealarm")
@@ -1121,114 +1104,114 @@ table tr:first-child th:first-child { border: none;}
..()
if (usr.stat || stat & (BROKEN|NOPOWER))
return
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
- usr.set_machine(src)
+ if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon)))
+ usr.machine = src
if (href_list["reset"])
- src.reset()
+ reset()
else
if (href_list["alarm"])
- src.alarm()
+ alarm()
else
if (href_list["time"])
- src.timing = text2num(href_list["time"])
- last_process = world.timeofday
- processing_objects.Add(src)
+ timing = text2num(href_list["time"])
else
if (href_list["tp"])
var/tp = text2num(href_list["tp"])
- src.time += tp
- src.time = min(max(round(src.time), 0), 120)
- src.updateUsrDialog()
+ time += tp
+ time = min(max(round(time), 0), 120)
+ updateUsrDialog()
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
else
usr << browse(null, "window=firealarm")
return
return
/obj/machinery/firealarm/proc/reset()
- if (!( src.working ))
- return
- var/area/A = src.loc
- A = A.loc
- if (!( istype(A, /area) ))
+ if (!working)
return
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
for(var/area/RA in A.related)
RA.firereset()
return
/obj/machinery/firealarm/proc/alarm()
- if (!( src.working ))
- return
- var/area/A = src.loc
- A = A.loc
- if (!( istype(A, /area) ))
+ if (!( working ))
return
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
for(var/area/RA in A.related)
RA.firealert()
- //playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
+ //playsound(loc, 'signal.ogg', 75, 0)
return
/obj/machinery/partyalarm/attack_paw(mob/user as mob)
- return src.attack_hand(user)
+ return attack_hand(user)
+
/obj/machinery/partyalarm/attack_hand(mob/user as mob)
if(user.stat || stat & (NOPOWER|BROKEN))
return
- user.set_machine(src)
- var/area/A = src.loc
+ user.machine = src
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
var/d1
var/d2
if (istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon/ai))
- A = A.loc
if (A.party)
d1 = text("No Party :(", src)
else
d1 = text("PARTY!!!", src)
- if (src.timing)
+ if (timing)
d2 = text("Stop Time Lock", src)
else
d2 = text("Initiate Time Lock", src)
- var/second = src.time % 60
- var/minute = (src.time - second) / 60
+ var/second = time % 60
+ var/minute = (time - second) / 60
var/dat = text("Party Button []\n
\nTimer System: []
\nTime Left: [][] - - + +\n", d1, d2, (minute ? text("[]:", minute) : null), second, src, src, src, src)
user << browse(dat, "window=partyalarm")
onclose(user, "partyalarm")
else
- A = A.loc
if (A.fire)
d1 = text("[]", src, stars("No Party :("))
else
d1 = text("[]", src, stars("PARTY!!!"))
- if (src.timing)
+ if (timing)
d2 = text("[]", src, stars("Stop Time Lock"))
else
d2 = text("[]", src, stars("Initiate Time Lock"))
- var/second = src.time % 60
- var/minute = (src.time - second) / 60
+ var/second = time % 60
+ var/minute = (time - second) / 60
var/dat = text("[] []\n
\nTimer System: []
\nTime Left: [][] - - + +\n", stars("Party Button"), d1, d2, (minute ? text("[]:", minute) : null), second, src, src, src, src)
user << browse(dat, "window=partyalarm")
onclose(user, "partyalarm")
return
/obj/machinery/partyalarm/proc/reset()
- if (!( src.working ))
- return
- var/area/A = src.loc
- A = A.loc
- if (!( istype(A, /area) ))
+ if (!( working ))
return
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
A.partyreset()
return
/obj/machinery/partyalarm/proc/alarm()
- if (!( src.working ))
- return
- var/area/A = src.loc
- A = A.loc
- if (!( istype(A, /area) ))
+ if (!( working ))
return
+ var/area/A = get_area(src)
+ ASSERT(isarea(A))
+ if(A.master)
+ A = A.master
A.partyalert()
return
@@ -1236,25 +1219,25 @@ table tr:first-child th:first-child { border: none;}
..()
if (usr.stat || stat & (BROKEN|NOPOWER))
return
- if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
- usr.set_machine(src)
+ if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(loc, /turf))) || (istype(usr, /mob/living/silicon/ai)))
+ usr.machine = src
if (href_list["reset"])
- src.reset()
+ reset()
else
if (href_list["alarm"])
- src.alarm()
+ alarm()
else
if (href_list["time"])
- src.timing = text2num(href_list["time"])
+ timing = text2num(href_list["time"])
else
if (href_list["tp"])
var/tp = text2num(href_list["tp"])
- src.time += tp
- src.time = min(max(round(src.time), 0), 120)
- src.updateUsrDialog()
+ time += tp
+ time = min(max(round(time), 0), 120)
+ updateUsrDialog()
- src.add_fingerprint(usr)
+ add_fingerprint(usr)
else
usr << browse(null, "window=partyalarm")
return
- return
+ return
\ No newline at end of file
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index 616a62c78b6..c3e0941b101 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -117,16 +117,16 @@
laws.add_inherent_law(M.newFreeFormLaw)
usr << "Added a freeform law."
- if(istype(P, /obj/item/device/mmi))
+ if(istype(P, /obj/item/device/mmi) || istype(P, /obj/item/device/posibrain))
if(!P:brainmob)
- user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose."
+ user << "\red Sticking an empty [P] into the frame would sort of defeat the purpose."
return
if(P:brainmob.stat == 2)
- user << "\red Sticking a dead brain into the frame would sort of defeat the purpose."
+ user << "\red Sticking a dead [P] into the frame would sort of defeat the purpose."
return
if(jobban_isbanned(P:brainmob, "AI"))
- user << "\red This MMI does not seem to fit."
+ user << "\red This [P] does not seem to fit."
return
if(P:brainmob.mind)
@@ -136,7 +136,7 @@
user.drop_item()
P.loc = src
brain = P
- usr << "Added a brain."
+ usr << "Added [P]."
icon_state = "3b"
if(istype(P, /obj/item/weapon/crowbar) && brain)
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 14e544dcb05..b755f16d0a0 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -1,52 +1,188 @@
/var/const/OPEN = 1
/var/const/CLOSED = 2
-
/obj/machinery/door/firedoor
- name = "Firelock"
- desc = "Apply crowbar"
- icon = 'icons/obj/doors/Doorfire.dmi'
+ name = "\improper Emergency Shutter"
+ desc = "Emergency air-tight shutter, capable of sealing off breached areas."
+ icon = 'DoorHazard.dmi'
icon_state = "door_open"
+ req_one_access = list(access_atmospherics, access_engine_equip)
opacity = 0
density = 0
- power_channel = ENVIRON
+
var/blocked = 0
var/nextstate = null
+ var/net_id
+ var/list/areas_added
+ var/list/users_to_open
+
+ New()
+ . = ..()
+ var/area/A = get_area(src)
+ ASSERT(istype(A))
+
+ A.all_doors.Add(src)
+ areas_added = list(A)
+
+ for(var/direction in cardinal)
+ A = get_area(get_step(src,direction))
+ if(istype(A) && !(A in areas_added))
+ A.all_doors.Add(src)
+ areas_added += A
+
+
+ Del()
+ for(var/area/A in areas_added)
+ A.all_doors.Remove(src)
+ . = ..()
+
+
+ examine()
+ set src in view()
+ . = ..()
+ if( islist(users_to_open) && users_to_open.len)
+ var/users_to_open_string = users_to_open[1]
+ if(users_to_open.len >= 2)
+ for(var/i = 2 to users_to_open.len)
+ users_to_open_string += ", [users_to_open[i]]"
+ usr << "These people have opened \the [src] during an alert: [users_to_open_string]."
Bumped(atom/AM)
- if(p_open || operating) return
- if(!density) return ..()
+ if(p_open || operating)
+ return
+ if(!density)
+ return ..()
return 0
power_change()
- if(powered(power_channel))
+ if(powered(ENVIRON))
stat &= ~NOPOWER
else
stat |= NOPOWER
return
+ attack_hand(mob/user as mob)
+ return attackby(null, user)
+
+
attackby(obj/item/weapon/C as obj, mob/user as mob)
add_fingerprint(user)
- if(operating) return//Already doing something.
+ if(operating)
+ return//Already doing something.
if(istype(C, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/W = C
if(W.remove_fuel(0, user))
blocked = !blocked
- user << text("\red You [blocked?"welded":"unwelded"] the [src]")
+ user.visible_message("\red \The [user] [blocked ? "welds" : "unwelds"] \the [src] with \a [W].",\
+ "You [blocked ? "weld" : "unweld"] \the [src] with \the [W].",\
+ "You hear something being welded.")
update_icon()
return
- if(istype(C, /obj/item/weapon/crowbar) || (istype(C,/obj/item/weapon/twohanded/fireaxe) && C:wielded == 1))
- if(blocked || operating) return
+ if(blocked)
+ user << "\red \The [src] is welded solid!"
+ return
+
+ var/area/A = get_area(src)
+ ASSERT(istype(A))
+ if(A.master)
+ A = A.master
+ var/alarmed = A.air_doors_activated || A.fire
+
+ if( istype(C, /obj/item/weapon/crowbar) || ( istype(C,/obj/item/weapon/twohanded/fireaxe) && C:wielded == 1 ) )
+ if(operating)
+ return
+ if( blocked && istype(C, /obj/item/weapon/crowbar) )
+ user.visible_message("\red \The [user] pries at \the [src] with \a [C], but \the [src] is welded in place!",\
+ "You try to pry \the [src] [density ? "open" : "closed"], but it is welded in place!",\
+ "You hear someone struggle and metal straining.")
+ return
+ if( istype(C, /obj/item/weapon/crowbar) )
+ if( stat & (BROKEN|NOPOWER) || !density || !alarmed )
+ user.visible_message("\red \The [user] forces \the [src] [density ? "open" : "closed"] with \a [C]!",\
+ "You force \the [src] [density ? "open" : "closed"] with \the [C]!",\
+ "You hear metal strain, and a door [density ? "open" : "close"].")
+ else if( allowed(user) )
+ user.visible_message("\blue \The [user] lifts \the [src] with \a [C].",\
+ "\The [src] scans your ID, and obediently opens as you apply your [C].",\
+ "You hear metal move, and a door [density ? "open" : "close"].")
+ else
+ user.visible_message("\blue \The [user] pries at \the [src] with \a [C], but \the [src] resists being opened.",\
+ "\red You pry at \the [src], but it actively resists your efforts. Maybe use your ID, perhaps?",\
+ "You hear someone struggling and metal straining")
+ return
+ else
+ user.visible_message("\red \The [user] forces \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \a [C]!",\
+ "You force \the [ blocked ? "welded" : "" ] [src] [density ? "open" : "closed"] with \the [C]!",\
+ "You hear metal strain and groan, and a door [density ? "open" : "close"].")
if(density)
+ spawn(0)
+ open()
+ else
+ spawn(0)
+ close()
+
+ var/access_granted = 0
+ var/users_name
+ if(!istype(C, /obj)) //If someone hit it with their hand. We need to see if they are allowed.
+ if(allowed(user))
+ access_granted = 1
+ if(ishuman(user))
+ users_name = FindNameFromID(user)
+ else
+ users_name = "Unknown"
+
+ if( !stat && ( istype(C, /obj/item/weapon/card/id) || istype(C, /obj/item/device/pda) ) )
+ var/obj/item/weapon/card/id/ID = C
+
+ if( istype(C, /obj/item/device/pda) )
+ var/obj/item/device/pda/pda = C
+ ID = pda.id
+ if(!istype(ID))
+ ID = null
+
+ if(ID)
+ users_name = ID.registered_name
+
+ if(check_access(ID))
+ access_granted = 1
+
+ var/answer = alert(user, "Would you like to [density ? "open" : "close"] this [src.name]?[ alarmed && density && !access_granted ? "\nNote that by doing so, you acknowledge any damages from opening this\n[src.name] as being your own fault, and you will be held accountable under the law." : ""]",\
+ "\The [src]", "Yes, [density ? "open" : "close"]", "No")
+ if(answer == "No")
+ return
+ if(user.stat || !user.canmove || user.stunned || user.weakened || user.paralysis || get_dist(src, user) > 1)
+ user << "Sorry, you must remain able bodied and close to \the [src] in order to use it."
+ return
+
+ if(alarmed && density && !access_granted && !( users_name in users_to_open ) )
+ user.visible_message("\red \The [src] opens for \the [user], but only after they acknowledged responsibility for the consequences.",\
+ "\The [src] opens after you acknowledge the consequences.",\
+ "You hear a beep, and a door opening.")
+ if(!users_to_open)
+ users_to_open = list()
+ users_to_open += users_name
+ else
+ user.visible_message("\blue \The [src] [density ? "open" : "close"]s for \the [user].",\
+ "\The [src] [density ? "open" : "close"]s.",\
+ "You hear a beep, and a door opening.")
+
+ var/needs_to_close = 0
+ if(density)
+ if(alarmed)
+ needs_to_close = 1
+ spawn()
open()
- return
- else //close it up again //fucking 10/10 commenting here einstein
+ else
+ spawn()
close()
- return
- return
+
+ if(needs_to_close)
+ spawn(50)
+ if(alarmed)
+ nextstate = CLOSED
process()
@@ -54,9 +190,11 @@
return
switch(nextstate)
if(OPEN)
- open()
+ spawn()
+ open()
if(CLOSED)
- close()
+ spawn()
+ close()
nextstate = null
return
@@ -83,6 +221,4 @@
return
-
-//border_only fire doors are special when it comes to air groups
/obj/machinery/door/firedoor/border_only
\ No newline at end of file
diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm
index b4992059f6f..dce2ab37bda 100644
--- a/code/game/machinery/doors/unpowered.dm
+++ b/code/game/machinery/doors/unpowered.dm
@@ -4,7 +4,8 @@
Bumped(atom/AM)
- if(src.locked) return
+ if(src.locked)
+ return
..()
return
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 84fd6c7ae9f..f3e14d0b291 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -668,7 +668,7 @@
/obj/mecha/attackby(obj/item/weapon/W as obj, mob/user as mob)
- if(istype(W, /obj/item/device/mmi))
+ if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
if(mmi_move_inside(W,user))
user << "[src]-MMI interface initialized successfuly"
else
@@ -1804,4 +1804,4 @@
//src.health = initial(src.health)/2.2
//src.check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
return
-*/
+*/
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index acd210f5ddc..189aad862a7 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -161,14 +161,14 @@
else
user << "\blue You need to attach a flash to it first!"
- if(istype(W, /obj/item/device/mmi))
+ if(istype(W, /obj/item/device/mmi) || istype(W, /obj/item/device/posibrain))
var/obj/item/device/mmi/M = W
if(check_completion())
if(!istype(loc,/turf))
- user << "\red You can't put the MMI in, the frame has to be standing on the ground to be perfectly precise."
+ user << "\red You can't put the [W] in, the frame has to be standing on the ground to be perfectly precise."
return
if(!M.brainmob)
- user << "\red Sticking an empty MMI into the frame would sort of defeat the purpose."
+ user << "\red Sticking an empty [W] into the frame would sort of defeat the purpose."
return
if(!M.brainmob.key)
var/ghost_can_reenter = 0
@@ -178,19 +178,19 @@
ghost_can_reenter = 1
break
if(!ghost_can_reenter)
- user << "The mmi indicates that their mind is completely unresponsive; there's no point."
+ user << "The [W] is completely unresponsive; there's no point."
return
if(M.brainmob.stat == DEAD)
- user << "\red Sticking a dead brain into the frame would sort of defeat the purpose."
+ user << "\red Sticking a dead [W] into the frame would sort of defeat the purpose."
return
if(M.brainmob.mind in ticker.mode.head_revolutionaries)
- user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the MMI."
+ user << "\red The frame's firmware lets out a shrill sound, and flashes 'Abnormal Memory Engram'. It refuses to accept the [W]."
return
if(jobban_isbanned(M.brainmob, "Cyborg"))
- user << "\red This MMI does not seem to fit."
+ user << "\red This [W] does not seem to fit."
return
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc))
diff --git a/code/game/objects/items/weapons/hydroponics.dm b/code/game/objects/items/weapons/hydroponics.dm
index 9ebb60804fa..619828f68ce 100644
--- a/code/game/objects/items/weapons/hydroponics.dm
+++ b/code/game/objects/items/weapons/hydroponics.dm
@@ -38,6 +38,118 @@
if(0)
usr << "The bag now picks up one plant at a time."
+/*
+ * SeedBag
+ */
+
+/obj/item/weapon/seedbag
+ icon = 'icons/obj/hydroponics.dmi'
+ icon_state = "seedbag"
+ name = "Seed Bag"
+ desc = "A small satchel made for organizing seeds."
+ var/mode = 1; //0 = pick one at a time, 1 = pick all on tile
+ var/capacity = 500; //the number of seeds it can carry.
+ flags = FPRINT | TABLEPASS
+ slot_flags = SLOT_BELT
+ w_class = 1
+ var/list/item_quants = list()
+
+/obj/item/weapon/seedbag/attack_self(mob/user as mob)
+ user.machine = src
+ interact(user)
+
+/obj/item/weapon/seedbag/verb/toggle_mode()
+ set name = "Switch Bagging Method"
+ set category = "Object"
+
+ mode = !mode
+ switch (mode)
+ if(1)
+ usr << "The bag now picks up all seeds in a tile at once."
+ if(0)
+ usr << "The bag now picks up one seed pouch at a time."
+
+/obj/item/seeds/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ ..()
+ if (istype(O, /obj/item/weapon/seedbag))
+ var/obj/item/weapon/seedbag/S = O
+ if (S.mode == 1)
+ for (var/obj/item/seeds/G in locate(src.x,src.y,src.z))
+ if (S.contents.len < S.capacity)
+ S.contents += G;
+ if(S.item_quants[G.name])
+ S.item_quants[G.name]++
+ else
+ S.item_quants[G.name] = 1
+ else
+ user << "\blue The seed bag is full."
+ S.updateUsrDialog()
+ return
+ user << "\blue You pick up all the seeds."
+ else
+ if (S.contents.len < S.capacity)
+ S.contents += src;
+ if(S.item_quants[name])
+ S.item_quants[name]++
+ else
+ S.item_quants[name] = 1
+ else
+ user << "\blue The seed bag is full."
+ S.updateUsrDialog()
+ return
+
+/obj/item/weapon/seedbag/interact(mob/user as mob)
+
+ var/dat = "Select an item:
"
+
+ if (contents.len == 0)
+ dat += "No seeds loaded!"
+ else
+ for (var/O in item_quants)
+ if(item_quants[O] > 0)
+ var/N = item_quants[O]
+ dat += "[capitalize(O)]:"
+ dat += " [N] "
+ dat += "Vend"
+ dat += "
"
+
+ dat += "
Unload All"
+ dat += ""
+ user << browse("Seedbag Supplies[dat]", "window=seedbag")
+ onclose(user, "seedbag")
+ return
+
+/obj/item/weapon/seedbag/Topic(href, href_list)
+ if(..())
+ return
+
+ usr.machine = src
+ if ( href_list["vend"] )
+ var/N = href_list["vend"]
+
+ if(item_quants[N] <= 0) // Sanity check, there are probably ways to press the button when it shouldn't be possible.
+ return
+
+ item_quants[N] -= 1
+ for(var/obj/O in contents)
+ if(O.name == N)
+ O.loc = get_turf(src)
+ usr.put_in_hands(O)
+ break
+
+ else if ( href_list["unload"] )
+ item_quants.Cut()
+ for(var/obj/O in contents )
+ O.loc = get_turf(src)
+
+ src.updateUsrDialog()
+ return
+
+/obj/item/weapon/seedbag/updateUsrDialog()
+ var/list/nearby = range(1, src)
+ for(var/mob/M in nearby)
+ if ((M.client && M.machine == src))
+ src.attack_self(M)
/*
* Sunflower
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm
index f96c0bdce34..b9c963ab0f8 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/hydroponics.dm
@@ -17,6 +17,7 @@
new /obj/item/clothing/suit/apron(src)
if(2)
new /obj/item/clothing/suit/apron/overalls(src)
+ new /obj/item/weapon/seedbag(src)
new /obj/item/weapon/plantbag(src)
new /obj/item/clothing/under/rank/hydroponics(src)
new /obj/item/device/analyzer/plant_analyzer(src)
diff --git a/code/modules/mob/living/carbon/brain/posibrain.dm b/code/modules/mob/living/carbon/brain/posibrain.dm
new file mode 100644
index 00000000000..bff5a6e192f
--- /dev/null
+++ b/code/modules/mob/living/carbon/brain/posibrain.dm
@@ -0,0 +1,118 @@
+/obj/item/device/posibrain
+ name = "positronic brain"
+ desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
+ icon = 'icons/obj/assemblies.dmi'
+ icon_state = "posibrain"
+ w_class = 3
+ origin_tech = "engineering=4;materials=4;bluespace=2;programming=6"
+
+ var/list/construction_cost = list("metal"=500,"glass"=500,"silver"=200,"gold"=200,"plasma"=100,"diamond"=10)
+ var/construction_time = 75
+ var/searching = 0
+ var/askDelay = 10 * 60 * 1
+
+ req_access = list(access_robotics)
+ var/locked = 0
+ var/mob/living/carbon/brain/brainmob = null//The current occupant.
+ var/obj/mecha = null//This does not appear to be used outside of reference in mecha.dm.
+
+ attack_self(mob/user as mob)
+ if(!brainmob && searching == 0)
+ //Start the process of searching for a new user.
+ user << "\blue You carefully locate the manual activation switch and start the positronic brain's boot process."
+ icon_state = "posibrain-searching"
+ src.searching = 1
+ src.request_player()
+ spawn(600) reset_search()
+
+ proc/request_player()
+ for(var/mob/dead/observer/O in player_list)
+ if(jobban_isbanned(O, "pAI"))
+ continue
+ if(O.client)
+ if(O.client.be_pai)
+ question(O.client)
+
+ proc/question(var/client/C)
+ spawn(0)
+ if(!C) return
+ var/response = alert(C, "Someone is requesting a personality for a positronic brain. Would you like to play as one?", "Positronic brain request", "Yes", "No", "Never for this round")
+ if(!C || brainmob) return //handle logouts that happen whilst the alert is waiting for a response, and responses issued after a brain has been located.
+ if(response == "Yes")
+ transfer_personality(C.mob)
+ else if (response == "Never for this round")
+ C.be_pai = 0
+
+
+ proc/transfer_personality(var/mob/candidate)
+
+ var/mob/living/carbon/brain/B = new(src)
+
+ src.searching = 0
+
+ src.brainmob = B
+ src.brainmob.mind = candidate.mind
+
+ src.brainmob.name = "PBU-[rand(100, 999)]"
+ src.brainmob.real_name = "PBU-[rand(100, 999)]"
+ src.brainmob.loc = src
+ src.brainmob.container = src
+ src.brainmob.stat = 0
+ src.brainmob.silent = 0
+ src.brainmob.brain_op_stage = 4.0
+ src.brainmob.key = candidate.key
+
+ dead_mob_list -= src.brainmob
+ living_mob_list += src.brainmob
+
+ var/turf/T = get_turf_or_move(src.loc)
+ for (var/mob/M in viewers(T))
+ M.show_message("\blue The positronic brain chimes quietly.")
+ icon_state = "posibrain-occupied"
+
+ proc/reset_search() //We give the players sixty seconds to decide, then reset the timer.
+
+ if(brainmob) return
+
+ src.searching = 0
+ icon_state = "posibrain"
+
+ var/turf/T = get_turf_or_move(src.loc)
+ for (var/mob/M in viewers(T))
+ M.show_message("\blue The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?")
+
+/obj/item/device/posibrain/examine()
+
+ set src in oview()
+
+ if(!usr || !src) return
+ if( (usr.sdisabilities & BLIND || usr.blinded || usr.stat) && !istype(usr,/mob/dead/observer) )
+ usr << "Something is there but you can't see it."
+ return
+
+ var/msg = "*---------*\nThis is \icon[src] \a [src]!\n[desc]\n"
+ msg += ""
+
+ if(src.brainmob)
+ switch(src.brainmob.stat)
+ if(CONSCIOUS)
+ if(!src.brainmob.client) msg += "It appears to be in stand-by mode.\n" //afk
+ if(UNCONSCIOUS) msg += "It doesn't seem to be responsive.\n"
+ if(DEAD) msg += "It appears to be completely inactive.\n"
+ else
+ msg += "*---------*"
+ usr << msg
+ return
+
+/obj/item/device/posibrain/emp_act(severity)
+ if(!brainmob)
+ return
+ else
+ switch(severity)
+ if(1)
+ brainmob.emp_damage += rand(20,30)
+ if(2)
+ brainmob.emp_damage += rand(10,20)
+ if(3)
+ brainmob.emp_damage += rand(0,10)
+ ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/brain/say.dm b/code/modules/mob/living/carbon/brain/say.dm
index 4b8174cc21b..c4d9a865da2 100644
--- a/code/modules/mob/living/carbon/brain/say.dm
+++ b/code/modules/mob/living/carbon/brain/say.dm
@@ -2,7 +2,7 @@
if (silent)
return
- if(!(container && istype(container, /obj/item/device/mmi)))
+ if(!(container && (istype(container, /obj/item/device/mmi) || istype(container, /obj/item/device/posibrain))))
return //No MMI, can't speak, bucko./N
else
if(prob(emp_damage*4))
diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi
index a0c27d7816b..a4a72b0a380 100644
Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ
diff --git a/icons/obj/hydroponics.dmi b/icons/obj/hydroponics.dmi
index e45d28d3c2c..03a8c72bc02 100644
Binary files a/icons/obj/hydroponics.dmi and b/icons/obj/hydroponics.dmi differ
diff --git a/maps/tgstation.2.0.9.1.dmm b/maps/tgstation.2.0.9.1.dmm
index e7e4ab656f0..1bce8a84949 100644
--- a/maps/tgstation.2.0.9.1.dmm
+++ b/maps/tgstation.2.0.9.1.dmm
@@ -5066,7 +5066,7 @@
"bTv" = (/obj/machinery/atmospherics/pipe/manifold{color = "red"; dir = 1; icon_state = "manifold-r"; level = 2},/obj/machinery/meter,/turf/simulated/wall,/area/atmos)
"bTw" = (/obj/machinery/atmospherics/pipe/simple{color = "red"; dir = 4; icon_state = "intact-r"; level = 2},/obj/machinery/light,/turf/simulated/floor,/area/atmos)
"bTx" = (/obj/machinery/atmospherics/pipe/simple/supply/hidden,/obj/machinery/atmospherics/pipe/simple{color = "red"; dir = 4; icon_state = "intact-r"; level = 2},/turf/simulated/wall/r_wall,/area/atmos)
-"bTy" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_x = -28; pixel_y = 0},/obj/machinery/requests_console{department = "Atmospherics"; departmentType = 4; name = "Atmos RC"; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple{color = "red"; dir = 4; icon_state = "intact-r"; level = 2},/turf/simulated/floor,/area/atmos)
+"bTy" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 31},/turf/simulated/floor{dir = 4; icon_state = "yellowcorner"},/area/engine/engineering)
"bTz" = (/obj/effect/landmark/start{name = "Atmospheric Technician"},/obj/structure/stool/bed/chair/office/dark,/obj/machinery/atmospherics/pipe/simple{color = "red"; dir = 4; icon_state = "intact-r"; level = 2},/turf/simulated/floor,/area/atmos)
"bTA" = (/obj/machinery/atmospherics/pipe/simple{color = "red"; dir = 4; icon_state = "intact-r"; level = 2},/obj/machinery/meter,/turf/simulated/floor,/area/atmos)
"bTB" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_atmos{name = "Monitoring Room"; req_access_txt = "24"},/obj/machinery/atmospherics/pipe/simple{color = "red"; dir = 4; icon_state = "intact-r"; level = 2},/turf/simulated/floor,/area/atmos)
@@ -5074,7 +5074,7 @@
"bTD" = (/obj/machinery/atmospherics/pipe/manifold{tag = "icon-manifold-r (EAST)"; icon_state = "manifold-r"; dir = 4; level = 2; color = "red"},/turf/simulated/floor,/area/atmos)
"bTE" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/atmos)
"bTF" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/floor,/area/atmos)
-"bTG" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/machinery/light,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/turf/simulated/floor,/area/atmos)
+"bTG" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_x = -28; pixel_y = 0},/obj/machinery/requests_console{department = "Atmospherics"; departmentType = 4; name = "Atmos RC"; pixel_x = -30; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple{color = "red"; dir = 4; icon_state = "intact-r"; level = 2},/obj/machinery/computer/atmoscontrol,/turf/simulated/floor,/area/atmos)
"bTH" = (/obj/machinery/atmospherics/pipe/manifold{dir = 8; icon_state = "manifold"; level = 2},/turf/simulated/floor,/area/atmos)
"bTI" = (/obj/machinery/atmospherics/pipe/manifold{icon_state = "manifold"; level = 2},/obj/machinery/meter,/turf/simulated/floor,/area/atmos)
"bTJ" = (/obj/machinery/atmospherics/pipe/manifold{dir = 4; icon_state = "manifold"; initialize_directions = 11; level = 2},/turf/simulated/floor,/area/atmos)
@@ -5884,7 +5884,7 @@
"cjh" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "Singularity"; layer = 2.8; name = "Singularity Shutters"; opacity = 0},/turf/simulated/floor/plating,/area/engine/engineering)
"cji" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/weapon/storage/belt/utility,/obj/item/weapon/wrench,/obj/item/weapon/weldingtool,/obj/item/clothing/head/welding{pixel_x = -3; pixel_y = 5},/turf/simulated/floor,/area/engine/engineering)
"cjj" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/gloves/yellow,/obj/item/weapon/storage/belt/utility,/turf/simulated/floor,/area/engine/engineering)
-"cjk" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/weapon/tank/emergency_oxygen/engi,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 31},/turf/simulated/floor{dir = 4; icon_state = "yellowcorner"},/area/engine/engineering)
+"cjk" = (/obj/structure/rack{dir = 8; layer = 2.9},/obj/machinery/light,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/obj/item/clothing/suit/storage/hazardvest,/turf/simulated/floor,/area/atmos)
"cjl" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/turf/simulated/floor/plating/airless,/area/solar/starboard)
"cjm" = (/obj/structure/cable{d1 = 2; d2 = 4; icon_state = "2-4"; tag = ""},/obj/structure/cable{d1 = 1; d2 = 4; icon_state = "1-4"; tag = ""},/obj/structure/cable{d1 = 4; d2 = 8; icon_state = "4-8"; pixel_x = 0; tag = ""},/turf/simulated/floor/plating/airless,/area/solar/starboard)
"cjn" = (/obj/structure/cable{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/plating/airless,/area/solar/starboard)
@@ -8989,7 +8989,7 @@
"dqS" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/plating,/area/maintenance/disposal)
"dqT" = (/obj/machinery/conveyor{dir = 1; id = "garbage"},/obj/effect/sign/vacuum{pixel_x = -32},/obj/machinery/light/small{dir = 8},/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"; tag = "icon-warnplate (NORTH)"},/area/maintenance/disposal)
"dqU" = (/turf/space,/obj/structure/shuttle/engine/propulsion{tag = "icon-propulsion_l (WEST)"; icon_state = "propulsion_l"; dir = 8},/turf/simulated/shuttle/wall{dir = 3; icon_state = "swall_f10"; layer = 2; tag = "icon-swall_f10"},/area/shuttle/transport1/centcom)
-
+
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -9152,7 +9152,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaafaafaafaaaaaaaaabPCbLjbPDbJLbJLbJLbOAbOAbOAbOAbOAbPEbOAbOAbOAbPFbPGbvZbMAbvZbPHbPIbNGbKsbPJbPKbHsbHsbHsbHsbPLbPMbPNbLGbPObPPbPQbPRbPSbPTbPUbPTbPVaafbLPbLPbLPbLPbLPaafaafaafbjIbPWbpGbIQbPXbPYbdpbPZbmxbQabQbbQcbQdbQebQfbQgbQhbQibQjbQibQkbLYbQlbQmbQnbQobQlbLYbQpbQqbNkbQrbQsbQtbQubQtbQvbQtbQwbQxbQxbQybQzbQAbccbccaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafaafbAsbAtbJxbJvbJvbBNbBNbBNbBNbBNbBNbBNbBNbAtbAtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaafaaaaaaaaabQCbLjbPDbJLaafaaabOAbQDbQEbQFbQGbQHbQIbQJbOAbOAbQKbQLbJYbvZbPHbQMbQNbMDbQObQPbQQbQRbQSbHsbQTbPMbLGbQUbLNbQVbQWbQXbQYbQZbRabRbbRcbMSbMTbRdbRebRebLPaafaaaaaablkbKvbdnbRfbEXbdnbdnbdnbRgbRhbRibRjbRkbRlbRmbRnbRobRpbRqbRrbRsbLYbLYbLYbLYbLYbLYbLYbRtbRubNkbRvbRwbRxbRybRzbRAbRBbRCbRDbREbRFbKObRGbQBbccbccbccaaaaaaaafaaaaaaaafagQagQagQaaaaaaaaaaafaaaaaaaafaaaaaaaafaaaaaabEfbAtbCSbAtbAtbBNbBNbBNbBNbBNbBNbBNbAtbAtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaabJLbJLbJLbJLbJLbLjbRSbRTbRUbRVbRWbRXbRYbRZbSabSbbQJbQJbScbSdbSebvZbMAbvZbSfbSgbLNbLNbShbSibSjbLNbSkbSlbSmbSnbLNbSobSpbSqbSrbSsbLGbStbSubSvbNRaafbNSbSwbSxbSybLPaafaaaaaablkbKvbdnbSzbSAbSBbSCbSDbdpbRhbSEbNbbSFbSGbQfbSHbSIbSJbSKbSLbRsbSMbSNbSObSPbSQbSRbSSbSTbSUbNkbSVbSWbSXbSYbSZbTabTbbTcbSYbTdbSVbKObTebRHbRIbRJbRKbRLbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRMbRNbRObRPbRPbRQbAtbAtbBNbBNbRRbBNbBNbAtbAtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaaabPCbTkbTlbTmbTnbTobTpbTnbTqbTrbTsbTtbQJbQJbQJbQJbQJbQJbScbSdbSebvZbMAbvZbTubTvbOKbTwbOKbTxbTybTzbTAbTBbTCbTDbTEbTFbTGbTHbTIbTJbLGbStbTKbTLbTMbOTbMTbTNbRebRebLPaafaafaafblkbKvbdnbTObTPbTQbTRbTSbdpbRhbTTbNbbNbbNbbNcbNbbNbbTUbNbbNbbRsbTVbTWbTVbTXbTYbTZbUabUabUbbNkbNkbKObUcbUdbUdbUdbUebUdbUfbKObKObKObUgbTfbccbTgbccaaaaaabThaaaaaaaafagQagQagQaaaaaaaaaaafaaaaaaaafaaaaaaaafaafaafbTibTjbBLbCTbAsbAtbAtbBNbBObBNbAtbAtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaaabPCbTkbTlbTmbTnbTobTpbTnbTqbTrbTsbTtbQJbQJbQJbQJbQJbQJbScbSdbSebvZbMAbvZbTubTvbOKbTwbOKbTxbTGbTzbTAbTBbTCbTDbTEbTFcjkbTHbTIbTJbLGbStbTKbTLbTMbOTbMTbTNbRebRebLPaafaafaafblkbKvbdnbTObTPbTQbTRbTSbdpbRhbTTbNbbNbbNbbNcbNbbNbbTUbNbbNbbRsbTVbTWbTVbTXbTYbTZbUabUabUbbNkbNkbKObUcbUdbUdbUdbUebUdbUfbKObKObKObUgbTfbccbTgbccaaaaaabThaaaaaaaafagQagQagQaaaaaaaaaaafaaaaaaaafaaaaaaaafaafaafbTibTjbBLbCTbAsbAtbAtbBNbBObBNbAtbAtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaafaaabQCbUlbUmbUnbIpbIpbJLbLgbUobLibOAbUpbQJbQFbQFbQFbQJbUqbOAbOAbQKbUrbMAbvZbTubUsbUtbHsbUubQPbUvbUwbUxbHsbUybUzbHsbHsbHsbUAbLGbUBbLGbStbSubUCbNRaafbLPbLPbLPbLPbLPaafaaaaaabNVbKvbdnbdnbdnbdnbdnbdnbUDbUEbdpbsDbUFbUGbUHbUIbUJbUKbULbUMbRsbUNbTVbUObTXbUPbUQbURbURbUSbUTbUUbKObUVbUWbUdbUXbUYbUWbUdbKObUZbVabVbbUhbUibUjaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafbUkbAqbAqbArbAsbAsbAtbAtbAtbAtbAtaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaabJLbJLbJLbJLbIpbUnbIpbIpbJLaaabVdaaabOAbVebQJbRZbSabSbbQJbQJbQJbQJbVfbvZbMAbVgbzvbHsbHsbHsbVhbVibVjbVkbVlbKcbNJbPMbVmbVnbVobTHbVpbTHbVqbVrbVsbVtbRcbMSbMTbVubVvbVwbLPaafaaaaaabccbVxbVybVybVybVybVzbdnbVAbRhbdpbdpbVBbQibVCbQibQibVDbQibVEbRsbVFbVGbVHbVIbVJbVGbVKbVLbVMbVNbVNbKObUdbVObUdbUdbUdbVObUdbKObTebccbVPbVQbccaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaaaaaaaaaaaaaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaaaaaaaaaaaabJLbVRbVSbVTbVUbVVbVWbVXbVWaaabVdaaabOAbVYbQJbQJbQJbVZbQJbWabWbbQJbWcbWdbLxbWdbWebWfbWgbWfbWhbWibWjbMFbLGbKcbNJbPMbWkbLGbWlbWmbVpbTHbVqbStbSubWnbNRaafbNSbWobWpbWqbLPaafaafaafbccbccbWrbWsbVQbccbWtbpGbPYbWubWvbWwbUFbWxbWxbWybWxbQibWzbWAbRsbWBbVGbVGbWCbVGbVGbWDbWEbWFbWGbWHbKObKObKObKObKObKObKObKObKObTebccaafaafaafaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaDxaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -9172,7 +9172,7 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajlaafbYVcglbYXaaabYVcglbYXaaabYVcglbYXaafaaaaaaaaaaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaabJLbIpchFbLjcdCcgZcgZchacdCchGchGchHchIchJchKchLchMchNchOchPchQchRchScdMchTchUchVcdQcdQcdQbLPchtchWchtbLPchvchXchvbLPchzchYchzbLPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachZaaaaaabZxciacibciccidciecifcigciecigcifbZxaaaaaaaaaaaaaZvaZvaZvcihaafaafaafaafchEaafaafaafaafaafajXaZvaZvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajlaafbYVcglbYXaaabYVcglbYXaafbYVcglbYXaafaafaafaaaaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaacdCciicdCcijcdCcgZchachacdCcikcilcimcincheciocipciqcircfQciociscitcfQciocirciucivciwcixcdCbLPbLPbLPbLPbLPbLPbLPbLPbLPbLPbLPbLPbLPaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabZxbZxciycizbZxbZxbZxbZxbZxbZxbZxbZxaaaaaaaaaaaaaZvaaaaafaaaaafaaaaaaaaaciAaaaaafaafaaaaaaaaaaaaaZvaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajXaafbYVciBbYXaaabYVciBbYXaaabYVciBbYXaafajlaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaacdCciCcdCciDcdCcdCcdCcdCciEciFciGciHciHciHciGciIciGciJciKciLciMciNciOciGciGciPciGciQciRcdCaaaaaaaaaaaaaafaafaaaaaaaafaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafbZxbZxbZxbZxaaaaafaafaafaafaafaaaaaaaaaaaaaaaaZvaaaciSciSciSciSciSaafciTaafciSciSciSciSciSaaaaZvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajlaaaaafaaaaaaaaaaafaafaafaaaaaaaafaafaaaajlaafaafaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafcdCchfchfcfQciUciVciWciXciGciYchfciZcjachfcjbcjccjdcjecjfcjecjgcjhcjbcjicjjchfchfciucjkcdCcdCchGchGchGcdCaaaaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaafaaaaaaaaaaaaaaaaZvaafcjlcjmcjmcjmcjmcjnciTcjocjpcjpcjpcjpcjqaafaZvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajlaaaaafaaaaaaaaaaafaafaafaaaaaaaafaafaaaajlaafaafaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafaafaafaafcdCchfchfcfQciUciVciWciXciGciYchfciZcjachfcjbcjccjdcjecjfcjecjgcjhcjbcjicjjchfchfciubTycdCcdCchGchGchGcdCaaaaafaafaafaafaafaafaafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaaaaaaaaaaaaaaaaaaafaaaaafaaaaaaaaaaaaaaaaZvaafcjlcjmcjmcjmcjmcjnciTcjocjpcjpcjpcjpcjqaafaZvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaajmajmajlajmajmajXajlajlajlajlajmajlajlajmcjraafaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaacdCcjschfcjtcjucjvcjwcjxcjyciuchfcjzchfchfcjAcjBcjCcjDcjEcjDcjFcjBcjGcjHcjIchfchfciuchfcjJchGcjKcjLcjMcjMcjNaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaafaaaaaaaaaaaaaaaaZvaafcjOcjOcjOcjOcjOaaaciTaaacjOcjOcjOcjOcjOaafaZvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaafaafcdCcdCcjPcjQchechfcjRcjScjTciucjachfcjUcjVcjVcjWcjXcjYcjZcfHckacjWciJciJckbchfchfckcchfckdckecfFckfckgckhckiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZvaaaaafaaaaafaafaafaaaciTaaaaafaaaaafaaaaafaaaaZvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaafaaaaaackjckkcklchfckmcknckockpckqckrckscktckucdCckvckwckxcjackycdCckzckAckAckrckBckCckockDchGckEckFcjMcjMckGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZvaaaciSciSciSciSciSaafciTaafciSciSciSciSciSaafaZvaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa