Files
7d058fc613 Jukebox TGUI update, Earphones autoplay, sound keys refactor (#21630)
V2 of [previous music playing
PR](https://github.com/Aurorastation/Aurora.3/pull/21466). TLDR no
longer uses the connect_range component for implementation because it
turned out a bit too inflexible for overlapping music players.

Removes a NanoUI template for the [TGUI
update](https://github.com/Aurorastation/Aurora.3/pull/21046).

New changelog:
  - refactor: "Ported Jukebox's NanoUI interface to TGUI."
- refactor: "Ported Jukebox audio playing functionality to a component."
- refactor: "Sound keys refactored from singletons to datums, along with
larger breakout of sound.dm to allow for easier SFX updates in future."
  - code_imp: "Expanded track datums to include track lengths."
- code_imp: "Reorganized music file folders for more intuitive access."
  - rscadd: "Earphone status feedback text now includes track length."
  - rscadd: "Added autoplay functionality to earphones."
- bugfix: "Fixed earphones' 'Previous Song' verb not sending you to the
end of the playlist when used while the first track is selected."
- bugfix: "Fixed gain adjustment for 'Konyang-1' (-23 dB -> standard
-9.8 dB)."
- bugfix: "Fixed y-offset of audioconsole-running overlay animation to
line up with the actual screen."

---------

Co-authored-by: VMSolidus <evilexecutive@gmail.com>
2026-01-22 16:54:40 +00:00

74 lines
3.3 KiB
Plaintext

ABSTRACT_TYPE(/singleton/overhead_emote)
var/icon = 'icons/mob/overhead_emote.dmi'
var/icon_state = "abstract"
var/emote_description = "abstract"
var/emote_sound
/singleton/overhead_emote/proc/get_image(var/mob/target)
var/image/image = image(icon, icon_state)
image.pixel_y = 18 + target.get_floating_chat_y_offset()
image.pixel_x = target.get_floating_chat_x_offset()
image.plane = ABOVE_GAME_PLANE
return image
/singleton/overhead_emote/proc/start_emote(var/mob/parent, var/mob/victim)
var/others_message
if(victim)
others_message = "<b>[parent]</b> lifts their hand to [emote_description] [victim]!"
else
others_message = "<b>[parent]</b> lifts their hand for a [emote_description]!"
var/self_message
if(victim)
self_message = SPAN_NOTICE("You lift your hand to [emote_description] [victim]!")
else
self_message = SPAN_NOTICE("You lift your hand for a [emote_description]!")
parent.visible_message(others_message, self_message)
/singleton/overhead_emote/proc/reciprocate_emote(var/mob/reciprocator, var/mob/original, var/reciprocating_emote_path)
var/datum/component/overhead_emote/original_emote_component = original.GetComponent(/datum/component/overhead_emote)
var/singleton/overhead_emote/original_emote = original_emote_component.emote_type
if(original_emote.type != reciprocating_emote_path)
fail_emote(reciprocator, original, original_emote_component, original_emote, reciprocating_emote_path)
return
var/others_message = "<b>[reciprocator]</b> lifts their to meet [original]'s, delivering a stunning [emote_description]!"
var/self_message = SPAN_NOTICE("You lift your hand to meet [original]'s, delivering a stunning [emote_description]!")
reciprocator.visible_message(others_message, self_message)
INVOKE_ASYNC(reciprocator, TYPE_PROC_REF(/atom/movable, do_attack_animation), original, FIST_ATTACK_ANIMATION)
INVOKE_ASYNC(original, TYPE_PROC_REF(/atom/movable, do_attack_animation), reciprocator, FIST_ATTACK_ANIMATION)
if(emote_sound)
playsound(reciprocator.loc, emote_sound, 30, 1)
original_emote_component.remove_from_mob()
/singleton/overhead_emote/proc/fail_emote(var/mob/reciprocator, var/mob/original, var/datum/component/overhead_emote/original_emote_component, var/singleton/overhead_emote/original_emote, var/fail_emote_path)
var/singleton/overhead_emote/fail_emote = GET_SINGLETON(fail_emote_path)
var/others_message = "<b>[reciprocator]</b> lifts their to meet [original]'s, who was expecting a [original_emote.emote_description], but received a [fail_emote.emote_description] instead."
var/self_message = SPAN_NOTICE("You lift your hand to meet [original]'s, who was expecting a [original_emote.emote_description], but received a [fail_emote.emote_description] instead.")
reciprocator.visible_message(others_message, self_message)
INVOKE_ASYNC(reciprocator, TYPE_PROC_REF(/atom/movable, do_attack_animation), original, FIST_ATTACK_ANIMATION)
INVOKE_ASYNC(original, TYPE_PROC_REF(/atom/movable, do_attack_animation), reciprocator, FIST_ATTACK_ANIMATION)
playsound(reciprocator.loc, SFX_PUNCH_MISS, 30, 1)
original_emote_component.remove_from_mob()
/singleton/overhead_emote/highfive
icon_state = "emote_highfive"
emote_description = "high-five"
emote_sound = 'sound/effects/snap.ogg'
/singleton/overhead_emote/fistbump
icon_state = "emote_fistbump"
emote_description = "fist-bump"
emote_sound = 'sound/weapons/Genhit.ogg'