diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm
index 9e011f442d..08589fb13c 100644
--- a/code/modules/modular_computers/file_system/program.dm
+++ b/code/modules/modular_computers/file_system/program.dm
@@ -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
diff --git a/code/modules/modular_computers/file_system/programs/ships/navigation.dm b/code/modules/modular_computers/file_system/programs/ships/navigation.dm
index 88db90598b..b8fecd9657 100644
--- a/code/modules/modular_computers/file_system/programs/ships/navigation.dm
+++ b/code/modules/modular_computers/file_system/programs/ships/navigation.dm
@@ -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, "You don't appear to be on a spaceship...")
- 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
diff --git a/code/modules/modular_computers/file_system/programs/ships/ship.dm b/code/modules/modular_computers/file_system/programs/ships/ship.dm
deleted file mode 100644
index 1db653153b..0000000000
--- a/code/modules/modular_computers/file_system/programs/ships/ship.dm
+++ /dev/null
@@ -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
\ No newline at end of file
diff --git a/code/modules/overmap/disperser/disperser_console.dm b/code/modules/overmap/disperser/disperser_console.dm
index 7ed212c8ac..5f97785341 100644
--- a/code/modules/overmap/disperser/disperser_console.dm
+++ b/code/modules/overmap/disperser/disperser_console.dm
@@ -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 = "UNKNOWN ERROR"
+ var/charge = "UNKNOWN ERROR"
if(get_charge_type() == OVERMAP_WEAKNESS_NONE)
- charge = "ERROR: 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)
\ No newline at end of file
diff --git a/code/modules/overmap/ships/computers/computer_shims.dm b/code/modules/overmap/ships/computers/computer_shims.dm
index 5dbb61405d..16d9285c39 100644
--- a/code/modules/overmap/ships/computers/computer_shims.dm
+++ b/code/modules/overmap/ships/computers/computer_shims.dm
@@ -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, "Access Denied.")
- return 1
- if(CanUseTopic(user, DefaultTopicState()) > STATUS_CLOSE)
+ return TRUE
+ if(tgui_status(user, tgui_state()) > STATUS_CLOSE)
return interface_interact(user)
diff --git a/code/modules/overmap/ships/computers/engine_control.dm b/code/modules/overmap/ships/computers/engine_control.dm
index c07fdf45cb..5721c6f9c7 100644
--- a/code/modules/overmap/ships/computers/engine_control.dm
+++ b/code/modules/overmap/ships/computers/engine_control.dm
@@ -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
\ No newline at end of file
+ . = TRUE
+
+ if(. && !issilicon(usr))
+ playsound(src, "terminal_type", 50, 1)
\ No newline at end of file
diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm
index 70deb4347b..1c231fc4e0 100644
--- a/code/modules/overmap/ships/computers/helm.dm
+++ b/code/modules/overmap/ships/computers/helm.dm
@@ -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 = "[speed]"
- if(linked.get_speed() > SHIP_SPEED_FAST)
- speed = "[speed]"
- 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, "Sector with that name already exists, please input a different name.")
- 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, "Sector with that name already exists, please input a different name.")
+ 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"
diff --git a/code/modules/overmap/ships/computers/sensors.dm b/code/modules/overmap/ships/computers/sensors.dm
index e4e77f9005..61f8297633 100644
--- a/code/modules/overmap/ships/computers/sensors.dm
+++ b/code/modules/overmap/ships/computers/sensors.dm
@@ -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()
..()
diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm
index 497077a76e..f0d54125ae 100644
--- a/code/modules/overmap/ships/computers/ship.dm
+++ b/code/modules/overmap/ships/computers/ship.dm
@@ -37,22 +37,31 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
popup.set_content("
Error
Unable to connect to [flavor].
Reconnect")
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
diff --git a/code/modules/overmap/ships/engines/engine.dm b/code/modules/overmap/ships/engines/engine.dm
index a5d3bc7016..5f8ef4f3be 100644
--- a/code/modules/overmap/ships/engines/engine.dm
+++ b/code/modules/overmap/ships/engines/engine.dm
@@ -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
diff --git a/code/modules/overmap/ships/engines/gas_thruster.dm b/code/modules/overmap/ships/engines/gas_thruster.dm
index fd689fb990..667cbae441 100644
--- a/code/modules/overmap/ships/engines/gas_thruster.dm
+++ b/code/modules/overmap/ships/engines/gas_thruster.dm
@@ -103,18 +103,17 @@
. = list()
.+= "Location: [get_area(src)]."
if(stat & NOPOWER)
- .+= "Insufficient power to operate."
+ .+= list(list("Insufficient power to operate.", "bad"))
if(!check_fuel())
- .+= "Insufficient fuel for a burn."
+ .+= list(list("Insufficient fuel for a burn.", "bad"))
if(stat & BROKEN)
- .+= "Inoperable engine configuration."
+ .+= list(list("Inoperable engine configuration.", "bad"))
if(blockage)
- .+= "Obstruction of airflow detected."
+ .+= 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(.,"
")
/obj/machinery/atmospherics/unary/engine/power_change()
. = ..()
diff --git a/code/modules/overmap/ships/engines/ion_thruster.dm b/code/modules/overmap/ships/engines/ion_thruster.dm
index 3252159391..222c801611 100644
--- a/code/modules/overmap/ships/engines/ion_thruster.dm
+++ b/code/modules/overmap/ships/engines/ion_thruster.dm
@@ -61,9 +61,7 @@
. = list()
.+= "Location: [get_area(src)]."
if(!powered())
- .+= "Insufficient power to operate."
-
- . = jointext(.,"
")
+ .+= list(list("Insufficient power to operate.", "bad"))
/obj/machinery/ion_engine/proc/burn()
if(!on && !powered())
diff --git a/code/modules/tgui/modules/_base.dm b/code/modules/tgui/modules/_base.dm
index 766ff34fb9..1a1027072d 100644
--- a/code/modules/tgui/modules/_base.dm
+++ b/code/modules/tgui/modules/_base.dm
@@ -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)
diff --git a/code/modules/tgui/modules/overmap.dm b/code/modules/tgui/modules/overmap.dm
new file mode 100644
index 0000000000..3b157fc0c2
--- /dev/null
+++ b/code/modules/tgui/modules/overmap.dm
@@ -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, "You don't appear to be on a spaceship...")
+ 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
\ No newline at end of file
diff --git a/nano/templates/disperser.tmpl b/nano/templates/disperser.tmpl
deleted file mode 100644
index 08db5ed2ba..0000000000
--- a/nano/templates/disperser.tmpl
+++ /dev/null
@@ -1,91 +0,0 @@
-{{if data.faillink}}
-
- ERROR: Machine is incomplete, out of range, or misaligned!
-
-{{else}}
-
-
Targeting
-
-
-
- {{: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)}}
-
-
- {{: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)}}
-
-
- {{: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)}}
-
-
-
-
-
-
Charge
-
- {{if data.nopower}}
-
At least one part of the machine is unpowered.
- {{/if}}
-
- Charge Load Type
-
-
- {{:data.chargeload}}
-
-
- Cooldown
-
-
- {{if data.next_shot == 0}}
- Ready
- {{else}}
- {{:data.next_shot}} seconds
-
Warning: Do not fire during cooldown.
- {{/if}}
-
-
-
-
-
-
Calibration
-
-
- {{:data.cal_accuracy}}%
-
-
- {{:helper.link('Pre-Calibration', 'transfer-e-w', { 'skill_calibration' : 1 }, data.skill ? null : 'disabled', null)}}
-
- {{for data.calibration}}
-
- {{:helper.link(value, 'shuffle', { 'calibration' : index }, null, null)}}
-
-
- {{/for}}
-
-
-
-
Setup
-
-
- Strength
-
-
- {{:helper.link(data.strength, 'lightbulb', { 'strength' : 1 }, null, null)}}
-
-
- Radius
-
-
- {{:helper.link(data.range, 'arrow-4-diag', { 'range' : 1 }, null, null)}}
-
-
-
-
-{{:helper.link("Fire", 'alert', { 'fire' : 1 }, null, null)}}
-
-{{/if}}
\ No newline at end of file
diff --git a/nano/templates/engines_control.tmpl b/nano/templates/engines_control.tmpl
deleted file mode 100644
index 2933b1cbe6..0000000000
--- a/nano/templates/engines_control.tmpl
+++ /dev/null
@@ -1,110 +0,0 @@
-
- {{: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)}}
-
-
-
-
- Global controls:
-
-
- {{:helper.link(data.global_state ? 'Shut all down' : 'Power all up', 'power', {'global_toggle' : 1}, null, data.global_state ? 'selected' : null)}}
-
-
-
-
- Volume limit:
-
-
- {{: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)}}
-
-
-
-
- Total thrust:
-
-
- {{:data.total_thrust}}
-
-
-
-{{if data.state == "engines"}}
- {{if data.engines_info}}
- {{for data.engines_info}}
-
-
- Engine #{{:(index + 1)}}:
-
-
- {{: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)}}
-
-
-
-
- Type:
-
-
- {{:value.eng_type}}
-
-
-
-
- Status:
-
-
- {{:value.eng_on ? value.eng_on == 1 ? 'Online' : 'Booting' : 'Offline'}}
- {{:value.eng_status}}
-
-
-
-
- Current thrust:
-
-
- {{:value.eng_thrust}}
-
-
-
-
- Volume limit:
-
-
- {{: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)}}
-
-
-
- {{/for}}
- {{/if}}
-{{/if}}
-{{if data.state == "status"}}
- {{if data.engines_info}}
- {{for data.engines_info}}
-
-
-
- Engine #{{:(index + 1)}}:
-
-
- {{: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)}}
-
-
-
-
- Thrust:
-
- Volume limit:
-
-
- {{:value.eng_thrust}}
-
- {{:value.eng_thrust_limiter}}%
-
-
-
- {{/for}}
- {{/if}}
-{{/if}}
\ No newline at end of file
diff --git a/nano/templates/helm.tmpl b/nano/templates/helm.tmpl
deleted file mode 100644
index 2d371b1154..0000000000
--- a/nano/templates/helm.tmpl
+++ /dev/null
@@ -1,159 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Navigation data
-
-
- Location:
-
-
- {{:data.sector}}
-
-
-
-
- Coordinates:
-
-
- {{:data.s_x}} : {{:data.s_y}}
-
-
-
-
- Scan data:
-
-
- {{:data.sector_info}}
-
-
-
-
- Status:
-
-
- {{:data.landed}}
-
-
-
- {{:helper.link('Save current position', 'disk', { 'add' : 'current' }, null)}}
- {{:helper.link('Add new entry', 'document', { 'add' : 'new' }, null)}}
-
-
-
- | Name | Coordinates | Actions
- {{for data.locations}}
- |
|---|
| {{:value.name}}
- | {{:value.x}} : {{:value.y}}
- | {{: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}}
- |
-
-
-
-
\ No newline at end of file
diff --git a/nano/templates/nav.tmpl b/nano/templates/nav.tmpl
deleted file mode 100644
index 6b5f5a9628..0000000000
--- a/nano/templates/nav.tmpl
+++ /dev/null
@@ -1,59 +0,0 @@
-
Navigation
-
-
-
-
- Map view
- {{:helper.link(data.viewing ? 'Engaged' : 'Disengaged', 'shuffle', { 'viewing' : 1 }, null, data.viewing ? 'selected' : null)}}
-
-
-
-
-
-
Sector information
-
- {{:data.sector}}
-
- Coordinates: {{:data.s_x}} : {{:data.s_y}}
-
- Additional information: {{:data.sector_info}}
-
-
-
-
-
Flight data
-
-
-
- ETA to next grid:
-
-
- {{:data.ETAnext}}
-
-
-
-
- Speed:
-
-
- {{:data.speed}} Gm/h
-
-
-
-
- Acceleration:
-
-
- {{:data.accel}} Gm/h
-
-
-
-
- Heading:
-
-
- {{:data.heading}}°
-
-
-
-
\ No newline at end of file
diff --git a/nano/templates/shipsensors.tmpl b/nano/templates/shipsensors.tmpl
deleted file mode 100644
index 5931fd01b2..0000000000
--- a/nano/templates/shipsensors.tmpl
+++ /dev/null
@@ -1,90 +0,0 @@
-
Sensors control console
-
- {{:helper.link(data.on ? 'Switch off' : 'Switch on', 'gear', { 'toggle' : 1 }, data.status != 'MISSING' ? null : 'disabled', data.on ? 'selected' : null)}}
-
-
- Status:
-
-
- {{:data.status}}
-
-
-
-
- Range:
-
-
- {{:helper.link(data.range, null, { 'range' : 1 }, null, null)}}
-
-
-
-
-
-
- Integrity:
-
-
- {{if data.health < (data.max_health * 0.25)}}
- {{:helper.displayBar(data.health, 0, data.max_health, 'bad')}}
-
{{:data.health}}/{{:data.max_health}}
- {{else data.health < data.max_health *.75}}
- {{:helper.displayBar(data.health, 0, data.max_health, 'average')}}
-
{{:data.health}}/{{:data.max_health}}
- {{else}}
- {{:helper.displayBar(data.health, 0, data.max_health, 'good')}}
-
{{:data.health}}/{{:data.max_health}}
- {{/if}}
-
-
-
-
- Temperature:
-
-
- {{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}}
-
-
- {{if data.heat < (data.critical_heat * 0.5)}}
- Temperature low.
- {{else data.heat < (data.critical_heat * 0.75)}}
- Sensor temperature high!
- {{else}}
- TEMPERATURE CRITICAL: Disable or reduce power immediately!
- {{/if}}
-
-
-
-
-
-
- Sector map view
- {{:helper.link(data.viewing ? 'Engaged' : 'Disengaged', 'shuffle', { 'viewing' : 1 }, null, data.viewing ? 'selected' : null)}}
-
-
-
-
Sensor contacts
-
-{{if data.contacts}}
-
- {{for data.contacts}}
-
-
-
{{:helper.link('Scan', 'search' ,{ 'scan' : value.ref }, null, null)}} |
- {{:value.name}}, bearing {{:value.bearing}} |
-
-
- {{/for}}
-
-{{/if}}
-
-{{if data.status == 'MISSING'}}
-
- {{:helper.link('Link up with the sensor suite', 'gear', { 'link' : 1 }, data.status == 'MISSING' ? null : 'disabled', null)}}
-
-{{/if}}
diff --git a/tgui/packages/tgui/interfaces/NtosOvermapNavigation.js b/tgui/packages/tgui/interfaces/NtosOvermapNavigation.js
new file mode 100644
index 0000000000..eb3dbe06f0
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/NtosOvermapNavigation.js
@@ -0,0 +1,15 @@
+import { NtosWindow } from '../layouts';
+import { OvermapNavigationContent } from './OvermapNavigation';
+
+export const NtosOvermapNavigation = () => {
+ return (
+
+
+
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/OvermapDisperser.js b/tgui/packages/tgui/interfaces/OvermapDisperser.js
new file mode 100644
index 0000000000..7f231bcb3a
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/OvermapDisperser.js
@@ -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 (
+
+
+
+
+
+ );
+};
+
+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 (
+
+ Machine is incomplete, out of range, or misaligned!
+
+ );
+ }
+
+ return (
+
+
+
+ val === overmapdir} />
+
+
+
+
+
+ {nopower && (
+
+ At least one part of the machine is unpowered.
+
+ ) || null}
+
+ {chargeload}
+
+
+ {next_shot === 0 && (
+ Ready
+ ) || next_shot > 1 && (
+
+ Seconds
+ Warning: Do not fire during cooldown.
+
+ ) || null}
+
+
+
+
+
+
+ %
+
+
+ {calibration.map((cal, i) => (
+
+ Cal #{i}:
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/tgui/packages/tgui/interfaces/OvermapEngines.js b/tgui/packages/tgui/interfaces/OvermapEngines.js
new file mode 100644
index 0000000000..5dd80a8b70
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/OvermapEngines.js
@@ -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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {engines_info.map((engine, i) => (
+
+
+
+ Engine #{i + 1} |
+ Thrust: |
+ Limit: val + "%"} />
+
+ // "Engine " + (i + 1)
+ // + " | Thrust: " + engine.eng_thrust
+ // + " | Limit: " + engine.eng_thrust_limiter + "%"
+ )}>
+
+
+
+ {engine.eng_type}
+
+
+
+ {engine.eng_on ? (engine.eng_on === 1 ? "Online" : "Booting") : "Offline"}
+
+ {engine.eng_status.map(status => {
+ if (Array.isArray(status)) {
+ return {status[0]};
+ } else {
+ return {status};
+ }
+ })}
+
+
+ {engine.eng_thrust}
+
+
+ act("limit", { limit: -0.1, engine: engine.eng_reference })}
+ icon="minus" />
+ act("set_limit", { engine: engine.eng_reference })}>
+ {engine.eng_thrust_limiter}%
+
+ act("limit", { limit: 0.1, engine: engine.eng_reference })}
+ icon="plus" />
+
+
+
+
+
+
+ act("toggle", { engine: engine.eng_reference })}>
+ {engine.eng_on ? (engine.eng_on === 1 ? "Shutoff" : "Booting") : "Startup"}
+
+
+
+ ))}
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/tgui/packages/tgui/interfaces/OvermapHelm.js b/tgui/packages/tgui/interfaces/OvermapHelm.js
new file mode 100644
index 0000000000..0ddd5112d6
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/OvermapHelm.js
@@ -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 (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+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 (
+
+ );
+};
+
+const OvermapManualControl = (props, context) => {
+ const { act, data } = useBackend(context);
+
+ const {
+ canburn,
+ manual_control,
+ } = data;
+
+ return (
+
+ );
+};
+
+const OvermapAutopilot = (props, context) => {
+ const { act, data } = useBackend(context);
+ const {
+ dest,
+ d_x,
+ d_y,
+ speedlimit,
+ autopilot,
+ autopilot_disabled,
+ } = data;
+
+ if (autopilot_disabled) {
+ return (
+
+ );
+ }
+
+ return (
+
+ );
+};
+
+const OvermapNavComputer = (props, context) => {
+ const { act, data } = useBackend(context);
+
+ const {
+ sector,
+ s_x,
+ s_y,
+ sector_info,
+ landed,
+ locations,
+ } = data;
+
+ return (
+
+
+
+ {sector}
+
+
+ {s_x} : {s_y}
+
+
+ {sector_info}
+
+
+ {landed}
+
+
+
+
+ act("add", { add: "current" })}>
+ Save Current Position
+
+
+
+ act("add", { add: "new" })}>
+ Add New Entry
+
+
+
+
+
+
+ Name
+ Coordinates
+ Actions
+
+ {locations.map(loc => (
+
+ {loc.name}
+ {loc.x} : {loc.y}
+
+ act("setds", { x: loc.x, y: loc.y })}>
+ Plot Course
+
+ act("remove", { remove: loc.reference })}>
+ Remove
+
+
+
+ ))}
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/tgui/packages/tgui/interfaces/OvermapNavigation.js b/tgui/packages/tgui/interfaces/OvermapNavigation.js
new file mode 100644
index 0000000000..48215060ab
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/OvermapNavigation.js
@@ -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 (
+
+
+
+
+
+ );
+};
+
+export const OvermapNavigationContent = (props, context) => {
+ const { act, data } = useBackend(context);
+ const {
+ sector,
+ s_x,
+ s_y,
+ sector_info,
+ viewing,
+ } = data;
+ return (
+
+ act("viewing")}>
+ Map View
+
+ }>
+
+
+ {sector}
+
+
+ {s_x} : {s_y}
+
+
+ {sector_info}
+
+
+
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/OvermapShipSensors.js b/tgui/packages/tgui/interfaces/OvermapShipSensors.js
new file mode 100644
index 0000000000..980b27446e
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/OvermapShipSensors.js
@@ -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 (
+
+
+
+ act("viewing")}>
+ Map View
+
+ act("toggle")}>
+ {on ? "Sensors Enabled" : "Sensors Disabled"}
+
+
+ )}>
+
+
+ {status}
+
+
+ act("range")}>
+ {range}
+
+
+
+
+ {health} / {max_health}
+
+
+
+
+ {heat < critical_heat * 0.5 && (
+ Temperature low.
+ ) || heat < critical_heat * 0.75 && (
+ Sensor temperature high!
+ ) || (
+ TEMPERATURE CRITICAL: Disable or reduce power immediately!
+ )}
+
+
+
+
+
+ {contacts.length && contacts.map(alien => (
+ act("scan", { scan: alien.ref })}>
+ Scan: {alien.name}
+ , bearing: {alien.bearing}°
+
+ )) || (
+
+ No contacts on sensors.
+
+ )}
+
+ {data.status === "MISSING" && (
+
+ act("link")}>
+ Link up with sensor suite?
+
+
+ ) || null}
+
+
+ );
+};
\ No newline at end of file
diff --git a/tgui/packages/tgui/interfaces/common/Overmap.js b/tgui/packages/tgui/interfaces/common/Overmap.js
new file mode 100644
index 0000000000..17a2b2cfee
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/common/Overmap.js
@@ -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 (
+
+
+ {ETAnext}
+
+
+ {speed} Gm/h
+
+
+ {accel} Gm/h
+
+
+ {heading}°
+
+ {!disableLimiterControls && (
+
+ act("accellimit")}>
+ {accellimit} Gm/h
+
+
+ ) || null}
+
+ );
+};
+
+export const OvermapPanControls = (props, context) => {
+ const { act } = useBackend(context);
+
+ const {
+ disabled,
+ actToDo,
+ selected = val => false,
+ } = props;
+
+ return (
+
+
+ act(actToDo, { dir: 9 })}
+ icon="arrow-up"
+ iconRotation={-45} />
+ act(actToDo, { dir: 1 })}
+ icon="arrow-up" />
+ act(actToDo, { dir: 5 })}
+ icon="arrow-up"
+ iconRotation={45} />
+
+
+ act(actToDo, { dir: 8 })}
+ icon="arrow-left" />
+ act("brake")}
+ icon="ban" />
+ act(actToDo, { dir: 4 })}
+ icon="arrow-right" />
+
+
+ act(actToDo, { dir: 10 })}
+ icon="arrow-down"
+ iconRotation={45} />
+ act(actToDo, { dir: 2 })}
+ icon="arrow-down" />
+ act(actToDo, { dir: 6 })}
+ icon="arrow-down"
+ iconRotation={-45} />
+
+
+ );
+};
\ No newline at end of file
diff --git a/vorestation.dme b/vorestation.dme
index 04ed3b7f86..c860cdab61 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -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"