diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 241941037e8..c38f4c98a9c 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 f8a535325d9..60e510bf861 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 34676c2ab11..0d697d35111 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 72b8219931d..1abbc586a1a 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 00000000000..8548753e1af --- /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 00000000000..fdf49aecb2b --- /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 02ffad499de..068afdce75c 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 00000000000..0a98c436e53 --- /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 4103f74f2cd..4fa56abf9b2 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 08bdef69289..8050ff1d0a0 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) + if(!istype(user)) + return - // - 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 - - 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 1a76e86370a..15df657564d 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 6ccceff86d9..df9059fb09e 100644 Binary files a/icons/mob/silicon/ai.dmi and b/icons/mob/silicon/ai.dmi differ diff --git a/strings/tips.txt b/strings/tips.txt index 50aadb2a46a..f0baf463e37 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 e05361bd286..8c386c6eeb1 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 00000000000..348ab4183e9 --- /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 00000000000..b933933b812 --- /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, +};