diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 97049254cc1..3d962eacf3b 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -789,3 +789,6 @@
///called when an elzu should unroot
#define COMSIG_DIGOUT "dig_out"
+
+///sent when the access on an id is changed/updated, ensures wallets get updated once ids generate there access
+#define COSMIG_ACCESS_UPDATED "acces_updated"
\ No newline at end of file
diff --git a/code/game/objects/effects/contraband.dm b/code/game/objects/effects/contraband.dm
index 372df8dc910..f9d098d24fa 100644
--- a/code/game/objects/effects/contraband.dm
+++ b/code/game/objects/effects/contraband.dm
@@ -386,7 +386,7 @@
icon_state = "poster_dday" // human sprite by quin
/obj/structure/sign/poster/contraband/roseusfilm1
- name = "D-Day Promo"
+ name = "The Last One Out
desc = "A movie poster for The Last One Out, a movie about how a cruise ship captain helped evacuate a research facility being attacked by its corporate overlords after being falsely accused of trying to revolt. One of Roseus Galactic's more popular films during the ICW."
icon_state = "poster-roseus-thelastoneout" //edited dday promo sprite!
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index ae7aa27cdc3..fb79cc447ab 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -165,6 +165,7 @@
. = ..()
if(mapload && access_txt)
access = text2access(access_txt)
+ SEND_SIGNAL(src, COSMIG_ACCESS_UPDATED)
update_label()
update_appearance()
RegisterSignal(src, COMSIG_ATOM_UPDATED_ICON, PROC_REF(update_in_wallet))
@@ -259,11 +260,13 @@
/obj/item/card/id/proc/add_ship_access(datum/overmap/ship/controlled/ship)
if (ship)
ship_access += ship
+ SEND_SIGNAL(src, COSMIG_ACCESS_UPDATED)
// Removes the referenced ship from the card
/obj/item/card/id/proc/remove_ship_access(datum/overmap/ship/controlled/ship)
if (ship)
ship_access -= ship
+ SEND_SIGNAL(src, COSMIG_ACCESS_UPDATED)
// Finds the referenced ship in the list
/obj/item/card/id/proc/has_ship_access(datum/overmap/ship/controlled/ship)
diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm
index c031e998cdc..002b7263329 100644
--- a/code/game/objects/items/storage/wallets.dm
+++ b/code/game/objects/items/storage/wallets.dm
@@ -42,9 +42,10 @@
/obj/item/storage/wallet/Exited(atom/movable/AM)
. = ..()
- refreshID()
+ UnregisterSignal(AM, COSMIG_ACCESS_UPDATED)
+ refresh_id()
-/obj/item/storage/wallet/proc/refreshID()
+/obj/item/storage/wallet/proc/refresh_id()
LAZYCLEARLIST(combined_access)
if(!(front_id in src))
front_id = null
@@ -61,7 +62,8 @@
/obj/item/storage/wallet/Entered(atom/movable/AM)
. = ..()
- refreshID()
+ RegisterSignal(AM, COSMIG_ACCESS_UPDATED, PROC_REF(refresh_id))
+ refresh_id()
/obj/item/storage/wallet/update_overlays()
. = ..()
diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm
index 122cb7ce28b..39eb0874987 100644
--- a/code/modules/jobs/access.dm
+++ b/code/modules/jobs/access.dm
@@ -117,10 +117,11 @@
if (gen_ship_access(ship))
return TRUE
- if(istype(item, /obj/item/card/id))
- var/obj/item/card/id/id = item.GetID()
- if (id.has_ship_access(ship))
- return TRUE
+ if(!item)
+ return FALSE
+ var/obj/item/card/id/id = item?.GetID()
+ if (id?.has_ship_access(ship))
+ return TRUE
return FALSE
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index f850eded96d..ee953b0fb74 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -273,6 +273,7 @@
var/obj/item/card/id/C = H.get_idcard(TRUE)
if(istype(C))
C.access = J.get_access()
+ SEND_SIGNAL(C, COSMIG_ACCESS_UPDATED)
shuffle_inplace(C.access) // Shuffle access list to make NTNet passkeys less predictable
C.registered_name = H.real_name
if(H.job)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 56ae0db795e..f4042464f98 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -232,6 +232,16 @@
message = "jumps!"
hands_use_check = TRUE
+/datum/emote/living/jump/run_emote(mob/living/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return FALSE
+ animate(user, pixel_y = user.pixel_y + 4, time = 0.1 SECONDS)
+ animate(pixel_y = user.pixel_y - 4, time = 0.1 SECONDS)
+
+/datum/emote/living/jump/get_sound(mob/living/user)
+ return 'sound/weapons/thudswoosh.ogg'
+
/datum/emote/living/kiss
key = "kiss"
key_third_person = "kisses"
@@ -361,6 +371,18 @@
message = "shivers."
emote_type = EMOTE_AUDIBLE
+#define SHIVER_LOOP_DURATION (1 SECONDS)
+/datum/emote/living/shiver/run_emote(mob/living/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return FALSE
+ animate(user, pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
+ for(var/i in 1 to SHIVER_LOOP_DURATION / (0.2 SECONDS)) //desired total duration divided by the iteration duration to give the necessary iteration count
+ animate(pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
+#undef SHIVER_LOOP_DURATION
+
/datum/emote/living/sigh
key = "sigh"
key_third_person = "sighs"
@@ -460,20 +482,62 @@
key_third_person = "sways"
message = "sways around dizzily."
+/datum/emote/living/sway/run_emote(mob/living/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return FALSE
+ animate(user, pixel_x = user.pixel_x + 2, time = 0.5 SECONDS)
+ for(var/i in 1 to 2)
+ animate(pixel_x = user.pixel_x - 4, time = 1.0 SECONDS)
+ animate(pixel_x = user.pixel_x + 4, time = 1.0 SECONDS)
+ animate(pixel_x = user.pixel_x - 2, time = 0.5 SECONDS)
+
/datum/emote/living/tremble
key = "tremble"
key_third_person = "trembles"
message = "trembles in fear!"
+#define TREMBLE_LOOP_DURATION (4.4 SECONDS)
+/datum/emote/living/tremble/run_emote(mob/living/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return FALSE
+ animate(user, pixel_x = user.pixel_x + 2, time = 0.2 SECONDS)
+ for(var/i in 1 to TREMBLE_LOOP_DURATION / (0.4 SECONDS)) //desired total duration divided by the iteration duration to give the necessary iteration count
+ animate(pixel_x = user.pixel_x - 2, time = 0.2 SECONDS)
+ animate(pixel_x = user.pixel_x + 2, time = 0.2 SECONDS)
+ animate(pixel_x = user.pixel_x - 2, time = 0.2 SECONDS)
+#undef TREMBLE_LOOP_DURATION
+
/datum/emote/living/twitch
key = "twitch"
key_third_person = "twitches"
message = "twitches violently."
+/datum/emote/living/twitch/run_emote(mob/living/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return FALSE
+ animate(user, pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
+ animate(time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
+
/datum/emote/living/twitch_s
key = "twitch_s"
message = "twitches."
+/datum/emote/living/twitch_s/run_emote(mob/living/user, params, type_override, intentional)
+ . = ..()
+ if(!.)
+ return FALSE
+ animate(user, pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
+ animate(time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x - 1, time = 0.1 SECONDS)
+ animate(pixel_x = user.pixel_x + 1, time = 0.1 SECONDS)
+
/datum/emote/living/wave
key = "wave"
key_third_person = "waves"
@@ -603,3 +667,85 @@
key_third_person = "clacks"
message = "clacks their beak."
emote_type = EMOTE_VISIBLE
+
+/datum/emote/living/tilt
+ key = "tilt"
+ key_third_person = "tilts"
+ message = "tilts their head to the side."
+
+/datum/emote/living/carbon/snap
+ key = "snap"
+ key_third_person = "snaps"
+ message = "snaps their fingers."
+ message_param = "snaps their fingers at %t."
+ emote_type = EMOTE_AUDIBLE
+ hands_use_check = TRUE
+ muzzle_ignore = TRUE
+
+/datum/emote/living/carbon/snap/get_sound(mob/living/user)
+ if(ishuman(user))
+ if(!user.get_bodypart(BODY_ZONE_L_ARM) || !user.get_bodypart(BODY_ZONE_R_ARM))
+ return
+ else
+ return pick('sound/misc/fingersnap1.ogg',
+ 'sound/misc/fingersnap2.ogg')
+
+/datum/emote/living/snap2
+ key = "snap2"
+ key_third_person = "snaps twice"
+ message = "snaps twice."
+ message_param = "snaps twice at %t."
+ emote_type = EMOTE_AUDIBLE
+ muzzle_ignore = TRUE
+ hands_use_check = TRUE
+ vary = TRUE
+ sound = 'sound/misc/snap2.ogg'
+
+/datum/emote/living/snap3
+ key = "snap3"
+ key_third_person = "snaps thrice"
+ message = "snaps thrice."
+ message_param = "snaps thrice at %t."
+ emote_type = EMOTE_AUDIBLE
+ muzzle_ignore = TRUE
+ hands_use_check = TRUE
+ vary = TRUE
+ sound = 'sound/misc/snap3.ogg'
+
+/datum/emote/living/carbon/clap
+ key = "clap"
+ key_third_person = "claps"
+ message = "claps."
+ muzzle_ignore = TRUE
+ hands_use_check = TRUE
+ emote_type = EMOTE_AUDIBLE
+ vary = TRUE
+
+/datum/emote/living/carbon/clap/get_sound(mob/living/user)
+ if(ishuman(user))
+ if(!user.get_bodypart(BODY_ZONE_L_ARM) || !user.get_bodypart(BODY_ZONE_R_ARM))
+ return
+ else
+ return pick('sound/misc/clap1.ogg',
+ 'sound/misc/clap2.ogg',
+ 'sound/misc/clap3.ogg',
+ 'sound/misc/clap4.ogg')
+
+/datum/emote/living/clap1
+ key = "clap1"
+ key_third_person = "claps once"
+ message = "claps once."
+ emote_type = EMOTE_AUDIBLE
+ muzzle_ignore = TRUE
+ hands_use_check = TRUE
+ vary = TRUE
+ mob_type_allowed_typecache = list(/mob/living/carbon, /mob/living/silicon/pai)
+
+/datum/emote/living/clap1/get_sound(mob/living/user)
+ return pick('sound/misc/claponce1.ogg',
+ 'sound/misc/claponce2.ogg')
+
+/datum/emote/living/clap1/can_run_emote(mob/living/carbon/user, status_check = TRUE , intentional)
+ if(user.usable_hands < 2)
+ return FALSE
+ return ..()
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 269c74a837b..7ffe22bbf1b 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -482,7 +482,9 @@
if(!silent)
to_chat(src, "You will now lay down as soon as you are able to.")
else
- if(!silent)
+ if(!silent && m_intent == MOVE_INTENT_WALK)
+ to_chat(src, "You gently lay down.")
+ else if(!silent)
to_chat(src, "You lay down.")
set_lying_down()
else
diff --git a/icons/obj/radio.dmi b/icons/obj/radio.dmi
index d3d1bb2298c..bfd0da6cd2b 100644
Binary files a/icons/obj/radio.dmi and b/icons/obj/radio.dmi differ
diff --git a/sound/effects/Nose_boop.ogg b/sound/effects/Nose_boop.ogg
new file mode 100644
index 00000000000..6a742e95eac
Binary files /dev/null and b/sound/effects/Nose_boop.ogg differ
diff --git a/sound/effects/boop.ogg b/sound/effects/boop.ogg
new file mode 100644
index 00000000000..482a2a8ecda
Binary files /dev/null and b/sound/effects/boop.ogg differ
diff --git a/sound/misc/claponce1.ogg b/sound/misc/claponce1.ogg
new file mode 100644
index 00000000000..1e12d0daa3b
Binary files /dev/null and b/sound/misc/claponce1.ogg differ
diff --git a/sound/misc/claponce2.ogg b/sound/misc/claponce2.ogg
new file mode 100644
index 00000000000..10dfdba121b
Binary files /dev/null and b/sound/misc/claponce2.ogg differ
diff --git a/sound/misc/fingersnap1.ogg b/sound/misc/fingersnap1.ogg
new file mode 100644
index 00000000000..2d5d255be1c
Binary files /dev/null and b/sound/misc/fingersnap1.ogg differ
diff --git a/sound/misc/fingersnap2.ogg b/sound/misc/fingersnap2.ogg
new file mode 100644
index 00000000000..d11f2f7a741
Binary files /dev/null and b/sound/misc/fingersnap2.ogg differ
diff --git a/sound/misc/snap2.ogg b/sound/misc/snap2.ogg
new file mode 100644
index 00000000000..1537084be43
Binary files /dev/null and b/sound/misc/snap2.ogg differ
diff --git a/sound/misc/snap3.ogg b/sound/misc/snap3.ogg
new file mode 100644
index 00000000000..ca7506dc2c3
Binary files /dev/null and b/sound/misc/snap3.ogg differ