mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-15 18:14:22 +01:00
6e9f2ccfc0
# Conflicts: # .github/workflows/compile_all_maps.yml # .github/workflows/run_integration_tests.yml # _maps/map_files/CatwalkStation/CatwalkStation_2023.dmm # code/_onclick/hud/credits.dm # code/controllers/subsystem/networks/id_access.dm # code/datums/diseases/advance/advance.dm # code/datums/diseases/advance/symptoms/heal.dm # code/game/machinery/doors/door.dm # code/game/objects/structures/crates_lockers/closets/secure/medical.dm # code/game/objects/structures/crates_lockers/closets/secure/security.dm # code/modules/antagonists/malf_ai/malf_ai_modules.dm # code/modules/jobs/job_types/_job.dm # code/modules/loadout/categories/accessories.dm # code/modules/loadout/loadout_helpers.dm # code/modules/loadout/loadout_items.dm # code/modules/loadout/loadout_preference.dm # code/modules/mob/living/silicon/robot/robot_defense.dm # code/modules/mod/mod_theme.dm # code/modules/projectiles/ammunition/energy/laser.dm # code/modules/reagents/reagent_containers/cups/drinks.dm # code/modules/shuttle/mobile_port/variants/supply.dm # code/modules/surgery/organs/internal/eyes/_eyes.dm # code/modules/unit_tests/screenshots/screenshot_antag_icons_heretic.png # icons/hud/screen_full.dmi
346 lines
12 KiB
Plaintext
346 lines
12 KiB
Plaintext
/// How often the sensor data is updated // BUBBER EDIT REMOVAL - Defined in code/__DEFINES/~~bubber_defines/misc.dm
|
|
// #define SENSORS_UPDATE_PERIOD (10 SECONDS) //How often the sensor data updates.
|
|
/// The job sorting ID associated with otherwise unknown jobs
|
|
#define UNKNOWN_JOB_ID 998
|
|
|
|
/obj/machinery/computer/crew
|
|
name = "crew monitoring console"
|
|
desc = "Used to monitor active health sensors built into most of the crew's uniforms."
|
|
icon_screen = "crew"
|
|
icon_keyboard = "med_key"
|
|
circuit = /obj/item/circuitboard/computer/crew
|
|
light_color = LIGHT_COLOR_BLUE
|
|
|
|
/obj/machinery/computer/crew/Initialize(mapload, obj/item/circuitboard/C)
|
|
. = ..()
|
|
AddComponent(/datum/component/usb_port, typecacheof(list(/obj/item/circuit_component/medical_console_data), only_root_path = TRUE))
|
|
|
|
/obj/item/circuit_component/medical_console_data
|
|
display_name = "Crew Monitoring Data"
|
|
desc = "Outputs the medical statuses of people on the crew monitoring computer, where it can then be filtered with a Select Query component."
|
|
circuit_flags = CIRCUIT_FLAG_INPUT_SIGNAL|CIRCUIT_FLAG_OUTPUT_SIGNAL
|
|
|
|
/// The records retrieved
|
|
var/datum/port/output/records
|
|
|
|
var/obj/machinery/computer/crew/attached_console
|
|
|
|
/obj/item/circuit_component/medical_console_data/populate_ports()
|
|
records = add_output_port("Crew Monitoring Data", PORT_TYPE_TABLE)
|
|
|
|
/obj/item/circuit_component/medical_console_data/register_usb_parent(atom/movable/shell)
|
|
. = ..()
|
|
if(istype(shell, /obj/machinery/computer/crew))
|
|
attached_console = shell
|
|
|
|
/obj/item/circuit_component/medical_console_data/unregister_usb_parent(atom/movable/shell)
|
|
attached_console = null
|
|
return ..()
|
|
|
|
/obj/item/circuit_component/medical_console_data/get_ui_notices()
|
|
. = ..()
|
|
. += create_table_notices(list(
|
|
"name",
|
|
"job",
|
|
"is_robot", //SKYRAT EDIT ADDITION - Displaying robotic species Icon
|
|
"is_dnr", //BUBBERSTATION EDIT ADDITION - Displays DNR status
|
|
"life_status",
|
|
"suffocation",
|
|
"toxin",
|
|
"burn",
|
|
"brute",
|
|
"location",
|
|
"health",
|
|
))
|
|
|
|
|
|
/obj/item/circuit_component/medical_console_data/input_received(datum/port/input/port)
|
|
|
|
if(!attached_console || !GLOB.crewmonitor)
|
|
return
|
|
|
|
var/list/new_table = list()
|
|
for(var/list/player_record as anything in GLOB.crewmonitor.update_data(attached_console.z))
|
|
var/list/entry = list()
|
|
entry["name"] = player_record["name"]
|
|
entry["job"] = player_record["assignment"]
|
|
entry["is_robot"] = player_record["is_robot"] //SKYRAT EDIT ADDITION - Displaying robotic species Icon
|
|
entry["life_status"] = player_record["life_status"]
|
|
entry["suffocation"] = player_record["oxydam"]
|
|
entry["toxin"] = player_record["toxdam"]
|
|
entry["burn"] = player_record["burndam"]
|
|
entry["brute"] = player_record["brutedam"]
|
|
entry["location"] = player_record["area"]
|
|
entry["health"] = player_record["health"]
|
|
new_table += list(entry)
|
|
|
|
records.set_output(new_table)
|
|
|
|
/obj/machinery/computer/crew/syndie
|
|
icon_keyboard = "syndie_key"
|
|
|
|
/obj/machinery/computer/crew/ui_interact(mob/user)
|
|
. = ..()
|
|
GLOB.crewmonitor.show(user,src)
|
|
|
|
GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
|
|
|
|
/datum/crewmonitor
|
|
/// List of user -> UI source
|
|
var/list/ui_sources = list()
|
|
/// Cache of data generated by z-level, used for serving the data within SENSOR_UPDATE_PERIOD of the last update
|
|
var/list/data_by_z = list()
|
|
/// Cache of last update time for each z-level
|
|
var/list/last_update = list()
|
|
/// Map of job to ID for sorting purposes
|
|
var/list/jobs = list(
|
|
// Note that jobs divisible by 10 are considered heads of staff, and bolded
|
|
// 00: Captain
|
|
JOB_CAPTAIN = 0,
|
|
JOB_HUMAN_AI = 1,
|
|
// 10-19: Security
|
|
JOB_HEAD_OF_SECURITY = 10,
|
|
JOB_WARDEN = 11,
|
|
JOB_SECURITY_OFFICER = 12,
|
|
/* SKYRAT EDIT REMOVAL - We need those slots for our own jobs, these jobs aren't on Skyrat anymore anyway.
|
|
JOB_SECURITY_OFFICER_MEDICAL = 13,
|
|
JOB_SECURITY_OFFICER_ENGINEERING = 14,
|
|
JOB_SECURITY_OFFICER_SCIENCE = 15,
|
|
JOB_SECURITY_OFFICER_SUPPLY = 16,
|
|
*/
|
|
JOB_SECURITY_MEDIC = 13, // BUBBER EDIT ADDITION
|
|
JOB_CORRECTIONS_OFFICER = 14, // SKYRAT EDIT ADDITION
|
|
JOB_DETECTIVE = 15,
|
|
// 20-29: Medbay
|
|
JOB_CHIEF_MEDICAL_OFFICER = 20,
|
|
JOB_CHEMIST = 21,
|
|
JOB_MEDICAL_DOCTOR = 22,
|
|
JOB_PARAMEDIC = 23,
|
|
JOB_CORONER = 24,
|
|
JOB_ORDERLY = 25, // SKYRAT EDIT ADDITION
|
|
JOB_PSYCHOLOGIST = 26, // SKYRAT EDIT - ORIGINAL: JOB_PSYCHOLOGIST = 71,
|
|
// 30-39: Science
|
|
JOB_RESEARCH_DIRECTOR = 30,
|
|
JOB_SCIENTIST = 31,
|
|
JOB_ROBOTICIST = 32,
|
|
JOB_GENETICIST = 33,
|
|
JOB_SCIENCE_GUARD = 34, // SKYRAT EDIT ADDITION
|
|
// 40-49: Engineering
|
|
JOB_CHIEF_ENGINEER = 40,
|
|
JOB_STATION_ENGINEER = 41,
|
|
JOB_ATMOSPHERIC_TECHNICIAN = 42,
|
|
JOB_ENGINEERING_GUARD = 43, // SKYRAT EDIT ADDITION
|
|
JOB_TELECOMMS_SPECIALIST = 44, // SKYRAT EDIT ADDITION
|
|
// 50-59: Cargo
|
|
JOB_QUARTERMASTER = 50,
|
|
JOB_SHAFT_MINER = 51,
|
|
JOB_CARGO_TECHNICIAN = 52,
|
|
JOB_BITRUNNER = 53,
|
|
JOB_CUSTOMS_AGENT = 54, // SKYRAT EDIT ADDITION
|
|
JOB_BLACKSMITH = 55, // Bubber edit Addition!
|
|
// 60+: Service
|
|
JOB_HEAD_OF_PERSONNEL = 60,
|
|
JOB_BARTENDER = 61,
|
|
JOB_CHEF = 62,
|
|
JOB_COOK = 63,
|
|
JOB_BOTANIST = 64,
|
|
JOB_CURATOR = 65,
|
|
JOB_CHAPLAIN = 66,
|
|
JOB_CLOWN = 67,
|
|
JOB_MIME = 68,
|
|
JOB_JANITOR = 69,
|
|
JOB_LAWYER = 71,
|
|
JOB_BARBER = 74, // SKYRAT EDIT ADDITION
|
|
JOB_BOUNCER = 73, // SKYRAT EDIT ADDITION
|
|
JOB_PSYCHOLOGIST = 72,
|
|
// 200-229: Centcom
|
|
JOB_CENTCOM_ADMIRAL = 200,
|
|
JOB_CENTCOM = 201,
|
|
JOB_CENTCOM_OFFICIAL = 210,
|
|
JOB_CENTCOM_COMMANDER = 211,
|
|
JOB_CENTCOM_BARTENDER = 212,
|
|
JOB_CENTCOM_CUSTODIAN = 213,
|
|
JOB_CENTCOM_MEDICAL_DOCTOR = 214,
|
|
JOB_CENTCOM_RESEARCH_OFFICER = 215,
|
|
JOB_ERT_COMMANDER = 220,
|
|
JOB_ERT_OFFICER = 221,
|
|
JOB_ERT_ENGINEER = 222,
|
|
JOB_ERT_MEDICAL_DOCTOR = 223,
|
|
JOB_ERT_CLOWN = 224,
|
|
JOB_ERT_CHAPLAIN = 225,
|
|
JOB_ERT_JANITOR = 226,
|
|
JOB_ERT_DEATHSQUAD = 227,
|
|
JOB_NT_REP = 230, // SKYRAT EDIT ADDITION
|
|
JOB_BLUESHIELD = 231, // SKYRAT EDIT ADDITION
|
|
|
|
// ANYTHING ELSE = UNKNOWN_JOB_ID, Unknowns/custom jobs will appear after civilians, and before assistants
|
|
JOB_ASSISTANT = 999,
|
|
)
|
|
|
|
/datum/crewmonitor/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if (!ui)
|
|
ui = new(user, src, "CrewConsoleBubbers") // BUBBER EDIT CHANGE - Crew Console
|
|
ui.open()
|
|
|
|
/datum/crewmonitor/proc/show(mob/M, source)
|
|
ui_sources[WEAKREF(M)] = WEAKREF(source)
|
|
ui_interact(M)
|
|
|
|
/datum/crewmonitor/ui_host(mob/user)
|
|
var/datum/weakref/host_ref = ui_sources[WEAKREF(user)]
|
|
return host_ref?.resolve()
|
|
|
|
/datum/crewmonitor/ui_data(mob/user)
|
|
var/z = user.z
|
|
if(!z)
|
|
var/turf/T = get_turf(user)
|
|
z = T.z
|
|
. = list(
|
|
"sensors" = update_data(z),
|
|
"link_allowed" = HAS_AI_ACCESS(user),
|
|
)
|
|
|
|
/datum/crewmonitor/proc/update_data(z)
|
|
if(data_by_z["[z]"] && last_update["[z]"] && world.time <= last_update["[z]"] + SENSORS_UPDATE_PERIOD)
|
|
return data_by_z["[z]"]
|
|
|
|
var/list/results = list()
|
|
for(var/tracked_mob in GLOB.suit_sensors_list | GLOB.nanite_sensors_list) // BUBBER CHANGE - NANITES
|
|
if(!tracked_mob)
|
|
stack_trace("Null entry in suit sensors or nanite sensors list.") // BUBBER CHANGE - NANITES
|
|
continue
|
|
|
|
var/mob/living/tracked_living_mob = tracked_mob
|
|
|
|
// Check if z-level is correct
|
|
var/turf/pos = get_turf(tracked_living_mob)
|
|
|
|
// Is our target in nullspace for some reason?
|
|
if(!pos)
|
|
stack_trace("Tracked mob has no loc and is likely in nullspace: [tracked_living_mob] ([tracked_living_mob.type])")
|
|
continue
|
|
|
|
// Machinery and the target should be on the same level or different levels of the same station
|
|
if(pos.z != z && (!is_station_level(pos.z) || !is_station_level(z)) && !HAS_TRAIT(tracked_living_mob, TRAIT_MULTIZ_SUIT_SENSORS))
|
|
continue
|
|
|
|
var/sensor_mode // BUBBER ADDITION - NANITES
|
|
var/has_monitoring_nanites = FALSE // BUBBER ADDITION - NANITES
|
|
var/mob/living/carbon/human/tracked_human = tracked_living_mob
|
|
|
|
// Set sensor level based on whether we're in the nanites list or the suit sensor list.
|
|
if(tracked_living_mob in GLOB.nanite_sensors_list) // BUBBER CHANGE - NANITES
|
|
sensor_mode = SENSOR_COORDS
|
|
has_monitoring_nanites = TRUE
|
|
|
|
if(!ishuman(tracked_human))
|
|
stack_trace("Non-human mob is in suit_sensors_list: [tracked_living_mob] ([tracked_living_mob.type])")
|
|
continue
|
|
|
|
// BUBBER CHANGE START - NANITES
|
|
// Check they have a uniform
|
|
var/obj/item/clothing/under/uniform = tracked_human.w_uniform
|
|
if(!has_monitoring_nanites)
|
|
// they don't have nanites, lets check uniform
|
|
if(!istype(uniform))
|
|
// no uniform, somethings fucked
|
|
stack_trace("Human without a uniform or nanites is in suit_sensors_list: [tracked_human] ([tracked_human.type])")
|
|
continue
|
|
else
|
|
// they have a uniform, lets check sensor status
|
|
if(uniform.has_sensor == NO_SENSORS)
|
|
// no sensors in the uniform, somethings fucked
|
|
stack_trace("Human without a suit sensors compatible uniform or nanites is in suit_sensors_list: [tracked_human] ([tracked_human.type]) ([uniform.type])")
|
|
continue
|
|
if(!uniform.sensor_mode)
|
|
// sensors are disabled, somethings fucked
|
|
stack_trace("Human without active suit sensors or nanites is in suit_sensors_list: [tracked_human] ([tracked_human.type]) ([uniform.type])")
|
|
continue
|
|
sensor_mode = uniform.sensor_mode
|
|
// BUBBER CHANGE END - NANITES
|
|
|
|
// The entry for this human
|
|
var/list/entry = list(
|
|
"ref" = REF(tracked_living_mob),
|
|
"name" = "Unknown",
|
|
"ijob" = UNKNOWN_JOB_ID,
|
|
)
|
|
|
|
// ID and id-related data
|
|
var/obj/item/card/id/id_card = tracked_living_mob.get_idcard(hand_first = FALSE)
|
|
if (id_card)
|
|
entry["name"] = id_card.registered_name
|
|
entry["assignment"] = id_card.assignment
|
|
var/trim_assignment = id_card.get_trim_assignment()
|
|
if (jobs[trim_assignment] != null)
|
|
entry["ijob"] = jobs[trim_assignment]
|
|
|
|
// BUBBER EDIT BEGIN: Checking for robotic race/Proteans
|
|
if (issynthetic(tracked_human) || isprotean(tracked_human))
|
|
entry["is_robot"] = TRUE
|
|
// BUBBER EDIT END
|
|
|
|
// Broken sensors show garbage data
|
|
if (uniform?.has_sensor == BROKEN_SENSORS) // BUBBER EDIT CHANGE - NANITES - Original: if (uniform.has_sensor == BROKEN_SENSORS)
|
|
entry["life_status"] = 1 // BUBBER EDIT CHANGE - Original: rand(0,1) - Mob stays in consistent list position when sensors are broken
|
|
entry["area"] = pick_list (ION_FILE, "ionarea")
|
|
entry["oxydam"] = rand(0,175)
|
|
entry["toxdam"] = rand(0,175)
|
|
entry["burndam"] = rand(0,175)
|
|
entry["brutedam"] = rand(0,175)
|
|
entry["health"] = -50
|
|
results[++results.len] = entry
|
|
continue
|
|
|
|
// BUBBERSTATION EDIT BEGIN: Add DNR status, proteans death state.
|
|
// If sensors are above living tracking, set DNR state
|
|
if (sensor_mode >= SENSOR_LIVING)
|
|
entry["is_dnr"] = tracked_human.get_dnr()
|
|
// Current status
|
|
var/obj/item/organ/brain/protean/protean_brain = tracked_human.get_organ_slot(ORGAN_SLOT_BRAIN)
|
|
if(istype(protean_brain))
|
|
if(!isprotean(tracked_human))
|
|
stack_trace("[tracked_human] brain-species mismatch! Species is [tracked_human.dna.species] but brain is Protean")
|
|
entry["life_status"] = protean_brain?.dead ? DEAD : tracked_living_mob.stat // If brain not dead/no brain then handling as usual
|
|
else
|
|
entry["life_status"] = tracked_living_mob.stat
|
|
// BUBBERSTATION EDIT END
|
|
|
|
// Damage
|
|
if (sensor_mode >= SENSOR_VITALS)
|
|
entry += list(
|
|
"oxydam" = round(tracked_living_mob.get_oxy_loss(), 1),
|
|
"toxdam" = round(tracked_living_mob.get_tox_loss(), 1),
|
|
"burndam" = round(tracked_living_mob.get_fire_loss(), 1),
|
|
"brutedam" = round(tracked_living_mob.get_brute_loss(), 1),
|
|
"health" = round(tracked_living_mob.health, 1),
|
|
)
|
|
|
|
// Location
|
|
if (sensor_mode >= SENSOR_COORDS)
|
|
entry["area"] = get_area_name(tracked_living_mob, format_text = TRUE)
|
|
|
|
results[++results.len] = entry
|
|
|
|
// Cache result
|
|
data_by_z["[z]"] = results
|
|
last_update["[z]"] = world.time
|
|
|
|
return results
|
|
|
|
/datum/crewmonitor/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
|
|
|
. = ..()
|
|
if(.)
|
|
return
|
|
switch (action)
|
|
if ("select_person")
|
|
var/mob/living/silicon/ai/AI = usr
|
|
if(!istype(AI))
|
|
return
|
|
AI.ai_tracking_tool.track_name(AI, params["name"])
|
|
|
|
// #undef SENSORS_UPDATE_PERIOD // BUBBER EDIT REMOVAL - Defined in code/__DEFINES/~~bubber_defines/misc.dm
|
|
#undef UNKNOWN_JOB_ID
|