mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-20 02:27:58 +01:00
Largely ported from the work done at Baystation in https://github.com/Baystation12/Baystation12/pull/17460 and later commits. - Shuttles no longer require a separate area for each location they jump to. Instead destinations are indicated by landmark objects, which are not necessarily exclusive to that shuttle. This means that more than one shuttle could use the same docking port (not at the same time of course). - Enhanced shuttle control computers to use nanoui if they didn't. - Organizes shuttle datum code a bit better so there is less re-inventing the wheel in subtypes. - Allows the possibility of shuttles (or destinations) that start on late-loaded maps. - Deprecate the "extra" shuttle areas that are no longer needed and update shuttle areas in unit tests This all required a bit of infrastructure improvements. - ChangeArea proc, for changing the area of a turf. - Fixed lighting overlays actually being able to be destroyed. - Added a few utility macros and procs. - Added "turf translation" procs which are like move_contents_to but more flexible.
543 lines
22 KiB
Plaintext
543 lines
22 KiB
Plaintext
/obj/item/device/communicator/proc/analyze_air()
|
|
var/list/results = list()
|
|
var/turf/T = get_turf(src.loc)
|
|
if(!isnull(T))
|
|
var/datum/gas_mixture/environment = T.return_air()
|
|
var/pressure = environment.return_pressure()
|
|
var/total_moles = environment.total_moles
|
|
if (total_moles)
|
|
var/o2_level = environment.gas["oxygen"]/total_moles
|
|
var/n2_level = environment.gas["nitrogen"]/total_moles
|
|
var/co2_level = environment.gas["carbon_dioxide"]/total_moles
|
|
var/phoron_level = environment.gas["phoron"]/total_moles
|
|
var/unknown_level = 1-(o2_level+n2_level+co2_level+phoron_level)
|
|
|
|
// Label is what the entry is describing
|
|
// Type identifies which unit or other special characters to use
|
|
// Val is the information reported
|
|
// Bad_high/_low are the values outside of which the entry reports as dangerous
|
|
// Poor_high/_low are the values outside of which the entry reports as unideal
|
|
// Values were extracted from the template itself
|
|
results = list(
|
|
list("entry" = "Pressure", "units" = "kPa", "val" = "[round(pressure,0.1)]", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80),
|
|
list("entry" = "Temperature", "units" = "°C", "val" = "[round(environment.temperature-T0C,0.1)]", "bad_high" = 35, "poor_high" = 25, "poor_low" = 15, "bad_low" = 5),
|
|
list("entry" = "Oxygen", "units" = "kPa", "val" = "[round(o2_level*100,0.1)]", "bad_high" = 140, "poor_high" = 135, "poor_low" = 19, "bad_low" = 17),
|
|
list("entry" = "Nitrogen", "units" = "kPa", "val" = "[round(n2_level*100,0.1)]", "bad_high" = 105, "poor_high" = 85, "poor_low" = 50, "bad_low" = 40),
|
|
list("entry" = "Carbon Dioxide", "units" = "kPa", "val" = "[round(co2_level*100,0.1)]", "bad_high" = 10, "poor_high" = 5, "poor_low" = 0, "bad_low" = 0),
|
|
list("entry" = "Phoron", "units" = "kPa", "val" = "[round(phoron_level*100,0.01)]", "bad_high" = 0.5, "poor_high" = 0, "poor_low" = 0, "bad_low" = 0),
|
|
list("entry" = "Other", "units" = "kPa", "val" = "[round(unknown_level, 0.01)]", "bad_high" = 1, "poor_high" = 0.5, "poor_low" = 0, "bad_low" = 0)
|
|
)
|
|
|
|
if(isnull(results))
|
|
results = list(list("entry" = "pressure", "units" = "kPa", "val" = "0", "bad_high" = 120, "poor_high" = 110, "poor_low" = 95, "bad_low" = 80))
|
|
return results
|
|
|
|
|
|
// Proc - compile_news()
|
|
// Parameters - none
|
|
// Description - Returns the list of newsfeeds, compiled for template processing
|
|
/obj/item/device/communicator/proc/compile_news()
|
|
var/list/feeds = list()
|
|
for(var/datum/feed_channel/channel in news_network.network_channels)
|
|
var/list/messages = list()
|
|
if(!channel.censored)
|
|
var/index = 0
|
|
for(var/datum/feed_message/FM in channel.messages)
|
|
index++
|
|
if(FM.img)
|
|
usr << browse_rsc(FM.img, "pda_news_tmp_photo_[feeds["channel"]]_[index].png")
|
|
// News stories are HTML-stripped but require newline replacement to be properly displayed in NanoUI
|
|
var/body = replacetext(FM.body, "\n", "<br>")
|
|
messages[++messages.len] = list(
|
|
"author" = FM.author,
|
|
"body" = body,
|
|
"message_type" = FM.message_type,
|
|
"time_stamp" = FM.time_stamp,
|
|
"has_image" = (FM.img != null),
|
|
"caption" = FM.caption,
|
|
"index" = index
|
|
)
|
|
|
|
feeds[++feeds.len] = list(
|
|
"name" = channel.channel_name,
|
|
"censored" = channel.censored,
|
|
"author" = channel.author,
|
|
"messages" = messages,
|
|
"index" = feeds.len + 1 // actually align them, since I guess the population of the list doesn't occur until after the evaluation of the new entry's contents
|
|
)
|
|
return feeds
|
|
|
|
// Proc - get_recent_news()
|
|
// Parameters - none
|
|
// Description - Returns the latest three newscasts, compiled for template processing
|
|
/obj/item/device/communicator/proc/get_recent_news()
|
|
var/list/news = list()
|
|
|
|
// Compile all the newscasts
|
|
for(var/datum/feed_channel/channel in news_network.network_channels)
|
|
if(!channel.censored)
|
|
for(var/datum/feed_message/FM in channel.messages)
|
|
var/body = replacetext(FM.body, "\n", "<br>")
|
|
news[++news.len] = list(
|
|
"channel" = channel.channel_name,
|
|
"author" = FM.author,
|
|
"body" = body,
|
|
"message_type" = FM.message_type,
|
|
"time_stamp" = FM.time_stamp,
|
|
"has_image" = (FM.img != null),
|
|
"caption" = FM.caption,
|
|
"time" = FM.post_time
|
|
)
|
|
|
|
// Cut out all but the youngest three
|
|
if(news.len > 3)
|
|
sortByKey(news, "time")
|
|
news.Cut(1, news.len - 2) // Last three have largest timestamps, youngest posts
|
|
news.Swap(1, 3) // List is sorted in ascending order of timestamp, we want descending
|
|
|
|
return news
|
|
|
|
|
|
|
|
// Putting the commcard data harvesting helpers here
|
|
// Not ideal to put all the procs on the base type
|
|
// but it may open options for adminbus,
|
|
// And it saves duplicated code
|
|
|
|
|
|
// Medical records
|
|
/obj/item/weapon/commcard/proc/get_med_records()
|
|
var/med_records[0]
|
|
for(var/datum/data/record/M in sortRecord(data_core.medical))
|
|
var/record[0]
|
|
record[++record.len] = list("tab" = "Name", "val" = M.fields["name"])
|
|
record[++record.len] = list("tab" = "ID", "val" = M.fields["id"])
|
|
record[++record.len] = list("tab" = "Blood Type", "val" = M.fields["b_type"])
|
|
record[++record.len] = list("tab" = "DNA #", "val" = M.fields["b_dna"])
|
|
record[++record.len] = list("tab" = "Gender", "val" = M.fields["id_gender"])
|
|
record[++record.len] = list("tab" = "Entity Classification", "val" = M.fields["brain_type"])
|
|
record[++record.len] = list("tab" = "Minor Disorders", "val" = M.fields["mi_dis"])
|
|
record[++record.len] = list("tab" = "Major Disorders", "val" = M.fields["ma_dis"])
|
|
record[++record.len] = list("tab" = "Allergies", "val" = M.fields["alg"])
|
|
record[++record.len] = list("tab" = "Condition", "val" = M.fields["cdi"])
|
|
record[++record.len] = list("tab" = "Notes", "val" = M.fields["notes"])
|
|
|
|
med_records[++med_records.len] = list("name" = M.fields["name"], "record" = record)
|
|
return med_records
|
|
|
|
|
|
// Employment records
|
|
/obj/item/weapon/commcard/proc/get_emp_records()
|
|
var/emp_records[0]
|
|
for(var/datum/data/record/G in sortRecord(data_core.general))
|
|
var/record[0]
|
|
record[++record.len] = list("tab" = "Name", "val" = G.fields["name"])
|
|
record[++record.len] = list("tab" = "ID", "val" = G.fields["id"])
|
|
record[++record.len] = list("tab" = "Rank", "val" = G.fields["rank"])
|
|
record[++record.len] = list("tab" = "Fingerprint", "val" = G.fields["fingerprint"])
|
|
record[++record.len] = list("tab" = "Entity Classification", "val" = G.fields["brain_type"])
|
|
record[++record.len] = list("tab" = "Sex", "val" = G.fields["sex"])
|
|
record[++record.len] = list("tab" = "Species", "val" = G.fields["species"])
|
|
record[++record.len] = list("tab" = "Age", "val" = G.fields["age"])
|
|
record[++record.len] = list("tab" = "Notes", "val" = G.fields["notes"])
|
|
|
|
emp_records[++emp_records.len] = list("name" = G.fields["name"], "record" = record)
|
|
return emp_records
|
|
|
|
|
|
// Security records
|
|
/obj/item/weapon/commcard/proc/get_sec_records()
|
|
var/sec_records[0]
|
|
for(var/datum/data/record/G in sortRecord(data_core.general))
|
|
var/record[0]
|
|
record[++record.len] = list("tab" = "Name", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Sex", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Species", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Age", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Rank", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Fingerprint", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Physical Status", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Mental Status", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Criminal Status", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Major Crimes", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Minor Crimes", "val" = G.fields[""])
|
|
record[++record.len] = list("tab" = "Notes", "val" = G.fields["notes"])
|
|
|
|
sec_records[++sec_records.len] = list("name" = G.fields["name"], "record" = record)
|
|
return sec_records
|
|
|
|
|
|
// Status of all secbots
|
|
// Weaker than what PDAs appear to do, but as of 7/1/2018 PDA secbot access is nonfunctional
|
|
/obj/item/weapon/commcard/proc/get_sec_bot_access()
|
|
var/sec_bots[0]
|
|
for(var/mob/living/bot/secbot/S in mob_list)
|
|
// Get new bot
|
|
var/status[0]
|
|
status[++status.len] = list("tab" = "Name", "val" = sanitize(S.name))
|
|
|
|
// If it's turned off, then it shouldn't be broadcasting any further info
|
|
if(!S.on)
|
|
status[++status.len] = list("tab" = "Power", "val" = "<span class='bad'>Off</span>") // Encoding the span classes here so I don't have to do complicated switches in the ui template
|
|
continue
|
|
status[++status.len] = list("tab" = "Power", "val" = "<span class='good'>On</span>")
|
|
|
|
// -- What it's doing
|
|
// If it's engaged, then say who it thinks it's engaging
|
|
if(S.target)
|
|
status[++status.len] = list("tab" = "Status", "val" = "<span class='bad'>Apprehending Target</span>")
|
|
status[++status.len] = list("tab" = "Target", "val" = S.target_name(S.target))
|
|
// Else if it's patrolling
|
|
else if(S.will_patrol)
|
|
status[++status.len] = list("tab" = "Status", "val" = "<span class='good'>Patrolling</span>")
|
|
// Otherwise we don't know what it's doing
|
|
else
|
|
status[++status.len] = list("tab" = "Status", "val" = "<span class='average'>Idle</span>")
|
|
|
|
// Where it is
|
|
status[++status.len] = list("tab" = "Location", "val" = sanitize("[get_area(S.loc)]"))
|
|
|
|
// Append bot to the list
|
|
sec_bots[++sec_bots.len] = list("bot" = S.name, "status" = status)
|
|
return sec_bots
|
|
|
|
|
|
// Code and frequency of stored signalers
|
|
// Supports multiple signalers within the device
|
|
/obj/item/weapon/commcard/proc/get_int_signalers()
|
|
var/signalers[0]
|
|
for(var/obj/item/device/assembly/signaler/S in internal_devices)
|
|
var/unit[0]
|
|
unit[++unit.len] = list("tab" = "Code", "val" = S.code)
|
|
unit[++unit.len] = list("tab" = "Frequency", "val" = S.frequency)
|
|
|
|
signalers[++signalers.len] = list("ref" = "\ref[S]", "status" = unit)
|
|
|
|
return signalers
|
|
|
|
// Returns list of all powernet sensors currently visible to the commcard
|
|
/obj/item/weapon/commcard/proc/find_powernet_sensors()
|
|
var/grid_sensors[0]
|
|
|
|
// Find all the powernet sensors we need to pull data from
|
|
// Copied from /datum/nano_module/power_monitor/proc/refresh_sensors(),
|
|
// located in '/code/modules/nano/modules/power_monitor.dm'
|
|
// Minor tweaks for efficiency and cleanliness
|
|
var/turf/T = get_turf(src)
|
|
if(T)
|
|
var/list/levels = using_map.get_map_levels(T.z, FALSE)
|
|
for(var/obj/machinery/power/sensor/S in machines)
|
|
if((S.long_range) || (S.loc.z in levels) || (S.loc.z == T.z)) // Consoles have range on their Z-Level. Sensors with long_range var will work between Z levels.
|
|
if(S.name_tag == "#UNKN#") // Default name. Shouldn't happen!
|
|
warning("Powernet sensor with unset ID Tag! [S.x]X [S.y]Y [S.z]Z")
|
|
else
|
|
grid_sensors += S
|
|
return grid_sensors
|
|
|
|
// List of powernets
|
|
/obj/item/weapon/commcard/proc/get_powernet_monitoring_list()
|
|
// Fetch power monitor data
|
|
var/sensors[0]
|
|
|
|
for(var/obj/machinery/power/sensor/S in internal_data["grid_sensors"])
|
|
var/list/focus = S.return_reading_data()
|
|
|
|
sensors[++sensors.len] = list(
|
|
"name" = S.name_tag,
|
|
"alarm" = focus["alarm"]
|
|
)
|
|
|
|
return sensors
|
|
|
|
// Information about the targeted powernet
|
|
/obj/item/weapon/commcard/proc/get_powernet_target(var/target_sensor)
|
|
if(!target_sensor)
|
|
return
|
|
|
|
var/powernet_target[0]
|
|
|
|
for(var/obj/machinery/power/sensor/S in internal_data["grid_sensors"])
|
|
var/list/focus = S.return_reading_data()
|
|
|
|
// Packages the span class here so it doesn't need to be interpreted w/in the for loop in the ui template
|
|
var/load_stat = "<span class='good'>Optimal</span>"
|
|
if(focus["load_percentage"] >= 95)
|
|
load_stat = "<span class='bad'>DANGER: Overload</span>"
|
|
else if(focus["load_percentage"] >= 85)
|
|
load_stat = "<span class='average'>WARNING: High Load</span>"
|
|
|
|
var/alarm_stat = focus["alarm"] ? "<span class='bad'>WARNING: Abnormal activity detected!</span>" : "<span class='good'>Secure</span>"
|
|
|
|
if(target_sensor == S.name_tag)
|
|
powernet_target = list(
|
|
"name" = S.name_tag,
|
|
"alarm" = focus["alarm"],
|
|
"error" = focus["error"],
|
|
"apc_data" = focus["apc_data"],
|
|
"status" = list(
|
|
list("field" = "Network Load Status", "statval" = load_stat),
|
|
list("field" = "Network Security Status", "statval" = alarm_stat),
|
|
list("field" = "Load Percentage", "statval" = focus["load_percentage"]),
|
|
list("field" = "Available Power", "statval" = focus["total_avail"]),
|
|
list("field" = "APC Power Usage", "statval" = focus["total_used_apc"]),
|
|
list("field" = "Other Power Usage", "statval" = focus["total_used_other"]),
|
|
list("field" = "Total Usage", "statval" = focus["total_used_all"])
|
|
)
|
|
)
|
|
|
|
return powernet_target
|
|
|
|
// Compiles the locations of all janitorial paraphernalia, as used by janitorialLocator.tmpl
|
|
/obj/item/weapon/commcard/proc/get_janitorial_locations()
|
|
// Fetch janitorial locator
|
|
var/janidata[0]
|
|
var/list/cleaningList = list()
|
|
cleaningList += all_mops + all_mopbuckets + all_janitorial_carts
|
|
|
|
// User's location
|
|
var/turf/userloc = get_turf(src)
|
|
if(isturf(userloc))
|
|
janidata[++janidata.len] = list("field" = "Current Location", "val" = "<span class='good'>[userloc.x], [userloc.y], [using_map.get_zlevel_name(userloc.z)]</span>")
|
|
else
|
|
janidata[++janidata.len] = list("field" = "Current Location", "val" = "<span class='bad'>Unknown</span>")
|
|
return janidata // If the user isn't on a valid turf, then it shouldn't be able to find anything anyways
|
|
|
|
// Mops, mop buckets, janitorial carts.
|
|
for(var/obj/C in cleaningList)
|
|
var/turf/T = get_turf(C)
|
|
if(isturf(T) )//&& T.z in using_map.get_map_levels(userloc, FALSE))
|
|
if(T.z == userloc.z)
|
|
janidata[++janidata.len] = list("field" = apply_text_macros("\proper [C.name]"), "val" = "<span class='good'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>")
|
|
else
|
|
janidata[++janidata.len] = list("field" = apply_text_macros("\proper [C.name]"), "val" = "<span class='average'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>")
|
|
|
|
// Cleanbots
|
|
for(var/mob/living/bot/cleanbot/B in living_mob_list)
|
|
var/turf/T = get_turf(B)
|
|
if(isturf(T) )//&& T.z in using_map.get_map_levels(userloc, FALSE))
|
|
var/textout = ""
|
|
if(B.on)
|
|
textout += "Status: <span class='good'>Online</span><br>"
|
|
if(T.z == userloc.z)
|
|
textout += "<span class='good'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>"
|
|
else
|
|
textout += "<span class='average'>[T.x], [T.y], [using_map.get_zlevel_name(T.z)]</span>"
|
|
else
|
|
textout += "Status: <span class='bad'>Offline</span>"
|
|
|
|
janidata[++janidata.len] = list("field" = "[B.name]", "val" = textout)
|
|
|
|
return janidata
|
|
|
|
// Compiles the three lists used by GPS_access.tmpl
|
|
// The contents of the three lists are inherently related, so separating them into different procs would be largely redundant
|
|
/obj/item/weapon/commcard/proc/get_GPS_lists()
|
|
// GPS Access
|
|
var/intgps[0] // Gps devices within the commcard -- Allow tag edits, turning on/off, etc
|
|
var/extgps[0] // Gps devices not inside the commcard -- Print locations if a gps is on
|
|
var/stagps[0] // Gps net status, location, whether it's on, if it's got long range
|
|
var/obj/item/device/gps/cumulative = new(src)
|
|
cumulative.tracking = FALSE
|
|
cumulative.local_mode = TRUE // Won't detect long-range signals automatically
|
|
cumulative.long_range = FALSE
|
|
var/list/toggled_gps = list() // List of GPS units that are turned off before display_list() is called
|
|
|
|
for(var/obj/item/device/gps/G in internal_devices)
|
|
var/gpsdata[0]
|
|
if(G.tracking && !G.emped)
|
|
cumulative.tracking = TRUE // Turn it on
|
|
if(G.long_range)
|
|
cumulative.long_range = TRUE // It can detect long-range
|
|
if(!G.local_mode)
|
|
cumulative.local_mode = FALSE // It is detecting long-range
|
|
|
|
gpsdata["ref"] = "\ref[G]"
|
|
gpsdata["tag"] = G.gps_tag
|
|
gpsdata["power"] = G.tracking
|
|
gpsdata["local_mode"] = G.local_mode
|
|
gpsdata["long_range"] = G.long_range
|
|
gpsdata["hide_signal"] = G.hide_signal
|
|
gpsdata["can_hide"] = G.can_hide_signal
|
|
|
|
intgps[++intgps.len] = gpsdata // Add it to the list
|
|
|
|
if(G.tracking)
|
|
G.tracking = FALSE // Disable the internal gps units so they don't show up in the report
|
|
toggled_gps += G
|
|
|
|
var/list/remote_gps = cumulative.display_list() // Fetch information for all units except the ones inside of this device
|
|
|
|
for(var/obj/item/device/gps/G in toggled_gps) // Reenable any internal GPS units
|
|
G.tracking = TRUE
|
|
|
|
stagps["enabled"] = cumulative.tracking
|
|
stagps["long_range_en"] = (cumulative.long_range && !cumulative.local_mode)
|
|
|
|
stagps["my_area_name"] = remote_gps["my_area_name"]
|
|
stagps["curr_x"] = remote_gps["curr_x"]
|
|
stagps["curr_y"] = remote_gps["curr_y"]
|
|
stagps["curr_z"] = remote_gps["curr_z"]
|
|
stagps["curr_z_name"] = remote_gps["curr_z_name"]
|
|
|
|
extgps = remote_gps["gps_list"] // Compiled by the GPS
|
|
|
|
qdel(cumulative) // Don't want spare GPS units building up in the contents
|
|
|
|
return list(
|
|
intgps,
|
|
extgps,
|
|
stagps
|
|
)
|
|
|
|
// Collects the current status of the supply shuttle
|
|
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
|
|
// code\game\machinery\computer\supply.dm, starting at line 55
|
|
/obj/item/weapon/commcard/proc/get_supply_shuttle_status()
|
|
var/shuttle_status[0]
|
|
var/datum/shuttle/autodock/ferry/supply/shuttle = supply_controller.shuttle
|
|
if(shuttle)
|
|
if(shuttle.has_arrive_time())
|
|
shuttle_status["location"] = "In transit"
|
|
shuttle_status["mode"] = SUP_SHUTTLE_TRANSIT
|
|
shuttle_status["time"] = shuttle.eta_minutes()
|
|
|
|
else
|
|
shuttle_status["time"] = 0
|
|
if(shuttle.at_station())
|
|
if(shuttle.shuttle_docking_controller)
|
|
switch(shuttle.shuttle_docking_controller.get_docking_status())
|
|
if("docked")
|
|
shuttle_status["location"] = "Docked"
|
|
shuttle_status["mode"] = SUP_SHUTTLE_DOCKED
|
|
if("undocked")
|
|
shuttle_status["location"] = "Undocked"
|
|
shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKED
|
|
if("docking")
|
|
shuttle_status["location"] = "Docking"
|
|
shuttle_status["mode"] = SUP_SHUTTLE_DOCKING
|
|
shuttle_status["force"] = shuttle.can_force()
|
|
if("undocking")
|
|
shuttle_status["location"] = "Undocking"
|
|
shuttle_status["mode"] = SUP_SHUTTLE_UNDOCKING
|
|
shuttle_status["force"] = shuttle.can_force()
|
|
|
|
else
|
|
shuttle_status["location"] = "Station"
|
|
shuttle_status["mode"] = SUP_SHUTTLE_DOCKED
|
|
|
|
else
|
|
shuttle_status["location"] = "Away"
|
|
shuttle_status["mode"] = SUP_SHUTTLE_AWAY
|
|
|
|
if(shuttle.can_launch())
|
|
shuttle_status["launch"] = 1
|
|
else if(shuttle.can_cancel())
|
|
shuttle_status["launch"] = 2
|
|
else
|
|
shuttle_status["launch"] = 0
|
|
|
|
switch(shuttle.moving_status)
|
|
if(SHUTTLE_IDLE)
|
|
shuttle_status["engine"] = "Idle"
|
|
if(SHUTTLE_WARMUP)
|
|
shuttle_status["engine"] = "Warming up"
|
|
if(SHUTTLE_INTRANSIT)
|
|
shuttle_status["engine"] = "Engaged"
|
|
|
|
else
|
|
shuttle["mode"] = SUP_SHUTTLE_ERROR
|
|
|
|
return shuttle_status
|
|
|
|
// Compiles the list of supply orders
|
|
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
|
|
// code\game\machinery\computer\supply.dm, starting at line 130
|
|
/obj/item/weapon/commcard/proc/get_supply_orders()
|
|
var/orders[0]
|
|
for(var/datum/supply_order/S in supply_controller.order_history)
|
|
orders[++orders.len] = list(
|
|
"ref" = "\ref[S]",
|
|
"status" = S.status,
|
|
"entries" = list(
|
|
list("field" = "Supply Pack", "entry" = S.name),
|
|
list("field" = "Cost", "entry" = S.cost),
|
|
list("field" = "Index", "entry" = S.index),
|
|
list("field" = "Reason", "entry" = S.comment),
|
|
list("field" = "Ordered by", "entry" = S.ordered_by),
|
|
list("field" = "Ordered at", "entry" = S.ordered_at),
|
|
list("field" = "Approved by", "entry" = S.approved_by),
|
|
list("field" = "Approved at", "entry" = S.approved_at)
|
|
)
|
|
)
|
|
|
|
return orders
|
|
|
|
// Compiles the list of supply export receipts
|
|
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
|
|
// code\game\machinery\computer\supply.dm, starting at line 147
|
|
/obj/item/weapon/commcard/proc/get_supply_receipts()
|
|
var/receipts[0]
|
|
for(var/datum/exported_crate/E in supply_controller.exported_crates)
|
|
receipts[++receipts.len] = list(
|
|
"ref" = "\ref[E]",
|
|
"contents" = E.contents,
|
|
"error" = E.contents["error"],
|
|
"title" = list(
|
|
list("field" = "Name", "entry" = E.name),
|
|
list("field" = "Value", "entry" = E.value)
|
|
)
|
|
)
|
|
return receipts
|
|
|
|
|
|
// Compiles the list of supply packs for the category currently stored in internal_data["supply_category"]
|
|
// Copied from /obj/machinery/computer/supplycomp/ui_interact(),
|
|
// code\game\machinery\computer\supply.dm, starting at line 147
|
|
/obj/item/weapon/commcard/proc/get_supply_pack_list()
|
|
var/supply_packs[0]
|
|
for(var/pack_name in supply_controller.supply_pack)
|
|
var/datum/supply_pack/P = supply_controller.supply_pack[pack_name]
|
|
if(P.group == internal_data["supply_category"])
|
|
var/list/pack = list(
|
|
"name" = P.name,
|
|
"cost" = P.cost,
|
|
"contraband" = P.contraband,
|
|
"manifest" = uniquelist(P.manifest),
|
|
"random" = P.num_contained,
|
|
"expand" = 0,
|
|
"ref" = "\ref[P]"
|
|
)
|
|
|
|
if(P in internal_data["supply_pack_expanded"])
|
|
pack["expand"] = 1
|
|
|
|
supply_packs[++supply_packs.len] = pack
|
|
|
|
return supply_packs
|
|
|
|
|
|
// Compiles miscellaneous data and permissions used by the supply template
|
|
/obj/item/weapon/commcard/proc/get_misc_supply_data()
|
|
return list(
|
|
"shuttle_auth" = (internal_data["supply_controls"] & SUP_SEND_SHUTTLE),
|
|
"order_auth" = (internal_data["supply_controls"] & SUP_ACCEPT_ORDERS),
|
|
"supply_points" = supply_controller.points,
|
|
"supply_categories" = all_supply_groups
|
|
)
|
|
|
|
/obj/item/weapon/commcard/proc/get_status_display()
|
|
return list(
|
|
"line1" = internal_data["stat_display_line1"],
|
|
"line2" = internal_data["stat_display_line2"],
|
|
"active_line1" = internal_data["stat_display_active1"],
|
|
"active_line2" = internal_data["stat_display_active2"],
|
|
"active" = internal_data["stat_display_special"]
|
|
)
|
|
|
|
/obj/item/weapon/commcard/proc/find_blast_doors()
|
|
var/target_doors[0]
|
|
for(var/obj/machinery/door/blast/B in machines)
|
|
if(B.id == internal_data["shuttle_door_code"])
|
|
target_doors += B
|
|
|
|
return target_doors |