diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm
index 1b028e117b..669cc60b5b 100644
--- a/code/_helpers/text.dm
+++ b/code/_helpers/text.dm
@@ -453,4 +453,22 @@ proc/TextPreview(var/string,var/len=40)
. += .(rest)
-#define gender2text(gender) capitalize(gender)
\ No newline at end of file
+#define gender2text(gender) capitalize(gender)
+
+/// Used to get a properly sanitized input, of max_length
+/// no_trim is self explanatory but it prevents the input from being trimed if you intend to parse newlines or whitespace.
+/proc/stripped_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE)
+ var/name = input(user, message, title, default) as text|null
+
+ if(no_trim)
+ return copytext(html_encode(name), 1, max_length)
+ else
+ return trim(html_encode(name), max_length) //trim is "outside" because html_encode can expand single symbols into multiple symbols (such as turning < into <)
+
+// Used to get a properly sanitized multiline input, of max_length
+/proc/stripped_multiline_input(mob/user, message = "", title = "", default = "", max_length=MAX_MESSAGE_LEN, no_trim=FALSE)
+ var/name = input(user, message, title, default) as message|null
+ if(no_trim)
+ return copytext(html_encode(name), 1, max_length)
+ else
+ return trim(html_encode(name), max_length)
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index 095f565bd4..e14a4c0edf 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -11,6 +11,7 @@ var/list/GPS_list = list()
matter = list(DEFAULT_WALL_MATERIAL = 500)
var/gps_tag = "GEN0"
var/emped = FALSE
+ var/updating = TRUE // Lets users lock the UI so they don't have to deal with constantly shifting signals
var/tracking = FALSE // Will not show other signals or emit its own signal if false.
var/long_range = FALSE // If true, can see farther, depending on get_map_levels().
var/local_mode = FALSE // If true, only GPS signals of the same Z level are shown.
@@ -66,7 +67,11 @@ var/list/GPS_list = list()
add_overlay("working")
/obj/item/device/gps/attack_self(mob/user)
- display(user)
+ tgui_interact(user)
+
+/obj/item/device/gps/examine(mob/user)
+ . = ..()
+ . += display()
// Compiles all the data not available directly from the GPS
// Like the positions and directions to all other GPS units
@@ -117,12 +122,12 @@ var/list/GPS_list = list()
return dat
-/obj/item/device/gps/proc/display(mob/user)
+/obj/item/device/gps/proc/display()
if(!tracking)
- to_chat(user, "The device is off. Alt-click it to turn it on.")
+ . = "The device is off. Alt-click it to turn it on."
return
if(emped)
- to_chat(user, "It's busted!")
+ . = "It's busted!"
return
var/list/dat = list()
@@ -143,8 +148,7 @@ var/list/GPS_list = list()
else
dat += "No other signals detected."
- var/result = dat.Join("
")
- to_chat(user, result)
+ . = dat
/obj/item/device/gps/Topic(var/href, var/list/href_list)
if(..())
@@ -168,6 +172,85 @@ var/list/GPS_list = list()
hide_signal = !hide_signal
to_chat(usr, "You set the device to [hide_signal ? "not " : ""]broadcast a signal while scanning for other signals.")
+/obj/item/device/gps/tgui_interact(mob/user, datum/tgui/ui)
+ if(emped)
+ to_chat(user, "[src] fizzles weakly.")
+ return
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "Gps", name)
+ ui.open()
+ ui.set_autoupdate(updating)
+
+/obj/item/device/gps/tgui_data(mob/user)
+ var/list/data = list()
+ data["power"] = tracking
+ data["tag"] = gps_tag
+ data["updating"] = updating
+ data["globalmode"] = !local_mode
+ if(!tracking || emped) //Do not bother scanning if the GPS is off or EMPed
+ return data
+
+ var/turf/curr = get_turf(src)
+ data["currentArea"] = "[get_area_name(curr, TRUE)]"
+ data["currentCoords"] = list(curr.x, curr.y, curr.z)
+ data["currentCoordsText"] = "[curr.x], [curr.y], [using_map.get_zlevel_name(curr.z)]"
+
+ data["zLevelDetection"] = using_map.get_map_levels(curr.z, long_range)
+
+ var/list/signals = list()
+ data["signals"] = list()
+
+ for(var/obj/item/device/gps/G in GPS_list - src)
+ if(!G.tracking || G.emped || G.hide_signal)
+ continue
+
+ var/turf/T = get_turf(G)
+ if(!T)
+ continue
+ if(local_mode && curr.z != T.z)
+ continue
+ if(!(T.z in data["zLevelDetection"]))
+ continue
+
+ var/list/signal = list()
+ signal["entrytag"] = G.gps_tag //Name or 'tag' of the GPS
+ signal["coords"] = list(T.x, T.y, T.z)
+ signal["coordsText"] = "[T.x], [T.y], [using_map.get_zlevel_name(T.z)]"
+ if(T.z == curr.z) //Distance/Direction calculations for same z-level only
+ signal["dist"] = max(get_dist(curr, T), 0) //Distance between the src and remote GPS turfs
+ signal["degrees"] = round(Get_Angle(curr, T)) //0-360 degree directional bearing, for more precision.
+ signals += list(signal) //Add this signal to the list of signals
+ data["signals"] = signals
+ return data
+
+/obj/item/device/gps/tgui_act(action, params)
+ if(..())
+ return TRUE
+
+ switch(action)
+ if("rename")
+ var/a = stripped_input(usr, "Please enter desired tag.", name, gps_tag, 20)
+
+ if(!a)
+ return
+
+ gps_tag = a
+ name = "global positioning system ([gps_tag])"
+ . = TRUE
+
+ if("power")
+ toggletracking(usr)
+ . = TRUE
+
+ if("updating")
+ updating = !updating
+ . = TRUE
+
+ if("globalmode")
+ local_mode = !local_mode
+ . = TRUE
+
/obj/item/device/gps/on // Defaults to off to avoid polluting the signal list with a bunch of GPSes without owners. If you need to spawn active ones, use these.
tracking = TRUE
@@ -291,10 +374,10 @@ var/list/GPS_list = list()
/obj/item/device/gps/syndie/display(mob/user)
if(!tracking)
- to_chat(user, "The device is off. Alt-click it to turn it on.")
+ . = "The device is off. Alt-click it to turn it on."
return
if(emped)
- to_chat(user, "It's busted!")
+ . = "It's busted!"
return
var/list/dat = list()
@@ -312,5 +395,4 @@ var/list/GPS_list = list()
else
dat += "No other signals detected."
- var/result = dat.Join("
")
- to_chat(user, result)
+ . = dat
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index 03b23b15a6..93c711b6be 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -33,7 +33,10 @@
/obj/machinery/mineral/processing_unit_console/attack_hand(mob/user)
if(..())
return
- interact(user)
+ if(!allowed(user))
+ to_chat(user, "Access denied.")
+ return
+ tgui_interact(user)
/obj/machinery/mineral/processing_unit_console/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/card/id))
@@ -42,97 +45,89 @@
if(!inserted_id && user.unEquip(I))
I.forceMove(src)
inserted_id = I
- interact(user)
+ SStgui.update_uis(src)
return
..()
-/obj/machinery/mineral/processing_unit_console/interact(mob/user)
- if(..())
- return
+/obj/machinery/mineral/processing_unit_console/tgui_interact(mob/user, datum/tgui/ui)
+ ui = SStgui.try_update_ui(user, src, ui)
+ if(!ui)
+ ui = new(user, src, "MiningOreProcessingConsole", name)
+ ui.open()
- if(!allowed(user))
- to_chat(user, "Access denied.")
- return
+/obj/machinery/mineral/processing_unit_console/tgui_data(mob/user, datum/tgui/ui, datum/tgui_state/state)
+ var/list/data = ..()
+ data["unclaimedPoints"] = machine.points
- user.set_machine(src)
-
- var/dat = "
Ore processor console
"
-
- dat += "Current unclaimed points: [machine.points]
"
- if(istype(inserted_id))
- dat += "You have [inserted_id.mining_points] mining points collected. Eject ID.
"
- dat += "Claim points.
"
+ if(inserted_id)
+ data["has_id"] = TRUE
+ data["id"] = list(
+ "name" = inserted_id.registered_name,
+ "points" = inserted_id.mining_points,
+ )
else
- dat += "No ID inserted. Insert ID.
"
-
- dat += "
"
+ data["has_id"] = FALSE
+ data["ores"] = list()
for(var/ore in machine.ores_processing)
-
- if(!machine.ores_stored[ore] && !show_all_ores) continue
+ if(!machine.ores_stored[ore] && !show_all_ores)
+ continue
var/ore/O = ore_data[ore]
- if(!O) continue
- dat += "| [capitalize(O.display_name)] | [machine.ores_stored[ore]] | "
- if(machine.ores_processing[ore])
- switch(machine.ores_processing[ore])
- if(PROCESS_NONE)
- dat += "not processing"
- if(PROCESS_SMELT)
- dat += "smelting"
- if(PROCESS_COMPRESS)
- dat += "compressing"
- if(PROCESS_ALLOY)
- dat += "alloying"
- else
- dat += "not processing"
- dat += ". | \[change\] |
"
+ if(!O)
+ continue
+ data["ores"].Add(list(list(
+ "ore" = ore,
+ "name" = O.display_name,
+ "amount" = machine.ores_stored[ore],
+ "processing" = machine.ores_processing[ore] ? machine.ores_processing[ore] : 0,
+ )))
- dat += "
"
- dat += "Currently displaying [show_all_ores ? "all ore types" : "only available ore types"]. \[[show_all_ores ? "show less" : "show more"]\]"
- dat += "The ore processor is currently [(machine.active ? "processing" : "disabled")]."
- user << browse(dat, "window=processor_console;size=400x500")
- onclose(user, "processor_console")
- return
+ data["showAllOres"] = show_all_ores
+ data["power"] = machine.active
-/obj/machinery/mineral/processing_unit_console/Topic(href, href_list)
+ return data
+
+/obj/machinery/mineral/processing_unit_console/tgui_act(action, list/params)
if(..())
- return 1
- usr.set_machine(src)
- src.add_fingerprint(usr)
+ return TRUE
- if(href_list["toggle_smelting"])
-
- var/choice = input("What setting do you wish to use for processing [href_list["toggle_smelting"]]?") as null|anything in list("Smelting","Compressing","Alloying","Nothing")
- if(!choice) return
-
- switch(choice)
- if("Nothing") choice = PROCESS_NONE
- if("Smelting") choice = PROCESS_SMELT
- if("Compressing") choice = PROCESS_COMPRESS
- if("Alloying") choice = PROCESS_ALLOY
-
- machine.ores_processing[href_list["toggle_smelting"]] = choice
-
- if(href_list["toggle_power"])
-
- machine.active = !machine.active
-
- if(href_list["toggle_ores"])
-
- show_all_ores = !show_all_ores
-
- if(href_list["choice"])
- if(istype(inserted_id))
- if(href_list["choice"] == "eject")
- usr.put_in_hands(inserted_id)
- inserted_id = null
- if(href_list["choice"] == "claim")
+ add_fingerprint(usr)
+ switch(action)
+ if("toggleSmelting")
+ var/ore = params["ore"]
+ var/new_setting = params["set"]
+ if(new_setting == null)
+ new_setting = input("What setting do you wish to use for processing [ore]]?") as null|anything in list("Smelting","Compressing","Alloying","Nothing")
+ if(!new_setting)
+ return
+ switch(new_setting)
+ if("Nothing") new_setting = PROCESS_NONE
+ if("Smelting") new_setting = PROCESS_SMELT
+ if("Compressing") new_setting = PROCESS_COMPRESS
+ if("Alloying") new_setting = PROCESS_ALLOY
+ machine.ores_processing[ore] = new_setting
+ . = TRUE
+ if("power")
+ machine.active = !machine.active
+ . = TRUE
+ if("showAllOres")
+ show_all_ores = !show_all_ores
+ . = TRUE
+ if("logoff")
+ if(!inserted_id)
+ return
+ usr.put_in_hands(inserted_id)
+ inserted_id = null
+ . = TRUE
+ if("claim")
+ if(istype(inserted_id))
if(access_mining_station in inserted_id.access)
inserted_id.mining_points += machine.points
machine.points = 0
else
to_chat(usr, "Required access not found.")
- else if(href_list["choice"] == "insert")
+ . = TRUE
+ if("insert")
var/obj/item/weapon/card/id/I = usr.get_active_hand()
if(istype(I))
usr.drop_item()
@@ -140,9 +135,9 @@
inserted_id = I
else
to_chat(usr, "No valid ID.")
-
- src.updateUsrDialog()
- return
+ . = TRUE
+ else
+ return FALSE
/**********************Mineral processing unit**************************/
diff --git a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm
index 90fa2659aa..152183de71 100644
--- a/code/modules/mining/ore_redemption_machine/equipment_vendor.dm
+++ b/code/modules/mining/ore_redemption_machine/equipment_vendor.dm
@@ -37,10 +37,10 @@
prize_list["Gear"] = list(
// TODO EQUIPMENT("Advanced Scanner", /obj/item/device/t_scanner/adv_mining_scanner, 800),
// TODO EQUIPMENT("Explorer's Webbing", /obj/item/storage/belt/mining, 500),
- EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 100),
+ EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500),
EQUIPMENT("Defense Equipment - Razor Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/manhacks/station/locked, 1000),
EQUIPMENT("Defense Equipment - Sentry Drone Deployer", /obj/item/weapon/grenade/spawnergrenade/ward, 1500),
- EQUIPMENT("Defense Equipment - Plasteel Machete", /obj/item/weapon/material/knife/machete, 500),
+ EQUIPMENT("Defense Equipment - Smoke Bomb", /obj/item/weapon/grenade/smokebomb, 100),
EQUIPMENT("Durasteel Fishing Rod", /obj/item/weapon/material/fishing_rod/modern/strong, 7500),
EQUIPMENT("Fishing Net", /obj/item/weapon/material/fishing_net, 500),
EQUIPMENT("Titanium Fishing Rod", /obj/item/weapon/material/fishing_rod/modern, 1000),
@@ -58,28 +58,28 @@
EQUIPMENT("10 Marker Beacons", /obj/item/stack/marker_beacon/ten, 100),
EQUIPMENT("30 Marker Beacons", /obj/item/stack/marker_beacon/thirty, 300),
EQUIPMENT("Fulton Pack", /obj/item/extraction_pack, 1200),
- EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500),
- EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 500),
- EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250),
- EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250),
- EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250),
- EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250),
EQUIPMENT("Injector (L) - Glucose", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/glucose, 500),
EQUIPMENT("Injector (L) - Panacea", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/purity, 500),
EQUIPMENT("Injector (L) - Trauma", /obj/item/weapon/reagent_containers/hypospray/autoinjector/biginjector/brute, 500),
EQUIPMENT("Nanopaste Tube", /obj/item/stack/nanopaste, 1000),
+ EQUIPMENT("Point Transfer Card", /obj/item/weapon/card/mining_point_card, 500),
+ EQUIPMENT("Shelter Capsule", /obj/item/device/survivalcapsule, 500),
+ EQUIPMENT("Burn Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/burn, 250),
+ EQUIPMENT("Detox Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/detox, 250),
+ EQUIPMENT("Oxy Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/oxy, 250),
+ EQUIPMENT("Trauma Medipen", /obj/item/weapon/reagent_containers/hypospray/autoinjector/trauma, 250),
)
prize_list["Kinetic Accelerator"] = list(
EQUIPMENT("Kinetic Accelerator", /obj/item/weapon/gun/energy/kinetic_accelerator, 900),
- EQUIPMENT("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125),
EQUIPMENT("KA Adjustable Tracer Rounds",/obj/item/borg/upgrade/modkit/tracer/adjustable, 175),
- EQUIPMENT("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250),
- EQUIPMENT("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300),
- EQUIPMENT("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000),
+ EQUIPMENT("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000),
EQUIPMENT("KA Damage Increase", /obj/item/borg/upgrade/modkit/damage, 1000),
EQUIPMENT("KA Efficiency Increase", /obj/item/borg/upgrade/modkit/efficiency, 1200),
- EQUIPMENT("KA AoE Damage", /obj/item/borg/upgrade/modkit/aoe/mobs, 2000),
EQUIPMENT("KA Holster", /obj/item/clothing/accessory/holster/waist/kinetic_accelerator, 350),
+ EQUIPMENT("KA Hyper Chassis", /obj/item/borg/upgrade/modkit/chassis_mod/orange, 300),
+ EQUIPMENT("KA Range Increase", /obj/item/borg/upgrade/modkit/range, 1000),
+ EQUIPMENT("KA Super Chassis", /obj/item/borg/upgrade/modkit/chassis_mod, 250),
+ EQUIPMENT("KA White Tracer Rounds", /obj/item/borg/upgrade/modkit/tracer, 125),
)
prize_list["Digging Tools"] = list(
// EQUIPMENT("Diamond Pickaxe", /obj/item/weapon/pickaxe/diamond, 2000),
@@ -94,20 +94,20 @@
)
prize_list["Hardsuit"] = list(
EQUIPMENT("Hardsuit - Control Module", /obj/item/weapon/rig/industrial/vendor, 2000),
- EQUIPMENT("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800),
EQUIPMENT("Hardsuit - Drill", /obj/item/rig_module/device/drill, 5000),
- EQUIPMENT("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000),
- EQUIPMENT("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500),
- EQUIPMENT("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250),
EQUIPMENT("Hardsuit - Intelligence Storage",/obj/item/rig_module/ai_container, 2500),
+ EQUIPMENT("Hardsuit - Maneuvering Jets", /obj/item/rig_module/maneuvering_jets, 1250),
+ EQUIPMENT("Hardsuit - Material Scanner", /obj/item/rig_module/vision/material, 500),
+ EQUIPMENT("Hardsuit - Ore Scanner", /obj/item/rig_module/device/orescanner, 1000),
+ EQUIPMENT("Hardsuit - Plasma Cutter", /obj/item/rig_module/device/plasmacutter, 800),
EQUIPMENT("Hardsuit - Smoke Bomb Deployer", /obj/item/rig_module/grenade_launcher/smoke,2000),
)
prize_list["Miscellaneous"] = list(
EQUIPMENT("Absinthe", /obj/item/weapon/reagent_containers/food/drinks/bottle/absinthe, 125),
EQUIPMENT("Bar Shelter Capsule", /obj/item/device/survivalcapsule/luxurybar, 10000),
EQUIPMENT("Cigar", /obj/item/clothing/mask/smokable/cigarette/cigar/havana, 150),
- EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500),
EQUIPMENT("Digital Tablet - Advanced", /obj/item/modular_computer/tablet/preset/custom_loadout/advanced, 1000),
+ EQUIPMENT("Digital Tablet - Standard", /obj/item/modular_computer/tablet/preset/custom_loadout/standard, 500),
EQUIPMENT("Industrial Equipment - Phoron Bore", /obj/item/weapon/gun/magnetic/matfed, 3000),
EQUIPMENT("Industrial Equipment - Sheet-Snatcher",/obj/item/weapon/storage/bag/sheetsnatcher, 500),
EQUIPMENT("Laser Pointer", /obj/item/device/laser_pointer, 900),
diff --git a/tgui/packages/tgui/format.js b/tgui/packages/tgui/format.js
index 8bddc19bff..2d5333d4f8 100644
--- a/tgui/packages/tgui/format.js
+++ b/tgui/packages/tgui/format.js
@@ -103,6 +103,7 @@ export const formatCommaNumber = value => {
let parts = value.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
+};
// Function from https://stackoverflow.com/a/34841026. CC BY-SA 4.0.
export const formatTime = seconds => {
diff --git a/tgui/packages/tgui/interfaces/Gps.js b/tgui/packages/tgui/interfaces/Gps.js
new file mode 100644
index 0000000000..f2549a31a5
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/Gps.js
@@ -0,0 +1,133 @@
+import { map, sortBy } from 'common/collections';
+import { flow } from 'common/fp';
+import { clamp } from 'common/math';
+import { vecLength, vecSubtract } from 'common/vector';
+import { Fragment } from 'inferno';
+import { useBackend } from '../backend';
+import { Box, Button, Icon, LabeledList, Section, Table } from '../components';
+import { Window } from '../layouts';
+
+import { createLogger } from '../logging';
+const logger = createLogger('lol what');
+
+const coordsToVec = coords => map(parseFloat)(coords.split(', '));
+
+export const Gps = (props, context) => {
+ const { act, data } = useBackend(context);
+ const {
+ currentArea,
+ currentCoords,
+ currentCoordsText,
+ globalmode,
+ power,
+ tag,
+ updating,
+ } = data;
+ const signals = flow([
+ map((signal, index) => {
+ // Calculate distance to the target. BYOND distance is capped to 127,
+ // that's why we roll our own calculations here.
+ const dist = signal.dist && (
+ Math.round(vecLength(vecSubtract(
+ currentCoords,
+ signal.coords)))
+ );
+ return { ...signal, dist, index };
+ }),
+ sortBy(
+ // Signals with distance metric go first
+ signal => signal.dist === undefined,
+ // Sort alphabetically
+ signal => signal.entrytag),
+ ])(data.signals || []);
+ return (
+
+
+ act('power')} />
+ )}>
+
+
+
+
+
+
+
+
+
+ {!!power && (
+
+
+
+ {currentArea} ({currentCoordsText})
+
+
+
+
+
+
+
+
+
+ {signals.map(signal => (
+
+
+ {signal.entrytag}
+
+
+ {signal.degrees !== undefined && (
+
+ )}
+ {signal.dist !== undefined && (
+ signal.dist + 'm'
+ )}
+
+
+ {signal.coordsText}
+
+
+ ))}
+
+
+
+ )}
+
+
+ );
+};
diff --git a/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js b/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js
new file mode 100644
index 0000000000..f1a22fbe8b
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/MiningOreProcessingConsole.js
@@ -0,0 +1,145 @@
+import { toTitleCase } from 'common/string';
+import { Fragment } from 'inferno';
+import { useBackend, useLocalState } from "../backend";
+import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section, LabeledList, AnimatedNumber } from '../components';
+import { Window } from "../layouts";
+import { refocusLayout } from '../layouts';
+import { sortBy } from 'common/collections';
+import { MiningUser } from './common/Mining';
+
+export const MiningOreProcessingConsole = (props, context) => {
+ const { act, data } = useBackend(context);
+
+ const {
+ unclaimedPoints,
+ ores,
+ showAllOres,
+ power,
+ } = data;
+
+ return (
+
+
+
+
+ in order to claim points.
+
+ )} />
+ act("power")}>
+ {power ? "Smelting" : "Not Smelting"}
+
+ }>
+
+ act("claim")}>
+ Claim
+
+ }>
+
+
+
+
+
+
+
+ );
+};
+
+// ORDER IS IMPORTANT HERE.
+const processingOptions = [
+ "Not Processing",
+ "Smelting",
+ "Compressing",
+ "Alloying",
+];
+
+// Higher in the list == closer to top
+// This is just kind of an arbitrary list to sort by because the machine has no predictable ore order in it's list
+// and alphabetizing them doesn't really make sense
+const oreOrder = [
+ "verdantium",
+ "mhydrogen",
+ "diamond",
+ "platinum",
+ "uranium",
+ "gold",
+ "silver",
+ "rutile",
+ "phoron",
+ "marble",
+ "lead",
+ "sand",
+ "carbon",
+ "hematite",
+];
+
+const oreSorter = (a, b) => {
+ if (oreOrder.indexOf(a.ore) === -1) {
+ return a.ore - b.ore;
+ }
+ if (oreOrder.indexOf(b.ore) === -1) {
+ return a.ore - b.ore;
+ }
+ return oreOrder.indexOf(b.ore) - oreOrder.indexOf(a.ore);
+};
+
+const MOPCOres = (props, context) => {
+ const { act, data } = useBackend(context);
+ const {
+ ores,
+ showAllOres,
+ power,
+ } = data;
+ return (
+ act("showAllOres")}>
+ {showAllOres ? "All Ores" : "Ores in Machine"}
+
+ }>
+
+ {ores.length && ores.sort(oreSorter).map(ore => (
+ act("toggleSmelting", {
+ ore: ore.ore,
+ set: processingOptions.indexOf(val),
+ })} />
+ }>
+
+
+
+
+ )) || (
+
+ No ores in machine.
+
+ )}
+
+
+ );
+};
\ No newline at end of file
diff --git a/tgui/packages/tgui/interfaces/MiningVendor.js b/tgui/packages/tgui/interfaces/MiningVendor.js
index 1aef533916..2b653faaae 100644
--- a/tgui/packages/tgui/interfaces/MiningVendor.js
+++ b/tgui/packages/tgui/interfaces/MiningVendor.js
@@ -4,6 +4,7 @@ import { useBackend, useLocalState } from "../backend";
import { Box, Button, Collapsible, Dropdown, Flex, Input, NoticeBox, Section } from '../components';
import { Window } from "../layouts";
import { refocusLayout } from '../layouts';
+import { MiningUser } from './common/Mining';
const sortTypes = {
'Alphabetical': (a, b) => a - b,
@@ -11,11 +12,11 @@ const sortTypes = {
'By price': (a, b) => a.price - b.price,
};
-export const MiningVendor = (_properties, _context) => {
+export const MiningVendor = (props, context) => {
return (
-
+
@@ -23,47 +24,8 @@ export const MiningVendor = (_properties, _context) => {
);
};
-const MiningVendorUser = (_properties, context) => {
- const { act, data } = useBackend(context);
- const {
- has_id,
- id,
- } = data;
- return (
-
- {has_id ? (
-
-
- Logged in as {id.name}.
- You have {id.points.toLocaleString('en-US')} points.
-
-
- ) : (
- "Please insert an ID in order to make purchases."
- )}
-
- );
-};
-const MiningVendorItems = (_properties, context) => {
+const MiningVendorItems = (props, context) => {
const { act, data } = useBackend(context);
const {
has_id,
@@ -126,7 +88,7 @@ const MiningVendorItems = (_properties, context) => {
);
};
-const MiningVendorSearch = (_properties, context) => {
+const MiningVendorSearch = (props, context) => {
const [
_searchText,
setSearchText,
diff --git a/tgui/packages/tgui/interfaces/common/Mining.js b/tgui/packages/tgui/interfaces/common/Mining.js
new file mode 100644
index 0000000000..4a4f12fd37
--- /dev/null
+++ b/tgui/packages/tgui/interfaces/common/Mining.js
@@ -0,0 +1,44 @@
+import { Fragment } from 'inferno';
+import { useBackend } from "../../backend";
+import { Box, Button, Input, NoticeBox } from '../../components';
+
+export const MiningUser = (props, context) => {
+ const { act, data } = useBackend(context);
+ const {
+ insertIdText,
+ } = props;
+ const {
+ has_id,
+ id,
+ } = data;
+ return (
+
+ {has_id ? (
+
+
+ Logged in as {id.name}.
+ You have {id.points.toLocaleString('en-US')} points.
+
+
+ ) : insertIdText}
+
+ );
+};
\ No newline at end of file