Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesigned Lifeline #4314

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions code/game/machinery/computer/crew.dm
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
. += create_table_notices(list(
"name",
"job",
"is_robot", //MONKESTATION EDIT ADDITION - Displaying robotic species Icon
"life_status",
"suffocation",
"toxin",
Expand All @@ -64,6 +65,7 @@
var/list/entry = list()
entry["name"] = player_record["name"]
entry["job"] = player_record["assignment"]
entry["is_robot"] = player_record["is_robot"] //MONKESTATION EDIT ADDITION - Displaying robotic species Icon
entry["life_status"] = player_record["life_status"]
entry["suffocation"] = player_record["oxydam"]
entry["toxin"] = player_record["toxdam"]
Expand Down Expand Up @@ -108,11 +110,11 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
JOB_SECURITY_ASSISTANT = 18, // monkestation edit: add security assistants
JOB_BRIG_PHYSICIAN = 19, // monkestation edit: add brig physician
// 20-29: Medbay
JOB_CHIEF_MEDICAL_OFFICER = 21,
JOB_CHEMIST = 22,
JOB_VIROLOGIST = 23,
JOB_MEDICAL_DOCTOR = 24,
JOB_PARAMEDIC = 25,
JOB_CHIEF_MEDICAL_OFFICER = 20,
JOB_CHEMIST = 21,
JOB_VIROLOGIST = 22,
JOB_MEDICAL_DOCTOR = 23,
JOB_PARAMEDIC = 24,
// 30-39: Science
JOB_RESEARCH_DIRECTOR = 30,
JOB_SCIENTIST = 31,
Expand Down Expand Up @@ -169,7 +171,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
/datum/crewmonitor/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if (!ui)
ui = new(user, src, "CrewConsole")
ui = new(user, src, "CrewConsoleNova") // MONKESTATION EDIT CHANGE - ORIGINAL: ui = new(user, src, "CrewConsole")
ui.open()

/datum/crewmonitor/proc/show(mob/M, source)
Expand All @@ -193,9 +195,14 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
/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]"]
// MONKESTATION EDIT START
var/nt_net = get_ntnet_wireless_status(z)
// MONKESTATION EDIT END

var/list/results = list()
for(var/tracked_mob in GLOB.suit_sensors_list | GLOB.nanite_sensors_list)
// MONKESTATION EDIT START
/* original - modified and moved into get_tracking_level
if(!tracked_mob)
stack_trace("Null entry in suit sensors or nanite sensors list.")
continue
Expand Down Expand Up @@ -239,6 +246,12 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
continue

sensor_mode = uniform.sensor_mode
*/
var/sensor_mode = get_tracking_level(tracked_mob, z, nt_net)
if (sensor_mode == SENSOR_OFF)
continue
var/mob/living/tracked_living_mob = tracked_mob
// MONKESTATION EDIT END

// The entry for this human
var/list/entry = list(
Expand All @@ -256,6 +269,11 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
if (jobs[trim_assignment] != null)
entry["ijob"] = jobs[trim_assignment]

// MONKESTATION EDIT ADDITION START - Checking for robotic race
if (isipc(tracked_living_mob))
entry["is_robot"] = TRUE
// MONKESTATION EDIT ADDITION END

// Current status
if (sensor_mode >= SENSOR_LIVING)
entry["life_status"] = tracked_living_mob.stat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@
name = "paramedic PDA"
starting_programs = list(
/datum/computer_file/program/records/medical,
/datum/computer_file/program/radar/lifeline,
/datum/computer_file/program/lifeline, // monkestation edit `/datum/computer_file/program/radar/lifeline` -> `/datum/computer_file/program/lifeline`
)

/obj/item/modular_computer/pda/viro
Expand Down
5 changes: 4 additions & 1 deletion code/modules/modular_computers/file_system/programs/radar.dm
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@
if(computer.active_program == src)
START_PROCESSING(SSfastprocess, src)

//MONKESTATION REMOVAL START
/*
///////////////////
//Suit Sensor App//
///////////////////
Expand Down Expand Up @@ -244,7 +246,8 @@
var/obj/item/clothing/under/uniform = humanoid.w_uniform
if(uniform.has_sensor && uniform.sensor_mode >= SENSOR_COORDS) // Suit sensors must be on maximum
return TRUE
return FALSE
return FALSE */
//MONKESTATION REMOVAL END

///Tracks all janitor equipment
/datum/computer_file/program/radar/custodial_locator
Expand Down
53 changes: 53 additions & 0 deletions monkestation/code/game/machinery/computer/crew.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/datum/crewmonitor/proc/get_ntnet_wireless_status(z)
// NTNet is down and we are not connected via wired connection. No signal.
if(!find_functional_ntnet_relay())
return NTNET_NO_SIGNAL

if(is_station_level(z))
return NTNET_GOOD_SIGNAL
else if(is_mining_level(z))
return NTNET_LOW_SIGNAL
return NTNET_NO_SIGNAL

/datum/crewmonitor/proc/get_tracking_level(tracked_mob, z, nt_net)
if(!tracked_mob)
stack_trace("Null entry in suit sensors or nanite sensors list.")
return SENSOR_OFF

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])")
return SENSOR_OFF

