diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ef0d97119409..414e78d92ae6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -58,11 +58,6 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' - - name: Setup Cache - uses: actions/cache@v3 - with: - path: $HOME/spaceman_dmm/$SPACEMAN_DMM_VERSION - key: ${{ runner.os }}-spacemandmm-${{ env.SPACEMAN_DMM_VERSION }} - name: Install OpenDream uses: robinraju/release-downloader@v1.9 with: @@ -71,7 +66,7 @@ jobs: fileName: "DMCompiler_linux-x64.tar.gz" extract: true - name: Run OpenDream - run: ./DMCompiler_linux-x64/DMCompiler nebula.dme --suppress-unimplemented --skip-anything-typecheck --version=${BYOND_MAJOR}.${BYOND_MINOR} | python tools/od_annotator/__main__.py "$@" + run: ./DMCompiler_linux-x64/DMCompiler nebula.dme --define=UNIT_TEST --suppress-unimplemented --skip-anything-typecheck --version=${BYOND_MAJOR}.${BYOND_MINOR} | bash test/annotate_od.sh Code: runs-on: ubuntu-22.04 steps: diff --git a/code/__defines/MC.dm b/code/__defines/MC.dm index ddc5a1c7516f..f01b2f954289 100644 --- a/code/__defines/MC.dm +++ b/code/__defines/MC.dm @@ -24,7 +24,7 @@ if (Datum.is_processing) {\ if(Datum.is_processing != #Processor)\ {\ - PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occured on [#Processor]."); \ + PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occurred on [#Processor]."); \ }\ } else {\ Datum.is_processing = Processor._internal_name;\ @@ -36,7 +36,7 @@ if(Datum.is_processing) {\ if(Processor.processing.Remove(Datum)) {\ Datum.is_processing = null;\ } else {\ - PRINT_STACK_TRACE("Failed to stop processing. [log_info_line(Datum)] is being processed by [Datum.is_processing] but de-queue attempt occured on [#Processor]."); \ + PRINT_STACK_TRACE("Failed to stop processing. [log_info_line(Datum)] is being processed by [Datum.is_processing] but de-queue attempt occurred on [#Processor]."); \ }\ } diff --git a/code/__defines/bodytype.dm b/code/__defines/bodytype.dm index a44b77cc47ff..ca9dccfe6082 100644 --- a/code/__defines/bodytype.dm +++ b/code/__defines/bodytype.dm @@ -18,7 +18,7 @@ // Bodytype feature flags /// Does not create DNA. Replaces SPECIES_FLAG_NO_SCAN. #define BODY_FLAG_NO_DNA BITFLAG(0) -/// Cannot suffer halloss/recieves deceptive health indicator. +/// Cannot suffer halloss/receives deceptive health indicator. #define BODY_FLAG_NO_PAIN BITFLAG(1) /// Cannot eat food/drink drinks even if a stomach organ is present. #define BODY_FLAG_NO_EAT BITFLAG(2) diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm index 169309b2dfdc..5e04e9499632 100644 --- a/code/__defines/flags.dm +++ b/code/__defines/flags.dm @@ -86,6 +86,7 @@ The latter will result in a linter warning and will not work correctly. #define ITEM_FLAG_PADDED BITFLAG(13) // When set on gloves, will act like pulling punches in unarmed combat. #define ITEM_FLAG_CAN_TAPE BITFLAG(14) // Whether the item can be taped onto something using tape #define ITEM_FLAG_IS_WEAPON BITFLAG(15) // Item is considered a weapon. Currently only used for force-based worth calculation. +#define ITEM_FLAG_MAGNETISED BITFLAG(16) // When worn on feet and standing on an appropriate spot, will prevent slipping. // Flags for pass_flags (/atom/var/pass_flags) #define PASS_FLAG_TABLE BITFLAG(0) diff --git a/code/__defines/hud.dm b/code/__defines/hud.dm index 7cb67e0fd28a..3353b89d20ae 100644 --- a/code/__defines/hud.dm +++ b/code/__defines/hud.dm @@ -1,23 +1,31 @@ -// Keys used to set and retrieve icons from the UI decl system. -#define UI_ICON_INTERACTION "icon_interaction" -#define UI_ICON_ZONE_SELECT "icon_zone_sel" -#define UI_ICON_MOVEMENT "icon_movement" -#define UI_ICON_INVENTORY "icon_inventory" -#define UI_ICON_ATTACK "icon_attack" -#define UI_ICON_HANDS "icon_hands" -#define UI_ICON_INTERNALS "icon_internals" -#define UI_ICON_HEALTH "icon_health" -#define UI_ICON_CRIT_MARKER "icon_crit_marker" -#define UI_ICON_NUTRITION "icon_nutrition" -#define UI_ICON_HYDRATION "icon_hydration" -#define UI_ICON_FIRE_INTENT "icon_fire_intent" -#define UI_ICON_UP_HINT "icon_uphint" -#define UI_ICON_STATUS "icon_status" -#define UI_ICON_STATUS_FIRE "icon_status_fire" -#define UI_ICON_CHARGE "icon_charge" +// Keys used to create HUD elements, and to set and retrieve icons from the UI decl system. +#define HUD_STAMINA /decl/hud_element/stamina +#define HUD_DROP /decl/hud_element/drop +#define HUD_RESIST /decl/hud_element/resist +#define HUD_THROW /decl/hud_element/throw_toggle +#define HUD_MANEUVER /decl/hud_element/maneuver +#define HUD_ZONE_SELECT /decl/hud_element/zone_selector +#define HUD_MOVEMENT /decl/hud_element/movement +#define HUD_INVENTORY /decl/hud_element/inventory +#define HUD_ATTACK /decl/hud_element/attack +#define HUD_HANDS /decl/hud_element/hands +#define HUD_INTERNALS /decl/hud_element/internals +#define HUD_HEALTH /decl/hud_element/health +#define HUD_INTENT /decl/hud_element/intent +#define HUD_CRIT_MARKER /decl/hud_element/crit +#define HUD_NUTRITION /decl/hud_element/nutrition +#define HUD_HYDRATION /decl/hud_element/hydration +#define HUD_FIRE_INTENT /decl/hud_element/gun_mode +#define HUD_UP_HINT /decl/hud_element/upward +#define HUD_BODYTEMP /decl/hud_element/bodytemp +#define HUD_PRESSURE /decl/hud_element/pressure +#define HUD_TOX /decl/hud_element/toxins +#define HUD_OXY /decl/hud_element/oxygen +#define HUD_FIRE /decl/hud_element/fire +#define HUD_CHARGE /decl/hud_element/charge +#define HUD_ROBOT_MODULE /decl/hud_element/module_selection #define GET_HUD_ALERT(M, A) ((istype(M?.hud_used, /datum/hud) && (A in M.hud_used.alerts)) ? M.hud_used.alerts[A] : 0) - #define CLEAR_HUD_ALERTS(M) if(istype(M?.hud_used, /datum/hud) && M.hud_used.alerts) { M.hud_used.alerts = null; } #define SET_HUD_ALERT(M, A, V) if(istype(M?.hud_used, /datum/hud)) { LAZYSET(M.hud_used.alerts, A, V); } #define SET_HUD_ALERT_MIN(M, A, V) if(istype(M?.hud_used, /datum/hud) && V < LAZYACCESS(M.hud_used.alerts, A)) { LAZYSET(M.hud_used.alerts, A, V); } diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index d6591b17acf4..b7018659403b 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -155,7 +155,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called #define PART_CARD /obj/item/stock_parts/computer/card_slot // ID Card slot component of this computer. Mostly for HoP modification console that needs ID slot for modification. #define PART_PRINTER /obj/item/stock_parts/computer/nano_printer // Nano Printer component of this computer, for your everyday paperwork needs. #define PART_DRIVE /obj/item/stock_parts/computer/hard_drive/portable // Portable data storage -#define PART_AI /obj/item/stock_parts/computer/ai_slot // AI slot, an intellicard housing that allows modifications of AIs. +#define PART_AI /obj/item/stock_parts/computer/ai_slot // AI slot, an intelliCard housing that allows modifications of AIs. #define PART_TESLA /obj/item/stock_parts/computer/tesla_link // Tesla Link, Allows remote charging from nearest APC. #define PART_SCANNER /obj/item/stock_parts/computer/scanner // One of several optional scanner attachments. #define PART_D_SLOT /obj/item/stock_parts/computer/drive_slot // Portable drive slot. diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 55fbbecd14d4..85583c6cedf8 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -142,6 +142,11 @@ #define CONFIG_SERVER_JOIN_WHITELIST 3 #define CONFIG_SERVER_CONNECT_WHITELIST 4 +// Coating name color config enums +#define CONFIG_COATING_COLOR_NONE 1 +#define CONFIG_COATING_COLOR_MIXTURE 2 +#define CONFIG_COATING_COLOR_COMPONENTS 3 + // Location for server whitelist file to load from. #define CONFIG_SERVER_WHITELIST_FILE "config/server_whitelist.txt" @@ -252,6 +257,7 @@ //Inserts 'a' or 'an' before X in ways \a doesn't allow #define ADD_ARTICLE(X) "[(lowertext(X[1]) in global.vowels) ? "an" : "a"] [X]" +#define ADD_ARTICLE_GENDER(X, GENDER) (GENDER == PLURAL ? "some [X]" : ADD_ARTICLE(X)) //Request Console Department Types #define RC_ASSIST 1 //Request Assistance @@ -376,5 +382,11 @@ #define CRAYON_DRAW_LETTER "letter" #define CRAYON_DRAW_ARROW "arrow" +// Enum for results of is_space_movement_permitted() +#define SPACE_MOVE_SUPPORTED (-1) +#define SPACE_MOVE_FORBIDDEN 0 +#define SPACE_MOVE_PERMITTED 1 + // Default UI style applied to client prefs. #define DEFAULT_UI_STYLE /decl/ui_style/midnight + diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 022c6011a7ad..00633e438b2f 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -272,8 +272,6 @@ #define SPECIES_HUMAN "Human" #define SPECIES_MONKEY "Monkey" -#define SPECIES_ALIEN "Humanoid" -#define SPECIES_GOLEM "Golem" #define SURGERY_CLOSED 0 #define SURGERY_OPEN 1 diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 13861c4d9f5d..127f3b2d1149 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -43,14 +43,14 @@ #define SS_INIT_OVERLAY 1 #define SS_INIT_DEFAULT 0 #define SS_INIT_AIR -1 -#define SS_INIT_VIS_CONTENTS -2 -#define SS_INIT_MISC_LATE -3 -#define SS_INIT_MISC_CODEX -4 -#define SS_INIT_ALARM -5 -#define SS_INIT_SHUTTLE -6 -#define SS_INIT_GOALS -7 -#define SS_INIT_LIGHTING -8 -#define SS_INIT_WEATHER -9 +#define SS_INIT_MISC_LATE -2 +#define SS_INIT_MISC_CODEX -3 +#define SS_INIT_ALARM -4 +#define SS_INIT_SHUTTLE -5 +#define SS_INIT_GOALS -6 +#define SS_INIT_LIGHTING -7 +#define SS_INIT_WEATHER -8 +#define SS_INIT_VIS_CONTENTS -9 #define SS_INIT_ZCOPY -10 #define SS_INIT_HOLOMAP -11 #define SS_INIT_XENOARCH -12 diff --git a/code/_helpers/animations.dm b/code/_helpers/animations.dm index be0d2188f5a3..e549a677f797 100644 --- a/code/_helpers/animations.dm +++ b/code/_helpers/animations.dm @@ -69,11 +69,20 @@ animate(time = 1) animate(alpha = 0, time = 3, easing = CIRCULAR_EASING|EASE_OUT) +// Shake animation stolen from Polaris. +/atom + /// How much to shake the atom when struck. + /// Larger objs should have smaller numbers or it looks weird. + var/shake_animation_degrees = 4 + /atom/proc/shake_animation(var/intensity = 8) var/init_px = pixel_x var/shake_dir = pick(-1, 1) - animate(src, transform=turn(matrix(), intensity*shake_dir), pixel_x=init_px + 2*shake_dir, time=1) - animate(transform=null, pixel_x=init_px, time=6, easing=ELASTIC_EASING) + var/matrix/M = matrix() + M.Scale(icon_scale_x, icon_scale_y) + M.Translate(0, 16*(icon_scale_y-1)) + animate(src, transform=turn(M, shake_animation_degrees * shake_dir), pixel_x=init_px + 2*shake_dir, time=1) + animate(transform=M, pixel_x=init_px, time=6, easing=ELASTIC_EASING) /atom/proc/SpinAnimation(speed = 10, loops = -1, clockwise = 1, segments = 3, parallel = TRUE) if(!segments) diff --git a/code/_helpers/mobs.dm b/code/_helpers/mobs.dm index 5360486eec8a..6c040f5a57c9 100644 --- a/code/_helpers/mobs.dm +++ b/code/_helpers/mobs.dm @@ -40,7 +40,7 @@ var/user_loc = user.loc var/drifting = 0 - if(!user.Process_Spacemove(0) && user.inertia_dir) + if(user.is_space_movement_permitted() == SPACE_MOVE_FORBIDDEN && user.inertia_dir) drifting = 1 var/target_loc = target.loc @@ -101,7 +101,7 @@ var/atom/original_loc = user.loc var/drifting = 0 - if(!user.Process_Spacemove(0) && user.inertia_dir) + if(user.is_space_movement_permitted() == SPACE_MOVE_FORBIDDEN && user.inertia_dir) drifting = 1 var/holding = user.get_active_held_item() diff --git a/code/_helpers/text.dm b/code/_helpers/text.dm index e25429b8fe50..103e0b49b97f 100644 --- a/code/_helpers/text.dm +++ b/code/_helpers/text.dm @@ -84,7 +84,7 @@ //Run sanitize(), but remove <, >, " first to prevent displaying them as > < &34; in some places after html_encode(). //Best used for sanitize object names, window titles. -//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entites - +//If you have a problem with sanitize() in chat, when quotes and >, < are displayed as html entities - //this is a problem of double-encode(when & becomes &), use sanitize() with encode=0, but not the sanitize_safe()! /proc/sanitize_safe(input, max_length = MAX_MESSAGE_LEN, encode = TRUE, trim = TRUE, extra = TRUE, ascii_only = FALSE) return sanitize(replace_characters(input, list(">"=" ","<"=" ", "\""="'")), max_length, encode, trim, extra, ascii_only) diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 88f8f402528e..02c769ae10af 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -275,7 +275,7 @@ Turf and target are seperate in case you want to teleport some distance from a t return 0 return 1 -//Ensure the frequency is within bounds of what it should be sending/recieving at +//Ensure the frequency is within bounds of what it should be sending/receiving at /proc/sanitize_frequency(var/f, var/low = PUBLIC_LOW_FREQ, var/high = PUBLIC_HIGH_FREQ) return clamp(round(f), low, high) diff --git a/code/_helpers/visual_filters.dm b/code/_helpers/visual_filters.dm index 10e485e18543..6c4f9939736e 100644 --- a/code/_helpers/visual_filters.dm +++ b/code/_helpers/visual_filters.dm @@ -1,15 +1,18 @@ -// These involve BYOND's built in filters that do visual effects, and not stuff that distinguishes between things. +// These involve BYOND's built-in filters that do visual effects, and not stuff that distinguishes between things. // All of this ported from TG. // And then ported to Nebula from Polaris. /atom/movable - var/list/filter_data // For handling persistent filters + VAR_PRIVATE/list/filter_data // For handling persistent filters // Defining this for future proofing and ease of searching for erroneous usage. /image/proc/add_filter(filter_name, priority, list/params) filters += filter(arglist(params)) return TRUE +/atom/movable/proc/has_filter(filter_name) + return (name in filter_data) + /atom/movable/proc/add_filter(filter_name, priority, list/params, force_update = FALSE) // Check if we already have a filter and hence don't need to rebuild filters. diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 90653cccc970..372ede052d3c 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -41,7 +41,7 @@ After that, mostly just check your state, check whether you're holding an item, check whether you're adjacent to the target, then pass off the click to whoever - is recieving it. + is receiving it. The most common are: * mob/UnarmedAttack(atom,adjacent) - used here only when adjacent, with no item in hand; in the case of humans, checks gloves * atom/attackby(item,user) - used only when adjacent diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index ec0965a969f3..9102b1b0e88e 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -1,6 +1,6 @@ /* The below procs are called on the atom you're dragging. In a lot of circumstances we want to use the - recieving object instead, so that's the default action. This allows you to drag + receiving object instead, so that's the default action. This allows you to drag almost anything into a trash can. */ diff --git a/code/_onclick/hud/_defines.dm b/code/_onclick/hud/_defines.dm index 5ac7ac42bd02..41016eea0b09 100644 --- a/code/_onclick/hud/_defines.dm +++ b/code/_onclick/hud/_defines.dm @@ -32,17 +32,13 @@ #define ui_storage1 "RIGHT-3:16,BOTTOM:5" #define ui_storage2 "RIGHT-4:16,BOTTOM:5" -#define ui_alien_head "CENTER-3:12,BOTTOM:5" //aliens -#define ui_alien_oclothing "CENTER-2:14,BOTTOM:5"//aliens - -#define ui_inv1 "CENTER-1,BOTTOM:5" //borgs -#define ui_inv2 "CENTER,BOTTOM:5" //borgs -#define ui_inv3 "CENTER+1,BOTTOM:5" //borgs -#define ui_borg_store "CENTER+2,BOTTOM:5" //borgs -#define ui_borg_inventory "CENTER-2,BOTTOM:5"//borgs -#define ui_borg_drop_grab "CENTER-3,BOTTOM:5"//borgs -#define ui_monkey_mask "LEFT+4:14,BOTTOM:5" //monkey -#define ui_monkey_back "LEFT+5:14,BOTTOM:5" //monkey +// Robot defines. +#define ui_inv1 "CENTER-1,BOTTOM:21" +#define ui_inv2 "CENTER,BOTTOM:21" +#define ui_inv3 "CENTER+1,BOTTOM:21" +#define ui_borg_store "CENTER+2,BOTTOM:21" +#define ui_borg_inventory "CENTER-2,BOTTOM:21" +#define ui_borg_drop_grab "CENTER-3,BOTTOM:21" #define ui_construct_health "RIGHT:00,CENTER:15" //same height as humans, hugging the right border #define ui_construct_fire "RIGHT-1:16,CENTER+1:13" //above health, slightly to the left @@ -57,18 +53,17 @@ #define ui_attack_selector "RIGHT-2:27,BOTTOM+2:9" #define ui_zonesel "RIGHT-1:28,BOTTOM:5" #define ui_acti_alt "RIGHT-1:28,BOTTOM:5" //alternative intent switcher for when the interface is hidden -#define ui_stamina "RIGHT-3:24,BOTTOM+1:5" +#define ui_stamina "RIGHT-2:24,BOTTOM:8" #define ui_borg_pull "RIGHT-3:24,BOTTOM+1:7" #define ui_borg_module "RIGHT-2:26,BOTTOM+1:7" #define ui_borg_panel "RIGHT-1:28,BOTTOM+1:7" //Gun buttons -#define ui_gun1 "RIGHT-2:26,BOTTOM+2:7" -#define ui_gun2 "RIGHT-1:28, BOTTOM+3:7" -#define ui_gun3 "RIGHT-2:26,BOTTOM+3:7" +#define ui_gun1 "RIGHT-1:28,BOTTOM+3:7" +#define ui_gun2 "RIGHT-2:28,BOTTOM+3:7" +#define ui_gun3 "RIGHT-3:28,BOTTOM+3:7" #define ui_gun_select "RIGHT-1:28,BOTTOM+2:7" -#define ui_gun4 "RIGHT-3:24,BOTTOM+2:7" //Upper-middle right (damage indicators and up hint) #define ui_up_hint "RIGHT-1:28,TOP-1:29" @@ -87,9 +82,9 @@ #define ui_temp "RIGHT-1:28,CENTER-1:13" #define ui_health "RIGHT-1:28,CENTER:15" #define ui_internal "RIGHT-1:28,CENTER+1:17" - //borgs -#define ui_borg_health "RIGHT-1:28,CENTER-1:13" //borgs have the health display where humans have the pressure damage indicator. -#define ui_alien_health "RIGHT-1:28,CENTER-1:13" //aliens have the health display where humans have the pressure damage indicator. + +// Robots have the health display where humans have the pressure damage indicator. +#define ui_borg_health "RIGHT-1:28,CENTER-1:13" //Pop-up inventory #define ui_shoes "LEFT+1:8,BOTTOM:5" @@ -105,22 +100,6 @@ #define ui_head "LEFT+1:8,BOTTOM+3:11" -//Intent small buttons -#define ui_help_small "RIGHT-3:8,BOTTOM:1" -#define ui_disarm_small "RIGHT-3:15,BOTTOM:18" -#define ui_grab_small "RIGHT-3:32,BOTTOM:18" -#define ui_harm_small "RIGHT-3:39,BOTTOM:1" - -//#define ui_swapbutton "6:-16,1:5" //Unused - -//#define ui_headset "BOTTOM,8" -#define ui_hand "CENTER-1:14,BOTTOM:5" -#define ui_hstore1 "CENTER-2,CENTER-2" -//#define ui_resist "RIGHT+1,BOTTOM-1" -#define ui_sleep "RIGHT+1, TOP-13" -#define ui_rest "RIGHT+1, TOP-14" - - #define ui_iarrowleft "BOTTOM-1,RIGHT-4" #define ui_iarrowright "BOTTOM-1,RIGHT-2" diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index e122262cdb96..54ff72145076 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -34,6 +34,12 @@ /datum/action/Destroy() if(owner) Remove(owner) + QDEL_NULL(button) + if(target) + var/obj/item/target_item = target + if(istype(target_item) && target_item.action == src) + target_item.action = null + target = null return ..() /datum/action/proc/SetTarget(var/atom/Target) diff --git a/code/_onclick/hud/ai.dm b/code/_onclick/hud/ai.dm deleted file mode 100644 index 651c4d1e007f..000000000000 --- a/code/_onclick/hud/ai.dm +++ /dev/null @@ -1,11 +0,0 @@ -/mob/living/silicon/ai - hud_used = /datum/hud/ai - -/datum/hud/ai - action_intent_type = null // no selector - -/datum/hud/ai/FinalizeInstantiation() - var/list/ai_hud_data = decls_repository.get_decls_of_subtype(/decl/ai_hud) - for(var/elem_type in ai_hud_data) - adding += new /obj/screen/ai_button(null, mymob, null, null, null, null, ai_hud_data[elem_type]) - ..() diff --git a/code/_onclick/hud/animal.dm b/code/_onclick/hud/animal.dm deleted file mode 100644 index 8b372aabdcc6..000000000000 --- a/code/_onclick/hud/animal.dm +++ /dev/null @@ -1,14 +0,0 @@ - -/mob/living/simple_animal - hud_used = /datum/hud/animal - -/datum/hud/animal/FinalizeInstantiation() - - var/ui_style = get_ui_style_data() - var/ui_color = get_ui_color() - var/ui_alpha = get_ui_alpha() - - move_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_MOVEMENT) - move_intent.icon_state = mymob.move_intent.hud_icon_state - adding += move_intent - ..() diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm deleted file mode 100644 index 48829da57dda..000000000000 --- a/code/_onclick/hud/hud.dm +++ /dev/null @@ -1,436 +0,0 @@ -/* - The hud datum - Used to show and hide huds for all the different mob types, - including inventories and item quick actions. -*/ - -/mob - var/datum/hud/hud_used - -/mob/proc/InitializeHud() - if(istype(hud_used)) - QDEL_NULL(hud_used) - hud_used = initial(hud_used) - if(ispath(hud_used)) - hud_used = new hud_used(src) - if(istype(hud_used)) - hud_used.refresh_hud_icons() - refresh_lighting_master() - -/datum/hud - var/mob/mymob - - var/hud_shown = 1 //Used for the HUD toggle (F12) - var/inventory_shown = TRUE //the inventory - var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) - - var/default_ui_style = DEFAULT_UI_STYLE - - var/list/alerts - - var/list/hand_hud_objects - var/list/swaphand_hud_objects - var/obj/screen/movement/move_intent - var/obj/screen/stamina/stamina_bar - - var/action_intent_type = /obj/screen/intent - var/obj/screen/intent/action_intent - - var/list/adding = list() - var/list/other = list() - var/list/hud_elements = list() - var/list/obj/screen/hotkeybuttons - - var/obj/screen/action_button/hide_toggle/hide_actions_toggle - var/action_buttons_hidden = FALSE - -/datum/hud/New(mob/owner) - mymob = owner - instantiate() - ..() - -/datum/hud/proc/refresh_hud_icons() - for(var/obj/screen/elem in mymob?.client?.screen) - elem.queue_icon_update() - -/datum/hud/Destroy() - . = ..() - stamina_bar = null - action_intent = null - move_intent = null - adding = null - other = null - hotkeybuttons = null - mymob = null - QDEL_NULL_LIST(hand_hud_objects) - QDEL_NULL_LIST(swaphand_hud_objects) - -/datum/hud/proc/update_stamina() - if(mymob && stamina_bar) - stamina_bar.set_invisibility(INVISIBILITY_MAXIMUM) - var/stamina = mymob.get_stamina() - if(stamina < 100) - stamina_bar.set_invisibility(INVISIBILITY_NONE) - stamina_bar.icon_state = "prog_bar_[floor(stamina/5)*5][(stamina >= 5) && (stamina <= 25) ? "_fail" : null]" - -/datum/hud/proc/hide_inventory() - inventory_shown = FALSE - hidden_inventory_update() - persistent_inventory_update() - -/datum/hud/proc/show_inventory() - inventory_shown = TRUE - hidden_inventory_update() - persistent_inventory_update() - -/datum/hud/proc/hidden_inventory_update() - var/decl/species/species = mymob?.get_species() - if(istype(species?.species_hud)) - refresh_inventory_slots(species.species_hud.hidden_slots, (inventory_shown && hud_shown)) - -/datum/hud/proc/persistent_inventory_update() - var/decl/species/species = mymob?.get_species() - if(istype(species?.species_hud)) - refresh_inventory_slots(species.species_hud.persistent_slots, hud_shown) - -/datum/hud/proc/refresh_inventory_slots(var/list/checking_slots, var/show_hud) - - for(var/slot in checking_slots) - - var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(slot) - if(!istype(inv_slot)) - continue - - // Check if we're even wearing anything in that slot. - var/obj/item/gear = inv_slot.get_equipped_item() - if(!istype(gear)) - continue - - // We're not showing anything, hide it. - gear.reconsider_client_screen_presence(mymob?.client, slot) - if(!show_hud) - inv_slot.hide_slot() - else - inv_slot.show_slot() - -/datum/hud/proc/instantiate() - if(ismob(mymob) && mymob.client) - FinalizeInstantiation() - return TRUE - return FALSE - -/datum/hud/proc/FinalizeInstantiation() - - SHOULD_CALL_PARENT(TRUE) - - if(!action_intent && action_intent_type) // Everyone needs an intent selector. - action_intent = new action_intent_type(null, mymob) - adding |= action_intent - hud_elements |= action_intent - - BuildInventoryUI() - BuildHandsUI() - - if(mymob.client) - mymob.client.screen = list() - if(length(hand_hud_objects)) - mymob.client.screen |= hand_hud_objects - if(length(swaphand_hud_objects)) - mymob.client.screen |= swaphand_hud_objects - if(length(hud_elements)) - mymob.client.screen |= hud_elements - if(length(adding)) - mymob.client.screen |= adding - if(length(hotkeybuttons)) - mymob.client.screen |= hotkeybuttons - - hide_inventory() - -/datum/hud/proc/get_ui_style_data() - RETURN_TYPE(/decl/ui_style) - . = GET_DECL(mymob?.client?.prefs?.UI_style) || GET_DECL(default_ui_style) - if(!.) - var/list/available_styles = get_ui_styles() - if(length(available_styles)) - . = available_styles[1] - -/datum/hud/proc/get_ui_color() - var/decl/ui_style/ui_style = get_ui_style_data() - if(!ui_style?.use_ui_color) - return COLOR_WHITE - return mymob?.client?.prefs?.UI_style_color || COLOR_WHITE - -/datum/hud/proc/get_ui_alpha() - return mymob?.client?.prefs?.UI_style_alpha || 255 - -/datum/hud/proc/rebuild_hands() - - var/decl/ui_style/ui_style = get_ui_style_data() - var/ui_color = get_ui_color() - var/ui_alpha = get_ui_alpha() - - // Build held item boxes for missing slots. - var/list/held_slots = mymob.get_held_item_slots() - - // Sort our slots for display. - var/list/gripper_datums = list() - for(var/hand_tag in held_slots) - gripper_datums += mymob.get_inventory_slot_datum(hand_tag) - gripper_datums = sortTim(gripper_datums, /proc/cmp_gripper_asc) - - for(var/datum/inventory_slot/gripper/inv_slot in gripper_datums) - - // Re-order the held slot list so it aligns with the display order. - var/hand_tag = inv_slot.slot_id - held_slots -= hand_tag - held_slots += hand_tag - - var/obj/screen/inventory/inv_box - for(var/obj/screen/inventory/existing_box in hand_hud_objects) - if(existing_box.slot_id == hand_tag) - inv_box = existing_box - break - - if(!inv_box) - inv_box = new /obj/screen/inventory/hand(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS) - else - inv_box.set_ui_style(ui_style, UI_ICON_HANDS) - inv_box.color = ui_color - inv_box.alpha = ui_alpha - - LAZYDISTINCTADD(hand_hud_objects, inv_box) - - inv_box.SetName(hand_tag) - inv_box.slot_id = hand_tag - inv_box.update_icon() - - // Clear held item boxes with no held slot. - for(var/obj/screen/inventory/inv_box in hand_hud_objects) - if(!(inv_box.slot_id in held_slots)) - if(mymob.client) - mymob.client.screen -= inv_box - LAZYREMOVE(hand_hud_objects, inv_box) - qdel(inv_box) - - // Rebuild offsets for the hand elements. - var/hand_y_offset = 21 - var/list/elements = hand_hud_objects?.Copy() - while(length(elements)) - var/copy_index = min(length(elements), 2)+1 - var/list/sublist = elements.Copy(1, copy_index) - elements.Cut(1, copy_index) - var/obj/screen/inventory/inv_box - if(length(sublist) == 1) - inv_box = sublist[1] - inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]" - else - inv_box = sublist[1] - inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]" - inv_box = sublist[2] - inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]" - hand_y_offset += world.icon_size - - if(mymob.client && islist(hand_hud_objects) && length(hand_hud_objects)) - mymob.client.screen |= hand_hud_objects - - // Make sure all held items are on the screen and set to the correct screen loc. - var/datum/inventory_slot/inv_slot - for(var/obj/inv_elem in hand_hud_objects) - inv_slot = mymob.get_inventory_slot_datum(inv_elem.name) - if(inv_slot) - inv_slot.ui_loc = inv_elem.screen_loc - var/obj/item/held = inv_slot.get_equipped_item() - if(held) - held.screen_loc = inv_slot.ui_loc - if(mymob.client) - mymob.client.screen |= held // just to make sure it's visible post-login - - if(length(swaphand_hud_objects)) - var/hand_x_offset = -(world.icon_size/2) - for(var/i = 1 to length(swaphand_hud_objects)) - var/obj/swap_elem = swaphand_hud_objects[i] - swap_elem.screen_loc = "CENTER:[hand_x_offset],BOTTOM:[hand_y_offset]" - if(i > 1) // first two elems share a slot - hand_x_offset += world.icon_size - if(mymob.client) - mymob.client.screen |= swap_elem - -/datum/hud/proc/BuildInventoryUI() - - var/decl/ui_style/ui_style = get_ui_style_data() - var/ui_color = get_ui_color() - var/ui_alpha = get_ui_alpha() - - var/has_hidden_gear = FALSE - - // Draw the various inventory equipment slots. - var/obj/screen/inventory/inv_box - var/list/held_slots = mymob.get_held_item_slots() - var/list/inventory_slots = mymob.get_inventory_slots() - for(var/gear_slot in inventory_slots) - - if(gear_slot in held_slots) - continue - - inv_box = new /obj/screen/inventory(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INVENTORY) - - var/datum/inventory_slot/inv_slot = inventory_slots[gear_slot] - inv_box.SetName(inv_slot.slot_name) - inv_box.slot_id = inv_slot.slot_id - inv_box.icon_state = inv_slot.slot_state - inv_box.screen_loc = inv_slot.ui_loc - - if(inv_slot.slot_dir) - inv_box.set_dir(inv_slot.slot_dir) - - if(inv_slot.can_be_hidden) - other += inv_box - has_hidden_gear = TRUE - else - adding += inv_box - - if(has_hidden_gear) - adding += new /obj/screen/toggle(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INVENTORY) - -/datum/hud/proc/BuildHandsUI() - - var/list/held_slots = mymob.get_held_item_slots() - if(length(held_slots) <= 0) - return - - var/decl/ui_style/ui_style = get_ui_style_data() - var/ui_color = get_ui_color() - var/ui_alpha = get_ui_alpha() - - // Swap hand and quick equip screen elems. - var/obj/screen/using = new /obj/screen/equip(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS) - adding += using - LAZYADD(swaphand_hud_objects, using) - - if(length(held_slots) > 1) - - using = new /obj/screen/inventory/swaphand(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS) - adding += using - LAZYADD(swaphand_hud_objects, using) - using = new /obj/screen/inventory/swaphand/right(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HANDS) - adding += using - LAZYADD(swaphand_hud_objects, using) - - // Actual hand elems. - rebuild_hands() - -/mob/verb/minimize_hud(full = FALSE as null) - set name = "Minimize Hud" - set hidden = TRUE - - if(isnull(hud_used)) - to_chat(usr, SPAN_WARNING("This mob type does not use a HUD.")) - return - - if(!client || !istype(hud_used)) - return - - if(hud_used.hud_shown) - hud_used.hud_shown = 0 - if(hud_used.adding) - client.screen -= hud_used.adding - if(hud_used.other) - client.screen -= hud_used.other - if(hud_used.hotkeybuttons) - client.screen -= hud_used.hotkeybuttons - - //Due to some poor coding some things need special treatment: - //These ones are a part of 'adding', 'other' or 'hotkeybuttons' but we want them to stay - if(!full) - if(LAZYLEN(hud_used.hand_hud_objects)) - client.screen += hud_used.hand_hud_objects // we want the hands to be visible - if(LAZYLEN(hud_used.swaphand_hud_objects)) - client.screen += hud_used.swaphand_hud_objects // we want the hands swap thingy to be visible - client.screen += hud_used.action_intent // we want the intent swticher visible - hud_used.action_intent.screen_loc = ui_acti_alt // move this to the alternative position, where zone_select usually is. - else - client.screen -= healths - client.screen -= internals - client.screen -= gun_setting_icon - - //These ones are not a part of 'adding', 'other' or 'hotkeybuttons' but we want them gone. - client.screen -= zone_sel //zone_sel is a mob variable for some reason. - - else - hud_used.hud_shown = 1 - if(hud_used.adding) - client.screen += hud_used.adding - if(hud_used.other && hud_used.inventory_shown) - client.screen += hud_used.other - if(hud_used.hotkeybuttons && !hud_used.hotkey_ui_hidden) - client.screen += hud_used.hotkeybuttons - if(healths) - client.screen |= healths - if(internals) - client.screen |= internals - if(gun_setting_icon) - client.screen |= gun_setting_icon - - hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position - client.screen += zone_sel //This one is a special snowflake - - hud_used.hidden_inventory_update() - hud_used.persistent_inventory_update() - update_action_buttons() - -//Similar to minimize_hud() but keeps zone_sel, gun_setting_icon, and healths. -/mob/proc/toggle_zoom_hud() - if(!istype(hud_used)) - return - if(!ishuman(src)) - return - if(!client) - return - if(client.view != world.view) - return - - if(hud_used.hud_shown) - hud_used.hud_shown = 0 - if(hud_used.adding) - client.screen -= hud_used.adding - if(hud_used.other) - client.screen -= hud_used.other - if(hud_used.hotkeybuttons) - client.screen -= hud_used.hotkeybuttons - client.screen -= internals - client.screen += hud_used.action_intent //we want the intent swticher visible - else - hud_used.hud_shown = 1 - if(hud_used.adding) - client.screen += hud_used.adding - if(hud_used.other && hud_used.inventory_shown) - client.screen += hud_used.other - if(hud_used.hotkeybuttons && !hud_used.hotkey_ui_hidden) - client.screen += hud_used.hotkeybuttons - if(internals) - client.screen |= internals - hud_used.action_intent.screen_loc = ui_acti //Restore intent selection to the original position - - hud_used.hidden_inventory_update() - hud_used.persistent_inventory_update() - update_action_buttons() - -/client/proc/reset_click_catchers() - - var/xmin = -(round(last_view_x_dim*0.5)) - var/xmax = last_view_x_dim - abs(xmin) - var/ymin = -(round(last_view_y_dim*0.5)) - var/ymax = last_view_y_dim - abs(ymin) - - var/list/click_catchers = get_click_catchers() - for(var/obj/screen/click_catcher/catcher in click_catchers) - if(catcher.x_offset <= xmin || catcher.x_offset >= xmax || catcher.y_offset <= ymin || catcher.y_offset >= ymax) - screen -= catcher - else - screen |= catcher - -/mob/proc/add_click_catcher() - client.reset_click_catchers() - -/mob/new_player/add_click_catcher() - return diff --git a/code/_onclick/hud/hud_elements/_hud_element.dm b/code/_onclick/hud/hud_elements/_hud_element.dm new file mode 100644 index 000000000000..6fce5a0eba1b --- /dev/null +++ b/code/_onclick/hud/hud_elements/_hud_element.dm @@ -0,0 +1,24 @@ +/decl/hud_element + abstract_type = /decl/hud_element + /// /obj/screen path to create + var/elem_type + /// Index value for /datum/hud; defaults to src.type if null + var/elem_reference_type + /// Adds element to hidable list (inventory) + var/elem_is_hidable = FALSE + /// Adds element to hotkey list + var/elem_is_hotkey = FALSE + /// Adds element to aux list (hidden by F12) + var/elem_is_auxilliary = TRUE + /// Updates element icon in mob Life() proc + var/elem_updates_in_life = FALSE + +/decl/hud_element/validate() + . = ..() + if(!ispath(elem_type, /obj/screen)) + . += "invalid elem_type ([elem_type || null]))" + +/decl/hud_element/Initialize() + . = ..() + if(isnull(elem_reference_type)) + elem_reference_type = type diff --git a/code/_onclick/hud/hud_elements/hud_auxilliary.dm b/code/_onclick/hud/hud_elements/hud_auxilliary.dm new file mode 100644 index 000000000000..42ae7a89178c --- /dev/null +++ b/code/_onclick/hud/hud_elements/hud_auxilliary.dm @@ -0,0 +1,42 @@ +/decl/hud_element/movement + elem_type = /obj/screen/movement + +/decl/hud_element/internals + elem_type = /obj/screen/internals + +/decl/hud_element/zone_selector + elem_type = /obj/screen/zone_selector + +/decl/hud_element/upward + elem_type = /obj/screen/look_upward + +/decl/hud_element/throw_toggle + elem_type = /obj/screen/throw_toggle + +/decl/hud_element/maneuver + elem_type = /obj/screen/maneuver + +/decl/hud_element/drop + elem_type = /obj/screen/drop + +/decl/hud_element/resist + elem_type = /obj/screen/resist + +/decl/hud_element/attack + elem_type = /obj/screen/default_attack_selector + +/decl/hud_element/stamina + elem_type = /obj/screen/stamina + elem_updates_in_life = TRUE + +/decl/hud_element/charge + elem_type = /obj/screen/need/cell_charge + elem_updates_in_life = TRUE + +/decl/hud_element/nutrition + elem_type = /obj/screen/need/nutrition + elem_updates_in_life = TRUE + +/decl/hud_element/hydration + elem_type = /obj/screen/need/hydration + elem_updates_in_life = TRUE diff --git a/code/_onclick/hud/hud_elements/hud_health.dm b/code/_onclick/hud/hud_elements/hud_health.dm new file mode 100644 index 000000000000..955c4d8d576c --- /dev/null +++ b/code/_onclick/hud/hud_elements/hud_health.dm @@ -0,0 +1,7 @@ +/decl/hud_element/health + elem_type = /obj/screen/health + elem_updates_in_life = TRUE + +/decl/hud_element/health/organs + elem_type = /obj/screen/health/organs + elem_reference_type = /decl/hud_element/health diff --git a/code/_onclick/hud/hud_elements/hud_permanent.dm b/code/_onclick/hud/hud_elements/hud_permanent.dm new file mode 100644 index 000000000000..518a698775ca --- /dev/null +++ b/code/_onclick/hud/hud_elements/hud_permanent.dm @@ -0,0 +1,3 @@ +/decl/hud_element/intent + elem_type = /obj/screen/intent + elem_is_auxilliary = FALSE diff --git a/code/_onclick/hud/hud_elements/hud_robot.dm b/code/_onclick/hud/hud_elements/hud_robot.dm new file mode 100644 index 000000000000..a47c9c7866f0 --- /dev/null +++ b/code/_onclick/hud/hud_elements/hud_robot.dm @@ -0,0 +1,62 @@ +/datum/hud/robot + gun_mode_toggle_type = /obj/screen/gun/mode + omit_hud_elements = list( + /decl/hud_element/health, + /decl/hud_element/charge, + /decl/hud_element/bodytemp, + /decl/hud_element/oxygen, + /decl/hud_element/toxins, + /decl/hud_element/pressure, + /decl/hud_element/nutrition, + /decl/hud_element/hydration, + /decl/hud_element/maneuver, + /decl/hud_element/movement, + /decl/hud_element/resist, + /decl/hud_element/drop, + /decl/hud_element/throw_toggle, + /decl/hud_element/internals, + ) + additional_hud_elements = list( + /decl/hud_element/health/robot, + /decl/hud_element/charge/robot, + /decl/hud_element/oxygen/robot, + /decl/hud_element/module_selection, + /decl/hud_element/robot_inventory, + /decl/hud_element/robot_radio, + /decl/hud_element/robot_panel, + /decl/hud_element/robot_store, + /decl/hud_element/robot_drop_grab + ) + +/decl/hud_element/oxygen/robot + elem_reference_type = /decl/hud_element/oxygen + elem_type = /obj/screen/warning/oxygen/robot + +/decl/hud_element/health/robot + elem_reference_type = /decl/hud_element/health + elem_type = /obj/screen/health/robot + +/decl/hud_element/charge/robot + elem_reference_type = /decl/hud_element/charge + elem_type = /obj/screen/need/cell_charge/robot + +/decl/hud_element/robot_inventory + elem_type = /obj/screen/robot/inventory + elem_is_auxilliary = FALSE + +/decl/hud_element/module_selection + elem_type = /obj/screen/robot/module/select + elem_is_auxilliary = FALSE + +/decl/hud_element/robot_radio + elem_type = /obj/screen/robot/radio + +/decl/hud_element/robot_panel + elem_type = /obj/screen/robot/panel + +/decl/hud_element/robot_store + elem_type = /obj/screen/robot/store + +/decl/hud_element/robot_drop_grab + elem_type = /obj/screen/robot/drop_grab + elem_updates_in_life = TRUE diff --git a/code/_onclick/hud/hud_elements/hud_stubs.dm b/code/_onclick/hud/hud_elements/hud_stubs.dm new file mode 100644 index 000000000000..261ae0d74e8b --- /dev/null +++ b/code/_onclick/hud/hud_elements/hud_stubs.dm @@ -0,0 +1,9 @@ +// Should not actually be used; defined for icon checks and HUD styles. +/decl/hud_element/inventory + elem_type = /obj/screen/inventory +/decl/hud_element/hands + elem_type = /obj/screen/inventory/hand +/decl/hud_element/crit + elem_type = /obj/screen +/decl/hud_element/gun_mode + elem_type = /obj/screen/gun diff --git a/code/_onclick/hud/hud_elements/hud_warnings.dm b/code/_onclick/hud/hud_elements/hud_warnings.dm new file mode 100644 index 000000000000..091aefa24c44 --- /dev/null +++ b/code/_onclick/hud/hud_elements/hud_warnings.dm @@ -0,0 +1,19 @@ +/decl/hud_element/fire + elem_type = /obj/screen/warning/fire + elem_updates_in_life = TRUE + +/decl/hud_element/oxygen + elem_type = /obj/screen/warning/oxygen + elem_updates_in_life = TRUE + +/decl/hud_element/toxins + elem_type = /obj/screen/warning/toxin + elem_updates_in_life = TRUE + +/decl/hud_element/bodytemp + elem_type = /obj/screen/warning/bodytemp + elem_updates_in_life = TRUE + +/decl/hud_element/pressure + elem_type = /obj/screen/warning/pressure + elem_updates_in_life = TRUE diff --git a/code/_onclick/hud/hud_types/_hud.dm b/code/_onclick/hud/hud_types/_hud.dm new file mode 100644 index 000000000000..d0a95fe197f5 --- /dev/null +++ b/code/_onclick/hud/hud_types/_hud.dm @@ -0,0 +1,591 @@ +/* + The hud datum + Used to show and hide huds for all the different mob types, + including inventories and item quick actions. +*/ + +/mob + var/datum/hud/hud_used + +/mob/proc/get_hud_element(hud_key) + if(!istype(hud_used)) + return FALSE + return hud_used.get_element(hud_key) + +/mob/proc/refresh_hud_element(hud_key) + if(!istype(hud_used)) + return FALSE + return hud_used.refresh_element(hud_key) + +/mob/proc/initialize_hud() + if(istype(hud_used)) + QDEL_NULL(hud_used) + hud_used = initial(hud_used) + if(ispath(hud_used)) + hud_used = new hud_used(src) + if(istype(hud_used)) + hud_used.refresh_hud_icons() + refresh_lighting_master() + +/datum/hud + /// A reference to our owning mob. + var/mob/mymob + /// Used for the HUD toggle (F12) + VAR_PRIVATE/hud_shown = TRUE + // Used for showing or hiding the equipment buttons on the left. + VAR_PRIVATE/inventory_shown = TRUE + /// This is to hide the buttons that can be used via hotkeys. (hud_elements_hotkeys list of buttons) + VAR_PRIVATE/hotkey_ui_hidden = FALSE + /// Defines an assumed default /decl/ui_style for elements to use. + VAR_PRIVATE/default_ui_style = DEFAULT_UI_STYLE + + /// Assoc list of current /decl/hud_element to values. Cannot be private, used by macro. + var/list/alerts + + /// List of elements related to hand slots. + VAR_PRIVATE/list/obj/screen/hud_elements_hands + /// List of elements related to swapping hand slots. + VAR_PRIVATE/list/obj/screen/hud_elements_swap + /// List of elements related to hotkeys. + VAR_PRIVATE/list/obj/screen/hud_elements_hotkeys + /// List of elements that are hidden by the inventory toggle. + VAR_PRIVATE/list/obj/screen/hud_elements_hidable + /// List of elements that are not hidden by anything. + VAR_PRIVATE/list/obj/screen/hud_elements_unhidable + /// List of elements that are hidden by F12. + VAR_PRIVATE/list/obj/screen/hud_elements_auxilliary + /// List of elements that update icon in Life() + VAR_PRIVATE/list/obj/screen/hud_elements_update_in_life + /// Combined list of the above, used for qdel. + VAR_PRIVATE/list/obj/screen/all_hud_elements + + /// List of /decl/hud_element types to use to populate this HUD on creation. + VAR_PROTECTED/list/hud_elements_to_create = list( + /decl/hud_element/movement, + /decl/hud_element/stamina, + /decl/hud_element/health, + /decl/hud_element/internals, + /decl/hud_element/charge, + /decl/hud_element/zone_selector, + /decl/hud_element/nutrition, + /decl/hud_element/hydration, + /decl/hud_element/upward, + /decl/hud_element/throw_toggle, + /decl/hud_element/maneuver, + /decl/hud_element/drop, + /decl/hud_element/resist, + /decl/hud_element/intent, + /decl/hud_element/fire, + /decl/hud_element/oxygen, + /decl/hud_element/toxins, + /decl/hud_element/bodytemp, + /decl/hud_element/pressure + ) + /// /decl/hud_element types to be inserted into hud_elements_to_create during init. + VAR_PROTECTED/list/additional_hud_elements + /// /decl/hud_element types to be removed from hud_elements_to_create during init. + VAR_PROTECTED/list/omit_hud_elements + /// Elem type to created object dict; used to retrieve/update elements. + VAR_PRIVATE/list/hud_elem_decl_to_object = list() + + // TODO: move these onto the HUD datum properly. + var/action_buttons_hidden = FALSE + var/obj/screen/action_button/hide_toggle/hide_actions_toggle + + // TODO: declify these. + VAR_PROTECTED/gun_mode_toggle_type + VAR_PRIVATE/obj/screen/gun/mode/gun_mode_toggle + VAR_PRIVATE/obj/screen/gun/move/gun_move_toggle + VAR_PRIVATE/obj/screen/gun/item/gun_item_use_toggle + VAR_PRIVATE/obj/screen/gun/radio/gun_radio_use_toggle + + +/datum/hud/New(mob/owner) + mymob = owner + instantiate() + ..() + +/datum/hud/Destroy() + . = ..() + + LAZYCLEARLIST(hud_elements_hands) + LAZYCLEARLIST(hud_elements_swap) + LAZYCLEARLIST(hud_elements_hotkeys) + LAZYCLEARLIST(hud_elements_hidable) + LAZYCLEARLIST(hud_elements_unhidable) + LAZYCLEARLIST(hud_elements_auxilliary) + LAZYCLEARLIST(hud_elem_decl_to_object) + QDEL_NULL_LIST(all_hud_elements) + + if(mymob) + if(mymob.hud_used == src) + mymob.hud_used = null + mymob = null + +/datum/hud/proc/is_hud_shown() + return hud_shown + +/datum/hud/proc/get_element(hud_key) + return hud_elem_decl_to_object[hud_key] + +/datum/hud/proc/refresh_element(hud_key) + var/obj/screen/elem = get_element(hud_key) + return elem?.update_icon() || FALSE + +/datum/hud/proc/refresh_hud_icons() + for(var/obj/screen/elem in mymob?.client?.screen) + elem.queue_icon_update() + +/datum/hud/proc/is_inventory_shown() + return inventory_shown + +/datum/hud/proc/hide_inventory() + inventory_shown = FALSE + if(LAZYLEN(hud_elements_hidable)) + mymob?.client?.screen -= hud_elements_hidable + hidden_inventory_update() + persistent_inventory_update() + +/datum/hud/proc/show_inventory() + inventory_shown = TRUE + if(LAZYLEN(hud_elements_hidable)) + mymob?.client?.screen += hud_elements_hidable + hidden_inventory_update() + persistent_inventory_update() + +/datum/hud/proc/hidden_inventory_update() + var/decl/species/species = mymob?.get_species() + if(istype(species?.species_hud)) + refresh_inventory_slots(species.species_hud.hidden_slots, (inventory_shown && hud_shown)) + +/datum/hud/proc/persistent_inventory_update() + var/decl/species/species = mymob?.get_species() + if(istype(species?.species_hud)) + refresh_inventory_slots(species.species_hud.persistent_slots, hud_shown) + +/datum/hud/proc/refresh_inventory_slots(var/list/checking_slots, var/show_hud) + + for(var/slot in checking_slots) + + var/datum/inventory_slot/inv_slot = mymob.get_inventory_slot_datum(slot) + if(!istype(inv_slot)) + continue + + // Check if we're even wearing anything in that slot. + var/obj/item/gear = inv_slot.get_equipped_item() + if(!istype(gear)) + continue + + // We're not showing anything, hide it. + gear.reconsider_client_screen_presence(mymob?.client, slot) + if(!show_hud) + inv_slot.hide_slot() + else + inv_slot.show_slot() + +/datum/hud/proc/instantiate() + if(ismob(mymob) && mymob.client) + finalize_instantiation() + refresh_hud_icons() + return TRUE + return FALSE + +/datum/hud/proc/handle_life_hud_update() + for(var/obj/screen/elem as anything in hud_elements_update_in_life) + elem.update_icon() + +/datum/hud/proc/finalize_instantiation() + + SHOULD_CALL_PARENT(TRUE) + + var/decl/ui_style/ui_style = get_ui_style_data() + var/ui_color = get_ui_color() + var/ui_alpha = get_ui_alpha() + + LAZYINITLIST(hud_elements_to_create) + if(length(additional_hud_elements)) + hud_elements_to_create |= additional_hud_elements + if(length(omit_hud_elements)) + hud_elements_to_create -= omit_hud_elements + UNSETEMPTY(hud_elements_to_create) + + for(var/hud_elem_type in hud_elements_to_create) + var/decl/hud_element/hud_element = GET_DECL(hud_elem_type) + create_and_register_element(hud_element, ui_style, ui_color, ui_alpha) + + //Handle the gun settings buttons + if(!gun_mode_toggle && gun_mode_toggle_type) + gun_mode_toggle = new gun_mode_toggle_type(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + LAZYADD(hud_elements_auxilliary, gun_mode_toggle) + gun_item_use_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + gun_move_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + gun_radio_use_toggle = new(null, mymob, ui_style, ui_color, ui_alpha, HUD_FIRE_INTENT) + + build_inventory_ui() + build_hands_ui() + + LAZYINITLIST(all_hud_elements) + if(LAZYLEN(hud_elements_hands)) + all_hud_elements |= hud_elements_hands + if(LAZYLEN(hud_elements_swap)) + all_hud_elements |= hud_elements_swap + if(LAZYLEN(hud_elements_hotkeys)) + all_hud_elements |= hud_elements_hotkeys + if(LAZYLEN(hud_elements_hidable)) + all_hud_elements |= hud_elements_hidable + if(LAZYLEN(hud_elements_unhidable)) + all_hud_elements |= hud_elements_unhidable + if(LAZYLEN(hud_elements_auxilliary)) + all_hud_elements |= hud_elements_auxilliary + UNSETEMPTY(all_hud_elements) + + if(mymob.client) + mymob.client.screen = list() + if(LAZYLEN(all_hud_elements)) + mymob.client.screen |= all_hud_elements + + hide_inventory() + +/datum/hud/proc/get_ui_style_data() + RETURN_TYPE(/decl/ui_style) + . = GET_DECL(mymob?.client?.prefs?.UI_style) || GET_DECL(default_ui_style) + if(!.) + var/list/available_styles = get_ui_styles() + if(length(available_styles)) + . = available_styles[1] + +/datum/hud/proc/get_ui_color() + var/decl/ui_style/ui_style = get_ui_style_data() + if(!ui_style?.use_ui_color) + return COLOR_WHITE + return mymob?.client?.prefs?.UI_style_color || COLOR_WHITE + +/datum/hud/proc/get_ui_alpha() + return mymob?.client?.prefs?.UI_style_alpha || 255 + +/datum/hud/proc/rebuild_hands() + + var/decl/ui_style/ui_style = get_ui_style_data() + var/ui_color = get_ui_color() + var/ui_alpha = get_ui_alpha() + + // Build held item boxes for missing slots. + var/list/held_slots = mymob.get_held_item_slots() + + // Sort our slots for display. + var/list/gripper_datums = list() + for(var/hand_tag in held_slots) + gripper_datums += mymob.get_inventory_slot_datum(hand_tag) + gripper_datums = sortTim(gripper_datums, /proc/cmp_gripper_asc) + + for(var/datum/inventory_slot/gripper/inv_slot in gripper_datums) + + // Re-order the held slot list so it aligns with the display order. + var/hand_tag = inv_slot.slot_id + held_slots -= hand_tag + held_slots += hand_tag + + var/obj/screen/inventory/inv_box + for(var/obj/screen/inventory/existing_box in hud_elements_hands) + if(existing_box.slot_id == hand_tag) + inv_box = existing_box + break + + if(!inv_box) + inv_box = new /obj/screen/inventory/hand(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS) + else + inv_box.set_ui_style(ui_style, HUD_HANDS) + inv_box.color = ui_color + inv_box.alpha = ui_alpha + + LAZYDISTINCTADD(hud_elements_hands, inv_box) + + inv_box.SetName(hand_tag) + inv_box.slot_id = hand_tag + inv_box.update_icon() + + // Clear held item boxes with no held slot. + for(var/obj/screen/inventory/inv_box in hud_elements_hands) + if(!(inv_box.slot_id in held_slots)) + if(mymob.client) + mymob.client.screen -= inv_box + LAZYREMOVE(hud_elements_hands, inv_box) + qdel(inv_box) + + // Rebuild offsets for the hand elements. + var/hand_y_offset = 21 + var/list/elements = hud_elements_hands?.Copy() + while(length(elements)) + var/copy_index = min(length(elements), 2)+1 + var/list/sublist = elements.Copy(1, copy_index) + elements.Cut(1, copy_index) + var/obj/screen/inventory/inv_box + if(length(sublist) == 1) + inv_box = sublist[1] + inv_box.screen_loc = "CENTER,BOTTOM:[hand_y_offset]" + else + inv_box = sublist[1] + inv_box.screen_loc = "CENTER:-[world.icon_size/2],BOTTOM:[hand_y_offset]" + inv_box = sublist[2] + inv_box.screen_loc = "CENTER:[world.icon_size/2],BOTTOM:[hand_y_offset]" + hand_y_offset += world.icon_size + + if(mymob.client && islist(hud_elements_hands) && length(hud_elements_hands)) + mymob.client.screen |= hud_elements_hands + + // Make sure all held items are on the screen and set to the correct screen loc. + var/datum/inventory_slot/inv_slot + for(var/obj/inv_elem in hud_elements_hands) + inv_slot = mymob.get_inventory_slot_datum(inv_elem.name) + if(inv_slot) + inv_slot.ui_loc = inv_elem.screen_loc + var/obj/item/held = inv_slot.get_equipped_item() + if(held) + held.screen_loc = inv_slot.ui_loc + if(mymob.client) + mymob.client.screen |= held // just to make sure it's visible post-login + + if(length(hud_elements_swap)) + var/hand_x_offset = -(world.icon_size/2) + for(var/i = 1 to length(hud_elements_swap)) + var/obj/swap_elem = hud_elements_swap[i] + swap_elem.screen_loc = "CENTER:[hand_x_offset],BOTTOM:[hand_y_offset]" + if(i > 1) // first two elems share a slot + hand_x_offset += world.icon_size + if(mymob.client) + mymob.client.screen |= swap_elem + +/datum/hud/proc/build_inventory_ui() + + var/decl/ui_style/ui_style = get_ui_style_data() + var/ui_color = get_ui_color() + var/ui_alpha = get_ui_alpha() + + var/has_hidden_gear = FALSE + + // Draw the various inventory equipment slots. + var/obj/screen/inventory/inv_box + var/list/held_slots = mymob.get_held_item_slots() + var/list/inventory_slots = mymob.get_inventory_slots() + for(var/gear_slot in inventory_slots) + + if(gear_slot in held_slots) + continue + + inv_box = new /obj/screen/inventory(null, mymob, ui_style, ui_color, ui_alpha, HUD_INVENTORY) + + var/datum/inventory_slot/inv_slot = inventory_slots[gear_slot] + inv_box.SetName(inv_slot.slot_name) + inv_box.slot_id = inv_slot.slot_id + inv_box.icon_state = inv_slot.slot_state + inv_box.screen_loc = inv_slot.ui_loc + + if(inv_slot.slot_dir) + inv_box.set_dir(inv_slot.slot_dir) + + if(inv_slot.can_be_hidden) + LAZYDISTINCTADD(hud_elements_hidable, inv_box) + has_hidden_gear = TRUE + else + hud_elements_auxilliary += inv_box + + if(has_hidden_gear) + hud_elements_auxilliary += new /obj/screen/toggle(null, mymob, ui_style, ui_color, ui_alpha, HUD_INVENTORY) + +/datum/hud/proc/build_hands_ui() + + var/list/held_slots = mymob.get_held_item_slots() + if(length(held_slots) <= 0) + return + + var/decl/ui_style/ui_style = get_ui_style_data() + var/ui_color = get_ui_color() + var/ui_alpha = get_ui_alpha() + + // Swap hand and quick equip screen elems. + var/obj/screen/using = new /obj/screen/equip(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS) + LAZYADD(hud_elements_swap, using) + if(length(held_slots) > 1) + + using = new /obj/screen/inventory/swaphand(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS) + LAZYADD(hud_elements_swap, using) + using = new /obj/screen/inventory/swaphand/right(null, mymob, ui_style, ui_color, ui_alpha, HUD_HANDS) + LAZYADD(hud_elements_swap, using) + + // Actual hand elems. + rebuild_hands() + +/datum/hud/proc/toggle_show_inventory() + if(inventory_shown) + hide_inventory() + else + show_inventory() + return TRUE + +/datum/hud/proc/toggle_action_buttons_hidden() + action_buttons_hidden = !action_buttons_hidden + return action_buttons_hidden + +/datum/hud/proc/toggle_minimize(var/full) + if(hud_shown) + hud_shown = FALSE + if(hud_elements_auxilliary) + mymob?.client?.screen -= hud_elements_auxilliary + if(hud_elements_hidable) + mymob?.client?.screen -= hud_elements_hidable + if(hud_elements_hotkeys) + mymob?.client?.screen -= hud_elements_hotkeys + if(!full) + if(LAZYLEN(hud_elements_hands)) + mymob?.client?.screen += hud_elements_hands // we want the hands to be visible + if(LAZYLEN(hud_elements_swap)) + mymob?.client?.screen += hud_elements_swap // we want the hands swap thingy to be visible + else + hud_shown = TRUE + if(LAZYLEN(hud_elements_auxilliary)) + mymob?.client?.screen |= hud_elements_auxilliary + if(LAZYLEN(hud_elements_hidable) && inventory_shown) + mymob?.client?.screen |= hud_elements_hidable + if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden) + mymob?.client?.screen |= hud_elements_hotkeys + hidden_inventory_update() + persistent_inventory_update() + +/datum/hud/proc/toggle_zoom_hud() + if(hud_shown) + hud_shown = FALSE + if(LAZYLEN(hud_elements_auxilliary)) + mymob?.client?.screen -= hud_elements_auxilliary + if(LAZYLEN(hud_elements_hidable)) + mymob?.client?.screen -= hud_elements_hidable + if(LAZYLEN(hud_elements_hotkeys)) + mymob?.client?.screen -= hud_elements_hotkeys + else + hud_shown = TRUE + if(LAZYLEN(hud_elements_auxilliary)) + mymob?.client?.screen += hud_elements_auxilliary + if(LAZYLEN(hud_elements_hidable) && inventory_shown) + mymob?.client?.screen += hud_elements_hidable + if(LAZYLEN(hud_elements_hotkeys) && !hotkey_ui_hidden) + mymob?.client?.screen += hud_elements_hotkeys + hidden_inventory_update() + persistent_inventory_update() + +/datum/hud/proc/toggle_hotkeys() + if(hotkey_ui_hidden) + mymob?.client?.screen += hud_elements_hotkeys + hotkey_ui_hidden = 0 + else + mymob?.client?.screen -= hud_elements_hotkeys + hotkey_ui_hidden = TRUE + +/mob/verb/toggle_hotkey_verbs() + set category = "OOC" + set name = "Toggle hotkey buttons" + set desc = "This disables or enables the user interface buttons which can be used with hotkeys." + if(!istype(hud_used)) + return + hud_used.toggle_hotkeys() + +/mob/verb/minimize_hud(full = FALSE as null) + set name = "Minimize Hud" + set hidden = TRUE + if(isnull(hud_used)) + to_chat(usr, SPAN_WARNING("This mob type does not use a HUD.")) + return + if(!client || !istype(hud_used)) + return + hud_used.toggle_minimize(full) + update_action_buttons() + +//Similar to minimize_hud() but keeps zone_selector, gun_setting_itoggle, and health_warning. +/mob/proc/toggle_zoom_hud() + if(!istype(hud_used)) + return + if(!ishuman(src)) + return + if(!client) + return + if(client.view != world.view) + return + + hud_used.toggle_zoom_hud() + update_action_buttons() + +/client/proc/reset_click_catchers() + + var/xmin = -(round(last_view_x_dim*0.5)) + var/xmax = last_view_x_dim - abs(xmin) + var/ymin = -(round(last_view_y_dim*0.5)) + var/ymax = last_view_y_dim - abs(ymin) + + var/list/click_catchers = get_click_catchers() + for(var/obj/screen/click_catcher/catcher in click_catchers) + if(catcher.x_offset <= xmin || catcher.x_offset >= xmax || catcher.y_offset <= ymin || catcher.y_offset >= ymax) + screen -= catcher + else + screen |= catcher + +/mob/proc/add_click_catcher() + client.reset_click_catchers() + +/mob/new_player/add_click_catcher() + return + +//These are called by the on-screen buttons, adjusting what the victim can and cannot do. +/datum/hud/proc/add_gun_icons() + // This can runtime if someone manages to throw a gun out of their hand before the proc is called. + if(!gun_item_use_toggle) + return TRUE + if(mymob?.client) + mymob.client.screen |= gun_item_use_toggle + mymob.client.screen |= gun_move_toggle + mymob.client.screen |= gun_radio_use_toggle + +/datum/hud/proc/remove_gun_icons() + if(mymob?.client) + mymob.client.screen -= gun_item_use_toggle + mymob.client.screen -= gun_move_toggle + mymob.client.screen -= gun_radio_use_toggle + +/datum/hud/proc/update_hand_elements() + for(var/atom/hand as anything in hud_elements_hands) + hand.update_icon() + + +/datum/hud/proc/update_gun_mode_icons(target_permissions) + if(gun_move_toggle) + if(!(target_permissions & TARGET_CAN_MOVE)) + gun_move_toggle.SetName("Allow Movement") + else + gun_move_toggle.SetName("Disallow Movement") + gun_move_toggle.update_icon() + if(gun_item_use_toggle) + if(!(target_permissions & TARGET_CAN_CLICK)) + gun_item_use_toggle.SetName("Allow Item Use") + else + gun_item_use_toggle.SetName("Disallow Item Use") + gun_item_use_toggle.update_icon() + if(gun_radio_use_toggle) + if(!(target_permissions & TARGET_CAN_RADIO)) + gun_radio_use_toggle.SetName("Allow Radio Use") + else + gun_radio_use_toggle.SetName("Disallow Radio Use") + gun_radio_use_toggle.update_icon() + +/datum/hud/proc/create_and_register_element(decl/hud_element/ui_elem, decl/ui_style/ui_style, ui_color, ui_alpha) + if(!istype(ui_elem) || !ui_elem.elem_type) + return FALSE + var/obj/screen/elem = new ui_elem.elem_type(null, mymob, ui_style, ui_color, ui_alpha, ui_elem.elem_reference_type) + if(ui_elem.elem_is_hotkey) + LAZYDISTINCTADD(hud_elements_hotkeys, elem) + else if(ui_elem.elem_is_auxilliary) + LAZYDISTINCTADD(hud_elements_auxilliary, elem) + else if(ui_elem.elem_is_hidable) + LAZYDISTINCTADD(hud_elements_hidable, elem) + else + LAZYDISTINCTADD(hud_elements_unhidable, elem) + if(ui_elem.elem_updates_in_life) + LAZYDISTINCTADD(hud_elements_update_in_life, elem) + hud_elem_decl_to_object[ui_elem.elem_reference_type] = elem + return elem diff --git a/code/_onclick/hud/hud_types/ai.dm b/code/_onclick/hud/hud_types/ai.dm new file mode 100644 index 000000000000..e6f0c0394aab --- /dev/null +++ b/code/_onclick/hud/hud_types/ai.dm @@ -0,0 +1,25 @@ +/mob/living/silicon/ai + hud_used = /datum/hud/ai + +/datum/hud/ai + omit_hud_elements = list( + /decl/hud_element/intent, + /decl/hud_element/health, + /decl/hud_element/charge, + /decl/hud_element/bodytemp, + /decl/hud_element/oxygen, + /decl/hud_element/toxins, + /decl/hud_element/pressure, + /decl/hud_element/nutrition, + /decl/hud_element/hydration, + /decl/hud_element/maneuver, + /decl/hud_element/movement, + /decl/hud_element/resist, + /decl/hud_element/drop, + /decl/hud_element/throw_toggle, + /decl/hud_element/internals + ) + +/datum/hud/ai/New() + additional_hud_elements = subtypesof(/decl/hud_element/ai) + ..() diff --git a/code/_onclick/hud/ai_hud.dm b/code/_onclick/hud/hud_types/ai_hud.dm similarity index 81% rename from code/_onclick/hud/ai_hud.dm rename to code/_onclick/hud/hud_types/ai_hud.dm index fa4e2200bb63..555c40a5d6f5 100644 --- a/code/_onclick/hud/ai_hud.dm +++ b/code/_onclick/hud/hud_types/ai_hud.dm @@ -1,5 +1,6 @@ -/decl/ai_hud - abstract_type = /decl/ai_hud +/decl/hud_element/ai + abstract_type = /decl/hud_element/ai + elem_type = /obj/screen/ai_button var/screen_loc var/name var/icon_state @@ -7,137 +8,137 @@ var/list/input_procs var/list/input_args -/decl/ai_hud/ai_core +/decl/hud_element/ai/core screen_loc = ui_ai_core name = "AI Core" icon_state = "ai_core" proc_path = /mob/living/silicon/ai/proc/core -/decl/ai_hud/ai_announcement +/decl/hud_element/ai/announcement screen_loc = ui_ai_announcement name = "AI Announcement" icon_state = "announcement" proc_path = /mob/living/silicon/ai/proc/ai_announcement -/decl/ai_hud/ai_cam_track +/decl/hud_element/ai/cam_track screen_loc = ui_ai_cam_track name = "Track With Camera" icon_state = "track" proc_path = /mob/living/silicon/ai/proc/ai_camera_track input_procs = list(/mob/living/silicon/ai/proc/trackable_mobs = (AI_BUTTON_PROC_BELONGS_TO_CALLER|AI_BUTTON_INPUT_REQUIRES_SELECTION)) -/decl/ai_hud/ai_cam_light +/decl/hud_element/ai/cam_light screen_loc = ui_ai_cam_light name = "Toggle Camera Lights" icon_state = "camera_light" proc_path = /mob/living/silicon/ai/proc/toggle_camera_light -/decl/ai_hud/ai_cam_change_channel +/decl/hud_element/ai/cam_change_channel screen_loc = ui_ai_cam_change_channel name = "Jump to Camera Channel" icon_state = "camera" proc_path = /mob/living/silicon/ai/proc/ai_channel_change input_procs = list(/mob/living/silicon/ai/proc/get_camera_channel_list = (AI_BUTTON_PROC_BELONGS_TO_CALLER|AI_BUTTON_INPUT_REQUIRES_SELECTION)) -/decl/ai_hud/ai_sensor +/decl/hud_element/ai/sensor screen_loc = ui_ai_sensor name = "Set Sensor Mode" icon_state = "ai_sensor" proc_path = /mob/living/silicon/ai/proc/sensor_mode -/decl/ai_hud/ai_manifest +/decl/hud_element/ai/manifest screen_loc = ui_ai_crew_manifest name = "Show Crew Manifest" icon_state = "manifest" proc_path = /mob/living/silicon/ai/proc/run_program input_args = list("crewmanifest") -/decl/ai_hud/ai_take_image +/decl/hud_element/ai/take_image screen_loc = ui_ai_take_image name = "Toggle Camera Mode" icon_state = "take_picture" proc_path = /mob/living/silicon/ai/proc/ai_take_image -/decl/ai_hud/ai_view_images +/decl/hud_element/ai/view_images screen_loc = ui_ai_view_images name = "View Images" icon_state = "view_images" proc_path = /mob/living/silicon/ai/proc/ai_view_images -/decl/ai_hud/ai_laws +/decl/hud_element/ai/laws screen_loc = ui_ai_state_laws name = "State Laws" icon_state = "state_laws" proc_path = /mob/living/silicon/ai/proc/ai_checklaws -/decl/ai_hud/ai_call_shuttle +/decl/hud_element/ai/call_shuttle screen_loc = ui_ai_call_shuttle name = "Call Shuttle" icon_state = "call_shuttle" proc_path = /mob/living/silicon/ai/proc/ai_call_shuttle -/decl/ai_hud/ai_up +/decl/hud_element/ai/up screen_loc = ui_ai_up name = "Move Upwards" icon_state = "ai_up" proc_path = /mob/verb/up -/decl/ai_hud/ai_down +/decl/hud_element/ai/down screen_loc = ui_ai_down name = "Move Downwards" icon_state = "ai_down" proc_path = /mob/verb/down -/decl/ai_hud/ai_color +/decl/hud_element/ai/color screen_loc = ui_ai_color name = "Change Floor Color" icon_state = "ai_floor" proc_path = /mob/living/silicon/ai/proc/change_floor -/decl/ai_hud/ai_hologram +/decl/hud_element/ai/hologram screen_loc = ui_ai_holo_change name = "Change Hologram" icon_state = "ai_holo_change" proc_path = /mob/living/silicon/ai/proc/ai_hologram_change -/decl/ai_hud/ai_crew_monitor +/decl/hud_element/ai/crew_monitor screen_loc = ui_ai_crew_mon name = "Crew Monitor" icon_state = "crew_monitor" proc_path = /mob/living/silicon/ai/proc/run_program input_args = list("sensormonitor") -/decl/ai_hud/ai_power_override +/decl/hud_element/ai/power_override screen_loc = ui_ai_power_override name = "Toggle Power Override" icon_state = "ai_p_override" proc_path = /mob/living/silicon/ai/proc/ai_power_override -/decl/ai_hud/ai_shutdown +/decl/hud_element/ai/shutdown screen_loc = ui_ai_shutdown name = "Shutdown" icon_state = "ai_shutdown" proc_path = /mob/living/silicon/ai/proc/ai_shutdown -/decl/ai_hud/ai_move_hologram +/decl/hud_element/ai/move_hologram screen_loc = ui_ai_holo_mov name = "Toggle Hologram Movement" icon_state = "ai_holo_mov" proc_path = /mob/living/silicon/ai/proc/toggle_hologram_movement -/decl/ai_hud/ai_core_icon +/decl/hud_element/ai/core_icon screen_loc = ui_ai_core_icon name = "Pick Icon" icon_state = "ai_core_pick" proc_path = /mob/living/silicon/ai/proc/pick_icon -/decl/ai_hud/ai_status +/decl/hud_element/ai/status screen_loc = ui_ai_status name = "Pick Status" icon_state = "ai_status" proc_path = /mob/living/silicon/ai/proc/ai_statuschange -/decl/ai_hud/ai_inbuilt_comp +/decl/hud_element/ai/inbuilt_comp screen_loc = ui_ai_crew_rec name = "Inbuilt Computer" icon_state = "ai_crew_rec" diff --git a/code/_onclick/hud/hud_types/animal.dm b/code/_onclick/hud/hud_types/animal.dm new file mode 100644 index 000000000000..84c9d7736b79 --- /dev/null +++ b/code/_onclick/hud/hud_types/animal.dm @@ -0,0 +1,11 @@ +/datum/hud/animal + hud_elements_to_create = list( + /decl/hud_element/movement, + /decl/hud_element/stamina, + /decl/hud_element/health, + /decl/hud_element/zone_selector, + /decl/hud_element/upward, + /decl/hud_element/maneuver, + /decl/hud_element/resist, + /decl/hud_element/intent + ) diff --git a/code/_onclick/hud/hud_types/human.dm b/code/_onclick/hud/hud_types/human.dm new file mode 100644 index 000000000000..9f08721970ef --- /dev/null +++ b/code/_onclick/hud/hud_types/human.dm @@ -0,0 +1,10 @@ +/mob/living/human + hud_used = /datum/hud/human + +/datum/hud/human + gun_mode_toggle_type = /obj/screen/gun/mode + omit_hud_elements = list(/decl/hud_element/health) + additional_hud_elements = list( + /decl/hud_element/health/organs, + /decl/hud_element/attack + ) diff --git a/code/_onclick/hud/hud_types/other_mobs.dm b/code/_onclick/hud/hud_types/other_mobs.dm new file mode 100644 index 000000000000..96c117e4d465 --- /dev/null +++ b/code/_onclick/hud/hud_types/other_mobs.dm @@ -0,0 +1,61 @@ +/datum/hud/animal/construct + omit_hud_elements = list(/decl/hud_element/health) + additional_hud_elements = list(/decl/hud_element/health/construct) + +/decl/hud_element/health/construct + elem_reference_type = /decl/hud_element/health + elem_type = /obj/screen/health/construct + +/datum/hud/animal/construct/get_ui_style_data() + return GET_DECL(/decl/ui_style/construct) + +/datum/hud/animal/construct/juggernaut/get_ui_style_data() + return GET_DECL(/decl/ui_style/construct/juggernaut) + +/datum/hud/animal/construct/harvester/get_ui_style_data() + return GET_DECL(/decl/ui_style/construct/harvester) + +/datum/hud/animal/construct/wraith/get_ui_style_data() + return GET_DECL(/decl/ui_style/construct/wraith) + +/datum/hud/animal/construct/artificer/get_ui_style_data() + return GET_DECL(/decl/ui_style/construct/artificer) + +/datum/hud/animal/construct/get_ui_color() + return COLOR_WHITE + +/datum/hud/animal/construct/get_ui_alpha() + return 255 + +/decl/ui_style/construct + name = "Construct" + restricted = TRUE + override_icons = list( + (HUD_FIRE) = 'icons/mob/screen/styles/constructs/status_fire.dmi', + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/constructs/zone_selector.dmi' + ) + uid = "ui_style_construct" +/decl/ui_style/construct/juggernaut + name = "Juggernaut" + uid = "ui_style_construct_juggernaut" +/decl/ui_style/construct/juggernaut/Initialize() + override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/juggernaut/health.dmi' + return ..() +/decl/ui_style/construct/harvester + name = "Harvester" + uid = "ui_style_construct_harvester" +/decl/ui_style/construct/harvester/Initialize() + override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/harvester/health.dmi' + return ..() +/decl/ui_style/construct/wraith + name = "Wraith" + uid = "ui_style_construct_wraith" +/decl/ui_style/construct/wraith/Initialize() + override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/wraith/health.dmi' + return ..() +/decl/ui_style/construct/artificer + name = "Artificer" + uid = "ui_style_construct_artificer" +/decl/ui_style/construct/artificer/Initialize() + override_icons[HUD_HEALTH] = 'icons/mob/screen/styles/constructs/artificer/health.dmi' + return ..() diff --git a/code/_onclick/hud/hud_types/pai.dm b/code/_onclick/hud/hud_types/pai.dm new file mode 100644 index 000000000000..4521b70b5823 --- /dev/null +++ b/code/_onclick/hud/hud_types/pai.dm @@ -0,0 +1,6 @@ +/datum/hud/pai + hud_elements_to_create = list(/decl/hud_element/health/robot) + +/datum/hud/pai/New() + hud_elements_to_create += subtypesof(/decl/hud_element/pai) + ..() diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/hud_types/robot.dm similarity index 51% rename from code/_onclick/hud/robot.dm rename to code/_onclick/hud/hud_types/robot.dm index b0680d9f047a..0f53b8f70777 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/hud_types/robot.dm @@ -1,5 +1,3 @@ -var/global/obj/screen/robot_inventory - /mob/living/silicon/robot hud_used = /datum/hud/robot @@ -8,10 +6,11 @@ var/global/obj/screen/robot_inventory restricted = TRUE uid = "ui_style_robot" override_icons = list( - UI_ICON_HEALTH = 'icons/mob/screen/styles/robot/health.dmi', - UI_ICON_STATUS_FIRE = 'icons/mob/screen/styles/robot/status_fire.dmi', - UI_ICON_UP_HINT = 'icons/mob/screen/styles/robot/uphint.dmi', - UI_ICON_ZONE_SELECT = 'icons/mob/screen/styles/robot/zone_selector.dmi' + (HUD_HEALTH) = 'icons/mob/screen/styles/robot/health.dmi', + (HUD_FIRE) = 'icons/mob/screen/styles/robot/status_fire.dmi', + (HUD_OXY) = 'icons/mob/screen/styles/robot/status_oxy.dmi', + (HUD_UP_HINT) = 'icons/mob/screen/styles/robot/uphint.dmi', + (HUD_ZONE_SELECT) = 'icons/mob/screen/styles/robot/zone_selector.dmi' ) /datum/hud/robot/get_ui_style_data() @@ -23,51 +22,18 @@ var/global/obj/screen/robot_inventory /datum/hud/robot/get_ui_alpha() return 255 -/datum/hud/robot/FinalizeInstantiation() - +// TODO: Convert robots to use inventory slots. +/datum/hud/robot/finalize_instantiation() var/mob/living/silicon/robot/R = mymob if(!istype(R)) - ..() - return - - var/decl/ui_style/ui_style = get_ui_style_data() - var/ui_color = get_ui_color() - var/ui_alpha = get_ui_alpha() - - //Radio - adding += new /obj/screen/robot_radio(null, mymob) - - //Module select + return ..() R.inv1 = new(null, mymob) R.inv2 = new(null, mymob) R.inv3 = new(null, mymob) - adding += R.inv1 - adding += R.inv2 - adding += R.inv3 - //End of module select - - // Drop UI - R.ui_drop_grab = new(null, mymob) - adding += R.ui_drop_grab - - adding += new /obj/screen/robot_panel(null, mymob) - adding += new /obj/screen/robot_store(null, mymob) - - R.hands = new /obj/screen/robot_module/select(null, mymob) - robot_inventory = new /obj/screen/robot_inventory( null, mymob) - R.cells = new /obj/screen/robot_charge( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_CHARGE) - R.healths = new /obj/screen/robot_health( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HEALTH) - R.bodytemp = new /obj/screen/bodytemp( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS) - R.oxygen = new /obj/screen/robot_oxygen( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS) - R.fire = new /obj/screen/robot_fire( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS_FIRE) - R.up_hint = new /obj/screen/up_hint( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_UP_HINT) - R.zone_sel = new( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ZONE_SELECT) - R.gun_setting_icon = new /obj/screen/gun/mode( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - R.item_use_icon = new /obj/screen/gun/item( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - R.gun_move_icon = new /obj/screen/gun/move( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - R.radio_use_icon = new /obj/screen/gun/radio( null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - - hud_elements = list(R.zone_sel, R.oxygen, R.fire, R.up_hint, R.hands, R.healths, R.cells, robot_inventory, R.gun_setting_icon) + LAZYINITLIST(hud_elements_auxilliary) + hud_elements_auxilliary += R.inv1 + hud_elements_auxilliary += R.inv2 + hud_elements_auxilliary += R.inv3 ..() /datum/hud/proc/toggle_show_robot_modules() @@ -135,7 +101,6 @@ var/global/obj/screen/robot_inventory else //Modules display is hidden - //R.client.screen -= robot_inventory //"store" icon for(var/atom/A in R.module.equipment) if( (A != R.module_state_1) && (A != R.module_state_2) && (A != R.module_state_3) ) //Module is not currently active diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm deleted file mode 100644 index 7dc1d837d915..000000000000 --- a/code/_onclick/hud/human.dm +++ /dev/null @@ -1,111 +0,0 @@ -/mob/living/human - hud_used = /datum/hud/human - -/datum/hud/human/FinalizeInstantiation() - - var/decl/ui_style/ui_style = get_ui_style_data() - var/ui_color = get_ui_color() - var/ui_alpha = get_ui_alpha() - - var/mob/living/human/target = mymob - var/datum/hud_data/hud_data = istype(target?.species?.species_hud) ? target.species.species_hud : new - - hotkeybuttons = list() //These can be disabled for hotkey usersx - - stamina_bar = new(null, mymob) - adding += stamina_bar - - if(hud_data.has_m_intent) - move_intent = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_MOVEMENT) - move_intent.icon_state = mymob.move_intent.hud_icon_state - src.adding += move_intent - - if(hud_data.has_drop) - src.hotkeybuttons += new /obj/screen/drop(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION) - - if(hud_data.has_resist) - src.hotkeybuttons += new /obj/screen/resist(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION) - - mymob.maneuver_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION) - src.hotkeybuttons += mymob.maneuver_icon - hud_elements |= mymob.maneuver_icon - - if(hud_data.has_throw) - mymob.throw_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERACTION) - src.hotkeybuttons += mymob.throw_icon - hud_elements |= mymob.throw_icon - - if(hud_data.has_internals) - mymob.internals = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_INTERNALS) - hud_elements |= mymob.internals - - if(hud_data.has_warnings) - mymob.healths = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS) - hud_elements |= mymob.healths - - mymob.oxygen = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS) - hud_elements |= mymob.oxygen - - mymob.toxin = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS) - hud_elements |= mymob.toxin - - mymob.fire = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS_FIRE) - hud_elements |= mymob.fire - - if(hud_data.has_pressure) - mymob.pressure = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS) - hud_elements |= mymob.pressure - - if(hud_data.has_bodytemp) - mymob.bodytemp = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS) - hud_elements |= mymob.bodytemp - - if(target.isSynthetic()) - target.cells = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_CHARGE) - hud_elements |= target.cells - - else if(hud_data.has_nutrition) - mymob.nutrition_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_NUTRITION) - hud_elements |= mymob.nutrition_icon - - mymob.hydration_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HYDRATION) - hud_elements |= mymob.hydration_icon - - if(hud_data.has_up_hint) - mymob.up_hint = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_UP_HINT) - hud_elements |= mymob.up_hint - - mymob.pain = new(null, mymob) - hud_elements |= mymob.pain - - mymob.zone_sel = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ZONE_SELECT) - mymob.zone_sel.update_icon() - hud_elements |= mymob.zone_sel - - target.attack_selector = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ATTACK) - hud_elements |= target.attack_selector - - //Handle the gun settings buttons - mymob.gun_setting_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - hud_elements |= mymob.gun_setting_icon - - mymob.item_use_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - mymob.gun_move_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - mymob.radio_use_icon = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_FIRE_INTENT) - - ..() - -/mob/living/human/verb/toggle_hotkey_verbs() - set category = "OOC" - set name = "Toggle hotkey buttons" - set desc = "This disables or enables the user interface buttons which can be used with hotkeys." - - if(!istype(hud_used)) - return - - if(hud_used.hotkey_ui_hidden) - client.screen += hud_used.hotkeybuttons - hud_used.hotkey_ui_hidden = 0 - else - client.screen -= hud_used.hotkeybuttons - hud_used.hotkey_ui_hidden = 1 diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm deleted file mode 100644 index 26437535d2bf..000000000000 --- a/code/_onclick/hud/other_mobs.dm +++ /dev/null @@ -1,63 +0,0 @@ -/datum/hud/construct/get_ui_style_data() - return GET_DECL(/decl/ui_style/construct) - -/datum/hud/construct/juggernaut/get_ui_style_data() - return GET_DECL(/decl/ui_style/construct/juggernaut) - -/datum/hud/construct/harvester/get_ui_style_data() - return GET_DECL(/decl/ui_style/construct/harvester) - -/datum/hud/construct/wraith/get_ui_style_data() - return GET_DECL(/decl/ui_style/construct/wraith) - -/datum/hud/construct/artificer/get_ui_style_data() - return GET_DECL(/decl/ui_style/construct/artificer) - -/datum/hud/construct/get_ui_color() - return COLOR_WHITE - -/datum/hud/construct/get_ui_alpha() - return 255 - -/datum/hud/construct/FinalizeInstantiation() - var/decl/ui_style/ui_style = get_ui_style_data() - var/ui_color = get_ui_color() - var/ui_alpha = get_ui_alpha() - mymob.fire = new /obj/screen/construct_fire(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_STATUS_FIRE) - mymob.healths = new /obj/screen/construct_health(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_HEALTH) - mymob.zone_sel = new(null, mymob, ui_style, ui_color, ui_alpha, UI_ICON_ZONE_SELECT) - adding += list(mymob.fire, mymob.healths, mymob.zone_sel) - ..() - -/decl/ui_style/construct - name = "Construct" - restricted = TRUE - override_icons = list( - UI_ICON_STATUS_FIRE = 'icons/mob/screen/styles/constructs/status_fire.dmi', - UI_ICON_ZONE_SELECT = 'icons/mob/screen/styles/constructs/zone_selector.dmi' - ) - uid = "ui_style_construct" -/decl/ui_style/construct/juggernaut - name = "Juggernaut" - uid = "ui_style_construct_juggernaut" -/decl/ui_style/construct/juggernaut/Initialize() - override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/juggernaut/health.dmi' - return ..() -/decl/ui_style/construct/harvester - name = "Harvester" - uid = "ui_style_construct_harvester" -/decl/ui_style/construct/harvester/Initialize() - override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/harvester/health.dmi' - return ..() -/decl/ui_style/construct/wraith - name = "Wraith" - uid = "ui_style_construct_wraith" -/decl/ui_style/construct/wraith/Initialize() - override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/wraith/health.dmi' - return ..() -/decl/ui_style/construct/artificer - name = "Artificer" - uid = "ui_style_construct_artificer" -/decl/ui_style/construct/artificer/Initialize() - override_icons[UI_ICON_HEALTH] = 'icons/mob/screen/styles/constructs/artificer/health.dmi' - return ..() diff --git a/code/_onclick/hud/pai.dm b/code/_onclick/hud/pai.dm deleted file mode 100644 index 5111dade42ce..000000000000 --- a/code/_onclick/hud/pai.dm +++ /dev/null @@ -1,9 +0,0 @@ -/datum/hud/pai/FinalizeInstantiation() - for(var/pai_hud_type in subtypesof(/obj/screen/pai)) - var/obj/screen/pai/hud_elem = pai_hud_type - if(TYPE_IS_ABSTRACT(hud_elem)) - continue - adding += new hud_elem(null, mymob) - - ..() - hide_inventory() diff --git a/code/_onclick/hud/screen/_screen.dm b/code/_onclick/hud/screen/_screen.dm index 4e891170d7bd..b3608bbf1cd9 100644 --- a/code/_onclick/hud/screen/_screen.dm +++ b/code/_onclick/hud/screen/_screen.dm @@ -26,12 +26,18 @@ var/requires_ui_style = TRUE /// Whether or not we look for/draw an additional detail overlay. var/apply_screen_overlay = TRUE - /// Reference to our last set ui_style + + // Do we take supplied color in Initialize()? + var/use_supplied_ui_color = FALSE + // Do we take supplied alpha in Initialize()? + var/use_supplied_ui_alpha = FALSE + // Do we take supplied icon in Initialize()? + var/use_supplied_ui_icon = TRUE /obj/screen/Initialize(mapload, mob/_owner, decl/ui_style/ui_style, ui_color, ui_alpha, ui_cat) if(requires_ui_style) - if(!istext(ui_cat) && !istext(ui_style_category)) + if(!ispath(ui_cat, /decl/hud_element) && !ispath(ui_style_category, /decl/hud_element)) PRINT_STACK_TRACE("Screen object [type] initializing with invalid UI style category: [ui_cat || "NULL"], [ui_style_category || "NULL"].") return INITIALIZE_HINT_QDEL if(!istype(ui_style)) @@ -51,9 +57,9 @@ return INITIALIZE_HINT_QDEL set_ui_style(ui_style, ui_cat) - if(!isnull(ui_color)) + if(!isnull(ui_color) && use_supplied_ui_color) color = ui_color - if(!isnull(ui_alpha)) + if(!isnull(ui_alpha) && use_supplied_ui_alpha) alpha = ui_alpha return ..() @@ -72,9 +78,9 @@ return FALSE /obj/screen/proc/set_ui_style(decl/ui_style/ui_style, ui_cat) - if(istext(ui_cat)) + if(!isnull(ui_cat)) ui_style_category = ui_cat - if(istype(ui_style) && ui_style_category) + if(istype(ui_style) && ui_style_category && use_supplied_ui_icon) icon = ui_style.get_icon(ui_style_category) update_icon() diff --git a/code/_onclick/hud/screen/robot/screen_robot.dm b/code/_onclick/hud/screen/robot/screen_robot.dm new file mode 100644 index 000000000000..594388da5aa0 --- /dev/null +++ b/code/_onclick/hud/screen/robot/screen_robot.dm @@ -0,0 +1,7 @@ +/obj/screen/robot + abstract_type = /obj/screen/robot + icon = 'icons/mob/screen/styles/robot/panel.dmi' + requires_ui_style = FALSE + use_supplied_ui_alpha = FALSE + use_supplied_ui_color = FALSE + use_supplied_ui_icon = FALSE diff --git a/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm b/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm new file mode 100644 index 000000000000..c3e71cef3d06 --- /dev/null +++ b/code/_onclick/hud/screen/robot/screen_robot_drop_grab.dm @@ -0,0 +1,23 @@ +/obj/screen/robot/drop_grab + name = "drop grab" + icon = 'icons/mob/screen/styles/robot/drop_grab.dmi' + icon_state = "drop_grab" + screen_loc = ui_borg_drop_grab + invisibility = INVISIBILITY_MAXIMUM + alpha = 0 + +/obj/screen/robot/drop_grab/handle_click(mob/user, params) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.drop_item() + update_icon() + +/obj/screen/robot/drop_grab/on_update_icon() + . = ..() + var/mob/living/owner = owner_ref?.resolve() + if(istype(owner) && length(owner.get_active_grabs())) + set_invisibility(INVISIBILITY_NONE) + alpha = 255 + else + set_invisibility(INVISIBILITY_ABSTRACT) + alpha = 0 diff --git a/code/_onclick/hud/screen/screen_robot_inventory.dm b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm similarity index 61% rename from code/_onclick/hud/screen/screen_robot_inventory.dm rename to code/_onclick/hud/screen/robot/screen_robot_inventory.dm index ebe63dcf3df5..a6360e2eaaab 100644 --- a/code/_onclick/hud/screen/screen_robot_inventory.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_inventory.dm @@ -1,11 +1,9 @@ -/obj/screen/robot_inventory +/obj/screen/robot/inventory name = "inventory" - icon = 'icons/mob/screen/styles/robot/panel.dmi' icon_state = "inventory" screen_loc = ui_borg_inventory - requires_ui_style = FALSE -/obj/screen/robot_inventory/handle_click(mob/user, params) +/obj/screen/robot/inventory/handle_click(mob/user, params) if(isrobot(user)) var/mob/living/silicon/robot/R = user if(R.module) diff --git a/code/_onclick/hud/screen/robot/screen_robot_module.dm b/code/_onclick/hud/screen/robot/screen_robot_module.dm new file mode 100644 index 000000000000..95e662167ec2 --- /dev/null +++ b/code/_onclick/hud/screen/robot/screen_robot_module.dm @@ -0,0 +1,17 @@ +/obj/screen/robot/module/select + name = "module" + icon = 'icons/mob/screen/styles/robot/module.dmi' + icon_state = "nomod" + screen_loc = ui_borg_module + +/obj/screen/robot/module/select/on_update_icon() + . = ..() + icon_state = initial(icon_state) + var/mob/living/silicon/robot/owner = owner_ref?.resolve() + if(istype(owner) && owner.modtype) + icon_state = lowertext(owner.modtype) + +/obj/screen/robot/module/select/handle_click(mob/user, params) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.pick_module() diff --git a/code/_onclick/hud/screen/screen_robot_modules.dm b/code/_onclick/hud/screen/robot/screen_robot_modules.dm similarity index 72% rename from code/_onclick/hud/screen/screen_robot_modules.dm rename to code/_onclick/hud/screen/robot/screen_robot_modules.dm index 12d82511fe10..8574676abda1 100644 --- a/code/_onclick/hud/screen/screen_robot_modules.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_modules.dm @@ -1,35 +1,33 @@ -/obj/screen/robot_modules_background +/obj/screen/robot/modules_background name = "module" icon_state = "block" icon = 'icons/mob/screen/styles/robot/modules_background.dmi' - requires_ui_style = FALSE -/obj/screen/robot_module +/obj/screen/robot/module dir = SOUTHWEST - requires_ui_style = FALSE icon = 'icons/mob/screen/styles/robot/inventory.dmi' var/module_index -/obj/screen/robot_module/handle_click(mob/user, params) +/obj/screen/robot/module/handle_click(mob/user, params) if(isrobot(user) && !isnull(module_index)) var/mob/living/silicon/robot/robot = user robot.toggle_module(module_index) return TRUE return ..() -/obj/screen/robot_module/one +/obj/screen/robot/module/one name = "module1" icon_state = "inv1" screen_loc = ui_inv1 module_index = 1 -/obj/screen/robot_module/two +/obj/screen/robot/module/two name = "module2" icon_state = "inv2" screen_loc = ui_inv2 module_index = 2 -/obj/screen/robot_module/three +/obj/screen/robot/module/three name = "module3" icon_state = "inv3" screen_loc = ui_inv3 diff --git a/code/_onclick/hud/screen/robot/screen_robot_panel.dm b/code/_onclick/hud/screen/robot/screen_robot_panel.dm new file mode 100644 index 000000000000..9f39909a52f9 --- /dev/null +++ b/code/_onclick/hud/screen/robot/screen_robot_panel.dm @@ -0,0 +1,9 @@ +/obj/screen/robot/panel + name = "panel" + icon_state = "panel" + screen_loc = ui_borg_panel + +/obj/screen/robot/panel/handle_click(mob/user, params) + if(isrobot(user)) + var/mob/living/silicon/robot/R = user + R.installed_modules() diff --git a/code/_onclick/hud/screen/screen_robot_radio.dm b/code/_onclick/hud/screen/robot/screen_robot_radio.dm similarity index 50% rename from code/_onclick/hud/screen/screen_robot_radio.dm rename to code/_onclick/hud/screen/robot/screen_robot_radio.dm index e1046ddfc75b..5207edef2b47 100644 --- a/code/_onclick/hud/screen/screen_robot_radio.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_radio.dm @@ -1,12 +1,10 @@ -/obj/screen/robot_radio +/obj/screen/robot/radio name = "radio" dir = SOUTHWEST - icon = 'icons/mob/screen/styles/robot/panel.dmi' icon_state = "radio" screen_loc = ui_movi - requires_ui_style = FALSE -/obj/screen/robot_radio/handle_click(mob/user, params) +/obj/screen/robot/radio/handle_click(mob/user, params) if(isrobot(user)) var/mob/living/silicon/robot/R = user R.radio_menu() \ No newline at end of file diff --git a/code/_onclick/hud/screen/screen_robot_store.dm b/code/_onclick/hud/screen/robot/screen_robot_store.dm similarity index 62% rename from code/_onclick/hud/screen/screen_robot_store.dm rename to code/_onclick/hud/screen/robot/screen_robot_store.dm index 8ea81ab05638..93f1a652b96e 100644 --- a/code/_onclick/hud/screen/screen_robot_store.dm +++ b/code/_onclick/hud/screen/robot/screen_robot_store.dm @@ -1,11 +1,9 @@ -/obj/screen/robot_store +/obj/screen/robot/store name = "store" - icon = 'icons/mob/screen/styles/robot/panel.dmi' icon_state = "store" screen_loc = ui_borg_store - requires_ui_style = FALSE -/obj/screen/robot_store/handle_click(mob/user, params) +/obj/screen/robot/store/handle_click(mob/user, params) if(isrobot(user)) var/mob/living/silicon/robot/R = user if(R.module) diff --git a/code/_onclick/hud/screen/robot/screen_robot_warnings.dm b/code/_onclick/hud/screen/robot/screen_robot_warnings.dm new file mode 100644 index 000000000000..c6365ba40d83 --- /dev/null +++ b/code/_onclick/hud/screen/robot/screen_robot_warnings.dm @@ -0,0 +1,4 @@ +/obj/screen/health/robot + name = "health" + icon_state = "health0" + screen_loc = ui_borg_health diff --git a/code/_onclick/hud/screen/screen_action_button.dm b/code/_onclick/hud/screen/screen_action_button.dm index df79fa29ce41..f0d4d6cbf79a 100644 --- a/code/_onclick/hud/screen/screen_action_button.dm +++ b/code/_onclick/hud/screen/screen_action_button.dm @@ -3,6 +3,14 @@ requires_ui_style = FALSE var/datum/action/action +/obj/screen/action_button/Destroy() + if(!QDELETED(action)) + if(action.button == src) + action.button = null + QDEL_NULL(action) + action = null + return ..() + /obj/screen/action_button/Initialize(mapload, mob/_owner, ui_style, ui_color, ui_alpha, ui_cat, _action) action = _action return ..() @@ -64,8 +72,7 @@ /obj/screen/action_button/hide_toggle/handle_click(mob/user, params) if(!istype(user.hud_used)) return - user.hud_used.action_buttons_hidden = !user.hud_used.action_buttons_hidden - hidden = user.hud_used.action_buttons_hidden + hidden = user.hud_used.toggle_action_buttons_hidden() if(hidden) name = "Show Buttons" else diff --git a/code/_onclick/hud/screen/screen_ai_button.dm b/code/_onclick/hud/screen/screen_ai_button.dm index e2060d6b8a1e..f1aaea0360f1 100644 --- a/code/_onclick/hud/screen/screen_ai_button.dm +++ b/code/_onclick/hud/screen/screen_ai_button.dm @@ -1,6 +1,10 @@ /obj/screen/ai_button - icon = 'icons/mob/screen/ai.dmi' - requires_ui_style = FALSE + icon = 'icons/mob/screen/ai.dmi' + requires_ui_style = FALSE + use_supplied_ui_alpha = FALSE + use_supplied_ui_color = FALSE + use_supplied_ui_icon = FALSE + var/ai_verb var/list/input_procs var/list/input_args @@ -40,15 +44,17 @@ call(A, ai_verb)(arglist(input_arguments)) return TRUE -/obj/screen/ai_button/Initialize(mapload, mob/_owner, ui_style, ui_color, ui_alpha, ui_cat, decl/ai_hud/ai_hud_data) +/obj/screen/ai_button/Initialize(mapload, mob/_owner, ui_style, ui_color, ui_alpha, ui_cat) . = ..() - name = ai_hud_data.name - icon_state = ai_hud_data.icon_state - screen_loc = ai_hud_data.screen_loc - ai_verb = ai_hud_data.proc_path - input_procs = ai_hud_data.input_procs?.Copy() - input_args = ai_hud_data.input_args?.Copy() + var/decl/hud_element/ai/ai_hud_data = GET_DECL(ui_cat) + if(istype(ai_hud_data)) + name = ai_hud_data.name + icon_state = ai_hud_data.icon_state + screen_loc = ai_hud_data.screen_loc + ai_verb = ai_hud_data.proc_path + input_procs = ai_hud_data.input_procs?.Copy() + input_args = ai_hud_data.input_args?.Copy() if(!LAZYLEN(template_icon)) template_icon = list(icon) diff --git a/code/_onclick/hud/screen/screen_attack_selector.dm b/code/_onclick/hud/screen/screen_attack_selector.dm index 537d2ccce389..ee9f4c019cfc 100644 --- a/code/_onclick/hud/screen/screen_attack_selector.dm +++ b/code/_onclick/hud/screen/screen_attack_selector.dm @@ -1,13 +1,9 @@ /obj/screen/default_attack_selector - name = "default attack selector" - icon_state = "attack_none" - screen_loc = ui_attack_selector - -/obj/screen/default_attack_selector/Destroy() - var/mob/living/human/owner = owner_ref?.resolve() - if(istype(owner) && owner.attack_selector == src) - owner.attack_selector = null - . = ..() + name = "default attack selector" + icon_state = "attack_none" + screen_loc = ui_attack_selector + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/default_attack_selector/handle_click(mob/user, params) @@ -31,4 +27,4 @@ ..() var/mob/living/human/owner = owner_ref?.resolve() var/decl/natural_attack/attack = istype(owner) && owner.default_attack - icon_state = attack?.selector_icon_state || "attack_none" + icon_state = (istype(attack) && attack.selector_icon_state) ? attack.selector_icon_state : "attack_none" diff --git a/code/_onclick/hud/screen/screen_constructs.dm b/code/_onclick/hud/screen/screen_constructs.dm index 96932a2d22c0..a0082f804fd6 100644 --- a/code/_onclick/hud/screen/screen_constructs.dm +++ b/code/_onclick/hud/screen/screen_constructs.dm @@ -4,6 +4,6 @@ icon_state = "fire0" screen_loc = ui_construct_fire -/obj/screen/construct_health +/obj/screen/health/construct name = "health" screen_loc = ui_construct_health diff --git a/code/_onclick/hud/screen/screen_gun.dm b/code/_onclick/hud/screen/screen_gun.dm index 86bba4206e74..e0bc13fee624 100644 --- a/code/_onclick/hud/screen/screen_gun.dm +++ b/code/_onclick/hud/screen/screen_gun.dm @@ -39,7 +39,7 @@ name = "Disallow Radio Use" icon_state = "no_radio1" base_icon_state = "no_radio" - screen_loc = ui_gun4 + screen_loc = ui_gun3 toggle_flag = TARGET_CAN_RADIO /obj/screen/gun/mode diff --git a/code/_onclick/hud/screen/screen_health.dm b/code/_onclick/hud/screen/screen_health.dm new file mode 100644 index 000000000000..2322dd2ee220 --- /dev/null +++ b/code/_onclick/hud/screen/screen_health.dm @@ -0,0 +1,66 @@ +/obj/screen/health + name = "health" + icon_state = "health0" + screen_loc = ui_health + +/obj/screen/health/handle_click(mob/user, params) + if(ishuman(user)) + var/mob/living/human/human_user = user + human_user.check_self_injuries() + return TRUE + +/obj/screen/health/on_update_icon() + . = ..() + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner) || owner.stat == DEAD) + icon_state = "health7" + else + icon_state = "health[round(((100-owner.get_health_percent())/100) * 6, 1)]" + +/obj/screen/health/organs/on_update_icon() + + var/mob/living/human/owner = owner_ref?.resolve() + if(!istype(owner)) + return + + cut_overlays() + + // We don't check can_feel_pain() here, otherwise FBP don't get variable health indicators. + if(owner.has_chemical_effect(CE_PAINKILLER, 100)) + icon_state = "health_numb" + compile_overlays() + return + + icon_state = "blank" + + // Generate a by-limb health display. + var/no_damage = 1 + var/trauma_val = 0 // Used in calculating softcrit/hardcrit indicators. + + var/decl/species/my_species = owner.get_species() + trauma_val = max(owner.shock_stage, owner.get_shock())/ (my_species.total_health-100) + + for(var/obj/item/organ/external/E in owner.get_external_organs()) + if(no_damage && (E.brute_dam || E.burn_dam)) + no_damage = 0 + var/damage_image = E.get_damage_hud_image() + if(damage_image) + add_overlay(damage_image) + + // Apply a fire overlay if we're burning. + var/crit_markers = get_ui_icon(owner.client?.prefs?.UI_style, HUD_CRIT_MARKER) + if(crit_markers) + if(owner.is_on_fire()) + add_overlay(image(crit_markers, "burning")) + // Show a general pain/crit indicator if needed. + if(owner.is_asystole()) + add_overlay(image(crit_markers, "hardcrit")) + else if(trauma_val) + if(trauma_val > 0.7) + add_overlay(image(crit_markers, "softcrit")) + if(trauma_val >= 1) + add_overlay(image(crit_markers, "hardcrit")) + else if(no_damage) + add_overlay(image(crit_markers, "fullhealth")) + + compile_overlays() diff --git a/code/_onclick/hud/screen/screen_intent.dm b/code/_onclick/hud/screen/screen_intent.dm index ca75b836812a..f05060384fb4 100644 --- a/code/_onclick/hud/screen/screen_intent.dm +++ b/code/_onclick/hud/screen/screen_intent.dm @@ -48,6 +48,19 @@ icon = intent.icon icon_state = selected ? intent.icon_state : "[intent.icon_state]_off" +/obj/screen/intent_button/MouseEntered(location, control, params) + if(intent && (intent.name || intent.desc)) + openToolTip(user = usr, tip_src = src, params = params, content = intent.desc) + return ..() + +/obj/screen/intent_button/MouseDown() + closeToolTip(usr) + return ..() + +/obj/screen/intent_button/MouseExited() + closeToolTip(usr) + return ..() + /obj/screen/intent name = "intent" icon = 'icons/screen/intents.dmi' @@ -67,7 +80,7 @@ verbs.Cut() /obj/screen/intent/Destroy() - QDEL_NULL(intent_selectors) + QDEL_NULL_LIST(intent_selectors) vis_contents.Cut() return ..() @@ -98,20 +111,21 @@ var/decl/intent/owner_intent = owner.get_intent() var/i = 1 - var/list/all_intents = owner.get_available_intents() + var/list/unused_selectors = intent_selectors?.Copy() + var/list/all_intents = owner.get_available_intents(skip_update = TRUE) for(var/decl/intent/intent as anything in all_intents) var/obj/screen/intent_button/intent_button = get_intent_button(i) if(intent == owner_intent) intent_button.set_selected(intent) else intent_button.set_deselected(intent) + LAZYREMOVE(unused_selectors, intent_button) i++ apply_intent_button_offset(intent_button, i, length(all_intents)) add_vis_contents(intent_button) - if(i < length(intent_selectors)) - for(var/index = i+1 to length(intent_selectors)) - remove_vis_contents(intent_selectors[index]) + if(length(unused_selectors)) + remove_vis_contents(unused_selectors) /obj/screen/intent/binary intent_width = 32 diff --git a/code/_onclick/hud/screen/screen_internal.dm b/code/_onclick/hud/screen/screen_internal.dm index 856132a3faac..20b9d82120f9 100644 --- a/code/_onclick/hud/screen/screen_internal.dm +++ b/code/_onclick/hud/screen/screen_internal.dm @@ -3,6 +3,14 @@ icon_state = "internal0" screen_loc = ui_internal +/obj/screen/internals/on_update_icon() + . = ..() + var/mob/living/owner = owner_ref?.resolve() + if(istype(owner) && owner.get_internals()) + icon_state = "internal1" + else + icon_state = "internal0" + /obj/screen/internals/handle_click(mob/user, params) if(isliving(user)) var/mob/living/M = user diff --git a/code/_onclick/hud/screen/screen_inventory.dm b/code/_onclick/hud/screen/screen_inventory.dm index cc4a4835b826..3714bc5fb107 100644 --- a/code/_onclick/hud/screen/screen_inventory.dm +++ b/code/_onclick/hud/screen/screen_inventory.dm @@ -1,4 +1,6 @@ /obj/screen/inventory + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE var/slot_id //The indentifier for the slot. It has nothing to do with ID cards. var/weakref/mouse_over_atom_ref diff --git a/code/_onclick/hud/screen/screen_module.dm b/code/_onclick/hud/screen/screen_module.dm deleted file mode 100644 index 8b3c162f43e2..000000000000 --- a/code/_onclick/hud/screen/screen_module.dm +++ /dev/null @@ -1,11 +0,0 @@ -/obj/screen/robot_module/select - name = "module" - icon = 'icons/mob/screen/styles/robot/module.dmi' - icon_state = "nomod" - screen_loc = ui_borg_module - requires_ui_style = FALSE - -/obj/screen/robot_module/select/handle_click(mob/user, params) - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.pick_module() diff --git a/code/_onclick/hud/screen/screen_movement.dm b/code/_onclick/hud/screen/screen_movement.dm index 674882295dda..0fd4f4fb52d9 100644 --- a/code/_onclick/hud/screen/screen_movement.dm +++ b/code/_onclick/hud/screen/screen_movement.dm @@ -1,7 +1,9 @@ /obj/screen/movement - name = "movement method" - screen_loc = ui_movi - icon_state = "creeping" + name = "movement method" + screen_loc = ui_movi + icon_state = "creeping" + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE /obj/screen/movement/handle_click(mob/user, params) if(istype(user)) diff --git a/code/_onclick/hud/screen/screen_needs.dm b/code/_onclick/hud/screen/screen_needs.dm index 8a4c66ca08b9..61c43f42c5ba 100644 --- a/code/_onclick/hud/screen/screen_needs.dm +++ b/code/_onclick/hud/screen/screen_needs.dm @@ -1,117 +1,104 @@ // Yes, these use icon state. Yes, these are terrible. The alternative is duplicating // a bunch of fairly blobby logic for every click override on these objects. -/obj/screen/food +/obj/screen/need + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE + screen_loc = ui_nutrition_small + +/obj/screen/need/nutrition name = "nutrition" icon = 'icons/mob/screen/styles/nutrition.dmi' pixel_w = 8 icon_state = "nutrition1" - screen_loc = ui_nutrition_small -/obj/screen/food/handle_click(mob/user, params) - if(user.nutrition_icon == src) - switch(icon_state) - if("nutrition0") - to_chat(user, SPAN_WARNING("You are completely stuffed.")) - if("nutrition1") - to_chat(user, SPAN_NOTICE("You are not hungry.")) - if("nutrition2") - to_chat(user, SPAN_NOTICE("You are a bit peckish.")) - if("nutrition3") - to_chat(user, SPAN_WARNING("You are quite hungry.")) - if("nutrition4") - to_chat(user, SPAN_DANGER("You are starving!")) +/obj/screen/need/nutrition/handle_click(mob/user, params) + switch(icon_state) + if("nutrition0") + to_chat(user, SPAN_WARNING("You are completely stuffed.")) + if("nutrition1") + to_chat(user, SPAN_NOTICE("You are not hungry.")) + if("nutrition2") + to_chat(user, SPAN_NOTICE("You are a bit peckish.")) + if("nutrition3") + to_chat(user, SPAN_WARNING("You are quite hungry.")) + if("nutrition4") + to_chat(user, SPAN_DANGER("You are starving!")) -/obj/screen/drink +/obj/screen/need/nutrition/on_update_icon() + . = ..() + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner) || owner.isSynthetic()) + invisibility = INVISIBILITY_ABSTRACT + return + invisibility = INVISIBILITY_NONE + switch(owner.get_nutrition()) + if(450 to INFINITY) + icon_state = "nutrition0" + if(350 to 450) + icon_state = "nutrition1" + if(250 to 350) + icon_state = "nutrition2" + if(150 to 250) + icon_state = "nutrition3" + else + icon_state = "nutrition4" + +/obj/screen/need/hydration name = "hydration" icon = 'icons/mob/screen/styles/hydration.dmi' icon_state = "hydration1" - screen_loc = ui_nutrition_small - -/obj/screen/drink/handle_click(mob/user, params) - if(user.hydration_icon == src) - switch(icon_state) - if("hydration0") - to_chat(user, SPAN_WARNING("You are overhydrated.")) - if("hydration1") - to_chat(user, SPAN_NOTICE("You are not thirsty.")) - if("hydration2") - to_chat(user, SPAN_NOTICE("You are a bit thirsty.")) - if("hydration3") - to_chat(user, SPAN_WARNING("You are quite thirsty.")) - if("hydration4") - to_chat(user, SPAN_DANGER("You are dying of thirst!")) -/obj/screen/bodytemp - name = "body temperature" - icon = 'icons/mob/screen/styles/status.dmi' - icon_state = "temp1" - screen_loc = ui_temp +/obj/screen/need/hydration/handle_click(mob/user, params) + switch(icon_state) + if("hydration0") + to_chat(user, SPAN_WARNING("You are overhydrated.")) + if("hydration1") + to_chat(user, SPAN_NOTICE("You are not thirsty.")) + if("hydration2") + to_chat(user, SPAN_NOTICE("You are a bit thirsty.")) + if("hydration3") + to_chat(user, SPAN_WARNING("You are quite thirsty.")) + if("hydration4") + to_chat(user, SPAN_DANGER("You are dying of thirst!")) -/obj/screen/bodytemp/handle_click(mob/user, params) - if(user.bodytemp == src) - switch(icon_state) - if("temp4") - to_chat(user, SPAN_DANGER("You are being cooked alive!")) - if("temp3") - to_chat(user, SPAN_DANGER("Your body is burning up!")) - if("temp2") - to_chat(user, SPAN_DANGER("You are overheating.")) - if("temp1") - to_chat(user, SPAN_WARNING("You are uncomfortably hot.")) - if("temp-4") - to_chat(user, SPAN_DANGER("You are being frozen solid!")) - if("temp-3") - to_chat(user, SPAN_DANGER("You are freezing cold!")) - if("temp-2") - to_chat(user, SPAN_WARNING("You are dangerously chilled!")) - if("temp-1") - to_chat(user, SPAN_NOTICE("You are uncomfortably cold.")) - else - to_chat(user, SPAN_NOTICE("Your body is at a comfortable temperature.")) - -/obj/screen/pressure - name = "pressure" - icon = 'icons/mob/screen/styles/status.dmi' - icon_state = "pressure0" - screen_loc = ui_temp - -/obj/screen/pressure/handle_click(mob/user, params) - if(user.pressure == src) - switch(icon_state) - if("pressure2") - to_chat(user, SPAN_DANGER("The air pressure here is crushing!")) - if("pressure1") - to_chat(user, SPAN_WARNING("The air pressure here is dangerously high.")) - if("pressure-1") - to_chat(user, SPAN_WARNING("The air pressure here is dangerously low.")) - if("pressure-2") - to_chat(user, SPAN_DANGER("There is nearly no air pressure here!")) - else - to_chat(user, SPAN_NOTICE("The local air pressure is comfortable.")) - -/obj/screen/toxins - name = "toxin" - icon = 'icons/mob/screen/styles/status.dmi' - icon_state = "tox0" - screen_loc = ui_temp - -/obj/screen/toxins/handle_click(mob/user, params) - if(user.toxin == src) - if(icon_state == "tox0") - to_chat(user, SPAN_NOTICE("The air is clear of toxins.")) +/obj/screen/need/hydration/on_update_icon() + . = ..() + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner) || owner.isSynthetic()) + invisibility = INVISIBILITY_ABSTRACT + return + invisibility = INVISIBILITY_NONE + switch(owner.get_hydration()) + if(450 to INFINITY) + icon_state = "hydration0" + if(350 to 450) + icon_state = "hydration1" + if(250 to 350) + icon_state = "hydration2" + if(150 to 250) + icon_state = "hydration3" else - to_chat(user, SPAN_DANGER("The air is eating away at your skin!")) + icon_state = "hydration4" -/obj/screen/oxygen - name = "oxygen" - icon = 'icons/mob/screen/styles/status.dmi' - icon_state = "oxy0" - screen_loc = ui_temp +/obj/screen/need/cell_charge + name = "cell" + icon_state = "charge-empty" + screen_loc = ui_nutrition -/obj/screen/oxygen/handle_click(mob/user, params) - if(user.oxygen == src) - if(icon_state == "oxy0") - to_chat(user, SPAN_NOTICE("You are breathing easy.")) - else - to_chat(user, SPAN_DANGER("You cannot breathe!")) +/obj/screen/need/cell_charge/robot + screen_loc = ui_toxin + +/obj/screen/need/cell_charge/on_update_icon() + . = ..() + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner) || !owner.isSynthetic()) + invisibility = INVISIBILITY_ABSTRACT + return + invisibility = INVISIBILITY_NONE + var/obj/item/cell/cell = owner.get_cell() + if(cell) + var/chargeNum = clamp(ceil(cell.percent()/25), 0, 4) //0-100 maps to 0-4, but give it a paranoid clamp just in case. + icon_state = "charge[chargeNum]" + else + icon_state = "charge-empty" diff --git a/code/_onclick/hud/screen/screen_pai.dm b/code/_onclick/hud/screen/screen_pai.dm index 51ceb9d7c27e..08de1ff85060 100644 --- a/code/_onclick/hud/screen/screen_pai.dm +++ b/code/_onclick/hud/screen/screen_pai.dm @@ -3,15 +3,9 @@ abstract_type = /obj/screen/pai requires_ui_style = FALSE user_incapacitation_flags = INCAPACITATION_KNOCKOUT - -/obj/screen/pai/shell - name = "Toggle Chassis" - -/obj/screen/pai/rest - name = "Rest" - -/obj/screen/pai/light - name = "Toggle Light" + use_supplied_ui_alpha = FALSE + use_supplied_ui_color = FALSE + use_supplied_ui_icon = FALSE /obj/screen/pai/software name = "Software Interface" @@ -74,3 +68,24 @@ var/stat_silicon_subsystem/SSS = pai.silicon_subsystems_by_name[ss_name] if(istype(SSS)) SSS.Click() + +/decl/hud_element/pai + abstract_type = /decl/hud_element/pai + +/decl/hud_element/pai/shell + elem_type = /obj/screen/pai/shell + +/decl/hud_element/pai/rest + elem_type = /obj/screen/pai/rest + +/decl/hud_element/pai/light + elem_type = /obj/screen/pai/light + +/decl/hud_element/pai/software + elem_type = /obj/screen/pai/software + +/decl/hud_element/pai/chassis + elem_type = /obj/screen/pai/chassis + +/decl/hud_element/pai/subsystems + elem_type = /obj/screen/pai/subsystems diff --git a/code/_onclick/hud/screen/screen_robot_drop_grab.dm b/code/_onclick/hud/screen/screen_robot_drop_grab.dm deleted file mode 100644 index 38232bf14d70..000000000000 --- a/code/_onclick/hud/screen/screen_robot_drop_grab.dm +++ /dev/null @@ -1,15 +0,0 @@ -/obj/screen/robot_drop_grab - name = "drop grab" - icon = 'icons/mob/screen/styles/robot/drop_grab.dmi' - icon_state = "drop_grab" - screen_loc = ui_borg_drop_grab - invisibility = INVISIBILITY_MAXIMUM - alpha = 0 - requires_ui_style = FALSE - -/obj/screen/robot_drop_grab/handle_click(mob/user, params) - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.drop_item() - set_invisibility(INVISIBILITY_MAXIMUM) - alpha = 0 diff --git a/code/_onclick/hud/screen/screen_robot_panel.dm b/code/_onclick/hud/screen/screen_robot_panel.dm deleted file mode 100644 index c712a6374423..000000000000 --- a/code/_onclick/hud/screen/screen_robot_panel.dm +++ /dev/null @@ -1,11 +0,0 @@ -/obj/screen/robot_panel - name = "panel" - icon = 'icons/mob/screen/styles/robot/panel.dmi' - icon_state = "panel" - screen_loc = ui_borg_panel - requires_ui_style = FALSE - -/obj/screen/robot_panel/handle_click(mob/user, params) - if(isrobot(user)) - var/mob/living/silicon/robot/R = user - R.installed_modules() diff --git a/code/_onclick/hud/screen/screen_robot_warnings.dm b/code/_onclick/hud/screen/screen_robot_warnings.dm deleted file mode 100644 index 6cff60008fd2..000000000000 --- a/code/_onclick/hud/screen/screen_robot_warnings.dm +++ /dev/null @@ -1,19 +0,0 @@ -/obj/screen/robot_charge - name = "cell" - icon_state = "charge-empty" - screen_loc = ui_toxin - -/obj/screen/robot_health - name = "health" - icon_state = "health0" - screen_loc = ui_borg_health - -/obj/screen/robot_oxygen - name = "oxygen" - icon_state = "oxy0" - screen_loc = ui_oxygen - -/obj/screen/robot_fire - name = "fire" - icon_state = "fire0" - screen_loc = ui_fire diff --git a/code/_onclick/hud/screen/screen_stamina.dm b/code/_onclick/hud/screen/screen_stamina.dm index 09051b8c74b4..b70d9e743618 100644 --- a/code/_onclick/hud/screen/screen_stamina.dm +++ b/code/_onclick/hud/screen/screen_stamina.dm @@ -1,7 +1,21 @@ /obj/screen/stamina - name = "stamina" - icon = 'icons/effects/progressbar.dmi' - icon_state = "prog_bar_100" - invisibility = INVISIBILITY_MAXIMUM - screen_loc = ui_stamina + name = "stamina" + icon = 'icons/effects/progressbar.dmi' + icon_state = "prog_bar_100" + invisibility = INVISIBILITY_MAXIMUM + screen_loc = ui_stamina requires_ui_style = FALSE + layer = HUD_BASE_LAYER + 0.1 // needs to layer over the movement intent element + +/obj/screen/stamina/on_update_icon() + . = ..() + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner)) + set_invisibility(INVISIBILITY_MAXIMUM) + else + var/stamina = owner.get_stamina() + if(stamina < 100) + set_invisibility(INVISIBILITY_NONE) + icon_state = "prog_bar_[floor(stamina/5)*5][(stamina >= 5) && (stamina <= 25) ? "_fail" : null]" + else + set_invisibility(INVISIBILITY_MAXIMUM) diff --git a/code/_onclick/hud/screen/screen_toggle.dm b/code/_onclick/hud/screen/screen_toggle.dm index ddeb923911b8..4f534e230f33 100644 --- a/code/_onclick/hud/screen/screen_toggle.dm +++ b/code/_onclick/hud/screen/screen_toggle.dm @@ -6,10 +6,4 @@ /obj/screen/toggle/handle_click(mob/user, params) if(!user.hud_used) return - if(user.hud_used.inventory_shown) - user.client.screen -= user.hud_used.other - user.hud_used.hide_inventory() - else - user.client.screen += user.hud_used.other - user.hud_used.show_inventory() - return TRUE + return user.hud_used.toggle_show_inventory() diff --git a/code/_onclick/hud/screen/screen_up_hint.dm b/code/_onclick/hud/screen/screen_up_hint.dm index 5a1a2b796fc1..4a97f61be1a5 100644 --- a/code/_onclick/hud/screen/screen_up_hint.dm +++ b/code/_onclick/hud/screen/screen_up_hint.dm @@ -1,14 +1,16 @@ -/obj/screen/up_hint - name = "up hint" - icon_state = "uphint0" - screen_loc = ui_up_hint +/obj/screen/look_upward + name = "up hint" + icon_state = "uphint0" + screen_loc = ui_up_hint + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE -/obj/screen/up_hint/handle_click(mob/user, params) +/obj/screen/look_upward/handle_click(mob/user, params) if(isliving(user)) var/mob/living/L = user L.lookup() -/obj/screen/up_hint/on_update_icon() +/obj/screen/look_upward/on_update_icon() var/mob/owner = owner_ref?.resolve() var/turf/above = istype(owner) ? GetAbove(get_turf(owner)) : null icon_state = "uphint[!!(istype(above) && TURF_IS_MIMICKING(above))]" diff --git a/code/_onclick/hud/screen/screen_warning.dm b/code/_onclick/hud/screen/screen_warning.dm new file mode 100644 index 000000000000..f7aad53c4872 --- /dev/null +++ b/code/_onclick/hud/screen/screen_warning.dm @@ -0,0 +1,12 @@ +/obj/screen/warning + use_supplied_ui_color = TRUE + use_supplied_ui_alpha = TRUE + var/base_state + var/check_alert + +/obj/screen/warning/on_update_icon() + . = ..() + if(base_state && check_alert) + var/mob/living/owner = owner_ref?.resolve() + if(istype(owner)) + icon_state = "[base_state][GET_HUD_ALERT(owner, check_alert)]" diff --git a/code/_onclick/hud/screen/screen_warning_bodytemp.dm b/code/_onclick/hud/screen/screen_warning_bodytemp.dm new file mode 100644 index 000000000000..88bdafba7dfa --- /dev/null +++ b/code/_onclick/hud/screen/screen_warning_bodytemp.dm @@ -0,0 +1,90 @@ + +/obj/screen/warning/bodytemp + name = "body temperature" + icon = 'icons/mob/screen/styles/status_bodytemp.dmi' + icon_state = "temp1" + screen_loc = ui_temp + +/obj/screen/warning/bodytemp/on_update_icon() + . = ..() + + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner)) + return + + var/decl/species/my_species = owner.get_species() + if(!my_species) + switch(owner.bodytemperature) //310.055 optimal body temp + if(370 to INFINITY) + icon_state = "temp4" + if(350 to 370) + icon_state = "temp3" + if(335 to 350) + icon_state = "temp2" + if(320 to 335) + icon_state = "temp1" + if(300 to 320) + icon_state = "temp0" + if(295 to 300) + icon_state = "temp-1" + if(280 to 295) + icon_state = "temp-2" + if(260 to 280) + icon_state = "temp-3" + else + icon_state = "temp-4" + return + + var/heat_1 = owner.get_mob_temperature_threshold(HEAT_LEVEL_1) + var/cold_1 = owner.get_mob_temperature_threshold(COLD_LEVEL_1) + + //TODO: precalculate all of this stuff when the species datum is created + var/base_temperature = my_species.body_temperature + if(base_temperature == null) //some species don't have a set metabolic temperature + base_temperature = (heat_1 + cold_1)/2 + + if (owner.bodytemperature >= base_temperature) + var/temp_step = (heat_1 - base_temperature)/4 + if (owner.bodytemperature >= heat_1) + icon_state = "temp4" + else if (owner.bodytemperature >= base_temperature + temp_step*3) + icon_state = "temp3" + else if (owner.bodytemperature >= base_temperature + temp_step*2) + icon_state = "temp2" + else if (owner.bodytemperature >= base_temperature + temp_step*1) + icon_state = "temp1" + else + icon_state = "temp0" + else if (owner.bodytemperature < base_temperature) + var/temp_step = (base_temperature - cold_1)/4 + if (owner.bodytemperature <= cold_1) + icon_state = "temp-4" + else if (owner.bodytemperature <= base_temperature - temp_step*3) + icon_state = "temp-3" + else if (owner.bodytemperature <= base_temperature - temp_step*2) + icon_state = "temp-2" + else if (owner.bodytemperature <= base_temperature - temp_step*1) + icon_state = "temp-1" + else + icon_state = "temp0" + +/obj/screen/warning/bodytemp/handle_click(mob/user, params) + switch(icon_state) + if("temp4") + to_chat(user, SPAN_DANGER("You are being cooked alive!")) + if("temp3") + to_chat(user, SPAN_DANGER("Your body is burning up!")) + if("temp2") + to_chat(user, SPAN_DANGER("You are overheating.")) + if("temp1") + to_chat(user, SPAN_WARNING("You are uncomfortably hot.")) + if("temp-4") + to_chat(user, SPAN_DANGER("You are being frozen solid!")) + if("temp-3") + to_chat(user, SPAN_DANGER("You are freezing cold!")) + if("temp-2") + to_chat(user, SPAN_WARNING("You are dangerously chilled!")) + if("temp-1") + to_chat(user, SPAN_NOTICE("You are uncomfortably cold.")) + else + to_chat(user, SPAN_NOTICE("Your body is at a comfortable temperature.")) diff --git a/code/_onclick/hud/screen/screen_warning_fire.dm b/code/_onclick/hud/screen/screen_warning_fire.dm new file mode 100644 index 000000000000..ec39eb5fa636 --- /dev/null +++ b/code/_onclick/hud/screen/screen_warning_fire.dm @@ -0,0 +1,6 @@ +/obj/screen/warning/fire + name = "fire" + icon_state = "fire0" + screen_loc = ui_fire + base_state = "fire" + check_alert = /decl/hud_element/fire diff --git a/code/_onclick/hud/screen/screen_warning_oxygen.dm b/code/_onclick/hud/screen/screen_warning_oxygen.dm new file mode 100644 index 000000000000..f964f7017a6c --- /dev/null +++ b/code/_onclick/hud/screen/screen_warning_oxygen.dm @@ -0,0 +1,34 @@ +/obj/screen/warning/oxygen + name = "oxygen" + icon = 'icons/mob/screen/styles/status_oxy.dmi' + icon_state = "oxy0" + screen_loc = ui_temp + base_state = "oxy" + check_alert = /decl/hud_element/oxygen + +/obj/screen/warning/oxygen/handle_click(mob/user, params) + if(icon_state == "oxy0") + to_chat(user, SPAN_NOTICE("You are breathing easy.")) + else + to_chat(user, SPAN_DANGER("You cannot breathe!")) + +// Robots use this warning icon as an environment indicator, not based on our own tolerances. +/obj/screen/warning/oxygen/robot + screen_loc = ui_oxygen + +/obj/screen/warning/oxygen/robot/on_update_icon() + var/mob/living/owner = owner_ref?.resolve() + if(!istype(owner)) + return + var/datum/gas_mixture/environment = owner.loc?.return_air() + if(!environment) + return + var/decl/species/species = get_species_by_key(global.using_map.default_species) + if(!species.breath_type || environment.gas[species.breath_type] > species.breath_pressure) + for(var/gas in species.poison_types) + if(environment.gas[gas]) + icon_state = "oxy1" + return + icon_state = "oxy0" + else + icon_state = "oxy1" diff --git a/code/_onclick/hud/screen/screen_warning_pressure.dm b/code/_onclick/hud/screen/screen_warning_pressure.dm new file mode 100644 index 000000000000..cd77e8d8c0db --- /dev/null +++ b/code/_onclick/hud/screen/screen_warning_pressure.dm @@ -0,0 +1,20 @@ +/obj/screen/warning/pressure + name = "pressure" + icon = 'icons/mob/screen/styles/status_pressure.dmi' + icon_state = "pressure0" + screen_loc = ui_temp + base_state = "pressure" + check_alert = /decl/hud_element/pressure + +/obj/screen/warning/pressure/handle_click(mob/user, params) + switch(icon_state) + if("pressure2") + to_chat(user, SPAN_DANGER("The air pressure here is crushing!")) + if("pressure1") + to_chat(user, SPAN_WARNING("The air pressure here is dangerously high.")) + if("pressure-1") + to_chat(user, SPAN_WARNING("The air pressure here is dangerously low.")) + if("pressure-2") + to_chat(user, SPAN_DANGER("There is nearly no air pressure here!")) + else + to_chat(user, SPAN_NOTICE("The local air pressure is comfortable.")) diff --git a/code/_onclick/hud/screen/screen_warning_toxins.dm b/code/_onclick/hud/screen/screen_warning_toxins.dm new file mode 100644 index 000000000000..ef8c391491be --- /dev/null +++ b/code/_onclick/hud/screen/screen_warning_toxins.dm @@ -0,0 +1,13 @@ +/obj/screen/warning/toxin + name = "toxin" + icon = 'icons/mob/screen/styles/status_tox.dmi' + icon_state = "tox0" + screen_loc = ui_temp + base_state = "tox" + check_alert = /decl/hud_element/toxins + +/obj/screen/warning/toxin/handle_click(mob/user, params) + if(icon_state == "tox0") + to_chat(user, SPAN_NOTICE("The air is clear of toxins.")) + else + to_chat(user, SPAN_DANGER("The air is eating away at your skin!")) diff --git a/code/_onclick/hud/screen/screen_warnings.dm b/code/_onclick/hud/screen/screen_warnings.dm deleted file mode 100644 index d89eb94e10b2..000000000000 --- a/code/_onclick/hud/screen/screen_warnings.dm +++ /dev/null @@ -1,20 +0,0 @@ -/obj/screen/fire_warning - name = "fire" - icon_state = "fire0" - screen_loc = ui_fire - -/obj/screen/health_warning - name = "health" - icon_state = "health0" - screen_loc = ui_health - -/obj/screen/health_warning/handle_click(mob/user, params) - if(ishuman(user)) - var/mob/living/human/human_user = user - human_user.check_self_injuries() - return TRUE - -/obj/screen/warning_cells - name = "cell" - icon_state = "charge-empty" - screen_loc = ui_nutrition diff --git a/code/_onclick/hud/screen/screen_zone_selector.dm b/code/_onclick/hud/screen/screen_zone_selector.dm index 0850498b7f2a..51b36db21255 100644 --- a/code/_onclick/hud/screen/screen_zone_selector.dm +++ b/code/_onclick/hud/screen/screen_zone_selector.dm @@ -2,7 +2,6 @@ name = "damage zone" icon_state = "zone_sel_tail" screen_loc = ui_zonesel - var/selecting = BP_CHEST /obj/screen/zone_selector/handle_click(mob/user, params) var/list/PL = params2list(params) @@ -61,16 +60,16 @@ if(25 to 27) if(icon_x in 15 to 17) new_selecting = BP_EYES - set_selected_zone(new_selecting) + user.set_target_zone(new_selecting) return TRUE -/obj/screen/zone_selector/proc/set_selected_zone(bodypart) - var/old_selecting = selecting - selecting = bodypart - if(old_selecting != selecting) +/obj/screen/zone_selector/proc/set_selected_zone(new_zone, old_zone) + if(new_zone != old_zone) update_icon() return TRUE /obj/screen/zone_selector/rebuild_screen_overlays() ..() - add_overlay(image('icons/mob/zone_sel.dmi', "[selecting]")) + var/mob/living/owner = owner_ref?.resolve() + if(istype(owner)) + add_overlay(image('icons/mob/zone_sel.dmi', "[owner.selected_zone]")) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index f3d74569b41b..3a3c22928073 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -33,7 +33,8 @@ user.visible_message( SPAN_DANGER("\The [user] shakes \the [src]!"), - SPAN_DANGER("You shake \the [src]!")) + SPAN_DANGER("You shake \the [src]!") + ) object_shaken() return TRUE diff --git a/code/controllers/communications.dm b/code/controllers/communications.dm index d91f03f89eed..05694e4565d7 100644 --- a/code/controllers/communications.dm +++ b/code/controllers/communications.dm @@ -94,13 +94,13 @@ var/global/const/EXTERNAL_AIR_FREQ = 1381 // Used by some external airlocks. //Other devices can then choose to send signals to only those devices that belong to a particular filter. //This is done for performance, so we don't send signals to lots of machines unnecessarily. -//This filter is special because devices belonging to default also recieve signals sent to any other filter. +//This filter is special because devices belonging to default also receive signals sent to any other filter. var/global/const/RADIO_DEFAULT = "radio_default" -//This filter is special because devices belonging to it do not recieve any signals at all. Useful for devices which only transmit. +//This filter is special because devices belonging to it do not receive any signals at all. Useful for devices which only transmit. var/global/const/RADIO_NULL = "radio_null" var/global/const/RADIO_TO_AIRALARM = "radio_airalarm" //air alarms -var/global/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in recieving signals from air alarms +var/global/const/RADIO_FROM_AIRALARM = "radio_airalarm_rcvr" //devices interested in receiving signals from air alarms var/global/const/RADIO_CHAT = "radio_telecoms" var/global/const/RADIO_ATMOSIA = "radio_atmos" var/global/const/RADIO_NAVBEACONS = "radio_navbeacon" diff --git a/code/controllers/subsystems/icon_updates.dm b/code/controllers/subsystems/icon_updates.dm index 7ad1540578ba..de98f51b0343 100644 --- a/code/controllers/subsystems/icon_updates.dm +++ b/code/controllers/subsystems/icon_updates.dm @@ -7,7 +7,6 @@ SUBSYSTEM_DEF(icon_update) // Linked lists, queue_refs[x] should have null or args stored in queue_args[x] var/list/queue_refs = list() // Atoms - var/list/queue_args = list() // null or args /datum/controller/subsystem/icon_update/stat_entry() ..("Queue: [queue_refs.len]") @@ -16,56 +15,43 @@ SUBSYSTEM_DEF(icon_update) fire(FALSE, TRUE) /datum/controller/subsystem/icon_update/fire(resumed = FALSE, no_mc_tick = FALSE) - if(!queue_refs.len) + var/list/cached_refs = queue_refs // local variables are quicker to access than instance variables. it's still the same list though + if(!cached_refs.len) suspend() return - while (queue_refs.len) - - if(Master.map_loading) - return - - // Pops the atom and its args - var/atom/A = queue_refs[queue_refs.len] - var/myArgs = queue_args[queue_args.len] - - queue_refs.len -= 1 - queue_args.len -= 1 - + var/static/count = 1 // proc-level static var, as with SSgarbage, in case a runtime makes this proc end early + while (count <= length(cached_refs)) // if we kept a copy of the queue to avoid mutating it while we run, this could possibly be made a lot faster by just using a for loop? + if(Master.map_loading) // we started loading a map mid-run, so stop and clean up + break + // Pops the atom from the queue + var/atom/A = cached_refs[count++] // count is used to cut our list later and save time if(QDELETED(A)) continue - A.icon_update_queued = FALSE - - if (islist(myArgs)) - A.update_icon(arglist(myArgs)) - else - A.update_icon() - + A.update_icon() if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) - return + break + cached_refs.Cut(1, count) + count = 1 /atom var/icon_update_queued = FALSE -/atom/proc/queue_icon_update(...) +/atom/proc/queue_icon_update() // Skips if this is already queued - if(!icon_update_queued) - - icon_update_queued = TRUE - SSicon_update.queue_refs.Add(src) - - // Makes sure these are in sync, in case runtimes/badmin - var/length = length(SSicon_update.queue_refs) - SSicon_update.queue_args.len = length - SSicon_update.queue_args[length] = args.len ? args : null - - // SSicon_update sleeps when it runs out of things in its - // queue, so wake it up. - if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads. - SSicon_update.wake() + if(icon_update_queued) + return + icon_update_queued = TRUE + // This is faster than using Add() because BYOND. + SSicon_update.queue_refs[++SSicon_update.queue_refs.len] = src + + // SSicon_update sleeps when it runs out of things in its + // queue, so wake it up. + if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads. + SSicon_update.wake() /datum/controller/subsystem/icon_update/StartLoadingMap() suspend() diff --git a/code/controllers/subsystems/initialization/modpacks.dm b/code/controllers/subsystems/initialization/modpacks.dm index f2f6c65a2e69..7a44aec55c6f 100644 --- a/code/controllers/subsystems/initialization/modpacks.dm +++ b/code/controllers/subsystems/initialization/modpacks.dm @@ -6,7 +6,7 @@ SUBSYSTEM_DEF(modpacks) // Compiled modpack information. var/list/default_submap_whitelisted_species = list() - var/list/default_submap_blacklisted_species = list(SPECIES_ALIEN, SPECIES_GOLEM) + var/list/default_submap_blacklisted_species = list() var/list/modpack_nanoui_directories = list() /datum/controller/subsystem/modpacks/Initialize() diff --git a/code/controllers/subsystems/lighting.dm b/code/controllers/subsystems/lighting.dm index 61f8b083a33b..068353abbe0c 100644 --- a/code/controllers/subsystems/lighting.dm +++ b/code/controllers/subsystems/lighting.dm @@ -57,7 +57,10 @@ SUBSYSTEM_DEF(lighting) var/datum/level_data/level = SSmapping.levels_by_z[zlevel] for (var/turf/tile as anything in block(1, 1, zlevel, level.level_max_width, level.level_max_height)) // include TRANSITIONEDGE turfs if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(tile)) - tile.lighting_build_overlay() + if(!isnull(tile.lighting_overlay)) + log_warning("Attempted to create lighting_overlay on [tile.get_log_info_line()] when it already had one.") + continue + new /atom/movable/lighting_overlay(tile) overlaycount++ CHECK_TICK diff --git a/code/controllers/subsystems/machines.dm b/code/controllers/subsystems/machines.dm index 674ec094cc68..19a5202daa38 100644 --- a/code/controllers/subsystems/machines.dm +++ b/code/controllers/subsystems/machines.dm @@ -7,7 +7,7 @@ if (Datum.is_processing) {\ if(Datum.is_processing != "SSmachines.[#List]")\ {\ - PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occured on SSmachines.[#List]."); \ + PRINT_STACK_TRACE("Failed to start processing. [log_info_line(Datum)] is already being processed by [Datum.is_processing] but queue attempt occurred on SSmachines.[#List]."); \ }\ } else {\ Datum.is_processing = "SSmachines.[#List]";\ diff --git a/code/controllers/subsystems/spacedrift.dm b/code/controllers/subsystems/spacedrift.dm index 31b4d0fae597..331e856cdf49 100644 --- a/code/controllers/subsystems/spacedrift.dm +++ b/code/controllers/subsystems/spacedrift.dm @@ -34,9 +34,9 @@ SUBSYSTEM_DEF(spacedrift) return continue - if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.Process_Spacemove(0)) + if (!AM.loc || AM.loc != AM.inertia_last_loc || AM.is_space_movement_permitted() != SPACE_MOVE_FORBIDDEN) AM.inertia_dir = 0 - + AM.inertia_ignore = null if (!AM.inertia_dir) diff --git a/code/controllers/subsystems/throwing.dm b/code/controllers/subsystems/throwing.dm index 4dc2001e17ed..0849837efd8f 100644 --- a/code/controllers/subsystems/throwing.dm +++ b/code/controllers/subsystems/throwing.dm @@ -33,7 +33,7 @@ SUBSYSTEM_DEF(throwing) continue if (QDELETED(TT)) if(!QDELETED(AM)) - AM.end_throw() + AM.end_throw(TT) processing -= AM if (MC_TICK_CHECK) return @@ -103,7 +103,7 @@ SUBSYSTEM_DEF(throwing) /datum/thrownthing/Destroy() SSthrowing.processing -= thrownthing - thrownthing.end_throw() + thrownthing.end_throw(src) thrownthing = null target = null thrower = null @@ -192,7 +192,7 @@ SUBSYSTEM_DEF(throwing) if(!QDELETED(thrownthing)) thrownthing.fall() - thrownthing.end_throw() + thrownthing.end_throw(src) qdel(src) /datum/thrownthing/proc/hit_atom(atom/A) diff --git a/code/controllers/subsystems/vis_contents.dm b/code/controllers/subsystems/vis_contents.dm index b18e803da68e..3cafe0983796 100644 --- a/code/controllers/subsystems/vis_contents.dm +++ b/code/controllers/subsystems/vis_contents.dm @@ -21,26 +21,24 @@ SUBSYSTEM_DEF(vis_contents_update) // Largely copied from SSicon_update. /datum/controller/subsystem/vis_contents_update/fire(resumed = FALSE, no_mc_tick = FALSE) - if(!queue_refs.len) + var/list/cached_refs = queue_refs // cache the instance var for more speed + if(!length(cached_refs)) suspend() return var/i = 0 - while (i < queue_refs.len) - i++ - var/atom/A = queue_refs[i] + while (i < length(cached_refs)) + if(Master.map_loading) + break + var/atom/A = cached_refs[++i] if(QDELETED(A)) continue - if(Master.map_loading) - queue_refs.Cut(1, i+1) - return A.vis_update_queued = FALSE - A.update_vis_contents(force_no_queue = TRUE) + A.update_vis_contents() if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) - queue_refs.Cut(1, i+1) - return - queue_refs.Cut() + break + cached_refs.Cut(1, i+1) /atom var/vis_update_queued = FALSE @@ -49,8 +47,8 @@ SUBSYSTEM_DEF(vis_contents_update) if(vis_update_queued) return vis_update_queued = TRUE - SSvis_contents_update.queue_refs.Add(src) - if(!Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads. + SSvis_contents_update.queue_refs[++SSvis_contents_update.queue_refs.len] = src + if(SSvis_contents_update.suspended && !Master.map_loading) // Don't wake early if we're loading a map, it'll get woken up when the map loads. SSvis_contents_update.wake() // Horrible colon syntax below is because vis_contents @@ -70,8 +68,8 @@ SUBSYSTEM_DEF(vis_contents_update) /atom/proc/get_vis_contents_to_add() return -/atom/proc/update_vis_contents(force_no_queue = FALSE) - if(!force_no_queue && (!SSvis_contents_update.initialized || TICK_CHECK)) +/atom/proc/update_vis_contents() + if(Master.map_loading || SSvis_contents_update.init_state == SS_INITSTATE_NONE || TICK_CHECK) queue_vis_contents_update() return vis_update_queued = FALSE diff --git a/code/controllers/subsystems/vote.dm b/code/controllers/subsystems/vote.dm index fb2a258791c9..5acccf7afe08 100644 --- a/code/controllers/subsystems/vote.dm +++ b/code/controllers/subsystems/vote.dm @@ -12,7 +12,7 @@ SUBSYSTEM_DEF(vote) var/list/old_votes //Stores completed votes for reference. var/queued_auto_vote //Used if a vote queues another vote to happen after it. - var/list/voting = list() //Clients recieving UI updates. + var/list/voting = list() //Clients receiving UI updates. var/list/vote_prototypes //To run checks on whether they are available. /datum/controller/subsystem/vote/Initialize() diff --git a/code/datums/communication/dsay.dm b/code/datums/communication/dsay.dm index 273f17a36b74..c329b243c89b 100644 --- a/code/datums/communication/dsay.dm +++ b/code/datums/communication/dsay.dm @@ -10,8 +10,9 @@ mute_setting = MUTE_DEADCHAT show_preference_setting = /datum/client_preference/show_dsay +// Changes the default speech_method kwarg. /decl/communication_channel/dsay/communicate(communicator, message, speech_method = /decl/dsay_communication/say) - ..() + return ..() /decl/communication_channel/dsay/can_communicate(var/client/communicator, var/message, var/speech_method_type) var/decl/dsay_communication/speech_method = GET_DECL(speech_method_type) diff --git a/code/datums/config/config_types/config_client.dm b/code/datums/config/config_types/config_client.dm index 7219bc3189fb..ed8a0224daff 100644 --- a/code/datums/config/config_types/config_client.dm +++ b/code/datums/config/config_types/config_client.dm @@ -51,7 +51,7 @@ /decl/config/toggle/popup_admin_pm uid = "popup_admin_pm" desc = list( - "Remove the # to show a popup 'reply to' window to every non-admin that recieves an adminPM.", + "Remove the # to show a popup 'reply to' window to every non-admin that receives an adminPM.", "The intention is to make adminPMs more visible. (although I fnd popups annoying so this defaults to off)." ) diff --git a/code/datums/config/config_types/config_game_world.dm b/code/datums/config/config_types/config_game_world.dm index f7749cfce81a..66b154dd6dc6 100644 --- a/code/datums/config/config_types/config_game_world.dm +++ b/code/datums/config/config_types/config_game_world.dm @@ -22,7 +22,8 @@ /decl/config/toggle/humans_need_surnames, /decl/config/toggle/roundstart_level_generation, /decl/config/toggle/lights_start_on, - /decl/config/toggle/on/cisnormativity + /decl/config/toggle/on/cisnormativity, + /decl/config/enum/colored_coating_names ) /decl/config/num/exterior_ambient_light @@ -134,4 +135,14 @@ /decl/config/toggle/on/cisnormativity uid = "cisnormativity" - desc = "If true, when bodytype is changed in character creation, selected pronouns are also changed." \ No newline at end of file + desc = "If true, when bodytype is changed in character creation, selected pronouns are also changed." + +/decl/config/enum/colored_coating_names + uid = "colored_coating_names" + desc = "Determines the coloring of various strings representing coatings on objects (blood, oil, mud, etc)." + default_value = CONFIG_COATING_COLOR_MIXTURE + enum_map = list( + "none" = CONFIG_COATING_COLOR_NONE, + "mixture" = CONFIG_COATING_COLOR_MIXTURE, + "components" = CONFIG_COATING_COLOR_COMPONENTS + ) \ No newline at end of file diff --git a/code/datums/movement/mob.dm b/code/datums/movement/mob.dm index cb703f6ca937..996c62150859 100644 --- a/code/datums/movement/mob.dm +++ b/code/datums/movement/mob.dm @@ -62,21 +62,28 @@ return (MOVEMENT_PROCEED|MOVEMENT_HANDLED) /datum/movement_handler/mob/space - var/allow_move + var/last_space_move_result + +// Notes on space movement chain: +// - owning mob calls MayMove() via normal movement handler chain +// - MayMove() sets last_space_move_result based on is_space_movement_permitted() (checks for footing, magboots, etc) +// - last_space_move_result is checked in DoMove() and passed to try_space_move() as a param, which returns TRUE/FALSE +// - if the original move result was forbidden, or try_space_move() fails, the handler prevents movement. +// - Otherwise it goes ahead and lets the mob move. // Space movement /datum/movement_handler/mob/space/DoMove(direction, mob/mover, is_external) if(mob.has_gravity() || (IS_NOT_SELF(mover) && is_external)) return - if(!allow_move || !mob.space_do_move(allow_move, direction)) + if(last_space_move_result == SPACE_MOVE_FORBIDDEN || !mob.try_space_move(last_space_move_result, direction)) return MOVEMENT_HANDLED /datum/movement_handler/mob/space/MayMove(mob/mover, is_external) if(IS_NOT_SELF(mover) && is_external) return MOVEMENT_PROCEED if(!mob.has_gravity()) - allow_move = mob.Process_Spacemove(1) - if(!allow_move) + last_space_move_result = mob.is_space_movement_permitted(allow_movement = TRUE) + if(last_space_move_result == SPACE_MOVE_FORBIDDEN) return MOVEMENT_STOP return MOVEMENT_PROCEED diff --git a/code/datums/movement/robot.dm b/code/datums/movement/robot.dm index 258c5e840b4c..2674938b3cc0 100644 --- a/code/datums/movement/robot.dm +++ b/code/datums/movement/robot.dm @@ -16,8 +16,11 @@ // Use power while moving. /datum/movement_handler/robot/use_power/DoMove(direction, mob/mover, is_external) var/datum/robot_component/actuator/A = robot.get_component("actuator") - if(!robot.cell_use_power(A.active_usage * robot.power_efficiency)) + if(!is_external && !robot.cell_use_power(A.active_usage * robot.power_efficiency)) return MOVEMENT_HANDLED + return MOVEMENT_PROCEED /datum/movement_handler/robot/use_power/MayMove(mob/mover, is_external) - return (!robot.lockcharge && robot.is_component_functioning("actuator")) ? MOVEMENT_PROCEED : MOVEMENT_STOP + if(is_external || (!robot.incapacitated() && !robot.lockcharge && robot.is_component_functioning("actuator"))) + return MOVEMENT_PROCEED + return MOVEMENT_STOP diff --git a/code/datums/observation/zone_selected.dm b/code/datums/observation/zone_selected.dm index 1b5272c33df9..8a4c7bc58756 100644 --- a/code/datums/observation/zone_selected.dm +++ b/code/datums/observation/zone_selected.dm @@ -17,7 +17,6 @@ * Zone Selected Handling * *******************/ -/obj/screen/zone_selector/set_selected_zone(bodypart) - var/old_selecting = selecting +/obj/screen/zone_selector/set_selected_zone(new_zone, old_zone) if((. = ..())) - RAISE_EVENT(/decl/observ/zone_selected, src, old_selecting, selecting) \ No newline at end of file + RAISE_EVENT(/decl/observ/zone_selected, src, old_zone, new_zone) \ No newline at end of file diff --git a/code/datums/extensions/storage/_storage.dm b/code/datums/storage/_storage.dm similarity index 99% rename from code/datums/extensions/storage/_storage.dm rename to code/datums/storage/_storage.dm index 4ff70967e1c6..07d0d0871521 100644 --- a/code/datums/extensions/storage/_storage.dm +++ b/code/datums/storage/_storage.dm @@ -380,7 +380,7 @@ var/global/list/_test_storage_items = list() /datum/storage/proc/can_view(mob/viewer) return (holder in viewer.contents) || viewer.Adjacent(holder) -///Overridable sound playback parameters. Since not all sounds are created equal. +///Overrideable sound playback parameters. Since not all sounds are created equal. /datum/storage/proc/play_open_sound(volume = 50) if(!length(open_sound) || !holder) return diff --git a/code/datums/extensions/storage/_storage_ui.dm b/code/datums/storage/_storage_ui.dm similarity index 100% rename from code/datums/extensions/storage/_storage_ui.dm rename to code/datums/storage/_storage_ui.dm diff --git a/code/datums/extensions/storage/subtypes_backpack.dm b/code/datums/storage/subtypes_backpack.dm similarity index 96% rename from code/datums/extensions/storage/subtypes_backpack.dm rename to code/datums/storage/subtypes_backpack.dm index 3523c4968260..360c835727d1 100644 --- a/code/datums/extensions/storage/subtypes_backpack.dm +++ b/code/datums/storage/subtypes_backpack.dm @@ -4,7 +4,6 @@ open_sound = 'sound/effects/storage/unzip.ogg' /datum/storage/backpack/holding - max_w_class = ITEM_SIZE_NORMAL max_storage_space = 56 /datum/storage/backpack/holding/can_be_inserted(obj/item/W, mob/user, stop_messages = 0, click_params) diff --git a/code/datums/extensions/storage/subtypes_bag.dm b/code/datums/storage/subtypes_bag.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_bag.dm rename to code/datums/storage/subtypes_bag.dm diff --git a/code/datums/extensions/storage/subtypes_basket.dm b/code/datums/storage/subtypes_basket.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_basket.dm rename to code/datums/storage/subtypes_basket.dm diff --git a/code/datums/extensions/storage/subtypes_belt.dm b/code/datums/storage/subtypes_belt.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_belt.dm rename to code/datums/storage/subtypes_belt.dm diff --git a/code/datums/extensions/storage/subtypes_box.dm b/code/datums/storage/subtypes_box.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_box.dm rename to code/datums/storage/subtypes_box.dm diff --git a/code/datums/extensions/storage/subtypes_excavation.dm b/code/datums/storage/subtypes_excavation.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_excavation.dm rename to code/datums/storage/subtypes_excavation.dm diff --git a/code/datums/extensions/storage/subtypes_firstaid.dm b/code/datums/storage/subtypes_firstaid.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_firstaid.dm rename to code/datums/storage/subtypes_firstaid.dm diff --git a/code/datums/extensions/storage/subtypes_holster.dm b/code/datums/storage/subtypes_holster.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_holster.dm rename to code/datums/storage/subtypes_holster.dm diff --git a/code/datums/extensions/storage/subtypes_misc.dm b/code/datums/storage/subtypes_misc.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_misc.dm rename to code/datums/storage/subtypes_misc.dm diff --git a/code/datums/extensions/storage/subtypes_mre.dm b/code/datums/storage/subtypes_mre.dm similarity index 95% rename from code/datums/extensions/storage/subtypes_mre.dm rename to code/datums/storage/subtypes_mre.dm index b5045c1fc1b2..696f0343718f 100644 --- a/code/datums/extensions/storage/subtypes_mre.dm +++ b/code/datums/storage/subtypes_mre.dm @@ -20,7 +20,7 @@ /datum/storage/mrebag/open(mob/user) if(!opened) - to_chat(user, "The pouch heats up as you break the vaccum seal.") + to_chat(user, "The pouch heats up as you break the vacuum seal.") . = ..() /datum/storage/mrebag/dessert diff --git a/code/datums/extensions/storage/subtypes_part_replacer.dm b/code/datums/storage/subtypes_part_replacer.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_part_replacer.dm rename to code/datums/storage/subtypes_part_replacer.dm diff --git a/code/datums/extensions/storage/subtypes_pills.dm b/code/datums/storage/subtypes_pills.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_pills.dm rename to code/datums/storage/subtypes_pills.dm diff --git a/code/datums/extensions/storage/subtypes_pockets.dm b/code/datums/storage/subtypes_pockets.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_pockets.dm rename to code/datums/storage/subtypes_pockets.dm diff --git a/code/datums/extensions/storage/subtypes_secure.dm b/code/datums/storage/subtypes_secure.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_secure.dm rename to code/datums/storage/subtypes_secure.dm diff --git a/code/datums/extensions/storage/subtypes_sheets.dm b/code/datums/storage/subtypes_sheets.dm similarity index 97% rename from code/datums/extensions/storage/subtypes_sheets.dm rename to code/datums/storage/subtypes_sheets.dm index a72c49ab856d..578282c8d4b9 100644 --- a/code/datums/extensions/storage/subtypes_sheets.dm +++ b/code/datums/storage/subtypes_sheets.dm @@ -77,7 +77,7 @@ return FALSE //I would prefer to drop a new stack, but the item/attack_hand code - // that calls this can't recieve a different object than you clicked on. + // that calls this can't receive a different object than you clicked on. //Therefore, make a new stack internally that has the remainder. // -Sayu diff --git a/code/datums/extensions/storage/subtypes_slides.dm b/code/datums/storage/subtypes_slides.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_slides.dm rename to code/datums/storage/subtypes_slides.dm diff --git a/code/datums/extensions/storage/subtypes_specialized.dm b/code/datums/storage/subtypes_specialized.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_specialized.dm rename to code/datums/storage/subtypes_specialized.dm diff --git a/code/datums/extensions/storage/subtypes_structure.dm b/code/datums/storage/subtypes_structure.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_structure.dm rename to code/datums/storage/subtypes_structure.dm diff --git a/code/datums/extensions/storage/subtypes_tray.dm b/code/datums/storage/subtypes_tray.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_tray.dm rename to code/datums/storage/subtypes_tray.dm diff --git a/code/datums/extensions/storage/subtypes_wallet.dm b/code/datums/storage/subtypes_wallet.dm similarity index 100% rename from code/datums/extensions/storage/subtypes_wallet.dm rename to code/datums/storage/subtypes_wallet.dm diff --git a/code/datums/supplypacks/custodial.dm b/code/datums/supplypacks/custodial.dm index 9dc185965993..9409c0b8912e 100644 --- a/code/datums/supplypacks/custodial.dm +++ b/code/datums/supplypacks/custodial.dm @@ -10,7 +10,7 @@ /obj/item/lightreplacer, /obj/item/chems/spray/cleaner, /obj/item/box/lights/mixed, - /obj/item/chems/glass/rag, + /obj/item/chems/rag, /obj/item/grenade/chem_grenade/cleaner = 3, /obj/structure/mopbucket) containertype = /obj/structure/closet/crate/large @@ -33,7 +33,7 @@ /obj/item/grenade/chem_grenade/cleaner = 3, /obj/item/box/detergent = 3, /obj/item/chems/glass/bucket, - /obj/item/chems/glass/rag, + /obj/item/chems/rag, /obj/item/chems/spray/cleaner = 2, /obj/item/soap) containertype = /obj/structure/closet/crate/large diff --git a/code/datums/supplypacks/dispcarts.dm b/code/datums/supplypacks/dispcarts.dm index dcaddd40fcb8..723e6f9443cc 100644 --- a/code/datums/supplypacks/dispcarts.dm +++ b/code/datums/supplypacks/dispcarts.dm @@ -86,6 +86,9 @@ PACK(syrup_chocolate, /obj/item/chems/chem_disp_cartridge/syrup_chocolate, "Reag PACK(syrup_caramel, /obj/item/chems/chem_disp_cartridge/syrup_caramel, "Reagent refill - Caramel Syrup", "caramel syrup reagent cartridge crate") PACK(syrup_vanilla, /obj/item/chems/chem_disp_cartridge/syrup_vanilla, "Reagent refill - Vanilla Syrup", "vanilla syrup reagent cartridge crate") PACK(syrup_pumpkin, /obj/item/chems/chem_disp_cartridge/syrup_pumpkin, "Reagent refill - Pumpkin Spice Syrup", "pumpkin spice syrup reagent cartridge crate") +PACK(syrup_lavender, /obj/item/chems/chem_disp_cartridge/syrup_lavender, "Reagent refill - Lavender Syrup", "lavender syrup reagent cartridge crate") +PACK(cinnamon, /obj/item/chems/chem_disp_cartridge/cinnamon, "Reagent refill - Cinnamon", "cinnamon reagent cartridge crate") + #undef SEC_PACK #undef PACK diff --git a/code/datums/supplypacks/livecargo.dm b/code/datums/supplypacks/livecargo.dm index 44900acbba45..4013f1887b24 100644 --- a/code/datums/supplypacks/livecargo.dm +++ b/code/datums/supplypacks/livecargo.dm @@ -9,12 +9,19 @@ containername = "monkey crate" /decl/hierarchy/supply_pack/livecargo/spidercubes - name = "Inert - Spiders" + name = "Inert - Spider Cubes" contains = list(/obj/item/box/animal_cubes/spiders) containertype = /obj/structure/closet/crate/secure containername = "spiderling crate" - contraband = 1 - security_level = null + access = access_research + +/decl/hierarchy/supply_pack/livecargo/carpcubes + name = "Inert - Space Carp Cubes" + contains = list(/obj/item/box/animal_cubes/carp) + containertype = /obj/structure/closet/crate/secure + containername = "space carp crate" + access = access_chemistry + //actual live animals /decl/hierarchy/supply_pack/livecargo/corgi diff --git a/code/datums/uplink/ammunition.dm b/code/datums/uplink/ammunition.dm index 2ee116a6b7e4..4c0f2ba93ab3 100644 --- a/code/datums/uplink/ammunition.dm +++ b/code/datums/uplink/ammunition.dm @@ -50,13 +50,13 @@ /datum/uplink_item/item/ammo/shotgun_shells name = "Ammobox of Shotgun Shells" - desc = "An ammobox with 2 sets of shell holders. Contains 8 buckshot shells total." + desc = "An ammo box with 2 sets of shell holders. Contains 8 buckshot shells total." item_cost = 8 path = /obj/item/box/ammo/shotgunshells /datum/uplink_item/item/ammo/shotgun_slugs name = "Ammobox of Shotgun Slugs" - desc = "An ammobox with 2 sets of shell holders. Contains 8 slugs total." + desc = "An ammo box with 2 sets of shell holders. Contains 8 slugs total." item_cost = 8 path = /obj/item/box/ammo/shotgunammo diff --git a/code/datums/uplink/badassery.dm b/code/datums/uplink/badassery.dm index 14954c31afdb..43375e941cb9 100644 --- a/code/datums/uplink/badassery.dm +++ b/code/datums/uplink/badassery.dm @@ -11,7 +11,7 @@ /datum/uplink_item/item/badassery/balloon/random name = "For showing 'Whatevah~' (Useless Balloon)" - desc = "Randomly selects a ballon for you!" + desc = "Randomly selects a balloon for you!" path = /obj/item/toy/balloon /datum/uplink_item/item/badassery/balloon/random/get_goods(var/obj/item/uplink/U, var/loc) diff --git a/code/datums/uplink/devices_and_tools.dm b/code/datums/uplink/devices_and_tools.dm index a6628ebabefa..7536a5d65616 100644 --- a/code/datums/uplink/devices_and_tools.dm +++ b/code/datums/uplink/devices_and_tools.dm @@ -104,7 +104,7 @@ /datum/uplink_item/item/tools/flashdark name = "Flashdark" - desc = "A device similar to a flash light that absorbs the surrounding light, casting a shadowy, black mass." + desc = "A device similar to a flashlight that absorbs the surrounding light, casting a shadowy, black mass." item_cost = 32 path = /obj/item/flashlight/flashdark diff --git a/code/datums/uplink/highly_visible_and_dangerous_weapons.dm b/code/datums/uplink/highly_visible_and_dangerous_weapons.dm index 097666428c62..c64cf84b614a 100644 --- a/code/datums/uplink/highly_visible_and_dangerous_weapons.dm +++ b/code/datums/uplink/highly_visible_and_dangerous_weapons.dm @@ -51,7 +51,7 @@ /datum/uplink_item/item/visible_weapons/energy_gun name = "Energy Gun" - desc = "A energy based sidearm with three different lethality settings." + desc = "An energy-based sidearm with three different lethality settings." item_cost = 32 path = /obj/item/gun/energy/gun @@ -71,14 +71,14 @@ //These are for traitors (or other antags, perhaps) to have the option of purchasing some merc gear. /datum/uplink_item/item/visible_weapons/smg name = "Standard Submachine Gun" - desc = "A quick-firing weapon with three togglable fire modes." + desc = "A quick-firing weapon with three toggleable fire modes." item_cost = 52 path = /obj/item/gun/projectile/automatic/smg antag_roles = list(/decl/special_role/mercenary) /datum/uplink_item/item/visible_weapons/assaultrifle name = "Assault Rifle" - desc = "A common rifle with three togglable fire modes." + desc = "A common rifle with three toggleable fire modes." item_cost = 60 path = /obj/item/gun/projectile/automatic/assault_rifle antag_roles = list(/decl/special_role/mercenary) @@ -98,7 +98,7 @@ /datum/uplink_item/item/visible_weapons/combat_shotgun name = "Pump Shotgun" - desc = "A high compacity, pump-action shotgun regularly used for repelling boarding parties in close range scenarios." + desc = "A high capacity, pump-action shotgun regularly used for repelling boarding parties in close range scenarios." item_cost = 52 path = /obj/item/gun/projectile/shotgun/pump antag_roles = list(/decl/special_role/mercenary) @@ -111,7 +111,7 @@ /datum/uplink_item/item/visible_weapons/flechetterifle name = "Flechette Rifle" - desc = "A railgun with two togglable fire modes, able to launch flechette ammunition at incredible speeds." + desc = "A railgun with two toggleable fire modes, able to launch flechette ammunition at incredible speeds." item_cost = 60 path = /obj/item/gun/magnetic/railgun/flechette antag_roles = list(/decl/special_role/mercenary) diff --git a/code/datums/uplink/implants.dm b/code/datums/uplink/implants.dm index 94bdff821a27..0495c267c1b8 100644 --- a/code/datums/uplink/implants.dm +++ b/code/datums/uplink/implants.dm @@ -6,7 +6,7 @@ /datum/uplink_item/item/implants/imp_freedom name = "Freedom Implant" - desc = "An implant with an emotive trigger that can break you free of restraints. Show Security who has the real upperhand!" + desc = "An implant with an emotive trigger that can break you free of restraints. Show Security who has the real upper hand!" item_cost = 24 path = /obj/item/box/syndie_kit/imp_freedom diff --git a/code/datums/uplink/medical.dm b/code/datums/uplink/medical.dm index 599c0f83f6a6..4aef274b938c 100644 --- a/code/datums/uplink/medical.dm +++ b/code/datums/uplink/medical.dm @@ -18,7 +18,7 @@ /datum/uplink_item/item/medical/stasis name = "Stasis Bag" - desc = "Reusable bag designed to slow down life functions of occupant, especially useful if short on time or in a hostile enviroment." + desc = "Reusable bag designed to slow down life functions of occupant, especially useful if short on time or in a hostile environment." item_cost = 24 path = /obj/item/bodybag/cryobag diff --git a/code/datums/uplink/stealth_and_camouflage_items.dm b/code/datums/uplink/stealth_and_camouflage_items.dm index 9a9d21c0761a..d2f189c5dd24 100644 --- a/code/datums/uplink/stealth_and_camouflage_items.dm +++ b/code/datums/uplink/stealth_and_camouflage_items.dm @@ -42,7 +42,7 @@ /datum/uplink_item/item/stealth_items/voice name = "Modified Gas Mask" - desc = "A fully functioning gas mask that is able to conceal your face and has a built in voice modulator, \ + desc = "A fully functioning gas mask that is able to conceal your face and has a built-in voice modulator, \ so you can become a true shadow operative!" item_cost = 20 path = /obj/item/clothing/mask/chameleon/voice diff --git a/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm b/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm index d085b9438d99..45deaffbf371 100644 --- a/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm +++ b/code/datums/uplink/stealthy_and_inconspicuous_weapons.dm @@ -17,7 +17,7 @@ /datum/uplink_item/item/stealthy_weapons/concealed_cane name = "Concealed Cane Sword" - desc = "A cane used by a true gentlemen, especially ones with sharp intentions." + desc = "A cane used by a true gentleman, especially ones with sharp intentions." item_cost = 8 path = /obj/item/cane/fancy/sword diff --git a/code/datums/wires/radio.dm b/code/datums/wires/radio.dm index 22b951263c56..d2d868a4a7d1 100644 --- a/code/datums/wires/radio.dm +++ b/code/datums/wires/radio.dm @@ -3,7 +3,7 @@ wire_count = 3 descriptions = list( new /datum/wire_description(WIRE_SIGNAL, "This wire connects several radio components."), - new /datum/wire_description(WIRE_RECEIVE, "This wire runs to the radio reciever.", SKILL_EXPERT), + new /datum/wire_description(WIRE_RECEIVE, "This wire runs to the radio receiver.", SKILL_EXPERT), new /datum/wire_description(WIRE_TRANSMIT, "This wire runs to the radio transmitter.") ) diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 56b88e8f986c..ea8bcbc016f7 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -192,7 +192,7 @@ var/global/list/wireColourNames = list("darkred" = "dark red") usr.unset_machine(holder) // -// Overridable Procs +// Overrideable Procs // // Called when wires cut/mended. diff --git a/code/game/antagonist/antagonist_objectives.dm b/code/game/antagonist/antagonist_objectives.dm index 5e0f27068cff..51caf655579f 100644 --- a/code/game/antagonist/antagonist_objectives.dm +++ b/code/game/antagonist/antagonist_objectives.dm @@ -17,7 +17,7 @@ /mob/proc/add_objectives() set name = "Get Objectives" - set desc = "Recieve optional objectives." + set desc = "Receive optional objectives." set category = "OOC" src.verbs -= /mob/proc/add_objectives diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 95cf7d39aee6..443f0046748c 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -422,7 +422,7 @@ var/global/list/mob/living/forced_ambiance_list = new if(isspaceturf(get_turf(mob))) // Can't fall onto nothing. return - if(mob.Check_Shoegrip()) + if(!mob.can_slip(magboots_only = TRUE)) return if(ishuman(mob)) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 196f4cc44e5c..a9fc6994d811 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -277,23 +277,20 @@ - `user`: The mob examining this atom - `distance`: The distance this atom is from the `user` - - `infix`: TODO - - `suffix`: TODO + - `infix`: An optional string appended directly to the 'That's an X' string, between the name the end of the sentence. + - `suffix`: An optional string appended in a separate sentence after the initial introduction line. - Return: `TRUE` when the call chain is valid, otherwise `FALSE` - Events: `atom_examined` */ /atom/proc/examine(mob/user, distance, infix = "", suffix = "") SHOULD_CALL_PARENT(TRUE) - //This reformat names to get a/an properly working on item descriptions when they are bloody - var/f_name = "\a [src][infix]." - if(blood_color && !istype(src, /obj/effect/decal)) - if(gender == PLURAL) - f_name = "some " - else - f_name = "a " - f_name += "stained [name][infix]!" + //This reformats names to get a/an properly working on item descriptions when they are bloody or coated in reagents. + var/examine_prefix = get_examine_prefix() + if(examine_prefix) + examine_prefix += " " // add a space to the end to be polite + var/composed_name = ADD_ARTICLE_GENDER("[examine_prefix][name]", gender) - to_chat(user, "[html_icon(src)] That's [f_name] [suffix]") + to_chat(user, "[html_icon(src)] That's [composed_name][infix][get_examine_punctuation()] [suffix]") to_chat(user, desc) var/list/alt_interactions = get_alt_interactions(user) @@ -375,13 +372,18 @@ /** Update this atom's icon. + If prior to the first SSicon_update flush (i.e. it's during init), icon updates are forced to queue instead. + This saves a lot of init time. - Events: `updated_icon` */ /atom/proc/update_icon() SHOULD_CALL_PARENT(TRUE) - on_update_icon(arglist(args)) - RAISE_EVENT(/decl/observ/updated_icon, src) + if(SSicon_update.init_state == SS_INITSTATE_NONE) + queue_icon_update() + else + on_update_icon() + RAISE_EVENT(/decl/observ/updated_icon, src) /** Update this atom's icon. @@ -618,7 +620,7 @@ Used for atoms performing audible actions - `message`: The string to show to anyone who can hear this atom - - `dead_message?`: The string deaf mobs will see + - `deaf_message?`: The string deaf mobs will see - `hearing_distance?`: The number of tiles away the message can be heard. Defaults to world.view - `check_ghosts?`: TRUE if ghosts should hear the message if their preferences allow - `radio_message?`: The string to send over radios @@ -966,7 +968,7 @@ /atom/proc/get_thermal_mass() return 0 -/atom/proc/get_thermal_mass_coefficient() +/atom/proc/get_thermal_mass_coefficient(delta) return 1 /atom/proc/spark_act(obj/effect/sparks/sparks) @@ -1003,5 +1005,15 @@ return required_dexterity /atom/proc/immune_to_floor_hazards() - return !simulated - + return !simulated || !has_gravity() +/// The punctuation used for the "That's an X." string. +/atom/proc/get_examine_punctuation() + // Could theoretically check if reagents in a coating are 'dangerous' or 'suspicious' (blood, acid, etc) + // in an override, but that'd require setting such a var on a bunch of materials and I'm lazy. + return blood_color ? "!" : "." + +/// The prefix that goes before the atom name on examine. +/atom/proc/get_examine_prefix() + if(blood_color) + return FONT_COLORED(blood_color, "stained") + return null diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 9c481be8d469..918c145cce6b 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -49,7 +49,7 @@ //call this proc to start space drifting /atom/movable/proc/space_drift(direction)//move this down - if(!loc || direction & (UP|DOWN) || Process_Spacemove(0)) + if(!loc || direction & (UP|DOWN) || is_space_movement_permitted() != SPACE_MOVE_FORBIDDEN) inertia_dir = 0 inertia_ignore = null return 0 @@ -62,29 +62,22 @@ return 1 //return 0 to space drift, 1 to stop, -1 for mobs to handle space slips -/atom/movable/proc/Process_Spacemove(var/allow_movement) +/atom/movable/proc/is_space_movement_permitted(allow_movement = FALSE) if(!simulated) - return 1 - + return SPACE_MOVE_PERMITTED if(has_gravity()) - return 1 - + return SPACE_MOVE_PERMITTED if(length(grabbed_by)) - return 1 - + return SPACE_MOVE_PERMITTED if(throwing) - return 1 - + return SPACE_MOVE_PERMITTED if(anchored) - return 1 - + return SPACE_MOVE_PERMITTED if(!isturf(loc)) - return 1 - + return SPACE_MOVE_PERMITTED if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier - return -1 - - return 0 + return SPACE_MOVE_SUPPORTED + return SPACE_MOVE_FORBIDDEN /atom/movable/attack_hand(mob/user) // Unbuckle anything buckled to us. @@ -502,7 +495,7 @@ return 0 return max(ITEM_SIZE_MIN, get_object_size()) * THERMAL_MASS_CONSTANT -/atom/movable/get_thermal_mass_coefficient() +/atom/movable/get_thermal_mass_coefficient(delta) if(!simulated) return 0 return (max(ITEM_SIZE_MIN, MOB_SIZE_MIN) * THERMAL_MASS_CONSTANT) / get_thermal_mass() @@ -566,7 +559,7 @@ appearance_flags &= ~remove_flags return old_appearance != appearance_flags -/atom/movable/proc/end_throw() +/atom/movable/proc/end_throw(datum/thrownthing/TT) throwing = null /atom/movable/proc/reset_movement_delay() diff --git a/code/game/atoms_temperature.dm b/code/game/atoms_temperature.dm index 2beb585761a0..099b566cf783 100644 --- a/code/game/atoms_temperature.dm +++ b/code/game/atoms_temperature.dm @@ -21,7 +21,7 @@ if(user && heated_by) visible_message(SPAN_NOTICE("\The [user] carefully heats \the [src] with \the [heated_by].")) // Update our own heat. - var/altered_temp = max(temperature + (get_thermal_mass_coefficient() * diff_temp * (heated_by ? heated_by.get_manual_heat_source_coefficient() : 1)), 0) + var/altered_temp = max(temperature + (get_thermal_mass_coefficient(diff_temp) * diff_temp * (heated_by ? heated_by.get_manual_heat_source_coefficient() : 1)), 0) ADJUST_ATOM_TEMPERATURE(src, min(adjust_temp, altered_temp)) return TRUE @@ -51,11 +51,11 @@ // Get our ambient temperature if possible. var/adjust_temp = get_ambient_temperature() - var/thermal_mass_coefficient = get_thermal_mass_coefficient() * get_ambient_temperature_coefficient() + var/diff_temp = adjust_temp - temperature + var/thermal_mass_coefficient = get_thermal_mass_coefficient(diff_temp) * get_ambient_temperature_coefficient() // Determine if our temperature needs to change. var/old_temp = temperature - var/diff_temp = adjust_temp - temperature if(abs(diff_temp) >= (thermal_mass_coefficient * ATOM_TEMPERATURE_EQUILIBRIUM_THRESHOLD)) var/altered_temp = max(temperature + (thermal_mass_coefficient * diff_temp), 0) ADJUST_ATOM_TEMPERATURE(src, (diff_temp > 0) ? min(adjust_temp, altered_temp) : max(adjust_temp, altered_temp)) diff --git a/code/game/machinery/_machines_base/machinery.dm b/code/game/machinery/_machines_base/machinery.dm index d6fafc99f1e5..cff48f06503d 100644 --- a/code/game/machinery/_machines_base/machinery.dm +++ b/code/game/machinery/_machines_base/machinery.dm @@ -240,6 +240,9 @@ Class Procs: /obj/machinery/CouldNotUseTopic(var/mob/user) user.unset_machine() +// This must not be converted to use OnTopic. +// mechanics_text and power_text can be done at a distance (via examination) +// while the TOPIC_REFRESH handling must come after OnTopic has resolved in the parent call of Topic. /obj/machinery/Topic(href, href_list, datum/topic_state/state) if(href_list["mechanics_text"] && construct_state) // This is an OOC examine thing handled via Topic; specifically bypass all checks, but do nothing other than message to chat. var/list/info = get_tool_manipulation_info() @@ -254,6 +257,13 @@ Class Procs: . = ..() if(. == TOPIC_REFRESH) updateUsrDialog() // Update legacy UIs to the extent possible. + SSnano.update_uis(src) // And our modern NanoUI ones, too. + update_icon() // A lot of machines like to do icon updates on refresh, so we'll handle it for them here. + else if(. == TOPIC_CLOSE) + usr.unset_machine() + var/datum/nanoui/open_ui = SSnano.get_open_ui(usr, src, "main") + if(open_ui) + open_ui.close() /obj/machinery/proc/get_tool_manipulation_info() return construct_state?.mechanics_info() diff --git a/code/game/machinery/_machines_base/machinery_public_vars.dm b/code/game/machinery/_machines_base/machinery_public_vars.dm index d1288ef7817b..594aa0238e02 100644 --- a/code/game/machinery/_machines_base/machinery_public_vars.dm +++ b/code/game/machinery/_machines_base/machinery_public_vars.dm @@ -17,7 +17,7 @@ Must be implemented by subtypes. // Reads off the var value and returns it /decl/public_access/public_variable/proc/access_var(datum/owner) -// Writes to the var. Returns true if change occured, false otherwise. +// Writes to the var. Returns true if change occurred, false otherwise. // Subtypes shall call parent, and perform the actual write if the return value is true. // If the var has_updates, you must never modify the var except through this proc. /decl/public_access/public_variable/proc/write_var(datum/owner, new_value) diff --git a/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm b/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm index 15cc987b4060..82c1e1736196 100644 --- a/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm +++ b/code/game/machinery/_machines_base/stock_parts/legacy_parts.dm @@ -169,7 +169,7 @@ /obj/item/stock_parts/subspace/filter name = "hyperwave filter" icon_state = "hyperwave_filter" - desc = "A tiny device capable of filtering and converting super-intense radiowaves." + desc = "A tiny device capable of filtering and converting super-intense radio waves." origin_tech = @'{"programming":4,"magnets":2}' material = /decl/material/solid/metal/steel matter = list(/decl/material/solid/metal/silver = MATTER_AMOUNT_REINFORCEMENT) diff --git a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm index 644941d02cda..1b09080e57c1 100644 --- a/code/game/machinery/_machines_base/stock_parts/network_receiver.dm +++ b/code/game/machinery/_machines_base/stock_parts/network_receiver.dm @@ -1,4 +1,4 @@ -// A reciever that allows for non-network machines to have public vars and methods interacted with by networks +// A receiver that allows for non-network machines to have public vars and methods interacted with by networks /obj/item/stock_parts/network_receiver name = "network receiver" diff --git a/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm b/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm index e1a967194179..9cca4b1b98a1 100644 --- a/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm +++ b/code/game/machinery/_machines_base/stock_parts/radio/stock_parts_radio.dm @@ -24,7 +24,7 @@ id_tag = new_tag set_frequency(frequency, filter) -/obj/item/stock_parts/radio/proc/get_receive_filter() // what filter should we register with to recieve updates on? +/obj/item/stock_parts/radio/proc/get_receive_filter() // what filter should we register with to receive updates on? return RADIO_NULL /obj/item/stock_parts/radio/proc/set_frequency(new_frequency, new_filter) diff --git a/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm b/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm index e56703abc157..bd43db38d6c3 100644 --- a/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm +++ b/code/game/machinery/_machines_base/stock_parts/stock_parts_interface.dm @@ -20,7 +20,7 @@ /obj/item/stock_parts/keyboard name = "input controller" - desc = "A standard part required by many machines to recieve user input." + desc = "A standard part required by many machines to receive user input." icon_state = "input" origin_tech = @'{"materials":1}' material = /decl/material/solid/organic/plastic diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index 1028e2d4098e..11d4e5c9b63b 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -667,7 +667,7 @@ var/device_id = href_list["id_tag"] switch(href_list["command"]) if("set_external_pressure") - var/input_pressure = input(user, "What pressure you like the system to mantain?", "Pressure Controls") as num|null + var/input_pressure = input(user, "What pressure you like the system to maintain?", "Pressure Controls") as num|null if(isnum(input_pressure) && CanUseTopic(user, state)) send_signal(device_id, list(href_list["command"] = input_pressure)) return TOPIC_REFRESH diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm index 721eddb4ad96..65ecb25cd2e3 100644 --- a/code/game/machinery/atmo_control.dm +++ b/code/game/machinery/atmo_control.dm @@ -114,9 +114,6 @@ data["automation"] = automation -/obj/machinery/computer/air_control/Process() - ..() - /obj/machinery/computer/air_control/receive_signal(datum/signal/signal) if(!signal || signal.encryption) return @@ -148,56 +145,56 @@ if(href_list["in_refresh_status"]) input_info = null refreshing_input = TRUE - signal.data = list ("tag" = input_tag, "status" = 1) + signal.data = list("tag" = input_tag, "status" = 1) . = 1 if(href_list["in_toggle_injector"]) input_info = null refreshing_input = TRUE - signal.data = list ("tag" = input_tag, "power_toggle" = 1) + signal.data = list("tag" = input_tag, "power_toggle" = 1) . = 1 if(href_list["in_set_flowrate"]) input_info = null refreshing_input = TRUE - input_flow_setting = input("What would you like to set the rate limit to?", "Set Volume", input_flow_setting) as num|null + input_flow_setting = input(user, "What would you like to set the rate limit to?", "Set Volume", input_flow_setting) as num|null input_flow_setting = clamp(input_flow_setting, 0, ATMOS_DEFAULT_VOLUME_PUMP+500) - signal.data = list ("tag" = input_tag, "set_volume_rate" = input_flow_setting) + signal.data = list("tag" = input_tag, "set_volume_rate" = input_flow_setting) . = 1 if(href_list["in_set_max"]) input_info = null refreshing_input = TRUE input_flow_setting = ATMOS_DEFAULT_VOLUME_PUMP+500 - signal.data = list ("tag" = input_tag, "set_volume_rate" = input_flow_setting) + signal.data = list("tag" = input_tag, "set_volume_rate" = input_flow_setting) . = 1 if(href_list["out_refresh_status"]) output_info = null refreshing_output = TRUE - signal.data = list ("tag" = output_tag, "status" = 1) + signal.data = list("tag" = output_tag, "status" = 1) . = 1 if(href_list["out_toggle_power"]) output_info = null refreshing_output = TRUE - signal.data = list ("tag" = output_tag, "power_toggle" = 1, "status" = 1) + signal.data = list("tag" = output_tag, "power_toggle" = 1, "status" = 1) . = 1 if(href_list["out_set_pressure"]) output_info = null refreshing_output = TRUE - pressure_setting = input("How much pressure would you like to output?", "Set Pressure", pressure_setting) as num|null + pressure_setting = input(user, "How much pressure would you like to output?", "Set Pressure", pressure_setting) as num|null pressure_setting = clamp(pressure_setting, 0, MAX_PUMP_PRESSURE) - signal.data = list ("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]", "status" = 1) + signal.data = list("tag" = output_tag, "set_internal_pressure" = "[pressure_setting]", "status" = 1) . = 1 if(href_list["s_out_set_pressure"]) output_info = null refreshing_output = TRUE - pressure_setting = input("How much pressure would you like to maintain inside the core?", "Set Core Pressure", pressure_setting) as num|null + pressure_setting = input(user, "How much pressure would you like to maintain inside the core?", "Set Core Pressure", pressure_setting) as num|null pressure_setting = clamp(pressure_setting, 0, MAX_PUMP_PRESSURE) - signal.data = list ("tag" = output_tag, "set_external_pressure" = pressure_setting, "checks" = 1, "status" = 1) + signal.data = list("tag" = output_tag, "set_external_pressure" = pressure_setting, "checks" = 1, "status" = 1) . = 1 if(href_list["s_set_default"]) @@ -210,11 +207,11 @@ output_info = null refreshing_output = TRUE pressure_setting = MAX_PUMP_PRESSURE - signal.data = list ("tag" = output_tag, "set_internal_pressure" = pressure_setting, "status" = 1) + signal.data = list("tag" = output_tag, "set_internal_pressure" = pressure_setting, "status" = 1) . = 1 if(href_list["set_frequency"]) - var/F = input("What frequency would you like to set this to? (Decimal is added automatically)", "Adjust Frequency", frequency) as num|null + var/F = input(user, "What frequency would you like to set this to? (Decimal is added automatically)", "Adjust Frequency", frequency) as num|null if(F) frequency = F set_frequency(F) @@ -291,7 +288,7 @@ else ..(signal) -/obj/machinery/computer/air_control/fuel_injection/Topic(href, href_list) +/obj/machinery/computer/air_control/fuel_injection/OnTopic(mob/user, href_list, datum/topic_state/state) if((. = ..())) return diff --git a/code/game/machinery/atmoalter/meter.dm b/code/game/machinery/atmoalter/meter.dm index 4dd3caeb6fd1..3b0ef569f603 100644 --- a/code/game/machinery/atmoalter/meter.dm +++ b/code/game/machinery/atmoalter/meter.dm @@ -1,6 +1,6 @@ /obj/machinery/meter name = "meter" - desc = "A gas flow meter." + desc = "A meter that monitors gas composition, pressure, and temperature in the attached pipe." icon = 'icons/obj/meter.dmi' icon_state = "meterX" var/atom/target = null //A pipe for the base type diff --git a/code/game/machinery/computer/area_atmos.dm b/code/game/machinery/computer/area_atmos.dm index f287fbbc0b3f..d6b82399d7ce 100644 --- a/code/game/machinery/computer/area_atmos.dm +++ b/code/game/machinery/computer/area_atmos.dm @@ -88,25 +88,25 @@ show_browser(user, "[dat]", "window=miningshuttle;size=400x400") status = "" -/obj/machinery/computer/area_atmos/Topic(href, href_list) - if(..()) +/obj/machinery/computer/area_atmos/OnTopic(mob/user, href_list) + if((. = ..())) return - usr.set_machine(src) - if(href_list["scan"]) scanscrubbers() + return TOPIC_REFRESH else if(href_list["toggle"]) var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber = locate(href_list["scrub"]) if(!validscrubber(scrubber)) - spawn(20) + spawn(2 SECONDS) status = "ERROR: Couldn't connect to scrubber! (timeout)" connectedscrubbers -= scrubber - src.updateUsrDialog() - return + updateUsrDialog() + return TOPIC_REFRESH scrubber.update_use_power(text2num(href_list["toggle"]) ? POWER_USE_ACTIVE : POWER_USE_IDLE) + return TOPIC_REFRESH /obj/machinery/computer/area_atmos/proc/validscrubber(var/obj/machinery/portable_atmospherics/powered/scrubber/huge/scrubber) if(!isobj(scrubber) || get_dist(scrubber.loc, src.loc) > src.range || scrubber.loc.z != src.loc.z) diff --git a/code/game/machinery/computer/message.dm b/code/game/machinery/computer/message.dm index 0c145faa9de9..da48f9028515 100644 --- a/code/game/machinery/computer/message.dm +++ b/code/game/machinery/computer/message.dm @@ -7,15 +7,18 @@ light_color = "#00b000" var/hack_icon = "error" - var/noserver = "ALERT: No server detected." - var/incorrectkey = "ALERT: Incorrect decryption key!" - var/defaultmsg = "Welcome. Please select an option." - var/rebootmsg = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!" - var/screen = 0 // 0 = Main menu, 1 = Message Logs, 2 = Hacked screen, 3 = Custom Message - var/hacking = 0 // Is it being hacked into by the AI/Cyborg - var/emag = 0 // When it is emagged. + var/const/noserver = "ALERT: No server detected." + var/const/incorrectkey = "ALERT: Incorrect decryption key!" + var/const/defaultmsg = "Welcome. Please select an option." + var/const/rebootmsg = "%$&(£: Critical %$$@ Error // !RestArting! - ?pLeaSe wAit!" + + var/const/SCREEN_MAIN_MENU = 0 + var/const/SCREEN_MESSAGE_LOGS = 1 + var/const/SCREEN_HACKING = 2 + var/screen = SCREEN_MAIN_MENU + var/hacking = FALSE // Is it being hacked into by a silicon? var/message = "System bootup complete. Please select an option." // The message that shows on the main menu. - var/auth = 0 // Are they authenticated? + var/auth = FALSE // Are they authenticated? var/obj/machinery/network/message_server/tracking_linked_server /obj/machinery/computer/message_monitor/Initialize() @@ -43,7 +46,7 @@ return ..() if(!istype(user)) return TRUE - if(IS_SCREWDRIVER(O) && emag) + if(IS_SCREWDRIVER(O) && emagged) //Stops people from just unscrewing the monitor and putting it back to get the console working again. to_chat(user, "It is too hot to mess with!") return TRUE @@ -53,11 +56,11 @@ // Will create sparks and print out the console's password. You will then have to wait a while for the console to be back online. // It'll take more time if there's more characters in the password. - if(!emag && operable()) + if(!emagged && operable()) var/obj/machinery/network/message_server/linked_server = get_message_server() if(linked_server) - emag = 1 - screen = 2 + emagged = TRUE + screen = SCREEN_HACKING spark_at(src, amount = 5) var/obj/item/paper/monitorkey/MK = new(loc) // Will help make emagging the console not so easy to get away with. @@ -70,7 +73,7 @@ to_chat(user, "A no server error appears on the screen.") /obj/machinery/computer/message_monitor/on_update_icon() - if(emag || hacking) + if(emagged || hacking) icon_screen = hack_icon else icon_screen = initial(icon_screen) @@ -82,10 +85,16 @@ /obj/machinery/computer/message_monitor/interact(var/mob/living/user) //If the computer is being hacked or is emagged, display the reboot message. - if(hacking || emag) + if(hacking || emagged) message = rebootmsg var/obj/machinery/network/message_server/linked_server = get_message_server() + // This must run early so that changing the message actually works. + if(hacking || emagged) + screen = SCREEN_HACKING + else if(!auth || !linked_server || (linked_server.stat & (NOPOWER|BROKEN))) + message = auth ? noserver : message + screen = SCREEN_MAIN_MENU var/list/dat = list() dat += "Message Monitor Console" dat += "

