From b5dfd8880d5e15f4f3c740cb1b52b5d6a15f4c5a Mon Sep 17 00:00:00 2001 From: actioninja Date: Thu, 9 Apr 2020 17:11:36 -0700 Subject: [PATCH 01/46] id to component name --- code/controllers/subsystem/shuttle.dm | 2 +- code/datums/achievements/_achievement_data.dm | 2 +- code/datums/components/crafting/crafting.dm | 2 +- code/datums/components/gps.dm | 2 +- code/datums/components/uplink.dm | 2 +- code/datums/spawners_menu.dm | 2 +- code/datums/wires/_wires.dm | 2 +- code/game/machinery/Sleeper.dm | 2 +- code/game/machinery/announcement_system.dm | 2 +- code/game/machinery/bank_machine.dm | 2 +- code/game/machinery/computer/Operating.dm | 2 +- code/game/machinery/computer/aifixer.dm | 2 +- code/game/machinery/computer/atmos_alert.dm | 2 +- code/game/machinery/computer/atmos_control.dm | 4 +- code/game/machinery/computer/camera.dm | 2 +- code/game/machinery/computer/crew.dm | 2 +- code/game/machinery/computer/dna_console.dm | 4018 ++++++++--------- .../machinery/computer/launchpad_control.dm | 2 +- .../computer/prisoner/gulag_teleporter.dm | 2 +- code/game/machinery/computer/robot.dm | 2 +- code/game/machinery/computer/station_alert.dm | 2 +- code/game/machinery/computer/teleporter.dm | 2 +- code/game/machinery/doors/airlock.dm | 2 +- .../machinery/doors/airlock_electronics.dm | 2 +- code/game/machinery/doors/brigdoors.dm | 2 +- code/game/machinery/gulag_item_reclaimer.dm | 2 +- code/game/machinery/hypnochair.dm | 2 +- code/game/machinery/launch_pad.dm | 2 +- code/game/machinery/medical_kiosk.dm | 2 +- code/game/machinery/roulette_machine.dm | 2 +- code/game/machinery/scan_gate.dm | 2 +- code/game/machinery/spaceheater.dm | 2 +- code/game/machinery/suit_storage_unit.dm | 2 +- code/game/mecha/mech_bay.dm | 2 +- code/game/mecha/mecha_control_console.dm | 2 +- code/game/objects/items/RPD.dm | 2 +- code/game/objects/items/airlock_painter.dm | 2 +- code/game/objects/items/crayons.dm | 2 +- code/game/objects/items/devices/aicard.dm | 2 +- .../items/devices/radio/electropack.dm | 2 +- .../game/objects/items/devices/radio/radio.dm | 2 +- .../objects/items/devices/traitordevices.dm | 2 +- .../objects/items/devices/transfer_valve.dm | 2 +- code/game/objects/items/eightball.dm | 2 +- code/game/objects/items/tanks/tanks.dm | 2 +- code/game/objects/structures/artstuff.dm | 2 +- .../game/objects/structures/tank_dispenser.dm | 2 +- code/modules/NTNet/relays.dm | 2 +- code/modules/admin/verbs/borgpanel.dm | 2 +- .../changeling/cellular_emporium.dm | 2 +- .../nukeop/equipment/nuclearbomb.dm | 2 +- .../traitor/equipment/module_picker.dm | 2 +- code/modules/assembly/infrared.dm | 2 +- code/modules/assembly/proximity.dm | 2 +- code/modules/assembly/signaler.dm | 2 +- code/modules/assembly/timer.dm | 2 +- .../atmospherics/machinery/airalarm.dm | 2 +- .../components/binary_devices/passive_gate.dm | 6 +- .../components/binary_devices/pump.dm | 2 +- .../components/binary_devices/volume_pump.dm | 2 +- .../components/trinary_devices/filter.dm | 2 +- .../components/trinary_devices/mixer.dm | 2 +- .../components/unary_devices/cryo.dm | 2 +- .../unary_devices/outlet_injector.dm | 4 +- .../components/unary_devices/thermomachine.dm | 2 +- .../machinery/portable/canister.dm | 2 +- .../atmospherics/machinery/portable/pump.dm | 2 +- .../machinery/portable/scrubber.dm | 2 +- code/modules/awaymissions/gateway.dm | 2 +- .../cargo/blackmarket/blackmarket_uplink.dm | 2 +- code/modules/cargo/centcom_podlauncher.dm | 2 +- code/modules/cargo/console.dm | 2 +- code/modules/cargo/expressconsole.dm | 2 +- code/modules/events/pirates.dm | 2 +- .../kitchen_machinery/smartfridge.dm | 2 +- code/modules/holodeck/computer.dm | 2 +- code/modules/language/language_menu.dm | 2 +- code/modules/library/lib_codex_gigas.dm | 2 +- code/modules/library/soapstone.dm | 2 +- code/modules/mining/laborcamp/laborstacker.dm | 2 +- code/modules/mining/machine_redemption.dm | 2 +- code/modules/mining/machine_vending.dm | 2 +- code/modules/mining/mint.dm | 2 +- code/modules/mining/satchel_ore_boxdm.dm | 2 +- .../mob/dead/observer/notificationprefs.dm | 2 +- .../carbon/human/species_types/jellypeople.dm | 2 +- .../mob/living/silicon/ai/robot_control.dm | 2 +- .../mob/living/simple_animal/bot/mulebot.dm | 2 +- .../computers/item/computer_ui.dm | 2 +- .../file_system/programs/airestorer.dm | 2 +- .../file_system/programs/alarm.dm | 2 +- .../programs/antagonist/contract_uplink.dm | 2 +- .../file_system/programs/antagonist/dos.dm | 2 +- .../programs/antagonist/revelation.dm | 2 +- .../file_system/programs/arcade.dm | 2 +- .../file_system/programs/atmosscan.dm | 2 +- .../file_system/programs/borg_monitor.dm | 2 +- .../file_system/programs/card.dm | 2 +- .../file_system/programs/cargoship.dm | 2 +- .../file_system/programs/configurator.dm | 2 +- .../file_system/programs/crewmanifest.dm | 2 +- .../file_system/programs/file_browser.dm | 2 +- .../file_system/programs/jobmanagement.dm | 2 +- .../file_system/programs/ntdownloader.dm | 2 +- .../file_system/programs/ntmonitor.dm | 2 +- .../file_system/programs/ntnrc_client.dm | 2 +- .../file_system/programs/powermonitor.dm | 2 +- .../file_system/programs/robocontrol.dm | 2 +- .../file_system/programs/sm_monitor.dm | 2 +- .../modular_computers/laptop_vendor.dm | 2 +- code/modules/plumbing/plumbers/acclimator.dm | 2 +- code/modules/plumbing/plumbers/filter.dm | 2 +- code/modules/plumbing/plumbers/pill_press.dm | 2 +- .../plumbing/plumbers/reaction_chamber.dm | 2 +- code/modules/plumbing/plumbers/splitters.dm | 2 +- code/modules/plumbing/plumbers/synthesizer.dm | 2 +- code/modules/power/apc.dm | 2 +- code/modules/power/gravitygenerator.dm | 2 +- code/modules/power/monitor.dm | 4 +- code/modules/power/port_gen.dm | 2 +- .../particle_accelerator/particle_control.dm | 2 +- code/modules/power/smes.dm | 2 +- code/modules/power/solar.dm | 2 +- code/modules/power/turbine.dm | 4 +- .../chemistry/machinery/chem_dispenser.dm | 2 +- .../chemistry/machinery/chem_heater.dm | 2 +- .../chemistry/machinery/chem_master.dm | 2 +- .../chemistry/machinery/chem_synthesizer.dm | 2 +- .../reagents/chemistry/machinery/pandemic.dm | 2 +- .../chemistry/machinery/smoke_machine.dm | 2 +- code/modules/recycling/disposal/bin.dm | 2 +- code/modules/research/bepis.dm | 2 +- .../nanites/nanite_chamber_computer.dm | 2 +- .../nanites/nanite_cloud_controller.dm | 2 +- .../research/nanites/nanite_program_hub.dm | 2 +- .../research/nanites/nanite_programmer.dm | 2 +- .../modules/research/nanites/nanite_remote.dm | 2 +- .../ruins/spaceruin_code/TheDerelict.dm | 2 +- .../security_levels/keycard_authentication.dm | 2 +- code/modules/shuttle/emergency.dm | 2 +- code/modules/station_goals/bsa.dm | 2 +- code/modules/station_goals/dna_vault.dm | 2 +- code/modules/station_goals/shield.dm | 2 +- code/modules/vending/_vending.dm | 2 +- 144 files changed, 2158 insertions(+), 2158 deletions(-) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 4ee6f9b539c..94ce94393e8 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -756,7 +756,7 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "shuttle_manipulator", name, 800, 600, master_ui, state) + ui = new(user, src, ui_key, "ShuttleManipulator", name, 800, 600, master_ui, state) ui.open() diff --git a/code/datums/achievements/_achievement_data.dm b/code/datums/achievements/_achievement_data.dm index fb943a484d7..9ff2c4a3c1c 100644 --- a/code/datums/achievements/_achievement_data.dm +++ b/code/datums/achievements/_achievement_data.dm @@ -97,7 +97,7 @@ if(!ui) var/datum/asset/spritesheet/simple/assets = get_asset_datum(/datum/asset/spritesheet/simple/achievements) assets.send(user) - ui = new(user, src, ui_key, "achievements", "Achievements Menu", 800, 1000, master_ui, state) + ui = new(user, src, ui_key, "Achievements", "Achievements Menu", 800, 1000, master_ui, state) ui.open() /datum/achievement_data/ui_data(mob/user) diff --git a/code/datums/components/crafting/crafting.dm b/code/datums/components/crafting/crafting.dm index 77e8e63fbfd..068769e36db 100644 --- a/code/datums/components/crafting/crafting.dm +++ b/code/datums/components/crafting/crafting.dm @@ -326,7 +326,7 @@ cur_subcategory = subcats[1] else cur_subcategory = CAT_NONE - ui = new(user, src, ui_key, "personal_crafting", "Crafting Menu", 700, 800, master_ui, state) + ui = new(user, src, ui_key, "PersonalCrafting", "Crafting Menu", 700, 800, master_ui, state) ui.open() /datum/component/personal_crafting/ui_data(mob/user) diff --git a/code/datums/components/gps.dm b/code/datums/components/gps.dm index d3f1a91b117..200ec2b956b 100644 --- a/code/datums/components/gps.dm +++ b/code/datums/components/gps.dm @@ -89,7 +89,7 @@ GLOBAL_LIST_EMPTY(GPS_list) // Variable window height, depending on how many GPS units there are // to show, clamped to relatively safe range. var/gps_window_height = clamp(325 + GLOB.GPS_list.len * 14, 325, 700) - ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height + ui = new(user, src, ui_key, "Gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height ui.open() ui.set_autoupdate(state = updating) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index a6d28a97b73..3dd4ebfaa62 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -125,7 +125,7 @@ active = TRUE ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "uplink", name, 620, 580, master_ui, state) + ui = new(user, src, ui_key, "Uplink", name, 620, 580, master_ui, state) ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. ui.set_style("syndicate") ui.open() diff --git a/code/datums/spawners_menu.dm b/code/datums/spawners_menu.dm index 9107e45e051..a6f49e9c323 100644 --- a/code/datums/spawners_menu.dm +++ b/code/datums/spawners_menu.dm @@ -9,7 +9,7 @@ /datum/spawners_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "spawners_menu", "Spawners Menu", 700, 600, master_ui, state) + ui = new(user, src, ui_key, "SpawnersMenu", "Spawners Menu", 700, 600, master_ui, state) ui.open() /datum/spawners_menu/ui_data(mob/user) diff --git a/code/datums/wires/_wires.dm b/code/datums/wires/_wires.dm index 55263a326a1..46d1a7261f6 100644 --- a/code/datums/wires/_wires.dm +++ b/code/datums/wires/_wires.dm @@ -219,7 +219,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if (!ui) - ui = new(user, src, ui_key, "wires", "[holder.name] Wires", 350, 150 + wires.len * 30, master_ui, state) + ui = new(user, src, ui_key, "Wires", "[holder.name] Wires", 350, 150 + wires.len * 30, master_ui, state) ui.open() /datum/wires/ui_data(mob/user) diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 625708dd091..7164b7676c3 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -144,7 +144,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "sleeper", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Sleeper", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/sleeper/AltClick(mob/user) diff --git a/code/game/machinery/announcement_system.dm b/code/game/machinery/announcement_system.dm index a1ba8f7f94d..054e75b348f 100644 --- a/code/game/machinery/announcement_system.dm +++ b/code/game/machinery/announcement_system.dm @@ -99,7 +99,7 @@ GLOBAL_LIST_EMPTY(announcement_systems) . = ..() ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "announcement_system", "Automated Announcement System", 500, 225, master_ui, state) + ui = new(user, src, ui_key, "AutomatedAnnouncement", "Automated Announcement System", 500, 225, master_ui, state) ui.open() /obj/machinery/announcement_system/ui_data() diff --git a/code/game/machinery/bank_machine.dm b/code/game/machinery/bank_machine.dm index c75ed084a09..1f3c57abcf0 100644 --- a/code/game/machinery/bank_machine.dm +++ b/code/game/machinery/bank_machine.dm @@ -65,7 +65,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "bank_machine", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "BankMachine", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/bank_machine/ui_data(mob/user) diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm index fdb3751872c..7715c5b5e0e 100644 --- a/code/game/machinery/computer/Operating.dm +++ b/code/game/machinery/computer/Operating.dm @@ -66,7 +66,7 @@ /obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "operating_computer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "OperatingComputer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/operating/ui_data(mob/user) diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm index 6ffef5fb5db..a918a6bc88f 100644 --- a/code/game/machinery/computer/aifixer.dm +++ b/code/game/machinery/computer/aifixer.dm @@ -26,7 +26,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ai_restorer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AiRestorer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/aifixer/ui_data(mob/user) diff --git a/code/game/machinery/computer/atmos_alert.dm b/code/game/machinery/computer/atmos_alert.dm index 5c61a0dca9d..cd88eaa10fa 100644 --- a/code/game/machinery/computer/atmos_alert.dm +++ b/code/game/machinery/computer/atmos_alert.dm @@ -25,7 +25,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_alert", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosAlertConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/atmos_alert/ui_data(mob/user) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index 7c4222a07ea..06ea408add3 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosControlConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/atmos_control/ui_data(mob/user) @@ -280,7 +280,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosControlConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/atmos_control/tank/ui_data(mob/user) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index ffcf84eae21..3a877dbdefd 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -79,7 +79,7 @@ user.client.register_map_obj(cam_plane_master) user.client.register_map_obj(cam_background) // Open UI - ui = new(user, src, ui_key, "camera_console", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "CameraConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/security/ui_data() diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 44a33a6f94c..39740b5cd89 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -81,7 +81,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if (!ui) - ui = new(user, src, ui_key, "crew", "crew monitor", 800, 600 , master_ui, state) + ui = new(user, src, ui_key, "CrewConsole", "crew monitor", 800, 600 , master_ui, state) ui.open() /datum/crewmonitor/proc/show(mob/M, source) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index e1b071b9b8c..97f167af086 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -1,2009 +1,2009 @@ -/// Base timeout for creating mutation activators and other injectors -#define INJECTOR_TIMEOUT 100 -/// Maximum number of genetic makeup storage slots in DNA Console -#define NUMBER_OF_BUFFERS 3 -/// Timeout for DNA Scramble in DNA Consoles -#define SCRAMBLE_TIMEOUT 600 -/// Timeout for using the Joker feature to solve a gene in DNA Console -#define JOKER_TIMEOUT 12000 -/// How much time DNA Scanner upgrade tiers remove from JOKER_TIMEOUT -#define JOKER_UPGRADE 3000 - -/// Maximum value for radiaton strength when pulsing enzymes -#define RADIATION_STRENGTH_MAX 15 -/// Larger multipliers will affect the range of values when pulsing enzymes -#define RADIATION_STRENGTH_MULTIPLIER 1 - -/// Maximum value for the radiation pulse duration when pulsing enzymes -#define RADIATION_DURATION_MAX 30 -/// Large values reduce pulse accuracy and may pulse other enzymes than selected -#define RADIATION_ACCURACY_MULTIPLIER 3 - -/// Special status indicating a scanner occupant is transforming eg. from monkey to human -#define STATUS_TRANSFORMING 4 - -/// Multiplier for how much radiation received from DNA Console functionality -#define RADIATION_IRRADIATION_MULTIPLIER 1 - -/// Flag for the mutation ref search system. Search will include scanner occupant -#define SEARCH_OCCUPANT 1 -/// Flag for the mutation ref search system. Search will include console storage -#define SEARCH_STORED 2 -/// Flag for the mutation ref search system. Search will include diskette storage -#define SEARCH_DISKETTE 4 -/// Flag for the mutation ref search system. Search will include advanced injector mutations -#define SEARCH_ADV_INJ 8 - -/obj/machinery/computer/scan_consolenew - name = "DNA Console" - desc = "Scan DNA." - icon_screen = "dna" - icon_keyboard = "med_key" - density = TRUE - circuit = /obj/item/circuitboard/computer/scan_consolenew - - use_power = IDLE_POWER_USE - idle_power_usage = 10 - active_power_usage = 400 - light_color = LIGHT_COLOR_BLUE - - /// Link to the techweb's stored research. Used to retrieve stored mutations - var/datum/techweb/stored_research - /// Maximum number of mutations that DNA Consoles are able to store - var/max_storage = 6 - /// Duration for enzyme radiation pulses - var/radduration = 2 - /// Strength for enzyme radiation pulses - var/radstrength = 1 - /// Maximum number of chromosomes that DNA Consoles are able to store. - var/max_chromosomes = 6 - /// Maximum number of enzymes we can store - var/list/genetic_makeup_buffer[NUMBER_OF_BUFFERS] - /// List of all mutations stored on the DNA Console - var/list/stored_mutations = list() - /// List of all chromosomes stored in the DNA Console - var/list/stored_chromosomes = list() - /// Assoc list of all advanced injectors. Keys are injector names. Values are lists of mutations. - var/list/list/injector_selection = list() - /// Maximum number of advanced injectors that DNA Consoles store - var/max_injector_selections = 2 - /// Maximum number of mutation that an advanced injector can store - var/max_injector_mutations = 10 - /// Maximum total instability of all combined mutations allowed on an advanced injector - var/max_injector_instability = 50 - - /// World time when injectors are ready to be printed - var/injectorready = 0 - /// World time when JOKER algorithm can be used in DNA Consoles - var/jokerready = 0 - /// World time when Scramble can be used in DNA Consoles - var/scrambleready = 0 - - /// Currently stored genetic data diskette - var/obj/item/disk/data/diskette = null - - /// Current delayed action, used for delayed enzyme transfer on scanner door close - var/list/delayed_action = null - - /// Index of the enzyme being modified during delayed enzyme pulse operations - var/rad_pulse_index = 0 - /// World time when the enzyme pulse should complete - var/rad_pulse_timer = 0 - - /// Used for setting tgui data - Whether the connected DNA Scanner is usable - var/can_use_scanner = FALSE - /// Used for setting tgui data - Whether the current DNA Scanner occupant is viable for genetic modification - var/is_viable_occupant = FALSE - /// Used for setting tgui data - Whether Scramble DNA is ready - var/is_scramble_ready = FALSE - /// Used for setting tgui data - Whether JOKER algorithm is ready - var/is_joker_ready = FALSE - /// Used for setting tgui data - Whether injectors are ready to be printed - var/is_injector_ready = FALSE - /// Used for setting tgui data - Wheher an enzyme pulse operation is ongoing - var/is_pulsing_rads = FALSE - /// Used for setting tgui data - Time until scramble is ready - var/time_to_scramble = 0 - /// Used for setting tgui data - Time until joker is ready - var/time_to_joker = 0 - /// Used for setting tgui data - Time until injectors are ready - var/time_to_injector = 0 - /// Used for setting tgui data - Time until the enzyme pulse is complete - var/time_to_pulse = 0 - - /// Currently connected DNA Scanner - var/obj/machinery/dna_scannernew/connected_scanner = null - /// Current DNA Scanner occupant - var/mob/living/carbon/scanner_occupant = null - - /// Used for setting tgui data - List of occupant mutations - var/list/tgui_occupant_mutations = list() - /// Used for setting tgui data - List of DNA Console stored mutations - var/list/tgui_console_mutations = list() - /// Used for setting tgui data - List of diskette stored mutations - var/list/tgui_diskette_mutations = list() - /// Used for setting tgui data - List of DNA Console chromosomes - var/list/tgui_console_chromosomes = list() - /// Used for setting tgui data - List of occupant mutations - var/list/tgui_genetic_makeup = list() - /// Used for setting tgui data - List of occupant mutations - var/list/tgui_advinjector_mutations = list() - - - /// State of tgui view, i.e. which tab is currently active, or which genome we're currently looking at. - var/list/list/tgui_view_state = list() - -/obj/machinery/computer/scan_consolenew/process() - . = ..() - - // This is for pulsing the UI element with radiation as part of genetic makeup - // If rad_pulse_index > 0 then it means we're attempting a rad pulse - if((rad_pulse_index > 0) && (rad_pulse_timer <= world.time)) - rad_pulse() - return - -/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params) - // Store chromosomes in the console if there's room - if (istype(I, /obj/item/chromosome)) - if(LAZYLEN(stored_chromosomes) < max_chromosomes) - I.forceMove(src) - stored_chromosomes += I - to_chat(user, "You insert [I].") - else - to_chat(user, "You cannot store any more chromosomes!") - return - - // Insert data disk if console disk slot is empty - // Swap data disk if there is one already a disk in the console - if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES - if (!user.transferItemToLoc(I,src)) - return - if(diskette) - diskette.forceMove(drop_location()) - diskette = null - diskette = I - to_chat(user, "You insert [I].") - return - - // Recycle non-activator used injectors - // Turn activator used injectors (aka research injectors) to chromosomes - if(istype(I, /obj/item/dnainjector/activator)) - var/obj/item/dnainjector/activator/A = I - if(A.used) - to_chat(user,"Recycled [I].") - if(A.research) - if(prob(60)) - var/c_typepath = generate_chromosome() - var/obj/item/chromosome/CM = new c_typepath (drop_location()) - if(LAZYLEN(stored_chromosomes) < max_chromosomes) - CM.forceMove(src) - stored_chromosomes += CM - to_chat(user,"[capitalize(CM.name)] added to storage.") - else - to_chat(user, "You cannot store any more chromosomes!") - to_chat(user, "[capitalize(CM.name)] added on top of the console.") - else - to_chat(user, "There was not enough genetic data to extract a viable chromosome.") - qdel(I) - return - - return ..() - -/obj/machinery/computer/scan_consolenew/Initialize() - . = ..() - - // Connect with a nearby DNA Scanner on init - connect_to_scanner() - - // Set appropriate ready timers and limits for machines functions - injectorready = world.time + INJECTOR_TIMEOUT - scrambleready = world.time + SCRAMBLE_TIMEOUT - jokerready = world.time + JOKER_TIMEOUT - - // Set the default tgui state - set_default_state() - - // Link machine with research techweb. Used for discovering and accessing - // already discovered mutations - stored_research = SSresearch.science_tech - -/obj/machinery/computer/scan_consolenew/examine(mob/user) - . = ..() - -/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) - . = ..() - - // Most of ui_interact is spent setting variables for passing to the tgui - // interface. - // We can also do some general state processing here too as it's a good - // indication that a player is using the console. - - var/scanner_op = scanner_operational() - var/can_modify_occ = can_modify_occupant() - - // Check for connected AND operational scanner. - if(scanner_op) - can_use_scanner = TRUE - else - can_use_scanner = FALSE - connected_scanner = null - is_viable_occupant = FALSE - - // Check for a viable occupant in the scanner. - if(can_modify_occ) - is_viable_occupant = TRUE - else - is_viable_occupant = FALSE - - - // Populates various buffers for passing to tgui - build_mutation_list(can_modify_occ) - build_genetic_makeup_list() - - // Populate variables for passing to tgui interface - is_scramble_ready = (scrambleready < world.time) - time_to_scramble = round((scrambleready - world.time)/10) - - is_joker_ready = (jokerready < world.time) - time_to_joker = round((jokerready - world.time)/10) - - is_injector_ready = (injectorready < world.time) - time_to_injector = round((injectorready - world.time)/10) - - is_pulsing_rads = ((rad_pulse_index > 0) && (rad_pulse_timer > world.time)) - time_to_pulse = round((rad_pulse_timer - world.time)/10) - - // Attempt to update tgui ui, open and update if needed. - ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) - - if(!ui) - ui = new(user, src, ui_key, "scan_consolenew", name, 539, 710, master_ui, state) - ui.open() - -/obj/machinery/computer/scan_consolenew/ui_data(mob/user) - var/list/data = list() - - data["view"] = tgui_view_state - data["storage"] = list() - - // This block of code generates the huge data structure passed to the tgui - // interface for displaying all the various bits of console/scanner data - // Should all be very self-explanatory - data["isScannerConnected"] = can_use_scanner - if(can_use_scanner) - data["scannerOpen"] = connected_scanner.state_open - data["scannerLocked"] = connected_scanner.locked - data["radStrength"] = radstrength - data["radDuration"] = radduration - data["stdDevStr"] = radstrength * RADIATION_STRENGTH_MULTIPLIER - switch(RADIATION_ACCURACY_MULTIPLIER / (radduration + (connected_scanner.precision_coeff ** 2))) //hardcoded values from a z-table for a normal distribution - if(0 to 0.25) - data["stdDevAcc"] = ">95 %" - if(0.25 to 0.5) - data["stdDevAcc"] = "68-95 %" - if(0.5 to 0.75) - data["stdDevAcc"] = "55-68 %" - else - data["stdDevAcc"] = "<38 %" - - data["isViableSubject"] = is_viable_occupant - if(is_viable_occupant) - data["subjectName"] = scanner_occupant.name - if(scanner_occupant.transformation_timer) - data["subjectStatus"] = STATUS_TRANSFORMING - else - data["subjectStatus"] = scanner_occupant.stat - data["subjectHealth"] = scanner_occupant.health - data["subjectRads"] = scanner_occupant.radiation/(RAD_MOB_SAFE/100) - data["subjectEnzymes"] = scanner_occupant.dna.unique_enzymes - data["isMonkey"] = ismonkey(scanner_occupant) - data["subjectUNI"] = scanner_occupant.dna.uni_identity - data["storage"]["occupant"] = tgui_occupant_mutations - //data["subjectMutations"] = tgui_occupant_mutations - else - data["subjectName"] = null - data["subjectStatus"] = null - data["subjectHealth"] = null - data["subjectRads"] = null - data["subjectEnzymes"] = null - //data["subjectMutations"] = null - data["storage"]["occupant"] = null - - data["hasDelayedAction"] = (delayed_action != null) - data["isScrambleReady"] = is_scramble_ready - data["isJokerReady"] = is_joker_ready - data["isInjectorReady"] = is_injector_ready - data["scrambleSeconds"] = time_to_scramble - data["jokerSeconds"] = time_to_joker - data["injectorSeconds"] = time_to_injector - data["isPulsingRads"] = is_pulsing_rads - data["radPulseSeconds"] = time_to_pulse - - if(diskette != null) - data["hasDisk"] = TRUE - data["diskCapacity"] = diskette.max_mutations - LAZYLEN(diskette.mutations) - data["diskReadOnly"] = diskette.read_only - //data["diskMutations"] = tgui_diskette_mutations - data["storage"]["disk"] = tgui_diskette_mutations - data["diskHasMakeup"] = (LAZYLEN(diskette.genetic_makeup_buffer) > 0) - data["diskMakeupBuffer"] = diskette.genetic_makeup_buffer.Copy() - else - data["hasDisk"] = FALSE - data["diskCapacity"] = 0 - data["diskReadOnly"] = TRUE - //data["diskMutations"] = null - data["storage"]["disk"] = null - data["diskHasMakeup"] = FALSE - data["diskMakeupBuffer"] = null - - data["mutationCapacity"] = max_storage - LAZYLEN(stored_mutations) - //data["mutationStorage"] = tgui_console_mutations - data["storage"]["console"] = tgui_console_mutations - data["chromoCapacity"] = max_chromosomes - LAZYLEN(stored_chromosomes) - data["chromoStorage"] = tgui_console_chromosomes - data["makeupCapacity"] = NUMBER_OF_BUFFERS - data["makeupStorage"] = tgui_genetic_makeup - - //data["advInjectors"] = tgui_advinjector_mutations - data["storage"]["injector"] = tgui_advinjector_mutations - data["maxAdvInjectors"] = max_injector_selections - - return data - -/obj/machinery/computer/scan_consolenew/ui_act(action, var/list/params) - if(..()) - return TRUE - - . = TRUE - - add_fingerprint(usr) - usr.set_machine(src) - - switch(action) - // Connect this DNA Console to a nearby DNA Scanner - // Usually only activate as an option if there is no connected scanner - if("connect_scanner") - connect_to_scanner() - return - - // Toggle the door open/closed status on attached DNA Scanner - if("toggle_door") - // GUARD CHECK - Scanner still connected and operational? - if(!scanner_operational()) - return - - connected_scanner.toggle_open(usr) - return - - // Toggle the door bolts on the attached DNA Scanner - if("toggle_lock") - // GUARD CHECK - Scanner still connected and operational? - if(!scanner_operational()) - return - - connected_scanner.locked = !connected_scanner.locked - return - - // Scramble scanner occupant's DNA - if("scramble_dna") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - // GUARD CHECK - Is scramble DNA actually ready? - if(!can_modify_occupant() || !(scrambleready < world.time)) - return - - scanner_occupant.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA)) - scanner_occupant.dna.generate_dna_blocks() - scrambleready = world.time + SCRAMBLE_TIMEOUT - to_chat(usr,"DNA scrambled.") - scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER*50/(connected_scanner.damage_coeff ** 2) - return - - // Check whether a specific mutation is eligible for discovery within the - // scanner occupant - // This is additionally done when a mutation's tab is selected in the tgui - // interface. This is because some mutations, such as Monkified on monkeys, - // are infact completed by default but not yet discovered. Likewise, all - // mutations can have their sequence completed while Monkified is still an - // active mutation and thus won't immediately be discovered but could be - // discovered when Monkified is removed - // ---------------------------------------------------------------------- // - // params["alias"] - Alias of a mutation. The alias is the "hidden" name of - // the mutation, for example "Mutation 5" or "Mutation 33" - if("check_discovery") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - // GUARD CHECK - Have we somehow cheekily swapped occupants? This is - // unexpected. - if(!(scanner_occupant == connected_scanner.occupant)) - return - - check_discovery(params["alias"]) - return - - // Check all mutations of the occupant and check if any are discovered. - // This is called when the Genetic Sequencer is selected. It'll do things - // like immediately discover Monkified without needing to click through - // the mutation tabs and handle cases where mutations are solved but not - // discovered due to the Monkified mutation being active then removed. - if("all_check_discovery") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - // GUARD CHECK - Have we somehow cheekily swapped occupants? This is - // unexpected. - if(!(scanner_occupant == connected_scanner.occupant)) - return - - // Go over all standard mutations and check if they've been discovered. - for(var/mutation_type in scanner_occupant.dna.mutation_index) - var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(mutation_type) - check_discovery(HM.alias) - - return - - // Set a gene in a mutation's genetic sequence. Will also check for mutations - // discovery as part of the process. - // ---------------------------------------------------------------------- // - // params["alias"] - Alias of a mutation. The alias is the "hidden" name of - // the mutation, for example "Mutation 5" or "Mutation 33" - // params["gene"] - The letter of the new gene - // params["pos"] - The BYOND index of the letter in the gene sequence to be - // changed. Expects a text string from TGUI and will convert to a number - if("pulse_gene") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - // GUARD CHECK - Have we somehow cheekily swapped occupants? This is - // unexpected. - if(!(scanner_occupant == connected_scanner.occupant)) - return - - // GUARD CHECK - Is the occupant currently undergoing some form of - // transformation? If so, we don't want to be pulsing genes. - if(scanner_occupant.transformation_timer) - to_chat(usr,"Gene pulse failed: The scanner occupant undergoing a transformation.") - return - - // Resolve mutation's BYOND path from the alias - var/alias = params["alias"] - var/path = GET_MUTATION_TYPE_FROM_ALIAS(alias) - - // Make sure the occupant still has this mutation - if(!(path in scanner_occupant.dna.mutation_index)) - return - - // Resolve BYOND path to genome sequence of scanner occupant - var/sequence = GET_GENE_STRING(path, scanner_occupant.dna) - - var/newgene = params["gene"] - var/genepos = text2num(params["pos"]) - - // If the new gene is J, this means we're dealing with a JOKER - // GUARD CHECK - Is JOKER actually ready? - if((newgene == "J") && (jokerready < world.time)) - var/truegenes = GET_SEQUENCE(path) - newgene = truegenes[genepos] - jokerready = world.time + JOKER_TIMEOUT - (JOKER_UPGRADE * (connected_scanner.precision_coeff-1)) - - // If the gene is an X, we want to update the default genes with the new - // X to allow highlighting logic to work on the tgui interface. - if(newgene == "X") - var/defaultseq = scanner_occupant.dna.default_mutation_genes[path] - defaultseq = copytext_char(defaultseq, 1, genepos) + newgene + copytext_char(defaultseq, genepos + 1) - scanner_occupant.dna.default_mutation_genes[path] = defaultseq - - // Copy genome to scanner occupant and do some basic mutation checks as - // we've increased the occupant rads - sequence = copytext_char(sequence, 1, genepos) + newgene + copytext_char(sequence, genepos + 1) - scanner_occupant.dna.mutation_index[path] = sequence - scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER/connected_scanner.damage_coeff - scanner_occupant.domutcheck() - - // GUARD CHECK - Modifying genetics can lead to edge cases where the - // scanner occupant is qdel'd and replaced with a different entity. - // Examples of this include adding/removing the Monkified mutation which - // qdels the previous entity and creates a brand new one in its place. - // We should redo all of our occupant modification checks again, although - // it is less than ideal. - if(!can_modify_occupant()) - return - - // Check if we cracked a mutation - check_discovery(alias) - - return - - // Apply a chromosome to a specific mutation. - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to apply the chromo to - // params["chromo"] - Name of the chromosome to apply to the mutation - if("apply_chromo") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - // GUARD CHECK - Have we somehow cheekily swapped occupants? This is - // unexpected. - if(!(scanner_occupant == connected_scanner.occupant)) - return - - var/bref = params["mutref"] - - // GUARD CHECK - Only search occupant for this specific ref, since your - // can only apply chromosomes to mutations occupants. - var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_OCCUPANT) - - // GUARD CHECK - This should not be possible. Unexpected result - if(!HM) - return - - // Look through our stored chromos and compare names to find a - // stored chromo we can apply. - for(var/obj/item/chromosome/CM in stored_chromosomes) - if(CM.can_apply(HM) && (CM.name == params["chromo"])) - stored_chromosomes -= CM - CM.apply(HM) - - return - - // Print any type of standard injector, limited right now to activators that - // activate a dormant mutation and mutators that forcibly create a new - // MUT_EXTRA mutation - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to create an injector of - // params["is_activator"] - Is this an "Activator" style injector, also - // referred to as a "Research" type. Expects a string with 0 or 1, which - // then gets converted to a number. - // params["source"] - The source the request came from. - // Expected results: - // "occupant" - From genetic sequencer - // "console" - From DNA Console storage - // "disk" - From inserted diskette - if("print_injector") - // Because printing mutators and activators share a bunch of code, - // it makes sense to keep them both together and set unique vars - // later in the code - - // As a side note, because mutations can contain unique metadata, - // this system uses BYOND Atom Refs to safely and accurately - // identify mutations from big ol' lists - - // GUARD CHECK - Is the injector actually ready? - if(world.time < injectorready) - return - - var/search_flags = 0 - - switch(params["source"]) - if("occupant") - // GUARD CHECK - Make sure we can modify the occupant before we - // attempt to search them for any given mutation refs. This could - // lead to no search flags being passed to get_mut_by_ref and this - // is intended functionality to prevent any cheese or abuse - if(can_modify_occupant()) - search_flags |= SEARCH_OCCUPANT - if("console") - search_flags |= SEARCH_STORED - if("disk") - search_flags |= SEARCH_DISKETTE - - var/bref = params["mutref"] - var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flags) - - // GUARD CHECK - This should not be possible. Unexpected result - if(!HM) - return - - // Create a new DNA Injector and add the appropriate mutations to it - var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc) - I.add_mutations += new HM.type(copymut = HM) - - var/is_activator = text2num(params["is_activator"]) - - // Activators are also called "research" injectors and are used to create - // chromosomes by recycling at the DNA Console - if(is_activator) - I.name = "[HM.name] activator" - I.research = TRUE - // If there's an operational connected scanner, we can use its upgrades - // to improve our injector's radiation generation - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff*4 - injectorready = world.time + INJECTOR_TIMEOUT * (1 - 0.1 * connected_scanner.precision_coeff) - else - injectorready = world.time + INJECTOR_TIMEOUT - else - I.name = "[HM.name] mutator" - I.doitanyway = TRUE - // If there's an operational connected scanner, we can use its upgrades - // to improve our injector's radiation generation - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - injectorready = world.time + INJECTOR_TIMEOUT * 5 * (1 - 0.1 * connected_scanner.precision_coeff) - else - injectorready = world.time + INJECTOR_TIMEOUT * 5 - - return - - // Save a mutation to the console's storage buffer. - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to store - // params["source"] - The source the request came from. - // Expected results: - // "occupant" - From genetic sequencer - // "disk" - From inserted diskette - if("save_console") - var/search_flags = 0 - - switch(params["source"]) - if("occupant") - // GUARD CHECK - Make sure we can modify the occupant before we - // attempt to search them for any given mutation refs. This could - // lead to no search flags being passed to get_mut_by_ref and this - // is intended functionality to prevent any cheese or abuse - if(can_modify_occupant()) - search_flags |= SEARCH_OCCUPANT - if("disk") - search_flags |= SEARCH_DISKETTE - - // GUARD CHECK - Is mutation storage full? - if(LAZYLEN(stored_mutations) >= max_storage) - to_chat(usr,"Mutation storage is full.") - return - - var/bref = params["mutref"] - var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flags) - - // GUARD CHECK - This should not be possible. Unexpected result - if(!HM) - return - - var/datum/mutation/human/A = new HM.type() - A.copy_mutation(HM) - stored_mutations += A - to_chat(usr,"Mutation successfully stored.") - return - - // Save a mutation to the diskette's storage buffer. - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to store - // params["source"] - The source the request came from - // Expected results: - // "occupant" - From genetic sequencer - // "console" - From DNA Console storage - if("save_disk") - // GUARD CHECK - This code shouldn't even be callable without a diskette - // inserted. Unexpected result - if(!diskette) - return - - // GUARD CHECK - Make sure the disk is not full - if(LAZYLEN(diskette.mutations) >= diskette.max_mutations) - to_chat(usr,"Disk storage is full.") - return - - // GUARD CHECK - Make sure the disk isn't set to read only, as we're - // attempting to write to it - if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") - return - - var/search_flags = 0 - - switch(params["source"]) - if("occupant") - // GUARD CHECK - Make sure we can modify the occupant before we - // attempt to search them for any given mutation refs. This could - // lead to no search flags being passed to get_mut_by_ref and this - // is intended functionality to prevent any cheese or abuse - if(can_modify_occupant()) - search_flags |= SEARCH_OCCUPANT - if("console") - search_flags |= SEARCH_STORED - - var/bref = params["mutref"] - var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flags) - - // GUARD CHECK - This should not be possible. Unexpected result - if(!HM) - return - - var/datum/mutation/human/A = new HM.type() - A.copy_mutation(HM) - diskette.mutations += A - to_chat(usr,"Mutation successfully stored to disk.") - return - - // Completely removes a MUT_EXTRA mutation or mutation with corrupt gene - // sequence from the scanner occupant - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to nullify - if("nullify") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - var/bref = params["mutref"] - var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_OCCUPANT) - - // GUARD CHECK - This should not be possible. Unexpected result - if(!HM) - return - - // GUARD CHECK - Nullify should only be used on scrambled or "extra" - // mutations. - if(!HM.scrambled && !(HM.class == MUT_EXTRA)) - return - - scanner_occupant.dna.remove_mutation(HM.type) - return - - // Deletes saved mutation from console buffer. - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to delete - if("delete_console_mut") - var/bref = params["mutref"] - var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_STORED) - - if(HM) - stored_mutations.Remove(HM) - qdel(HM) - - return - - // Deletes saved mutation from disk buffer. - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to delete - if("delete_disk_mut") - // GUARD CHECK - This code shouldn't even be callable without a diskette - // inserted. Unexpected result - if(!diskette) - return - - // GUARD CHECK - Make sure the disk isn't set to read only, as we're - // attempting to write to it (via deletion) - if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") - return - - var/bref = params["mutref"] - var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_DISKETTE) - - if(HM) - diskette.mutations.Remove(HM) - qdel(HM) - - return - - // Ejects a stored chromosome from the DNA Console - // ---------------------------------------------------------------------- // - // params["chromo"] - Text string of the chromosome name - if("eject_chromo") - var/chromname = params["chromo"] - - for(var/obj/item/chromosome/CM in stored_chromosomes) - if(chromname == CM.name) - CM.forceMove(drop_location()) - adjust_item_drop_location(CM) - stored_chromosomes -= CM - return - - return - - // Combines two mutations from the console to try and create a new mutation - // ---------------------------------------------------------------------- // - // params["firstref"] - ATOM Ref of first mutation for combination - // params["secondref"] - ATOM Ref of second mutation for combination - // mutation - if("combine_console") - // GUaRD CHECK - Make sure mutation storage isn't full. If it is, we won't - // be able to store the new combo mutation - if(LAZYLEN(stored_mutations) >= max_storage) - to_chat(usr,"Mutation storage is full.") - return - - // GUARD CHECK - We're running a research-type operation. If, for some - // reason, somehow the DNA Console has been disconnected from the research - // network - Or was never in it to begin with - don't proceed - if(!stored_research) - return - - var/first_bref = params["firstref"] - var/second_bref = params["secondref"] - - // GUARD CHECK - Find the source and destination mutations on the console - // and make sure they actually exist. - var/datum/mutation/human/source_mut = get_mut_by_ref(first_bref, SEARCH_STORED | SEARCH_DISKETTE) - if(!source_mut) - return - - var/datum/mutation/human/dest_mut = get_mut_by_ref(second_bref, SEARCH_STORED | SEARCH_DISKETTE) - if(!dest_mut) - return - - // Attempt to mix the two mutations to get a new type - var/result_path = get_mixed_mutation(source_mut.type, dest_mut.type) - - if(!result_path) - return - - // If we got a new type, add it to our storage - stored_mutations += new result_path() - to_chat(usr, "Success! New mutation has been added to console storage.") - - // If it's already discovered, end here. Otherwise, add it to the list of - // discovered mutations. - // We've already checked for stored_research earlier - if(result_path in stored_research.discovered_mutations) - return - - var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(result_path) - stored_research.discovered_mutations += result_path - say("Successfully mutated [HM.name].") - return - - // Combines two mutations from the disk to try and create a new mutation - // ---------------------------------------------------------------------- // - // params["firstref"] - ATOM Ref of first mutation for combination - // params["secondref"] - ATOM Ref of second mutation for combination - // mutation - if("combine_disk") - // GUARD CHECK - This code shouldn't even be callable without a diskette - // inserted. Unexpected result - if(!diskette) - return - - // GUARD CHECK - Make sure the disk is not full. - if(LAZYLEN(diskette.mutations) >= diskette.max_mutations) - to_chat(usr,"Disk storage is full.") - return - - // GUARD CHECK - Make sure the disk isn't set to read only, as we're - // attempting to write to it - if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") - return - - // GUARD CHECK - We're running a research-type operation. If, for some - // reason, somehow the DNA Console has been disconnected from the research - // network - Or was never in it to begin with - don't proceed - if(!stored_research) - return - - var/first_bref = params["firstref"] - var/second_bref = params["secondref"] - - // GUARD CHECK - Find the source and destination mutations on the console - // and make sure they actually exist. - var/datum/mutation/human/source_mut = get_mut_by_ref(first_bref, SEARCH_STORED | SEARCH_DISKETTE) - if(!source_mut) - return - - var/datum/mutation/human/dest_mut = get_mut_by_ref(second_bref, SEARCH_STORED | SEARCH_DISKETTE) - if(!dest_mut) - return - - // Attempt to mix the two mutations to get a new type - var/result_path = get_mixed_mutation(source_mut.type, dest_mut.type) - - if(!result_path) - return - - // If we got a new type, add it to our storage - diskette.mutations += new result_path() - to_chat(usr, "Success! New mutation has been added to the disk.") - - // If it's already discovered, end here. Otherwise, add it to the list of - // discovered mutations - // We've already checked for stored_research earlier - if(result_path in stored_research.discovered_mutations) - return - - var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(result_path) - stored_research.discovered_mutations += result_path - say("Successfully mutated [HM.name].") - return - - // Sets the Genetic Makeup pulse strength. - // ---------------------------------------------------------------------- // - // params["val"] - New strength value as text string, converted to number - // later on in code - if("set_pulse_strength") - var/value = round(text2num(params["val"])) - radstrength = WRAP(value, 1, RADIATION_STRENGTH_MAX+1) - return - - // Sets the Genetic Makeup pulse duration - // ---------------------------------------------------------------------- // - // params["val"] - New strength value as text string, converted to number - // later on in code - if("set_pulse_duration") - var/value = round(text2num(params["val"])) - radduration = WRAP(value, 1, RADIATION_DURATION_MAX+1) - return - - // Saves Genetic Makeup information to disk - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the console genetic makeup buffer to - // copy to disk - if("save_makeup_disk") - // GUARD CHECK - This code shouldn't even be callable without a diskette - // inserted. Unexpected result - if(!diskette) - return - - // GUARD CHECK - Make sure the disk isn't set to read only, as we're - // attempting to write to it - if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") - return - - // Convert the index to a number and clamp within the array range - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - - var/list/buffer_slot = genetic_makeup_buffer[buffer_index] - - // GUARD CHECK - This should not be possible to activate on a buffer slot - // that doesn't have any genetic data. Unexpected result - if(!istype(buffer_slot)) - return - - diskette.genetic_makeup_buffer = buffer_slot.Copy() - return - - // Loads Genetic Makeup from disk to a console buffer - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the console genetic makeup buffer to - // copy to. Expected as text string, converted to number later - if("load_makeup_disk") - // GUARD CHECK - This code shouldn't even be callable without a diskette - // inserted. Unexpected result - if(!diskette) - return - - // GUARD CHECK - This should not be possible to activate on a diskette - // that doesn't have any genetic data. Unexpected result - if(LAZYLEN(diskette.genetic_makeup_buffer) == 0) - return - - // Convert the index to a number and clamp within the array range, then - // copy the data from the disk to that buffer - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - genetic_makeup_buffer[buffer_index] = diskette.genetic_makeup_buffer.Copy() - return - - // Deletes genetic makeup buffer from the inserted diskette - if("del_makeup_disk") - // GUARD CHECK - This code shouldn't even be callable without a diskette - // inserted. Unexpected result - if(!diskette) - return - - // GUARD CHECK - Make sure the disk isn't set to read only, as we're - // attempting to write (via deletion) to it - if(diskette.read_only) - to_chat(usr,"Disk is set to read only mode.") - return - - diskette.genetic_makeup_buffer.Cut() - return - - // Saves the scanner occupant's genetic makeup to a given console buffer - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the console genetic makeup buffer to - // save the new genetic data to. Expected as text string, converted to - // number later - if("save_makeup_console") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - // Convert the index to a number and clamp within the array range, then - // copy the data from the disk to that buffer - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - - // Set the new information - genetic_makeup_buffer[buffer_index] = list( - "label"="Slot [buffer_index]:[scanner_occupant.real_name]", - "UI"=scanner_occupant.dna.uni_identity, - "UE"=scanner_occupant.dna.unique_enzymes, - "name"=scanner_occupant.real_name, - "blood_type"=scanner_occupant.dna.blood_type) - - return - - // Deleted genetic makeup data from a console buffer slot - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the console genetic makeup buffer to - // delete the genetic data from. Expected as text string, converted to - // number later - if("del_makeup_console") - // Convert the index to a number and clamp within the array range, then - // copy the data from the disk to that buffer - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = genetic_makeup_buffer[buffer_index] - - // GUARD CHECK - This shouldn't be possible to execute this on a null - // buffer. Unexpected resut - if(!istype(buffer_slot)) - return - - genetic_makeup_buffer[buffer_index] = null - return - - // Eject stored diskette from console - if("eject_disk") - // GUARD CHECK - This code shouldn't even be callable without a diskette - // inserted. Unexpected result - if(!diskette) - return - - diskette.forceMove(drop_location()) - diskette = null - return - - // Create a Genetic Makeup injector. These injectors are timed and thus are - // only temporary - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the console genetic makeup buffer to - // create the makeup injector from. Expected as text string, converted to - // number later - // params["type"] - Type of injector to create - // Expected results: - // "ue" - Unique Enzyme, changes name and blood type - // "ui" - Unique Identity, changes looks - // "mixed" - Combination of both ue and ui - if("makeup_injector") - // Convert the index to a number and clamp within the array range, then - // copy the data from the disk to that buffer - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = genetic_makeup_buffer[buffer_index] - - // GUARD CHECK - This shouldn't be possible to execute this on a null - // buffer. Unexpected resut - if(!istype(buffer_slot)) - return - - var/type = params["type"] - var/obj/item/dnainjector/timed/I - - switch(type) - if("ui") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["UI"]) - to_chat(usr,"Genetic data corrupted, unable to create injector.") - return - - I = new /obj/item/dnainjector/timed(loc) - I.fields = list("UI"=buffer_slot["UI"]) - - // If there is a connected scanner, we can use its upgrades to reduce - // the radiation generated by this injector - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - if("ue") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to create injector.") - return - - I = new /obj/item/dnainjector/timed(loc) - I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) - - // If there is a connected scanner, we can use its upgrades to reduce - // the radiation generated by this injector - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - if("mixed") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to create injector.") - return - - I = new /obj/item/dnainjector/timed(loc) - I.fields = list("UI"=buffer_slot["UI"],"name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) - - // If there is a connected scanner, we can use its upgrades to reduce - // the radiation generated by this injector - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - - // If we successfully created an injector, don't forget to set the new - // ready timer. - if(I) - injectorready = world.time + INJECTOR_TIMEOUT - - return - - // Applies a genetic makeup buffer to the scanner occupant - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the console genetic makeup buffer to - // apply to the scanner occupant. Expected as text string, converted to - // number later - // params["type"] - Type of genetic makeup copy to implement - // Expected results: - // "ue" - Unique Enzyme, changes name and blood type - // "ui" - Unique Identity, changes looks - // "mixed" - Combination of both ue and ui - if("makeup_apply") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - // Convert the index to a number and clamp within the array range, then - // copy the data from the disk to that buffer - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = genetic_makeup_buffer[buffer_index] - - // GUARD CHECK - This shouldn't be possible to execute this on a null - // buffer. Unexpected resut - if(!istype(buffer_slot)) - return - - var/type = params["type"] - - apply_genetic_makeup(type, buffer_slot) - return - - // Applies a genetic makeup buffer to the next scanner occupant. This sets - // some code that will run when the connected DNA Scanner door is next - // closed - // This allows people to self-modify their genetic makeup, as tgui - // interfaces can not be accessed while inside the DNA Scanner and genetic - // makeup injectors are only temporary - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the console genetic makeup buffer to - // apply to the scanner occupant. Expected as text string, converted to - // number later - // params["type"] - Type of genetic makeup copy to implement - // Expected results: - // "ue" - Unique Enzyme, changes name and blood type - // "ui" - Unique Identity, changes looks - // "mixed" - Combination of both ue and ui - if("makeup_delay") - // Convert the index to a number and clamp within the array range, then - // copy the data from the disk to that buffer - var/buffer_index = text2num(params["index"]) - buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) - var/list/buffer_slot = genetic_makeup_buffer[buffer_index] - - // GUARD CHECK - This shouldn't be possible to execute this on a null - // buffer. Unexpected resut - if(!istype(buffer_slot)) - return - - var/type = params["type"] - - // Set the delayed action. The next time the scanner door is closed, - // unless this is cancelled in the UI, the action will happen - delayed_action = list("type" = type, "buffer_slot" = buffer_slot) - return - - // Attempts to modify the indexed element of the Unique Identity string - // This is a time delayed action that is handled in process() - // ---------------------------------------------------------------------- // - // params["index"] - The BYOND index of the Unique Identity string to - // attempt to modify - if("makeup_pulse") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - if(!can_modify_occupant()) - return - - // Set the appropriate timer and index to pulse. This is then managed - // later on in process() - var/len = length_char(scanner_occupant.dna.uni_identity) - rad_pulse_timer = world.time + (radduration*10) - rad_pulse_index = WRAP(text2num(params["index"]), 1, len+1) - begin_processing() - return - - // Cancels the delayed action - In this context it is not the radiation - // pulse from "makeup_pulse", which can not be cancelled. It is instead - // the delayed genetic transfer from "makeup_delay" - if("cancel_delay") - delayed_action = null - return - - // Creates a new advanced injector storage buffer in the console - // ---------------------------------------------------------------------- // - // params["name"] - The name to apply to the new injector - if("new_adv_inj") - // GUARD CHECK - Make sure we can make a new injector. This code should - // not be called if we're already maxed out and this is an Unexpected - // result - if(!(LAZYLEN(injector_selection) < max_injector_selections)) - return - - // GUARD CHECK - Sanitise and trim the proposed name. This prevents HTML - // injection and equivalent as tgui input is not stripped - var/inj_name = params["name"] - inj_name = trim(sanitize(inj_name)) - - // GUARD CHECK - If the name is null or blank, or the name is already in - // the list of advanced injectors, we want to reject it as we can't have - // duplicate named advanced injectors - if(!inj_name || (inj_name in injector_selection)) - return - - injector_selection[inj_name] = list() - return - - // Deleted an advanced injector storage buffer from the console - // ---------------------------------------------------------------------- // - // params["name"] - The name of the injector to delete - if("del_adv_inj") - var/inj_name = params["name"] - - // GUARD CHECK - If the name is null or blank, reject. - // GUARD CHECK - If the name isn't in the list of advanced injectors, we - // want to reject this as it shouldn't be possible ever do this. - // Unexpected result - if(!inj_name || !(inj_name in injector_selection)) - return - - injector_selection.Remove(inj_name) - return - - // Creates an injector from an advanced injector buffer - // ---------------------------------------------------------------------- // - // params["name"] - The name of the injector to print - if("print_adv_inj") - // As a side note, because mutations can contain unique metadata, - // this system uses BYOND Atom Refs to safely and accurately - // identify mutations from big ol' lists. - - // GUARD CHECK - Is the injector actually ready? - if(world.time < injectorready) - return - - var/inj_name = params["name"] - - // GUARD CHECK - If the name is null or blank, reject. - // GUARD CHECK - If the name isn't in the list of advanced injectors, we - // want to reject this as it shouldn't be possible ever do this. - // Unexpected result - if(!inj_name || !(inj_name in injector_selection)) - return - - var/list/injector = injector_selection[inj_name] - var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc) - - // Run through each mutation in our Advanced Injector and add them to a - // new injector - for(var/A in injector) - var/datum/mutation/human/HM = A - I.add_mutations += new HM.type(copymut=HM) - - // Force apply any mutations, this is functionality similar to mutators - I.doitanyway = TRUE - I.name = "Advanced [inj_name] injector" - - // If there's an operational connected scanner, we can use its upgrades - // to improve our injector's radiation generation - if(scanner_operational()) - I.damage_coeff = connected_scanner.damage_coeff - injectorready = world.time + INJECTOR_TIMEOUT * 8 * (1 - 0.1 * connected_scanner.precision_coeff) - else - injectorready = world.time + INJECTOR_TIMEOUT * 8 - - return - - // Adds a mutation to an advanced injector - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to add to the injector - // params["advinj"] - Name of the advanced injector to add the mutation to - if("add_advinj_mut") - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - // This is needed because this operation can only be completed from the - // genetic sequencer. - if(!can_modify_occupant()) - return - - var/adv_inj = params["advinj"] - - // GUARD CHECK - Make sure our advanced injector actually exists. This - // should not be possible. Unexpected result - if(!(adv_inj in injector_selection)) - return - - // GUARD CHECK - Make sure we limit the number of mutations appropriately - if(LAZYLEN(injector_selection[adv_inj]) >= max_injector_mutations) - to_chat(usr,"Advanced injector mutation storage is full.") - return - - var/mut_source = params["source"] - var/search_flag = 0 - - switch(mut_source) - if("disk") - search_flag = SEARCH_DISKETTE - if("occupant") - search_flag = SEARCH_OCCUPANT - if("console") - search_flag = SEARCH_STORED - - if(!search_flag) - return - - var/bref = params["mutref"] - // We've already made sure we can modify the occupant, so this is safe to - // call - var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flag) - - // GUARD CHECK - This should not be possible. Unexpected result - if(!HM) - return - - // We want to make sure we stick within the instability limit. - // We start with the instability of the mutation we're intending to add. - var/instability_total = HM.instability - - // We then add the instabilities of all other mutations in the injector, - // remembering to apply the Stabilizer chromosome modifiers - for(var/datum/mutation/human/I in injector_selection[adv_inj]) - instability_total += I.instability * GET_MUTATION_STABILIZER(I) - - // If this would take us over the max instability, we inform the user. - if(instability_total > max_injector_instability) - to_chat(usr,"Extra mutation would make the advanced injector too instable.") - return - - // If we've got here, all our checks are passed and we can successfully - // add the mutation to the advanced injector. - var/datum/mutation/human/A = new HM.type() - A.copy_mutation(HM) - injector_selection[adv_inj] += A - to_chat(usr,"Mutation successfully added to advanced injector.") - return - - // Deletes a mutation from an advanced injector - // ---------------------------------------------------------------------- // - // params["mutref"] - ATOM Ref of specific mutation to del from the injector - if("delete_injector_mut") - var/bref = params["mutref"] - - var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_ADV_INJ) - - // GUARD CHECK - This should not be possible. Unexpected result - if(!HM) - return - - // Check Advanced Injectors to find and remove the mutation - for(var/I in injector_selection) - if(injector_selection["[I]"].Remove(HM)) - qdel(HM) - return - - return - - // Sets a new tgui view state - // ---------------------------------------------------------------------- // - // params["id"] - Key for the state to set - // params[...] - Every other element is used to set state variables - if("set_view") - for (var/key in params) - if(key == "src") - continue - tgui_view_state[key] = params[key] - return TRUE - return FALSE - -/** - * Applies the enzyme buffer to the current scanner occupant - * - * Applies the type of a specific genetic makeup buffer to the current scanner - * occupant - * - * Arguments: - * * type - "ui"/"ue"/"mixed" - Which part of the enzyme buffer to apply - * * buffer_slot - Index of the enzyme buffer to apply - */ -/obj/machinery/computer/scan_consolenew/proc/apply_genetic_makeup(type, buffer_slot) - // Note - This proc is only called from code that has already performed the - // necessary occupant guard checks. If you call this code yourself, please - // apply can_modify_occupant() or equivalent checks first. - - // Pre-calc the rad increase since we'll be using it in all the possible - // operations - var/rad_increase = rand(100/(connected_scanner.damage_coeff ** 2),250/(connected_scanner.damage_coeff ** 2)) - - switch(type) - if("ui") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["UI"]) - to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") - return FALSE - scanner_occupant.dna.uni_identity = buffer_slot["UI"] - scanner_occupant.updateappearance(mutations_overlay_update=1) - scanner_occupant.radiation += rad_increase - scanner_occupant.domutcheck() - return TRUE - if("ue") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") - return FALSE - scanner_occupant.real_name = buffer_slot["name"] - scanner_occupant.name = buffer_slot["name"] - scanner_occupant.dna.unique_enzymes = buffer_slot["UE"] - scanner_occupant.dna.blood_type = buffer_slot["blood_type"] - scanner_occupant.radiation += rad_increase - scanner_occupant.domutcheck() - return TRUE - if("mixed") - // GUARD CHECK - There's currently no way to save partial genetic data. - // However, if this is the case, we can't make a complete injector and - // this catches that edge case - if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) - to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") - return FALSE - scanner_occupant.dna.uni_identity = buffer_slot["UI"] - scanner_occupant.updateappearance(mutations_overlay_update=1) - scanner_occupant.real_name = buffer_slot["name"] - scanner_occupant.name = buffer_slot["name"] - scanner_occupant.dna.unique_enzymes = buffer_slot["UE"] - scanner_occupant.dna.blood_type = buffer_slot["blood_type"] - scanner_occupant.radiation += rad_increase - scanner_occupant.domutcheck() - return TRUE - - return FALSE -/** - * Checks if there is a connected DNA Scanner that is operational - */ -/obj/machinery/computer/scan_consolenew/proc/scanner_operational() - if(!connected_scanner) - return FALSE - - return (connected_scanner && connected_scanner.is_operational()) - -/** - * Checks if there is a valid DNA Scanner occupant for genetic modification - * - * Checks if there is a valid subject in the DNA Scanner that can be genetically - * modified. Will set the scanner occupant var as part of this check. - * Requires that the scanner can be operated and will return early if it can't - */ -/obj/machinery/computer/scan_consolenew/proc/can_modify_occupant() - // GUARD CHECK - We always want to perform the scanner operational check as - // part of checking if we can modify the occupant. - // We can never modify the occupant of a broken scanner. - if(!scanner_operational()) - return FALSE - - if(!connected_scanner.occupant) - return FALSE - - scanner_occupant = connected_scanner.occupant - - // Check validity of occupent for DNA Modification - // DNA Modification: - // requires DNA - // this DNA can not be bad - // is done via radiation bursts, so radiation immune carbons are not viable - // And the DNA Scanner itself must have a valid scan level - if(scanner_occupant.has_dna() && !HAS_TRAIT(scanner_occupant, TRAIT_RADIMMUNE) && !HAS_TRAIT(scanner_occupant, TRAIT_BADDNA) || (connected_scanner.scan_level == 3)) - return TRUE - - return FALSE - -/** - * Checks for adjacent DNA scanners and connects when it finds a viable one - * - * Seearches cardinal directions in order. Stops when it finds a viable DNA Scanner. - * Will connect to a broken scanner if no functional scanner is available. - * Links itself to the DNA Scanner to receive door open and close events. - */ -/obj/machinery/computer/scan_consolenew/proc/connect_to_scanner() - var/obj/machinery/dna_scannernew/test_scanner = null - var/obj/machinery/dna_scannernew/broken_scanner = null - - // Look in each cardinal direction and try and find a DNA Scanner - // If you find a DNA Scanner, check to see if it broken or working - // If it's working, set the current scanner and return early - // If it's not working, remember it anyway as a broken scanner - for(var/direction in GLOB.cardinals) - test_scanner = locate(/obj/machinery/dna_scannernew, get_step(src, direction)) - if(!isnull(test_scanner)) - if(test_scanner.is_operational()) - connected_scanner = test_scanner - connected_scanner.linked_console = src - return - else - broken_scanner = test_scanner - - // Ultimately, if we have a broken scanner, we'll attempt to connect to it as - // a fallback case, but the code above will prefer a working scanner - if(!isnull(broken_scanner)) - connected_scanner = broken_scanner - connected_scanner.linked_console = src - -/** - * Called by connected DNA Scanners when their doors close. - * - * Sets the new scanner occupant and completes delayed enzyme transfer if one - * is queued. - */ -/obj/machinery/computer/scan_consolenew/proc/on_scanner_close() - // Set the appropriate occupant now the scanner is closed - if(connected_scanner.occupant) - scanner_occupant = connected_scanner.occupant - else - scanner_occupant = null - - // If we have a delayed action - In this case the only delayed action is - // applying a genetic makeup buffer the next time the DNA Scanner is closed - - // we want to perform it. - // GUARD CHECK - Make sure we can modify the occupant, apply_genetic_makeup() - // assumes we've already done this. - if(delayed_action && can_modify_occupant()) - var/type = delayed_action["type"] - var/buffer_slot = delayed_action["buffer_slot"] - if(apply_genetic_makeup(type, buffer_slot)) - to_chat(connected_scanner.occupant, "[src] activates!") - delayed_action = null - -/** - * Called by connected DNA Scanners when their doors open. - * - * Clears enzyme pulse operations, stops processing and nulls the current - * scanner occupant var. - */ -/obj/machinery/computer/scan_consolenew/proc/on_scanner_open() - // If we had a radiation pulse action ongoing, we want to stop this. - // Imagine it being like a microwave stopping when you open the door. - rad_pulse_index = 0 - rad_pulse_timer = 0 - end_processing() - scanner_occupant = null - -/** - * Builds the genetic makeup list which will be sent to tgui interface. - */ -/obj/machinery/computer/scan_consolenew/proc/build_genetic_makeup_list() - // No code will ever null this list, we can safely Cut it. - tgui_genetic_makeup.Cut() - - for(var/i=1, i <= NUMBER_OF_BUFFERS, i++) - if(genetic_makeup_buffer[i]) - tgui_genetic_makeup["[i]"] = genetic_makeup_buffer[i].Copy() - else - tgui_genetic_makeup["[i]"] = null - -/** - * Builds the genetic makeup list which will be sent to tgui interface. - * - * Will iterate over the connected scanner occupant, DNA Console, inserted - * diskette and chromosomes and any advanced injectors, building the main data - * structures which get passed to the tgui interface. - */ -/obj/machinery/computer/scan_consolenew/proc/build_mutation_list(can_modify_occ) - // No code will ever null these lists. We can safely Cut them. - tgui_occupant_mutations.Cut() - tgui_diskette_mutations.Cut() - tgui_console_mutations.Cut() - tgui_console_chromosomes.Cut() - tgui_advinjector_mutations.Cut() - - // ------------------------------------------------------------------------ // - // GUARD CHECK - Can we genetically modify the occupant? This check will have - // previously included checks to make sure the DNA Scanner is still - // operational - if(can_modify_occ) - // ---------------------------------------------------------------------- // - // Start cataloguing all mutations that the occupant has by default - for(var/mutation_type in scanner_occupant.dna.mutation_index) - var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(mutation_type) - - var/list/mutation_data = list() - var/text_sequence = scanner_occupant.dna.mutation_index[mutation_type] - var/default_sequence = scanner_occupant.dna.default_mutation_genes[mutation_type] - var/discovered = (stored_research && (mutation_type in stored_research.discovered_mutations)) - - mutation_data["Alias"] = HM.alias - mutation_data["Sequence"] = text_sequence - mutation_data["DefaultSeq"] = default_sequence - mutation_data["Discovered"] = discovered - mutation_data["Source"] = "occupant" - - // We only want to pass this information along to the tgui interface if - // the mutation has been discovered. Prevents people being able to cheese - // or "hack" their way to figuring out what undiscovered mutations are - if(discovered) - mutation_data["Name"] = HM.name - mutation_data["Description"] = HM.desc - mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) - mutation_data["Quality"] = HM.quality - - // Assume the mutation is normal unless assigned otherwise. - var/mut_class = MUT_NORMAL - - // Check if the mutation is currently activated. If it is, we can add even - // MORE information to send to tgui. - var/datum/mutation/human/A = scanner_occupant.dna.get_mutation(mutation_type) - if(A) - mutation_data["Active"] = TRUE - mutation_data["Scrambled"] = A.scrambled - mutation_data["Class"] = A.class - mut_class = A.class - mutation_data["CanChromo"] = A.can_chromosome - mutation_data["ByondRef"] = REF(A) - mutation_data["Type"] = A.type - if(A.can_chromosome) - mutation_data["ValidChromos"] = jointext(A.valid_chrom_list, ", ") - mutation_data["AppliedChromo"] = A.chromosome_name - mutation_data["ValidStoredChromos"] = build_chrom_list(A) - else - mutation_data["Active"] = FALSE - mutation_data["Scrambled"] = FALSE - mutation_data["Class"] = MUT_NORMAL - - // Technically NONE of these mutations should be MUT_EXTRA but this will - // catch any weird edge cases - // Assign icons by priority - MUT_EXTRA will ALSO be discovered, so it - // has a higher priority for icon/image assignment - if (mut_class == MUT_EXTRA) - mutation_data["Image"] = "dna_extra.gif" - else if(discovered) - mutation_data["Image"] = "dna_discovered.gif" - else - mutation_data["Image"] = "dna_undiscovered.gif" - - tgui_occupant_mutations += list(mutation_data) - - // ---------------------------------------------------------------------- // - // Now get additional/"extra" mutations that they shouldn't have by default - for(var/datum/mutation/human/HM in scanner_occupant.dna.mutations) - // If it's in the mutation index array, we've already catalogued this - // mutation and can safely skip over it. It really shouldn't be, but this - // will catch any weird edge cases - if(HM.type in scanner_occupant.dna.mutation_index) - continue - - var/list/mutation_data = list() - var/text_sequence = GET_SEQUENCE(HM.type) - - // These will all be active mutations. They're added by injector and their - // sequencing code can't be changed. They can only be nullified, which - // completely removes them. - var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) - - mutation_data["Alias"] = A.alias - mutation_data["Sequence"] = text_sequence - mutation_data["Discovered"] = TRUE - mutation_data["Quality"] = HM.quality - mutation_data["Source"] = "occupant" - - mutation_data["Name"] = HM.name - mutation_data["Description"] = HM.desc - mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) - - mutation_data["Active"] = TRUE - mutation_data["Scrambled"] = HM.scrambled - mutation_data["Class"] = HM.class - mutation_data["CanChromo"] = HM.can_chromosome - mutation_data["ByondRef"] = REF(HM) - mutation_data["Type"] = HM.type - - if(HM.can_chromosome) - mutation_data["ValidChromos"] = jointext(HM.valid_chrom_list, ", ") - mutation_data["AppliedChromo"] = HM.chromosome_name - mutation_data["ValidStoredChromos"] = build_chrom_list(HM) - - // Nothing in this list should be undiscovered. Technically nothing - // should be anything but EXTRA. But we're just handling some edge cases. - if (HM.class == MUT_EXTRA) - mutation_data["Image"] = "dna_extra.gif" - else - mutation_data["Image"] = "dna_discovered.gif" - - tgui_occupant_mutations += list(mutation_data) - - // ------------------------------------------------------------------------ // - // Build the list of mutations stored within the DNA Console - for(var/datum/mutation/human/HM in stored_mutations) - var/list/mutation_data = list() - - var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) - - mutation_data["Alias"] = A.alias - mutation_data["Name"] = HM.name - mutation_data["Source"] = "console" - mutation_data["Active"] = TRUE - mutation_data["Description"] = HM.desc - mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) - mutation_data["ByondRef"] = REF(HM) - mutation_data["Type"] = HM.type - - mutation_data["CanChromo"] = HM.can_chromosome - if(HM.can_chromosome) - mutation_data["ValidChromos"] = jointext(HM.valid_chrom_list, ", ") - mutation_data["AppliedChromo"] = HM.chromosome_name - mutation_data["ValidStoredChromos"] = build_chrom_list(HM) - - tgui_console_mutations += list(mutation_data) - - // ------------------------------------------------------------------------ // - // Build the list of chromosomes stored within the DNA Console - var/chrom_index = 1 - for(var/obj/item/chromosome/CM in stored_chromosomes) - var/list/chromo_data = list() - - chromo_data["Name"] = CM.name - chromo_data["Description"] = CM.desc - chromo_data["Index"] = chrom_index - - tgui_console_chromosomes += list(chromo_data) - ++chrom_index - - // ------------------------------------------------------------------------ // - // Build the list of mutations stored on any inserted diskettes - if(diskette) - for(var/datum/mutation/human/HM in diskette.mutations) - var/list/mutation_data = list() - - var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) - - mutation_data["Alias"] = A.alias - mutation_data["Name"] = HM.name - mutation_data["Active"] = TRUE - //mutation_data["Sequence"] = GET_SEQUENCE(HM.type) - mutation_data["Source"] = "disk" - mutation_data["Description"] = HM.desc - mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) - mutation_data["ByondRef"] = REF(HM) - mutation_data["Type"] = HM.type - - mutation_data["CanChromo"] = HM.can_chromosome - if(HM.can_chromosome) - mutation_data["ValidChromos"] = jointext(HM.valid_chrom_list, ", ") - mutation_data["AppliedChromo"] = HM.chromosome_name - mutation_data["ValidStoredChromos"] = build_chrom_list(HM) - - tgui_diskette_mutations += list(mutation_data) - - // ------------------------------------------------------------------------ // - // Build the list of mutations stored within any Advanced Injectors - if(LAZYLEN(injector_selection)) - for(var/I in injector_selection) - var/list/mutations = list() - for(var/datum/mutation/human/HM in injector_selection[I]) - var/list/mutation_data = list() - - var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) - - mutation_data["Alias"] = A.alias - mutation_data["Name"] = HM.name - mutation_data["Active"] = TRUE - //mutation_data["Sequence"] = GET_SEQUENCE(HM.type) - mutation_data["Source"] = "injector" - mutation_data["Description"] = HM.desc - mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) - mutation_data["ByondRef"] = REF(HM) - mutation_data["Type"] = HM.type - - if(HM.can_chromosome) - mutation_data["AppliedChromo"] = HM.chromosome_name - - mutations += list(mutation_data) - tgui_advinjector_mutations += list(list( - "name" = "[I]", - "mutations" = mutations, - )) - -/** - * Takes any given chromosome and calculates chromosome compatibility - * - * Will iterate over the stored chromosomes in the DNA Console and will check - * whether it can be applied to the supplied mutation. Then returns a list of - * names of chromosomes that were compatible. - * - * Arguments: - * * mutation - The mutation to check chromosome compatibility with - */ -/obj/machinery/computer/scan_consolenew/proc/build_chrom_list(mutation) - var/list/chromosomes = list() - - for(var/obj/item/chromosome/CM in stored_chromosomes) - if(CM.can_apply(mutation)) - chromosomes += CM.name - - return chromosomes - -/** - * Checks whether a mutation alias has been discovered - * - * Checks whether a given mutation's genetic sequence has been completed and - * discovers it if appropriate - * - * Arguments: - * * alias - Alias of the mutation to check (ie "Mutation 51" or "Mutation 12") - */ -/obj/machinery/computer/scan_consolenew/proc/check_discovery(alias) - // Note - All code paths that call this have already done checks on the - // current occupant to prevent cheese and other abuses. If you call this - // proc please also do the following checks first: - // if(!can_modify_occupant()) - // return - // if(!(scanner_occupant == connected_scanner.occupant)) - // return - - // Turn the alias ("Mutation 1", "Mutation 35") into a mutation path - var/path = GET_MUTATION_TYPE_FROM_ALIAS(alias) - - // Check to see if this mutation is in the active mutation list. If it isn't, - // then the mutation isn't eligible for discovery. If it is but is scrambled, - // then the mutation isn't eligible for discovery. Finally, check if the - // mutation is in discovered mutations - If it isn't, add it to discover. - var/datum/mutation/human/M = scanner_occupant.dna.get_mutation(path) - if(!M) - return FALSE - if(M.scrambled) - return FALSE - if(stored_research && !(path in stored_research.discovered_mutations)) - var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(path) - stored_research.discovered_mutations += path - say("Successfully discovered [HM.name].") - return TRUE - - return FALSE - -/** - * Find a mutation from various storage locations via ATOM ref - * - * Takes an ATOM Ref and searches the appropriate mutation buffers and storage - * vars to try and find the associated mutation. - * - * Arguments: - * * ref - ATOM ref of the mutation to locate - * * target_flags - Flags for storage mediums to search, see #defines - */ -/obj/machinery/computer/scan_consolenew/proc/get_mut_by_ref(ref, target_flags) - var/mutation - - // Assume the occupant is valid and the check has been carried out before - // calling this proc with the relevant flags. - if(target_flags & SEARCH_OCCUPANT) - mutation = (locate(ref) in scanner_occupant.dna.mutations) - if(mutation) - return mutation - - if(target_flags & SEARCH_STORED) - mutation = (locate(ref) in stored_mutations) - if(mutation) - return mutation - - if(diskette && (target_flags & SEARCH_DISKETTE)) - mutation = (locate(ref) in diskette.mutations) - if(mutation) - return mutation - - if(injector_selection && (target_flags & SEARCH_ADV_INJ)) - for(var/I in injector_selection) - mutation = (locate(ref) in injector_selection["[I]"]) - if(mutation) - return mutation - - return null - -/** - * Creates a randomised accuracy value for the enzyme pulse functionality. - * - * Donor code from previous DNA Console iteration. - * - * Arguments: - * * position - Index of the intended enzyme element to pulse - * * radduration - Duration of intended radiation pulse - * * number_of_blocks - Number of individual data blocks in the pulsed enzyme - */ -/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position, radduration, number_of_blocks) - var/val = round(gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration) + position, 1) - return WRAP(val, 1, number_of_blocks+1) - -/** - * Scrambles an enzyme element value for the enzyme pulse functionality. - * - * Donor code from previous DNA Console iteration. - * - * Arguments: - * * input - Enzyme identity element to scramble, expected hex value - * * rs - Strength of radiation pulse, increases the range of possible outcomes - */ -/obj/machinery/computer/scan_consolenew/proc/scramble(input,rs) - var/length = length(input) - var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER) - if(ran == 0) - ran = pick(-1,1) //hacky, statistically should almost never happen. 0-chance makes people mad though - else if(ran < 0) - ran = round(ran) //negative, so floor it - else - ran = -round(-ran) //positive, so ceiling it - return num2hex(WRAP(hex2num(input)+ran, 0, 16**length), length) - - /** - * Performs the enzyme radiation pulse. - * - * Donor code from previous DNA Console iteration. Called from process() when - * there is a radiation pulse in progress. Ends processing. - */ -/obj/machinery/computer/scan_consolenew/proc/rad_pulse() - // GUARD CHECK - Can we genetically modify the occupant? Includes scanner - // operational guard checks. - // If we can't, abort the procedure. - if(!can_modify_occupant()) - rad_pulse_index = 0 - end_processing() - return - - var/len = length_char(scanner_occupant.dna.uni_identity) - var/num = randomize_radiation_accuracy(rad_pulse_index, radduration + (connected_scanner.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low - var/hex = copytext_char(scanner_occupant.dna.uni_identity, num, num+1) - hex = scramble(hex, radstrength, radduration) - - scanner_occupant.dna.uni_identity = copytext_char(scanner_occupant.dna.uni_identity, 1, num) + hex + copytext_char(scanner_occupant.dna.uni_identity, num + 1) - scanner_occupant.updateappearance(mutations_overlay_update=1) - - rad_pulse_index = 0 - end_processing() - return - -/** - * Sets the default state for the tgui interface. - */ -/obj/machinery/computer/scan_consolenew/proc/set_default_state() - tgui_view_state["consoleMode"] = "storage" - tgui_view_state["storageMode"] = "console" - tgui_view_state["storageConsSubMode"] = "mutations" - tgui_view_state["storageDiskSubMode"] = "mutations" - - -#undef INJECTOR_TIMEOUT -#undef NUMBER_OF_BUFFERS -#undef SCRAMBLE_TIMEOUT -#undef JOKER_TIMEOUT -#undef JOKER_UPGRADE - -#undef RADIATION_STRENGTH_MAX -#undef RADIATION_STRENGTH_MULTIPLIER - -#undef RADIATION_DURATION_MAX -#undef RADIATION_ACCURACY_MULTIPLIER - -#undef RADIATION_IRRADIATION_MULTIPLIER - -#undef STATUS_TRANSFORMING - -#undef SEARCH_OCCUPANT -#undef SEARCH_STORED -#undef SEARCH_DISKETTE -#undef SEARCH_ADV_INJ +/// Base timeout for creating mutation activators and other injectors +#define INJECTOR_TIMEOUT 100 +/// Maximum number of genetic makeup storage slots in DNA Console +#define NUMBER_OF_BUFFERS 3 +/// Timeout for DNA Scramble in DNA Consoles +#define SCRAMBLE_TIMEOUT 600 +/// Timeout for using the Joker feature to solve a gene in DNA Console +#define JOKER_TIMEOUT 12000 +/// How much time DNA Scanner upgrade tiers remove from JOKER_TIMEOUT +#define JOKER_UPGRADE 3000 + +/// Maximum value for radiaton strength when pulsing enzymes +#define RADIATION_STRENGTH_MAX 15 +/// Larger multipliers will affect the range of values when pulsing enzymes +#define RADIATION_STRENGTH_MULTIPLIER 1 + +/// Maximum value for the radiation pulse duration when pulsing enzymes +#define RADIATION_DURATION_MAX 30 +/// Large values reduce pulse accuracy and may pulse other enzymes than selected +#define RADIATION_ACCURACY_MULTIPLIER 3 + +/// Special status indicating a scanner occupant is transforming eg. from monkey to human +#define STATUS_TRANSFORMING 4 + +/// Multiplier for how much radiation received from DNA Console functionality +#define RADIATION_IRRADIATION_MULTIPLIER 1 + +/// Flag for the mutation ref search system. Search will include scanner occupant +#define SEARCH_OCCUPANT 1 +/// Flag for the mutation ref search system. Search will include console storage +#define SEARCH_STORED 2 +/// Flag for the mutation ref search system. Search will include diskette storage +#define SEARCH_DISKETTE 4 +/// Flag for the mutation ref search system. Search will include advanced injector mutations +#define SEARCH_ADV_INJ 8 + +/obj/machinery/computer/scan_consolenew + name = "DNA Console" + desc = "Scan DNA." + icon_screen = "dna" + icon_keyboard = "med_key" + density = TRUE + circuit = /obj/item/circuitboard/computer/scan_consolenew + + use_power = IDLE_POWER_USE + idle_power_usage = 10 + active_power_usage = 400 + light_color = LIGHT_COLOR_BLUE + + /// Link to the techweb's stored research. Used to retrieve stored mutations + var/datum/techweb/stored_research + /// Maximum number of mutations that DNA Consoles are able to store + var/max_storage = 6 + /// Duration for enzyme radiation pulses + var/radduration = 2 + /// Strength for enzyme radiation pulses + var/radstrength = 1 + /// Maximum number of chromosomes that DNA Consoles are able to store. + var/max_chromosomes = 6 + /// Maximum number of enzymes we can store + var/list/genetic_makeup_buffer[NUMBER_OF_BUFFERS] + /// List of all mutations stored on the DNA Console + var/list/stored_mutations = list() + /// List of all chromosomes stored in the DNA Console + var/list/stored_chromosomes = list() + /// Assoc list of all advanced injectors. Keys are injector names. Values are lists of mutations. + var/list/list/injector_selection = list() + /// Maximum number of advanced injectors that DNA Consoles store + var/max_injector_selections = 2 + /// Maximum number of mutation that an advanced injector can store + var/max_injector_mutations = 10 + /// Maximum total instability of all combined mutations allowed on an advanced injector + var/max_injector_instability = 50 + + /// World time when injectors are ready to be printed + var/injectorready = 0 + /// World time when JOKER algorithm can be used in DNA Consoles + var/jokerready = 0 + /// World time when Scramble can be used in DNA Consoles + var/scrambleready = 0 + + /// Currently stored genetic data diskette + var/obj/item/disk/data/diskette = null + + /// Current delayed action, used for delayed enzyme transfer on scanner door close + var/list/delayed_action = null + + /// Index of the enzyme being modified during delayed enzyme pulse operations + var/rad_pulse_index = 0 + /// World time when the enzyme pulse should complete + var/rad_pulse_timer = 0 + + /// Used for setting tgui data - Whether the connected DNA Scanner is usable + var/can_use_scanner = FALSE + /// Used for setting tgui data - Whether the current DNA Scanner occupant is viable for genetic modification + var/is_viable_occupant = FALSE + /// Used for setting tgui data - Whether Scramble DNA is ready + var/is_scramble_ready = FALSE + /// Used for setting tgui data - Whether JOKER algorithm is ready + var/is_joker_ready = FALSE + /// Used for setting tgui data - Whether injectors are ready to be printed + var/is_injector_ready = FALSE + /// Used for setting tgui data - Wheher an enzyme pulse operation is ongoing + var/is_pulsing_rads = FALSE + /// Used for setting tgui data - Time until scramble is ready + var/time_to_scramble = 0 + /// Used for setting tgui data - Time until joker is ready + var/time_to_joker = 0 + /// Used for setting tgui data - Time until injectors are ready + var/time_to_injector = 0 + /// Used for setting tgui data - Time until the enzyme pulse is complete + var/time_to_pulse = 0 + + /// Currently connected DNA Scanner + var/obj/machinery/dna_scannernew/connected_scanner = null + /// Current DNA Scanner occupant + var/mob/living/carbon/scanner_occupant = null + + /// Used for setting tgui data - List of occupant mutations + var/list/tgui_occupant_mutations = list() + /// Used for setting tgui data - List of DNA Console stored mutations + var/list/tgui_console_mutations = list() + /// Used for setting tgui data - List of diskette stored mutations + var/list/tgui_diskette_mutations = list() + /// Used for setting tgui data - List of DNA Console chromosomes + var/list/tgui_console_chromosomes = list() + /// Used for setting tgui data - List of occupant mutations + var/list/tgui_genetic_makeup = list() + /// Used for setting tgui data - List of occupant mutations + var/list/tgui_advinjector_mutations = list() + + + /// State of tgui view, i.e. which tab is currently active, or which genome we're currently looking at. + var/list/list/tgui_view_state = list() + +/obj/machinery/computer/scan_consolenew/process() + . = ..() + + // This is for pulsing the UI element with radiation as part of genetic makeup + // If rad_pulse_index > 0 then it means we're attempting a rad pulse + if((rad_pulse_index > 0) && (rad_pulse_timer <= world.time)) + rad_pulse() + return + +/obj/machinery/computer/scan_consolenew/attackby(obj/item/I, mob/user, params) + // Store chromosomes in the console if there's room + if (istype(I, /obj/item/chromosome)) + if(LAZYLEN(stored_chromosomes) < max_chromosomes) + I.forceMove(src) + stored_chromosomes += I + to_chat(user, "You insert [I].") + else + to_chat(user, "You cannot store any more chromosomes!") + return + + // Insert data disk if console disk slot is empty + // Swap data disk if there is one already a disk in the console + if (istype(I, /obj/item/disk/data)) //INSERT SOME DISKETTES + if (!user.transferItemToLoc(I,src)) + return + if(diskette) + diskette.forceMove(drop_location()) + diskette = null + diskette = I + to_chat(user, "You insert [I].") + return + + // Recycle non-activator used injectors + // Turn activator used injectors (aka research injectors) to chromosomes + if(istype(I, /obj/item/dnainjector/activator)) + var/obj/item/dnainjector/activator/A = I + if(A.used) + to_chat(user,"Recycled [I].") + if(A.research) + if(prob(60)) + var/c_typepath = generate_chromosome() + var/obj/item/chromosome/CM = new c_typepath (drop_location()) + if(LAZYLEN(stored_chromosomes) < max_chromosomes) + CM.forceMove(src) + stored_chromosomes += CM + to_chat(user,"[capitalize(CM.name)] added to storage.") + else + to_chat(user, "You cannot store any more chromosomes!") + to_chat(user, "[capitalize(CM.name)] added on top of the console.") + else + to_chat(user, "There was not enough genetic data to extract a viable chromosome.") + qdel(I) + return + + return ..() + +/obj/machinery/computer/scan_consolenew/Initialize() + . = ..() + + // Connect with a nearby DNA Scanner on init + connect_to_scanner() + + // Set appropriate ready timers and limits for machines functions + injectorready = world.time + INJECTOR_TIMEOUT + scrambleready = world.time + SCRAMBLE_TIMEOUT + jokerready = world.time + JOKER_TIMEOUT + + // Set the default tgui state + set_default_state() + + // Link machine with research techweb. Used for discovering and accessing + // already discovered mutations + stored_research = SSresearch.science_tech + +/obj/machinery/computer/scan_consolenew/examine(mob/user) + . = ..() + +/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) + . = ..() + + // Most of ui_interact is spent setting variables for passing to the tgui + // interface. + // We can also do some general state processing here too as it's a good + // indication that a player is using the console. + + var/scanner_op = scanner_operational() + var/can_modify_occ = can_modify_occupant() + + // Check for connected AND operational scanner. + if(scanner_op) + can_use_scanner = TRUE + else + can_use_scanner = FALSE + connected_scanner = null + is_viable_occupant = FALSE + + // Check for a viable occupant in the scanner. + if(can_modify_occ) + is_viable_occupant = TRUE + else + is_viable_occupant = FALSE + + + // Populates various buffers for passing to tgui + build_mutation_list(can_modify_occ) + build_genetic_makeup_list() + + // Populate variables for passing to tgui interface + is_scramble_ready = (scrambleready < world.time) + time_to_scramble = round((scrambleready - world.time)/10) + + is_joker_ready = (jokerready < world.time) + time_to_joker = round((jokerready - world.time)/10) + + is_injector_ready = (injectorready < world.time) + time_to_injector = round((injectorready - world.time)/10) + + is_pulsing_rads = ((rad_pulse_index > 0) && (rad_pulse_timer > world.time)) + time_to_pulse = round((rad_pulse_timer - world.time)/10) + + // Attempt to update tgui ui, open and update if needed. + ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) + + if(!ui) + ui = new(user, src, ui_key, "DnaConsole", name, 539, 710, master_ui, state) + ui.open() + +/obj/machinery/computer/scan_consolenew/ui_data(mob/user) + var/list/data = list() + + data["view"] = tgui_view_state + data["storage"] = list() + + // This block of code generates the huge data structure passed to the tgui + // interface for displaying all the various bits of console/scanner data + // Should all be very self-explanatory + data["isScannerConnected"] = can_use_scanner + if(can_use_scanner) + data["scannerOpen"] = connected_scanner.state_open + data["scannerLocked"] = connected_scanner.locked + data["radStrength"] = radstrength + data["radDuration"] = radduration + data["stdDevStr"] = radstrength * RADIATION_STRENGTH_MULTIPLIER + switch(RADIATION_ACCURACY_MULTIPLIER / (radduration + (connected_scanner.precision_coeff ** 2))) //hardcoded values from a z-table for a normal distribution + if(0 to 0.25) + data["stdDevAcc"] = ">95 %" + if(0.25 to 0.5) + data["stdDevAcc"] = "68-95 %" + if(0.5 to 0.75) + data["stdDevAcc"] = "55-68 %" + else + data["stdDevAcc"] = "<38 %" + + data["isViableSubject"] = is_viable_occupant + if(is_viable_occupant) + data["subjectName"] = scanner_occupant.name + if(scanner_occupant.transformation_timer) + data["subjectStatus"] = STATUS_TRANSFORMING + else + data["subjectStatus"] = scanner_occupant.stat + data["subjectHealth"] = scanner_occupant.health + data["subjectRads"] = scanner_occupant.radiation/(RAD_MOB_SAFE/100) + data["subjectEnzymes"] = scanner_occupant.dna.unique_enzymes + data["isMonkey"] = ismonkey(scanner_occupant) + data["subjectUNI"] = scanner_occupant.dna.uni_identity + data["storage"]["occupant"] = tgui_occupant_mutations + //data["subjectMutations"] = tgui_occupant_mutations + else + data["subjectName"] = null + data["subjectStatus"] = null + data["subjectHealth"] = null + data["subjectRads"] = null + data["subjectEnzymes"] = null + //data["subjectMutations"] = null + data["storage"]["occupant"] = null + + data["hasDelayedAction"] = (delayed_action != null) + data["isScrambleReady"] = is_scramble_ready + data["isJokerReady"] = is_joker_ready + data["isInjectorReady"] = is_injector_ready + data["scrambleSeconds"] = time_to_scramble + data["jokerSeconds"] = time_to_joker + data["injectorSeconds"] = time_to_injector + data["isPulsingRads"] = is_pulsing_rads + data["radPulseSeconds"] = time_to_pulse + + if(diskette != null) + data["hasDisk"] = TRUE + data["diskCapacity"] = diskette.max_mutations - LAZYLEN(diskette.mutations) + data["diskReadOnly"] = diskette.read_only + //data["diskMutations"] = tgui_diskette_mutations + data["storage"]["disk"] = tgui_diskette_mutations + data["diskHasMakeup"] = (LAZYLEN(diskette.genetic_makeup_buffer) > 0) + data["diskMakeupBuffer"] = diskette.genetic_makeup_buffer.Copy() + else + data["hasDisk"] = FALSE + data["diskCapacity"] = 0 + data["diskReadOnly"] = TRUE + //data["diskMutations"] = null + data["storage"]["disk"] = null + data["diskHasMakeup"] = FALSE + data["diskMakeupBuffer"] = null + + data["mutationCapacity"] = max_storage - LAZYLEN(stored_mutations) + //data["mutationStorage"] = tgui_console_mutations + data["storage"]["console"] = tgui_console_mutations + data["chromoCapacity"] = max_chromosomes - LAZYLEN(stored_chromosomes) + data["chromoStorage"] = tgui_console_chromosomes + data["makeupCapacity"] = NUMBER_OF_BUFFERS + data["makeupStorage"] = tgui_genetic_makeup + + //data["advInjectors"] = tgui_advinjector_mutations + data["storage"]["injector"] = tgui_advinjector_mutations + data["maxAdvInjectors"] = max_injector_selections + + return data + +/obj/machinery/computer/scan_consolenew/ui_act(action, var/list/params) + if(..()) + return TRUE + + . = TRUE + + add_fingerprint(usr) + usr.set_machine(src) + + switch(action) + // Connect this DNA Console to a nearby DNA Scanner + // Usually only activate as an option if there is no connected scanner + if("connect_scanner") + connect_to_scanner() + return + + // Toggle the door open/closed status on attached DNA Scanner + if("toggle_door") + // GUARD CHECK - Scanner still connected and operational? + if(!scanner_operational()) + return + + connected_scanner.toggle_open(usr) + return + + // Toggle the door bolts on the attached DNA Scanner + if("toggle_lock") + // GUARD CHECK - Scanner still connected and operational? + if(!scanner_operational()) + return + + connected_scanner.locked = !connected_scanner.locked + return + + // Scramble scanner occupant's DNA + if("scramble_dna") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + // GUARD CHECK - Is scramble DNA actually ready? + if(!can_modify_occupant() || !(scrambleready < world.time)) + return + + scanner_occupant.dna.remove_all_mutations(list(MUT_NORMAL, MUT_EXTRA)) + scanner_occupant.dna.generate_dna_blocks() + scrambleready = world.time + SCRAMBLE_TIMEOUT + to_chat(usr,"DNA scrambled.") + scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER*50/(connected_scanner.damage_coeff ** 2) + return + + // Check whether a specific mutation is eligible for discovery within the + // scanner occupant + // This is additionally done when a mutation's tab is selected in the tgui + // interface. This is because some mutations, such as Monkified on monkeys, + // are infact completed by default but not yet discovered. Likewise, all + // mutations can have their sequence completed while Monkified is still an + // active mutation and thus won't immediately be discovered but could be + // discovered when Monkified is removed + // ---------------------------------------------------------------------- // + // params["alias"] - Alias of a mutation. The alias is the "hidden" name of + // the mutation, for example "Mutation 5" or "Mutation 33" + if("check_discovery") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + // GUARD CHECK - Have we somehow cheekily swapped occupants? This is + // unexpected. + if(!(scanner_occupant == connected_scanner.occupant)) + return + + check_discovery(params["alias"]) + return + + // Check all mutations of the occupant and check if any are discovered. + // This is called when the Genetic Sequencer is selected. It'll do things + // like immediately discover Monkified without needing to click through + // the mutation tabs and handle cases where mutations are solved but not + // discovered due to the Monkified mutation being active then removed. + if("all_check_discovery") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + // GUARD CHECK - Have we somehow cheekily swapped occupants? This is + // unexpected. + if(!(scanner_occupant == connected_scanner.occupant)) + return + + // Go over all standard mutations and check if they've been discovered. + for(var/mutation_type in scanner_occupant.dna.mutation_index) + var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(mutation_type) + check_discovery(HM.alias) + + return + + // Set a gene in a mutation's genetic sequence. Will also check for mutations + // discovery as part of the process. + // ---------------------------------------------------------------------- // + // params["alias"] - Alias of a mutation. The alias is the "hidden" name of + // the mutation, for example "Mutation 5" or "Mutation 33" + // params["gene"] - The letter of the new gene + // params["pos"] - The BYOND index of the letter in the gene sequence to be + // changed. Expects a text string from TGUI and will convert to a number + if("pulse_gene") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + // GUARD CHECK - Have we somehow cheekily swapped occupants? This is + // unexpected. + if(!(scanner_occupant == connected_scanner.occupant)) + return + + // GUARD CHECK - Is the occupant currently undergoing some form of + // transformation? If so, we don't want to be pulsing genes. + if(scanner_occupant.transformation_timer) + to_chat(usr,"Gene pulse failed: The scanner occupant undergoing a transformation.") + return + + // Resolve mutation's BYOND path from the alias + var/alias = params["alias"] + var/path = GET_MUTATION_TYPE_FROM_ALIAS(alias) + + // Make sure the occupant still has this mutation + if(!(path in scanner_occupant.dna.mutation_index)) + return + + // Resolve BYOND path to genome sequence of scanner occupant + var/sequence = GET_GENE_STRING(path, scanner_occupant.dna) + + var/newgene = params["gene"] + var/genepos = text2num(params["pos"]) + + // If the new gene is J, this means we're dealing with a JOKER + // GUARD CHECK - Is JOKER actually ready? + if((newgene == "J") && (jokerready < world.time)) + var/truegenes = GET_SEQUENCE(path) + newgene = truegenes[genepos] + jokerready = world.time + JOKER_TIMEOUT - (JOKER_UPGRADE * (connected_scanner.precision_coeff-1)) + + // If the gene is an X, we want to update the default genes with the new + // X to allow highlighting logic to work on the tgui interface. + if(newgene == "X") + var/defaultseq = scanner_occupant.dna.default_mutation_genes[path] + defaultseq = copytext_char(defaultseq, 1, genepos) + newgene + copytext_char(defaultseq, genepos + 1) + scanner_occupant.dna.default_mutation_genes[path] = defaultseq + + // Copy genome to scanner occupant and do some basic mutation checks as + // we've increased the occupant rads + sequence = copytext_char(sequence, 1, genepos) + newgene + copytext_char(sequence, genepos + 1) + scanner_occupant.dna.mutation_index[path] = sequence + scanner_occupant.radiation += RADIATION_STRENGTH_MULTIPLIER/connected_scanner.damage_coeff + scanner_occupant.domutcheck() + + // GUARD CHECK - Modifying genetics can lead to edge cases where the + // scanner occupant is qdel'd and replaced with a different entity. + // Examples of this include adding/removing the Monkified mutation which + // qdels the previous entity and creates a brand new one in its place. + // We should redo all of our occupant modification checks again, although + // it is less than ideal. + if(!can_modify_occupant()) + return + + // Check if we cracked a mutation + check_discovery(alias) + + return + + // Apply a chromosome to a specific mutation. + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to apply the chromo to + // params["chromo"] - Name of the chromosome to apply to the mutation + if("apply_chromo") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + // GUARD CHECK - Have we somehow cheekily swapped occupants? This is + // unexpected. + if(!(scanner_occupant == connected_scanner.occupant)) + return + + var/bref = params["mutref"] + + // GUARD CHECK - Only search occupant for this specific ref, since your + // can only apply chromosomes to mutations occupants. + var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_OCCUPANT) + + // GUARD CHECK - This should not be possible. Unexpected result + if(!HM) + return + + // Look through our stored chromos and compare names to find a + // stored chromo we can apply. + for(var/obj/item/chromosome/CM in stored_chromosomes) + if(CM.can_apply(HM) && (CM.name == params["chromo"])) + stored_chromosomes -= CM + CM.apply(HM) + + return + + // Print any type of standard injector, limited right now to activators that + // activate a dormant mutation and mutators that forcibly create a new + // MUT_EXTRA mutation + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to create an injector of + // params["is_activator"] - Is this an "Activator" style injector, also + // referred to as a "Research" type. Expects a string with 0 or 1, which + // then gets converted to a number. + // params["source"] - The source the request came from. + // Expected results: + // "occupant" - From genetic sequencer + // "console" - From DNA Console storage + // "disk" - From inserted diskette + if("print_injector") + // Because printing mutators and activators share a bunch of code, + // it makes sense to keep them both together and set unique vars + // later in the code + + // As a side note, because mutations can contain unique metadata, + // this system uses BYOND Atom Refs to safely and accurately + // identify mutations from big ol' lists + + // GUARD CHECK - Is the injector actually ready? + if(world.time < injectorready) + return + + var/search_flags = 0 + + switch(params["source"]) + if("occupant") + // GUARD CHECK - Make sure we can modify the occupant before we + // attempt to search them for any given mutation refs. This could + // lead to no search flags being passed to get_mut_by_ref and this + // is intended functionality to prevent any cheese or abuse + if(can_modify_occupant()) + search_flags |= SEARCH_OCCUPANT + if("console") + search_flags |= SEARCH_STORED + if("disk") + search_flags |= SEARCH_DISKETTE + + var/bref = params["mutref"] + var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flags) + + // GUARD CHECK - This should not be possible. Unexpected result + if(!HM) + return + + // Create a new DNA Injector and add the appropriate mutations to it + var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc) + I.add_mutations += new HM.type(copymut = HM) + + var/is_activator = text2num(params["is_activator"]) + + // Activators are also called "research" injectors and are used to create + // chromosomes by recycling at the DNA Console + if(is_activator) + I.name = "[HM.name] activator" + I.research = TRUE + // If there's an operational connected scanner, we can use its upgrades + // to improve our injector's radiation generation + if(scanner_operational()) + I.damage_coeff = connected_scanner.damage_coeff*4 + injectorready = world.time + INJECTOR_TIMEOUT * (1 - 0.1 * connected_scanner.precision_coeff) + else + injectorready = world.time + INJECTOR_TIMEOUT + else + I.name = "[HM.name] mutator" + I.doitanyway = TRUE + // If there's an operational connected scanner, we can use its upgrades + // to improve our injector's radiation generation + if(scanner_operational()) + I.damage_coeff = connected_scanner.damage_coeff + injectorready = world.time + INJECTOR_TIMEOUT * 5 * (1 - 0.1 * connected_scanner.precision_coeff) + else + injectorready = world.time + INJECTOR_TIMEOUT * 5 + + return + + // Save a mutation to the console's storage buffer. + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to store + // params["source"] - The source the request came from. + // Expected results: + // "occupant" - From genetic sequencer + // "disk" - From inserted diskette + if("save_console") + var/search_flags = 0 + + switch(params["source"]) + if("occupant") + // GUARD CHECK - Make sure we can modify the occupant before we + // attempt to search them for any given mutation refs. This could + // lead to no search flags being passed to get_mut_by_ref and this + // is intended functionality to prevent any cheese or abuse + if(can_modify_occupant()) + search_flags |= SEARCH_OCCUPANT + if("disk") + search_flags |= SEARCH_DISKETTE + + // GUARD CHECK - Is mutation storage full? + if(LAZYLEN(stored_mutations) >= max_storage) + to_chat(usr,"Mutation storage is full.") + return + + var/bref = params["mutref"] + var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flags) + + // GUARD CHECK - This should not be possible. Unexpected result + if(!HM) + return + + var/datum/mutation/human/A = new HM.type() + A.copy_mutation(HM) + stored_mutations += A + to_chat(usr,"Mutation successfully stored.") + return + + // Save a mutation to the diskette's storage buffer. + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to store + // params["source"] - The source the request came from + // Expected results: + // "occupant" - From genetic sequencer + // "console" - From DNA Console storage + if("save_disk") + // GUARD CHECK - This code shouldn't even be callable without a diskette + // inserted. Unexpected result + if(!diskette) + return + + // GUARD CHECK - Make sure the disk is not full + if(LAZYLEN(diskette.mutations) >= diskette.max_mutations) + to_chat(usr,"Disk storage is full.") + return + + // GUARD CHECK - Make sure the disk isn't set to read only, as we're + // attempting to write to it + if(diskette.read_only) + to_chat(usr,"Disk is set to read only mode.") + return + + var/search_flags = 0 + + switch(params["source"]) + if("occupant") + // GUARD CHECK - Make sure we can modify the occupant before we + // attempt to search them for any given mutation refs. This could + // lead to no search flags being passed to get_mut_by_ref and this + // is intended functionality to prevent any cheese or abuse + if(can_modify_occupant()) + search_flags |= SEARCH_OCCUPANT + if("console") + search_flags |= SEARCH_STORED + + var/bref = params["mutref"] + var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flags) + + // GUARD CHECK - This should not be possible. Unexpected result + if(!HM) + return + + var/datum/mutation/human/A = new HM.type() + A.copy_mutation(HM) + diskette.mutations += A + to_chat(usr,"Mutation successfully stored to disk.") + return + + // Completely removes a MUT_EXTRA mutation or mutation with corrupt gene + // sequence from the scanner occupant + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to nullify + if("nullify") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + var/bref = params["mutref"] + var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_OCCUPANT) + + // GUARD CHECK - This should not be possible. Unexpected result + if(!HM) + return + + // GUARD CHECK - Nullify should only be used on scrambled or "extra" + // mutations. + if(!HM.scrambled && !(HM.class == MUT_EXTRA)) + return + + scanner_occupant.dna.remove_mutation(HM.type) + return + + // Deletes saved mutation from console buffer. + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to delete + if("delete_console_mut") + var/bref = params["mutref"] + var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_STORED) + + if(HM) + stored_mutations.Remove(HM) + qdel(HM) + + return + + // Deletes saved mutation from disk buffer. + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to delete + if("delete_disk_mut") + // GUARD CHECK - This code shouldn't even be callable without a diskette + // inserted. Unexpected result + if(!diskette) + return + + // GUARD CHECK - Make sure the disk isn't set to read only, as we're + // attempting to write to it (via deletion) + if(diskette.read_only) + to_chat(usr,"Disk is set to read only mode.") + return + + var/bref = params["mutref"] + var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_DISKETTE) + + if(HM) + diskette.mutations.Remove(HM) + qdel(HM) + + return + + // Ejects a stored chromosome from the DNA Console + // ---------------------------------------------------------------------- // + // params["chromo"] - Text string of the chromosome name + if("eject_chromo") + var/chromname = params["chromo"] + + for(var/obj/item/chromosome/CM in stored_chromosomes) + if(chromname == CM.name) + CM.forceMove(drop_location()) + adjust_item_drop_location(CM) + stored_chromosomes -= CM + return + + return + + // Combines two mutations from the console to try and create a new mutation + // ---------------------------------------------------------------------- // + // params["firstref"] - ATOM Ref of first mutation for combination + // params["secondref"] - ATOM Ref of second mutation for combination + // mutation + if("combine_console") + // GUaRD CHECK - Make sure mutation storage isn't full. If it is, we won't + // be able to store the new combo mutation + if(LAZYLEN(stored_mutations) >= max_storage) + to_chat(usr,"Mutation storage is full.") + return + + // GUARD CHECK - We're running a research-type operation. If, for some + // reason, somehow the DNA Console has been disconnected from the research + // network - Or was never in it to begin with - don't proceed + if(!stored_research) + return + + var/first_bref = params["firstref"] + var/second_bref = params["secondref"] + + // GUARD CHECK - Find the source and destination mutations on the console + // and make sure they actually exist. + var/datum/mutation/human/source_mut = get_mut_by_ref(first_bref, SEARCH_STORED | SEARCH_DISKETTE) + if(!source_mut) + return + + var/datum/mutation/human/dest_mut = get_mut_by_ref(second_bref, SEARCH_STORED | SEARCH_DISKETTE) + if(!dest_mut) + return + + // Attempt to mix the two mutations to get a new type + var/result_path = get_mixed_mutation(source_mut.type, dest_mut.type) + + if(!result_path) + return + + // If we got a new type, add it to our storage + stored_mutations += new result_path() + to_chat(usr, "Success! New mutation has been added to console storage.") + + // If it's already discovered, end here. Otherwise, add it to the list of + // discovered mutations. + // We've already checked for stored_research earlier + if(result_path in stored_research.discovered_mutations) + return + + var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(result_path) + stored_research.discovered_mutations += result_path + say("Successfully mutated [HM.name].") + return + + // Combines two mutations from the disk to try and create a new mutation + // ---------------------------------------------------------------------- // + // params["firstref"] - ATOM Ref of first mutation for combination + // params["secondref"] - ATOM Ref of second mutation for combination + // mutation + if("combine_disk") + // GUARD CHECK - This code shouldn't even be callable without a diskette + // inserted. Unexpected result + if(!diskette) + return + + // GUARD CHECK - Make sure the disk is not full. + if(LAZYLEN(diskette.mutations) >= diskette.max_mutations) + to_chat(usr,"Disk storage is full.") + return + + // GUARD CHECK - Make sure the disk isn't set to read only, as we're + // attempting to write to it + if(diskette.read_only) + to_chat(usr,"Disk is set to read only mode.") + return + + // GUARD CHECK - We're running a research-type operation. If, for some + // reason, somehow the DNA Console has been disconnected from the research + // network - Or was never in it to begin with - don't proceed + if(!stored_research) + return + + var/first_bref = params["firstref"] + var/second_bref = params["secondref"] + + // GUARD CHECK - Find the source and destination mutations on the console + // and make sure they actually exist. + var/datum/mutation/human/source_mut = get_mut_by_ref(first_bref, SEARCH_STORED | SEARCH_DISKETTE) + if(!source_mut) + return + + var/datum/mutation/human/dest_mut = get_mut_by_ref(second_bref, SEARCH_STORED | SEARCH_DISKETTE) + if(!dest_mut) + return + + // Attempt to mix the two mutations to get a new type + var/result_path = get_mixed_mutation(source_mut.type, dest_mut.type) + + if(!result_path) + return + + // If we got a new type, add it to our storage + diskette.mutations += new result_path() + to_chat(usr, "Success! New mutation has been added to the disk.") + + // If it's already discovered, end here. Otherwise, add it to the list of + // discovered mutations + // We've already checked for stored_research earlier + if(result_path in stored_research.discovered_mutations) + return + + var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(result_path) + stored_research.discovered_mutations += result_path + say("Successfully mutated [HM.name].") + return + + // Sets the Genetic Makeup pulse strength. + // ---------------------------------------------------------------------- // + // params["val"] - New strength value as text string, converted to number + // later on in code + if("set_pulse_strength") + var/value = round(text2num(params["val"])) + radstrength = WRAP(value, 1, RADIATION_STRENGTH_MAX+1) + return + + // Sets the Genetic Makeup pulse duration + // ---------------------------------------------------------------------- // + // params["val"] - New strength value as text string, converted to number + // later on in code + if("set_pulse_duration") + var/value = round(text2num(params["val"])) + radduration = WRAP(value, 1, RADIATION_DURATION_MAX+1) + return + + // Saves Genetic Makeup information to disk + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the console genetic makeup buffer to + // copy to disk + if("save_makeup_disk") + // GUARD CHECK - This code shouldn't even be callable without a diskette + // inserted. Unexpected result + if(!diskette) + return + + // GUARD CHECK - Make sure the disk isn't set to read only, as we're + // attempting to write to it + if(diskette.read_only) + to_chat(usr,"Disk is set to read only mode.") + return + + // Convert the index to a number and clamp within the array range + var/buffer_index = text2num(params["index"]) + buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) + + var/list/buffer_slot = genetic_makeup_buffer[buffer_index] + + // GUARD CHECK - This should not be possible to activate on a buffer slot + // that doesn't have any genetic data. Unexpected result + if(!istype(buffer_slot)) + return + + diskette.genetic_makeup_buffer = buffer_slot.Copy() + return + + // Loads Genetic Makeup from disk to a console buffer + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the console genetic makeup buffer to + // copy to. Expected as text string, converted to number later + if("load_makeup_disk") + // GUARD CHECK - This code shouldn't even be callable without a diskette + // inserted. Unexpected result + if(!diskette) + return + + // GUARD CHECK - This should not be possible to activate on a diskette + // that doesn't have any genetic data. Unexpected result + if(LAZYLEN(diskette.genetic_makeup_buffer) == 0) + return + + // Convert the index to a number and clamp within the array range, then + // copy the data from the disk to that buffer + var/buffer_index = text2num(params["index"]) + buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) + genetic_makeup_buffer[buffer_index] = diskette.genetic_makeup_buffer.Copy() + return + + // Deletes genetic makeup buffer from the inserted diskette + if("del_makeup_disk") + // GUARD CHECK - This code shouldn't even be callable without a diskette + // inserted. Unexpected result + if(!diskette) + return + + // GUARD CHECK - Make sure the disk isn't set to read only, as we're + // attempting to write (via deletion) to it + if(diskette.read_only) + to_chat(usr,"Disk is set to read only mode.") + return + + diskette.genetic_makeup_buffer.Cut() + return + + // Saves the scanner occupant's genetic makeup to a given console buffer + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the console genetic makeup buffer to + // save the new genetic data to. Expected as text string, converted to + // number later + if("save_makeup_console") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + // Convert the index to a number and clamp within the array range, then + // copy the data from the disk to that buffer + var/buffer_index = text2num(params["index"]) + buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) + + // Set the new information + genetic_makeup_buffer[buffer_index] = list( + "label"="Slot [buffer_index]:[scanner_occupant.real_name]", + "UI"=scanner_occupant.dna.uni_identity, + "UE"=scanner_occupant.dna.unique_enzymes, + "name"=scanner_occupant.real_name, + "blood_type"=scanner_occupant.dna.blood_type) + + return + + // Deleted genetic makeup data from a console buffer slot + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the console genetic makeup buffer to + // delete the genetic data from. Expected as text string, converted to + // number later + if("del_makeup_console") + // Convert the index to a number and clamp within the array range, then + // copy the data from the disk to that buffer + var/buffer_index = text2num(params["index"]) + buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = genetic_makeup_buffer[buffer_index] + + // GUARD CHECK - This shouldn't be possible to execute this on a null + // buffer. Unexpected resut + if(!istype(buffer_slot)) + return + + genetic_makeup_buffer[buffer_index] = null + return + + // Eject stored diskette from console + if("eject_disk") + // GUARD CHECK - This code shouldn't even be callable without a diskette + // inserted. Unexpected result + if(!diskette) + return + + diskette.forceMove(drop_location()) + diskette = null + return + + // Create a Genetic Makeup injector. These injectors are timed and thus are + // only temporary + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the console genetic makeup buffer to + // create the makeup injector from. Expected as text string, converted to + // number later + // params["type"] - Type of injector to create + // Expected results: + // "ue" - Unique Enzyme, changes name and blood type + // "ui" - Unique Identity, changes looks + // "mixed" - Combination of both ue and ui + if("makeup_injector") + // Convert the index to a number and clamp within the array range, then + // copy the data from the disk to that buffer + var/buffer_index = text2num(params["index"]) + buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = genetic_makeup_buffer[buffer_index] + + // GUARD CHECK - This shouldn't be possible to execute this on a null + // buffer. Unexpected resut + if(!istype(buffer_slot)) + return + + var/type = params["type"] + var/obj/item/dnainjector/timed/I + + switch(type) + if("ui") + // GUARD CHECK - There's currently no way to save partial genetic data. + // However, if this is the case, we can't make a complete injector and + // this catches that edge case + if(!buffer_slot["UI"]) + to_chat(usr,"Genetic data corrupted, unable to create injector.") + return + + I = new /obj/item/dnainjector/timed(loc) + I.fields = list("UI"=buffer_slot["UI"]) + + // If there is a connected scanner, we can use its upgrades to reduce + // the radiation generated by this injector + if(scanner_operational()) + I.damage_coeff = connected_scanner.damage_coeff + if("ue") + // GUARD CHECK - There's currently no way to save partial genetic data. + // However, if this is the case, we can't make a complete injector and + // this catches that edge case + if(!buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) + to_chat(usr,"Genetic data corrupted, unable to create injector.") + return + + I = new /obj/item/dnainjector/timed(loc) + I.fields = list("name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) + + // If there is a connected scanner, we can use its upgrades to reduce + // the radiation generated by this injector + if(scanner_operational()) + I.damage_coeff = connected_scanner.damage_coeff + if("mixed") + // GUARD CHECK - There's currently no way to save partial genetic data. + // However, if this is the case, we can't make a complete injector and + // this catches that edge case + if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) + to_chat(usr,"Genetic data corrupted, unable to create injector.") + return + + I = new /obj/item/dnainjector/timed(loc) + I.fields = list("UI"=buffer_slot["UI"],"name"=buffer_slot["name"], "UE"=buffer_slot["UE"], "blood_type"=buffer_slot["blood_type"]) + + // If there is a connected scanner, we can use its upgrades to reduce + // the radiation generated by this injector + if(scanner_operational()) + I.damage_coeff = connected_scanner.damage_coeff + + // If we successfully created an injector, don't forget to set the new + // ready timer. + if(I) + injectorready = world.time + INJECTOR_TIMEOUT + + return + + // Applies a genetic makeup buffer to the scanner occupant + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the console genetic makeup buffer to + // apply to the scanner occupant. Expected as text string, converted to + // number later + // params["type"] - Type of genetic makeup copy to implement + // Expected results: + // "ue" - Unique Enzyme, changes name and blood type + // "ui" - Unique Identity, changes looks + // "mixed" - Combination of both ue and ui + if("makeup_apply") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + // Convert the index to a number and clamp within the array range, then + // copy the data from the disk to that buffer + var/buffer_index = text2num(params["index"]) + buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = genetic_makeup_buffer[buffer_index] + + // GUARD CHECK - This shouldn't be possible to execute this on a null + // buffer. Unexpected resut + if(!istype(buffer_slot)) + return + + var/type = params["type"] + + apply_genetic_makeup(type, buffer_slot) + return + + // Applies a genetic makeup buffer to the next scanner occupant. This sets + // some code that will run when the connected DNA Scanner door is next + // closed + // This allows people to self-modify their genetic makeup, as tgui + // interfaces can not be accessed while inside the DNA Scanner and genetic + // makeup injectors are only temporary + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the console genetic makeup buffer to + // apply to the scanner occupant. Expected as text string, converted to + // number later + // params["type"] - Type of genetic makeup copy to implement + // Expected results: + // "ue" - Unique Enzyme, changes name and blood type + // "ui" - Unique Identity, changes looks + // "mixed" - Combination of both ue and ui + if("makeup_delay") + // Convert the index to a number and clamp within the array range, then + // copy the data from the disk to that buffer + var/buffer_index = text2num(params["index"]) + buffer_index = clamp(buffer_index, 1, NUMBER_OF_BUFFERS) + var/list/buffer_slot = genetic_makeup_buffer[buffer_index] + + // GUARD CHECK - This shouldn't be possible to execute this on a null + // buffer. Unexpected resut + if(!istype(buffer_slot)) + return + + var/type = params["type"] + + // Set the delayed action. The next time the scanner door is closed, + // unless this is cancelled in the UI, the action will happen + delayed_action = list("type" = type, "buffer_slot" = buffer_slot) + return + + // Attempts to modify the indexed element of the Unique Identity string + // This is a time delayed action that is handled in process() + // ---------------------------------------------------------------------- // + // params["index"] - The BYOND index of the Unique Identity string to + // attempt to modify + if("makeup_pulse") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + if(!can_modify_occupant()) + return + + // Set the appropriate timer and index to pulse. This is then managed + // later on in process() + var/len = length_char(scanner_occupant.dna.uni_identity) + rad_pulse_timer = world.time + (radduration*10) + rad_pulse_index = WRAP(text2num(params["index"]), 1, len+1) + begin_processing() + return + + // Cancels the delayed action - In this context it is not the radiation + // pulse from "makeup_pulse", which can not be cancelled. It is instead + // the delayed genetic transfer from "makeup_delay" + if("cancel_delay") + delayed_action = null + return + + // Creates a new advanced injector storage buffer in the console + // ---------------------------------------------------------------------- // + // params["name"] - The name to apply to the new injector + if("new_adv_inj") + // GUARD CHECK - Make sure we can make a new injector. This code should + // not be called if we're already maxed out and this is an Unexpected + // result + if(!(LAZYLEN(injector_selection) < max_injector_selections)) + return + + // GUARD CHECK - Sanitise and trim the proposed name. This prevents HTML + // injection and equivalent as tgui input is not stripped + var/inj_name = params["name"] + inj_name = trim(sanitize(inj_name)) + + // GUARD CHECK - If the name is null or blank, or the name is already in + // the list of advanced injectors, we want to reject it as we can't have + // duplicate named advanced injectors + if(!inj_name || (inj_name in injector_selection)) + return + + injector_selection[inj_name] = list() + return + + // Deleted an advanced injector storage buffer from the console + // ---------------------------------------------------------------------- // + // params["name"] - The name of the injector to delete + if("del_adv_inj") + var/inj_name = params["name"] + + // GUARD CHECK - If the name is null or blank, reject. + // GUARD CHECK - If the name isn't in the list of advanced injectors, we + // want to reject this as it shouldn't be possible ever do this. + // Unexpected result + if(!inj_name || !(inj_name in injector_selection)) + return + + injector_selection.Remove(inj_name) + return + + // Creates an injector from an advanced injector buffer + // ---------------------------------------------------------------------- // + // params["name"] - The name of the injector to print + if("print_adv_inj") + // As a side note, because mutations can contain unique metadata, + // this system uses BYOND Atom Refs to safely and accurately + // identify mutations from big ol' lists. + + // GUARD CHECK - Is the injector actually ready? + if(world.time < injectorready) + return + + var/inj_name = params["name"] + + // GUARD CHECK - If the name is null or blank, reject. + // GUARD CHECK - If the name isn't in the list of advanced injectors, we + // want to reject this as it shouldn't be possible ever do this. + // Unexpected result + if(!inj_name || !(inj_name in injector_selection)) + return + + var/list/injector = injector_selection[inj_name] + var/obj/item/dnainjector/activator/I = new /obj/item/dnainjector/activator(loc) + + // Run through each mutation in our Advanced Injector and add them to a + // new injector + for(var/A in injector) + var/datum/mutation/human/HM = A + I.add_mutations += new HM.type(copymut=HM) + + // Force apply any mutations, this is functionality similar to mutators + I.doitanyway = TRUE + I.name = "Advanced [inj_name] injector" + + // If there's an operational connected scanner, we can use its upgrades + // to improve our injector's radiation generation + if(scanner_operational()) + I.damage_coeff = connected_scanner.damage_coeff + injectorready = world.time + INJECTOR_TIMEOUT * 8 * (1 - 0.1 * connected_scanner.precision_coeff) + else + injectorready = world.time + INJECTOR_TIMEOUT * 8 + + return + + // Adds a mutation to an advanced injector + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to add to the injector + // params["advinj"] - Name of the advanced injector to add the mutation to + if("add_advinj_mut") + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + // This is needed because this operation can only be completed from the + // genetic sequencer. + if(!can_modify_occupant()) + return + + var/adv_inj = params["advinj"] + + // GUARD CHECK - Make sure our advanced injector actually exists. This + // should not be possible. Unexpected result + if(!(adv_inj in injector_selection)) + return + + // GUARD CHECK - Make sure we limit the number of mutations appropriately + if(LAZYLEN(injector_selection[adv_inj]) >= max_injector_mutations) + to_chat(usr,"Advanced injector mutation storage is full.") + return + + var/mut_source = params["source"] + var/search_flag = 0 + + switch(mut_source) + if("disk") + search_flag = SEARCH_DISKETTE + if("occupant") + search_flag = SEARCH_OCCUPANT + if("console") + search_flag = SEARCH_STORED + + if(!search_flag) + return + + var/bref = params["mutref"] + // We've already made sure we can modify the occupant, so this is safe to + // call + var/datum/mutation/human/HM = get_mut_by_ref(bref, search_flag) + + // GUARD CHECK - This should not be possible. Unexpected result + if(!HM) + return + + // We want to make sure we stick within the instability limit. + // We start with the instability of the mutation we're intending to add. + var/instability_total = HM.instability + + // We then add the instabilities of all other mutations in the injector, + // remembering to apply the Stabilizer chromosome modifiers + for(var/datum/mutation/human/I in injector_selection[adv_inj]) + instability_total += I.instability * GET_MUTATION_STABILIZER(I) + + // If this would take us over the max instability, we inform the user. + if(instability_total > max_injector_instability) + to_chat(usr,"Extra mutation would make the advanced injector too instable.") + return + + // If we've got here, all our checks are passed and we can successfully + // add the mutation to the advanced injector. + var/datum/mutation/human/A = new HM.type() + A.copy_mutation(HM) + injector_selection[adv_inj] += A + to_chat(usr,"Mutation successfully added to advanced injector.") + return + + // Deletes a mutation from an advanced injector + // ---------------------------------------------------------------------- // + // params["mutref"] - ATOM Ref of specific mutation to del from the injector + if("delete_injector_mut") + var/bref = params["mutref"] + + var/datum/mutation/human/HM = get_mut_by_ref(bref, SEARCH_ADV_INJ) + + // GUARD CHECK - This should not be possible. Unexpected result + if(!HM) + return + + // Check Advanced Injectors to find and remove the mutation + for(var/I in injector_selection) + if(injector_selection["[I]"].Remove(HM)) + qdel(HM) + return + + return + + // Sets a new tgui view state + // ---------------------------------------------------------------------- // + // params["id"] - Key for the state to set + // params[...] - Every other element is used to set state variables + if("set_view") + for (var/key in params) + if(key == "src") + continue + tgui_view_state[key] = params[key] + return TRUE + return FALSE + +/** + * Applies the enzyme buffer to the current scanner occupant + * + * Applies the type of a specific genetic makeup buffer to the current scanner + * occupant + * + * Arguments: + * * type - "ui"/"ue"/"mixed" - Which part of the enzyme buffer to apply + * * buffer_slot - Index of the enzyme buffer to apply + */ +/obj/machinery/computer/scan_consolenew/proc/apply_genetic_makeup(type, buffer_slot) + // Note - This proc is only called from code that has already performed the + // necessary occupant guard checks. If you call this code yourself, please + // apply can_modify_occupant() or equivalent checks first. + + // Pre-calc the rad increase since we'll be using it in all the possible + // operations + var/rad_increase = rand(100/(connected_scanner.damage_coeff ** 2),250/(connected_scanner.damage_coeff ** 2)) + + switch(type) + if("ui") + // GUARD CHECK - There's currently no way to save partial genetic data. + // However, if this is the case, we can't make a complete injector and + // this catches that edge case + if(!buffer_slot["UI"]) + to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") + return FALSE + scanner_occupant.dna.uni_identity = buffer_slot["UI"] + scanner_occupant.updateappearance(mutations_overlay_update=1) + scanner_occupant.radiation += rad_increase + scanner_occupant.domutcheck() + return TRUE + if("ue") + // GUARD CHECK - There's currently no way to save partial genetic data. + // However, if this is the case, we can't make a complete injector and + // this catches that edge case + if(!buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) + to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") + return FALSE + scanner_occupant.real_name = buffer_slot["name"] + scanner_occupant.name = buffer_slot["name"] + scanner_occupant.dna.unique_enzymes = buffer_slot["UE"] + scanner_occupant.dna.blood_type = buffer_slot["blood_type"] + scanner_occupant.radiation += rad_increase + scanner_occupant.domutcheck() + return TRUE + if("mixed") + // GUARD CHECK - There's currently no way to save partial genetic data. + // However, if this is the case, we can't make a complete injector and + // this catches that edge case + if(!buffer_slot["UI"] || !buffer_slot["name"] || !buffer_slot["UE"] || !buffer_slot["blood_type"]) + to_chat(usr,"Genetic data corrupted, unable to apply genetic data.") + return FALSE + scanner_occupant.dna.uni_identity = buffer_slot["UI"] + scanner_occupant.updateappearance(mutations_overlay_update=1) + scanner_occupant.real_name = buffer_slot["name"] + scanner_occupant.name = buffer_slot["name"] + scanner_occupant.dna.unique_enzymes = buffer_slot["UE"] + scanner_occupant.dna.blood_type = buffer_slot["blood_type"] + scanner_occupant.radiation += rad_increase + scanner_occupant.domutcheck() + return TRUE + + return FALSE +/** + * Checks if there is a connected DNA Scanner that is operational + */ +/obj/machinery/computer/scan_consolenew/proc/scanner_operational() + if(!connected_scanner) + return FALSE + + return (connected_scanner && connected_scanner.is_operational()) + +/** + * Checks if there is a valid DNA Scanner occupant for genetic modification + * + * Checks if there is a valid subject in the DNA Scanner that can be genetically + * modified. Will set the scanner occupant var as part of this check. + * Requires that the scanner can be operated and will return early if it can't + */ +/obj/machinery/computer/scan_consolenew/proc/can_modify_occupant() + // GUARD CHECK - We always want to perform the scanner operational check as + // part of checking if we can modify the occupant. + // We can never modify the occupant of a broken scanner. + if(!scanner_operational()) + return FALSE + + if(!connected_scanner.occupant) + return FALSE + + scanner_occupant = connected_scanner.occupant + + // Check validity of occupent for DNA Modification + // DNA Modification: + // requires DNA + // this DNA can not be bad + // is done via radiation bursts, so radiation immune carbons are not viable + // And the DNA Scanner itself must have a valid scan level + if(scanner_occupant.has_dna() && !HAS_TRAIT(scanner_occupant, TRAIT_RADIMMUNE) && !HAS_TRAIT(scanner_occupant, TRAIT_BADDNA) || (connected_scanner.scan_level == 3)) + return TRUE + + return FALSE + +/** + * Checks for adjacent DNA scanners and connects when it finds a viable one + * + * Seearches cardinal directions in order. Stops when it finds a viable DNA Scanner. + * Will connect to a broken scanner if no functional scanner is available. + * Links itself to the DNA Scanner to receive door open and close events. + */ +/obj/machinery/computer/scan_consolenew/proc/connect_to_scanner() + var/obj/machinery/dna_scannernew/test_scanner = null + var/obj/machinery/dna_scannernew/broken_scanner = null + + // Look in each cardinal direction and try and find a DNA Scanner + // If you find a DNA Scanner, check to see if it broken or working + // If it's working, set the current scanner and return early + // If it's not working, remember it anyway as a broken scanner + for(var/direction in GLOB.cardinals) + test_scanner = locate(/obj/machinery/dna_scannernew, get_step(src, direction)) + if(!isnull(test_scanner)) + if(test_scanner.is_operational()) + connected_scanner = test_scanner + connected_scanner.linked_console = src + return + else + broken_scanner = test_scanner + + // Ultimately, if we have a broken scanner, we'll attempt to connect to it as + // a fallback case, but the code above will prefer a working scanner + if(!isnull(broken_scanner)) + connected_scanner = broken_scanner + connected_scanner.linked_console = src + +/** + * Called by connected DNA Scanners when their doors close. + * + * Sets the new scanner occupant and completes delayed enzyme transfer if one + * is queued. + */ +/obj/machinery/computer/scan_consolenew/proc/on_scanner_close() + // Set the appropriate occupant now the scanner is closed + if(connected_scanner.occupant) + scanner_occupant = connected_scanner.occupant + else + scanner_occupant = null + + // If we have a delayed action - In this case the only delayed action is + // applying a genetic makeup buffer the next time the DNA Scanner is closed - + // we want to perform it. + // GUARD CHECK - Make sure we can modify the occupant, apply_genetic_makeup() + // assumes we've already done this. + if(delayed_action && can_modify_occupant()) + var/type = delayed_action["type"] + var/buffer_slot = delayed_action["buffer_slot"] + if(apply_genetic_makeup(type, buffer_slot)) + to_chat(connected_scanner.occupant, "[src] activates!") + delayed_action = null + +/** + * Called by connected DNA Scanners when their doors open. + * + * Clears enzyme pulse operations, stops processing and nulls the current + * scanner occupant var. + */ +/obj/machinery/computer/scan_consolenew/proc/on_scanner_open() + // If we had a radiation pulse action ongoing, we want to stop this. + // Imagine it being like a microwave stopping when you open the door. + rad_pulse_index = 0 + rad_pulse_timer = 0 + end_processing() + scanner_occupant = null + +/** + * Builds the genetic makeup list which will be sent to tgui interface. + */ +/obj/machinery/computer/scan_consolenew/proc/build_genetic_makeup_list() + // No code will ever null this list, we can safely Cut it. + tgui_genetic_makeup.Cut() + + for(var/i=1, i <= NUMBER_OF_BUFFERS, i++) + if(genetic_makeup_buffer[i]) + tgui_genetic_makeup["[i]"] = genetic_makeup_buffer[i].Copy() + else + tgui_genetic_makeup["[i]"] = null + +/** + * Builds the genetic makeup list which will be sent to tgui interface. + * + * Will iterate over the connected scanner occupant, DNA Console, inserted + * diskette and chromosomes and any advanced injectors, building the main data + * structures which get passed to the tgui interface. + */ +/obj/machinery/computer/scan_consolenew/proc/build_mutation_list(can_modify_occ) + // No code will ever null these lists. We can safely Cut them. + tgui_occupant_mutations.Cut() + tgui_diskette_mutations.Cut() + tgui_console_mutations.Cut() + tgui_console_chromosomes.Cut() + tgui_advinjector_mutations.Cut() + + // ------------------------------------------------------------------------ // + // GUARD CHECK - Can we genetically modify the occupant? This check will have + // previously included checks to make sure the DNA Scanner is still + // operational + if(can_modify_occ) + // ---------------------------------------------------------------------- // + // Start cataloguing all mutations that the occupant has by default + for(var/mutation_type in scanner_occupant.dna.mutation_index) + var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(mutation_type) + + var/list/mutation_data = list() + var/text_sequence = scanner_occupant.dna.mutation_index[mutation_type] + var/default_sequence = scanner_occupant.dna.default_mutation_genes[mutation_type] + var/discovered = (stored_research && (mutation_type in stored_research.discovered_mutations)) + + mutation_data["Alias"] = HM.alias + mutation_data["Sequence"] = text_sequence + mutation_data["DefaultSeq"] = default_sequence + mutation_data["Discovered"] = discovered + mutation_data["Source"] = "occupant" + + // We only want to pass this information along to the tgui interface if + // the mutation has been discovered. Prevents people being able to cheese + // or "hack" their way to figuring out what undiscovered mutations are + if(discovered) + mutation_data["Name"] = HM.name + mutation_data["Description"] = HM.desc + mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) + mutation_data["Quality"] = HM.quality + + // Assume the mutation is normal unless assigned otherwise. + var/mut_class = MUT_NORMAL + + // Check if the mutation is currently activated. If it is, we can add even + // MORE information to send to tgui. + var/datum/mutation/human/A = scanner_occupant.dna.get_mutation(mutation_type) + if(A) + mutation_data["Active"] = TRUE + mutation_data["Scrambled"] = A.scrambled + mutation_data["Class"] = A.class + mut_class = A.class + mutation_data["CanChromo"] = A.can_chromosome + mutation_data["ByondRef"] = REF(A) + mutation_data["Type"] = A.type + if(A.can_chromosome) + mutation_data["ValidChromos"] = jointext(A.valid_chrom_list, ", ") + mutation_data["AppliedChromo"] = A.chromosome_name + mutation_data["ValidStoredChromos"] = build_chrom_list(A) + else + mutation_data["Active"] = FALSE + mutation_data["Scrambled"] = FALSE + mutation_data["Class"] = MUT_NORMAL + + // Technically NONE of these mutations should be MUT_EXTRA but this will + // catch any weird edge cases + // Assign icons by priority - MUT_EXTRA will ALSO be discovered, so it + // has a higher priority for icon/image assignment + if (mut_class == MUT_EXTRA) + mutation_data["Image"] = "dna_extra.gif" + else if(discovered) + mutation_data["Image"] = "dna_discovered.gif" + else + mutation_data["Image"] = "dna_undiscovered.gif" + + tgui_occupant_mutations += list(mutation_data) + + // ---------------------------------------------------------------------- // + // Now get additional/"extra" mutations that they shouldn't have by default + for(var/datum/mutation/human/HM in scanner_occupant.dna.mutations) + // If it's in the mutation index array, we've already catalogued this + // mutation and can safely skip over it. It really shouldn't be, but this + // will catch any weird edge cases + if(HM.type in scanner_occupant.dna.mutation_index) + continue + + var/list/mutation_data = list() + var/text_sequence = GET_SEQUENCE(HM.type) + + // These will all be active mutations. They're added by injector and their + // sequencing code can't be changed. They can only be nullified, which + // completely removes them. + var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) + + mutation_data["Alias"] = A.alias + mutation_data["Sequence"] = text_sequence + mutation_data["Discovered"] = TRUE + mutation_data["Quality"] = HM.quality + mutation_data["Source"] = "occupant" + + mutation_data["Name"] = HM.name + mutation_data["Description"] = HM.desc + mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) + + mutation_data["Active"] = TRUE + mutation_data["Scrambled"] = HM.scrambled + mutation_data["Class"] = HM.class + mutation_data["CanChromo"] = HM.can_chromosome + mutation_data["ByondRef"] = REF(HM) + mutation_data["Type"] = HM.type + + if(HM.can_chromosome) + mutation_data["ValidChromos"] = jointext(HM.valid_chrom_list, ", ") + mutation_data["AppliedChromo"] = HM.chromosome_name + mutation_data["ValidStoredChromos"] = build_chrom_list(HM) + + // Nothing in this list should be undiscovered. Technically nothing + // should be anything but EXTRA. But we're just handling some edge cases. + if (HM.class == MUT_EXTRA) + mutation_data["Image"] = "dna_extra.gif" + else + mutation_data["Image"] = "dna_discovered.gif" + + tgui_occupant_mutations += list(mutation_data) + + // ------------------------------------------------------------------------ // + // Build the list of mutations stored within the DNA Console + for(var/datum/mutation/human/HM in stored_mutations) + var/list/mutation_data = list() + + var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) + + mutation_data["Alias"] = A.alias + mutation_data["Name"] = HM.name + mutation_data["Source"] = "console" + mutation_data["Active"] = TRUE + mutation_data["Description"] = HM.desc + mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) + mutation_data["ByondRef"] = REF(HM) + mutation_data["Type"] = HM.type + + mutation_data["CanChromo"] = HM.can_chromosome + if(HM.can_chromosome) + mutation_data["ValidChromos"] = jointext(HM.valid_chrom_list, ", ") + mutation_data["AppliedChromo"] = HM.chromosome_name + mutation_data["ValidStoredChromos"] = build_chrom_list(HM) + + tgui_console_mutations += list(mutation_data) + + // ------------------------------------------------------------------------ // + // Build the list of chromosomes stored within the DNA Console + var/chrom_index = 1 + for(var/obj/item/chromosome/CM in stored_chromosomes) + var/list/chromo_data = list() + + chromo_data["Name"] = CM.name + chromo_data["Description"] = CM.desc + chromo_data["Index"] = chrom_index + + tgui_console_chromosomes += list(chromo_data) + ++chrom_index + + // ------------------------------------------------------------------------ // + // Build the list of mutations stored on any inserted diskettes + if(diskette) + for(var/datum/mutation/human/HM in diskette.mutations) + var/list/mutation_data = list() + + var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) + + mutation_data["Alias"] = A.alias + mutation_data["Name"] = HM.name + mutation_data["Active"] = TRUE + //mutation_data["Sequence"] = GET_SEQUENCE(HM.type) + mutation_data["Source"] = "disk" + mutation_data["Description"] = HM.desc + mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) + mutation_data["ByondRef"] = REF(HM) + mutation_data["Type"] = HM.type + + mutation_data["CanChromo"] = HM.can_chromosome + if(HM.can_chromosome) + mutation_data["ValidChromos"] = jointext(HM.valid_chrom_list, ", ") + mutation_data["AppliedChromo"] = HM.chromosome_name + mutation_data["ValidStoredChromos"] = build_chrom_list(HM) + + tgui_diskette_mutations += list(mutation_data) + + // ------------------------------------------------------------------------ // + // Build the list of mutations stored within any Advanced Injectors + if(LAZYLEN(injector_selection)) + for(var/I in injector_selection) + var/list/mutations = list() + for(var/datum/mutation/human/HM in injector_selection[I]) + var/list/mutation_data = list() + + var/datum/mutation/human/A = GET_INITIALIZED_MUTATION(HM.type) + + mutation_data["Alias"] = A.alias + mutation_data["Name"] = HM.name + mutation_data["Active"] = TRUE + //mutation_data["Sequence"] = GET_SEQUENCE(HM.type) + mutation_data["Source"] = "injector" + mutation_data["Description"] = HM.desc + mutation_data["Instability"] = HM.instability * GET_MUTATION_STABILIZER(HM) + mutation_data["ByondRef"] = REF(HM) + mutation_data["Type"] = HM.type + + if(HM.can_chromosome) + mutation_data["AppliedChromo"] = HM.chromosome_name + + mutations += list(mutation_data) + tgui_advinjector_mutations += list(list( + "name" = "[I]", + "mutations" = mutations, + )) + +/** + * Takes any given chromosome and calculates chromosome compatibility + * + * Will iterate over the stored chromosomes in the DNA Console and will check + * whether it can be applied to the supplied mutation. Then returns a list of + * names of chromosomes that were compatible. + * + * Arguments: + * * mutation - The mutation to check chromosome compatibility with + */ +/obj/machinery/computer/scan_consolenew/proc/build_chrom_list(mutation) + var/list/chromosomes = list() + + for(var/obj/item/chromosome/CM in stored_chromosomes) + if(CM.can_apply(mutation)) + chromosomes += CM.name + + return chromosomes + +/** + * Checks whether a mutation alias has been discovered + * + * Checks whether a given mutation's genetic sequence has been completed and + * discovers it if appropriate + * + * Arguments: + * * alias - Alias of the mutation to check (ie "Mutation 51" or "Mutation 12") + */ +/obj/machinery/computer/scan_consolenew/proc/check_discovery(alias) + // Note - All code paths that call this have already done checks on the + // current occupant to prevent cheese and other abuses. If you call this + // proc please also do the following checks first: + // if(!can_modify_occupant()) + // return + // if(!(scanner_occupant == connected_scanner.occupant)) + // return + + // Turn the alias ("Mutation 1", "Mutation 35") into a mutation path + var/path = GET_MUTATION_TYPE_FROM_ALIAS(alias) + + // Check to see if this mutation is in the active mutation list. If it isn't, + // then the mutation isn't eligible for discovery. If it is but is scrambled, + // then the mutation isn't eligible for discovery. Finally, check if the + // mutation is in discovered mutations - If it isn't, add it to discover. + var/datum/mutation/human/M = scanner_occupant.dna.get_mutation(path) + if(!M) + return FALSE + if(M.scrambled) + return FALSE + if(stored_research && !(path in stored_research.discovered_mutations)) + var/datum/mutation/human/HM = GET_INITIALIZED_MUTATION(path) + stored_research.discovered_mutations += path + say("Successfully discovered [HM.name].") + return TRUE + + return FALSE + +/** + * Find a mutation from various storage locations via ATOM ref + * + * Takes an ATOM Ref and searches the appropriate mutation buffers and storage + * vars to try and find the associated mutation. + * + * Arguments: + * * ref - ATOM ref of the mutation to locate + * * target_flags - Flags for storage mediums to search, see #defines + */ +/obj/machinery/computer/scan_consolenew/proc/get_mut_by_ref(ref, target_flags) + var/mutation + + // Assume the occupant is valid and the check has been carried out before + // calling this proc with the relevant flags. + if(target_flags & SEARCH_OCCUPANT) + mutation = (locate(ref) in scanner_occupant.dna.mutations) + if(mutation) + return mutation + + if(target_flags & SEARCH_STORED) + mutation = (locate(ref) in stored_mutations) + if(mutation) + return mutation + + if(diskette && (target_flags & SEARCH_DISKETTE)) + mutation = (locate(ref) in diskette.mutations) + if(mutation) + return mutation + + if(injector_selection && (target_flags & SEARCH_ADV_INJ)) + for(var/I in injector_selection) + mutation = (locate(ref) in injector_selection["[I]"]) + if(mutation) + return mutation + + return null + +/** + * Creates a randomised accuracy value for the enzyme pulse functionality. + * + * Donor code from previous DNA Console iteration. + * + * Arguments: + * * position - Index of the intended enzyme element to pulse + * * radduration - Duration of intended radiation pulse + * * number_of_blocks - Number of individual data blocks in the pulsed enzyme + */ +/obj/machinery/computer/scan_consolenew/proc/randomize_radiation_accuracy(position, radduration, number_of_blocks) + var/val = round(gaussian(0, RADIATION_ACCURACY_MULTIPLIER/radduration) + position, 1) + return WRAP(val, 1, number_of_blocks+1) + +/** + * Scrambles an enzyme element value for the enzyme pulse functionality. + * + * Donor code from previous DNA Console iteration. + * + * Arguments: + * * input - Enzyme identity element to scramble, expected hex value + * * rs - Strength of radiation pulse, increases the range of possible outcomes + */ +/obj/machinery/computer/scan_consolenew/proc/scramble(input,rs) + var/length = length(input) + var/ran = gaussian(0, rs*RADIATION_STRENGTH_MULTIPLIER) + if(ran == 0) + ran = pick(-1,1) //hacky, statistically should almost never happen. 0-chance makes people mad though + else if(ran < 0) + ran = round(ran) //negative, so floor it + else + ran = -round(-ran) //positive, so ceiling it + return num2hex(WRAP(hex2num(input)+ran, 0, 16**length), length) + + /** + * Performs the enzyme radiation pulse. + * + * Donor code from previous DNA Console iteration. Called from process() when + * there is a radiation pulse in progress. Ends processing. + */ +/obj/machinery/computer/scan_consolenew/proc/rad_pulse() + // GUARD CHECK - Can we genetically modify the occupant? Includes scanner + // operational guard checks. + // If we can't, abort the procedure. + if(!can_modify_occupant()) + rad_pulse_index = 0 + end_processing() + return + + var/len = length_char(scanner_occupant.dna.uni_identity) + var/num = randomize_radiation_accuracy(rad_pulse_index, radduration + (connected_scanner.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2 //Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low + var/hex = copytext_char(scanner_occupant.dna.uni_identity, num, num+1) + hex = scramble(hex, radstrength, radduration) + + scanner_occupant.dna.uni_identity = copytext_char(scanner_occupant.dna.uni_identity, 1, num) + hex + copytext_char(scanner_occupant.dna.uni_identity, num + 1) + scanner_occupant.updateappearance(mutations_overlay_update=1) + + rad_pulse_index = 0 + end_processing() + return + +/** + * Sets the default state for the tgui interface. + */ +/obj/machinery/computer/scan_consolenew/proc/set_default_state() + tgui_view_state["consoleMode"] = "storage" + tgui_view_state["storageMode"] = "console" + tgui_view_state["storageConsSubMode"] = "mutations" + tgui_view_state["storageDiskSubMode"] = "mutations" + + +#undef INJECTOR_TIMEOUT +#undef NUMBER_OF_BUFFERS +#undef SCRAMBLE_TIMEOUT +#undef JOKER_TIMEOUT +#undef JOKER_UPGRADE + +#undef RADIATION_STRENGTH_MAX +#undef RADIATION_STRENGTH_MULTIPLIER + +#undef RADIATION_DURATION_MAX +#undef RADIATION_ACCURACY_MULTIPLIER + +#undef RADIATION_IRRADIATION_MULTIPLIER + +#undef STATUS_TRANSFORMING + +#undef SEARCH_OCCUPANT +#undef SEARCH_STORED +#undef SEARCH_DISKETTE +#undef SEARCH_ADV_INJ diff --git a/code/game/machinery/computer/launchpad_control.dm b/code/game/machinery/computer/launchpad_control.dm index 26efe7c4ba0..9b7d73f48e0 100644 --- a/code/game/machinery/computer/launchpad_control.dm +++ b/code/game/machinery/computer/launchpad_control.dm @@ -56,7 +56,7 @@ /obj/machinery/computer/launchpad/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "launchpad_console", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Launchpad", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/launchpad/ui_data(mob/user) diff --git a/code/game/machinery/computer/prisoner/gulag_teleporter.dm b/code/game/machinery/computer/prisoner/gulag_teleporter.dm index 9da901cd20e..6cb6a1d34ed 100644 --- a/code/game/machinery/computer/prisoner/gulag_teleporter.dm +++ b/code/game/machinery/computer/prisoner/gulag_teleporter.dm @@ -25,7 +25,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "gulag_console", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "GulagTeleporterConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_data(mob/user) diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm index 917d6f9f7af..115b827e54e 100644 --- a/code/game/machinery/computer/robot.dm +++ b/code/game/machinery/computer/robot.dm @@ -27,7 +27,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "robotics_control_console", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "RoboticsControlConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/robotics/ui_data(mob/user) diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 1cab2bd0456..ab42b16d8ae 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -22,7 +22,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "station_alert", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "StationAlertConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/station_alert/ui_data(mob/user) diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm index 4028a1347aa..1e85a6d76f5 100644 --- a/code/game/machinery/computer/teleporter.dm +++ b/code/game/machinery/computer/teleporter.dm @@ -37,7 +37,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "teleporter", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Teleporter", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/teleporter/ui_data(mob/user) diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 8cb7502d6cb..288fdfab112 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1323,7 +1323,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ai_airlock", name, 500, 390, master_ui, state) + ui = new(user, src, ui_key, "AiAirlock", name, 500, 390, master_ui, state) ui.open() return TRUE diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index e1b826ffeee..6d4e055bbd5 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -15,7 +15,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "airlock_electronics", name, 420, 485, master_ui, state) + ui = new(user, src, ui_key, "AirlockElectronics", name, 420, 485, master_ui, state) ui.open() /obj/item/electronics/airlock/ui_static_data(mob/user) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 4e5fa5f48ae..315ef79b289 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -146,7 +146,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "brig_timer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "BrigTimer", name, ui_x, ui_y, master_ui, state) ui.open() //icon update function diff --git a/code/game/machinery/gulag_item_reclaimer.dm b/code/game/machinery/gulag_item_reclaimer.dm index c872fa661a7..98f9a304f72 100644 --- a/code/game/machinery/gulag_item_reclaimer.dm +++ b/code/game/machinery/gulag_item_reclaimer.dm @@ -31,7 +31,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "gulag_item_reclaimer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "GulagItemReclaimer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/gulag_item_reclaimer/ui_data(mob/user) diff --git a/code/game/machinery/hypnochair.dm b/code/game/machinery/hypnochair.dm index ff8f1698d65..670d8f758c3 100644 --- a/code/game/machinery/hypnochair.dm +++ b/code/game/machinery/hypnochair.dm @@ -37,7 +37,7 @@ /obj/machinery/hypnochair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "hypnochair", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "HypnoChair", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/hypnochair/ui_data() diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 265832a6a74..2776c05da9e 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -324,7 +324,7 @@ /obj/item/launchpad_remote/ui_interact(mob/user, ui_key = "launchpad_remote", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "launchpad_remote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height + ui = new(user, src, ui_key, "Launchpad", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height ui.set_style("syndicate") ui.open() diff --git a/code/game/machinery/medical_kiosk.dm b/code/game/machinery/medical_kiosk.dm index b71b7e59572..a75812eefea 100644 --- a/code/game/machinery/medical_kiosk.dm +++ b/code/game/machinery/medical_kiosk.dm @@ -172,7 +172,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "medical_kiosk", name, 625, 550, master_ui, state) + ui = new(user, src, ui_key, "MedicalKiosk", name, 625, 550, master_ui, state) ui.open() icon_state = "kiosk_off" RefreshParts() diff --git a/code/game/machinery/roulette_machine.dm b/code/game/machinery/roulette_machine.dm index 6407b0e8b62..76e502db17c 100644 --- a/code/game/machinery/roulette_machine.dm +++ b/code/game/machinery/roulette_machine.dm @@ -65,7 +65,7 @@ return ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "roulette", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Roulette", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/roulette/ui_data(mob/user) diff --git a/code/game/machinery/scan_gate.dm b/code/game/machinery/scan_gate.dm index 8eaff2478d4..334557a814a 100644 --- a/code/game/machinery/scan_gate.dm +++ b/code/game/machinery/scan_gate.dm @@ -184,7 +184,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "scanner_gate", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ScannerGate", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/scanner_gate/ui_data() diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 888e627482e..b9632c9a6a6 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -174,7 +174,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "space_heater", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "SpaceHeater", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/space_heater/ui_data() diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 9ab6c8ec855..c6e97bc2b64 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -438,7 +438,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "suit_storage_unit", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "SuitStorageUnit", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/suit_storage_unit/ui_data() diff --git a/code/game/mecha/mech_bay.dm b/code/game/mecha/mech_bay.dm index b9d3912852c..36f17f281c1 100644 --- a/code/game/mecha/mech_bay.dm +++ b/code/game/mecha/mech_bay.dm @@ -94,7 +94,7 @@ /obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "MechBayPowerConsole", "Mech Bay Power Control Console", ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/mech_bay_power_console/ui_act(action, params) diff --git a/code/game/mecha/mecha_control_console.dm b/code/game/mecha/mecha_control_console.dm index 3a9cb26f50e..9c52797129e 100644 --- a/code/game/mecha/mecha_control_console.dm +++ b/code/game/mecha/mecha_control_console.dm @@ -12,7 +12,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "exosuit_control_console", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ExosuitControlConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/mecha/ui_data(mob/user) diff --git a/code/game/objects/items/RPD.dm b/code/game/objects/items/RPD.dm index de7f7984847..f72a8189e63 100644 --- a/code/game/objects/items/RPD.dm +++ b/code/game/objects/items/RPD.dm @@ -248,7 +248,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list( var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes) assets.send(user) - ui = new(user, src, ui_key, "rpd", name, 425, 515, master_ui, state) + ui = new(user, src, ui_key, "RapidPipeDispenser", name, 425, 515, master_ui, state) ui.open() /obj/item/pipe_dispenser/ui_data(mob/user) diff --git a/code/game/objects/items/airlock_painter.dm b/code/game/objects/items/airlock_painter.dm index 75f36289907..94fd0a910dd 100644 --- a/code/game/objects/items/airlock_painter.dm +++ b/code/game/objects/items/airlock_painter.dm @@ -200,7 +200,7 @@ /obj/item/airlock_painter/decal/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "decal_painter", name, 500, 400, master_ui, state) + ui = new(user, src, ui_key, "DecalPainter", name, 500, 400, master_ui, state) ui.open() /obj/item/airlock_painter/decal/ui_data(mob/user) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 1d8dafd4ff9..8fab41ecf24 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -149,7 +149,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "crayon", name, 600, 600, + ui = new(user, src, ui_key, "Crayon", name, 600, 600, master_ui, state) ui.open() diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index 5500bcd1ab1..ee9730d8601 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -58,7 +58,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "intellicard", name, 500, 500, master_ui, state) + ui = new(user, src, ui_key, "Intellicard", name, 500, 500, master_ui, state) ui.open() /obj/item/aicard/ui_data() diff --git a/code/game/objects/items/devices/radio/electropack.dm b/code/game/objects/items/devices/radio/electropack.dm index de4623298cb..f574aaea16b 100644 --- a/code/game/objects/items/devices/radio/electropack.dm +++ b/code/game/objects/items/devices/radio/electropack.dm @@ -89,7 +89,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "electropack", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Electropack", name, ui_x, ui_y, master_ui, state) ui.open() /obj/item/electropack/ui_data(mob/user) diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index 14801f6f496..ea218cd5146 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -118,7 +118,7 @@ ui_height += 6 + channels.len * 21 else ui_height += 24 - ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state) + ui = new(user, src, ui_key, "Radio", name, ui_width, ui_height, master_ui, state) ui.open() /obj/item/radio/ui_data(mob/user) diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index 1be9024bcb2..d16cb5aa181 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -116,7 +116,7 @@ effective or pretty fucking useless. datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "radioactive_microlaser", "Radioactive Microlaser", ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "RadioactiveMicrolaser", "Radioactive Microlaser", ui_x, ui_y, master_ui, state) ui.open() /obj/item/healthanalyzer/rad_laser/ui_data(mob/user) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 6258d0d41c6..a800a9e49fb 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -197,7 +197,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "transfer_valve", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "TransferValve", name, ui_x, ui_y, master_ui, state) ui.open() /obj/item/transfer_valve/ui_data(mob/user) diff --git a/code/game/objects/items/eightball.dm b/code/game/objects/items/eightball.dm index 210c0846307..775fdd04468 100644 --- a/code/game/objects/items/eightball.dm +++ b/code/game/objects/items/eightball.dm @@ -196,7 +196,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "eightball", name, 400, 600, master_ui, state) + ui = new(user, src, ui_key, "EightBallVote", name, 400, 600, master_ui, state) ui.open() /obj/item/toy/eightball/haunted/ui_data(mob/user) diff --git a/code/game/objects/items/tanks/tanks.dm b/code/game/objects/items/tanks/tanks.dm index 015add093bc..5803882e3be 100644 --- a/code/game/objects/items/tanks/tanks.dm +++ b/code/game/objects/items/tanks/tanks.dm @@ -145,7 +145,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "tanks", name, 400, 120, master_ui, state) + ui = new(user, src, ui_key, "Tank", name, 400, 120, master_ui, state) ui.open() /obj/item/tank/ui_data(mob/user) diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index 8f120e3d309..627a41349eb 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -80,7 +80,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "canvas", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Canvas", name, ui_x, ui_y, master_ui, state) ui.set_autoupdate(FALSE) ui.open() diff --git a/code/game/objects/structures/tank_dispenser.dm b/code/game/objects/structures/tank_dispenser.dm index cc76a9975e3..1988510b7b8 100644 --- a/code/game/objects/structures/tank_dispenser.dm +++ b/code/game/objects/structures/tank_dispenser.dm @@ -71,7 +71,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "tank_dispenser", name, 275, 103, master_ui, state) + ui = new(user, src, ui_key, "TankDispenser", name, 275, 103, master_ui, state) ui.open() /obj/structure/tank_dispenser/ui_data(mob/user) diff --git a/code/modules/NTNet/relays.dm b/code/modules/NTNet/relays.dm index 43c6334d65b..6289158901e 100644 --- a/code/modules/NTNet/relays.dm +++ b/code/modules/NTNet/relays.dm @@ -69,7 +69,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ntnet_relay", "NTNet Quantum Relay", ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "NtnetRelay", "NTNet Quantum Relay", ui_x, ui_y, master_ui, state) ui.open() diff --git a/code/modules/admin/verbs/borgpanel.dm b/code/modules/admin/verbs/borgpanel.dm index 671db413779..cbee1a066a5 100644 --- a/code/modules/admin/verbs/borgpanel.dm +++ b/code/modules/admin/verbs/borgpanel.dm @@ -36,7 +36,7 @@ /datum/borgpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.admin_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "borgopanel", "Borg Panel", 700, 700, master_ui, state) + ui = new(user, src, ui_key, "BorgPanel", "Borg Panel", 700, 700, master_ui, state) ui.open() /datum/borgpanel/ui_data(mob/user) diff --git a/code/modules/antagonists/changeling/cellular_emporium.dm b/code/modules/antagonists/changeling/cellular_emporium.dm index 57346397c7b..bc433ef0cbb 100644 --- a/code/modules/antagonists/changeling/cellular_emporium.dm +++ b/code/modules/antagonists/changeling/cellular_emporium.dm @@ -16,7 +16,7 @@ /datum/cellular_emporium/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "cellular_emporium", name, 900, 480, master_ui, state) + ui = new(user, src, ui_key, "CellularEmporium", name, 900, 480, master_ui, state) ui.open() /datum/cellular_emporium/ui_data(mob/user) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index c49c8f2621e..1d7c0bd5458 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -264,7 +264,7 @@ /obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state=GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "nuclear_bomb", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "NuclearBomb", name, ui_x, ui_y, master_ui, state) ui.set_style(ui_style) ui.open() diff --git a/code/modules/antagonists/traitor/equipment/module_picker.dm b/code/modules/antagonists/traitor/equipment/module_picker.dm index 738bf46aab2..ce0062890cb 100644 --- a/code/modules/antagonists/traitor/equipment/module_picker.dm +++ b/code/modules/antagonists/traitor/equipment/module_picker.dm @@ -34,7 +34,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "malfunction_module_picker", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "MalfunctionModulePicker", name, ui_x, ui_y, master_ui, state) ui.open() /datum/module_picker/ui_data(mob/user) diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 4cbd667f600..9e5da7038bb 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -192,7 +192,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "infrared_emitter", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "InfraredEmitter", name, ui_x, ui_y, master_ui, state) ui.open() /obj/item/assembly/infra/ui_data(mob/user) diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 2bc4c3e19fc..285d9c3599e 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -119,7 +119,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "proximity_sensor", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ProximitySensor", name, ui_x, ui_y, master_ui, state) ui.open() /obj/item/assembly/prox_sensor/ui_data(mob/user) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 7da4fb7bbc9..c4108e061f1 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -73,7 +73,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "signaler", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Signaler", name, ui_x, ui_y, master_ui, state) ui.open() /obj/item/assembly/signaler/ui_data(mob/user) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 6dda7ff00e0..2ebc929eb65 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -94,7 +94,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "timer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Timer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/item/assembly/timer/ui_data(mob/user) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index e721f32f393..4d930fa2a76 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -244,7 +244,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "airalarm", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AirAlarm", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/airalarm/ui_data(mob/user) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 75061a4aa2d..35a8e33deda 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -28,13 +28,13 @@ Passive gate is similar to the regular pump except: ui_x = 335 ui_y = 115 - + /obj/machinery/atmospherics/components/binary/passive_gate/CtrlClick(mob/user) if(can_interact(user)) on = !on update_icon() return ..() - + /obj/machinery/atmospherics/components/binary/passive_gate/AltClick(mob/user) if(can_interact(user)) target_pressure = MAX_OUTPUT_PRESSURE @@ -106,7 +106,7 @@ Passive gate is similar to the regular pump except: datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_pump", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/binary/passive_gate/ui_data() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 9d6f6b82cab..b300cadbdfe 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -100,7 +100,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_pump", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/binary/pump/ui_data() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index c33336758f4..65891612503 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -113,7 +113,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_pump", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/binary/volume_pump/ui_data() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 75bb2355414..f1fc9ee0b67 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -123,7 +123,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_filter", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosFilter", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/trinary/filter/ui_data() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 326c978f308..83de28843fc 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -129,7 +129,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_mixer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosMixer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/trinary/mixer/ui_data() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index b3eb35e2ef8..56376e1bdfc 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -333,7 +333,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "cryo", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Cryo", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/unary/cryo_cell/ui_data() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index c3ffa680239..6d0d3b4c4b1 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -25,7 +25,7 @@ ui_x = 310 ui_y = 115 - + /obj/machinery/atmospherics/components/unary/outlet_injector/CtrlClick(mob/user) if(can_interact(user)) on = !on @@ -146,7 +146,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "atmos_pump", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "AtmosPump", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/unary/outlet_injector/ui_data() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 267530f10a7..53325f5a6dd 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -127,7 +127,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "thermomachine", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ThermoMachine", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/atmospherics/components/unary/thermomachine/ui_data(mob/user) diff --git a/code/modules/atmospherics/machinery/portable/canister.dm b/code/modules/atmospherics/machinery/portable/canister.dm index 2273db86746..a86c90bd140 100644 --- a/code/modules/atmospherics/machinery/portable/canister.dm +++ b/code/modules/atmospherics/machinery/portable/canister.dm @@ -399,7 +399,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "canister", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Canister", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/portable_atmospherics/canister/ui_data() diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index d3768d3d216..c468e9489e3 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -87,7 +87,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "portable_pump", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "PortableAtmos", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/portable_atmospherics/pump/ui_data() diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 9729f6c4980..7f205ae9808 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -78,7 +78,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "portable_scrubber", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "PortableAtmos", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/portable_atmospherics/scrubber/ui_data() diff --git a/code/modules/awaymissions/gateway.dm b/code/modules/awaymissions/gateway.dm index 0164d188d36..2f7ae0f9065 100644 --- a/code/modules/awaymissions/gateway.dm +++ b/code/modules/awaymissions/gateway.dm @@ -279,7 +279,7 @@ GLOBAL_LIST_EMPTY(gateway_destinations) . = ..() ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "gateway", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Gateway", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/gateway_control/ui_data(mob/user) diff --git a/code/modules/cargo/blackmarket/blackmarket_uplink.dm b/code/modules/cargo/blackmarket/blackmarket_uplink.dm index 35ba17e2418..453294b44c2 100644 --- a/code/modules/cargo/blackmarket/blackmarket_uplink.dm +++ b/code/modules/cargo/blackmarket/blackmarket_uplink.dm @@ -58,7 +58,7 @@ /obj/item/blackmarket_uplink/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "blackmarket_uplink", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "BlackmarketUplink", name, ui_x, ui_y, master_ui, state) ui.open() /obj/item/blackmarket_uplink/ui_data(mob/user) diff --git a/code/modules/cargo/centcom_podlauncher.dm b/code/modules/cargo/centcom_podlauncher.dm index 52310187939..7c6aa16c5dd 100644 --- a/code/modules/cargo/centcom_podlauncher.dm +++ b/code/modules/cargo/centcom_podlauncher.dm @@ -56,7 +56,7 @@ force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.adm ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "centcom_podlauncher", "Config/Launch Supplypod", 700, 700, master_ui, state) + ui = new(user, src, ui_key, "CentcomPodLauncher", "Config/Launch Supplypod", 700, 700, master_ui, state) ui.open() /datum/centcom_podlauncher/ui_data(mob/user) //Sends info about the pod to the UI. diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index e8bf847b499..c07abe8f104 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -68,7 +68,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "cargo", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Cargo", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/cargo/ui_data() diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index af01a824684..440c0dcbcd4 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -91,7 +91,7 @@ /obj/machinery/computer/cargo/express/ui_interact(mob/living/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) // Remember to use the appropriate state. ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "cargo_express", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "CargoExpress", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/cargo/express/ui_data(mob/user) diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm index a856efc601a..0db4cde1d4a 100644 --- a/code/modules/events/pirates.dm +++ b/code/modules/events/pirates.dm @@ -291,7 +291,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "cargo_hold_terminal", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "CargoHoldTerminal", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/piratepad_control/ui_data(mob/user) diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 033a9729f32..db5f1b747d6 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -165,7 +165,7 @@ /obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "smartvend", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "SmartVend", name, ui_x, ui_y, master_ui, state) ui.set_autoupdate(FALSE) ui.open() diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm index cbb7abf67df..e30eb171a08 100644 --- a/code/modules/holodeck/computer.dm +++ b/code/modules/holodeck/computer.dm @@ -84,7 +84,7 @@ /obj/machinery/computer/holodeck/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "holodeck", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Holodeck", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/holodeck/ui_data(mob/user) diff --git a/code/modules/language/language_menu.dm b/code/modules/language/language_menu.dm index a7ce211a187..0df7c01fca8 100644 --- a/code/modules/language/language_menu.dm +++ b/code/modules/language/language_menu.dm @@ -11,7 +11,7 @@ /datum/language_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.language_menu_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "language_menu", "Language Menu", 700, 600, master_ui, state) + ui = new(user, src, ui_key, "LanguageMenu", "Language Menu", 700, 600, master_ui, state) ui.open() /datum/language_menu/ui_data(mob/user) diff --git a/code/modules/library/lib_codex_gigas.dm b/code/modules/library/lib_codex_gigas.dm index 598d375888c..e7bb86ff799 100644 --- a/code/modules/library/lib_codex_gigas.dm +++ b/code/modules/library/lib_codex_gigas.dm @@ -95,7 +95,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "codex_gigas", name, 450, 450, master_ui, state) + ui = new(user, src, ui_key, "CodexGigas", name, 450, 450, master_ui, state) ui.open() /obj/item/book/codex_gigas/ui_data(mob/user) diff --git a/code/modules/library/soapstone.dm b/code/modules/library/soapstone.dm index 8c37a8645b7..3f1ea429e54 100644 --- a/code/modules/library/soapstone.dm +++ b/code/modules/library/soapstone.dm @@ -207,7 +207,7 @@ /obj/structure/chisel_message/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "engraved_message", name, 600, 300, master_ui, state) + ui = new(user, src, ui_key, "EngravedMessage", name, 600, 300, master_ui, state) ui.open() /obj/structure/chisel_message/ui_data(mob/user) diff --git a/code/modules/mining/laborcamp/laborstacker.dm b/code/modules/mining/laborcamp/laborstacker.dm index d91d1c3af22..60a34385841 100644 --- a/code/modules/mining/laborcamp/laborstacker.dm +++ b/code/modules/mining/laborcamp/laborstacker.dm @@ -39,7 +39,7 @@ GLOBAL_LIST(labor_sheet_values) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "labor_claim_console", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "LaborClaimConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/mineral/labor_claim_console/ui_data(mob/user) diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm index 731826bf4bc..2af7e26ea7f 100644 --- a/code/modules/mining/machine_redemption.dm +++ b/code/modules/mining/machine_redemption.dm @@ -205,7 +205,7 @@ /obj/machinery/mineral/ore_redemption/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ore_redemption_machine", "Ore Redemption Machine", ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "OreRedemptionMachine", "Ore Redemption Machine", ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/mineral/ore_redemption/ui_data(mob/user) diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm index 8743d26b980..57961492813 100644 --- a/code/modules/mining/machine_vending.dm +++ b/code/modules/mining/machine_vending.dm @@ -99,7 +99,7 @@ if(!ui) var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/vending) assets.send(user) - ui = new(user, src, ui_key, "mining_vendor", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "MiningVendor", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/mineral/equipment_vendor/ui_static_data(mob/user) diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm index a396979f415..a64f98acd90 100644 --- a/code/modules/mining/mint.dm +++ b/code/modules/mining/mint.dm @@ -82,7 +82,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "mint", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Mint", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/mineral/mint/ui_data() diff --git a/code/modules/mining/satchel_ore_boxdm.dm b/code/modules/mining/satchel_ore_boxdm.dm index 7463f8943da..10961cfa609 100644 --- a/code/modules/mining/satchel_ore_boxdm.dm +++ b/code/modules/mining/satchel_ore_boxdm.dm @@ -65,7 +65,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "ore_box", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "OreBox", name, ui_x, ui_y, master_ui, state) ui.open() /obj/structure/ore_box/ui_data() diff --git a/code/modules/mob/dead/observer/notificationprefs.dm b/code/modules/mob/dead/observer/notificationprefs.dm index 6c1d76eaf3b..160abd57e1f 100644 --- a/code/modules/mob/dead/observer/notificationprefs.dm +++ b/code/modules/mob/dead/observer/notificationprefs.dm @@ -24,7 +24,7 @@ /datum/notificationpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "notificationpanel", "Notification Preferences", 270, 360, master_ui, state) + ui = new(user, src, ui_key, "NotificationPreferences", "Notification Preferences", 270, 360, master_ui, state) ui.open() /datum/notificationpanel/ui_data(mob/user) diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 06e1f98cd25..f3db121fe03 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -267,7 +267,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "slime_swap_body", name, 400, 400, master_ui, state) + ui = new(user, src, ui_key, "SlimeBodySwapper", name, 400, 400, master_ui, state) ui.open() /datum/action/innate/swap_body/ui_data(mob/user) diff --git a/code/modules/mob/living/silicon/ai/robot_control.dm b/code/modules/mob/living/silicon/ai/robot_control.dm index c09b93c621c..0eaea103f2a 100644 --- a/code/modules/mob/living/silicon/ai/robot_control.dm +++ b/code/modules/mob/living/silicon/ai/robot_control.dm @@ -23,7 +23,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.always_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "remote_robot_control", "Remote Robot Control", 500, 500, master_ui, state) + ui = new(user, src, ui_key, "RemoteRobotControl", "Remote Robot Control", 500, 500, master_ui, state) ui.open() /datum/robot_control/ui_data(mob/user) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 5c1eac84b9a..8ee08e8b7db 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -176,7 +176,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "mulebot", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Mule", name, ui_x, ui_y, master_ui, state) ui.open() /mob/living/simple_animal/bot/mulebot/ui_data(mob/user) diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index e75cef7db0f..82cb26e5a02 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -39,7 +39,7 @@ assets.send(user) assets = get_asset_datum(/datum/asset/simple/arcade) assets.send(user) - ui = new(user, src, ui_key, "ntos_main", "NtOS Main menu", 400, 500, master_ui, state) + ui = new(user, src, ui_key, "NtosMain", "NtOS Main menu", 400, 500, master_ui, state) ui.open() ui.set_autoupdate(state = 1) diff --git a/code/modules/modular_computers/file_system/programs/airestorer.dm b/code/modules/modular_computers/file_system/programs/airestorer.dm index 16939688b40..a60be4529b5 100644 --- a/code/modules/modular_computers/file_system/programs/airestorer.dm +++ b/code/modules/modular_computers/file_system/programs/airestorer.dm @@ -8,7 +8,7 @@ usage_flags = PROGRAM_CONSOLE | PROGRAM_LAPTOP transfer_access = ACCESS_HEADS available_on_ntnet = TRUE - tgui_id = "ntos_ai_restorer" + tgui_id = "AiRestorer" ui_x = 370 ui_y = 400 /// Variable dictating if we are in the process of restoring the AI in the inserted intellicard diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index 4737f298c99..34daeff6ca9 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -7,7 +7,7 @@ requires_ntnet = 1 network_destination = "alarm monitoring network" size = 5 - tgui_id = "ntos_station_alert" + tgui_id = "NtosStationAlertConsole" ui_x = 315 ui_y = 500 diff --git a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm index ffb9761743d..9c5fb36a871 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/contract_uplink.dm @@ -8,7 +8,7 @@ available_on_ntnet = 0 unsendable = 1 undeletable = 1 - tgui_id = "synd_contract" + tgui_id = "SyndContractor" ui_x = 500 ui_y = 600 var/error = "" diff --git a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm index 004b86ef81d..9dedc3810f9 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/dos.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/dos.dm @@ -7,7 +7,7 @@ requires_ntnet = TRUE available_on_ntnet = FALSE available_on_syndinet = TRUE - tgui_id = "ntos_net_dos" + tgui_id = "NtosNetDos" ui_x = 400 ui_y = 250 diff --git a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm index 5b85e5a67bb..a3128150087 100644 --- a/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm +++ b/code/modules/modular_computers/file_system/programs/antagonist/revelation.dm @@ -7,7 +7,7 @@ requires_ntnet = FALSE available_on_ntnet = FALSE available_on_syndinet = TRUE - tgui_id = "ntos_revelation" + tgui_id = "NtosRevelation" ui_x = 400 ui_y = 250 diff --git a/code/modules/modular_computers/file_system/programs/arcade.dm b/code/modules/modular_computers/file_system/programs/arcade.dm index ea38eca44c2..efd82a9d88a 100644 --- a/code/modules/modular_computers/file_system/programs/arcade.dm +++ b/code/modules/modular_computers/file_system/programs/arcade.dm @@ -6,7 +6,7 @@ requires_ntnet = FALSE network_destination = "arcade network" size = 6 - tgui_id = "ntos_arcade" + tgui_id = "NtosArcade" ui_x = 450 ui_y = 350 diff --git a/code/modules/modular_computers/file_system/programs/atmosscan.dm b/code/modules/modular_computers/file_system/programs/atmosscan.dm index 33d49849843..fe3833facd0 100644 --- a/code/modules/modular_computers/file_system/programs/atmosscan.dm +++ b/code/modules/modular_computers/file_system/programs/atmosscan.dm @@ -5,7 +5,7 @@ extended_desc = "A small built-in sensor reads out the atmospheric conditions around the device." network_destination = "atmos scan" size = 4 - tgui_id = "ntos_atmos" + tgui_id = "NtosAtmos" ui_x = 300 ui_y = 350 diff --git a/code/modules/modular_computers/file_system/programs/borg_monitor.dm b/code/modules/modular_computers/file_system/programs/borg_monitor.dm index 59c2ae85f99..e3e43dcf843 100644 --- a/code/modules/modular_computers/file_system/programs/borg_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/borg_monitor.dm @@ -8,7 +8,7 @@ transfer_access = ACCESS_ROBOTICS network_destination = "cyborg remote monitoring" size = 5 - tgui_id = "ntos_cyborg_monitor" + tgui_id = "NtosCyborgRemoteMonitor" ui_x = 600 ui_y = 800 diff --git a/code/modules/modular_computers/file_system/programs/card.dm b/code/modules/modular_computers/file_system/programs/card.dm index 927f787e18d..eb7b60b0706 100644 --- a/code/modules/modular_computers/file_system/programs/card.dm +++ b/code/modules/modular_computers/file_system/programs/card.dm @@ -14,7 +14,7 @@ transfer_access = ACCESS_HEADS requires_ntnet = 0 size = 8 - tgui_id = "ntos_card" + tgui_id = "NtosCard" ui_x = 450 ui_y = 520 diff --git a/code/modules/modular_computers/file_system/programs/cargoship.dm b/code/modules/modular_computers/file_system/programs/cargoship.dm index e4acf46bd21..39543adfa57 100644 --- a/code/modules/modular_computers/file_system/programs/cargoship.dm +++ b/code/modules/modular_computers/file_system/programs/cargoship.dm @@ -5,7 +5,7 @@ extended_desc = "A combination printer/scanner app that enables modular computers to print barcodes for easy scanning and shipping." network_destination = "ship scanner" size = 6 - tgui_id = "ntos_shipping" + tgui_id = "NtosShipping" ui_x = 450 ui_y = 350 ///Account used for creating barcodes. diff --git a/code/modules/modular_computers/file_system/programs/configurator.dm b/code/modules/modular_computers/file_system/programs/configurator.dm index 2d60323d107..76da58ea11f 100644 --- a/code/modules/modular_computers/file_system/programs/configurator.dm +++ b/code/modules/modular_computers/file_system/programs/configurator.dm @@ -14,7 +14,7 @@ ui_y = 630 available_on_ntnet = 0 requires_ntnet = 0 - tgui_id = "ntos_configuration" + tgui_id = "NtosConfiguration" var/obj/item/modular_computer/movable = null diff --git a/code/modules/modular_computers/file_system/programs/crewmanifest.dm b/code/modules/modular_computers/file_system/programs/crewmanifest.dm index 4910febe2ff..662c867a39a 100644 --- a/code/modules/modular_computers/file_system/programs/crewmanifest.dm +++ b/code/modules/modular_computers/file_system/programs/crewmanifest.dm @@ -6,7 +6,7 @@ transfer_access = ACCESS_HEADS requires_ntnet = FALSE size = 4 - tgui_id = "ntos_crew_manifest" + tgui_id = "NtosCrewManifest" ui_x = 400 ui_y = 480 diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index 52ba479c049..aba826fce89 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -7,7 +7,7 @@ requires_ntnet = FALSE available_on_ntnet = FALSE undeletable = TRUE - tgui_id = "ntos_file_manager" + tgui_id = "NtosFileManager" var/open_file var/error diff --git a/code/modules/modular_computers/file_system/programs/jobmanagement.dm b/code/modules/modular_computers/file_system/programs/jobmanagement.dm index efeb8c7ab97..7b847c123e7 100644 --- a/code/modules/modular_computers/file_system/programs/jobmanagement.dm +++ b/code/modules/modular_computers/file_system/programs/jobmanagement.dm @@ -6,7 +6,7 @@ transfer_access = ACCESS_HEADS requires_ntnet = 0 size = 4 - tgui_id = "ntos_job_manager" + tgui_id = "NtosJobManager" ui_x = 400 ui_y = 620 diff --git a/code/modules/modular_computers/file_system/programs/ntdownloader.dm b/code/modules/modular_computers/file_system/programs/ntdownloader.dm index 5c793198ea9..2a07474c0a9 100644 --- a/code/modules/modular_computers/file_system/programs/ntdownloader.dm +++ b/code/modules/modular_computers/file_system/programs/ntdownloader.dm @@ -10,7 +10,7 @@ requires_ntnet_feature = NTNET_SOFTWAREDOWNLOAD available_on_ntnet = 0 ui_header = "downloader_finished.gif" - tgui_id = "ntos_net_downloader" + tgui_id = "NtosNetMonitor" ui_x = 480 ui_y = 735 diff --git a/code/modules/modular_computers/file_system/programs/ntmonitor.dm b/code/modules/modular_computers/file_system/programs/ntmonitor.dm index 1932f671f9b..7d6d89f32c4 100644 --- a/code/modules/modular_computers/file_system/programs/ntmonitor.dm +++ b/code/modules/modular_computers/file_system/programs/ntmonitor.dm @@ -7,7 +7,7 @@ requires_ntnet = TRUE required_access = ACCESS_NETWORK //NETWORK CONTROL IS A MORE SECURE PROGRAM. available_on_ntnet = TRUE - tgui_id = "ntos_net_monitor" + tgui_id = "NtosNetMonitor" /datum/computer_file/program/ntnetmonitor/ui_act(action, params) if(..()) diff --git a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm index d8b3f96f42e..4ae5bd326b8 100644 --- a/code/modules/modular_computers/file_system/programs/ntnrc_client.dm +++ b/code/modules/modular_computers/file_system/programs/ntnrc_client.dm @@ -9,7 +9,7 @@ network_destination = "NTNRC server" ui_header = "ntnrc_idle.gif" available_on_ntnet = 1 - tgui_id = "ntos_net_chat" + tgui_id = "NtosNetChat" ui_x = 900 ui_y = 675 diff --git a/code/modules/modular_computers/file_system/programs/powermonitor.dm b/code/modules/modular_computers/file_system/programs/powermonitor.dm index 7ecdf63406c..d2d57b14470 100644 --- a/code/modules/modular_computers/file_system/programs/powermonitor.dm +++ b/code/modules/modular_computers/file_system/programs/powermonitor.dm @@ -11,7 +11,7 @@ requires_ntnet = 0 network_destination = "power monitoring system" size = 9 - tgui_id = "ntos_power_monitor" + tgui_id = "NtosPowerMonitor" ui_x = 550 ui_y = 700 diff --git a/code/modules/modular_computers/file_system/programs/robocontrol.dm b/code/modules/modular_computers/file_system/programs/robocontrol.dm index d4ebe4c0439..910f9233277 100644 --- a/code/modules/modular_computers/file_system/programs/robocontrol.dm +++ b/code/modules/modular_computers/file_system/programs/robocontrol.dm @@ -8,7 +8,7 @@ requires_ntnet = TRUE network_destination = "robotics control network" size = 12 - tgui_id = "ntos_robocontrol" + tgui_id = "NtosRoboControl" ui_x = 550 ui_y = 550 ///Number of simple robots on-station. diff --git a/code/modules/modular_computers/file_system/programs/sm_monitor.dm b/code/modules/modular_computers/file_system/programs/sm_monitor.dm index 9aecf12258e..d78ed9239e3 100644 --- a/code/modules/modular_computers/file_system/programs/sm_monitor.dm +++ b/code/modules/modular_computers/file_system/programs/sm_monitor.dm @@ -8,7 +8,7 @@ transfer_access = ACCESS_CONSTRUCTION network_destination = "supermatter monitoring system" size = 5 - tgui_id = "ntos_supermatter_monitor" + tgui_id = "NtosSupermatterMonitor" ui_x = 600 ui_y = 350 var/last_status = SUPERMATTER_INACTIVE diff --git a/code/modules/modular_computers/laptop_vendor.dm b/code/modules/modular_computers/laptop_vendor.dm index 9bee5681b28..1743cf515f7 100644 --- a/code/modules/modular_computers/laptop_vendor.dm +++ b/code/modules/modular_computers/laptop_vendor.dm @@ -232,7 +232,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if (!ui) - ui = new(user, src, ui_key, "computer_fabricator", "Personal Computer Vendor", ui_x, ui_y, state = state) + ui = new(user, src, ui_key, "ComputerFabricator", "Personal Computer Vendor", ui_x, ui_y, state = state) ui.open() /obj/machinery/lapvend/attackby(obj/item/I, mob/user) diff --git a/code/modules/plumbing/plumbers/acclimator.dm b/code/modules/plumbing/plumbers/acclimator.dm index 0c1c099090d..e16d891f268 100644 --- a/code/modules/plumbing/plumbers/acclimator.dm +++ b/code/modules/plumbing/plumbers/acclimator.dm @@ -68,7 +68,7 @@ /obj/machinery/plumbing/acclimator/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "acclimator", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemAcclimator", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/plumbing/acclimator/ui_data(mob/user) diff --git a/code/modules/plumbing/plumbers/filter.dm b/code/modules/plumbing/plumbers/filter.dm index f7a22e599d5..afae76e5c5d 100644 --- a/code/modules/plumbing/plumbers/filter.dm +++ b/code/modules/plumbing/plumbers/filter.dm @@ -23,7 +23,7 @@ /obj/machinery/plumbing/filter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "chemical_filter", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemFilter", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/plumbing/filter/ui_data(mob/user) diff --git a/code/modules/plumbing/plumbers/pill_press.dm b/code/modules/plumbing/plumbers/pill_press.dm index 3cb51379ed1..896a83444fd 100644 --- a/code/modules/plumbing/plumbers/pill_press.dm +++ b/code/modules/plumbing/plumbers/pill_press.dm @@ -75,7 +75,7 @@ if(!ui) var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) assets.send(user) - ui = new(user, src, ui_key, "chem_press", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemPress", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/plumbing/pill_press/ui_data(mob/user) diff --git a/code/modules/plumbing/plumbers/reaction_chamber.dm b/code/modules/plumbing/plumbers/reaction_chamber.dm index 94ff75ea138..0ff34ed55e8 100644 --- a/code/modules/plumbing/plumbers/reaction_chamber.dm +++ b/code/modules/plumbing/plumbers/reaction_chamber.dm @@ -34,7 +34,7 @@ /obj/machinery/plumbing/reaction_chamber/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "reaction_chamber", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemReactionChamber", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/plumbing/reaction_chamber/ui_data(mob/user) diff --git a/code/modules/plumbing/plumbers/splitters.dm b/code/modules/plumbing/plumbers/splitters.dm index 03bb680116f..fe8fbd5ebb3 100644 --- a/code/modules/plumbing/plumbers/splitters.dm +++ b/code/modules/plumbing/plumbers/splitters.dm @@ -25,7 +25,7 @@ /obj/machinery/plumbing/splitter/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "chem_splitter", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemSplitter", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/plumbing/splitter/ui_data(mob/user) diff --git a/code/modules/plumbing/plumbers/synthesizer.dm b/code/modules/plumbing/plumbers/synthesizer.dm index 690a3d7f8c4..24b5df99ec3 100644 --- a/code/modules/plumbing/plumbers/synthesizer.dm +++ b/code/modules/plumbing/plumbers/synthesizer.dm @@ -63,7 +63,7 @@ /obj/machinery/plumbing/synthesizer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "synthesizer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemSynthesizer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/plumbing/synthesizer/ui_data(mob/user) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index fe0c3edf9d5..9c1526758c4 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -854,7 +854,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "apc", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Apc", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/power/apc/ui_data(mob/user) diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index c9b1eea82bf..91f3c440c16 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -226,7 +226,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "gravity_generator", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "GravityGenerator", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/gravity_generator/main/ui_data(mob/user) diff --git a/code/modules/power/monitor.dm b/code/modules/power/monitor.dm index 5c199ea2ffc..7a596418701 100644 --- a/code/modules/power/monitor.dm +++ b/code/modules/power/monitor.dm @@ -10,7 +10,7 @@ idle_power_usage = 20 active_power_usage = 100 circuit = /obj/item/circuitboard/computer/powermonitor - tgui_id = "power_monitor" + tgui_id = "PowerMonitor" ui_x = 550 ui_y = 700 @@ -88,7 +88,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, tgui_id, name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "PowerMonitor", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/monitor/ui_data() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 97e40f96400..a8a720ad94d 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -226,7 +226,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "portable_generator", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "PortableGenerator", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/power/port_gen/pacman/ui_data() diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index 35924a9455d..b82936d3f4b 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -281,7 +281,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "particle_accelerator", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ParticleAccelerator", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/particle_accelerator/control_box/ui_data(mob/user) diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index fc253fd92aa..0b2d16053d0 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -322,7 +322,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "smes", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Smes", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/power/smes/ui_data() diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index a82e3b946ab..66a6719e492 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -352,7 +352,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "solar_control", name, 380, 230, master_ui, state) + ui = new(user, src, ui_key, "SolarControl", name, 380, 230, master_ui, state) ui.open() /obj/machinery/power/solar_control/ui_data() diff --git a/code/modules/power/turbine.dm b/code/modules/power/turbine.dm index dca92893bb0..6321ed75a44 100644 --- a/code/modules/power/turbine.dm +++ b/code/modules/power/turbine.dm @@ -253,7 +253,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "turbine_computer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "TurbineComputer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/power/turbine/ui_data(mob/user) @@ -317,7 +317,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "turbine_computer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "TurbineComputer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/turbine_computer/ui_data(mob/user) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 07f2a81873b..16b76177baa 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -169,7 +169,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "chem_dispenser", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemDispenser", name, ui_x, ui_y, master_ui, state) if(user.hallucinating()) ui.set_autoupdate(FALSE) //to not ruin the immersion by constantly changing the fake chemicals ui.open() diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index ed655bd31f0..362fe121fac 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -95,7 +95,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "chem_heater", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemHeater", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/chem_heater/ui_data() diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index fd993154675..2c2aa8fd48b 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -147,7 +147,7 @@ var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/simple/pills) assets.send(user) - ui = new(user, src, ui_key, "chem_master", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemMaster", name, ui_x, ui_y, master_ui, state) ui.open() //Insert our custom spritesheet css link into the html diff --git a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm index 130de98a1b0..6ecc6788575 100644 --- a/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm +++ b/code/modules/reagents/chemistry/machinery/chem_synthesizer.dm @@ -18,7 +18,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "chem_synthesizer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "ChemDebugSynthesizer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/chem_dispenser/chem_synthesizer/ui_act(action, params) diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index cd3b1ac5e8b..7bdd0d8e0ab 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -148,7 +148,7 @@ /obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "pandemic", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "Pandemic", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/pandemic/ui_data(mob/user) diff --git a/code/modules/reagents/chemistry/machinery/smoke_machine.dm b/code/modules/reagents/chemistry/machinery/smoke_machine.dm index ae2fc49c858..a604137c262 100644 --- a/code/modules/reagents/chemistry/machinery/smoke_machine.dm +++ b/code/modules/reagents/chemistry/machinery/smoke_machine.dm @@ -107,7 +107,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "smoke_machine", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "SmokeMachine", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/smoke_machine/ui_data(mob/user) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index 5aa6d590f3b..ec40b24d2fc 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -285,7 +285,7 @@ return ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "disposal_unit", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "DisposalUnit", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/disposal/bin/ui_data(mob/user) diff --git a/code/modules/research/bepis.dm b/code/modules/research/bepis.dm index 79d8a1bfe2f..96e459f3d8a 100644 --- a/code/modules/research/bepis.dm +++ b/code/modules/research/bepis.dm @@ -181,7 +181,7 @@ /obj/machinery/rnd/bepis/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "bepis", name, 500, 480, master_ui, state) + ui = new(user, src, ui_key, "Bepis", name, 500, 480, master_ui, state) ui.open() RefreshParts() diff --git a/code/modules/research/nanites/nanite_chamber_computer.dm b/code/modules/research/nanites/nanite_chamber_computer.dm index 79ccee7555c..021067fb8ec 100644 --- a/code/modules/research/nanites/nanite_chamber_computer.dm +++ b/code/modules/research/nanites/nanite_chamber_computer.dm @@ -28,7 +28,7 @@ /obj/machinery/computer/nanite_chamber_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "nanite_chamber_control", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "NaniteChamberControl", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/nanite_chamber_control/ui_data() diff --git a/code/modules/research/nanites/nanite_cloud_controller.dm b/code/modules/research/nanites/nanite_cloud_controller.dm index 00626cb525d..3ba7834f694 100644 --- a/code/modules/research/nanites/nanite_cloud_controller.dm +++ b/code/modules/research/nanites/nanite_cloud_controller.dm @@ -62,7 +62,7 @@ /obj/machinery/computer/nanite_cloud_controller/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "nanite_cloud_control", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "NaniteCloudControl", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/nanite_cloud_controller/ui_data() diff --git a/code/modules/research/nanites/nanite_program_hub.dm b/code/modules/research/nanites/nanite_program_hub.dm index 5e932579049..64ba28fc622 100644 --- a/code/modules/research/nanites/nanite_program_hub.dm +++ b/code/modules/research/nanites/nanite_program_hub.dm @@ -56,7 +56,7 @@ /obj/machinery/nanite_program_hub/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "nanite_program_hub", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "NaniteProgramHub", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/nanite_program_hub/ui_data() diff --git a/code/modules/research/nanites/nanite_programmer.dm b/code/modules/research/nanites/nanite_programmer.dm index 10796fbd972..c6576e7b430 100644 --- a/code/modules/research/nanites/nanite_programmer.dm +++ b/code/modules/research/nanites/nanite_programmer.dm @@ -43,7 +43,7 @@ /obj/machinery/nanite_programmer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "nanite_programmer", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "NaniteProgrammer", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/nanite_programmer/ui_data() diff --git a/code/modules/research/nanites/nanite_remote.dm b/code/modules/research/nanites/nanite_remote.dm index 0d9361b5348..b222b2ad358 100644 --- a/code/modules/research/nanites/nanite_remote.dm +++ b/code/modules/research/nanites/nanite_remote.dm @@ -83,7 +83,7 @@ /obj/item/nanite_remote/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "nanite_remote", name, 420, 500, master_ui, state) + ui = new(user, src, ui_key, "NaniteRemote", name, 420, 500, master_ui, state) ui.open() /obj/item/nanite_remote/ui_data() diff --git a/code/modules/ruins/spaceruin_code/TheDerelict.dm b/code/modules/ruins/spaceruin_code/TheDerelict.dm index 81aa4dcadf8..e153b159cde 100644 --- a/code/modules/ruins/spaceruin_code/TheDerelict.dm +++ b/code/modules/ruins/spaceruin_code/TheDerelict.dm @@ -133,7 +133,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "vault_controller", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "VaultController", name, ui_x, ui_y, master_ui, state) ui.open() diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index ee639ab7d92..e52416131c1 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -37,7 +37,7 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "keycard_auth", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "KeycardAuth", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/keycard_auth/ui_data() diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index 09373fa177d..648f0bf4b71 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -23,7 +23,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "emergency_shuttle_console", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "EmergencyShuttleConsole", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/emergency_shuttle/ui_data() diff --git a/code/modules/station_goals/bsa.dm b/code/modules/station_goals/bsa.dm index 2d7efe42486..3a3b0dee9c7 100644 --- a/code/modules/station_goals/bsa.dm +++ b/code/modules/station_goals/bsa.dm @@ -248,7 +248,7 @@ datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "bsa", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "BluespaceArtillery", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/bsa_control/ui_data() diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm index a66b07ec039..a2c9f4d4a57 100644 --- a/code/modules/station_goals/dna_vault.dm +++ b/code/modules/station_goals/dna_vault.dm @@ -181,7 +181,7 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) roll_powers(user) - ui = new(user, src, ui_key, "dna_vault", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "DnaVault", name, ui_x, ui_y, master_ui, state) ui.open() diff --git a/code/modules/station_goals/shield.dm b/code/modules/station_goals/shield.dm index a809b1d68a7..57fd3aaa615 100644 --- a/code/modules/station_goals/shield.dm +++ b/code/modules/station_goals/shield.dm @@ -48,7 +48,7 @@ /obj/machinery/computer/sat_control/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state) ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) - ui = new(user, src, ui_key, "sat_control", name, ui_x, ui_y, master_ui, state) + ui = new(user, src, ui_key, "SatelliteControl", name, ui_x, ui_y, master_ui, state) ui.open() /obj/machinery/computer/sat_control/ui_act(action, params) diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index fc8f33daccc..83964121688 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -685,7 +685,7 @@ GLOBAL_LIST_EMPTY(vending_products) if(!ui) var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/vending) assets.send(user) - ui = new(user, src, ui_key, "vending", ui_key, 450, 600, master_ui, state) + ui = new(user, src, ui_key, "Vending", ui_key, 450, 600, master_ui, state) ui.open() /obj/machinery/vending/ui_static_data(mob/user) From 87578896901dcb1dc19eb2952cb6df022f7b11d6 Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 04:02:28 +0300 Subject: [PATCH 02/46] Layout, routes and React Context --- tgui/packages/tgui/backend.js | 17 +- tgui/packages/tgui/components/Layout.js | 145 +++ tgui/packages/tgui/components/TitleBar.js | 51 - tgui/packages/tgui/components/index.js | 2 +- tgui/packages/tgui/index.js | 13 +- tgui/packages/tgui/interfaces/AirAlarm.js | 88 +- tgui/packages/tgui/layout.js | 113 -- tgui/packages/tgui/routes.js | 1402 ++++++++++----------- tgui/packages/tgui/store.js | 13 + 9 files changed, 858 insertions(+), 986 deletions(-) create mode 100644 tgui/packages/tgui/components/Layout.js delete mode 100644 tgui/packages/tgui/components/TitleBar.js delete mode 100644 tgui/packages/tgui/layout.js diff --git a/tgui/packages/tgui/backend.js b/tgui/packages/tgui/backend.js index 37b72464260..8d02ad14a29 100644 --- a/tgui/packages/tgui/backend.js +++ b/tgui/packages/tgui/backend.js @@ -1,5 +1,5 @@ +import { act } from './byond'; import { UI_DISABLED, UI_INTERACTIVE } from './constants'; -import { tridentVersion, act as _act } from './byond'; /** * This file provides a clear separation layer between backend updates @@ -83,13 +83,20 @@ export const backendReducer = (state, action) => { * act: (action: string, params?: object) => void, * }} */ -export const useBackend = props => { +export const useBackend = context => { // TODO: Dispatch "act" calls as Redux actions - const { state, dispatch } = props; + const { store } = context; + // Obsolete bits + const { + state = store.getState(), + dispatch = store.dispatch, + } = context; const ref = state.config.ref; - const act = (action, params = {}) => _act(ref, action, params); + const boundAct = (action, params = {}) => { + act(ref, action, params); + }; return { ...state, - act, + act: boundAct, }; }; diff --git a/tgui/packages/tgui/components/Layout.js b/tgui/packages/tgui/components/Layout.js new file mode 100644 index 00000000000..0230a1582ce --- /dev/null +++ b/tgui/packages/tgui/components/Layout.js @@ -0,0 +1,145 @@ +import { classes } from 'common/react'; +import { decodeHtmlEntities, toTitleCase } from 'common/string'; +import { Component, Fragment } from 'inferno'; +import { runCommand, tridentVersion, winset } from '../byond'; +import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants'; +import { dragStartHandler, resizeStartHandler } from '../drag'; +import { releaseHeldKeys } from '../hotkeys'; +import { createLogger } from '../logging'; +import { refocusLayout } from '../refocus'; +import { Box } from './Box'; +import { Icon } from './Icon'; +import { useBackend } from '../backend'; + +const logger = createLogger('Layout'); + +export class Layout extends Component { + componentDidMount() { + refocusLayout(); + } + + render() { + const { + resizable, + theme = 'nanotrasen', + children, + } = this.props; + const { + config, + debugLayout, + } = useBackend(this.context); + // Determine when to show dimmer + const showDimmer = config.observer + ? config.status < UI_DISABLED + : config.status < UI_INTERACTIVE; + return ( +
+
+ { + logger.log('pressed close'); + releaseHeldKeys(); + winset(config.window, 'is-visible', false); + runCommand(`uiclose ${config.ref}`); + }} /> +
+ {children} + {showDimmer && ( +
+ )} +
+ {config.fancy && resizable && ( + +
+
+
+ + )} +
+
+ ); + } +} + +const LayoutContent = props => { + const { scrollable, children } = props; + return ( +
+ + {children} + +
+ ); +}; + +Layout.Content = LayoutContent; + +const statusToColor = status => { + switch (status) { + case UI_INTERACTIVE: + return 'good'; + case UI_UPDATE: + return 'average'; + case UI_DISABLED: + default: + return 'bad'; + } +}; + +const TitleBar = props => { + const { + className, + title, + status, + fancy, + onDragStart, + onClose, + } = props; + return ( +
+ +
+ {title === title.toLowerCase() + ? toTitleCase(title) + : title} +
+
fancy && onDragStart(e)} /> + {!!fancy && ( +
+ {tridentVersion <= 4 ? 'x' : '×'} +
+ )} +
+ ); +}; diff --git a/tgui/packages/tgui/components/TitleBar.js b/tgui/packages/tgui/components/TitleBar.js deleted file mode 100644 index f0a50405008..00000000000 --- a/tgui/packages/tgui/components/TitleBar.js +++ /dev/null @@ -1,51 +0,0 @@ -import { classes, pureComponentHooks } from 'common/react'; -import { toTitleCase } from 'common/string'; -import { tridentVersion } from '../byond'; -import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants'; -import { Icon } from './Icon'; - -const statusToColor = status => { - switch (status) { - case UI_INTERACTIVE: - return 'good'; - case UI_UPDATE: - return 'average'; - case UI_DISABLED: - default: - return 'bad'; - } -}; - -export const TitleBar = props => { - const { className, title, status, fancy, onDragStart, onClose } = props; - return ( -
- -
- {title === title.toLowerCase() ? toTitleCase(title) : title} -
-
fancy && onDragStart(e)} /> - {!!fancy && ( -
- {tridentVersion <= 4 ? 'x' : '×'} -
- )} -
- ); -}; - -TitleBar.defaultHooks = pureComponentHooks; diff --git a/tgui/packages/tgui/components/index.js b/tgui/packages/tgui/components/index.js index 0c38f8a812c..5f5d14b5d1a 100644 --- a/tgui/packages/tgui/components/index.js +++ b/tgui/packages/tgui/components/index.js @@ -15,6 +15,7 @@ export { Icon } from './Icon'; export { Input } from './Input'; export { Knob } from './Knob'; export { LabeledList } from './LabeledList'; +export { Layout } from './Layout'; export { NoticeBox } from './NoticeBox'; export { NumberInput } from './NumberInput'; export { ProgressBar } from './ProgressBar'; @@ -22,5 +23,4 @@ export { Section } from './Section'; export { Slider } from './Slider'; export { Table } from './Table'; export { Tabs } from './Tabs'; -export { TitleBar } from './TitleBar'; export { Tooltip } from './Tooltip'; diff --git a/tgui/packages/tgui/index.js b/tgui/packages/tgui/index.js index 460df8570f4..b682bd5f227 100644 --- a/tgui/packages/tgui/index.js +++ b/tgui/packages/tgui/index.js @@ -12,7 +12,8 @@ import { backendUpdate } from './backend'; import { tridentVersion } from './byond'; import { setupDrag } from './drag'; import { createLogger } from './logging'; -import { createStore } from './store'; +import { createStore, StoreProvider } from './store'; +import { getRoutedComponent } from './routes'; const logger = createLogger(); const store = createStore(); @@ -35,8 +36,12 @@ const renderLayout = () => { setupDrag(state); } // Start rendering - const { Layout } = require('./layout'); - const element = ; + const Component = getRoutedComponent(state); + const element = ( + + + + ); render(element, reactRoot); } catch (err) { @@ -101,7 +106,7 @@ const setupApp = () => { // Enable hot module reloading if (module.hot) { setupHotReloading(); - module.hot.accept(['./layout', './routes'], () => { + module.hot.accept(['./components', './routes'], () => { renderLayout(); }); } diff --git a/tgui/packages/tgui/interfaces/AirAlarm.js b/tgui/packages/tgui/interfaces/AirAlarm.js index 20d808606c4..f77f88281d8 100644 --- a/tgui/packages/tgui/interfaces/AirAlarm.js +++ b/tgui/packages/tgui/interfaces/AirAlarm.js @@ -2,30 +2,34 @@ import { toFixed } from 'common/math'; import { decodeHtmlEntities } from 'common/string'; import { Fragment } from 'inferno'; import { useBackend } from '../backend'; -import { Box, Button, LabeledList, NumberInput, Section } from '../components'; +import { Box, Button, LabeledList, Layout, NumberInput, Section } from '../components'; import { getGasLabel } from '../constants'; +import { createLogger } from '../logging'; import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox'; -export const AirAlarm = props => { - const { state } = props; - const { act, data } = useBackend(props); +const logger = createLogger('AirAlarm'); + +export const AirAlarm = (props, context) => { + const { act, data } = useBackend(context); const locked = data.locked && !data.siliconUser; return ( - - act('lock')} /> - - {!locked && ( - - )} - + + + act('lock')} /> + + {!locked && ( + + )} + + ); }; -const AirAlarmStatus = props => { - const { data } = useBackend(props); +const AirAlarmStatus = (props, context) => { + const { data } = useBackend(context); const entries = (data.environment_data || []) .filter(entry => entry.value >= 0.01); const dangerMap = { @@ -114,9 +118,8 @@ const AIR_ALARM_ROUTES = { }, }; -const AirAlarmControl = props => { - const { state } = props; - const { act, config } = useBackend(props); +const AirAlarmControl = (props, context) => { + const { act, config } = useBackend(context); const route = AIR_ALARM_ROUTES[config.screen] || AIR_ALARM_ROUTES.home; const Component = route.component(); return ( @@ -130,7 +133,7 @@ const AirAlarmControl = props => { screen: 'home', })} /> )}> - + ); }; @@ -139,8 +142,8 @@ const AirAlarmControl = props => { // Home screen // -------------------------------------------------------- -const AirAlarmControlHome = props => { - const { act, data } = useBackend(props); +const AirAlarmControlHome = (props, context) => { + const { act, data } = useBackend(context); const { mode, atmos_alarm, @@ -200,21 +203,22 @@ const AirAlarmControlHome = props => { // Vents // -------------------------------------------------------- -const AirAlarmControlVents = props => { - const { state } = props; - const { data } = useBackend(props); +const AirAlarmControlVents = (props, context) => { + const { data } = useBackend(context); const { vents } = data; if (!vents || vents.length === 0) { return 'Nothing to show'; } return vents.map(vent => ( - + )); }; -const Vent = props => { +const Vent = (props, context) => { + const { vent } = props; + const { act } = useBackend(context); const { id_tag, long_name, @@ -227,8 +231,7 @@ const Vent = props => { internal, extdefault, intdefault, - } = props; - const { act } = useBackend(props); + } = vent; return (
{ // Scrubbers // -------------------------------------------------------- -const AirAlarmControlScrubbers = props => { - const { state } = props; - const { data } = useBackend(props); +const AirAlarmControlScrubbers = (props, context) => { + const { data } = useBackend(context); const { scrubbers } = data; if (!scrubbers || scrubbers.length === 0) { return 'Nothing to show'; @@ -328,12 +330,13 @@ const AirAlarmControlScrubbers = props => { return scrubbers.map(scrubber => ( + scrubber={scrubber} /> )); }; -const Scrubber = props => { +const Scrubber = (props, context) => { + const { scrubber } = props; + const { act } = useBackend(context); const { long_name, power, @@ -341,8 +344,7 @@ const Scrubber = props => { id_tag, widenet, filter_types, - } = props; - const { act } = useBackend(props); + } = scrubber; return (
{ // Modes // -------------------------------------------------------- -const AirAlarmControlModes = props => { - const { act, data } = useBackend(props); +const AirAlarmControlModes = (props, context) => { + const { act, data } = useBackend(context); const { modes } = data; if (!modes || modes.length === 0) { return 'Nothing to show'; @@ -423,8 +425,8 @@ const AirAlarmControlModes = props => { // Thresholds // -------------------------------------------------------- -const AirAlarmControlThresholds = props => { - const { act, data } = useBackend(props); +const AirAlarmControlThresholds = (props, context) => { + const { act, data } = useBackend(context); const { thresholds } = data; return ( { - const { scrollable, children } = props; - return ( -
- - {children} - -
- ); -}; - -export class Layout extends Component { - componentDidMount() { - refocusLayout(); - } - - render() { - const { props } = this; - const { state, dispatch } = props; - const { config, debugLayout } = state; - const route = getRoute(state); - const { scrollable, resizable, theme } = route || {}; - let contentElement; - if (route) { - const RoutedComponent = route.component(); - const WrapperComponent = route.wrapper && route.wrapper(); - // Render content - contentElement = ( - - - - ); - // Wrap into the wrapper component - if (WrapperComponent) { - contentElement = ( - - {contentElement} - - ); - } - } - else { - contentElement = ( - - Route entry missing for {config.interface}. - - ); - } - // Determine when to show dimmer - const showDimmer = config.observer - ? config.status < UI_DISABLED - : config.status < UI_INTERACTIVE; - return ( -
-
- { - logger.log('pressed close'); - releaseHeldKeys(); - winset(config.window, 'is-visible', false); - runCommand(`uiclose ${config.ref}`); - }} /> -
- {contentElement} - {showDimmer && ( -
- )} -
- {config.fancy && (scrollable || resizable) && ( - -
-
-
- - )} -
-
- ); - } -} diff --git a/tgui/packages/tgui/routes.js b/tgui/packages/tgui/routes.js index 46bf0417496..393d5cb97d9 100644 --- a/tgui/packages/tgui/routes.js +++ b/tgui/packages/tgui/routes.js @@ -1,776 +1,640 @@ -// routes.js -// Tip: Press Shift+Alt+O in VSCode to organize these imports. - -import { Achievements } from './interfaces/Achievements'; -import { AiAirlock } from './interfaces/AiAirlock'; -import { AirAlarm } from './interfaces/AirAlarm'; -import { AiRestorer } from './interfaces/AiRestorer'; -import { AirlockElectronics } from './interfaces/AirlockElectronics'; -import { Apc } from './interfaces/Apc'; -import { AtmosAlertConsole } from './interfaces/AtmosAlertConsole'; -import { AtmosControlConsole } from './interfaces/AtmosControlConsole'; -import { AtmosFilter } from './interfaces/AtmosFilter'; -import { AtmosMixer } from './interfaces/AtmosMixer'; -import { AtmosPump } from './interfaces/AtmosPump'; -import { AutomatedAnnouncement } from './interfaces/AutomatedAnnouncement'; -import { BankMachine } from './interfaces/BankMachine'; -import { Bepis } from './interfaces/Bepis'; -import { BlackmarketUplink } from './interfaces/BlackmarketUplink'; -import { BluespaceArtillery } from './interfaces/BluespaceArtillery'; -import { BorgPanel } from './interfaces/BorgPanel'; -import { BrigTimer } from './interfaces/BrigTimer'; -import { CameraConsole, CameraConsoleWrapper } from './interfaces/CameraConsole'; -import { Canister } from './interfaces/Canister'; -import { Canvas } from './interfaces/Canvas'; -import { Cargo, CargoExpress } from './interfaces/Cargo'; -import { CargoHoldTerminal } from './interfaces/CargoHoldTerminal'; -import { CellularEmporium } from './interfaces/CellularEmporium'; -import { CentcomPodLauncher } from './interfaces/CentcomPodLauncher'; -import { ChemAcclimator } from './interfaces/ChemAcclimator'; -import { ChemDebugSynthesizer } from './interfaces/ChemDebugSynthesizer'; -import { ChemDispenser } from './interfaces/ChemDispenser'; -import { ChemFilter } from './interfaces/ChemFilter'; -import { ChemHeater } from './interfaces/ChemHeater'; -import { ChemMaster } from './interfaces/ChemMaster'; -import { ChemPress } from './interfaces/ChemPress'; -import { ChemReactionChamber } from './interfaces/ChemReactionChamber'; -import { ChemSplitter } from './interfaces/ChemSplitter'; -import { ChemSynthesizer } from './interfaces/ChemSynthesizer'; -import { CodexGigas } from './interfaces/CodexGigas'; -import { ComputerFabricator } from './interfaces/ComputerFabricator'; -import { Crayon } from './interfaces/Crayon'; -import { CrewConsole } from './interfaces/CrewConsole'; -import { Cryo } from './interfaces/Cryo'; -import { DecalPainter } from './interfaces/DecalPainter'; -import { DisposalUnit } from './interfaces/DisposalUnit'; -import { DnaConsole } from './interfaces/DnaConsole'; -import { DnaVault } from './interfaces/DnaVault'; -import { EightBallVote } from './interfaces/EightBallVote'; -import { Electropack } from './interfaces/Electropack'; -import { EmergencyShuttleConsole } from './interfaces/EmergencyShuttleConsole'; -import { EngravedMessage } from './interfaces/EngravedMessage'; -import { ExosuitControlConsole } from './interfaces/ExosuitControlConsole'; -import { Gateway } from './interfaces/Gateway'; -import { Gps } from './interfaces/Gps'; -import { GravityGenerator } from './interfaces/GravityGenerator'; -import { GulagItemReclaimer } from './interfaces/GulagItemReclaimer'; -import { GulagTeleporterConsole } from './interfaces/GulagTeleporterConsole'; -import { Holodeck } from './interfaces/Holodeck'; -import { HypnoChair } from './interfaces/HypnoChair'; -import { ImplantChair } from './interfaces/ImplantChair'; -import { InfraredEmitter } from './interfaces/InfraredEmitter'; -import { Intellicard } from './interfaces/Intellicard'; -import { KeycardAuth } from './interfaces/KeycardAuth'; -import { LaborClaimConsole } from './interfaces/LaborClaimConsole'; -import { LanguageMenu } from './interfaces/LanguageMenu'; -import { LaunchpadConsole, LaunchpadRemote } from './interfaces/Launchpad'; -import { MalfunctionModulePicker } from './interfaces/MalfunctionModulePicker'; -import { MechBayPowerConsole } from './interfaces/MechBayPowerConsole'; -import { MedicalKiosk } from './interfaces/MedicalKiosk'; -import { MiningVendor } from './interfaces/MiningVendor'; -import { Mint } from './interfaces/Mint'; -import { Mule } from './interfaces/Mule'; -import { NaniteChamberControl } from './interfaces/NaniteChamberControl'; -import { NaniteCloudControl } from './interfaces/NaniteCloudControl'; -import { NaniteProgramHub } from './interfaces/NaniteProgramHub'; -import { NaniteProgrammer } from './interfaces/NaniteProgrammer'; -import { NaniteRemote } from './interfaces/NaniteRemote'; -import { NotificationPreferences } from './interfaces/NotificationPreferences'; -import { NtnetRelay } from './interfaces/NtnetRelay'; -import { NtosArcade } from './interfaces/NtosArcade'; -import { NtosAtmos } from './interfaces/NtosAtmos'; -import { NtosCard } from './interfaces/NtosCard'; -import { NtosConfiguration } from './interfaces/NtosConfiguration'; -import { NtosCrewManifest } from './interfaces/NtosCrewManifest'; -import { NtosCyborgRemoteMonitor } from './interfaces/NtosCyborgRemoteMonitor'; -import { NtosFileManager } from './interfaces/NtosFileManager'; -import { NtosJobManager } from './interfaces/NtosJobManager'; -import { NtosMain } from './interfaces/NtosMain'; -import { NtosNetChat } from './interfaces/NtosNetChat'; -import { NtosNetDos } from './interfaces/NtosNetDos'; -import { NtosNetDownloader } from './interfaces/NtosNetDownloader'; -import { NtosNetMonitor } from './interfaces/NtosNetMonitor'; -import { NtosRevelation } from './interfaces/NtosRevelation'; -import { NtosRoboControl } from './interfaces/NtosRoboControl'; -import { NtosShipping } from './interfaces/NtosShipping'; -import { NtosSupermatterMonitor } from './interfaces/NtosSupermatterMonitor'; -import { NtosWrapper } from './interfaces/NtosWrapper'; -import { NuclearBomb } from './interfaces/NuclearBomb'; -import { OperatingComputer } from './interfaces/OperatingComputer'; -import { OreBox } from './interfaces/OreBox'; -import { OreRedemptionMachine } from './interfaces/OreRedemptionMachine'; -import { Pandemic } from './interfaces/Pandemic'; -import { ParticleAccelerator } from './interfaces/ParticleAccelerator'; -import { PersonalCrafting } from './interfaces/PersonalCrafting'; -import { PortablePump, PortableScrubber } from './interfaces/PortableAtmos'; -import { PortableGenerator } from './interfaces/PortableGenerator'; -import { PowerMonitor } from './interfaces/PowerMonitor'; -import { ProximitySensor } from './interfaces/ProximitySensor'; -import { Radio } from './interfaces/Radio'; -import { RadioactiveMicrolaser } from './interfaces/RadioactiveMicrolaser'; -import { RapidPipeDispenser } from './interfaces/RapidPipeDispenser'; -import { RemoteRobotControl } from './interfaces/RemoteRobotControl'; -import { RoboticsControlConsole } from './interfaces/RoboticsControlConsole'; -import { Roulette } from './interfaces/Roulette'; -import { SatelliteControl } from './interfaces/SatelliteControl'; -import { ScannerGate } from './interfaces/ScannerGate'; -import { ShuttleManipulator } from './interfaces/ShuttleManipulator'; -import { Signaler } from './interfaces/Signaler'; -import { Sleeper } from './interfaces/Sleeper'; -import { SlimeBodySwapper } from './interfaces/SlimeBodySwapper'; -import { SmartVend } from './interfaces/SmartVend'; -import { Smes } from './interfaces/Smes'; -import { SmokeMachine } from './interfaces/SmokeMachine'; -import { SolarControl } from './interfaces/SolarControl'; -import { SpaceHeater } from './interfaces/SpaceHeater'; -import { SpawnersMenu } from './interfaces/SpawnersMenu'; -import { StationAlertConsole } from './interfaces/StationAlertConsole'; -import { SuitStorageUnit } from './interfaces/SuitStorageUnit'; -import { SyndContractor } from './interfaces/SyndContractor'; -import { Tank } from './interfaces/Tank'; -import { TankDispenser } from './interfaces/TankDispenser'; -import { Teleporter } from './interfaces/Teleporter'; -import { ThermoMachine } from './interfaces/ThermoMachine'; -import { Timer } from './interfaces/Timer'; -import { TransferValve } from './interfaces/TransferValve'; -import { TurbineComputer } from './interfaces/TurbineComputer'; -import { Uplink } from './interfaces/Uplink'; -import { VaultController } from './interfaces/VaultController'; -import { Vending } from './interfaces/Vending'; -import { Wires } from './interfaces/Wires'; - -const ROUTES = { - achievements: { - component: () => Achievements, - scrollable: true, - }, - ai_airlock: { - component: () => AiAirlock, - scrollable: false, - }, - airalarm: { - component: () => AirAlarm, - scrollable: true, - }, - ai_restorer: { - component: () => AiRestorer, - scrollable: true, - }, - airlock_electronics: { - component: () => AirlockElectronics, - scrollable: false, - }, - apc: { - component: () => Apc, - scrollable: false, - }, - atmos_alert: { - component: () => AtmosAlertConsole, - scrollable: true, - }, - atmos_control: { - component: () => AtmosControlConsole, - scrollable: true, - }, - atmos_filter: { - component: () => AtmosFilter, - scrollable: false, - }, - atmos_mixer: { - component: () => AtmosMixer, - scrollable: false, - }, - atmos_pump: { - component: () => AtmosPump, - scrollable: false, - }, - announcement_system: { - component: () => AutomatedAnnouncement, - scrollable: false, - }, - bepis: { - component: () => Bepis, - scrollable: false, - }, - bank_machine: { - component: () => BankMachine, - scrollable: false, - }, - blackmarket_uplink: { - component: () => BlackmarketUplink, - scrollable: true, - theme: 'hackerman', - }, - borgopanel: { - component: () => BorgPanel, - scrollable: true, - }, - brig_timer: { - component: () => BrigTimer, - scrollable: false, - }, - bsa: { - component: () => BluespaceArtillery, - scrollable: false, - }, - camera_console: { - component: () => CameraConsole, - wrapper: () => CameraConsoleWrapper, - scrollable: true, - }, - canister: { - component: () => Canister, - scrollable: false, - }, - canvas: { - component: () => Canvas, - scrollable: false, - }, - cargo: { - component: () => Cargo, - scrollable: true, - }, - cargo_express: { - component: () => CargoExpress, - scrollable: true, - }, - cargo_hold_terminal: { - component: () => CargoHoldTerminal, - scrollable: true, - }, - cellular_emporium: { - component: () => CellularEmporium, - scrollable: true, - }, - centcom_podlauncher: { - component: () => CentcomPodLauncher, - scrollable: false, - }, - acclimator: { - component: () => ChemAcclimator, - scrollable: false, - }, - chem_dispenser: { - component: () => ChemDispenser, - scrollable: true, - }, - chemical_filter: { - component: () => ChemFilter, - scrollable: true, - }, - chem_heater: { - component: () => ChemHeater, - scrollable: true, - }, - chem_master: { - component: () => ChemMaster, - scrollable: true, - }, - chem_press: { - component: () => ChemPress, - scrollable: false, - }, - reaction_chamber: { - component: () => ChemReactionChamber, - scrollable: true, - }, - chem_splitter: { - component: () => ChemSplitter, - scrollable: false, - }, - chem_synthesizer: { - component: () => ChemDebugSynthesizer, - scrollable: false, - }, - synthesizer: { - component: () => ChemSynthesizer, - scrollable: false, - }, - codex_gigas: { - component: () => CodexGigas, - scrollable: false, - }, - computer_fabricator: { - component: () => ComputerFabricator, - scrollable: false, - }, - crayon: { - component: () => Crayon, - scrollable: true, - }, - crew: { - component: () => CrewConsole, - scrollable: true, - }, - cryo: { - component: () => Cryo, - scrollable: false, - }, - decal_painter: { - component: () => DecalPainter, - scrollable: false, - }, - disposal_unit: { - component: () => DisposalUnit, - scrollable: false, - }, - dna_vault: { - component: () => DnaVault, - scrollable: false, - }, - eightball: { - component: () => EightBallVote, - scrollable: false, - }, - electropack: { - component: () => Electropack, - scrollable: false, - }, - emergency_shuttle_console: { - component: () => EmergencyShuttleConsole, - scrollable: false, - }, - engraved_message: { - component: () => EngravedMessage, - scrollable: false, - }, - exosuit_control_console: { - component: () => ExosuitControlConsole, - scrollable: true, - }, - gateway: { - component: () => Gateway, - scrollable: true, - }, - gps: { - component: () => Gps, - scrollable: true, - }, - gravity_generator: { - component: () => GravityGenerator, - scrollable: false, - }, - gulag_console: { - component: () => GulagTeleporterConsole, - scrollable: false, - }, - gulag_item_reclaimer: { - component: () => GulagItemReclaimer, - scrollable: true, - }, - holodeck: { - component: () => Holodeck, - scrollable: true, - }, - hypnochair: { - component: () => HypnoChair, - scrollable: false, - }, - implantchair: { - component: () => ImplantChair, - scrollable: false, - }, - infrared_emitter: { - component: () => InfraredEmitter, - scrollable: false, - }, - intellicard: { - component: () => Intellicard, - scrollable: true, - }, - keycard_auth: { - component: () => KeycardAuth, - scrollable: false, - }, - labor_claim_console: { - component: () => LaborClaimConsole, - scrollable: false, - }, - language_menu: { - component: () => LanguageMenu, - scrollable: true, - }, - launchpad_console: { - component: () => LaunchpadConsole, - scrollable: true, - }, - launchpad_remote: { - component: () => LaunchpadRemote, - scrollable: false, - theme: 'syndicate', - }, - mech_bay_power_console: { - component: () => MechBayPowerConsole, - scrollable: false, - }, - medical_kiosk: { - component: () => MedicalKiosk, - scrollable: false, - }, - mining_vendor: { - component: () => MiningVendor, - scrollable: true, - }, - mint: { - component: () => Mint, - scrollable: false, - }, - malfunction_module_picker: { - component: () => MalfunctionModulePicker, - scrollable: true, - theme: 'malfunction', - }, - mulebot: { - component: () => Mule, - scrollable: false, - }, - nanite_chamber_control: { - component: () => NaniteChamberControl, - scrollable: true, - }, - nanite_cloud_control: { - component: () => NaniteCloudControl, - scrollable: true, - }, - nanite_program_hub: { - component: () => NaniteProgramHub, - scrollable: true, - }, - nanite_programmer: { - component: () => NaniteProgrammer, - scrollable: true, - }, - nanite_remote: { - component: () => NaniteRemote, - scrollable: true, - }, - notificationpanel: { - component: () => NotificationPreferences, - scrollable: true, - }, - ntnet_relay: { - component: () => NtnetRelay, - scrollable: false, - }, - ntos_ai_restorer: { - component: () => AiRestorer, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_atmos: { - component: () => NtosAtmos, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_arcade: { - component: () => NtosArcade, - wrapper: () => NtosWrapper, - scrollable: false, - theme: 'ntos', - }, - ntos_card: { - component: () => NtosCard, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_configuration: { - component: () => NtosConfiguration, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_crew_manifest: { - component: () => NtosCrewManifest, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_cyborg_monitor: { - component: () => NtosCyborgRemoteMonitor, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_file_manager: { - component: () => NtosFileManager, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_job_manager: { - component: () => NtosJobManager, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_main: { - component: () => NtosMain, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_net_chat: { - component: () => NtosNetChat, - wrapper: () => NtosWrapper, - scrollable: false, - theme: 'ntos', - }, - ntos_net_dos: { - component: () => NtosNetDos, - wrapper: () => NtosWrapper, - scrollable: false, - theme: 'syndicate', - }, - ntos_net_downloader: { - component: () => NtosNetDownloader, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_net_monitor: { - component: () => NtosNetMonitor, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_power_monitor: { - component: () => PowerMonitor, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_revelation: { - component: () => NtosRevelation, - wrapper: () => NtosWrapper, - scrollable: false, - theme: 'syndicate', - }, - ntos_robocontrol: { - component: () => NtosRoboControl, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_shipping: { - component: () => NtosShipping, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_station_alert: { - component: () => StationAlertConsole, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - ntos_supermatter_monitor: { - component: () => NtosSupermatterMonitor, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'ntos', - }, - nuclear_bomb: { - component: () => NuclearBomb, - scrollable: false, - theme: 'retro', - }, - ore_redemption_machine: { - component: () => OreRedemptionMachine, - scrollable: true, - }, - ore_box: { - component: () => OreBox, - scrollable: true, - }, - operating_computer: { - component: () => OperatingComputer, - scrollable: true, - }, - pandemic: { - component: () => Pandemic, - scrollable: true, - }, - particle_accelerator: { - component: () => ParticleAccelerator, - scrollable: false, - }, - personal_crafting: { - component: () => PersonalCrafting, - scrollable: true, - }, - portable_generator: { - component: () => PortableGenerator, - scrollable: false, - }, - portable_pump: { - component: () => PortablePump, - scrollable: false, - }, - portable_scrubber: { - component: () => PortableScrubber, - scrollable: false, - }, - power_monitor: { - component: () => PowerMonitor, - scrollable: true, - }, - proximity_sensor: { - component: () => ProximitySensor, - scrollable: false, - }, - radio: { - component: () => Radio, - scrollable: false, - }, - radioactive_microlaser: { - component: () => RadioactiveMicrolaser, - scrollable: false, - theme: 'syndicate', - }, - remote_robot_control: { - component: () => RemoteRobotControl, - scrollable: true, - }, - robotics_control_console: { - component: () => RoboticsControlConsole, - scrollable: true, - }, - roulette: { - component: () => Roulette, - scrollable: false, - theme: 'cardtable', - }, - rpd: { - component: () => RapidPipeDispenser, - scrollable: true, - }, - sat_control: { - component: () => SatelliteControl, - scrollable: false, - }, - scanner_gate: { - component: () => ScannerGate, - scrollable: true, - }, - shuttle_manipulator: { - component: () => ShuttleManipulator, - scrollable: true, - }, - signaler: { - component: () => Signaler, - scrollable: false, - }, - sleeper: { - component: () => Sleeper, - scrollable: false, - }, - slime_swap_body: { - component: () => SlimeBodySwapper, - scrollable: true, - }, - smartvend: { - component: () => SmartVend, - scrollable: true, - }, - smes: { - component: () => Smes, - scrollable: false, - }, - smoke_machine: { - component: () => SmokeMachine, - scrollable: false, - }, - solar_control: { - component: () => SolarControl, - scrollable: false, - }, - space_heater: { - component: () => SpaceHeater, - scrollable: false, - }, - spawners_menu: { - component: () => SpawnersMenu, - scrollable: true, - }, - station_alert: { - component: () => StationAlertConsole, - scrollable: true, - }, - suit_storage_unit: { - component: () => SuitStorageUnit, - scrollable: false, - }, - synd_contract: { - component: () => SyndContractor, - wrapper: () => NtosWrapper, - scrollable: true, - theme: 'syndicate', - }, - tanks: { - component: () => Tank, - scrollable: false, - }, - tank_dispenser: { - component: () => TankDispenser, - scrollable: false, - }, - teleporter: { - component: () => Teleporter, - scrollable: false, - }, - thermomachine: { - component: () => ThermoMachine, - scrollable: false, - }, - timer: { - component: () => Timer, - scrollable: false, - }, - transfer_valve: { - component: () => TransferValve, - scrollable: false, - }, - turbine_computer: { - component: () => TurbineComputer, - scrollable: false, - }, - uplink: { - component: () => Uplink, - scrollable: true, - theme: 'syndicate', - }, - vault_controller: { - component: () => VaultController, - scrollable: false, - }, - vending: { - component: () => Vending, - scrollable: true, - }, - wires: { - component: () => Wires, - scrollable: false, - }, - scan_consolenew: { - component: () => DnaConsole, - scrollable: true, - }, -}; - -export const getRoute = state => { +export const getRoutedComponent = state => { if (process.env.NODE_ENV !== 'production') { // Show a kitchen sink if (state.showKitchenSink) { const { KitchenSink } = require('./interfaces/KitchenSink'); - return { - component: () => KitchenSink, - scrollable: true, - }; + return KitchenSink; } } - // Refer to the routing table - return ROUTES[state.config && state.config.interface]; + const name = state.config?.interface; + if (!name) { + throw new Error('Interface is undefined.'); + } + const esModule = require(`./interfaces/${name}.js`); + const Component = esModule[name]; + if (!Component) { + throw new Error(`Interface "${name}" is missing an export.`); + } + return Component; }; + +// const ROUTES = { +// achievements: { +// component: () => Achievements, +// scrollable: true, +// }, +// ai_airlock: { +// component: () => AiAirlock, +// scrollable: false, +// }, +// airalarm: { +// component: () => AirAlarm, +// scrollable: true, +// }, +// ai_restorer: { +// component: () => AiRestorer, +// scrollable: true, +// }, +// airlock_electronics: { +// component: () => AirlockElectronics, +// scrollable: false, +// }, +// apc: { +// component: () => Apc, +// scrollable: false, +// }, +// atmos_alert: { +// component: () => AtmosAlertConsole, +// scrollable: true, +// }, +// atmos_control: { +// component: () => AtmosControlConsole, +// scrollable: true, +// }, +// atmos_filter: { +// component: () => AtmosFilter, +// scrollable: false, +// }, +// atmos_mixer: { +// component: () => AtmosMixer, +// scrollable: false, +// }, +// atmos_pump: { +// component: () => AtmosPump, +// scrollable: false, +// }, +// announcement_system: { +// component: () => AutomatedAnnouncement, +// scrollable: false, +// }, +// bepis: { +// component: () => Bepis, +// scrollable: false, +// }, +// bank_machine: { +// component: () => BankMachine, +// scrollable: false, +// }, +// blackmarket_uplink: { +// component: () => BlackmarketUplink, +// scrollable: true, +// theme: 'hackerman', +// }, +// borgopanel: { +// component: () => BorgPanel, +// scrollable: true, +// }, +// brig_timer: { +// component: () => BrigTimer, +// scrollable: false, +// }, +// bsa: { +// component: () => BluespaceArtillery, +// scrollable: false, +// }, +// camera_console: { +// component: () => CameraConsole, +// wrapper: () => CameraConsoleWrapper, +// scrollable: true, +// }, +// canister: { +// component: () => Canister, +// scrollable: false, +// }, +// canvas: { +// component: () => Canvas, +// scrollable: false, +// }, +// cargo: { +// component: () => Cargo, +// scrollable: true, +// }, +// cargo_express: { +// component: () => CargoExpress, +// scrollable: true, +// }, +// cargo_hold_terminal: { +// component: () => CargoHoldTerminal, +// scrollable: true, +// }, +// cellular_emporium: { +// component: () => CellularEmporium, +// scrollable: true, +// }, +// centcom_podlauncher: { +// component: () => CentcomPodLauncher, +// scrollable: false, +// }, +// acclimator: { +// component: () => ChemAcclimator, +// scrollable: false, +// }, +// chem_dispenser: { +// component: () => ChemDispenser, +// scrollable: true, +// }, +// chemical_filter: { +// component: () => ChemFilter, +// scrollable: true, +// }, +// chem_heater: { +// component: () => ChemHeater, +// scrollable: true, +// }, +// chem_master: { +// component: () => ChemMaster, +// scrollable: true, +// }, +// chem_press: { +// component: () => ChemPress, +// scrollable: false, +// }, +// reaction_chamber: { +// component: () => ChemReactionChamber, +// scrollable: true, +// }, +// chem_splitter: { +// component: () => ChemSplitter, +// scrollable: false, +// }, +// chem_synthesizer: { +// component: () => ChemDebugSynthesizer, +// scrollable: false, +// }, +// synthesizer: { +// component: () => ChemSynthesizer, +// scrollable: false, +// }, +// codex_gigas: { +// component: () => CodexGigas, +// scrollable: false, +// }, +// computer_fabricator: { +// component: () => ComputerFabricator, +// scrollable: false, +// }, +// crayon: { +// component: () => Crayon, +// scrollable: true, +// }, +// crew: { +// component: () => CrewConsole, +// scrollable: true, +// }, +// cryo: { +// component: () => Cryo, +// scrollable: false, +// }, +// decal_painter: { +// component: () => DecalPainter, +// scrollable: false, +// }, +// disposal_unit: { +// component: () => DisposalUnit, +// scrollable: false, +// }, +// dna_vault: { +// component: () => DnaVault, +// scrollable: false, +// }, +// eightball: { +// component: () => EightBallVote, +// scrollable: false, +// }, +// electropack: { +// component: () => Electropack, +// scrollable: false, +// }, +// emergency_shuttle_console: { +// component: () => EmergencyShuttleConsole, +// scrollable: false, +// }, +// engraved_message: { +// component: () => EngravedMessage, +// scrollable: false, +// }, +// exosuit_control_console: { +// component: () => ExosuitControlConsole, +// scrollable: true, +// }, +// gateway: { +// component: () => Gateway, +// scrollable: true, +// }, +// gps: { +// component: () => Gps, +// scrollable: true, +// }, +// gravity_generator: { +// component: () => GravityGenerator, +// scrollable: false, +// }, +// gulag_console: { +// component: () => GulagTeleporterConsole, +// scrollable: false, +// }, +// gulag_item_reclaimer: { +// component: () => GulagItemReclaimer, +// scrollable: true, +// }, +// holodeck: { +// component: () => Holodeck, +// scrollable: true, +// }, +// hypnochair: { +// component: () => HypnoChair, +// scrollable: false, +// }, +// implantchair: { +// component: () => ImplantChair, +// scrollable: false, +// }, +// infrared_emitter: { +// component: () => InfraredEmitter, +// scrollable: false, +// }, +// intellicard: { +// component: () => Intellicard, +// scrollable: true, +// }, +// keycard_auth: { +// component: () => KeycardAuth, +// scrollable: false, +// }, +// labor_claim_console: { +// component: () => LaborClaimConsole, +// scrollable: false, +// }, +// language_menu: { +// component: () => LanguageMenu, +// scrollable: true, +// }, +// launchpad_console: { +// component: () => LaunchpadConsole, +// scrollable: true, +// }, +// launchpad_remote: { +// component: () => LaunchpadRemote, +// scrollable: false, +// theme: 'syndicate', +// }, +// mech_bay_power_console: { +// component: () => MechBayPowerConsole, +// scrollable: false, +// }, +// medical_kiosk: { +// component: () => MedicalKiosk, +// scrollable: false, +// }, +// mining_vendor: { +// component: () => MiningVendor, +// scrollable: true, +// }, +// mint: { +// component: () => Mint, +// scrollable: false, +// }, +// malfunction_module_picker: { +// component: () => MalfunctionModulePicker, +// scrollable: true, +// theme: 'malfunction', +// }, +// mulebot: { +// component: () => Mule, +// scrollable: false, +// }, +// nanite_chamber_control: { +// component: () => NaniteChamberControl, +// scrollable: true, +// }, +// nanite_cloud_control: { +// component: () => NaniteCloudControl, +// scrollable: true, +// }, +// nanite_program_hub: { +// component: () => NaniteProgramHub, +// scrollable: true, +// }, +// nanite_programmer: { +// component: () => NaniteProgrammer, +// scrollable: true, +// }, +// nanite_remote: { +// component: () => NaniteRemote, +// scrollable: true, +// }, +// notificationpanel: { +// component: () => NotificationPreferences, +// scrollable: true, +// }, +// ntnet_relay: { +// component: () => NtnetRelay, +// scrollable: false, +// }, +// ntos_ai_restorer: { +// component: () => AiRestorer, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_atmos: { +// component: () => NtosAtmos, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_arcade: { +// component: () => NtosArcade, +// wrapper: () => NtosWrapper, +// scrollable: false, +// theme: 'ntos', +// }, +// ntos_card: { +// component: () => NtosCard, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_configuration: { +// component: () => NtosConfiguration, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_crew_manifest: { +// component: () => NtosCrewManifest, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_cyborg_monitor: { +// component: () => NtosCyborgRemoteMonitor, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_file_manager: { +// component: () => NtosFileManager, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_job_manager: { +// component: () => NtosJobManager, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_main: { +// component: () => NtosMain, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_net_chat: { +// component: () => NtosNetChat, +// wrapper: () => NtosWrapper, +// scrollable: false, +// theme: 'ntos', +// }, +// ntos_net_dos: { +// component: () => NtosNetDos, +// wrapper: () => NtosWrapper, +// scrollable: false, +// theme: 'syndicate', +// }, +// ntos_net_downloader: { +// component: () => NtosNetDownloader, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_net_monitor: { +// component: () => NtosNetMonitor, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_power_monitor: { +// component: () => PowerMonitor, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_revelation: { +// component: () => NtosRevelation, +// wrapper: () => NtosWrapper, +// scrollable: false, +// theme: 'syndicate', +// }, +// ntos_robocontrol: { +// component: () => NtosRoboControl, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_shipping: { +// component: () => NtosShipping, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_station_alert: { +// component: () => StationAlertConsole, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// ntos_supermatter_monitor: { +// component: () => NtosSupermatterMonitor, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'ntos', +// }, +// nuclear_bomb: { +// component: () => NuclearBomb, +// scrollable: false, +// theme: 'retro', +// }, +// ore_redemption_machine: { +// component: () => OreRedemptionMachine, +// scrollable: true, +// }, +// ore_box: { +// component: () => OreBox, +// scrollable: true, +// }, +// operating_computer: { +// component: () => OperatingComputer, +// scrollable: true, +// }, +// pandemic: { +// component: () => Pandemic, +// scrollable: true, +// }, +// particle_accelerator: { +// component: () => ParticleAccelerator, +// scrollable: false, +// }, +// personal_crafting: { +// component: () => PersonalCrafting, +// scrollable: true, +// }, +// portable_generator: { +// component: () => PortableGenerator, +// scrollable: false, +// }, +// portable_pump: { +// component: () => PortablePump, +// scrollable: false, +// }, +// portable_scrubber: { +// component: () => PortableScrubber, +// scrollable: false, +// }, +// power_monitor: { +// component: () => PowerMonitor, +// scrollable: true, +// }, +// proximity_sensor: { +// component: () => ProximitySensor, +// scrollable: false, +// }, +// radio: { +// component: () => Radio, +// scrollable: false, +// }, +// radioactive_microlaser: { +// component: () => RadioactiveMicrolaser, +// scrollable: false, +// theme: 'syndicate', +// }, +// remote_robot_control: { +// component: () => RemoteRobotControl, +// scrollable: true, +// }, +// robotics_control_console: { +// component: () => RoboticsControlConsole, +// scrollable: true, +// }, +// roulette: { +// component: () => Roulette, +// scrollable: false, +// theme: 'cardtable', +// }, +// rpd: { +// component: () => RapidPipeDispenser, +// scrollable: true, +// }, +// sat_control: { +// component: () => SatelliteControl, +// scrollable: false, +// }, +// scanner_gate: { +// component: () => ScannerGate, +// scrollable: true, +// }, +// shuttle_manipulator: { +// component: () => ShuttleManipulator, +// scrollable: true, +// }, +// signaler: { +// component: () => Signaler, +// scrollable: false, +// }, +// sleeper: { +// component: () => Sleeper, +// scrollable: false, +// }, +// slime_swap_body: { +// component: () => SlimeBodySwapper, +// scrollable: true, +// }, +// smartvend: { +// component: () => SmartVend, +// scrollable: true, +// }, +// smes: { +// component: () => Smes, +// scrollable: false, +// }, +// smoke_machine: { +// component: () => SmokeMachine, +// scrollable: false, +// }, +// solar_control: { +// component: () => SolarControl, +// scrollable: false, +// }, +// space_heater: { +// component: () => SpaceHeater, +// scrollable: false, +// }, +// spawners_menu: { +// component: () => SpawnersMenu, +// scrollable: true, +// }, +// station_alert: { +// component: () => StationAlertConsole, +// scrollable: true, +// }, +// suit_storage_unit: { +// component: () => SuitStorageUnit, +// scrollable: false, +// }, +// synd_contract: { +// component: () => SyndContractor, +// wrapper: () => NtosWrapper, +// scrollable: true, +// theme: 'syndicate', +// }, +// tanks: { +// component: () => Tank, +// scrollable: false, +// }, +// tank_dispenser: { +// component: () => TankDispenser, +// scrollable: false, +// }, +// teleporter: { +// component: () => Teleporter, +// scrollable: false, +// }, +// thermomachine: { +// component: () => ThermoMachine, +// scrollable: false, +// }, +// timer: { +// component: () => Timer, +// scrollable: false, +// }, +// transfer_valve: { +// component: () => TransferValve, +// scrollable: false, +// }, +// turbine_computer: { +// component: () => TurbineComputer, +// scrollable: false, +// }, +// uplink: { +// component: () => Uplink, +// scrollable: true, +// theme: 'syndicate', +// }, +// vault_controller: { +// component: () => VaultController, +// scrollable: false, +// }, +// vending: { +// component: () => Vending, +// scrollable: true, +// }, +// wires: { +// component: () => Wires, +// scrollable: false, +// }, +// scan_consolenew: { +// component: () => DnaConsole, +// scrollable: true, +// }, +// }; diff --git a/tgui/packages/tgui/store.js b/tgui/packages/tgui/store.js index f52c9e70178..0edaefdfcae 100644 --- a/tgui/packages/tgui/store.js +++ b/tgui/packages/tgui/store.js @@ -1,8 +1,10 @@ import { flow } from 'common/fp'; import { applyMiddleware, createStore as createReduxStore } from 'common/redux'; +import { Component } from 'inferno'; import { backendReducer } from './backend'; import { hotKeyMiddleware, hotKeyReducer } from './hotkeys'; import { createLogger } from './logging'; +import { act } from './byond'; const logger = createLogger('store'); @@ -26,3 +28,14 @@ export const createStore = () => { ]; return createReduxStore(reducer, applyMiddleware(...middleware)); }; + +export class StoreProvider extends Component { + getChildContext() { + const { store } = this.props; + return { store }; + } + + render() { + return this.props.children; + } +} From e9dc313f1169049400633ba4c9fce023446cac55 Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 04:18:19 +0300 Subject: [PATCH 03/46] Improve logging and error reporting --- tgui/packages/tgui/index.js | 1 + tgui/packages/tgui/logging.js | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/tgui/packages/tgui/index.js b/tgui/packages/tgui/index.js index b682bd5f227..c1c7a46ccde 100644 --- a/tgui/packages/tgui/index.js +++ b/tgui/packages/tgui/index.js @@ -46,6 +46,7 @@ const renderLayout = () => { } catch (err) { logger.error('rendering error', err); + throw err; } // Report rendering time if (process.env.NODE_ENV !== 'production') { diff --git a/tgui/packages/tgui/logging.js b/tgui/packages/tgui/logging.js index b0b6f671585..ef678046fbe 100644 --- a/tgui/packages/tgui/logging.js +++ b/tgui/packages/tgui/logging.js @@ -42,3 +42,10 @@ export const createLogger = ns => { error: (...args) => log(LEVEL_ERROR, ns, ...args), }; }; + +/** + * A generic instance of a logger. + * + * Does not have a namespace associated with it. + */ +export const logger = createLogger(); From 2488d67790d6da05b4f2fa59d75025985071cd74 Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 04:39:01 +0300 Subject: [PATCH 04/46] Remove logging from store --- tgui/packages/tgui/store.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tgui/packages/tgui/store.js b/tgui/packages/tgui/store.js index 0edaefdfcae..2fc95f6476e 100644 --- a/tgui/packages/tgui/store.js +++ b/tgui/packages/tgui/store.js @@ -3,16 +3,6 @@ import { applyMiddleware, createStore as createReduxStore } from 'common/redux'; import { Component } from 'inferno'; import { backendReducer } from './backend'; import { hotKeyMiddleware, hotKeyReducer } from './hotkeys'; -import { createLogger } from './logging'; -import { act } from './byond'; - -const logger = createLogger('store'); - -// const loggingMiddleware = store => next => action => { -// const { type, payload } = action; -// logger.log('dispatching', type); -// next(action); -// }; export const createStore = () => { const reducer = flow([ From fc55b6addad612e7764ece25542b159e0e92d3cf Mon Sep 17 00:00:00 2001 From: actioninja Date: Thu, 9 Apr 2020 19:02:31 -0700 Subject: [PATCH 05/46] make interface key not lowercased/no wrapper proc --- code/modules/tgui/tgui.dm | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 8340f993d4d..91d0021d8d8 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -69,7 +69,7 @@ src.window_id = browser_id ? browser_id : "[REF(src_object)]-[ui_key]" // DO NOT replace with \ref here. src_object could potentially be tagged src.custom_browser_id = browser_id ? TRUE : FALSE - set_interface(interface) + src.interface = interface if(title) src.title = sanitize(title) @@ -149,7 +149,7 @@ **/ /datum/tgui/proc/reinitialize(interface, list/data, list/static_data) if(interface) - set_interface(interface) // Set a new interface. + src.interface = interface if(data) initial_data = data if(static_data) @@ -182,16 +182,6 @@ /datum/tgui/proc/set_style(style) src.style = lowertext(style) - /** - * public - * - * Set the interface (template) for this UI. - * - * required interface string The new UI interface. - **/ -/datum/tgui/proc/set_interface(interface) - src.interface = lowertext(interface) - /** * public * From 158e70df990fce070dd862d92f8f9de95d28ce06 Mon Sep 17 00:00:00 2001 From: actioninja Date: Thu, 9 Apr 2020 19:03:45 -0700 Subject: [PATCH 06/46] remove deprecated style var --- code/datums/components/uplink.dm | 1 - code/game/machinery/launch_pad.dm | 1 - .../antagonists/nukeop/equipment/nuclearbomb.dm | 2 -- code/modules/tgui/tgui.dm | 14 -------------- 4 files changed, 18 deletions(-) diff --git a/code/datums/components/uplink.dm b/code/datums/components/uplink.dm index 3dd4ebfaa62..20a550c3b83 100644 --- a/code/datums/components/uplink.dm +++ b/code/datums/components/uplink.dm @@ -127,7 +127,6 @@ if(!ui) ui = new(user, src, ui_key, "Uplink", name, 620, 580, master_ui, state) ui.set_autoupdate(FALSE) // This UI is only ever opened by one person, and never is updated outside of user input. - ui.set_style("syndicate") ui.open() /datum/component/uplink/ui_data(mob/user) diff --git a/code/game/machinery/launch_pad.dm b/code/game/machinery/launch_pad.dm index 2776c05da9e..152e5995e76 100644 --- a/code/game/machinery/launch_pad.dm +++ b/code/game/machinery/launch_pad.dm @@ -325,7 +325,6 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "Launchpad", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height - ui.set_style("syndicate") ui.open() ui.set_autoupdate(TRUE) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 1d7c0bd5458..cc67881e715 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -7,7 +7,6 @@ density = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - ui_style = "nanotrasen" ui_x = 350 ui_y = 442 @@ -265,7 +264,6 @@ ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open) if(!ui) ui = new(user, src, ui_key, "NuclearBomb", name, ui_x, ui_y, master_ui, state) - ui.set_style(ui_style) ui.open() /obj/machinery/nuclearbomb/ui_data(mob/user) diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm index 91d0021d8d8..b225758a7fd 100644 --- a/code/modules/tgui/tgui.dm +++ b/code/modules/tgui/tgui.dm @@ -22,8 +22,6 @@ var/width = 0 /// The window height var/height = 0 - /// The style to be used for this UI. - var/style = "nanotrasen" /// The interface (template) to be used for this UI. var/interface /// Update the UI every MC tick. @@ -121,7 +119,6 @@ // NOTE: Intentional \ref usage; tgui datums can't/shouldn't // be tagged, so this is an effective unwrap html = replacetextEx(html, "\[ref]", "\ref[src]") - html = replacetextEx(html, "\[style]", style) // Open the window. user << browse(html, "window=[window_id];can_minimize=0;auto_format=0;[window_size][have_title_bar]") @@ -172,16 +169,6 @@ master_ui = null qdel(src) - /** - * public - * - * Set the style for this UI. - * - * required style string The new UI style. - **/ -/datum/tgui/proc/set_style(style) - src.style = lowertext(style) - /** * public * @@ -207,7 +194,6 @@ "title" = title, "status" = status, "screen" = ui_screen, - "style" = style, "interface" = interface, "fancy" = user.client.prefs.tgui_fancy, "locked" = user.client.prefs.tgui_lock && !custom_browser_id, From cf0239052c404d0645b8d8b100e9b8a08f80cd70 Mon Sep 17 00:00:00 2001 From: actioninja Date: Thu, 9 Apr 2020 19:43:51 -0700 Subject: [PATCH 07/46] wire ui --- tgui/packages/tgui/interfaces/Wires.js | 100 +++++++++++++------------ 1 file changed, 51 insertions(+), 49 deletions(-) diff --git a/tgui/packages/tgui/interfaces/Wires.js b/tgui/packages/tgui/interfaces/Wires.js index f33b2617382..e3fcdeeebd0 100644 --- a/tgui/packages/tgui/interfaces/Wires.js +++ b/tgui/packages/tgui/interfaces/Wires.js @@ -1,59 +1,61 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; -import { Box, Button, LabeledList, Section } from '../components'; +import { Box, Button, LabeledList, Section, Layout } from '../components'; -export const Wires = props => { - const { act, data } = useBackend(props); +export const Wires = (props, context) => { + const { act, data } = useBackend(context); const wires = data.wires || []; const statuses = data.status || []; return ( - -
- - {wires.map(wire => ( - -
- {!!statuses.length && ( + +
- {statuses.map(status => ( - - {status} - - ))} + + {wires.map(wire => ( + +
- )} -
+ {!!statuses.length && ( +
+ {statuses.map(status => ( + + {status} + + ))} +
+ )} + + ); }; From 5b079bd6a83b8ac84ae127b67a7990d08ce28b39 Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 05:15:35 +0300 Subject: [PATCH 08/46] Add layout typedefs --- tgui/packages/tgui/components/Layout.d.ts | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tgui/packages/tgui/components/Layout.d.ts diff --git a/tgui/packages/tgui/components/Layout.d.ts b/tgui/packages/tgui/components/Layout.d.ts new file mode 100644 index 00000000000..c142d920d2d --- /dev/null +++ b/tgui/packages/tgui/components/Layout.d.ts @@ -0,0 +1,27 @@ +import { Component } from 'inferno'; + +declare interface LayoutProps { + /** + * Makes window resizable. + */ + resizable: boolean, + /** + * Theme applied to the window + */ + theme: string = 'nanotrasen', + children: any, +}; + +export declare class Layout + extends Component {}; + +declare interface LayoutContentProps { + /** + * Makes content scrollable. + */ + scrollable: boolean, + children: any, +}; + +export declare class LayoutContent + extends Component { }; From 4307dd441453e0dba44094065a2f21eb5694656d Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 05:24:40 +0300 Subject: [PATCH 09/46] Move refocusLayout to Layout.js --- tgui/packages/tgui/components/Button.js | 2 +- tgui/packages/tgui/components/Layout.js | 17 ++++++++++++++++- tgui/packages/tgui/interfaces/CameraConsole.js | 2 +- tgui/packages/tgui/interfaces/NtosWrapper.js | 2 +- tgui/packages/tgui/refocus.js | 12 ------------ 5 files changed, 19 insertions(+), 16 deletions(-) delete mode 100644 tgui/packages/tgui/refocus.js diff --git a/tgui/packages/tgui/components/Button.js b/tgui/packages/tgui/components/Button.js index 3b7c3a3776e..367a15db971 100644 --- a/tgui/packages/tgui/components/Button.js +++ b/tgui/packages/tgui/components/Button.js @@ -3,9 +3,9 @@ import { Component, createRef } from 'inferno'; import { tridentVersion } from '../byond'; import { KEY_ENTER, KEY_ESCAPE, KEY_SPACE } from '../hotkeys'; import { createLogger } from '../logging'; -import { refocusLayout } from '../refocus'; import { Box } from './Box'; import { Icon } from './Icon'; +import { refocusLayout } from './Layout'; import { Tooltip } from './Tooltip'; const logger = createLogger('Button'); diff --git a/tgui/packages/tgui/components/Layout.js b/tgui/packages/tgui/components/Layout.js index 0230a1582ce..45f2253d043 100644 --- a/tgui/packages/tgui/components/Layout.js +++ b/tgui/packages/tgui/components/Layout.js @@ -6,13 +6,28 @@ import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants'; import { dragStartHandler, resizeStartHandler } from '../drag'; import { releaseHeldKeys } from '../hotkeys'; import { createLogger } from '../logging'; -import { refocusLayout } from '../refocus'; import { Box } from './Box'; import { Icon } from './Icon'; import { useBackend } from '../backend'; const logger = createLogger('Layout'); +/** + * Brings Layout__content DOM element back to focus. + * + * Commonly used to keep the content scrollable in IE. + */ +export const refocusLayout = () => { + // IE8: Focus method is seemingly fucked. + if (tridentVersion <= 4) { + return; + } + const element = document.getElementById('Layout__content'); + if (element) { + element.focus(); + } +}; + export class Layout extends Component { componentDidMount() { refocusLayout(); diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js index 95e5de4c9bb..d0f7bf1e5ab 100644 --- a/tgui/packages/tgui/interfaces/CameraConsole.js +++ b/tgui/packages/tgui/interfaces/CameraConsole.js @@ -4,7 +4,7 @@ import { classes } from 'common/react'; import { Component, Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Button, ByondUi, Input, Section } from '../components'; -import { refocusLayout } from '../refocus'; +import { refocusLayout } from '../components/Layout'; /** * Returns previous and next camera names relative to the currently diff --git a/tgui/packages/tgui/interfaces/NtosWrapper.js b/tgui/packages/tgui/interfaces/NtosWrapper.js index b342883e79e..4a986c1e4b5 100644 --- a/tgui/packages/tgui/interfaces/NtosWrapper.js +++ b/tgui/packages/tgui/interfaces/NtosWrapper.js @@ -1,6 +1,6 @@ import { useBackend } from '../backend'; import { Box, Button } from '../components'; -import { refocusLayout } from '../refocus'; +import { refocusLayout } from '../components/Layout'; export const NtosWrapper = props => { const { children } = props; diff --git a/tgui/packages/tgui/refocus.js b/tgui/packages/tgui/refocus.js deleted file mode 100644 index 8a96c47ff41..00000000000 --- a/tgui/packages/tgui/refocus.js +++ /dev/null @@ -1,12 +0,0 @@ -import { tridentVersion } from './byond'; - -export const refocusLayout = () => { - // IE8: Focus method is seemingly fucked. - if (tridentVersion <= 4) { - return; - } - const element = document.getElementById('Layout__content'); - if (element) { - element.focus(); - } -}; From 3c78c22ac6e39e7f191b98d1a6848262db616c75 Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 06:51:58 +0300 Subject: [PATCH 10/46] Refactor Layout and styles, PortableGenerator --- tgui/packages/tgui/components/Button.js | 2 +- tgui/packages/tgui/components/Layout.d.ts | 27 --- tgui/packages/tgui/components/Layout.js | 159 +---------------- tgui/packages/tgui/index.js | 6 +- tgui/packages/tgui/interfaces/AirAlarm.js | 14 +- .../packages/tgui/interfaces/CameraConsole.js | 2 +- tgui/packages/tgui/interfaces/NtosMain.js | 101 +++++------ tgui/packages/tgui/interfaces/NtosWrapper.js | 109 ------------ .../tgui/interfaces/PortableGenerator.js | 165 +++++++++--------- tgui/packages/tgui/layouts/Layout.js | 58 ++++++ tgui/packages/tgui/layouts/NtosWindow.js | 119 +++++++++++++ tgui/packages/tgui/layouts/Window.js | 142 +++++++++++++++ tgui/packages/tgui/layouts/index.js | 3 + tgui/packages/tgui/routes.js | 8 - .../CameraConsole.scss | 0 .../NuclearBomb.scss | 0 .../{components => interfaces}/Roulette.scss | 0 tgui/packages/tgui/styles/layouts/Layout.scss | 41 +++++ .../{components => layouts}/NtosHeader.scss | 0 .../NtosWindow.scss} | 4 +- .../{components => layouts}/TitleBar.scss | 0 .../Layout.scss => layouts/Window.scss} | 55 +----- tgui/packages/tgui/styles/main.scss | 19 +- .../tgui/styles/themes/cardtable.scss | 8 +- .../tgui/styles/themes/hackerman.scss | 7 +- .../tgui/styles/themes/malfunction.scss | 11 +- tgui/packages/tgui/styles/themes/ntos.scss | 7 +- tgui/packages/tgui/styles/themes/retro.scss | 7 +- .../tgui/styles/themes/syndicate.scss | 11 +- 29 files changed, 571 insertions(+), 514 deletions(-) delete mode 100644 tgui/packages/tgui/components/Layout.d.ts delete mode 100644 tgui/packages/tgui/interfaces/NtosWrapper.js create mode 100644 tgui/packages/tgui/layouts/Layout.js create mode 100644 tgui/packages/tgui/layouts/NtosWindow.js create mode 100644 tgui/packages/tgui/layouts/Window.js create mode 100644 tgui/packages/tgui/layouts/index.js rename tgui/packages/tgui/styles/{components => interfaces}/CameraConsole.scss (100%) rename tgui/packages/tgui/styles/{components => interfaces}/NuclearBomb.scss (100%) rename tgui/packages/tgui/styles/{components => interfaces}/Roulette.scss (100%) create mode 100644 tgui/packages/tgui/styles/layouts/Layout.scss rename tgui/packages/tgui/styles/{components => layouts}/NtosHeader.scss (100%) rename tgui/packages/tgui/styles/{components/NtosWrapper.scss => layouts/NtosWindow.scss} (83%) rename tgui/packages/tgui/styles/{components => layouts}/TitleBar.scss (100%) rename tgui/packages/tgui/styles/{components/Layout.scss => layouts/Window.scss} (54%) diff --git a/tgui/packages/tgui/components/Button.js b/tgui/packages/tgui/components/Button.js index 367a15db971..2ad326e47e6 100644 --- a/tgui/packages/tgui/components/Button.js +++ b/tgui/packages/tgui/components/Button.js @@ -2,10 +2,10 @@ import { classes, pureComponentHooks } from 'common/react'; import { Component, createRef } from 'inferno'; import { tridentVersion } from '../byond'; import { KEY_ENTER, KEY_ESCAPE, KEY_SPACE } from '../hotkeys'; +import { refocusLayout } from '../layouts'; import { createLogger } from '../logging'; import { Box } from './Box'; import { Icon } from './Icon'; -import { refocusLayout } from './Layout'; import { Tooltip } from './Tooltip'; const logger = createLogger('Button'); diff --git a/tgui/packages/tgui/components/Layout.d.ts b/tgui/packages/tgui/components/Layout.d.ts deleted file mode 100644 index c142d920d2d..00000000000 --- a/tgui/packages/tgui/components/Layout.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Component } from 'inferno'; - -declare interface LayoutProps { - /** - * Makes window resizable. - */ - resizable: boolean, - /** - * Theme applied to the window - */ - theme: string = 'nanotrasen', - children: any, -}; - -export declare class Layout - extends Component {}; - -declare interface LayoutContentProps { - /** - * Makes content scrollable. - */ - scrollable: boolean, - children: any, -}; - -export declare class LayoutContent - extends Component { }; diff --git a/tgui/packages/tgui/components/Layout.js b/tgui/packages/tgui/components/Layout.js index 45f2253d043..052ac987293 100644 --- a/tgui/packages/tgui/components/Layout.js +++ b/tgui/packages/tgui/components/Layout.js @@ -1,160 +1,9 @@ -import { classes } from 'common/react'; -import { decodeHtmlEntities, toTitleCase } from 'common/string'; -import { Component, Fragment } from 'inferno'; -import { runCommand, tridentVersion, winset } from '../byond'; -import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants'; -import { dragStartHandler, resizeStartHandler } from '../drag'; -import { releaseHeldKeys } from '../hotkeys'; -import { createLogger } from '../logging'; -import { Box } from './Box'; -import { Icon } from './Icon'; -import { useBackend } from '../backend'; - -const logger = createLogger('Layout'); - /** - * Brings Layout__content DOM element back to focus. - * - * Commonly used to keep the content scrollable in IE. + * DELETE ME when you're done moving to Window. */ -export const refocusLayout = () => { - // IE8: Focus method is seemingly fucked. - if (tridentVersion <= 4) { - return; - } - const element = document.getElementById('Layout__content'); - if (element) { - element.focus(); - } -}; - -export class Layout extends Component { - componentDidMount() { - refocusLayout(); - } - - render() { - const { - resizable, - theme = 'nanotrasen', - children, - } = this.props; - const { - config, - debugLayout, - } = useBackend(this.context); - // Determine when to show dimmer - const showDimmer = config.observer - ? config.status < UI_DISABLED - : config.status < UI_INTERACTIVE; - return ( -
-
- { - logger.log('pressed close'); - releaseHeldKeys(); - winset(config.window, 'is-visible', false); - runCommand(`uiclose ${config.ref}`); - }} /> -
- {children} - {showDimmer && ( -
- )} -
- {config.fancy && resizable && ( - -
-
-
- - )} -
-
- ); - } -} - -const LayoutContent = props => { - const { scrollable, children } = props; - return ( -
- - {children} - -
- ); -}; -Layout.Content = LayoutContent; +import { Window } from '../layouts'; -const statusToColor = status => { - switch (status) { - case UI_INTERACTIVE: - return 'good'; - case UI_UPDATE: - return 'average'; - case UI_DISABLED: - default: - return 'bad'; - } -}; +const Layout = Window; -const TitleBar = props => { - const { - className, - title, - status, - fancy, - onDragStart, - onClose, - } = props; - return ( -
- -
- {title === title.toLowerCase() - ? toTitleCase(title) - : title} -
-
fancy && onDragStart(e)} /> - {!!fancy && ( -
- {tridentVersion <= 4 ? 'x' : '×'} -
- )} -
- ); -}; +export { Layout }; diff --git a/tgui/packages/tgui/index.js b/tgui/packages/tgui/index.js index c1c7a46ccde..ee3588211b6 100644 --- a/tgui/packages/tgui/index.js +++ b/tgui/packages/tgui/index.js @@ -107,7 +107,11 @@ const setupApp = () => { // Enable hot module reloading if (module.hot) { setupHotReloading(); - module.hot.accept(['./components', './routes'], () => { + module.hot.accept([ + './components', + './layouts', + './routes', + ], () => { renderLayout(); }); } diff --git a/tgui/packages/tgui/interfaces/AirAlarm.js b/tgui/packages/tgui/interfaces/AirAlarm.js index f77f88281d8..c451c81166a 100644 --- a/tgui/packages/tgui/interfaces/AirAlarm.js +++ b/tgui/packages/tgui/interfaces/AirAlarm.js @@ -2,19 +2,17 @@ import { toFixed } from 'common/math'; import { decodeHtmlEntities } from 'common/string'; import { Fragment } from 'inferno'; import { useBackend } from '../backend'; -import { Box, Button, LabeledList, Layout, NumberInput, Section } from '../components'; +import { Box, Button, LabeledList, NumberInput, Section } from '../components'; import { getGasLabel } from '../constants'; -import { createLogger } from '../logging'; +import { Window } from '../layouts'; import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox'; -const logger = createLogger('AirAlarm'); - export const AirAlarm = (props, context) => { const { act, data } = useBackend(context); const locked = data.locked && !data.siliconUser; return ( - - + + { {!locked && ( )} - - + + ); }; diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js index d0f7bf1e5ab..707416bcc3d 100644 --- a/tgui/packages/tgui/interfaces/CameraConsole.js +++ b/tgui/packages/tgui/interfaces/CameraConsole.js @@ -4,7 +4,7 @@ import { classes } from 'common/react'; import { Component, Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Button, ByondUi, Input, Section } from '../components'; -import { refocusLayout } from '../components/Layout'; +import { refocusLayout } from '../layouts'; /** * Returns previous and next camera names relative to the currently diff --git a/tgui/packages/tgui/interfaces/NtosMain.js b/tgui/packages/tgui/interfaces/NtosMain.js index fdcb1819983..84c8c9b6da0 100644 --- a/tgui/packages/tgui/interfaces/NtosMain.js +++ b/tgui/packages/tgui/interfaces/NtosMain.js @@ -1,6 +1,6 @@ -import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Button, ColorBox, Section, Table } from '../components'; +import { NtosWindow } from '../layouts'; const PROGRAM_ICONS = { compconfig: 'cog', @@ -20,8 +20,8 @@ const PROGRAM_ICONS = { shipping: 'tags', }; -export const NtosMain = props => { - const { act, data } = useBackend(props); +export const NtosMain = (props, context) => { + const { act, data } = useBackend(context); const { programs = [], has_light, @@ -29,56 +29,59 @@ export const NtosMain = props => { comp_light_color, } = data; return ( - - {!!has_light && ( -
- - -
- )} -
-
- {programs.map(program => ( - - - + + + )} +
+
+ {programs.map(program => ( + +
-
- + + + {!!program.running && ( +
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/NtosWrapper.js b/tgui/packages/tgui/interfaces/NtosWrapper.js deleted file mode 100644 index 4a986c1e4b5..00000000000 --- a/tgui/packages/tgui/interfaces/NtosWrapper.js +++ /dev/null @@ -1,109 +0,0 @@ -import { useBackend } from '../backend'; -import { Box, Button } from '../components'; -import { refocusLayout } from '../components/Layout'; - -export const NtosWrapper = props => { - const { children } = props; - const { act, data } = useBackend(props); - const { - PC_batteryicon, - PC_showbatteryicon, - PC_batterypercent, - PC_ntneticon, - PC_apclinkicon, - PC_stationtime, - PC_programheaders = [], - PC_showexitprogram, - } = data; - return ( -
-
{ - refocusLayout(); - }}> -
- - {PC_stationtime} - - - NtOS - -
-
- {PC_programheaders.map(header => ( - - - - ))} - - {PC_ntneticon && ( - - )} - - {!!PC_showbatteryicon && PC_batteryicon && ( - - {PC_batteryicon && ( - - )} - {PC_batterypercent && ( - PC_batterypercent - )} - - )} - {PC_apclinkicon && ( - - - - )} - {!!PC_showexitprogram && ( -
-
-
- {children} -
-
- ); -}; diff --git a/tgui/packages/tgui/interfaces/PortableGenerator.js b/tgui/packages/tgui/interfaces/PortableGenerator.js index b29c71f38f7..5a1b0cd46c2 100644 --- a/tgui/packages/tgui/interfaces/PortableGenerator.js +++ b/tgui/packages/tgui/interfaces/PortableGenerator.js @@ -1,92 +1,93 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, LabeledList, NoticeBox, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; -export const PortableGenerator = props => { - const { act, data } = useBackend(props); - let stackPercentState; - if (data.stack_percent > 50) { - stackPercentState = 'good'; - } - else if (data.stack_percent > 15) { - stackPercentState = 'average'; - } - else { - stackPercentState = 'bad'; - } +export const PortableGenerator = (props, context) => { + const { act, data } = useBackend(context); + const { + stack_percent, + } = data; + const stackPercentState = ( + stack_percent > 50 && 'good' + || stack_percent > 15 && 'average' + || 'bad' + ); return ( - - {!data.anchored && ( - Generator not anchored. - )} -
- - - - - - {data.sheets} - {(data.sheets >= 1) && ( + + + {!data.anchored && ( + Generator not anchored. + )} +
+ + - )} - - - - - - {data.current_heat < 100 ? ( - Nominal - ) : ( - data.current_heat < 200 ? ( - Caution + + + {data.sheets} + {(data.sheets >= 1) && ( + + )} + + + + + + {data.current_heat < 100 ? ( + Nominal ) : ( - DANGER - ) - )} - - -
-
- - - {data.power_output} - - - - - - - - {data.connected ? data.power_available : "Unconnected"} - - - -
- + data.current_heat < 200 ? ( + Caution + ) : ( + DANGER + ) + )} +
+
+
+
+ + + {data.power_output} + + + + + + + + {data.connected ? data.power_available : "Unconnected"} + + + +
+ + ); }; diff --git a/tgui/packages/tgui/layouts/Layout.js b/tgui/packages/tgui/layouts/Layout.js new file mode 100644 index 00000000000..7a17612fdeb --- /dev/null +++ b/tgui/packages/tgui/layouts/Layout.js @@ -0,0 +1,58 @@ +import { classes } from 'common/react'; +import { tridentVersion } from '../byond'; + +/** + * Brings Layout__content DOM element back to focus. + * + * Commonly used to keep the content scrollable in IE. + */ +export const refocusLayout = () => { + // IE8: Focus method is seemingly fucked. + if (tridentVersion <= 4) { + return; + } + const element = document.getElementById('Layout__content'); + if (element) { + element.focus(); + } +}; + +export const Layout = props => { + const { + className, + theme = 'nanotrasen', + children, + } = props; + return ( +
+
+ {children} +
+
+ ); +}; + +const LayoutContent = props => { + const { + className, + scrollable, + children, + } = props; + return ( +
+ {children} +
+ ); +}; + +Layout.Content = LayoutContent; diff --git a/tgui/packages/tgui/layouts/NtosWindow.js b/tgui/packages/tgui/layouts/NtosWindow.js new file mode 100644 index 00000000000..c3a5579262c --- /dev/null +++ b/tgui/packages/tgui/layouts/NtosWindow.js @@ -0,0 +1,119 @@ +import { useBackend } from '../backend'; +import { Box, Button } from '../components'; +import { Layout, refocusLayout } from './Layout'; + +export const NtosWindow = (props, context) => { + const { children } = props; + const { act, data } = useBackend(context); + const { + PC_batteryicon, + PC_showbatteryicon, + PC_batterypercent, + PC_ntneticon, + PC_apclinkicon, + PC_stationtime, + PC_programheaders = [], + PC_showexitprogram, + } = data; + return ( + +
+
{ + refocusLayout(); + }}> +
+ + {PC_stationtime} + + + NtOS + +
+
+ {PC_programheaders.map(header => ( + + + + ))} + + {PC_ntneticon && ( + + )} + + {!!PC_showbatteryicon && PC_batteryicon && ( + + {PC_batteryicon && ( + + )} + {PC_batterypercent && ( + PC_batterypercent + )} + + )} + {PC_apclinkicon && ( + + + + )} + {!!PC_showexitprogram && ( +
+
+ {children} +
+
+ ); +}; + +const NtosWindowContent = props => { + return ( +
+ +
+ ); +}; + +NtosWindow.Content = NtosWindowContent; diff --git a/tgui/packages/tgui/layouts/Window.js b/tgui/packages/tgui/layouts/Window.js new file mode 100644 index 00000000000..21f8e1792da --- /dev/null +++ b/tgui/packages/tgui/layouts/Window.js @@ -0,0 +1,142 @@ +import { classes } from 'common/react'; +import { decodeHtmlEntities, toTitleCase } from 'common/string'; +import { Component, Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { runCommand, tridentVersion, winset } from '../byond'; +import { Box, Icon } from '../components'; +import { UI_DISABLED, UI_INTERACTIVE, UI_UPDATE } from '../constants'; +import { dragStartHandler, resizeStartHandler } from '../drag'; +import { releaseHeldKeys } from '../hotkeys'; +import { createLogger } from '../logging'; +import { Layout, refocusLayout } from './Layout'; + +const logger = createLogger('Window'); + +export class Window extends Component { + componentDidMount() { + refocusLayout(); + } + + render() { + const { + resizable, + theme, + children, + } = this.props; + const { + config, + debugLayout, + } = useBackend(this.context); + // Determine when to show dimmer + const showDimmer = config.observer + ? config.status < UI_DISABLED + : config.status < UI_INTERACTIVE; + return ( + + { + logger.log('pressed close'); + releaseHeldKeys(); + winset(config.window, 'is-visible', false); + runCommand(`uiclose ${config.ref}`); + }} /> +
+ {children} + {showDimmer && ( +
+ )} +
+ {config.fancy && resizable && ( + +
+
+
+ + )} + + ); + } +} + +const WindowContent = props => { + const { scrollable, children } = props; + // A bit lazy to actually write styles for it, + // so we simply include a Box with margins. + return ( + + + {children} + + + ); +}; + +Window.Content = WindowContent; + +const statusToColor = status => { + switch (status) { + case UI_INTERACTIVE: + return 'good'; + case UI_UPDATE: + return 'average'; + case UI_DISABLED: + default: + return 'bad'; + } +}; + +const TitleBar = props => { + const { + className, + title, + status, + fancy, + onDragStart, + onClose, + } = props; + return ( +
+ +
+ {title === title.toLowerCase() + ? toTitleCase(title) + : title} +
+
fancy && onDragStart(e)} /> + {!!fancy && ( +
+ {tridentVersion <= 4 ? 'x' : '×'} +
+ )} +
+ ); +}; diff --git a/tgui/packages/tgui/layouts/index.js b/tgui/packages/tgui/layouts/index.js new file mode 100644 index 00000000000..13351853bd0 --- /dev/null +++ b/tgui/packages/tgui/layouts/index.js @@ -0,0 +1,3 @@ +export { Layout, refocusLayout } from './Layout'; +export { NtosWindow } from './NtosWindow'; +export { Window } from './Window'; diff --git a/tgui/packages/tgui/routes.js b/tgui/packages/tgui/routes.js index 393d5cb97d9..f8041aab55a 100644 --- a/tgui/packages/tgui/routes.js +++ b/tgui/packages/tgui/routes.js @@ -27,10 +27,6 @@ export const getRoutedComponent = state => { // component: () => AiAirlock, // scrollable: false, // }, -// airalarm: { -// component: () => AirAlarm, -// scrollable: true, -// }, // ai_restorer: { // component: () => AiRestorer, // scrollable: true, @@ -480,10 +476,6 @@ export const getRoutedComponent = state => { // component: () => PersonalCrafting, // scrollable: true, // }, -// portable_generator: { -// component: () => PortableGenerator, -// scrollable: false, -// }, // portable_pump: { // component: () => PortablePump, // scrollable: false, diff --git a/tgui/packages/tgui/styles/components/CameraConsole.scss b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss similarity index 100% rename from tgui/packages/tgui/styles/components/CameraConsole.scss rename to tgui/packages/tgui/styles/interfaces/CameraConsole.scss diff --git a/tgui/packages/tgui/styles/components/NuclearBomb.scss b/tgui/packages/tgui/styles/interfaces/NuclearBomb.scss similarity index 100% rename from tgui/packages/tgui/styles/components/NuclearBomb.scss rename to tgui/packages/tgui/styles/interfaces/NuclearBomb.scss diff --git a/tgui/packages/tgui/styles/components/Roulette.scss b/tgui/packages/tgui/styles/interfaces/Roulette.scss similarity index 100% rename from tgui/packages/tgui/styles/components/Roulette.scss rename to tgui/packages/tgui/styles/interfaces/Roulette.scss diff --git a/tgui/packages/tgui/styles/layouts/Layout.scss b/tgui/packages/tgui/styles/layouts/Layout.scss new file mode 100644 index 00000000000..8f5572345ca --- /dev/null +++ b/tgui/packages/tgui/styles/layouts/Layout.scss @@ -0,0 +1,41 @@ +@use 'sass:color'; +@use '../base.scss'; + +.Layout__content { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow-x: hidden; + overflow-y: hidden; + margin-bottom: -6px; + + // Fancy scrollbar + scrollbar-base-color: color.scale( + base.$color-bg, + $lightness: -25%); + scrollbar-face-color: color.scale( + base.$color-bg, + $lightness: 10%); + scrollbar-3dlight-color: color.scale( + base.$color-bg, + $lightness: 0%); + scrollbar-highlight-color: color.scale( + base.$color-bg, + $lightness: 0%); + scrollbar-track-color: color.scale( + base.$color-bg, + $lightness: -25%); + scrollbar-arrow-color: color.scale( + base.$color-bg, + $lightness: 50%); + scrollbar-shadow-color: color.scale( + base.$color-bg, + $lightness: 10%); +} + +.Layout__content--scrollable { + overflow-y: scroll; + margin-bottom: 0; +} diff --git a/tgui/packages/tgui/styles/components/NtosHeader.scss b/tgui/packages/tgui/styles/layouts/NtosHeader.scss similarity index 100% rename from tgui/packages/tgui/styles/components/NtosHeader.scss rename to tgui/packages/tgui/styles/layouts/NtosHeader.scss diff --git a/tgui/packages/tgui/styles/components/NtosWrapper.scss b/tgui/packages/tgui/styles/layouts/NtosWindow.scss similarity index 83% rename from tgui/packages/tgui/styles/components/NtosWrapper.scss rename to tgui/packages/tgui/styles/layouts/NtosWindow.scss index 87b803e2d47..9dd392b3e34 100644 --- a/tgui/packages/tgui/styles/components/NtosWrapper.scss +++ b/tgui/packages/tgui/styles/layouts/NtosWindow.scss @@ -1,4 +1,4 @@ -.NtosWrapper__header { +.NtosWindow__header { position: absolute; top: 0; left: 0; @@ -12,7 +12,7 @@ -ms-user-select: none; } -.NtosWrapper__content .Layout__content { +.NtosWindow__content .Layout__content { margin-top: 28px; font-family: Consolas, monospace; font-size: 14px; diff --git a/tgui/packages/tgui/styles/components/TitleBar.scss b/tgui/packages/tgui/styles/layouts/TitleBar.scss similarity index 100% rename from tgui/packages/tgui/styles/components/TitleBar.scss rename to tgui/packages/tgui/styles/layouts/TitleBar.scss diff --git a/tgui/packages/tgui/styles/components/Layout.scss b/tgui/packages/tgui/styles/layouts/Window.scss similarity index 54% rename from tgui/packages/tgui/styles/components/Layout.scss rename to tgui/packages/tgui/styles/layouts/Window.scss index dddaebf01e4..e4e6a353ee5 100644 --- a/tgui/packages/tgui/styles/components/Layout.scss +++ b/tgui/packages/tgui/styles/layouts/Window.scss @@ -2,7 +2,7 @@ @use '../base.scss'; @use '../functions.scss' as *; -.Layout { +.Window { position: fixed; top: 0; bottom: 0; @@ -15,7 +15,7 @@ base.$color-bg-end 100%); } -.Layout__titleBar { +.Window__titleBar { position: fixed; z-index: 1; top: 0; @@ -25,7 +25,7 @@ } // Everything after the title bar -.Layout__rest { +.Window__rest { position: fixed; top: 32px; bottom: 0; @@ -33,46 +33,7 @@ right: 0; } -.Layout__content { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - overflow-x: hidden; - overflow-y: hidden; - margin-bottom: -6px; - - // Fancy scrollbar - scrollbar-base-color: color.scale( - base.$color-bg, - $lightness: -25%); - scrollbar-face-color: color.scale( - base.$color-bg, - $lightness: 10%); - scrollbar-3dlight-color: color.scale( - base.$color-bg, - $lightness: 0%); - scrollbar-highlight-color: color.scale( - base.$color-bg, - $lightness: 0%); - scrollbar-track-color: color.scale( - base.$color-bg, - $lightness: -25%); - scrollbar-arrow-color: color.scale( - base.$color-bg, - $lightness: 50%); - scrollbar-shadow-color: color.scale( - base.$color-bg, - $lightness: 10%); -} - -.Layout__content--scrollable { - overflow-y: scroll; - margin-bottom: 0; -} - -.Layout__dimmer { +.Window__dimmer { position: fixed; top: 0; bottom: 0; @@ -82,7 +43,7 @@ pointer-events: none; } -.Layout__toast { +.Window__toast { position: fixed; bottom: 0; left: 0; @@ -95,7 +56,7 @@ color: rgba(255, 255, 255, 0.8); } -.Layout__resizeHandle__se { +.Window__resizeHandle__se { position: fixed; bottom: 0; right: 0; @@ -104,7 +65,7 @@ cursor: se-resize; } -.Layout__resizeHandle__s { +.Window__resizeHandle__s { position: fixed; bottom: 0; left: 0; @@ -113,7 +74,7 @@ cursor: s-resize; } -.Layout__resizeHandle__e { +.Window__resizeHandle__e { position: fixed; top: 0; bottom: 0; diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index 1e67639fa7b..a47abe207e0 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -17,7 +17,6 @@ // Components @include meta.load-css('./components/BlockQuote.scss'); @include meta.load-css('./components/Button.scss'); -@include meta.load-css('./components/CameraConsole.scss'); @include meta.load-css('./components/ColorBox.scss'); @include meta.load-css('./components/Dimmer.scss'); @include meta.load-css('./components/Divider.scss'); @@ -27,21 +26,27 @@ @include meta.load-css('./components/Input.scss'); @include meta.load-css('./components/Knob.scss'); @include meta.load-css('./components/LabeledList.scss'); -@include meta.load-css('./components/Layout.scss'); @include meta.load-css('./components/NoticeBox.scss'); -@include meta.load-css('./components/NtosHeader.scss'); -@include meta.load-css('./components/NtosWrapper.scss'); -@include meta.load-css('./components/NuclearBomb.scss'); @include meta.load-css('./components/NumberInput.scss'); @include meta.load-css('./components/ProgressBar.scss'); -@include meta.load-css('./components/Roulette.scss'); @include meta.load-css('./components/Section.scss'); @include meta.load-css('./components/Slider.scss'); @include meta.load-css('./components/Table.scss'); @include meta.load-css('./components/Tabs.scss'); -@include meta.load-css('./components/TitleBar.scss'); @include meta.load-css('./components/Tooltip.scss'); +// Interfaces +@include meta.load-css('./interfaces/CameraConsole.scss'); +@include meta.load-css('./interfaces/NuclearBomb.scss'); +@include meta.load-css('./interfaces/Roulette.scss'); + +// Layouts +@include meta.load-css('./layouts/Layout.scss'); +@include meta.load-css('./layouts/NtosHeader.scss'); +@include meta.load-css('./layouts/NtosWindow.scss'); +@include meta.load-css('./layouts/TitleBar.scss'); +@include meta.load-css('./layouts/Window.scss'); + // NT Theme .Layout__content { background-image: url('../assets/bg-nanotrasen.svg'); diff --git a/tgui/packages/tgui/styles/themes/cardtable.scss b/tgui/packages/tgui/styles/themes/cardtable.scss index 67ae46c2205..6b6c456357e 100644 --- a/tgui/packages/tgui/styles/themes/cardtable.scss +++ b/tgui/packages/tgui/styles/themes/cardtable.scss @@ -25,16 +25,18 @@ 'color-caution': #be6209, 'color-danger': #9a9d00, )); - @include meta.load-css('../components/Layout.scss'); @include meta.load-css('../components/NumberInput.scss', $with: ( 'border-color': #FFFFFF, )); - @include meta.load-css('../components/ProgressBar.scss', $with: ( 'color-background': rgba(0, 0, 0, 0.5), )); @include meta.load-css('../components/Section.scss'); - @include meta.load-css('../components/TitleBar.scss', $with: ( + + // Layouts + @include meta.load-css('../layouts/Layout.scss'); + @include meta.load-css('../layouts/Window.scss'); + @include meta.load-css('../layouts/TitleBar.scss', $with: ( 'color-background': #381608, )); diff --git a/tgui/packages/tgui/styles/themes/hackerman.scss b/tgui/packages/tgui/styles/themes/hackerman.scss index 73745ce6c8a..96d3cb8d92c 100644 --- a/tgui/packages/tgui/styles/themes/hackerman.scss +++ b/tgui/packages/tgui/styles/themes/hackerman.scss @@ -25,9 +25,12 @@ @include meta.load-css('../components/Input.scss', $with: ( 'border-color': colors.$primary, )); - @include meta.load-css('../components/Layout.scss'); @include meta.load-css('../components/Section.scss'); - @include meta.load-css('../components/TitleBar.scss', $with: ( + + // Layouts + @include meta.load-css('../layouts/Layout.scss'); + @include meta.load-css('../layouts/Window.scss'); + @include meta.load-css('../layouts/TitleBar.scss', $with: ( 'color-background': #223d22, )); diff --git a/tgui/packages/tgui/styles/themes/malfunction.scss b/tgui/packages/tgui/styles/themes/malfunction.scss index 53629bddbfb..f433430890a 100644 --- a/tgui/packages/tgui/styles/themes/malfunction.scss +++ b/tgui/packages/tgui/styles/themes/malfunction.scss @@ -27,7 +27,6 @@ @include meta.load-css('../components/Input.scss', $with: ( 'border-color': #910101, )); - @include meta.load-css('../components/Layout.scss'); @include meta.load-css('../components/NoticeBox.scss', $with: ( 'color-first': #1a3f57, 'color-second': #1a3f57, @@ -39,13 +38,17 @@ 'color-background': rgba(0, 0, 0, 0.5), )); @include meta.load-css('../components/Section.scss'); - @include meta.load-css('../components/TitleBar.scss', $with: ( - 'color-background': #1a3f57, - )); @include meta.load-css('../components/Tooltip.scss', $with: ( 'color-background': #235577, )); + // Layouts + @include meta.load-css('../layouts/Layout.scss'); + @include meta.load-css('../layouts/Window.scss'); + @include meta.load-css('../layouts/TitleBar.scss', $with: ( + 'color-background': #1a3f57, + )); + .Layout__content { background-image: none; } diff --git a/tgui/packages/tgui/styles/themes/ntos.scss b/tgui/packages/tgui/styles/themes/ntos.scss index b1335f89b5a..145b0a3657a 100644 --- a/tgui/packages/tgui/styles/themes/ntos.scss +++ b/tgui/packages/tgui/styles/themes/ntos.scss @@ -18,13 +18,16 @@ $nanotrasen: #384e68; 'color-default': $nanotrasen, 'color-transparent-text': rgba(227, 240, 255, 0.75), )); - @include meta.load-css('../components/Layout.scss'); @include meta.load-css('../components/ProgressBar.scss', $with: ( 'color-default': $nanotrasen, 'color-background': rgba(0, 0, 0, 0.5), )); @include meta.load-css('../components/Section.scss'); - @include meta.load-css('../components/TitleBar.scss', $with: ( + + // Layouts + @include meta.load-css('../layouts/Layout.scss'); + @include meta.load-css('../layouts/Window.scss'); + @include meta.load-css('../layouts/TitleBar.scss', $with: ( 'color-background': color.scale($nanotrasen, $lightness: -25%), )); } diff --git a/tgui/packages/tgui/styles/themes/retro.scss b/tgui/packages/tgui/styles/themes/retro.scss index 2c69e1d04d3..800628427cd 100644 --- a/tgui/packages/tgui/styles/themes/retro.scss +++ b/tgui/packages/tgui/styles/themes/retro.scss @@ -26,12 +26,15 @@ 'color-caution': #be6209, 'color-danger': #9a9d00, )); - @include meta.load-css('../components/Layout.scss'); @include meta.load-css('../components/ProgressBar.scss', $with: ( 'color-background': rgba(0, 0, 0, 0.5), )); @include meta.load-css('../components/Section.scss'); - @include meta.load-css('../components/TitleBar.scss', $with: ( + + // Layouts + @include meta.load-css('../layouts/Layout.scss'); + @include meta.load-css('../layouts/Window.scss'); + @include meta.load-css('../layouts/TitleBar.scss', $with: ( 'color-background': #585337, )); diff --git a/tgui/packages/tgui/styles/themes/syndicate.scss b/tgui/packages/tgui/styles/themes/syndicate.scss index 35cfedc4216..0567dee7024 100644 --- a/tgui/packages/tgui/styles/themes/syndicate.scss +++ b/tgui/packages/tgui/styles/themes/syndicate.scss @@ -27,7 +27,6 @@ @include meta.load-css('../components/Input.scss', $with: ( 'border-color': #87ce87, )); - @include meta.load-css('../components/Layout.scss'); @include meta.load-css('../components/NoticeBox.scss', $with: ( 'color-first': #750000, 'color-second': #910101, @@ -39,13 +38,17 @@ 'color-background': rgba(0, 0, 0, 0.5), )); @include meta.load-css('../components/Section.scss'); - @include meta.load-css('../components/TitleBar.scss', $with: ( - 'color-background': #910101, - )); @include meta.load-css('../components/Tooltip.scss', $with: ( 'color-background': #4a0202, )); + // Layouts + @include meta.load-css('../layouts/Layout.scss'); + @include meta.load-css('../layouts/Window.scss'); + @include meta.load-css('../layouts/TitleBar.scss', $with: ( + 'color-background': #910101, + )); + .Layout__content { background-image: url('../../assets/bg-syndicate.svg'); } From 44358c23425f05f686db8da60ec65830f4b6fa1d Mon Sep 17 00:00:00 2001 From: actioninja Date: Thu, 9 Apr 2020 21:11:58 -0700 Subject: [PATCH 11/46] refactor wires to use Window instead of Layout --- tgui/packages/tgui/interfaces/Wires.js | 11 ++--- tgui/packages/tgui/layouts/Layout.js | 58 -------------------------- 2 files changed, 6 insertions(+), 63 deletions(-) delete mode 100644 tgui/packages/tgui/layouts/Layout.js diff --git a/tgui/packages/tgui/interfaces/Wires.js b/tgui/packages/tgui/interfaces/Wires.js index e3fcdeeebd0..6e9ac9b160b 100644 --- a/tgui/packages/tgui/interfaces/Wires.js +++ b/tgui/packages/tgui/interfaces/Wires.js @@ -1,14 +1,15 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; -import { Box, Button, LabeledList, Section, Layout } from '../components'; +import { Box, Button, LabeledList, Section } from '../components'; +import { Window } from '../layouts'; export const Wires = (props, context) => { const { act, data } = useBackend(context); const wires = data.wires || []; const statuses = data.status || []; return ( - - + +
{wires.map(wire => ( @@ -55,7 +56,7 @@ export const Wires = (props, context) => { ))}
)} -
-
+ + ); }; diff --git a/tgui/packages/tgui/layouts/Layout.js b/tgui/packages/tgui/layouts/Layout.js deleted file mode 100644 index 7a17612fdeb..00000000000 --- a/tgui/packages/tgui/layouts/Layout.js +++ /dev/null @@ -1,58 +0,0 @@ -import { classes } from 'common/react'; -import { tridentVersion } from '../byond'; - -/** - * Brings Layout__content DOM element back to focus. - * - * Commonly used to keep the content scrollable in IE. - */ -export const refocusLayout = () => { - // IE8: Focus method is seemingly fucked. - if (tridentVersion <= 4) { - return; - } - const element = document.getElementById('Layout__content'); - if (element) { - element.focus(); - } -}; - -export const Layout = props => { - const { - className, - theme = 'nanotrasen', - children, - } = props; - return ( -
-
- {children} -
-
- ); -}; - -const LayoutContent = props => { - const { - className, - scrollable, - children, - } = props; - return ( -
- {children} -
- ); -}; - -Layout.Content = LayoutContent; From fe81f64dcb943488ead53a39f04ef483744bee89 Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 07:31:12 +0300 Subject: [PATCH 12/46] Apc, Canister, PowerMonitor, Smes --- tgui/packages/tgui/interfaces/Apc.js | 15 +- tgui/packages/tgui/interfaces/Canister.js | 205 ++++++------ .../tgui/interfaces/NtosPowerMonitor.js | 12 + tgui/packages/tgui/interfaces/PowerMonitor.js | 17 +- tgui/packages/tgui/interfaces/Smes.js | 300 +++++++++--------- tgui/packages/tgui/layouts/NtosWindow.js | 9 +- 6 files changed, 299 insertions(+), 259 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/NtosPowerMonitor.js diff --git a/tgui/packages/tgui/interfaces/Apc.js b/tgui/packages/tgui/interfaces/Apc.js index 605f5ef23df..59c65f0ba71 100644 --- a/tgui/packages/tgui/interfaces/Apc.js +++ b/tgui/packages/tgui/interfaces/Apc.js @@ -1,10 +1,21 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, LabeledList, NoticeBox, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; import { InterfaceLockNoticeBox } from './common/InterfaceLockNoticeBox'; -export const Apc = props => { - const { act, data } = useBackend(props); +export const Apc = (props, context) => { + return ( + + + + + + ); +}; + +const ApcContent = (props, context) => { + const { act, data } = useBackend(context); const locked = data.locked && !data.siliconUser; const powerStatusMap = { 2: { diff --git a/tgui/packages/tgui/interfaces/Canister.js b/tgui/packages/tgui/interfaces/Canister.js index 50a4f09fcc8..ddf881007ae 100644 --- a/tgui/packages/tgui/interfaces/Canister.js +++ b/tgui/packages/tgui/interfaces/Canister.js @@ -1,9 +1,10 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { AnimatedNumber, Box, Button, Flex, Knob, LabeledList, NoticeBox, Section } from '../components'; +import { Window } from '../layouts'; -export const Canister = props => { - const { act, data } = useBackend(props); +export const Canister = (props, context) => { + const { act, data } = useBackend(context); const { portConnected, tankPressure, @@ -18,109 +19,111 @@ export const Canister = props => { restricted, } = data; return ( - - - The regulator {hasHoldingTank ? 'is' : 'is not'} connected - to a tank. - -
act('relabel')} /> - )}> - - - act('pressure', { - pressure: value, - })} /> - - - - Valve - - - kPa - + + + + The regulator {hasHoldingTank ? 'is' : 'is not'} connected + to a tank. + +
act('relabel')} /> + )}> + + + act('pressure', { + pressure: value, + })} /> + + + + Valve + + + kPa + +
+
act('valve')} /> - - + icon="eject" + color={valveOpen && 'danger'} + content="Eject" + onClick={() => act('eject')} /> + )}> + {!!hasHoldingTank && ( - - kPa + + {holdingTank.name} - - {portConnected ? 'Connected' : 'Not Connected'} + + kPa - {!!isPrototype && ( - -
-
act('eject')} /> - )}> - {!!hasHoldingTank && ( - - - {holdingTank.name} - - - kPa - - - )} - {!hasHoldingTank && ( - - No Holding Tank - - )} -
- + )} + {!hasHoldingTank && ( + + No Holding Tank + + )} +
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/NtosPowerMonitor.js b/tgui/packages/tgui/interfaces/NtosPowerMonitor.js new file mode 100644 index 00000000000..a9f6d2e8fc2 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosPowerMonitor.js @@ -0,0 +1,12 @@ +import { NtosWindow } from '../layouts'; +import { PowerMonitorContent } from './PowerMonitor'; + +export const NtosPowerMonitor = () => { + return ( + + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/PowerMonitor.js b/tgui/packages/tgui/interfaces/PowerMonitor.js index ebb343039f2..20d6943c605 100644 --- a/tgui/packages/tgui/interfaces/PowerMonitor.js +++ b/tgui/packages/tgui/interfaces/PowerMonitor.js @@ -4,6 +4,8 @@ import { toFixed } from 'common/math'; import { pureComponentHooks } from 'common/react'; import { Component, Fragment } from 'inferno'; import { Box, Button, Chart, ColorBox, Flex, Icon, LabeledList, ProgressBar, Section, Table } from '../components'; +import { Window } from '../layouts'; +import { useBackend } from '../backend'; const PEAK_DRAW = 500000; @@ -12,7 +14,17 @@ const powerRank = str => { return ['w', 'kw', 'mw', 'gw'].indexOf(unit); }; -export class PowerMonitor extends Component { +export const PowerMonitor = () => { + return ( + + + + + + ); +}; + +export class PowerMonitorContent extends Component { constructor() { super(); this.state = { @@ -21,8 +33,7 @@ export class PowerMonitor extends Component { } render() { - const { state } = this.props; - const { data } = state; + const { data } = useBackend(this.context); const { history } = data; const { sortByField } = this.state; const supply = history.supply[history.supply.length - 1] || 0; diff --git a/tgui/packages/tgui/interfaces/Smes.js b/tgui/packages/tgui/interfaces/Smes.js index 368ddda78e3..552ad1d1a5d 100644 --- a/tgui/packages/tgui/interfaces/Smes.js +++ b/tgui/packages/tgui/interfaces/Smes.js @@ -1,13 +1,13 @@ -import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, Flex, LabeledList, ProgressBar, Section, Slider } from '../components'; import { formatPower } from '../format'; +import { Window } from '../layouts'; // Common power multiplier const POWER_MUL = 1e3; -export const Smes = props => { - const { act, data } = useBackend(props); +export const Smes = (props, context) => { + const { act, data } = useBackend(context); const { capacityPercent, capacity, @@ -34,153 +34,155 @@ export const Smes = props => { || 'bad' ); return ( - -
- -
-
- - act('tryinput')}> - {inputAttempt ? 'Auto' : 'Off'} - - }> - - {capacityPercent >= 100 && 'Fully Charged' - || inputting && 'Charging' - || 'Not Charging'} - - - - - + + +
+ +
+
+ + act('input', { - target: 'min', - })} /> + icon={inputAttempt ? 'sync-alt' : 'times'} + selected={inputAttempt} + onClick={() => act('tryinput')}> + {inputAttempt ? 'Auto' : 'Off'} + + }> + + {capacityPercent >= 100 && 'Fully Charged' + || inputting && 'Charging' + || 'Not Charging'} + + + + + +
+
+ + act('input', { - adjust: -10000, - })} /> - - - formatPower(value * POWER_MUL, 1)} - onDrag={(e, value) => act('input', { - target: value * POWER_MUL, - })} /> - - -
-
- - act('tryoutput')}> - {outputAttempt ? 'On' : 'Off'} - - }> - - {outputting - ? 'Sending' - : charge > 0 - ? 'Not Sending' - : 'No Charge'} - - - - - -
- + icon={outputAttempt ? 'power-off' : 'times'} + selected={outputAttempt} + onClick={() => act('tryoutput')}> + {outputAttempt ? 'On' : 'Off'} + + }> + + {outputting + ? 'Sending' + : charge > 0 + ? 'Not Sending' + : 'No Charge'} + +
+ + + +
+ + ); }; diff --git a/tgui/packages/tgui/layouts/NtosWindow.js b/tgui/packages/tgui/layouts/NtosWindow.js index c3a5579262c..010a7b4fda3 100644 --- a/tgui/packages/tgui/layouts/NtosWindow.js +++ b/tgui/packages/tgui/layouts/NtosWindow.js @@ -1,6 +1,7 @@ import { useBackend } from '../backend'; import { Box, Button } from '../components'; -import { Layout, refocusLayout } from './Layout'; +import { refocusLayout } from './Layout'; +import { Window } from './Window'; export const NtosWindow = (props, context) => { const { children } = props; @@ -16,7 +17,7 @@ export const NtosWindow = (props, context) => { PC_showexitprogram, } = data; return ( - +
{
{children}
-
+ ); }; const NtosWindowContent = props => { return (
- +
); }; From 8b63e1acf7b383c20c41b3cddf7cef09659f960b Mon Sep 17 00:00:00 2001 From: Aleksej Komarov Date: Fri, 10 Apr 2020 07:41:27 +0300 Subject: [PATCH 13/46] Undelete the Layout --- tgui/packages/tgui/components/Layout.js | 9 ---- tgui/packages/tgui/components/index.js | 1 - tgui/packages/tgui/layouts/Layout.js | 58 +++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 10 deletions(-) delete mode 100644 tgui/packages/tgui/components/Layout.js create mode 100644 tgui/packages/tgui/layouts/Layout.js diff --git a/tgui/packages/tgui/components/Layout.js b/tgui/packages/tgui/components/Layout.js deleted file mode 100644 index 052ac987293..00000000000 --- a/tgui/packages/tgui/components/Layout.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * DELETE ME when you're done moving to Window. - */ - -import { Window } from '../layouts'; - -const Layout = Window; - -export { Layout }; diff --git a/tgui/packages/tgui/components/index.js b/tgui/packages/tgui/components/index.js index 5f5d14b5d1a..a09d333fa1c 100644 --- a/tgui/packages/tgui/components/index.js +++ b/tgui/packages/tgui/components/index.js @@ -15,7 +15,6 @@ export { Icon } from './Icon'; export { Input } from './Input'; export { Knob } from './Knob'; export { LabeledList } from './LabeledList'; -export { Layout } from './Layout'; export { NoticeBox } from './NoticeBox'; export { NumberInput } from './NumberInput'; export { ProgressBar } from './ProgressBar'; diff --git a/tgui/packages/tgui/layouts/Layout.js b/tgui/packages/tgui/layouts/Layout.js new file mode 100644 index 00000000000..7a17612fdeb --- /dev/null +++ b/tgui/packages/tgui/layouts/Layout.js @@ -0,0 +1,58 @@ +import { classes } from 'common/react'; +import { tridentVersion } from '../byond'; + +/** + * Brings Layout__content DOM element back to focus. + * + * Commonly used to keep the content scrollable in IE. + */ +export const refocusLayout = () => { + // IE8: Focus method is seemingly fucked. + if (tridentVersion <= 4) { + return; + } + const element = document.getElementById('Layout__content'); + if (element) { + element.focus(); + } +}; + +export const Layout = props => { + const { + className, + theme = 'nanotrasen', + children, + } = props; + return ( +
+
+ {children} +
+
+ ); +}; + +const LayoutContent = props => { + const { + className, + scrollable, + children, + } = props; + return ( +
+ {children} +
+ ); +}; + +Layout.Content = LayoutContent; From 775c318d922ecb76abc5e9bcf0793df027110cfc Mon Sep 17 00:00:00 2001 From: actioninja Date: Thu, 9 Apr 2020 21:41:49 -0700 Subject: [PATCH 14/46] Vending - Tank Dispenser vending vault controller turbine computer uplink fix for turbine computer transfer valve timer thermomachine teleporter Tank Tank Dispenser --- tgui/packages/tgui/interfaces/Tank.js | 101 ++++---- .../packages/tgui/interfaces/TankDispenser.js | 61 ++--- tgui/packages/tgui/interfaces/Teleporter.js | 115 ++++----- .../packages/tgui/interfaces/ThermoMachine.js | 139 +++++------ tgui/packages/tgui/interfaces/Timer.js | 79 ++++--- .../packages/tgui/interfaces/TransferValve.js | 149 ++++++------ .../tgui/interfaces/TurbineComputer.js | 111 ++++----- tgui/packages/tgui/interfaces/Uplink.js | 164 ++++++------- .../tgui/interfaces/VaultController.js | 55 +++-- tgui/packages/tgui/interfaces/Vending.js | 221 ++++++++++-------- 10 files changed, 629 insertions(+), 566 deletions(-) diff --git a/tgui/packages/tgui/interfaces/Tank.js b/tgui/packages/tgui/interfaces/Tank.js index 0922a3efb95..bee6deddea0 100644 --- a/tgui/packages/tgui/interfaces/Tank.js +++ b/tgui/packages/tgui/interfaces/Tank.js @@ -1,54 +1,59 @@ import { useBackend } from '../backend'; import { Button, LabeledList, NumberInput, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; -export const Tank = props => { - const { act, data } = useBackend(props); +export const Tank = (props, context) => { + const { act, data } = useBackend(context); return ( -
- - - - {data.tankPressure + ' kPa'} - - - -
+ + +
+ + + + {data.tankPressure + ' kPa'} + + + +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/TankDispenser.js b/tgui/packages/tgui/interfaces/TankDispenser.js index de05a5750b1..a11476df2c8 100644 --- a/tgui/packages/tgui/interfaces/TankDispenser.js +++ b/tgui/packages/tgui/interfaces/TankDispenser.js @@ -1,34 +1,39 @@ import { useBackend } from '../backend'; import { Button, LabeledList, Section } from '../components'; +import { Window } from '../layouts'; -export const TankDispenser = props => { - const { act, data } = useBackend(props); +export const TankDispenser = (props, context) => { + const { act, data } = useBackend(context); return ( -
- - act('plasma')} /> - )}> - {data.plasma} - - act('oxygen')} /> - )}> - {data.oxygen} - - -
+ + +
+ + act('plasma')} /> + )}> + {data.plasma} + + act('oxygen')} /> + )}> + {data.oxygen} + + +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/Teleporter.js b/tgui/packages/tgui/interfaces/Teleporter.js index 0e0490ea07a..8f61f9d8c4e 100644 --- a/tgui/packages/tgui/interfaces/Teleporter.js +++ b/tgui/packages/tgui/interfaces/Teleporter.js @@ -1,8 +1,9 @@ import { useBackend } from '../backend'; import { Box, Button, LabeledList, Section } from '../components'; +import { Window } from '../layouts'; -export const Teleporter = props => { - const { act, data } = useBackend(props); +export const Teleporter = (props, context) => { + const { act, data } = useBackend(context); const { calibrated, calibrating, @@ -12,58 +13,62 @@ export const Teleporter = props => { target, } = data; return ( -
- {!power_station && ( - - No power station linked. - - ) || (!teleporter_hub && ( - - No hub linked. - - )) || ( - - act('regimeset')} /> - )}> - {regime_set} - - act('settarget')} /> - )}> - {target} - - act('calibrate')} /> - )}> - {calibrating && ( - - In Progress - - ) || (calibrated && ( - - Optimal - - ) || ( - - Sub-Optimal - - ))} - - - )} -
+ + +
+ {!power_station && ( + + No power station linked. + + ) || (!teleporter_hub && ( + + No hub linked. + + )) || ( + + act('regimeset')} /> + )}> + {regime_set} + + act('settarget')} /> + )}> + {target} + + act('calibrate')} /> + )}> + {calibrating && ( + + In Progress + + ) || (calibrated && ( + + Optimal + + ) || ( + + Sub-Optimal + + ))} + + + )} +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/ThermoMachine.js b/tgui/packages/tgui/interfaces/ThermoMachine.js index acb31e34d7f..40364ebffd5 100644 --- a/tgui/packages/tgui/interfaces/ThermoMachine.js +++ b/tgui/packages/tgui/interfaces/ThermoMachine.js @@ -2,76 +2,79 @@ import { toFixed } from 'common/math'; import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { AnimatedNumber, Button, LabeledList, NumberInput, Section } from '../components'; +import { Window } from '../layouts'; -export const ThermoMachine = props => { - const { act, data } = useBackend(props); +export const ThermoMachine = (props, context) => { + const { act, data } = useBackend(context); return ( - -
- - - toFixed(value, 2)} /> - {' K'} - - - toFixed(value, 2)} /> - {' kPa'} - - -
-
act('power')} /> - )}> - - - act('target', { - target: value, - })} /> - - + + +
+ + + toFixed(value, 2)} /> + {' K'} + + + toFixed(value, 2)} /> + {' kPa'} + + +
+
act('target', { - target: data.min, - })} /> -
- + icon={data.on ? 'power-off' : 'times'} + content={data.on ? 'On' : 'Off'} + selected={data.on} + onClick={() => act('power')} /> + )}> + + + act('target', { + target: value, + })} /> + + +
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/Timer.js b/tgui/packages/tgui/interfaces/Timer.js index 86b49cbac72..9ba3366a68d 100644 --- a/tgui/packages/tgui/interfaces/Timer.js +++ b/tgui/packages/tgui/interfaces/Timer.js @@ -1,9 +1,10 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Button, Section } from '../components'; +import { Window } from '../layouts'; -export const Timer = props => { - const { act, data } = useBackend(props); +export const Timer = (props, context) => { + const { act, data } = useBackend(context); const { minutes, seconds, @@ -11,42 +12,46 @@ export const Timer = props => { loop, } = data; return ( -
+ + +
+
+ icon="backward" + disabled={timing} + onClick={() => act('input', { adjust: -1 })} /> + {' '} + {String(minutes).padStart(2, '0')}: + {String(seconds).padStart(2, '0')} + {' '} +
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/TransferValve.js b/tgui/packages/tgui/interfaces/TransferValve.js index ed480a97b1b..c66883b6db2 100644 --- a/tgui/packages/tgui/interfaces/TransferValve.js +++ b/tgui/packages/tgui/interfaces/TransferValve.js @@ -1,9 +1,10 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Button, LabeledList, NoticeBox, Section } from '../components'; +import { Window } from '../layouts'; -export const TransferValve = props => { - const { act, data } = useBackend(props); +export const TransferValve = (props, context) => { + const { act, data } = useBackend(context); const { tank_one, tank_two, @@ -11,78 +12,80 @@ export const TransferValve = props => { valve, } = data; return ( - -
- - -
-
act('device')} /> - )}> - - {attached_device ? ( - -
-
- - {tank_one ? ( - + + +
+ +
-
- - {tank_two ? ( - -
- +
+
+
act('device')} /> + )}> + + {attached_device ? ( + +
+
+ + {tank_one ? ( + +
+
+ + {tank_two ? ( + +
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/TurbineComputer.js b/tgui/packages/tgui/interfaces/TurbineComputer.js index 4f632cc149f..1f851286822 100644 --- a/tgui/packages/tgui/interfaces/TurbineComputer.js +++ b/tgui/packages/tgui/interfaces/TurbineComputer.js @@ -1,64 +1,69 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Button, LabeledList, Section } from '../components'; +import { Window } from '../layouts'; -export const TurbineComputer = props => { - const { act, data } = useBackend(props); +export const TurbineComputer = (props, context) => { + const { act, data } = useBackend(context); const operational = Boolean(data.compressor && !data.compressor_broke && data.turbine && !data.turbine_broke); return ( -
-
+ + +
+
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/Uplink.js b/tgui/packages/tgui/interfaces/Uplink.js index 4f2b047c9b5..be245dc4d2f 100644 --- a/tgui/packages/tgui/interfaces/Uplink.js +++ b/tgui/packages/tgui/interfaces/Uplink.js @@ -2,6 +2,8 @@ import { decodeHtmlEntities } from 'common/string'; import { Component, Fragment } from 'inferno'; import { act } from '../byond'; import { Box, Button, Input, Section, Table, Tabs } from '../components'; +import { useBackend } from '../backend'; +import { Window } from '../layouts'; // It's a class because we need to store state in the form of the current // hovered item, and current search terms @@ -27,9 +29,7 @@ export class Uplink extends Component { } render() { - const { state } = this.props; - const { config, data } = state; - const { ref } = config; + const { act, data } = useBackend(this.context); const { compact_mode, lockable, @@ -38,84 +38,90 @@ export class Uplink extends Component { } = data; const { hoveredItem, currentSearch } = this.state; return ( -
0 ? 'good' : 'bad'}> - {telecrystals} TC - - )} - buttons={( - - Search - this.setSearchText(value)} - ml={1} - mr={1} /> -
+ + ); } } diff --git a/tgui/packages/tgui/interfaces/VaultController.js b/tgui/packages/tgui/interfaces/VaultController.js index dc6cbfa00f2..f5fb00add92 100644 --- a/tgui/packages/tgui/interfaces/VaultController.js +++ b/tgui/packages/tgui/interfaces/VaultController.js @@ -1,33 +1,38 @@ import { toFixed } from 'common/math'; import { useBackend } from '../backend'; import { Button, LabeledList, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; -export const VaultController = props => { - const { act, data } = useBackend(props); +export const VaultController = (props, context) => { + const { act, data } = useBackend(context); return ( -
act('togglelock')} /> - )}> - - - - {toFixed(data.stored / 1000) + ' / ' + + +
act('togglelock')} /> + )}> + + + + {toFixed(data.stored / 1000) + ' / ' + toFixed(data.max / 1000) + ' kW'} - - - -
+
+
+
+
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/Vending.js b/tgui/packages/tgui/interfaces/Vending.js index 8d252291ba7..74d7566e91a 100644 --- a/tgui/packages/tgui/interfaces/Vending.js +++ b/tgui/packages/tgui/interfaces/Vending.js @@ -2,9 +2,95 @@ import { classes } from 'common/react'; import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, Section, Table } from '../components'; +import { Window } from '../layouts'; -export const Vending = props => { - const { act, data } = useBackend(props); +export const VendingRow = (props, context) => { + const { act, data } = useBackend(context); + + const { + product, + productStock, + custom, + } = props; + + const free = ( + !data.onstation + || product.price === 0 + || ( + !product.premium + && data.department + && data.user + && data.department === data.user.department + ) + ); + + return ( + + + {product.base64 ? ( + + ) : ( + + )} + + + {product.name} + + + + {productStock} in stock + + + + {custom && ( + - ))} - - - - -
- - {categories.map(category => ( - - {() => category.recipes.map(recipe => ( + + +
+ + +
+ {rootCategoryIndex === 0 && ( + + {[1, 2, 3].map(layer => ( act('pipe_type', { - pipe_type: recipe.pipe_index, - category: category.cat_name, + checked={layer === piping_layer} + content={'Layer ' + layer} + onClick={() => act('piping_layer', { + piping_layer: layer, })} /> ))} - - ))} - -
-
-
-
+ + )} + + {previews.map(preview => ( + + ))} + + + + +
+ + {categories.map(category => ( + + {() => category.recipes.map(recipe => ( + act('pipe_type', { + pipe_type: recipe.pipe_index, + category: category.cat_name, + })} /> + ))} + + ))} + +
+
+ + + ); }; diff --git a/tgui/packages/tgui/interfaces/RemoteRobotControl.js b/tgui/packages/tgui/interfaces/RemoteRobotControl.js index 123e4c708f7..eb24bf22f8c 100644 --- a/tgui/packages/tgui/interfaces/RemoteRobotControl.js +++ b/tgui/packages/tgui/interfaces/RemoteRobotControl.js @@ -2,9 +2,20 @@ import { decodeHtmlEntities } from 'common/string'; import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, NoticeBox, Section, LabeledList } from '../components'; +import { Window } from '../layouts'; -export const RemoteRobotControl = props => { - const { act, data } = useBackend(props); +export const RemoteRobotControl = (props, context) => { + return ( + + + + + + ); +}; + +export const RemoteRobotControlContent = (props, context) => { + const { act, data } = useBackend(context); const { robots = [], } = data; diff --git a/tgui/packages/tgui/interfaces/RoboticsControlConsole.js b/tgui/packages/tgui/interfaces/RoboticsControlConsole.js index 8a25eba57d7..c9495730d2e 100644 --- a/tgui/packages/tgui/interfaces/RoboticsControlConsole.js +++ b/tgui/packages/tgui/interfaces/RoboticsControlConsole.js @@ -1,10 +1,10 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, NoticeBox, Section, Tabs, LabeledList } from '../components'; +import { Window } from '../layouts'; -export const RoboticsControlConsole = props => { - const { state } = props; - const { act, data } = useBackend(props); +export const RoboticsControlConsole = (props, context) => { + const { act, data } = useBackend(context); const { can_hack, cyborgs = [], @@ -12,32 +12,36 @@ export const RoboticsControlConsole = props => { } = data; return ( - - - {() => ( - - )} - - - {() => ( - - )} - - + + + + + {() => ( + + )} + + + {() => ( + + )} + + + + ); }; -const Cyborgs = props => { - const { state, cyborgs, can_hack } = props; - const { act, data } = useBackend(props); +const Cyborgs = (props, context) => { + const { cyborgs, can_hack } = props; + const { act, data } = useBackend(context); if (!cyborgs.length) { return ( @@ -120,9 +124,9 @@ const Cyborgs = props => { }); }; -const Drones = props => { - const { state, drones } = props; - const { act, data } = useBackend(props); +const Drones = (props, context) => { + const { drones } = props; + const { act } = useBackend(context); if (!drones.length) { return ( diff --git a/tgui/packages/tgui/interfaces/Roulette.js b/tgui/packages/tgui/interfaces/Roulette.js index d87ffceba7a..9134b874584 100644 --- a/tgui/packages/tgui/interfaces/Roulette.js +++ b/tgui/packages/tgui/interfaces/Roulette.js @@ -1,11 +1,8 @@ import { classes } from "common/react"; import { useBackend } from "../backend"; import { Box, Button, Grid, NumberInput } from "../components"; -import { createLogger } from "../logging"; -import { Fragment, Component } from "inferno"; -import { act } from "../byond"; - -const logger = createLogger('Roulette'); +import { Component } from "inferno"; +import { Window } from "../layouts"; const getNumberColor = number => { if (number === 0) { @@ -31,9 +28,9 @@ const getNumberColor = number => { return (oddRed ? isOdd : !isOdd) ? 'red' : 'black'; }; -export const RouletteNumberButton = props => { +export const RouletteNumberButton = (props, context) => { const { number } = props; - const { act } = useBackend(props); + const { act } = useBackend(context); return ( - )}> - {data.contents.length === 0 && ( - - Unfortunately, this {data.name} is empty. - - ) || ( - - - - Item - - - - {data.verb ? data.verb : 'Dispense'} - - - {map((value, key) => ( - - - {value.name} - - - {value.amount} - - -
- )} - + + +
act('Dry')}> + {data.drying ? 'Stop drying' : 'Dry'} + + )}> + {data.contents.length === 0 && ( + + Unfortunately, this {data.name} is empty. + + ) || ( + + + + Item + + + + {data.verb ? data.verb : 'Dispense'} + + + {map((value, key) => ( + + + {value.name} + + + {value.amount} + + +
+ )} +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/SmokeMachine.js b/tgui/packages/tgui/interfaces/SmokeMachine.js index 449c04e754d..bc76dfb23ac 100644 --- a/tgui/packages/tgui/interfaces/SmokeMachine.js +++ b/tgui/packages/tgui/interfaces/SmokeMachine.js @@ -1,9 +1,9 @@ import { useBackend } from '../backend'; -import { Fragment } from 'inferno'; -import { AnimatedNumber, Box, Button, LabeledList, ProgressBar, NoticeBox, Section } from '../components'; +import { AnimatedNumber, Box, Button, LabeledList, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; -export const SmokeMachine = props => { - const { act, data } = useBackend(props); +export const SmokeMachine = (props, context) => { + const { act, data } = useBackend(context); const { TankContents, isTankLoaded, @@ -15,58 +15,60 @@ export const SmokeMachine = props => { maxSetting = [], } = data; return ( - -
act('power')} /> - )}> - - - {' / ' + TankMaxVolume} - - - - - {[1, 2, 3, 4, 5].map(amount => ( -
-
act('purge')} /> - )}> - {TankContents.map(chemical => ( - - - {' '} - units of {chemical.name} + + +
act('power')} /> + )}> + + + {' / ' + TankMaxVolume} + + + + + {[1, 2, 3, 4, 5].map(amount => ( +
- +
+
act('purge')} /> + )}> + {TankContents.map(chemical => ( + + + {' '} + units of {chemical.name} + + ))} +
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/SolarControl.js b/tgui/packages/tgui/interfaces/SolarControl.js index 62ebcef427f..36cb711916c 100644 --- a/tgui/packages/tgui/interfaces/SolarControl.js +++ b/tgui/packages/tgui/interfaces/SolarControl.js @@ -2,9 +2,10 @@ import { toFixed } from 'common/math'; import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, Grid, LabeledList, NumberInput, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; -export const SolarControl = props => { - const { act, data } = useBackend(props); +export const SolarControl = (props, context) => { + const { act, data } = useBackend(context); const { generated, generated_ratio, @@ -16,104 +17,106 @@ export const SolarControl = props => { connected_tracker, } = data; return ( - -
act('refresh')} /> - )}> - - - - - {connected_tracker ? 'OK' : 'N/A'} - - 0 ? 'good' : 'bad'}> - {connected_panels} - - - - - - - - {generated + ' W'} - - - - - -
-
- - -
+
+ + +
+ + ); }; diff --git a/tgui/packages/tgui/interfaces/SpaceHeater.js b/tgui/packages/tgui/interfaces/SpaceHeater.js index 45e3fd15140..0dbc0908ac8 100644 --- a/tgui/packages/tgui/interfaces/SpaceHeater.js +++ b/tgui/packages/tgui/interfaces/SpaceHeater.js @@ -1,105 +1,108 @@ import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, LabeledList, NumberInput, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; -export const SpaceHeater = props => { - const { act, data } = useBackend(props); +export const SpaceHeater = (props, context) => { + const { act, data } = useBackend(context); return ( - -
-
-
- - - 50 - ? 'bad' - : Math.abs(data.targetTemp - data.currentTemp) > 20 - ? 'average' - : 'good'}> - {data.currentTemp}°C - - - - {data.open && ( - act('target', { - target: value, - })} /> - ) || ( - data.targetTemp + '°C' - )} - - - {!data.open && 'Auto' || ( - -
+
+ + + 50 + ? 'bad' + : Math.abs(data.targetTemp - data.currentTemp) > 20 + ? 'average' + : 'good'}> + {data.currentTemp}°C + + + + {data.open && ( + act('target', { + target: value, })} /> -
-
+ ) || ( + data.targetTemp + '°C' + )} + + + {!data.open && 'Auto' || ( + + + + {!requestonly && ( + + )} + + {tab === 'catalog' && ( + + )} + {tab === 'requests' && ( + + )} + {tab === 'cart' && ( + + )} + + ); +}; +const CargoStatus = (props, context) => { + const { act, data } = useBackend(context); + const { + away, + docked, + loan, + loan_dispatched, + location, + message, + points, + requestonly, + } = data; return ( - -
- credits - - )}> - - - {data.docked && !data.requestonly && ( +
+ credits + + )}> + + + {docked && !requestonly && ( +
- - - {() => ( -
- {cartButtons} -
- )} -
- 0} - lineHeight="23px"> - {() => ( -
act(ref, 'denyall')} /> - )}> - -
- )} -
- {!data.requestonly && ( - 0} - lineHeight="23px"> - {() => ( -
- -
+ content="Loan Shuttle" + disabled={!(away && docked)} + onClick={() => act('loan')} /> + ) || ( + + Loaned to Centcom + )} -
+
)} - - +
+
); }; -const Catalog = props => { - const { state, supplies } = props; - const { config, data } = state; - const { ref } = config; - const renderTab = key => { - const supply = supplies[key]; - const packs = supply.packs; - return ( - - {packs.map(pack => ( - - - - - - - ))} -
- {pack.name}: - - {!!pack.small_item && ( - Small Item - )} - - {!!pack.access && ( - Restrictions Apply - )} - -
- ); - }; +export const CargoCatalog = (props, context) => { + const { express } = props; + const { act, data } = useBackend(context); + const { + self_paid, + } = data; + const supplies = toArray(data.supplies); + const [ + activeSupplyName, + setActiveSupplyName, + ] = useGlobal(context, 'supply', supplies[0]?.name); + const activeSupply = supplies.find(supply => { + return supply.name === activeSupplyName; + }); return ( - - {map(supply => { - const name = supply.name; - return ( - - {renderTab} - - ); - })(supplies)} - +
+ + act('toggleprivate')} /> + + )}> + + + {supplies.map(supply => ( + + ))} + + + + + + + {activeSupply?.packs.map(pack => { + const tags = []; + if (pack.small_item) { + tags.push('Small'); + } + if (pack.access) { + tags.push('Restricted'); + } + return ( + + + {pack.name} + + + {tags.join(', ')} + + + + + + ); + })} +
+
+
+
); }; -const Requests = props => { - const { state, requests } = props; - const { config, data } = state; - const { ref } = config; - if (requests.length === 0) { - return ( - - No Requests - - ); - } +const CargoRequests = (props, context) => { + const { act, data } = useBackend(context); + const { + requestonly, + } = data; + const requests = data.requests || []; // Labeled list reimplementation to squeeze extra columns out of it return ( - - {requests.map(request => ( - - - - - - -
- #{request.id}: - - {request.object} - - By {request.orderer} - - {request.reason} - - {request.cost} credits - {' '} - {!data.requestonly && ( - +
act('denyall')} /> + )}> + {requests.length === 0 && ( + + No Requests + + )} + {requests.length > 0 && ( + + {requests.map(request => ( + + + #{request.id} + + + {request.object} + + + {request.orderer} + + + {request.reason} + + + {request.cost} cr. + + {!requestonly && ( +
+ + ))} +
+ )} + ); }; -const Cart = props => { - const { state, cart } = props; - const { config, data } = state; - const { ref } = config; +const CargoCartButtons = (props, context) => { + const { act, data } = useBackend(context); + const { + requestonly, + } = data; + const cart = data.cart || []; + const total = cart.reduce((total, entry) => total + entry.cost, 0); + if (requestonly) { + return null; + } return ( - {cart.length === 0 && 'Nothing in cart'} + + {cart.length === 0 && 'Cart is empty'} + {cart.length === 1 && '1 item'} + {cart.length >= 2 && cart.length + ' items'} + {' '} + {total > 0 && `(${total} cr)`} + + - + - ))} -
- )} - {!condi && ( - this.setState({ - pillAmount: value, - })} - onCreate={() => act(ref, 'create', { - type: 'pill', - amount: pillAmount, - volume: 'auto', - })} /> - )} - {!condi && ( - this.setState({ - patchAmount: value, - })} - onCreate={() => act(ref, 'create', { - type: 'patch', - amount: patchAmount, - volume: 'auto', - })} /> - )} - {!condi && ( - this.setState({ - bottleAmount: value, - })} - onCreate={() => act(ref, 'create', { - type: 'bottle', - amount: bottleAmount, - volume: 'auto', - })} /> - )} - {!!condi && ( - this.setState({ - packAmount: value, - })} - onCreate={() => act(ref, 'create', { - type: 'condimentPack', - amount: packAmount, - volume: 'auto', - })} /> - )} - {!!condi && ( - this.setState({ - bottleAmount: value, - })} - onCreate={() => act(ref, 'create', { - type: 'condimentBottle', - amount: bottleAmount, - volume: 'auto', - })} /> - )} - - ); - } -} +const PackagingControls = (props, context) => { + const { act, data } = useBackend(context); + const [ + pillAmount, + setPillAmount, + ] = useGlobal(context, 'pillAmount', 1); + const [ + patchAmount, + setPatchAmount, + ] = useGlobal(context, 'patchAmount', 1); + const [ + bottleAmount, + setBottleAmount, + ] = useGlobal(context, 'bottleAmount', 1); + const [ + packAmount, + setPackAmount, + ] = useGlobal(context, 'packAmount', 1); + const { + condi, + chosenPillStyle, + pillStyles = [], + } = data; + return ( + + {!condi && ( + + {pillStyles.map(pill => ( + + ))} + + )} + {!condi && ( + setPillAmount(value)} + onCreate={() => act('create', { + type: 'pill', + amount: pillAmount, + volume: 'auto', + })} /> + )} + {!condi && ( + setPatchAmount(value)} + onCreate={() => act('create', { + type: 'patch', + amount: patchAmount, + volume: 'auto', + })} /> + )} + {!condi && ( + setBottleAmount(value)} + onCreate={() => act('create', { + type: 'bottle', + amount: bottleAmount, + volume: 'auto', + })} /> + )} + {!!condi && ( + setPackAmount(value)} + onCreate={() => act('create', { + type: 'condimentPack', + amount: packAmount, + volume: 'auto', + })} /> + )} + {!!condi && ( + setBottleAmount(value)} + onCreate={() => act('create', { + type: 'condimentBottle', + amount: bottleAmount, + volume: 'auto', + })} /> + )} + + ); +}; -const AnalysisResults = props => { - const { state } = props; - const { ref } = state.config; - const { analyzeVars } = state.data; +const AnalysisResults = (props, context) => { + const { act, data } = useBackend(context); + const { analyzeVars } = data; return (
{ - ))} - - -
+ + +
+ + + act('change_pill_size', { + volume: value, + })} /> + + + act('change_pill_name', { + name: value, + })} /> + + + {pill_styles.map(pill => ( + + ))} + + +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/ChemReactionChamber.js b/tgui/packages/tgui/interfaces/ChemReactionChamber.js index 8c829258ece..af1ba6f71b0 100644 --- a/tgui/packages/tgui/interfaces/ChemReactionChamber.js +++ b/tgui/packages/tgui/interfaces/ChemReactionChamber.js @@ -1,98 +1,85 @@ -import { Component } from 'inferno'; -import { act } from '../byond'; -import { Box, Button, LabeledList, NumberInput, Section, Input } from '../components'; import { map } from 'common/collections'; import { classes } from 'common/react'; +import { useBackend } from '../backend'; +import { Box, Button, Input, LabeledList, NumberInput, Section } from '../components'; +import { useGlobal } from '../store'; - -export class ChemReactionChamber extends Component { - constructor() { - super(); - this.state = { - reagentName: "", - reagentQuantity: 1, - }; - } - - setReagentName(reagentName) { - this.setState({ - reagentName, - }); - } - - setReagentQuantity(reagentQuantity) { - this.setState({ - reagentQuantity, - }); - } - - render() { - const { state } = this.props; - const { config, data } = state; - const { ref } = config; - const emptying = data.emptying; - const reagents = data.reagents || []; - return ( -
- {emptying ? "Emptying" : "Filling"} - - )} > - - - - this.setReagentName(value)} /> - - - this.setReagentQuantity(value)} /> - -
- ); - } -} + + + {map((amount, reagent) => ( + act('remove', { + chem: reagent, + })} /> + )}> + {amount} + + ))(reagents)} + + + + + ); +}; diff --git a/tgui/packages/tgui/interfaces/ChemSplitter.js b/tgui/packages/tgui/interfaces/ChemSplitter.js index 8e64c43e0f2..c11a374ac7b 100644 --- a/tgui/packages/tgui/interfaces/ChemSplitter.js +++ b/tgui/packages/tgui/interfaces/ChemSplitter.js @@ -1,48 +1,53 @@ import { toFixed } from 'common/math'; import { useBackend } from '../backend'; import { LabeledList, NumberInput, Section } from '../components'; +import { Window } from '../layouts'; -export const ChemSplitter = props => { - const { act, data } = useBackend(props); +export const ChemSplitter = (props, context) => { + const { act, data } = useBackend(context); const { straight, side, max_transfer, } = data; return ( -
- - - toFixed(value, 2)} - step={0.05} - stepPixelSize={4} - onChange={(e, value) => act('set_amount', { - target: 'straight', - amount: value, - })} /> - - - toFixed(value, 2)} - step={0.05} - stepPixelSize={4} - onChange={(e, value) => act('set_amount', { - target: 'side', - amount: value, - })} /> - - -
+ + +
+ + + toFixed(value, 2)} + step={0.05} + stepPixelSize={4} + onChange={(e, value) => act('set_amount', { + target: 'straight', + amount: value, + })} /> + + + toFixed(value, 2)} + step={0.05} + stepPixelSize={4} + onChange={(e, value) => act('set_amount', { + target: 'side', + amount: value, + })} /> + + +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/ChemSynthesizer.js b/tgui/packages/tgui/interfaces/ChemSynthesizer.js index df56dfdc073..26db58cb3ac 100644 --- a/tgui/packages/tgui/interfaces/ChemSynthesizer.js +++ b/tgui/packages/tgui/interfaces/ChemSynthesizer.js @@ -1,9 +1,10 @@ import { toFixed } from 'common/math'; import { useBackend } from '../backend'; import { Box, Button, Section } from '../components'; +import { Window } from '../layouts'; -export const ChemSynthesizer = props => { - const { act, data } = useBackend(props); +export const ChemSynthesizer = (props, context) => { + const { act, data } = useBackend(context); const { amount, current_reagent, @@ -11,32 +12,36 @@ export const ChemSynthesizer = props => { possible_amounts = [], } = data; return ( -
- - {possible_amounts.map(possible_amount => ( -
+ + +
+ + {possible_amounts.map(possible_amount => ( +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/CodexGigas.js b/tgui/packages/tgui/interfaces/CodexGigas.js index f96ce9380bc..b55911750ba 100644 --- a/tgui/packages/tgui/interfaces/CodexGigas.js +++ b/tgui/packages/tgui/interfaces/CodexGigas.js @@ -1,98 +1,107 @@ import { useBackend } from '../backend'; import { Button, LabeledList, Section } from '../components'; +import { Window } from '../layouts'; + +const PREFIXES = [ + "Dark", + "Hellish", + "Fallen", + "Fiery", + "Sinful", + "Blood", + "Fluffy", +]; + +const TITLES = [ + "Lord", + "Prelate", + "Count", + "Viscount", + "Vizier", + "Elder", + "Adept", +]; + +const NAMES = [ + "hal", + "ve", + "odr", + "neit", + "ci", + "quon", + "mya", + "folth", + "wren", + "geyr", + "hil", + "niet", + "twou", + "phi", + "coa", +]; + +const SUFFIXES = [ + "the Red", + "the Soulless", + "the Master", + "the Lord of all things", + "Jr.", +]; // TODO: refactor the backend of this it's a trainwreck -export const CodexGigas = props => { - const { act, data } = useBackend(props); - const prefixes = [ - "Dark", - "Hellish", - "Fallen", - "Fiery", - "Sinful", - "Blood", - "Fluffy", - ]; - const titles = [ - "Lord", - "Prelate", - "Count", - "Viscount", - "Vizier", - "Elder", - "Adept", - ]; - const names = [ - "hal", - "ve", - "odr", - "neit", - "ci", - "quon", - "mya", - "folth", - "wren", - "geyr", - "hil", - "niet", - "twou", - "phi", - "coa", - ]; - const suffixes = [ - "the Red", - "the Soulless", - "the Master", - "the Lord of all things", - "Jr.", - ]; +export const CodexGigas = (props, context) => { + const { act, data } = useBackend(context); return ( -
- {data.name} - - - {prefixes.map(prefix => ( -
+ + +
+ {data.name} + + + {PREFIXES.map(prefix => ( +
+
+
); }; diff --git a/tgui/packages/tgui/interfaces/ComputerFabricator.js b/tgui/packages/tgui/interfaces/ComputerFabricator.js index 87366f6f732..4504a8124d7 100644 --- a/tgui/packages/tgui/interfaces/ComputerFabricator.js +++ b/tgui/packages/tgui/interfaces/ComputerFabricator.js @@ -2,402 +2,417 @@ import { multiline } from 'common/string'; import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, Grid, Section, Table, Tooltip } from '../components'; +import { Window } from '../layouts'; -export const ComputerFabricator = props => { - const { state } = props; - const { act, data } = useBackend(props); +export const ComputerFabricator = (props, context) => { + const { act, data } = useBackend(context); return ( - -
- Your perfect device, only three steps away... -
- {data.state !== 0 && ( - + ); } - if (current_target) { return ( -
+
); } - if (!destinations.length) { return (
@@ -42,42 +55,6 @@ export const Gateway = props => {
); } - - const renderGatewayDest = dest => { - if (dest.availible) { - return ( -
- -
- ); - } - return ( -
- - {dest.reason} - - {!!dest.timeout && ( - - Calibrating... - - )} -
- ); - }; - return ( {!gateway_status && ( @@ -85,7 +62,33 @@ export const Gateway = props => { Gateway Unpowered )} - {destinations.map(renderGatewayDest)} + {destinations.map(dest => ( +
+ {dest.availible && ( + + ) || ( + + + {dest.reason} + + {!!dest.timeout && ( + + Calibrating... + + )} + + )} +
+ ))}
); }; diff --git a/tgui/packages/tgui/interfaces/Gps.js b/tgui/packages/tgui/interfaces/Gps.js index 752c76b6d84..a5fcb8d1941 100644 --- a/tgui/packages/tgui/interfaces/Gps.js +++ b/tgui/packages/tgui/interfaces/Gps.js @@ -5,11 +5,12 @@ 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'; const coordsToVec = coords => map(parseFloat)(coords.split(', ')); -export const Gps = props => { - const { act, data } = useBackend(props); +export const Gps = (props, context) => { + const { act, data } = useBackend(context); const { currentArea, currentCoords, @@ -36,87 +37,89 @@ export const Gps = props => { signal => signal.entrytag), ])(data.signals || []); return ( - -
act('power')} /> - )}> - - + + +
act('rename')} /> - - -
- {!!power && ( - -
- - {currentArea} ({currentCoords}) - -
-
- - - - - - - {signals.map(signal => ( - - - {signal.entrytag} - - - {signal.degrees !== undefined && ( - - )} - {signal.dist !== undefined && ( - signal.dist + 'm' - )} - - - {signal.coords} - + icon="power-off" + content={power ? "On" : "Off"} + selected={power} + onClick={() => act('power')} /> + )}> + + +
+ + + + - ))} -
-
-
- )} - + {signals.map(signal => ( + + + {signal.entrytag} + + + {signal.degrees !== undefined && ( + + )} + {signal.dist !== undefined && ( + signal.dist + 'm' + )} + + + {signal.coords} + + + ))} + +
+
+ )} + + ); }; diff --git a/tgui/packages/tgui/interfaces/GravityGenerator.js b/tgui/packages/tgui/interfaces/GravityGenerator.js index 11e203b97a1..0f8c2549318 100644 --- a/tgui/packages/tgui/interfaces/GravityGenerator.js +++ b/tgui/packages/tgui/interfaces/GravityGenerator.js @@ -1,9 +1,41 @@ -import { Fragment } from 'inferno'; import { useBackend } from '../backend'; import { Box, Button, LabeledList, NoticeBox, ProgressBar, Section } from '../components'; +import { Window } from '../layouts'; -export const GravityGenerator = props => { - const { act, data } = useBackend(props); +export const GravityGenerator = (props, context) => { + const { act, data } = useBackend(context); + const { + charging_state, + operational, + } = data; + return ( + + + {!operational && ( + + No data available + + )} + {!!operational && charging_state !== 0 && ( + + WARNING - Radiation detected + + )} + {!!operational && charging_state === 0 && ( + + No radiation detected + + )} + {!!operational && ( + + )} + + + ); +}; + +const GravityGeneratorContent = (props, context) => { + const { act, data } = useBackend(context); const { breaker, charge_count, @@ -11,72 +43,49 @@ export const GravityGenerator = props => { on, operational, } = data; - - if (!operational) { - return ( -
- - No data available - -
- ); - } - return ( - -
- - -
- {operational && charging_state !== 0 && ( - - WARNING - Radiation detected - - )} - {operational && charging_state === 0 && ( - - No radiation detected - - )} -
+ ))} + {charging_state === 1 && ( + + Charging + + )} + {charging_state === 2 && ( + + Discharging + + )} + + +
); }; diff --git a/tgui/packages/tgui/interfaces/GulagItemReclaimer.js b/tgui/packages/tgui/interfaces/GulagItemReclaimer.js index ed640c122e5..846b4659988 100644 --- a/tgui/packages/tgui/interfaces/GulagItemReclaimer.js +++ b/tgui/packages/tgui/interfaces/GulagItemReclaimer.js @@ -1,41 +1,42 @@ import { useBackend } from '../backend'; import { Button, NoticeBox, Section, Table } from '../components'; +import { Window } from '../layouts'; -export const GulagItemReclaimer = props => { - const { act, data } = useBackend(props); +export const GulagItemReclaimer = (props, context) => { + const { act, data } = useBackend(context); const { mobs = [], } = data; - - if (!mobs.length) { - return ( -
- - No stored items - -
- ); - } - return ( -
- - {mobs.map(mob => ( - - - {mob.name} - - -
-
+ + + {mobs.length === 0 && ( + + No stored items + + )} + {mobs.length > 0 && ( +
+ + {mobs.map(mob => ( + + + {mob.name} + + +
+
+ )} +
+
); }; diff --git a/tgui/packages/tgui/interfaces/GulagTeleporterConsole.js b/tgui/packages/tgui/interfaces/GulagTeleporterConsole.js index 7291cedcbc8..3b709cbcb03 100644 --- a/tgui/packages/tgui/interfaces/GulagTeleporterConsole.js +++ b/tgui/packages/tgui/interfaces/GulagTeleporterConsole.js @@ -1,10 +1,10 @@ -import { useBackend } from '../backend'; -import { Section, LabeledList, Button, NumberInput } from '../components'; import { Fragment } from 'inferno'; +import { useBackend } from '../backend'; +import { Button, LabeledList, NumberInput, Section } from '../components'; +import { Window } from '../layouts'; -export const GulagTeleporterConsole = props => { - const { act, data } = useBackend(props); - +export const GulagTeleporterConsole = (props, context) => { + const { act, data } = useBackend(context); const { teleporter, teleporter_lock, @@ -18,86 +18,82 @@ export const GulagTeleporterConsole = props => { goal = 0, prisoner = {}, } = data; - return ( - -
-
+
+ +
-
- - -
- - ); - })} -
-
- {content || null} -
- - ); - } -} - -/** - * A dummy component, which is used for carrying props for the - * tab container. - */ -export const Tab = props => null; - -Tab.defaultProps = { - __type__: TAB_MAGIC_TYPE, +const Tab = props => { + const { + className, + selected, + altSelection, + ...rest + } = props; + return ( + - + {!requestonly && ( - + )} - + {tab === 'catalog' && ( )} @@ -81,7 +76,10 @@ const CargoStatus = (props, context) => { title="Cargo" buttons={( - credits + formatMoney(value)} /> + {' credits'} )}> @@ -143,19 +141,16 @@ export const CargoCatalog = (props, context) => { )}> - {supplies.map(supply => ( - - ))} - - - + + {supplies.map(supply => ( + setActiveSupplyName(supply.name)}> + {supply.name} ({supply.packs.length}) + + ))} + @@ -190,9 +185,9 @@ export const CargoCatalog = (props, context) => { onClick={() => act('add', { id: pack.id, })}> - {self_paid + {formatMoney(self_paid ? Math.round(pack.cost * 1.1) - : pack.cost} + : pack.cost)} {' cr'} @@ -247,7 +242,7 @@ const CargoRequests = (props, context) => { {request.reason} - {request.cost} cr. + {formatMoney(request.cost)} cr {!requestonly && ( @@ -290,7 +285,7 @@ const CargoCartButtons = (props, context) => { {cart.length === 1 && '1 item'} {cart.length >= 2 && cart.length + ' items'} {' '} - {total > 0 && `(${total} cr)`} + {total > 0 && `(${formatMoney(total)} cr)`} - ); }; diff --git a/tgui/packages/tgui/format.js b/tgui/packages/tgui/format.js index 1518d14c392..8ce1915f515 100644 --- a/tgui/packages/tgui/format.js +++ b/tgui/packages/tgui/format.js @@ -56,10 +56,28 @@ export const formatPower = (value, minBase1000 = 0) => { }; export const formatMoney = (value, precision = 0) => { - return round(value, precision) - .toLocaleString('en', { - minimumFractionDigits: precision, - }) - // Thin space - .replace(/,/g, '\u2009'); + if (!Number.isFinite(value)) { + return value; + } + // Round the number and make it fixed precision + let fixed = round(value, precision); + if (precision > 0) { + fixed = toFixed(value, precision); + } + fixed = String(fixed); + // Place thousand separators + const length = fixed.length; + let indexOfPoint = fixed.indexOf('.'); + if (indexOfPoint === -1) { + indexOfPoint = length; + } + let result = ''; + for (let i = 0; i < length; i++) { + if (i > 0 && i < indexOfPoint && (indexOfPoint - i) % 3 === 0) { + // Thin space + result += '\u2009'; + } + result += fixed.charAt(i); + } + return result; }; diff --git a/tgui/packages/tgui/index.js b/tgui/packages/tgui/index.js index 769820b9f58..59199f9edbe 100644 --- a/tgui/packages/tgui/index.js +++ b/tgui/packages/tgui/index.js @@ -1,13 +1,23 @@ +// Polyfills import 'core-js/es'; import 'core-js/web/immediate'; import 'core-js/web/queue-microtask'; import 'core-js/web/timers'; import 'regenerator-runtime/runtime'; +import './polyfills/html5shiv'; +import './polyfills/ie8'; +import './polyfills/dom4'; +import './polyfills/css-om'; +import './polyfills/inferno'; -// This one is necessary for Inferno. -if (!window.Int32Array) { - window.Int32Array = Array; -} +// Themes +import './styles/main.scss'; +import './styles/themes/cardtable.scss'; +import './styles/themes/malfunction.scss'; +import './styles/themes/ntos.scss'; +import './styles/themes/hackerman.scss'; +import './styles/themes/retro.scss'; +import './styles/themes/syndicate.scss'; import { loadCSS } from 'fg-loadcss'; import { render } from 'inferno'; diff --git a/tgui/packages/tgui/interfaces/Achievements.js b/tgui/packages/tgui/interfaces/Achievements.js index 0f6a224893f..464708d2484 100644 --- a/tgui/packages/tgui/interfaces/Achievements.js +++ b/tgui/packages/tgui/interfaces/Achievements.js @@ -1,7 +1,6 @@ import { useBackend, useLocalState } from '../backend'; -import { Box, Icon, Table, Tabs } from '../components'; +import { Box, Flex, Icon, Table, Tabs } from '../components'; import { Window } from '../layouts'; -import { Fragment } from 'inferno'; export const Achievements = (props, context) => { const { data } = useBackend(context); @@ -63,11 +62,11 @@ const Achievement = props => { score, } = achievement; return ( - - - - + + ); }; @@ -105,54 +104,58 @@ const HighScoreTable = (props, context) => { value: highscore.scores[key], })); return ( - - - {highscores.map((highscore, i) => ( - setHighScoreIndex(i)}> - {highscore.name} - - ))} - -
+ + +
- - + + + + +

{name}

{desc} {score && ( @@ -79,8 +78,8 @@ const Achievement = props => { {value ? 'Unlocked' : 'Locked'} )} -
- - - # - - - Key - - - Score - - - {scores.map((score, i) => ( - - - {i + 1} + + + + {highscores.map((highscore, i) => ( + setHighScoreIndex(i)}> + {highscore.name} + + ))} + + + +
+ + + # - - {i === 0 && ( - - )} - {score.ckey} - {i === 0 && ( - - )} + + Key - {score.value} + Score - ))} -
- + {scores.map((score, i) => ( + + + {i + 1} + + + {i === 0 && ( + + )} + {score.ckey} + {i === 0 && ( + + )} + + + {score.value} + + + ))} + +
+
); }; diff --git a/tgui/packages/tgui/interfaces/BlackmarketUplink.js b/tgui/packages/tgui/interfaces/BlackmarketUplink.js index 1a0e17a8e0b..a2e2f0b7adf 100644 --- a/tgui/packages/tgui/interfaces/BlackmarketUplink.js +++ b/tgui/packages/tgui/interfaces/BlackmarketUplink.js @@ -1,45 +1,145 @@ -import { map } from 'common/collections'; import { useBackend } from '../backend'; import { AnimatedNumber, Box, Button, Flex, Modal, Section, Table, Tabs } from '../components'; +import { formatMoney } from '../format'; import { Window } from '../layouts'; -export const BlackmarketUplink = (props, context) => { +export const BlackMarketUplink = (props, context) => { const { act, data } = useBackend(context); - const categories = data.categories || []; - const deliveryMethods = data.delivery_methods || []; - const deliveryMethodDesc = data.delivery_method_description || []; - const markets = data.markets || {}; - const items = data.items || {}; + const { + categories = [], + markets = [], + items = [], + money, + viewing_market, + viewing_category, + } = data; + return ( + + + +
+ formatMoney(value) + ' cr'} /> + + )} /> + + {markets.map(market => ( + act('set_market', { + market: market.id, + })}> + {market.name} + + ))} + + + + + {categories.map(category => ( + act('set_category', { + category: category, + })}> + {category} + + ))} + + + + {items.map(item => ( + + + + {item.name} + + + {item.amount + ? item.amount + " in stock" + : "Out of stock"} + + + {formatMoney(item.cost) + ' cr'} + + +
+
); }; - -const ItemList = props => { - const { - items, - hoveredItem, - processing_time, - compact, - onBuy, - onBuyMouseOver, - onBuyMouseOut, - } = props; - const hoveredCost = hoveredItem && hoveredItem.cost || 0; - if (compact) { - return ( - - {items.map(item => { - const notSameItem = hoveredItem && hoveredItem.name !== item.name; - const notEnoughHovered = processing_time - hoveredCost < item.cost; - const disabledDueToHovered = notSameItem && notEnoughHovered; - return ( - - - {decodeHtmlEntities(item.name)} - - -
- ); - } - return items.map(item => { - const notSameItem = hoveredItem && hoveredItem.name !== item.name; - const notEnoughHovered = processing_time - hoveredCost < item.cost; - const disabledDueToHovered = notSameItem && notEnoughHovered; - return ( -
onBuyMouseOver(item)} - onmouseout={() => onBuyMouseOut(item)} - onClick={() => onBuy(item)} /> - )}> - {decodeHtmlEntities(item.desc)} -
- ); - }); -}; diff --git a/tgui/packages/tgui/interfaces/MedicalKiosk.js b/tgui/packages/tgui/interfaces/MedicalKiosk.js index 60a0cdc8bb9..3b475e78e75 100644 --- a/tgui/packages/tgui/interfaces/MedicalKiosk.js +++ b/tgui/packages/tgui/interfaces/MedicalKiosk.js @@ -1,302 +1,358 @@ import { multiline } from 'common/string'; -import { useBackend } from '../backend'; -import { AnimatedNumber, Box, Button, LabeledList, ProgressBar, Section, Tabs } from '../components'; +import { useBackend, useSharedState } from '../backend'; +import { AnimatedNumber, Box, Button, Flex, Icon, LabeledList, ProgressBar, Section } from '../components'; import { Window } from '../layouts'; export const MedicalKiosk = (props, context) => { const { act, data } = useBackend(context); + const [scanIndex] = useSharedState(context, 'scanIndex'); + const { + active_status_1, + active_status_2, + active_status_3, + active_status_4, + } = data; return ( -
- - Greetings Valued Employee. Please select your desired diagnosis. - Diagnosis costs {data.kiosk_cost} credits. - - - Current patient targeted for scanning: {data.patient_name} | - - -
- - - {() => ( - - {data.active_status_1 === 0 && ( -
- - - - % - - - - - - - - - - - - - - - - - - - - - - - - -
- )} -
- )} -
- - {() => ( - - {data.active_status_2 === 0 && ( -
- - - {data.patient_status} - - - - {data.patient_illness} - - - {data.illness_info} - - - - {data.bleed_status} - - - - - - - {data.blood_status} - - -
- )} -
- )} -
- - {() => ( - - {data.active_status_3 === 0 && ( -
- - - - - - - - - - - - {data.brain_health} - - - {data.rad_status} - - - {data.rad_value}% - - - {data.trauma_status} - -
- )} -
- )} -
- - {() => ( - - {data.active_status_4 === 0 && ( -
- - {data.are_chems_present ? ( - data.chemical_list.length ? ( - data.chemical_list.map(specificChem => ( - - {specificChem.volume} units of {specificChem.name} - - )) - ) : ( - - No reagents detected. - - ) - ) : ( - - No reagents detected. - - )} - - - {data.are_overdoses_present ? ( - data.overdose_status.length ? ( - data.overdose_status.map(specificOD => ( - - Overdosing on {specificOD.name} - - )) - ) : ( - - No reagents detected. - - ) - ) : ( - - Patient is not overdosing. - - )} - - - {data.are_addictions_present ? ( - data.addiction_status.length ? ( - data.addiction_status.map(specificAddict => ( - - Addicted to {specificAddict.name} - - )) - ) : ( - - Patient has no addictions. - - ) - ) : ( - - Patient has no addictions detected. - - )} - - - {data.hallucinating_status} - -
- )} -
- )} -
-
+ + +
+ + + + +
+
+ + + +
+ {!!active_status_1 && scanIndex === 1 && ( + + )} + {!!active_status_2 && scanIndex === 2 && ( + + )} + {!!active_status_3 && scanIndex === 3 && ( + + )} + {!!active_status_4 && scanIndex === 4 && ( + + )}
); }; + +const MedicalKioskScanButton = (props, context) => { + const { + index, + name, + description, + icon, + } = props; + const { act, data } = useBackend(context); + const [scanIndex, setScanIndex] = useSharedState(context, 'scanIndex'); + const paid = data[`active_status_${index}`]; + return ( + + +