|
|
|
@@ -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,89 @@
|
|
|
|
|
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!")
|
|
|
|
|
playsound(src, 'sound/machines/ping.ogg', 50, TRUE)
|
|
|
|
|
else if(!playing)
|
|
|
|
|
activate_music()
|
|
|
|
|
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)
|
|
|
|
|
return TRUE
|
|
|
|
|
else
|
|
|
|
|
return FALSE
|
|
|
|
|
|
|
|
|
|
/obj/machinery/jukebox/disco/activate_music()
|
|
|
|
|
..()
|
|
|
|
|
. = ..()
|
|
|
|
|
if(!.)
|
|
|
|
|
return
|
|
|
|
|
dance_setup()
|
|
|
|
|
lights_spin()
|
|
|
|
|
|
|
|
|
@@ -243,7 +293,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 +349,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 +481,7 @@
|
|
|
|
|
return
|
|
|
|
|
SSjukeboxes.removejukebox(position)
|
|
|
|
|
STOP_PROCESSING(SSobj, src)
|
|
|
|
|
playing = null
|
|
|
|
|
rangers = list()
|
|
|
|
|
|
|
|
|
|
/obj/machinery/jukebox/disco/dance_over()
|
|
|
|
@@ -442,9 +493,13 @@
|
|
|
|
|
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(stop && queuedplaylist.len)
|
|
|
|
|
activate_music()
|
|
|
|
|
else
|
|
|
|
|
playsound(src,'sound/machines/terminal_off.ogg',50,1)
|
|
|
|
|
update_icon()
|
|
|
|
|
playing = null
|
|
|
|
|
stop = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/obj/machinery/jukebox/disco/process()
|
|
|
|
|