Message Monitor Console


" @@ -98,16 +107,9 @@ dat += "

\[Unauthenticated\] /" dat += " Server Power: [linked_server?.active ? "\[On\]":"\[Off\]"]

" - if(hacking || emag) - screen = 2 - else if(!auth || !linked_server || (linked_server.stat & (NOPOWER|BROKEN))) - if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN))) - message = noserver - screen = 0 - switch(screen) //Main menu - if(0) + if(SCREEN_MAIN_MENU) // = TAB var/i = 0 dat += "
[++i]. Link To A Server
" @@ -123,10 +125,32 @@ if((isAI(user) || isrobot(user)) && player_is_antag(user.mind)) //Malf/Traitor AIs can bruteforce into the system to gain the Key. dat += "
*&@#. Bruteforce Key
" - + //Request Console Logs + if(SCREEN_MESSAGE_LOGS) + var/index = 0 + /* data_rc_msg + X - 5% + var/rec_dpt = "Unspecified" //name of the person - 15% + var/send_dpt = "Unspecified" //name of the sender- 15% + var/message = "Blank" //transferred message - 300px + var/stamp = "Unstamped" - 15% + var/id_auth = "Unauthenticated" - 15% + var/priority = "Normal" - 10% + */ + dat += "
Back - Refresh

