Files
Paradise/code/controllers/subsystem/SStgui.dm
Contrabang 3f87165a03 CI now bans files with the same name (PART 2) (#21051)
* CI change

* world.dm

* .dme world.dm

* subsystem renaming

* .dme for subsystems

* ai_laws.dm

* armor.dm

* emote.dm

* logging.dm

* spell.dm

* air_alarm.dm

* crew.dm

* decal.dm

* emissive_blocker.dm

* footstep.dm

* spawner.dm

* fire.dm

* carbon.dm

* living.dm

* mob.dm

* movement.dm

* thermal_drill.dm

* plasmamen.dm

* lavaland.dm

* chaplain.dm

* lightning.dm

* magnet.dm

* mimic.dm

* wizard.dm

* morph.dm

* vampire.dm

* click.dm

* self.dm

* radiation_storm.dm

* airlock.dm

* autolathe.dm

* mulebot.dm

* nuclearbomb.dm

* particle_accelerator.dm

* smartfridge.dm

* syndicatebomb.dm

* vending.dm

* wires.dm

* sound.dm

* mining.dm

* syndicate_space_base.dm

* monkey.dm

* guardian.dm

* bomb.dm

* standard.dm

* nuclear.dm

* pinpointer.dm

* access.dm

* departments.dm

* job.dm

* science.dm

* buttons.dm

* cloning.dm

* igniter.dm

* wishgranter.dm

* atmos_control.dm

* message.dm

* power_monitor.dm

* mecha.dm

* combat.dm

* mining_tools.dm

* meteors.dm

* spiders.dm

* contraband.dm

* aliens.dm

* uplinks.dm

* voice.dm

* intercom.dm

* lights.dm

* robot_items.dm

* mineral.dm

* dice.dm

* extinguisher.dm

* paint.dm

* signs.dm

* staff.dm

* smokebomb.dm

* boxes.dm

* random.dm

* janicart.dm

* statue.dm

* cargo.dm

* asteroid.dm

* headslug.dm

* fulton.dm

* atmospherics.dm

* pump.dm

* corpse.dm

* oldstation.dm

* gps.dm

* preferences.dm

* clothing.dm

* ears.dm

* glasses.dm

* boxing.dm

* color.dm

* renames ninja gear files

* recipes.dm

* error_handler.dm

* anomaly.dm

* floorcluwne.dm

* undead.dm

* overmind.dm

* shield.dm

* bottle.dm

* organ.dm

* piano.dm

* plasma_fist.dm

* language.dm

* mob_defines.dm

* mob_helpers.dm

* damage_procs.dm

* _defines.dm

* empress.dm and queen.dm

* brain.dm

* organ file renaming

* subsystems.dm

* constructs.dm

* bot.dm

* pet.dm

* nature.dm

* magic.dm

* colors.dm

* drugs.dm

* medicine.dm

* toxins.dm

* shuttle.dm

* surgery.dm

* moves a bunch of define files

* traits.dm

* names.dm

* other_mobs.dm

* flags.dm

* some final define files

* well turns out contractor_pinpointer.dm was  taken

* I forgot to remove this file

* how in the hell did this get unticked

* I DID INCLUDE IT, but there was a "w" there

* swaps the world definitions

* camera renamed to SScamera

* examine -> alien_examine
2023-06-02 14:30:17 -05:00

312 lines
10 KiB
Plaintext

/**
* tgui subsystem
*
* Contains all tgui state and subsystem code.
**/
SUBSYSTEM_DEF(tgui)
name = "TGUI"
wait = 9
flags = SS_NO_INIT
priority = FIRE_PRIORITY_TGUI
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
offline_implications = "All TGUIs will no longer process. Shuttle call recommended."
var/list/currentrun = list()
var/list/open_uis = list() // A list of open UIs, grouped by src_object and ui_key.
var/list/processing_uis = list() // A list of processing UIs, ungrouped.
var/basehtml // The HTML base used for all UIs.
/datum/controller/subsystem/tgui/PreInit()
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
/datum/controller/subsystem/tgui/get_stat_details()
return "P:[length(processing_uis)]"
/datum/controller/subsystem/tgui/get_metrics()
. = ..()
var/list/cust = list()
cust["processing"] = length(processing_uis)
.["custom"] = cust
/datum/controller/subsystem/tgui/fire(resumed = 0)
if (!resumed)
src.currentrun = processing_uis.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/datum/tgui/ui = currentrun[currentrun.len]
currentrun.len--
if(ui && ui.user && ui.src_object)
ui.process()
else
processing_uis.Remove(ui)
if (MC_TICK_CHECK)
return
/**
* public
*
* Get an open UI given a user, src_object, and ui_key and try to update it with data.
* Returns the found UI.
*
* * mob/user - The mob who opened/is using the UI. (REQUIRED)
* * datum/src_object - The object/datum which owns the UI. (REQUIRED)
* * ui_key - The ui_key of the UI. (REQUIRED)
* * datum/tgui/ui - The UI to be updated, if it exists. (OPTIONAL)
* * force_open - If the UI should be re-opened instead of updated. (OPTIONAL)
*/
/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)
if(!isnull(ui))
var/data = src_object.ui_data(user) // Get data from the src_object.
if(!force_open) // UI is already open; update it.
ui.push_data(data)
else // Re-open it anyways.
ui.reinitialize(null, data)
return ui // We found the UI, return it.
else
return null // We couldn't find a UI.
/**
* private
*
* Get an open UI given a user, src_object, and ui_key.
* Returns the found UI.
*
* * mob/user - The mob who opened/is using the UI. (REQUIRED)
* * datum/src_object - The object/datum which owns the UI. (REQUIRED)
* * ui_key - The ui_key of the UI. (REQUIRED)
*/
/datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object, ui_key)
var/src_object_key = "[src_object.UID()]"
if(isnull(open_uis[src_object_key]) || !islist(open_uis[src_object_key]))
return null // No UIs open.
else if(isnull(open_uis[src_object_key][ui_key]) || !islist(open_uis[src_object_key][ui_key]))
return null // No UIs open for this object.
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key]) // Find UIs for this object.
if(ui.user == user) // Make sure we have the right user
return ui
return null // Couldn't find a UI!
/**
* private
*
* Update all UIs attached to src_object.
* Returns the number of UIs updated.
*
* * datum/src_object - The object/datum which owns the UIs.
* * update_static_data - If the static data of the `src_object` should be updated for every viewing user.
*/
/datum/controller/subsystem/tgui/proc/update_uis(datum/src_object, update_static_data = FALSE)
var/src_object_key = "[src_object.UID()]"
if(isnull(open_uis[src_object_key]) || !islist(open_uis[src_object_key]))
return 0 // Couldn't find any UIs for this object.
var/update_count = 0
for(var/ui_key in open_uis[src_object_key])
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user)) // Check the UI is valid.
if(update_static_data)
src_object.update_static_data(ui.user, ui, ui_key)
ui.process(force = 1) // Update the UI.
update_count++ // Count each UI we update.
return update_count
/**
* private
*
* Close all UIs attached to src_object.
* Returns the number of UIs closed.
*
* * datum/src_object - The object/datum which owns the UIs.
*/
/datum/controller/subsystem/tgui/proc/close_uis(datum/src_object)
if(!src_object.unique_datum_id) // First check if the datum has an UID set
return 0
var/src_object_key = "[src_object.UID()]"
if(isnull(open_uis[src_object_key]) || !islist(open_uis[src_object_key]))
return 0 // Couldn't find any UIs for this object.
var/close_count = 0
for(var/ui_key in open_uis[src_object_key])
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user)) // Check the UI is valid.
ui.close() // Close the UI.
close_count++ // Count each UI we close.
return close_count
/**
*
* Gets the amount of open UIs on an object
* Returns the number of UIs open.
*
* * datum/src_object - The object/datum which owns the UIs.
*/
/datum/controller/subsystem/tgui/proc/get_open_ui_count(datum/src_object)
if(!src_object.unique_datum_id) // First check if the datum has an UID set
return 0
var/src_object_key = "[src_object.UID()]"
if(isnull(open_uis[src_object_key]) || !islist(open_uis[src_object_key]))
return 0 // Couldn't find any UIs for this object.
var/open_count = 0
for(var/ui_key in open_uis[src_object_key])
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user)) // Check the UI is valid.
open_count++ // Count each UI thats open
return open_count
/**
* private
*
* Close *ALL* UIs
* Returns 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)
for(var/ui_key in open_uis[src_object_key])
for(var/datum/tgui/ui in open_uis[src_object_key][ui_key])
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user)) // Check the UI is valid.
ui.close() // Close the UI.
close_count++ // Count each UI we close.
return close_count
/**
* private
*
* Update all UIs belonging to a user.
* Returns the number of UIs updated.
*
* * mob/user - The mob who opened/is using the UI. (REQUIRED)
* * datum/src_object - If provided, only update UIs belonging this src_object. (OPTIONAL)
* * ui_key - If provided, only update UIs with this UI key. (OPTIONAL)
*/
/datum/controller/subsystem/tgui/proc/update_user_uis(mob/user, datum/src_object = null, ui_key = null)
if(isnull(user.open_uis) || !islist(user.open_uis) || open_uis.len == 0)
return 0 // Couldn't find any UIs for this user.
var/update_count = 0
for(var/datum/tgui/ui in user.open_uis)
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
ui.process(force = 1) // Update the UI.
update_count++ // Count each UI we upadte.
return update_count
/**
* private
*
* Close all UIs belonging to a user.
* Returns the number of UIs closed.
*
* * mob/user - The mob who opened/is using the UI. (REQUIRED)
* * datum/src_object - If provided, only close UIs belonging this src_object. (OPTIONAL)
* * ui_key - If provided, only close UIs with this UI key. (OPTIONAL)
*/
/datum/controller/subsystem/tgui/proc/close_user_uis(mob/user, datum/src_object = null, ui_key = null)
if(isnull(user.open_uis) || !islist(user.open_uis) || open_uis.len == 0)
return 0 // Couldn't find any UIs for this user.
var/close_count = 0
for(var/datum/tgui/ui in user.open_uis)
if((isnull(src_object) || !isnull(src_object) && ui.src_object == src_object) && (isnull(ui_key) || !isnull(ui_key) && ui.ui_key == ui_key))
ui.close() // Close the UI.
close_count++ // Count each UI we close.
return close_count
/**
* private
*
* Add a UI to the list of open UIs.
*
* * datum/tgui/ui - The UI to be added.
*/
/datum/controller/subsystem/tgui/proc/on_open(datum/tgui/ui)
var/src_object_key = "[ui.src_object.UID()]"
if(isnull(open_uis[src_object_key]) || !islist(open_uis[src_object_key]))
open_uis[src_object_key] = list(ui.ui_key = list()) // Make a list for the ui_key and src_object.
else if(isnull(open_uis[src_object_key][ui.ui_key]) || !islist(open_uis[src_object_key][ui.ui_key]))
open_uis[src_object_key][ui.ui_key] = list() // Make a list for the ui_key.
// Append the UI to all the lists.
ui.user.open_uis |= ui
var/list/uis = open_uis[src_object_key][ui.ui_key]
uis |= ui
processing_uis |= ui
/**
* private
*
* Remove a UI from the list of open UIs.
* Returns TRUE if removed, and FALSE if not.
*
* * datum/tgui/ui - The UI to be removed.
*/
/datum/controller/subsystem/tgui/proc/on_close(datum/tgui/ui)
var/src_object_key = "[ui.src_object.UID()]"
if(isnull(open_uis[src_object_key]) || !islist(open_uis[src_object_key]))
return FALSE // It wasn't open.
else if(isnull(open_uis[src_object_key][ui.ui_key]) || !islist(open_uis[src_object_key][ui.ui_key]))
return FALSE // It wasn't open.
processing_uis.Remove(ui) // Remove it from the list of processing UIs.
if(ui.user) // If the user exists, remove it from them too.
ui.user.open_uis.Remove(ui)
var/Ukey = ui.ui_key
var/list/uis = open_uis[src_object_key][Ukey] // Remove it from the list of open UIs.
uis.Remove(ui)
if(!uis.len)
var/list/uiobj = open_uis[src_object_key]
uiobj.Remove(Ukey)
if(!uiobj.len)
open_uis.Remove(src_object_key)
return TRUE // Let the caller know we did it.
/**
* private
*
* Handle client logout, by closing all their UIs.
* Returns the number of UIs closed.
*
* * mob/user - The mob which logged out.
*/
/datum/controller/subsystem/tgui/proc/on_logout(mob/user)
return close_user_uis(user)
/**
* private
*
* Handle clients switching mobs, by transferring their UIs.
* Returns TRUE if the UIs were transferred, and FALSE if not.
*
* * mob/source - The client's original mob.
* * mob/target - The client's new mob.
*/
/datum/controller/subsystem/tgui/proc/on_transfer(mob/source, mob/target)
if(!source || isnull(source.open_uis) || !islist(source.open_uis) || open_uis.len == 0)
return FALSE // The old mob had no open UIs.
if(isnull(target.open_uis) || !islist(target.open_uis))
target.open_uis = list() // Create a list for the new mob if needed.
for(var/datum/tgui/ui in source.open_uis)
ui.user = target // Inform the UIs of their new owner.
target.open_uis.Add(ui) // Transfer all the UIs.
source.open_uis.Cut() // Clear the old list.
return TRUE // Let the caller know we did it.