[MIRROR] tgui: Auxiliary Base Management Console (#2453)

* tgui: Auxiliary Base Management Console

* rebuild tgui

Co-authored-by: Jordan Brown <Cyberboss@users.noreply.github.com>
Co-authored-by: Avunia Takiya <git@takiya.cloud>
This commit is contained in:
SkyratBot
2021-01-02 23:58:06 +01:00
committed by GitHub
co-authored by Jordan Brown Avunia Takiya
parent 3f506307ad
commit e80f19c901
6 changed files with 278 additions and 101 deletions
+145 -93
View File
@@ -10,121 +10,171 @@
name = "Auxiliary Base"
luminosity = 0 //Lighting gets lost when it lands anyway
/obj/machinery/computer/auxiliary_base
name = "auxiliary base management console"
desc = "Allows a deployable expedition base to be dropped from the station to a designated mining location. It can also \
interface with the mining shuttle at the landing site if a mobile beacon is also deployed."
icon = 'icons/obj/terminals.dmi'
icon_state = "dorm_available"
var/shuttleId = "colony_drop"
desc = "Allows a deployable expedition base to be dropped from the station to a designated mining location. It can also \
interface with the mining shuttle at the landing site if a mobile beacon is also deployed."
var/launch_warning = TRUE
var/list/turrets = list() //List of connected turrets
req_one_access = list(ACCESS_AUX_BASE, ACCESS_HEADS)
var/possible_destinations
circuit = /obj/item/circuitboard/computer/auxiliary_base
/// Shuttle ID of the base
var/shuttleId = "colony_drop"
/// If we give warnings before base is launched
var/launch_warning = TRUE
/// List of connected turrets
var/list/turrets = list()
/// List of all possible destinations
var/possible_destinations
/// ID of the currently selected destination of the attached base
var/destination
/// If blind drop option is available
var/blind_drop_ready = TRUE
/obj/machinery/computer/auxiliary_base/Initialize()
. = ..()
AddComponent(/datum/component/gps, "NT_AUX")
/obj/machinery/computer/auxiliary_base/ui_interact(mob/user)
. = ..()
/obj/machinery/computer/auxiliary_base/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "AuxBaseConsole", name)
ui.open()
/obj/machinery/computer/auxiliary_base/ui_data(mob/user)
var/list/data = list()
var/list/options = params2list(possible_destinations)
var/obj/docking_port/mobile/M = SSshuttle.getShuttle(shuttleId)
var/dat = "[is_station_level(z) ? "Docking clamps engaged. Standing by." : "Mining Shuttle Uplink: [M ? M.getStatusText() : "*OFFLINE*"]"]<br>"
if(M)
var/destination_found
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
if(!options.Find(S.id))
continue
if(!M.check_dock(S, silent=TRUE))
continue
destination_found = 1
dat += "<A href='?src=[REF(src)];move=[S.id]'>Send to [S.name]</A><br>"
if(!destination_found && is_station_level(z)) //Only available if miners are lazy and did not set an LZ using the remote.
dat += "<A href='?src=[REF(src)];random=1'>Prepare for blind drop? (Dangerous)</A><br>"
data["type"] = shuttleId == "colony_drop" ? "base" : "shuttle"
data["docked_location"] = M ? M.get_status_text_tgui() : "Unknown"
data["locations"] = list()
data["locked"] = FALSE
data["timer_str"] = M ? M.getTimerStr() : "00:00"
data["destination"] = destination
data["blind_drop"] = blind_drop_ready
data["turrets"] = list()
if(LAZYLEN(turrets))
dat += "<br><b>Perimeter Defense System:</b> <A href='?src=[REF(src)];turrets_power=on'>Enable All</A> / <A href='?src=[REF(src)];turrets_power=off'>Disable All</A><br> \
Units connected: [LAZYLEN(turrets)]<br>\
Unit | Condition | Status | Direction | Distance<br>"
for(var/PDT in turrets)
var/obj/machinery/porta_turret/aux_base/T = PDT
var/integrity = max((T.obj_integrity-T.integrity_failure * T.max_integrity)/(T.max_integrity-T.integrity_failure * max_integrity)*100, 0)
var/status
if(T.machine_stat & BROKEN)
status = "<span class='bad'>ERROR</span>"
else if(!T.on)
status = "Disabled"
else if(T.raised)
status = "<span class='average'><b>Firing</b></span>"
for(var/turret in turrets)
var/obj/machinery/porta_turret/aux_base/base_turret = turret
var/turret_integrity = max((base_turret.obj_integrity - base_turret.integrity_failure * base_turret.max_integrity) / (base_turret.max_integrity - base_turret.integrity_failure * max_integrity) * 100, 0)
var/turret_status
if(base_turret.machine_stat & BROKEN)
turret_status = "ERROR"
else if(!base_turret.on)
turret_status = "Disabled"
else if(base_turret.raised)
turret_status = "Firing"
else
status = "<span class='good'>All Clear</span>"
dat += "[T.name] | [integrity]% | [status] | [dir2text(get_dir(src, T))] | [get_dist(src, T)]m <A href='?src=[REF(src)];single_turret_power=[REF(T)]'>Toggle Power</A><br>"
turret_status = "All Clear"
var/list/turret_data = list(
name = base_turret.name,
integrity = turret_integrity,
status = turret_status,
direction = dir2text(get_dir(src, base_turret)),
distance = get_dist(src, base_turret),
ref = REF(base_turret)
)
data["turrets"] += list(turret_data)
if(!M)
data["status"] = "Missing"
return data
switch(M.mode)
if(SHUTTLE_IGNITING)
data["status"] = "Igniting"
if(SHUTTLE_IDLE)
data["status"] = "Idle"
if(SHUTTLE_RECHARGING)
data["status"] = "Recharging"
else
data["status"] = "In Transit"
for(var/obj/docking_port/stationary/S in SSshuttle.stationary)
if(!options.Find(S.port_destinations))
continue
if(!M.check_dock(S, silent = TRUE))
continue
var/list/location_data = list(
id = S.id,
name = S.name
)
data["locations"] += list(location_data)
if(length(data["locations"]) == 1)
for(var/location in data["locations"])
destination = location["id"]
data["destination"] = destination
if(!length(data["locations"]))
data["locked"] = TRUE
data["status"] = "Locked"
return data
/**
* Checks if we are allowed to launch the base
*
* Arguments:
* * user - The mob trying to initiate the launch
*/
/obj/machinery/computer/auxiliary_base/proc/launch_check(mob/user)
if(!is_station_level(z) && shuttleId == "colony_drop")
to_chat(user, "<span class='warning'>You can't move the base again!</span>")
return FALSE
return TRUE
dat += "<a href='?src=[REF(user)];mach_close=computer'>Close</a>"
var/datum/browser/popup = new(user, "computer", "base management", 550, 300) //width, height
popup.set_content("<center>[dat]</center>")
popup.open()
/obj/machinery/computer/auxiliary_base/Topic(href, href_list)
if(..())
/obj/machinery/computer/auxiliary_base/ui_act(action, params)
. = ..()
if(.)
return
usr.set_machine(src)
add_fingerprint(usr)
if(!allowed(usr))
to_chat(usr, "<span class='danger'>Access denied.</span>")
return
if(href_list["move"])
if(!is_station_level(z) && shuttleId == "colony_drop")
to_chat(usr, "<span class='warning'>You can't move the base again!</span>")
return
var/shuttle_error = SSshuttle.moveShuttle(shuttleId, href_list["move"], 1)
if(launch_warning)
say("<span class='danger'>Launch sequence activated! Prepare for drop!!</span>")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 70, FALSE)
launch_warning = FALSE
log_shuttle("[key_name(usr)] has launched the auxiliary base.")
else if(!shuttle_error)
say("Shuttle request uploaded. Please stand away from the doors.")
else
say("Shuttle interface failed.")
if(href_list["random"] && !possible_destinations)
usr.changeNext_move(CLICK_CD_RAPID) //Anti-spam
var/list/all_mining_turfs = list()
for (var/z_level in SSmapping.levels_by_trait(ZTRAIT_MINING))
all_mining_turfs += Z_TURFS(z_level)
var/turf/LZ = pick(all_mining_turfs) //Pick a random mining Z-level turf
if(!ismineralturf(LZ) && !istype(LZ, /turf/open/floor/plating/asteroid))
//Find a suitable mining turf. Reduces chance of landing in a bad area
to_chat(usr, "<span class='warning'>Landing zone scan failed. Please try again.</span>")
updateUsrDialog()
return
if(set_landing_zone(LZ, usr) != ZONE_SET)
to_chat(usr, "<span class='warning'>Landing zone unsuitable. Please recalculate.</span>")
updateUsrDialog()
return
if(LAZYLEN(turrets))
if(href_list["turrets_power"])
for(var/obj/machinery/porta_turret/aux_base/T in turrets)
if(href_list["turrets_power"] == "on")
T.on = TRUE
else
T.on = FALSE
if(href_list["single_turret_power"])
var/obj/machinery/porta_turret/aux_base/T = locate(href_list["single_turret_power"]) in turrets
if(istype(T))
T.on = !T.on
updateUsrDialog()
switch(action)
if("move")
if(!launch_check(usr))
return
var/shuttle_error = SSshuttle.moveShuttle(shuttleId, params["shuttle_id"], 1)
if(launch_warning)
say("<span class='danger'>Launch sequence activated! Prepare for drop!!</span>")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 70, FALSE)
launch_warning = FALSE
blind_drop_ready = FALSE
log_shuttle("[key_name(usr)] has launched the auxiliary base.")
return TRUE
else if(!shuttle_error)
say("Shuttle request uploaded. Please stand away from the doors.")
else
say("Shuttle interface failed.")
if("random")
if(possible_destinations)
return
usr.changeNext_move(CLICK_CD_RAPID) //Anti-spam
var/list/all_mining_turfs = list()
for(var/z_level in SSmapping.levels_by_trait(ZTRAIT_MINING))
all_mining_turfs += Z_TURFS(z_level)
var/turf/LZ = pick(all_mining_turfs) //Pick a random mining Z-level turf
if(!ismineralturf(LZ) && !istype(LZ, /turf/open/floor/plating/asteroid))
//Find a suitable mining turf. Reduces chance of landing in a bad area
to_chat(usr, "<span class='warning'>Landing zone scan failed. Please try again.</span>")
return
if(set_landing_zone(LZ, usr) != ZONE_SET)
to_chat(usr, "<span class='warning'>Landing zone unsuitable. Please recalculate.</span>")
return
blind_drop_ready = FALSE
return TRUE
if("set_destination")
var/target_destination = params["destination"]
if(!target_destination)
return
destination = target_destination
return TRUE
if("turrets_power")
for(var/obj/machinery/porta_turret/aux_base/base_turret in turrets)
base_turret.toggle_on()
return TRUE
if("single_turret_power")
var/obj/machinery/porta_turret/aux_base/base_turret = locate(params["single_turret_power"]) in turrets
if(!istype(base_turret))
return
base_turret.toggle_on()
return TRUE
/obj/machinery/computer/auxiliary_base/proc/set_mining_mode()
if(is_mining_level(z)) //The console switches to controlling the mining shuttle once landed.
@@ -166,6 +216,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
var/obj/docking_port/stationary/landing_zone = new /obj/docking_port/stationary(T)
landing_zone.id = "colony_drop([REF(src)])"
landing_zone.port_destinations = "colony_drop([REF(src)])"
landing_zone.name = "Landing Zone ([T.x], [T.y])"
landing_zone.dwidth = base_dock.dwidth
landing_zone.dheight = base_dock.dheight
@@ -310,6 +361,7 @@ interface with the mining shuttle at the landing site if a mobile beacon is also
Mport = new(landing_spot)
Mport.id = "landing_zone_dock"
Mport.port_destinations = "landing_zone_dock"
Mport.name = "auxiliary base landing site"
Mport.dwidth = SM.dwidth
Mport.dheight = SM.dheight
@@ -0,0 +1,108 @@
import { useBackend, useSharedState } from '../backend';
import { Button, NoticeBox, Section, Table, Tabs } from '../components';
import { Window } from '../layouts';
import { ShuttleConsoleContent } from './ShuttleConsole';
export const AuxBaseConsole = (props, context) => {
const { data } = useBackend(context);
const [tab, setTab] = useSharedState(context, 'tab', 1);
const {
type,
blind_drop,
turrets = [],
} = data;
return (
<Window
width={turrets.length ? 620 : 350}
height={turrets.length ? 310 : 260}>
<Window.Content scrollable={!!turrets.length}>
<Tabs>
<Tabs.Tab
icon="list"
lineHeight="23px"
selected={tab === 1}
onClick={() => setTab(1)}>
{type === "shuttle" ? "Shuttle Launch" : "Base Launch"}
</Tabs.Tab>
<Tabs.Tab
icon="list"
lineHeight="23px"
selected={tab === 2}
onClick={() => setTab(2)}>
Turrets ({turrets.length})
</Tabs.Tab>
</Tabs>
{tab === 1 && (
<ShuttleConsoleContent
type={type}
blind_drop={blind_drop} />
)}
{tab === 2 && (
<AuxBaseConsoleContent />
)}
</Window.Content>
</Window>
);
};
const STATUS_COLOR_KEYS = {
"ERROR": "bad",
"Disabled": "bad",
"Firing": "average",
"All Clear": "good",
};
export const AuxBaseConsoleContent = (props, context) => {
const { act, data } = useBackend(context);
const {
turrets = [],
} = data;
return (
<Section
title={"Turret Control"}
buttons={(
!!turrets.length && (
<Button
icon="power-off"
content={"Toggle Power"}
onClick={() => act('turrets_power')} />
))}>
{!turrets.length ? (
<NoticeBox>
No connected turrets
</NoticeBox>
) : (
<Table cellpadding="3" textAlign="center">
<Table.Row header>
<Table.Cell>Unit</Table.Cell>
<Table.Cell>Condition</Table.Cell>
<Table.Cell>Status</Table.Cell>
<Table.Cell>Direction</Table.Cell>
<Table.Cell>Distance</Table.Cell>
<Table.Cell>Power</Table.Cell>
</Table.Row>
{turrets.map(turret => (
<Table.Row key={turret.key}>
<Table.Cell bold>{turret.name}</Table.Cell>
<Table.Cell>{turret.integrity}%</Table.Cell>
<Table.Cell
color={STATUS_COLOR_KEYS[turret.status] || "bad"}>
{turret.status}
</Table.Cell>
<Table.Cell>{turret.direction}</Table.Cell>
<Table.Cell>{turret.distance}m</Table.Cell>
<Table.Cell>
<Button
icon="power-off"
content="Toggle"
onClick={() => act('single_turret_power', {
single_turret_power: turret.ref,
})} />
</Table.Cell>
</Table.Row>
))}
</Table>
)}
</Section>
);
};
@@ -4,6 +4,10 @@ import { Window } from '../layouts';
export const ShuttleConsole = (props, context) => {
const { act, data } = useBackend(context);
const {
type = "shuttle",
blind_drop,
} = props;
const {
authorization_required,
} = data;
@@ -29,7 +33,7 @@ export const ShuttleConsole = (props, context) => {
mt={2}
ml={2}
color="bad">
{'SHUTTLE LOCKED'}
{type === "shuttle" ? 'SHUTTLE LOCKED' : "BASE LOCKED"}
</Flex.Item>
</Flex>
<Box
@@ -45,7 +49,9 @@ export const ShuttleConsole = (props, context) => {
</Modal>
)}
<Window.Content>
<ShuttleConsoleContent />
<ShuttleConsoleContent
type={type}
blind_drop={blind_drop} />
</Window.Content>
</Window>
);
@@ -69,8 +75,9 @@ const STATUS_COLOR_KEYS = {
"Locked": "bad",
};
const ShuttleConsoleContent = (props, context) => {
export const ShuttleConsoleContent = (props, context) => {
const { act, data } = useBackend(context);
const { type, blind_drop } = props;
const {
status,
locked,
@@ -106,13 +113,23 @@ const ShuttleConsoleContent = (props, context) => {
</Box>
</Box>
<Section
title="Shuttle Controls"
title={type === "shuttle" ? "Shuttle Controls" : "Base Launch Controls"}
level={2}>
<LabeledList>
<LabeledList.Item label="Location">
{docked_location || "Not Available"}
</LabeledList.Item>
<LabeledList.Item label="Destination">
<LabeledList.Item
label="Destination"
buttons={(
type !== "shuttle" && locations.length===0 && !!blind_drop && (
<Button
color="bad"
icon="exclamation-triangle"
disabled={authorization_required || !blind_drop}
content={"Blind Drop"}
onClick={() => act('random')} />
))} >
{locations.length===0 && (
<Box
mb={1.7}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long