" + dat += {" + "} + for(var/datum/data_rc_msg/rc in linked_server.rc_msgs) + if(++index > 3000) + break + // Del - Sender - Recepient - Message + // X - Al Green - Your Mom - WHAT UP!? + dat += {" + "} + dat += "
XSending Dep.Receiving Dep.MessageStampID Auth.Priority.
X
[rc.send_dpt][rc.rec_dpt][rc.message][rc.stamp][rc.id_auth][rc.priority]
" //Hacking screen. - if(2) - if(isAI(user) || isrobot(user)) + if(SCREEN_HACKING) + if(issilicon(user)) dat += "Brute-forcing for server key.
It will take 20 seconds for every character that the password has." dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time." else @@ -166,35 +190,7 @@ 10010000001100100011101010111001001101001011011100110011
10010000001110100011010000110000101110100001000000111010
001101001011011010110010100101110"} - - //Request Console Logs - if(4) - - var/index = 0 - /* data_rc_msg - X - 5% - var/rec_dpt = "Unspecified" //name of the person - 15% - var/send_dpt = "Unspecified" //name of the sender- 15% - var/message = "Blank" //transferred message - 300px - var/stamp = "Unstamped" - 15% - var/id_auth = "Unauthenticated" - 15% - var/priority = "Normal" - 10% - */ - dat += "
Back - Refresh

