From 2a19963297f91efb452dbb5c1d4eb28a14776b0a Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Jun 2023 03:43:26 -0500 Subject: [PATCH] Add UI preference menus for AI hologram and status displays (#75740) This adds two new dropdown menus for AI preferences with holograms and status displays. It also sets these preferences if admins transform a player into an AI. --- code/__DEFINES/mobs.dm | 20 +++ code/_globalvars/lists/flavor_misc.dm | 62 --------- code/game/machinery/status_display.dm | 30 +---- .../client/preferences/ai_core_display.dm | 2 +- .../client/preferences/ai_emote_display.dm | 26 ++++ .../client/preferences/ai_hologram_display.dm | 25 ++++ code/modules/jobs/job_types/_job.dm | 3 +- .../mob/living/silicon/ai/_preferences.dm | 126 ++++++++++++++++++ code/modules/mob/living/silicon/ai/ai.dm | 34 ++++- code/modules/mob/living/silicon/ai/emote.dm | 16 +-- code/modules/mob/transform_procs.dm | 2 + icons/mob/silicon/ai.dmi | Bin 419341 -> 419492 bytes strings/tips.txt | 1 + tgstation.dme | 3 + .../ai_emote_display.tsx | 6 + .../ai_hologram_display.tsx | 6 + 16 files changed, 256 insertions(+), 106 deletions(-) create mode 100644 code/modules/client/preferences/ai_emote_display.dm create mode 100644 code/modules/client/preferences/ai_hologram_display.dm create mode 100644 code/modules/mob/living/silicon/ai/_preferences.dm create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx create mode 100644 tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 241941037e870..c38f4c98a9c3e 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -600,6 +600,26 @@ #define AI_EMOTION_BLUE_GLOW "Blue Glow" #define AI_EMOTION_RED_GLOW "Red Glow" +///Defines for AI hologram preferences +#define AI_HOLOGRAM_BEAR "Bear" +#define AI_HOLOGRAM_CARP "Carp" +#define AI_HOLOGRAM_CAT "Cat" +#define AI_HOLOGRAM_CAT_2 "Cat Alternate" +#define AI_HOLOGRAM_CHICKEN "Chicken" +#define AI_HOLOGRAM_CORGI "Corgi" +#define AI_HOLOGRAM_COW "Cow" +#define AI_HOLOGRAM_CRAB "Crab" +#define AI_HOLOGRAM_DEFAULT "Default" +#define AI_HOLOGRAM_FACE "Floating Face" +#define AI_HOLOGRAM_FOX "Fox" +#define AI_HOLOGRAM_GOAT "Goat" +#define AI_HOLOGRAM_NARSIE "Narsie" +#define AI_HOLOGRAM_PARROT "Parrot" +#define AI_HOLOGRAM_PUG "Pug" +#define AI_HOLOGRAM_RATVAR "Ratvar" +#define AI_HOLOGRAM_SPIDER "Spider" +#define AI_HOLOGRAM_XENO "Xeno Queen" + /// Icon state to use for ai displays that just turns them off #define AI_DISPLAY_DONT_GLOW "ai_off" /// Throw modes, defines whether or not to turn off throw mode after diff --git a/code/_globalvars/lists/flavor_misc.dm b/code/_globalvars/lists/flavor_misc.dm index f8a535325d9f4..60e510bf8611d 100644 --- a/code/_globalvars/lists/flavor_misc.dm +++ b/code/_globalvars/lists/flavor_misc.dm @@ -122,68 +122,6 @@ GLOBAL_LIST_INIT(ghost_forms_with_accessories_list, list( )) //stores the ghost forms that support hair and other such things -GLOBAL_LIST_INIT(ai_core_display_screens, sort_list(list( - ":thinking:", - "Alien", - "Angel", - "Banned", - "Bliss", - "Blue", - "Clown", - "Database", - "Dorf", - "Firewall", - "Fuzzy", - "Gentoo", - "Glitchman", - "Gondola", - "Goon", - "Hades", - "HAL 9000", - "Heartline", - "Helios", - "House", - "Inverted", - "Matrix", - "Monochrome", - "Murica", - "Nanotrasen", - "Not Malf", - "Portrait", - "President", - "Rainbow", - "Random", - "Red October", - "Red", - "Static", - "Syndicat Meow", - "Text", - "Too Deep", - "Triumvirate-M", - "Triumvirate", - "Weird", -))) - -/// A form of resolve_ai_icon that is guaranteed to never sleep. -/// Not always accurate, but always synchronous. -/proc/resolve_ai_icon_sync(input) - SHOULD_NOT_SLEEP(TRUE) - - if(!input || !(input in GLOB.ai_core_display_screens)) - return "ai" - else - if(input == "Random") - input = pick(GLOB.ai_core_display_screens - "Random") - return "ai-[lowertext(input)]" - -/proc/resolve_ai_icon(input) - if (input == "Portrait") - var/datum/portrait_picker/tgui = new(usr)//create the datum - tgui.ui_interact(usr)//datum has a tgui component, here we open the window - return "ai-portrait" //just take this until they decide - - return resolve_ai_icon_sync(input) - GLOBAL_LIST_INIT(security_depts_prefs, sort_list(list( SEC_DEPT_ENGINEERING, SEC_DEPT_MEDICAL, diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index 34676c2ab1172..0d697d35111b3 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -463,29 +463,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/evac, 32) name = "\improper AI display" desc = "A small screen which the AI can use to present itself." current_mode = SD_PICTURE - - var/emotion = AI_EMOTION_BLANK - - /// A mapping between AI_EMOTION_* string constants, which also double as user readable descriptions, and the name of the iconfile. - var/static/list/emotion_map = list( - AI_EMOTION_BLANK = AI_DISPLAY_DONT_GLOW, - AI_EMOTION_VERY_HAPPY = "ai_veryhappy", - AI_EMOTION_HAPPY = "ai_happy", - AI_EMOTION_NEUTRAL = "ai_neutral", - AI_EMOTION_UNSURE = "ai_unsure", - AI_EMOTION_CONFUSED = "ai_confused", - AI_EMOTION_SAD = "ai_sad", - AI_EMOTION_BSOD = "ai_bsod", - AI_EMOTION_PROBLEMS = "ai_trollface", - AI_EMOTION_AWESOME = "ai_awesome", - AI_EMOTION_DORFY = "ai_urist", - AI_EMOTION_THINKING = "ai_thinking", - AI_EMOTION_FACEPALM = "ai_facepalm", - AI_EMOTION_FRIEND_COMPUTER = "ai_friend", - AI_EMOTION_BLUE_GLOW = "ai_sal", - AI_EMOTION_RED_GLOW = "ai_hal", - ) - + var/emotion = AI_DISPLAY_DONT_GLOW MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32) @@ -501,8 +479,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32) if(!isAI(user)) return var/list/choices = list() - for(var/emotion_const in emotion_map) - var/icon_state = emotion_map[emotion_const] + for(var/emotion_const in GLOB.ai_status_display_emotes) + var/icon_state = GLOB.ai_status_display_emotes[emotion_const] choices[emotion_const] = image(icon = 'icons/obj/status_display.dmi', icon_state = icon_state) var/emotion_result = show_radial_menu(user, src, choices, tooltips = TRUE) @@ -517,7 +495,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/status_display/ai, 32) update_appearance() return PROCESS_KILL - set_picture(emotion_map[emotion]) + set_picture(GLOB.ai_status_display_emotes[emotion]) return PROCESS_KILL /obj/item/circuit_component/status_display diff --git a/code/modules/client/preferences/ai_core_display.dm b/code/modules/client/preferences/ai_core_display.dm index 72b8219931daa..1abbc586a1a53 100644 --- a/code/modules/client/preferences/ai_core_display.dm +++ b/code/modules/client/preferences/ai_core_display.dm @@ -8,7 +8,7 @@ /datum/preference/choiced/ai_core_display/init_possible_values() var/list/values = list() - values["Random"] = icon('icons/mob/silicon/ai.dmi', "ai-empty") + values["Random"] = icon('icons/mob/silicon/ai.dmi', "questionmark") for (var/screen in GLOB.ai_core_display_screens - "Portrait" - "Random") values[screen] = icon('icons/mob/silicon/ai.dmi', resolve_ai_icon_sync(screen)) diff --git a/code/modules/client/preferences/ai_emote_display.dm b/code/modules/client/preferences/ai_emote_display.dm new file mode 100644 index 0000000000000..8548753e1af34 --- /dev/null +++ b/code/modules/client/preferences/ai_emote_display.dm @@ -0,0 +1,26 @@ +/// What to show on the AI monitor +/datum/preference/choiced/ai_emote_display + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "preferred_ai_emote_display" + should_generate_icons = TRUE + +/datum/preference/choiced/ai_emote_display/init_possible_values() + var/list/values = list() + + values["Random"] = icon('icons/mob/silicon/ai.dmi', "questionmark") + + for(var/emote in GLOB.ai_status_display_emotes) + var/emote_icon = GLOB.ai_status_display_emotes[emote] + values[emote] = icon('icons/obj/status_display.dmi', emote_icon) + + return values + +/datum/preference/choiced/ai_emote_display/is_accessible(datum/preferences/preferences) + if (!..(preferences)) + return FALSE + + return istype(preferences.get_highest_priority_job(), /datum/job/ai) + +/datum/preference/choiced/ai_emote_display/apply_to_human(mob/living/carbon/human/target, value) + return diff --git a/code/modules/client/preferences/ai_hologram_display.dm b/code/modules/client/preferences/ai_hologram_display.dm new file mode 100644 index 0000000000000..fdf49aecb2b3f --- /dev/null +++ b/code/modules/client/preferences/ai_hologram_display.dm @@ -0,0 +1,25 @@ +/// What to show on the AI hologram +/datum/preference/choiced/ai_hologram_display + category = PREFERENCE_CATEGORY_NON_CONTEXTUAL + savefile_identifier = PREFERENCE_CHARACTER + savefile_key = "preferred_ai_hologram_display" + should_generate_icons = TRUE + +/datum/preference/choiced/ai_hologram_display/init_possible_values() + var/list/values = list() + + values["Random"] = icon('icons/mob/silicon/ai.dmi', "questionmark") + + for(var/hologram in GLOB.ai_hologram_icons - "Random") + values[hologram] = icon(GLOB.ai_hologram_icons[hologram], GLOB.ai_hologram_icon_state[hologram]) + + return values + +/datum/preference/choiced/ai_hologram_display/is_accessible(datum/preferences/preferences) + if (!..(preferences)) + return FALSE + + return istype(preferences.get_highest_priority_job(), /datum/job/ai) + +/datum/preference/choiced/ai_hologram_display/apply_to_human(mob/living/carbon/human/target, value) + return diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm index 02ffad499de65..068afdce75c2f 100644 --- a/code/modules/jobs/job_types/_job.dm +++ b/code/modules/jobs/job_types/_job.dm @@ -506,7 +506,8 @@ return apply_pref_name(/datum/preference/name/ai, player_client) // This proc already checks if the player is appearance banned. set_core_display_icon(null, player_client) - + apply_pref_emote_display(player_client) + apply_pref_hologram_display(player_client) /mob/living/silicon/robot/apply_prefs_job(client/player_client, datum/job/job) if(mmi) diff --git a/code/modules/mob/living/silicon/ai/_preferences.dm b/code/modules/mob/living/silicon/ai/_preferences.dm new file mode 100644 index 0000000000000..0a98c436e5381 --- /dev/null +++ b/code/modules/mob/living/silicon/ai/_preferences.dm @@ -0,0 +1,126 @@ +// A mapping between AI_EMOTION_* string constants, which also double as user readable descriptions, and the name of the iconfile. (used for /obj/machinery/status_display/ai ) +GLOBAL_LIST_INIT(ai_status_display_emotes, list( + AI_EMOTION_AWESOME = "ai_awesome", + AI_EMOTION_BLANK = AI_DISPLAY_DONT_GLOW, + AI_EMOTION_BLUE_GLOW = "ai_sal", + AI_EMOTION_BSOD = "ai_bsod", + AI_EMOTION_CONFUSED = "ai_confused", + AI_EMOTION_DORFY = "ai_urist", + AI_EMOTION_FACEPALM = "ai_facepalm", + AI_EMOTION_FRIEND_COMPUTER = "ai_friend", + AI_EMOTION_HAPPY = "ai_happy", + AI_EMOTION_NEUTRAL = "ai_neutral", + AI_EMOTION_PROBLEMS = "ai_trollface", + AI_EMOTION_RED_GLOW = "ai_hal", + AI_EMOTION_SAD = "ai_sad", + AI_EMOTION_THINKING = "ai_thinking", + AI_EMOTION_UNSURE = "ai_unsure", + AI_EMOTION_VERY_HAPPY = "ai_veryhappy", +)) + +// New items need to also be added to ai_hologram_icon_state list +GLOBAL_LIST_INIT(ai_hologram_icons, list( + AI_HOLOGRAM_BEAR = 'icons/mob/simple/animal.dmi', + AI_HOLOGRAM_CARP = 'icons/mob/simple/carp.dmi', + AI_HOLOGRAM_CAT = 'icons/mob/simple/pets.dmi', + AI_HOLOGRAM_CAT_2 = 'icons/mob/simple/pets.dmi', + AI_HOLOGRAM_CHICKEN = 'icons/mob/simple/animal.dmi', + AI_HOLOGRAM_CORGI = 'icons/mob/simple/pets.dmi', + AI_HOLOGRAM_COW = 'icons/mob/simple/animal.dmi', + AI_HOLOGRAM_CRAB = 'icons/mob/simple/animal.dmi', + AI_HOLOGRAM_DEFAULT = 'icons/mob/silicon/ai.dmi', + AI_HOLOGRAM_FACE = 'icons/mob/silicon/ai.dmi', + AI_HOLOGRAM_FOX = 'icons/mob/simple/pets.dmi', + AI_HOLOGRAM_GOAT = 'icons/mob/simple/animal.dmi', + AI_HOLOGRAM_NARSIE = 'icons/mob/silicon/ai.dmi', + AI_HOLOGRAM_PARROT = 'icons/mob/simple/animal.dmi', + AI_HOLOGRAM_PUG = 'icons/mob/simple/pets.dmi', + AI_HOLOGRAM_RATVAR = 'icons/mob/silicon/ai.dmi', + AI_HOLOGRAM_SPIDER = 'icons/mob/simple/animal.dmi', + AI_HOLOGRAM_XENO = 'icons/mob/nonhuman-player/alien.dmi', +)) + +// New items need to also be added to ai_hologram_icons list +GLOBAL_LIST_INIT(ai_hologram_icon_state, list( + AI_HOLOGRAM_BEAR = "bear", + AI_HOLOGRAM_CARP = "carp", + AI_HOLOGRAM_CAT = "cat", + AI_HOLOGRAM_CAT_2 = "cat2", + AI_HOLOGRAM_CHICKEN = "chicken_brown", + AI_HOLOGRAM_CORGI = "corgi", + AI_HOLOGRAM_COW = "cow", + AI_HOLOGRAM_CRAB = "crab", + AI_HOLOGRAM_DEFAULT = "default", + AI_HOLOGRAM_FACE = "floating face", + AI_HOLOGRAM_FOX = "fox", + AI_HOLOGRAM_GOAT = "goat", + AI_HOLOGRAM_NARSIE = "horror", + AI_HOLOGRAM_PARROT = "parrot_fly", + AI_HOLOGRAM_PUG = "pug", + AI_HOLOGRAM_RATVAR = "clock", + AI_HOLOGRAM_SPIDER = "guard", + AI_HOLOGRAM_XENO = "alienq", +)) + + +GLOBAL_LIST_INIT(ai_core_display_screens, sort_list(list( + ":thinking:", + "Alien", + "Angel", + "Banned", + "Bliss", + "Blue", + "Clown", + "Database", + "Dorf", + "Firewall", + "Fuzzy", + "Gentoo", + "Glitchman", + "Gondola", + "Goon", + "Hades", + "HAL 9000", + "Heartline", + "Helios", + "House", + "Inverted", + "Matrix", + "Monochrome", + "Murica", + "Nanotrasen", + "Not Malf", + "Portrait", + "President", + "Rainbow", + "Random", + "Red October", + "Red", + "Static", + "Syndicat Meow", + "Text", + "Too Deep", + "Triumvirate-M", + "Triumvirate", + "Weird", +))) + +/// A form of resolve_ai_icon that is guaranteed to never sleep. +/// Not always accurate, but always synchronous. +/proc/resolve_ai_icon_sync(input) + SHOULD_NOT_SLEEP(TRUE) + + if(!input || !(input in GLOB.ai_core_display_screens)) + return "ai" + else + if(input == "Random") + input = pick(GLOB.ai_core_display_screens - "Random") + return "ai-[lowertext(input)]" + +/proc/resolve_ai_icon(input) + if (input == "Portrait") + var/datum/portrait_picker/tgui = new(usr)//create the datum + tgui.ui_interact(usr)//datum has a tgui component, here we open the window + return "ai-portrait" //just take this until they decide + + return resolve_ai_icon_sync(input) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 4103f74f2cd11..4fa56abf9b2b9 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -157,21 +157,20 @@ create_modularInterface() + // /mob/living/silicon/ai/apply_prefs_job() uses these to set these procs at mapload + // this is used when a person is being inserted into an AI core during a round if(client) INVOKE_ASYNC(src, PROC_REF(apply_pref_name), /datum/preference/name/ai, client) + INVOKE_ASYNC(src, PROC_REF(apply_pref_hologram_display), client) INVOKE_ASYNC(src, PROC_REF(set_core_display_icon)) - - hologram_appearance = mutable_appearance('icons/mob/silicon/ai.dmi',"default") - spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, src) spark_system.attach(src) add_verb(src, /mob/living/silicon/ai/proc/show_laws_verb) - aiMulti = new(src) aicamera = new/obj/item/camera/siliconcam/ai_camera(src) @@ -262,6 +261,33 @@ var/preferred_icon = input ? input : C.prefs.read_preference(/datum/preference/choiced/ai_core_display) icon_state = resolve_ai_icon(preferred_icon) +/// Apply an AI's hologram preference +/mob/living/silicon/ai/proc/apply_pref_hologram_display(client/player_client) + if(player_client.prefs?.read_preference(/datum/preference/choiced/ai_hologram_display)) + var/list/hologram_choice = player_client.prefs.read_preference(/datum/preference/choiced/ai_hologram_display) + if(hologram_choice == "Random") + hologram_choice = pick(GLOB.ai_hologram_icons) + + hologram_appearance = mutable_appearance(GLOB.ai_hologram_icons[hologram_choice], GLOB.ai_hologram_icon_state[hologram_choice]) + + hologram_appearance ||= mutable_appearance(GLOB.ai_hologram_icons[AI_HOLOGRAM_DEFAULT], GLOB.ai_hologram_icon_state[AI_HOLOGRAM_DEFAULT]) + +/// Apply an AI's emote display preference +/mob/living/silicon/ai/proc/apply_pref_emote_display(client/player_client) + if(player_client.prefs?.read_preference(/datum/preference/choiced/ai_emote_display)) + var/emote_choice = player_client.prefs.read_preference(/datum/preference/choiced/ai_emote_display) + + if(emote_choice == "Random") + emote_choice = pick(GLOB.ai_status_display_emotes) + + apply_emote_display(emote_choice) + +/// Apply an emote to all AI status displays on the station +/mob/living/silicon/ai/proc/apply_emote_display(emote) + for(var/obj/machinery/status_display/ai/ai_display as anything in GLOB.ai_status_displays) + ai_display.emotion = emote + ai_display.update() + /mob/living/silicon/ai/verb/pick_icon() set category = "AI Commands" set name = "Set AI Core Display" diff --git a/code/modules/mob/living/silicon/ai/emote.dm b/code/modules/mob/living/silicon/ai/emote.dm index 08bdef6928973..8050ff1d0a0d9 100644 --- a/code/modules/mob/living/silicon/ai/emote.dm +++ b/code/modules/mob/living/silicon/ai/emote.dm @@ -7,23 +7,15 @@ key = "blank" var/emotion = AI_EMOTION_BLANK -/datum/emote/ai/emotion_display/run_emote(mob/user, params, type_override, intentional) +/datum/emote/ai/emotion_display/run_emote(mob/living/silicon/ai/user, params, type_override, intentional) . = ..() if(!.) return - var/mob/living/silicon/ai/ai = user - var/turf/ai_turf = get_turf(ai) - for(var/obj/machinery/status_display/ai/ai_display as anything in GLOB.ai_status_displays) - var/turf/display_turf = get_turf(ai_display) - - // - Station AIs can change every display on the station Z. - // - Ghost role AIs (or AIs on the mining base?) can only affect their Z - if(!is_valid_z_level(ai_turf, display_turf)) - continue + if(!istype(user)) + return - ai_display.emotion = emotion - ai_display.update() + user.apply_emote_display(emotion) /datum/emote/ai/emotion_display/very_happy key = "veryhappy" diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 1a76e86370acf..15df657564deb 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -99,6 +99,8 @@ if(preference_source) apply_pref_name(/datum/preference/name/ai, preference_source) + our_AI.apply_pref_hologram_display(preference_source) + our_AI.set_core_display_icon(null, preference_source) qdel(src) diff --git a/icons/mob/silicon/ai.dmi b/icons/mob/silicon/ai.dmi index 6ccceff86d9c717d628032f26920a8ee3aee5e43..df9059fb09e6af97b2aaa6398c6550824f18d91f 100644 GIT binary patch delta 14862 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 Txs8u}3Q|+nQmRw12>t&6<;Pe9 delta 14726 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 diff --git a/strings/tips.txt b/strings/tips.txt index 50aadb2a46a2a..f0baf463e377f 100644 --- a/strings/tips.txt +++ b/strings/tips.txt @@ -141,6 +141,7 @@ As an Engineer, your departmental protolathe and circuit printer can manufacture As an Engineer, your RCD can be reloaded with iron, glass or plasteel sheets instead of just compressed matter cartridges. As an Engineering Cyborg, you can attach air alarm/fire alarm/APC frames to walls by placing them on the floor and using a screwdriver on them. As the AI, you can click on people's names to look at them. This only works if there are cameras that can see them, they aren't wearing agent IDs and aren't using digital camouflage as changelings. +As the AI, you can emote to change the status displays near your core. Some emotes can even be used to change the status displays across the entire station. As the AI, you can quickly open and close doors by holding shift while clicking them, bolt them when holding ctrl, and even shock them while holding alt. As the AI, you can take pictures with your camera and upload them to newscasters. As the AI, you can use CTRL + 1-9 to set a location hotkey for your camera, allowing you to save the location and jump to it at will. Tilde and zero will return you to the last spot you jumped from, and the numpad numbers act as aliases to the regular number keys. diff --git a/tgstation.dme b/tgstation.dme index e05361bd28686..8c386c6eeb16f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3054,6 +3054,8 @@ #include "code\modules\client\preferences\admin.dm" #include "code\modules\client\preferences\age.dm" #include "code\modules\client\preferences\ai_core_display.dm" +#include "code\modules\client\preferences\ai_emote_display.dm" +#include "code\modules\client\preferences\ai_hologram_display.dm" #include "code\modules\client\preferences\ambient_occlusion.dm" #include "code\modules\client\preferences\assets.dm" #include "code\modules\client\preferences\auto_fit_viewport.dm" @@ -4150,6 +4152,7 @@ #include "code\modules\mob\living\silicon\silicon_defense.dm" #include "code\modules\mob\living\silicon\silicon_movement.dm" #include "code\modules\mob\living\silicon\silicon_say.dm" +#include "code\modules\mob\living\silicon\ai\_preferences.dm" #include "code\modules\mob\living\silicon\ai\ai.dm" #include "code\modules\mob\living\silicon\ai\ai_defense.dm" #include "code\modules\mob\living\silicon\ai\ai_portrait_picker.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx new file mode 100644 index 0000000000000..348ab4183e9ef --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_emote_display.tsx @@ -0,0 +1,6 @@ +import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base'; + +export const preferred_ai_emote_display: FeatureWithIcons = { + name: 'AI emote display', + component: FeatureIconnedDropdownInput, +}; diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx new file mode 100644 index 0000000000000..b933933b812c6 --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/character_preferences/ai_hologram_display.tsx @@ -0,0 +1,6 @@ +import { FeatureIconnedDropdownInput, FeatureWithIcons } from '../base'; + +export const preferred_ai_hologram_display: FeatureWithIcons = { + name: 'AI hologram display', + component: FeatureIconnedDropdownInput, +};