Files
Bubberstation/code/modules/modular_computers/file_system/programs/radar.dm
zxaber 5a07c3f29a Adds two new modular apps: Lifeline for tracking suit sensors, and the Syndicate-only Fission360 for tracking nuke-related items (#51152)
About The Pull Request

    Adds two new modular computer programs. Both use the same underlying parts;
    -- Lifeline is an improved suit sensor tracker, showing where the target is on a grid if they're within 24 tiles. The scan button has a two-second delay (since the program has to check every humanoid in glob.human_list for trackability and we don't want that spammed). The app works pretty much how you would expect.
    -- Fission360 uses the same processes as above but for the nuke disk and all nukes in the area (self destruct, beer, syndicate). Available only via emagging a tablet for the moment.
    --
    Rudimentary multiZ support exists, in the form of replacing the crosshairs icon with an up or down arrow (once it's visible within the circle) to indicate if the target is above or below, if both the target and the computer are on a station Z level of some sort. Also, the grid lines are exactly two-tiles apart.

    Added support for programs to list special assets to load, so that we don't have to have every program loading all modular program assets. The radar apps use this to load the background grid and the too-far-away-to-display arrow.

Why It's Good For The Game

More modular apps are good. I'm hoping to see a syndicate-version of the modular tablet in the hands of nuke ops at some point, which is really where Fission360 will make sense. Otherwise, it's an extra tool for traitors with the nuke theft objective, I suppose.
Changelog

cl
add: Two new apps for modular computers are available: Lifeline for Medical, and Fission360 for anyone with access to the Syndicate repository. Lifeline is an improved suit sensors tracker, and Fission360 is the same but for nuclear-related things.
/cl
2020-05-27 15:36:28 +12:00

250 lines
7.2 KiB
Plaintext

/datum/computer_file/program/radar //generic parent that handles most of the process
filename = "genericfinder"
filedesc = "debug_finder"
ui_header = "borg_mon.gif" //DEBUG -- new icon before PR
program_icon_state = "generic"
extended_desc = "generic"
requires_ntnet = TRUE
transfer_access = null
available_on_ntnet = FALSE
network_destination = "tracking program"
size = 5
tgui_id = "NtosRadar"
ui_x = 800
ui_y = 600
special_assets = list(
/datum/asset/simple/radar_assets,
)
///List of trackable entities. Updated by the scan() proc.
var/list/objects
///Ref of the last trackable object selected by the user in the tgui window. Updated in the ui_act() proc.
var/atom/selected
///Used to store when the next scan is available. Updated by the scan() proc.
var/next_scan = 0
/datum/computer_file/program/radar/kill_program(forced = FALSE)
objects = list()
selected = null
return ..()
/datum/computer_file/program/radar/ui_data(mob/user)
var/list/data = get_header_data()
data["selected"] = selected
data["objects"] = list()
data["scanning"] = (world.time < next_scan)
for(var/list/i in objects)
var/list/objectdata = list(
ref = i["ref"],
name = i["name"],
)
data["object"] += list(objectdata)
data["target"] = list()
var/list/trackinfo = track()
if(trackinfo)
data["target"] = trackinfo
return data
/datum/computer_file/program/radar/ui_act(action, params)
if(..())
return
switch(action)
if("selecttarget")
selected = params["ref"]
if("scan")
scan()
/**
*Updates tracking information of the selected target.
*
*The track() proc updates the entire set of information about the location
*of the target, including whether the Ntos window should use a pinpointer
*crosshair over the up/down arrows, or none in favor of a rotating arrow
*for far away targets. This information is returned in the form of a list.
*
*/
/datum/computer_file/program/radar/proc/track()
return
/**
*
*Checks the trackability of the selected target.
*
*If the target is on the computer's Z level, or both are on station Z
*levels, and the target isn't untrackable, return TRUE.
*Arguments:
**arg1 is the atom being evaluated.
*/
/datum/computer_file/program/radar/proc/trackable(atom/movable/signal)
if(!signal)
return FALSE
var/turf/here = get_turf(computer)
var/turf/there = get_turf(signal)
return (there.z == here.z) || (is_station_level(here.z) && is_station_level(there.z))
/**
*
*Runs a scan of all the trackable atoms.
*
*Checks each entry in the GLOB of the specific trackable atoms against
*the track() proc, and fill the objects list with lists containing the
*atoms' names and REFs. The objects list is handed to the tgui screen
*for displaying to, and being selected by, the user. A two second
*sleep is used to delay the scan, both for thematical reasons as well
*as to limit the load players may place on the server using these
*somewhat costly loops.
*/
/datum/computer_file/program/radar/proc/scan()
return
///////////////////
//Suit Sensor App//
///////////////////
///A program that tracks crew members via suit sensors
/datum/computer_file/program/radar/lifeline
filename = "Lifeline"
filedesc = "Lifeline"
program_icon_state = "generic"
extended_desc = "This program allows for tracking of crew members via their suit sensors."
requires_ntnet = TRUE
transfer_access = ACCESS_MEDICAL
available_on_ntnet = TRUE
/datum/computer_file/program/radar/lifeline/track()
var/mob/living/carbon/human/humanoid = locate(selected) in GLOB.human_list
if(!istype(humanoid) || !trackable(humanoid))
return
var/turf/here_turf = (get_turf(computer))
var/turf/target_turf = (get_turf(humanoid))
var/userot = FALSE
var/rot = 0
var/pointer="crosshairs"
var/locx = (target_turf.x - here_turf.x)
var/locy = (here_turf.y - target_turf.y)
if(get_dist_euclidian(here_turf, target_turf) > 24) //If they're too far away, we need the angle for the arrow along the edge of the radar display
userot = TRUE
rot = round(Get_Angle(here_turf, target_turf))
else
locx = locx + 24
locy = locy + 24
if(target_turf.z > here_turf.z)
pointer="caret-up"
else if(target_turf.z < here_turf.z)
pointer="caret-down"
var/list/trackinfo = list(
locx = locx,
locy = locy,
userot = userot,
rot = rot,
arrowstyle = "ntosradarpointer.png", //For the rotation arrow, it's stupid I know
color = "green",
pointer = pointer,
)
return trackinfo
/datum/computer_file/program/radar/lifeline/scan()
if(world.time < next_scan)
return
next_scan = world.time + (2 SECONDS)
objects = list()
for(var/i in GLOB.human_list)
var/mob/living/carbon/human/humanoid = i
if(!trackable(humanoid))
continue
var/crewmember_name = "Unknown"
if(humanoid.wear_id)
var/obj/item/card/id/ID = humanoid.wear_id.GetID()
if(ID && ID.registered_name)
crewmember_name = ID.registered_name
var/list/crewinfo = list(
ref = REF(humanoid),
name = crewmember_name,
)
objects += list(crewinfo)
/datum/computer_file/program/radar/lifeline/trackable(mob/living/carbon/human/humanoid)
if(!humanoid || !istype(humanoid))
return FALSE
if(..() && istype(humanoid.w_uniform, /obj/item/clothing/under))
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 FALSE
return TRUE
////////////////////////
//Nuke Disk Finder App//
////////////////////////
///A program that tracks crew members via suit sensors
/datum/computer_file/program/radar/fission360
filename = "Fission360"
filedesc = "Fission360"
program_icon_state = "generic"
extended_desc = "This program allows for tracking of nuclear authorization disks and warheads."
requires_ntnet = FALSE
transfer_access = null
available_on_ntnet = FALSE
available_on_syndinet = TRUE
tgui_id = "NtosRadarSyndicate"
/datum/computer_file/program/radar/fission360/track()
var/obj/nuke = locate(selected) in GLOB.poi_list
if(!trackable(nuke))
return
var/turf/here_turf = (get_turf(computer))
var/turf/target_turf = (get_turf(nuke))
var/userot = FALSE
var/rot = 0
var/pointer="crosshairs"
var/locx = (target_turf.x - here_turf.x)
var/locy = (here_turf.y - target_turf.y)
if(get_dist_euclidian(here_turf, target_turf) > 24) //If they're too far away, we need the angle for the arrow along the edge of the radar display
userot = TRUE
rot = round(Get_Angle(here_turf, target_turf))
else
locx = locx + 24
locy = locy + 24
if(target_turf.z > here_turf.z)
pointer="caret-up"
else if(target_turf.z < here_turf.z)
pointer="caret-down"
var/list/trackinfo = list(
locx = locx,
locy = locy,
userot = userot,
rot = rot,
arrowstyle = "ntosradarpointerS.png",
color = "red",
pointer = pointer,
)
return trackinfo
/datum/computer_file/program/radar/fission360/scan()
if(world.time < next_scan)
return
next_scan = world.time + (2 SECONDS)
objects = list()
for(var/i in GLOB.nuke_list)
var/obj/machinery/nuclearbomb/nuke = i
if(!trackable(nuke))
continue
var/list/nukeinfo = list(
ref = REF(nuke),
name = nuke.name,
)
objects += list(nukeinfo)
var/obj/item/disk/nuclear/disk = locate() in GLOB.poi_list
if(trackable(disk))
var/list/nukeinfo = list(
ref = REF(disk),
name = disk.name,
)
objects += list(nukeinfo)