// Machinery and the target should be on the same level or different levels of the same station
if(pos.z != z && !(z in SSmapping.get_connected_levels(pos.z)) && !(nt_net && get_ntnet_wireless_status(pos.z)) && !HAS_TRAIT(tracked_living_mob, TRAIT_MULTIZ_SUIT_SENSORS))
return SENSOR_OFF

// 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)
return SENSOR_COORDS

var/mob/living/carbon/human/tracked_human = tracked_living_mob

// Check their humanity.
if(!ishuman(tracked_human))
stack_trace("Non-human mob is in suit_sensors_list: [tracked_living_mob] ([tracked_living_mob.type])")
return SENSOR_OFF

// Check they have a uniform
var/obj/item/clothing/under/uniform = tracked_human.w_uniform
if (!istype(uniform))
stack_trace("Human without a suit sensors compatible uniform is in suit_sensors_list: [tracked_human] ([tracked_human.type]) ([uniform?.type])")
return SENSOR_OFF

// Check if their uniform is in a compatible mode.
if((uniform.has_sensor <= NO_SENSORS) || !uniform.sensor_mode)
stack_trace("Human without active suit sensors is in suit_sensors_list: [tracked_human] ([tracked_human.type]) ([uniform.type])")
return SENSOR_OFF

return uniform.sensor_mode
36 changes: 5 additions & 31 deletions monkestation/code/modules/blueshield/devices/crew_monitor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -50,40 +50,14 @@ GLOBAL_DATUM_INIT(blueshield_crewmonitor, /datum/crewmonitor/blueshield, new)
/datum/crewmonitor/blueshield/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/nt_net = GLOB.crewmonitor.get_ntnet_wireless_status(z)

var/list/results = list()
for(var/tracked_mob in GLOB.suit_sensors_list)
if(!tracked_mob)
stack_trace("Null entry in suit sensors list.")
for(var/tracked_mob in GLOB.suit_sensors_list | GLOB.nanite_sensors_list)
var/sensor_mode = GLOB.crewmonitor.get_tracking_level(tracked_mob, z, nt_net)
if (sensor_mode == SENSOR_OFF)
continue

var/mob/living/tracked_living_mob = tracked_mob

var/turf/pos = get_turf(tracked_living_mob)

if(!pos)
stack_trace("Tracked mob has no loc and is likely in nullspace: [tracked_living_mob] ([tracked_living_mob.type])")
continue

if(pos.z != z && (!is_station_level(pos.z) || !is_station_level(z)) && !HAS_TRAIT(tracked_living_mob, TRAIT_MULTIZ_SUIT_SENSORS))
continue

var/mob/living/carbon/human/tracked_human = tracked_living_mob