" - dat += {" - "} - for(var/datum/data_rc_msg/rc in linked_server.rc_msgs) - index++ - if(index > 3000) - break - // Del - Sender - Recepient - Message - // X - Al Green - Your Mom - WHAT UP!? - dat += {" - "} - dat += "
XSending Dep.Receiving Dep.MessageStampID Auth.Priority.
X
[rc.send_dpt][rc.rec_dpt][rc.message][rc.stamp][rc.id_auth][rc.priority]
" - dat += "" - message = defaultmsg var/datum/browser/written_digital/popup = new(user, "message", "Message Monitoring Console", 700, 700) popup.set_content(JOINTEXT(dat)) popup.open() @@ -207,15 +203,16 @@ else var/currentKey = linked_server.decryptkey to_chat(user, "Brute-force completed! The key is '[currentKey]'.") - src.hacking = 0 + hacking = FALSE update_icon() - src.screen = 0 // Return the screen back to normal + screen = SCREEN_MAIN_MENU // Return the screen back to normal + message = defaultmsg // reset it for the next interaction /obj/machinery/computer/message_monitor/proc/UnemagConsole() - src.emag = 0 + emagged = FALSE update_icon() -/obj/machinery/computer/message_monitor/Topic(href, href_list) +/obj/machinery/computer/message_monitor/OnTopic(mob/user, href_list) if((. = ..())) return @@ -223,19 +220,24 @@ var/obj/machinery/network/message_server/linked_server = get_message_server() if (href_list["auth"]) if(auth) - auth = 0 - screen = 0 + auth = FALSE + screen = SCREEN_MAIN_MENU + message = defaultmsg // reset it for the next interaction + . = TOPIC_REFRESH else - var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) - if(dkey && dkey != "") - if(linked_server && linked_server.decryptkey == dkey) - auth = 1 + var/dkey = trim(input(user, "Please enter the decryption key.") as text|null) + . = TOPIC_HANDLED + if(dkey) + . = TOPIC_REFRESH + if(linked_server?.decryptkey == dkey) + auth = TRUE else message = incorrectkey //Turn the server on/off. if (href_list["active"] && auth && linked_server) linked_server.active = !linked_server.active + . = TOPIC_REFRESH //Find a server if (href_list["find"]) @@ -245,7 +247,7 @@ if((MS.z in local_zs) && !(MS.stat & (BROKEN|NOPOWER))) local_message_servers += MS if(length(local_message_servers) > 1) - tracking_linked_server = input(usr,"Please select a server.", "Select a server.", null) as null|anything in local_message_servers + tracking_linked_server = input(user, "Please select a server.", "Select a server.", null) as null|anything in local_message_servers message = "NOTICE: Server selected." else if(length(local_message_servers) > 0) tracking_linked_server = local_message_servers[1] @@ -253,47 +255,53 @@ else message = noserver linked_server = get_message_server() + . = TOPIC_REFRESH //Clears the request console logs - KEY REQUIRED if (href_list["clearr"]) if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN))) message = noserver + . = TOPIC_REFRESH else if(auth) linked_server.rc_msgs = list() message = "NOTICE: Logs cleared." + . = TOPIC_REFRESH //Change the password - KEY REQUIRED if (href_list["pass"]) if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN))) message = noserver - else - if(auth) - var/dkey = trim(input(usr, "Please enter the decryption key.") as text|null) - if(dkey && dkey != "") - if(linked_server.decryptkey == dkey) - var/newkey = trim(input(usr,"Please enter the new key (3 - 16 characters max):")) - if(length(newkey) <= 3) - message = "NOTICE: Decryption key too short!" - else if(length(newkey) > 16) - message = "NOTICE: Decryption key too long!" - else if(newkey && newkey != "") - linked_server.decryptkey = newkey - message = "NOTICE: Decryption key set." - else - message = incorrectkey + . = TOPIC_REFRESH + else if(auth) + var/dkey = trim(input(user, "Please enter the decryption key.") as text|null) + . = TOPIC_HANDLED + if(dkey) + . = TOPIC_REFRESH + if(linked_server.decryptkey == dkey) + var/newkey = trim(input(user,"Please enter the new key (3 - 16 characters max):")) + if(length(newkey) <= 3) + message = "NOTICE: Decryption key too short!" + else if(length(newkey) > 16) + message = "NOTICE: Decryption key too long!" + else if(newkey && newkey != "") + linked_server.decryptkey = newkey + message = "NOTICE: Decryption key set." + else + message = incorrectkey //Hack the Console to get the password if (href_list["hack"]) - if((isAI(usr) || isrobot(usr)) && player_is_antag(usr.mind)) - src.hacking = 1 - src.screen = 2 - update_icon() + if(issilicon(user) && player_is_antag(user.mind)) + hacking = TRUE + screen = SCREEN_HACKING + . = TOPIC_REFRESH //Time it takes to bruteforce is dependant on the password length. - addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/message_monitor, BruteForceConsole), usr, linked_server), 100*length(linked_server.decryptkey)) + addtimer(CALLBACK(src, TYPE_PROC_REF(/obj/machinery/computer/message_monitor, BruteForceConsole), user, linked_server), 10 SECONDS * length(linked_server.decryptkey)) //Delete the request console log. if (href_list["deleter"]) - //Are they on the view logs screen? - if(screen == 4) + . = TOPIC_REFRESH + //Make sure they're still on the view logs screen. + if(screen == SCREEN_MESSAGE_LOGS) if(!linked_server || (linked_server.stat & (NOPOWER|BROKEN))) message = noserver else //if(istype(href_list["delete"], /datum/data_pda_msg)) @@ -304,14 +312,16 @@ if(href_list["viewr"]) if(linked_server == null || (linked_server.stat & (NOPOWER|BROKEN))) message = noserver - else - if(auth) - src.screen = 4 + . = TOPIC_REFRESH + else if(auth) + screen = SCREEN_MESSAGE_LOGS + . = TOPIC_REFRESH if (href_list["back"]) - src.screen = 0 - - return interact(usr) + screen = SCREEN_MAIN_MENU + message = defaultmsg // reset it for the next interaction + . = TOPIC_REFRESH + // don't call interact() here, let the prior Topic() call do that via our TOPIC_REFRESH return value /obj/machinery/computer/message_monitor/proc/BruteForceConsole(var/mob/user, var/decrypting) var/obj/machinery/network/message_server/linked_server = get_message_server() diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm index 84a1b64504fa..b3903352d555 100644 --- a/code/game/machinery/computer/prisoner.dm +++ b/code/game/machinery/computer/prisoner.dm @@ -50,8 +50,8 @@ show_browser(user, dat, "window=computer;size=400x500") onclose(user, "computer") -/obj/machinery/computer/prisoner/Topic(href, href_list) - if(..()) +/obj/machinery/computer/prisoner/OnTopic(mob/user, href_list) + if((. = ..())) return . = TOPIC_REFRESH @@ -68,15 +68,15 @@ if(I) I.activate(10) else if(href_list["lock"]) - if(src.allowed(usr)) + if(allowed(user)) screen = !screen else - to_chat(usr, "Unauthorized Access.") + to_chat(user, "Unauthorized Access.") else if(href_list["warn"]) - var/warning = sanitize(input(usr,"Message:","Enter your message here!","")) - if(!warning) return + var/warning = sanitize(input(user,"Message:","Enter your message here!","")) + if(!warning) return TOPIC_HANDLED var/obj/item/implant/I = locate(href_list["warn"]) - if((I)&&(I.imp_in)) + if(I?.imp_in) var/mob/living/R = I.imp_in to_chat(R, "You hear a voice in your head saying: '[warning]'") diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 1be24240e750..b845e67c52b3 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -49,6 +49,8 @@ normalspeed = 1 var/hasShocked = 0 //Prevents multiple shocks from happening var/secured_wires = FALSE + /// This state overrides the density-based state while we're doing animations and such. + var/animating_state = 0 var/open_sound_powered = 'sound/machines/airlock_open.ogg' var/open_sound_unpowered = 'sound/machines/airlock_open_force.ogg' @@ -124,7 +126,7 @@ About the new airlock wires panel: */ /obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite - if(!issilicon(usr)) + if(!issilicon(user)) if(src.isElectrified()) if(!src.justzap) if(src.shock(user, 100)) @@ -290,29 +292,22 @@ About the new airlock wires panel: else return 0 -/obj/machinery/door/airlock/on_update_icon(state=0, override=0) - +/obj/machinery/door/airlock/on_update_icon() if(set_dir_on_update) if((connections & (NORTH|SOUTH)) == (NORTH|SOUTH)) set_dir(EAST) else if ((connections & (EAST|WEST)) == (EAST|WEST)) set_dir(SOUTH) + var/state = animating_state || (density ? AIRLOCK_CLOSED : AIRLOCK_OPEN) switch(state) - if(0) - if(density) - icon_state = icon_state_closed - state = AIRLOCK_CLOSED - else - icon_state = icon_state_open - state = AIRLOCK_OPEN - if(AIRLOCK_OPEN) - icon_state = icon_state_open if(AIRLOCK_CLOSED) icon_state = icon_state_closed - if(AIRLOCK_OPENING, AIRLOCK_CLOSING, AIRLOCK_EMAG, AIRLOCK_DENY) - icon_state = "" - + if(AIRLOCK_OPEN) + icon_state = icon_state_open + else + icon_state = "" // this should never happen, this is just what the old code did in this case + animating_state = null set_airlock_overlays(state) /obj/machinery/door/airlock/proc/set_airlock_overlays(state) @@ -432,18 +427,21 @@ About the new airlock wires panel: if("opening") set_airlock_overlays(AIRLOCK_OPENING) flick("opening", src)//[stat ? "_stat":] - update_icon(AIRLOCK_OPEN) + animating_state = AIRLOCK_OPEN + update_icon() if("closing") set_airlock_overlays(AIRLOCK_CLOSING) flick("closing", src) - update_icon(AIRLOCK_CLOSED) + animating_state = AIRLOCK_CLOSED + update_icon() if("deny") set_airlock_overlays(AIRLOCK_DENY) if(density && arePowerSystemsOn()) flick("deny", src) if(speaker) playsound(loc, open_failure_access_denied, 50, 0) - update_icon(AIRLOCK_CLOSED) + animating_state = AIRLOCK_CLOSED + update_icon() if("emag") set_airlock_overlays(AIRLOCK_EMAG) if(density && arePowerSystemsOn()) @@ -536,7 +534,7 @@ About the new airlock wires panel: src.attack_ai(user) /obj/machinery/door/airlock/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if (src.isElectrified()) + if (isElectrified()) if (istype(mover, /obj/item)) var/obj/item/i = mover if(i.material && i.material.conductive) @@ -544,9 +542,9 @@ About the new airlock wires panel: return ..() /obj/machinery/door/airlock/physical_attack_hand(mob/user) - if(!issilicon(usr)) - if(src.isElectrified()) - if(src.shock(user, 100)) + if(!issilicon(user)) + if(isElectrified()) + if(shock(user, 100)) return TRUE . = ..() @@ -566,63 +564,77 @@ About the new airlock wires panel: return ..() -/obj/machinery/door/airlock/Topic(href, href_list) - if(..()) - return 1 +/obj/machinery/door/airlock/OnTopic(mob/user, href_list) + if((. = ..())) + return var/activate = text2num(href_list["activate"]) switch (href_list["command"]) if("idscan") set_idscan(activate, 1) + . = TOPIC_REFRESH if("main_power") if(!main_power_lost_until) - src.loseMainPower() + loseMainPower() + . = TOPIC_REFRESH if("backup_power") if(!backup_power_lost_until) - src.loseBackupPower() + loseBackupPower() + . = TOPIC_REFRESH if("bolts") - if(src.isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) - to_chat(usr, "The door bolt control wire is cut - Door bolts permanently dropped.") - else if(activate && src.lock()) - to_chat(usr, "The door bolts have been dropped.") - else if(!activate && src.unlock()) - to_chat(usr, "The door bolts have been raised.") + if(isWireCut(AIRLOCK_WIRE_DOOR_BOLTS)) + to_chat(user, "The door bolt control wire is cut - Door bolts permanently dropped.") + . = TOPIC_HANDLED + else if(activate && lock()) + to_chat(user, "The door bolts have been dropped.") + . = TOPIC_REFRESH + else if(!activate && unlock()) + to_chat(user, "The door bolts have been raised.") + . = TOPIC_REFRESH if("electrify_temporary") electrify(30 * activate, 1) + . = TOPIC_REFRESH if("electrify_permanently") electrify(-1 * activate, 1) + . = TOPIC_REFRESH if("open") - if(src.welded) - to_chat(usr, text("The airlock has been welded shut!")) - else if(src.locked) - to_chat(usr, text("The door bolts are down!")) + if(welded) + to_chat(user, text("The airlock has been welded shut!")) + . = TOPIC_HANDLED + else if(locked) + to_chat(user, text("The door bolts are down!")) + . = TOPIC_HANDLED else if(activate && density) open() + . = TOPIC_REFRESH else if(!activate && !density) close() + . = TOPIC_REFRESH if("safeties") set_safeties(!activate, 1) if("timing") // Door speed control if(src.isWireCut(AIRLOCK_WIRE_SPEED)) - to_chat(usr, text("The timing wire is cut - Cannot alter timing.")) + to_chat(user, text("The timing wire is cut - Cannot alter timing.")) + . = TOPIC_HANDLED else if (activate && src.normalspeed) - normalspeed = 0 + normalspeed = FALSE + . = TOPIC_REFRESH else if (!activate && !src.normalspeed) - normalspeed = 1 + normalspeed = TRUE + . = TOPIC_REFRESH if("lights") // Lights - if(src.isWireCut(AIRLOCK_WIRE_LIGHT)) - to_chat(usr, "The lights wire is cut - The door lights are permanently disabled.") + if(isWireCut(AIRLOCK_WIRE_LIGHT)) + to_chat(user, "The lights wire is cut - The door lights are permanently disabled.") else if (!activate && src.lights) lights = 0 - to_chat(usr, "The door lights have been disabled.") + . = TOPIC_REFRESH + to_chat(user, "The door lights have been disabled.") else if (activate && !src.lights) lights = 1 - to_chat(usr, "The door lights have been enabled.") - - update_icon() - return 1 + . = TOPIC_REFRESH + to_chat(user, "The door lights have been enabled.") //returns 1 on success, 0 on failure /obj/machinery/door/airlock/proc/cut_bolts(var/obj/item/item, var/mob/user) diff --git a/code/game/machinery/doors/airlock_electronics.dm b/code/game/machinery/doors/airlock_electronics.dm index 6533978f8529..dbca57d4ca78 100644 --- a/code/game/machinery/doors/airlock_electronics.dm +++ b/code/game/machinery/doors/airlock_electronics.dm @@ -17,7 +17,7 @@ var/secure = 0 //if set, then wires will be randomized and bolts will drop if the door is broken /obj/item/stock_parts/circuitboard/airlock_electronics/secure name = "secure airlock electronics" - desc = "designed to be somewhat more resistant to hacking than standard electronics." + desc = "Airlock control electronics, designed to be somewhat more resistant to hacking than standard electronics." origin_tech = @'{"programming":2}' secure = TRUE diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm index fab7e5836fe0..d6e1916fb871 100644 --- a/code/game/machinery/doors/firedoor.dm +++ b/code/game/machinery/doors/firedoor.dm @@ -10,7 +10,7 @@ /obj/machinery/door/firedoor name = "emergency shutter" - desc = "Emergency air-tight shutters, capable of sealing off breached areas." + desc = "Emergency airtight shutters, capable of sealing off breached areas." icon = 'icons/obj/doors/hazard/door.dmi' var/panel_file = 'icons/obj/doors/hazard/panel.dmi' var/welded_file = 'icons/obj/doors/hazard/welded.dmi' diff --git a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm index dabbb7680fbb..66aa8d5c057c 100644 --- a/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm +++ b/code/game/machinery/embedded_controller/airlock_controllers_dummy.dm @@ -1,7 +1,7 @@ ///Provides remote access to a controller (since they must be unique). /obj/machinery/dummy_airlock_controller name = "remote airlock control terminal" - desc = "A secondary airlock control terminal meant to be subordinated to a master airlock control terminal to allow remotely controlling the later from the former." + desc = "A secondary airlock control terminal meant to be subordinated to a master airlock control terminal to allow remotely controlling the latter from the former." icon = 'icons/obj/airlock_machines.dmi' icon_state = "airlock_control_off" layer = ABOVE_OBJ_LAYER diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller.dm b/code/game/machinery/embedded_controller/airlock_docking_controller.dm index 87696262c887..026318090b40 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller.dm @@ -69,7 +69,7 @@ disable_override() else enable_override() - return TRUE + return TOPIC_REFRESH . = ..(command) . = airlock_program.receive_user_command(command) || . //pass along to subprograms; bypass shortcircuit @@ -129,6 +129,7 @@ /datum/computer/file/embedded_program/airlock/docking/receive_user_command(command) if (master_prog.undocked() || master_prog.override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled return ..(command) + return TOPIC_NOACTION /datum/computer/file/embedded_program/airlock/docking/proc/open_doors() toggleDoor(memory["interior_status"], tag_interior_door, memory["secure"], "open") diff --git a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm index eca7ae8fb8ce..ea88e24d38da 100644 --- a/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm +++ b/code/game/machinery/embedded_controller/airlock_docking_controller_multi.dm @@ -46,8 +46,8 @@ ui.open() ui.set_auto_update(1) -/obj/machinery/embedded_controller/radio/docking_port_multi/Topic(href, href_list) - return 1 // Apparently we swallow all input (this is corrected legacy code) +/obj/machinery/embedded_controller/radio/docking_port_multi/OnTopic(user, href_list) + return TOPIC_HANDLED // Apparently we swallow all input (this is corrected legacy code) diff --git a/code/game/machinery/embedded_controller/airlock_program.dm b/code/game/machinery/embedded_controller/airlock_program.dm index eda2a4421eb4..467b170bd841 100644 --- a/code/game/machinery/embedded_controller/airlock_program.dm +++ b/code/game/machinery/embedded_controller/airlock_program.dm @@ -145,7 +145,7 @@ /datum/computer/file/embedded_program/airlock/receive_user_command(command) var/shutdown_pump = 0 - . = TRUE + . = TOPIC_REFRESH switch(command) if("cycle_ext") //If airlock is already cycled in this direction, just toggle the doors. @@ -188,7 +188,7 @@ toggleDoor(memory["interior_status"], tag_interior_door, !memory["secure"]) memory["secure"] = !memory["secure"] else - . = FALSE + . = TOPIC_NOACTION if(shutdown_pump) signalPump(tag_airpump, 0) //send a signal to stop pressurizing diff --git a/code/game/machinery/embedded_controller/docking_program.dm b/code/game/machinery/embedded_controller/docking_program.dm index 5a8dbad94e82..c247336a132b 100644 --- a/code/game/machinery/embedded_controller/docking_program.dm +++ b/code/game/machinery/embedded_controller/docking_program.dm @@ -57,7 +57,7 @@ var/response_sent = 0 //so we don't spam confirmation messages var/override_enabled = 0 //when enabled, do not open/close doors or cycle airlocks and wait for the player to do it manually - var/received_confirm = 0 //for undocking, whether the server has recieved a confirmation from the client + var/received_confirm = 0 //for undocking, whether the server has received a confirmation from the client var/docking_codes //would only allow docking when receiving signal with these, if set var/display_name //how would it show up on docking monitoring program, area name + coordinates if unset @@ -78,8 +78,8 @@ /datum/computer/file/embedded_program/docking/receive_user_command(command) if(command == "dock" || command == "undock") - if(!tag_target) //Prevents from self destructing if no docking buddy - return FALSE + if(!tag_target) //Prevents from self-destructing if no docking buddy + return TOPIC_NOACTION var/datum/signal/signal = new() signal.data["tag"] = tag_target @@ -87,7 +87,8 @@ signal.data["recipient"] = id_tag signal.data["code"] = docking_codes receive_signal(signal) - return TRUE + return TOPIC_REFRESH + return TOPIC_NOACTION /datum/computer/file/embedded_program/docking/get_receive_filters() return list("[id_tag]" = "primary controller") diff --git a/code/game/machinery/embedded_controller/docking_program_multi.dm b/code/game/machinery/embedded_controller/docking_program_multi.dm index c525e650e890..45da8d68e822 100644 --- a/code/game/machinery/embedded_controller/docking_program_multi.dm +++ b/code/game/machinery/embedded_controller/docking_program_multi.dm @@ -135,10 +135,11 @@ else override_enabled = 1 broadcast_override_status() - return TRUE + return TOPIC_REFRESH - if (!docking_enabled|| override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled + if (!docking_enabled || override_enabled) //only allow the port to be used as an airlock if nothing is docked here or the override is enabled return ..(command) + return TOPIC_NOACTION /datum/computer/file/embedded_program/airlock/multi_docking/get_receive_filters() return ..() + master_tag // master_tag is specifically to get "dock_status" diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 2f893501f6e8..5b622e965a41 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -28,14 +28,14 @@ update_icon() //spawn(5) program.process() //no, program.process sends some signals and machines respond and we here again and we lag -rastaf0 -/obj/machinery/embedded_controller/Topic(href, href_list) - if(..()) - update_icon() +/obj/machinery/embedded_controller/OnTopic(mob/user, href_list) + if((. = ..())) return - if(usr) - usr.set_machine(src) + if(user) + user.set_machine(src) if(program) return program.receive_user_command(href_list["command"]) // Any further sanitization should be done in here. + return TOPIC_NOACTION /obj/machinery/embedded_controller/Process() if(program) diff --git a/code/game/machinery/embedded_controller/embedded_program_base.dm b/code/game/machinery/embedded_controller/embedded_program_base.dm index e6bcb5b68c33..31e409c555f9 100644 --- a/code/game/machinery/embedded_controller/embedded_program_base.dm +++ b/code/game/machinery/embedded_controller/embedded_program_base.dm @@ -16,7 +16,7 @@ return ..() /datum/computer/file/embedded_program/proc/receive_user_command(command) - return FALSE + return TOPIC_NOACTION // Returns all filters on which you want to receive signals /datum/computer/file/embedded_program/proc/get_receive_filters(var/for_ui = FALSE) diff --git a/code/game/machinery/embedded_controller/simple_docking_controller.dm b/code/game/machinery/embedded_controller/simple_docking_controller.dm index 332077048e63..52dae59a4531 100644 --- a/code/game/machinery/embedded_controller/simple_docking_controller.dm +++ b/code/game/machinery/embedded_controller/simple_docking_controller.dm @@ -63,7 +63,7 @@ ..(signal, receive_method, receive_param) /datum/computer/file/embedded_program/docking/simple/receive_user_command(command) - . = TRUE + . = TOPIC_REFRESH switch(command) if("force_door") if (override_enabled) @@ -74,7 +74,7 @@ else enable_override() else - . = FALSE + . = TOPIC_NOACTION //tell the docking port to start getting ready for docking - e.g. pressurize /datum/computer/file/embedded_program/docking/simple/prepare_for_docking() diff --git a/code/game/machinery/embedded_controller/tin_can.dm b/code/game/machinery/embedded_controller/tin_can.dm index d2cada82a3d4..1dcf86bdcfe4 100644 --- a/code/game/machinery/embedded_controller/tin_can.dm +++ b/code/game/machinery/embedded_controller/tin_can.dm @@ -44,34 +44,34 @@ ..() /datum/computer/file/embedded_program/airlock/tin_can/receive_user_command(command) - . = TRUE + . = TOPIC_REFRESH switch(command) if("toggle_door_safety") door_safety = !door_safety toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety) if("evacuate_atmos") if(state == STATE_EVACUATE) - return + return TOPIC_HANDLED state = STATE_EVACUATE toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety, "close") - signalPump(tag_pump_out_internal, 1, 0, 0) // Interior pump, target is a vaccum + signalPump(tag_pump_out_internal, 1, 0, 0) // Interior pump, target is a vacuum signalPump(tag_pump_out_external, 1, 1, 10000) // Exterior pump, target is infinite if("fill_atmos") if(state == STATE_FILL) - return + return TOPIC_HANDLED state = STATE_FILL toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety, "close") signalPump(tag_pump_out_internal, 1, 1, memory["external_sensor_pressure"]) // Interior pump, target is exterior pressure signalPump(tag_pump_out_external, 1, 0, 0) // Exterior pump, target is zero, to intake if("seal") if(state == STATE_SEALED) - return + return TOPIC_HANDLED state = STATE_SEALED toggleDoor(memory["exterior_status"], tag_exterior_door, door_safety, "close") signalPump(tag_pump_out_internal, 0) signalPump(tag_pump_out_external, 0) else - . = FALSE + . = TOPIC_NOACTION /datum/computer/file/embedded_program/airlock/tin_can/process() if(door_safety) diff --git a/code/game/machinery/igniter.dm b/code/game/machinery/igniter.dm index 47f7eab52117..26a071ea6aef 100644 --- a/code/game/machinery/igniter.dm +++ b/code/game/machinery/igniter.dm @@ -1,6 +1,6 @@ /obj/machinery/igniter name = "igniter" - desc = "It's useful for igniting flammable items." + desc = "A device that ignites flammable items and gases nearby when activated." icon = 'icons/obj/machines/igniter.dmi' icon_state = "igniter1" var/on = 0 diff --git a/code/game/machinery/kitchen/cooking_machines/fryer.dm b/code/game/machinery/kitchen/cooking_machines/fryer.dm index 0be1e523f110..090c58670cf6 100644 --- a/code/game/machinery/kitchen/cooking_machines/fryer.dm +++ b/code/game/machinery/kitchen/cooking_machines/fryer.dm @@ -1,6 +1,6 @@ /obj/machinery/cooker/fryer name = "deep fryer" - desc = "Deep fried everything." + desc = "Deep-fried everything." icon_state = "fryer_off" can_cook_mobs = 1 cook_type = "deep fried" diff --git a/code/game/machinery/kitchen/microwave.dm b/code/game/machinery/kitchen/microwave.dm index bda3e44c704c..886b8ce43997 100644 --- a/code/game/machinery/kitchen/microwave.dm +++ b/code/game/machinery/kitchen/microwave.dm @@ -87,7 +87,7 @@ dispose() return else if(dirty==100) // The microwave is all dirty so can't be used! - if(istype(O, /obj/item/chems/spray/cleaner) || istype(O, /obj/item/chems/glass/rag)) // If they're trying to clean it then let them + if(istype(O, /obj/item/chems/spray/cleaner) || istype(O, /obj/item/chems/rag)) // If they're trying to clean it then let them user.visible_message( SPAN_NOTICE("\The [user] starts to clean [src]."), SPAN_NOTICE("You start to clean [src].") diff --git a/code/game/machinery/mech_recharger.dm b/code/game/machinery/mech_recharger.dm index bd9e8be69364..5c2449e37ed2 100644 --- a/code/game/machinery/mech_recharger.dm +++ b/code/game/machinery/mech_recharger.dm @@ -1,6 +1,6 @@ /obj/machinery/mech_recharger name = "exosuit dock" - desc = "A exosuit recharger, built into the floor." + desc = "An exosuit recharger, built into the floor." icon = 'icons/mecha/mech_bay.dmi' icon_state = "recharge_floor" density = FALSE diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 2e01d1262171..b129241b2ea4 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -29,7 +29,7 @@ var/global/list/navbeacons = list() navbeacons += src /obj/machinery/navbeacon/hide(var/intact) - set_invisibility(intact ? 101 : 0) + set_invisibility(intact ? INVISIBILITY_ABSTRACT : INVISIBILITY_NONE) update_icon() /obj/machinery/navbeacon/on_update_icon() @@ -73,100 +73,80 @@ var/global/list/navbeacons = list() var/ai = isAI(user) var/turf/T = loc if(!T.is_plating()) - return // prevent intraction when T-scanner revealed + return // prevent intraction when T-scanner revealed - if(!open && !ai) // can't alter controls if not open, unless you're an AI + if(!open && !ai) // can't alter controls if not open, unless you're an AI to_chat(user, "The beacon's control cover is closed.") return - var/t - - if(locked && !ai) - t = {"Navigation Beacon

-(swipe card to unlock controls)

-Location: [location ? location : "(none)"]

-Transponder Codes: