diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index 7323debadc..795a29527b 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -14,6 +14,8 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
var/obj/item/device/radio/radio
var/looking_for_personality = 0
var/mob/living/silicon/pai/pai
+ var/image/screen_layer
+ var/screen_color = "#21ffff"
/obj/item/device/paicard/relaymove(var/mob/user, var/direction)
if(user.stat || user.stunned)
@@ -313,36 +315,40 @@ GLOBAL_LIST_BOILERPLATE(all_pai_cards, /obj/item/device/paicard)
/obj/item/device/paicard/proc/setPersonality(mob/living/silicon/pai/personality)
src.pai = personality
- add_overlay("pai-neutral")
+ setEmotion(1)
/obj/item/device/paicard/proc/removePersonality()
src.pai = null
cut_overlays()
- add_overlay("pai-off")
+ setEmotion(16)
/obj/item/device/paicard
var/current_emotion = 1
/obj/item/device/paicard/proc/setEmotion(var/emotion)
if(pai)
cut_overlays()
+ qdel(screen_layer)
+ screen_layer = null
switch(emotion)
- if(1) add_overlay("pai-neutral")
- if(2) add_overlay("pai-what")
- if(3) add_overlay("pai-happy")
- if(4) add_overlay("pai-cat")
- if(5) add_overlay("pai-extremely-happy")
- if(6) add_overlay("pai-face")
- if(7) add_overlay("pai-laugh")
- if(8) add_overlay("pai-sad")
- if(9) add_overlay("pai-angry")
- if(10) add_overlay("pai-silly")
- if(11) add_overlay("pai-nose")
- if(12) add_overlay("pai-smirk")
- if(13) add_overlay("pai-exclamation")
- if(14) add_overlay("pai-question")
- if(15) add_overlay("pai-blank")
- if(16) add_overlay("pai-off")
+ if(1) screen_layer = image(icon, "pai-neutral")
+ if(2) screen_layer = image(icon, "pai-what")
+ if(3) screen_layer = image(icon, "pai-happy")
+ if(4) screen_layer = image(icon, "pai-cat")
+ if(5) screen_layer = image(icon, "pai-extremely-happy")
+ if(6) screen_layer = image(icon, "pai-face")
+ if(7) screen_layer = image(icon, "pai-laugh")
+ if(8) screen_layer = image(icon, "pai-sad")
+ if(9) screen_layer = image(icon, "pai-angry")
+ if(10) screen_layer = image(icon, "pai-silly")
+ if(11) screen_layer = image(icon, "pai-nose")
+ if(12) screen_layer = image(icon, "pai-smirk")
+ if(13) screen_layer = image(icon, "pai-exclamation")
+ if(14) screen_layer = image(icon, "pai-question")
+ if(15) screen_layer = image(icon, "pai-blank")
+ if(16) screen_layer = image(icon, "pai-off")
+ screen_layer.color = pai.eye_color
+ add_overlay(screen_layer)
current_emotion = emotion
/obj/item/device/paicard/proc/alertUpdate()
diff --git a/code/modules/emotes/definitions/audible_furry_vr.dm b/code/modules/emotes/definitions/audible_furry_vr.dm
index 61d980ad27..7fc32a3986 100644
--- a/code/modules/emotes/definitions/audible_furry_vr.dm
+++ b/code/modules/emotes/definitions/audible_furry_vr.dm
@@ -34,6 +34,7 @@
key = "chirp"
emote_message_3p = "chirps!"
emote_sound = 'sound/misc/nymphchirp.ogg'
+ sound_vary = FALSE
/decl/emote/audible/hoot
key = "hoot"
emote_message_3p = "hoots!"
diff --git a/code/modules/emotes/definitions/synthetics.dm b/code/modules/emotes/definitions/synthetics.dm
index f5f94b6697..fa4937b6d1 100644
--- a/code/modules/emotes/definitions/synthetics.dm
+++ b/code/modules/emotes/definitions/synthetics.dm
@@ -56,12 +56,13 @@
emote_sound = 'sound/machines/dwoop.ogg'
/decl/emote/audible/synth/boop
- key = "boop"
+ key = "roboboop"
emote_message_1p_target = "You boop at TARGET!"
emote_message_1p = "You boop."
emote_message_3p_target = "boops at TARGET!"
emote_message_3p = "boops."
emote_sound = 'sound/voice/roboboop.ogg'
+ sound_vary = FALSE
/decl/emote/audible/synth/robochirp
key = "robochirp"
diff --git a/code/modules/emotes/emote_define.dm b/code/modules/emotes/emote_define.dm
index daff23f85d..712b5f016f 100644
--- a/code/modules/emotes/emote_define.dm
+++ b/code/modules/emotes/emote_define.dm
@@ -44,6 +44,7 @@ var/global/list/emotes_by_key
var/emote_range = 0 // If >0, restricts emote visibility to viewers within range.
var/sound_preferences = list(/datum/client_preference/emote_noises) // Default emote sound_preferences is just emote_noises. Belch emote overrides this list for pref-checks.
+ var/sound_vary = TRUE
/decl/emote/Initialize()
. = ..()
@@ -186,7 +187,7 @@ var/global/list/emotes_by_key
if(islist(sound_to_play) && length(sound_to_play))
sound_to_play = pick(sound_to_play)
if(sound_to_play)
- playsound(user.loc, sound_to_play, use_sound["vol"], 0, preference = sound_preferences) //VOREStation Add - Preference
+ playsound(user.loc, sound_to_play, use_sound["vol"], sound_vary, preference = sound_preferences) //VOREStation Add - Preference
/decl/emote/proc/mob_can_use(var/mob/user)
return istype(user) && user.stat != DEAD && (type in user.get_available_emotes())
diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm
index 9caaf03d66..4879b7460c 100644
--- a/code/modules/mob/living/silicon/pai/life.dm
+++ b/code/modules/mob/living/silicon/pai/life.dm
@@ -26,8 +26,8 @@
if(health <= 0)
death(null,"gives one shrill beep before falling lifeless.")
else if(health < maxHealth && istype(src.loc , /obj/item/device/paicard))
- adjustBruteLoss(0.5)
- adjustFireLoss(0.5)
+ adjustBruteLoss(-0.5)
+ adjustFireLoss(-0.5)
/mob/living/silicon/pai/updatehealth()
if(status_flags & GODMODE)
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 9ba6d39883..53700c4a22 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -31,7 +31,7 @@
"Cat" = "pai-cat",
"Mouse" = "pai-mouse",
"Monkey" = "pai-monkey",
- "Corgi" = "pai-borgi",
+ "Borgi" = "pai-borgi",
"Fox" = "pai-fox",
"Parrot" = "pai-parrot",
"Rabbit" = "pai-rabbit",
@@ -409,6 +409,8 @@
resting = 0
icon_state = "[chassis]"
verbs -= /mob/living/silicon/pai/proc/pai_nom //VOREStation edit. Let's remove their nom verb
+ if(isopenspace(card.loc))
+ fall()
// No binary for pAIs.
/mob/living/silicon/pai/binarycheck()
@@ -453,11 +455,11 @@
if(idaccessible == 0)
idaccessible = 1
- to_chat(src, "You allow access modifications.")
-
+ visible_message("\The [src] clicks as their access modification slot opens.","You allow access modifications.", runemessage = "click")
else
idaccessible = 0
- to_chat(src, "You block access modfications.")
+ visible_message("\The [src] clicks as their access modification slot closes.","You block access modfications.", runemessage = "click")
+
/mob/living/silicon/pai/verb/wipe_software()
set name = "Enter Storage"
diff --git a/code/modules/mob/living/silicon/pai/pai_vr.dm b/code/modules/mob/living/silicon/pai/pai_vr.dm
index df2a1f18b0..9d56b3bb0a 100644
--- a/code/modules/mob/living/silicon/pai/pai_vr.dm
+++ b/code/modules/mob/living/silicon/pai/pai_vr.dm
@@ -1,10 +1,44 @@
/mob/living/silicon/pai
var/people_eaten = 0
icon = 'icons/mob/pai_vr.dmi'
+ softfall = TRUE
+ var/eye_glow = TRUE
+ var/image/eye_layer = null // Holds the eye overlay.
+ var/eye_color = "#00ff0d"
var/global/list/wide_chassis = list(
"rat",
"panther"
)
+ var/global/list/flying_chassis = list(
+ "pai-parrot",
+ "pai-bat",
+ "pai-butterfly",
+ "pai-hawk"
+ )
+
+ //Sure I could spend all day making wacky overlays for all of the different forms
+ //but quite simply most of these sprites aren't made for that, and I'd rather just make new ones
+ //the birds especially! Just naw. If someone else wants to mess with 12x4 frames of animation where
+ //most of the pixels are different kinds of green and tastefully translate that to whitescale
+ //they can have fun with that! I not doing it!
+ var/global/list/allows_eye_color = list(
+ "pai-repairbot",
+ "pai-typezero",
+ "pai-bat",
+ "pai-butterfly",
+ "pai-mouse",
+ "pai-monkey",
+ "pai-raccoon",
+ "pai-cat",
+ "rat",
+ "panther"
+ )
+
+/mob/living/silicon/pai/Initialize()
+ . = ..()
+
+ verbs |= /mob/living/proc/hide
+ verbs |= /mob/living/proc/vertical_nom
/mob/living/silicon/pai/proc/pai_nom(var/mob/living/T in oview(1))
set name = "pAI Nom"
@@ -42,6 +76,7 @@
icon_state = "[chassis]_rest_full"
else
icon_state = "[chassis]_rest"
+ add_eyes()
/mob/living/silicon/pai/update_icons() //And other functions cause this to occur, such as digesting someone.
..()
@@ -54,6 +89,7 @@
icon_state = "[chassis]_full"
else if(people_eaten && resting)
icon_state = "[chassis]_rest_full"
+ add_eyes()
//proc override to avoid pAI players being invisible while the chassis selection window is open
/mob/living/silicon/pai/proc/choose_chassis()
@@ -64,10 +100,7 @@
choice = tgui_input_list(usr, "What would you like to use for your mobile chassis icon?", "Chassis Choice", possible_chassis)
if(!choice) return
chassis = possible_chassis[choice]
- verbs |= /mob/living/proc/hide
- if(icon != 'icons/mob/pai_vr64x64.dmi' || icon != 'icons/mob/pai_vr.dmi')
- //It's been modified to something else, so just leave it alone
- else if(chassis in wide_chassis)
+ if(chassis in wide_chassis)
icon = 'icons/mob/pai_vr64x64.dmi'
pixel_x = -16
vis_height = 64
@@ -76,8 +109,60 @@
pixel_x = 0
vis_height = 32
+ if(chassis in flying_chassis)
+ hovering = TRUE
+ else
+ hovering = FALSE
+ if(isopenspace(loc))
+ fall()
+
update_icon()
+
+/mob/living/silicon/pai/verb/toggle_eyeglow()
+ set category = "pAI Commands"
+ set name = "Toggle Eye Glow"
+ if(chassis in allows_eye_color)
+ if(eye_glow)
+ eye_glow = FALSE
+ else
+ eye_glow = TRUE
+ update_icon()
+ else
+ to_chat(src, "Your selected chassis cannot modify its eye glow!")
+ return
+
+
+/mob/living/silicon/pai/verb/pick_eye_color()
+ set category = "pAI Commands"
+ set name = "Pick Eye Color"
+ if(chassis in allows_eye_color)
+ else
+ to_chat(src, "Your selected chassis eye color can not be modified. The color you pick will only apply to supporting chassis and your card screen.")
+
+ eye_color = input(src, "Choose your character's eye color:", "Eye Color") as color|null
+ update_icon()
+ card.setEmotion(card.current_emotion)
+
// Release belly contents before being gc'd!
/mob/living/silicon/pai/Destroy()
release_vore_contents()
- return ..()
\ No newline at end of file
+ return ..()
+
+/mob/living/silicon/pai/proc/add_eyes()
+ remove_eyes()
+ if(!chassis in allows_eye_color)
+ return
+ if(!eye_layer)
+ eye_layer = image(icon, "[icon_state]-eyes")
+ eye_layer.appearance_flags = appearance_flags
+ eye_layer.color = eye_color
+ if(eye_glow)
+ eye_layer.plane = PLANE_LIGHTING_ABOVE
+ add_overlay(eye_layer)
+
+/mob/living/silicon/pai/proc/remove_eyes()
+ if(!chassis in allows_eye_color)
+ return
+ cut_overlay(eye_layer)
+ qdel(eye_layer)
+ eye_layer = null
diff --git a/icons/mob/pai_vr.dmi b/icons/mob/pai_vr.dmi
index 0b8b985ff7..dddb880816 100644
Binary files a/icons/mob/pai_vr.dmi and b/icons/mob/pai_vr.dmi differ
diff --git a/icons/mob/pai_vr64x64.dmi b/icons/mob/pai_vr64x64.dmi
index f9c99e51eb..800b6a902d 100644
Binary files a/icons/mob/pai_vr64x64.dmi and b/icons/mob/pai_vr64x64.dmi differ
diff --git a/icons/obj/paicard.dmi b/icons/obj/paicard.dmi
index 990757c465..c69ead6efd 100644
Binary files a/icons/obj/paicard.dmi and b/icons/obj/paicard.dmi differ
diff --git a/icons/obj/pda.dmi b/icons/obj/pda.dmi
index 7a94c033c1..e7e7f0859c 100644
Binary files a/icons/obj/pda.dmi and b/icons/obj/pda.dmi differ
diff --git a/sound/voice/roboboop.ogg b/sound/voice/roboboop.ogg
index cb42d0a22d..a56749a104 100644
Binary files a/sound/voice/roboboop.ogg and b/sound/voice/roboboop.ogg differ
diff --git a/sound/voice/robochirp.ogg b/sound/voice/robochirp.ogg
index 64db4c2c4c..51d534662d 100644
Binary files a/sound/voice/robochirp.ogg and b/sound/voice/robochirp.ogg differ