mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-26 21:48:21 +01:00
TGUIv4 - Core backend updates, TGchat, Asset cache updates (#23726)
* TGUI upgrade project: Port initial TGUI 4.0 changes from TG (#23440) * tgui4.0 * bugfix for un-interaction * fix for input not resetting on close * NTOS restore * fix all interfaces having scrollbars, fix colours * bundle update * dep bumps * bumps the deps as much as possible * button regression fix * TGUI test map rev 1 * fix theme and some component regression * fix login screen regression * fixes regression with uplink cart * bundle * fix regressions * fix the input issue, again * regression fixes, stylesheet edition, hash restore * fixes GPS BSOD * draggable control regression * dev server dep regression * byondUI regression fix * section regression fix * fix secure storage weirdness * Fixed mining vendor scrolling * Arthri review pass 1 * mining vendor double-scroll * fix for RPD, AirAlarm, and Radio * arthri review pass 2 * arthri review pass 3 * sanitize var setting, fix colours, delete unused file * adds CI to branch * god damn AI making random changes * I should remember to compile when changes are made * fixes scrollbar issues * fix camera console, fix flexGrow for sections * CI fix * nanomap fix * Update code/modules/atmospherics/machinery/airalarm.dm * restore margin * style semicolon * TGUIv4 - Moves TGUI Window Sizing from DM to JS (#23524) * Initial commit * Transferring the remaining windows to JS * Resizing part 1 * Resizing part 2 * Some reverts and polish * Forgot that * undeployed nuke window size --------- Co-authored-by: Aylong <alexanderkitsa@gmail.com> * TGUIv4: Remove force_open (#23537) * First state fixes * Removes "force_open" * TGUIv4 - TGUI Version 4.1 (#23547) * Reduced Logging Changes * setSharedState early return for non-interactive UI * TGUI version bump to 4.1 * Fix sending updates for non-interactive UIs * Scalablue UI Stylesheet Changes * CSS Tgui Bundle * JavaScript TGUI Style Changes * Update tgui/packages/tgui/styles/base.scss Co-authored-by: Aylong <69762909+Aylong220@users.noreply.github.com> * Additional changes to Input and Button scalability * TGUI logging proc update * Indentation fix for logging proc * Update code/__HELPERS/_logging.dm Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * Additional log_tgui changes --------- Co-authored-by: Aylong <69762909+Aylong220@users.noreply.github.com> Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * dev server hotfix (#23584) * ui_interact object constructor argument check (#23594) * feat: add smart asset cache, add CDN support for assets, properly group assets (#23585) * feat: add smart asset cache, add CDN support for assets, properly group assets * fix: make tgui actually work * fix: keeping local name for `tgui.bundle.js` and `tgui.bundle.css` for debug and dev server functioning * fix: make `fontawesome` assets finally work * fix: make proper identation for `if` * fix: add `resolveAsset` to `NanoMap.js` * refactor: update `claw_game` and `chess` to new asset framework * refactor/tweak: don't use string concatenation for browser `content` and `head_content`, use list instead. Don't use `common.css` for paper UI, keep local name for stamp image assets, replace hard ref of browser to `atom` (rare case) to `UID` * refactor: remove redundant debug logs * refactor: remove space betwee `if` and `(` * refactor: remove one more redundant log, properly reload UI resources * rafactor: change names of asset files * fix: adjust existing UIs to properly use assets * fix: properly pass args to to `onclose` proc * Update code/modules/asset_cache/transports/asset_transport.dm Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * Update code/modules/asset_cache/transports/asset_transport.dm Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * TGUI 4.2: TGchat + Refactor Asset Delivery + Yarn Berry (#23643) * tgchat * Little cleanup * Refactor Asset Delivery (Part 2) * Little tweaks * fix code styling issues * fix file name duplications * Browser window options fix @gaxeer * transfer valve fixes * yarn berry initial * vsc tasks * yarn berry working * node 20 * fix dev server (lol wrong yarn) * bloody regressions * fixes that damn scrolltracking bug * Some tweaks and flexGrow deletions It still doesn't work as it should, which makes me nervous * remove unneeded deps * 514 regression fix * change stuff to not conflict with other servers * name it as requested --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * revert test_TGUI map addition * TGUI 4.3: Stack, Webpack 5 & UI Tweaks, Yarn 3.6.4, TS support, Jest (#23677) * Stack & UI's Refactor Almost final, polish required Stack & UI's Refactor (Part 1) Stack & UI's Refactor (Part 2) Stack & UI's Refactor (Part 3) * Prettier Maybe bad * ClearChat & some tweaks * Adds a Chat Reliability Layer https://github.com/tgstation/tgstation/pull/79479 * Fix chat BSOD https://github.com/tgstation/tgstation/pull/79821 * WebPack 5 (Didn't work) I hate this shit * Yarn 3.6.4 * make it all work * revert snowflake fix * Stories * adds TS support * re-enable test and prettier * update yarn sdk's * Fix some box regression * ping/reply * Fixes regressions and some things * Zebra and Fix chat button transfer +rebuild * make VSC use the proper local typescript lib * Popper Tooltips https://github.com/tgstation/tgstation/pull/58980 * Popper Tooltips performancy fixes * Dropdown v2 https://github.com/tgstation/tgstation/pull/75164 Without Icon.tsx * BB test map * run build --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * we moved these * change test values * ignore scss files * change hash function * TGUIv4: TGchat fix traitor codeword highlighting (#23720) * Codeword highlighting for TGUIv4 * null safeties * Apply suggestions from code review Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> --------- Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * TGUIv4 - updates standalone build tooling (#23721) * swap `xxhash64` for `md4` * remove hash function * remove old file * TGUI 4.3+4.4: Newscaster fix, `inline-block` replacements and other fixes (#23722) * TGUI 4.3 fixes Newscaster fix + inline-blocks * Be gone Box * Mod Chat -> Mentor Chat * Some warning filters * Rebuild * Delete tgui-common.bundle.js * please work * try it like this * 4.3.1 * 4.3.2 * fix * i forgot to build * 4.4.0 * give me more diff details please so I can fix you * its not binary pls git * test without svgs * removes an un-needed SVG file * inlined SVGs test * fix code styling * comment these --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * TGUIv4 - Removes resizable and improves drag code (#23719) * Initial commit * bundle rebuild * Fixes Radio Sizing * Updates Radio sizing to fix wrapping issues * fix dev server --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * fix hotkeys not being passed to BYOND * Apply suggestions from code review * bump deps * forgot these deps * ci fix * ChemDispenser fixes and HoloControl cooldown * Station Traits TGUI +Rebuild * CI * fix CI for real this time * I have no idea * fix station trait panel * Update code/controllers/subsystem/SSping.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * Update code/controllers/subsystem/SSticker.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * Update code/controllers/subsystem/SSping.dm Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> * deterministic module IDs * TGUI fixes. Again... (#23762) * TGUI Fixes: Part 1 ORM icon for reinforced glass now showing correctly Mining vendor moved to Stack Exofab UI buttons descended from the heavens to the earth * TGUI Fixes: Part 2 DestTagger now works, forgot import LabeledList PowerMonitor graph displays correct Request Console updated to 2.0, BUT, problem with message priority, it was there before the changes, maybe even before the project, I'll have to check it out * TGUI Fixes: Part 2 Fixed `onEnter` input Fixed Cloning Console storage (Im dumbass) Some windows resizing Fixed bad picture in security and medical records console Fixed scrollable dropdown Added translucent color for buttons * Fucking uplink DONE, and Button.Input fix * NT Recruiter and Uplink polish * Del LabeledList from dest. tagger * ChemMaster and OreRedemption log deletion * Update test_tiny.dmm * Translucent button story * Filter for SQL error * del: `log_debug` in `hear_say.dm` * Some little fixes and SpecMenu Stack * Panel.js: mx -> mr * fix ghost spawners * null check --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * fix material name in protolathe * fix various UI interacts * card machine runtime fix * remove legacy folders * TGUIv4 - TGchat Theme Adjustments (#23772) * Initial commit * Changes rule grouping * Robot class style changes and webpack config * Reverts webpack/font changes and subs robot font * revert a state changed in error * fix uninteractable UIs due to chunky fingers * TGUIv4: More fixes, tweaks and fixes for tweaks (#23781) * I fuckin hate PDA * Vending * Add `|` to highlight splitters and some light mode tweaks * Teleporter rewrite * APC and AiAirlock (God forgive me) * clarify highlight syntax --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * TGUIv4 - Abductor Experiment Machine TGUI (#23776) * Experiment Console TGUI * Update for TGUIv4 * UI Size adjustment * ui state and ghost attack update * remove this --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> * fix * TGUIv4 - Adjustments, Fixes, and Tweaks (#23785) * Photocopier layout adjustments * Autolathe Text and Button spacing adjustment * Hotkey fix for moving bug * Removes rule sets for visited links * Fixes ordering multiples on cargo console * fix possible wonky json payloads * fix admin log input list stuff * TGUIv4: Reconnect fix and some other fixes + tweaks (#23790) * Fix reconnecting and transfer it to TSX * RPD polish * RCD, AccessList, GuestPass * Focus reset fix when camera switched. God forgive me again... * Purple box and identation fixes For votes and health scanner * ChemMaster and ChemDispenser ChemMaster - translucent pills buttons and no grow produce section ChemDuspenser - dynamic height * ShuttleManipulator Tabs * RCD buttons * make input bar mode more prominent * fix chem master icons * tab fix * Properly sanitizes loaded messages in tgui chat * TGUIv4 - Adjustments, Fixes, and Tweaks v2 (#23795) * Fixes icon spacing for nanobank tabs * Tweaks Dropdown styling * Fixes sending stuff to old chat * OpenDream TGUI fix * Resizes Station Traits window * Adjusts health analyzer messages for chat tabs * Revert "Properly sanitizes loaded messages in tgui chat" This reverts commit4c32a7094a. * Revert "Revert "Properly sanitizes loaded messages in tgui chat"" This reverts commit24afa55922. * Changes how tgui handles static data * Reenable no-undef rule. Enable Format On Save for VSCode (#23803) * Enable Format On Save for VSCode * Re-enable and fix no-undef --------- Co-authored-by: Arthri <41360489+a@users.noreply.github.com> * pda scanner message improvements * fix mentor/admin PMs being sent to the "unsorted" category * fix garbled custom vote messages * moves cyborg analyser to use chatboxes * fixes regression * Prevent F5 reload * TGUIv4: Themes polish and some new ones + misc fixes (#23814) * Little themes tweaks * NTOS chat theme * Update tgui-panel.bundle.js * Capitalize themes * Paradise theme v1.0 * Little StationTraitsPanel cleanup * Update member_content.dmi * NoCapitalize * Rebuild * Delete Paradise.scss * Create paradise.scss * Forgot * Rewritten Security Records Console For Jesus fucking christ... * Vending and Wires sizes tweaks * ThermoMachine * Syndicate Theme * Little darker * Rewritten Medical Records Console * PDA Nanobank fix * Syndicate Theme Darker * Rebuild TGUI * Wires section grow fix * fixes the enshittified paradise icon * Sirryan+Warrior reviews * bloody define comments * comment correction * unprivate these * errant . begone (how did this not cause a compiler error) * TGUIv4 - Adjustments, Fixes, and Tweaks v3 (#23807) * Fixes ERT Manager silenced message function * Adjusts progress bar on ExosuitFabricator * Sets Dropdown selected to align left * Removes the use of self_state select interfaces * Exosuit Fabricator style adjustments * fix sextractor UI * remove empty tochat string * fix human air alarm interactions * fix modals * add F12/IEChooser --------- Co-authored-by: S34N <12197162+S34NW@users.noreply.github.com> --------- Co-authored-by: Burzah <116982774+Burzah@users.noreply.github.com> Co-authored-by: Aylong <alexanderkitsa@gmail.com> Co-authored-by: Aylong <69762909+Aylong220@users.noreply.github.com> Co-authored-by: Gaxeer <44334376+Gaxeer@users.noreply.github.com> Co-authored-by: DGamerL <108773801+DGamerL@users.noreply.github.com> Co-authored-by: Arthri <41360489+Arthri@users.noreply.github.com> Co-authored-by: Arthri <41360489+a@users.noreply.github.com>
This commit is contained in:
co-authored by
Arthri
Burzah
Aylong
Aylong
Gaxeer
DGamerL
Arthri
parent
98638f1d38
commit
22fbd9aced
Vendored
+2
-1
@@ -7,6 +7,7 @@
|
||||
"eamodio.gitlens",
|
||||
"usernamehw.errorlens",
|
||||
"anturk.dmi-editor",
|
||||
"esbenp.prettier-vscode"
|
||||
"esbenp.prettier-vscode",
|
||||
"arcanis.vscode-zipfs"
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+11
-2
@@ -4,8 +4,16 @@
|
||||
],
|
||||
// ESLint settings:
|
||||
"eslint.workingDirectories": [
|
||||
"tgui/"
|
||||
"./tgui"
|
||||
],
|
||||
"search.exclude": {
|
||||
"**/.yarn": true,
|
||||
"**/.pnp.*": true
|
||||
},
|
||||
"eslint.nodePath": "tgui/.yarn/sdks",
|
||||
"prettier.prettierPath": "tgui/.yarn/sdks/prettier/index.cjs",
|
||||
"typescript.tsdk": "tgui/.yarn/sdks/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"eslint.rules.customizations": [
|
||||
// We really want to fail the CI builds on styling errors,
|
||||
// but it's better to show them as yellow squigglies in IDE
|
||||
@@ -22,5 +30,6 @@
|
||||
},
|
||||
"[scss]": {
|
||||
"editor.rulers": [80]
|
||||
}
|
||||
},
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
|
||||
Vendored
+1
-14
@@ -14,7 +14,7 @@
|
||||
"type": "shell",
|
||||
"command": "tgui/bin/tgui-build",
|
||||
"windows": {
|
||||
"command": ".\\tgui\\bin\\tgui-build.bat"
|
||||
"command": ".\\tgui\\bin\\tgui.bat"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc",
|
||||
@@ -37,18 +37,5 @@
|
||||
"label": "tgui: run dev server"
|
||||
}
|
||||
,
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "tgui/bin/tgui-formatting",
|
||||
"windows": {
|
||||
"command": ".\\tgui\\bin\\tgui-formatting.bat"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc",
|
||||
"$eslint-stylish"
|
||||
],
|
||||
"group": "build",
|
||||
"label": "tgui: run prettier formatting"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# For dreamchecker
|
||||
export SPACEMANDMM_TAG=suite-1.7.1
|
||||
# For TGUI
|
||||
export NODE_VERSION=18
|
||||
export NODE_VERSION=20
|
||||
# Stable Byond Major
|
||||
export STABLE_BYOND_MAJOR=515
|
||||
# Stable Byond Minor
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/// Get html to load a url.
|
||||
/// for use inside of browse() calls to html assets that might be loaded on a cdn.
|
||||
#define URL2HTMLLOADER(url) {"<html><head><meta http-equiv="refresh" content="0;URL='[url]'"/></head><body onLoad="parent.location='[url]'"></body></html>"}
|
||||
|
||||
/// Generate a filename for this asset
|
||||
/// The same asset will always lead to the same asset name
|
||||
/// Generated names do not include file extension.
|
||||
#define GENERATE_ASSET_NAME(file) "asset.[md5(fcopy_rsc(file))]"
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Aleksej Komarov
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
/// How many chat payloads to keep in history
|
||||
#define CHAT_RELIABILITY_HISTORY_SIZE 5
|
||||
/// How many resends to allow before giving up
|
||||
#define CHAT_RELIABILITY_MAX_RESENDS 3
|
||||
|
||||
#define MESSAGE_TYPE_SYSTEM "system"
|
||||
#define MESSAGE_TYPE_LOCALCHAT "localchat"
|
||||
#define MESSAGE_TYPE_RADIO "radio"
|
||||
#define MESSAGE_TYPE_INFO "info"
|
||||
#define MESSAGE_TYPE_WARNING "warning"
|
||||
#define MESSAGE_TYPE_DEADCHAT "deadchat"
|
||||
#define MESSAGE_TYPE_OOC "ooc"
|
||||
#define MESSAGE_TYPE_ADMINPM "adminpm"
|
||||
#define MESSAGE_TYPE_COMBAT "combat"
|
||||
#define MESSAGE_TYPE_ADMINCHAT "adminchat"
|
||||
#define MESSAGE_TYPE_MENTORCHAT "mentorchat"
|
||||
#define MESSAGE_TYPE_EVENTCHAT "eventchat"
|
||||
#define MESSAGE_TYPE_ADMINLOG "adminlog"
|
||||
#define MESSAGE_TYPE_ATTACKLOG "attacklog"
|
||||
#define MESSAGE_TYPE_DEBUG "debug"
|
||||
@@ -2,6 +2,7 @@
|
||||
#define chat_box_examine(str) ("<div class='boxed_message left_align_text'>" + str + "</div>")
|
||||
#define chat_box_red(str) ("<div class='boxed_message red_border'>" + str + "</div>")
|
||||
#define chat_box_green(str) ("<div class='boxed_message green_border'>" + str + "</div>")
|
||||
#define chat_box_purple(str) ("<div class='boxed_message purple_border'>" + str + "</div>")
|
||||
#define chat_box_notice(str) ("<div class='boxed_message notice_border'>" + str + "</div>")
|
||||
#define chat_box_healthscan(str) ("<div class='boxed_message notice_border left_align_text'>" + str + "</div>")
|
||||
#define chat_box_notice_thick(str) ("<div class='boxed_message notice_border thick_border'>" + str + "</div>")
|
||||
|
||||
@@ -59,19 +59,19 @@
|
||||
#define FULLTILE_WINDOW_DIR NORTHEAST
|
||||
|
||||
//Material defines, for determining how much of a given material an item contains
|
||||
#define MAT_METAL "$metal"
|
||||
#define MAT_GLASS "$glass"
|
||||
#define MAT_SILVER "$silver"
|
||||
#define MAT_GOLD "$gold"
|
||||
#define MAT_DIAMOND "$diamond"
|
||||
#define MAT_URANIUM "$uranium"
|
||||
#define MAT_PLASMA "$plasma"
|
||||
#define MAT_BLUESPACE "$bluespace"
|
||||
#define MAT_BANANIUM "$bananium"
|
||||
#define MAT_TRANQUILLITE "$tranquillite"
|
||||
#define MAT_TITANIUM "$titanium"
|
||||
#define MAT_BIOMASS "$biomass"
|
||||
#define MAT_PLASTIC "$plastic"
|
||||
#define MAT_METAL "metal"
|
||||
#define MAT_GLASS "glass"
|
||||
#define MAT_SILVER "silver"
|
||||
#define MAT_GOLD "gold"
|
||||
#define MAT_DIAMOND "diamond"
|
||||
#define MAT_URANIUM "uranium"
|
||||
#define MAT_PLASMA "plasma"
|
||||
#define MAT_BLUESPACE "bluespace"
|
||||
#define MAT_BANANIUM "bananium"
|
||||
#define MAT_TRANQUILLITE "tranquillite"
|
||||
#define MAT_TITANIUM "titanium"
|
||||
#define MAT_BIOMASS "biomass"
|
||||
#define MAT_PLASTIC "plastic"
|
||||
//The amount of materials you get from a sheet of mineral like iron/diamond/glass etc
|
||||
#define MINERAL_MATERIAL_AMOUNT 2000
|
||||
//The maximum size of a stack object.
|
||||
|
||||
@@ -313,6 +313,23 @@
|
||||
#define TRIGGER_GUARD_NONE 0
|
||||
#define TRIGGER_GUARD_NORMAL 1
|
||||
|
||||
// These comments mirror the below define in the order of operations to help you understand what it is doing
|
||||
// Check if datum I is a mob
|
||||
// If I is a mob, return the client of mob I
|
||||
// Else, check to see if I is a client
|
||||
// If I is a client, return I
|
||||
// Else, check to see if I is a mind
|
||||
// If I is a mind, try and return the mind's current mob's client
|
||||
|
||||
/// Return a Client
|
||||
#define CLIENT_FROM_VAR(I) (ismob(I) \
|
||||
? I:client \
|
||||
: istype(I, /client) \
|
||||
? I \
|
||||
: istype(I, /datum/mind \
|
||||
? I:current?:client \
|
||||
: null))
|
||||
|
||||
// Macro to get the current elapsed round time, rather than total world runtime
|
||||
#define ROUND_TIME (SSticker.time_game_started ? (world.time - SSticker.time_game_started) : 0)
|
||||
|
||||
|
||||
@@ -3,12 +3,6 @@
|
||||
#define UNCONSCIOUS 1
|
||||
#define DEAD 2
|
||||
|
||||
// TGUI flags
|
||||
#define STATUS_INTERACTIVE 2 // GREEN Visability
|
||||
#define STATUS_UPDATE 1 // ORANGE Visability
|
||||
#define STATUS_DISABLED 0 // RED Visability
|
||||
#define STATUS_CLOSE -1 // Close the interface
|
||||
|
||||
/*
|
||||
Shuttles
|
||||
*/
|
||||
|
||||
@@ -84,10 +84,12 @@
|
||||
#define INIT_ORDER_LATE_MAPPING -40
|
||||
#define INIT_ORDER_PATH -50
|
||||
#define INIT_ORDER_PERSISTENCE -95
|
||||
#define INIT_ORDER_CHAT -100 // Should be last to ensure chat remains smooth during init.
|
||||
|
||||
// Subsystem fire priority, from lowest to highest priority
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
|
||||
#define FIRE_PRIORITY_PING 10
|
||||
#define FIRE_PRIORITY_NANOMOB 10
|
||||
#define FIRE_PRIORITY_NIGHTSHIFT 10
|
||||
#define FIRE_PRIORITY_IDLE_NPC 10
|
||||
@@ -112,6 +114,7 @@
|
||||
#define FIRE_PRIORITY_MOBS 100
|
||||
#define FIRE_PRIORITY_TGUI 110
|
||||
#define FIRE_PRIORITY_TICKER 200
|
||||
#define FIRE_PRIORITY_CHAT 400
|
||||
#define FIRE_PRIORITY_RUNECHAT 410 // I hate how high the fire priority on this is -aa
|
||||
#define FIRE_PRIORITY_OVERLAYS 500
|
||||
#define FIRE_PRIORITY_DELAYED_VERBS 950
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// TGUI defines
|
||||
// TGUI Modal defines
|
||||
#define UI_MODAL_INPUT_MAX_LENGTH 1024
|
||||
#define UI_MODAL_INPUT_MAX_LENGTH_NAME 64 // Names for generally anything don't go past 32, let alone 64.
|
||||
|
||||
@@ -6,3 +6,41 @@
|
||||
#define UI_MODAL_DELEGATE 2
|
||||
#define UI_MODAL_ANSWER 3
|
||||
#define UI_MODAL_CLOSE 4
|
||||
|
||||
/// Green eye; fully interactive
|
||||
#define UI_INTERACTIVE 2
|
||||
/// Orange eye; updates but is not interactive
|
||||
#define UI_UPDATE 1
|
||||
/// Red eye; disabled, does not update
|
||||
#define UI_DISABLED 0
|
||||
/// UI Should close
|
||||
#define UI_CLOSE -1
|
||||
|
||||
/// Maximum number of windows that can be suspended/reused
|
||||
#define TGUI_WINDOW_SOFT_LIMIT 5
|
||||
/// Maximum number of open windows
|
||||
#define TGUI_WINDOW_HARD_LIMIT 9
|
||||
|
||||
/// Maximum ping timeout allowed to detect zombie windows
|
||||
#define TGUI_PING_TIMEOUT (4 SECONDS)
|
||||
/// Used for rate-limiting to prevent DoS by excessively refreshing a TGUI window
|
||||
#define TGUI_REFRESH_FULL_UPDATE_COOLDOWN (1 SECONDS)
|
||||
|
||||
/// Window does not exist
|
||||
#define TGUI_WINDOW_CLOSED 0
|
||||
/// Window was just opened, but is still not ready to be sent data
|
||||
#define TGUI_WINDOW_LOADING 1
|
||||
/// Window is free and ready to receive data
|
||||
#define TGUI_WINDOW_READY 2
|
||||
|
||||
/// Get a window id based on the provided pool index
|
||||
#define TGUI_WINDOW_ID(index) "tgui-window-[index]"
|
||||
/// Get a pool index of the provided window id
|
||||
#define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13))
|
||||
|
||||
/// Creates a message packet for sending via output()
|
||||
#define TGUI_CREATE_MESSAGE(type, payload) ( \
|
||||
url_encode(json_encode(list( \
|
||||
"type" = type, \
|
||||
"payload" = payload, \
|
||||
))))
|
||||
|
||||
@@ -40,7 +40,10 @@ GLOBAL_PROTECT(log_end)
|
||||
|
||||
for(var/client/C in GLOB.admins)
|
||||
if(check_rights(R_DEBUG | R_VIEWRUNTIMES, FALSE, C.mob) && (C.prefs.toggles & PREFTOGGLE_CHAT_DEBUGLOGS))
|
||||
to_chat(C, "<span class='debug'>DEBUG: [text]</span>")
|
||||
to_chat(C,
|
||||
type = MESSAGE_TYPE_DEBUG,
|
||||
html = "<span class='debug'>DEBUG: [text]</span>",
|
||||
confidential = TRUE)
|
||||
|
||||
/proc/log_game(text)
|
||||
if(GLOB.configuration.logging.game_logging)
|
||||
@@ -149,8 +152,19 @@ GLOBAL_PROTECT(log_end)
|
||||
/proc/log_runtime_summary(text)
|
||||
rustg_log_write(GLOB.runtime_summary_log, "[text][GLOB.log_end]")
|
||||
|
||||
/proc/log_tgui(text)
|
||||
rustg_log_write(GLOB.tgui_log, "[text][GLOB.log_end]")
|
||||
/proc/log_tgui(user_or_client, text)
|
||||
var/list/messages = list()
|
||||
if(!user_or_client)
|
||||
messages.Add("no user")
|
||||
else if(ismob(user_or_client))
|
||||
var/mob/user = user_or_client
|
||||
messages.Add("[user.ckey] (as [user])")
|
||||
else if(isclient(user_or_client))
|
||||
var/client/client = user_or_client
|
||||
messages.Add("[client.ckey]")
|
||||
messages.Add(": [text]")
|
||||
messages.Add("[GLOB.log_end]")
|
||||
rustg_log_write(GLOB.tgui_log, messages.Join())
|
||||
|
||||
#ifdef REFERENCE_TRACKING
|
||||
/proc/log_gc(text)
|
||||
|
||||
@@ -33,11 +33,6 @@
|
||||
|
||||
return text
|
||||
|
||||
//Sends resource files to client cache
|
||||
/client/proc/getFiles()
|
||||
for(var/file in args)
|
||||
src << browse_rsc(file)
|
||||
|
||||
/client/proc/browse_files(root="data/logs/", max_iterations=10, list/valid_extensions=list("txt", "log", "htm", "json"))
|
||||
// wow why was this ever a parameter
|
||||
root = "data/logs/"
|
||||
|
||||
@@ -299,3 +299,44 @@ world
|
||||
M.Blend("#ffffff", ICON_SUBTRACT)
|
||||
// apply mask
|
||||
Blend(M, ICON_ADD)
|
||||
|
||||
// Converts an icon to base64. Operates by putting the icon in the iconCache savefile,
|
||||
// exporting it as text, and then parsing the base64 from that.
|
||||
// (This relies on byond automatically storing icons in savefiles as base64)
|
||||
GLOBAL_DATUM_INIT(iconCache, /savefile, new /savefile("data/iconCache.sav"))
|
||||
|
||||
GLOBAL_LIST_EMPTY(bicon_cache)
|
||||
|
||||
/proc/icon2base64(icon/icon, iconKey = "misc")
|
||||
if(!isicon(icon)) return 0
|
||||
|
||||
GLOB.iconCache[iconKey] << icon
|
||||
var/iconData = GLOB.iconCache.ExportText(iconKey)
|
||||
var/list/partial = splittext(iconData, "{")
|
||||
return replacetext(copytext(partial[2], 3, -5), "\n", "")
|
||||
|
||||
/proc/bicon(obj, use_class = 1)
|
||||
var/class = use_class ? "class='icon misc'" : null
|
||||
if(!obj)
|
||||
return
|
||||
|
||||
if(isicon(obj))
|
||||
if(!GLOB.bicon_cache["\ref[obj]"]) // Doesn't exist yet, make it.
|
||||
GLOB.bicon_cache["\ref[obj]"] = icon2base64(obj)
|
||||
|
||||
return "<img [class] src='data:image/png;base64,[GLOB.bicon_cache["\ref[obj]"]]'>"
|
||||
|
||||
// Either an atom or somebody fucked up and is gonna get a runtime, which I'm fine with.
|
||||
var/atom/A = obj
|
||||
var/key = "[istype(A.icon, /icon) ? "\ref[A.icon]" : A.icon]:[A.icon_state]"
|
||||
if(!GLOB.bicon_cache[key]) // Doesn't exist, make it.
|
||||
var/icon/I = icon(A.icon, A.icon_state, SOUTH, 1)
|
||||
if(ishuman(obj)) // Shitty workaround for a BYOND issue.
|
||||
var/icon/temp = I
|
||||
I = icon()
|
||||
I.Insert(temp, dir = SOUTH)
|
||||
GLOB.bicon_cache[key] = icon2base64(I, key)
|
||||
if(use_class)
|
||||
class = "class='icon [A.icon_state]'"
|
||||
|
||||
return "<img [class] src='data:image/png;base64,[GLOB.bicon_cache[key]]'>"
|
||||
|
||||
@@ -410,13 +410,6 @@
|
||||
var/middle = L.len / 2 + 1 // Copy is first,second-1
|
||||
return mergeLists(sortList(L.Copy(0,middle)), sortList(L.Copy(middle))) //second parameter null = to end of list
|
||||
|
||||
//Mergsorge: uses sortAssoc() but uses the var's name specifically. This should probably be using mergeAtom() instead
|
||||
/proc/sortNames(list/L)
|
||||
var/list/Q = new()
|
||||
for(var/atom/x in L)
|
||||
Q[x.name] = x
|
||||
return sortAssoc(Q)
|
||||
|
||||
/proc/mergeLists(list/L, list/R)
|
||||
var/Li=1
|
||||
var/Ri=1
|
||||
|
||||
+24
-103
@@ -108,6 +108,10 @@ GLOBAL_VAR(syndicate_name)
|
||||
GLOBAL_VAR(syndicate_code_phrase) //Code phrase for traitors.
|
||||
GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
|
||||
|
||||
//Cached regex search - for checking if codewords are used.
|
||||
GLOBAL_DATUM(syndicate_code_phrase_regex, /regex)
|
||||
GLOBAL_DATUM(syndicate_code_response_regex, /regex)
|
||||
|
||||
/*
|
||||
Should be expanded.
|
||||
How this works:
|
||||
@@ -122,9 +126,12 @@ GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
|
||||
/N
|
||||
*/
|
||||
|
||||
/proc/generate_code_phrase()//Proc is used for phrase and response in master_controller.dm
|
||||
/proc/generate_code_phrase(return_list = FALSE) // Proc is used for phrase and response in master_controller.dm
|
||||
|
||||
var/code_phrase = ""//What is returned when the proc finishes.
|
||||
if(!return_list)
|
||||
. = ""
|
||||
else
|
||||
. = list()
|
||||
var/words = pick(//How many words there will be. Minimum of two. 2, 4 and 5 have a lesser chance of being selected. 3 is the most likely.
|
||||
50; 2,
|
||||
200; 3,
|
||||
@@ -152,34 +159,34 @@ GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
|
||||
|
||||
switch(pick(safety))//Chance based on the safety list.
|
||||
if(1)//1 and 2 can only be selected once each to prevent more than two specific names/places/etc.
|
||||
switch(rand(1,2))//Mainly to add more options later.
|
||||
switch(rand(1, 2)) // Mainly to add more options later.
|
||||
if(1)
|
||||
if(names.len)
|
||||
code_phrase += pick(names)
|
||||
if(length(names))
|
||||
. += pick(names)
|
||||
if(2)
|
||||
code_phrase += pick(GLOB.joblist)//Returns a job.
|
||||
. += pick(GLOB.joblist)//Returns a job.
|
||||
safety -= 1
|
||||
if(2)
|
||||
switch(rand(1,2))//Places or things.
|
||||
if(1)
|
||||
code_phrase += pick(drinks)
|
||||
. += pick(drinks)
|
||||
if(2)
|
||||
code_phrase += pick(locations)
|
||||
. += pick(locations)
|
||||
safety -= 2
|
||||
if(3)
|
||||
switch(rand(1,3))//Nouns, adjectives, verbs. Can be selected more than once.
|
||||
switch(rand(1, 3)) // Nouns, adjectives, verbs. Can be selected more than once.
|
||||
if(1)
|
||||
code_phrase += pick(nouns)
|
||||
. += pick(nouns)
|
||||
if(2)
|
||||
code_phrase += pick(GLOB.adjectives)
|
||||
. += pick(GLOB.adjectives)
|
||||
if(3)
|
||||
code_phrase += pick(GLOB.verbs)
|
||||
if(words==1)
|
||||
code_phrase += "."
|
||||
else
|
||||
code_phrase += ", "
|
||||
. += pick(GLOB.verbs)
|
||||
|
||||
return code_phrase
|
||||
if(!return_list)
|
||||
if(words == 1)
|
||||
. += "."
|
||||
else
|
||||
. += ", "
|
||||
|
||||
/proc/GenerateKey()
|
||||
var/newKey
|
||||
@@ -187,89 +194,3 @@ GLOBAL_VAR(syndicate_code_response) //Code response for traitors.
|
||||
newKey += pick("diamond", "beer", "mushroom", "assistant", "clown", "captain", "twinkie", "security", "nuke", "small", "big", "escape", "yellow", "gloves", "monkey", "engine", "nuclear", "ai")
|
||||
newKey += pick("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")
|
||||
return newKey
|
||||
|
||||
/*
|
||||
//This proc tests the gen above.
|
||||
/client/verb/test_code_phrase()
|
||||
set name = "Generate Code Phrase"
|
||||
set category = "Debug"
|
||||
|
||||
to_chat(world, "<span class='warning'>Code Phrase is:</span> [generate_code_phrase()]")
|
||||
return
|
||||
|
||||
|
||||
This was an earlier attempt at code phrase system, aside from an even earlier attempt (and failure).
|
||||
This system more or less works as intended--aside from being unfinished--but it's still very predictable.
|
||||
Particularly, the phrase opening statements are pretty easy to recognize and identify when metagaming.
|
||||
I think the above-used method solves this issue by using words in a sequence, providing for much greater flexibility.
|
||||
/N
|
||||
|
||||
switch(choice)
|
||||
if(1)
|
||||
syndicate_code_phrase += pick("I'm looking for","Have you seen","Maybe you've seen","I'm trying to find","I'm tracking")
|
||||
syndicate_code_phrase += " "
|
||||
syndicate_code_phrase += pick(pick(GLOB.first_names_male,GLOB.first_names_female))
|
||||
syndicate_code_phrase += " "
|
||||
syndicate_code_phrase += pick(GLOB.last_names)
|
||||
syndicate_code_phrase += "."
|
||||
if(2)
|
||||
syndicate_code_phrase += pick("How do I get to","How do I find","Where is","Where do I find")
|
||||
syndicate_code_phrase += " "
|
||||
syndicate_code_phrase += pick("Escape","Engineering","Atmos","the bridge","the brig","CentComm","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict")
|
||||
syndicate_code_phrase += "?"
|
||||
if(3)
|
||||
if(prob(70))
|
||||
syndicate_code_phrase += pick("Get me","I want","I'd like","Make me")
|
||||
syndicate_code_phrase += " a "
|
||||
else
|
||||
syndicate_code_phrase += pick("One")
|
||||
syndicate_code_phrase += " "
|
||||
syndicate_code_phrase += pick("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequila sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine")
|
||||
syndicate_code_phrase += "."
|
||||
if(4)
|
||||
syndicate_code_phrase += pick("I wish I was","My dad was","His mom was","Where do I find","The hero this station needs is","I'd fuck","I wouldn't trust","Someone caught","HoS caught","Someone found","I'd wrestle","I wanna kill")
|
||||
syndicate_code_phrase += " [pick("a","the")] "
|
||||
syndicate_code_phrase += pick("wizard","ninja","xeno","lizard","slime","monkey","syndicate","cyborg","clown","space carp","singularity","singulo","mime")
|
||||
syndicate_code_phrase += "."
|
||||
if(5)
|
||||
syndicate_code_phrase += pick("Do we have","Is there","Where is","Where's","Who's")
|
||||
syndicate_code_phrase += " "
|
||||
syndicate_code_phrase += "[pick(GLOB.joblist)]"
|
||||
syndicate_code_phrase += "?"
|
||||
|
||||
switch(choice)
|
||||
if(1)
|
||||
if(prob(80))
|
||||
syndicate_code_response += pick("Try looking for them near","I they ran off to","Yes. I saw them near","Nope. I'm heading to","Try searching")
|
||||
syndicate_code_response += " "
|
||||
syndicate_code_response += pick("Escape","Engineering","Atmos","the bridge","the brig","CentComm","the library","the chapel","a bathroom","Med Bay","Tool Storage","the escape shuttle","Robotics","a locker room","the living quarters","the gym","the autolathe","QM","the bar","the theater","the derelict")
|
||||
syndicate_code_response += "."
|
||||
else if(prob(60))
|
||||
syndicate_code_response += pick("No. I'm busy, sorry.","I don't have the time.","Not sure, maybe?","There is no time.")
|
||||
else
|
||||
syndicate_code_response += pick("*shrug*","*smile*","*blink*","*sigh*","*laugh*","*nod*","*giggle*")
|
||||
if(2)
|
||||
if(prob(80))
|
||||
syndicate_code_response += pick("Go to","Navigate to","Try","Sure, run to","Try searching","It's near","It's around")
|
||||
syndicate_code_response += " the "
|
||||
syndicate_code_response += pick("[pick("south","north","east","west")] maitenance door","nearby maitenance","teleporter","[pick("cold","dead")] space","morgue","vacuum","[pick("south","north","east","west")] hall ","[pick("south","north","east","west")] hallway","[pick("white","black","red","green","blue","pink","purple")] [pick("rabbit","frog","lion","tiger","panther","snake","facehugger")]")
|
||||
syndicate_code_response += "."
|
||||
else if(prob(60))
|
||||
syndicate_code_response += pick("Try asking","Ask","Talk to","Go see","Follow","Hunt down")
|
||||
syndicate_code_response += " "
|
||||
if(prob(50))
|
||||
syndicate_code_response += pick(pick(GLOB.first_names_male,GLOB.first_names_female))
|
||||
syndicate_code_response += " "
|
||||
syndicate_code_response += pick(GLOB.last_names)
|
||||
else
|
||||
syndicate_code_response += " the "
|
||||
syndicate_code_response += "[pic(GLOB.joblist)]"
|
||||
syndicate_code_response += "."
|
||||
else
|
||||
syndicate_code_response += pick("*shrug*","*smile*","*blink*","*sigh*","*laugh*","*nod*","*giggle*")
|
||||
if(3)
|
||||
if(4)
|
||||
if(5)
|
||||
|
||||
return
|
||||
*/
|
||||
|
||||
@@ -46,6 +46,8 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
var/datum/configuration_section/url_configuration/url
|
||||
/// Holder for the voting configuration datum
|
||||
var/datum/configuration_section/vote_configuration/vote
|
||||
/// Holder for the asset cache configuration datum
|
||||
var/datum/configuration_section/asset_cache_configuration/asset_cache
|
||||
/// Raw data. Stored here to avoid passing data between procs constantly
|
||||
var/list/raw_data = list()
|
||||
|
||||
@@ -92,6 +94,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
system = new()
|
||||
url = new()
|
||||
vote = new()
|
||||
asset_cache = new()
|
||||
|
||||
// Load our stuff up
|
||||
var/config_file = "config/config.toml"
|
||||
@@ -129,6 +132,7 @@ GLOBAL_DATUM_INIT(configuration, /datum/server_configuration, new())
|
||||
safe_load(system, "system_configuration")
|
||||
safe_load(url, "url_configuration")
|
||||
safe_load(vote, "voting_configuration")
|
||||
safe_load(asset_cache, "asset_cache_configuration")
|
||||
|
||||
// Proc to load up instance-specific overrides
|
||||
/datum/server_configuration/proc/load_overrides()
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/datum/configuration_section/asset_cache_configuration
|
||||
/// Type of asset transport that will be used for asset delivery.
|
||||
/// Available options are "simple" or "webroot".
|
||||
var/asset_transport = "simple"
|
||||
/// Whether to make server passively send all browser assets to each client in the background
|
||||
/// (instead of waiting for them to be needed)
|
||||
var/asset_simple_preload = TRUE
|
||||
/// Local folder to save assets to.
|
||||
/// Assets will be saved in the format of asset.MD5HASH.EXT or in namespaces/hash/
|
||||
/// as ASSET_FILE_NAME or asset.MD5HASH.EXT
|
||||
var/asset_cdn_webroot = "data/asset-store/"
|
||||
/// URL the `asset_cdn_webroot` can be accessed from.
|
||||
/// For best results the webserver powering this should return a long cache validity time,
|
||||
/// as all assets sent via this transport use hash based urls
|
||||
/// if you want to test this locally, you simpily run the `localhost-asset-webroot-server.py` python3 script
|
||||
/// to host assets stored in `data/asset-store/` via http://localhost:58715/
|
||||
var/asset_cdn_url = "http://localhost:58715/"
|
||||
|
||||
/datum/configuration_section/asset_cache_configuration/load_data(list/data)
|
||||
CONFIG_LOAD_STR(asset_transport, data["asset_transport"])
|
||||
CONFIG_LOAD_BOOL(asset_simple_preload, data["asset_simple_preload"])
|
||||
CONFIG_LOAD_STR(asset_cdn_webroot, data["asset_cdn_webroot"])
|
||||
CONFIG_LOAD_STR(asset_cdn_url, data["asset_cdn_url"])
|
||||
@@ -23,5 +23,8 @@
|
||||
*/
|
||||
/datum/controller/proc/log_startup_progress(message)
|
||||
Master.last_init_info = "([name]): [message]"
|
||||
to_chat(world, "<span class='danger'><small>\[[name]]</small> [message]</span>")
|
||||
to_chat(world,
|
||||
type = MESSAGE_TYPE_DEBUG,
|
||||
html = "<span class='danger'><small>\[[name]]</small> [message]</span>",
|
||||
confidential = TRUE)
|
||||
log_world("\[[name]] [message]")
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Aleksej Komarov
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
SUBSYSTEM_DEF(chat)
|
||||
name = "Chat"
|
||||
flags = SS_TICKER|SS_NO_INIT
|
||||
wait = 1
|
||||
priority = FIRE_PRIORITY_CHAT
|
||||
init_order = INIT_ORDER_CHAT
|
||||
offline_implications = "Chat will no longer function correctly. Immediate server restart recommended."
|
||||
|
||||
/// Associates a ckey with a list of messages to send to them.
|
||||
var/list/list/datum/chat_payload/client_to_payloads = list()
|
||||
|
||||
/// Associates a ckey with an associative list of their last CHAT_RELIABILITY_HISTORY_SIZE messages.
|
||||
var/list/list/datum/chat_payload/client_to_reliability_history = list()
|
||||
|
||||
/// Associates a ckey with their next sequence number.
|
||||
var/list/client_to_sequence_number = list()
|
||||
|
||||
/datum/controller/subsystem/chat/proc/generate_payload(client/target, message_data)
|
||||
var/sequence = client_to_sequence_number[target.ckey]
|
||||
client_to_sequence_number[target.ckey] += 1
|
||||
|
||||
var/datum/chat_payload/payload = new
|
||||
payload.sequence = sequence
|
||||
payload.content = message_data
|
||||
|
||||
if(!(target.ckey in client_to_reliability_history))
|
||||
client_to_reliability_history[target.ckey] = list()
|
||||
var/list/client_history = client_to_reliability_history[target.ckey]
|
||||
client_history["[sequence]"] = payload
|
||||
|
||||
if(length(client_history) > CHAT_RELIABILITY_HISTORY_SIZE)
|
||||
var/oldest = text2num(client_history[1])
|
||||
for(var/index in 2 to length(client_history))
|
||||
var/test = text2num(client_history[index])
|
||||
if(test < oldest)
|
||||
oldest = test
|
||||
client_history -= "[oldest]"
|
||||
return payload
|
||||
|
||||
/datum/controller/subsystem/chat/proc/send_payload_to_client(client/target, datum/chat_payload/payload)
|
||||
target.tgui_panel.window.send_message("chat/message", payload.into_message())
|
||||
SEND_TEXT(target, payload.get_content_as_html())
|
||||
|
||||
/datum/controller/subsystem/chat/fire()
|
||||
for(var/ckey in client_to_payloads)
|
||||
var/client/target = GLOB.directory[ckey]
|
||||
if(isnull(target)) // verify client still exists
|
||||
LAZYREMOVE(client_to_payloads, ckey)
|
||||
continue
|
||||
|
||||
for(var/datum/chat_payload/payload as anything in client_to_payloads[ckey])
|
||||
send_payload_to_client(target, payload)
|
||||
LAZYREMOVE(client_to_payloads, ckey)
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/chat/proc/queue(queue_target, list/message_data)
|
||||
var/list/targets = islist(queue_target) ? queue_target : list(queue_target)
|
||||
for(var/target in targets)
|
||||
var/client/client = CLIENT_FROM_VAR(target)
|
||||
if(isnull(client))
|
||||
continue
|
||||
LAZYADDASSOC(client_to_payloads, client.ckey, generate_payload(client, message_data))
|
||||
|
||||
/datum/controller/subsystem/chat/proc/send_immediate(send_target, list/message_data)
|
||||
var/list/targets = islist(send_target) ? send_target : list(send_target)
|
||||
for(var/target in targets)
|
||||
var/client/client = CLIENT_FROM_VAR(target)
|
||||
if(isnull(client))
|
||||
continue
|
||||
send_payload_to_client(client, generate_payload(client, message_data))
|
||||
|
||||
/datum/controller/subsystem/chat/proc/handle_resend(client/client, sequence)
|
||||
var/list/client_history = client_to_reliability_history[client.ckey]
|
||||
sequence = "[sequence]"
|
||||
if(isnull(client_history) || !(sequence in client_history))
|
||||
return
|
||||
|
||||
var/datum/chat_payload/payload = client_history[sequence]
|
||||
if(payload.resends > CHAT_RELIABILITY_MAX_RESENDS)
|
||||
return // we tried but byond said no
|
||||
|
||||
payload.resends += 1
|
||||
send_payload_to_client(client, client_history[sequence])
|
||||
SSblackbox.record_feedback(
|
||||
"nested tally",
|
||||
"chat_resend_byond_version",
|
||||
1,
|
||||
list(
|
||||
"[client.byond_version]",
|
||||
"[client.byond_build]",
|
||||
),
|
||||
)
|
||||
@@ -1,17 +0,0 @@
|
||||
SUBSYSTEM_DEF(chat_pings)
|
||||
name = "Chat Pings"
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_INIT | RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME // ALL OF THEM
|
||||
wait = 30 SECONDS // Chat pings every 30 seconds
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
/// List of all held chat datums
|
||||
var/list/datum/chatOutput/chat_datums = list() // Do NOT put this in Initialize(). You will cause issues.
|
||||
|
||||
/datum/controller/subsystem/chat_pings/fire(resumed)
|
||||
for(var/datum/chatOutput/CO as anything in chat_datums)
|
||||
CO.updatePing()
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/chat_pings/get_stat_details()
|
||||
return "P: [length(chat_datums)]"
|
||||
@@ -386,7 +386,10 @@ SUBSYSTEM_DEF(dbcore)
|
||||
if(!.)
|
||||
SSdbcore.total_errors++
|
||||
if(usr)
|
||||
to_chat(usr, "<span class='danger'>A SQL error occurred during this operation, please inform an admin or a coder.</span>")
|
||||
to_chat(usr,
|
||||
type = MESSAGE_TYPE_ADMINLOG,
|
||||
html = "<span class='danger'>A SQL error occurred during this operation, please inform an admin or a coder.</span>",
|
||||
confidential = TRUE)
|
||||
message_admins("An SQL error has occurred. Please check the server logs, with the following timestamp ID: \[[time_stamp()]]")
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,7 +31,7 @@ SUBSYSTEM_DEF(debugview)
|
||||
entries += "\[Processing] Cost: [round(SSprocessing.cost, 1)]ms | P: [length(SSprocessing.processing)]"
|
||||
entries += "\[Projectiles] Cost: [round(SSprojectiles.cost, 1)]ms | P: [length(SSprojectiles.processing)]"
|
||||
entries += "\[Runechat] Cost: [round(SSrunechat.cost, 1)]ms | AM: [SSrunechat.bucket_count] | SQ: [length(SSrunechat.second_queue)]"
|
||||
entries += "\[TGUI] Cost: [round(SStgui.cost, 1)]ms | P: [length(SStgui.processing_uis)]"
|
||||
entries += "\[TGUI] Cost: [round(SStgui.cost, 1)]ms | P: [length(SStgui.open_uis)]]"
|
||||
entries += "\[Timer] Cost: [round(SStimer.cost, 1)]ms | B: [SStimer.bucket_count] | P: [length(SStimer.second_queue)] | RST: [SStimer.bucket_reset_count]"
|
||||
|
||||
// Do some parsing to format it properly
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* Copyright (c) 2022 Aleksej Komarov
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
SUBSYSTEM_DEF(ping)
|
||||
name = "Ping"
|
||||
priority = FIRE_PRIORITY_PING
|
||||
wait = 4 SECONDS
|
||||
flags = SS_NO_INIT
|
||||
runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||
offline_implications = "Chat ping system will no longer function correctly. No immediate action is needed."
|
||||
|
||||
/// List used each time SS fires to track which clients have been processed so far
|
||||
var/list/current_run = list()
|
||||
|
||||
/datum/controller/subsystem/ping/stat_entry()
|
||||
..("P:[length(GLOB.clients)]")
|
||||
|
||||
/datum/controller/subsystem/ping/fire(resumed = FALSE)
|
||||
// Prepare the new batch of clients
|
||||
if(!resumed)
|
||||
src.current_run = GLOB.clients.Copy()
|
||||
|
||||
// De-reference the list for sanic speeds
|
||||
var/list/current_run = src.current_run
|
||||
|
||||
while(length(current_run))
|
||||
var/client/client = current_run[current_run.len]
|
||||
current_run.len--
|
||||
|
||||
if(client?.tgui_panel?.is_ready())
|
||||
// Send a soft ping
|
||||
client.tgui_panel.window.send_message("ping/soft", list(
|
||||
// Slightly less than the subsystem timer (somewhat arbitrary)
|
||||
// to prevent incoming pings from resetting the afk state
|
||||
"afk" = client.is_afk(3.5 SECONDS),
|
||||
))
|
||||
|
||||
if(MC_TICK_CHECK)
|
||||
return
|
||||
@@ -1,311 +1,357 @@
|
||||
/**
|
||||
* tgui subsystem
|
||||
*
|
||||
* Contains all tgui state and subsystem code.
|
||||
**/
|
||||
|
||||
/**
|
||||
* tgui subsystem
|
||||
*
|
||||
* Contains all tgui state and subsystem code.
|
||||
*
|
||||
* Copyright (c) 2020 Aleksej Komarov
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
SUBSYSTEM_DEF(tgui)
|
||||
name = "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.
|
||||
/// A list of UIs scheduled to process
|
||||
var/list/current_run = list()
|
||||
/// A list of open UIs
|
||||
var/list/open_uis = list()
|
||||
/// A list of open UIs, grouped by src_object.
|
||||
var/list/open_uis_by_src = list()
|
||||
/// The HTML base used for all UIs.
|
||||
var/basehtml
|
||||
|
||||
/datum/controller/subsystem/tgui/PreInit()
|
||||
basehtml = file2text('tgui/packages/tgui/public/tgui.html')
|
||||
basehtml = file2text('tgui/public/tgui.html')
|
||||
// Inject inline polyfills
|
||||
var/polyfill = file2text('tgui/public/tgui-polyfill.min.js')
|
||||
polyfill = "<script>\n[polyfill]\n</script>"
|
||||
basehtml = replacetextEx(basehtml, "<!-- tgui:inline-polyfill -->", polyfill)
|
||||
|
||||
/datum/controller/subsystem/tgui/Shutdown()
|
||||
close_all_uis()
|
||||
|
||||
/datum/controller/subsystem/tgui/get_stat_details()
|
||||
return "P:[length(processing_uis)]"
|
||||
/datum/controller/subsystem/tgui/stat_entry(msg)
|
||||
msg = "P:[length(open_uis)]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/tgui/get_metrics()
|
||||
. = ..()
|
||||
var/list/cust = list()
|
||||
cust["processing"] = length(processing_uis)
|
||||
.["custom"] = cust
|
||||
|
||||
|
||||
/datum/controller/subsystem/tgui/fire(resumed = 0)
|
||||
/datum/controller/subsystem/tgui/fire(resumed = FALSE)
|
||||
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--
|
||||
src.current_run = open_uis.Copy()
|
||||
// Cache for sanic speed (lists are references anyways)
|
||||
var/list/current_run = src.current_run
|
||||
while(current_run.len)
|
||||
var/datum/tgui/ui = current_run[current_run.len]
|
||||
current_run.len--
|
||||
// TODO: Move user/src_object check to process()
|
||||
if(ui && ui.user && ui.src_object)
|
||||
ui.process()
|
||||
else
|
||||
processing_uis.Remove(ui)
|
||||
open_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.
|
||||
* Requests a usable tgui window from the pool.
|
||||
* Returns null if pool was exhausted.
|
||||
*
|
||||
* * 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)
|
||||
* required user mob
|
||||
* return datum/tgui
|
||||
*/
|
||||
/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.
|
||||
/datum/controller/subsystem/tgui/proc/request_pooled_window(mob/user)
|
||||
if(!user.client)
|
||||
return
|
||||
var/list/windows = user.client.tgui_windows
|
||||
var/window_id
|
||||
var/datum/tgui_window/window
|
||||
var/window_found = FALSE
|
||||
// Find a usable window
|
||||
for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT)
|
||||
window_id = TGUI_WINDOW_ID(i)
|
||||
window = windows[window_id]
|
||||
// As we are looping, create missing window datums
|
||||
if(!window)
|
||||
window = new(user.client, window_id, pooled = TRUE)
|
||||
// Skip windows with acquired locks
|
||||
if(window.locked)
|
||||
continue
|
||||
if(window.status == TGUI_WINDOW_READY)
|
||||
return window
|
||||
if(window.status == TGUI_WINDOW_CLOSED)
|
||||
window.status = TGUI_WINDOW_LOADING
|
||||
window_found = TRUE
|
||||
break
|
||||
if(!window_found)
|
||||
log_tgui(user, "Error: Pool exhausted")
|
||||
return
|
||||
return window
|
||||
|
||||
/**
|
||||
* private
|
||||
* public
|
||||
*
|
||||
* Get an open UI given a user, src_object, and ui_key.
|
||||
* Returns the found UI.
|
||||
* Force closes all tgui windows.
|
||||
*
|
||||
* * 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)
|
||||
* required user mob
|
||||
*/
|
||||
/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.
|
||||
/datum/controller/subsystem/tgui/proc/force_close_all_windows(mob/user)
|
||||
log_tgui(user, "force_close_all_windows")
|
||||
if(user.client)
|
||||
user.client.tgui_windows = list()
|
||||
for(var/i in 1 to TGUI_WINDOW_HARD_LIMIT)
|
||||
var/window_id = TGUI_WINDOW_ID(i)
|
||||
user << browse(null, "window=[window_id]")
|
||||
|
||||
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
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Force closes the tgui window by window_id.
|
||||
*
|
||||
* required user mob
|
||||
* required window_id string
|
||||
*/
|
||||
/datum/controller/subsystem/tgui/proc/force_close_window(mob/user, window_id)
|
||||
log_tgui(user, "force_close_window")
|
||||
// Close all tgui datums based on window_id.
|
||||
for(var/datum/tgui/ui in user.tgui_open_uis)
|
||||
if(ui.window && ui.window.id == window_id)
|
||||
ui.close(can_be_suspended = FALSE)
|
||||
// Unset machine just to be sure.
|
||||
user.unset_machine()
|
||||
// Close window directly just to be sure.
|
||||
user << browse(null, "window=[window_id]")
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Try to find an instance of a UI, and push an update to it.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object datum The object/datum which owns 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, datum/tgui/ui, force_open = FALSE)
|
||||
// Look up a UI if it wasn't passed
|
||||
if(isnull(ui))
|
||||
ui = get_open_ui(user, src_object)
|
||||
// Couldn't find a UI.
|
||||
if(isnull(ui))
|
||||
return
|
||||
var/data = src_object.ui_data(user) // Get data from the src_object.
|
||||
if(force_open) // UI is already open; update it.
|
||||
ui.send_full_update(data, TRUE)
|
||||
return ui // We found the UI, return it
|
||||
ui.process_status()
|
||||
// UI ended up with the closed status
|
||||
// or is actively trying to close itself.
|
||||
// FIXME: Doesn't actually fix the paper bug.
|
||||
if(ui.status <= UI_CLOSE)
|
||||
ui.close()
|
||||
return
|
||||
ui.send_update()
|
||||
return ui
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Get a open UI given a user and src_object.
|
||||
*
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* required src_object datum The object/datum which owns the UI.
|
||||
*
|
||||
* return datum/tgui The found UI.
|
||||
*/
|
||||
/datum/controller/subsystem/tgui/proc/get_open_ui(mob/user, datum/src_object)
|
||||
var/key = "[src_object.UID()]"
|
||||
// No UIs opened for this src_object
|
||||
if(isnull(open_uis_by_src[key]) || !islist(open_uis_by_src[key]))
|
||||
return
|
||||
for(var/datum/tgui/ui in open_uis_by_src[key])
|
||||
// Make sure we have the right user
|
||||
if(ui.user == user)
|
||||
return ui
|
||||
|
||||
return null // Couldn't find a UI!
|
||||
return
|
||||
|
||||
/**
|
||||
* private
|
||||
* public
|
||||
*
|
||||
* 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.
|
||||
* 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, 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
|
||||
/datum/controller/subsystem/tgui/proc/update_uis(datum/src_object)
|
||||
var/count = 0
|
||||
var/key = "[src_object.UID()]"
|
||||
// No UIs opened for this src_object
|
||||
if(isnull(open_uis_by_src[key]) || !islist(open_uis_by_src[key]))
|
||||
return count
|
||||
for(var/datum/tgui/ui in open_uis_by_src[key])
|
||||
// Check if UI is valid.
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user))
|
||||
ui.process(force = TRUE)
|
||||
count++
|
||||
return count
|
||||
|
||||
/**
|
||||
* private
|
||||
* public
|
||||
*
|
||||
* Close all UIs attached to src_object.
|
||||
* Returns the number of UIs closed.
|
||||
*
|
||||
* * datum/src_object - The object/datum which owns the UIs.
|
||||
* 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)
|
||||
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
|
||||
. = 0
|
||||
var/key = "[src_object.UID()]"
|
||||
// No UIs opened for this src_object
|
||||
if(isnull(open_uis_by_src[key]) || !islist(open_uis_by_src[key]))
|
||||
return
|
||||
for(var/datum/tgui/ui in open_uis_by_src[key])
|
||||
// Check if UI is valid.
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user))
|
||||
ui.close()
|
||||
.++
|
||||
return
|
||||
|
||||
/**
|
||||
* public
|
||||
*
|
||||
* Gets the amount of open UIs on an object
|
||||
* Returns the number of UIs open.
|
||||
* Close all UIs regardless of their attachment to src_object.
|
||||
*
|
||||
* * 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.
|
||||
* 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)
|
||||
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
|
||||
var/count = 0
|
||||
for(var/key in open_uis_by_src)
|
||||
for(var/datum/tgui/ui in open_uis_by_src[key])
|
||||
// Check if UI is valid.
|
||||
if(ui && ui.src_object && ui.user && ui.src_object.ui_host(ui.user))
|
||||
ui.close()
|
||||
count++
|
||||
return count
|
||||
|
||||
/**
|
||||
* private
|
||||
* public
|
||||
*
|
||||
* 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)
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object datum If provided, only update UIs belonging this src_object.
|
||||
*
|
||||
* 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) || !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
|
||||
/datum/controller/subsystem/tgui/proc/update_user_uis(mob/user, datum/src_object)
|
||||
var/count = 0
|
||||
if(length(user?.tgui_open_uis) == 0)
|
||||
return count
|
||||
for(var/datum/tgui/ui in user.tgui_open_uis)
|
||||
if(isnull(src_object) || ui.src_object == src_object)
|
||||
ui.process(force = TRUE)
|
||||
count++
|
||||
return count
|
||||
|
||||
/**
|
||||
* private
|
||||
* public
|
||||
*
|
||||
* 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)
|
||||
* required user mob The mob who opened/is using the UI.
|
||||
* optional src_object datum If provided, only close UIs belonging this src_object.
|
||||
*
|
||||
* 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) || !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
|
||||
/datum/controller/subsystem/tgui/proc/close_user_uis(mob/user, datum/src_object)
|
||||
var/count = 0
|
||||
if(length(user?.tgui_open_uis) == 0)
|
||||
return count
|
||||
for(var/datum/tgui/ui in user.tgui_open_uis)
|
||||
if(isnull(src_object) || ui.src_object == src_object)
|
||||
ui.close()
|
||||
count++
|
||||
return count
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Add a UI to the list of open UIs.
|
||||
*
|
||||
* * datum/tgui/ui - The UI to be added.
|
||||
* required ui datum/tgui 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]
|
||||
var/key = "[ui.src_object.UID()]"
|
||||
if(isnull(open_uis_by_src[key]) || !islist(open_uis_by_src[key]))
|
||||
open_uis_by_src[key] = list()
|
||||
ui.user.tgui_open_uis |= ui
|
||||
var/list/uis = open_uis_by_src[key]
|
||||
uis |= ui
|
||||
processing_uis |= ui
|
||||
open_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.
|
||||
* 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 = "[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.
|
||||
var/key = "[ui.src_object.UID()]"
|
||||
if(isnull(open_uis_by_src[key]) || !islist(open_uis_by_src[key]))
|
||||
return FALSE
|
||||
// Remove it from the list of processing UIs.
|
||||
open_uis.Remove(ui)
|
||||
// If the user exists, remove it from them too.
|
||||
if(ui.user)
|
||||
ui.user.tgui_open_uis.Remove(ui)
|
||||
var/list/uis = open_uis_by_src[key]
|
||||
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.
|
||||
if(length(uis) == 0)
|
||||
open_uis_by_src.Remove(key)
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* private
|
||||
*
|
||||
* Handle client logout, by closing all their UIs.
|
||||
* Returns the number of UIs closed.
|
||||
*
|
||||
* * mob/user - The mob which logged out.
|
||||
* 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)
|
||||
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.
|
||||
* 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) || !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.
|
||||
// The old mob had no open UIs.
|
||||
if(length(source?.tgui_open_uis) == 0)
|
||||
return FALSE
|
||||
if(isnull(target.tgui_open_uis) || !istype(target.tgui_open_uis, /list))
|
||||
target.tgui_open_uis = list()
|
||||
// Transfer all the UIs.
|
||||
for(var/datum/tgui/ui in source.tgui_open_uis)
|
||||
// Inform the UIs of their new owner.
|
||||
ui.user = target
|
||||
target.tgui_open_uis.Add(ui)
|
||||
// Clear the old list.
|
||||
source.tgui_open_uis.Cut()
|
||||
return TRUE
|
||||
|
||||
@@ -296,9 +296,25 @@ SUBSYSTEM_DEF(ticker)
|
||||
|
||||
// Generate code phrases and responses
|
||||
if(!GLOB.syndicate_code_phrase)
|
||||
GLOB.syndicate_code_phrase = generate_code_phrase()
|
||||
var/temp_syndicate_code_phrase = generate_code_phrase(return_list = TRUE)
|
||||
|
||||
var/codewords = jointext(temp_syndicate_code_phrase, "|")
|
||||
var/regex/codeword_match = new("([codewords])", "ig")
|
||||
|
||||
GLOB.syndicate_code_phrase_regex = codeword_match
|
||||
temp_syndicate_code_phrase = jointext(temp_syndicate_code_phrase, ", ")
|
||||
GLOB.syndicate_code_phrase = temp_syndicate_code_phrase
|
||||
|
||||
|
||||
if(!GLOB.syndicate_code_response)
|
||||
GLOB.syndicate_code_response = generate_code_phrase()
|
||||
var/temp_syndicate_code_response = generate_code_phrase(return_list = TRUE)
|
||||
|
||||
var/codewords = jointext(temp_syndicate_code_response, "|")
|
||||
var/regex/codeword_match = new("([codewords])", "ig")
|
||||
|
||||
GLOB.syndicate_code_response_regex = codeword_match
|
||||
temp_syndicate_code_response = jointext(temp_syndicate_code_response, ", ")
|
||||
GLOB.syndicate_code_response = temp_syndicate_code_response
|
||||
|
||||
// Run post setup stuff
|
||||
mode.post_setup()
|
||||
|
||||
@@ -2,15 +2,38 @@ SUBSYSTEM_DEF(assets)
|
||||
name = "Assets"
|
||||
init_order = INIT_ORDER_ASSETS
|
||||
flags = SS_NO_FIRE
|
||||
/// Contains /datum/asset_cache_item
|
||||
var/list/cache = list()
|
||||
var/list/preload = list()
|
||||
var/datum/asset_transport/transport = new()
|
||||
|
||||
/datum/controller/subsystem/assets/Initialize()
|
||||
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
|
||||
var/datum/asset/A = new type()
|
||||
A.register()
|
||||
/datum/controller/subsystem/assets/Initialize(timeofday)
|
||||
load_assets()
|
||||
apply_configuration()
|
||||
|
||||
preload = cache.Copy() //don't preload assets generated during the round
|
||||
/datum/controller/subsystem/assets/Recover()
|
||||
cache = SSassets.cache
|
||||
preload = SSassets.preload
|
||||
|
||||
for(var/client/C in GLOB.clients)
|
||||
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(getFilesSlow), C, preload, FALSE), 10)
|
||||
/datum/controller/subsystem/assets/proc/apply_configuration(initialize_transport = TRUE)
|
||||
var/newtransporttype = /datum/asset_transport
|
||||
switch(GLOB.configuration.asset_cache.asset_transport)
|
||||
if("webroot")
|
||||
newtransporttype = /datum/asset_transport/webroot
|
||||
|
||||
if(newtransporttype == transport.type)
|
||||
return
|
||||
|
||||
var/datum/asset_transport/newtransport = new newtransporttype
|
||||
if(newtransport.validate_config())
|
||||
transport = newtransport
|
||||
|
||||
if(initialize_transport)
|
||||
transport.Initialize(cache)
|
||||
|
||||
/datum/controller/subsystem/assets/proc/load_assets()
|
||||
for(var/datum/asset/asset_to_load as anything in typesof(/datum/asset))
|
||||
if(initial(asset_to_load._abstract))
|
||||
continue
|
||||
|
||||
get_asset_datum(type)
|
||||
|
||||
@@ -53,12 +53,6 @@ SUBSYSTEM_DEF(changelog)
|
||||
if(!ss_ready)
|
||||
return // Only return here, we dont have to worry about a queue list because this will be called from ShowChangelog()
|
||||
|
||||
if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE)
|
||||
winset(C, "rpane.changelog", "background-color=#40628a;font-color=#ffffff;font-style=none")
|
||||
else
|
||||
winset(C, "rpane.changelog", "background-color=none;font-style=none")
|
||||
|
||||
|
||||
C.prefs.lastchangelog = current_cl_timestamp
|
||||
|
||||
var/datum/db_query/updatePlayerCLTime = SSdbcore.NewQuery(
|
||||
@@ -76,22 +70,12 @@ SUBSYSTEM_DEF(changelog)
|
||||
/datum/controller/subsystem/changelog/proc/UpdatePlayerChangelogButton(client/C)
|
||||
// If SQL aint even enabled, or we aint ready just set the button to default style
|
||||
if(!SSdbcore.IsConnected() || !ss_ready)
|
||||
if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE)
|
||||
winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
|
||||
else
|
||||
winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
|
||||
return
|
||||
|
||||
// If we are ready, process the button style
|
||||
if(C.prefs.lastchangelog != current_cl_timestamp)
|
||||
winset(C, "rpane.changelog", "background-color=#bb7700;text-color=#FFFFFF;font-style=bold")
|
||||
winset(C, "rpane.changelog", "border=line;font-style=bold")
|
||||
to_chat(C, "<span class='boldnotice'>Changelog has changed since your last visit.</span>")
|
||||
else
|
||||
if(C.prefs.toggles & PREFTOGGLE_UI_DARKMODE)
|
||||
winset(C, "rpane.changelog", "background-color=#40628a;text-color=#FFFFFF")
|
||||
else
|
||||
winset(C, "rpane.changelog", "background-color=none;text-color=#000000")
|
||||
|
||||
|
||||
/datum/controller/subsystem/changelog/proc/OpenChangelog(client/C)
|
||||
// If SQL isnt enabled, dont even queue them, just tell them it wont work
|
||||
@@ -204,10 +188,13 @@ SUBSYSTEM_DEF(changelog)
|
||||
|
||||
return data
|
||||
|
||||
/datum/controller/subsystem/changelog/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)
|
||||
/datum/controller/subsystem/changelog/ui_state(mob/user)
|
||||
return GLOB.always_state
|
||||
|
||||
/datum/controller/subsystem/changelog/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ChangelogView", name, 750, 800, master_ui, state)
|
||||
ui = new(user, src, "ChangelogView", name)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
|
||||
+90
-104
@@ -1,24 +1,29 @@
|
||||
/datum/browser
|
||||
var/mob/user
|
||||
var/title
|
||||
var/window_id // window_id is used as the window name for browse and onclose
|
||||
/// window_id is used as the window name for browse and onclose calls
|
||||
var/window_id
|
||||
var/width = 0
|
||||
var/height = 0
|
||||
var/atom/ref = null
|
||||
var/window_options = "focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;" // window option is set using window_id
|
||||
/// UID of the host atom
|
||||
var/atom_uid = null
|
||||
/// Various options to control elements such as titlebar buttons for the window
|
||||
var/list/window_options = list("focus=0;can_close=1;can_minimize=1;can_maximize=0;can_resize=1;titlebar=1;") // window option is set using window_id
|
||||
/// Assoc list of stylesheets for use by the datum
|
||||
var/stylesheets[0]
|
||||
/// Assoc list of script files for use by the datum
|
||||
var/scripts[0]
|
||||
var/title_image
|
||||
var/head_elements
|
||||
var/body_elements
|
||||
var/head_content = ""
|
||||
var/content = ""
|
||||
var/title_buttons = ""
|
||||
/// Should default stylesheets be loaded
|
||||
var/include_default_stylesheet = TRUE
|
||||
/// Header HTML content of the browser datum
|
||||
var/list/head_content = list()
|
||||
/// HTML content of the browser datum
|
||||
var/list/content = list()
|
||||
|
||||
|
||||
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/nref = null)
|
||||
|
||||
/datum/browser/New(nuser, nwindow_id, ntitle = 0, nwidth = 0, nheight = 0, atom/atom = null)
|
||||
user = nuser
|
||||
RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(user_deleted))
|
||||
window_id = nwindow_id
|
||||
if(ntitle)
|
||||
title = format_text(ntitle)
|
||||
@@ -26,64 +31,71 @@
|
||||
width = nwidth
|
||||
if(nheight)
|
||||
height = nheight
|
||||
if(nref)
|
||||
ref = nref
|
||||
add_stylesheet("common", 'html/browser/common.css') // this CSS sheet is common to all UIs
|
||||
if(atom)
|
||||
atom_uid = atom.UID()
|
||||
|
||||
/datum/browser/proc/user_deleted(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
user = null
|
||||
|
||||
/datum/browser/proc/set_title(ntitle)
|
||||
title = format_text(ntitle)
|
||||
title = islist(ntitle) ? ntitle : list(ntitle)
|
||||
|
||||
/datum/browser/proc/add_head_content(nhead_content)
|
||||
head_content = nhead_content
|
||||
|
||||
/datum/browser/proc/set_title_buttons(ntitle_buttons)
|
||||
title_buttons = ntitle_buttons
|
||||
head_content = islist(nhead_content) ? nhead_content : list(nhead_content)
|
||||
|
||||
/datum/browser/proc/set_window_options(nwindow_options)
|
||||
window_options = nwindow_options
|
||||
|
||||
/datum/browser/proc/set_title_image(ntitle_image)
|
||||
//title_image = ntitle_image
|
||||
window_options = islist(nwindow_options) ? nwindow_options : list(nwindow_options)
|
||||
|
||||
/datum/browser/proc/add_stylesheet(name, file)
|
||||
stylesheets[name] = file
|
||||
if(istype(name, /datum/asset/spritesheet))
|
||||
var/datum/asset/spritesheet/sheet = name
|
||||
stylesheets["spritesheet_[sheet.name].css"] = "data/spritesheets/[sheet.name]"
|
||||
else
|
||||
var/asset_name = "[name].css"
|
||||
|
||||
stylesheets[asset_name] = file
|
||||
|
||||
if(!SSassets.cache[asset_name])
|
||||
SSassets.transport.register_asset(asset_name, file)
|
||||
|
||||
/datum/browser/proc/add_scss_stylesheet(name, file)
|
||||
var/asset_name = "[name].scss"
|
||||
stylesheets[asset_name] = file
|
||||
|
||||
if(!SSassets.cache[asset_name])
|
||||
SSassets.transport.register_asset(asset_name, file)
|
||||
|
||||
/datum/browser/proc/add_script(name, file)
|
||||
scripts[name] = file
|
||||
scripts["[ckey(name)].js"] = file
|
||||
SSassets.transport.register_asset("[ckey(name)].js", file)
|
||||
|
||||
/datum/browser/proc/set_content(ncontent)
|
||||
content = ncontent
|
||||
content = islist(ncontent) ? ncontent : list(ncontent)
|
||||
|
||||
/datum/browser/proc/add_content(ncontent)
|
||||
content += ncontent
|
||||
|
||||
/datum/browser/proc/get_header()
|
||||
var/key
|
||||
var/filename
|
||||
for(key in stylesheets)
|
||||
filename = "[ckey(key)].css"
|
||||
user << browse_rsc(stylesheets[key], filename)
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[filename]'>"
|
||||
if(include_default_stylesheet)
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url("common.css")]'>"
|
||||
|
||||
for(key in scripts)
|
||||
filename = "[ckey(key)].js"
|
||||
user << browse_rsc(scripts[key], filename)
|
||||
head_content += "<script type='text/javascript' src='[filename]'></script>"
|
||||
for(var/file in stylesheets)
|
||||
head_content += "<link rel='stylesheet' type='text/css' href='[SSassets.transport.get_asset_url(file)]'>"
|
||||
|
||||
var/title_attributes = "class='uiTitle'"
|
||||
if(title_image)
|
||||
title_attributes = "class='uiTitle icon' style='background-image: url([title_image]);'"
|
||||
for(var/file in scripts)
|
||||
head_content += "<script type='text/javascript' src='[SSassets.transport.get_asset_url(file)]'></script>"
|
||||
|
||||
return {"<!DOCTYPE html>
|
||||
return {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<meta charset="UTF-8">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
[head_content]
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
|
||||
[head_content.Join("")]
|
||||
</head>
|
||||
<body scroll=auto>
|
||||
<div class='uiWrapper'>
|
||||
[title ? "<div class='uiTitleWrapper'><div [title_attributes]><tt>[title]</tt></div><div class='uiTitleButtons'>[title_buttons]</div></div>" : ""]
|
||||
[title ? "<div class='uiTitleWrapper'><div class='uiTitle'><tt>[title]</tt></div></div>" : ""]
|
||||
<div class='uiContent'>
|
||||
"}
|
||||
|
||||
@@ -97,86 +109,60 @@
|
||||
/datum/browser/proc/get_content()
|
||||
return {"
|
||||
[get_header()]
|
||||
[content]
|
||||
[content.Join("")]
|
||||
[get_footer()]
|
||||
"}
|
||||
|
||||
/datum/browser/proc/open(use_onclose = 1)
|
||||
/datum/browser/proc/open(use_onclose = TRUE)
|
||||
if(isnull(window_id)) //null check because this can potentially nuke goonchat
|
||||
WARNING("Browser [title] tried to open with a null ID")
|
||||
to_chat(user, "<span class='userdanger'>The [title] browser you tried to open failed a sanity check! Please report this on github!</span>")
|
||||
return
|
||||
|
||||
var/window_size = ""
|
||||
if(width && height)
|
||||
window_size = "size=[width]x[height];"
|
||||
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
|
||||
if(include_default_stylesheet)
|
||||
var/datum/asset/simple/common/common_asset = get_asset_datum(/datum/asset/simple/common)
|
||||
common_asset.send(user)
|
||||
if(length(stylesheets))
|
||||
SSassets.transport.send_assets(user, stylesheets)
|
||||
if(length(scripts))
|
||||
SSassets.transport.send_assets(user, scripts)
|
||||
user << browse(get_content(), "window=[window_id];[window_size][window_options.Join("")]")
|
||||
if(use_onclose)
|
||||
onclose(user, window_id, ref)
|
||||
onclose(user, window_id, atom_uid)
|
||||
|
||||
/datum/browser/proc/close()
|
||||
user << browse(null, "window=[window_id]")
|
||||
|
||||
// This will allow you to show an icon in the browse window
|
||||
// This is added to mob so that it can be used without a reference to the browser object
|
||||
// There is probably a better place for this...
|
||||
/mob/proc/browse_rsc_icon(icon, icon_state, dir = -1)
|
||||
/*
|
||||
var/icon/I
|
||||
if(dir >= 0)
|
||||
I = new /icon(icon, icon_state, dir)
|
||||
if(!isnull(window_id))//null check because this can potentially nuke goonchat
|
||||
user << browse(null, "window=[window_id]")
|
||||
else
|
||||
I = new /icon(icon, icon_state)
|
||||
dir = "default"
|
||||
WARNING("Browser [title] tried to close with a null ID")
|
||||
|
||||
var/filename = "[ckey("[icon]_[icon_state]_[dir]")].png"
|
||||
src << browse_rsc(I, filename)
|
||||
return filename
|
||||
*/
|
||||
|
||||
|
||||
// Registers the on-close verb for a browse window (client/verb/.windowclose)
|
||||
// this will be called when the close-button of a window is pressed.
|
||||
//
|
||||
// This is usually only needed for devices that regularly update the browse window,
|
||||
// e.g. canisters, timers, etc.
|
||||
//
|
||||
// windowid should be the specified window name
|
||||
// e.g. code is : user << browse(text, "window=fred")
|
||||
// then use : onclose(user, "fred")
|
||||
//
|
||||
// Optionally, specify the "ref" parameter as the controlled atom (usually src)
|
||||
// to pass a "close=1" parameter to the atom's Topic() proc for special handling.
|
||||
// Otherwise, the user mob's machine var will be reset directly.
|
||||
//
|
||||
|
||||
/proc/onclose(mob/user, windowid, atom/ref=null)
|
||||
if(!user || !user.client) return
|
||||
var/param = "null"
|
||||
if(ref)
|
||||
param = "\ref[ref]"
|
||||
|
||||
winset(user, windowid, "on-close=\".windowclose [param]\"")
|
||||
|
||||
// to_chat(world, "OnClose [user]: [windowid] : ["on-close=\".windowclose [param]\""]")
|
||||
/proc/onclose(mob/user, windowid, atom_uid)
|
||||
if(!user?.client)
|
||||
return
|
||||
|
||||
winset(user, windowid, "on-close=\".windowclose [atom_uid || "null"]\"")
|
||||
|
||||
// the on-close client verb
|
||||
// called when a browser popup window is closed after registering with proc/onclose()
|
||||
// if a valid atom reference is supplied, call the atom's Topic() with "close=1"
|
||||
// if a valid atom uid is supplied, call the atom's Topic() with "close=1"
|
||||
// otherwise, just reset the client mob's machine var.
|
||||
//
|
||||
/client/verb/windowclose(atomref as text)
|
||||
set hidden = 1 // hide this verb from the user's panel
|
||||
set name = ".windowclose" // no autocomplete on cmd line
|
||||
/client/verb/windowclose(atom_uid as text)
|
||||
set hidden = TRUE // hide this verb from the user's panel
|
||||
set name = ".windowclose" // no autocomplete on cmd line
|
||||
|
||||
// to_chat(world, "windowclose: [atomref]")
|
||||
if(atomref!="null") // if passed a real atomref
|
||||
var/hsrc = locate(atomref) // find the reffed atom
|
||||
if(atom_uid != "null") // if passed a real atom_uid
|
||||
var/hsrc = locateUID(atom_uid) // find the reffed atom
|
||||
if(hsrc)
|
||||
// to_chat(world, "[src] Topic [href] [hsrc]")
|
||||
var/href = "close=1"
|
||||
usr = src.mob
|
||||
src.Topic("close=1", list("close"="1"), hsrc) // this will direct to the atom's
|
||||
return // Topic() proc via client.Topic()
|
||||
src.Topic(href, params2list(href), hsrc) // this will direct to the atom's
|
||||
return // Topic() proc via client.Topic()
|
||||
|
||||
// no atomref specified (or not found)
|
||||
// no atom_uid specified (or not found)
|
||||
// so just reset the user mob's machine var
|
||||
if(src && src.mob)
|
||||
// to_chat(world, "[src] was [src.mob.machine], setting to null")
|
||||
if(src?.mob)
|
||||
src.mob.unset_machine()
|
||||
return
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
global proc:
|
||||
GLOBAL_PROC_REF(procname)
|
||||
Example:
|
||||
CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(some_proc_here))
|
||||
CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(some_proc_here), args)
|
||||
|
||||
proc defined on current(src) object:
|
||||
PROC_REF(procname)
|
||||
Example:
|
||||
CALLBACK(src, PROC_REF(some_proc_here))
|
||||
CALLBACK(src, PROC_REF(some_proc_here), args)
|
||||
|
||||
proc defined on some other type:
|
||||
TYPE_PROC_REF(some_type, procname)
|
||||
Example:
|
||||
CALLBACK(other_atom, TYPE_PROC_REF(other_atom_type, procname)
|
||||
CALLBACK(other_atom, TYPE_PROC_REF(other_atom_type, procname), args)
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
/// Stores information about a chat payload
|
||||
/datum/chat_payload
|
||||
/// Sequence number of this payload
|
||||
var/sequence = 0
|
||||
/// Message we are sending
|
||||
var/list/content
|
||||
/// Resend count
|
||||
var/resends = 0
|
||||
|
||||
/// Converts the chat payload into a JSON string
|
||||
/datum/chat_payload/proc/into_message()
|
||||
return "{\"sequence\":[sequence],\"content\":[json_encode(content)]}"
|
||||
|
||||
/// Returns an HTML-encoded message from our contents.
|
||||
/datum/chat_payload/proc/get_content_as_html()
|
||||
return message_to_html(content)
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Component that allows for highlighting of words or phrases in chat based on regular expressions.
|
||||
*
|
||||
* Hooks into /mob/proc/combine_message to wrap every regex match in the message
|
||||
* between <span class=''></span> tags with the provided span class. This modifies the output that
|
||||
* is sent to the parent's chat window.
|
||||
*
|
||||
* Removal of this component should be done by calling [GetComponents(/datum/component/codeword_hearing)]
|
||||
* on the parent and then iterating through all components calling [delete_if_from_source(source)].
|
||||
*/
|
||||
/datum/component/codeword_hearing
|
||||
dupe_mode = COMPONENT_DUPE_ALLOWED
|
||||
|
||||
/// Regex for matching words or phrases you want highlighted.
|
||||
var/regex/replace_regex
|
||||
/// The <span class=''> to use for highlighting matches.
|
||||
var/span_class
|
||||
/// The source of this component. Used to identify the source in delete_if_from_source since this component is COMPONENT_DUPE_ALLOWED.
|
||||
var/source
|
||||
|
||||
/datum/component/codeword_hearing/Initialize(regex/codeword_regex, highlight_span_class, component_source)
|
||||
if(!ismovable(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
replace_regex = codeword_regex
|
||||
span_class = highlight_span_class
|
||||
source = component_source
|
||||
return ..()
|
||||
|
||||
/datum/component/codeword_hearing/proc/handle_hearing(message)
|
||||
var/mob/living/owner = parent
|
||||
if(!istype(owner))
|
||||
return
|
||||
|
||||
// don't skip codewords when owner speaks
|
||||
if(!owner.can_hear())
|
||||
return
|
||||
|
||||
return replace_regex.Replace(message, "<span class='[span_class]'>$1</span>")
|
||||
|
||||
/// Since a parent can have multiple of these components on them simultaneously, this allows a datum to delete components from a specific source.
|
||||
/datum/component/codeword_hearing/proc/delete_if_from_source(component_source)
|
||||
if(source == component_source)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
return FALSE
|
||||
@@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(PDA_Manifest)
|
||||
is_custom_job = FALSE
|
||||
break
|
||||
|
||||
if(is_custom_job)
|
||||
if(is_custom_job && foundrecord)
|
||||
real_title = foundrecord.fields["real_rank"]
|
||||
|
||||
if(foundrecord)
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
/client/can_vv_get(var_name)
|
||||
var/static/list/protected_vars = list(
|
||||
"address", "chatOutput", "computer_id", "connection", "jbh", "pm_tracker", "related_accounts_cid", "related_accounts_ip", "watchlisted"
|
||||
"address", "computer_id", "connection", "jbh", "pm_tracker", "related_accounts_cid", "related_accounts_ip", "watchlisted"
|
||||
)
|
||||
if(!check_rights(R_ADMIN, FALSE, usr) && (var_name in protected_vars))
|
||||
return FALSE
|
||||
|
||||
@@ -251,13 +251,13 @@ if(!result || result.ckey != __ckey){\
|
||||
return
|
||||
if(href_list["add_mob"])
|
||||
var/list/mobs = getpois(TRUE, TRUE)
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a mob: ", mobs)
|
||||
A.on_close(CALLBACK(src, PROC_REF(add_mob), usr))
|
||||
var/mob_choice = tgui_input_list(usr, "Please, select a mob: ", "Mob selector", mobs)
|
||||
add_mob(usr, mobs[mob_choice])
|
||||
return
|
||||
if(href_list["add_ckey"])
|
||||
var/list/ckeys = GLOB.logging.get_ckeys_logged()
|
||||
var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a ckey: ", ckeys)
|
||||
A.on_close(CALLBACK(src, PROC_REF(add_ckey), usr))
|
||||
var/ckey_choice = tgui_input_list(usr, "Please, select a ckey: ", "Ckey selector", ckeys)
|
||||
add_ckey(usr, ckey_choice)
|
||||
return
|
||||
if(href_list["remove_mob"])
|
||||
var/mob/M = locate(href_list["remove_mob"])
|
||||
|
||||
@@ -6,10 +6,13 @@
|
||||
qdel(src)
|
||||
owner = new_owner
|
||||
|
||||
/datum/spawners_menu/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/ui_state/state = GLOB.observer_state, datum/tgui/master_ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/spawners_menu/ui_state(mob/user)
|
||||
return GLOB.observer_state
|
||||
|
||||
/datum/spawners_menu/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SpawnersMenu", "Spawners Menu", 700, 600, master_ui, state = state)
|
||||
ui = new(user, src, "SpawnersMenu", "Spawners Menu")
|
||||
ui.open()
|
||||
|
||||
/datum/spawners_menu/ui_data(mob/user)
|
||||
@@ -43,8 +46,9 @@
|
||||
/datum/spawners_menu/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
var/spawners = replacetext(params["ID"], ",", ";")
|
||||
var/list/possible_spawners = params2list(spawners)
|
||||
var/list/possible_spawners = params["ID"]
|
||||
if(!length(possible_spawners))
|
||||
return
|
||||
var/obj/effect/mob_spawn/MS = locate(pick(possible_spawners))
|
||||
if(!MS || !istype(MS))
|
||||
CRASH("A ghost tried to interact with an invalid spawner, or the spawner didn't exist.")
|
||||
|
||||
@@ -80,10 +80,8 @@
|
||||
|
||||
var/list/new_future_traits = list()
|
||||
var/list/station_trait_names = list()
|
||||
var/station_trait_text = params["station_traits"]
|
||||
var/list/temp_list = splittext(station_trait_text, ",")
|
||||
for(var/thing in temp_list) //TODO QWERTY / HI REVIEWERS NAME THIS BETTER BUT ITS ALMOST MIDNIGHT AND i HATE MYSELF
|
||||
var/datum/station_trait/station_trait_path = text2path(thing)
|
||||
for(var/station_trait_text in params["station_traits"])
|
||||
var/datum/station_trait/station_trait_path = text2path(station_trait_text)
|
||||
if(!ispath(station_trait_path, /datum/station_trait) || station_trait_path == /datum/station_trait)
|
||||
log_admin("[key_name(ui.user)] tried to set an invalid future station trait: [station_trait_text]")
|
||||
to_chat(ui.user, "<span class='warning'>Invalid future station trait: [station_trait_text]</span>")
|
||||
@@ -126,8 +124,11 @@
|
||||
/datum/ui_module/station_traits_panel/proc/too_late_to_revert()
|
||||
return SSticker.current_state >= GAME_STATE_PLAYING
|
||||
|
||||
/datum/ui_module/station_traits_panel/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)
|
||||
/datum/ui_module/station_traits_panel/ui_state(mob/user)
|
||||
return GLOB.admin_state
|
||||
|
||||
/datum/ui_module/station_traits_panel/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "StationTraitsPanel", "Station Traits Panel", 700, 600, master_ui, state = state)
|
||||
ui = new(user, src, "StationTraitsPanel")
|
||||
ui.open()
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
holder_type = /obj/machinery/door/airlock
|
||||
wire_count = 12 // 10 actual, 2 duds.
|
||||
proper_name = "Airlock"
|
||||
window_x = 400
|
||||
window_y = 101
|
||||
|
||||
/datum/wires/airlock/New(atom/_holder)
|
||||
wires = list(
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
/datum/wires/alarm
|
||||
holder_type = /obj/machinery/alarm
|
||||
wire_count = 5
|
||||
window_x = 385
|
||||
window_y = 90
|
||||
proper_name = "Air alarm"
|
||||
|
||||
/datum/wires/alarm/New(atom/_holder)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
holder_type = /obj/machinery/power/apc
|
||||
wire_count = 4
|
||||
proper_name = "APC"
|
||||
window_x = 355
|
||||
window_y = 97
|
||||
|
||||
/datum/wires/apc/New(atom/_holder)
|
||||
wires = list(WIRE_IDSCAN, WIRE_MAIN_POWER1, WIRE_MAIN_POWER2, WIRE_AI_CONTROL)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
holder_type = /obj/machinery/autolathe
|
||||
wire_count = 10
|
||||
proper_name = "Autolathe"
|
||||
window_x = 340
|
||||
window_y = 55
|
||||
|
||||
/datum/wires/autolathe/New(atom/_holder)
|
||||
wires = list(WIRE_AUTOLATHE_HACK, WIRE_ELECTRIFY, WIRE_AUTOLATHE_DISABLE)
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
holder_type = /obj/machinery/camera
|
||||
wire_count = 2
|
||||
proper_name = "Camera"
|
||||
window_x = 350
|
||||
window_y = 95
|
||||
|
||||
/datum/wires/camera/New(atom/_holder)
|
||||
wires = list(WIRE_FOCUS, WIRE_MAIN_POWER1)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/datum/wires/explosive
|
||||
wire_count = 1
|
||||
proper_name = "Explosive"
|
||||
window_x = 320
|
||||
window_y = 50
|
||||
|
||||
/datum/wires/explosive/New(atom/_holder)
|
||||
wires = list(WIRE_EXPLODE)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
randomize = TRUE //Every modsuit is personalised
|
||||
wire_count = 6 // 4 actual, 2 duds
|
||||
proper_name = "MOD control unit"
|
||||
window_x = 345
|
||||
window_y = 90
|
||||
|
||||
/datum/wires/mod/New(atom/holder)
|
||||
wires = list(WIRE_HACK, WIRE_DISABLE, WIRE_ELECTRIFY, WIRE_INTERFACE)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
holder_type = /mob/living/simple_animal/bot/mulebot
|
||||
wire_count = 10
|
||||
proper_name = "Mulebot"
|
||||
window_x = 370
|
||||
window_y = -12
|
||||
|
||||
/datum/wires/mulebot/New(atom/_holder)
|
||||
wires = list(
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
randomize = TRUE
|
||||
wire_count = 7 // 3 actual, 4 duds.
|
||||
proper_name = "Nuclear bomb"
|
||||
window_x = 345
|
||||
window_y = 75
|
||||
|
||||
/datum/wires/nuclearbomb/New(atom/_holder)
|
||||
wires = list(WIRE_BOMB_LIGHT, WIRE_BOMB_TIMING, WIRE_BOMB_SAFETY)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
wire_count = 5
|
||||
holder_type = /obj/machinery/particle_accelerator/control_box
|
||||
proper_name = "Particle accelerator control"
|
||||
window_x = 361
|
||||
window_y = 22
|
||||
|
||||
/datum/wires/particle_acc/control_box/New(atom/_holder)
|
||||
wires = list(WIRE_PARTICLE_POWER, WIRE_PARTICLE_STRENGTH, WIRE_PARTICLE_INTERFACE, WIRE_PARTICLE_POWER_LIMIT)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
holder_type = /obj/item/radio
|
||||
wire_count = 3
|
||||
proper_name = "Radio"
|
||||
window_x = 330
|
||||
window_y = 37
|
||||
|
||||
/datum/wires/radio/New(atom/_holder)
|
||||
wires = list(WIRE_RADIO_SIGNAL, WIRE_RADIO_RECEIVER, WIRE_RADIO_TRANSMIT)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
randomize = TRUE
|
||||
holder_type = /mob/living/silicon/robot
|
||||
wire_count = 5
|
||||
window_x = 340
|
||||
window_y = 106
|
||||
proper_name = "Cyborg"
|
||||
|
||||
/datum/wires/robot/New(atom/_holder)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
holder_type = /obj/machinery/smartfridge
|
||||
wire_count = 3
|
||||
proper_name = "Smartfridge"
|
||||
window_x = 340
|
||||
window_y = 103
|
||||
|
||||
/datum/wires/smartfridge/New(atom/_holder)
|
||||
wires = list(WIRE_ELECTRIFY, WIRE_IDSCAN, WIRE_THROW_ITEM)
|
||||
@@ -12,7 +10,6 @@
|
||||
/datum/wires/smartfridge/secure
|
||||
randomize = TRUE
|
||||
wire_count = 4 // 3 actual, 1 dud.
|
||||
window_y = 97
|
||||
|
||||
/datum/wires/smartfridge/interactable(mob/user)
|
||||
var/obj/machinery/smartfridge/S = holder
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
holder_type = /obj/machinery/suit_storage_unit
|
||||
wire_count = 8
|
||||
proper_name = "Suit storage unit"
|
||||
window_x = 350
|
||||
window_y = 85
|
||||
|
||||
/datum/wires/suitstorage/New(atom/_holder)
|
||||
wires = list(WIRE_IDSCAN, WIRE_ELECTRIFY, WIRE_SAFETY, WIRE_SSU_UV)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
holder_type = /obj/machinery/syndicatebomb
|
||||
wire_count = 5
|
||||
proper_name = "Syndicate bomb"
|
||||
window_x = 320
|
||||
window_y = 22
|
||||
|
||||
/datum/wires/syndicatebomb/New(atom/_holder)
|
||||
wires = list(WIRE_BOMB_DELAY, WIRE_EXPLODE, WIRE_BOMB_UNBOLT,WIRE_BOMB_PROCEED, WIRE_BOMB_ACTIVATE)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
wire_count = 1
|
||||
holder_type = /obj/machinery/power/tesla_coil
|
||||
proper_name = "Tesla coil"
|
||||
window_x = 320
|
||||
window_y = 50
|
||||
|
||||
/datum/wires/tesla_coil/New(atom/_holder)
|
||||
wires = list(WIRE_TESLACOIL_ZAP)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/datum/wires/vending
|
||||
holder_type = /obj/machinery/economy/vending
|
||||
wire_count = 4
|
||||
window_y = 112
|
||||
window_x = 350
|
||||
proper_name = "Vending machine"
|
||||
|
||||
/datum/wires/vending/New(atom/_holder)
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
var/list/colors
|
||||
/// An associative list of signalers attached to the wires. The wire color is the key, and the signaler object reference is the value.
|
||||
var/list/assemblies
|
||||
/// The width of the wire TGUI window.
|
||||
var/window_x = 300
|
||||
/// The height of the wire TGUI window. Will get longer as needed, based on the `wire_count`.
|
||||
var/window_y = 100
|
||||
|
||||
/datum/wires/New(atom/_holder)
|
||||
..()
|
||||
@@ -92,10 +88,13 @@
|
||||
/datum/wires/ui_host()
|
||||
return holder
|
||||
|
||||
/datum/wires/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/datum/wires/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
/datum/wires/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Wires", "[proper_name] wires", window_x, window_y + wire_count * 30, master_ui, state)
|
||||
ui = new(user, src, "Wires", "[proper_name] wires")
|
||||
ui.open()
|
||||
|
||||
/datum/wires/ui_data(mob/user)
|
||||
|
||||
@@ -398,13 +398,16 @@
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/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)
|
||||
/obj/machinery/computer/scan_consolenew/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
if(user == connected.occupant)
|
||||
return
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "DNAModifier", name, 660, 700, master_ui, state)
|
||||
ui = new(user, src, "DNAModifier", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/scan_consolenew/ui_data(mob/user)
|
||||
|
||||
@@ -102,7 +102,6 @@
|
||||
dat += "<span class='bad'>NO AGENT VEST DETECTED</span>"
|
||||
var/datum/browser/popup = new(user, "computer", "Abductor Console", 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/abductor/console/Topic(href, href_list)
|
||||
|
||||
@@ -40,10 +40,13 @@
|
||||
if(!length(colors))
|
||||
colors = shuffle(color_pool)
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/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)
|
||||
/obj/machinery/abductor/gland_dispenser/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "GlandDispenser", name, 300, 338, master_ui, state)
|
||||
ui = new(user, src, "GlandDispenser", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/abductor/gland_dispenser/ui_data(mob/user)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var/credits = 0
|
||||
var/list/history = list()
|
||||
var/list/abductee_minds = list()
|
||||
var/flash = " - || - "
|
||||
var/flash = "Idle."
|
||||
var/obj/machinery/abductor/console/console
|
||||
var/mob/living/carbon/human/occupant
|
||||
|
||||
@@ -40,15 +40,16 @@
|
||||
|
||||
target.forceMove(src)
|
||||
occupant = target
|
||||
flash = "Machine ready."
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
add_fingerprint(user)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/abductor/experiment/attack_hand(mob/user)
|
||||
if(..())
|
||||
if(!isabductor(user))
|
||||
to_chat(user, "<span class='warning'>You don't understand any of the alien writing!</span>")
|
||||
return
|
||||
|
||||
experimentUI(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
|
||||
var/icon/I = icon(H.stand_icon)
|
||||
@@ -60,75 +61,62 @@
|
||||
|
||||
return I
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/experimentUI(mob/user)
|
||||
var/dat
|
||||
dat += "<h3> Experiment </h3>"
|
||||
/obj/machinery/abductor/experiment/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/abductor/experiment/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/abductor/experiment/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "ExperimentConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/abductor/experiment/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["open"] = occupant ? TRUE : FALSE
|
||||
data["feedback"] = flash
|
||||
data["occupant"] = occupant ? TRUE : FALSE
|
||||
data["occupant_name"] = null
|
||||
data["occupant_status"] = null
|
||||
if(occupant)
|
||||
var/icon/H = icon(dissection_icon(occupant), dir = SOUTH)
|
||||
if(H)
|
||||
user << browse_rsc(H, "dissection_img.png")
|
||||
dat += "<table><tr><td>"
|
||||
dat += "<img src='dissection_img.png' height='80' width='80'>"
|
||||
dat += "</td><td>"
|
||||
else
|
||||
dat += "ERR: Unable to retrieve image data for occupant."
|
||||
dat += "<a href='?src=[UID()];experiment=1'>Probe</a><br>"
|
||||
dat += "<a href='?src=[UID()];experiment=2'>Dissect</a><br>"
|
||||
dat += "<a href='?src=[UID()];experiment=3'>Analyze</a><br>"
|
||||
dat += "</td></tr></table>"
|
||||
else
|
||||
dat += "<span class='linkOff'>Experiment </span>"
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant_name"] = mob_occupant.name
|
||||
data["occupant_status"] = mob_occupant.stat
|
||||
return data
|
||||
|
||||
if(!occupant)
|
||||
dat += "<h3>Machine Unoccupied</h3>"
|
||||
else
|
||||
dat += "<h3>Subject Status : </h3>"
|
||||
dat += "[occupant.name] => "
|
||||
switch(occupant.stat)
|
||||
if(0)
|
||||
dat += "<span class='good'>Conscious</span>"
|
||||
if(1)
|
||||
dat += "<span class='average'>Unconscious</span>"
|
||||
else
|
||||
dat += "<span class='bad'>Deceased</span>"
|
||||
dat += "<br>"
|
||||
dat += "[flash]"
|
||||
dat += "<br>"
|
||||
dat += "<a href='?src=[UID()];refresh=1'>Scan</a>"
|
||||
dat += "<a href='?src=[UID()];[occupant ? "eject=1'>Eject Occupant</a>" : "unoccupied=1'>Unoccupied</a>"]"
|
||||
var/datum/browser/popup = new(user, "experiment", "Probing Console", 300, 300)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.set_content(dat)
|
||||
popup.open()
|
||||
/obj/machinery/abductor/experiment/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
/obj/machinery/abductor/experiment/Topic(href, href_list)
|
||||
if(..() || usr == occupant)
|
||||
return
|
||||
usr.set_machine(src)
|
||||
if(href_list["refresh"])
|
||||
updateUsrDialog()
|
||||
return
|
||||
if(href_list["eject"])
|
||||
eject_abductee()
|
||||
return
|
||||
if(occupant && occupant.stat != DEAD)
|
||||
if(href_list["experiment"])
|
||||
flash = Experiment(occupant,href_list["experiment"])
|
||||
updateUsrDialog()
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("door")
|
||||
eject_abductee()
|
||||
flash = "Specimen ejected!"
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/Experiment(mob/occupant,type)
|
||||
if("experiment")
|
||||
if(!occupant)
|
||||
return
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(mob_occupant.stat == DEAD)
|
||||
return
|
||||
flash = experiment(mob_occupant, params["experiment_type"], usr)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/experiment(mob/occupant,type)
|
||||
var/mob/living/carbon/human/H = occupant
|
||||
var/point_reward = 0
|
||||
if(H in history)
|
||||
return "<span class='bad'>Specimen already in database.</span>"
|
||||
return "Specimen already in database."
|
||||
if(H.stat == DEAD)
|
||||
atom_say("Specimen deceased - please provide fresh sample.")
|
||||
return "<span class='bad'>Specimen deceased.</span>"
|
||||
return "Specimen deceased."
|
||||
var/obj/item/organ/internal/heart/gland/GlandTest = locate() in H.internal_organs
|
||||
if(!GlandTest)
|
||||
atom_say("Experimental dissection not detected!")
|
||||
return "<span class='bad'>No glands detected!</span>"
|
||||
return "No glands detected!"
|
||||
if(H.mind != null && H.ckey != null)
|
||||
history += H
|
||||
abductee_minds += H.mind
|
||||
@@ -158,22 +146,22 @@
|
||||
point_reward++
|
||||
if(point_reward > 0)
|
||||
eject_abductee()
|
||||
SendBack(H)
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
|
||||
send_back(H)
|
||||
playsound(src.loc, 'sound/machines/ding.ogg', 50, TRUE)
|
||||
points += point_reward
|
||||
credits += point_reward
|
||||
return "<span class='good'>Experiment successful! [point_reward] new data-points collected.</span>"
|
||||
return "Experiment successful! [point_reward] new data-points collected."
|
||||
else
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, 1)
|
||||
return "<span class='bad'>Experiment failed! No replacement organ detected.</span>"
|
||||
playsound(src.loc, 'sound/machines/buzz-sigh.ogg', 50, TRUE)
|
||||
return "Experiment failed! No replacement organ detected."
|
||||
else
|
||||
atom_say("Brain activity nonexistent - disposing sample...")
|
||||
eject_abductee()
|
||||
SendBack(H)
|
||||
return "<span class='bad'>Specimen braindead - disposed.</span>"
|
||||
send_back(H)
|
||||
return "Specimen braindead - disposed."
|
||||
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/SendBack(mob/living/carbon/human/H)
|
||||
/obj/machinery/abductor/experiment/proc/send_back(mob/living/carbon/human/H)
|
||||
H.Sleeping(16 SECONDS)
|
||||
if(console && console.pad && console.pad.teleport_target)
|
||||
H.forceMove(console.pad.teleport_target)
|
||||
@@ -201,6 +189,7 @@
|
||||
var/mob/living/carbon/human/H = grabbed.affecting
|
||||
H.forceMove(src)
|
||||
occupant = H
|
||||
flash = "Machine ready."
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
add_fingerprint(user)
|
||||
qdel(G)
|
||||
|
||||
@@ -335,7 +335,7 @@ GLOBAL_VAR(bomb_set)
|
||||
|
||||
/obj/machinery/nuclearbomb/attack_ghost(mob/user as mob)
|
||||
if(!panel_open)
|
||||
return ui_interact(user, state = GLOB.viewer_state)
|
||||
return ui_interact(user)
|
||||
if(removal_stage != NUKE_CORE_FULLY_EXPOSED || !core)
|
||||
return wires.Interact(user)
|
||||
|
||||
@@ -356,10 +356,13 @@ GLOBAL_VAR(bomb_set)
|
||||
core = null
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/nuclearbomb/ui_state(mob/user)
|
||||
return GLOB.physical_state
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "NuclearBomb", name, 450, 300, master_ui, state)
|
||||
ui = new(user, src, "NuclearBomb", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/nuclearbomb/ui_data(mob/user)
|
||||
|
||||
@@ -10,10 +10,13 @@
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/used = FALSE
|
||||
|
||||
/obj/item/contract/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/contract/ui_state(mob/user)
|
||||
return GLOB.inventory_state
|
||||
|
||||
/obj/item/contract/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "WizardApprenticeContract", name, 400, 600, master_ui, state)
|
||||
ui = new(user, src, "WizardApprenticeContract", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/contract/ui_data(mob/user)
|
||||
|
||||
@@ -98,10 +98,10 @@
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/pdapainter/ui_interact(mob/user, ui_key, datum/tgui/ui, force_open, datum/tgui/master_ui, datum/ui_state/state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/pdapainter/ui_interact(mob/user, datum/tgui/ui, datum/ui_state/state)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "PdaPainter", "PDA Painter", 510, 510)
|
||||
ui = new(user, src, "PdaPainter", "PDA Painter")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/pdapainter/ui_data(mob/user)
|
||||
|
||||
@@ -157,10 +157,13 @@
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/sleeper/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)
|
||||
/obj/machinery/sleeper/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/sleeper/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Sleeper", "Sleeper", 550, 775)
|
||||
ui = new(user, src, "Sleeper", "Sleeper")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/sleeper/ui_data(mob/user)
|
||||
|
||||
@@ -218,10 +218,13 @@
|
||||
new /obj/effect/gibspawner/generic(get_turf(loc)) //I REPLACE YOUR TECHNOLOGY WITH FLESH!
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/bodyscanner/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)
|
||||
/obj/machinery/bodyscanner/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/bodyscanner/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "BodyScanner", "Body Scanner", 690, 600)
|
||||
ui = new(user, src, "BodyScanner", "Body Scanner")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/bodyscanner/ui_data(mob/user)
|
||||
|
||||
@@ -345,10 +345,13 @@ send an additional command to open the door again.
|
||||
else
|
||||
icon_state = "access_control_off"
|
||||
|
||||
/obj/machinery/airlock_controller/access_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)
|
||||
/obj/machinery/airlock_controller/access_controller/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/airlock_controller/access_controller/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AirlockAccessController", name, 470, 290, master_ui, state)
|
||||
ui = new(user, src, "AirlockAccessController", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/airlock_controller/access_controller/ui_data(mob/user)
|
||||
@@ -378,10 +381,13 @@ send an additional command to open the door again.
|
||||
stack_trace("[src] at [x],[y],[z] didnt setup any vents! Please double check the IDs!")
|
||||
|
||||
|
||||
/obj/machinery/airlock_controller/air_cycler/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)
|
||||
/obj/machinery/airlock_controller/air_cycler/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/airlock_controller/air_cycler/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "ExternalAirlockController", name, 470, 290, master_ui, state)
|
||||
ui = new(user, src, "ExternalAirlockController", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/airlock_controller/air_cycler/ui_data(mob/user)
|
||||
|
||||
@@ -98,10 +98,13 @@
|
||||
else if(!disabled)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/autolathe/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/autolathe/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/autolathe/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Autolathe", name, 750, 700, master_ui, state)
|
||||
ui = new(user, src, "Autolathe", name)
|
||||
ui.open()
|
||||
|
||||
|
||||
@@ -191,10 +194,10 @@
|
||||
return
|
||||
var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
|
||||
var/coeff = get_coeff(design_last_ordered)
|
||||
if(design_last_ordered.materials["$metal"] / coeff > materials.amount(MAT_METAL))
|
||||
if(design_last_ordered.materials[MAT_METAL] / coeff > materials.amount(MAT_METAL))
|
||||
to_chat(usr, "<span class='warning'>Invalid design (not enough metal)</span>")
|
||||
return
|
||||
if(design_last_ordered.materials["$glass"] / coeff > materials.amount(MAT_GLASS))
|
||||
if(design_last_ordered.materials[MAT_GLASS] / coeff > materials.amount(MAT_GLASS))
|
||||
to_chat(usr, "<span class='warning'>Invalid design (not enough glass)</span>")
|
||||
return
|
||||
if(!hacked && ("hacked" in design_last_ordered.category))
|
||||
@@ -220,7 +223,7 @@
|
||||
busy = FALSE
|
||||
|
||||
/obj/machinery/autolathe/ui_status(mob/user, datum/ui_state/state)
|
||||
. = disabled ? STATUS_DISABLED : STATUS_INTERACTIVE
|
||||
. = disabled ? UI_DISABLED : UI_INTERACTIVE
|
||||
|
||||
return min(..(), .)
|
||||
|
||||
|
||||
@@ -143,10 +143,13 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/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)
|
||||
/obj/machinery/computer/HolodeckControl/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/HolodeckControl/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "Holodeck", name, 400, 500, master_ui, state)
|
||||
ui = new(user, src, "Holodeck", name)
|
||||
ui.autoupdate = TRUE
|
||||
ui.open()
|
||||
|
||||
|
||||
@@ -59,10 +59,13 @@
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/operating/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)
|
||||
/obj/machinery/computer/operating/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/operating/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "OperatingComputer", "Patient Monitor", 650, 455, master_ui, state)
|
||||
ui = new(user, src, "OperatingComputer", "Patient Monitor")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/operating/ui_data(mob/user)
|
||||
|
||||
@@ -28,10 +28,13 @@
|
||||
/obj/machinery/computer/aifixer/attack_hand(mob/user as mob)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/aifixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/aifixer/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/aifixer/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AIFixer", name, 550, 500, master_ui, state)
|
||||
ui = new(user, src, "AIFixer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/aifixer/ui_data(mob/user)
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
//onclose(user, "arcade")
|
||||
var/datum/browser/popup = new(user, "arcade", "Space Villain 2000")
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
return
|
||||
|
||||
@@ -411,7 +410,6 @@
|
||||
dat += "<P ALIGN=Right><a href='byond://?src=[UID()];close=1'>Close</a></P>"
|
||||
var/datum/browser/popup = new(user, "arcade", "The Orion Trail",400,700)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
return
|
||||
|
||||
|
||||
@@ -190,10 +190,13 @@
|
||||
emagged = FALSE
|
||||
prizevend(50)
|
||||
|
||||
/obj/machinery/computer/arcade/recruiter/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)
|
||||
/obj/machinery/computer/arcade/recruiter/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/arcade/recruiter/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "NTRecruiter", name, 400, 480)
|
||||
ui = new(user, src, "NTRecruiter", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/arcade/recruiter/ui_data(mob/user)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
name = "atmospheric alert computer"
|
||||
desc = "Used to access the station's atmospheric sensors."
|
||||
circuit = /obj/item/circuitboard/atmos_alert
|
||||
var/ui_x = 350
|
||||
var/ui_y = 300
|
||||
icon_keyboard = "atmos_key"
|
||||
icon_screen = "alert:0"
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
@@ -42,10 +40,13 @@
|
||||
/obj/machinery/computer/atmos_alert/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmos_alert/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)
|
||||
/obj/machinery/computer/atmos_alert/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/atmos_alert/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AtmosAlertConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "AtmosAlertConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/atmos_alert/ui_data(mob/user)
|
||||
|
||||
@@ -145,15 +145,18 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
/obj/machinery/computer/general_air_control/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/general_air_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)
|
||||
/obj/machinery/computer/general_air_control/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/general_air_control/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
if(!isprocessing)
|
||||
START_PROCESSING(SSmachines, src)
|
||||
refresh_all()
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
// We can use the same template here for sensors and for tanks with inlets/outlets with TGUI memes
|
||||
ui = new(user, src, ui_key, "AtmosTankControl", name, 400, 400, master_ui, state)
|
||||
ui = new(user, src, "AtmosTankControl", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/general_air_control/ui_data(mob/user)
|
||||
@@ -274,10 +277,11 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
|
||||
/obj/machinery/computer/general_air_control/process()
|
||||
// We only care about refreshing if people are looking at us
|
||||
if(SStgui.get_open_ui_count(src) < 1)
|
||||
return PROCESS_KILL
|
||||
if(src in SStgui.open_uis_by_src)
|
||||
refresh_all()
|
||||
return
|
||||
|
||||
refresh_all()
|
||||
return PROCESS_KILL
|
||||
|
||||
/obj/machinery/computer/general_air_control/large_tank_control
|
||||
circuit = /obj/item/circuitboard/large_tank_control
|
||||
@@ -516,5 +520,8 @@ GLOBAL_LIST_EMPTY(gas_sensors)
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/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)
|
||||
atmos_control.ui_interact(user, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/atmoscontrol/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/atmoscontrol/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
atmos_control.ui_interact(user, ui)
|
||||
|
||||
@@ -22,10 +22,13 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/brigcells/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/brigcells/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/brigcells/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "BrigCells", "Brig Cell Management", 1000, 400, master_ui, state)
|
||||
ui = new(user, src, "BrigCells", "Brig Cell Management")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/brigcells/ui_data(mob/user)
|
||||
|
||||
@@ -55,9 +55,12 @@
|
||||
qdel(cam_background)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/computer/security/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)
|
||||
/obj/machinery/computer/security/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
// Update UI
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
// Show static if can't use the camera
|
||||
if(!active_camera?.can_use())
|
||||
show_camera_static()
|
||||
@@ -79,7 +82,7 @@
|
||||
user.client.register_map_obj(plane)
|
||||
user.client.register_map_obj(cam_background)
|
||||
// Open UI
|
||||
ui = new(user, src, ui_key, "CameraConsole", name, 870, 708, master_ui, state)
|
||||
ui = new(user, src, "CameraConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/security/ui_close(mob/user)
|
||||
|
||||
@@ -307,10 +307,13 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/card/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/card/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/card/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CardComputer", name, 800, 800, master_ui, state)
|
||||
ui = new(user, src, "CardComputer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/card/ui_data(mob/user)
|
||||
|
||||
@@ -110,18 +110,23 @@
|
||||
updatemodules()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/cloning/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)
|
||||
/obj/machinery/computer/cloning/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/cloning/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
if(stat & (NOPOWER|BROKEN))
|
||||
return
|
||||
|
||||
var/datum/asset/cloning/assets = get_asset_datum(/datum/asset/cloning)
|
||||
assets.send(user)
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CloningConsole", "Cloning Console", 640, 520)
|
||||
ui = new(user, src, "CloningConsole", "Cloning Console")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/cloning/ui_assets(mob/user)
|
||||
return list(
|
||||
get_asset_datum(/datum/asset/simple/cloning)
|
||||
)
|
||||
|
||||
/obj/machinery/computer/cloning/ui_data(mob/user)
|
||||
var/data[0]
|
||||
data["menu"] = src.menu
|
||||
|
||||
@@ -418,10 +418,13 @@
|
||||
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/communications/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/communications/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/communications/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CommunicationsComputer", name, 500, 600, master_ui, state)
|
||||
ui = new(user, src, "CommunicationsComputer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/communications/ui_data(mob/user)
|
||||
|
||||
@@ -26,8 +26,11 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/crew/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)
|
||||
crew_monitor.ui_interact(user, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/crew/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/crew/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
crew_monitor.ui_interact(user, ui)
|
||||
|
||||
/obj/machinery/computer/crew/interact(mob/user)
|
||||
crew_monitor.ui_interact(user)
|
||||
|
||||
@@ -72,10 +72,13 @@
|
||||
/obj/machinery/computer/syndicate_depot/proc/disable_special_functions()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/syndicate_depot/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/syndicate_depot/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/syndicate_depot/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SyndicateComputerSimple", name, window_width, window_height, master_ui, state)
|
||||
ui = new(user, src, "SyndicateComputerSimple", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/syndicate_depot/ui_data(mob/user)
|
||||
|
||||
@@ -75,10 +75,13 @@
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/med_data/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)
|
||||
/obj/machinery/computer/med_data/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/med_data/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "MedicalRecords", "Medical Records", 800, 800, master_ui, state)
|
||||
ui = new(user, src, "MedicalRecords", "Medical Records")
|
||||
ui.open()
|
||||
ui.set_autoupdate(FALSE)
|
||||
|
||||
|
||||
@@ -70,8 +70,11 @@
|
||||
powernet = find_powernet()
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/monitor/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)
|
||||
power_monitor.ui_interact(user, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/monitor/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/monitor/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
power_monitor.ui_interact(user, ui)
|
||||
|
||||
/obj/machinery/computer/monitor/interact(mob/user)
|
||||
power_monitor.ui_interact(user)
|
||||
|
||||
@@ -55,10 +55,13 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/prisoner/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/prisoner/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/prisoner/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "PrisonerImplantManager", name, 500, 500, master_ui, state)
|
||||
ui = new(user, src, "PrisonerImplantManager", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/prisoner/ui_data(mob/user)
|
||||
|
||||
@@ -131,10 +131,13 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/computer/robotics/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/robotics/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/robotics/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "RoboticsControlConsole", name, 500, 460, master_ui, state)
|
||||
ui = new(user, src, "RoboticsControlConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/robotics/ui_data(mob/user)
|
||||
|
||||
@@ -71,10 +71,13 @@
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/secure_data/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/computer/secure_data/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/secure_data/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SecurityRecords", name, 800, 800)
|
||||
ui = new(user, src, "SecurityRecords", name)
|
||||
ui.open()
|
||||
ui.set_autoupdate(FALSE)
|
||||
|
||||
|
||||
@@ -25,10 +25,13 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/sm_monitor/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)
|
||||
/obj/machinery/computer/sm_monitor/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/sm_monitor/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "SupermatterMonitor", name, 600, 350, master_ui, state)
|
||||
ui = new(user, src, "SupermatterMonitor", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/sm_monitor/ui_data(mob/user)
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
icon_screen = "alert:0"
|
||||
light_color = LIGHT_COLOR_CYAN
|
||||
circuit = /obj/item/circuitboard/stationalert_engineering
|
||||
var/ui_x = 325
|
||||
var/ui_y = 500
|
||||
var/list/alarms_listend_for = list("Fire", "Atmosphere", "Power")
|
||||
|
||||
/obj/machinery/computer/station_alert/Initialize(mapload)
|
||||
@@ -28,10 +26,13 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/station_alert/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)
|
||||
/obj/machinery/computer/station_alert/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/station_alert/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "StationAlertConsole", name, ui_x, ui_y, master_ui, state)
|
||||
ui = new(user, src, "StationAlertConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/station_alert/ui_data(mob/user)
|
||||
|
||||
@@ -58,10 +58,13 @@
|
||||
add_fingerprint(user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/cryopod/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)
|
||||
/obj/machinery/computer/cryopod/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/cryopod/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "CryopodConsole", name, 400, 480)
|
||||
ui = new(user, src, "CryopodConsole", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/computer/cryopod/ui_data(mob/user)
|
||||
|
||||
@@ -664,10 +664,13 @@ GLOBAL_LIST_EMPTY(airlock_emissive_underlays)
|
||||
/obj/machinery/door/airlock/attack_ai(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/door/airlock/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/door/airlock/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/door/airlock/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AiAirlock", name, 600, 400, master_ui, state)
|
||||
ui = new(user, src, "AiAirlock", name)
|
||||
ui.open()
|
||||
|
||||
|
||||
|
||||
@@ -40,10 +40,13 @@
|
||||
|
||||
|
||||
// tgui\packages\tgui\interfaces\AirlockElectronics.js
|
||||
/obj/item/airlock_electronics/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.inventory_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/item/airlock_electronics/ui_state(mob/user)
|
||||
return GLOB.inventory_state
|
||||
|
||||
/obj/item/airlock_electronics/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "AirlockElectronics", name, 450, 575, master_ui, state)
|
||||
ui = new(user, src, "AirlockElectronics", name)
|
||||
ui.open()
|
||||
|
||||
/obj/item/airlock_electronics/ui_data(mob/user)
|
||||
|
||||
@@ -295,10 +295,13 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/door_timer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/door_timer/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/door_timer/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "BrigTimer", name, 500, 450, master_ui, state)
|
||||
ui = new(user, src, "BrigTimer", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/door_timer/ui_static_data(mob/user)
|
||||
|
||||
@@ -163,10 +163,13 @@ GLOBAL_LIST_EMPTY(doppler_arrays)
|
||||
else
|
||||
stat |= NOPOWER
|
||||
|
||||
/obj/machinery/doppler_array/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)
|
||||
/obj/machinery/doppler_array/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/doppler_array/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "TachyonArray", name, 500, 600, master_ui, state)
|
||||
ui = new(user, src, "TachyonArray", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/doppler_array/ui_data(mob/user)
|
||||
|
||||
@@ -50,18 +50,17 @@
|
||||
if(.)
|
||||
return
|
||||
|
||||
var/dat
|
||||
dat = replacetext(file2text('html/chess.html'), "\[hsrc]", UID())
|
||||
var/datum/asset/simple/chess/assets = get_asset_datum(/datum/asset/simple/chess)
|
||||
assets.send(user)
|
||||
var/datum/asset/chess_asset = get_asset_datum(/datum/asset/group/chess)
|
||||
chess_asset.send(user)
|
||||
|
||||
var/dat = replacetext(file2text('html/chess.html'), "\[hsrc]", UID())
|
||||
var/datum/browser/popup = new(user, "SpessChess", name, 500, 800, src)
|
||||
popup.set_content(dat)
|
||||
popup.add_stylesheet("chess.css", 'html/browser/chess.css')
|
||||
popup.add_script("garbochess.js", 'html/browser/garbochess.js')
|
||||
//popup.add_script("boardui.js", 'html/browser/boardui.js')
|
||||
popup.add_script("jquery-1.8.2.min.js", 'html/browser/jquery-1.8.2.min.js')
|
||||
popup.add_script("jquery-ui-1.8.24.custom.min.js", 'html/browser/jquery-ui-1.8.24.custom.min.js')
|
||||
popup.add_stylesheet("chess", 'html/browser/chess.css')
|
||||
popup.add_script("boardui", 'html/browser/boardui.js')
|
||||
popup.add_script("garbochess", 'html/browser/garbochess.js')
|
||||
popup.add_script("jquery-1.8.2.min", 'html/browser/jquery-1.8.2.min.js')
|
||||
popup.add_script("jquery-ui-1.8.24.custom.min", 'html/browser/jquery-ui-1.8.24.custom.min.js')
|
||||
popup.set_window_options("titlebar=0")
|
||||
popup.open()
|
||||
user.set_machine(src)
|
||||
@@ -72,7 +71,6 @@
|
||||
if(user.client && user.machine == src) // I will look for you,
|
||||
user.unset_machine() // I will find you,
|
||||
user << browse(null, "window=SpessChess") // And I will kill you.
|
||||
return
|
||||
|
||||
/obj/machinery/gameboard/Topic(href, list/href_list)
|
||||
. = ..()
|
||||
|
||||
@@ -80,12 +80,14 @@
|
||||
return
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/computer/guestpass/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)
|
||||
/obj/machinery/computer/guestpass/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/computer/guestpass/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "GuestPass", name, 500, 850, master_ui, state)
|
||||
ui = new(user, src, "GuestPass", name)
|
||||
ui.open()
|
||||
ui.set_autoupdate(FALSE)
|
||||
|
||||
/obj/machinery/computer/guestpass/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
@@ -193,7 +193,6 @@ GLOBAL_LIST_EMPTY(holopads)
|
||||
var/area/area = get_area(src)
|
||||
var/datum/browser/popup = new(user, "holopad", "[area] holopad", 400, 300)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(icon, icon_state))
|
||||
popup.open()
|
||||
|
||||
/obj/machinery/hologram/holopad/Topic(href, href_list)
|
||||
|
||||
@@ -189,13 +189,13 @@
|
||||
|
||||
/obj/machinery/ui_status(mob/user, datum/ui_state/state)
|
||||
if(!interact_offline && (stat & (NOPOWER|BROKEN)))
|
||||
return STATUS_CLOSE
|
||||
return UI_CLOSE
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/ui_status(mob/user, datum/ui_state/state)
|
||||
if(!interact_offline && (stat & (NOPOWER|BROKEN)))
|
||||
return STATUS_CLOSE
|
||||
return UI_CLOSE
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -237,10 +237,13 @@
|
||||
if(magnets.len == 0 && autolink)
|
||||
link_magnets()
|
||||
|
||||
/obj/machinery/magnetic_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)
|
||||
/obj/machinery/magnetic_controller/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/magnetic_controller/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "MagnetController", name, 400, 600)
|
||||
ui = new(user, src, "MagnetController", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/magnetic_controller/attack_ai(mob/user as mob)
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
/obj/machinery/economy/merch/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/economy/merch/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/machinery/economy/merch/Initialize(mapload)
|
||||
. = ..()
|
||||
component_parts = list()
|
||||
@@ -74,10 +77,13 @@
|
||||
user.put_in_hands(D)
|
||||
SSeconomy.total_vendor_transactions++
|
||||
|
||||
/obj/machinery/economy/merch/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/economy/merch/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/economy/merch/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "MerchVendor", name, 450, 500, master_ui, state)
|
||||
ui = new(user, src, "MerchVendor", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/economy/merch/ui_data(mob/user)
|
||||
|
||||
@@ -161,10 +161,13 @@
|
||||
linkedmist.Cut()
|
||||
|
||||
|
||||
/obj/machinery/poolcontroller/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = TRUE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
/obj/machinery/poolcontroller/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/machinery/poolcontroller/ui_interact(mob/user, datum/tgui/ui = null)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "PoolController", "Pool Controller Interface", 520, 410)
|
||||
ui = new(user, src, "PoolController", "Pool Controller Interface")
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/poolcontroller/proc/temp_to_str(temp)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user