if(!ishuman(tracked_human))
stack_trace("Non-human mob is in suit_sensors_list: [tracked_living_mob] ([tracked_living_mob.type])")
continue

var/obj/item/clothing/under/uniform = tracked_human.w_uniform
if (!istype(uniform))
stack_trace("Human without a suit sensors compatible uniform is in suit_sensors_list: [tracked_human] ([tracked_human.type]) ([uniform?.type])")
continue

if((uniform.has_sensor <= NO_SENSORS) || !uniform.sensor_mode)
stack_trace("Human without active suit sensors is in suit_sensors_list: [tracked_human] ([tracked_human.type]) ([uniform.type])")
continue

var/sensor_mode = uniform.sensor_mode
var/list/entry = list()

var/obj/item/card/id/id_card = tracked_living_mob.get_idcard(hand_first = FALSE)
Expand All @@ -99,7 +73,7 @@ GLOBAL_DATUM_INIT(blueshield_crewmonitor, /datum/crewmonitor/blueshield, new)
else
continue

if (isipc(tracked_human))
if (isipc(tracked_living_mob))
entry["is_robot"] = TRUE

if (sensor_mode >= SENSOR_LIVING)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/datum/computer_file/program/records/medical,
/datum/computer_file/program/crew_manifest,
/datum/computer_file/program/robocontrol,
/datum/computer_file/program/radar/lifeline, // For finding security officers
/datum/computer_file/program/lifeline, // For finding security officers
)

/obj/item/modular_computer/pda/engineering
Expand Down Expand Up @@ -43,7 +43,7 @@
/datum/computer_file/program/records/security,
/datum/computer_file/program/crew_manifest,
/datum/computer_file/program/robocontrol,
/datum/computer_file/program/radar/lifeline,
/datum/computer_file/program/lifeline,
)

/obj/item/modular_computer/pda/signal
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/datum/computer_file/program/lifeline
filename = "lifeline"
filedesc = "Lifeline"
extended_desc = "This program allows for tracking of crew members via their suit sensors."
transfer_access = list(ACCESS_MEDICAL)
category = PROGRAM_CATEGORY_CREW
ui_header = "borg_mon.gif" //DEBUG -- new icon before PR (classic)
program_icon_state = "radarntos"
// requires_ntnet = TRUE -- disabled to be constistent with the paramedic's crew monitor
available_on_ntnet = TRUE
usage_flags = PROGRAM_LAPTOP | PROGRAM_TABLET
size = 5
tgui_id = "NtosLifeline"
program_icon = "heartbeat"

// Tracking information
var/list/sensors = list()
var/mob/living/selected
var/last_update_time

// UI Settings
var/sort_asc = TRUE
var/sort_by = "dist"
var/blueshield = FALSE

///Used to keep track of the last value program_icon_state was set to, to prevent constant unnecessary update_appearance() calls
var/last_icon_state = ""


/datum/computer_file/program/lifeline/on_start(mob/living/user)
. = ..()
if(.)
blueshield = istype(computer, /obj/item/modular_computer/pda/blueshield)
START_PROCESSING(SSfastprocess, src)

/datum/computer_file/program/lifeline/kill_program(mob/user)
sensors = list()
selected = null
STOP_PROCESSING(SSfastprocess, src)
return ..()

/datum/computer_file/program/lifeline/Destroy()
STOP_PROCESSING(SSfastprocess, src)
return ..()

/datum/computer_file/program/lifeline/ui_data(mob/user)
return list(
"selected" = selected,
"sensors" = update_sensors(),
"settings" = list(
"blueshield" = blueshield,
"sortAsc" = sort_asc,
"sortBy" = sort_by
)
)

/datum/computer_file/program/lifeline/ui_act(action, params, datum/tgui/ui, datum/ui_state/state)
switch(action)
if("select")
selected = params["ref"]
if("sortAsc")
sort_asc = params["val"]
if("sortBy")
sort_by = params["val"]
if("blueshield")
blueshield = params["val"]
return TRUE

