Merge pull request #15634 from deathride58/jukeboxrefresh

Jukebox refresh - Jukebox queue, working volume knob, emagging, preliminary multiz support, and more!
This commit is contained in:
Lin
2022-06-01 21:18:02 +00:00
committed by GitHub
20 changed files with 391 additions and 175 deletions
+2
View File
@@ -1192,6 +1192,8 @@
log_mecha(log_text)
if(LOG_SHUTTLE)
log_shuttle(log_text)
if(LOG_ECON)
log_econ(log_text)
else
stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).")
log_game(log_text)
+30
View File
@@ -312,6 +312,36 @@ Class Procs:
return TRUE // If we passed all of those checks, woohoo! We can interact with this machine.
/obj/machinery/proc/can_transact(obj/item/card/id/thecard, allowdepartment, silent)
if(!istype(thecard))
if(!silent)
say("No card found.")
return FALSE
else if (!thecard.registered_account)
if(!silent)
say("No account found.")
return FALSE
else if(!allowdepartment && !thecard.registered_account.account_job)
if(!silent)
say("Departmental accounts have been blacklisted from personal expenses due to embezzlement.")
return FALSE
return TRUE
/obj/machinery/proc/attempt_transact(obj/item/card/id/thecard, transaction_cost)
if(!istype(thecard))
return FALSE
var/datum/bank_account/account = thecard.registered_account
if(!istype(account))
return FALSE
if(transaction_cost)
if(!account.adjust_money(-transaction_cost))
return FALSE
var/datum/bank_account/D = SSeconomy.get_dep_account(payment_department)
if(D)
D.adjust_money(transaction_cost)
return TRUE
/obj/machinery/proc/check_nap_violations()
if(!SSeconomy.full_ancap)
return TRUE
+103 -41
View File
@@ -6,17 +6,22 @@
verb_say = "states"
density = TRUE
req_one_access = list(ACCESS_BAR, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_ENGINE, ACCESS_CARGO, ACCESS_THEATRE)
payment_department = ACCOUNT_SRV
var/active = FALSE
var/list/rangers = list()
var/stop = 0
var/volume = 70
var/datum/track/selection = null
var/queuecost = PRICE_CHEAP //Set to -1 to make this jukebox require access for queueing
var/datum/track/playing = null
var/datum/track/selectedtrack = null
var/list/queuedplaylist = list()
var/queuecooldown //This var exists solely to prevent accidental repeats of John Mulaney's 'What's New Pussycat?' incident. Intentional, however......
/obj/machinery/jukebox/disco
name = "radiant dance machine mark IV"
desc = "The first three prototypes were discontinued after mass casualty incidents."
icon_state = "disco"
req_access = list(ACCESS_ENGINE)
req_one_access = list(ACCESS_ENGINE)
anchored = FALSE
var/list/spotlights = list()
var/list/sparkles = list()
@@ -24,7 +29,7 @@
/obj/machinery/jukebox/disco/indestructible
name = "radiant dance machine mark V"
desc = "Now redesigned with data gathered from the extensive disco and plasma research."
req_access = null
req_one_access = null
anchored = TRUE
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
flags_1 = NODECONSTRUCT_1
@@ -46,6 +51,16 @@
return
return ..()
/obj/machinery/jukebox/emag_act(mob/user)
. = ..()
if(obj_flags & EMAGGED)
return
obj_flags |= EMAGGED
queuecost = PRICE_FREE
req_one_access = null
to_chat(user, "<span class='notice'>You've bypassed [src]'s audio volume limiter, and enabled free play.</span>")
return TRUE
/obj/machinery/jukebox/update_icon_state()
if(active)
icon_state = "[initial(icon_state)]-active"
@@ -56,7 +71,7 @@
if(!anchored)
to_chat(user,"<span class='warning'>This device must be anchored by a wrench!</span>")
return UI_CLOSE
if(!allowed(user) && !isobserver(user))
if((queuecost < 0 && !allowed(user)) && !isobserver(user))
to_chat(user,"<span class='warning'>Error: Access Denied.</span>")
user.playsound_local(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
return UI_CLOSE
@@ -77,18 +92,21 @@
data["active"] = active
data["songs"] = list()
for(var/datum/track/S in SSjukeboxes.songs)
var/list/track_data = list(
name = S.song_name
)
var/list/track_data = list(name = S.song_name)
data["songs"] += list(track_data)
data["queued_tracks"] = list()
for(var/datum/track/S in queuedplaylist)
var/list/track_data = list(name = S.song_name)
data["queued_tracks"] += list(track_data)
data["track_selected"] = null
data["track_length"] = null
data["track_beat"] = null
if(selection)
data["track_selected"] = selection.song_name
data["track_length"] = DisplayTimeText(selection.song_length)
data["track_beat"] = selection.song_beat
if(playing)
data["track_selected"] = playing.song_name
data["track_length"] = DisplayTimeText(playing.song_length)
data["volume"] = volume
data["is_emagged"] = (obj_flags & EMAGGED)
data["cost_for_play"] = queuecost
data["has_access"] = allowed(user)
return data
/obj/machinery/jukebox/ui_act(action, list/params)
@@ -100,57 +118,91 @@
if("toggle")
if(QDELETED(src))
return
if(!active)
if(stop > world.time)
to_chat(usr, "<span class='warning'>Error: The device is still resetting from the last activation, it will be ready again in [DisplayTimeText(stop-world.time)].</span>")
playsound(src, 'sound/misc/compiler-failure.ogg', 50, TRUE)
return
if(!allowed(usr))
return
if(!active && !playing)
activate_music()
START_PROCESSING(SSobj, src)
return TRUE
else
stop = 0
return TRUE
if("select_track")
if(active)
to_chat(usr, "<span class='warning'>Error: You cannot change the song until the current one is over.</span>")
return TRUE
if("add_to_queue")
if(QDELETED(src))
return
if(world.time < queuecooldown)
return
if(!istype(selectedtrack, /datum/track))
return
if(!allowed(usr) && queuecost)
var/obj/item/card/id/C
if(isliving(usr))
var/mob/living/L = usr
C = L.get_idcard(TRUE)
if(!can_transact(C))
queuecooldown = world.time + (1 SECONDS)
playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
return
if(!attempt_transact(C, queuecost))
say("Insufficient funds.")
queuecooldown = world.time + (1 SECONDS)
playsound(src, 'sound/misc/compiler-failure.ogg', 25, TRUE)
return
to_chat(usr, "<span class='notice'>You spend [queuecost] credits to queue [selectedtrack.song_name].</span>")
log_econ("[queuecost] credits were inserted into [src] by [key_name(usr)] (ID: [C.registered_name]) to queue [selectedtrack.song_name].")
queuedplaylist += selectedtrack
if(active)
say("[selectedtrack.song_name] has been added to the queue.")
else if(!playing)
activate_music()
playsound(src, 'sound/machines/ping.ogg', 50, TRUE)
queuecooldown = world.time + (3 SECONDS)
return TRUE
if("select_track")
var/list/available = list()
for(var/datum/track/S in SSjukeboxes.songs)
available[S.song_name] = S
var/selected = params["track"]
if(QDELETED(src) || !selected || !istype(available[selected], /datum/track))
return
selection = available[selected]
selectedtrack = available[selected]
return TRUE
if("set_volume")
if(!allowed(usr))
return
var/new_volume = params["volume"]
if(new_volume == "reset")
volume = initial(volume)
return TRUE
else if(new_volume == "min")
volume = 0
return TRUE
else if(new_volume == "max")
volume = 100
return TRUE
volume = ((obj_flags & EMAGGED) ? 210 : 100)
else if(text2num(new_volume) != null)
volume = text2num(new_volume)
return TRUE
volume = clamp(0, text2num(new_volume), ((obj_flags & EMAGGED) ? 210 : 100))
var/wherejuke = SSjukeboxes.findjukeboxindex(src)
if(wherejuke)
SSjukeboxes.updatejukebox(wherejuke, jukefalloff = volume/35)
return TRUE
/obj/machinery/jukebox/proc/activate_music()
var/jukeboxslottotake = SSjukeboxes.addjukebox(src, selection, 2)
if(playing || !queuedplaylist.len)
return FALSE
playing = queuedplaylist[1]
var/jukeboxslottotake = SSjukeboxes.addjukebox(src, playing, volume/35)
if(jukeboxslottotake)
active = TRUE
update_icon()
START_PROCESSING(SSobj, src)
stop = world.time + selection.song_length
stop = world.time + playing.song_length
queuedplaylist.Cut(1, 2)
say("Now playing: [playing.song_name]")
playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, TRUE)
return TRUE
else
return FALSE
/obj/machinery/jukebox/disco/activate_music()
..()
. = ..()
if(!.)
return
dance_setup()
lights_spin()
@@ -243,7 +295,7 @@
S.pixel_y = 7
S.forceMove(get_turf(src))
sleep(7)
if(selection.song_name == "Engineering's Ultimate High-Energy Hustle")
if(playing.song_name == "Engineering's Ultimate High-Energy Hustle")
sleep(280)
for(var/obj/reveal in sparkles)
reveal.alpha = 255
@@ -299,7 +351,7 @@
continue
if(prob(2)) // Unique effects for the dance floor that show up randomly to mix things up
INVOKE_ASYNC(src, .proc/hierofunk)
sleep(selection.song_beat)
sleep(playing.song_beat)
#undef DISCO_INFENO_RANGE
@@ -431,6 +483,7 @@
return
SSjukeboxes.removejukebox(position)
STOP_PROCESSING(SSobj, src)
playing = null
rangers = list()
/obj/machinery/jukebox/disco/dance_over()
@@ -439,12 +492,21 @@
QDEL_LIST(sparkles)
/obj/machinery/jukebox/process()
if(active && world.time >= stop)
active = FALSE
dance_over()
playsound(src,'sound/machines/terminal_off.ogg',50,1)
update_icon()
stop = world.time + 100
if(active)
if(world.time >= stop)
active = FALSE
dance_over()
if(stop && queuedplaylist.len)
activate_music()
else
playsound(src,'sound/machines/terminal_off.ogg',50,1)
update_icon()
playing = null
stop = 0
else if(volume > 140) // BOOM BOOM BOOM BOOM
for(var/mob/living/carbon/C in hearers(round(volume/35), src)) // I WANT YOU IN MY ROOM
if(istype(C)) // LETS SPEND THE NIGHT TOGETHER
C.adjustEarDamage(max((((volume/35) - sqrt(get_dist(C, src) * 4)) - C.get_ear_protection())*0.1, 0)) // FROM NOW UNTIL FOREVER
/obj/machinery/jukebox/disco/process()
+5 -2
View File
@@ -111,12 +111,15 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
/mob/proc/playsound_local(turf/turf_source, soundin, vol as num, vary, frequency, falloff_exponent = SOUND_FALLOFF_EXPONENT, channel = 0, pressure_affected = TRUE, sound/S, max_distance,
falloff_distance = SOUND_DEFAULT_FALLOFF_DISTANCE, distance_multiplier = SOUND_DEFAULT_DISTANCE_MULTIPLIER, envwet = -10000, envdry = 0)
if(!client || !can_hear())
if(!client)
return
if(!S)
S = sound(get_sfx(soundin))
if(!can_hear() && !(S.status & SOUND_UPDATE)) //This is primarily to make sure sound updates still go through when a spaceman's deaf
return
S.wait = 0 //No queue
S.channel = channel || SSsounds.random_available_channel()
S.volume = vol
@@ -173,7 +176,7 @@ distance_multiplier - Can be used to multiply the distance at which the sound is
var/dz = turf_source.y - T.y // Hearing from infront/behind
S.z = dz * distance_multiplier
var/dy = (turf_source.z - T.z) * 5 * distance_multiplier // Hearing from above / below, multiplied by 5 because we assume height is further along coords.
S.y = dy + 1
S.y = dy + distance_multiplier
S.falloff = isnull(max_distance)? FALLOFF_SOUNDS : max_distance //use max_distance, else just use 1 as we are a direct sound so falloff isnt relevant.
+1
View File
@@ -117,6 +117,7 @@ GLOBAL_LIST(topic_status_cache)
GLOB.world_asset_log = "[GLOB.log_directory]/asset.log"
GLOB.world_attack_log = "[GLOB.log_directory]/attack.log"
GLOB.world_victim_log = "[GLOB.log_directory]/victim.log"
GLOB.world_econ_log = "[GLOB.log_directory]/econ.log"
GLOB.world_pda_log = "[GLOB.log_directory]/pda.log"
GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log"
GLOB.world_manifest_log = "[GLOB.log_directory]/manifest.log"