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 @@ - - - -
-
- Flight data -
-
- ETA to next grid: -
-
- {{:data.ETAnext}} -
-
-
-
- Speed: -
-
- {{:data.speed}} Gm/h -
-
-
-
- Acceleration: -
-
- {{:data.accel}} Gm/h -
-
-
-
- Heading: -
-
- {{:data.heading}}° -
-
-
-
- Acceleration limiter: -
-
- {{:helper.link(data.accellimit, null, { 'accellimit' : 1}, null, null)}} Gm/h -
-
-
-
- -
-
- Manual control -
-
- {{: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)}} -
-
- {{: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)}} -
-
- {{: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)}} -
- -
- Direct control -
- {{:helper.link(data.manual_control ? 'Engaged' : 'Disengaged', 'shuffle', { 'manual' : 1 }, null, data.manual_control ? 'selected' : null)}} -
-
-
-
- -
-
- Autopilot -
-
- Target: -
-
- {{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}} -
-
-
-
- Speed limit: -
-
- {{:helper.link(data.speedlimit, null, { 'speedlimit' : 1 }, null, null)}} Gm/h -
-
-
- {{:helper.link(data.autopilot ? 'Engaged' : 'Disengaged', 'gear', { 'apilot' : 1 }, data.dest ? null : 'disabled', data.autopilot ? 'selected' : null)}} -
-
-
- -
-

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)}} -
-
- -
NameCoordinatesActions - {{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}} - -
-
- - - - {{/for}} -
{{:helper.link('Scan', 'search' ,{ 'scan' : value.ref }, null, null)}}{{:value.name}}, bearing {{:value.bearing}}
-{{/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} + + + +
+
+
+ + + +
+ ))} +
+
+
+ ); +}; \ 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 ( +
+ Flight Data + +
+ ); +}; + +const OvermapManualControl = (props, context) => { + const { act, data } = useBackend(context); + + const { + canburn, + manual_control, + } = data; + + return ( +
+ Manual Control + + + + + + + + Direct Control + + + +
+ ); +}; + +const OvermapAutopilot = (props, context) => { + const { act, data } = useBackend(context); + const { + dest, + d_x, + d_y, + speedlimit, + autopilot, + autopilot_disabled, + } = data; + + if (autopilot_disabled) { + return ( +
+ Autopilot + + AUTOPILOT DISABLED + + + 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. + + + act("apilot_lock")} /> + +
+ ); + } + + return ( +
+ Autopilot + + + {dest && ( + + + + + ) || ( + + )} + + + + + + + +
+ ); +}; + +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} + + + + + + + + + + +
+ + + Name + Coordinates + Actions + + {locations.map(loc => ( + + {loc.name} + {loc.x} : {loc.y} + + + + + + ))} +
+
+
+ ); +}; \ 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 ( + + +
+ + + + )}> + + + {status} + + + + + + + {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 => ( + + )) || ( + + No contacts on sensors. + + )} +
+ {data.status === "MISSING" && ( +
+ +
+ ) || 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 && ( + + + + ) || null} + + ); +}; + +export const OvermapPanControls = (props, context) => { + const { act } = useBackend(context); + + const { + disabled, + actToDo, + selected = val => false, + } = props; + + return ( + + +