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..f353ef03614 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", 540, 680, 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..ba3d4b48678 100644
--- a/code/datums/components/uplink.dm
+++ b/code/datums/components/uplink.dm
@@ -125,9 +125,8 @@
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()
/datum/component/uplink/ui_data(mob/user)
@@ -136,8 +135,7 @@
var/list/data = list()
data["telecrystals"] = telecrystals
data["lockable"] = lockable
- data["compact_mode"] = compact_mode
-
+ data["compactMode"] = compact_mode
return data
/datum/component/uplink/ui_static_data(mob/user)
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 821b7d14531..04e35bcb6e3 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)
@@ -96,7 +96,6 @@
else
data["patient"] = null
return data
-
switch(patient.stat)
if(CONSCIOUS)
data["patient"]["stat"] = "Conscious"
@@ -118,8 +117,8 @@
data["patient"]["fireLoss"] = patient.getFireLoss()
data["patient"]["toxLoss"] = patient.getToxLoss()
data["patient"]["oxyLoss"] = patient.getOxyLoss()
+ data["procedures"] = list()
if(patient.surgeries.len)
- data["procedures"] = list()
for(var/datum/surgery/procedure in patient.surgeries)
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
var/chems_needed = surgery_step.get_chem_list()
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..ed5a031dba2 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, "LaunchpadConsole", 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..23e1b9dcc1c 100644
--- a/code/game/machinery/launch_pad.dm
+++ b/code/game/machinery/launch_pad.dm
@@ -324,8 +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.set_style("syndicate")
+ ui = new(user, src, ui_key, "LaunchpadRemote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(TRUE)
diff --git a/code/game/machinery/medical_kiosk.dm b/code/game/machinery/medical_kiosk.dm
index b71b7e59572..ba33ab23ad5 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, 575, 420, master_ui, state)
ui.open()
icon_state = "kiosk_off"
RefreshParts()
@@ -236,29 +236,18 @@
trauma_text += trauma_desc
trauma_status = "Cerebral traumas detected: patient appears to be suffering from [english_list(trauma_text)]."
- var/chem_status = FALSE
- var/chemical_list= list()
- var/overdose_status = FALSE
+ var/chemical_list = list()
var/overdose_list = list()
- var/addict_status = FALSE
var/addict_list = list()
var/hallucination_status = "Patient is not hallucinating."
- for(var/datum/reagent/R in altPatient.reagents.reagent_list)
- if(R.overdosed)
- overdose_status = TRUE
-
if(altPatient.reagents.reagent_list.len) //Chemical Analysis details.
- chem_status = TRUE
for(var/datum/reagent/R in altPatient.reagents.reagent_list)
chemical_list += list(list("name" = R.name, "volume" = round(R.volume, 0.01)))
if(R.overdosed == 1)
overdose_list += list(list("name" = R.name))
- else
- chemical_list = "Patient contains no reagents"
if(altPatient.reagents.addiction_list.len)
- addict_status = TRUE
for(var/datum/reagent/R in altPatient.reagents.addiction_list)
addict_list += list(list("name" = R.name))
if (altPatient.hallucinating())
@@ -296,7 +285,6 @@
else if (user.hallucinating())
chaos_modifier = 0.3
-
data["kiosk_cost"] = active_price + (chaos_modifier * (rand(1,25)))
data["patient_name"] = patient_name
data["patient_health"] = round(((total_health - (chaos_modifier * (rand(1,50)))) / max_health) * 100, 0.001)
@@ -316,18 +304,15 @@
data["bleed_status"] = bleed_status
data["blood_levels"] = blood_percent - (chaos_modifier * (rand(1,35)))
data["blood_status"] = blood_status
- data["are_chems_present"] = chem_status ? TRUE : FALSE
data["chemical_list"] = chemical_list
- data["are_overdoses_present"] = overdose_status ? TRUE : FALSE
- data["overdose_status"] = overdose_list
- data["are_addictions_present"] = addict_status ? TRUE : FALSE
- data["addiction_status"] = addict_list
+ data["overdose_list"] = overdose_list
+ data["addict_list"] = addict_list
data["hallucinating_status"] = hallucination_status
- data["active_status_1"] = scan_active_1 ? FALSE : TRUE //General Scan Check
- data["active_status_2"] = scan_active_2 ? FALSE : TRUE //Symptom Scan Check
- data["active_status_3"] = scan_active_3 ? FALSE : TRUE //Radio-Neuro Scan Check
- data["active_status_4"] = scan_active_4 ? FALSE : TRUE //Radio-Neuro Scan Check
+ data["active_status_1"] = scan_active_1 // General Scan Check
+ data["active_status_2"] = scan_active_2 // Symptom Scan Check
+ data["active_status_3"] = scan_active_3 // Radio-Neuro Scan Check
+ data["active_status_4"] = scan_active_4 // Radio-Neuro Scan Check
return data
/obj/machinery/medical_kiosk/ui_act(action,active)
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..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
@@ -264,8 +263,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.set_style(ui_style)
+ ui = new(user, src, ui_key, "NuclearBomb", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/nuclearbomb/ui_data(mob/user)
diff --git a/code/modules/antagonists/traitor/equipment/module_picker.dm b/code/modules/antagonists/traitor/equipment/module_picker.dm
index 738bf46aab2..1185c0b60e0 100644
--- a/code/modules/antagonists/traitor/equipment/module_picker.dm
+++ b/code/modules/antagonists/traitor/equipment/module_picker.dm
@@ -34,13 +34,13 @@
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)
var/list/data = list()
- data["processing_time"] = processing_time
- data["compact_mode"] = compact_mode
+ data["processingTime"] = processing_time
+ data["compactMode"] = compact_mode
return data
/datum/module_picker/ui_static_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/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm
index 53fc478c617..19f8bd81c5e 100644
--- a/code/modules/asset_cache/asset_list_items.dm
+++ b/code/modules/asset_cache/asset_list_items.dm
@@ -4,10 +4,6 @@
assets = list(
"tgui.bundle.js" = 'tgui/packages/tgui/public/tgui.bundle.js',
"tgui.bundle.css" = 'tgui/packages/tgui/public/tgui.bundle.css',
- "shim-html5shiv.js" = 'tgui/packages/tgui/public/shim-html5shiv.js',
- "shim-ie8.js" = 'tgui/packages/tgui/public/shim-ie8.js',
- "shim-dom4.js" = 'tgui/packages/tgui/public/shim-dom4.js',
- "shim-css-om.js" = 'tgui/packages/tgui/public/shim-css-om.js',
)
/datum/asset/group/tgui
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 821898653a9..287b3329221 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 04a8bc2507a..decfcbcc404 100644
--- a/code/modules/atmospherics/machinery/portable/pump.dm
+++ b/code/modules/atmospherics/machinery/portable/pump.dm
@@ -101,7 +101,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, "PortablePump", 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 e492c1fe118..8438e147287 100644
--- a/code/modules/atmospherics/machinery/portable/scrubber.dm
+++ b/code/modules/atmospherics/machinery/portable/scrubber.dm
@@ -3,7 +3,7 @@
icon_state = "pscrubber:0"
density = TRUE
ui_x = 320
- ui_y = 335
+ ui_y = 350
max_integrity = 250
///Max amount of heat allowed inside of the canister before it starts to melt (different tiers have different limits)
@@ -92,7 +92,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, "PortableScrubber", 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..3833b0505a5 100644
--- a/code/modules/cargo/blackmarket/blackmarket_uplink.dm
+++ b/code/modules/cargo/blackmarket/blackmarket_uplink.dm
@@ -4,7 +4,7 @@
icon_state = "uplink"
// UI variables.
- var/ui_x = 720
+ var/ui_x = 600
var/ui_y = 480
var/viewing_category
var/viewing_market
@@ -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..63b1935cfee 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -82,24 +82,23 @@
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()
var/list/data = list()
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
+ data["inserted_materials"] = list()
+ data["chosen_material"] = null
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/datum/material/inserted_material in materials.materials)
var/amount = materials.get_material_amount(inserted_material)
-
if(!amount)
continue
-
data["inserted_materials"] += list(list(
"material" = inserted_material.name,
- "amount" = amount
+ "amount" = amount,
))
-
if(chosen == inserted_material)
data["chosen_material"] = inserted_material.name
@@ -109,25 +108,25 @@
return data;
/obj/machinery/mineral/mint/ui_act(action, params, datum/tgui/ui)
-
. = ..()
if(.)
return
-
- switch(action)
- if ("startpress")
- if (!processing)
- produced_coins = 0
- processing = TRUE
- begin_processing()
- if ("stoppress")
- processing = FALSE
- end_processing()
- if ("changematerial")
- var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
- for(var/datum/material/mat in materials.materials)
- if (params["material_name"] == mat.name)
- chosen = mat
+ if(action == "startpress")
+ if (!processing)
+ produced_coins = 0
+ processing = TRUE
+ begin_processing()
+ return TRUE
+ if (action == "stoppress")
+ processing = FALSE
+ end_processing()
+ return TRUE
+ if (action == "changematerial")
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
+ for(var/datum/material/mat in materials.materials)
+ if (params["material_name"] == mat.name)
+ chosen = mat
+ return TRUE
/obj/machinery/mineral/mint/proc/create_coins()
var/turf/T = get_step(src,output_dir)
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..4e9cd855772 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 = "NtosAiRestorer"
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..352f13f3053 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 = "NtosNetDownloader"
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/tgui/external.dm b/code/modules/tgui/external.dm
index 8032930268b..5de54c439cc 100644
--- a/code/modules/tgui/external.dm
+++ b/code/modules/tgui/external.dm
@@ -1,133 +1,142 @@
- /**
- * tgui external
- *
- * Contains all external tgui declarations.
- **/
+/**
+ * tgui external
+ *
+ * Contains all external tgui declarations.
+ */
- /**
- * public
- *
- * Used to open and update UIs.
- * If this proc is not implemented properly, the UI will not update correctly.
- *
- * required user mob The mob who opened/is using the UI.
- * optional ui_key string The ui_key of the UI.
- * optional ui datum/tgui The UI to be updated, if it exists.
- * optional force_open bool If the UI should be re-opened instead of updated.
- * optional master_ui datum/tgui The parent UI.
- * optional state datum/ui_state The state used to determine status.
- **/
+/**
+ * public
+ *
+ * Used to open and update UIs.
+ * If this proc is not implemented properly, the UI will not update correctly.
+ *
+ * required user mob The mob who opened/is using the UI.
+ * optional ui_key string The ui_key of the UI.
+ * optional ui datum/tgui The UI to be updated, if it exists.
+ * optional force_open bool If the UI should be re-opened instead of updated.
+ * optional master_ui datum/tgui The parent UI.
+ * optional state datum/ui_state The state used to determine status.
+ */
/datum/proc/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)
return FALSE // Not implemented.
- /**
- * public
- *
- * Data to be sent to the UI.
- * This must be implemented for a UI to work.
- *
- * required user mob The mob interacting with the UI.
- *
- * return list Data to be sent to the UI.
- **/
+/**
+ * public
+ *
+ * Data to be sent to the UI.
+ * This must be implemented for a UI to work.
+ *
+ * required user mob The mob interacting with the UI.
+ *
+ * return list Data to be sent to the UI.
+ */
/datum/proc/ui_data(mob/user)
return list() // Not implemented.
- /**
- * public
- *
- * Static Data to be sent to the UI.
- * Static data differs from normal data in that it's large data that should be sent infrequently
- * This is implemented optionally for heavy uis that would be sending a lot of redundant data
- * frequently.
- * Gets squished into one object on the frontend side, but the static part is cached.
- *
- * required user mob The mob interacting with the UI.
- *
- * return list Statuic Data to be sent to the UI.
- **/
+/**
+ * public
+ *
+ * Static Data to be sent to the UI.
+ * Static data differs from normal data in that it's large data that should be sent infrequently
+ * This is implemented optionally for heavy uis that would be sending a lot of redundant data
+ * frequently.
+ * Gets squished into one object on the frontend side, but the static part is cached.
+ *
+ * required user mob The mob interacting with the UI.
+ *
+ * return list Statuic Data to be sent to the UI.
+ */
/datum/proc/ui_static_data(mob/user)
return list()
/**
- * public
- *
- * Forces an update on static data. Should be done manually whenever something happens to change static data.
- *
- * required user the mob currently interacting with the ui
- * optional ui ui to be updated
- * optional ui_key ui key of ui to be updated
- *
-**/
+ * public
+ *
+ * Forces an update on static data. Should be done manually whenever something happens to change static data.
+ *
+ * required user the mob currently interacting with the ui
+ * optional ui ui to be updated
+ * optional ui_key ui key of ui to be updated
+ */
/datum/proc/update_static_data(mob/user, datum/tgui/ui, ui_key = "main")
ui = SStgui.try_update_ui(user, src, ui_key, ui)
+ // If there was no ui to update, there's no static data to update either.
if(!ui)
- return //If there was no ui to update, there's no static data to update either.
+ return
ui.push_data(null, ui_static_data(), TRUE)
- /**
- * public
- *
- * Called on a UI when the UI receieves a href.
- * Think of this as Topic().
- *
- * required action string The action/button that has been invoked by the user.
- * required params list A list of parameters attached to the button.
- *
- * return bool If the UI should be updated or not.
- **/
+/**
+ * public
+ *
+ * Called on a UI when the UI receieves a href.
+ * Think of this as Topic().
+ *
+ * required action string The action/button that has been invoked by the user.
+ * required params list A list of parameters attached to the button.
+ *
+ * return bool If the UI should be updated or not.
+ */
/datum/proc/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
+ // If UI is not interactive or usr calling Topic is not the UI user, bail.
if(!ui || ui.status != UI_INTERACTIVE)
- return 1 // If UI is not interactive or usr calling Topic is not the UI user, bail.
+ return 1
- /**
- * public
- *
- * Called on an object when a tgui object is being created, allowing you to customise the html
- * For example: inserting a custom stylesheet that you need in the head
- *
- * For this purpose, some tags are available in the html, to be parsed out with replacetext
- * (customheadhtml) - Additions to the head tag
- *
- * required html the html base text
- *
- **/
+/**
+ * public
+ *
+ * Called on an object when a tgui object is being created, allowing you to
+ * customise the html
+ * For example: inserting a custom stylesheet that you need in the head
+ *
+ * For this purpose, some tags are available in the html, to be parsed out
+ ^ with replacetext
+ * (customheadhtml) - Additions to the head tag
+ *
+ * required html the html base text
+ */
/datum/proc/ui_base_html(html)
return html
- /**
- * private
- *
- * The UI's host object (usually src_object).
- * This allows modules/datums to have the UI attached to them,
- * and be a part of another object.
- **/
+/**
+ * private
+ *
+ * The UI's host object (usually src_object).
+ * This allows modules/datums to have the UI attached to them,
+ * and be a part of another object.
+ */
/datum/proc/ui_host(mob/user)
return src // Default src.
- /**
- * global
- *
- * Used to track UIs for a mob.
- **/
+/**
+ * global
+ *
+ * Associative list of JSON-encoded shared states that were set by
+ * tgui clients.
+ */
+/datum/var/list/tgui_shared_states
+
+/**
+ * global
+ *
+ * Used to track UIs for a mob.
+ */
/mob/var/list/open_uis = list()
- /**
- * public
- *
- * Called on a UI's object when the UI is closed, not to be confused with client/verb/uiclose(), which closes the ui window
- *
- *
- **/
+/**
+ * public
+ *
+ * Called on a UI's object when the UI is closed, not to be confused with
+ * client/verb/uiclose(), which closes the ui window
+ */
/datum/proc/ui_close(mob/user)
- /**
- * verb
- *
- * Called by UIs when they are closed.
- * Must be a verb so winset() can call it.
- *
- * required uiref ref The UI that was closed.
- **/
+/**
+ * verb
+ *
+ * Called by UIs when they are closed.
+ * Must be a verb so winset() can call it.
+ *
+ * required uiref ref The UI that was closed.
+ */
/client/verb/uiclose(ref as text)
// Name the verb, and hide it from the user panel.
set name = "uiclose"
diff --git a/code/modules/tgui/states.dm b/code/modules/tgui/states.dm
index d66d5d30364..7a87ed916f1 100644
--- a/code/modules/tgui/states.dm
+++ b/code/modules/tgui/states.dm
@@ -1,19 +1,19 @@
- /**
- * tgui states
- *
- * Base state and helpers for states. Just does some sanity checks, implement a state for in-depth checks.
- **/
+/**
+ * tgui states
+ *
+ * Base state and helpers for states. Just does some sanity checks, implement a state for in-depth checks.
+ */
- /**
- * public
- *
- * Checks the UI state for a mob.
- *
- * required user mob The mob who opened/is using the UI.
- * required state datum/ui_state The state to check.
- *
- * return UI_state The state of the UI.
- **/
+/**
+ * public
+ *
+ * Checks the UI state for a mob.
+ *
+ * required user mob The mob who opened/is using the UI.
+ * required state datum/ui_state The state to check.
+ *
+ * return UI_state The state of the UI.
+ */
/datum/proc/ui_status(mob/user, datum/ui_state/state)
var/src_object = ui_host(user)
. = UI_CLOSE
@@ -34,27 +34,27 @@
var/result = state.can_use_topic(src_object, user)
. = max(., result)
- /**
- * private
- *
- * Checks if a user can use src_object's UI, and returns the state.
- * Can call a mob proc, which allows overrides for each mob.
- *
- * required src_object datum The object/datum which owns the UI.
- * required user mob The mob who opened/is using the UI.
- *
- * return UI_state The state of the UI.
- **/
+/**
+ * private
+ *
+ * Checks if a user can use src_object's UI, and returns the state.
+ * Can call a mob proc, which allows overrides for each mob.
+ *
+ * required src_object datum The object/datum which owns the UI.
+ * required user mob The mob who opened/is using the UI.
+ *
+ * return UI_state The state of the UI.
+ */
/datum/ui_state/proc/can_use_topic(src_object, mob/user)
return UI_CLOSE // Don't allow interaction by default.
- /**
- * public
- *
- * Standard interaction/sanity checks. Different mob types may have overrides.
- *
- * return UI_state The state of the UI.
- **/
+/**
+ * public
+ *
+ * Standard interaction/sanity checks. Different mob types may have overrides.
+ *
+ * return UI_state The state of the UI.
+ */
/mob/proc/shared_ui_interaction(src_object)
if(!client) // Close UIs if mindless.
return UI_CLOSE
@@ -80,29 +80,29 @@
return ..()
/**
- * public
- *
- * Check the distance for a living mob.
- * Really only used for checks outside the context of a mob.
- * Otherwise, use shared_living_ui_distance().
- *
- * required src_object The object which owns the UI.
- * required user mob The mob who opened/is using the UI.
- *
- * return UI_state The state of the UI.
- **/
+ * public
+ *
+ * Check the distance for a living mob.
+ * Really only used for checks outside the context of a mob.
+ * Otherwise, use shared_living_ui_distance().
+ *
+ * required src_object The object which owns the UI.
+ * required user mob The mob who opened/is using the UI.
+ *
+ * return UI_state The state of the UI.
+ */
/atom/proc/contents_ui_distance(src_object, mob/living/user)
return user.shared_living_ui_distance(src_object) // Just call this mob's check.
- /**
- * public
- *
- * Distance versus interaction check.
- *
- * required src_object atom/movable The object which owns the UI.
- *
- * return UI_state The state of the UI.
- **/
+/**
+ * public
+ *
+ * Distance versus interaction check.
+ *
+ * required src_object atom/movable The object which owns the UI.
+ *
+ * return UI_state The state of the UI.
+ */
/mob/living/proc/shared_living_ui_distance(atom/movable/src_object, viewcheck = TRUE)
if(viewcheck && !(src_object in view(src))) // If the object is obscured, close it.
return UI_CLOSE
diff --git a/code/modules/tgui/states/admin.dm b/code/modules/tgui/states/admin.dm
index 945a8644301..61fc3731188 100644
--- a/code/modules/tgui/states/admin.dm
+++ b/code/modules/tgui/states/admin.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: admin_state
- *
- * Checks that the user is an admin, end-of-story.
- **/
+/**
+ * tgui state: admin_state
+ *
+ * Checks that the user is an admin, end-of-story.
+ */
GLOBAL_DATUM_INIT(admin_state, /datum/ui_state/admin_state, new)
diff --git a/code/modules/tgui/states/always.dm b/code/modules/tgui/states/always.dm
index b6c689d5d8b..a741e2e3d4b 100644
--- a/code/modules/tgui/states/always.dm
+++ b/code/modules/tgui/states/always.dm
@@ -1,9 +1,8 @@
-
- /**
- * tgui state: always_state
- *
- * Always grants the user UI_INTERACTIVE. Period.
- **/
+/**
+ * tgui state: always_state
+ *
+ * Always grants the user UI_INTERACTIVE. Period.
+ */
GLOBAL_DATUM_INIT(always_state, /datum/ui_state/always_state, new)
diff --git a/code/modules/tgui/states/conscious.dm b/code/modules/tgui/states/conscious.dm
index 4323c1391c4..4e2793d1300 100644
--- a/code/modules/tgui/states/conscious.dm
+++ b/code/modules/tgui/states/conscious.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: conscious_state
- *
- * Only checks if the user is conscious.
- **/
+/**
+ * tgui state: conscious_state
+ *
+ * Only checks if the user is conscious.
+ */
GLOBAL_DATUM_INIT(conscious_state, /datum/ui_state/conscious_state, new)
diff --git a/code/modules/tgui/states/contained.dm b/code/modules/tgui/states/contained.dm
index 7387f7e6cbb..f02424d01e6 100644
--- a/code/modules/tgui/states/contained.dm
+++ b/code/modules/tgui/states/contained.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: contained_state
- *
- * Checks that the user is inside the src_object.
- **/
+/**
+ * tgui state: contained_state
+ *
+ * Checks that the user is inside the src_object.
+ */
GLOBAL_DATUM_INIT(contained_state, /datum/ui_state/contained_state, new)
diff --git a/code/modules/tgui/states/deep_inventory.dm b/code/modules/tgui/states/deep_inventory.dm
index 06bdb92f3a5..43758cbab17 100644
--- a/code/modules/tgui/states/deep_inventory.dm
+++ b/code/modules/tgui/states/deep_inventory.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: deep_inventory_state
- *
- * Checks that the src_object is in the user's deep (backpack, box, toolbox, etc) inventory.
- **/
+/**
+ * tgui state: deep_inventory_state
+ *
+ * Checks that the src_object is in the user's deep (backpack, box, toolbox, etc) inventory.
+ */
GLOBAL_DATUM_INIT(deep_inventory_state, /datum/ui_state/deep_inventory_state, new)
diff --git a/code/modules/tgui/states/default.dm b/code/modules/tgui/states/default.dm
index c6741f20b8b..6bb159640e4 100644
--- a/code/modules/tgui/states/default.dm
+++ b/code/modules/tgui/states/default.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: default_state
- *
- * Checks a number of things -- mostly physical distance for humans and view for robots.
- **/
+/**
+ * tgui state: default_state
+ *
+ * Checks a number of things -- mostly physical distance for humans and view for robots.
+ */
GLOBAL_DATUM_INIT(default_state, /datum/ui_state/default, new)
diff --git a/code/modules/tgui/states/hands.dm b/code/modules/tgui/states/hands.dm
index 5da0e5d500f..aedae477dd2 100644
--- a/code/modules/tgui/states/hands.dm
+++ b/code/modules/tgui/states/hands.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: hands_state
- *
- * Checks that the src_object is in the user's hands.
- **/
+/**
+ * tgui state: hands_state
+ *
+ * Checks that the src_object is in the user's hands.
+ */
GLOBAL_DATUM_INIT(hands_state, /datum/ui_state/hands_state, new)
diff --git a/code/modules/tgui/states/human_adjacent.dm b/code/modules/tgui/states/human_adjacent.dm
index 0ab20b36ffd..7aefe43e44c 100644
--- a/code/modules/tgui/states/human_adjacent.dm
+++ b/code/modules/tgui/states/human_adjacent.dm
@@ -1,10 +1,9 @@
-
- /**
- * tgui state: human_adjacent_state
- *
- * In addition to default checks, only allows interaction for a
- * human adjacent user.
- **/
+/**
+ * tgui state: human_adjacent_state
+ *
+ * In addition to default checks, only allows interaction for a
+ * human adjacent user.
+ */
GLOBAL_DATUM_INIT(human_adjacent_state, /datum/ui_state/human_adjacent_state, new)
diff --git a/code/modules/tgui/states/inventory.dm b/code/modules/tgui/states/inventory.dm
index b8b1ad3b6a9..43fe2cb4512 100644
--- a/code/modules/tgui/states/inventory.dm
+++ b/code/modules/tgui/states/inventory.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: inventory_state
- *
- * Checks that the src_object is in the user's top-level (hand, ear, pocket, belt, etc) inventory.
- **/
+/**
+ * tgui state: inventory_state
+ *
+ * Checks that the src_object is in the user's top-level (hand, ear, pocket, belt, etc) inventory.
+ */
GLOBAL_DATUM_INIT(inventory_state, /datum/ui_state/inventory_state, new)
diff --git a/code/modules/tgui/states/language_menu.dm b/code/modules/tgui/states/language_menu.dm
index fedc4320e47..5c816c8922a 100644
--- a/code/modules/tgui/states/language_menu.dm
+++ b/code/modules/tgui/states/language_menu.dm
@@ -1,6 +1,6 @@
- /**
- * tgui state: language_menu_state
- */
+/**
+ * tgui state: language_menu_state
+ */
GLOBAL_DATUM_INIT(language_menu_state, /datum/ui_state/language_menu, new)
diff --git a/code/modules/tgui/states/not_incapacitated.dm b/code/modules/tgui/states/not_incapacitated.dm
index 1fde1d34d0f..1b48f7f41a4 100644
--- a/code/modules/tgui/states/not_incapacitated.dm
+++ b/code/modules/tgui/states/not_incapacitated.dm
@@ -1,16 +1,16 @@
- /**
- * tgui state: not_incapacitated_state
- *
- * Checks that the user isn't incapacitated
- **/
+/**
+ * tgui state: not_incapacitated_state
+ *
+ * Checks that the user isn't incapacitated
+ */
GLOBAL_DATUM_INIT(not_incapacitated_state, /datum/ui_state/not_incapacitated_state, new)
- /**
- * tgui state: not_incapacitated_turf_state
- *
- * Checks that the user isn't incapacitated and that their loc is a turf
- **/
+/**
+ * tgui state: not_incapacitated_turf_state
+ *
+ * Checks that the user isn't incapacitated and that their loc is a turf
+ */
GLOBAL_DATUM_INIT(not_incapacitated_turf_state, /datum/ui_state/not_incapacitated_state, new(no_turfs = TRUE))
diff --git a/code/modules/tgui/states/notcontained.dm b/code/modules/tgui/states/notcontained.dm
index 77a7fe01b00..642c6ce95f4 100644
--- a/code/modules/tgui/states/notcontained.dm
+++ b/code/modules/tgui/states/notcontained.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: notcontained_state
- *
- * Checks that the user is not inside src_object, and then makes the default checks.
- **/
+/**
+ * tgui state: notcontained_state
+ *
+ * Checks that the user is not inside src_object, and then makes the default checks.
+ */
GLOBAL_DATUM_INIT(notcontained_state, /datum/ui_state/notcontained_state, new)
diff --git a/code/modules/tgui/states/observer.dm b/code/modules/tgui/states/observer.dm
index ade0ce66bb8..86ad776b135 100644
--- a/code/modules/tgui/states/observer.dm
+++ b/code/modules/tgui/states/observer.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: observer_state
- *
- * Checks that the user is an observer/ghost.
- **/
+/**
+ * tgui state: observer_state
+ *
+ * Checks that the user is an observer/ghost.
+ */
GLOBAL_DATUM_INIT(observer_state, /datum/ui_state/observer_state, new)
diff --git a/code/modules/tgui/states/physical.dm b/code/modules/tgui/states/physical.dm
index da994cdb884..88c8a291aa8 100644
--- a/code/modules/tgui/states/physical.dm
+++ b/code/modules/tgui/states/physical.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: physical_state
- *
- * Short-circuits the default state to only check physical distance.
- **/
+/**
+ * tgui state: physical_state
+ *
+ * Short-circuits the default state to only check physical distance.
+ */
GLOBAL_DATUM_INIT(physical_state, /datum/ui_state/physical, new)
@@ -24,11 +24,11 @@ GLOBAL_DATUM_INIT(physical_state, /datum/ui_state/physical, new)
return UI_UPDATE // AIs are not physical.
- /**
- * tgui state: physical_obscured_state
- *
- * Short-circuits the default state to only check physical distance, being in view doesn't matter
- **/
+/**
+ * tgui state: physical_obscured_state
+ *
+ * Short-circuits the default state to only check physical distance, being in view doesn't matter
+ */
GLOBAL_DATUM_INIT(physical_obscured_state, /datum/ui_state/physical_obscured_state, new)
diff --git a/code/modules/tgui/states/self.dm b/code/modules/tgui/states/self.dm
index 10849772c6c..b0c9500fbcf 100644
--- a/code/modules/tgui/states/self.dm
+++ b/code/modules/tgui/states/self.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: self_state
- *
- * Only checks that the user and src_object are the same.
- **/
+/**
+ * tgui state: self_state
+ *
+ * Only checks that the user and src_object are the same.
+ */
GLOBAL_DATUM_INIT(self_state, /datum/ui_state/self_state, new)
diff --git a/code/modules/tgui/states/zlevel.dm b/code/modules/tgui/states/zlevel.dm
index 6ccfd0fe7dd..5e3ccfb7de2 100644
--- a/code/modules/tgui/states/zlevel.dm
+++ b/code/modules/tgui/states/zlevel.dm
@@ -1,8 +1,8 @@
- /**
- * tgui state: z_state
- *
- * Only checks that the Z-level of the user and src_object are the same.
- **/
+/**
+ * tgui state: z_state
+ *
+ * Only checks that the Z-level of the user and src_object are the same.
+ */
GLOBAL_DATUM_INIT(z_state, /datum/ui_state/z_state, new)
diff --git a/code/modules/tgui/subsystem.dm b/code/modules/tgui/subsystem.dm
index 90a00fb6074..cbe94e2d7f5 100644
--- a/code/modules/tgui/subsystem.dm
+++ b/code/modules/tgui/subsystem.dm
@@ -1,22 +1,22 @@
- /**
- * tgui subsystem
- *
- * Contains all tgui state and subsystem code.
- **/
+/**
+ * tgui subsystem
+ *
+ * Contains all tgui state and subsystem code.
+ */
- /**
- * public
- *
- * Get a open UI given a user, src_object, and ui_key and try to update it with data.
- *
- * required user mob The mob who opened/is using the UI.
- * required src_object datum The object/datum which owns the UI.
- * required ui_key string The ui_key of the UI.
- * optional ui datum/tgui The UI to be updated, if it exists.
- * optional force_open bool If the UI should be re-opened instead of updated.
- *
- * return datum/tgui The found UI.
- **/
+/**
+ * public
+ *
+ * Get a open UI given a user, src_object, and ui_key and try to update it with data.
+ *
+ * required user mob The mob who opened/is using the UI.
+ * required src_object datum The object/datum which owns the UI.
+ * required ui_key string The ui_key of the UI.
+ * optional ui datum/tgui The UI to be updated, if it exists.
+ * optional force_open bool If the UI should be re-opened instead of updated.
+ *
+ * return datum/tgui The found UI.
+ */
/datum/controller/subsystem/tgui/proc/try_update_ui(mob/user, datum/src_object, ui_key, datum/tgui/ui, force_open = FALSE)
if(isnull(ui)) // No UI was passed, so look for one.
ui = get_open_ui(user, src_object, ui_key)
@@ -31,17 +31,17 @@
else
return null // We couldn't find a UI.
- /**
- * private
- *
- * Get a open UI given a user, src_object, and ui_key.
- *
- * required user mob The mob who opened/is using the UI.
- * required src_object datum The object/datum which owns the UI.
- * required ui_key string The ui_key of the UI.
- *
- * return datum/tgui The found UI.
- **/
+/**
+ * private
+ *
+ * Get a open UI given a user, src_object, and ui_key.
+ *
+ * required user mob The mob who opened/is using the UI.
+ * required src_object datum The object/datum which owns the UI.
+ * required ui_key string The ui_key of the UI.
+ *
+ * return datum/tgui The found UI.
+ */
/datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object, ui_key)
var/src_object_key = "[REF(src_object)]"
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
@@ -55,15 +55,15 @@
return null // Couldn't find a UI!
- /**
- * private
- *
- * Update all UIs attached to src_object.
- *
- * required src_object datum The object/datum which owns the UIs.
- *
- * return int The number of UIs updated.
- **/
+/**
+ * private
+ *
+ * Update all UIs attached to src_object.
+ *
+ * required src_object datum The object/datum which owns the UIs.
+ *
+ * return int The number of UIs updated.
+ */
/datum/controller/subsystem/tgui/proc/update_uis(datum/src_object)
var/src_object_key = "[REF(src_object)]"
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
@@ -77,15 +77,15 @@
update_count++ // Count each UI we update.
return update_count
- /**
- * private
- *
- * Close all UIs attached to src_object.
- *
- * required src_object datum The object/datum which owns the UIs.
- *
- * return int The number of UIs closed.
- **/
+/**
+ * private
+ *
+ * Close all UIs attached to src_object.
+ *
+ * required src_object datum The object/datum which owns the UIs.
+ *
+ * return int The number of UIs closed.
+ */
/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object)
var/src_object_key = "[REF(src_object)]"
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
@@ -99,13 +99,13 @@
close_count++ // Count each UI we close.
return close_count
- /**
- * private
- *
- * Close *ALL* UIs
- *
- * return int The number of UIs closed.
- **/
+/**
+ * private
+ *
+ * Close *ALL* UIs
+ *
+ * return int The number of UIs closed.
+ */
/datum/controller/subsystem/tgui/proc/close_all_uis()
var/close_count = 0
for(var/src_object_key in open_uis)
@@ -116,17 +116,17 @@
close_count++ // Count each UI we close.
return close_count
- /**
- * private
- *
- * Update all UIs belonging to a user.
- *
- * required user mob The mob who opened/is using the UI.
- * optional src_object datum If provided, only update UIs belonging this src_object.
- * optional ui_key string If provided, only update UIs with this UI key.
- *
- * return int The number of UIs updated.
- **/
+/**
+ * private
+ *
+ * Update all UIs belonging to a user.
+ *
+ * required user mob The mob who opened/is using the UI.
+ * optional src_object datum If provided, only update UIs belonging this src_object.
+ * optional ui_key string If provided, only update UIs with this UI key.
+ *
+ * return int The number of UIs updated.
+ */
/datum/controller/subsystem/tgui/proc/update_user_uis(mob/user, datum/src_object = null, ui_key = null)
if(isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
return 0 // Couldn't find any UIs for this user.
@@ -138,17 +138,17 @@
update_count++ // Count each UI we upadte.
return update_count
- /**
- * private
- *
- * Close all UIs belonging to a user.
- *
- * required user mob The mob who opened/is using the UI.
- * optional src_object datum If provided, only close UIs belonging this src_object.
- * optional ui_key string If provided, only close UIs with this UI key.
- *
- * return int The number of UIs closed.
- **/
+/**
+ * private
+ *
+ * Close all UIs belonging to a user.
+ *
+ * required user mob The mob who opened/is using the UI.
+ * optional src_object datum If provided, only close UIs belonging this src_object.
+ * optional ui_key string If provided, only close UIs with this UI key.
+ *
+ * return int The number of UIs closed.
+ */
/datum/controller/subsystem/tgui/proc/close_user_uis(mob/user, datum/src_object = null, ui_key = null)
if(isnull(user.open_uis) || !istype(user.open_uis, /list) || open_uis.len == 0)
return 0 // Couldn't find any UIs for this user.
@@ -160,13 +160,13 @@
close_count++ // Count each UI we close.
return close_count
- /**
- * private
- *
- * Add a UI to the list of open UIs.
- *
- * required ui datum/tgui The UI to be added.
- **/
+/**
+ * private
+ *
+ * Add a UI to the list of open UIs.
+ *
+ * required ui datum/tgui The UI to be added.
+ */
/datum/controller/subsystem/tgui/proc/on_open(datum/tgui/ui)
var/src_object_key = "[REF(ui.src_object)]"
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
@@ -180,15 +180,15 @@
uis |= ui
processing_uis |= ui
- /**
- * private
- *
- * Remove a UI from the list of open UIs.
- *
- * required ui datum/tgui The UI to be removed.
- *
- * return bool If the UI was removed or not.
- **/
+/**
+ * private
+ *
+ * Remove a UI from the list of open UIs.
+ *
+ * required ui datum/tgui The UI to be removed.
+ *
+ * return bool If the UI was removed or not.
+ */
/datum/controller/subsystem/tgui/proc/on_close(datum/tgui/ui)
var/src_object_key = "[REF(ui.src_object)]"
if(isnull(open_uis[src_object_key]) || !istype(open_uis[src_object_key], /list))
@@ -210,28 +210,28 @@
return 1 // Let the caller know we did it.
- /**
- * private
- *
- * Handle client logout, by closing all their UIs.
- *
- * required user mob The mob which logged out.
- *
- * return int The number of UIs closed.
- **/
+/**
+ * private
+ *
+ * Handle client logout, by closing all their UIs.
+ *
+ * required user mob The mob which logged out.
+ *
+ * return int The number of UIs closed.
+ */
/datum/controller/subsystem/tgui/proc/on_logout(mob/user)
return close_user_uis(user)
- /**
- * private
- *
- * Handle clients switching mobs, by transferring their UIs.
- *
- * required user source The client's original mob.
- * required user target The client's new mob.
- *
- * return bool If the UIs were transferred.
- **/
+/**
+ * private
+ *
+ * Handle clients switching mobs, by transferring their UIs.
+ *
+ * required user source The client's original mob.
+ * required user target The client's new mob.
+ *
+ * return bool If the UIs were transferred.
+ */
/datum/controller/subsystem/tgui/proc/on_transfer(mob/source, mob/target)
if(!source || isnull(source.open_uis) || !istype(source.open_uis, /list) || open_uis.len == 0)
return 0 // The old mob had no open UIs.
diff --git a/code/modules/tgui/tgui.dm b/code/modules/tgui/tgui.dm
index 8340f993d4d..51648da5635 100644
--- a/code/modules/tgui/tgui.dm
+++ b/code/modules/tgui/tgui.dm
@@ -1,12 +1,12 @@
- /**
- * tgui
- *
- * /tg/station user interface library
- **/
+/**
+ * tgui
+ *
+ * /tg/station user interface library
+ */
- /**
- * tgui datum (represents a UI).
- **/
+/**
+ * tgui datum (represents a UI).
+ */
/datum/tgui
/// The mob who opened/is using the UI.
var/mob/user
@@ -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.
@@ -34,6 +32,8 @@
var/list/initial_data
/// The static data used to initialize the UI.
var/list/initial_static_data
+ /// Holder for the json string, that is sent during the initial update
+ var/_initial_update
/// The status/visibility of the UI.
var/status = UI_INTERACTIVE
/// Topic state used to determine status/interactability.
@@ -42,34 +42,31 @@
var/datum/tgui/master_ui
/// Children of this UI.
var/list/datum/tgui/children = list()
- var/custom_browser_id = FALSE
- var/ui_screen = "home"
- /**
- * public
- *
- * Create a new UI.
- *
- * required user mob The mob who opened/is using the UI.
- * required src_object datum The object or datum which owns the UI.
- * required ui_key string The ui_key of the UI.
- * required interface string The interface used to render the UI.
- * optional title string The title of the UI.
- * optional width int The window width.
- * optional height int The window height.
- * optional master_ui datum/tgui The parent UI.
- * optional state datum/ui_state The state used to determine status.
- *
- * return datum/tgui The requested UI.
- **/
-/datum/tgui/New(mob/user, datum/src_object, ui_key, interface, title, width = 0, height = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state, browser_id = null)
+/**
+ * public
+ *
+ * Create a new UI.
+ *
+ * required user mob The mob who opened/is using the UI.
+ * required src_object datum The object or datum which owns the UI.
+ * required ui_key string The ui_key of the UI.
+ * required interface string The interface used to render the UI.
+ * optional title string The title of the UI.
+ * optional width int The window width.
+ * optional height int The window height.
+ * optional master_ui datum/tgui The parent UI.
+ * optional state datum/ui_state The state used to determine status.
+ *
+ * return datum/tgui The requested UI.
+ */
+/datum/tgui/New(mob/user, datum/src_object, ui_key, interface, title, width = 0, height = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
src.user = user
src.src_object = src_object
src.ui_key = ui_key
- 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)
+ // DO NOT replace with \ref here. src_object could potentially be tagged
+ src.window_id = "[REF(src_object)]-[ui_key]"
+ src.interface = interface
if(title)
src.title = sanitize(title)
@@ -86,11 +83,11 @@
var/datum/asset/assets = get_asset_datum(/datum/asset/group/tgui)
assets.send(user)
- /**
- * public
- *
- * Open this UI (and initialize it with data).
- **/
+/**
+ * public
+ *
+ * Open this UI (and initialize it with data).
+ */
/datum/tgui/proc/open()
if(!user.client)
return // Bail if there is no client.
@@ -99,18 +96,16 @@
if(status < UI_UPDATE)
return // Bail if we're not supposed to open.
- var/window_size
- if(width && height) // If we have a width and height, use them.
- window_size = "size=[width]x[height];"
- else
- window_size = ""
-
+ // Build window options
+ var/window_options = "can_minimize=0;auto_format=0;"
+ // If we have a width and height, use them.
+ if(width && height)
+ window_options += "size=[width]x[height];"
// Remove titlebar and resize handles for a fancy window
- var/have_title_bar
if(user.client.prefs.tgui_fancy)
- have_title_bar = "titlebar=0;can_resize=0;"
+ window_options += "titlebar=0;can_resize=0;"
else
- have_title_bar = "titlebar=1;can_resize=1;"
+ window_options += "titlebar=1;can_resize=1;"
// Generate page html
var/html
@@ -120,47 +115,51 @@
// Replace template tokens with important UI data
// 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)
+ html = replacetextEx(html, "\[tgui:ref]", "\ref[src]")
// Open the window.
- user << browse(html, "window=[window_id];can_minimize=0;auto_format=0;[window_size][have_title_bar]")
- if (!custom_browser_id)
- // Instruct the client to signal UI when the window is closed.
- // NOTE: Intentional \ref usage; tgui datums can't/shouldn't
- // be tagged, so this is an effective unwrap
- winset(user, window_id, "on-close=\"uiclose \ref[src]\"")
+ user << browse(html, "window=[window_id];[window_options]")
- if(!initial_data)
+ // Instruct the client to signal UI when the window is closed.
+ // NOTE: Intentional \ref usage; tgui datums can't/shouldn't
+ // be tagged, so this is an effective unwrap
+ winset(user, window_id, "on-close=\"uiclose \ref[src]\"")
+
+ // Pre-fetch initial state while browser is still loading in
+ // another thread
+ if(!initial_data) {
initial_data = src_object.ui_data(user)
- if(!initial_static_data)
+ }
+ if(!initial_static_data) {
initial_static_data = src_object.ui_static_data(user)
+ }
+ _initial_update = url_encode(get_json(initial_data, initial_static_data))
SStgui.on_open(src)
- /**
- * public
- *
- * Reinitialize the UI.
- * (Possibly with a new interface and/or data).
- *
- * optional template string The name of the new interface.
- * optional data list The new initial data.
- **/
+/**
+ * public
+ *
+ * Reinitialize the UI.
+ * (Possibly with a new interface and/or data).
+ *
+ * optional template string The name of the new interface.
+ * optional data list The new initial data.
+ */
/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)
initial_static_data = static_data
open()
- /**
- * public
- *
- * Close the UI, and all its children.
- **/
+/**
+ * public
+ *
+ * Close the UI, and all its children.
+ */
/datum/tgui/proc/close()
user << browse(null, "window=[window_id]") // Close the window.
src_object.ui_close(user)
@@ -172,55 +171,33 @@
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
- *
- * 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
- *
- * Enable/disable auto-updating of the UI.
- *
- * required state bool Enable/disable auto-updating.
- **/
+/**
+ * public
+ *
+ * Enable/disable auto-updating of the UI.
+ *
+ * required state bool Enable/disable auto-updating.
+ */
/datum/tgui/proc/set_autoupdate(state = TRUE)
autoupdate = state
- /**
- * private
- *
- * Package the data to send to the UI, as JSON.
- * This includes the UI data and config_data.
- *
- * return string The packaged JSON.
- **/
+/**
+ * private
+ *
+ * Package the data to send to the UI, as JSON.
+ * This includes the UI data and config_data.
+ *
+ * return string The packaged JSON.
+ */
/datum/tgui/proc/get_json(list/data, list/static_data)
var/list/json_data = list()
json_data["config"] = list(
"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,
+ "locked" = user.client.prefs.tgui_lock,
"observer" = isobserver(user),
"window" = window_id,
// NOTE: Intentional \ref usage; tgui datums can't/shouldn't
@@ -233,6 +210,10 @@
if(!isnull(static_data))
json_data["static_data"] = static_data
+ // Send shared states
+ if(src_object.tgui_shared_states)
+ json_data["shared"] = src_object.tgui_shared_states
+
// Generate the JSON.
var/json = json_encode(json_data)
// Strip #255/improper.
@@ -240,13 +221,13 @@
json = replacetext(json, "\improper", "")
return json
- /**
- * private
- *
- * Handle clicks from the UI.
- * Call the src_object's ui_act() if status is UI_INTERACTIVE.
- * If the src_object's ui_act() returns 1, update all UIs attacked to it.
- **/
+/**
+ * private
+ *
+ * Handle clicks from the UI.
+ * Call the src_object's ui_act() if status is UI_INTERACTIVE.
+ * If the src_object's ui_act() returns 1, update all UIs attacked to it.
+ */
/datum/tgui/Topic(href, href_list)
if(user != usr)
return // Something is not right here.
@@ -256,12 +237,24 @@
switch(action)
if("tgui:initialize")
- user << output(url_encode(get_json(initial_data, initial_static_data)), "[custom_browser_id ? window_id : "[window_id].browser"]:initialize")
+ user << output(_initial_update, "[window_id].browser:update")
initialized = TRUE
- if("tgui:view")
- if(params["screen"])
- ui_screen = params["screen"]
+ if("tgui:setSharedState")
+ // Update the window state.
+ update_status(push = FALSE)
+ // Bail if UI is not interactive or usr calling Topic
+ // is not the UI user.
+ if(status != UI_INTERACTIVE)
+ return
+ var/key = params["key"]
+ var/value = params["value"]
+ if(!src_object.tgui_shared_states)
+ src_object.tgui_shared_states = list()
+ src_object.tgui_shared_states[key] = value
SStgui.update_uis(src_object)
+ if("tgui:setFancy")
+ var/value = text2num(params["value"])
+ user.client.prefs.tgui_fancy = value
if("tgui:log")
// Force window to show frills on fatal errors
if(params["fatal"])
@@ -269,23 +262,22 @@
log_message(params["log"])
if("tgui:link")
user << link(params["url"])
- if("tgui:fancy")
- user.client.prefs.tgui_fancy = TRUE
- if("tgui:nofrills")
- user.client.prefs.tgui_fancy = FALSE
else
- update_status(push = FALSE) // Update the window state.
- if(src_object.ui_act(action, params, src, state)) // Call ui_act() on the src_object.
- SStgui.update_uis(src_object) // Update if the object requested it.
+ // Update the window state.
+ update_status(push = FALSE)
+ // Call ui_act() on the src_object.
+ if(src_object.ui_act(action, params, src, state))
+ // Update if the object requested it.
+ SStgui.update_uis(src_object)
- /**
- * private
- *
- * Update the UI.
- * Only updates the data if update is true, otherwise only updates the status.
- *
- * optional force bool If the UI should be forced to update.
- **/
+/**
+ * private
+ *
+ * Update the UI.
+ * Only updates the data if update is true, otherwise only updates the status.
+ *
+ * optional force bool If the UI should be forced to update.
+ */
/datum/tgui/process(force = FALSE)
var/datum/host = src_object.ui_host(user)
if(!src_object || !host || !user) // If the object or user died (or something else), abort.
@@ -297,42 +289,46 @@
else
update_status(push = TRUE) // Otherwise only update status.
- /**
- * private
- *
- * Push data to an already open UI.
- *
- * required data list The data to send.
- * optional force bool If the update should be sent regardless of state.
- **/
+/**
+ * private
+ *
+ * Push data to an already open UI.
+ *
+ * required data list The data to send.
+ * optional force bool If the update should be sent regardless of state.
+ */
/datum/tgui/proc/push_data(data, static_data, force = FALSE)
- update_status(push = FALSE) // Update the window state.
+ // Update the window state.
+ update_status(push = FALSE)
+ // Cannot update UI if it is not set up yet.
if(!initialized)
- return // Cannot update UI if it is not set up yet.
+ return
+ // Cannot update UI, we have no visibility.
if(status <= UI_DISABLED && !force)
- return // Cannot update UI, we have no visibility.
-
+ return
// Send the new JSON to the update() Javascript function.
- user << output(url_encode(get_json(data, static_data)), "[custom_browser_id ? window_id : "[window_id].browser"]:update")
+ user << output(
+ url_encode(get_json(data, static_data)),
+ "[window_id].browser:update")
- /**
- * private
- *
- * Updates the UI by interacting with the src_object again, which will hopefully
- * call try_ui_update on it.
- *
- * optional force_open bool If force_open should be passed to ui_interact.
- **/
+/**
+ * private
+ *
+ * Updates the UI by interacting with the src_object again, which will hopefully
+ * call try_ui_update on it.
+ *
+ * optional force_open bool If force_open should be passed to ui_interact.
+ */
/datum/tgui/proc/update(force_open = FALSE)
src_object.ui_interact(user, ui_key, src, force_open, master_ui, state)
- /**
- * private
- *
- * Update the status/visibility of the UI for its user.
- *
- * optional push bool Push an update to the UI (an update is always sent for UI_DISABLED).
- **/
+/**
+ * private
+ *
+ * Update the status/visibility of the UI for its user.
+ *
+ * optional push bool Push an update to the UI (an update is always sent for UI_DISABLED).
+ */
/datum/tgui/proc/update_status(push = FALSE)
var/status = src_object.ui_status(user, state)
if(master_ui)
@@ -341,23 +337,25 @@
if(status == UI_CLOSE)
close()
- /**
- * private
- *
- * Set the status/visibility of the UI.
- *
- * required status int The status to set (UI_CLOSE/UI_DISABLED/UI_UPDATE/UI_INTERACTIVE).
- * optional push bool Push an update to the UI (an update is always sent for UI_DISABLED).
- **/
+/**
+ * private
+ *
+ * Set the status/visibility of the UI.
+ *
+ * required status int The status to set (UI_CLOSE/UI_DISABLED/UI_UPDATE/UI_INTERACTIVE).
+ * optional push bool Push an update to the UI (an update is always sent for UI_DISABLED).
+ */
/datum/tgui/proc/set_status(status, push = FALSE)
- if(src.status != status) // Only update if status has changed.
+ // Only update if status has changed.
+ if(src.status != status)
if(src.status == UI_DISABLED)
src.status = status
if(push)
update()
else
src.status = status
- if(status == UI_DISABLED || push) // Update if the UI just because disabled, or a push is requested.
+ // Update if the UI just because disabled, or a push is requested.
+ if(status == UI_DISABLED || push)
push_data(null, force = TRUE)
/datum/tgui/proc/log_message(message)
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)
diff --git a/tgui/.eslintrc.yml b/tgui/.eslintrc.yml
index e5ebafddcfc..67e74085c7e 100644
--- a/tgui/.eslintrc.yml
+++ b/tgui/.eslintrc.yml
@@ -305,7 +305,13 @@ rules:
## Enforce or disallow capitalization of the first letter of a comment
# capitalized-comments: error
## Require or disallow trailing commas
- comma-dangle: [error, always-multiline]
+ comma-dangle: [error, {
+ arrays: always-multiline,
+ objects: always-multiline,
+ imports: always-multiline,
+ exports: always-multiline,
+ functions: only-multiline, ## Optional on functions
+ }]
## Enforce consistent spacing before and after commas
comma-spacing: [error, { before: false, after: true }]
## Enforce consistent comma style
diff --git a/tgui/README.md b/tgui/README.md
index a7ef35602ed..5ddeb18fdda 100644
--- a/tgui/README.md
+++ b/tgui/README.md
@@ -151,893 +151,37 @@ together, and can reveal certain layout bugs which are not normally visible.
- `/packages/tgui/interfaces` - Actual in-game interfaces.
Interface takes data via the `state` prop and outputs an html-like stucture,
which you can build using existing UI components.
-- `/packages/tgui/routes.js` - This is where you want to register new
-interfaces, otherwise they simply won't load.
+- `/packages/tgui/layouts` - Root level UI components, that affect the final
+look and feel of the browser window. They usually hold various window
+elements, like the titlebar and resize handlers, and control the UI theme.
+- `/packages/tgui/routes.js` - This is where tgui decides which interface to
+pull and render.
- `/packages/tgui/layout.js` - A root-level component, holding the
window elements, like the titlebar, buttons, resize handlers. Calls
`routes.js` to decide which component to render.
- `/packages/tgui/styles/main.scss` - CSS entry point.
+- `/packages/tgui/styles/functions.scss` - Useful SASS functions.
+Stuff like `lighten`, `darken`, `luminance` are defined here.
- `/packages/tgui/styles/atomic` - Atomic CSS classes.
These are very simple, tiny, reusable CSS classes which you can use and
combine to change appearance of your elements. Keep them small.
- `/packages/tgui/styles/components` - CSS classes which are used
-in UI components, and most of the stylesheets referenced here are located
-in `/packages/tgui/components`. These stylesheets closely follow the
+in UI components. These stylesheets closely follow the
[BEM](https://en.bem.info/methodology/) methodology.
-- `/packages/tgui/styles/functions.scss` - Useful SASS functions.
-Stuff like `lighten`, `darken`, `luminance` are defined here.
+- `/packages/tgui/styles/interfaces` - Custom stylesheets for your interfaces.
+Add stylesheets here if you really need a fine control over your UI styles.
+- `/packages/tgui/styles/layouts` - Layout-related styles.
+- `/packages/tgui/styles/themes` - Contains all the various themes you can
+use in tgui. Each theme must be registered in `webpack.config.js` file.
## Component Reference
-> Notice: This documentation might be out of date, so always check the source
-> code to see the most up-to-date information.
+See: [Component Reference](docs/component-reference.md).
-These are the components which you can use for interface construction.
-If you have trouble finding the exact prop you need on a component,
-please note, that most of these components inherit from other basic
-components, such as `Box`. This component in particular provides a lot
-of styling options for all components, e.g. `color` and `opacity`, thus
-it is used a lot in this framework.
+## License
-There are a few important semantics you need to know about:
+All code is licensed with the parent license of *tgstation*, **AGPL-3.0**.
-- Some elements support a `content` prop, which is a synonym to a
-`children` prop.
- - `content` is better used when your element is a self-closing tag
- (like ``), and when content is small and simple
- enough to fit in a prop. Keep in mind, that this prop is **not** native
- to React, and is only available on these components: `Button`, `Tooltip`.
- - You should never use `children` explicitly as a prop on an element.
- Instead open a full tag, and place children or text inside the tag.
-- Inferno supports both camelcase (`onClick`) and lowercase (`onclick`)
-event names.
- - Camel case names are what's called "synthetic" events, and are the
- *preferred way* of handling events in React, for efficiency and
- performance reasons. Please read
- [Inferno Event Handling](https://infernojs.org/docs/guides/event-handling)
- to understand what this is about.
- - Lower case names are native browser events and should be used sparingly,
- for example when you need an explicit IE8 support. **DO NOT** use
- lowercase event handlers unless you really know what you are doing.
- - [Button](#button) component does not support lowercase `onclick` event.
- Use the camel case `onClick` instead.
+See the main [README](../README.md) for more details.
-### `AnimatedNumber`
-
-This component provides animations for numeric values.
-
-Props:
-
-- `value: number` - Value to animate.
-- `initial: number` - Initial value to use in animation when element
-first appears. If you set initial to `0` for example, number will always
-animate starting from `0`, and if omitted, it will not play an initial
-animation.
-- `format: value => value` - Output formatter.
- - Example: `value => Math.round(value)`.
-- `children: (formattedValue, rawValue) => any` - Pull the animated number to
-animate more complex things deeper in the DOM tree.
- - Example: `(_, value) =>