Merged with dev.
@@ -93,14 +93,15 @@
|
||||
#include "code\controllers\lighting_controller.dm"
|
||||
#include "code\controllers\master_controller.dm"
|
||||
#include "code\controllers\shuttle_controller.dm"
|
||||
#include "code\controllers\subsystems.dm"
|
||||
#include "code\controllers\verbs.dm"
|
||||
#include "code\controllers\voting.dm"
|
||||
#include "code\controllers\subsystem\alarms.dm"
|
||||
#include "code\datums\ai_laws.dm"
|
||||
#include "code\datums\browser.dm"
|
||||
#include "code\datums\computerfiles.dm"
|
||||
#include "code\datums\datacore.dm"
|
||||
#include "code\datums\datumvars.dm"
|
||||
#include "code\datums\descriptions.dm"
|
||||
#include "code\datums\disease.dm"
|
||||
#include "code\datums\mind.dm"
|
||||
#include "code\datums\mixed.dm"
|
||||
@@ -808,6 +809,13 @@
|
||||
#include "code\modules\admin\verbs\ticklag.dm"
|
||||
#include "code\modules\admin\verbs\tripAI.dm"
|
||||
#include "code\modules\admin\verbs\vox_raiders.dm"
|
||||
#include "code\modules\alarm\alarm.dm"
|
||||
#include "code\modules\alarm\alarm_handler.dm"
|
||||
#include "code\modules\alarm\atmosphere_alarm.dm"
|
||||
#include "code\modules\alarm\camera_alarm.dm"
|
||||
#include "code\modules\alarm\fire_alarm.dm"
|
||||
#include "code\modules\alarm\motion_alarm.dm"
|
||||
#include "code\modules\alarm\power_alarm.dm"
|
||||
#include "code\modules\assembly\assembly.dm"
|
||||
#include "code\modules\assembly\bomb.dm"
|
||||
#include "code\modules\assembly\helpers.dm"
|
||||
@@ -953,6 +961,13 @@
|
||||
#include "code\modules\events\spontaneous_appendicitis.dm"
|
||||
#include "code\modules\events\viral_infection.dm"
|
||||
#include "code\modules\events\wallrot.dm"
|
||||
#include "code\modules\examine\examine.dm"
|
||||
#include "code\modules\examine\descriptions\atmospherics.dm"
|
||||
#include "code\modules\examine\descriptions\engineering.dm"
|
||||
#include "code\modules\examine\descriptions\mobs.dm"
|
||||
#include "code\modules\examine\descriptions\stacks.dm"
|
||||
#include "code\modules\examine\descriptions\structures.dm"
|
||||
#include "code\modules\examine\descriptions\turfs.dm"
|
||||
#include "code\modules\ext_scripts\irc.dm"
|
||||
#include "code\modules\ext_scripts\python.dm"
|
||||
#include "code\modules\flufftext\Dreaming.dm"
|
||||
@@ -1130,7 +1145,6 @@
|
||||
#include "code\modules\mob\living\carbon\monkey\login.dm"
|
||||
#include "code\modules\mob\living\carbon\monkey\monkey.dm"
|
||||
#include "code\modules\mob\living\carbon\monkey\update_icons.dm"
|
||||
#include "code\modules\mob\living\silicon\alarm.dm"
|
||||
#include "code\modules\mob\living\silicon\death.dm"
|
||||
#include "code\modules\mob\living\silicon\laws.dm"
|
||||
#include "code\modules\mob\living\silicon\login.dm"
|
||||
@@ -1144,8 +1158,8 @@
|
||||
#include "code\modules\mob\living\silicon\ai\life.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\login.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\logout.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\nano.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\say.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\subsystems.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\freelook\chunk.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\freelook\eye.dm"
|
||||
@@ -1178,6 +1192,7 @@
|
||||
#include "code\modules\mob\living\silicon\robot\robot_items.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_modules.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\robot_movement.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\subsystems.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_abilities.dm"
|
||||
#include "code\modules\mob\living\silicon\robot\drone\drone_console.dm"
|
||||
@@ -1236,6 +1251,7 @@
|
||||
#include "code\modules\nano\nanomanager.dm"
|
||||
#include "code\modules\nano\nanomapgen.dm"
|
||||
#include "code\modules\nano\nanoui.dm"
|
||||
#include "code\modules\nano\modules\alarm_monitor.dm"
|
||||
#include "code\modules\nano\modules\crew_monitor.dm"
|
||||
#include "code\modules\nano\modules\power_monitor.dm"
|
||||
#include "code\modules\nano\modules\rcon.dm"
|
||||
|
||||
@@ -383,6 +383,7 @@
|
||||
user << "You are too far away to read the gauge."
|
||||
if(welded)
|
||||
user << "It seems welded shut."
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_pump/power_change()
|
||||
var/old_stat = stat
|
||||
|
||||
@@ -277,6 +277,7 @@
|
||||
user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W"
|
||||
else
|
||||
user << "You are too far away to read the gauge."
|
||||
..()
|
||||
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/Del()
|
||||
if(initial_loc)
|
||||
|
||||
@@ -491,5 +491,8 @@ datum/projectile_data
|
||||
temps[direction] = rstats
|
||||
return temps
|
||||
|
||||
/proc/MinutesToTicks(var/minutes as num)
|
||||
return minutes * 60 * 10
|
||||
/proc/MinutesToTicks(var/minutes)
|
||||
return SecondsToTicks(60 * minutes)
|
||||
|
||||
/proc/SecondsToTicks(var/seconds)
|
||||
return seconds * 10
|
||||
|
||||
@@ -596,3 +596,7 @@ datum/proc/dd_SortValue()
|
||||
|
||||
/obj/machinery/camera/dd_SortValue()
|
||||
return "[c_tag]"
|
||||
|
||||
/datum/alarm/dd_SortValue()
|
||||
return "[sanitize(last_name)]"
|
||||
|
||||
|
||||
@@ -256,59 +256,99 @@ datum/hud/New(mob/owner)
|
||||
set name = "F12"
|
||||
set hidden = 1
|
||||
|
||||
if(hud_used)
|
||||
if(ishuman(src))
|
||||
if(!client) return
|
||||
if(client.view != world.view)
|
||||
return
|
||||
if(hud_used.hud_shown)
|
||||
hud_used.hud_shown = 0
|
||||
if(src.hud_used.adding)
|
||||
src.client.screen -= src.hud_used.adding
|
||||
if(src.hud_used.other)
|
||||
src.client.screen -= src.hud_used.other
|
||||
if(src.hud_used.hotkeybuttons)
|
||||
src.client.screen -= src.hud_used.hotkeybuttons
|
||||
if(src.hud_used.item_action_list)
|
||||
src.client.screen -= src.hud_used.item_action_list
|
||||
|
||||
//Due to some poor coding some things need special treatment:
|
||||
//These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay
|
||||
if(!full)
|
||||
src.client.screen += src.hud_used.l_hand_hud_object //we want the hands to be visible
|
||||
src.client.screen += src.hud_used.r_hand_hud_object //we want the hands to be visible
|
||||
src.client.screen += src.hud_used.action_intent //we want the intent swticher visible
|
||||
src.hud_used.action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is.
|
||||
else
|
||||
src.client.screen -= src.healths
|
||||
src.client.screen -= src.internals
|
||||
src.client.screen -= src.gun_setting_icon
|
||||
|
||||
//These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone.
|
||||
src.client.screen -= src.zone_sel //zone_sel is a mob variable for some reason.
|
||||
|
||||
else
|
||||
hud_used.hud_shown = 1
|
||||
if(src.hud_used.adding)
|
||||
src.client.screen += src.hud_used.adding
|
||||
if(src.hud_used.other && src.hud_used.inventory_shown)
|
||||
src.client.screen += src.hud_used.other
|
||||
if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden)
|
||||
src.client.screen += src.hud_used.hotkeybuttons
|
||||
if(src.healths)
|
||||
src.client.screen |= src.healths
|
||||
if(src.internals)
|
||||
src.client.screen |= src.internals
|
||||
if(src.gun_setting_icon)
|
||||
src.client.screen |= src.gun_setting_icon
|
||||
|
||||
src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
|
||||
src.client.screen += src.zone_sel //This one is a special snowflake
|
||||
|
||||
hud_used.hidden_inventory_update()
|
||||
hud_used.persistant_inventory_update()
|
||||
update_action_buttons()
|
||||
else
|
||||
usr << "\red Inventory hiding is currently only supported for human mobs, sorry."
|
||||
else
|
||||
if(!hud_used)
|
||||
usr << "\red This mob type does not use a HUD."
|
||||
return
|
||||
|
||||
if(!ishuman(src))
|
||||
usr << "\red Inventory hiding is currently only supported for human mobs, sorry."
|
||||
return
|
||||
|
||||
if(!client) return
|
||||
if(client.view != world.view)
|
||||
return
|
||||
if(hud_used.hud_shown)
|
||||
hud_used.hud_shown = 0
|
||||
if(src.hud_used.adding)
|
||||
src.client.screen -= src.hud_used.adding
|
||||
if(src.hud_used.other)
|
||||
src.client.screen -= src.hud_used.other
|
||||
if(src.hud_used.hotkeybuttons)
|
||||
src.client.screen -= src.hud_used.hotkeybuttons
|
||||
if(src.hud_used.item_action_list)
|
||||
src.client.screen -= src.hud_used.item_action_list
|
||||
|
||||
//Due to some poor coding some things need special treatment:
|
||||
//These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay
|
||||
if(!full)
|
||||
src.client.screen += src.hud_used.l_hand_hud_object //we want the hands to be visible
|
||||
src.client.screen += src.hud_used.r_hand_hud_object //we want the hands to be visible
|
||||
src.client.screen += src.hud_used.action_intent //we want the intent swticher visible
|
||||
src.hud_used.action_intent.screen_loc = ui_acti_alt //move this to the alternative position, where zone_select usually is.
|
||||
else
|
||||
src.client.screen -= src.healths
|
||||
src.client.screen -= src.internals
|
||||
src.client.screen -= src.gun_setting_icon
|
||||
|
||||
//These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone.
|
||||
src.client.screen -= src.zone_sel //zone_sel is a mob variable for some reason.
|
||||
|
||||
else
|
||||
hud_used.hud_shown = 1
|
||||
if(src.hud_used.adding)
|
||||
src.client.screen += src.hud_used.adding
|
||||
if(src.hud_used.other && src.hud_used.inventory_shown)
|
||||
src.client.screen += src.hud_used.other
|
||||
if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden)
|
||||
src.client.screen += src.hud_used.hotkeybuttons
|
||||
if(src.healths)
|
||||
src.client.screen |= src.healths
|
||||
if(src.internals)
|
||||
src.client.screen |= src.internals
|
||||
if(src.gun_setting_icon)
|
||||
src.client.screen |= src.gun_setting_icon
|
||||
|
||||
src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
|
||||
src.client.screen += src.zone_sel //This one is a special snowflake
|
||||
|
||||
hud_used.hidden_inventory_update()
|
||||
hud_used.persistant_inventory_update()
|
||||
update_action_buttons()
|
||||
|
||||
//Similar to button_pressed_F12() but keeps zone_sel, gun_setting_icon, and healths.
|
||||
/mob/proc/toggle_zoom_hud()
|
||||
if(!hud_used)
|
||||
return
|
||||
if(!ishuman(src))
|
||||
return
|
||||
if(!client)
|
||||
return
|
||||
if(client.view != world.view)
|
||||
return
|
||||
|
||||
if(hud_used.hud_shown)
|
||||
hud_used.hud_shown = 0
|
||||
if(src.hud_used.adding)
|
||||
src.client.screen -= src.hud_used.adding
|
||||
if(src.hud_used.other)
|
||||
src.client.screen -= src.hud_used.other
|
||||
if(src.hud_used.hotkeybuttons)
|
||||
src.client.screen -= src.hud_used.hotkeybuttons
|
||||
if(src.hud_used.item_action_list)
|
||||
src.client.screen -= src.hud_used.item_action_list
|
||||
src.client.screen -= src.internals
|
||||
else
|
||||
hud_used.hud_shown = 1
|
||||
if(src.hud_used.adding)
|
||||
src.client.screen += src.hud_used.adding
|
||||
if(src.hud_used.other && src.hud_used.inventory_shown)
|
||||
src.client.screen += src.hud_used.other
|
||||
if(src.hud_used.hotkeybuttons && !src.hud_used.hotkey_ui_hidden)
|
||||
src.client.screen += src.hud_used.hotkeybuttons
|
||||
if(src.internals)
|
||||
src.client.screen |= src.internals
|
||||
src.hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position
|
||||
|
||||
hud_used.hidden_inventory_update()
|
||||
hud_used.persistant_inventory_update()
|
||||
update_action_buttons()
|
||||
@@ -182,6 +182,8 @@
|
||||
var/dooc_allowed = 1
|
||||
var/dsay_allowed = 1
|
||||
|
||||
var/starlight = 0 // Whether space turfs have ambient light or not
|
||||
|
||||
/datum/configuration/New()
|
||||
var/list/L = typesof(/datum/game_mode) - /datum/game_mode
|
||||
for (var/T in L)
|
||||
@@ -603,6 +605,9 @@
|
||||
config.event_delay_upper[EVENT_LEVEL_MODERATE] = MinutesToTicks(values[2])
|
||||
config.event_delay_upper[EVENT_LEVEL_MAJOR] = MinutesToTicks(values[3])
|
||||
|
||||
if("starlight")
|
||||
config.starlight = 1
|
||||
|
||||
else
|
||||
log_misc("Unknown setting in configuration: '[name]'")
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ datum/controller/game_controller
|
||||
var/powernets_cost = 0
|
||||
var/nano_cost = 0
|
||||
var/events_cost = 0
|
||||
var/alarms_cost = 0
|
||||
var/ticker_cost = 0
|
||||
var/total_cost = 0
|
||||
|
||||
@@ -231,6 +232,11 @@ datum/controller/game_controller/proc/process()
|
||||
process_events()
|
||||
events_cost = (world.timeofday - timer) / 10
|
||||
|
||||
//ALARMS
|
||||
timer = world.timeofday
|
||||
process_alarms()
|
||||
alarms_cost = (world.timeofday - timer) / 10
|
||||
|
||||
//TICKER
|
||||
timer = world.timeofday
|
||||
last_thing_processed = ticker.type
|
||||
@@ -238,7 +244,7 @@ datum/controller/game_controller/proc/process()
|
||||
ticker_cost = (world.timeofday - timer) / 10
|
||||
|
||||
//TIMING
|
||||
total_cost = air_cost + sun_cost + mobs_cost + diseases_cost + machines_cost + objects_cost + networks_cost + powernets_cost + nano_cost + events_cost + ticker_cost
|
||||
total_cost = air_cost + sun_cost + mobs_cost + diseases_cost + machines_cost + objects_cost + networks_cost + powernets_cost + nano_cost + events_cost + alarms_cost + ticker_cost
|
||||
|
||||
var/end_time = world.timeofday
|
||||
if(end_time < start_time) //why not just use world.time instead?
|
||||
@@ -334,9 +340,13 @@ datum/controller/game_controller/proc/process_nano()
|
||||
nanomanager.processing_uis.Cut(i,i+1)
|
||||
|
||||
datum/controller/game_controller/proc/process_events()
|
||||
last_thing_processed = /datum/event
|
||||
last_thing_processed = /datum/event_manager
|
||||
event_manager.process()
|
||||
|
||||
datum/controller/game_controller/proc/process_alarms()
|
||||
last_thing_processed = /datum/subsystem/alarm
|
||||
alarm_manager.fire()
|
||||
|
||||
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)
|
||||
|
||||
33
code/controllers/subsystem/alarms.dm
Normal file
@@ -0,0 +1,33 @@
|
||||
// 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/stat_entry()
|
||||
stat(null,"Alarm-[master_controller.alarms_cost]\t#[number_of_active_alarms()]")
|
||||
|
||||
/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
|
||||
46
code/controllers/subsystems.dm
Normal file
@@ -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()
|
||||
@@ -56,7 +56,7 @@
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
return
|
||||
|
||||
/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants"))
|
||||
/client/proc/debug_controller(controller in list("Master","Failsafe","Ticker","Lighting","Air","Jobs","Sun","Radio","Supply","Shuttles","Emergency Shuttle","Configuration","pAI", "Cameras", "Transfer Controller", "Gas Data","Event","Plants","Alarm"))
|
||||
set category = "Debug"
|
||||
set name = "Debug Controller"
|
||||
set desc = "Debug the various periodic loop controllers for the game (be careful!)"
|
||||
@@ -117,5 +117,8 @@
|
||||
if("Plants")
|
||||
debug_variables(plant_controller)
|
||||
feedback_add_details("admin_verb", "DPlants")
|
||||
if("Alarm")
|
||||
debug_variables(alarm_manager)
|
||||
feedback_add_details("admin_verb", "DAlarm")
|
||||
message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
|
||||
return
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
This is what is supplied to the examine tab. Everything has a 'descriptions' variable, which is null by default. When it is not null,
|
||||
it contains this datum. To add this datum to something, all you do is add this to the thing..
|
||||
|
||||
descriptions = new/datum/descriptions("I am some helpful blue text","I have backstory text about this obj.","You can use this to kill everyone.")
|
||||
|
||||
First string is the 'info' var, second is the 'fluff' var, and third is the 'antag' var. All are optional. Just add it to the object you want to have it.
|
||||
|
||||
If you are wondering, BYOND does not let you do desc = new/datum/descriptions .
|
||||
|
||||
More strings can be added easily, but you will need to add a proc to retrieve it from the atom. The procs are defined in atoms.dm.
|
||||
|
||||
*/
|
||||
/datum/descriptions
|
||||
var/info
|
||||
var/fluff
|
||||
var/antag
|
||||
|
||||
/datum/descriptions/New(var/info, var/fluff, var/antag)
|
||||
src.info = info
|
||||
src.fluff = fluff
|
||||
src.antag = antag
|
||||
@@ -46,7 +46,7 @@ var/const/AALARM_WIRE_AALARM = 16
|
||||
//world << "Syphon Wire Cut"
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
if (A.alarm_area.atmosalert(2))
|
||||
if (A.alarm_area.atmosalert(2, A))
|
||||
A.post_alert(2)
|
||||
A.update_icon()
|
||||
|
||||
@@ -88,6 +88,6 @@ var/const/AALARM_WIRE_AALARM = 16
|
||||
|
||||
if(AALARM_WIRE_AALARM)
|
||||
// world << "Aalarm wire pulsed"
|
||||
if (A.alarm_area.atmosalert(0))
|
||||
if (A.alarm_area.atmosalert(0, A))
|
||||
A.post_alert(0)
|
||||
A.update_icon()
|
||||
|
||||
@@ -110,7 +110,13 @@ var/list/ghostteleportlocs = list()
|
||||
power_environ = 0
|
||||
ambience = list('sound/ambience/ambispace.ogg','sound/music/title2.ogg','sound/music/space.ogg','sound/music/main.ogg','sound/music/traitor.ogg')
|
||||
|
||||
/area/space/firealert()
|
||||
area/space/atmosalert()
|
||||
return
|
||||
|
||||
/area/space/fire_alert()
|
||||
return
|
||||
|
||||
/area/space/fire_reset()
|
||||
return
|
||||
|
||||
/area/space/readyalert()
|
||||
@@ -633,7 +639,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/prison/cell_block/C
|
||||
name = "Prison Cell Block C"
|
||||
icon_state = "brig"
|
||||
|
||||
|
||||
////////////////////
|
||||
//SPACE STATION 13//
|
||||
////////////////////
|
||||
@@ -1070,7 +1076,7 @@ var/list/ghostteleportlocs = list()
|
||||
name = "\improper Engineering"
|
||||
icon_state = "engineering"
|
||||
ambience = list('sound/ambience/ambisin1.ogg','sound/ambience/ambisin2.ogg','sound/ambience/ambisin3.ogg','sound/ambience/ambisin4.ogg')
|
||||
|
||||
|
||||
/area/engineering/atmos
|
||||
name = "\improper Atmospherics"
|
||||
icon_state = "atmos"
|
||||
@@ -1082,7 +1088,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/engineering/atmos/storage
|
||||
name = "\improper Atmospherics Storage"
|
||||
icon_state = "atmos_storage"
|
||||
|
||||
|
||||
/area/engineering/drone_fabrication
|
||||
name = "\improper Drone Fabrication"
|
||||
icon_state = "drone_fab"
|
||||
@@ -1130,7 +1136,7 @@ var/list/ghostteleportlocs = list()
|
||||
/area/engineering/locker_room
|
||||
name = "\improper Engineering Locker Room"
|
||||
icon_state = "engineering_locker"
|
||||
|
||||
|
||||
/area/engineering/workshop
|
||||
name = "\improper Engineering Workshop"
|
||||
icon_state = "engineering_workshop"
|
||||
|
||||
@@ -30,37 +30,14 @@
|
||||
power_change() // all machines set to current power level, also updates lighting icon
|
||||
InitializeLighting()
|
||||
|
||||
/area/proc/get_cameras()
|
||||
var/list/cameras = list()
|
||||
for (var/area/RA in related)
|
||||
for (var/obj/machinery/camera/C in RA)
|
||||
cameras += C
|
||||
return cameras
|
||||
|
||||
/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/area/RA in related)
|
||||
for (var/obj/machinery/camera/C in RA)
|
||||
cameras += C
|
||||
if(state == 1)
|
||||
C.network.Remove("Power Alarms")
|
||||
else
|
||||
C.network.Add("Power Alarms")
|
||||
for (var/mob/living/silicon/aiPlayer in player_list)
|
||||
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(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/set_firelocks=1)
|
||||
// if(type==/area) //No atmos alarms in space
|
||||
// return 0 //redudant
|
||||
|
||||
/area/proc/atmosalert(danger_level, var/alarm_source)
|
||||
//Check all the alarms before lowering atmosalm. Raising is perfectly fine.
|
||||
for (var/area/RA in related)
|
||||
for (var/obj/machinery/alarm/AA in RA)
|
||||
@@ -68,32 +45,16 @@
|
||||
danger_level = max(danger_level, AA.danger_level)
|
||||
|
||||
if(danger_level != atmosalm)
|
||||
if (set_firelocks && danger_level < 1 && atmosalm >= 1)
|
||||
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()
|
||||
|
||||
if (danger_level < 2 && atmosalm >= 2)
|
||||
for(var/area/RA in related)
|
||||
for(var/obj/machinery/camera/C in RA)
|
||||
C.network.Remove("Atmosphere Alarms")
|
||||
for(var/mob/living/silicon/aiPlayer in player_list)
|
||||
aiPlayer.cancelAlarm("Atmosphere", src, src)
|
||||
for(var/obj/machinery/computer/station_alert/a in machines)
|
||||
a.cancelAlarm("Atmosphere", src, src)
|
||||
|
||||
if (danger_level >= 2 && atmosalm < 2)
|
||||
var/list/cameras = list()
|
||||
for(var/area/RA in related)
|
||||
//updateicon()
|
||||
for(var/obj/machinery/camera/C in RA)
|
||||
cameras += C
|
||||
C.network.Add("Atmosphere Alarms")
|
||||
for(var/mob/living/silicon/aiPlayer in player_list)
|
||||
aiPlayer.triggerAlarm("Atmosphere", src, cameras, src)
|
||||
for(var/obj/machinery/computer/station_alert/a in machines)
|
||||
a.triggerAlarm("Atmosphere", src, cameras, src)
|
||||
if (set_firelocks)
|
||||
air_doors_close()
|
||||
if (danger_level == 0)
|
||||
atmosphere_alarm.clearAlarm(master, alarm_source)
|
||||
else
|
||||
atmosphere_alarm.triggerAlarm(master, alarm_source, severity = danger_level)
|
||||
|
||||
atmosalm = danger_level
|
||||
for(var/area/RA in related)
|
||||
@@ -107,9 +68,9 @@
|
||||
if(!src.master.air_doors_activated)
|
||||
src.master.air_doors_activated = 1
|
||||
for(var/obj/machinery/door/firedoor/E in src.master.all_doors)
|
||||
if(!E:blocked)
|
||||
if(!E.blocked)
|
||||
if(E.operating)
|
||||
E:nextstate = CLOSED
|
||||
E.nextstate = CLOSED
|
||||
else if(!E.density)
|
||||
spawn(0)
|
||||
E.close()
|
||||
@@ -118,21 +79,21 @@
|
||||
if(src.master.air_doors_activated)
|
||||
src.master.air_doors_activated = 0
|
||||
for(var/obj/machinery/door/firedoor/E in src.master.all_doors)
|
||||
if(!E:blocked)
|
||||
if(!E.blocked)
|
||||
if(E.operating)
|
||||
E:nextstate = OPEN
|
||||
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
|
||||
master.fire = 1 //used for firedoor checks
|
||||
updateicon()
|
||||
/area/proc/fire_alert()
|
||||
if(!fire)
|
||||
master.fire = 1 //used for firedoor checks
|
||||
master.updateicon()
|
||||
for(var/area/A in related)
|
||||
A.fire = 1
|
||||
A.updateicon()
|
||||
mouse_opacity = 0
|
||||
for(var/obj/machinery/door/firedoor/D in all_doors)
|
||||
if(!D.blocked)
|
||||
@@ -141,22 +102,15 @@
|
||||
else if(!D.density)
|
||||
spawn()
|
||||
D.close()
|
||||
var/list/cameras = list()
|
||||
for(var/area/RA in related)
|
||||
for (var/obj/machinery/camera/C in RA)
|
||||
cameras.Add(C)
|
||||
C.network.Add("Fire Alarms")
|
||||
for (var/mob/living/silicon/ai/aiPlayer in player_list)
|
||||
aiPlayer.triggerAlarm("Fire", src, cameras, src)
|
||||
for (var/obj/machinery/computer/station_alert/a in machines)
|
||||
a.triggerAlarm("Fire", src, cameras, src)
|
||||
|
||||
/area/proc/firereset()
|
||||
/area/proc/fire_reset()
|
||||
if (fire)
|
||||
fire = 0
|
||||
master.fire = 0 //used for firedoor checks
|
||||
master.fire = 0 //used for firedoor checks
|
||||
master.updateicon()
|
||||
for(var/area/A in related)
|
||||
A.fire = 0
|
||||
A.updateicon()
|
||||
mouse_opacity = 0
|
||||
updateicon()
|
||||
for(var/obj/machinery/door/firedoor/D in all_doors)
|
||||
if(!D.blocked)
|
||||
if(D.operating)
|
||||
@@ -164,13 +118,6 @@
|
||||
else if(D.density)
|
||||
spawn(0)
|
||||
D.open()
|
||||
for(var/area/RA in related)
|
||||
for (var/obj/machinery/camera/C in RA)
|
||||
C.network.Remove("Fire Alarms")
|
||||
for (var/mob/living/silicon/ai/aiPlayer in player_list)
|
||||
aiPlayer.cancelAlarm("Fire", src, src)
|
||||
for (var/obj/machinery/computer/station_alert/a in machines)
|
||||
a.cancelAlarm("Fire", src, src)
|
||||
|
||||
/area/proc/readyalert()
|
||||
if(!eject)
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
var/throwpass = 0
|
||||
var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
|
||||
|
||||
//Examine tab
|
||||
var/datum/descriptions/descriptions = null //See code/datums/descriptions.dm for details.
|
||||
|
||||
///Chemistry.
|
||||
var/datum/reagents/reagents = null
|
||||
|
||||
@@ -205,47 +202,8 @@ its easier to just keep the beam vertical.
|
||||
|
||||
user << "\icon[src] That's [f_name] [suffix]"
|
||||
|
||||
var/datum/descriptions/D = descriptions
|
||||
if(istype(D))
|
||||
user.description_holders["info"] = get_descriptions_info()
|
||||
user.description_holders["fluff"] = get_descriptions_fluff()
|
||||
if(user.mind.special_role)
|
||||
user.description_holders["antag"] = get_descriptions_antag()
|
||||
else
|
||||
user.description_holders["info"] = null
|
||||
user.description_holders["fluff"] = null
|
||||
user.description_holders["antag"] = null
|
||||
|
||||
if(name) //This shouldn't be needed but I'm paranoid.
|
||||
user.description_holders["name"] = "[src.name]" //\icon[src]
|
||||
|
||||
user.description_holders["icon"] = "\icon[src]"
|
||||
|
||||
if(desc)
|
||||
user << desc
|
||||
user.description_holders["desc"] = src.desc
|
||||
else
|
||||
user.description_holders["desc"] = null //This is needed, or else if you examine one thing with a desc, then another without, the panel will retain the first examined's desc.
|
||||
|
||||
return distance == -1 || (get_dist(src, user) <= distance)
|
||||
|
||||
//Override these if you need special behaviour for a specific type.
|
||||
|
||||
/atom/proc/get_descriptions_info()
|
||||
if(descriptions && descriptions.info)
|
||||
return descriptions.info
|
||||
return
|
||||
|
||||
/atom/proc/get_descriptions_fluff()
|
||||
if(descriptions && descriptions.fluff)
|
||||
return descriptions.fluff
|
||||
return
|
||||
|
||||
/atom/proc/get_descriptions_antag()
|
||||
if(descriptions && descriptions.antag)
|
||||
return descriptions.antag
|
||||
return
|
||||
|
||||
// called by mobs when e.g. having the atom as their machine, pulledby, loc (AKA mob being inside the atom) or buckled var set.
|
||||
// see code/modules/mob/mob_movement.dm for more.
|
||||
/atom/proc/relaymove()
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
recommended_enemies = 4
|
||||
|
||||
uplink_welcome = "Nar-Sie Uplink Console:"
|
||||
uplink_uses = 10
|
||||
|
||||
var/datum/mind/sacrifice_target = null
|
||||
var/finished = 0
|
||||
|
||||
@@ -30,30 +30,37 @@
|
||||
var/newscaster_announcements = null
|
||||
var/ert_disabled = 0
|
||||
var/uplink_welcome = "Illegal Uplink Console:"
|
||||
var/uplink_uses = 10
|
||||
var/uplink_uses = 12
|
||||
var/list/datum/uplink_item/uplink_items = list(
|
||||
"Ammunition" = list(
|
||||
new/datum/uplink_item(/obj/item/ammo_magazine/a357, 2, ".357", "RA"),
|
||||
new/datum/uplink_item(/obj/item/ammo_magazine/mc9mm, 2, "9mm", "R9"),
|
||||
new/datum/uplink_item(/obj/item/ammo_magazine/chemdart, 2, "Darts", "AD"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/sniperammo, 3, "14.5mm", "RA")
|
||||
),
|
||||
"Highly Visible and Dangerous Weapons" = list(
|
||||
new/datum/uplink_item(/obj/item/ammo_magazine/mc9mm, 2, "Ammo-9mm", "R9"),
|
||||
new/datum/uplink_item(/obj/item/ammo_magazine/a357, 2, "Ammo-357", "RA"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/emps, 3, "5 EMP Grenades", "EM"),
|
||||
new/datum/uplink_item(/obj/item/weapon/melee/energy/sword, 4, "Energy Sword", "ES"),
|
||||
new/datum/uplink_item(/obj/item/weapon/gun/projectile/dartgun, 5, "Dart Gun", "DG"),
|
||||
new/datum/uplink_item(/obj/item/weapon/gun/energy/crossbow, 5, "Energy Crossbow", "XB"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/g9mm, 5, "Silenced 9mm", "S9"),
|
||||
new/datum/uplink_item(/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser, 6, "Exosuit Rigged Laser", "RL"),
|
||||
new/datum/uplink_item(/obj/item/weapon/gun/projectile/revolver, 6, "Revolver", "RE"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndicate, 10, "Mercenary Bundle", "BU")
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndicate, 10, "Mercenary Bundle", "BU"),
|
||||
new/datum/uplink_item(/obj/item/weapon/gun/projectile/heavysniper, 12, "PTRS Rifle", "BU")
|
||||
),
|
||||
"Stealthy and Inconspicuous Weapons" = list(
|
||||
new/datum/uplink_item(/obj/item/weapon/soap/syndie, 1, "Subversive Soap", "SP"),
|
||||
new/datum/uplink_item(/obj/item/weapon/cane/concealed, 2, "Concealed Cane Sword", "CC"),
|
||||
new/datum/uplink_item(/obj/item/weapon/cartridge/syndicate, 3, "Detomatix PDA Cartridge", "DC"),
|
||||
new/datum/uplink_item(/obj/item/weapon/pen/paralysis, 3, "Paralysis Pen", "PP"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/cigarette, 4, "Cigarette Kit", "BH")
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/cigarette, 4, "Cigarette Kit", "BH"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/toxin, 4, "Random Toxin - Beaker", "RT")
|
||||
),
|
||||
"Stealth and Camouflage Items" = list(
|
||||
new/datum/uplink_item(/obj/item/weapon/card/id/syndicate, 2, "Agent ID card", "AC"),
|
||||
new/datum/uplink_item(/obj/item/clothing/shoes/syndigaloshes, 2, "No-Slip Shoes", "SH"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/spy, 2, "Bug Kit", "SK"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/spy, 2, "Bug Kit", "BK"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/chameleon, 3, "Chameleon Kit", "CB"),
|
||||
new/datum/uplink_item(/obj/item/device/chameleon, 4, "Chameleon-Projector", "CP"),
|
||||
new/datum/uplink_item(/obj/item/clothing/mask/gas/voice, 4, "Voice Changer", "VC"),
|
||||
@@ -62,11 +69,13 @@
|
||||
"Devices and Tools" = list(
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/toolbox/syndicate, 1, "Fully Loaded Toolbox", "ST"),
|
||||
new/datum/uplink_item(/obj/item/weapon/plastique, 2, "C-4 (Destroys walls)", "C4"),
|
||||
new/datum/uplink_item(/obj/item/device/encryptionkey/syndicate, 2, "Encrypted Radio Channel Key", "ER"),
|
||||
new/datum/uplink_item(/obj/item/device/encryptionkey/binary, 3, "Binary Translator Key", "BT"),
|
||||
new/datum/uplink_item(/obj/item/weapon/card/emag, 3, "Cryptographic Sequencer", "EC"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/clerical, 3, "Morphic Clerical Kit", "CK"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/space, 3, "Space Suit", "SS"),
|
||||
new/datum/uplink_item(/obj/item/clothing/glasses/thermal/syndi, 3, "Thermal Imaging Glasses", "TM"),
|
||||
new/datum/uplink_item(/obj/item/clothing/suit/storage/vest/heavy/merc, 4, "Heavy Armor Vest", "HAV"),
|
||||
new/datum/uplink_item(/obj/item/weapon/aiModule/syndicate, 7, "Hacked AI Upload Module", "AI"),
|
||||
new/datum/uplink_item(/obj/item/device/powersink, 5, "Powersink (DANGER!)", "PS",),
|
||||
new/datum/uplink_item(/obj/item/device/radio/beacon/syndicate, 7, "Singularity Beacon (DANGER!)", "SB"),
|
||||
@@ -78,10 +87,20 @@
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_explosive, 6, "Explosive Implant (DANGER!)", "EI"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/imp_uplink, 10, "Uplink Implant (Contains 5 Telecrystals)", "UI")
|
||||
),
|
||||
"Health Aids" = list(
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/donkpockets, 1, "Box of Donk-Pockets", "DP"),
|
||||
"Medical" = list(
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/donkpockets, 1, "Box of Sin-Pockets", "DP"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/firstaid/surgery, 5, "Surgery kit", "SK"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/firstaid/combat, 5, "Combat medical kit", "CM")
|
||||
),
|
||||
"Hardsuit Modules" = list(
|
||||
new/datum/uplink_item(/obj/item/rig_module/vision/thermal, 2, "Thermal Scanner", "RTS"),
|
||||
new/datum/uplink_item(/obj/item/rig_module/fabricator/energy_net, 3, "Net Projector", "REN"),
|
||||
new/datum/uplink_item(/obj/item/weapon/storage/box/syndie_kit/ewar_voice, 4, "Electrowarfare Suite and Voice Synthesiser", "REV"),
|
||||
new/datum/uplink_item(/obj/item/rig_module/maneuvering_jets, 4, "Maneuvering Jets", "RMJ"),
|
||||
new/datum/uplink_item(/obj/item/rig_module/mounted/egun, 6, "Mounted Energy Gun", "REG"),
|
||||
new/datum/uplink_item(/obj/item/rig_module/power_sink, 6, "Power Sink", "RPS"),
|
||||
new/datum/uplink_item(/obj/item/rig_module/mounted, 8, "Mounted Laser Cannon", "RLC")
|
||||
),
|
||||
"(Pointless) Badassery" = list(
|
||||
new/datum/uplink_item(/obj/item/toy/syndicateballoon, 10, "For showing that You Are The BOSS (Useless Balloon)", "BS"),
|
||||
new/datum/uplink_item(/obj/item/toy/nanotrasenballoon, 10, "For showing that you love NT SOO much (Useless Balloon)", "NT")
|
||||
@@ -251,16 +270,6 @@
|
||||
special_role == "Head Revolutionary" && prob(30))
|
||||
suspects += man
|
||||
|
||||
// If they're a traitor or likewise, give them extra TC in exchange.
|
||||
var/obj/item/device/uplink/hidden/suplink = man.mind.find_syndicate_uplink()
|
||||
if(suplink)
|
||||
var/extra = 4
|
||||
suplink.uses += extra
|
||||
man << "\red We have received notice that enemy intelligence suspects you to be linked with us. We have thus invested significant resources to increase your uplink's capacity."
|
||||
else
|
||||
// Give them a warning!
|
||||
man << "\red They are on to you!"
|
||||
|
||||
// Some poor people who were just in the wrong place at the wrong time..
|
||||
else if(prob(10))
|
||||
suspects += man
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
recommended_enemies = 1
|
||||
|
||||
uplink_welcome = "Crazy AI Uplink Console:"
|
||||
uplink_uses = 10
|
||||
|
||||
var/const/waittime_l = 600
|
||||
var/const/waittime_h = 1800 // started at 1800
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
votable = 0
|
||||
|
||||
uplink_welcome = "EVIL METEOR Uplink Console:"
|
||||
uplink_uses = 10
|
||||
|
||||
|
||||
/datum/game_mode/meteor/announce()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
recommended_enemies = 3
|
||||
|
||||
uplink_welcome = "AntagCorp Uplink Console:"
|
||||
uplink_uses = 5
|
||||
uplink_uses = 7
|
||||
|
||||
newscaster_announcements = /datum/news_announcement/revolution_inciting_event
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
|
||||
uplink_welcome = "AntagCorp Portable Teleportation Relay:"
|
||||
uplink_uses = 10
|
||||
|
||||
var/const/waittime_l = 600 //lower bound on time before intercept arrives (in tenths of seconds)
|
||||
var/const/waittime_h = 1800 //upper bound on time before intercept arrives (in tenths of seconds)
|
||||
|
||||
@@ -117,19 +117,6 @@
|
||||
|
||||
first_run()
|
||||
|
||||
/obj/machinery/alarm/Del()
|
||||
//If there's an active alarm, clear it after minute so that alarms don't keep going forver
|
||||
delayed_reset()
|
||||
..()
|
||||
|
||||
//needed to cancel the alarm after it is deleted
|
||||
/obj/machinery/alarm/proc/delayed_reset()
|
||||
var/area/A = alarm_area
|
||||
src = null
|
||||
spawn(600)
|
||||
//It makes sense not to touch firelocks here. The alarm itself is gone, we have no idea what the atmos is like.
|
||||
A.atmosalert(0, set_firelocks=0)
|
||||
|
||||
/obj/machinery/alarm/proc/first_run()
|
||||
alarm_area = get_area(src)
|
||||
if (alarm_area.master)
|
||||
@@ -441,7 +428,7 @@
|
||||
send_signal(device_id, list("power"= 0) )
|
||||
|
||||
/obj/machinery/alarm/proc/apply_danger_level(var/new_danger_level)
|
||||
if (report_danger_level && alarm_area.atmosalert(new_danger_level))
|
||||
if (report_danger_level && alarm_area.atmosalert(new_danger_level, src))
|
||||
post_alert(new_danger_level)
|
||||
|
||||
update_icon()
|
||||
@@ -769,13 +756,13 @@
|
||||
return 1
|
||||
|
||||
if(href_list["atmos_alarm"])
|
||||
if (alarm_area.atmosalert(2))
|
||||
if (alarm_area.atmosalert(2, src))
|
||||
apply_danger_level(2)
|
||||
update_icon()
|
||||
return 1
|
||||
|
||||
if(href_list["atmos_reset"])
|
||||
if (alarm_area.atmosalert(0))
|
||||
if (alarm_area.atmosalert(0, src))
|
||||
apply_danger_level(0)
|
||||
update_icon()
|
||||
return 1
|
||||
@@ -947,7 +934,6 @@ FIRE ALARM
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
|
||||
/obj/machinery/firealarm/update_icon()
|
||||
|
||||
if(wiresexposed)
|
||||
switch(buildstage)
|
||||
if(2)
|
||||
@@ -981,7 +967,8 @@ FIRE ALARM
|
||||
return src.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)
|
||||
@@ -1080,6 +1067,7 @@ FIRE ALARM
|
||||
var/d2
|
||||
if (istype(user, /mob/living/carbon/human) || istype(user, /mob/living/silicon))
|
||||
A = A.loc
|
||||
A = A.master
|
||||
|
||||
if (A.fire)
|
||||
d1 = text("<A href='?src=\ref[];reset=1'>Reset - Lockdown</A>", src)
|
||||
@@ -1145,26 +1133,26 @@ 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()
|
||||
var/area/area = get_area(src)
|
||||
for(var/area/A in area.related)
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
fire_alarm.clearAlarm(loc, FA)
|
||||
update_icon()
|
||||
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/area = get_area(src)
|
||||
for(var/area/A in area.related)
|
||||
for(var/obj/machinery/firealarm/FA in A)
|
||||
fire_alarm.triggerAlarm(loc, FA, duration)
|
||||
update_icon()
|
||||
//playsound(src.loc, 'sound/ambience/signal.ogg', 75, 0)
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/machinery/firealarm/New(loc, dir, building)
|
||||
..()
|
||||
|
||||
@@ -1180,20 +1168,6 @@ FIRE ALARM
|
||||
pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24)
|
||||
pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0
|
||||
|
||||
/obj/machinery/firealarm/Del()
|
||||
//so fire alarms don't keep going forever
|
||||
delayed_reset()
|
||||
..()
|
||||
|
||||
//needed to cancel the alarm after it is deleted
|
||||
/obj/machinery/firealarm/proc/delayed_reset()
|
||||
var/area/A = get_area(src)
|
||||
if (!A) return
|
||||
|
||||
src = null
|
||||
spawn(600)
|
||||
A.firereset()
|
||||
|
||||
/obj/machinery/firealarm/initialize()
|
||||
if(z in config.contact_levels)
|
||||
if(security_level)
|
||||
|
||||
@@ -53,13 +53,6 @@
|
||||
ASSERT(src.network.len > 0)
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
if(!alarm_on)
|
||||
triggerCameraAlarm()
|
||||
|
||||
cancelCameraAlarm()
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/emp_act(severity)
|
||||
if(!isEmpProof())
|
||||
if(prob(100/severity))
|
||||
@@ -67,7 +60,7 @@
|
||||
stat |= EMPED
|
||||
SetLuminosity(0)
|
||||
kick_viewers()
|
||||
triggerCameraAlarm()
|
||||
triggerCameraAlarm(10 * severity)
|
||||
update_icon()
|
||||
|
||||
spawn(900)
|
||||
@@ -261,22 +254,16 @@
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/machinery/camera/proc/triggerCameraAlarm()
|
||||
/obj/machinery/camera/proc/triggerCameraAlarm(var/duration = 0)
|
||||
alarm_on = 1
|
||||
if(!get_area(src))
|
||||
return
|
||||
|
||||
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()
|
||||
alarm_on = 0
|
||||
if(!get_area(src))
|
||||
if(wires.IsIndexCut(CAMERA_WIRE_ALARM))
|
||||
return
|
||||
|
||||
for(var/mob/living/silicon/S in mob_list)
|
||||
S.cancelAlarm("Camera", get_area(src), src)
|
||||
alarm_on = 0
|
||||
camera_alarm.clearAlarm(loc, src)
|
||||
|
||||
//if false, then the camera is listed as DEACTIVATED and cannot be used
|
||||
/obj/machinery/camera/proc/can_use()
|
||||
@@ -361,3 +348,13 @@
|
||||
|
||||
user.set_machine(src)
|
||||
wires.Interact(user)
|
||||
|
||||
/obj/machinery/camera/proc/nano_structure()
|
||||
var/cam[0]
|
||||
cam["name"] = sanitize(c_tag)
|
||||
cam["deact"] = !can_use()
|
||||
cam["camera"] = "\ref[src]"
|
||||
cam["x"] = x
|
||||
cam["y"] = y
|
||||
cam["z"] = z
|
||||
return cam
|
||||
|
||||
@@ -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,116 +1,85 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
|
||||
|
||||
// Converting these to global lists may be a bit laggy when removal procs are called. Consider
|
||||
// rewriting this properly to fix the update bug, rather than unifying all monitors. ~Z
|
||||
|
||||
var/global/list/priority_air_alarms = list()
|
||||
var/global/list/minor_air_alarms = list()
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert
|
||||
name = "atmospheric alert computer"
|
||||
desc = "Used to access the station's atmospheric sensors."
|
||||
circuit = "/obj/item/weapon/circuitboard/atmos_alert"
|
||||
icon_state = "alert:0"
|
||||
var/receive_frequency = 1437
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
|
||||
/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"]
|
||||
|
||||
if(!zone || !severity) return
|
||||
|
||||
minor_air_alarms -= zone
|
||||
priority_air_alarms -= zone
|
||||
if(severity=="severe")
|
||||
priority_air_alarms |= zone
|
||||
else if (severity=="minor")
|
||||
minor_air_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/Del()
|
||||
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_air_alarms.len)
|
||||
var/list/alarms = atmosphere_alarm.major_alarms()
|
||||
if(alarms.len)
|
||||
icon_state = "alert:2"
|
||||
|
||||
else if(minor_air_alarms.len)
|
||||
icon_state = "alert:1"
|
||||
|
||||
else
|
||||
icon_state = "alert:0"
|
||||
alarms = atmosphere_alarm.minor_alarms()
|
||||
if(alarms.len)
|
||||
icon_state = "alert:1"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
return
|
||||
|
||||
|
||||
/obj/machinery/computer/atmos_alert/proc/return_text()
|
||||
var/priority_text
|
||||
var/minor_text
|
||||
|
||||
if(priority_air_alarms.len)
|
||||
for(var/zone in priority_air_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_air_alarms.len)
|
||||
for(var/zone in minor_air_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
|
||||
return 1
|
||||
|
||||
if(href_list["priority_clear"])
|
||||
var/removing_zone = href_list["priority_clear"]
|
||||
for(var/zone in priority_air_alarms)
|
||||
if(ckey(zone) == removing_zone)
|
||||
priority_air_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, custom_state = atmos_alert_topic)
|
||||
return 1
|
||||
|
||||
if(href_list["minor_clear"])
|
||||
var/removing_zone = href_list["minor_clear"]
|
||||
for(var/zone in minor_air_alarms)
|
||||
if(ckey(zone) == removing_zone)
|
||||
minor_air_alarms -= zone
|
||||
update_icon()
|
||||
return
|
||||
|
||||
var/datum/topic_state/atmos_alert/atmos_alert_topic = new()
|
||||
|
||||
/datum/topic_state/atmos_alert
|
||||
flags = NANO_IGNORE_DISTANCE
|
||||
|
||||
/datum/topic_state/air_alarm/href_list(var/mob/user)
|
||||
var/list/extra_href = list()
|
||||
extra_href["remote_connection"] = 1
|
||||
extra_href["remote_access"] = 1
|
||||
|
||||
return extra_href
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
/proc/invalidateCameraCache()
|
||||
for(var/obj/machinery/computer/security/s in world)
|
||||
s.camera_cache = null
|
||||
for(var/datum/alarm/A in world)
|
||||
A.cameras = null
|
||||
|
||||
/obj/machinery/computer/security
|
||||
name = "security camera monitor"
|
||||
@@ -43,33 +45,17 @@
|
||||
if(!can_access_camera(C))
|
||||
continue
|
||||
|
||||
var/cam[0]
|
||||
cam["name"] = sanitize(C.c_tag)
|
||||
cam["deact"] = !C.can_use()
|
||||
cam["camera"] = "\ref[C]"
|
||||
cam["x"] = C.x
|
||||
cam["y"] = C.y
|
||||
cam["z"] = C.z
|
||||
|
||||
var/cam = C.nano_structure()
|
||||
cameras[++cameras.len] = cam
|
||||
|
||||
if(C == current)
|
||||
data["current"] = cam
|
||||
|
||||
var/list/camera_list = list("cameras" = cameras)
|
||||
camera_cache=list2json(camera_list)
|
||||
|
||||
var/list/camera_list = list("cameras" = cameras)
|
||||
camera_cache=list2json(camera_list)
|
||||
else
|
||||
if(current)
|
||||
var/cam[0]
|
||||
cam["name"] = current.c_tag
|
||||
cam["deact"] = !current.can_use()
|
||||
cam["camera"] = "\ref[current]"
|
||||
cam["x"] = current.x
|
||||
cam["y"] = current.y
|
||||
cam["z"] = current.z
|
||||
|
||||
data["current"] = cam
|
||||
data["current"] = current.nano_structure()
|
||||
|
||||
|
||||
if(ui)
|
||||
|
||||
@@ -5,106 +5,42 @@
|
||||
icon_state = "alert:0"
|
||||
circuit = "/obj/item/weapon/circuitboard/stationalert"
|
||||
var/alarms = list("Fire"=list(), "Atmosphere"=list(), "Power"=list())
|
||||
var/obj/nano_module/alarm_monitor/engineering/alarm_monitor
|
||||
|
||||
/obj/machinery/computer/station_alert/New()
|
||||
..()
|
||||
alarm_monitor = new(src)
|
||||
alarm_monitor.register(src, /obj/machinery/computer/station_alert/update_icon)
|
||||
|
||||
attack_ai(mob/user)
|
||||
add_fingerprint(user)
|
||||
if(stat & (BROKEN|NOPOWER))
|
||||
return
|
||||
interact(user)
|
||||
/obj/machinery/computer/station_alert/Del()
|
||||
alarm_monitor.unregister(src)
|
||||
..()
|
||||
|
||||
/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]
|
||||
dat += "<NOBR>"
|
||||
dat += "• "
|
||||
dat += "[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"
|
||||
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_state = "atmos0"
|
||||
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)
|
||||
icon_state = "alert:2"
|
||||
else
|
||||
icon_state = "alert:0"
|
||||
..()
|
||||
return
|
||||
var/list/alarms = alarm_monitor.active_alarms()
|
||||
if(alarms.len)
|
||||
icon_state = "alert:2"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
return
|
||||
|
||||
@@ -250,6 +250,9 @@
|
||||
target = safepick(view(3,target))
|
||||
if(!target)
|
||||
return
|
||||
if(istype(target, /obj/machinery))
|
||||
if (src.interface_action(target))
|
||||
return
|
||||
if(!target.Adjacent(src))
|
||||
if(selected && selected.is_ranged())
|
||||
selected.action(target)
|
||||
@@ -259,6 +262,29 @@
|
||||
src.melee_action(target)
|
||||
return
|
||||
|
||||
/obj/mecha/proc/interface_action(obj/machinery/target)
|
||||
if(istype(target, /obj/machinery/access_button))
|
||||
src.occupant_message("<span class='notice'>Interfacing with [target].</span>")
|
||||
src.log_message("Interfaced with [target].")
|
||||
target.attack_hand(src.occupant)
|
||||
return 1
|
||||
if(istype(target, /obj/machinery/embedded_controller))
|
||||
target.ui_interact(src.occupant)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/mecha/contents_nano_distance(var/src_object, var/mob/living/user)
|
||||
. = user.shared_living_nano_distance(src_object) //allow them to interact with anything they can interact with normally.
|
||||
if(. != STATUS_INTERACTIVE)
|
||||
//Allow interaction with the mecha or anything that is part of the mecha
|
||||
if(src_object == src || (src_object in src))
|
||||
return STATUS_INTERACTIVE
|
||||
if(src.Adjacent(src_object))
|
||||
src.occupant_message("<span class='notice'>Interfacing with [src_object]...</span>")
|
||||
src.log_message("Interfaced with [src_object].")
|
||||
return STATUS_INTERACTIVE
|
||||
if(src_object in view(2, src))
|
||||
return STATUS_UPDATE //if they're close enough, allow the occupant to see the screen through the viewport or whatever.
|
||||
|
||||
/obj/mecha/proc/melee_action(atom/target)
|
||||
return
|
||||
|
||||
@@ -198,11 +198,7 @@
|
||||
// apparently called whenever an item is removed from a slot, container, or anything else.
|
||||
/obj/item/proc/dropped(mob/user as mob)
|
||||
..()
|
||||
if(zoom) //binoculars, scope, etc
|
||||
user.client.view = world.view
|
||||
user.client.pixel_x = 0
|
||||
user.client.pixel_y = 0
|
||||
zoom = 0
|
||||
if(zoom) zoom() //binoculars, scope, etc
|
||||
|
||||
// called just as an item is picked up (loc is not yet changed)
|
||||
/obj/item/proc/pickup(mob/user)
|
||||
@@ -660,9 +656,8 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
|
||||
cannotzoom = 1
|
||||
|
||||
if(!zoom && !cannotzoom)
|
||||
if(!usr.hud_used.hud_shown)
|
||||
usr.button_pressed_F12(1) // If the user has already limited their HUD this avoids them having a HUD when they zoom in
|
||||
usr.button_pressed_F12(1)
|
||||
if(usr.hud_used.hud_shown)
|
||||
usr.toggle_zoom_hud() // If the user has already limited their HUD this avoids them having a HUD when they zoom in
|
||||
usr.client.view = viewsize
|
||||
zoom = 1
|
||||
|
||||
@@ -688,7 +683,7 @@ modules/mob/living/carbon/human/life.dm if you die, you will be zoomed out.
|
||||
else
|
||||
usr.client.view = world.view
|
||||
if(!usr.hud_used.hud_shown)
|
||||
usr.button_pressed_F12(1)
|
||||
usr.toggle_zoom_hud()
|
||||
zoom = 0
|
||||
|
||||
usr.client.pixel_x = 0
|
||||
|
||||
@@ -28,3 +28,30 @@
|
||||
new /obj/item/weapon/reagent_containers/pill/zoom( src )
|
||||
new /obj/item/weapon/reagent_containers/pill/zoom( src )
|
||||
new /obj/item/weapon/reagent_containers/pill/zoom( src )
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/random
|
||||
flags = 0
|
||||
var/list/random_reagent_list = list(list("water" = 15) = 1, list("cleaner" = 15) = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/random/toxin
|
||||
random_reagent_list = list(
|
||||
list("mindbreaker" = 10, "space_drugs" = 20) = 3,
|
||||
list("carpotoxin" = 15) = 2,
|
||||
list("impedrezene" = 15) = 2,
|
||||
list("zombiepowder" = 10) = 1)
|
||||
|
||||
/obj/item/weapon/reagent_containers/glass/beaker/vial/random/New()
|
||||
..()
|
||||
if(is_open_container())
|
||||
flags ^= OPENCONTAINER
|
||||
|
||||
var/list/picked_reagents = pickweight(random_reagent_list)
|
||||
for(var/reagent in picked_reagents)
|
||||
reagents.add_reagent(reagent, picked_reagents[reagent])
|
||||
|
||||
var/list/names = new
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
names += R.name
|
||||
|
||||
desc = "Contains [english_list(names)]."
|
||||
update_icon()
|
||||
|
||||
@@ -11,12 +11,30 @@ A list of items and costs is stored under the datum of every game mode, alongsid
|
||||
var/cost = 0
|
||||
var/path = null
|
||||
var/reference = ""
|
||||
var/description = ""
|
||||
|
||||
datum/uplink_item/New(var/itemPath, var/itemCost as num, var/itemName as text, var/itemReference as text)
|
||||
datum/uplink_item/New(var/itemPath, var/itemCost as num, var/itemName as text, var/itemReference as text, var/itemDescription)
|
||||
cost = itemCost
|
||||
path = itemPath
|
||||
name = itemName
|
||||
reference = itemReference
|
||||
description = itemDescription
|
||||
|
||||
|
||||
datum/uplink_item/proc/description()
|
||||
if(!description)
|
||||
// Fallback description
|
||||
var/obj/temp = src.path
|
||||
description = replacetext(initial(temp.desc), "\n", "<br>")
|
||||
return description
|
||||
|
||||
/datum/uplink_item/proc/generate_item(var/newloc)
|
||||
var/list/L = list()
|
||||
if(ispath(path))
|
||||
L += new path(newloc)
|
||||
else if(islist(path))
|
||||
for(var/item_path in path)
|
||||
L += new item_path(newloc)
|
||||
return L
|
||||
|
||||
datum/nano_item_lists
|
||||
var/list/items_nano
|
||||
@@ -41,16 +59,17 @@ datum/nano_item_lists
|
||||
uses = ticker.mode.uplink_uses
|
||||
ItemsCategory = ticker.mode.uplink_items
|
||||
|
||||
var/datum/nano_item_lists/IL = generate_item_lists()
|
||||
nanoui_items = IL.items_nano
|
||||
ItemsReference = IL.items_reference
|
||||
|
||||
world_uplinks += src
|
||||
|
||||
/obj/item/device/uplink/Del()
|
||||
world_uplinks -= src
|
||||
..()
|
||||
|
||||
/obj/item/device/uplink/proc/generate_items()
|
||||
var/datum/nano_item_lists/IL = generate_item_lists()
|
||||
nanoui_items = IL.items_nano
|
||||
ItemsReference = IL.items_reference
|
||||
|
||||
// BS12 no longer use this menu but there are forks that do, hency why we keep it
|
||||
/obj/item/device/uplink/proc/generate_menu()
|
||||
var/dat = "<B>[src.welcome]</B><BR>"
|
||||
@@ -87,7 +106,7 @@ datum/nano_item_lists
|
||||
for(var/category in ItemsCategory)
|
||||
nano[++nano.len] = list("Category" = category, "items" = list())
|
||||
for(var/datum/uplink_item/I in ItemsCategory[category])
|
||||
nano[nano.len]["items"] += list(list("Name" = I.name, "Cost" = I.cost, "obj_path" = I.reference))
|
||||
nano[nano.len]["items"] += list(list("Name" = I.name, "Description" = I.description(),"Cost" = I.cost, "obj_path" = I.reference))
|
||||
reference[I.reference] = I
|
||||
|
||||
var/datum/nano_item_lists/result = new
|
||||
@@ -126,10 +145,11 @@ datum/nano_item_lists
|
||||
used_TC += UI.cost
|
||||
feedback_add_details("traitor_uplink_items_bought", reference)
|
||||
|
||||
var/obj/I = new UI.path(get_turf(usr))
|
||||
var/list/L = UI.generate_item(get_turf(usr))
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/A = usr
|
||||
A.put_in_any_hand_if_possible(I)
|
||||
for(var/obj/I in L)
|
||||
A.put_in_any_hand_if_possible(I)
|
||||
|
||||
purchase_log[UI] = purchase_log[UI] + 1
|
||||
|
||||
@@ -189,6 +209,8 @@ datum/nano_item_lists
|
||||
data["welcome"] = welcome
|
||||
data["crystals"] = uses
|
||||
data["menu"] = nanoui_menu
|
||||
if(!nanoui_items)
|
||||
generate_items()
|
||||
data["nano_items"] = nanoui_items
|
||||
data += nanoui_data
|
||||
|
||||
|
||||
@@ -219,8 +219,8 @@
|
||||
new /obj/item/ammo_casing/shotgun/stunshell(src)
|
||||
new /obj/item/ammo_casing/shotgun/stunshell(src)
|
||||
|
||||
/obj/item/weapon/storage/box/heavysniperammo
|
||||
name = "box of 14.5mm AP shells"
|
||||
/obj/item/weapon/storage/box/sniperammo
|
||||
name = "box of 14.5mm shells"
|
||||
desc = "It has a picture of a gun and several warning symbols on the front.<br>WARNING: Live ammunition. Misuse may result in serious injury or death."
|
||||
|
||||
New()
|
||||
|
||||
@@ -128,6 +128,22 @@
|
||||
new /obj/item/stack/medical/splint(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/storage/firstaid/surgery
|
||||
name = "surgery kit"
|
||||
desc = "Contains tools for surgery."
|
||||
|
||||
/obj/item/weapon/storage/firstaid/surgery/New()
|
||||
..()
|
||||
if (empty) return
|
||||
new /obj/item/weapon/bonesetter(src)
|
||||
new /obj/item/weapon/cautery(src)
|
||||
new /obj/item/weapon/circular_saw(src)
|
||||
new /obj/item/weapon/hemostat(src)
|
||||
new /obj/item/weapon/retractor(src)
|
||||
new /obj/item/weapon/scalpel(src)
|
||||
new /obj/item/weapon/surgicaldrill(src)
|
||||
return
|
||||
|
||||
/*
|
||||
* Pill Bottles
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
new /obj/item/ammo_magazine/a357(src)
|
||||
new /obj/item/weapon/card/emag(src)
|
||||
new /obj/item/weapon/plastique(src)
|
||||
new /obj/item/weapon/plastique(src)
|
||||
return
|
||||
|
||||
if("murder")
|
||||
@@ -47,6 +48,7 @@
|
||||
return
|
||||
|
||||
if("hacker")
|
||||
new /obj/item/device/encryptionkey/syndicate(src)
|
||||
new /obj/item/weapon/aiModule/syndicate(src)
|
||||
new /obj/item/weapon/card/emag(src)
|
||||
new /obj/item/device/encryptionkey/binary(src)
|
||||
@@ -62,10 +64,9 @@
|
||||
return
|
||||
|
||||
if("smoothoperator")
|
||||
new /obj/item/weapon/gun/projectile/pistol(src)
|
||||
new /obj/item/weapon/silencer(src)
|
||||
new /obj/item/weapon/soap/syndie(src)
|
||||
new /obj/item/weapon/storage/box/syndie_kit/g9mm(src)
|
||||
new /obj/item/weapon/storage/bag/trash(src)
|
||||
new /obj/item/weapon/soap/syndie(src)
|
||||
new /obj/item/bodybag(src)
|
||||
new /obj/item/clothing/under/suit_jacket(src)
|
||||
new /obj/item/clothing/shoes/laceup(src)
|
||||
@@ -176,6 +177,15 @@
|
||||
new /obj/item/weapon/gun/projectile/pistol(src)
|
||||
new /obj/item/weapon/silencer(src)
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/toxin
|
||||
name = "toxin kit"
|
||||
desc = "An apple will not be enough to keep the doctor away after this."
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/toxin/New()
|
||||
..()
|
||||
new /obj/item/weapon/reagent_containers/glass/beaker/vial/random/toxin(src)
|
||||
new /obj/item/weapon/reagent_containers/syringe(src)
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/cigarette
|
||||
name = "\improper Tricky smokes"
|
||||
desc = "Comes with the following brands of cigarettes, in this order: 2xFlash, 2xSmoke, 1xMindBreaker, 1xTricordrazine. Avoid mixing them up."
|
||||
@@ -217,3 +227,11 @@
|
||||
for(var/reagent in reagents)
|
||||
C.reagents.add_reagent(reagent, reagents[reagent] * C.storage_slots)
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/ewar_voice
|
||||
name = "Electrowarfare and Voice Synthesiser kit"
|
||||
desc = "Kit for confounding organic and synthetic entities alike."
|
||||
|
||||
/obj/item/weapon/storage/box/syndie_kit/ewar_voice/New()
|
||||
..()
|
||||
new /obj/item/rig_module/electrowarfare_suite(src)
|
||||
new /obj/item/rig_module/voice(src)
|
||||
|
||||
@@ -14,6 +14,15 @@ var/list/accessible_z_levels = list("1" = 5, "3" = 10, "4" = 15, "5" = 10, "6" =
|
||||
/turf/space/New()
|
||||
if(!istype(src, /turf/space/transit))
|
||||
icon_state = "[((x + y) ^ ~(x * y) + z) % 25]"
|
||||
update_starlight()
|
||||
|
||||
/turf/space/proc/update_starlight()
|
||||
if(!config.starlight)
|
||||
return
|
||||
if(locate(/turf/simulated) in orange(src,1))
|
||||
SetLuminosity(3)
|
||||
else
|
||||
SetLuminosity(0)
|
||||
|
||||
/turf/space/attackby(obj/item/C as obj, mob/user as mob)
|
||||
|
||||
|
||||
@@ -251,6 +251,9 @@
|
||||
if(air_master)
|
||||
air_master.mark_for_update(src)
|
||||
|
||||
for(var/turf/space/S in range(W,1))
|
||||
S.update_starlight()
|
||||
|
||||
W.levelupdate()
|
||||
return W
|
||||
|
||||
@@ -272,6 +275,9 @@
|
||||
if(air_master)
|
||||
air_master.mark_for_update(src)
|
||||
|
||||
for(var/turf/space/S in range(W,1))
|
||||
S.update_starlight()
|
||||
|
||||
W.levelupdate()
|
||||
return W
|
||||
|
||||
|
||||
@@ -174,8 +174,9 @@ var/gravity_is_on = 1
|
||||
var/join_motd = null
|
||||
var/forceblob = 0
|
||||
|
||||
var/datum/nanomanager/nanomanager = new() // NanoManager, the manager for Nano UIs.
|
||||
var/datum/event_manager/event_manager = new() // Event Manager, the manager for events.
|
||||
var/datum/nanomanager/nanomanager = new() // NanoManager, the manager for Nano UIs.
|
||||
var/datum/event_manager/event_manager = new() // Event Manager, the manager for events.
|
||||
var/datum/subsystem/alarm/alarm_manager = new() // Alarm Manager, the manager for alarms.
|
||||
|
||||
var/list/awaydestinations = list() // Away missions. A list of landmarks that the warpgate can take you to.
|
||||
|
||||
|
||||
@@ -292,7 +292,7 @@
|
||||
if("monkey") M.change_mob_type( /mob/living/carbon/monkey , null, null, delmob )
|
||||
if("robot") M.change_mob_type( /mob/living/silicon/robot , null, null, delmob )
|
||||
if("cat") M.change_mob_type( /mob/living/simple_animal/cat , null, null, delmob )
|
||||
if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/Runtime , null, null, delmob )
|
||||
if("runtime") M.change_mob_type( /mob/living/simple_animal/cat/fluff/Runtime , null, null, delmob )
|
||||
if("corgi") M.change_mob_type( /mob/living/simple_animal/corgi , null, null, delmob )
|
||||
if("ian") M.change_mob_type( /mob/living/simple_animal/corgi/Ian , null, null, delmob )
|
||||
if("crab") M.change_mob_type( /mob/living/simple_animal/crab , null, null, delmob )
|
||||
|
||||
138
code/modules/alarm/alarm.dm
Normal file
@@ -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.master
|
||||
|
||||
/area/get_alarm_area()
|
||||
return src.master
|
||||
|
||||
/atom/proc/get_alarm_name()
|
||||
var/area/A = get_area(src)
|
||||
return A.master.name
|
||||
|
||||
/area/get_alarm_name()
|
||||
return master.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
|
||||
99
code/modules/alarm/alarm_handler.dm
Normal file
@@ -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.master // 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)
|
||||
19
code/modules/alarm/atmosphere_alarm.dm
Normal file
@@ -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
|
||||
2
code/modules/alarm/camera_alarm.dm
Normal file
@@ -0,0 +1,2 @@
|
||||
/datum/alarm_handler/camera
|
||||
category = "Camera Alarms"
|
||||
11
code/modules/alarm/fire_alarm.dm
Normal file
@@ -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()
|
||||
..()
|
||||
2
code/modules/alarm/motion_alarm.dm
Normal file
@@ -0,0 +1,2 @@
|
||||
/datum/alarm_handler/motion
|
||||
category = "Motion Alarms"
|
||||
10
code/modules/alarm/power_alarm.dm
Normal file
@@ -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)
|
||||
@@ -24,4 +24,11 @@
|
||||
/obj/item/rig_module/electrowarfare_suite,
|
||||
/obj/item/rig_module/chem_dispenser/combat,
|
||||
/obj/item/rig_module/fabricator/energy_net
|
||||
)
|
||||
|
||||
//Has most of the modules removed
|
||||
/obj/item/weapon/rig/merc/empty
|
||||
initial_modules = list(
|
||||
/obj/item/rig_module/ai_container,
|
||||
/obj/item/rig_module/electrowarfare_suite, //might as well
|
||||
)
|
||||
@@ -1412,12 +1412,6 @@
|
||||
|
||||
////////////////////////////// Foxler - Erstatz Vryroxes /////////////////////////////////////////////////
|
||||
|
||||
/obj/item/weapon/holder/cat/fluff/bones
|
||||
name = "Bones"
|
||||
desc = "It's Bones! Meow."
|
||||
gender = MALE
|
||||
icon_state = "cat3"
|
||||
|
||||
//Use this subtype for spawning in the custom item.
|
||||
/obj/item/weapon/holder/cat/fluff/bones/custom_item
|
||||
|
||||
@@ -1426,6 +1420,12 @@
|
||||
new/mob/living/simple_animal/cat/fluff/bones (src)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/holder/cat/fluff/bones
|
||||
name = "Bones"
|
||||
desc = "It's Bones! Meow."
|
||||
gender = MALE
|
||||
icon_state = "cat3"
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/bones
|
||||
name = "Bones"
|
||||
desc = "That's Bones the cat. He's a laid back, black cat. Meow."
|
||||
@@ -1434,61 +1434,12 @@
|
||||
icon_living = "cat3"
|
||||
icon_dead = "cat3_dead"
|
||||
holder_type = /obj/item/weapon/holder/cat/fluff/bones
|
||||
bff_name = "Erstatz Vryroxes"
|
||||
var/friend_name = "Erstatz Vryroxes"
|
||||
|
||||
/mob/living/simple_animal/cat/fluff
|
||||
var/bff_name
|
||||
var/mob/living/carbon/human/bff
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/handle_movement_target()
|
||||
if (!bff)
|
||||
/mob/living/simple_animal/cat/fluff/bones/handle_movement_target()
|
||||
if (!friend)
|
||||
for (var/mob/living/carbon/human/M in player_list)
|
||||
if (M.real_name == bff_name)
|
||||
bff = M
|
||||
if (M.real_name == friend_name)
|
||||
friend = M
|
||||
break
|
||||
|
||||
if (bff)
|
||||
var/follow_dist = 5
|
||||
if (bff.stat >= DEAD || bff.health <= config.health_threshold_softcrit) //danger
|
||||
follow_dist = 1
|
||||
else if (bff.stat || bff.health <= 50) //danger or just sleeping
|
||||
follow_dist = 2
|
||||
var/near_dist = max(follow_dist - 3, 1)
|
||||
var/current_dist = get_dist(src, bff)
|
||||
|
||||
if (movement_target != bff)
|
||||
if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (bff in oview(src)))
|
||||
//stop existing movement
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
|
||||
//walk to bff
|
||||
stop_automated_movement = 1
|
||||
movement_target = bff
|
||||
walk_to(src, movement_target, near_dist, 4)
|
||||
|
||||
//already following and close enough, stop
|
||||
else if (current_dist <= near_dist)
|
||||
walk_to(src,0)
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
|
||||
if (!(bff && movement_target == bff))
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/Life()
|
||||
..()
|
||||
if (stat || !bff)
|
||||
return
|
||||
if (get_dist(src, bff) <= 1)
|
||||
if (bff.stat >= DEAD || bff.health <= config.health_threshold_softcrit)
|
||||
if (prob((bff.stat < DEAD)? 50 : 15))
|
||||
audible_emote(pick("meows in distress.", "meows anxiously."))
|
||||
else
|
||||
if (prob(5))
|
||||
visible_emote(pick("nuzzles [bff].",
|
||||
"brushes against [bff].",
|
||||
"rubs against [bff].",
|
||||
"purrs."))
|
||||
else if (bff.health <= 50)
|
||||
if (prob(10)) audible_emote("meows anxiously.")
|
||||
|
||||
166
code/modules/examine/descriptions/atmospherics.dm
Normal file
@@ -0,0 +1,166 @@
|
||||
/obj/machinery/atmospherics/pipe
|
||||
description_info = "This pipe, and all other pipes, can be connected or disconnected by a wrench. The internal pressure of the pipe must \
|
||||
be below 300 kPa to do this. More pipes can be obtained from the pipe dispenser."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/New() //This is needed or else 20+ lines of copypasta to dance around inheritence.
|
||||
..()
|
||||
description_info += "<br>Most pipes and atmospheric devices can be connected or disconnected with a wrench. The pipe's pressure must not be too high, \
|
||||
or if it is a device, it must be turned off first."
|
||||
|
||||
//HE pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging
|
||||
description_info = "This radiates heat from the pipe's gas to space, cooling it down."
|
||||
|
||||
//Supply/Scrubber pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Universal adapters
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/universal
|
||||
description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/universal
|
||||
description_info = "This allows you to connect 'normal' pipes, red 'scrubber' pipes, and blue 'supply' pipes."
|
||||
|
||||
//Three way manifolds
|
||||
/obj/machinery/atmospherics/pipe/manifold
|
||||
description_info = "A normal pipe with three ends to connect to."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Insulated pipes
|
||||
/obj/machinery/atmospherics/pipe/simple/insulated
|
||||
description_info = "This is completely useless, use a normal pipe." //Sorry, but it's true.
|
||||
|
||||
//Four way manifolds
|
||||
/obj/machinery/atmospherics/pipe/manifold4w
|
||||
description_info = "This is a four-way pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/visible/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply
|
||||
description_info = "This is a special 'supply' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers
|
||||
description_info = "This is a special 'scrubber' pipe, which does not connect to 'normal' pipes. If you want to connect it, use \
|
||||
a Universal Adapter pipe."
|
||||
|
||||
//Endcaps
|
||||
/obj/machinery/atmospherics/pipe/cap
|
||||
description_info = "This is a cosmetic attachment, as pipes currently do not spill their contents into the air."
|
||||
|
||||
//T-shaped valves
|
||||
/obj/machinery/atmospherics/tvalve
|
||||
description_info = "Click this to toggle the mode. The direction with the green light is where the gas will flow."
|
||||
|
||||
//Normal valves
|
||||
/obj/machinery/atmospherics/valve
|
||||
description_info = "Click this to turn the valve. If red, the pipes on each end are seperated. Otherwise, they are connected."
|
||||
|
||||
//TEG ports
|
||||
/obj/machinery/atmospherics/binary/circulator
|
||||
description_info = "This generates electricity, depending on the difference in temperature between each side of the machine. The meter in \
|
||||
the center of the machine gives an indicator of how much elecrtricity is being generated."
|
||||
|
||||
//Passive gates
|
||||
/obj/machinery/atmospherics/binary/passive_gate
|
||||
description_info = "This is a one-way regulator, allowing gas to flow only at a specific pressure and flow rate. If the light is green, it is flowing."
|
||||
|
||||
//Normal pumps (high power one inherits from this)
|
||||
/obj/machinery/atmospherics/binary/pump
|
||||
description_info = "This moves gas from one pipe to another. A higher target pressure demands more energy. The side with the red end is the output."
|
||||
|
||||
//Vents
|
||||
/obj/machinery/atmospherics/unary/vent_pump
|
||||
description_info = "This pumps the contents of the attached pipe out into the atmosphere, if needed. It can be controlled from an Air Alarm."
|
||||
|
||||
//Freezers
|
||||
/obj/machinery/atmospherics/unary/freezer
|
||||
description_info = "Cools down the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
|
||||
//Heaters
|
||||
/obj/machinery/atmospherics/unary/heater
|
||||
description_info = "Heats up the gas of the pipe it is connected to. It uses massive amounts of electricity while on. \
|
||||
It can be upgraded by replacing the capacitors, manipulators, and matter bins. It can be deconstructed by screwing the maintenance panel open with a \
|
||||
screwdriver, and then using a crowbar."
|
||||
|
||||
//Gas injectors
|
||||
/obj/machinery/atmospherics/unary/outlet_injector
|
||||
description_info = "Outputs the pipe's gas into the atmosphere, similar to an airvent. It can be controlled by a nearby atmospherics computer. \
|
||||
A green light on it means it is on."
|
||||
|
||||
//Scrubbers
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber
|
||||
description_info = "This filters the atmosphere of harmful gas. Filtered gas goes to the pipes connected to it, typically a scrubber pipe. \
|
||||
It can be controlled from an Air Alarm. It can be configured to drain all air rapidly with a 'panic syphon' from an air alarm."
|
||||
|
||||
//Omni filters
|
||||
/obj/machinery/atmospherics/omni/filter
|
||||
description_info = "Filters gas from a custom input direction, with up to two filtered outputs and a 'everything else' \
|
||||
output. The filtered output's arrows glow orange."
|
||||
|
||||
//Omni mixers
|
||||
/obj/machinery/atmospherics/omni/mixer
|
||||
description_info = "Combines gas from custom input and output directions. The percentage of combined gas can be defined."
|
||||
|
||||
//Canisters
|
||||
/obj/machinery/portable_atmospherics/canister
|
||||
description_info = "The canister can be connected to a connector port with a wrench. Tanks of gas (the kind you can hold in your hand) \
|
||||
can be filled by the canister, by using the tank on the canister, increasing the release pressure, then opening the valve until it is full, and then close it. \
|
||||
*DO NOT* remove the tank until the valve is closed. A gas analyzer can be used to check the contents of the canister."
|
||||
|
||||
description_antag = "Canisters can be damaged, spilling their contents into the air, or you can just leave the release valve open."
|
||||
|
||||
//Portable pumps
|
||||
/obj/machinery/portable_atmospherics/powered/pump
|
||||
description_info = "Invaluable for filling air in a room rapidly after a breach repair. The internal gas container can be filled by \
|
||||
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
|
||||
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the air pump."
|
||||
|
||||
//Portable scrubbers
|
||||
/obj/machinery/portable_atmospherics/powered/scrubber
|
||||
description_info = "Filters the air, placing harmful gases into the internal gas container. The container can be emptied by \
|
||||
connecting it to a connector port. The pump can pump the air in (sucking) or out (blowing), at a specific target pressure. The powercell inside can be \
|
||||
replaced by using a screwdriver, and then adding a new cell. A tank of gas can also be attached to the scrubber. "
|
||||
|
||||
//Meters
|
||||
/obj/machinery/meter
|
||||
description_info = "Measures the volume and temperature of the pipe under the meter."
|
||||
|
||||
//Pipe dispensers
|
||||
/obj/machinery/pipedispenser
|
||||
description_info = "This can be moved by using a wrench. You will need to wrench it again when you want to use it. You can put \
|
||||
excess (atmospheric) pipes into the dispenser, as well. The dispenser requires electricity to function."
|
||||
|
||||
35
code/modules/examine/descriptions/engineering.dm
Normal file
@@ -0,0 +1,35 @@
|
||||
/obj/machinery/power/supermatter
|
||||
description_info = "When energized by a laser (or something hitting it), it emits radiation and heat. If the heat reaches above 7000 kelvin, it will send an alert and start taking damage. \
|
||||
After integrity falls to zero percent, it will delaminate, causing a massive explosion, station-wide radiation spikes, and hallucinations. \
|
||||
Supermatter reacts badly to oxygen in the atmosphere. It'll also heat up really quick if it is in vacuum.<br>\
|
||||
<br>\
|
||||
Supermatter cores are extremely dangerous to be close to, and requires protection to handle properly. The protection you will need is:<br>\
|
||||
Optical meson scanners on your eyes, to prevent hallucinations when looking at the supermatter.<br>\
|
||||
Radiation helmet and suit, as the supermatter is radioactive.<br>\
|
||||
<br>\
|
||||
Touching the supermatter will result in *instant death*, with no corpse left behind! You can drag the supermatter, but anything else will kill you. \
|
||||
It is advised to obtain a genetic backup before trying to drag it."
|
||||
|
||||
description_antag = "Exposing the supermatter to oxygen or vaccum will cause it to start rapidly heating up. Sabotaging the supermatter and making it explode will \
|
||||
cause a period of lag as the explosion is processed by the server, as well as irradiating the entire station and causing hallucinations to happen. \
|
||||
Wearing radiation equipment will protect you from most of the delamination effects sans explosion."
|
||||
|
||||
/obj/machinery/power/apc
|
||||
description_info = "An APC (Area Power Controller) regulates and supplies backup power for the area they are in. Their power channels are divided \
|
||||
out into 'environmental' (Items that manipulate airflow and temperature), 'lighting' (the lights), and 'equipment' (Everything else that consumes power). \
|
||||
Power consumption and backup power cell charge can be seen from the interface, further controls (turning a specific channel on, off or automatic, \
|
||||
toggling the APC's ability to charge the backup cell, or toggling power for the entire area via master breaker) first requires the interface to be unlocked \
|
||||
with an ID with Engineering access or by one of the station's robots or the artificial intelligence."
|
||||
|
||||
description_antag = "This can be emagged to unlock it. It will cause the APC to have a blue error screen. \
|
||||
Wires can be pulsed remotely with a signaler attached to it. A powersink will also drain any APCs connected to the same wire the powersink is on."
|
||||
|
||||
/obj/item/inflatable
|
||||
description_info = "Inflate by using it in your hand. The inflatable barrier will inflate on your tile. To deflate it, use the 'deflate' verb."
|
||||
|
||||
/obj/structure/inflatable
|
||||
description_info = "To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
|
||||
|
||||
/obj/structure/inflatable/door
|
||||
description_info = "Click the door to open or close it. It only stops air while closed.<br>\
|
||||
To remove these safely, use the 'deflate' verb. Hitting these with any objects will probably puncture and break it forever."
|
||||
8
code/modules/examine/descriptions/mobs.dm
Normal file
@@ -0,0 +1,8 @@
|
||||
/mob/living/silicon/robot/drone
|
||||
description_info = "Drones are player-controlled synthetics which are lawed to maintain the station and not \
|
||||
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
|
||||
They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
|
||||
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
|
||||
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access."
|
||||
|
||||
description_antag = "An Electromagnetic Sequencer can be used to subvert the drone to your cause."
|
||||
24
code/modules/examine/descriptions/stacks.dm
Normal file
@@ -0,0 +1,24 @@
|
||||
/obj/item/stack/rods
|
||||
description_info = "Made from metal sheets. You can build a grille by using it in your hand. \
|
||||
Clicking on a floor without any tiles will reinforce the floor. You can make reinforced glass by combining rods and normal glass sheets."
|
||||
|
||||
/obj/item/stack/sheet/glass
|
||||
description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets."
|
||||
|
||||
/obj/item/stack/sheet/glass/cyborg
|
||||
description_info = "Use in your hand to build a window. Can be upgraded to reinforced glass by adding metal rods, which are made from metal sheets.<br>\
|
||||
As a synthetic, you can acquire more sheets of glass by recharging."
|
||||
|
||||
/obj/item/stack/sheet/glass/reinforced
|
||||
description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage."
|
||||
|
||||
/obj/item/stack/sheet/glass/reinforced/cyborg
|
||||
description_info = "Use in your hand to build a window. Reinforced glass is much stronger against damage.<br>\
|
||||
As a synthetic, you can gain more reinforced glass by recharging."
|
||||
|
||||
/obj/item/stack/sheet/metal/cyborg
|
||||
description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it.<br>\
|
||||
You can replenish your supply of metal as a synthetic by recharging."
|
||||
|
||||
/obj/item/stack/sheet
|
||||
description_info = "Use in your hand to bring up the recipe menu. If you have enough sheets, click on something on the list to build it."
|
||||
15
code/modules/examine/descriptions/structures.dm
Normal file
@@ -0,0 +1,15 @@
|
||||
/obj/structure/girder
|
||||
description_info = "Use metal sheets on this to build a normal wall. Adding plasteel instead will make a reinforced wall.<br>\
|
||||
A false wall can be made by using a crowbar on this girder, and then adding metal or plasteel.<br>\
|
||||
You can dismantle the grider with a wrench."
|
||||
|
||||
/obj/structure/girder/reinforced
|
||||
description_info = "Add another sheet of plasteel to finish."
|
||||
|
||||
/obj/structure/grille
|
||||
description_info = "A powered and knotted wire underneath this will cause the grille to shock anyone not wearing insulated gloves.<br>\
|
||||
Wirecutters will turn the grille into metal rods instantly. Grilles are made with metal rods."
|
||||
|
||||
/obj/structure/lattice
|
||||
description_info = "Add a metal floor tile to build a floor on top of the lattice.<br>\
|
||||
Lattices can be made by applying metal rods to a space tile."
|
||||
3
code/modules/examine/descriptions/turfs.dm
Normal file
@@ -0,0 +1,3 @@
|
||||
/turf/simulated/wall
|
||||
description_info = "You can deconstruct this by welding it, and then wrenching the girder.<br>\
|
||||
You can build a wall by using metal sheets and making a girder, then adding more metal or plasteel."
|
||||
71
code/modules/examine/examine.dm
Normal file
@@ -0,0 +1,71 @@
|
||||
/* This code is responsible for the examine tab. When someone examines something, it copies the examined object's description_info,
|
||||
description_fluff, and description_antag, and shows it in a new tab.
|
||||
|
||||
In this file, some atom and mob stuff is defined here. It is defined here instead of in the normal files, to keep the whole system self-contained.
|
||||
This means that this file can be unchecked, along with the other examine files, and can be removed entirely with no effort.
|
||||
*/
|
||||
|
||||
|
||||
/atom/
|
||||
var/description_info = null //Helpful blue text.
|
||||
var/description_fluff = null //Green text about the atom's fluff, if any exists.
|
||||
var/description_antag = null //Malicious red text, for the antags.
|
||||
|
||||
/atom/examine(mob/user)
|
||||
..()
|
||||
user.description_holders["info"] = get_description_info()
|
||||
user.description_holders["fluff"] = get_description_fluff()
|
||||
if(user.mind && user.mind.special_role || isobserver(user)) //Runtime prevention, as ghosts don't have minds.
|
||||
user.description_holders["antag"] = get_description_antag()
|
||||
|
||||
if(name) //This shouldn't be needed but I'm paranoid.
|
||||
user.description_holders["name"] = "[src.name]" //\icon[src]
|
||||
|
||||
user.description_holders["icon"] = "\icon[src]"
|
||||
|
||||
if(desc)
|
||||
user << desc
|
||||
user.description_holders["desc"] = src.desc
|
||||
else
|
||||
user.description_holders["desc"] = null //This is needed, or else if you examine one thing with a desc, then another without, the panel will retain the first examined's desc.
|
||||
|
||||
//Override these if you need special behaviour for a specific type.
|
||||
|
||||
/atom/proc/get_description_info()
|
||||
if(description_info)
|
||||
return description_info
|
||||
return
|
||||
|
||||
/atom/proc/get_description_fluff()
|
||||
if(description_fluff)
|
||||
return description_fluff
|
||||
return
|
||||
|
||||
/atom/proc/get_description_antag()
|
||||
if(description_antag)
|
||||
return description_antag
|
||||
return
|
||||
|
||||
/mob/
|
||||
var/description_holders[0]
|
||||
|
||||
/mob/Stat()
|
||||
..()
|
||||
if(statpanel("Examine"))
|
||||
stat(null,"[description_holders["icon"]] <font size='5'>[description_holders["name"]]</font>") //The name, written in big letters.
|
||||
stat(null,"[description_holders["desc"]]") //the default examine text.
|
||||
if(description_holders["info"])
|
||||
stat(null,"<font color='#084B8A'><b>[description_holders["info"]]</b></font>") //Blue, informative text.
|
||||
if(description_holders["fluff"])
|
||||
stat(null,"<font color='#298A08'><b>[description_holders["fluff"]]</b></font>") //Yellow, fluff-related text.
|
||||
if(description_holders["antag"])
|
||||
stat(null,"<font color='#8A0808'><b>[description_holders["antag"]]</b></font>") //Red, malicious antag-related text
|
||||
|
||||
/mob/living/get_description_fluff()
|
||||
if(flavor_text) //Get flavor text for the green text.
|
||||
return flavor_text
|
||||
else //No flavor text? Try for hardcoded fluff instead.
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_description_fluff()
|
||||
return print_flavor_text(0)
|
||||
@@ -1280,9 +1280,6 @@
|
||||
else
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/get_descriptions_fluff()
|
||||
return print_flavor_text(0)
|
||||
|
||||
/mob/living/carbon/human/getDNA()
|
||||
if(species.flags & NO_SCAN)
|
||||
return null
|
||||
|
||||
@@ -1240,7 +1240,7 @@
|
||||
if(!druggy) see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
if(healths) healths.icon_state = "health7" //DEAD healthmeter
|
||||
if(client)
|
||||
if(client.view != world.view) // If mob moves while zoomed in with device, unzoom them.
|
||||
if(client.view != world.view) // If mob dies while zoomed in with device, unzoom them.
|
||||
for(var/obj/item/item in contents)
|
||||
if(item.zoom)
|
||||
item.zoom()
|
||||
|
||||
@@ -171,13 +171,6 @@
|
||||
|
||||
// ++++ROCKDTBEN++++ MOB PROCS //END
|
||||
|
||||
|
||||
/mob/living/get_descriptions_fluff()
|
||||
if(flavor_text) //Get flavor text for the green text.
|
||||
return flavor_text
|
||||
else //No flavor text? Try for hardcoded fluff instead.
|
||||
return ..()
|
||||
|
||||
/mob/proc/get_contents()
|
||||
|
||||
|
||||
|
||||
@@ -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/ai_announcement,
|
||||
/mob/living/silicon/ai/proc/ai_call_shuttle,
|
||||
// /mob/living/silicon/ai/proc/ai_recall_shuttle,
|
||||
@@ -23,10 +22,7 @@ var/list/ai_verbs_default = list(
|
||||
/mob/living/silicon/ai/proc/sensor_mode,
|
||||
/mob/living/silicon/ai/proc/show_laws_verb,
|
||||
/mob/living/silicon/ai/proc/toggle_acceleration,
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light,
|
||||
/mob/living/silicon/ai/proc/nano_rcon,
|
||||
/mob/living/silicon/ai/proc/nano_crew_monitor,
|
||||
/mob/living/silicon/ai/proc/nano_power_monitor
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light
|
||||
)
|
||||
|
||||
//Not sure why this is necessary...
|
||||
@@ -83,9 +79,11 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/ai/proc/add_ai_verbs()
|
||||
src.verbs |= ai_verbs_default
|
||||
src.verbs |= ai_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/ai/proc/remove_ai_verbs()
|
||||
src.verbs -= ai_verbs_default
|
||||
src.verbs -= ai_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
|
||||
announcement = new()
|
||||
@@ -166,8 +164,6 @@ var/list/ai_verbs_default = list(
|
||||
hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
|
||||
init_subsystems()
|
||||
|
||||
ai_list += src
|
||||
..()
|
||||
return
|
||||
@@ -325,36 +321,6 @@ var/list/ai_verbs_default = list(
|
||||
if(malf && 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 category = "AI Commands"
|
||||
set name = "Show 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=aialerts'>Close</A><BR><BR>"
|
||||
for (var/cat in alarms)
|
||||
dat += text("<B>[]</B><BR>\n", cat)
|
||||
var/list/alarmlist = alarms[cat]
|
||||
if (alarmlist.len)
|
||||
for (var/area_name in alarmlist)
|
||||
var/datum/alarm/alarm = alarmlist[area_name]
|
||||
dat += "<NOBR>"
|
||||
|
||||
var/cameratext = ""
|
||||
if (alarm.cameras)
|
||||
for (var/obj/machinery/camera/I in alarm.cameras)
|
||||
cameratext += text("[]<A HREF=?src=\ref[];switchcamera=\ref[]>[]</A>", (cameratext=="") ? "" : " | ", src, I, I.c_tag)
|
||||
dat += text("-- [] ([])", alarm.area.name, (cameratext)? cameratext : "No Camera")
|
||||
|
||||
if (alarm.sources.len > 1)
|
||||
dat += text(" - [] sources", alarm.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 category = "AI Commands"
|
||||
@@ -451,7 +417,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()
|
||||
//Carn: holopad requests
|
||||
if (href_list["jumptoholopad"])
|
||||
var/obj/machinery/hologram/holopad/H = locate(href_list["jumptoholopad"])
|
||||
@@ -526,29 +492,6 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, list/cameralist, var/source)
|
||||
if (stat == 2)
|
||||
return 1
|
||||
|
||||
..()
|
||||
|
||||
var/cameratext = ""
|
||||
for (var/obj/machinery/camera/C in cameralist)
|
||||
cameratext += "[(cameratext == "")? "" : "|"]<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>"
|
||||
|
||||
queueAlarm("--- [class] alarm detected in [A.name]! ([(cameratext)? cameratext : "No Camera"])", class)
|
||||
|
||||
if (viewalerts) ai_alerts()
|
||||
|
||||
/mob/living/silicon/ai/cancelAlarm(var/class, area/A as area, var/source)
|
||||
var/has_alarm = ..()
|
||||
|
||||
if (!has_alarm)
|
||||
queueAlarm(text("--- [] alarm in [] has been cleared.", class, A.name), class, 0)
|
||||
if (viewalerts) ai_alerts()
|
||||
|
||||
return has_alarm
|
||||
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
set category = "AI Commands"
|
||||
set name = "Cancel Camera View"
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
sleep(50)
|
||||
theAPC = null
|
||||
|
||||
process_queued_alarms()
|
||||
regular_hud_updates()
|
||||
switch(src.sensor_mode)
|
||||
if (SEC_HUD)
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
var/obj/nano_module/crew_monitor/crew_monitor
|
||||
var/obj/nano_module/rcon/rcon
|
||||
var/obj/nano_module/power_monitor/power_monitor
|
||||
|
||||
/mob/living/silicon/ai/proc/init_subsystems()
|
||||
crew_monitor = new(src)
|
||||
rcon = new(src)
|
||||
power_monitor = new(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/nano_crew_monitor()
|
||||
set category = "AI Subystems"
|
||||
set name = "Crew Monitor"
|
||||
|
||||
crew_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/ai/proc/nano_power_monitor()
|
||||
set category = "AI Subystems"
|
||||
set name = "Power Monitor"
|
||||
|
||||
power_monitor.ui_interact(usr)
|
||||
|
||||
|
||||
/mob/living/silicon/ai/proc/nano_rcon()
|
||||
set category = "AI Subystems"
|
||||
set name = "RCON"
|
||||
|
||||
rcon.ui_interact(usr)
|
||||
44
code/modules/mob/living/silicon/ai/subsystems.dm
Normal file
@@ -0,0 +1,44 @@
|
||||
var/list/ai_verbs_subsystems = list(
|
||||
/mob/living/silicon/ai/proc/subsystem_alarm_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_crew_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_power_monitor,
|
||||
/mob/living/silicon/ai/proc/subsystem_rcon
|
||||
)
|
||||
|
||||
/mob/living/silicon/ai
|
||||
var/
|
||||
var/obj/nano_module/crew_monitor/crew_monitor
|
||||
var/obj/nano_module/rcon/rcon
|
||||
var/obj/nano_module/power_monitor/power_monitor
|
||||
|
||||
/mob/living/silicon/ai/init_subsystems()
|
||||
..()
|
||||
del(alarm_monitor)
|
||||
alarm_monitor = new/obj/nano_module/alarm_monitor/ai(src)
|
||||
crew_monitor = new(src)
|
||||
rcon = new(src)
|
||||
power_monitor = new(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "AI Subystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_crew_monitor()
|
||||
set category = "AI Subystems"
|
||||
set name = "Crew Monitor"
|
||||
|
||||
crew_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_power_monitor()
|
||||
set category = "AI Subystems"
|
||||
set name = "Power Monitor"
|
||||
|
||||
power_monitor.ui_interact(usr)
|
||||
|
||||
/mob/living/silicon/ai/proc/subsystem_rcon()
|
||||
set category = "AI Subystems"
|
||||
set name = "RCON"
|
||||
|
||||
rcon.ui_interact(usr)
|
||||
@@ -1,111 +0,0 @@
|
||||
/datum/alarm
|
||||
var/area/area //the area associated with the alarm. Used to identify the alarm
|
||||
var/list/sources //list of things triggering the alarm. Used to determine when the alarm should be cleared.
|
||||
var/list/cameras //list of cameras that can be switched to, if the player has that capability.
|
||||
|
||||
/datum/alarm/New(area/A, list/sourcelist=list(), list/cameralist=list())
|
||||
area = A
|
||||
sources = sourcelist
|
||||
cameras = cameralist
|
||||
|
||||
/mob/living/silicon
|
||||
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list()) //each sublist stores alarms keyed by the area name
|
||||
var/list/alarms_to_show = list()
|
||||
var/list/alarms_to_clear = list()
|
||||
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
|
||||
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
|
||||
|
||||
/mob/living/silicon/proc/triggerAlarm(var/class, area/A, list/cameralist, var/source)
|
||||
var/list/alarmlist = alarms[class]
|
||||
|
||||
//see if there is already an alarm of this class for this area
|
||||
if (A.name in alarmlist)
|
||||
var/datum/alarm/existing = alarmlist[A.name]
|
||||
existing.sources += source
|
||||
existing.cameras |= cameralist
|
||||
else
|
||||
alarmlist[A.name] = new /datum/alarm(A, list(source), cameralist)
|
||||
|
||||
/mob/living/silicon/proc/cancelAlarm(var/class, area/A as area, var/source)
|
||||
var/cleared = 0
|
||||
var/list/alarmlist = alarms[class]
|
||||
|
||||
if (A.name in alarmlist)
|
||||
var/datum/alarm/alarm = alarmlist[A.name]
|
||||
alarm.sources -= source
|
||||
|
||||
if (!(alarm.sources.len))
|
||||
cleared = 1
|
||||
alarmlist -= A.name
|
||||
|
||||
return !cleared
|
||||
|
||||
/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
|
||||
@@ -3,13 +3,6 @@
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
icon_state = "repairbot"
|
||||
descriptions = new/datum/descriptions("Drones are player-controlled synthetics which are lawed to maintain the station and not \
|
||||
interact with anyone else, except for other drones. They hold a wide array of tools to build, repair, maintain, and clean. \
|
||||
They fuction similarly to other synthetics, in that they require recharging regularly, have laws, and are resilient to many hazards, \
|
||||
such as fire, radiation, vacuum, and more. Ghosts can join the round as a maintenance drone by using the appropriate verb in the 'ghost' tab. \
|
||||
An inactive drone can be rebooted by swiping an ID card on it with engineering or robotics access.",\
|
||||
,"An <u>Electromagnetic Sequencer</u> can be used to subvert the drone to your cause.")
|
||||
//desc_fluff is already provided with flavor_text.
|
||||
maxHealth = 35
|
||||
health = 35
|
||||
universal_speak = 0
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use_power()
|
||||
process_killswitch()
|
||||
process_locks()
|
||||
process_queued_alarms()
|
||||
update_canmove()
|
||||
|
||||
/mob/living/silicon/robot/proc/clamp_values()
|
||||
|
||||
@@ -437,39 +437,12 @@ var/list/robot_verbs_default = list(
|
||||
updatename()
|
||||
updateicon()
|
||||
|
||||
/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 Crew 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/alarmlist = alarms[cat]
|
||||
if (alarmlist.len)
|
||||
for (var/area_name in alarmlist)
|
||||
var/datum/alarm/alarm = alarmlist[area_name]
|
||||
dat += "<NOBR>"
|
||||
dat += text("-- [area_name]")
|
||||
if (alarm.sources.len > 1)
|
||||
dat += text("- [alarm.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
|
||||
@@ -639,25 +612,6 @@ var/list/robot_verbs_default = list(
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
/mob/living/silicon/robot/triggerAlarm(var/class, area/A, list/cameralist, var/source)
|
||||
if (stat == 2)
|
||||
return 1
|
||||
|
||||
..()
|
||||
|
||||
queueAlarm(text("--- [class] alarm detected in [A.name]!"), class)
|
||||
|
||||
|
||||
/mob/living/silicon/robot/cancelAlarm(var/class, area/A as area, obj/origin)
|
||||
var/has_alarm = ..()
|
||||
|
||||
if (!has_alarm)
|
||||
queueAlarm(text("--- [class] alarm in [A.name] has been cleared."), class, 0)
|
||||
// if (viewalerts) robot_alerts()
|
||||
return has_alarm
|
||||
|
||||
|
||||
/mob/living/silicon/robot/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if (istype(W, /obj/item/weapon/handcuffs)) // fuck i don't even know why isrobot() in handcuff code isn't working so this will have to do
|
||||
return
|
||||
@@ -1043,30 +997,31 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/robot/Topic(href, href_list)
|
||||
if(..())
|
||||
return
|
||||
return 1
|
||||
if(usr != src)
|
||||
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))
|
||||
return
|
||||
return 1
|
||||
|
||||
if(!((O in src.module.modules) || (O == src.module.emag)))
|
||||
return
|
||||
return 1
|
||||
|
||||
if(activated(O))
|
||||
src << "Already activated"
|
||||
return
|
||||
return 1
|
||||
if(!module_state_1)
|
||||
module_state_1 = O
|
||||
O.layer = 20
|
||||
@@ -1088,6 +1043,7 @@ var/list/robot_verbs_default = list(
|
||||
else
|
||||
src << "You need to disable a module first!"
|
||||
installed_modules()
|
||||
return 1
|
||||
|
||||
if (href_list["deact"])
|
||||
var/obj/item/O = locate(href_list["deact"])
|
||||
@@ -1106,6 +1062,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"])
|
||||
@@ -1114,6 +1071,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"])
|
||||
@@ -1122,9 +1080,11 @@ 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 1
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/proc/radio_menu()
|
||||
@@ -1257,9 +1217,11 @@ var/list/robot_verbs_default = list(
|
||||
|
||||
/mob/living/silicon/robot/proc/add_robot_verbs()
|
||||
src.verbs |= robot_verbs_default
|
||||
src.verbs |= robot_verbs_subsystems
|
||||
|
||||
/mob/living/silicon/robot/proc/remove_robot_verbs()
|
||||
src.verbs -= robot_verbs_default
|
||||
src.verbs -= robot_verbs_subsystems
|
||||
|
||||
// Uses power from cyborg's cell. Returns 1 on success or 0 on failure.
|
||||
// Properly converts using CELLRATE now! Amount is in Joules.
|
||||
|
||||
9
code/modules/mob/living/silicon/robot/subsystems.dm
Normal file
@@ -0,0 +1,9 @@
|
||||
var/list/robot_verbs_subsystems = list(
|
||||
/mob/living/silicon/robot/proc/subsystem_alarm_monitor
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/proc/subsystem_alarm_monitor()
|
||||
set name = "Alarm Monitor"
|
||||
set category = "Robot Subystems"
|
||||
|
||||
alarm_monitor.ui_interact(usr)
|
||||
@@ -22,13 +22,26 @@
|
||||
var/obj/item/device/camera/siliconcam/aiCamera = null //photography
|
||||
var/local_transmit //If set, can only speak to others of the same type within a short range.
|
||||
|
||||
// Subsystems
|
||||
var/obj/nano_module/alarm_monitor = null
|
||||
|
||||
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
|
||||
|
||||
/mob/living/silicon/New()
|
||||
..()
|
||||
add_language("Galactic Common")
|
||||
init_subsystems()
|
||||
|
||||
/mob/living/silicon/Del()
|
||||
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
|
||||
AH.unregister(src)
|
||||
..()
|
||||
|
||||
/mob/living/silicon/proc/SetName(pickedName as text)
|
||||
real_name = pickedName
|
||||
@@ -243,7 +256,8 @@
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/Topic(href, href_list)
|
||||
..()
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if (href_list["lawr"]) // Selects on which channel to state laws
|
||||
var/list/channels = list(MAIN_CHANNEL)
|
||||
@@ -282,3 +296,62 @@
|
||||
adjustBruteLoss(30)
|
||||
|
||||
updatehealth()
|
||||
|
||||
/mob/living/silicon/proc/init_subsystems()
|
||||
alarm_monitor = new/obj/nano_module/alarm_monitor/borg(src)
|
||||
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
|
||||
AH.register(src, /mob/living/silicon/proc/receive_alarm)
|
||||
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order
|
||||
|
||||
/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
|
||||
|
||||
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()]."
|
||||
|
||||
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"])"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
response_harm = "kicks"
|
||||
var/turns_since_scan = 0
|
||||
var/mob/living/simple_animal/mouse/movement_target
|
||||
var/mob/flee_target
|
||||
min_oxy = 16 //Require atleast 16kPA oxygen
|
||||
minbodytemp = 223 //Below -50 Degrees Celcius
|
||||
maxbodytemp = 323 //Above 50 Degrees Celcius
|
||||
@@ -44,27 +45,71 @@
|
||||
break
|
||||
|
||||
if(!stat && !resting && !buckled)
|
||||
handle_movement_target()
|
||||
turns_since_scan++
|
||||
if (turns_since_scan > 5)
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
|
||||
if (flee_target) //fleeing takes precendence
|
||||
handle_flee_target()
|
||||
else
|
||||
handle_movement_target()
|
||||
|
||||
/mob/living/simple_animal/cat/proc/handle_movement_target()
|
||||
turns_since_scan++
|
||||
if(turns_since_scan > 5)
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
/mob/living/simple_animal/cat/proc/handle_movement_target()
|
||||
//if our target is neither inside a turf or inside a human(???), stop
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
//if we have no target or our current one is out of sight/too far away
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 4)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/mob/living/simple_animal/mouse/snack in oview(src)) //search for a new target
|
||||
if(isturf(snack.loc) && !snack.stat)
|
||||
movement_target = snack
|
||||
break
|
||||
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
|
||||
if((movement_target) && !(isturf(movement_target.loc) || ishuman(movement_target.loc) ))
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if( !movement_target || !(movement_target.loc in oview(src, 4)) )
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
for(var/mob/living/simple_animal/mouse/snack in oview(src))
|
||||
if(isturf(snack.loc) && !snack.stat)
|
||||
movement_target = snack
|
||||
break
|
||||
if(movement_target)
|
||||
stop_automated_movement = 1
|
||||
walk_to(src,movement_target,0,3)
|
||||
/mob/living/simple_animal/cat/proc/handle_flee_target()
|
||||
//see if we should stop fleeing
|
||||
if (flee_target && !(flee_target.loc in view(src)))
|
||||
flee_target = null
|
||||
stop_automated_movement = 0
|
||||
|
||||
if (flee_target)
|
||||
if(prob(25)) say("HSSSSS")
|
||||
stop_automated_movement = 1
|
||||
walk_away(src, flee_target, 7, 2)
|
||||
|
||||
/mob/living/simple_animal/cat/proc/set_flee_target(atom/A)
|
||||
if(A)
|
||||
flee_target = A
|
||||
turns_since_scan = 5
|
||||
|
||||
/mob/living/simple_animal/cat/attackby(var/obj/item/O, var/mob/user)
|
||||
. = ..()
|
||||
if(O.force)
|
||||
set_flee_target(user? user : src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/attack_hand(mob/living/carbon/human/M as mob)
|
||||
. = ..()
|
||||
if(M.a_intent == "hurt")
|
||||
set_flee_target(M)
|
||||
|
||||
/mob/living/simple_animal/cat/ex_act()
|
||||
. = ..()
|
||||
set_flee_target(src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/bullet_act(var/obj/item/projectile/proj)
|
||||
. = ..()
|
||||
set_flee_target(proj.firer? proj.firer : src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/hitby(atom/movable/AM)
|
||||
. = ..()
|
||||
set_flee_target(AM.thrower? AM.thrower : src.loc)
|
||||
|
||||
/mob/living/simple_animal/cat/MouseDrop(atom/over_object)
|
||||
|
||||
@@ -82,14 +127,91 @@
|
||||
return //since the holder icon looks like a living cat
|
||||
..()
|
||||
|
||||
//Basic friend AI
|
||||
/mob/living/simple_animal/cat/fluff
|
||||
var/mob/living/carbon/human/friend
|
||||
var/befriend_job = null
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/handle_movement_target()
|
||||
if (friend)
|
||||
var/follow_dist = 5
|
||||
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) //danger
|
||||
follow_dist = 1
|
||||
else if (friend.stat || friend.health <= 50) //danger or just sleeping
|
||||
follow_dist = 2
|
||||
var/near_dist = max(follow_dist - 2, 1)
|
||||
var/current_dist = get_dist(src, friend)
|
||||
|
||||
if (movement_target != friend)
|
||||
if (current_dist > follow_dist && !istype(movement_target, /mob/living/simple_animal/mouse) && (friend in oview(src)))
|
||||
//stop existing movement
|
||||
walk_to(src,0)
|
||||
turns_since_scan = 0
|
||||
|
||||
//walk to friend
|
||||
stop_automated_movement = 1
|
||||
movement_target = friend
|
||||
walk_to(src, movement_target, near_dist, 4)
|
||||
|
||||
//already following and close enough, stop
|
||||
else if (current_dist <= near_dist)
|
||||
walk_to(src,0)
|
||||
movement_target = null
|
||||
stop_automated_movement = 0
|
||||
if (prob(10))
|
||||
say("Meow!")
|
||||
|
||||
if (!friend || movement_target != friend)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/Life()
|
||||
..()
|
||||
if (stat || !friend)
|
||||
return
|
||||
if (get_dist(src, friend) <= 1)
|
||||
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
|
||||
if (prob((friend.stat < DEAD)? 50 : 15))
|
||||
var/verb = pick("meows", "mews", "mrowls")
|
||||
audible_emote(pick("[verb] in distress.", "[verb] anxiously."))
|
||||
else
|
||||
if (prob(5))
|
||||
visible_emote(pick("nuzzles [friend].",
|
||||
"brushes against [friend].",
|
||||
"rubs against [friend].",
|
||||
"purrs."))
|
||||
else if (friend.health <= 50)
|
||||
if (prob(10))
|
||||
var/verb = pick("meows", "mews", "mrowls")
|
||||
audible_emote("[verb] anxiously.")
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/verb/friend()
|
||||
set name = "Become Friends"
|
||||
set category = "IC"
|
||||
set src in view(1)
|
||||
|
||||
if(friend && usr == friend)
|
||||
set_dir(get_dir(src, friend))
|
||||
say("Meow!")
|
||||
return
|
||||
|
||||
if (!(ishuman(usr) && befriend_job && usr.job == befriend_job))
|
||||
usr << "<span class='notice'>[src] ignores you.</span>"
|
||||
return
|
||||
|
||||
friend = usr
|
||||
|
||||
set_dir(get_dir(src, friend))
|
||||
say("Meow!")
|
||||
|
||||
//RUNTIME IS ALIVE! SQUEEEEEEEE~
|
||||
/mob/living/simple_animal/cat/Runtime
|
||||
/mob/living/simple_animal/cat/fluff/Runtime
|
||||
name = "Runtime"
|
||||
desc = "Her fur has the look and feel of velvet, and her tail quivers occasionally."
|
||||
gender = FEMALE
|
||||
icon_state = "cat"
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat_dead"
|
||||
befriend_job = "Chief Medical Officer"
|
||||
|
||||
/mob/living/simple_animal/cat/kitten
|
||||
name = "kitten"
|
||||
@@ -97,4 +219,8 @@
|
||||
icon_state = "kitten"
|
||||
icon_living = "kitten"
|
||||
icon_dead = "kitten_dead"
|
||||
gender = NEUTER
|
||||
gender = NEUTER
|
||||
|
||||
/mob/living/simple_animal/cat/kitten/New()
|
||||
gender = pick(MALE, FEMALE)
|
||||
..()
|
||||
|
||||
@@ -265,7 +265,7 @@
|
||||
adjustBruteLoss(-medical_pack.heal_brute)
|
||||
visible_message("<span class='warning'>\The [user] applies the [medical_pack] to \the [src].</span>")
|
||||
else
|
||||
user << "<span class='warning'>\The [src] cannot benefit from medical items in its current state.</span>"
|
||||
user << "<span class='warning'>\The [src] cannot benefit from medical items in \his current state.</span>"
|
||||
return
|
||||
|
||||
else if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
|
||||
|
||||
@@ -792,26 +792,25 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
/mob/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("MC")) //not looking at that panel
|
||||
|
||||
if(client && client.holder)
|
||||
if(client && client.holder)
|
||||
if(statpanel("Status"))
|
||||
stat(null,"Location:\t([x], [y], [z])")
|
||||
stat(null,"CPU:\t[world.cpu]")
|
||||
stat(null,"Instances:\t[world.contents.len]")
|
||||
|
||||
if(master_controller)
|
||||
stat(null,"MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])")
|
||||
stat(null,"Air-[master_controller.air_cost]\tSun-[master_controller.sun_cost]")
|
||||
stat(null,"Mob-[master_controller.mobs_cost]\t#[mob_list.len]")
|
||||
stat(null,"Dis-[master_controller.diseases_cost]\t#[active_diseases.len]")
|
||||
stat(null,"Mch-[master_controller.machines_cost]\t#[machines.len]")
|
||||
stat(null,"Obj-[master_controller.objects_cost]\t#[processing_objects.len]")
|
||||
stat(null,"Net-[master_controller.networks_cost]\tPnet-[master_controller.powernets_cost]")
|
||||
stat(null,"NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]")
|
||||
stat(null,"Events-[master_controller.events_cost]\t#[event_manager.active_events.len]")
|
||||
stat(null,"Tick-[master_controller.ticker_cost]\tALL-[master_controller.total_cost]")
|
||||
else
|
||||
stat(null,"MasterController-ERROR")
|
||||
if(statpanel("MC") && master_controller)
|
||||
stat(null,"MasterController-[last_tick_duration] ([master_controller.processing?"On":"Off"]-[controller_iteration])")
|
||||
stat(null,"Air-[master_controller.air_cost]\tSun-[master_controller.sun_cost]")
|
||||
stat(null,"Mob-[master_controller.mobs_cost]\t#[mob_list.len]")
|
||||
stat(null,"Dis-[master_controller.diseases_cost]\t#[active_diseases.len]")
|
||||
stat(null,"Mch-[master_controller.machines_cost]\t#[machines.len]")
|
||||
stat(null,"Obj-[master_controller.objects_cost]\t#[processing_objects.len]")
|
||||
stat(null,"Net-[master_controller.networks_cost]\tPnet-[master_controller.powernets_cost]")
|
||||
stat(null,"NanoUI-[master_controller.nano_cost]\t#[nanomanager.processing_uis.len]")
|
||||
stat(null,"Event-[master_controller.events_cost]\t#[event_manager.active_events.len]")
|
||||
alarm_manager.stat_entry()
|
||||
stat(null,"Tick-[master_controller.ticker_cost]\tALL-[master_controller.total_cost]")
|
||||
else
|
||||
stat(null,"MasterController-ERROR")
|
||||
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
@@ -834,16 +833,6 @@ note dizziness decrements automatically in the mob's Life() proc.
|
||||
statpanel("Spells","[S.charge_counter]/[S.charge_max]",S)
|
||||
if("holdervar")
|
||||
statpanel("Spells","[S.holder_var_type] [S.holder_var_amount]",S)
|
||||
if(statpanel("Examine"))
|
||||
stat(null,"[description_holders["icon"]] <font size='5'>[description_holders["name"]]</font>") //The name, written in big letters.
|
||||
stat(null,"[description_holders["desc"]]") //the default examine text.
|
||||
if(description_holders["info"])
|
||||
stat(null,"<font color='#084B8A'><b>[description_holders["info"]]</b></font>") //Blue, informative text.
|
||||
if(description_holders["fluff"])
|
||||
stat(null,"<font color='#298A08'><b>[description_holders["fluff"]]</b></font>") //Yellow, fluff-related text.
|
||||
if(mind.special_role)
|
||||
if(description_holders["antag"])
|
||||
stat(null,"<font color='#8A0808'><b>[description_holders["antag"]]</b></font>") //Red, malicious antag-related text
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -224,7 +224,4 @@
|
||||
|
||||
var/list/active_genes=list()
|
||||
|
||||
//Examine tab vars
|
||||
//These hold the descriptions and other info, to relay to the actual tab.
|
||||
var/description_holders[0]
|
||||
|
||||
|
||||
@@ -559,3 +559,16 @@ proc/is_blind(A)
|
||||
say_dead_direct("The ghost of <span class='name'>[name]</span> now [pick("skulks","lurks","prowls","creeps","stalks")] among the dead. [message]")
|
||||
else
|
||||
say_dead_direct("<span class='name'>[name]</span> no longer [pick("skulks","lurks","prowls","creeps","stalks")] in the realm of the dead. [message]")
|
||||
|
||||
/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(C)
|
||||
return 1
|
||||
|
||||
83
code/modules/nano/modules/alarm_monitor.dm
Normal file
@@ -0,0 +1,83 @@
|
||||
/obj/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.
|
||||
|
||||
/obj/nano_module/alarm_monitor/ai
|
||||
list_cameras = 1
|
||||
|
||||
/obj/nano_module/alarm_monitor/ai/New()
|
||||
..()
|
||||
alarm_handlers = alarm_manager.all_handlers
|
||||
|
||||
/obj/nano_module/alarm_monitor/borg/New()
|
||||
..()
|
||||
alarm_handlers = alarm_manager.all_handlers
|
||||
|
||||
/obj/nano_module/alarm_monitor/engineering/New()
|
||||
..()
|
||||
alarm_handlers = list(atmosphere_alarm, fire_alarm, power_alarm)
|
||||
|
||||
/obj/nano_module/alarm_monitor/security/New()
|
||||
..()
|
||||
alarm_handlers = list(camera_alarm, motion_alarm)
|
||||
|
||||
/obj/nano_module/alarm_monitor/proc/register(var/object, var/procName)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.register(object, procName)
|
||||
|
||||
/obj/nano_module/alarm_monitor/proc/unregister(var/object)
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
AH.unregister(object)
|
||||
|
||||
/obj/nano_module/alarm_monitor/proc/active_alarms()
|
||||
var/list/all_alarms = new()
|
||||
for(var/datum/alarm_handler/AH in alarm_handlers)
|
||||
var/list/alarms = AH.alarms
|
||||
all_alarms += alarms
|
||||
|
||||
return all_alarms
|
||||
|
||||
/obj/nano_module/alarm_monitor/ai/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)
|
||||
|
||||
return
|
||||
|
||||
usr.switch_to_camera(C)
|
||||
return 1
|
||||
|
||||
/obj/nano_module/alarm_monitor/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
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(list_cameras)
|
||||
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" = 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)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
@@ -1,5 +1,5 @@
|
||||
/obj/nano_module/rcon
|
||||
name = "RCON interface"
|
||||
name = "Power RCON"
|
||||
|
||||
var/list/known_SMESs = null
|
||||
var/list/known_breakers = null
|
||||
|
||||
@@ -78,6 +78,10 @@
|
||||
return STATUS_UPDATE // update only (orange visibility)
|
||||
return STATUS_INTERACTIVE
|
||||
|
||||
//Some atoms such as vehicles might have special rules for how mobs inside them interact with NanoUI.
|
||||
/atom/proc/contents_nano_distance(var/src_object, var/mob/living/user)
|
||||
return user.shared_living_nano_distance(src_object)
|
||||
|
||||
/mob/living/proc/shared_living_nano_distance(var/atom/movable/src_object)
|
||||
if(!isturf(src_object.loc))
|
||||
if(src_object.loc == src) // Item in the inventory
|
||||
@@ -100,7 +104,10 @@
|
||||
/mob/living/can_use_topic(var/src_object, var/datum/topic_state/custom_state)
|
||||
. = shared_living_nano_interaction(src_object)
|
||||
if(. == STATUS_INTERACTIVE && !(custom_state.flags & NANO_IGNORE_DISTANCE))
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(loc)
|
||||
. = loc.contents_nano_distance(src_object, src)
|
||||
else
|
||||
. = shared_living_nano_distance(src_object)
|
||||
if(STATUS_INTERACTIVE)
|
||||
return STATUS_UPDATE
|
||||
|
||||
|
||||
@@ -497,10 +497,11 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
H = owner
|
||||
|
||||
for(var/datum/wound/W in wounds)
|
||||
if(W.damage_type == CUT || W.damage_type == BRUISE)
|
||||
brute_dam += W.damage
|
||||
else if(W.damage_type == BURN)
|
||||
burn_dam += W.damage
|
||||
if(!W.internal) //so IB doesn't count towards crit/paincrit
|
||||
if(W.damage_type == CUT || W.damage_type == BRUISE)
|
||||
brute_dam += W.damage
|
||||
else if(W.damage_type == BURN)
|
||||
burn_dam += W.damage
|
||||
|
||||
if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && !(H.species.flags & NO_BLOOD)))
|
||||
W.bleed_timer--
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
if(terminal)
|
||||
disconnect_terminal()
|
||||
|
||||
//If there's no more APC then there shouldn't be a cause for alarm I guess
|
||||
area.poweralert(1, src) //so that alarms don't go on forever
|
||||
|
||||
..()
|
||||
|
||||
/obj/machinery/power/apc/proc/make_terminal()
|
||||
@@ -725,7 +722,7 @@
|
||||
src.interact(user)
|
||||
|
||||
/obj/machinery/power/apc/attack_ghost(user as mob)
|
||||
if(stat & (BROKEN|MAINT))
|
||||
if(stat & (BROKEN|MAINT))
|
||||
return
|
||||
return ui_interact(user)
|
||||
|
||||
@@ -1164,29 +1161,27 @@
|
||||
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.percent() <= 30) && (cell.percent() > 15) && 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)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 2
|
||||
else if(cell.percent() <= 15) // <15%, turn off lighting & equipment
|
||||
if((autoflag > 1 && longtermpower < 0) || (autoflag > 1 && longtermpower >= 0))
|
||||
equipment = autoset(equipment, 2)
|
||||
lighting = autoset(lighting, 2)
|
||||
environ = autoset(environ, 1)
|
||||
area.poweralert(0, src)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 1
|
||||
else // zero charge, turn all off
|
||||
if(autoflag != 0)
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
area.poweralert(0, src)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 0
|
||||
|
||||
// now trickle-charge the cell
|
||||
@@ -1233,7 +1228,7 @@
|
||||
equipment = autoset(equipment, 0)
|
||||
lighting = autoset(lighting, 0)
|
||||
environ = autoset(environ, 0)
|
||||
area.poweralert(0, src)
|
||||
power_alarm.triggerAlarm(loc, src)
|
||||
autoflag = 0
|
||||
|
||||
// update icon & area power if anything changed
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/area/engineering/poweralert(var/state, var/source)
|
||||
if (state != poweralm)
|
||||
/area/engineering/power_alert(var/alarming)
|
||||
if (alarming)
|
||||
investigate_log("has a power alarm!","singulo")
|
||||
..()
|
||||
@@ -76,7 +76,13 @@
|
||||
/obj/item/weapon/gun/energy/update_icon()
|
||||
if(charge_meter)
|
||||
var/ratio = power_supply.charge / power_supply.maxcharge
|
||||
ratio = round(ratio, 0.25) * 100
|
||||
|
||||
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
|
||||
if(power_supply.charge < charge_cost)
|
||||
ratio = 0
|
||||
else
|
||||
ratio = max(round(ratio, 0.25) * 100, 25)
|
||||
|
||||
if(modifystate)
|
||||
icon_state = "[modifystate][ratio]"
|
||||
else
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
name = "ion rifle"
|
||||
desc = "A man portable anti-armor weapon designed to disable mechanical threats"
|
||||
icon_state = "ionrifle"
|
||||
item_state = "ionrifle"
|
||||
fire_sound = 'sound/weapons/Laser.ogg'
|
||||
origin_tech = "combat=2;magnets=4"
|
||||
w_class = 4.0
|
||||
w_class = 4
|
||||
force = 10
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BACK
|
||||
@@ -16,6 +17,13 @@
|
||||
return //so it doesn't EMP itself, I guess
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/ionrifle/update_icon()
|
||||
..()
|
||||
if(power_supply.charge < charge_cost)
|
||||
item_state = "ionrifle-empty"
|
||||
else
|
||||
item_state = initial(item_state)
|
||||
|
||||
/obj/item/weapon/gun/energy/decloner
|
||||
name = "biological demolecularisor"
|
||||
desc = "A gun that discharges high amounts of controlled radiation to slowly break a target into component elements."
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/item/weapon/gun/projectile/heavysniper
|
||||
name = "\improper PTRS-7 rifle"
|
||||
desc = "A portable anti-armour rifle fitted with a scope. Originally designed to used against armoured exosuits, it is capable of punching through non-reinforced walls with ease. Fires armor piercing 14.5mm shells."
|
||||
desc = "A portable anti-armour rifle fitted with a scope. Originally designed to used against armoured exosuits, it is capable of punching through windows and non-reinforced walls with ease. Fires armor piercing 14.5mm shells."
|
||||
icon_state = "heavysniper"
|
||||
item_state = "shotgun"
|
||||
w_class = 4
|
||||
|
||||
@@ -43,10 +43,10 @@
|
||||
var/chance = 0
|
||||
if(istype(A, /turf/simulated/wall))
|
||||
var/turf/simulated/wall/W = A
|
||||
chance = round(damage/W.damage_cap*180)
|
||||
chance = round(damage/W.damage_cap*250)
|
||||
else if(istype(A, /obj/machinery/door))
|
||||
var/obj/machinery/door/D = A
|
||||
chance = round(damage/D.maxhealth*100)
|
||||
chance = round(damage/D.maxhealth*150)
|
||||
else if(istype(A, /obj/structure/girder) || istype(A, /obj/structure/cultgirder))
|
||||
chance = 100
|
||||
else if(istype(A, /obj/machinery) || istype(A, /obj/structure))
|
||||
@@ -141,13 +141,13 @@
|
||||
penetrating = 1
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a145
|
||||
damage = 80
|
||||
damage = 60
|
||||
stun = 3
|
||||
weaken = 3
|
||||
penetrating = 5
|
||||
|
||||
/obj/item/projectile/bullet/rifle/a556
|
||||
damage = 50
|
||||
damage = 40
|
||||
penetrating = 1
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
@@ -320,4 +320,7 @@ EVENT_CUSTOM_START_MAJOR 80;100
|
||||
#DISABLE_DSAY
|
||||
|
||||
## Uncomment to disable respawning by default.
|
||||
#DISABLE_RESPAWN
|
||||
#DISABLE_RESPAWN
|
||||
|
||||
## Uncomment to make space turfs have a short-range ambient light.
|
||||
# STARLIGHT
|
||||
|
||||
|
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 52 KiB |
@@ -271,6 +271,12 @@ div.notice {
|
||||
color: #e9c183;
|
||||
}
|
||||
|
||||
.itemLabelWidest {
|
||||
float: left;
|
||||
width: 100%;
|
||||
color: #e9c183;
|
||||
}
|
||||
|
||||
.itemContentWide {
|
||||
float: left;
|
||||
width: 79%;
|
||||
|
||||
37
nano/templates/alarm_monitor.tmpl
Normal file
@@ -0,0 +1,37 @@
|
||||
<!--
|
||||
Title: Alarm Monitor Console (Main content)
|
||||
Used In File(s): \code\modules\nano\modules\alarm_monitor.dm
|
||||
-->
|
||||
|
||||
{{for data.categories}}
|
||||
<H2><span class="itemLabelWidest">{{:value.category}}</span></H2>
|
||||
{{for value.alarms :alarmValue:alarmIndex}}
|
||||
{{if alarmValue.origin_lost}}
|
||||
{{:alarmValue.name}} <span class='notice'>Alarm Origin Lost</span><br>
|
||||
{{else}}
|
||||
{{:alarmValue.name}}<br>
|
||||
{{/if}}
|
||||
{{if alarmValue.has_cameras || alarmValue.lost_sources != ""}}
|
||||
<div class="item">
|
||||
{{if alarmValue.has_cameras}}
|
||||
<div class="itemContent" style="width: 100%;">
|
||||
{{for alarmValue.cameras :cameraValue:cameraIndex}}
|
||||
{{if cameraValue.deact}}
|
||||
{{:helper.link(cameraValue.name + " (deactivated)", '', {}, 'inactive')}}
|
||||
{{else}}
|
||||
{{:helper.link(cameraValue.name, '', {'switchTo' : cameraValue.camera})}}
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{if alarmValue.lost_sources != ""}}
|
||||
<div class="itemContent" style="width: 100%;">
|
||||
<H4><span class='notice'>Lost Alarm Sources: {{:alarmValue.lost_sources}}</span></H4>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{empty}}
|
||||
<span class="white">--All Systems Nominal</span>
|
||||
{{/for}}
|
||||
{{/for}}
|
||||
17
nano/templates/atmos_alert.tmpl
Normal file
@@ -0,0 +1,17 @@
|
||||
<H1>Priority Alerts</H1>
|
||||
{{for data.priority_alarms}}
|
||||
<div class="item">
|
||||
{{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}}
|
||||
</div>
|
||||
{{empty}}
|
||||
No priority alerts detected.
|
||||
{{/for}}
|
||||
|
||||
<H3>Minor Alerts</H3>
|
||||
<div class="item">
|
||||
{{for data.minor_alarms}}
|
||||
{{:value.name}} {{:helper.link('Reset', null, {'clear_alarm' : value.ref})}}
|
||||
{{empty}}
|
||||
No minor alerts detected.
|
||||
{{/for}}
|
||||
</div>
|
||||
@@ -1,93 +1,99 @@
|
||||
|
||||
<!--
|
||||
Title: Syndicate Uplink, uses some javascript to change nanoUI up a bit.
|
||||
Used In File(s): \code\game\objects\items\devices\uplinks.dm
|
||||
-->
|
||||
{{:helper.syndicateMode()}}
|
||||
<H2><span class="white">{{:data.welcome}}</span></H2>
|
||||
<br>
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
<b>Functions</b>:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}}
|
||||
{{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}}
|
||||
{{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}}
|
||||
{{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
{{if data.menu == 0}}
|
||||
<H2><span class="white">Request items:</span></H2>
|
||||
<span class="white"><i>Each item costs a number of tele-crystals as indicated by the number following their name.</i></span>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
<b>Tele-Crystals</b>:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.crystals}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{{for data.nano_items}}
|
||||
<div class="item">
|
||||
<H3><span class="white">{{:value.Category}}</span></H3>
|
||||
</div>
|
||||
{{for value.items :itemValue:itemIndex}}
|
||||
<div class="item">
|
||||
{{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - <span class="white">{{:itemValue.Cost}}</span>
|
||||
</div>
|
||||
{{/for}}
|
||||
<br>
|
||||
{{/for}}
|
||||
|
||||
<div class="item">
|
||||
{{:helper.link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, data.crystals <= 0 ? 'disabled' : null, null)}}
|
||||
</div>
|
||||
|
||||
{{else data.menu == 1}}
|
||||
<H2><span class="white">Information Record List:</span></H2>
|
||||
<br>
|
||||
<div class="item">
|
||||
Select a Record
|
||||
</div>
|
||||
<br>
|
||||
{{for data.exploit_records}}
|
||||
<div class="item">
|
||||
{{:helper.link(value.Name, 'gear', {'menu' : 11, 'id' : value.id}, null, null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
|
||||
{{else data.menu == 11}}
|
||||
<H2><span class="white">Information Record:</span></H2>
|
||||
<br>
|
||||
<div class="statusDisplayRecords">
|
||||
<div class="item">
|
||||
<div class="itemContent" style="width: 100%;">
|
||||
{{if data.exploit_exists == 1}}
|
||||
<span class="good">Name: </span> <span class="average">{{:data.exploit.name}} </span><br>
|
||||
<span class="good">Sex: </span> <span class="average">{{:data.exploit.sex}} </span><br>
|
||||
<span class="good">Species: </span> <span class="average">{{:data.exploit.species}} </span><br>
|
||||
<span class="good">Age: </span> <span class="average">{{:data.exploit.age}} </span><br>
|
||||
<span class="good">Rank: </span> <span class="average">{{:data.exploit.rank}} </span><br>
|
||||
<span class="good">Home System: </span> <span class="average">{{:data.exploit.home_system}} </span><br>
|
||||
<span class="good">Citizenship: </span> <span class="average">{{:data.exploit.citizenship}} </span><br>
|
||||
<span class="good">Faction: </span> <span class="average">{{:data.exploit.faction}} </span><br>
|
||||
<span class="good">Religion: </span> <span class="average">{{:data.exploit.religion}} </span><br>
|
||||
<span class="good">Fingerprint: </span> <span class="average">{{:data.exploit.fingerprint}} </span><br>
|
||||
|
||||
<br>Acquired Information:<br>
|
||||
<span class="good">Notes:<br> </span> <span class="average">{{:data.exploit.nanoui_exploit_record}}</span><br><br>
|
||||
{{else}}
|
||||
<span class="bad">
|
||||
No exploitative information acquired!
|
||||
<br>
|
||||
<br>
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<!--
|
||||
Title: Syndicate Uplink, uses some javascript to change nanoUI up a bit.
|
||||
Used In File(s): \code\game\objects\items\devices\uplinks.dm
|
||||
-->
|
||||
{{:helper.syndicateMode()}}
|
||||
<H2><span class="white">{{:data.welcome}}</span></H2>
|
||||
<br>
|
||||
<div class="item">
|
||||
<div class="itemLabelNarrow">
|
||||
<b>Functions</b>:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('Request Items', 'gear', {'menu' : 0}, null, 'fixedLeftWider')}}
|
||||
{{:helper.link('Exploitable Information', 'gear', {'menu' : 1}, null, 'fixedLeftWider')}}
|
||||
{{:helper.link('Return', 'arrowreturn-1-w', {'return' : 1}, null, 'fixedLeft')}}
|
||||
{{:helper.link('Close', 'gear', {'lock' : "1"}, null, 'fixedLeft')}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
{{if data.menu == 0}}
|
||||
<H2><span class="white">Request items:</span></H2>
|
||||
<span class="white"><i>Each item costs a number of tele-crystals as indicated by the number following their name.</i></span>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
<b>Tele-Crystals</b>:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.crystals}}
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
{{for data.nano_items}}
|
||||
<div class="item">
|
||||
<H3><span class="white">{{:value.Category}}</span></H3>
|
||||
</div>
|
||||
{{for value.items :itemValue:itemIndex}}
|
||||
<div class="item">
|
||||
{{:helper.link( itemValue.Name, 'gear', {'buy_item' : itemValue.obj_path, 'cost' : itemValue.Cost}, itemValue.Cost > data.crystals ? 'disabled' : null, null)}} - <span class="white">{{:itemValue.Cost}}</span>
|
||||
</div>
|
||||
|
||||
{{if itemValue.Cost <= data.crystals}}
|
||||
<div class="item">
|
||||
{{:itemValue.Description}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/for}}
|
||||
<br>
|
||||
{{/for}}
|
||||
|
||||
<div class="item">
|
||||
{{:helper.link('Buy Random (??)' , 'gear', {'buy_item' : 'random'}, data.crystals <= 0 ? 'disabled' : null, null)}}
|
||||
</div>
|
||||
|
||||
{{else data.menu == 1}}
|
||||
<H2><span class="white">Information Record List:</span></H2>
|
||||
<br>
|
||||
<div class="item">
|
||||
Select a Record
|
||||
</div>
|
||||
<br>
|
||||
{{for data.exploit_records}}
|
||||
<div class="item">
|
||||
{{:helper.link(value.Name, 'gear', {'menu' : 11, 'id' : value.id}, null, null)}}
|
||||
</div>
|
||||
{{/for}}
|
||||
|
||||
{{else data.menu == 11}}
|
||||
<H2><span class="white">Information Record:</span></H2>
|
||||
<br>
|
||||
<div class="statusDisplayRecords">
|
||||
<div class="item">
|
||||
<div class="itemContent" style="width: 100%;">
|
||||
{{if data.exploit_exists == 1}}
|
||||
<span class="good">Name: </span> <span class="average">{{:data.exploit.name}} </span><br>
|
||||
<span class="good">Sex: </span> <span class="average">{{:data.exploit.sex}} </span><br>
|
||||
<span class="good">Species: </span> <span class="average">{{:data.exploit.species}} </span><br>
|
||||
<span class="good">Age: </span> <span class="average">{{:data.exploit.age}} </span><br>
|
||||
<span class="good">Rank: </span> <span class="average">{{:data.exploit.rank}} </span><br>
|
||||
<span class="good">Home System: </span> <span class="average">{{:data.exploit.home_system}} </span><br>
|
||||
<span class="good">Citizenship: </span> <span class="average">{{:data.exploit.citizenship}} </span><br>
|
||||
<span class="good">Faction: </span> <span class="average">{{:data.exploit.faction}} </span><br>
|
||||
<span class="good">Religion: </span> <span class="average">{{:data.exploit.religion}} </span><br>
|
||||
<span class="good">Fingerprint: </span> <span class="average">{{:data.exploit.fingerprint}} </span><br>
|
||||
|
||||
<br>Acquired Information:<br>
|
||||
<span class="good">Notes:<br> </span> <span class="average">{{:data.exploit.nanoui_exploit_record}}</span><br><br>
|
||||
{{else}}
|
||||
<span class="bad">
|
||||
No exploitative information acquired!
|
||||
<br>
|
||||
<br>
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||