/datum/computer_file/program/lifeline/proc/update_sensors()
var/turf/pos = get_turf(computer)
if (world.time <= last_update_time + 3 SECONDS && sensors)
return sensors
var/nt_net = GLOB.crewmonitor.get_ntnet_wireless_status(pos.z)

sensors = list()
for(var/tracked_mob in GLOB.suit_sensors_list | GLOB.nanite_sensors_list)
var/sensor_mode = GLOB.crewmonitor.get_tracking_level(tracked_mob, pos.z, nt_net)
if (sensor_mode == SENSOR_OFF)
continue
var/mob/living/tracked_living_mob = tracked_mob

var/turf/sensor_pos = get_turf(tracked_living_mob)

var/list/crewinfo = list(
ref = REF(tracked_living_mob),
name = "Unknown",
ijob = 81, // UNKNOWN_JOB_ID from crew.dm
dist = -1, // This value tells the UI that location is disabled
)

if (sensor_pos.z == pos.z || (sensor_pos.z in SSmapping.get_connected_levels(pos.z)))
if (sensor_mode == SENSOR_COORDS)
crewinfo["zdiff"] = sensor_pos.z-pos.z
crewinfo["dist"] = max(get_dist(pos, sensor_pos), 0)
crewinfo["degrees"] = round(get_angle(pos, sensor_pos))
crewinfo["area"] = get_area_name(tracked_living_mob, format_text = TRUE)
else // tracking through NT Net
crewinfo["zdiff"] = is_station_level(sensor_pos.z) ? 0 : -1 // 0: on station, -1: mining
if (sensor_mode == SENSOR_COORDS)
crewinfo["dist"] = -2 // This value tells the UI that tracking is through NT Net
crewinfo["area"] = get_area_name(tracked_living_mob, format_text = TRUE)
else
crewinfo["dist"] = -3 // This value tells the UI that tracking is through NT Net and location is disabled

var/obj/item/card/id/id_card = tracked_living_mob.get_idcard(hand_first = FALSE)
if(id_card)
crewinfo["name"] = id_card.registered_name
crewinfo["assignment"] = id_card.assignment
var/trim_assignment = id_card.get_trim_assignment()
if (GLOB.crewmonitor.jobs[trim_assignment] != null)
crewinfo["trim"] = trim_assignment
crewinfo["ijob"] = GLOB.crewmonitor.jobs[trim_assignment]

sensors += list(crewinfo)
last_update_time = world.time
return sensors

//We use SSfastprocess for the program icon state because it runs faster than process_tick() does.
/datum/computer_file/program/lifeline/process()
if(computer.active_program != src)
STOP_PROCESSING(SSfastprocess, src) //We're not the active program, it's time to stop.
return
if(!selected)
return

var/atom/movable/signal = locate(selected) in GLOB.human_list
var/turf/here_turf = get_turf(computer)
if(GLOB.crewmonitor.get_tracking_level(signal, here_turf.z, nt_net=FALSE) != SENSOR_COORDS)
program_icon_state = "[initial(program_icon_state)]lost"
if(last_icon_state != program_icon_state)
computer.update_appearance()
last_icon_state = program_icon_state
return

var/turf/target_turf = get_turf(signal)
var/trackdistance = get_dist_euclidean(here_turf, target_turf)
switch(trackdistance)
if(0)
program_icon_state = "[initial(program_icon_state)]direct"
if(1 to 12)
program_icon_state = "[initial(program_icon_state)]close"
if(13 to 24)
program_icon_state = "[initial(program_icon_state)]medium"
if(25 to INFINITY)
program_icon_state = "[initial(program_icon_state)]far"

if(last_icon_state != program_icon_state)
computer.update_appearance()
last_icon_state = program_icon_state
computer.setDir(get_dir(here_turf, target_turf))

//We can use process_tick to restart fast processing, since the computer will be running this constantly either way.
/datum/computer_file/program/lifeline/process_tick(seconds_per_tick)
if(computer.active_program == src)
START_PROCESSING(SSfastprocess, src)
Loading
Loading