mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-21 19:17:50 +01:00
Alarm system overhaul
This commit is contained in:
@@ -575,4 +575,7 @@ datum/proc/dd_SortValue()
|
||||
return "[sanitize(name)]"
|
||||
|
||||
/obj/machinery/camera/dd_SortValue()
|
||||
return "[c_tag]"
|
||||
return "[c_tag]"
|
||||
|
||||
/datum/alarm/dd_SortValue()
|
||||
return "[sanitize(last_name)]"
|
||||
|
||||
@@ -3,8 +3,10 @@ var/global/obj/effect/overlay/slmaster = null
|
||||
|
||||
// nanomanager, the manager for Nano UIs
|
||||
var/datum/nanomanager/nanomanager = new()
|
||||
// event manager, the manager for events
|
||||
var/datum/event_manager/event_manager = new()
|
||||
// Event Manager, the manager for events.
|
||||
var/datum/event_manager/event_manager = new()
|
||||
// Alarm Manager, the manager for alarms.
|
||||
var/datum/subsystem/alarm/alarm_manager = new()
|
||||
// Announcer intercom, because too much stuff creates an intercom for one message then hard del()s it.
|
||||
var/global/obj/item/device/radio/intercom/global_announcer = create_global_announcer()
|
||||
// Load order issues means this can't be new'd until other code runs
|
||||
|
||||
@@ -479,7 +479,7 @@
|
||||
if("Crew Monitoring")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.nano_crew_monitor()
|
||||
AI.subsystem_crew_monitor()
|
||||
|
||||
if("Show Crew Manifest")
|
||||
if(isAI(usr))
|
||||
@@ -489,7 +489,7 @@
|
||||
if("Show Alerts")
|
||||
if(isAI(usr))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
AI.ai_alerts()
|
||||
AI.subsystem_alarm_monitor()
|
||||
|
||||
if("Announcement")
|
||||
if(isAI(usr))
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/datum/controller/process/alarm/setup()
|
||||
name = "alarm"
|
||||
schedule_interval = 20 // every 2 seconds
|
||||
|
||||
/datum/controller/process/alarm/doWork()
|
||||
alarm_manager.fire()
|
||||
@@ -1,11 +1,19 @@
|
||||
/var/global/machinery_sort_required = 0
|
||||
|
||||
/datum/controller/process/machinery/setup()
|
||||
name = "machinery"
|
||||
schedule_interval = 20 // every 2 seconds
|
||||
|
||||
/datum/controller/process/machinery/doWork()
|
||||
process_sort()
|
||||
process_power()
|
||||
process_machines()
|
||||
|
||||
/datum/controller/process/machinery/proc/process_sort()
|
||||
if(machinery_sort_required)
|
||||
machinery_sort_required = 0
|
||||
machines = dd_sortedObjectList(machines)
|
||||
|
||||
/datum/controller/process/machinery/proc/process_machines()
|
||||
for(var/obj/machinery/M in machines)
|
||||
if(M && isnull(M.gcDestroyed))
|
||||
|
||||
@@ -25,7 +25,7 @@ var/global/datum/controller/failsafe/failsafe
|
||||
|
||||
failsafe = src
|
||||
|
||||
failsafe.process()
|
||||
//failsafe.process()
|
||||
|
||||
/datum/controller/failsafe/proc/process()
|
||||
processing = 1
|
||||
@@ -36,22 +36,4 @@ var/global/datum/controller/failsafe/failsafe
|
||||
while(1) // More efficient than recursivly calling ourself over and over. background = 1 ensures we do not trigger an infinite loop.
|
||||
iteration++
|
||||
|
||||
if(processing)
|
||||
if(master_controller.processing) // Only poke if these overrides aren't in effect
|
||||
if(masterControllerIteration == master_controller.iteration) // Master controller hasn't finished processing in the defined interval.
|
||||
switch(masterControllerAlertLevel)
|
||||
if(0 to 3)
|
||||
masterControllerAlertLevel++
|
||||
if(4)
|
||||
admins << "<font color='red' size='2'><b>Warning. The master Controller has not fired in the last [masterControllerAlertLevel * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</b></font>"
|
||||
masterControllerAlertLevel = 5
|
||||
if(5)
|
||||
admins << "<font color='red' size='2'><b>Warning. The master Controller has still not fired within the last [masterControllerAlertLevel * processing_interval] ticks. Killing and restarting...</b></font>"
|
||||
new /datum/controller/game_controller() // Replace the old master controller (hence killing the old one's process).
|
||||
master_controller.process() // Start it rolling again.
|
||||
masterControllerAlertLevel = 0
|
||||
else
|
||||
masterControllerAlertLevel = 0
|
||||
masterControllerIteration = master_controller.iteration
|
||||
|
||||
sleep(processing_interval)
|
||||
|
||||
@@ -18,27 +18,6 @@ var/global/pipe_processing_killed = 0
|
||||
/datum/controller/proc/recover() // If we are replacing an existing controller (due to a crash) we attempt to preserve as much as we can.
|
||||
|
||||
datum/controller/game_controller
|
||||
var/breather_ticks = 2 //a somewhat crude attempt to iron over the 'bumps' caused by high-cpu use by letting the MC have a breather for this many ticks after every loop
|
||||
var/minimum_ticks = 20 //The minimum length of time between MC ticks
|
||||
|
||||
var/air_cost = 0
|
||||
var/sun_cost = 0
|
||||
var/mobs_cost = 0
|
||||
var/diseases_cost = 0
|
||||
var/machines_cost = 0
|
||||
var/aibots_cost = 0
|
||||
var/objects_cost = 0
|
||||
var/networks_cost = 0
|
||||
var/powernets_cost = 0
|
||||
var/nano_cost = 0
|
||||
var/events_cost = 0
|
||||
var/puddles_cost
|
||||
var/ticker_cost = 0
|
||||
var/garbageCollectorCost = 0
|
||||
var/total_cost = 0
|
||||
|
||||
var/last_thing_processed
|
||||
|
||||
var/list/shuttle_list // For debugging and VV
|
||||
|
||||
var/global/datum/garbage_collector/garbageCollector
|
||||
@@ -47,7 +26,6 @@ datum/controller/game_controller/New()
|
||||
//There can be only one master_controller. Out with the old and in with the new.
|
||||
if(master_controller != src)
|
||||
if(istype(master_controller))
|
||||
Recover()
|
||||
del(master_controller)
|
||||
master_controller = src
|
||||
|
||||
@@ -59,8 +37,6 @@ datum/controller/game_controller/New()
|
||||
|
||||
if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
|
||||
if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
|
||||
//if(!emergency_shuttle) emergency_shuttle = new /datum/emergency_shuttle_controller() MOVED TO SCHEDULER
|
||||
//if(!shuttle_controller) shuttle_controller = new /datum/shuttle_controller()
|
||||
|
||||
datum/controller/game_controller/proc/setup()
|
||||
world.tick_lag = config.Ticklag
|
||||
@@ -68,16 +44,6 @@ datum/controller/game_controller/proc/setup()
|
||||
spawn(20)
|
||||
createRandomZlevel()
|
||||
|
||||
/* MOVED TO SCHEDULER
|
||||
if(!air_master)
|
||||
air_master = new /datum/controller/air_system()
|
||||
air_master.Setup()
|
||||
|
||||
if(!ticker)
|
||||
ticker = new /datum/controller/gameticker()
|
||||
*/
|
||||
|
||||
|
||||
setup_objects()
|
||||
setup_starlight()
|
||||
setupgenetics()
|
||||
@@ -89,14 +55,6 @@ datum/controller/game_controller/proc/setup()
|
||||
make_mining_asteroid_secret()
|
||||
|
||||
populate_spawn_points()
|
||||
/* MOVED TO SCHEDULER
|
||||
|
||||
spawn(0)
|
||||
if(ticker)
|
||||
ticker.pregame()
|
||||
|
||||
lighting_controller.Initialize()
|
||||
*/
|
||||
|
||||
datum/controller/game_controller/proc/setup_objects()
|
||||
world << "\red \b Initializing objects"
|
||||
@@ -119,9 +77,6 @@ datum/controller/game_controller/proc/setup_objects()
|
||||
var/obj/machinery/atmospherics/unary/vent_scrubber/T = U
|
||||
T.broadcast_status()
|
||||
|
||||
//Set up roundstart seed list.
|
||||
//populate_seed_list()
|
||||
|
||||
world << "\red \b Initializations complete."
|
||||
sleep(-1)
|
||||
|
||||
@@ -130,236 +85,3 @@ datum/controller/game_controller/proc/setup_starlight()
|
||||
for(var/turf/space/S in world)
|
||||
S.update_starlight()
|
||||
world << "\red \b Starlight Initilization Complete"
|
||||
|
||||
datum/controller/game_controller/proc/process()
|
||||
processing = 1
|
||||
spawn(0)
|
||||
//set background = 1
|
||||
while(1) //far more efficient than recursively calling ourself
|
||||
if(!failsafe) new /datum/controller/failsafe()
|
||||
|
||||
|
||||
if(processing)
|
||||
var/timer
|
||||
var/start_time = world.timeofday
|
||||
controller_iteration++
|
||||
|
||||
vote.process()
|
||||
// transfer_controller.process()
|
||||
shuttle_controller.process()
|
||||
process_newscaster()
|
||||
|
||||
//AIR
|
||||
|
||||
if(!air_processing_killed)
|
||||
timer = world.timeofday
|
||||
last_thing_processed = air_master.type
|
||||
|
||||
air_master.current_cycle++
|
||||
// if(!air_master.tick()) Runtimed.
|
||||
if(!air_master.process())
|
||||
air_master.failed_ticks++
|
||||
if(air_master.failed_ticks > 5)
|
||||
world << "<font color='red'><b>RUNTIMES IN ATMOS TICKER. Killing air simulation!</font></b>"
|
||||
world.log << "### LINDA SHUTDOWN"
|
||||
message_admins("LINDAALERT: unable to run [air_master.tick_progress], shutting down!")
|
||||
log_admin("LINDAALERT: unable run zone/process() -- [air_master.tick_progress]")
|
||||
air_processing_killed = 1
|
||||
air_master.failed_ticks = 0
|
||||
air_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//SUN
|
||||
timer = world.timeofday
|
||||
last_thing_processed = sun.type
|
||||
sun.calc_position()
|
||||
sun_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//MOBS
|
||||
timer = world.timeofday
|
||||
processMobs()
|
||||
mobs_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//MACHINES
|
||||
timer = world.timeofday
|
||||
processMachines()
|
||||
machines_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//BOTS
|
||||
timer = world.timeofday
|
||||
process_bots()
|
||||
aibots_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//OBJECTS
|
||||
timer = world.timeofday
|
||||
processObjects()
|
||||
objects_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//PIPENETS
|
||||
if(!pipe_processing_killed)
|
||||
timer = world.timeofday
|
||||
processPipenets()
|
||||
networks_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//POWERNETS
|
||||
timer = world.timeofday
|
||||
processPowernets()
|
||||
powernets_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//NANO UIS
|
||||
timer = world.timeofday
|
||||
processNano()
|
||||
nano_cost = (world.timeofday - timer) / 10
|
||||
|
||||
sleep(breather_ticks)
|
||||
|
||||
//EVENTS
|
||||
timer = world.timeofday
|
||||
processEvents()
|
||||
events_cost = (world.timeofday - timer) / 10
|
||||
|
||||
/*
|
||||
//PUDDLES
|
||||
timer = world.timeofday
|
||||
processPuddles()
|
||||
puddles_cost = (world.timeofday - timer) / 10
|
||||
*/
|
||||
|
||||
//TICKER
|
||||
timer = world.timeofday
|
||||
last_thing_processed = ticker.type
|
||||
ticker.process()
|
||||
ticker_cost = (world.timeofday - timer) / 10
|
||||
|
||||
// GC
|
||||
timer = world.timeofday
|
||||
last_thing_processed = garbageCollector.type
|
||||
garbageCollector.process()
|
||||
garbageCollectorCost = (world.timeofday - timer) / 10
|
||||
|
||||
//TIMING
|
||||
total_cost = air_cost + sun_cost + mobs_cost + diseases_cost + machines_cost + aibots_cost + objects_cost + networks_cost + powernets_cost + nano_cost + events_cost + puddles_cost + ticker_cost + garbageCollectorCost
|
||||
|
||||
var/end_time = world.timeofday
|
||||
if(end_time < start_time) //why not just use world.time instead?
|
||||
start_time -= 864000 //deciseconds in a day
|
||||
sleep( round(minimum_ticks - (end_time - start_time),1) )
|
||||
else
|
||||
sleep(10)
|
||||
|
||||
/datum/controller/game_controller/proc/processMobs()
|
||||
for (var/mob/Mob in mob_list)
|
||||
if (Mob)
|
||||
last_thing_processed = Mob.type
|
||||
Mob.Life()
|
||||
continue
|
||||
|
||||
mob_list = mob_list - Mob
|
||||
|
||||
|
||||
|
||||
/datum/controller/game_controller/proc/processMachines()
|
||||
for (var/obj/machinery/Machinery in machines)
|
||||
if (Machinery && Machinery.loc)
|
||||
last_thing_processed = Machinery.type
|
||||
|
||||
if(Machinery.process() != PROCESS_KILL)
|
||||
if (Machinery) // Why another check?
|
||||
if (Machinery.use_power)
|
||||
Machinery.auto_use_power()
|
||||
|
||||
continue
|
||||
|
||||
if(Machinery) Machinery.removeAtProcessing()
|
||||
|
||||
/datum/controller/game_controller/proc/process_bots()
|
||||
for(var/obj/machinery/bot/Bot in aibots)
|
||||
if(Bot && isnull(Bot.gcDestroyed))
|
||||
last_thing_processed = Bot.type
|
||||
spawn(0)
|
||||
Bot.bot_process()
|
||||
continue
|
||||
else
|
||||
aibots -= Bot
|
||||
|
||||
/datum/controller/game_controller/proc/processObjects()
|
||||
for (var/obj/Object in processing_objects)
|
||||
if (Object && Object.loc)
|
||||
last_thing_processed = Object.type
|
||||
Object.process()
|
||||
continue
|
||||
|
||||
processing_objects -= Object
|
||||
|
||||
/datum/controller/game_controller/proc/processPipenets()
|
||||
last_thing_processed = /datum/pipe_network
|
||||
|
||||
for (var/datum/pipe_network/Pipe_Network in pipe_networks)
|
||||
if(Pipe_Network)
|
||||
Pipe_Network.process()
|
||||
continue
|
||||
|
||||
pipe_networks -= Pipe_Network
|
||||
|
||||
/datum/controller/game_controller/proc/processPowernets()
|
||||
last_thing_processed = /datum/powernet
|
||||
|
||||
for (var/datum/powernet/Powernet in powernets)
|
||||
if (Powernet)
|
||||
Powernet.reset()
|
||||
continue
|
||||
|
||||
powernets -= Powernet
|
||||
|
||||
/datum/controller/game_controller/proc/processNano()
|
||||
last_thing_processed = /datum/nanoui
|
||||
for (var/datum/nanoui/Nanoui in nanomanager.processing_uis)
|
||||
if (Nanoui)
|
||||
Nanoui.process()
|
||||
continue
|
||||
|
||||
nanomanager.processing_uis -= Nanoui
|
||||
|
||||
/datum/controller/game_controller/proc/processEvents()
|
||||
last_thing_processed = /datum/event
|
||||
event_manager.process()
|
||||
|
||||
|
||||
/*
|
||||
/datum/controller/game_controller/proc/processPuddles()
|
||||
last_thing_processed = /datum/puddle
|
||||
|
||||
for (var/datum/puddle/Puddle in puddles)
|
||||
if (Puddle)
|
||||
Puddle.process()
|
||||
continue
|
||||
*/
|
||||
|
||||
datum/controller/game_controller/proc/Recover() //Mostly a placeholder for now.
|
||||
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
|
||||
for(var/varname in master_controller.vars)
|
||||
switch(varname)
|
||||
if("tag","bestF","type","parent_type","vars") continue
|
||||
else
|
||||
var/varval = master_controller.vars[varname]
|
||||
if(istype(varval,/datum))
|
||||
var/datum/D = varval
|
||||
msg += "\t [varname] = [D.type]\n"
|
||||
else
|
||||
msg += "\t [varname] = [varval]\n"
|
||||
world.log << msg
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// We manually initialize the alarm handlers instead of looping over all existing types
|
||||
// to make it possible to write: camera.triggerAlarm() rather than alarm_manager.managers[datum/alarm_handler/camera].triggerAlarm() or a variant thereof.
|
||||
/var/global/datum/alarm_handler/atmosphere/atmosphere_alarm = new()
|
||||
/var/global/datum/alarm_handler/camera/camera_alarm = new()
|
||||
/var/global/datum/alarm_handler/fire/fire_alarm = new()
|
||||
/var/global/datum/alarm_handler/motion/motion_alarm = new()
|
||||
/var/global/datum/alarm_handler/power/power_alarm = new()
|
||||
|
||||
/datum/subsystem/alarm
|
||||
name = "Alarm"
|
||||
var/list/datum/alarm/all_handlers
|
||||
|
||||
/datum/subsystem/alarm/New()
|
||||
all_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm)
|
||||
|
||||
/datum/subsystem/alarm/fire()
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
AH.process()
|
||||
|
||||
/datum/subsystem/alarm/proc/active_alarms()
|
||||
var/list/all_alarms = new
|
||||
for(var/datum/alarm_handler/AH in all_handlers)
|
||||
var/list/alarms = AH.alarms
|
||||
all_alarms += alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/subsystem/alarm/proc/number_of_active_alarms()
|
||||
var/list/alarms = active_alarms()
|
||||
return alarms.len
|
||||
@@ -0,0 +1,46 @@
|
||||
#define NEW_SS_GLOBAL(varname) if(varname != src){if(istype(varname)){Recover();qdel(varname);}varname = src;}
|
||||
|
||||
/datum/subsystem
|
||||
//things you will want to define
|
||||
var/name //name of the subsystem
|
||||
var/priority = 0 //priority affects order of initialization. Higher priorities are initialized first, lower priorities later. Can be decimal and negative values.
|
||||
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
|
||||
|
||||
//things you will probably want to leave alone
|
||||
var/can_fire = 0 //prevent fire() calls
|
||||
var/last_fire = 0 //last world.time we called fire()
|
||||
var/next_fire = 0 //scheduled world.time for next fire()
|
||||
var/cpu = 0 //cpu-usage stats (somewhat vague)
|
||||
var/cost = 0 //average time to execute
|
||||
var/times_fired = 0 //number of times we have called fire()
|
||||
|
||||
//used to initialize the subsystem BEFORE the map has loaded
|
||||
/datum/subsystem/New()
|
||||
|
||||
//previously, this would have been named 'process()' but that name is used everywhere for different things!
|
||||
//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds.
|
||||
//fire(), and the procs it calls, SHOULD NOT HAVE ANY SLEEP OPERATIONS in them!
|
||||
//YE BE WARNED!
|
||||
/datum/subsystem/proc/fire()
|
||||
can_fire = 0
|
||||
|
||||
//used to initialize the subsystem AFTER the map has loaded
|
||||
/datum/subsystem/proc/Initialize(start_timeofday)
|
||||
var/time = (world.timeofday - start_timeofday) / 10
|
||||
var/msg = "Initialized [name] SubSystem within [time] seconds"
|
||||
world << "<span class='userdanger'>[msg]</span>"
|
||||
world.log << msg
|
||||
|
||||
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
|
||||
/datum/subsystem/proc/stat_entry()
|
||||
stat(name, "[round(cost,0.001)]ds\t(CPU:[round(cpu,1)]%)")
|
||||
|
||||
//could be used to postpone a costly subsystem for one cycle
|
||||
//for instance, during cpu intensive operations like explosions
|
||||
/datum/subsystem/proc/postpone()
|
||||
if(next_fire - world.time < wait)
|
||||
next_fire += wait
|
||||
|
||||
//usually called via datum/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
|
||||
//should attempt to salvage what it can from the old instance of subsystem
|
||||
/datum/subsystem/proc/Recover()
|
||||
@@ -11,10 +11,6 @@
|
||||
usr = null
|
||||
src = null
|
||||
switch(controller)
|
||||
if("Master")
|
||||
new /datum/controller/game_controller()
|
||||
master_controller.process()
|
||||
feedback_add_details("admin_verb","RMC")
|
||||
if("Failsafe")
|
||||
new /datum/controller/failsafe()
|
||||
feedback_add_details("admin_verb","RFailsafe")
|
||||
@@ -25,7 +21,7 @@
|
||||
return
|
||||
|
||||
|
||||
/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Lighting","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Scheduler"))
|
||||
/client/proc/debug_controller(controller in list("Master","failsafe","Ticker","Air","Lighting","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras","Garbage", "Transfer Controller","Event","Alarm","Scheduler"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
|
||||
@@ -77,6 +73,9 @@
|
||||
if("Event")
|
||||
debug_variables(event_manager)
|
||||
feedback_add_details("admin_verb","DEvent")
|
||||
if("Alarm")
|
||||
debug_variables(alarm_manager)
|
||||
feedback_add_details("admin_verb", "DAlarm")
|
||||
if("Garbage")
|
||||
debug_variables(garbageCollector)
|
||||
feedback_add_details("admin_verb","DGarbage")
|
||||
|
||||
@@ -47,8 +47,8 @@ var/const/AALARM_WIRE_AALARM = 16
|
||||
//world << "Syphon Wire Cut"
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
//if (A.alarm_area.atmosalert(2))
|
||||
// A.post_alert(2)
|
||||
if (A.alarm_area.atmosalert(2, A))
|
||||
A.post_alert(2)
|
||||
A.update_icon()
|
||||
|
||||
/datum/wires/alarm/UpdatePulsed(var/index)
|
||||
@@ -89,6 +89,6 @@ var/const/AALARM_WIRE_AALARM = 16
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
// world << "Aalarm wire pulsed"
|
||||
//if (A.alarm_area.atmosalert(0))
|
||||
// A.post_alert(0)
|
||||
if (A.alarm_area.atmosalert(0, A))
|
||||
A.post_alert(0)
|
||||
A.update_icon()
|
||||
|
||||
@@ -128,6 +128,24 @@ var/list/ghostteleportlocs = list()
|
||||
power_equip = 0
|
||||
power_environ = 0
|
||||
ambientsounds = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/traitor.ogg')
|
||||
|
||||
/area/space/atmosalert()
|
||||
return
|
||||
|
||||
/area/space/fire_alert()
|
||||
return
|
||||
|
||||
/area/space/fire_reset()
|
||||
return
|
||||
|
||||
/area/space/readyalert()
|
||||
return
|
||||
|
||||
/area/space/radiation_alert()
|
||||
return
|
||||
|
||||
/area/space/partyalert()
|
||||
return
|
||||
|
||||
//These are shuttle areas, they must contain two areas in a subgroup if you want to move a shuttle from one
|
||||
//place to another. Look at escape shuttle for example.
|
||||
|
||||
+84
-159
@@ -39,180 +39,88 @@
|
||||
// spawn(15)
|
||||
power_change() // all machines set to current power level, also updates lighting icon
|
||||
|
||||
/area/proc/poweralert(var/state, var/obj/source as obj)
|
||||
if (state != poweralm)
|
||||
poweralm = state
|
||||
if(istype(source)) //Only report power alarms on the z-level where the source is located.
|
||||
var/list/cameras = list()
|
||||
for (var/obj/machinery/camera/C in src)
|
||||
if(!report_alerts)
|
||||
break
|
||||
cameras += C
|
||||
if(state == 1)
|
||||
/area/proc/get_cameras()
|
||||
var/list/cameras = list()
|
||||
for (var/obj/machinery/camera/C in src)
|
||||
cameras += C
|
||||
return cameras
|
||||
|
||||
|
||||
C.network.Remove("Power Alarms")
|
||||
else
|
||||
C.network.Add("Power Alarms")
|
||||
for (var/mob/living/silicon/aiPlayer in player_list)
|
||||
if(!report_alerts)
|
||||
break
|
||||
if(aiPlayer.z == source.z)
|
||||
if (state == 1)
|
||||
aiPlayer.cancelAlarm("Power", src, source)
|
||||
else
|
||||
aiPlayer.triggerAlarm("Power", src, cameras, source)
|
||||
for(var/obj/machinery/computer/station_alert/a in machines)
|
||||
if(!report_alerts)
|
||||
break
|
||||
if(a.z == source.z)
|
||||
if(state == 1)
|
||||
a.cancelAlarm("Power", src, source)
|
||||
else
|
||||
a.triggerAlarm("Power", src, cameras, source)
|
||||
return
|
||||
/area/proc/atmosalert(danger_level, var/alarm_source)
|
||||
if (danger_level == 0)
|
||||
atmosphere_alarm.clearAlarm(src, alarm_source)
|
||||
else
|
||||
atmosphere_alarm.triggerAlarm(src, alarm_source, severity = danger_level)
|
||||
|
||||
/area/proc/updateDangerLevel()
|
||||
// if(type==/area) //No atmos alarms in space
|
||||
// return 0 //redudant
|
||||
//Check all the alarms before lowering atmosalm. Raising is perfectly fine.
|
||||
for (var/obj/machinery/alarm/AA in src)
|
||||
if (!(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted && AA.report_danger_level)
|
||||
danger_level = max(danger_level, AA.local_danger_level)
|
||||
|
||||
|
||||
var/danger_level = 0
|
||||
|
||||
// Determine what the highest DL reported by air alarms is
|
||||
for(var/obj/machinery/alarm/AA in src)
|
||||
if((AA.stat & (NOPOWER|BROKEN)) || AA.shorted || AA.buildstage != 2)
|
||||
continue
|
||||
var/reported_danger_level=AA.local_danger_level
|
||||
if(AA.alarmActivated)
|
||||
reported_danger_level=2
|
||||
if(reported_danger_level>danger_level)
|
||||
danger_level=reported_danger_level
|
||||
// testing("Danger level at [AA.name]: [AA.local_danger_level] (reported [reported_danger_level])")
|
||||
|
||||
// testing("Danger level decided upon in [name]: [danger_level] (from [atmosalm])")
|
||||
|
||||
// Danger level change?
|
||||
if(danger_level != atmosalm)
|
||||
// Going to danger level 2 from something else
|
||||
if (danger_level == 2)
|
||||
var/list/cameras = list()
|
||||
for(var/obj/machinery/camera/C in src)
|
||||
if(!report_alerts)
|
||||
break
|
||||
cameras += C
|
||||
C.network.Add("Atmosphere Alarms")
|
||||
for(var/mob/living/silicon/aiPlayer in player_list)
|
||||
if(!report_alerts)
|
||||
break
|
||||
aiPlayer.triggerAlarm("Atmosphere", src, cameras, src)
|
||||
for(var/obj/machinery/computer/station_alert/a in machines)
|
||||
if(!report_alerts)
|
||||
break
|
||||
a.triggerAlarm("Atmosphere", src, cameras, src)
|
||||
air_doors_activated=1
|
||||
CloseFirelocks()
|
||||
// Dropping from danger level 2.
|
||||
else if (atmosalm == 2)
|
||||
for(var/obj/machinery/camera/C in src)
|
||||
if(!report_alerts)
|
||||
break
|
||||
C.network.Remove("Atmosphere Alarms")
|
||||
for(var/mob/living/silicon/aiPlayer in player_list)
|
||||
if(!report_alerts)
|
||||
break
|
||||
aiPlayer.cancelAlarm("Atmosphere", src, src)
|
||||
for(var/obj/machinery/computer/station_alert/a in machines)
|
||||
if(!report_alerts)
|
||||
break
|
||||
a.cancelAlarm("Atmosphere", src, src)
|
||||
air_doors_activated=0
|
||||
OpenFirelocks()
|
||||
if (danger_level < 1 && atmosalm >= 1)
|
||||
//closing the doors on red and opening on green provides a bit of hysteresis that will hopefully prevent fire doors from opening and closing repeatedly due to noise
|
||||
air_doors_open()
|
||||
else if (danger_level >= 2 && atmosalm < 2)
|
||||
air_doors_close()
|
||||
|
||||
atmosalm = danger_level
|
||||
for (var/obj/machinery/alarm/AA in src)
|
||||
if ( !(AA.stat & (NOPOWER|BROKEN)) && !AA.shorted)
|
||||
AA.update_icon()
|
||||
AA.update_icon()
|
||||
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/area/proc/CloseFirelocks()
|
||||
for(var/obj/machinery/door/firedoor/D in all_doors)
|
||||
if(!D.blocked)
|
||||
if(D.operating)
|
||||
D.nextstate = CLOSED
|
||||
else if(!D.density)
|
||||
spawn()
|
||||
D.close()
|
||||
/area/proc/air_doors_close()
|
||||
if(!src.air_doors_activated)
|
||||
src.air_doors_activated = 1
|
||||
for(var/obj/machinery/door/firedoor/E in src.all_doors)
|
||||
if(!E.blocked)
|
||||
if(E.operating)
|
||||
E.nextstate = CLOSED
|
||||
else if(!E.density)
|
||||
spawn(0)
|
||||
E.close()
|
||||
|
||||
/area/proc/OpenFirelocks()
|
||||
for(var/obj/machinery/door/firedoor/D in all_doors)
|
||||
if(!D.blocked)
|
||||
if(D.operating)
|
||||
D.nextstate = OPEN
|
||||
else if(D.density)
|
||||
spawn()
|
||||
D.open()
|
||||
/area/proc/air_doors_open()
|
||||
if(src.air_doors_activated)
|
||||
src.air_doors_activated = 0
|
||||
for(var/obj/machinery/door/firedoor/E in src.all_doors)
|
||||
if(!E.blocked)
|
||||
if(E.operating)
|
||||
E.nextstate = OPEN
|
||||
else if(E.density)
|
||||
spawn(0)
|
||||
E.open()
|
||||
|
||||
/area/proc/firealert()
|
||||
if(name == "Space") //no fire alarms in space
|
||||
return
|
||||
if( !fire )
|
||||
fire = 1
|
||||
|
||||
/area/proc/fire_alert()
|
||||
if(!fire)
|
||||
fire = 1 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = 0
|
||||
CloseFirelocks()
|
||||
var/list/cameras = list()
|
||||
for (var/obj/machinery/camera/C in src)
|
||||
if(!report_alerts)
|
||||
continue
|
||||
cameras.Add(C)
|
||||
C.network.Add("Fire Alarms")
|
||||
for (var/mob/living/silicon/ai/aiPlayer in player_list)
|
||||
if(!report_alerts)
|
||||
continue
|
||||
aiPlayer.triggerAlarm("Fire", src, cameras, src)
|
||||
for (var/obj/machinery/computer/station_alert/a in machines)
|
||||
if(!report_alerts)
|
||||
continue
|
||||
a.triggerAlarm("Fire", src, cameras, src)
|
||||
for(var/obj/machinery/door/firedoor/D in all_doors)
|
||||
if(!D.blocked)
|
||||
if(D.operating)
|
||||
D.nextstate = CLOSED
|
||||
else if(!D.density)
|
||||
spawn()
|
||||
D.close()
|
||||
|
||||
/area/proc/firereset()
|
||||
/area/proc/fire_reset()
|
||||
if (fire)
|
||||
fire = 0
|
||||
fire = 0 //used for firedoor checks
|
||||
updateicon()
|
||||
mouse_opacity = 0
|
||||
updateicon()
|
||||
for (var/obj/machinery/camera/C in src)
|
||||
if(!report_alerts)
|
||||
continue
|
||||
C.network.Remove("Fire Alarms")
|
||||
for (var/mob/living/silicon/ai/aiPlayer in player_list)
|
||||
if(!report_alerts)
|
||||
continue
|
||||
aiPlayer.cancelAlarm("Fire", src, src)
|
||||
for (var/obj/machinery/computer/station_alert/a in machines)
|
||||
if(!report_alerts)
|
||||
continue
|
||||
a.cancelAlarm("Fire", src, src)
|
||||
OpenFirelocks()
|
||||
|
||||
/area/proc/radiation_alert()
|
||||
if(name == "Space")
|
||||
return
|
||||
if(!radalert)
|
||||
radalert = 1
|
||||
updateicon()
|
||||
return
|
||||
|
||||
/area/proc/reset_radiation_alert()
|
||||
if(name == "Space")
|
||||
return
|
||||
if(radalert)
|
||||
radalert = 0
|
||||
updateicon()
|
||||
return
|
||||
|
||||
for(var/obj/machinery/door/firedoor/D in all_doors)
|
||||
if(!D.blocked)
|
||||
if(D.operating)
|
||||
D.nextstate = OPEN
|
||||
else if(D.density)
|
||||
spawn(0)
|
||||
D.open()
|
||||
|
||||
/area/proc/readyalert()
|
||||
if(name == "Space")
|
||||
return
|
||||
if(!eject)
|
||||
eject = 1
|
||||
updateicon()
|
||||
@@ -224,9 +132,19 @@
|
||||
updateicon()
|
||||
return
|
||||
|
||||
/area/proc/radiation_alert()
|
||||
if(!radalert)
|
||||
radalert = 1
|
||||
updateicon()
|
||||
return
|
||||
|
||||
/area/proc/reset_radiation_alert()
|
||||
if(radalert)
|
||||
radalert = 0
|
||||
updateicon()
|
||||
return
|
||||
|
||||
/area/proc/partyalert()
|
||||
if(name == "Space") //no parties in space!!!
|
||||
return
|
||||
if (!( party ))
|
||||
party = 1
|
||||
updateicon()
|
||||
@@ -238,6 +156,13 @@
|
||||
party = 0
|
||||
mouse_opacity = 0
|
||||
updateicon()
|
||||
for(var/obj/machinery/door/firedoor/D in src)
|
||||
if(!D.blocked)
|
||||
if(D.operating)
|
||||
D.nextstate = OPEN
|
||||
else if(D.density)
|
||||
spawn(0)
|
||||
D.open()
|
||||
return
|
||||
|
||||
/area/proc/updateicon()
|
||||
|
||||
+101
-141
@@ -49,6 +49,7 @@
|
||||
active_power_usage = 8
|
||||
power_channel = ENVIRON
|
||||
req_one_access = list(access_atmospherics, access_engine_equip)
|
||||
var/alarm_id = null
|
||||
var/frequency = 1439
|
||||
//var/skipprocess = 0 //Experimenting
|
||||
var/alarm_frequency = 1437
|
||||
@@ -82,17 +83,20 @@
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
var/list/TLV = list()
|
||||
var/hidden = 0
|
||||
|
||||
var/report_danger_level = 1
|
||||
|
||||
/obj/machinery/alarm/server
|
||||
preset = AALARM_PRESET_SERVER
|
||||
req_access = list(access_rd, access_atmospherics, access_engine_equip)
|
||||
|
||||
|
||||
/obj/machinery/alarm/vox
|
||||
preset = AALARM_PRESET_VOX
|
||||
req_access = list()
|
||||
|
||||
/obj/machinery/alarm/monitor
|
||||
report_danger_level = 0
|
||||
|
||||
/obj/machinery/alarm/proc/apply_preset(var/no_cycle_after=0)
|
||||
// Propogate settings.
|
||||
for (var/obj/machinery/alarm/AA in alarm_area)
|
||||
@@ -232,7 +236,7 @@
|
||||
// we're going up a level
|
||||
// OR if we're going down a level and have sufficient confidence (prevents spamming update_icon).
|
||||
if (old_level < new_danger || (danger_averted_confidence >= 5 && new_danger < old_level))
|
||||
setDangerLevel(new_danger)
|
||||
apply_danger_level(new_danger)
|
||||
update_icon()
|
||||
danger_averted_confidence=0 // Reset counter.
|
||||
|
||||
@@ -252,8 +256,6 @@
|
||||
remote_control = 1
|
||||
if(RCON_YES)
|
||||
remote_control = 3
|
||||
if(screen == AALARM_SCREEN_MAIN)
|
||||
updateDialog()
|
||||
return
|
||||
|
||||
/obj/machinery/alarm/proc/calculate_local_danger_level()
|
||||
@@ -441,14 +443,12 @@
|
||||
for(var/device_id in alarm_area.air_vent_names)
|
||||
send_signal(device_id, list("power"= 0) )
|
||||
|
||||
// This sets our danger level, and, if it's changed, forces a new election of danger levels.
|
||||
/obj/machinery/alarm/proc/setDangerLevel(var/new_danger_level)
|
||||
if(local_danger_level==new_danger_level)
|
||||
return
|
||||
local_danger_level=new_danger_level
|
||||
if(alarm_area.updateDangerLevel())
|
||||
/obj/machinery/alarm/proc/apply_danger_level(var/new_danger_level)
|
||||
if (report_danger_level && alarm_area.atmosalert(new_danger_level, src))
|
||||
post_alert(new_danger_level)
|
||||
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/alarm/proc/post_alert(alert_level)
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(alarm_frequency)
|
||||
if(!frequency)
|
||||
@@ -459,7 +459,6 @@
|
||||
alert_signal.transmission_method = 1
|
||||
alert_signal.data["zone"] = alarm_area.name
|
||||
alert_signal.data["type"] = "Atmospheric"
|
||||
alert_signal.data["hidden"] = hidden
|
||||
|
||||
if(alert_level==2)
|
||||
alert_signal.data["alert"] = "severe"
|
||||
@@ -557,6 +556,16 @@
|
||||
if (.)
|
||||
return
|
||||
return interact(user)
|
||||
|
||||
/obj/machinery/alarm/interact(mob/user)
|
||||
if(buildstage != 2)
|
||||
return
|
||||
|
||||
if(wiresexposed && !istype(user, /mob/living/silicon/ai))
|
||||
wires.Interact(user)
|
||||
|
||||
if(!shorted)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/alarm/proc/ui_air_status()
|
||||
var/turf/location = get_turf(src)
|
||||
@@ -623,21 +632,18 @@
|
||||
data["danger"]=danger
|
||||
return data
|
||||
|
||||
/obj/machinery/alarm/proc/get_nano_data(mob/user, fromAtmosConsole=0, AtmosConsoleEmagged=0)
|
||||
|
||||
/obj/machinery/alarm/proc/get_nano_data(mob/user)
|
||||
var/data[0]
|
||||
data["name"] = name
|
||||
data["air"]=ui_air_status()
|
||||
data["alarmActivated"]=alarmActivated || local_danger_level==2
|
||||
data["sensors"]=TLV
|
||||
data["name"] = sanitize(name)
|
||||
data["air"] = ui_air_status()
|
||||
data["alarmActivated"] = alarmActivated || local_danger_level==2
|
||||
data["sensors"] = TLV
|
||||
|
||||
// Locked when:
|
||||
// Not sent from atmos console AND
|
||||
// Not silicon AND locked.
|
||||
data["locked"]=!fromAtmosConsole && (!(istype(user, /mob/living/silicon)) && locked)
|
||||
if(fromAtmosConsole && (remote_control < 2 && !AtmosConsoleEmagged))
|
||||
data["locked"] = 1
|
||||
data["rcon"]=rcon_setting
|
||||
data["locked"] = (!(istype(user, /mob/living/silicon)) && locked)
|
||||
data["rcon"] = rcon_setting
|
||||
data["target_temp"] = target_temperature - T0C
|
||||
data["atmos_alarm"] = alarm_area.atmosalm
|
||||
data["modes"] = list(
|
||||
@@ -681,107 +687,79 @@
|
||||
scrubbers+=list(scrubber_data)
|
||||
data["scrubbers"]=scrubbers
|
||||
return data
|
||||
|
||||
/obj/machinery/alarm/proc/get_nano_data_console(mob/user)
|
||||
var/data[0]
|
||||
data["name"] = sanitize(name)
|
||||
data["ref"] = "\ref[src]"
|
||||
data["danger"] = max(local_danger_level, alarm_area.atmosalm)
|
||||
data["area"] = sanitize(get_area(src))
|
||||
var/turf/pos = get_turf(src)
|
||||
data["x"] = pos.x
|
||||
data["y"] = pos.y
|
||||
data["z"] = pos.z
|
||||
return data
|
||||
|
||||
/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
var/list/data = get_nano_data(user)
|
||||
|
||||
var/remote_connection = 0
|
||||
var/remote_access = 0
|
||||
if(state)
|
||||
var/list/href = state.href_list(user)
|
||||
remote_connection = href["remote_connection"] // Remote connection means we're non-adjacent/connecting from another computer
|
||||
remote_access = href["remote_access"] // Remote access means we also have the privilege to alter the air alarm.
|
||||
|
||||
/obj/machinery/alarm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
|
||||
if(user.stat && !isobserver(user))
|
||||
return
|
||||
|
||||
var/list/data=src.get_nano_data(user,FALSE)
|
||||
|
||||
if (!ui) // no ui has been passed, so we'll search for one
|
||||
{
|
||||
ui = nanomanager.get_open_ui(user, src, ui_key)
|
||||
}
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new one
|
||||
ui = new(user, src, ui_key, "air_alarm.tmpl", name, 570, 410)
|
||||
// When the UI is first opened this is the data it will use
|
||||
data["remote_connection"] = remote_connection
|
||||
data["remote_access"] = remote_access
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "air_alarm.tmpl", name, 570, 410, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
// Auto update every Master Controller tick
|
||||
ui.set_auto_update(1)
|
||||
else
|
||||
// The UI is already open so push the new data to it
|
||||
ui.push_data(data)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/alarm/interact(mob/user)
|
||||
user.set_machine(src)
|
||||
|
||||
if(buildstage!=2)
|
||||
return
|
||||
|
||||
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/ai))
|
||||
wires.Interact(user)
|
||||
if(!shorted)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/alarm/proc/can_use(mob/user as mob)
|
||||
if (user.stat && !isobserver(user))
|
||||
user << "\red You must be conscious to use this [src]!"
|
||||
return 0
|
||||
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return 0
|
||||
|
||||
if(buildstage != 2)
|
||||
return 0
|
||||
|
||||
if((get_dist(src, user) > 1) && !istype(user, /mob/living/silicon))
|
||||
return 0
|
||||
|
||||
if(istype(user, /mob/living/silicon) && aidisabled)
|
||||
user << "AI control for this air alarm interface has been disabled."
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
/obj/machinery/alarm/proc/is_authenticated(mob/user as mob)
|
||||
if(isAI(user) || isrobot(user))
|
||||
return 1
|
||||
else
|
||||
return !locked
|
||||
|
||||
/obj/machinery/alarm/CanUseTopic(var/mob/user, var/datum/topic_state/state, var/href_list = list())
|
||||
if(buildstage != 2)
|
||||
return STATUS_CLOSE
|
||||
|
||||
/obj/machinery/alarm/Topic(href, href_list)
|
||||
if(..())
|
||||
if(aidisabled && isAI(user))
|
||||
user << "<span class='warning'>AI control for \the [src] interface has been disabled.</span>"
|
||||
return STATUS_CLOSE
|
||||
|
||||
. = shorted ? STATUS_DISABLED : STATUS_INTERACTIVE
|
||||
|
||||
if(. == STATUS_INTERACTIVE)
|
||||
var/extra_href = state.href_list(usr)
|
||||
// Prevent remote users from altering RCON settings unless they already have access
|
||||
if(href_list["rcon"] && extra_href["remote_connection"] && !extra_href["remote_access"])
|
||||
. = STATUS_UPDATE
|
||||
return min(..(), .)
|
||||
|
||||
/obj/machinery/alarm/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state)
|
||||
if(..(href, href_list, nowindow, state))
|
||||
return 1
|
||||
|
||||
if(!can_use(usr))
|
||||
return 1
|
||||
|
||||
var/changed=0
|
||||
|
||||
|
||||
if(href_list["rcon"])
|
||||
rcon_setting = text2num(href_list["rcon"])
|
||||
changed=1
|
||||
|
||||
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
|
||||
var/attempted_rcon_setting = text2num(href_list["rcon"])
|
||||
switch(attempted_rcon_setting)
|
||||
if(RCON_NO)
|
||||
rcon_setting = RCON_NO
|
||||
if(RCON_AUTO)
|
||||
rcon_setting = RCON_AUTO
|
||||
if(RCON_YES)
|
||||
rcon_setting = RCON_YES
|
||||
return 1
|
||||
|
||||
add_fingerprint(usr)
|
||||
usr.machine = src
|
||||
|
||||
//testing(href)
|
||||
if(href_list["command"])
|
||||
if(!is_authenticated(usr))
|
||||
return
|
||||
@@ -815,7 +793,6 @@
|
||||
val = newval
|
||||
|
||||
send_signal(device_id, list(href_list["command"] = val ) )
|
||||
changed=0 // We wait for the device to reply.
|
||||
waiting_on_device=device_id
|
||||
|
||||
if("set_threshold")
|
||||
@@ -867,7 +844,6 @@
|
||||
selected[3] = selected[4]
|
||||
|
||||
apply_mode()
|
||||
ui_interact(usr)
|
||||
return 1
|
||||
|
||||
if(href_list["screen"])
|
||||
@@ -875,27 +851,20 @@
|
||||
return
|
||||
|
||||
screen = text2num(href_list["screen"])
|
||||
ui_interact(usr)
|
||||
return 1
|
||||
|
||||
if(href_list["atmos_alarm"])
|
||||
if(!is_authenticated(usr))
|
||||
return
|
||||
|
||||
alarmActivated=1
|
||||
alarm_area.updateDangerLevel()
|
||||
if (alarm_area.atmosalert(2, src))
|
||||
apply_danger_level(2)
|
||||
alarmActivated = 1
|
||||
update_icon()
|
||||
ui_interact(usr)
|
||||
return 1
|
||||
|
||||
if(href_list["atmos_reset"])
|
||||
if(!is_authenticated(usr))
|
||||
return
|
||||
|
||||
alarmActivated=0
|
||||
alarm_area.updateDangerLevel()
|
||||
if (alarm_area.atmosalert(0, src))
|
||||
apply_danger_level(0)
|
||||
alarmActivated = 0
|
||||
update_icon()
|
||||
ui_interact(usr)
|
||||
return 1
|
||||
|
||||
if(href_list["mode"])
|
||||
@@ -904,7 +873,6 @@
|
||||
|
||||
mode = text2num(href_list["mode"])
|
||||
apply_mode()
|
||||
ui_interact(usr)
|
||||
return 1
|
||||
|
||||
if(href_list["preset"])
|
||||
@@ -913,7 +881,6 @@
|
||||
|
||||
preset = text2num(href_list["preset"])
|
||||
apply_preset()
|
||||
ui_interact(usr)
|
||||
return 1
|
||||
|
||||
if(href_list["temperature"])
|
||||
@@ -927,10 +894,7 @@
|
||||
usr << "Temperature must be between [min_temperature]C and [max_temperature]C"
|
||||
else
|
||||
target_temperature = input_temperature + T0C
|
||||
ui_interact(usr)
|
||||
return 1
|
||||
if(changed)
|
||||
updateUsrDialog()
|
||||
|
||||
|
||||
/obj/machinery/alarm/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
@@ -1122,7 +1086,8 @@ FIRE ALARM
|
||||
|
||||
|
||||
/obj/machinery/firealarm/emp_act(severity)
|
||||
if(prob(50/severity)) alarm()
|
||||
if(prob(50/severity))
|
||||
alarm(rand(30/severity, 60/severity))
|
||||
..()
|
||||
|
||||
/obj/machinery/firealarm/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
@@ -1298,24 +1263,19 @@ FIRE ALARM
|
||||
/obj/machinery/firealarm/proc/reset()
|
||||
if (!( src.working ))
|
||||
return
|
||||
var/area/A = src.loc
|
||||
A = A.loc
|
||||
if (!( istype(A, /area) ))
|
||||
return
|
||||
A.firereset()
|
||||
update_icon()
|
||||
var/area/A = get_area(src)
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
fire_alarm.clearAlarm(loc, FA)
|
||||
return
|
||||
|
||||
/obj/machinery/firealarm/proc/alarm()
|
||||
if (!( src.working ))
|
||||
/obj/machinery/firealarm/proc/alarm(var/duration = 0)
|
||||
if (!( src.working))
|
||||
return
|
||||
var/area/A = src.loc
|
||||
A = A.loc
|
||||
if (!( istype(A, /area) ))
|
||||
return
|
||||
A.firealert()
|
||||
var/area/A = get_area(src)
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
fire_alarm.triggerAlarm(loc, FA, duration)
|
||||
update_icon()
|
||||
//playsound(get_turf(src), 'sound/ambience/signal.ogg', 75, 0)
|
||||
//playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
|
||||
return
|
||||
|
||||
/obj/machinery/firealarm/New(loc, dir, building)
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
cameranet.removeCamera(src)
|
||||
stat |= EMPED
|
||||
set_light(0)
|
||||
triggerCameraAlarm()
|
||||
triggerCameraAlarm(10 * severity)
|
||||
emped = emped+1 //Increase the number of consecutive EMP's
|
||||
var/thisemp = emped //Take note of which EMP this proc is for
|
||||
spawn(900)
|
||||
@@ -256,16 +256,16 @@
|
||||
O.reset_view(null)
|
||||
O << "The screen bursts into static."
|
||||
|
||||
/obj/machinery/camera/proc/triggerCameraAlarm()
|
||||
/obj/machinery/camera/proc/triggerCameraAlarm(var/duration = 0)
|
||||
alarm_on = 1
|
||||
for(var/mob/living/silicon/S in mob_list)
|
||||
S.triggerAlarm("Camera", get_area(src), list(src), src)
|
||||
|
||||
camera_alarm.triggerAlarm(loc, src, duration)
|
||||
|
||||
/obj/machinery/camera/proc/cancelCameraAlarm()
|
||||
if(wires.IsIndexCut(CAMERA_WIRE_ALARM))
|
||||
return
|
||||
|
||||
alarm_on = 0
|
||||
for(var/mob/living/silicon/S in mob_list)
|
||||
S.cancelAlarm("Camera", get_area(src), src)
|
||||
camera_alarm.clearAlarm(loc, src)
|
||||
|
||||
/obj/machinery/camera/proc/can_use()
|
||||
if(!status)
|
||||
|
||||
@@ -45,8 +45,7 @@
|
||||
if (!status || (stat & NOPOWER))
|
||||
return 0
|
||||
if (detectTime == -1)
|
||||
for (var/mob/living/silicon/aiPlayer in player_list)
|
||||
aiPlayer.cancelAlarm("Motion", get_area(src), src)
|
||||
motion_alarm.clearAlarm(loc, src)
|
||||
detectTime = 0
|
||||
return 1
|
||||
|
||||
@@ -54,8 +53,7 @@
|
||||
if (!status || (stat & NOPOWER))
|
||||
return 0
|
||||
if (!detectTime) return 0
|
||||
for (var/mob/living/silicon/aiPlayer in player_list)
|
||||
aiPlayer.triggerAlarm("Motion", get_area(src), list(src), src)
|
||||
motion_alarm.triggerAlarm(loc, src)
|
||||
detectTime = -1
|
||||
return 1
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
var/global/list/priority_air_alarms = list()
|
||||
var/global/list/minor_air_alarms = list()
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert
|
||||
name = "Atmospheric Alert Computer"
|
||||
@@ -7,118 +10,79 @@
|
||||
circuit = "/obj/item/weapon/circuitboard/atmos_alert"
|
||||
icon_keyboard = "atmos_key"
|
||||
icon_screen = "alert:0"
|
||||
var/list/priority_alarms = list()
|
||||
var/list/minor_alarms = list()
|
||||
var/receive_frequency = 1437
|
||||
var/datum/radio_frequency/radio_connection
|
||||
light_color = "#e6ffff"
|
||||
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert/initialize()
|
||||
/obj/machinery/computer/atmos_alert/New()
|
||||
..()
|
||||
set_frequency(receive_frequency)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/receive_signal(datum/signal/signal)
|
||||
if(!signal || signal.encryption) return
|
||||
|
||||
var/zone = signal.data["zone"]
|
||||
var/severity = signal.data["alert"]
|
||||
var/hidden = signal.data["hidden"]
|
||||
|
||||
if(!zone || !severity) return
|
||||
if(hidden) return
|
||||
|
||||
minor_alarms -= zone
|
||||
priority_alarms -= zone
|
||||
if(severity=="severe")
|
||||
priority_alarms += zone
|
||||
else if (severity=="minor")
|
||||
minor_alarms += zone
|
||||
update_icon()
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert/proc/set_frequency(new_frequency)
|
||||
radio_controller.remove_object(src, receive_frequency)
|
||||
receive_frequency = new_frequency
|
||||
radio_connection = radio_controller.add_object(src, receive_frequency, RADIO_ATMOSIA)
|
||||
atmosphere_alarm.register(src, /obj/machinery/computer/station_alert/update_icon)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/Destroy()
|
||||
atmosphere_alarm.unregister(src)
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/attack_hand(mob/user)
|
||||
if(..(user))
|
||||
return
|
||||
user << browse(return_text(),"window=computer")
|
||||
user.set_machine(src)
|
||||
onclose(user, "computer")
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/process()
|
||||
if(..())
|
||||
src.updateDialog()
|
||||
/obj/machinery/computer/atmos_alert/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
var/major_alarms[0]
|
||||
var/minor_alarms[0]
|
||||
|
||||
for(var/datum/alarm/alarm in atmosphere_alarm.major_alarms())
|
||||
major_alarms[++major_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]")
|
||||
|
||||
for(var/datum/alarm/alarm in atmosphere_alarm.minor_alarms())
|
||||
minor_alarms[++minor_alarms.len] = list("name" = sanitize(alarm.alarm_name()), "ref" = "\ref[alarm]")
|
||||
|
||||
data["priority_alarms"] = major_alarms
|
||||
data["minor_alarms"] = minor_alarms
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_alert.tmpl", src.name, 500, 500)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/update_icon()
|
||||
..()
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
if(priority_alarms.len)
|
||||
var/list/alarms = atmosphere_alarm.major_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:2"
|
||||
|
||||
else if(minor_alarms.len)
|
||||
icon_screen = "alert:1"
|
||||
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
|
||||
alarms = atmosphere_alarm.minor_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:1"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert/proc/return_text()
|
||||
var/priority_text
|
||||
var/minor_text
|
||||
|
||||
if(priority_alarms.len)
|
||||
for(var/zone in priority_alarms)
|
||||
priority_text += "<FONT color='red'><B>[zone]</B></FONT> <A href='?src=\ref[src];priority_clear=[ckey(zone)]'>X</A><BR>"
|
||||
else
|
||||
priority_text = "No priority alerts detected.<BR>"
|
||||
|
||||
if(minor_alarms.len)
|
||||
for(var/zone in minor_alarms)
|
||||
minor_text += "<B>[zone]</B> <A href='?src=\ref[src];minor_clear=[ckey(zone)]'>X</A><BR>"
|
||||
else
|
||||
minor_text = "No minor alerts detected.<BR>"
|
||||
|
||||
var/output = {"<B>[name]</B><HR>
|
||||
<B>Priority Alerts:</B><BR>
|
||||
[priority_text]
|
||||
<BR>
|
||||
<HR>
|
||||
<B>Minor Alerts:</B><BR>
|
||||
[minor_text]
|
||||
<BR>"}
|
||||
|
||||
return output
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["priority_clear"])
|
||||
var/removing_zone = href_list["priority_clear"]
|
||||
for(var/zone in priority_alarms)
|
||||
if(ckey(zone) == removing_zone)
|
||||
priority_alarms -= zone
|
||||
if(href_list["clear_alarm"])
|
||||
var/datum/alarm/alarm = locate(href_list["clear_alarm"]) in atmosphere_alarm.alarms
|
||||
if(alarm)
|
||||
for(var/datum/alarm_source/alarm_source in alarm.sources)
|
||||
var/obj/machinery/alarm/air_alarm = alarm_source.source
|
||||
if(istype(air_alarm))
|
||||
var/list/new_ref = list("atmos_reset" = 1)
|
||||
air_alarm.Topic(href, new_ref, state = air_alarm_topic)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
if(href_list["minor_clear"])
|
||||
var/removing_zone = href_list["minor_clear"]
|
||||
for(var/zone in minor_alarms)
|
||||
if(ckey(zone) == removing_zone)
|
||||
minor_alarms -= zone
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/atmos_alert/Destroy()
|
||||
if(radio_controller)
|
||||
radio_controller.remove_object(src, receive_frequency)
|
||||
return ..()
|
||||
var/datum/topic_state/air_alarm_topic/air_alarm_topic = new()
|
||||
|
||||
/datum/topic_state/air_alarm_topic/href_list(var/mob/user)
|
||||
var/list/extra_href = list()
|
||||
extra_href["remote_connection"] = 1
|
||||
extra_href["remote_access"] = 1
|
||||
|
||||
return extra_href
|
||||
|
||||
/datum/topic_state/air_alarm_topic/can_use_topic(var/src_object, var/mob/user)
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
@@ -1,266 +1,39 @@
|
||||
/obj/item/weapon/circuitboard/atmoscontrol
|
||||
name = "\improper Central Atmospherics Computer Circuitboard"
|
||||
build_path = /obj/machinery/computer/atmoscontrol
|
||||
|
||||
/obj/machinery/computer/atmoscontrol
|
||||
name = "\improper Central Atmospherics Computer"
|
||||
icon = 'icons/obj/computer.dmi'
|
||||
icon_keyboard = "atmos_key"
|
||||
icon_screen = "tank"
|
||||
light_color = "#00b000"
|
||||
density = 1
|
||||
anchored = 1.0
|
||||
circuit = "/obj/item/weapon/circuitboard/atmoscontrol"
|
||||
var/obj/machinery/alarm/current
|
||||
var/list/filter=null
|
||||
var/overridden = 0 //not set yet, can't think of a good way to do it
|
||||
req_one_access = list(access_ce)
|
||||
circuit = /obj/item/weapon/circuitboard/atmoscontrol
|
||||
req_access = list(access_atmospherics)
|
||||
var/list/monitored_alarm_ids = null
|
||||
var/datum/nano_module/atmos_control/atmos_control
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/laptop
|
||||
name = "Atmospherics Laptop"
|
||||
desc = "Cheap Nanotrasen Laptop."
|
||||
icon_state = "medlaptop"
|
||||
density = 0
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/attack_ai(var/mob/user as mob)
|
||||
src.add_hiddenprint(user)
|
||||
return interact(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/attack_hand(mob/user)
|
||||
if(..())
|
||||
return
|
||||
return interact(user)
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/interact(mob/user)
|
||||
user.set_machine(src)
|
||||
if(allowed(user))
|
||||
overridden = 1
|
||||
else if(!emagged)
|
||||
overridden = 0
|
||||
|
||||
return ui_interact(user)
|
||||
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/emag_act(user as mob)
|
||||
if(!emagged)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
var/mob/living/carbon/human/H = user
|
||||
H.visible_message("\red \The [user] swipes \a card through \the [src], causing the screen to flash!",\
|
||||
"\red You swipe your card through \the [src], the screen flashing as you gain full control.",\
|
||||
"You hear the swipe of a card through a reader, and an electronic warble.")
|
||||
emagged = 1
|
||||
overridden = 1
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null)
|
||||
if(user.stat && !isobserver(user))
|
||||
return
|
||||
|
||||
var/list/data[0]
|
||||
data["alarm"]=null
|
||||
if(current)
|
||||
data += current.get_nano_data(user,1,emagged)
|
||||
data["alarm"] = "\ref[current]"
|
||||
|
||||
var/list/alarms=list()
|
||||
var/list/alarm_list=list()
|
||||
for(var/obj/machinery/alarm/alarm in machines)
|
||||
alarm_list+=alarm
|
||||
for(var/obj/machinery/alarm/alarm in sortAtom(alarm_list))
|
||||
if(!is_in_filter(alarm.alarm_area.type))
|
||||
continue
|
||||
if(!alarm.remote_control)
|
||||
continue
|
||||
if(alarm.hidden)
|
||||
continue
|
||||
if(alarm.z != z)
|
||||
continue
|
||||
var/turf/pos = get_turf(alarm)
|
||||
var/list/alarm_data=list()
|
||||
alarm_data["ID"]="\ref[alarm]"
|
||||
alarm_data["danger"] = max(alarm.local_danger_level, alarm.alarm_area.atmosalm-1)
|
||||
alarm_data["name"] = "[alarm]"
|
||||
alarm_data["area"] = get_area(alarm)
|
||||
alarm_data["x"] = pos.x
|
||||
alarm_data["y"] = pos.y
|
||||
alarm_data["z"] = pos.z
|
||||
alarms+=list(alarm_data)
|
||||
data["alarms"]=alarms
|
||||
|
||||
if (!ui) // no ui has been passed, so we'll search for one
|
||||
ui = nanomanager.get_open_ui(user, src, ui_key)
|
||||
|
||||
if (!ui)
|
||||
// the ui does not exist, so we'll create a new one
|
||||
ui = new(user, src, ui_key, "atmos_control.tmpl", name, 900, 800)
|
||||
// adding a template with the key "mapContent" enables the map ui functionality
|
||||
ui.add_template("mapContent", "atmos_control_map_content.tmpl")
|
||||
// adding a template with the key "mapHeader" replaces the map header content
|
||||
ui.add_template("mapHeader", "atmos_control_map_header.tmpl")
|
||||
// When the UI is first opened this is the data it will use
|
||||
// we want to show the map by default
|
||||
ui.set_show_map(1)
|
||||
|
||||
ui.set_initial_data(data)
|
||||
|
||||
ui.open()
|
||||
// Auto update every Master Controller tick
|
||||
if(current)
|
||||
ui.set_auto_update(1)
|
||||
else
|
||||
// The UI is already open so push the new data to it
|
||||
ui.push_data(data)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/proc/is_in_filter(var/typepath)
|
||||
if(!filter) return 1 // YEP. TOTALLY.
|
||||
return typepath in filter
|
||||
|
||||
//a bunch of this is copied from atmos alarms
|
||||
/obj/machinery/computer/atmoscontrol/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["reset"])
|
||||
current = null
|
||||
ui_interact(user)
|
||||
|
||||
if(href_list["alarm"])
|
||||
current = locate(href_list["alarm"])
|
||||
updateUsrDialog()
|
||||
return
|
||||
/obj/machinery/computer/atmoscontrol/emag_act(var/remaining_carges, var/mob/user)
|
||||
if(!emagged)
|
||||
user.visible_message("<span class='warning'>\The [user] does something \the [src], causing the screen to flash!</span>",\
|
||||
"<span class='warning'>You cause the screen to flash as you gain full control.</span>",\
|
||||
"You hear an electronic warble.")
|
||||
atmos_control.emagged = 1
|
||||
return 1
|
||||
|
||||
if(current)
|
||||
if(href_list["command"])
|
||||
var/device_id = href_list["id_tag"]
|
||||
switch(href_list["command"])
|
||||
if(
|
||||
"power",
|
||||
"adjust_external_pressure",
|
||||
"checks",
|
||||
"co2_scrub",
|
||||
"tox_scrub",
|
||||
"n2o_scrub",
|
||||
"o2_scrub",
|
||||
"panic_siphon",
|
||||
"scrubbing"
|
||||
)
|
||||
var/val
|
||||
if(href_list["val"])
|
||||
val=text2num(href_list["val"])
|
||||
else
|
||||
var/newval = input("Enter new value") as num|null
|
||||
if(isnull(newval))
|
||||
return
|
||||
val = newval
|
||||
current.send_signal(device_id, list (href_list["command"] = val))
|
||||
spawn(3)
|
||||
src.updateUsrDialog()
|
||||
//if("adjust_threshold") //was a good idea but required very wide window
|
||||
if("set_threshold")
|
||||
var/env = href_list["env"]
|
||||
var/threshold = text2num(href_list["var"])
|
||||
var/list/selected = current.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 num|null
|
||||
if (isnull(newval) || ..() || (current.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]
|
||||
|
||||
//Sets the temperature the built-in heater/cooler tries to maintain.
|
||||
if(env == "temperature")
|
||||
if(current.target_temperature < selected[2])
|
||||
current.target_temperature = selected[2]
|
||||
if(current.target_temperature > selected[3])
|
||||
current.target_temperature = selected[3]
|
||||
|
||||
spawn(1)
|
||||
updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["screen"])
|
||||
current.screen = text2num(href_list["screen"])
|
||||
spawn(1)
|
||||
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"])
|
||||
current.alarmActivated=1
|
||||
current.alarm_area.updateDangerLevel()
|
||||
spawn(1)
|
||||
src.updateUsrDialog()
|
||||
current.update_icon()
|
||||
return
|
||||
if(href_list["atmos_reset"])
|
||||
current.alarmActivated=0
|
||||
current.alarm_area.updateDangerLevel()
|
||||
spawn(1)
|
||||
src.updateUsrDialog()
|
||||
current.update_icon()
|
||||
return
|
||||
|
||||
if(href_list["mode"])
|
||||
current.mode = text2num(href_list["mode"])
|
||||
current.apply_mode()
|
||||
spawn(5)
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["preset"])
|
||||
current.preset = text2num(href_list["preset"])
|
||||
current.apply_preset()
|
||||
spawn(5)
|
||||
src.updateUsrDialog()
|
||||
return
|
||||
|
||||
if(href_list["temperature"])
|
||||
var/list/selected = current.TLV["temperature"]
|
||||
var/max_temperature = min(selected[3] - T0C, MAX_TEMPERATURE)
|
||||
var/min_temperature = max(selected[2] - T0C, MIN_TEMPERATURE)
|
||||
var/input_temperature = input("What temperature would you like the system to maintain? (Capped between [min_temperature]C and [max_temperature]C)", "Thermostat Controls") as num|null
|
||||
if(input_temperature==null)
|
||||
return
|
||||
if(input_temperature > max_temperature || input_temperature < min_temperature)
|
||||
usr << "Temperature must be between [min_temperature]C and [max_temperature]C"
|
||||
else
|
||||
current.target_temperature = input_temperature + T0C
|
||||
return
|
||||
updateUsrDialog()
|
||||
/obj/machinery/computer/atmoscontrol/ui_interact(var/mob/user)
|
||||
if(!atmos_control)
|
||||
atmos_control = new(src, req_access, req_one_access, monitored_alarm_ids)
|
||||
atmos_control.ui_interact(user)
|
||||
|
||||
@@ -32,11 +32,11 @@
|
||||
|
||||
/obj/item/weapon/circuitboard/message_monitor
|
||||
name = "Circuit board (Message Monitor)"
|
||||
build_path = "/obj/machinery/computer/message_monitor"
|
||||
build_path = /obj/machinery/computer/message_monitor
|
||||
origin_tech = "programming=3"
|
||||
/obj/item/weapon/circuitboard/camera
|
||||
name = "Circuit board (Camera Monitor)"
|
||||
build_path = "/obj/machinery/computer/security"
|
||||
build_path = /obj/machinery/computer/security
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/aicore
|
||||
name = "Circuit board (AI Core)"
|
||||
@@ -44,203 +44,209 @@
|
||||
board_type = "other"
|
||||
/obj/item/weapon/circuitboard/aiupload
|
||||
name = "Circuit board (AI Upload)"
|
||||
build_path = "/obj/machinery/computer/aiupload"
|
||||
build_path = /obj/machinery/computer/aiupload
|
||||
origin_tech = "programming=4"
|
||||
/obj/item/weapon/circuitboard/borgupload
|
||||
name = "Circuit board (Cyborg Upload)"
|
||||
build_path = "/obj/machinery/computer/borgupload"
|
||||
build_path = /obj/machinery/computer/borgupload
|
||||
origin_tech = "programming=4"
|
||||
/obj/item/weapon/circuitboard/med_data
|
||||
name = "Circuit board (Medical Records)"
|
||||
build_path = "/obj/machinery/computer/med_data"
|
||||
build_path = /obj/machinery/computer/med_data
|
||||
/obj/item/weapon/circuitboard/scan_consolenew
|
||||
name = "Circuit board (DNA Machine)"
|
||||
build_path = "/obj/machinery/computer/scan_consolenew"
|
||||
build_path = /obj/machinery/computer/scan_consolenew
|
||||
origin_tech = "programming=2;biotech=2"
|
||||
/obj/item/weapon/circuitboard/communications
|
||||
name = "Circuit board (Communications Console)"
|
||||
build_path = "/obj/machinery/computer/communications"
|
||||
build_path = /obj/machinery/computer/communications
|
||||
origin_tech = "programming=2;magnets=2"
|
||||
/obj/item/weapon/circuitboard/card
|
||||
name = "Circuit board (ID Computer)"
|
||||
build_path = "/obj/machinery/computer/card"
|
||||
build_path = /obj/machinery/computer/card
|
||||
/obj/item/weapon/circuitboard/card/centcom
|
||||
name = "Circuit board (CentCom ID Computer)"
|
||||
build_path = "/obj/machinery/computer/card/centcom"
|
||||
build_path = /obj/machinery/computer/card/centcom
|
||||
/obj/item/weapon/circuitboard/teleporter
|
||||
name = "Circuit board (Teleporter Console)"
|
||||
build_path = "/obj/machinery/computer/teleporter"
|
||||
build_path = /obj/machinery/computer/teleporter
|
||||
origin_tech = "programming=2;bluespace=2"
|
||||
/obj/item/weapon/circuitboard/secure_data
|
||||
name = "Circuit board (Security Records)"
|
||||
build_path = "/obj/machinery/computer/secure_data"
|
||||
build_path = /obj/machinery/computer/secure_data
|
||||
/obj/item/weapon/circuitboard/skills
|
||||
name = "Circuit board (Employment Records)"
|
||||
build_path = "/obj/machinery/computer/skills"
|
||||
/obj/item/weapon/circuitboard/stationalert
|
||||
name = "Circuit board (Station Alerts)"
|
||||
build_path = "/obj/machinery/computer/station_alert"
|
||||
/obj/item/weapon/circuitboard/atmospheresiphonswitch
|
||||
name = "Circuit board (Atmosphere Siphon control)"
|
||||
build_path = "/obj/machinery/computer/atmosphere/siphonswitch"
|
||||
build_path = /obj/machinery/computer/skills
|
||||
/obj/item/weapon/circuitboard/stationalert_engineering
|
||||
name = "Circuit Board (Station Alert Console (Engineering))"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
/obj/item/weapon/circuitboard/stationalert_security
|
||||
name = "Circuit Board (Station Alert Console (Security))"
|
||||
build_path = /obj/machinery/computer/station_alert
|
||||
/obj/item/weapon/circuitboard/stationalert_all
|
||||
name = "Circuit Board (Station Alert Console (All))"
|
||||
build_path = /obj/machinery/computer/station_alert/all
|
||||
/obj/item/weapon/circuitboard/atmos_alert
|
||||
name = "Circuit Board (Atmospheric Alert Computer)"
|
||||
build_path = /obj/machinery/computer/atmos_alert
|
||||
/obj/item/weapon/circuitboard/atmoscontrol
|
||||
name = "Circuit Board (Central Atmospherics Computer)"
|
||||
build_path = /obj/machinery/computer/atmoscontrol
|
||||
/obj/item/weapon/circuitboard/air_management
|
||||
name = "Circuit board (Atmospheric Monitor)"
|
||||
build_path = "/obj/machinery/computer/general_air_control"
|
||||
build_path = /obj/machinery/computer/general_air_control
|
||||
/obj/item/weapon/circuitboard/injector_control
|
||||
name = "Circuit board (Injector Control)"
|
||||
build_path = "/obj/machinery/computer/general_air_control/fuel_injection"
|
||||
/obj/item/weapon/circuitboard/atmos_alert
|
||||
name = "Circuit board (Atmospheric Alert)"
|
||||
build_path = "/obj/machinery/computer/atmos_alert"
|
||||
build_path = /obj/machinery/computer/general_air_control/fuel_injection
|
||||
/obj/item/weapon/circuitboard/pod
|
||||
name = "Circuit board (Massdriver Control)"
|
||||
build_path = "/obj/machinery/computer/pod"
|
||||
build_path = /obj/machinery/computer/pod
|
||||
/obj/item/weapon/circuitboard/pod/deathsquad
|
||||
name = "Circuit board (Deathsquad Massdriver control)"
|
||||
build_path = "/obj/machinery/computer/pod/deathsquad"
|
||||
build_path = /obj/machinery/computer/pod/deathsquad
|
||||
/obj/item/weapon/circuitboard/robotics
|
||||
name = "Circuit board (Robotics Control Console)"
|
||||
build_path = "/obj/machinery/computer/robotics"
|
||||
build_path = /obj/machinery/computer/robotics
|
||||
origin_tech = "programming=3"
|
||||
/obj/item/weapon/circuitboard/drone_control
|
||||
name = "Circuit board (Drone Control)"
|
||||
build_path = "/obj/machinery/computer/drone_control"
|
||||
build_path = /obj/machinery/computer/drone_control
|
||||
origin_tech = "programming=3"
|
||||
/obj/item/weapon/circuitboard/cloning
|
||||
name = "Circuit board (Cloning Machine Console)"
|
||||
build_path = "/obj/machinery/computer/cloning"
|
||||
build_path = /obj/machinery/computer/cloning
|
||||
origin_tech = "programming=3;biotech=3"
|
||||
/obj/item/weapon/circuitboard/arcade/battle
|
||||
name = "circuit board (Arcade Battle)"
|
||||
build_path = "/obj/machinery/computer/arcade/battle"
|
||||
build_path = /obj/machinery/computer/arcade/battle
|
||||
origin_tech = "programming=1"
|
||||
/obj/item/weapon/circuitboard/arcade/orion_trail
|
||||
name = "circuit board (Orion Trail)"
|
||||
build_path = "/obj/machinery/computer/arcade/orion_trail"
|
||||
build_path = /obj/machinery/computer/arcade/orion_trail
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/turbine_control
|
||||
name = "Circuit board (Turbine Control)"
|
||||
build_path = "/obj/machinery/computer/turbine_computer"
|
||||
build_path = /obj/machinery/computer/turbine_computer
|
||||
/obj/item/weapon/circuitboard/solar_control
|
||||
name = "Circuit board (Solar Control)"
|
||||
build_path = "/obj/machinery/power/solar_control"
|
||||
build_path = /obj/machinery/power/solar_control
|
||||
origin_tech = "programming=2;powerstorage=2"
|
||||
/obj/item/weapon/circuitboard/powermonitor
|
||||
name = "Circuit board (Power Monitor)"
|
||||
build_path = "/obj/machinery/computer/monitor"
|
||||
build_path = /obj/machinery/computer/monitor
|
||||
/obj/item/weapon/circuitboard/olddoor
|
||||
name = "Circuit board (DoorMex)"
|
||||
build_path = "/obj/machinery/computer/pod/old"
|
||||
build_path = /obj/machinery/computer/pod/old
|
||||
/obj/item/weapon/circuitboard/syndicatedoor
|
||||
name = "Circuit board (ProComp Executive)"
|
||||
build_path = "/obj/machinery/computer/pod/old/syndicate"
|
||||
build_path = /obj/machinery/computer/pod/old/syndicate
|
||||
/obj/item/weapon/circuitboard/swfdoor
|
||||
name = "Circuit board (Magix)"
|
||||
build_path = "/obj/machinery/computer/pod/old/swf"
|
||||
build_path = /obj/machinery/computer/pod/old/swf
|
||||
/obj/item/weapon/circuitboard/prisoner
|
||||
name = "Circuit board (Prisoner Management)"
|
||||
build_path = "/obj/machinery/computer/prisoner"
|
||||
build_path = /obj/machinery/computer/prisoner
|
||||
/obj/item/weapon/circuitboard/rdconsole
|
||||
name = "Circuit Board (RD Console)"
|
||||
build_path = "/obj/machinery/computer/rdconsole/core"
|
||||
build_path = /obj/machinery/computer/rdconsole/core
|
||||
/obj/item/weapon/circuitboard/mecha_control
|
||||
name = "Circuit Board (Exosuit Control Console)"
|
||||
build_path = "/obj/machinery/computer/mecha"
|
||||
build_path = /obj/machinery/computer/mecha
|
||||
/obj/item/weapon/circuitboard/pod_locater
|
||||
name = "Circuit Board (Pod Location Console)"
|
||||
build_path = "/obj/machinery/computer/podtracker"
|
||||
build_path = /obj/machinery/computer/podtracker
|
||||
/obj/item/weapon/circuitboard/rdservercontrol
|
||||
name = "Circuit Board (RD Server Control)"
|
||||
build_path = "/obj/machinery/computer/rdservercontrol"
|
||||
build_path = /obj/machinery/computer/rdservercontrol
|
||||
/obj/item/weapon/circuitboard/crew
|
||||
name = "Circuit board (Crew Monitoring Computer)"
|
||||
build_path = "/obj/machinery/computer/crew"
|
||||
build_path = /obj/machinery/computer/crew
|
||||
origin_tech = "programming=3;biotech=2;magnets=2"
|
||||
/obj/item/weapon/circuitboard/mech_bay_power_console
|
||||
name = "Circuit board (Mech Bay Power Control Console)"
|
||||
build_path = "/obj/machinery/computer/mech_bay_power_console"
|
||||
build_path = /obj/machinery/computer/mech_bay_power_console
|
||||
origin_tech = "programming=2;powerstorage=3"
|
||||
/obj/item/weapon/circuitboard/ordercomp
|
||||
name = "Circuit board (Supply Ordering Console)"
|
||||
build_path = "/obj/machinery/computer/ordercomp"
|
||||
build_path = /obj/machinery/computer/ordercomp
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/supplycomp
|
||||
name = "Circuit board (Supply Shuttle Console)"
|
||||
build_path = "/obj/machinery/computer/supplycomp"
|
||||
build_path = /obj/machinery/computer/supplycomp
|
||||
origin_tech = "programming=3"
|
||||
var/contraband_enabled = 0
|
||||
|
||||
/obj/item/weapon/circuitboard/operating
|
||||
name = "Circuit board (Operating Computer)"
|
||||
build_path = "/obj/machinery/computer/operating"
|
||||
build_path = /obj/machinery/computer/operating
|
||||
origin_tech = "programming=2;biotech=2"
|
||||
/obj/item/weapon/circuitboard/comm_monitor
|
||||
name = "Circuit board (Telecommunications Monitor)"
|
||||
build_path = "/obj/machinery/computer/telecomms/monitor"
|
||||
build_path = /obj/machinery/computer/telecomms/monitor
|
||||
origin_tech = "programming=3"
|
||||
/obj/item/weapon/circuitboard/comm_server
|
||||
name = "Circuit board (Telecommunications Server Monitor)"
|
||||
build_path = "/obj/machinery/computer/telecomms/server"
|
||||
build_path = /obj/machinery/computer/telecomms/server
|
||||
origin_tech = "programming=3"
|
||||
/obj/item/weapon/circuitboard/comm_traffic
|
||||
name = "Circuitboard (Telecommunications Traffic Control)"
|
||||
build_path = "/obj/machinery/computer/telecomms/traffic"
|
||||
build_path = /obj/machinery/computer/telecomms/traffic
|
||||
origin_tech = "programming=3"
|
||||
|
||||
/obj/item/weapon/circuitboard/curefab
|
||||
name = "Circuit board (Cure Fabricator)"
|
||||
build_path = "/obj/machinery/computer/curer"
|
||||
build_path = /obj/machinery/computer/curer
|
||||
/obj/item/weapon/circuitboard/splicer
|
||||
name = "Circuit board (Disease Splicer)"
|
||||
build_path = "/obj/machinery/computer/diseasesplicer"
|
||||
build_path = /obj/machinery/computer/diseasesplicer
|
||||
/obj/item/weapon/circuitboard/mining_shuttle
|
||||
name = "Circuit board (Mining Shuttle)"
|
||||
build_path = "/obj/machinery/computer/shuttle_control/mining"
|
||||
build_path = /obj/machinery/computer/shuttle_control/mining
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/white_ship
|
||||
name = "circuit Board (White Ship)"
|
||||
desc = {"A dusty circuitboard, marked "property of the NGV Venal"."}
|
||||
build_path = "/obj/machinery/computer/shuttle_control/multi/whiteship"
|
||||
build_path = /obj/machinery/computer/shuttle_control/multi/whiteship
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/engineering_shuttle
|
||||
name = "Circuit board (Engineering Shuttle)"
|
||||
build_path = "/obj/machinery/computer/shuttle_control/engineering"
|
||||
build_path = /obj/machinery/computer/shuttle_control/engineering
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/research_shuttle
|
||||
name = "Circuit board (Research Shuttle)"
|
||||
build_path = "/obj/machinery/computer/shuttle_control/research"
|
||||
build_path = /obj/machinery/computer/shuttle_control/research
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/HolodeckControl
|
||||
name = "Circuit board (Holodeck Control)"
|
||||
build_path = "/obj/machinery/computer/HolodeckControl"
|
||||
build_path = /obj/machinery/computer/HolodeckControl
|
||||
origin_tech = "programming=4"
|
||||
/obj/item/weapon/circuitboard/aifixer
|
||||
name = "Circuit board (AI Integrity Restorer)"
|
||||
build_path = "/obj/machinery/computer/aifixer"
|
||||
build_path = /obj/machinery/computer/aifixer
|
||||
origin_tech = "programming=3;biotech=2"
|
||||
/obj/item/weapon/circuitboard/area_atmos
|
||||
name = "Circuit board (Area Air Control)"
|
||||
build_path = "/obj/machinery/computer/area_atmos"
|
||||
build_path = /obj/machinery/computer/area_atmos
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/prison_shuttle
|
||||
name = "Circuit board (Prison Shuttle)"
|
||||
build_path = "/obj/machinery/computer/prison_shuttle"
|
||||
build_path = /obj/machinery/computer/prison_shuttle
|
||||
origin_tech = "programming=2"
|
||||
/obj/item/weapon/circuitboard/telesci_console
|
||||
name = "Circuit board (Telepad Control Console)"
|
||||
build_path = "/obj/machinery/computer/telescience"
|
||||
build_path = /obj/machinery/computer/telescience
|
||||
origin_tech = "programming=3;bluespace=2"
|
||||
|
||||
/obj/item/weapon/circuitboard/atmos_automation
|
||||
name = "Circuit board (Atmospherics Automation)"
|
||||
build_path = "/obj/machinery/computer/general_air_control/atmos_automation"
|
||||
build_path = /obj/machinery/computer/general_air_control/atmos_automation
|
||||
/obj/item/weapon/circuitboard/large_tank_control
|
||||
name = "Circuit board (Atmospheric Tank Control)"
|
||||
build_path = "/obj/machinery/computer/general_air_control/large_tank_control"
|
||||
build_path = /obj/machinery/computer/general_air_control/large_tank_control
|
||||
|
||||
/obj/item/weapon/circuitboard/HONKputer
|
||||
name = "Circuit board (HONKputer)"
|
||||
build_path = "/obj/machinery/computer/HONKputer"
|
||||
build_path = /obj/machinery/computer/HONKputer
|
||||
origin_tech = "programming=4"
|
||||
icon = 'icons/obj/machines/HONKputer.dmi'
|
||||
icon_state = "bananium_board"
|
||||
@@ -274,11 +280,11 @@
|
||||
user.visible_message("\blue \the [user] adjusts the jumper on the [src]'s access protocol pins.", "\blue You adjust the jumper on the access protocol pins.")
|
||||
if(src.build_path == "/obj/machinery/computer/rdconsole/core")
|
||||
src.name = "Circuit Board (RD Console - Robotics)"
|
||||
src.build_path = "/obj/machinery/computer/rdconsole/robotics"
|
||||
src.build_path = /obj/machinery/computer/rdconsole/robotics
|
||||
user << "\blue Access protocols set to robotics."
|
||||
else
|
||||
src.name = "Circuit Board (RD Console)"
|
||||
src.build_path = "/obj/machinery/computer/rdconsole/core"
|
||||
src.build_path = /obj/machinery/computer/rdconsole/core
|
||||
user << "\blue Access protocols set to default."
|
||||
return
|
||||
|
||||
|
||||
@@ -1,117 +1,57 @@
|
||||
|
||||
/obj/machinery/computer/station_alert
|
||||
name = "Station Alert Computer"
|
||||
name = "Station Alert Console"
|
||||
desc = "Used to access the station's automated alert system."
|
||||
icon_keyboard = "tech_key"
|
||||
icon_screen = "alert:0"
|
||||
circuit = "/obj/item/weapon/circuitboard/stationalert"
|
||||
var/alarms = list("Fire"=list(), "Atmosphere"=list(), "Power"=list())
|
||||
circuit = /obj/item/weapon/circuitboard/stationalert_engineering
|
||||
var/datum/nano_module/alarm_monitor/alarm_monitor
|
||||
var/monitor_type = /datum/nano_module/alarm_monitor/engineering
|
||||
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
/obj/machinery/computer/station_alert/security
|
||||
monitor_type = /datum/nano_module/alarm_monitor/security
|
||||
circuit = /obj/item/weapon/circuitboard/stationalert_security
|
||||
|
||||
/obj/machinery/computer/station_alert/all
|
||||
monitor_type = /datum/nano_module/alarm_monitor/all
|
||||
circuit = /obj/item/weapon/circuitboard/stationalert_all
|
||||
|
||||
attack_ai(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
/obj/machinery/computer/station_alert/New()
|
||||
..()
|
||||
alarm_monitor = new monitor_type(src)
|
||||
alarm_monitor.register(src, /obj/machinery/computer/station_alert/update_icon)
|
||||
|
||||
/obj/machinery/computer/station_alert/Destroy()
|
||||
alarm_monitor.unregister(src)
|
||||
qdel(alarm_monitor)
|
||||
..()
|
||||
|
||||
/obj/machinery/computer/station_alert/attack_ai(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
return
|
||||
|
||||
/obj/machinery/computer/station_alert/attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
return
|
||||
|
||||
/obj/machinery/computer/station_alert/interact(mob/user)
|
||||
alarm_monitor.ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/station_alert/update_icon()
|
||||
..()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
|
||||
|
||||
attack_hand(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
return
|
||||
|
||||
|
||||
interact(mob/user)
|
||||
usr.set_machine(src)
|
||||
var/dat = "<HEAD><TITLE>Current Station Alerts</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
|
||||
dat += "<A HREF='?src=\ref[user];mach_close=alerts'>Close</A><br><br>"
|
||||
for (var/cat in src.alarms)
|
||||
dat += text("<B>[]</B><BR>\n", cat)
|
||||
var/list/L = src.alarms[cat]
|
||||
if (L.len)
|
||||
for (var/alarm in L)
|
||||
var/list/alm = L[alarm]
|
||||
var/area/A = alm[1]
|
||||
var/list/sources = alm[3]
|
||||
|
||||
// AUTOFIXED BY fix_string_idiocy.py
|
||||
// C:\Users\Rob\Documents\Projects\vgstation13\code\game\machinery\computer\station_alert.dm:39: dat += "<NOBR>"
|
||||
dat += {"<NOBR>
|
||||
•
|
||||
[A.name]"}
|
||||
// END AUTOFIX
|
||||
if (sources.len > 1)
|
||||
dat += text(" - [] sources", sources.len)
|
||||
dat += "</NOBR><BR>\n"
|
||||
else
|
||||
dat += "-- All Systems Nominal<BR>\n"
|
||||
dat += "<BR>\n"
|
||||
user << browse(dat, "window=alerts")
|
||||
onclose(user, "alerts")
|
||||
|
||||
|
||||
Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
proc/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
var/list/L = src.alarms[class]
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[3]
|
||||
if (!(alarmsource in sources))
|
||||
sources += alarmsource
|
||||
return 1
|
||||
var/obj/machinery/camera/C = null
|
||||
var/list/CL = null
|
||||
if (O && istype(O, /list))
|
||||
CL = O
|
||||
if (CL.len == 1)
|
||||
C = CL[1]
|
||||
else if (O && istype(O, /obj/machinery/camera))
|
||||
C = O
|
||||
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
|
||||
return 1
|
||||
|
||||
|
||||
proc/cancelAlarm(var/class, area/A as area, obj/origin)
|
||||
if(stat & (BROKEN))
|
||||
return
|
||||
var/list/L = src.alarms[class]
|
||||
var/cleared = 0
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[3]
|
||||
if (origin in srcs)
|
||||
srcs -= origin
|
||||
if (srcs.len == 0)
|
||||
cleared = 1
|
||||
L -= I
|
||||
return !cleared
|
||||
|
||||
|
||||
process()
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
icon_screen = "alert:0"
|
||||
return
|
||||
var/active_alarms = 0
|
||||
for (var/cat in src.alarms)
|
||||
var/list/L = src.alarms[cat]
|
||||
if(L.len) active_alarms = 1
|
||||
if(active_alarms)
|
||||
if(alarm_monitor)
|
||||
var/list/alarms = alarm_monitor.major_alarms()
|
||||
if(alarms.len)
|
||||
icon_screen = "alert:2"
|
||||
else
|
||||
icon_screen = "alert:0"
|
||||
..()
|
||||
return
|
||||
|
||||
@@ -291,9 +291,10 @@ Class Procs:
|
||||
update_multitool_menu(usr)
|
||||
return 1
|
||||
|
||||
/obj/machinery/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/custom_state = default_state)
|
||||
if(..())
|
||||
/obj/machinery/Topic(href, href_list, var/nowindow = 0, var/datum/topic_state/state = default_state)
|
||||
if(..(href, href_list, nowindow, state))
|
||||
return 1
|
||||
|
||||
handle_multitool_topic(href,href_list,usr)
|
||||
add_fingerprint(usr)
|
||||
return 0
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
#define ALARM_RESET_DELAY 100 // How long will the alarm/trigger remain active once origin/source has been found to be gone?
|
||||
|
||||
/datum/alarm_source
|
||||
var/source = null // The source trigger
|
||||
var/source_name = "" // The name of the source should it be lost (for example a destroyed camera)
|
||||
var/duration = 0 // How long this source will be alarming, 0 for indefinetely.
|
||||
var/severity = 1 // How severe the alarm from this source is.
|
||||
var/start_time = 0 // When this source began alarming.
|
||||
var/end_time = 0 // Use to set when this trigger should clear, in case the source is lost.
|
||||
|
||||
/datum/alarm_source/New(var/atom/source)
|
||||
src.source = source
|
||||
start_time = world.time
|
||||
source_name = source.get_source_name()
|
||||
|
||||
/datum/alarm
|
||||
var/atom/origin //Used to identify the alarm area.
|
||||
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
|
||||
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
|
||||
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
|
||||
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
|
||||
var/area/last_name //The last acquired name, used should origin be lost
|
||||
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
|
||||
var/end_time //Used to set when this alarm should clear, in case the origin is lost.
|
||||
|
||||
/datum/alarm/New(var/atom/origin, var/atom/source, var/duration, var/severity)
|
||||
src.origin = origin
|
||||
|
||||
cameras() // Sets up both cameras and last alarm area.
|
||||
set_source_data(source, duration, severity)
|
||||
|
||||
/datum/alarm/proc/process()
|
||||
// Has origin gone missing?
|
||||
if(!origin && !end_time)
|
||||
end_time = world.time + ALARM_RESET_DELAY
|
||||
for(var/datum/alarm_source/AS in sources)
|
||||
// Has the alarm passed its best before date?
|
||||
if((AS.end_time && world.time > AS.end_time) || (AS.duration && world.time > (AS.start_time + AS.duration)))
|
||||
sources -= AS
|
||||
// Has the source gone missing? Then reset the normal duration and set end_time
|
||||
if(!AS.source && !AS.end_time) // end_time is used instead of duration to ensure the reset doesn't remain in the future indefinetely.
|
||||
AS.duration = 0
|
||||
AS.end_time = world.time + ALARM_RESET_DELAY
|
||||
|
||||
/datum/alarm/proc/set_source_data(var/atom/source, var/duration, var/severity)
|
||||
var/datum/alarm_source/AS = sources_assoc[source]
|
||||
if(!AS)
|
||||
AS = new/datum/alarm_source(source)
|
||||
sources += AS
|
||||
sources_assoc[source] = AS
|
||||
// Currently only non-0 durations can be altered (normal alarms VS EMP blasts)
|
||||
if(AS.duration)
|
||||
duration = SecondsToTicks(duration)
|
||||
AS.duration = duration
|
||||
AS.severity = severity
|
||||
|
||||
/datum/alarm/proc/clear(var/source)
|
||||
var/datum/alarm_source/AS = sources_assoc[source]
|
||||
sources -= AS
|
||||
sources_assoc -= source
|
||||
|
||||
/datum/alarm/proc/alarm_area()
|
||||
if(!origin)
|
||||
return last_area
|
||||
|
||||
last_area = origin.get_alarm_area()
|
||||
return last_area
|
||||
|
||||
/datum/alarm/proc/alarm_name()
|
||||
if(!origin)
|
||||
return last_name
|
||||
|
||||
last_name = origin.get_alarm_name()
|
||||
return last_name
|
||||
|
||||
/datum/alarm/proc/cameras()
|
||||
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
|
||||
if(cameras && (last_camera_area != alarm_area()))
|
||||
cameras = null
|
||||
|
||||
// The list of cameras is also reset by /proc/invalidateCameraCache()
|
||||
if(!cameras)
|
||||
cameras = origin ? origin.get_alarm_cameras() : last_area.get_alarm_cameras()
|
||||
|
||||
last_camera_area = last_area
|
||||
return cameras
|
||||
|
||||
/datum/alarm/proc/max_severity()
|
||||
var/max_severity = 0
|
||||
for(var/datum/alarm_source/AS in sources)
|
||||
max_severity = max(AS.severity, max_severity)
|
||||
|
||||
return max_severity
|
||||
|
||||
/******************
|
||||
* Assisting procs *
|
||||
******************/
|
||||
/atom/proc/get_alarm_area()
|
||||
var/area/A = get_area(src)
|
||||
return A
|
||||
|
||||
/area/get_alarm_area()
|
||||
return src
|
||||
|
||||
/atom/proc/get_alarm_name()
|
||||
var/area/A = get_area(src)
|
||||
return A.name
|
||||
|
||||
/area/get_alarm_name()
|
||||
return name
|
||||
|
||||
/mob/get_alarm_name()
|
||||
return name
|
||||
|
||||
/atom/proc/get_source_name()
|
||||
return name
|
||||
|
||||
/obj/machinery/camera/get_source_name()
|
||||
return c_tag
|
||||
|
||||
/atom/proc/get_alarm_cameras()
|
||||
var/area/A = get_area(src)
|
||||
return A.get_cameras()
|
||||
|
||||
/area/get_alarm_cameras()
|
||||
return get_cameras()
|
||||
|
||||
/mob/living/silicon/robot/get_alarm_cameras()
|
||||
var/list/cameras = ..()
|
||||
if(camera)
|
||||
cameras += camera
|
||||
|
||||
return cameras
|
||||
|
||||
/mob/living/silicon/robot/syndicate/get_alarm_cameras()
|
||||
return list()
|
||||
|
||||
#undef ALARM_LOSS_DELAY
|
||||
@@ -0,0 +1,99 @@
|
||||
#define ALARM_RAISED 1
|
||||
#define ALARM_CLEARED 0
|
||||
|
||||
/datum/alarm_handler
|
||||
var/category = ""
|
||||
var/list/datum/alarm/alarms = new // All alarms, to handle cases when an origin has been deleted with one or more active alarms
|
||||
var/list/datum/alarm/alarms_assoc = new // Associative list of alarms, to efficiently acquire them based on origin.
|
||||
var/list/listeners = new // A list of all objects interested in alarm changes.
|
||||
|
||||
/datum/alarm_handler/proc/process()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
A.process()
|
||||
check_alarm_cleared(A)
|
||||
|
||||
/datum/alarm_handler/proc/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1)
|
||||
var/new_alarm
|
||||
//Proper origin and source mandatory
|
||||
if(!(origin && source))
|
||||
return
|
||||
origin = origin.get_alarm_origin()
|
||||
|
||||
new_alarm = 0
|
||||
//see if there is already an alarm of this origin
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(existing)
|
||||
existing.set_source_data(source, duration, severity)
|
||||
else
|
||||
existing = new/datum/alarm(origin, source, duration, severity)
|
||||
new_alarm = 1
|
||||
|
||||
alarms |= existing
|
||||
alarms_assoc[origin] = existing
|
||||
if(new_alarm)
|
||||
alarms = dd_sortedObjectList(alarms)
|
||||
on_alarm_change(existing, ALARM_RAISED)
|
||||
|
||||
return new_alarm
|
||||
|
||||
/datum/alarm_handler/proc/clearAlarm(var/atom/origin, var/source)
|
||||
//Proper origin and source mandatory
|
||||
if(!(origin && source))
|
||||
return
|
||||
origin = origin.get_alarm_origin()
|
||||
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(existing)
|
||||
existing.clear(source)
|
||||
return check_alarm_cleared(existing)
|
||||
|
||||
/datum/alarm_handler/proc/major_alarms()
|
||||
return alarms
|
||||
|
||||
/datum/alarm_handler/proc/minor_alarms()
|
||||
return alarms
|
||||
|
||||
/datum/alarm_handler/proc/check_alarm_cleared(var/datum/alarm/alarm)
|
||||
if ((alarm.end_time && world.time > alarm.end_time) || !alarm.sources.len)
|
||||
alarms -= alarm
|
||||
alarms_assoc -= alarm.origin
|
||||
on_alarm_change(alarm, ALARM_CLEARED)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/alarm_handler/proc/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
for(var/obj/machinery/camera/C in alarm.cameras())
|
||||
if(was_raised)
|
||||
C.network.Add(category)
|
||||
invalidateCameraCache()
|
||||
else
|
||||
C.network.Remove(category)
|
||||
notify_listeners(alarm, was_raised)
|
||||
|
||||
/datum/alarm_handler/proc/get_alarm_severity_for_origin(var/atom/origin)
|
||||
if(!origin)
|
||||
return
|
||||
|
||||
origin = origin.get_alarm_origin()
|
||||
var/datum/alarm/existing = alarms_assoc[origin]
|
||||
if(!existing)
|
||||
return
|
||||
|
||||
return existing.max_severity()
|
||||
|
||||
/atom/proc/get_alarm_origin()
|
||||
return src
|
||||
|
||||
/turf/get_alarm_origin()
|
||||
var/area/area = get_area(src)
|
||||
return area // Very important to get area.master, as dynamic lightning can and will split areas.
|
||||
|
||||
/datum/alarm_handler/proc/register(var/object, var/procName)
|
||||
listeners[object] = procName
|
||||
|
||||
/datum/alarm_handler/proc/unregister(var/object)
|
||||
listeners -= object
|
||||
|
||||
/datum/alarm_handler/proc/notify_listeners(var/alarm, var/was_raised)
|
||||
for(var/listener in listeners)
|
||||
call(listener, listeners[listener])(src, alarm, was_raised)
|
||||
@@ -0,0 +1,19 @@
|
||||
/datum/alarm_handler/atmosphere
|
||||
category = "Atmosphere Alarms"
|
||||
|
||||
/datum/alarm_handler/atmosphere/triggerAlarm(var/atom/origin, var/atom/source, var/duration = 0, var/severity = 1)
|
||||
..()
|
||||
|
||||
/datum/alarm_handler/atmosphere/major_alarms()
|
||||
var/list/major_alarms = new()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(A.max_severity() > 1)
|
||||
major_alarms.Add(A)
|
||||
return major_alarms
|
||||
|
||||
/datum/alarm_handler/atmosphere/minor_alarms()
|
||||
var/list/minor_alarms = new()
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(A.max_severity() == 1)
|
||||
minor_alarms.Add(A)
|
||||
return minor_alarms
|
||||
@@ -0,0 +1,2 @@
|
||||
/datum/alarm_handler/camera
|
||||
category = "Camera Alarms"
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/alarm_handler/fire
|
||||
category = "Fire Alarms"
|
||||
|
||||
/datum/alarm_handler/fire/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
var/area/A = alarm.origin
|
||||
if(istype(A))
|
||||
if(was_raised)
|
||||
A.fire_alert()
|
||||
else
|
||||
A.fire_reset()
|
||||
..()
|
||||
@@ -0,0 +1,2 @@
|
||||
/datum/alarm_handler/motion
|
||||
category = "Motion Alarms"
|
||||
@@ -0,0 +1,10 @@
|
||||
/datum/alarm_handler/power
|
||||
category = "Power Alarms"
|
||||
|
||||
/datum/alarm_handler/power/on_alarm_change(var/datum/alarm/alarm, var/was_raised)
|
||||
var/area/A = alarm.origin
|
||||
if(istype(A))
|
||||
A.power_alert(was_raised)
|
||||
..()
|
||||
|
||||
/area/proc/power_alert(var/alarming)
|
||||
@@ -182,7 +182,7 @@
|
||||
if(!E.event_meta)
|
||||
continue
|
||||
var/datum/event_meta/EM = E.event_meta
|
||||
var/ends_at = E.startedAt + (E.lastProcessAt() * master_controller.minimum_ticks) // A best estimate
|
||||
var/ends_at = E.startedAt + (E.lastProcessAt() * 20) // A best estimate, based on how often the manager processes
|
||||
var/ends_in = max(0, round((ends_at - world.time) / 600, 0.1))
|
||||
var/no_end = E.noAutoEnd
|
||||
html += "<tr>"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
var/list/ai_list = list()
|
||||
var/list/ai_verbs_default = list(
|
||||
/mob/living/silicon/ai/proc/ai_alerts,
|
||||
/mob/living/silicon/ai/proc/announcement,
|
||||
/mob/living/silicon/ai/proc/ai_call_shuttle,
|
||||
/mob/living/silicon/ai/proc/ai_camera_track,
|
||||
@@ -25,7 +24,6 @@ var/list/ai_verbs_default = list(
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light,
|
||||
/mob/living/silicon/ai/proc/botcall,
|
||||
/mob/living/silicon/ai/proc/change_arrival_message,
|
||||
/mob/living/silicon/ai/proc/nano_crew_monitor
|
||||
)
|
||||
|
||||
//Not sure why this is necessary...
|
||||
@@ -95,9 +93,11 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/proc/add_ai_verbs()
|
||||
src.verbs |= ai_verbs_default
|
||||
|
||||
src.verbs |= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/ai/proc/remove_ai_verbs()
|
||||
src.verbs -= ai_verbs_default
|
||||
src.verbs -= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
|
||||
var/list/possibleNames = ai_names
|
||||
@@ -181,8 +181,6 @@ var/list/ai_verbs_default = list(
|
||||
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
hud_list[NATIONS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
|
||||
init_subsystems()
|
||||
|
||||
ai_list += src
|
||||
..()
|
||||
return
|
||||
@@ -321,43 +319,6 @@ var/list/ai_verbs_default = list(
|
||||
if (malf.apcs >= 3)
|
||||
stat(null, "Time until station control secured: [max(malf.AI_win_timeleft/(malf.apcs/3), 0)] seconds")
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_alerts()
|
||||
set name = "Show Alerts"
|
||||
set category = "AI Commands"
|
||||
|
||||
var/dat = "<HEAD><TITLE>Current Station Alerts</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
|
||||
dat += "<A HREF='?src=\ref[src];mach_close=aialerts'>Close</A><BR><BR>"
|
||||
for (var/cat in alarms)
|
||||
dat += text("<B>[]</B><BR>\n", cat)
|
||||
var/list/L = alarms[cat]
|
||||
if (L.len)
|
||||
for (var/alarm in L)
|
||||
var/list/alm = L[alarm]
|
||||
var/area/A = alm[1]
|
||||
var/C = alm[2]
|
||||
var/list/sources = alm[3]
|
||||
dat += "<NOBR>"
|
||||
if (C && istype(C, /list))
|
||||
var/dat2 = ""
|
||||
for (var/obj/machinery/camera/I in C)
|
||||
dat2 += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (dat2=="") ? "" : " | ", src, I, I.c_tag)
|
||||
dat += text("-- [] ([])", A.name, (dat2!="") ? dat2 : "No Camera")
|
||||
else if (C && istype(C, /obj/machinery/camera))
|
||||
var/obj/machinery/camera/Ctmp = C
|
||||
dat += text("-- [] (<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>)", A.name, src, C, Ctmp.c_tag)
|
||||
else
|
||||
dat += text("-- [] (No Camera)", A.name)
|
||||
if (sources.len > 1)
|
||||
dat += text("- [] sources", sources.len)
|
||||
dat += "</NOBR><BR>\n"
|
||||
else
|
||||
dat += "-- All Systems Nominal<BR>\n"
|
||||
dat += "<BR>\n"
|
||||
|
||||
viewalerts = 1
|
||||
src << browse(dat, "window=aialerts&can_close=0")
|
||||
|
||||
// this verb lets the ai see the stations manifest
|
||||
/mob/living/silicon/ai/proc/ai_roster()
|
||||
set name = "Show Crew Manifest"
|
||||
@@ -495,7 +456,7 @@ var/list/ai_verbs_default = list(
|
||||
if (href_list["switchcamera"])
|
||||
switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras
|
||||
if (href_list["showalerts"])
|
||||
ai_alerts()
|
||||
subsystem_alarm_monitor()
|
||||
if(href_list["show_paper"])
|
||||
if(last_paper_seen)
|
||||
src << browse(last_paper_seen, "window=show_paper")
|
||||
@@ -721,60 +682,6 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
|
||||
if (stat == 2)
|
||||
return 1
|
||||
var/list/L = alarms[class]
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[3]
|
||||
if (!(alarmsource in sources))
|
||||
sources += alarmsource
|
||||
return 1
|
||||
var/obj/machinery/camera/C = null
|
||||
var/list/CL = null
|
||||
if (O && istype(O, /list))
|
||||
CL = O
|
||||
if (CL.len == 1)
|
||||
C = CL[1]
|
||||
else if (O && istype(O, /obj/machinery/camera))
|
||||
C = O
|
||||
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
|
||||
if (O)
|
||||
if (C && C.can_use())
|
||||
queueAlarm("--- [class] alarm detected in [A.name]! (<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>)", class)
|
||||
else if (CL && CL.len)
|
||||
var/foo = 0
|
||||
var/dat2 = ""
|
||||
for (var/obj/machinery/camera/I in CL)
|
||||
dat2 += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (!foo) ? "" : " | ", src, I, I.c_tag) //I'm not fixing this shit...
|
||||
foo = 1
|
||||
queueAlarm(text ("--- [] alarm detected in []! ([])", class, A.name, dat2), class)
|
||||
else
|
||||
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
|
||||
else
|
||||
queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class)
|
||||
if (viewalerts) ai_alerts()
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, obj/origin)
|
||||
var/list/L = alarms[class]
|
||||
var/cleared = 0
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[3]
|
||||
if (origin in srcs)
|
||||
srcs -= origin
|
||||
if (srcs.len == 0)
|
||||
cleared = 1
|
||||
L -= I
|
||||
if (cleared)
|
||||
queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0)
|
||||
if (viewalerts) ai_alerts()
|
||||
return !cleared
|
||||
|
||||
//Replaces /mob/living/silicon/ai/verb/change_network() in ai.dm & camera.dm
|
||||
//Adds in /mob/living/silicon/ai/proc/ai_network_change() instead
|
||||
//Addition by Mord_Sith to define AI's network change ability
|
||||
|
||||
@@ -173,6 +173,7 @@
|
||||
sleep(50)
|
||||
theAPC = null
|
||||
|
||||
process_queued_alarms()
|
||||
regular_hud_updates()
|
||||
switch(src.sensor_mode)
|
||||
if (SEC_HUD)
|
||||
@@ -188,4 +189,13 @@
|
||||
if(fire_res_on_core)
|
||||
health = 100 - getOxyLoss() - getToxLoss() - getBruteLoss()
|
||||
else
|
||||
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
||||
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
|
||||
|
||||
/mob/living/silicon/ai/proc/lacks_power()
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(src)
|
||||
return ((!A.power_equip) && A.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item)
|
||||
|
||||
/mob/living/silicon/ai/rejuvenate()
|
||||
..()
|
||||
add_ai_verbs(src)
|
||||
@@ -1,11 +0,0 @@
|
||||
/mob/living/silicon/ai
|
||||
var/datum/nano_module/crew_monitor/crew_monitor
|
||||
|
||||
/mob/living/silicon/ai/proc/init_subsystems()
|
||||
crew_monitor = new(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/nano_crew_monitor()
|
||||
set category = "AI Commands"
|
||||
set name = "Crew Monitor"
|
||||
|
||||
crew_monitor.ui_interact(usr)
|
||||
@@ -318,3 +318,9 @@
|
||||
else
|
||||
src << "<span class='warning'>You are too small to pull that.</span>"
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/add_robot_verbs()
|
||||
src.verbs |= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/robot/drone/remove_robot_verbs()
|
||||
src.verbs -= silicon_subsystems
|
||||
@@ -19,6 +19,7 @@
|
||||
if (src.stat != DEAD) //still using power
|
||||
use_power()
|
||||
process_locks()
|
||||
process_queued_alarms()
|
||||
|
||||
update_canmove()
|
||||
|
||||
|
||||
@@ -300,6 +300,8 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
//languages
|
||||
module.add_languages(src)
|
||||
//subsystems
|
||||
module.add_subsystems(src)
|
||||
|
||||
//Custom_sprite check and entry
|
||||
if (custom_sprite == 1)
|
||||
@@ -374,41 +376,12 @@ var/list/robot_verbs_default = list(
|
||||
updatename()
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/verb/cmd_robot_alerts()
|
||||
set category = "Robot Commands"
|
||||
set name = "Show Alerts"
|
||||
robot_alerts()
|
||||
|
||||
// this verb lets cyborgs see the stations manifest
|
||||
/mob/living/silicon/robot/verb/cmd_station_manifest()
|
||||
set category = "Robot Commands"
|
||||
set name = "Show Station Manifest"
|
||||
show_station_manifest()
|
||||
|
||||
|
||||
/mob/living/silicon/robot/proc/robot_alerts()
|
||||
var/dat = "<HEAD><TITLE>Current Station Alerts</TITLE><META HTTP-EQUIV='Refresh' CONTENT='10'></HEAD><BODY>\n"
|
||||
dat += "<A HREF='?src=\ref[src];mach_close=robotalerts'>Close</A><BR><BR>"
|
||||
for (var/cat in alarms)
|
||||
dat += text("<B>[cat]</B><BR>\n")
|
||||
var/list/L = alarms[cat]
|
||||
if (L.len)
|
||||
for (var/alarm in L)
|
||||
var/list/alm = L[alarm]
|
||||
var/area/A = alm[1]
|
||||
var/list/sources = alm[3]
|
||||
dat += "<NOBR>" // wat
|
||||
dat += text("-- [A.name]")
|
||||
if (sources.len > 1)
|
||||
dat += text("- [sources.len] sources")
|
||||
dat += "</NOBR><BR>\n"
|
||||
else
|
||||
dat += "-- All Systems Nominal<BR>\n"
|
||||
dat += "<BR>\n"
|
||||
|
||||
viewalerts = 1
|
||||
src << browse(dat, "window=robotalerts&can_close=0")
|
||||
|
||||
/mob/living/silicon/robot/proc/self_diagnosis()
|
||||
if(!is_component_functioning("diagnosis unit"))
|
||||
return null
|
||||
@@ -420,7 +393,6 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
return dat
|
||||
|
||||
|
||||
/mob/living/silicon/robot/verb/self_diagnosis_verb()
|
||||
set category = "Robot Commands"
|
||||
set name = "Self Diagnosis"
|
||||
@@ -464,9 +436,11 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/robot/proc/add_robot_verbs()
|
||||
src.verbs |= robot_verbs_default
|
||||
src.verbs |= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/robot/proc/remove_robot_verbs()
|
||||
src.verbs -= robot_verbs_default
|
||||
src.verbs -= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/robot/blob_act()
|
||||
if (stat != 2)
|
||||
@@ -590,50 +564,6 @@ var/list/robot_verbs_default = list(
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/mob/living/silicon/robot/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
|
||||
if (stat == 2)
|
||||
return 1
|
||||
var/list/L = alarms[class]
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/sources = alarm[3]
|
||||
if (!(alarmsource in sources))
|
||||
sources += alarmsource
|
||||
return 1
|
||||
var/obj/machinery/camera/C = null
|
||||
var/list/CL = null
|
||||
if (O && istype(O, /list))
|
||||
CL = O
|
||||
if (CL.len == 1)
|
||||
C = CL[1]
|
||||
else if (O && istype(O, /obj/machinery/camera))
|
||||
C = O
|
||||
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
|
||||
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
|
||||
// if (viewalerts) robot_alerts()
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/silicon/robot/cancelAlarm(var/class, area/A as area, obj/origin)
|
||||
var/list/L = alarms[class]
|
||||
var/cleared = 0
|
||||
for (var/I in L)
|
||||
if (I == A.name)
|
||||
var/list/alarm = L[I]
|
||||
var/list/srcs = alarm[3]
|
||||
if (origin in srcs)
|
||||
srcs -= origin
|
||||
if (srcs.len == 0)
|
||||
cleared = 1
|
||||
L -= I
|
||||
if (cleared)
|
||||
queueAlarm(text("--- [class] alarm in [A.name] has been cleared."), class, 0)
|
||||
// if (viewalerts) robot_alerts()
|
||||
return !cleared
|
||||
|
||||
|
||||
/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob, params)
|
||||
if (istype(W, /obj/item/weapon/restraints/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
|
||||
return
|
||||
@@ -1124,32 +1054,32 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
|
||||
/mob/living/silicon/robot/Topic(href, href_list)
|
||||
..()
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(usr != src)
|
||||
return
|
||||
return 1
|
||||
|
||||
if (href_list["mach_close"])
|
||||
var/t1 = text("window=[href_list["mach_close"]]")
|
||||
unset_machine()
|
||||
src << browse(null, t1)
|
||||
return
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
if (href_list["showalerts"])
|
||||
robot_alerts()
|
||||
return
|
||||
subsystem_alarm_monitor()
|
||||
return 1
|
||||
|
||||
if (href_list["mod"])
|
||||
var/obj/item/O = locate(href_list["mod"])
|
||||
if (istype(O) && (O.loc == src))
|
||||
O.attack_self(src)
|
||||
return 1
|
||||
|
||||
if (href_list["act"])
|
||||
var/obj/item/O = locate(href_list["act"])
|
||||
if (!istype(O) || !(O.loc == src || O.loc == src.module))
|
||||
return
|
||||
return 1
|
||||
|
||||
activate_module(O)
|
||||
installed_modules()
|
||||
@@ -1171,6 +1101,7 @@ var/list/robot_verbs_default = list(
|
||||
else
|
||||
src << "Module isn't activated"
|
||||
installed_modules()
|
||||
return 1
|
||||
|
||||
if (href_list["lawc"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawc"])
|
||||
@@ -1179,6 +1110,7 @@ var/list/robot_verbs_default = list(
|
||||
if ("No") lawcheck[L+1] = "Yes"
|
||||
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
|
||||
checklaws()
|
||||
return 1
|
||||
|
||||
if (href_list["lawi"]) // Toggling whether or not a law gets stated by the State Laws verb --NeoFite
|
||||
var/L = text2num(href_list["lawi"])
|
||||
@@ -1187,10 +1119,12 @@ var/list/robot_verbs_default = list(
|
||||
if ("No") ioncheck[L] = "Yes"
|
||||
// src << text ("Switching Law [L]'s report status to []", lawcheck[L+1])
|
||||
checklaws()
|
||||
return 1
|
||||
|
||||
if (href_list["laws"]) // With how my law selection code works, I changed statelaws from a verb to a proc, and call it through my law selection panel. --NeoFite
|
||||
statelaws()
|
||||
return
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/robot/proc/radio_menu()
|
||||
radio.interact(src)//Just use the radio's Topic() instead of bullshit special-snowflake code
|
||||
@@ -1347,6 +1281,7 @@ var/list/robot_verbs_default = list(
|
||||
var/choice = input("Look at your icon - is this what you want?") in list("Yes","No")
|
||||
if(choice=="No")
|
||||
choose_icon(triesleft, module_sprites)
|
||||
return
|
||||
else
|
||||
triesleft = 0
|
||||
return
|
||||
|
||||
@@ -9,32 +9,30 @@
|
||||
var/list/modules = list()
|
||||
var/obj/item/emag = null
|
||||
var/obj/item/borg/upgrade/jetpack = null
|
||||
var/list/subsystems = list()
|
||||
|
||||
var/list/stacktypes
|
||||
var/channels = list()
|
||||
|
||||
|
||||
emp_act(severity)
|
||||
if(modules)
|
||||
for(var/obj/O in modules)
|
||||
O.emp_act(severity)
|
||||
if(emag)
|
||||
emag.emp_act(severity)
|
||||
..()
|
||||
return
|
||||
/obj/item/weapon/robot_module/emp_act(severity)
|
||||
if(modules)
|
||||
for(var/obj/O in modules)
|
||||
O.emp_act(severity)
|
||||
if(emag)
|
||||
emag.emp_act(severity)
|
||||
..()
|
||||
return
|
||||
|
||||
|
||||
New()
|
||||
src.modules += new /obj/item/device/flashlight(src)
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
src.emag = new /obj/item/toy/sword(src)
|
||||
src.emag.name = "Placeholder Emag Item"
|
||||
// src.jetpack = new /obj/item/toy/sword(src)
|
||||
// src.jetpack.name = "Placeholder Upgrade Item"
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/New()
|
||||
src.modules += new /obj/item/device/flashlight(src)
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
src.emag = new /obj/item/toy/sword(src)
|
||||
src.emag.name = "Placeholder Emag Item"
|
||||
return
|
||||
|
||||
/obj/item/weapon/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R)
|
||||
|
||||
if(!stacktypes || !stacktypes.len) return
|
||||
|
||||
var/stack_respawned = 0
|
||||
@@ -77,6 +75,12 @@
|
||||
R.add_language("Chittin", 0)
|
||||
R.add_language("Bubblish", 0)
|
||||
R.add_language("Clownish",0)
|
||||
|
||||
/obj/item/weapon/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
|
||||
R.verbs |= subsystems
|
||||
|
||||
/obj/item/weapon/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R)
|
||||
R.verbs -= subsystems
|
||||
|
||||
/obj/item/weapon/robot_module/standard
|
||||
name = "standard robot module"
|
||||
@@ -94,13 +98,14 @@
|
||||
|
||||
/obj/item/weapon/robot_module/medical
|
||||
name = "medical robot module"
|
||||
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
|
||||
stacktypes = list(
|
||||
/obj/item/stack/medical/advanced/bruise_pack = 5,
|
||||
/obj/item/stack/medical/advanced/ointment = 5,
|
||||
/obj/item/stack/medical/splint = 5,
|
||||
/obj/item/stack/nanopaste = 5
|
||||
)
|
||||
|
||||
|
||||
New()
|
||||
src.modules += new /obj/item/device/flash/cyborg(src)
|
||||
src.modules += new /obj/item/device/healthanalyzer/advanced(src)
|
||||
@@ -197,6 +202,7 @@
|
||||
|
||||
/obj/item/weapon/robot_module/security
|
||||
name = "security robot module"
|
||||
subsystems = list(/mob/living/silicon/proc/subsystem_crew_monitor)
|
||||
|
||||
|
||||
New()
|
||||
|
||||
@@ -17,91 +17,29 @@
|
||||
var/speak_exclamation = "declares"
|
||||
var/speak_query = "queries"
|
||||
var/pose //Yes, now AIs can pose too.
|
||||
|
||||
var/sensor_mode = 0 //Determines the current HUD.
|
||||
|
||||
var/next_alarm_notice
|
||||
var/list/datum/alarm/queued_alarms = new()
|
||||
|
||||
#define SEC_HUD 1 //Security HUD mode
|
||||
#define MED_HUD 2 //Medical HUD mode
|
||||
var/local_transmit //If set, can only speak to others of the same type within a short range.
|
||||
var/obj/item/device/radio/common_radio
|
||||
|
||||
/mob/living/silicon/proc/cancelAlarm()
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/triggerAlarm()
|
||||
return
|
||||
|
||||
/mob/living/silicon/New()
|
||||
..()
|
||||
init_subsystems()
|
||||
|
||||
/mob/living/silicon/Destroy()
|
||||
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
|
||||
AH.unregister(src)
|
||||
..()
|
||||
|
||||
/mob/living/silicon/proc/show_laws()
|
||||
return
|
||||
|
||||
/mob/living/silicon/proc/queueAlarm(var/message, var/type, var/incoming = 1)
|
||||
var/in_cooldown = (alarms_to_show.len > 0 || alarms_to_clear.len > 0)
|
||||
if(incoming)
|
||||
alarms_to_show += message
|
||||
alarm_types_show[type] += 1
|
||||
else
|
||||
alarms_to_clear += message
|
||||
alarm_types_clear[type] += 1
|
||||
|
||||
if(!in_cooldown)
|
||||
spawn(10 * 10) // 10 seconds
|
||||
|
||||
if(alarms_to_show.len < 5)
|
||||
for(var/msg in alarms_to_show)
|
||||
src << msg
|
||||
else if(alarms_to_show.len)
|
||||
|
||||
var/msg = "--- "
|
||||
|
||||
if(alarm_types_show["Motion"])
|
||||
msg += "MOTION: [alarm_types_show["Motion"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Fire"])
|
||||
msg += "FIRE: [alarm_types_show["Fire"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Atmosphere"])
|
||||
msg += "ATMOSPHERE: [alarm_types_show["Atmosphere"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Power"])
|
||||
msg += "POWER: [alarm_types_show["Power"]] alarms detected. - "
|
||||
|
||||
if(alarm_types_show["Camera"])
|
||||
msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - "
|
||||
|
||||
msg += "<A href=?src=\ref[src];showalerts=1'>\[Show Alerts\]</a>"
|
||||
src << msg
|
||||
|
||||
if(alarms_to_clear.len < 3)
|
||||
for(var/msg in alarms_to_clear)
|
||||
src << msg
|
||||
|
||||
else if(alarms_to_clear.len)
|
||||
var/msg = "--- "
|
||||
|
||||
if(alarm_types_clear["Motion"])
|
||||
msg += "MOTION: [alarm_types_clear["Motion"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Fire"])
|
||||
msg += "FIRE: [alarm_types_clear["Fire"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Atmosphere"])
|
||||
msg += "ATMOSPHERE: [alarm_types_clear["Atmosphere"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_clear["Power"])
|
||||
msg += "POWER: [alarm_types_clear["Power"]] alarms cleared. - "
|
||||
|
||||
if(alarm_types_show["Camera"])
|
||||
msg += "CAMERA: [alarm_types_show["Power"]] alarms detected. - "
|
||||
|
||||
msg += "<A href=?src=\ref[src];showalerts=1'>\[Show Alerts\]</a>"
|
||||
src << msg
|
||||
|
||||
|
||||
alarms_to_show = list()
|
||||
alarms_to_clear = list()
|
||||
for(var/i = 1; i < alarm_types_show.len; i++)
|
||||
alarm_types_show[i] = 0
|
||||
for(var/i = 1; i < alarm_types_clear.len; i++)
|
||||
alarm_types_clear[i] = 0
|
||||
|
||||
/mob/living/silicon/drop_item()
|
||||
return
|
||||
|
||||
@@ -323,4 +261,62 @@
|
||||
src << "Sensor augmentations disabled."
|
||||
|
||||
/mob/living/silicon/IsAdvancedToolUser()
|
||||
return 1
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/proc/receive_alarm(var/datum/alarm_handler/alarm_handler, var/datum/alarm/alarm, was_raised)
|
||||
if(!next_alarm_notice)
|
||||
next_alarm_notice = world.time + SecondsToTicks(10)
|
||||
|
||||
var/list/alarms = queued_alarms[alarm_handler]
|
||||
if(was_raised)
|
||||
// Raised alarms are always set
|
||||
alarms[alarm] = 1
|
||||
else
|
||||
// Alarms that were raised but then cleared before the next notice are instead removed
|
||||
if(alarm in alarms)
|
||||
alarms -= alarm
|
||||
// And alarms that have only been cleared thus far are set as such
|
||||
else
|
||||
alarms[alarm] = -1
|
||||
|
||||
/mob/living/silicon/proc/process_queued_alarms()
|
||||
if(next_alarm_notice && (world.time > next_alarm_notice))
|
||||
next_alarm_notice = 0
|
||||
|
||||
var/alarm_raised = 0
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
var/reported = 0
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(alarms[A] == 1)
|
||||
if(!reported)
|
||||
reported = 1
|
||||
src << "<span class='warning'>--- [AH.category] Detected ---</span>"
|
||||
raised_alarm(A)
|
||||
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
var/reported = 0
|
||||
for(var/datum/alarm/A in alarms)
|
||||
if(alarms[A] == -1)
|
||||
if(!reported)
|
||||
reported = 1
|
||||
src << "<span class='notice'>--- [AH.category] Cleared ---</span>"
|
||||
src << "\The [A.alarm_name()]."
|
||||
|
||||
if(alarm_raised)
|
||||
src << "<A HREF=?src=\ref[src];showalerts=1>\[Show Alerts\]</A>"
|
||||
|
||||
for(var/datum/alarm_handler/AH in queued_alarms)
|
||||
var/list/alarms = queued_alarms[AH]
|
||||
alarms.Cut()
|
||||
|
||||
/mob/living/silicon/proc/raised_alarm(var/datum/alarm/A)
|
||||
src << "[A.alarm_name()]!"
|
||||
|
||||
/mob/living/silicon/ai/raised_alarm(var/datum/alarm/A)
|
||||
var/cameratext = ""
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>"
|
||||
src << "[A.alarm_name()]! ([(cameratext)? cameratext : "No Camera"])"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/mob/living/silicon
|
||||
var/register_alarms = 1
|
||||
var/datum/nano_module/alarm_monitor/all/alarm_monitor
|
||||
var/datum/nano_module/atmos_control/atmos_control
|
||||
var/datum/nano_module/crew_monitor/crew_monitor
|
||||
|
||||
/mob/living/silicon
|
||||
var/list/silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor
|
||||
)
|
||||
|
||||
/mob/living/silicon/ai
|
||||
silicon_subsystems = list(
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/proc/subsystem_atmos_control,
|
||||
/mob/living/silicon/proc/subsystem_crew_monitor
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/syndicate
|
||||
register_alarms = 0
|
||||
|
||||
/mob/living/silicon/proc/init_subsystems()
|
||||
alarm_monitor = new(src)
|
||||
atmos_control = new(src)
|
||||
crew_monitor = new(src)
|
||||
|
||||
if(!register_alarms)
|
||||
return
|
||||
|
||||
var/list/register_to = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm)
|
||||
for(var/datum/alarm_handler/AH in register_to)
|
||||
AH.register(src, /mob/living/silicon/proc/receive_alarm)
|
||||
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order
|
||||
|
||||
/********************
|
||||
* Alarm Monitor *
|
||||
********************/
|
||||
/mob/living/silicon/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "Subsystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr, state = self_state)
|
||||
|
||||
/********************
|
||||
* Atmos Control *
|
||||
********************/
|
||||
/mob/living/silicon/proc/subsystem_atmos_control()
|
||||
set category = "Subsystems"
|
||||
set name = "Atmospherics Control"
|
||||
|
||||
atmos_control.ui_interact(usr, state = self_state)
|
||||
|
||||
/********************
|
||||
* Crew Monitor *
|
||||
********************/
|
||||
/mob/living/silicon/proc/subsystem_crew_monitor()
|
||||
set category = "Subsystems"
|
||||
set name = "Crew Monitor"
|
||||
|
||||
crew_monitor.ui_interact(usr, state = self_state)
|
||||
@@ -498,4 +498,19 @@ var/list/intents = list("help","disarm","grab","harm")
|
||||
if(O.client)
|
||||
O << "<span class='ghostalert'>[message]<span>"
|
||||
if(ghost_sound)
|
||||
O << sound(ghost_sound)
|
||||
O << sound(ghost_sound)
|
||||
|
||||
/mob/proc/switch_to_camera(var/obj/machinery/camera/C)
|
||||
if (!C.can_use() || stat || (get_dist(C, src) > 1 || machine != src || blinded || !canmove))
|
||||
return 0
|
||||
check_eye(src)
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/switch_to_camera(var/obj/machinery/camera/C)
|
||||
if(!C.can_use() || !is_in_chassis())
|
||||
return 0
|
||||
|
||||
eyeobj.setLoc(get_turf(C))
|
||||
client.eye = eyeobj
|
||||
return 1
|
||||
|
||||
@@ -17,3 +17,18 @@
|
||||
else if (restrained() || lying || stat || stunned || weakened)
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
/mob/living/silicon/ai/shared_nano_interaction()
|
||||
if(lacks_power())
|
||||
return STATUS_CLOSE
|
||||
if (check_unable(1, 0))
|
||||
return STATUS_CLOSE
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/shared_nano_interaction()
|
||||
. = STATUS_INTERACTIVE
|
||||
if(cell.charge <= 0)
|
||||
return STATUS_CLOSE
|
||||
if(lockcharge)
|
||||
. = STATUS_DISABLED
|
||||
return min(., ..())
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/*
|
||||
This state checks that the src_object is the same the as user
|
||||
*/
|
||||
/var/global/datum/topic_state/self_state/self_state = new()
|
||||
|
||||
/datum/topic_state/self_state/can_use_topic(var/src_object, var/mob/user)
|
||||
if(src_object != user)
|
||||
return STATUS_CLOSE
|
||||
return user.shared_nano_interaction()
|
||||
@@ -0,0 +1,88 @@
|
||||
/datum/nano_module/alarm_monitor
|
||||
name = "Alarm monitor"
|
||||
var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use.
|
||||
var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user.
|
||||
|
||||
/datum/nano_module/alarm_monitor/all/New()
|
||||
..()
|
||||
alarm_handlers = list(atmosphere_alarm, camera_alarm, fire_alarm, motion_alarm, power_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/engineering/New()
|
||||
..()
|
||||
alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/security/New()
|
||||
..()
|
||||
alarm_handlers = list(camera_alarm, motion_alarm)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/register(var/object, var/procName)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.register(object, procName)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/unregister(var/object)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister(object)
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/all_alarms()
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/major_alarms()
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.major_alarms()
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/proc/minor_alarms()
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
all_alarms += AH.minor_alarms()
|
||||
|
||||
return all_alarms
|
||||
|
||||
/datum/nano_module/alarm_monitor/Topic(ref, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
if(href_list["switchTo"])
|
||||
var/obj/machinery/camera/C = locate(href_list["switchTo"]) in cameranet.cameras
|
||||
if(!C || !isAI(usr))
|
||||
return
|
||||
|
||||
usr.switch_to_camera(C)
|
||||
return 1
|
||||
|
||||
/datum/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
|
||||
var/categories[0]
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
categories[++categories.len] = list("category" = AH.category, "alarms" = list())
|
||||
for(var/datum/alarm/A in AH.major_alarms())
|
||||
var/cameras[0]
|
||||
var/lost_sources[0]
|
||||
|
||||
if(isAI(user))
|
||||
for(var/obj/machinery/camera/C in A.cameras())
|
||||
cameras[++cameras.len] = C.nano_structure()
|
||||
for(var/datum/alarm_source/AS in A.sources)
|
||||
if(!AS.source)
|
||||
lost_sources[++lost_sources.len] = AS.source_name
|
||||
|
||||
categories[categories.len]["alarms"] += list(list(
|
||||
"name" = sanitize(A.alarm_name()),
|
||||
"origin_lost" = A.origin == null,
|
||||
"has_cameras" = cameras.len,
|
||||
"cameras" = cameras,
|
||||
"lost_sources" = lost_sources.len ? sanitize(english_list(lost_sources, nothing_text = "", and_text = ", ")) : ""))
|
||||
data["categories"] = categories
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "alarm_monitor.tmpl", "Alarm Monitoring Console", 800, 800, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
@@ -0,0 +1,79 @@
|
||||
/datum/nano_module/atmos_control
|
||||
name = "Atmospherics Control"
|
||||
var/obj/access = new()
|
||||
var/emagged = 0
|
||||
var/ui_ref
|
||||
var/list/monitored_alarms = list()
|
||||
|
||||
/datum/nano_module/atmos_control/New(atmos_computer, req_access, req_one_access, monitored_alarm_ids)
|
||||
..()
|
||||
access.req_access = req_access
|
||||
access.req_one_access = req_one_access
|
||||
|
||||
if(monitored_alarm_ids)
|
||||
for(var/obj/machinery/alarm/alarm in machines)
|
||||
if(alarm.alarm_id && alarm.alarm_id in monitored_alarm_ids)
|
||||
monitored_alarms += alarm
|
||||
// machines may not yet be ordered at this point
|
||||
monitored_alarms = dd_sortedObjectList(monitored_alarms)
|
||||
|
||||
/datum/nano_module/atmos_control/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(href_list["alarm"])
|
||||
if(ui_ref)
|
||||
var/obj/machinery/alarm/alarm = locate(href_list["alarm"]) in (monitored_alarms.len ? monitored_alarms : machines)
|
||||
if(alarm)
|
||||
var/datum/topic_state/TS = generate_state(alarm)
|
||||
alarm.ui_interact(usr, master_ui = ui_ref, state = TS)
|
||||
return 1
|
||||
|
||||
/datum/nano_module/atmos_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/master_ui = null, var/datum/topic_state/state = default_state)
|
||||
var/data[0]
|
||||
var/alarms[0]
|
||||
|
||||
// TODO: Move these to a cache, similar to cameras
|
||||
for(var/obj/machinery/alarm/alarm in sortAtom((monitored_alarms.len ? monitored_alarms : machines)))
|
||||
if(!monitored_alarms.len && alarm.z != ZLEVEL_STATION && alarm.z != ZLEVEL_ASTEROID)
|
||||
continue
|
||||
alarms[++alarms.len] = alarm.get_nano_data_console()
|
||||
data["alarms"] = alarms
|
||||
|
||||
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "atmos_control.tmpl", src.name, 900, 800, state = state)
|
||||
ui.add_template("mapContent", "atmos_control_map_content.tmpl")
|
||||
ui.add_template("mapHeader", "atmos_control_map_header.tmpl")
|
||||
ui.set_show_map(1)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
ui_ref = ui
|
||||
|
||||
/datum/nano_module/atmos_control/proc/generate_state(air_alarm)
|
||||
var/datum/topic_state/air_alarm/state = new()
|
||||
state.atmos_control = src
|
||||
state.air_alarm = air_alarm
|
||||
return state
|
||||
|
||||
/datum/topic_state/air_alarm
|
||||
var/datum/nano_module/atmos_control/atmos_control = null
|
||||
var/obj/machinery/alarm/air_alarm = null
|
||||
|
||||
/datum/topic_state/air_alarm/can_use_topic(var/src_object, var/mob/user)
|
||||
if(!isAI(user) && !in_range(atmos_control.nano_host(), user))
|
||||
return STATUS_CLOSE
|
||||
if(has_access(user))
|
||||
return STATUS_INTERACTIVE
|
||||
return STATUS_UPDATE
|
||||
|
||||
/datum/topic_state/air_alarm/href_list(var/mob/user)
|
||||
var/list/extra_href = list()
|
||||
extra_href["remote_connection"] = 1
|
||||
extra_href["remote_access"] = has_access(user)
|
||||
|
||||
return extra_href
|
||||
|
||||
/datum/topic_state/air_alarm/proc/has_access(var/mob/user)
|
||||
return user && (isAI(user) || atmos_control.access.allowed(user) || atmos_control.emagged || air_alarm.rcon_setting == RCON_YES || (air_alarm.alarm_area.atmosalm && air_alarm.rcon_setting == RCON_AUTO))
|
||||
@@ -16,7 +16,7 @@
|
||||
AI.ai_actual_track(H)
|
||||
return 1
|
||||
|
||||
/datum/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/datum/nano_module/crew_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
src.scan()
|
||||
|
||||
var/data[0]
|
||||
|
||||
@@ -98,6 +98,10 @@
|
||||
var/global/list/status_overlays_lighting
|
||||
var/global/list/status_overlays_environ
|
||||
var/indestructible = 0 // If set, prevents aliens from destroying it
|
||||
var/report_power_alarm = 1
|
||||
|
||||
/obj/machinery/power/apc/noalarm
|
||||
report_power_alarm = 0
|
||||
|
||||
/obj/machinery/power/apc/updateDialog()
|
||||
if (stat & (BROKEN|MAINT))
|
||||
@@ -1153,29 +1157,30 @@
|
||||
lighting = autoset(lighting, 1)
|
||||
environ = autoset(environ, 1)
|
||||
autoflag = 3
|
||||
area.poweralert(1, src)
|
||||
if(cell_charge >= 4000)
|
||||
area.poweralert(1, src)
|
||||
power_alarm.clearAlarm(loc, src)
|
||||
else if(cell_charge < 1250 && cell_charge > 750 && longtermpower < 0) // <30%, turn off equipment
|
||||
if(autoflag != 2)
|
||||
equipment = autoset(equipment, 2)
|
||||
lighting = autoset(lighting, 1)
|
||||
environ = autoset(environ, 1)
|
||||
area.poweralert(0, src)
|
||||
if(report_power_alarm)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 2
|
||||
else if(cell_charge < 750 && cell_charge > 10 && longtermpower < 0) // <15%, turn off lighting & equipment
|
||||
if(autoflag != 1)
|
||||
equipment = autoset(equipment, 2)
|
||||
lighting = autoset(lighting, 2)
|
||||
environ = autoset(environ, 1)
|
||||
area.poweralert(0, src)
|
||||
if(report_power_alarm)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 1
|
||||
else if(cell_charge <= 0) // zero charge, turn all off
|
||||
if(autoflag != 0)
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
area.poweralert(0, src)
|
||||
if(report_power_alarm)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 0
|
||||
|
||||
// now trickle-charge the cell
|
||||
@@ -1221,7 +1226,8 @@
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
area.poweralert(0, src)
|
||||
if(report_power_alarm)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 0
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/area/engine/engineering/poweralert(var/state, var/source)
|
||||
if (state != poweralm)
|
||||
/area/engine/engineering/power_alert(var/alarming)
|
||||
if (alarming)
|
||||
investigate_log("has a power alarm!","singulo")
|
||||
..()
|
||||
Reference in New Issue
Block a user