mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-22 11:38:12 +01:00
Merge pull request #8741 from ShadowLarkens/tgui_exploration
TGUI exploration
This commit is contained in:
@@ -15,7 +15,6 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
|
||||
anchored = TRUE
|
||||
circuit = /obj/item/weapon/circuitboard/pointdefense_control
|
||||
var/list/targets = list() // Targets being engaged by associated batteries
|
||||
var/ui_template = "pointdefense_control.tmpl"
|
||||
var/id_tag = null
|
||||
|
||||
/obj/machinery/pointdefense_control/Initialize(mapload)
|
||||
@@ -37,48 +36,42 @@ GLOBAL_LIST_BOILERPLATE(pointdefense_turrets, /obj/machinery/power/pointdefense)
|
||||
if(!id_tag)
|
||||
. += "[desc_panel_image("multitool")]to set ident tag"
|
||||
|
||||
/obj/machinery/pointdefense_control/ui_interact(var/mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(ui_template)
|
||||
var/list/data = build_ui_data()
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, ui_template, name, 400, 600)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
/obj/machinery/pointdefense_control/tgui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "PointDefenseControl") // 400, 600
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/pointdefense_control/attack_hand(mob/user)
|
||||
if((. = ..()))
|
||||
return
|
||||
if(CanUseTopic(user, global.default_state) > STATUS_CLOSE)
|
||||
ui_interact(user)
|
||||
if(..())
|
||||
return TRUE
|
||||
tgui_interact(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/pointdefense_control/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/pointdefense_control/Topic(var/mob/user, var/href_list)
|
||||
if((. = ..()))
|
||||
return
|
||||
|
||||
if(href_list["toggle_active"])
|
||||
var/obj/machinery/power/pointdefense/PD = locate(href_list["toggle_active"])
|
||||
if(action == "toggle_active")
|
||||
var/obj/machinery/power/pointdefense/PD = locate(params["target"])
|
||||
if(!istype(PD))
|
||||
return TOPIC_NOACTION
|
||||
return FALSE
|
||||
|
||||
//if(!lan || !lan.is_connected(PD))
|
||||
if(PD.id_tag != id_tag)
|
||||
return TOPIC_NOACTION
|
||||
return FALSE
|
||||
|
||||
if(!(get_z(PD) in GetConnectedZlevels(get_z(src))))
|
||||
to_chat(user, "<span class='warning'>[PD] is not within control range.</span>")
|
||||
return TOPIC_NOACTION
|
||||
to_chat(usr, "<span class='warning'>[PD] is not within control range.</span>")
|
||||
return FALSE
|
||||
|
||||
if(!PD.Activate()) //Activate() whilst the device is active will return false.
|
||||
PD.Deactivate()
|
||||
return TOPIC_REFRESH
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/pointdefense_control/proc/build_ui_data()
|
||||
/obj/machinery/pointdefense_control/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["id"] = id_tag
|
||||
data["name"] = name
|
||||
var/list/turrets = list()
|
||||
if(id_tag)
|
||||
var/list/connected_z_levels = GetConnectedZlevels(get_z(src))
|
||||
|
||||
@@ -189,6 +189,8 @@
|
||||
/datum/computer_file/program/proc/check_eye(var/mob/user)
|
||||
if(NM)
|
||||
return NM.check_eye(user)
|
||||
if(TM)
|
||||
return TM.check_eye(user)
|
||||
else
|
||||
return -1
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/datum/computer_file/program/ship_nav
|
||||
filename = "navviewer"
|
||||
filedesc = "Ship Navigational Screen"
|
||||
nanomodule_path = /datum/nano_module/program/ship/nav
|
||||
tguimodule_path = /datum/tgui_module/ship/nav/ntos
|
||||
program_icon_state = "helm"
|
||||
program_key_state = "generic_key"
|
||||
program_menu_icon = "pin-s"
|
||||
@@ -10,54 +10,3 @@
|
||||
requires_ntnet = 1
|
||||
network_destination = "ship position sensors"
|
||||
size = 4
|
||||
|
||||
/datum/nano_module/program/ship/nav
|
||||
name = "Navigation Display"
|
||||
|
||||
/datum/nano_module/program/ship/nav/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1, var/datum/topic_state/state = default_state)
|
||||
if(!linked)
|
||||
to_chat(user, "<span class='warning'>You don't appear to be on a spaceship...</span>")
|
||||
if(program)
|
||||
program.kill_program()
|
||||
else if(ui)
|
||||
ui.close()
|
||||
return
|
||||
|
||||
var/list/data = list()
|
||||
if(program)
|
||||
data = program.get_header_data()
|
||||
|
||||
var/turf/T = get_turf(linked)
|
||||
var/obj/effect/overmap/visitable/sector/current_sector = locate() in T
|
||||
|
||||
data["sector"] = current_sector ? current_sector.name : "Deep Space"
|
||||
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
|
||||
data["s_x"] = linked.x
|
||||
data["s_y"] = linked.y
|
||||
data["speed"] = round(linked.get_speed()*1000, 0.01)
|
||||
data["accel"] = round(linked.get_acceleration()*1000, 0.01)
|
||||
data["heading"] = linked.get_heading_degrees()
|
||||
data["viewing"] = viewing_overmap(user)
|
||||
|
||||
if(linked.get_speed())
|
||||
data["ETAnext"] = "[round(linked.ETA()/10)] seconds"
|
||||
else
|
||||
data["ETAnext"] = "N/A"
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "nav.tmpl", "[linked.name] Navigation Screen", 380, 530, state = state)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/datum/nano_module/program/ship/nav/OnTopic(var/mob/user, var/list/href_list)
|
||||
if(..())
|
||||
return TOPIC_HANDLED
|
||||
|
||||
if (!linked)
|
||||
return TOPIC_NOACTION
|
||||
|
||||
if (href_list["viewing"])
|
||||
viewing_overmap(user) ? unlook(user) : look(user)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/datum/nano_module/program/ship
|
||||
var/obj/effect/overmap/visitable/ship/linked
|
||||
var/list/viewers
|
||||
var/extra_view = 0
|
||||
|
||||
/datum/nano_module/program/ship/New()
|
||||
..()
|
||||
sync_linked()
|
||||
if(linked)
|
||||
name = "[linked.name] [name]"
|
||||
|
||||
/datum/nano_module/program/ship/Destroy()
|
||||
if(LAZYLEN(viewers))
|
||||
for(var/weakref/W in viewers)
|
||||
var/M = W.resolve()
|
||||
if(M)
|
||||
unlook(M)
|
||||
. = ..()
|
||||
|
||||
/datum/nano_module/program/ship/proc/sync_linked()
|
||||
var/obj/effect/overmap/visitable/ship/sector = get_overmap_sector(get_z(nano_host()))
|
||||
if(!sector)
|
||||
return
|
||||
return attempt_hook_up_recursive(sector)
|
||||
|
||||
/datum/nano_module/program/ship/proc/attempt_hook_up_recursive(obj/effect/overmap/visitable/ship/sector)
|
||||
if(attempt_hook_up(sector))
|
||||
return sector
|
||||
for(var/obj/effect/overmap/visitable/ship/candidate in sector)
|
||||
if((. = .(candidate)))
|
||||
return
|
||||
|
||||
/datum/nano_module/program/ship/proc/attempt_hook_up(obj/effect/overmap/visitable/ship/sector)
|
||||
if(!istype(sector))
|
||||
return
|
||||
if(sector.check_ownership(nano_host()))
|
||||
linked = sector
|
||||
return 1
|
||||
|
||||
/datum/nano_module/program/ship/proc/look(var/mob/user)
|
||||
if(linked)
|
||||
user.machine = nano_host()
|
||||
user.reset_view(linked)
|
||||
user.set_viewsize(world.view + extra_view)
|
||||
GLOB.moved_event.register(user, src, /datum/nano_module/program/ship/proc/unlook)
|
||||
LAZYDISTINCTADD(viewers, weakref(user))
|
||||
|
||||
/datum/nano_module/program/ship/proc/unlook(var/mob/user)
|
||||
user.reset_view()
|
||||
user.set_viewsize() // reset to default
|
||||
GLOB.moved_event.unregister(user, src, /datum/nano_module/program/ship/proc/unlook)
|
||||
LAZYREMOVE(viewers, weakref(user))
|
||||
|
||||
/datum/nano_module/program/ship/proc/viewing_overmap(mob/user)
|
||||
return (weakref(user) in viewers)
|
||||
|
||||
/datum/nano_module/program/ship/proc/DefaultTopicState()
|
||||
return global.default_state
|
||||
|
||||
/datum/nano_module/program/ship/Topic(var/href, var/href_list = list(), var/datum/topic_state/state)
|
||||
if((. = ..()))
|
||||
return
|
||||
state = state || DefaultTopicState() || global.default_state
|
||||
if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE)
|
||||
CouldUseTopic(usr)
|
||||
return OnTopic(usr, href_list, state)
|
||||
CouldNotUseTopic(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/nano_module/program/ship/proc/OnTopic(var/mob/user, var/href_list, var/datum/topic_state/state)
|
||||
return TOPIC_NOACTION
|
||||
|
||||
/datum/nano_module/program/ship/proc/CouldNotUseTopic(mob/user)
|
||||
. = ..()
|
||||
unlook(user)
|
||||
|
||||
/datum/nano_module/program/ship/proc/CouldUseTopic(mob/user)
|
||||
. = ..()
|
||||
if(viewing_overmap(user))
|
||||
look(user)
|
||||
|
||||
/datum/nano_module/program/ship/check_eye(var/mob/user)
|
||||
if (!get_dist(user, nano_host()) > 1 || user.blinded || !linked )
|
||||
unlook(user)
|
||||
return -1
|
||||
else
|
||||
return 0
|
||||
@@ -118,14 +118,30 @@ obj/machinery/computer/ship/disperser/proc/is_valid_setup()
|
||||
if(B)
|
||||
return B
|
||||
|
||||
/obj/machinery/computer/ship/disperser/ui_interact(mob/user, ui_key = "main", datum/nanoui/ui = null, force_open = TRUE)
|
||||
/obj/machinery/computer/ship/disperser/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
if(!linked)
|
||||
display_reconnect_dialog(user, "disperser synchronization")
|
||||
return
|
||||
|
||||
var/data[0]
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OvermapDisperser", "[linked.name] ORB control") // 400, 550
|
||||
ui.open()
|
||||
|
||||
if (!link_parts())
|
||||
/obj/machinery/computer/ship/disperser/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["faillink"] = FALSE
|
||||
data["calibration"] = null
|
||||
data["overmapdir"] = null
|
||||
data["cal_accuracy"] = 0
|
||||
data["strength"] = 0
|
||||
data["range"] = 0
|
||||
data["next_shot"] = -1
|
||||
data["nopower"] = TRUE
|
||||
data["skill"] = FALSE
|
||||
data["chargeload"] = null
|
||||
|
||||
if(!link_parts())
|
||||
data["faillink"] = TRUE
|
||||
else
|
||||
data["calibration"] = calibration
|
||||
@@ -137,56 +153,58 @@ obj/machinery/computer/ship/disperser/proc/is_valid_setup()
|
||||
data["nopower"] = !data["faillink"] && (!front.powered() || !middle.powered() || !back.powered())
|
||||
data["skill"] = user.get_skill_value(core_skill) > skill_offset
|
||||
|
||||
var/charge = "<b>UNKNOWN ERROR</b>"
|
||||
var/charge = "UNKNOWN ERROR"
|
||||
if(get_charge_type() == OVERMAP_WEAKNESS_NONE)
|
||||
charge = "<b>ERROR</b>: No valid charge detected."
|
||||
charge = "ERROR: No valid charge detected."
|
||||
else
|
||||
var/obj/structure/ship_munition/disperser_charge/B = get_charge()
|
||||
charge = B.chargedesc
|
||||
data["chargeload"] = charge
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "disperser.tmpl", "[linked.name] ORB control", 400, 550)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/ship/disperser/OnTopic(mob/user, list/href_list, state)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
/obj/machinery/computer/ship/disperser/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(!linked)
|
||||
return TOPIC_HANDLED
|
||||
return FALSE
|
||||
|
||||
if (href_list["choose"])
|
||||
overmapdir = sanitize_integer(text2num(href_list["choose"]), 0, 9, 0)
|
||||
reset_calibration()
|
||||
switch(action)
|
||||
if("choose")
|
||||
overmapdir = sanitize_integer(text2num(params["dir"]), 0, 9, 0)
|
||||
reset_calibration()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["calibration"])
|
||||
var/input = input("0-9", "disperser calibration", 0) as num|null
|
||||
if(!isnull(input)) //can be zero so we explicitly check for null
|
||||
var/calnum = sanitize_integer(text2num(href_list["calibration"]), 0, caldigit)//sanitiiiiize
|
||||
calibration[calnum + 1] = sanitize_integer(input, 0, 9, 0)//must add 1 because nanoui indexes from 0
|
||||
if("calibration")
|
||||
var/input = input("0-9", "disperser calibration", 0) as num|null
|
||||
if(!isnull(input)) //can be zero so we explicitly check for null
|
||||
var/calnum = sanitize_integer(text2num(params["calibration"]), 0, caldigit)//sanitiiiiize
|
||||
calibration[calnum + 1] = sanitize_integer(input, 0, 9, 0)//must add 1 because js indexes from 0
|
||||
. = TRUE
|
||||
|
||||
if(href_list["skill_calibration"])
|
||||
for(var/i = 1 to min(caldigit, user.get_skill_value(core_skill) - skill_offset))
|
||||
calibration[i] = calexpected[i]
|
||||
if("skill_calibration")
|
||||
for(var/i = 1 to min(caldigit, usr.get_skill_value(core_skill) - skill_offset))
|
||||
calibration[i] = calexpected[i]
|
||||
. = TRUE
|
||||
|
||||
if(href_list["strength"])
|
||||
var/input = input("1-5", "disperser strength", 1) as num|null
|
||||
if(input && CanInteract(user, state))
|
||||
strength = sanitize_integer(input, 1, 5, 1)
|
||||
middle.update_idle_power_usage(strength * range * 100)
|
||||
if("strength")
|
||||
var/input = input("1-5", "disperser strength", 1) as num|null
|
||||
if(input && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
strength = sanitize_integer(input, 1, 5, 1)
|
||||
middle.update_idle_power_usage(strength * range * 100)
|
||||
. = TRUE
|
||||
|
||||
if(href_list["range"])
|
||||
var/input = input("1-5", "disperser radius", 1) as num|null
|
||||
if(input && CanInteract(user, state))
|
||||
range = sanitize_integer(input, 1, 5, 1)
|
||||
middle.update_idle_power_usage(strength * range * 100)
|
||||
if("range")
|
||||
var/input = input("1-5", "disperser radius", 1) as num|null
|
||||
if(input && tgui_status(usr, state) == STATUS_INTERACTIVE)
|
||||
range = sanitize_integer(input, 1, 5, 1)
|
||||
middle.update_idle_power_usage(strength * range * 100)
|
||||
. = TRUE
|
||||
|
||||
if(href_list["fire"])
|
||||
fire(user)
|
||||
if("fire")
|
||||
fire(usr)
|
||||
. = TRUE
|
||||
|
||||
return TOPIC_REFRESH
|
||||
if(. && !issilicon(usr))
|
||||
playsound(src, "terminal_type", 50, 1)
|
||||
@@ -54,22 +54,8 @@
|
||||
//
|
||||
// Topic
|
||||
//
|
||||
|
||||
/obj/machinery/computer/ship/proc/DefaultTopicState()
|
||||
return global.default_state
|
||||
|
||||
/obj/machinery/computer/ship/Topic(var/href, var/href_list = list(), var/datum/topic_state/state)
|
||||
if((. = ..()))
|
||||
return
|
||||
state = state || DefaultTopicState() || global.default_state
|
||||
if(CanUseTopic(usr, state, href_list) == STATUS_INTERACTIVE)
|
||||
CouldUseTopic(usr)
|
||||
return OnTopic(usr, href_list, state)
|
||||
CouldNotUseTopic(usr)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/ship/proc/OnTopic(var/mob/user, var/href_list, var/datum/topic_state/state)
|
||||
return TOPIC_NOACTION
|
||||
/obj/machinery/computer/ship/tgui_state()
|
||||
return GLOB.tgui_default_state
|
||||
|
||||
//
|
||||
// Interaction
|
||||
@@ -80,11 +66,11 @@
|
||||
// If you perform direct interactions in here, you are responsible for ensuring that full interactivity checks have been made (i.e CanInteract).
|
||||
// The checks leading in to here only guarantee that the user should be able to view a UI.
|
||||
/obj/machinery/computer/ship/proc/interface_interact(var/mob/user)
|
||||
ui_interact(user)
|
||||
tgui_interact(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/ship/attack_ai(mob/user)
|
||||
if(CanUseTopic(user, DefaultTopicState()) > STATUS_CLOSE)
|
||||
if(tgui_status(user, tgui_state()) > STATUS_CLOSE)
|
||||
return interface_interact(user)
|
||||
|
||||
// After a recent rework this should mostly be safe.
|
||||
@@ -98,6 +84,6 @@
|
||||
return
|
||||
if(!allowed(user))
|
||||
to_chat(user, "<span class='warning'>Access Denied.</span>")
|
||||
return 1
|
||||
if(CanUseTopic(user, DefaultTopicState()) > STATUS_CLOSE)
|
||||
return TRUE
|
||||
if(tgui_status(user, tgui_state()) > STATUS_CLOSE)
|
||||
return interface_interact(user)
|
||||
|
||||
@@ -5,92 +5,92 @@
|
||||
icon_keyboard = "tech_key"
|
||||
icon_screen = "engines"
|
||||
circuit = /obj/item/weapon/circuitboard/engine
|
||||
var/display_state = "status"
|
||||
|
||||
/obj/machinery/computer/ship/engines/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/machinery/computer/ship/engines/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!linked)
|
||||
display_reconnect_dialog(user, "ship control systems")
|
||||
return
|
||||
|
||||
var/data[0]
|
||||
data["state"] = display_state
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OvermapEngines", "[linked.name] Engines Control") // 390, 530
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/ship/engines/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = list()
|
||||
data["global_state"] = linked.engines_state
|
||||
data["global_limit"] = round(linked.thrust_limit*100)
|
||||
var/total_thrust = 0
|
||||
|
||||
var/list/enginfo[0]
|
||||
var/list/enginfo = list()
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
var/list/rdata[0]
|
||||
var/list/rdata = list()
|
||||
rdata["eng_type"] = E.name
|
||||
rdata["eng_on"] = E.is_on()
|
||||
rdata["eng_thrust"] = E.get_thrust()
|
||||
rdata["eng_thrust_limiter"] = round(E.get_thrust_limit()*100)
|
||||
rdata["eng_status"] = E.get_status()
|
||||
var/list/status = E.get_status()
|
||||
if(!islist(status))
|
||||
log_runtime(EXCEPTION("Warning, ship [E.name] (\ref[E]) for [linked.name] returned a non-list status!"))
|
||||
status = list("Error")
|
||||
rdata["eng_status"] = status
|
||||
rdata["eng_reference"] = "\ref[E]"
|
||||
total_thrust += E.get_thrust()
|
||||
enginfo.Add(list(rdata))
|
||||
|
||||
data["engines_info"] = enginfo
|
||||
data["total_thrust"] = total_thrust
|
||||
return data
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "engines_control.tmpl", "[linked.name] Engines Control", 390, 530)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/ship/engines/OnTopic(var/mob/user, var/list/href_list, state)
|
||||
/obj/machinery/computer/ship/engines/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return ..()
|
||||
return TRUE
|
||||
|
||||
if(href_list["state"])
|
||||
display_state = href_list["state"]
|
||||
return TOPIC_REFRESH
|
||||
switch(action)
|
||||
if("global_toggle")
|
||||
linked.engines_state = !linked.engines_state
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
if(linked.engines_state == !E.is_on())
|
||||
E.toggle()
|
||||
. = TRUE
|
||||
|
||||
if(href_list["global_toggle"])
|
||||
linked.engines_state = !linked.engines_state
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
if(linked.engines_state == !E.is_on())
|
||||
E.toggle()
|
||||
return TOPIC_REFRESH
|
||||
if("set_global_limit")
|
||||
var/newlim = input("Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100) as num
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return FALSE
|
||||
linked.thrust_limit = clamp(newlim/100, 0, 1)
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
E.set_thrust_limit(linked.thrust_limit)
|
||||
. = TRUE
|
||||
|
||||
if(href_list["set_global_limit"])
|
||||
var/newlim = input("Input new thrust limit (0..100%)", "Thrust limit", linked.thrust_limit*100) as num
|
||||
if(!CanInteract(user, state))
|
||||
return TOPIC_NOACTION
|
||||
linked.thrust_limit = CLAMP(newlim/100, 0, 1)
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
E.set_thrust_limit(linked.thrust_limit)
|
||||
return TOPIC_REFRESH
|
||||
if("global_limit")
|
||||
linked.thrust_limit = clamp(linked.thrust_limit + text2num(params["global_limit"]), 0, 1)
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
E.set_thrust_limit(linked.thrust_limit)
|
||||
. = TRUE
|
||||
|
||||
if(href_list["global_limit"])
|
||||
linked.thrust_limit = CLAMP(linked.thrust_limit + text2num(href_list["global_limit"]), 0, 1)
|
||||
for(var/datum/ship_engine/E in linked.engines)
|
||||
E.set_thrust_limit(linked.thrust_limit)
|
||||
return TOPIC_REFRESH
|
||||
|
||||
if(href_list["engine"])
|
||||
if(href_list["set_limit"])
|
||||
var/datum/ship_engine/E = locate(href_list["engine"])
|
||||
if("set_limit")
|
||||
var/datum/ship_engine/E = locate(params["engine"])
|
||||
var/newlim = input("Input new thrust limit (0..100)", "Thrust limit", E.get_thrust_limit()) as num
|
||||
if(!CanInteract(user, state))
|
||||
return
|
||||
var/limit = CLAMP(newlim/100, 0, 1)
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return FALSE
|
||||
var/limit = clamp(newlim/100, 0, 1)
|
||||
if(istype(E))
|
||||
E.set_thrust_limit(limit)
|
||||
return TOPIC_REFRESH
|
||||
if(href_list["limit"])
|
||||
var/datum/ship_engine/E = locate(href_list["engine"])
|
||||
var/limit = CLAMP(E.get_thrust_limit() + text2num(href_list["limit"]), 0, 1)
|
||||
if(istype(E))
|
||||
E.set_thrust_limit(limit)
|
||||
return TOPIC_REFRESH
|
||||
. = TRUE
|
||||
|
||||
if(href_list["toggle"])
|
||||
var/datum/ship_engine/E = locate(href_list["engine"])
|
||||
if("limit")
|
||||
var/datum/ship_engine/E = locate(params["engine"])
|
||||
var/limit = clamp(E.get_thrust_limit() + text2num(params["limit"]), 0, 1)
|
||||
if(istype(E))
|
||||
E.set_thrust_limit(limit)
|
||||
. = TRUE
|
||||
|
||||
if("toggle")
|
||||
var/datum/ship_engine/E = locate(params["engine"])
|
||||
if(istype(E))
|
||||
E.toggle()
|
||||
return TOPIC_REFRESH
|
||||
return TOPIC_REFRESH
|
||||
return TOPIC_NOACTION
|
||||
. = TRUE
|
||||
|
||||
if(. && !issilicon(usr))
|
||||
playsound(src, "terminal_type", 50, 1)
|
||||
@@ -22,6 +22,7 @@ GLOBAL_LIST_EMPTY(all_waypoints)
|
||||
circuit = /obj/item/weapon/circuitboard/helm
|
||||
core_skill = /datum/skill/pilot
|
||||
var/autopilot = 0
|
||||
var/autopilot_disabled = TRUE
|
||||
var/list/known_sectors = list()
|
||||
var/dx //desitnation
|
||||
var/dy //coordinates
|
||||
@@ -36,7 +37,7 @@ GLOBAL_LIST_EMPTY(all_waypoints)
|
||||
/obj/machinery/computer/ship/helm/proc/get_known_sectors()
|
||||
var/area/overmap/map = locate() in world
|
||||
for(var/obj/effect/overmap/visitable/sector/S in map)
|
||||
if (S.known)
|
||||
if(S.known)
|
||||
var/datum/computer_file/data/waypoint/R = new()
|
||||
R.fields["name"] = S.name
|
||||
R.fields["x"] = S.x
|
||||
@@ -45,7 +46,7 @@ GLOBAL_LIST_EMPTY(all_waypoints)
|
||||
|
||||
/obj/machinery/computer/ship/helm/process()
|
||||
..()
|
||||
if (autopilot && dx && dy)
|
||||
if(autopilot && dx && dy && !autopilot_disabled)
|
||||
var/turf/T = locate(dx,dy,global.using_map.overmap_z)
|
||||
if(linked.loc == T)
|
||||
if(linked.is_still())
|
||||
@@ -60,13 +61,13 @@ GLOBAL_LIST_EMPTY(all_waypoints)
|
||||
var/heading = linked.get_heading()
|
||||
|
||||
// Destination is current grid or speedlimit is exceeded
|
||||
if ((get_dist(linked.loc, T) <= brake_path) || speed > speedlimit)
|
||||
if((get_dist(linked.loc, T) <= brake_path) || speed > speedlimit)
|
||||
linked.decelerate()
|
||||
// Heading does not match direction
|
||||
else if (heading & ~direction)
|
||||
else if(heading & ~direction)
|
||||
linked.accelerate(turn(heading & ~direction, 180), accellimit)
|
||||
// All other cases, move toward direction
|
||||
else if (speed + acceleration <= speedlimit)
|
||||
else if(speed + acceleration <= speedlimit)
|
||||
linked.accelerate(direction, accellimit)
|
||||
linked.operator_skill = null//if this is on you can't dodge meteors
|
||||
return
|
||||
@@ -78,149 +79,176 @@ GLOBAL_LIST_EMPTY(all_waypoints)
|
||||
linked.relaymove(user, direction, accellimit)
|
||||
return 1
|
||||
|
||||
/obj/machinery/computer/ship/helm/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
|
||||
/obj/machinery/computer/ship/helm/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!linked)
|
||||
display_reconnect_dialog(user, "helm")
|
||||
return
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OvermapHelm", "[linked.name] Helm Control") // 565, 545
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/ship/helm/tgui_data(mob/user)
|
||||
var/list/data = ..()
|
||||
|
||||
var/turf/T = get_turf(linked)
|
||||
var/obj/effect/overmap/visitable/sector/current_sector = locate() in T
|
||||
|
||||
data["sector"] = current_sector ? current_sector.name : "Deep Space"
|
||||
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
|
||||
data["landed"] = linked.get_landed_info()
|
||||
data["s_x"] = linked.x
|
||||
data["s_y"] = linked.y
|
||||
data["dest"] = dy && dx
|
||||
data["d_x"] = dx
|
||||
data["d_y"] = dy
|
||||
data["speedlimit"] = speedlimit ? speedlimit*1000 : "Halted"
|
||||
data["accel"] = min(round(linked.get_acceleration()*1000, 0.01),accellimit*1000)
|
||||
data["heading"] = linked.get_heading_degrees()
|
||||
data["autopilot_disabled"] = autopilot_disabled
|
||||
data["autopilot"] = autopilot
|
||||
data["manual_control"] = viewing_overmap(user)
|
||||
data["canburn"] = linked.can_burn()
|
||||
data["accellimit"] = accellimit*1000
|
||||
|
||||
var/speed = round(linked.get_speed()*1000, 0.01)
|
||||
var/speed_color = null
|
||||
if(linked.get_speed() < SHIP_SPEED_SLOW)
|
||||
speed_color = "good"
|
||||
if(linked.get_speed() > SHIP_SPEED_FAST)
|
||||
speed_color = "average"
|
||||
data["speed"] = speed
|
||||
data["speed_color"] = speed_color
|
||||
|
||||
if(linked.get_speed())
|
||||
data["ETAnext"] = "[round(linked.ETA()/10)] seconds"
|
||||
else
|
||||
var/turf/T = get_turf(linked)
|
||||
var/obj/effect/overmap/visitable/sector/current_sector = locate() in T
|
||||
data["ETAnext"] = "N/A"
|
||||
|
||||
data["sector"] = current_sector ? current_sector.name : "Deep Space"
|
||||
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
|
||||
data["landed"] = linked.get_landed_info()
|
||||
data["s_x"] = linked.x
|
||||
data["s_y"] = linked.y
|
||||
data["dest"] = dy && dx
|
||||
data["d_x"] = dx
|
||||
data["d_y"] = dy
|
||||
data["speedlimit"] = speedlimit ? speedlimit*1000 : "Halted"
|
||||
data["accel"] = min(round(linked.get_acceleration()*1000, 0.01),accellimit*1000)
|
||||
data["heading"] = linked.get_heading_degrees()
|
||||
data["autopilot"] = autopilot
|
||||
data["manual_control"] = viewing_overmap(user)
|
||||
data["canburn"] = linked.can_burn()
|
||||
data["accellimit"] = accellimit*1000
|
||||
var/list/locations[0]
|
||||
for (var/key in known_sectors)
|
||||
var/datum/computer_file/data/waypoint/R = known_sectors[key]
|
||||
var/list/rdata[0]
|
||||
rdata["name"] = R.fields["name"]
|
||||
rdata["x"] = R.fields["x"]
|
||||
rdata["y"] = R.fields["y"]
|
||||
rdata["reference"] = "\ref[R]"
|
||||
locations.Add(list(rdata))
|
||||
|
||||
var/speed = round(linked.get_speed()*1000, 0.01)
|
||||
if(linked.get_speed() < SHIP_SPEED_SLOW)
|
||||
speed = "<span class='good'>[speed]</span>"
|
||||
if(linked.get_speed() > SHIP_SPEED_FAST)
|
||||
speed = "<span class='average'>[speed]</span>"
|
||||
data["speed"] = speed
|
||||
data["locations"] = locations
|
||||
return data
|
||||
|
||||
if(linked.get_speed())
|
||||
data["ETAnext"] = "[round(linked.ETA()/10)] seconds"
|
||||
else
|
||||
data["ETAnext"] = "N/A"
|
||||
|
||||
var/list/locations[0]
|
||||
for (var/key in known_sectors)
|
||||
var/datum/computer_file/data/waypoint/R = known_sectors[key]
|
||||
var/list/rdata[0]
|
||||
rdata["name"] = R.fields["name"]
|
||||
rdata["x"] = R.fields["x"]
|
||||
rdata["y"] = R.fields["y"]
|
||||
rdata["reference"] = "\ref[R]"
|
||||
locations.Add(list(rdata))
|
||||
|
||||
data["locations"] = locations
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "helm.tmpl", "[linked.name] Helm Control", 565, 545)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/ship/helm/OnTopic(var/mob/user, var/list/href_list, state)
|
||||
/obj/machinery/computer/ship/helm/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TOPIC_HANDLED
|
||||
return TRUE
|
||||
|
||||
if(!linked)
|
||||
return TOPIC_HANDLED
|
||||
return FALSE
|
||||
|
||||
if (href_list["add"])
|
||||
var/datum/computer_file/data/waypoint/R = new()
|
||||
var/sec_name = input("Input naviation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text
|
||||
if(!CanInteract(user,state))
|
||||
return TOPIC_NOACTION
|
||||
if(!sec_name)
|
||||
sec_name = "Sector #[known_sectors.len]"
|
||||
R.fields["name"] = sec_name
|
||||
if(sec_name in known_sectors)
|
||||
to_chat(user, "<span class='warning'>Sector with that name already exists, please input a different name.</span>")
|
||||
return TOPIC_REFRESH
|
||||
switch(href_list["add"])
|
||||
if("current")
|
||||
R.fields["x"] = linked.x
|
||||
R.fields["y"] = linked.y
|
||||
if("new")
|
||||
var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num
|
||||
if(!CanInteract(user,state))
|
||||
return TOPIC_REFRESH
|
||||
var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num
|
||||
if(!CanInteract(user,state))
|
||||
return TOPIC_NOACTION
|
||||
R.fields["x"] = CLAMP(newx, 1, world.maxx)
|
||||
R.fields["y"] = CLAMP(newy, 1, world.maxy)
|
||||
known_sectors[sec_name] = R
|
||||
switch(action)
|
||||
if("add")
|
||||
var/datum/computer_file/data/waypoint/R = new()
|
||||
var/sec_name = input("Input navigation entry name", "New navigation entry", "Sector #[known_sectors.len]") as text
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return FALSE
|
||||
if(!sec_name)
|
||||
sec_name = "Sector #[known_sectors.len]"
|
||||
R.fields["name"] = sec_name
|
||||
if(sec_name in known_sectors)
|
||||
to_chat(usr, "<span class='warning'>Sector with that name already exists, please input a different name.</span>")
|
||||
return TRUE
|
||||
switch(params["add"])
|
||||
if("current")
|
||||
R.fields["x"] = linked.x
|
||||
R.fields["y"] = linked.y
|
||||
if("new")
|
||||
var/newx = input("Input new entry x coordinate", "Coordinate input", linked.x) as num
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return TRUE
|
||||
var/newy = input("Input new entry y coordinate", "Coordinate input", linked.y) as num
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return FALSE
|
||||
R.fields["x"] = CLAMP(newx, 1, world.maxx)
|
||||
R.fields["y"] = CLAMP(newy, 1, world.maxy)
|
||||
known_sectors[sec_name] = R
|
||||
. = TRUE
|
||||
|
||||
if (href_list["remove"])
|
||||
var/datum/computer_file/data/waypoint/R = locate(href_list["remove"])
|
||||
if(R)
|
||||
known_sectors.Remove(R.fields["name"])
|
||||
qdel(R)
|
||||
if("remove")
|
||||
var/datum/computer_file/data/waypoint/R = locate(params["remove"])
|
||||
if(R)
|
||||
known_sectors.Remove(R.fields["name"])
|
||||
qdel(R)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["setx"])
|
||||
var/newx = input("Input new destiniation x coordinate", "Coordinate input", dx) as num|null
|
||||
if(!CanInteract(user,state))
|
||||
return
|
||||
if (newx)
|
||||
dx = CLAMP(newx, 1, world.maxx)
|
||||
if("setcoord")
|
||||
if(params["setx"])
|
||||
var/newx = input("Input new destiniation x coordinate", "Coordinate input", dx) as num|null
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return
|
||||
if(newx)
|
||||
dx = CLAMP(newx, 1, world.maxx)
|
||||
|
||||
if (href_list["sety"])
|
||||
var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null
|
||||
if(!CanInteract(user,state))
|
||||
return
|
||||
if (newy)
|
||||
dy = CLAMP(newy, 1, world.maxy)
|
||||
if(params["sety"])
|
||||
var/newy = input("Input new destiniation y coordinate", "Coordinate input", dy) as num|null
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return
|
||||
if(newy)
|
||||
dy = CLAMP(newy, 1, world.maxy)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["x"] && href_list["y"])
|
||||
dx = text2num(href_list["x"])
|
||||
dy = text2num(href_list["y"])
|
||||
if("setds")
|
||||
dx = text2num(params["x"])
|
||||
dy = text2num(params["y"])
|
||||
. = TRUE
|
||||
|
||||
if (href_list["reset"])
|
||||
dx = 0
|
||||
dy = 0
|
||||
if("reset")
|
||||
dx = 0
|
||||
dy = 0
|
||||
. = TRUE
|
||||
|
||||
if (href_list["speedlimit"])
|
||||
var/newlimit = input("Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000) as num|null
|
||||
if(newlimit)
|
||||
speedlimit = CLAMP(newlimit/1000, 0, 100)
|
||||
if (href_list["accellimit"])
|
||||
var/newlimit = input("Input new acceleration limit", "Acceleration limit", accellimit*1000) as num|null
|
||||
if(newlimit)
|
||||
accellimit = max(newlimit/1000, 0)
|
||||
if("speedlimit")
|
||||
var/newlimit = input("Input new speed limit for autopilot (0 to brake)", "Autopilot speed limit", speedlimit*1000) as num|null
|
||||
if(newlimit)
|
||||
speedlimit = CLAMP(newlimit/1000, 0, 100)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["move"])
|
||||
var/ndir = text2num(href_list["move"])
|
||||
if(prob(user.skill_fail_chance(/datum/skill/pilot, 50, linked.skill_needed, factor = 1)))
|
||||
ndir = turn(ndir,pick(90,-90))
|
||||
linked.relaymove(user, ndir, accellimit)
|
||||
if("accellimit")
|
||||
var/newlimit = input("Input new acceleration limit", "Acceleration limit", accellimit*1000) as num|null
|
||||
if(newlimit)
|
||||
accellimit = max(newlimit/1000, 0)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["brake"])
|
||||
linked.decelerate()
|
||||
if("move")
|
||||
var/ndir = text2num(params["dir"])
|
||||
if(prob(usr.skill_fail_chance(/datum/skill/pilot, 50, linked.skill_needed, factor = 1)))
|
||||
ndir = turn(ndir,pick(90,-90))
|
||||
linked.relaymove(usr, ndir, accellimit)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["apilot"])
|
||||
autopilot = !autopilot
|
||||
if("brake")
|
||||
linked.decelerate()
|
||||
. = TRUE
|
||||
|
||||
if (href_list["manual"])
|
||||
viewing_overmap(user) ? unlook(user) : look(user)
|
||||
if("apilot")
|
||||
if(autopilot_disabled)
|
||||
autopilot = FALSE
|
||||
else
|
||||
autopilot = !autopilot
|
||||
. = TRUE
|
||||
|
||||
if("apilot_lock")
|
||||
autopilot_disabled = !autopilot_disabled
|
||||
autopilot = FALSE
|
||||
. = TRUE
|
||||
|
||||
add_fingerprint(user)
|
||||
updateUsrDialog()
|
||||
if("manual")
|
||||
viewing_overmap(usr) ? unlook(usr) : look(usr)
|
||||
. = TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
if(. && !issilicon(usr))
|
||||
playsound(src, "terminal_type", 50, 1)
|
||||
|
||||
|
||||
/obj/machinery/computer/ship/navigation
|
||||
@@ -228,49 +256,21 @@ GLOBAL_LIST_EMPTY(all_waypoints)
|
||||
icon_keyboard = "generic_key"
|
||||
icon_screen = "helm"
|
||||
circuit = /obj/item/weapon/circuitboard/nav
|
||||
var/datum/tgui_module/ship/nav/nav_tgui
|
||||
|
||||
/obj/machinery/computer/ship/navigation/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
if(!linked)
|
||||
display_reconnect_dialog(user, "Navigation")
|
||||
return
|
||||
/obj/machinery/computer/ship/navigation/Initialize()
|
||||
. = ..()
|
||||
nav_tgui = new(src)
|
||||
|
||||
var/data[0]
|
||||
/obj/machinery/computer/ship/navigation/Destroy()
|
||||
QDEL_NULL(nav_tgui)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/computer/ship/navigation/sync_linked(user)
|
||||
return nav_tgui?.sync_linked()
|
||||
|
||||
var/turf/T = get_turf(linked)
|
||||
var/obj/effect/overmap/visitable/sector/current_sector = locate() in T
|
||||
|
||||
data["sector"] = current_sector ? current_sector.name : "Deep Space"
|
||||
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
|
||||
data["s_x"] = linked.x
|
||||
data["s_y"] = linked.y
|
||||
data["speed"] = round(linked.get_speed()*1000, 0.01)
|
||||
data["accel"] = round(linked.get_acceleration()*1000, 0.01)
|
||||
data["heading"] = linked.get_heading_degrees()
|
||||
data["viewing"] = viewing_overmap(user)
|
||||
|
||||
if(linked.get_speed())
|
||||
data["ETAnext"] = "[round(linked.ETA()/10)] seconds"
|
||||
else
|
||||
data["ETAnext"] = "N/A"
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "nav.tmpl", "[linked.name] Navigation Screen", 380, 530)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
|
||||
/obj/machinery/computer/ship/navigation/OnTopic(var/mob/user, var/list/href_list)
|
||||
if(..())
|
||||
return TOPIC_HANDLED
|
||||
|
||||
if (!linked)
|
||||
return TOPIC_NOACTION
|
||||
|
||||
if (href_list["viewing"])
|
||||
viewing_overmap(user) ? unlook(user) : look(user)
|
||||
return TOPIC_REFRESH
|
||||
/obj/machinery/computer/ship/navigation/tgui_interact(mob/user, datum/tgui/ui)
|
||||
return nav_tgui?.tgui_interact(user, ui)
|
||||
|
||||
/obj/machinery/computer/ship/navigation/telescreen //little hacky but it's only used on one ship so it should be okay
|
||||
icon_state = "tele_nav"
|
||||
|
||||
@@ -20,14 +20,29 @@
|
||||
sensors = S
|
||||
break
|
||||
|
||||
/obj/machinery/computer/ship/sensors/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
/obj/machinery/computer/ship/sensors/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!linked)
|
||||
display_reconnect_dialog(user, "sensors")
|
||||
return
|
||||
|
||||
var/data[0]
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OvermapShipSensors", "[linked.name] Sensors Control") // 420, 530
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/ship/sensors/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["viewing"] = viewing_overmap(user)
|
||||
data["on"] = 0
|
||||
data["range"] = "N/A"
|
||||
data["health"] = 0
|
||||
data["max_health"] = 0
|
||||
data["heat"] = 0
|
||||
data["critical_heat"] = 0
|
||||
data["status"] = "MISSING"
|
||||
data["contacts"] = list()
|
||||
|
||||
if(sensors)
|
||||
data["on"] = sensors.use_power
|
||||
data["range"] = sensors.range
|
||||
@@ -53,54 +68,48 @@
|
||||
if(bearing < 0)
|
||||
bearing += 360
|
||||
contacts.Add(list(list("name"=O.name, "ref"="\ref[O]", "bearing"=bearing)))
|
||||
if(contacts.len)
|
||||
data["contacts"] = contacts
|
||||
else
|
||||
data["status"] = "MISSING"
|
||||
data["range"] = "N/A"
|
||||
data["on"] = 0
|
||||
data["contacts"] = contacts
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "shipsensors.tmpl", "[linked.name] Sensors Control", 420, 530, src)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/computer/ship/sensors/OnTopic(var/mob/user, var/list/href_list, state)
|
||||
/obj/machinery/computer/ship/sensors/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TOPIC_HANDLED
|
||||
return TRUE
|
||||
|
||||
if (!linked)
|
||||
return TOPIC_NOACTION
|
||||
if(!linked)
|
||||
return FALSE
|
||||
|
||||
if (href_list["viewing"])
|
||||
if(user && !isAI(user))
|
||||
viewing_overmap(user) ? unlook(user) : look(user)
|
||||
return TOPIC_REFRESH
|
||||
switch(action)
|
||||
if("viewing")
|
||||
if(usr && !isAI(usr))
|
||||
viewing_overmap(usr) ? unlook(usr) : look(usr)
|
||||
. = TRUE
|
||||
|
||||
if (href_list["link"])
|
||||
find_sensors()
|
||||
return TOPIC_REFRESH
|
||||
if("link")
|
||||
find_sensors()
|
||||
. = TRUE
|
||||
|
||||
if("scan")
|
||||
var/obj/effect/overmap/O = locate(params["scan"])
|
||||
if(istype(O) && !QDELETED(O) && (O in view(7,linked)))
|
||||
new/obj/item/weapon/paper/(get_turf(src), O.get_scan_data(usr), "paper (Sensor Scan - [O])")
|
||||
. = TRUE
|
||||
|
||||
if(sensors)
|
||||
if (href_list["range"])
|
||||
var/nrange = input("Set new sensors range", "Sensor range", sensors.range) as num|null
|
||||
if(!CanInteract(user,state))
|
||||
return TOPIC_NOACTION
|
||||
if (nrange)
|
||||
sensors.set_range(CLAMP(nrange, 1, world.view))
|
||||
return TOPIC_REFRESH
|
||||
if (href_list["toggle"])
|
||||
sensors.toggle()
|
||||
return TOPIC_REFRESH
|
||||
switch(action)
|
||||
if("range")
|
||||
var/nrange = input("Set new sensors range", "Sensor range", sensors.range) as num|null
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return FALSE
|
||||
if(nrange)
|
||||
sensors.set_range(CLAMP(nrange, 1, world.view))
|
||||
. = TRUE
|
||||
if("toggle")
|
||||
sensors.toggle()
|
||||
. = TRUE
|
||||
|
||||
if (href_list["scan"])
|
||||
var/obj/effect/overmap/O = locate(href_list["scan"])
|
||||
if(istype(O) && !QDELETED(O) && (O in view(7,linked)))
|
||||
playsound(src, "sound/machines/dotprinter.ogg", 30, 1)
|
||||
new/obj/item/weapon/paper/(get_turf(src), O.get_scan_data(user), "paper (Sensor Scan - [O])")
|
||||
return TOPIC_HANDLED
|
||||
if(. && !issilicon(usr))
|
||||
playsound(src, "terminal_type", 50, 1)
|
||||
|
||||
/obj/machinery/computer/ship/sensors/process()
|
||||
..()
|
||||
|
||||
@@ -37,22 +37,31 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
|
||||
popup.set_content("<center><strong><font color = 'red'>Error</strong></font><br>Unable to connect to [flavor].<br><a href='?src=\ref[src];sync=1'>Reconnect</a></center>")
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/computer/ship/Topic(href, href_list)
|
||||
if(..())
|
||||
return TRUE
|
||||
if(href_list["sync"])
|
||||
if(sync_linked(usr))
|
||||
interface_interact(usr)
|
||||
return TRUE
|
||||
|
||||
// In computer_shims for now - we had to define it.
|
||||
// /obj/machinery/computer/ship/interface_interact(var/mob/user)
|
||||
// ui_interact(user)
|
||||
// return TRUE
|
||||
|
||||
/obj/machinery/computer/ship/OnTopic(var/mob/user, var/list/href_list)
|
||||
/obj/machinery/computer/ship/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TOPIC_HANDLED
|
||||
if(href_list["sync"])
|
||||
sync_linked(user)
|
||||
return TOPIC_REFRESH
|
||||
if(href_list["close"])
|
||||
unlook(user)
|
||||
user.unset_machine()
|
||||
return TOPIC_HANDLED
|
||||
return TOPIC_NOACTION
|
||||
return TRUE
|
||||
switch(action)
|
||||
if("sync")
|
||||
sync_linked(usr)
|
||||
return TRUE
|
||||
if("close")
|
||||
unlook(usr)
|
||||
usr.unset_machine()
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
// Management of mob view displacement. look to shift view to the ship on the overmap; unlook to shift back.
|
||||
|
||||
@@ -60,6 +69,7 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
|
||||
if(linked)
|
||||
apply_visual(user)
|
||||
user.reset_view(linked)
|
||||
user.set_machine(src)
|
||||
user.set_viewsize(world.view + extra_view)
|
||||
GLOB.moved_event.register(user, src, /obj/machinery/computer/ship/proc/unlook)
|
||||
// TODO GLOB.stat_set_event.register(user, src, /obj/machinery/computer/ship/proc/unlook)
|
||||
@@ -75,17 +85,21 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
|
||||
/obj/machinery/computer/ship/proc/viewing_overmap(mob/user)
|
||||
return (weakref(user) in viewers)
|
||||
|
||||
/obj/machinery/computer/ship/CouldNotUseTopic(mob/user)
|
||||
/obj/machinery/computer/ship/tgui_status(mob/user)
|
||||
. = ..()
|
||||
if(. > STATUS_DISABLED)
|
||||
if(viewing_overmap(user))
|
||||
look(user)
|
||||
return
|
||||
unlook(user)
|
||||
|
||||
/obj/machinery/computer/ship/CouldUseTopic(mob/user)
|
||||
/obj/machinery/computer/ship/tgui_close(mob/user)
|
||||
. = ..()
|
||||
if(viewing_overmap(user))
|
||||
look(user)
|
||||
user.unset_machine()
|
||||
unlook(user)
|
||||
|
||||
/obj/machinery/computer/ship/check_eye(var/mob/user)
|
||||
if (!get_dist(user, src) > 1 || user.blinded || !linked )
|
||||
if(!get_dist(user, src) > 1 || user.blinded || !linked)
|
||||
unlook(user)
|
||||
return -1
|
||||
else
|
||||
|
||||
@@ -19,7 +19,7 @@ var/list/ship_engines = list()
|
||||
|
||||
//Returns status string for this engine
|
||||
/datum/ship_engine/proc/get_status()
|
||||
return "All systems nominal"
|
||||
return list("All systems nominal")
|
||||
|
||||
/datum/ship_engine/proc/get_thrust()
|
||||
return 1
|
||||
|
||||
@@ -103,18 +103,17 @@
|
||||
. = list()
|
||||
.+= "Location: [get_area(src)]."
|
||||
if(stat & NOPOWER)
|
||||
.+= "<span class='average'>Insufficient power to operate.</span>"
|
||||
.+= list(list("Insufficient power to operate.", "bad"))
|
||||
if(!check_fuel())
|
||||
.+= "<span class='average'>Insufficient fuel for a burn.</span>"
|
||||
.+= list(list("Insufficient fuel for a burn.", "bad"))
|
||||
if(stat & BROKEN)
|
||||
.+= "<span class='average'>Inoperable engine configuration.</span>"
|
||||
.+= list(list("Inoperable engine configuration.", "bad"))
|
||||
if(blockage)
|
||||
.+= "<span class='average'>Obstruction of airflow detected.</span>"
|
||||
.+= list(list("Obstruction of airflow detected.", "bad"))
|
||||
|
||||
.+= "Propellant total mass: [round(air_contents.get_mass(),0.01)] kg."
|
||||
.+= "Propellant used per burn: [round(air_contents.get_mass() * volume_per_burn * thrust_limit / air_contents.volume,0.01)] kg."
|
||||
.+= "Propellant pressure: [round(air_contents.return_pressure()/1000,0.1)] MPa."
|
||||
. = jointext(.,"<br>")
|
||||
|
||||
/obj/machinery/atmospherics/unary/engine/power_change()
|
||||
. = ..()
|
||||
|
||||
@@ -61,9 +61,7 @@
|
||||
. = list()
|
||||
.+= "Location: [get_area(src)]."
|
||||
if(!powered())
|
||||
.+= "Insufficient power to operate."
|
||||
|
||||
. = jointext(.,"<br>")
|
||||
.+= list(list("Insufficient power to operate.", "bad"))
|
||||
|
||||
/obj/machinery/ion_engine/proc/burn()
|
||||
if(!on && !powered())
|
||||
|
||||
@@ -400,8 +400,14 @@
|
||||
spinup_counter = round(spinup_delay / idle_multiplier)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/power/shield_generator/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
|
||||
var/data[0]
|
||||
/obj/machinery/power/shield_generator/tgui_interact(mob/user, datum/tgui/ui, datum/tgui/parent_ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "OvermapShieldGenerator", name) // 500, 800
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/power/shield_generator/tgui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["running"] = running
|
||||
data["modes"] = get_flag_descriptions()
|
||||
@@ -427,12 +433,7 @@
|
||||
data["idle_valid_values"] = idle_valid_values
|
||||
data["spinup_counter"] = spinup_counter
|
||||
|
||||
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
||||
if (!ui)
|
||||
ui = new(user, src, ui_key, "shield_generator.tmpl", src.name, 500, 800)
|
||||
ui.set_initial_data(data)
|
||||
ui.open()
|
||||
ui.set_auto_update(1)
|
||||
return data
|
||||
|
||||
/obj/machinery/power/shield_generator/attack_hand(mob/user)
|
||||
if((. = ..()))
|
||||
@@ -440,99 +441,99 @@
|
||||
if(panel_open && Adjacent(user))
|
||||
wires.Interact(user)
|
||||
return
|
||||
if(CanUseTopic(user, global.default_state) > STATUS_CLOSE)
|
||||
ui_interact(user)
|
||||
return TRUE
|
||||
tgui_interact(user)
|
||||
|
||||
/obj/machinery/power/shield_generator/CanUseTopic(var/mob/user)
|
||||
/obj/machinery/power/shield_generator/tgui_status(mob/user)
|
||||
if(issilicon(user) && !Adjacent(user) && ai_control_disabled)
|
||||
return STATUS_UPDATE
|
||||
if(panel_open)
|
||||
return min(..(), STATUS_DISABLED)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/power/shield_generator/Topic(href, href_list, datum/topic_state/state = default_state)
|
||||
if((. = ..()))
|
||||
return
|
||||
/obj/machinery/power/shield_generator/tgui_act(action, list/params, datum/tgui/ui, datum/tgui_state/state)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(href_list["begin_shutdown"])
|
||||
if(running < SHIELD_RUNNING) // Discharging or off
|
||||
return
|
||||
var/alert = alert(usr, "Are you sure you wish to do this? It will drain the power inside the internal storage rapidly.", "Are you sure?", "Yes", "No")
|
||||
if(!CanInteract(usr, state))
|
||||
return
|
||||
if(running < SHIELD_RUNNING)
|
||||
return
|
||||
if(alert == "Yes")
|
||||
set_idle(TRUE) // do this first to clear the field
|
||||
running = SHIELD_DISCHARGING
|
||||
return TOPIC_REFRESH
|
||||
switch(action)
|
||||
if("begin_shutdown")
|
||||
if(running < SHIELD_RUNNING) // Discharging or off
|
||||
return
|
||||
var/alert = alert(usr, "Are you sure you wish to do this? It will drain the power inside the internal storage rapidly.", "Are you sure?", "Yes", "No")
|
||||
if(tgui_status(usr, state) != STATUS_INTERACTIVE)
|
||||
return
|
||||
if(running < SHIELD_RUNNING)
|
||||
return
|
||||
if(alert == "Yes")
|
||||
set_idle(TRUE) // do this first to clear the field
|
||||
running = SHIELD_DISCHARGING
|
||||
return TRUE
|
||||
|
||||
if(href_list["start_generator"])
|
||||
if(offline_for)
|
||||
return
|
||||
set_idle(TRUE)
|
||||
return TOPIC_REFRESH
|
||||
if("start_generator")
|
||||
if(offline_for)
|
||||
return
|
||||
set_idle(TRUE)
|
||||
return TRUE
|
||||
|
||||
if(href_list["toggle_idle"])
|
||||
if(running < SHIELD_RUNNING)
|
||||
return TOPIC_HANDLED
|
||||
set_idle(text2num(href_list["toggle_idle"]))
|
||||
return TOPIC_REFRESH
|
||||
if("toggle_idle")
|
||||
if(running < SHIELD_RUNNING)
|
||||
return TRUE
|
||||
set_idle(text2num(params["toggle_idle"]))
|
||||
return TRUE
|
||||
|
||||
// Instantly drops the shield, but causes a cooldown before it may be started again. Also carries a risk of EMP at high charge.
|
||||
if(href_list["emergency_shutdown"])
|
||||
if(!running)
|
||||
return TOPIC_HANDLED
|
||||
// Instantly drops the shield, but causes a cooldown before it may be started again. Also carries a risk of EMP at high charge.
|
||||
if("emergency_shutdown")
|
||||
if(!running)
|
||||
return TRUE
|
||||
|
||||
var/choice = input(usr, "Are you sure that you want to initiate an emergency shield shutdown? This will instantly drop the shield, and may result in unstable release of stored electromagnetic energy. Proceed at your own risk.") in list("Yes", "No")
|
||||
if((choice != "Yes") || !running)
|
||||
return TOPIC_HANDLED
|
||||
var/choice = input(usr, "Are you sure that you want to initiate an emergency shield shutdown? This will instantly drop the shield, and may result in unstable release of stored electromagnetic energy. Proceed at your own risk.") in list("Yes", "No")
|
||||
if((choice != "Yes") || !running)
|
||||
return TRUE
|
||||
|
||||
// If the shield would take 5 minutes to disperse and shut down using regular methods, it will take x1.5 (7 minutes and 30 seconds) of this time to cool down after emergency shutdown
|
||||
offline_for = round(current_energy / (SHIELD_SHUTDOWN_DISPERSION_RATE / 1.5))
|
||||
var/old_energy = current_energy
|
||||
shutdown_field()
|
||||
log_and_message_admins("has triggered \the [src]'s emergency shutdown!", usr)
|
||||
spawn()
|
||||
empulse(src, old_energy / 60000000, old_energy / 32000000, 1) // If shields are charged at 450 MJ, the EMP will be 7.5, 14.0625. 90 MJ, 1.5, 2.8125
|
||||
old_energy = 0
|
||||
// If the shield would take 5 minutes to disperse and shut down using regular methods, it will take x1.5 (7 minutes and 30 seconds) of this time to cool down after emergency shutdown
|
||||
offline_for = round(current_energy / (SHIELD_SHUTDOWN_DISPERSION_RATE / 1.5))
|
||||
var/old_energy = current_energy
|
||||
shutdown_field()
|
||||
log_and_message_admins("has triggered \the [src]'s emergency shutdown!", usr)
|
||||
spawn()
|
||||
empulse(src, old_energy / 60000000, old_energy / 32000000, 1) // If shields are charged at 450 MJ, the EMP will be 7.5, 14.0625. 90 MJ, 1.5, 2.8125
|
||||
old_energy = 0
|
||||
|
||||
return TOPIC_REFRESH
|
||||
return TRUE
|
||||
|
||||
if(mode_changes_locked)
|
||||
return TOPIC_REFRESH
|
||||
return TRUE
|
||||
|
||||
if(href_list["set_range"])
|
||||
var/new_range = input(usr, "Enter new field range (1-[world.maxx]). Leave blank to cancel.", "Field Radius Control", field_radius) as num
|
||||
if(!new_range)
|
||||
return TOPIC_HANDLED
|
||||
target_radius = between(1, new_range, world.maxx)
|
||||
return TOPIC_REFRESH
|
||||
switch(action)
|
||||
if("set_range")
|
||||
var/new_range = input(usr, "Enter new field range (1-[world.maxx]). Leave blank to cancel.", "Field Radius Control", field_radius) as num
|
||||
if(!new_range)
|
||||
return TRUE
|
||||
target_radius = between(1, new_range, world.maxx)
|
||||
return TRUE
|
||||
|
||||
if(href_list["set_input_cap"])
|
||||
var/new_cap = round(input(usr, "Enter new input cap (in kW). Enter 0 or nothing to disable input cap.", "Generator Power Control", round(input_cap / 1000)) as num)
|
||||
if(!new_cap)
|
||||
input_cap = 0
|
||||
return
|
||||
input_cap = max(0, new_cap) * 1000
|
||||
return TOPIC_REFRESH
|
||||
if("set_input_cap")
|
||||
var/new_cap = round(input(usr, "Enter new input cap (in kW). Enter 0 or nothing to disable input cap.", "Generator Power Control", round(input_cap / 1000)) as num)
|
||||
if(!new_cap)
|
||||
input_cap = 0
|
||||
return
|
||||
input_cap = max(0, new_cap) * 1000
|
||||
return TRUE
|
||||
|
||||
if(href_list["toggle_mode"])
|
||||
// Toggling hacked-only modes requires the hacked var to be set to 1
|
||||
if((text2num(href_list["toggle_mode"]) & (MODEFLAG_BYPASS | MODEFLAG_OVERCHARGE)) && !hacked)
|
||||
return TOPIC_HANDLED
|
||||
if("toggle_mode")
|
||||
// Toggling hacked-only modes requires the hacked var to be set to 1
|
||||
if((text2num(params["toggle_mode"]) & (MODEFLAG_BYPASS | MODEFLAG_OVERCHARGE)) && !hacked)
|
||||
return TRUE
|
||||
|
||||
toggle_flag(text2num(href_list["toggle_mode"]))
|
||||
return TOPIC_REFRESH
|
||||
toggle_flag(text2num(params["toggle_mode"]))
|
||||
return TRUE
|
||||
|
||||
if(href_list["switch_idle"])
|
||||
if(running == SHIELD_SPINNING_UP)
|
||||
return TOPIC_REFRESH
|
||||
var/new_idle = text2num(href_list["switch_idle"])
|
||||
if(new_idle in idle_valid_values)
|
||||
idle_multiplier = new_idle
|
||||
return TOPIC_REFRESH
|
||||
if("switch_idle")
|
||||
if(running == SHIELD_SPINNING_UP)
|
||||
return TRUE
|
||||
var/new_idle = text2num(params["switch_idle"])
|
||||
if(new_idle in idle_valid_values)
|
||||
idle_multiplier = new_idle
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/power/shield_generator/proc/field_integrity()
|
||||
if(full_shield_strength)
|
||||
|
||||
@@ -26,6 +26,9 @@ Code is pretty much ripped verbatim from nano modules, but with un-needed stuff
|
||||
if(host)
|
||||
host.tgui_close(user)
|
||||
|
||||
/datum/tgui_module/proc/check_eye(mob/user)
|
||||
return -1
|
||||
|
||||
/datum/tgui_module/proc/can_still_topic(mob/user, datum/tgui_state/state)
|
||||
return (tgui_status(user, state) == STATUS_INTERACTIVE)
|
||||
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/datum/tgui_module/ship
|
||||
var/obj/effect/overmap/visitable/ship/linked
|
||||
var/list/viewers
|
||||
var/extra_view = 0
|
||||
|
||||
/datum/tgui_module/ship/New()
|
||||
. = ..()
|
||||
sync_linked()
|
||||
if(linked)
|
||||
name = "[linked.name] [name]"
|
||||
|
||||
/datum/tgui_module/ship/Destroy()
|
||||
if(LAZYLEN(viewers))
|
||||
for(var/weakref/W in viewers)
|
||||
var/M = W.resolve()
|
||||
if(M)
|
||||
unlook(M)
|
||||
. = ..()
|
||||
|
||||
/datum/tgui_module/ship/tgui_status(mob/user)
|
||||
. = ..()
|
||||
if(. > STATUS_DISABLED)
|
||||
if(viewing_overmap(user))
|
||||
look(user)
|
||||
return
|
||||
unlook(user)
|
||||
|
||||
/datum/tgui_module/ship/tgui_close(mob/user)
|
||||
. = ..()
|
||||
user.unset_machine()
|
||||
unlook(user)
|
||||
|
||||
/datum/tgui_module/ship/proc/sync_linked()
|
||||
var/obj/effect/overmap/visitable/ship/sector = get_overmap_sector(get_z(tgui_host()))
|
||||
if(!sector)
|
||||
return
|
||||
return attempt_hook_up_recursive(sector)
|
||||
|
||||
/datum/tgui_module/ship/proc/attempt_hook_up_recursive(obj/effect/overmap/visitable/ship/sector)
|
||||
if(attempt_hook_up(sector))
|
||||
return sector
|
||||
for(var/obj/effect/overmap/visitable/ship/candidate in sector)
|
||||
if((. = .(candidate)))
|
||||
return
|
||||
|
||||
/datum/tgui_module/ship/proc/attempt_hook_up(obj/effect/overmap/visitable/ship/sector)
|
||||
if(!istype(sector))
|
||||
return
|
||||
if(sector.check_ownership(tgui_host()))
|
||||
linked = sector
|
||||
return 1
|
||||
|
||||
/datum/tgui_module/ship/proc/look(var/mob/user)
|
||||
if(linked)
|
||||
user.set_machine(tgui_host())
|
||||
user.reset_view(linked)
|
||||
user.set_viewsize(world.view + extra_view)
|
||||
GLOB.moved_event.register(user, src, /datum/tgui_module/ship/proc/unlook)
|
||||
LAZYDISTINCTADD(viewers, weakref(user))
|
||||
|
||||
/datum/tgui_module/ship/proc/unlook(var/mob/user)
|
||||
user.reset_view()
|
||||
user.set_viewsize() // reset to default
|
||||
GLOB.moved_event.unregister(user, src, /datum/tgui_module/ship/proc/unlook)
|
||||
LAZYREMOVE(viewers, weakref(user))
|
||||
|
||||
/datum/tgui_module/ship/proc/viewing_overmap(mob/user)
|
||||
return (weakref(user) in viewers)
|
||||
|
||||
/datum/tgui_module/ship/check_eye(var/mob/user)
|
||||
if(!get_dist(user, tgui_host()) > 1 || user.blinded || !linked)
|
||||
unlook(user)
|
||||
return -1
|
||||
else
|
||||
return 0
|
||||
|
||||
// Navigation
|
||||
/datum/tgui_module/ship/nav
|
||||
name = "Navigation Display"
|
||||
tgui_id = "OvermapNavigation"
|
||||
|
||||
/datum/tgui_module/ship/nav/tgui_interact(mob/user, datum/tgui/ui)
|
||||
if(!linked)
|
||||
var/obj/machinery/computer/ship/navigation/host = tgui_host()
|
||||
if(istype(host))
|
||||
// Real Computer path
|
||||
host.display_reconnect_dialog(user, "Navigation")
|
||||
return
|
||||
|
||||
// NTOS Path
|
||||
if(!sync_linked())
|
||||
to_chat(user, "<span class='warning'>You don't appear to be on a spaceship...</span>")
|
||||
if(ui)
|
||||
ui.close(can_be_suspended = FALSE)
|
||||
if(ntos)
|
||||
var/obj/item/modular_computer/M = tgui_host()
|
||||
if(istype(M))
|
||||
M.kill_program()
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/tgui_module/ship/nav/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
|
||||
var/list/data = ..()
|
||||
|
||||
var/turf/T = get_turf(linked)
|
||||
var/obj/effect/overmap/visitable/sector/current_sector = locate() in T
|
||||
|
||||
data["sector"] = current_sector ? current_sector.name : "Deep Space"
|
||||
data["sector_info"] = current_sector ? current_sector.desc : "Not Available"
|
||||
data["s_x"] = linked.x
|
||||
data["s_y"] = linked.y
|
||||
data["speed"] = round(linked.get_speed()*1000, 0.01)
|
||||
data["accel"] = round(linked.get_acceleration()*1000, 0.01)
|
||||
data["heading"] = linked.get_heading_degrees()
|
||||
data["viewing"] = viewing_overmap(user)
|
||||
|
||||
if(linked.get_speed())
|
||||
data["ETAnext"] = "[round(linked.ETA()/10)] seconds"
|
||||
else
|
||||
data["ETAnext"] = "N/A"
|
||||
|
||||
return data
|
||||
|
||||
/datum/tgui_module/ship/nav/tgui_act(action, params)
|
||||
if(..())
|
||||
return TRUE
|
||||
|
||||
if(!linked)
|
||||
return FALSE
|
||||
|
||||
if(action == "viewing")
|
||||
viewing_overmap(usr) ? unlook(usr) : look(usr)
|
||||
return TRUE
|
||||
|
||||
/datum/tgui_module/ship/nav/ntos
|
||||
ntos = TRUE
|
||||
@@ -1,91 +0,0 @@
|
||||
{{if data.faillink}}
|
||||
<div class='notice'>
|
||||
ERROR: Machine is incomplete, out of range, or misaligned!
|
||||
</div>
|
||||
{{else}}
|
||||
<div style="float:left;width:50%">
|
||||
<h3>Targeting</h3>
|
||||
<div class='block'>
|
||||
<div class='item'>
|
||||
<div class='item'>
|
||||
{{:helper.link('', 'triangle-1-nw', { 'choose' : 9 }, data.overmapdir == 9 ? 'selected' : null, null)}}
|
||||
{{:helper.link('', 'triangle-1-n', { 'choose' : 1 }, data.overmapdir == 1 ? 'selected' : null, null)}}
|
||||
{{:helper.link('', 'triangle-1-ne', { 'choose' : 5 }, data.overmapdir == 5 ? 'selected' : null, null)}}
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link('', 'triangle-1-w', { 'choose' : 8 }, data.overmapdir == 8 ? 'selected' : null, null)}}
|
||||
{{:helper.link('', 'circle-close', { 'choose' : 0 }, data.overmapdir == 0 ? 'selected' : null, null)}}
|
||||
{{:helper.link('', 'triangle-1-e', { 'choose' : 4 }, data.overmapdir == 4 ? 'selected' : null, null)}}
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link('', 'triangle-1-sw', { 'choose' : 10 }, data.overmapdir == 10 ? 'selected' : null, null)}}
|
||||
{{:helper.link('', 'triangle-1-s', { 'choose' : 2 }, data.overmapdir == 2 ? 'selected' : null, null)}}
|
||||
{{:helper.link('', 'triangle-1-se', { 'choose' : 6 }, data.overmapdir == 6 ? 'selected' : null, null)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="float:right;width:50%">
|
||||
<h3>Charge</h3>
|
||||
<div class='block'>
|
||||
{{if data.nopower}}
|
||||
<b>At least one part of the machine is unpowered.</b>
|
||||
{{/if}}
|
||||
<div class='itemLabelWidest'>
|
||||
Charge Load Type
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:data.chargeload}}
|
||||
</div>
|
||||
<div class='itemLabelWidest'>
|
||||
Cooldown
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{if data.next_shot == 0}}
|
||||
Ready
|
||||
{{else}}
|
||||
{{:data.next_shot}} seconds
|
||||
<br><i>Warning: Do not fire during cooldown.</i>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div style="float:left;width:50%">
|
||||
<h3>Calibration</h3>
|
||||
<div class='block'>
|
||||
<div class='itemLabelWidest'>
|
||||
{{:data.cal_accuracy}}%
|
||||
</div>
|
||||
<div class='itemLabelWidest'>
|
||||
{{:helper.link('Pre-Calibration', 'transfer-e-w', { 'skill_calibration' : 1 }, data.skill ? null : 'disabled', null)}}
|
||||
</div><br>
|
||||
{{for data.calibration}}
|
||||
<div class='item'>
|
||||
{{:helper.link(value, 'shuffle', { 'calibration' : index }, null, null)}}
|
||||
<br>
|
||||
</div>
|
||||
{{/for}}
|
||||
</div>
|
||||
</div>
|
||||
<div style="float:right;width:50%">
|
||||
<h3>Setup</h3>
|
||||
<div class='block'>
|
||||
<div class='itemLabelWidest'>
|
||||
Strength
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link(data.strength, 'lightbulb', { 'strength' : 1 }, null, null)}}
|
||||
</div>
|
||||
<div class='itemLabelWidest'>
|
||||
Radius
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link(data.range, 'arrow-4-diag', { 'range' : 1 }, null, null)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link("Fire", 'alert', { 'fire' : 1 }, null, null)}}
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -1,110 +0,0 @@
|
||||
<div class="item">
|
||||
{{:helper.link('Overall info', 'note', {'state' :'status'}, null, data.state == 'status' ? 'selected' : null)}}
|
||||
{{:helper.link('Details', 'note', {'state' : 'engines'}, null, data.state == 'engines' ? 'selected' : null)}}
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Global controls:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link(data.global_state ? 'Shut all down' : 'Power all up', 'power', {'global_toggle' : 1}, null, data.global_state ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Volume limit:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('', 'circle-plus', { 'global_limit' : 0.1}, null, null)}}
|
||||
{{:helper.link(data.global_limit+'%', null, { 'set_global_limit' : 1 }, null, null)}}
|
||||
{{:helper.link('', 'circle-minus', { 'global_limit' : -0.1}, null, null)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Total thrust:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<span class='white'>{{:data.total_thrust}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{if data.state == "engines"}}
|
||||
{{if data.engines_info}}
|
||||
{{for data.engines_info}}
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='white'>Engine #{{:(index + 1)}}:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link(value.eng_on ? 'Shutdown' : 'Power up', 'power', { 'toggle' : 1, 'engine' : value.eng_reference }, null, value.eng_on ? value.eng_on == 1 ? 'linkOn' : 'yellowButton' : null)}}
|
||||
</div>
|
||||
<div class='statusDisplay'>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Type:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<span class='white'>{{:value.eng_type}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Status:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<span class='{{:value.eng_on ? value.eng_on == 1 ? 'good' : 'average' : 'bad'}}'>{{:value.eng_on ? value.eng_on == 1 ? 'Online' : 'Booting' : 'Offline'}}</span><br>
|
||||
<span class='white'>{{:value.eng_status}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Current thrust:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<span class='white'>{{:value.eng_thrust}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Volume limit:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link('', 'circle-plus', { 'limit' : 0.1, 'engine' : value.eng_reference }, null, null)}}
|
||||
{{:helper.link(value.eng_thrust_limiter+'%', null, { 'set_limit' : 1, 'engine' : value.eng_reference }, null, null)}}
|
||||
{{:helper.link('', 'circle-minus', { 'limit' : -0.1, 'engine' : value.eng_reference }, null, null)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{if data.state == "status"}}
|
||||
{{if data.engines_info}}
|
||||
{{for data.engines_info}}
|
||||
<div class='block'>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='white'>Engine #{{:(index + 1)}}:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link(value.eng_on ? 'Shutdown' : 'Power up', 'power', { 'toggle' : 1, 'engine' : value.eng_reference }, null, value.eng_on ? value.eng_on == 1 ? 'linkOn' : 'yellowButton' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Thrust:</span>
|
||||
<br>
|
||||
<span class='average'>Volume limit:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
<span class='white'>{{:value.eng_thrust}}</span>
|
||||
<br>
|
||||
<span class='white'>{{:value.eng_thrust_limiter}}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/for}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
@@ -1,159 +0,0 @@
|
||||
|
||||
|
||||
|
||||
<div style="float:left;width:45%;">
|
||||
<fieldset style="min-height:180px;background-color: #202020;">
|
||||
<legend style="text-align:center">Flight data</legend>
|
||||
<div class='item'>
|
||||
<div class="itemLabelWider">
|
||||
ETA to next grid:
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.ETAnext}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabelWider">
|
||||
Speed:
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.speed}} Gm/h
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabelWider">
|
||||
Acceleration:
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.accel}} Gm/h
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabelWider">
|
||||
Heading:
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.heading}}°
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabelWider">
|
||||
Acceleration limiter:
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:helper.link(data.accellimit, null, { 'accellimit' : 1}, null, null)}} Gm/h
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div style="float:left;width:25%">
|
||||
<fieldset style="min-height:180px;background-color: #202020;">
|
||||
<legend style="text-align:center">Manual control</legend>
|
||||
<div class='item'>
|
||||
<div class='item'>
|
||||
{{:helper.link('', 'triangle-1-nw', { 'move' : 9 }, data.canburn ? null : 'disabled', null)}}
|
||||
{{:helper.link('', 'triangle-1-n', { 'move' : 1 }, data.canburn ? null : 'disabled', null)}}
|
||||
{{:helper.link('', 'triangle-1-ne', { 'move' : 5 }, data.canburn ? null : 'disabled', null)}}
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link('', 'triangle-1-w', { 'move' : 8 }, data.canburn ? null : 'disabled', null)}}
|
||||
{{:helper.link('', 'circle-close', { 'brake' : 1 }, data.canburn ? null : 'disabled', null)}}
|
||||
{{:helper.link('', 'triangle-1-e', { 'move' : 4 }, data.canburn ? null : 'disabled', null)}}
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link('', 'triangle-1-sw', { 'move' : 10 }, data.canburn ? null : 'disabled', null)}}
|
||||
{{:helper.link('', 'triangle-1-s', { 'move' : 2 }, data.canburn ? null : 'disabled', null)}}
|
||||
{{:helper.link('', 'triangle-1-se', { 'move' : 6 }, data.canburn ? null : 'disabled', null)}}
|
||||
</div>
|
||||
|
||||
<div class='item'>
|
||||
<span class='white'>Direct control</span>
|
||||
<br>
|
||||
{{:helper.link(data.manual_control ? 'Engaged' : 'Disengaged', 'shuffle', { 'manual' : 1 }, null, data.manual_control ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div style="float:left;width:30%">
|
||||
<fieldset style="min-height:180px;background-color: #202020;">
|
||||
<legend style="text-align:center">Autopilot</legend>
|
||||
<div class='item'>
|
||||
<div class="itemLabelWide">
|
||||
Target:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.dest}}
|
||||
{{:helper.link(data.d_x, null, { 'setx' : 1 }, null, null)}} {{:helper.link(data.d_y, null, { 'sety' : 1 }, null, null)}}
|
||||
{{else}}
|
||||
{{:helper.link('None', null, { 'sety' : 1, 'setx' : 1 }, null, null)}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabelWide">
|
||||
Speed limit:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link(data.speedlimit, null, { 'speedlimit' : 1 }, null, null)}} Gm/h
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
{{:helper.link(data.autopilot ? 'Engaged' : 'Disengaged', 'gear', { 'apilot' : 1 }, data.dest ? null : 'disabled', data.autopilot ? 'selected' : null)}}
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class='block' style='clear: both;'>
|
||||
<h3>Navigation data</h3>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
Location:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.sector}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
Coordinates:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.s_x}} : {{:data.s_y}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
Scan data:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.sector_info}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
Status:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.landed}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
{{:helper.link('Save current position', 'disk', { 'add' : 'current' }, null)}}
|
||||
{{:helper.link('Add new entry', 'document', { 'add' : 'new' }, null)}}
|
||||
</div>
|
||||
<div class='statusDisplay'>
|
||||
<table style="width:100%">
|
||||
<tr><th style="width:40%">Name<th>Coordinates<th>Actions
|
||||
{{for data.locations}}
|
||||
<tr class="candystripe"><td>{{:value.name}}
|
||||
<td>{{:value.x}} : {{:value.y}}
|
||||
<td>{{:helper.link('Plot course', 'arrowreturnthick-1-e', { 'x' : value.x, 'y' : value.y }, null, null)}}
|
||||
{{:helper.link('Remove', 'close', { 'remove' : value.reference }, null, null)}}
|
||||
{{/for}}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
<h3>Navigation</h3>
|
||||
<div class='block'>
|
||||
<div class='item'>
|
||||
<div class="itemContent">
|
||||
<div class='item'>
|
||||
<span class='white'>Map view</span>
|
||||
{{:helper.link(data.viewing ? 'Engaged' : 'Disengaged', 'shuffle', { 'viewing' : 1 }, null, data.viewing ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="float:left;width:50%">
|
||||
<h3>Sector information</h3>
|
||||
<div class='block'>
|
||||
{{:data.sector}}
|
||||
<br>
|
||||
<span class='average'>Coordinates:</span> {{:data.s_x}} : {{:data.s_y}}
|
||||
<br>
|
||||
<span class='average'>Additional information:</span> {{:data.sector_info}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="float:right;width:50%">
|
||||
<h3>Flight data</h3>
|
||||
<div class='block'>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>ETA to next grid:</span>
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.ETAnext}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Speed:</span>
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.speed}} Gm/h
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Acceleration:</span>
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.accel}} Gm/h
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='average'>Heading:</span>
|
||||
</div>
|
||||
<div style="float:right">
|
||||
{{:data.heading}}°
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,54 +0,0 @@
|
||||
<h2>Fire Assist Mainframe: {{:data.id || "[no tag]"}}</h2>
|
||||
{{if !(data.id)}}
|
||||
<div class="notice">
|
||||
<span class='bad'>This system has not been assigned an ident tag. Please contact your system administrator or conduct a manual update with a standard multitool.</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{for data.turrets}}
|
||||
<h3>{{:value.id}}</h3>
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
Battery status
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{if value.active}}
|
||||
<span class="fixedLeft good">Online</span> {{:helper.link('Shut down', null, {'toggle_active': value.ref})}}
|
||||
{{else}}
|
||||
<span class="fixedLeft average">Offline</span> {{:helper.link('Start up', null, {'toggle_active': value.ref})}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
Effective range
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:value.effective_range}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
Reaction wheel delay
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:value.reaction_wheel_delay}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabelWide">
|
||||
Recharge time
|
||||
</div>
|
||||
<div class="itemContentMedium">
|
||||
{{:value.recharge_time}}
|
||||
</div>
|
||||
{{empty}}
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Error:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
No weapon systems detected. Please check network connection.
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
{{/for}}
|
||||
@@ -1,158 +0,0 @@
|
||||
{{if data.offline_for}}
|
||||
<h1>EMERGENCY SHUTDOWN</h1>
|
||||
<b>An emergency shutdown has been initiated - generator cooling down</b><br>
|
||||
<i>Please wait until the generator cools down before resuming operation. Estimated time left: {{:data.offline_for}} seconds.</i>
|
||||
{{else}}
|
||||
<h2>SYSTEM STATUS</h2>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Generator is:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.running == 2}}
|
||||
{{if data.overloaded}}
|
||||
Recovering
|
||||
{{else}}
|
||||
Active
|
||||
{{/if}}
|
||||
{{else data.running == 1}}
|
||||
Shutting Down
|
||||
{{else data.running == 3}}
|
||||
Inactive
|
||||
{{else data.running == 4}}
|
||||
Spinning Up
|
||||
{{if data.target_radius != data.field_radius}}
|
||||
(Adjusting Radius)
|
||||
{{else}}
|
||||
({{:data.spinup_counter * 2}}s)
|
||||
{{/if}}
|
||||
{{else}}
|
||||
Offline
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Energy Storage:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.current_energy}}/{{:data.max_energy}} MJ ({{:data.percentage_energy}}%)
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Shield Integrity:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.field_integrity}}%
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Mitigation:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.mitigation_em}}% EM / {{:data.mitigation_physical}}% PH / {{:data.mitigation_heat}}% HE / {{:data.mitigation_max}}% MAX
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Upkeep Energy Use:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.upkeep_power_usage}} kW
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Total Energy Use:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.input_cap_kw}}
|
||||
{{:data.power_usage}} / {{:data.input_cap_kw}} kW
|
||||
{{else}}
|
||||
{{:data.power_usage}} kW (No Limit)
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Field Size:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.functional_segments}} / {{:data.total_segments}} m2 (radius {{:data.field_radius}}, target {{:data.target_radius}})
|
||||
</div>
|
||||
</div>
|
||||
<h2>CONTROLS</h2>
|
||||
<table>
|
||||
<tr>
|
||||
{{if (data.running >= 2)}}
|
||||
<td>{{:helper.link('Turn off', null, {'begin_shutdown' : '1'})}}
|
||||
{{if (data.running == 3)}}
|
||||
<td>{{:helper.link('Activate', null, {'toggle_idle' : '0'})}} </td>
|
||||
{{else}}
|
||||
<td>{{:helper.link('Deactivate', null, {'toggle_idle' : '1'})}} </td>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<td>{{:helper.link('Turn on', null, {'start_generator' : '1'})}}
|
||||
{{/if}}
|
||||
{{if data.running}}
|
||||
{{if data.hacked}}
|
||||
<td>{{:helper.link('EMERGENCY SHUTDOWN', null, {'emergency_shutdown' : '1'}, null, 'redButton')}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
<tr>
|
||||
<td>{{:helper.link('Set Field Range', null, {'set_range' : '1'})}}
|
||||
<td>{{:helper.link('Set Input Cap', null, {'set_input_cap' : '1'})}}
|
||||
<tr>
|
||||
<td>Set inactive power use intensity:</td>
|
||||
<td>
|
||||
{{for data.idle_valid_values}}
|
||||
{{:helper.link(value, null, {'switch_idle' : value}, (value == data.idle_multiplier) ? 'selected' : (data.running == 4 ? 'disabled' : null))}}
|
||||
{{/for}}
|
||||
</td>
|
||||
</table>
|
||||
<h2>FIELD CALIBRATION</h2>
|
||||
<hr>
|
||||
{{for data.modes}}
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Mode:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.name}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Description:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.desc}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Status:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if value.status}}
|
||||
Enabled
|
||||
{{else}}
|
||||
Disabled
|
||||
{{/if}}
|
||||
{{:helper.link('Toggle', null, {'toggle_mode' : value.flag})}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="itemLabel">
|
||||
Multiplier:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:value.multiplier}}
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
{{/for}}
|
||||
{{/if}}
|
||||
@@ -1,90 +0,0 @@
|
||||
<h3>Sensors control console</h3>
|
||||
<div class='block'>
|
||||
{{:helper.link(data.on ? 'Switch off' : 'Switch on', 'gear', { 'toggle' : 1 }, data.status != 'MISSING' ? null : 'disabled', data.on ? 'selected' : null)}}
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='white'>Status:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:data.status}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
<span class='white'>Range:</span>
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{:helper.link(data.range, null, { 'range' : 1 }, null, null)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='block'>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
Integrity:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.health < (data.max_health * 0.25)}}
|
||||
{{:helper.displayBar(data.health, 0, data.max_health, 'bad')}}
|
||||
<br><span class="bad">{{:data.health}}/{{:data.max_health}}</span>
|
||||
{{else data.health < data.max_health *.75}}
|
||||
{{:helper.displayBar(data.health, 0, data.max_health, 'average')}}
|
||||
<br><span class="average">{{:data.health}}/{{:data.max_health}}</span>
|
||||
{{else}}
|
||||
{{:helper.displayBar(data.health, 0, data.max_health, 'good')}}
|
||||
<br><span class="good">{{:data.health}}/{{:data.max_health}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemLabel">
|
||||
Temperature:
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.heat < (data.critical_heat * 0.5)}}
|
||||
{{:helper.displayBar(data.heat, 0, data.critical_heat, 'good')}}
|
||||
{{else data.heat < (data.critical_heat * 0.75)}}
|
||||
{{:helper.displayBar(data.heat, 0, data.critical_heat, 'average')}}
|
||||
{{else}}
|
||||
{{:helper.displayBar(data.heat, 0, data.critical_heat, 'bad')}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="itemContent">
|
||||
{{if data.heat < (data.critical_heat * 0.5)}}
|
||||
<span class="good">Temperature low.</span>
|
||||
{{else data.heat < (data.critical_heat * 0.75)}}
|
||||
<span class="average">Sensor temperature high!</span>
|
||||
{{else}}
|
||||
<span class="bad">TEMPERATURE CRITICAL: Disable or reduce power immediately!</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='item'>
|
||||
<div class="itemContent">
|
||||
<div class='item'>
|
||||
<span class='white'>Sector map view</span>
|
||||
{{:helper.link(data.viewing ? 'Engaged' : 'Disengaged', 'shuffle', { 'viewing' : 1 }, null, data.viewing ? 'selected' : null)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h4>Sensor contacts</h4>
|
||||
<div class='block'>
|
||||
{{if data.contacts}}
|
||||
<table>
|
||||
{{for data.contacts}}
|
||||
<tr>
|
||||
<div class='item'>
|
||||
<td>{{:helper.link('Scan', 'search' ,{ 'scan' : value.ref }, null, null)}}</td>
|
||||
<td><span class='white'>{{:value.name}}</span>, bearing {{:value.bearing}}</td>
|
||||
</div>
|
||||
</tr>
|
||||
{{/for}}
|
||||
</table>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{if data.status == 'MISSING'}}
|
||||
<div class='item'>
|
||||
{{:helper.link('Link up with the sensor suite', 'gear', { 'link' : 1 }, data.status == 'MISSING' ? null : 'disabled', null)}}
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { NtosWindow } from '../layouts';
|
||||
import { OvermapNavigationContent } from './OvermapNavigation';
|
||||
|
||||
export const NtosOvermapNavigation = () => {
|
||||
return (
|
||||
<NtosWindow
|
||||
width={380}
|
||||
height={530}
|
||||
resizable>
|
||||
<NtosWindow.Content scrollable>
|
||||
<OvermapNavigationContent />
|
||||
</NtosWindow.Content>
|
||||
</NtosWindow>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,129 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend, useLocalState } from "../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table, AnimatedNumber } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
import { OvermapPanControls } from './common/Overmap';
|
||||
|
||||
export const OvermapDisperser = (props, context) => {
|
||||
return (
|
||||
<Window width={400} height={550} resizable>
|
||||
<Window.Content>
|
||||
<OvermapDisperserContent />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const OvermapDisperserContent = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
faillink,
|
||||
calibration,
|
||||
overmapdir,
|
||||
cal_accuracy,
|
||||
strength,
|
||||
range,
|
||||
next_shot,
|
||||
nopower,
|
||||
skill,
|
||||
chargeload,
|
||||
} = data;
|
||||
|
||||
if (faillink) {
|
||||
return (
|
||||
<Section title="Error">
|
||||
Machine is incomplete, out of range, or misaligned!
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex wrap="wrap" spacing={1}>
|
||||
<Flex.Item basis="22%">
|
||||
<Section title="Targeting" textAlign="center">
|
||||
<OvermapPanControls actToDo="choose" selected={val => val === overmapdir} />
|
||||
</Section>
|
||||
</Flex.Item>
|
||||
<Flex.Item basis="74%" grow={1}>
|
||||
<Section title="Charge">
|
||||
<LabeledList>
|
||||
{nopower && (
|
||||
<LabeledList.Item label="Error">
|
||||
At least one part of the machine is unpowered.
|
||||
</LabeledList.Item>
|
||||
) || null}
|
||||
<LabeledList.Item label="Charge Load Type">
|
||||
{chargeload}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Cooldown">
|
||||
{next_shot === 0 && (
|
||||
<Box color="good">Ready</Box>
|
||||
) || next_shot > 1 && (
|
||||
<Box color="average">
|
||||
<AnimatedNumber value={next_shot} /> Seconds
|
||||
<Box color="bad">Warning: Do not fire during cooldown.</Box>
|
||||
</Box>
|
||||
) || null}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Flex.Item>
|
||||
<Flex.Item basis="50%" mt={1}>
|
||||
<Section title="Calibration">
|
||||
<AnimatedNumber value={cal_accuracy} />%
|
||||
<Button
|
||||
ml={1}
|
||||
icon="exchange-alt"
|
||||
onClick={() => act("skill_calibration")}>
|
||||
Pre-Calibration
|
||||
</Button>
|
||||
<Box mt={1}>
|
||||
{calibration.map((cal, i) => (
|
||||
<Box key={i}>
|
||||
Cal #{i}:
|
||||
<Button
|
||||
ml={1}
|
||||
icon="random"
|
||||
onClick={() => act("calibration", { calibration: i })}>
|
||||
{cal.toString() /* We do this to make the button size correctly at 0 */}
|
||||
</Button>
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
</Section>
|
||||
</Flex.Item>
|
||||
<Flex.Item basis="45%" grow={1} mt={1}>
|
||||
<Section title="Setup">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Strength">
|
||||
<Button
|
||||
fluid
|
||||
icon="fist-raised"
|
||||
onClick={() => act("strength")}>
|
||||
{strength}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Radius">
|
||||
<Button
|
||||
fluid
|
||||
icon="expand-arrows-alt"
|
||||
onClick={() => act("range")}>
|
||||
{range}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Flex.Item>
|
||||
<Flex.Item grow={1} mt={1}>
|
||||
<Button
|
||||
fluid
|
||||
color="red"
|
||||
icon="bomb"
|
||||
onClick={() => act("fire")}>
|
||||
Fire ORB
|
||||
</Button>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,110 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from "../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, AnimatedNumber, Collapsible } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
|
||||
export const OvermapEngines = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
global_state, // This indicates all engines being powered up or not
|
||||
global_limit, // Global Thrust limit
|
||||
engines_info, // Array of engines
|
||||
total_thrust, // Total thrust of all engines together
|
||||
} = data;
|
||||
return (
|
||||
<Window width={390} height={530}>
|
||||
<Window.Content>
|
||||
<Section title="Status">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Engines">
|
||||
<Button
|
||||
icon="power-off"
|
||||
selected={global_state}
|
||||
onClick={() => act("global_toggle")}>
|
||||
{global_state ? "Shut All Engines Down" : "Start All Engines"}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Volume Limit">
|
||||
<Button
|
||||
onClick={() => act("global_limit", { global_limit: -0.1 })}
|
||||
icon="minus" />
|
||||
<Button onClick={() => act("set_global_limit")}>
|
||||
{global_limit}%
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => act("global_limit", { global_limit: 0.1 })}
|
||||
icon="plus" />
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Total Thrust">
|
||||
<AnimatedNumber value={total_thrust} />
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
<Section title="Engines" height="340px" style={{ "overflow-y": "auto" }}>
|
||||
{engines_info.map((engine, i) => (
|
||||
<Flex spacing={1} mt={i !== 0 && -1} key={i}>
|
||||
<Flex.Item basis="80%">
|
||||
<Collapsible title={(
|
||||
<Box inline>
|
||||
Engine #{i + 1} |
|
||||
Thrust: <AnimatedNumber value={engine.eng_thrust} /> |
|
||||
Limit: <AnimatedNumber value={engine.eng_thrust_limiter} format={val => val + "%"} />
|
||||
</Box>
|
||||
// "Engine " + (i + 1)
|
||||
// + " | Thrust: " + engine.eng_thrust
|
||||
// + " | Limit: " + engine.eng_thrust_limiter + "%"
|
||||
)}>
|
||||
<Section width="127%">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Type">
|
||||
{engine.eng_type}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Status">
|
||||
<Box color={engine.eng_on ? (engine.eng_on === 1 ? "good" : "average") : "bad"}>
|
||||
{engine.eng_on ? (engine.eng_on === 1 ? "Online" : "Booting") : "Offline"}
|
||||
</Box>
|
||||
{engine.eng_status.map(status => {
|
||||
if (Array.isArray(status)) {
|
||||
return <Box color={status[1]}>{status[0]}</Box>;
|
||||
} else {
|
||||
return <Box>{status}</Box>;
|
||||
}
|
||||
})}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Current Thrust">
|
||||
{engine.eng_thrust}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Volume Limit">
|
||||
<Button
|
||||
onClick={() => act("limit", { limit: -0.1, engine: engine.eng_reference })}
|
||||
icon="minus" />
|
||||
<Button onClick={() => act("set_limit", { engine: engine.eng_reference })}>
|
||||
{engine.eng_thrust_limiter}%
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => act("limit", { limit: 0.1, engine: engine.eng_reference })}
|
||||
icon="plus" />
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
</Collapsible>
|
||||
</Flex.Item>
|
||||
<Flex.Item basis="20%">
|
||||
<Button
|
||||
fluid
|
||||
iconSpin={engine.eng_on === -1}
|
||||
color={engine.eng_on === -1 ? "purple" : null}
|
||||
selected={engine.eng_on === 1}
|
||||
icon="power-off"
|
||||
onClick={() => act("toggle", { engine: engine.eng_reference })}>
|
||||
{engine.eng_on ? (engine.eng_on === 1 ? "Shutoff" : "Booting") : "Startup"}
|
||||
</Button>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
))}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,235 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend, useLocalState } from "../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
import { OvermapFlightData, OvermapPanControls } from './common/Overmap';
|
||||
|
||||
export const OvermapHelm = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
return (
|
||||
<Window width={565} height={545} resizable>
|
||||
<Window.Content>
|
||||
<Flex>
|
||||
<Flex.Item basis="40%" height="180px">
|
||||
<OvermapFlightDataWrap />
|
||||
</Flex.Item>
|
||||
<Flex.Item basis="25%" height="180px">
|
||||
<OvermapManualControl />
|
||||
</Flex.Item>
|
||||
<Flex.Item basis="35%" height="180px">
|
||||
<OvermapAutopilot />
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
<OvermapNavComputer />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
export const OvermapFlightDataWrap = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
// While, yes, this is a strange choice to use fieldset over Section
|
||||
// just look at how pretty the legend is, sticking partially through the border ;///;
|
||||
return (
|
||||
<fieldset style={{ height: "100%", border: "1px solid #4972a1", margin: 'none' }} className="Section">
|
||||
<legend>Flight Data</legend>
|
||||
<OvermapFlightData />
|
||||
</fieldset>
|
||||
);
|
||||
};
|
||||
|
||||
const OvermapManualControl = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
canburn,
|
||||
manual_control,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<fieldset style={{ height: "100%", border: "1px solid #4972a1" }} className="Section">
|
||||
<legend>Manual Control</legend>
|
||||
<Flex align="center" justify="center">
|
||||
<Flex.Item>
|
||||
<OvermapPanControls disabled={!canburn} actToDo="move" />
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
<Box textAlign="center" mt={1}>
|
||||
<Box bold underline>
|
||||
Direct Control
|
||||
</Box>
|
||||
<Button
|
||||
selected={manual_control}
|
||||
onClick={() => act("manual")}
|
||||
icon="compass">
|
||||
{manual_control ? "Enabled" : "Disabled"}
|
||||
</Button>
|
||||
</Box>
|
||||
</fieldset>
|
||||
);
|
||||
};
|
||||
|
||||
const OvermapAutopilot = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
dest,
|
||||
d_x,
|
||||
d_y,
|
||||
speedlimit,
|
||||
autopilot,
|
||||
autopilot_disabled,
|
||||
} = data;
|
||||
|
||||
if (autopilot_disabled) {
|
||||
return (
|
||||
<fieldset style={{ height: "100%", border: "1px solid #4972a1" }} className="Section">
|
||||
<legend>Autopilot</legend>
|
||||
<Box textAlign="center" color="bad" fontSize={1.2}>
|
||||
AUTOPILOT DISABLED
|
||||
</Box>
|
||||
<Box textAlign="center" color="average">
|
||||
Warning: This vessel is equipped with a class I autopilot.
|
||||
Class I autopilots are unable to do anything but fly in a
|
||||
straight line directly towards the target, and may result in
|
||||
collisions.
|
||||
</Box>
|
||||
<Box textAlign="center">
|
||||
<Button.Confirm
|
||||
mt={1}
|
||||
color="bad"
|
||||
content="Unlock Autopilot"
|
||||
confirmContent="ACCEPT RISKS?"
|
||||
icon="exclamation-triangle"
|
||||
confirmIcon="exclamation-triangle"
|
||||
onClick={() => act("apilot_lock")} />
|
||||
</Box>
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<fieldset style={{ height: "100%", border: "1px solid #4972a1" }} className="Section">
|
||||
<legend>Autopilot</legend>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Target">
|
||||
{dest && (
|
||||
<Fragment>
|
||||
<Button onClick={() => act("setcoord", { setx: true })}>
|
||||
{d_x}
|
||||
</Button>
|
||||
<Button onClick={() => act("setcoord", { sety: true })}>
|
||||
{d_y}
|
||||
</Button>
|
||||
</Fragment>
|
||||
) || (
|
||||
<Button icon="pen" onClick={() => act("setcoord", { setx: true, sety: true })}>
|
||||
None
|
||||
</Button>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Speed Limit">
|
||||
<Button
|
||||
icon="tachometer-alt"
|
||||
onClick={() => act("speedlimit")}>
|
||||
{speedlimit} Gm/h
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<Button
|
||||
mt={1}
|
||||
fluid
|
||||
selected={autopilot}
|
||||
disabled={!dest}
|
||||
icon="robot"
|
||||
onClick={() => act("apilot")}>
|
||||
{autopilot ? "Engaged" : "Disengaged"}
|
||||
</Button>
|
||||
<Button
|
||||
fluid
|
||||
color="good"
|
||||
icon="exclamation-triangle"
|
||||
onClick={() => act("apilot_lock")}>
|
||||
Lock Autopilot
|
||||
</Button>
|
||||
</fieldset>
|
||||
);
|
||||
};
|
||||
|
||||
const OvermapNavComputer = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
sector,
|
||||
s_x,
|
||||
s_y,
|
||||
sector_info,
|
||||
landed,
|
||||
locations,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Section title="Navigation Data" m={0.3} mt={1}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Location">
|
||||
{sector}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Coordinates">
|
||||
{s_x} : {s_y}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Scan Data">
|
||||
{sector_info}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Status">
|
||||
{landed}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
<Flex mt={1} align="center" justify="center" spacing={1}>
|
||||
<Flex.Item basis="50%">
|
||||
<Button
|
||||
fluid
|
||||
icon="save"
|
||||
onClick={() => act("add", { add: "current" })}>
|
||||
Save Current Position
|
||||
</Button>
|
||||
</Flex.Item>
|
||||
<Flex.Item basis="50%">
|
||||
<Button
|
||||
fluid
|
||||
icon="sticky-note"
|
||||
onClick={() => act("add", { add: "new" })}>
|
||||
Add New Entry
|
||||
</Button>
|
||||
</Flex.Item>
|
||||
</Flex>
|
||||
<Section mt={1} scrollable height="130px">
|
||||
<Table>
|
||||
<Table.Row header>
|
||||
<Table.Cell>Name</Table.Cell>
|
||||
<Table.Cell>Coordinates</Table.Cell>
|
||||
<Table.Cell>Actions</Table.Cell>
|
||||
</Table.Row>
|
||||
{locations.map(loc => (
|
||||
<Table.Row key={loc.name}>
|
||||
<Table.Cell>{loc.name}</Table.Cell>
|
||||
<Table.Cell>{loc.x} : {loc.y}</Table.Cell>
|
||||
<Table.Cell collapsing>
|
||||
<Button
|
||||
icon="rocket"
|
||||
onClick={() => act("setds", { x: loc.x, y: loc.y })}>
|
||||
Plot Course
|
||||
</Button>
|
||||
<Button
|
||||
icon="trash"
|
||||
onClick={() => act("remove", { remove: loc.reference })}>
|
||||
Remove
|
||||
</Button>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
))}
|
||||
</Table>
|
||||
</Section>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from "../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
import { OvermapFlightData } from "./common/Overmap";
|
||||
|
||||
export const OvermapNavigation = (props, context) => {
|
||||
return (
|
||||
<Window width={380} height={530} resizable>
|
||||
<Window.Content>
|
||||
<OvermapNavigationContent />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
export const OvermapNavigationContent = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
sector,
|
||||
s_x,
|
||||
s_y,
|
||||
sector_info,
|
||||
viewing,
|
||||
} = data;
|
||||
return (
|
||||
<Fragment>
|
||||
<Section title="Current Location" buttons={
|
||||
<Button
|
||||
icon="eye"
|
||||
selected={viewing}
|
||||
onClick={() => act("viewing")}>
|
||||
Map View
|
||||
</Button>
|
||||
}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Current Location">
|
||||
{sector}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Coordiantes">
|
||||
{s_x} : {s_y}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Additional Information">
|
||||
{sector_info}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
<Section title="Flight Data">
|
||||
<OvermapFlightData disableLimiterControls />
|
||||
</Section>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,212 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend, useLocalState } from "../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table, AnimatedNumber } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
|
||||
export const OvermapShieldGenerator = (props, context) => {
|
||||
return (
|
||||
<Window width={500} height={800} resizable>
|
||||
<Window.Content scrollable>
|
||||
<OvermapShieldGeneratorContent />
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const OvermapShieldGeneratorContent = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
modes,
|
||||
offline_for,
|
||||
} = data;
|
||||
|
||||
if (offline_for) {
|
||||
return (
|
||||
<Section title="EMERGENCY SHUTDOWN" color="bad">
|
||||
An emergency shutdown has been initiated - generator cooling down.
|
||||
Please wait until the generator cools down before resuming operation.
|
||||
Estimated time left: {offline_for} seconds.
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<OvermapShieldGeneratorStatus />
|
||||
<OvermapShieldGeneratorControls />
|
||||
<Section title="Field Calibration">
|
||||
{modes.map(mode => (
|
||||
<Section title={mode.name} level={2} key={mode.name} buttons={
|
||||
<Button
|
||||
icon="power-off"
|
||||
selected={mode.status}
|
||||
onClick={() => act("toggle_mode", { toggle_mode: mode.flag })}>
|
||||
{mode.status ? "Enabled" : "Disabled"}
|
||||
</Button>
|
||||
}>
|
||||
<Box color="label">
|
||||
{mode.desc}
|
||||
</Box>
|
||||
<Box mt={0.5}>
|
||||
Multiplier: {mode.multiplier}
|
||||
</Box>
|
||||
</Section>
|
||||
))}
|
||||
</Section>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const OvermapShieldGeneratorStatus = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
running,
|
||||
overloaded,
|
||||
mitigation_max,
|
||||
mitigation_physical,
|
||||
mitigation_em,
|
||||
mitigation_heat,
|
||||
field_integrity,
|
||||
max_energy,
|
||||
current_energy,
|
||||
percentage_energy,
|
||||
total_segments,
|
||||
functional_segments,
|
||||
field_radius,
|
||||
target_radius,
|
||||
input_cap_kw,
|
||||
upkeep_power_usage,
|
||||
power_usage,
|
||||
spinup_counter,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Section title="System Status">
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Generator is">
|
||||
{running === 1 && (
|
||||
<Box color="average">Shutting Down</Box>
|
||||
) || running === 2 && (
|
||||
overloaded && (
|
||||
<Box color="bad">Overloaded</Box>
|
||||
) || (
|
||||
<Box color="good">Running</Box>
|
||||
)
|
||||
) || running === 3 && (
|
||||
<Box color="average">Inactive</Box>
|
||||
) || running === 4 && (
|
||||
<Box color="blue">
|
||||
Spinning Up
|
||||
{target_radius !== field_radius && (
|
||||
<Box inline>(Adjusting Radius)</Box>
|
||||
) || (
|
||||
<Box inline>{spinup_counter * 2}s</Box>
|
||||
)}
|
||||
</Box>
|
||||
) || (
|
||||
<Box color="bad">
|
||||
Offline
|
||||
</Box>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Energy Storage">
|
||||
<ProgressBar
|
||||
value={current_energy}
|
||||
maxValue={max_energy}>
|
||||
{current_energy} / {max_energy} MJ ({percentage_energy}%)
|
||||
</ProgressBar>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Shield Integrity">
|
||||
<AnimatedNumber value={field_integrity} />%
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Mitigation">
|
||||
{mitigation_em}% EM / {mitigation_physical}% PH / {mitigation_heat}% HE / {mitigation_max}% MAX
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Upkeep Energy Use">
|
||||
<AnimatedNumber value={upkeep_power_usage} /> kW
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Total Energy Use">
|
||||
{input_cap_kw && (
|
||||
<Box>
|
||||
<ProgressBar
|
||||
value={power_usage}
|
||||
maxValue={input_cap_kw}>
|
||||
{power_usage} / {input_cap_kw} kW
|
||||
</ProgressBar>
|
||||
</Box>
|
||||
) || (
|
||||
<Box>
|
||||
<AnimatedNumber value={power_usage} /> kW (No Limit)
|
||||
</Box>
|
||||
)}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Field Size">
|
||||
<AnimatedNumber value={functional_segments} /> /
|
||||
<AnimatedNumber value={total_segments} /> m²
|
||||
(radius <AnimatedNumber value={field_radius} />, target <AnimatedNumber value={target_radius} />)
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
const OvermapShieldGeneratorControls = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
running,
|
||||
hacked,
|
||||
idle_multiplier,
|
||||
idle_valid_values,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Section title="Controls" buttons={
|
||||
<Fragment>
|
||||
{running >= 2 && (
|
||||
<Box>
|
||||
<Button icon="power-off" onClick={() => act("begin_shutdown")} selected>Turn off</Button>
|
||||
{running === 3 && (
|
||||
<Button icon="power-off" onClick={() => act("toggle_idle", { toggle_idle: 0 })}>Activate</Button>
|
||||
) || (
|
||||
<Button icon="power-off" onClick={() => act("toggle_idle", { toggle_idle: 1 })} selected>
|
||||
Deactivate
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
) || (
|
||||
<Button icon="power-off" onClick={() => act("start_generator")}>Turn on</Button>
|
||||
)}
|
||||
{running && hacked && (
|
||||
<Button icon="exclamation-triangle" onClick={() => act("emergency_shutdown")} color="bad">
|
||||
EMERGENCY SHUTDOWN
|
||||
</Button>
|
||||
) || null}
|
||||
</Fragment>
|
||||
}>
|
||||
<Button
|
||||
icon="expand-arrows-alt"
|
||||
onClick={() => act("set_range")}>
|
||||
Set Field Range
|
||||
</Button>
|
||||
<Button
|
||||
icon="bolt"
|
||||
onClick={() => act("set_input_cap")}>
|
||||
Set Input Cap
|
||||
</Button>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Set inactive power use intensity">
|
||||
{idle_valid_values.map(val => (
|
||||
<Button
|
||||
key={val}
|
||||
selected={val === idle_multiplier}
|
||||
disabled={running === 4}
|
||||
onClick={() => act("switch_idle", { switch_idle: val })}>
|
||||
{val}
|
||||
</Button>
|
||||
))}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,111 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend } from "../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
|
||||
export const OvermapShipSensors = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
viewing,
|
||||
on,
|
||||
range,
|
||||
health,
|
||||
max_health,
|
||||
heat,
|
||||
critical_heat,
|
||||
status,
|
||||
contacts,
|
||||
} = data;
|
||||
|
||||
return (
|
||||
<Window width={375} height={545} resizable>
|
||||
<Window.Content>
|
||||
<Section title="Status" buttons={(
|
||||
<Fragment>
|
||||
<Button
|
||||
icon="eye"
|
||||
selected={viewing}
|
||||
onClick={() => act("viewing")}>
|
||||
Map View
|
||||
</Button>
|
||||
<Button
|
||||
icon="power-off"
|
||||
selected={on}
|
||||
onClick={() => act("toggle")}>
|
||||
{on ? "Sensors Enabled" : "Sensors Disabled"}
|
||||
</Button>
|
||||
</Fragment>
|
||||
)}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Status">
|
||||
{status}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Range">
|
||||
<Button
|
||||
icon="signal"
|
||||
onClick={() => act("range")}>
|
||||
{range}
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Integrity">
|
||||
<ProgressBar
|
||||
ranges={{
|
||||
good: [max_health * 0.75, Infinity],
|
||||
average: [max_health * 0.25, max_health * 0.75],
|
||||
bad: [-Infinity, max_health * 0.25],
|
||||
}}
|
||||
value={health}
|
||||
maxValue={max_health}>
|
||||
{health} / {max_health}
|
||||
</ProgressBar>
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Temperature">
|
||||
<ProgressBar
|
||||
ranges={{
|
||||
bad: [critical_heat * 0.75, Infinity],
|
||||
average: [critical_heat * 0.5, critical_heat * 0.75],
|
||||
good: [-Infinity, critical_heat * 0.5],
|
||||
}}
|
||||
value={heat}
|
||||
maxValue={critical_heat}>
|
||||
{heat < critical_heat * 0.5 && (
|
||||
<Box>Temperature low.</Box>
|
||||
) || heat < critical_heat * 0.75 && (
|
||||
<Box>Sensor temperature high!</Box>
|
||||
) || (
|
||||
<Box>TEMPERATURE CRITICAL: Disable or reduce power immediately!</Box>
|
||||
)}
|
||||
</ProgressBar>
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
<Section title="Contacts">
|
||||
{contacts.length && contacts.map(alien => (
|
||||
<Button
|
||||
key={alien.ref}
|
||||
fluid
|
||||
icon="search"
|
||||
onClick={() => act("scan", { scan: alien.ref })}>
|
||||
<Box bold inline>Scan: {alien.name}</Box>
|
||||
<Box inline>, bearing: {alien.bearing}°</Box>
|
||||
</Button>
|
||||
)) || (
|
||||
<Box color="average">
|
||||
No contacts on sensors.
|
||||
</Box>
|
||||
)}
|
||||
</Section>
|
||||
{data.status === "MISSING" && (
|
||||
<Section title="Error">
|
||||
<Button
|
||||
icon="wifi"
|
||||
onClick={() => act("link")}>
|
||||
Link up with sensor suite?
|
||||
</Button>
|
||||
</Section>
|
||||
) || null}
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend, useLocalState } from "../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table, AnimatedNumber } from "../components";
|
||||
import { Window } from "../layouts";
|
||||
|
||||
export const PointDefenseControl = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
const {
|
||||
id,
|
||||
turrets,
|
||||
} = data;
|
||||
return (
|
||||
<Window width={400} height={600}>
|
||||
<Window.Content scrollable>
|
||||
<Section title={"Fire Assist Mainframe: " + (id || "[no tag]")}>
|
||||
{turrets.length && turrets.map(pd => (
|
||||
<Section level={2} title={pd.id} key={pd.id} buttons={
|
||||
<Button
|
||||
selected={pd.active}
|
||||
icon="power-off"
|
||||
onClick={() => act("toggle_active", { target: pd.ref })}>
|
||||
{pd.active ? "Online" : "Offline"}
|
||||
</Button>
|
||||
}>
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="Effective range">
|
||||
{pd.effective_range}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Reaction wheel delay">
|
||||
{pd.reaction_wheel_delay}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Recharge time">
|
||||
{pd.recharge_time}
|
||||
</LabeledList.Item>
|
||||
</LabeledList>
|
||||
</Section>
|
||||
)) || (
|
||||
<Box color="bad">
|
||||
Error: No weapon systems detected. Please check network connection.
|
||||
</Box>
|
||||
)}
|
||||
</Section>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
import { round } from 'common/math';
|
||||
import { Fragment } from 'inferno';
|
||||
import { useBackend, useLocalState } from "../../backend";
|
||||
import { Box, Button, Flex, Icon, LabeledList, ProgressBar, Section, Table } from "../../components";
|
||||
|
||||
export const OvermapFlightData = (props, context) => {
|
||||
const { act, data } = useBackend(context);
|
||||
|
||||
const {
|
||||
disableLimiterControls,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
ETAnext,
|
||||
speed,
|
||||
speed_color,
|
||||
accel,
|
||||
heading,
|
||||
accellimit,
|
||||
} = data;
|
||||
|
||||
// While, yes, this is a strange choice to use fieldset over Section
|
||||
// just look at how pretty the legend is, sticking partially through the border ;///;
|
||||
return (
|
||||
<LabeledList>
|
||||
<LabeledList.Item label="ETA To Next Grid">
|
||||
{ETAnext}
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Speed" color={speed_color}>
|
||||
{speed} Gm/h
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Acceleration">
|
||||
{accel} Gm/h
|
||||
</LabeledList.Item>
|
||||
<LabeledList.Item label="Heading">
|
||||
{heading}°
|
||||
</LabeledList.Item>
|
||||
{!disableLimiterControls && (
|
||||
<LabeledList.Item label="Acceleration Limiter">
|
||||
<Button onClick={() => act("accellimit")}>
|
||||
{accellimit} Gm/h
|
||||
</Button>
|
||||
</LabeledList.Item>
|
||||
) || null}
|
||||
</LabeledList>
|
||||
);
|
||||
};
|
||||
|
||||
export const OvermapPanControls = (props, context) => {
|
||||
const { act } = useBackend(context);
|
||||
|
||||
const {
|
||||
disabled,
|
||||
actToDo,
|
||||
selected = val => false,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Box>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(9)}
|
||||
onClick={() => act(actToDo, { dir: 9 })}
|
||||
icon="arrow-up"
|
||||
iconRotation={-45} />
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(1)}
|
||||
onClick={() => act(actToDo, { dir: 1 })}
|
||||
icon="arrow-up" />
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(5)}
|
||||
onClick={() => act(actToDo, { dir: 5 })}
|
||||
icon="arrow-up"
|
||||
iconRotation={45} />
|
||||
</Box>
|
||||
<Box>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(8)}
|
||||
onClick={() => act(actToDo, { dir: 8 })}
|
||||
icon="arrow-left" />
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(0)}
|
||||
onClick={() => act("brake")}
|
||||
icon="ban" />
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(4)}
|
||||
onClick={() => act(actToDo, { dir: 4 })}
|
||||
icon="arrow-right" />
|
||||
</Box>
|
||||
<Box>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(10)}
|
||||
onClick={() => act(actToDo, { dir: 10 })}
|
||||
icon="arrow-down"
|
||||
iconRotation={45} />
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(2)}
|
||||
onClick={() => act(actToDo, { dir: 2 })}
|
||||
icon="arrow-down" />
|
||||
<Button
|
||||
disabled={disabled}
|
||||
selected={selected(6)}
|
||||
onClick={() => act(actToDo, { dir: 6 })}
|
||||
icon="arrow-down"
|
||||
iconRotation={-45} />
|
||||
</Box>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -2901,7 +2901,6 @@
|
||||
#include "code\modules\modular_computers\file_system\programs\security\alarm_monitor.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\security\digitalwarrant.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\ships\navigation.dm"
|
||||
#include "code\modules\modular_computers\file_system\programs\ships\ship.dm"
|
||||
#include "code\modules\modular_computers\hardware\_hardware.dm"
|
||||
#include "code\modules\modular_computers\hardware\battery_module.dm"
|
||||
#include "code\modules\modular_computers\hardware\card_slot.dm"
|
||||
@@ -3497,6 +3496,7 @@
|
||||
#include "code\modules\tgui\modules\atmos_control.dm"
|
||||
#include "code\modules\tgui\modules\camera.dm"
|
||||
#include "code\modules\tgui\modules\crew_monitor.dm"
|
||||
#include "code\modules\tgui\modules\overmap.dm"
|
||||
#include "code\modules\tgui\modules\power_monitor.dm"
|
||||
#include "code\modules\tgui\modules\rcon.dm"
|
||||
#include "code\modules\tgui\modules\shutoff_monitor.dm"
|
||||
|
||||
Reference in New Issue
Block a user