mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-08-23 05:06:50 +01:00
NB. In some cases we go from a more complex image() to a single icon_state string and I assume this works for every case but do not care to check because of the sheer scale of extra fiddly effort. Buyer beware, not my code.
276 lines
7.4 KiB
Plaintext
276 lines
7.4 KiB
Plaintext
/obj/machinery/media/jukebox/
|
|
name = "space jukebox"
|
|
desc = "Filled with songs both past and present!"
|
|
icon = 'icons/obj/jukebox.dmi'
|
|
icon_state = "jukebox-nopower"
|
|
var/state_base = "jukebox"
|
|
anchored = 1
|
|
density = 1
|
|
power_channel = EQUIP
|
|
use_power = USE_POWER_IDLE
|
|
idle_power_usage = 10
|
|
active_power_usage = 100
|
|
circuit = /obj/item/circuitboard/jukebox
|
|
clicksound = 'sound/machines/buttonbeep.ogg'
|
|
|
|
var/playing = 0
|
|
|
|
// Vars for hacking
|
|
var/datum/wires/jukebox/wires = null
|
|
var/hacked = 0 // Whether to show the hidden songs or not
|
|
var/freq = 0
|
|
|
|
var/datum/track/current_track
|
|
var/list/datum/track/tracks
|
|
|
|
// Only visible if hacked
|
|
var/list/datum/track/secret_tracks
|
|
|
|
/obj/machinery/media/jukebox/Initialize()
|
|
. = ..()
|
|
default_apply_parts()
|
|
wires = new/datum/wires/jukebox(src)
|
|
tracks = setup_music_tracks(tracks)
|
|
secret_tracks = setup_secret_music_tracks(secret_tracks)
|
|
update_icon()
|
|
|
|
/obj/machinery/media/jukebox/Destroy()
|
|
StopPlaying()
|
|
qdel(wires)
|
|
QDEL_NULL_LIST(tracks)
|
|
current_track = null
|
|
wires = null
|
|
return ..()
|
|
|
|
/obj/machinery/media/jukebox/proc/set_hacked(var/newhacked)
|
|
if (hacked == newhacked) return
|
|
hacked = newhacked
|
|
if (hacked)
|
|
tracks.Add(secret_tracks)
|
|
else
|
|
tracks.Remove(secret_tracks)
|
|
updateDialog()
|
|
|
|
/obj/machinery/media/jukebox/attackby(obj/item/W as obj, mob/user as mob)
|
|
src.add_fingerprint(user)
|
|
|
|
if(default_deconstruction_screwdriver(user, W))
|
|
return
|
|
if(default_deconstruction_crowbar(user, W))
|
|
return
|
|
if(W.is_wirecutter())
|
|
return wires.Interact(user)
|
|
if(istype(W, /obj/item/multitool))
|
|
return wires.Interact(user)
|
|
if(W.is_wrench())
|
|
if(playing)
|
|
StopPlaying()
|
|
user.visible_message("<span class='warning'>[user] has [anchored ? "un" : ""]secured \the [src].</span>", "<span class='notice'>You [anchored ? "un" : ""]secure \the [src].</span>")
|
|
anchored = !anchored
|
|
playsound(src, W.usesound, 50, 1)
|
|
power_change()
|
|
update_icon()
|
|
return
|
|
return ..()
|
|
|
|
/obj/machinery/media/jukebox/power_change()
|
|
if(!powered(power_channel) || !anchored)
|
|
stat |= NOPOWER
|
|
else
|
|
stat &= ~NOPOWER
|
|
|
|
if(stat & (NOPOWER|BROKEN) && playing)
|
|
StopPlaying()
|
|
update_icon()
|
|
|
|
/obj/machinery/media/jukebox/update_icon()
|
|
cut_overlays()
|
|
if(stat & (NOPOWER|BROKEN) || !anchored)
|
|
if(stat & BROKEN)
|
|
icon_state = "[state_base]-broken"
|
|
else
|
|
icon_state = "[state_base]-nopower"
|
|
return
|
|
icon_state = state_base
|
|
if(playing)
|
|
if(emagged)
|
|
add_overlay("[state_base]-emagged")
|
|
else
|
|
add_overlay("[state_base]-running")
|
|
if (panel_open)
|
|
add_overlay("panel_open")
|
|
|
|
/obj/machinery/media/jukebox/Topic(href, href_list)
|
|
if(..() || !(Adjacent(usr) || istype(usr, /mob/living/silicon)))
|
|
return
|
|
|
|
if(!anchored)
|
|
to_chat(usr, "<span class='warning'>You must secure \the [src] first.</span>")
|
|
return
|
|
|
|
if(stat & (NOPOWER|BROKEN))
|
|
to_chat(usr, "\The [src] doesn't appear to function.")
|
|
return
|
|
|
|
if(href_list["change_track"])
|
|
for(var/datum/track/T in tracks)
|
|
if(T.title == href_list["title"])
|
|
current_track = T
|
|
StartPlaying()
|
|
break
|
|
else if(href_list["stop"])
|
|
StopPlaying()
|
|
else if(href_list["play"])
|
|
if(emagged)
|
|
playsound(src, 'sound/items/AirHorn.ogg', 100, 1)
|
|
for(var/mob/living/carbon/M in ohearers(6, src))
|
|
if(M.get_sound_volume_multiplier() < 0.2)
|
|
continue
|
|
M.SetSleeping(0)
|
|
M.stuttering += 20
|
|
M.ear_deaf += 30
|
|
M.Weaken(3)
|
|
if(prob(30))
|
|
M.Stun(10)
|
|
M.Paralyse(4)
|
|
else
|
|
M.make_jittery(500)
|
|
spawn(15)
|
|
explode()
|
|
else if(current_track == null)
|
|
to_chat(usr, "No track selected.")
|
|
else
|
|
StartPlaying()
|
|
|
|
return 1
|
|
|
|
/obj/machinery/media/jukebox/interact(mob/user)
|
|
if(stat & (NOPOWER|BROKEN))
|
|
to_chat(usr, "\The [src] doesn't appear to function.")
|
|
return
|
|
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/media/jukebox/ui_interact(mob/user, ui_key = "jukebox", var/datum/nanoui/ui = null, var/force_open = 1)
|
|
var/title = "RetroBox - Space Style"
|
|
var/data[0]
|
|
|
|
if(!(stat & (NOPOWER|BROKEN)))
|
|
data["current_track"] = current_track != null ? current_track.title : ""
|
|
data["playing"] = playing
|
|
|
|
var/list/nano_tracks = new
|
|
for(var/datum/track/T in tracks)
|
|
nano_tracks[++nano_tracks.len] = list("track" = T.title)
|
|
|
|
data["tracks"] = nano_tracks
|
|
|
|
// update the ui if it exists, returns null if no ui is passed/found
|
|
ui = SSnanoui.try_update_ui(user, src, ui_key, ui, data, force_open)
|
|
if (!ui)
|
|
// the ui does not exist, so we'll create a new() one
|
|
// for a list of parameters and their descriptions see the code docs in \code\modules\nano\nanoui.dm
|
|
ui = new(user, src, ui_key, "jukebox.tmpl", title, 450, 600)
|
|
// when the ui is first opened this is the data it will use
|
|
ui.set_initial_data(data)
|
|
// open the new ui window
|
|
ui.open()
|
|
|
|
/obj/machinery/media/jukebox/attack_ai(mob/user as mob)
|
|
return src.attack_hand(user)
|
|
|
|
/obj/machinery/media/jukebox/attack_hand(var/mob/user as mob)
|
|
interact(user)
|
|
|
|
/obj/machinery/media/jukebox/proc/explode()
|
|
walk_to(src,0)
|
|
src.visible_message("<span class='danger'>\the [src] blows apart!</span>", 1)
|
|
|
|
explosion(src.loc, 0, 0, 1, rand(1,2), 1)
|
|
|
|
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
|
s.set_up(3, 1, src)
|
|
s.start()
|
|
|
|
new /obj/effect/decal/cleanable/blood/oil(src.loc)
|
|
qdel(src)
|
|
|
|
/obj/machinery/media/jukebox/attackby(obj/item/W as obj, mob/user as mob)
|
|
src.add_fingerprint(user)
|
|
|
|
if(default_deconstruction_screwdriver(user, W))
|
|
return
|
|
if(default_deconstruction_crowbar(user, W))
|
|
return
|
|
if(W.is_wrench())
|
|
if(playing)
|
|
StopPlaying()
|
|
user.visible_message("<span class='warning'>[user] has [anchored ? "un" : ""]secured \the [src].</span>", "<span class='notice'>You [anchored ? "un" : ""]secure \the [src].</span>")
|
|
anchored = !anchored
|
|
playsound(src, W.usesound, 50, 1)
|
|
power_change()
|
|
update_icon()
|
|
return
|
|
return ..()
|
|
|
|
/obj/machinery/media/jukebox/emag_act(var/remaining_charges, var/mob/user)
|
|
if(!emagged)
|
|
emagged = 1
|
|
StopPlaying()
|
|
visible_message("<span class='danger'>\The [src] makes a fizzling sound.</span>")
|
|
update_icon()
|
|
return 1
|
|
|
|
/obj/machinery/media/jukebox/proc/StopPlaying()
|
|
var/area/main_area = get_area(src)
|
|
// Always kill the current sound
|
|
for(var/mob/living/M in mobs_in_area(main_area))
|
|
M << sound(null, channel = 1)
|
|
|
|
main_area.forced_ambience = null
|
|
playing = 0
|
|
update_use_power(USE_POWER_IDLE)
|
|
update_icon()
|
|
|
|
|
|
/obj/machinery/media/jukebox/proc/StartPlaying()
|
|
StopPlaying()
|
|
if(!current_track)
|
|
return
|
|
|
|
var/area/main_area = get_area(src)
|
|
if(freq)
|
|
var/sound/new_song = sound(current_track.GetTrack(), channel = 1, repeat = 1, volume = 25)
|
|
new_song.frequency = freq
|
|
main_area.forced_ambience = list(new_song)
|
|
else
|
|
main_area.forced_ambience = list(current_track.GetTrack())
|
|
|
|
for(var/mob/living/M in mobs_in_area(main_area))
|
|
if(M.mind)
|
|
main_area.play_ambience(M)
|
|
|
|
playing = 1
|
|
update_use_power(USE_POWER_ACTIVE)
|
|
update_icon()
|
|
|
|
// Advance to the next track - Don't start playing it unless we were already playing
|
|
/obj/machinery/media/jukebox/proc/NextTrack()
|
|
if(!tracks.len) return
|
|
var/curTrackIndex = max(1, tracks.Find(current_track))
|
|
var/newTrackIndex = (curTrackIndex % tracks.len) + 1 // Loop back around if past end
|
|
current_track = tracks[newTrackIndex]
|
|
if(playing)
|
|
StartPlaying()
|
|
updateDialog()
|
|
|
|
// Advance to the next track - Don't start playing it unless we were already playing
|
|
/obj/machinery/media/jukebox/proc/PrevTrack()
|
|
if(!tracks.len) return
|
|
var/curTrackIndex = max(1, tracks.Find(current_track))
|
|
var/newTrackIndex = curTrackIndex == 1 ? tracks.len : curTrackIndex - 1
|
|
current_track = tracks[newTrackIndex]
|
|
if(playing)
|
|
StartPlaying()
|
|
updateDialog()
|