mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-09 16:05:07 +00:00
Skyrat jukebox code cleanup (#2762)
## About The Pull Request And by cleanup I mean rip literally all of it out because it turns out tg's jukebox code basically has feature parity with what we have now while also being better code-wise. ## Why It's Good For The Game Less code to maintain. ## Proof Of Testing It compiled and it plays music properly and the rave visor also plays music properly ## Changelog 🆑 refactor: ripped out all the skyrat jukebox code in favor of tg's. /🆑
This commit is contained in:
@@ -42886,7 +42886,7 @@
|
||||
/obj/effect/turf_decal/siding/wood{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/jukebox/public,
|
||||
/obj/machinery/jukebox/no_access,
|
||||
/turf/open/floor/wood/large,
|
||||
/area/station/commons/lounge)
|
||||
"oGU" = (
|
||||
|
||||
@@ -3733,7 +3733,7 @@
|
||||
/obj/effect/turf_decal/trimline/white/filled/warning{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/jukebox/public,
|
||||
/obj/machinery/jukebox/no_access,
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/shuttle/escape)
|
||||
"Sz" = (
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
#define MAX_INSTRUMENT_CHANNELS (128 * 6)
|
||||
|
||||
// SKYRAT EDIT START - JUKEBOX
|
||||
#define CHANNEL_JUKEBOX_START 1006
|
||||
// SKYRAT EDIT START
|
||||
#define CHANNEL_HEV 1005
|
||||
//SKYRAT EDIT CHANGE END
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SKYRAT EDIT: See modular_skyrat/modules/jukebox /// Checks if the mob has jukebox muted in their preferences
|
||||
/// Checks if the mob has jukebox muted in their preferences
|
||||
#define IS_PREF_MUTED(mob) (!isnull(mob.client) && !mob.client.prefs.read_preference(/datum/preference/toggle/sound_jukebox))
|
||||
|
||||
// Reasons for appling STATUS_MUTE to a mob's sound status
|
||||
@@ -103,7 +103,7 @@
|
||||
var/datum/track/new_track = new()
|
||||
new_track.song_path = file("[global.config.directory]/jukebox_music/sounds/[track_file]")
|
||||
var/list/track_data = splittext(track_file, "+")
|
||||
if(length(track_data) != 3)
|
||||
if(length(track_data) < 3) // BUBBER EDIT - This is fucking stupid - ORIGINAL: if(length(track_data) != 3)
|
||||
continue
|
||||
new_track.song_name = track_data[1]
|
||||
new_track.song_length = text2num(track_data[2])
|
||||
@@ -404,4 +404,3 @@
|
||||
song_name = "Tintin on the Moon"
|
||||
song_length = 3 MINUTES + 52 SECONDS
|
||||
song_beat = 1 SECONDS
|
||||
SKYRAT EDIT END*/
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* SKYRAT EDIT: See modular_skyrat/modules/jukebox
|
||||
/obj/machinery/jukebox
|
||||
name = "jukebox"
|
||||
desc = "A classic music player."
|
||||
@@ -384,4 +383,3 @@
|
||||
/obj/machinery/jukebox/disco/proc/dance4_revert(mob/living/dancer, matrix/starting_matrix)
|
||||
animate(dancer, transform = starting_matrix, time = 5, loop = 0)
|
||||
REMOVE_TRAIT(dancer, TRAIT_DISCO_DANCER, REF(src))
|
||||
SKYRAT EDIT END*/
|
||||
|
||||
@@ -80,7 +80,6 @@
|
||||
flash_color(mod.wearer, flash_color = "#FF0000", flash_time = 10 SECONDS)
|
||||
set_off = FALSE
|
||||
|
||||
/* SKYRAT EDIT: See skyrat_modular/modules/jukebox
|
||||
///Rave Visor - Gives you a rainbow visor and plays jukebox music to you.
|
||||
/obj/item/mod/module/visor/rave
|
||||
name = "MOD rave visor module"
|
||||
@@ -159,7 +158,7 @@
|
||||
return
|
||||
|
||||
music_player.selection = new_song
|
||||
SKYRAT EDIT END */
|
||||
|
||||
///Tanner - Tans you with spraytan.
|
||||
/obj/item/mod/module/tanner
|
||||
name = "MOD tanning module"
|
||||
|
||||
@@ -13,5 +13,3 @@ Every sound you add must have a unique name. Avoid using the plus sign "+" and t
|
||||
Sound names must be in the format of [song name]+[length in deciseconds]+[beat in deciseconds].ogg
|
||||
|
||||
A three minute song title "SS13" that lasted 3 minutes would have a file name SS13+1800+5.ogg
|
||||
|
||||
SKYRAT CHANGE: The title must also include the associated ID. So: [song name]+[length in deciseconds]+[beat in deciseconds]+[song ID]
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
/datum/area_spawn/bar_jukebox
|
||||
target_areas = list(/area/station/commons/lounge, /area/station/service/bar/atrium, /area/station/service/bar)
|
||||
desired_atom = /obj/machinery/jukebox/public
|
||||
desired_atom = /obj/machinery/jukebox/no_access
|
||||
mode = AREA_SPAWN_MODE_OPEN
|
||||
|
||||
// Wall mounts. Use sparingly as walls are prime real estate
|
||||
|
||||
@@ -1,484 +0,0 @@
|
||||
/// Helper macro to check if the passed mob has jukebox sound preference enabled
|
||||
#define HAS_JUKEBOX_PREF(mob) (!QDELETED(mob) && !isnull(mob.client) && mob.client.prefs.read_preference(/datum/preference/toggle/sound_jukebox))
|
||||
|
||||
/obj/machinery/jukebox
|
||||
name = "jukebox"
|
||||
desc = "A classic music player."
|
||||
icon = 'icons/obj/machines/music.dmi'
|
||||
icon_state = "jukebox"
|
||||
verb_say = "states"
|
||||
density = TRUE
|
||||
req_access = list(ACCESS_BAR)
|
||||
/// Whether we're actively playing music
|
||||
var/active = FALSE
|
||||
/// List of weakrefs to mobs listening to the current song
|
||||
var/list/datum/weakref/rangers = list()
|
||||
/// World.time when the current song will stop playing, but also a cooldown between activations
|
||||
var/stop = 0
|
||||
/// Current song selected
|
||||
var/datum/track/selection = null
|
||||
/// Volume of the songs played
|
||||
var/volume = 50
|
||||
//https://www.desmos.com/calculator/ybto1dyqzk
|
||||
var/falloff_dist_offset = 20 // higher = jukebox can be heard from further away
|
||||
var/falloff_dist_divider = 100 // lower = falloff begins sooner
|
||||
|
||||
/obj/machinery/jukebox/disco
|
||||
name = "radiant dance machine mark IV"
|
||||
desc = "The first three prototypes were discontinued after mass casualty incidents."
|
||||
icon = 'icons/obj/machines/music.dmi'
|
||||
icon_state = "disco"
|
||||
anchored = FALSE
|
||||
var/list/spotlights = list()
|
||||
var/list/sparkles = list()
|
||||
|
||||
/obj/machinery/jukebox/disco/indestructible
|
||||
name = "radiant dance machine mark V"
|
||||
desc = "Now redesigned with data gathered from the extensive disco and plasma research."
|
||||
anchored = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/machinery/jukebox/public
|
||||
req_access = list()
|
||||
falloff_dist_offset = 10
|
||||
falloff_dist_divider = 50
|
||||
|
||||
/obj/machinery/jukebox/no_access
|
||||
req_access = null
|
||||
falloff_dist_offset = 10
|
||||
falloff_dist_divider = 50
|
||||
|
||||
/obj/machinery/jukebox/Initialize(mapload)
|
||||
. = ..()
|
||||
if(length(SSjukeboxes.songs))
|
||||
selection = pick(SSjukeboxes.songs)
|
||||
|
||||
/obj/machinery/jukebox/Destroy()
|
||||
dance_over()
|
||||
selection = null
|
||||
return ..()
|
||||
|
||||
/obj/machinery/jukebox/attackby(obj/item/O, mob/user, params)
|
||||
if(!active)
|
||||
if(O.tool_behaviour == TOOL_WRENCH)
|
||||
if(!anchored && !isinspace())
|
||||
to_chat(user,span_notice("You secure [src] to the floor."))
|
||||
set_anchored(TRUE)
|
||||
else if(anchored)
|
||||
to_chat(user,span_notice("You unsecure and disconnect [src]."))
|
||||
set_anchored(FALSE)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
|
||||
return
|
||||
return ..()
|
||||
|
||||
/obj/machinery/jukebox/update_icon_state()
|
||||
. = ..()
|
||||
SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays)
|
||||
luminosity = 0
|
||||
|
||||
if(active)
|
||||
luminosity = 1
|
||||
SSvis_overlays.add_vis_overlay(src, icon, "active", layer, plane, dir, alpha)
|
||||
SSvis_overlays.add_vis_overlay(src, icon, "active", 0, EMISSIVE_PLANE, dir, alpha)
|
||||
|
||||
/obj/machinery/jukebox/examine(mob/user)
|
||||
. = ..()
|
||||
if (active)
|
||||
. += "Now playing: [selection.song_name]"
|
||||
|
||||
/obj/machinery/jukebox/ui_status(mob/user)
|
||||
if(!anchored)
|
||||
to_chat(user,span_warning("This device must be anchored by a wrench!"))
|
||||
return UI_CLOSE
|
||||
if(!allowed(user) && !isobserver(user))
|
||||
to_chat(user,span_warning("Error: Access Denied."))
|
||||
return UI_CLOSE
|
||||
if(!SSjukeboxes.songs.len && !isobserver(user))
|
||||
to_chat(user,span_warning("Error: No music tracks have been authorized for your station. Petition Central Command to resolve this issue."))
|
||||
return UI_CLOSE
|
||||
return ..()
|
||||
|
||||
/obj/machinery/jukebox/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Jukebox", name)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/jukebox/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["active"] = active
|
||||
data["songs"] = list()
|
||||
for(var/datum/track/S in SSjukeboxes.songs)
|
||||
var/list/track_data = list(
|
||||
name = S.song_name
|
||||
)
|
||||
data["songs"] += 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
|
||||
data["volume"] = volume
|
||||
return data
|
||||
|
||||
/obj/machinery/jukebox/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("toggle")
|
||||
if(QDELETED(src))
|
||||
return
|
||||
if(!active)
|
||||
if(stop > world.time)
|
||||
to_chat(usr, span_warning("Error: The device is still resetting from the last activation, it will be ready again in [DisplayTimeText(stop-world.time)]."))
|
||||
return
|
||||
activate_music()
|
||||
return TRUE
|
||||
else
|
||||
stop = 0
|
||||
return TRUE
|
||||
if("select_track")
|
||||
if(active)
|
||||
to_chat(usr, span_warning("Error: You cannot change the song until the current one is over."))
|
||||
return
|
||||
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]
|
||||
return TRUE
|
||||
if("set_volume")
|
||||
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
|
||||
else if(text2num(new_volume) != null)
|
||||
volume = text2num(new_volume)
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/jukebox/proc/activate_music()
|
||||
var/jukeboxslottotake = SSjukeboxes.addjukebox(src, selection, 2)
|
||||
if(jukeboxslottotake)
|
||||
active = TRUE
|
||||
update_use_power(ACTIVE_POWER_USE)
|
||||
update_appearance(UPDATE_ICON_STATE)
|
||||
START_PROCESSING(SSobj, src)
|
||||
stop = world.time + selection.song_length
|
||||
return TRUE
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/obj/machinery/jukebox/disco/activate_music()
|
||||
..()
|
||||
dance_setup()
|
||||
lights_spin()
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/dance_setup()
|
||||
var/turf/cen = get_turf(src)
|
||||
FOR_DVIEW(var/turf/t, 3, get_turf(src),INVISIBILITY_LIGHTING)
|
||||
if(t.x == cen.x && t.y > cen.y)
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1 + get_dist(src, t), 30 - (get_dist(src, t) * 8), COLOR_SOFT_RED)
|
||||
continue
|
||||
if(t.x == cen.x && t.y < cen.y)
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1 + get_dist(src, t), 30 - (get_dist(src, t) * 8), LIGHT_COLOR_PURPLE)
|
||||
continue
|
||||
if(t.x > cen.x && t.y == cen.y)
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1 + get_dist(src, t), 30 - (get_dist(src, t) * 8), LIGHT_COLOR_BRIGHT_YELLOW)
|
||||
continue
|
||||
if(t.x < cen.x && t.y == cen.y)
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1 + get_dist(src, t), 30 - (get_dist(src, t) * 8), LIGHT_COLOR_GREEN)
|
||||
continue
|
||||
if((t.x+1 == cen.x && t.y+1 == cen.y) || (t.x+2==cen.x && t.y+2 == cen.y))
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1.4 + get_dist(src, t), 30 - (get_dist(src, t) * 8), LIGHT_COLOR_ORANGE)
|
||||
continue
|
||||
if((t.x-1 == cen.x && t.y-1 == cen.y) || (t.x-2==cen.x && t.y-2 == cen.y))
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1.4 + get_dist(src, t), 30 - (get_dist(src, t) * 8), LIGHT_COLOR_CYAN)
|
||||
continue
|
||||
if((t.x-1 == cen.x && t.y+1 == cen.y) || (t.x-2==cen.x && t.y+2 == cen.y))
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1.4 + get_dist(src, t), 30 - (get_dist(src, t) * 8), LIGHT_COLOR_BLUEGREEN)
|
||||
continue
|
||||
if((t.x+1 == cen.x && t.y-1 == cen.y) || (t.x+2==cen.x && t.y-2 == cen.y))
|
||||
spotlights += new /obj/item/flashlight/spotlight(t, 1.4 + get_dist(src, t), 30 - (get_dist(src, t) * 8), LIGHT_COLOR_BLUE)
|
||||
continue
|
||||
continue
|
||||
FOR_DVIEW_END
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/hierofunk()
|
||||
for(var/i in 1 to 10)
|
||||
spawn_atom_to_turf(/obj/effect/temp_visual/hierophant/telegraph/edge, src, 1, FALSE)
|
||||
sleep(0.5 SECONDS)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
#define DISCO_INFENO_RANGE (rand(85, 115)*0.01)
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/lights_spin()
|
||||
for(var/i in 1 to 25)
|
||||
if(QDELETED(src) || !active)
|
||||
return
|
||||
var/obj/effect/overlay/sparkles/S = new /obj/effect/overlay/sparkles(src)
|
||||
S.alpha = 0
|
||||
sparkles += S
|
||||
switch(i)
|
||||
if(1 to 8)
|
||||
S.orbit(src, 30, TRUE, 60, 36, TRUE)
|
||||
if(9 to 16)
|
||||
S.orbit(src, 62, TRUE, 60, 36, TRUE)
|
||||
if(17 to 24)
|
||||
S.orbit(src, 95, TRUE, 60, 36, TRUE)
|
||||
if(25)
|
||||
S.pixel_y = 7
|
||||
S.forceMove(get_turf(src))
|
||||
sleep(0.7 SECONDS)
|
||||
if(selection.song_name == "Engineering's Ultimate High-Energy Hustle")
|
||||
sleep(28 SECONDS)
|
||||
for(var/s in sparkles)
|
||||
var/obj/effect/overlay/sparkles/reveal = s
|
||||
reveal.alpha = 255
|
||||
while(active)
|
||||
for(var/g in spotlights) // The multiples reflects custom adjustments to each colors after dozens of tests
|
||||
var/obj/item/flashlight/spotlight/glow = g
|
||||
if(QDELETED(glow))
|
||||
stack_trace("[glow?.gc_destroyed ? "Qdeleting glow" : "null entry"] found in [src].[gc_destroyed ? " Source qdeleting at the time." : ""]")
|
||||
return
|
||||
switch(glow.light_color)
|
||||
if(COLOR_SOFT_RED)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(LIGHT_COLOR_BLUE)
|
||||
else
|
||||
glow.set_light_range_power_color(glow.base_light_range * DISCO_INFENO_RANGE, glow.light_power * 1.48, LIGHT_COLOR_BLUE)
|
||||
glow.set_light_on(TRUE)
|
||||
if(LIGHT_COLOR_BLUE)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_range_power_color(glow.base_light_range * DISCO_INFENO_RANGE, glow.light_power * 2, LIGHT_COLOR_GREEN)
|
||||
glow.set_light_on(TRUE)
|
||||
else
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(LIGHT_COLOR_GREEN)
|
||||
if(LIGHT_COLOR_GREEN)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(LIGHT_COLOR_ORANGE)
|
||||
else
|
||||
glow.set_light_range_power_color(glow.base_light_range * DISCO_INFENO_RANGE, glow.light_power * 0.5, LIGHT_COLOR_ORANGE)
|
||||
glow.set_light_on(TRUE)
|
||||
if(LIGHT_COLOR_ORANGE)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_range_power_color(glow.base_light_range * DISCO_INFENO_RANGE, glow.light_power * 2.27, LIGHT_COLOR_PURPLE)
|
||||
glow.set_light_on(TRUE)
|
||||
else
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(LIGHT_COLOR_PURPLE)
|
||||
if(LIGHT_COLOR_PURPLE)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(LIGHT_COLOR_BLUEGREEN)
|
||||
else
|
||||
glow.set_light_range_power_color(glow.base_light_range * DISCO_INFENO_RANGE, glow.light_power * 0.44, LIGHT_COLOR_BLUEGREEN)
|
||||
glow.set_light_on(TRUE)
|
||||
if(LIGHT_COLOR_BLUEGREEN)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_range(glow.base_light_range * DISCO_INFENO_RANGE)
|
||||
glow.set_light_color(LIGHT_COLOR_BRIGHT_YELLOW)
|
||||
glow.set_light_on(TRUE)
|
||||
else
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(LIGHT_COLOR_DIM_YELLOW)
|
||||
if(LIGHT_COLOR_DIM_YELLOW)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(LIGHT_COLOR_CYAN)
|
||||
else
|
||||
glow.set_light_range(glow.base_light_range * DISCO_INFENO_RANGE)
|
||||
glow.set_light_color(LIGHT_COLOR_CYAN)
|
||||
glow.set_light_on(TRUE)
|
||||
if(LIGHT_COLOR_CYAN)
|
||||
if(glow.even_cycle)
|
||||
glow.set_light_range_power_color(glow.base_light_range * DISCO_INFENO_RANGE, glow.light_power * 0.68, COLOR_SOFT_RED)
|
||||
glow.set_light_on(TRUE)
|
||||
else
|
||||
glow.set_light_on(FALSE)
|
||||
glow.set_light_color(COLOR_SOFT_RED)
|
||||
glow.even_cycle = !glow.even_cycle
|
||||
if(prob(2)) // Unique effects for the dance floor that show up randomly to mix things up
|
||||
INVOKE_ASYNC(src, PROC_REF(hierofunk))
|
||||
sleep(selection.song_beat)
|
||||
if(QDELETED(src))
|
||||
return
|
||||
|
||||
#undef DISCO_INFENO_RANGE
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/dance(mob/living/M) //Show your moves
|
||||
set waitfor = FALSE
|
||||
switch(rand(0, 9))
|
||||
if(0 to 1)
|
||||
dance2(M)
|
||||
if(2 to 3)
|
||||
dance3(M)
|
||||
if(4 to 6)
|
||||
dance4(M)
|
||||
if(7 to 9)
|
||||
dance5(M)
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/dance2(mob/living/M)
|
||||
for(var/i in 0 to 9)
|
||||
dance_rotate(M, CALLBACK(M, TYPE_PROC_REF(/mob, dance_flip)))
|
||||
sleep(2 SECONDS)
|
||||
|
||||
/mob/proc/dance_flip()
|
||||
if(dir == WEST)
|
||||
emote("flip")
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/dance3(mob/living/M)
|
||||
set waitfor = FALSE
|
||||
var/matrix/initial_matrix = matrix(M.transform)
|
||||
for (var/i in 1 to 75)
|
||||
if (!M)
|
||||
return
|
||||
switch(i)
|
||||
if (1 to 15)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(0,1)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
if (16 to 30)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(1,-1)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
if (31 to 45)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(-1,-1)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
if (46 to 60)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(-1,1)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
if (61 to 75)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(1,0)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
M.setDir(turn(M.dir, 90))
|
||||
switch (M.dir)
|
||||
if (NORTH)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(0,3)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
if (SOUTH)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(0,-3)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
if (EAST)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(3,0)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
if (WEST)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(-3,0)
|
||||
animate(M, transform = initial_matrix, time = 0.1 SECONDS, loop = 0)
|
||||
sleep(0.1 SECONDS)
|
||||
M.lying_fix()
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/dance4(mob/living/lead_dancer)
|
||||
var/speed = rand(1,3)
|
||||
set waitfor = 0
|
||||
var/time = 30
|
||||
while(time)
|
||||
sleep(speed)
|
||||
for(var/i in 1 to speed)
|
||||
lead_dancer.setDir(pick(GLOB.cardinals))
|
||||
// makes people dance with us nearby
|
||||
for(var/datum/weakref/weak_dancer as anything in rangers)
|
||||
var/mob/living/carbon/dancer = weak_dancer.resolve()
|
||||
if(!istype(dancer))
|
||||
continue
|
||||
dancer.set_resting(!dancer.resting, silent = TRUE, instant = TRUE)
|
||||
time--
|
||||
|
||||
/obj/machinery/jukebox/disco/proc/dance5(mob/living/M)
|
||||
animate(M, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0)
|
||||
var/matrix/initial_matrix = matrix(M.transform)
|
||||
for (var/i in 1 to 60)
|
||||
if (!M)
|
||||
return
|
||||
if(!active)
|
||||
break
|
||||
if (i<31)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(0,1)
|
||||
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
||||
if (i>30)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(0,-1)
|
||||
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
||||
M.setDir(turn(M.dir, 90))
|
||||
switch (M.dir)
|
||||
if (NORTH)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(0,3)
|
||||
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
||||
if (SOUTH)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(0,-3)
|
||||
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
||||
if (EAST)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(3,0)
|
||||
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
||||
if (WEST)
|
||||
initial_matrix = matrix(M.transform)
|
||||
initial_matrix.Translate(-3,0)
|
||||
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
||||
sleep(0.1 SECONDS)
|
||||
M.lying_fix()
|
||||
|
||||
/mob/living/proc/lying_fix()
|
||||
animate(src, transform = null, time = 0.1 SECONDS, loop = 0)
|
||||
lying_prev = 0
|
||||
|
||||
/obj/machinery/jukebox/proc/dance_over()
|
||||
var/position = SSjukeboxes.findjukeboxindex(src)
|
||||
if(!position)
|
||||
return
|
||||
SSjukeboxes.removejukebox(position)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
rangers.Cut()
|
||||
|
||||
/obj/machinery/jukebox/disco/dance_over()
|
||||
..()
|
||||
QDEL_LIST(spotlights)
|
||||
QDEL_LIST(sparkles)
|
||||
|
||||
/obj/machinery/jukebox/process()
|
||||
if(active && world.time >= stop)
|
||||
active = FALSE
|
||||
update_use_power(IDLE_POWER_USE)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
dance_over()
|
||||
playsound(src,'sound/machines/terminal/terminal_off.ogg',50,TRUE)
|
||||
update_appearance(UPDATE_ICON_STATE)
|
||||
stop = world.time + 100
|
||||
|
||||
/obj/machinery/jukebox/disco/process()
|
||||
. = ..()
|
||||
if(!active)
|
||||
return
|
||||
|
||||
for(var/datum/weakref/weak_dancer as anything in rangers)
|
||||
var/mob/living/to_dance = weak_dancer.resolve()
|
||||
if(!istype(to_dance) || !(to_dance.mobility_flags & MOBILITY_MOVE))
|
||||
continue
|
||||
if(prob(5 + (allowed(to_dance) * 4)))
|
||||
dance(to_dance)
|
||||
|
||||
#undef HAS_JUKEBOX_PREF
|
||||
@@ -1,138 +0,0 @@
|
||||
#define HAS_JUKEBOX_PREF(mob) (!QDELETED(mob) && !isnull(mob.client) && mob.client.prefs.read_preference(/datum/preference/toggle/sound_jukebox) && mob.can_hear())
|
||||
|
||||
SUBSYSTEM_DEF(jukeboxes)
|
||||
name = "Jukeboxes"
|
||||
wait = 5
|
||||
var/list/songs = list()
|
||||
var/list/activejukeboxes = list()
|
||||
var/list/freejukeboxchannels = list()
|
||||
|
||||
/datum/track
|
||||
var/song_name = "generic"
|
||||
var/song_path = null
|
||||
var/song_length = 0
|
||||
var/song_beat = 0
|
||||
var/song_associated_id = null
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/proc/addjukebox(obj/machinery/jukebox/jukebox, datum/track/T, jukefalloff = 1)
|
||||
if(!istype(T))
|
||||
CRASH("[src] tried to play a song with a nonexistant track")
|
||||
var/channeltoreserve = pick(freejukeboxchannels)
|
||||
if(!channeltoreserve)
|
||||
return FALSE
|
||||
freejukeboxchannels -= channeltoreserve
|
||||
var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff)
|
||||
activejukeboxes.len++
|
||||
activejukeboxes[activejukeboxes.len] = youvegotafreejukebox
|
||||
|
||||
//Due to changes in later versions of 512, SOUND_UPDATE no longer properly plays audio when a file is defined in the sound datum. As such, we are now required to init the audio before we can actually do anything with it.
|
||||
//Downsides to this? This means that you can *only* hear the jukebox audio if you were present on the server when it started playing, and it means that it's now impossible to add loops to the jukebox track list.
|
||||
var/sound/song_to_init = sound(T.song_path)
|
||||
song_to_init.status = SOUND_MUTE
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(!(M.client.prefs.read_preference(/datum/preference/toggle/sound_instruments)))
|
||||
continue
|
||||
|
||||
M.playsound_local(M, null, (jukebox.volume / 2), channel = youvegotafreejukebox[2], sound_to_use = song_to_init)
|
||||
return activejukeboxes.len
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/proc/removejukebox(IDtoremove)
|
||||
if(islist(activejukeboxes[IDtoremove]))
|
||||
var/jukechannel = activejukeboxes[IDtoremove][2]
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
M.stop_sound_channel(jukechannel)
|
||||
freejukeboxchannels |= jukechannel
|
||||
activejukeboxes.Cut(IDtoremove, IDtoremove+1)
|
||||
return TRUE
|
||||
else
|
||||
CRASH("Tried to remove jukebox with invalid ID")
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/proc/findjukeboxindex(obj/machinery/jukebox)
|
||||
if(length(activejukeboxes))
|
||||
for(var/list/jukeinfo in activejukeboxes)
|
||||
if(jukebox in jukeinfo)
|
||||
return activejukeboxes.Find(jukeinfo)
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/proc/reload_songs()
|
||||
songs = list()
|
||||
var/list/tracks = flist("[global.config.directory]/jukebox_music/sounds/")
|
||||
for(var/S in tracks)
|
||||
var/datum/track/T = new()
|
||||
T.song_path = file("[global.config.directory]/jukebox_music/sounds/[S]")
|
||||
var/list/L = splittext(S,"+")
|
||||
if(L.len != 4)
|
||||
continue
|
||||
T.song_name = L[1]
|
||||
T.song_length = text2num(L[2])
|
||||
T.song_beat = text2num(L[3])
|
||||
T.song_associated_id = L[4]
|
||||
songs |= T
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/Initialize()
|
||||
reload_songs()
|
||||
for(var/i in CHANNEL_JUKEBOX_START to CHANNEL_JUKEBOX)
|
||||
freejukeboxchannels |= i
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/fire()
|
||||
if(!length(activejukeboxes))
|
||||
return
|
||||
for(var/list/jukeinfo in activejukeboxes)
|
||||
if(!length(jukeinfo))
|
||||
stack_trace("Active jukebox without any associated metadata.")
|
||||
continue
|
||||
var/datum/track/juketrack = jukeinfo[1]
|
||||
if(!istype(juketrack))
|
||||
stack_trace("Invalid jukebox track datum.")
|
||||
continue
|
||||
var/obj/machinery/jukebox/jukebox = jukeinfo[3]
|
||||
if(!istype(jukebox))
|
||||
stack_trace("Nonexistant or invalid object associated with jukebox.")
|
||||
continue
|
||||
var/sound/song_played = sound(juketrack.song_path)
|
||||
|
||||
song_played.falloff = 255
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!HAS_JUKEBOX_PREF(M))
|
||||
M.stop_sound_channel(jukeinfo[2])
|
||||
continue
|
||||
|
||||
var/volume = jukebox.volume
|
||||
|
||||
if(jukebox.z == M.z) //todo - expand this to work with mining planet z-levels when robust jukebox audio gets merged to master
|
||||
song_played.status = SOUND_UPDATE
|
||||
//https://www.desmos.com/calculator/ybto1dyqzk
|
||||
if(jukeinfo[4]) //HAS FALLOFF
|
||||
var/distance = get_dist(M,jukebox)
|
||||
volume = min(
|
||||
50,
|
||||
volume,
|
||||
volume * ((max(1,volume*0.1 + jukebox.falloff_dist_offset - distance)/80)**0.2 - (distance/jukebox.falloff_dist_divider))
|
||||
)
|
||||
volume = round(volume,1)
|
||||
if(volume < jukebox.volume*0.5)
|
||||
var/volume_mod = 1 - (volume / 50)
|
||||
song_played.x = clamp(jukebox.x - M.x,-1,1) * volume_mod * 4
|
||||
song_played.y = clamp(jukebox.y - M.y,-1,1) * volume_mod * 4
|
||||
song_played.z = 1
|
||||
else
|
||||
song_played.x = 0
|
||||
song_played.y = 0
|
||||
song_played.z = 1
|
||||
|
||||
if(volume < 1)
|
||||
song_played.status |= SOUND_MUTE
|
||||
else
|
||||
song_played.status = SOUND_MUTE | SOUND_UPDATE //Setting volume = 0 doesn't let the sound properties update at all, which is lame.
|
||||
|
||||
M.playsound_local(null, null, volume, channel = jukeinfo[2], sound_to_use = song_played)
|
||||
CHECK_TICK
|
||||
return
|
||||
|
||||
#undef HAS_JUKEBOX_PREF
|
||||
@@ -1,90 +0,0 @@
|
||||
///Rave Visor - Gives you a rainbow visor and plays jukebox music to you.
|
||||
/obj/item/mod/module/visor/rave
|
||||
name = "MOD rave visor module"
|
||||
desc = "A Super Cool Awesome Visor (SCAV), intended for modular suits."
|
||||
icon_state = "rave_visor"
|
||||
complexity = 1
|
||||
overlay_state_inactive = "module_rave"
|
||||
/// The client colors applied to the wearer.
|
||||
var/datum/client_colour/rave_screen
|
||||
/// The current element in the rainbow_order list we are on.
|
||||
var/rave_number = 1
|
||||
/// The track we selected to play.
|
||||
var/datum/track/selection
|
||||
/// A list of all the songs we can play.
|
||||
var/list/songs = list()
|
||||
/// A list of the colors the module can take.
|
||||
var/static/list/rainbow_order = list(
|
||||
list(1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0),
|
||||
list(1,0,0,0, 0,0.5,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0),
|
||||
list(1,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0),
|
||||
list(0,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0),
|
||||
list(0,0,0,0, 0,0.5,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0),
|
||||
list(1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0),
|
||||
)
|
||||
|
||||
/obj/item/mod/module/visor/rave/Initialize(mapload)
|
||||
. = ..()
|
||||
var/list/tracks = flist("[global.config.directory]/jukebox_music/sounds/")
|
||||
for(var/sound in tracks)
|
||||
var/datum/track/track = new()
|
||||
track.song_path = file("[global.config.directory]/jukebox_music/sounds/[sound]")
|
||||
var/list/sound_params = splittext(sound,"+")
|
||||
if(length(sound_params) != 3)
|
||||
continue
|
||||
track.song_name = sound_params[1]
|
||||
track.song_length = text2num(sound_params[2])
|
||||
track.song_beat = text2num(sound_params[3])
|
||||
songs[track.song_name] = track
|
||||
if(length(songs))
|
||||
var/song_name = pick(songs)
|
||||
selection = songs[song_name]
|
||||
|
||||
/obj/item/mod/module/visor/rave/on_activation()
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
rave_screen = mod.wearer.add_client_colour(/datum/client_colour/rave)
|
||||
rave_screen.update_colour(rainbow_order[rave_number])
|
||||
if(selection)
|
||||
mod.wearer.playsound_local(get_turf(src), null, 50, channel = CHANNEL_JUKEBOX, sound_to_use = sound(selection.song_path), use_reverb = FALSE)
|
||||
|
||||
/obj/item/mod/module/visor/rave/on_deactivation(display_message = TRUE, deleting = FALSE)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
QDEL_NULL(rave_screen)
|
||||
if(selection)
|
||||
mod.wearer.stop_sound_channel(CHANNEL_JUKEBOX)
|
||||
if(deleting)
|
||||
return
|
||||
SEND_SOUND(mod.wearer, sound('sound/machines/terminal/terminal_off.ogg', volume = 50, channel = CHANNEL_JUKEBOX))
|
||||
|
||||
/obj/item/mod/module/visor/rave/generate_worn_overlay(mutable_appearance/standing)
|
||||
. = ..()
|
||||
for(var/mutable_appearance/appearance as anything in .)
|
||||
appearance.color = active ? rainbow_order[rave_number] : null
|
||||
|
||||
/obj/item/mod/module/visor/rave/on_active_process(seconds_per_tick)
|
||||
rave_number++
|
||||
if(rave_number > length(rainbow_order))
|
||||
rave_number = 1
|
||||
mod.wearer.update_clothing(mod.slot_flags)
|
||||
rave_screen.update_colour(rainbow_order[rave_number])
|
||||
|
||||
/obj/item/mod/module/visor/rave/get_configuration()
|
||||
. = ..()
|
||||
if(length(songs))
|
||||
.["selection"] = add_ui_configuration("Song", "list", selection.song_name, clean_songs())
|
||||
|
||||
/obj/item/mod/module/visor/rave/configure_edit(key, value)
|
||||
switch(key)
|
||||
if("selection")
|
||||
if(active)
|
||||
return
|
||||
selection = songs[value]
|
||||
|
||||
/obj/item/mod/module/visor/rave/proc/clean_songs()
|
||||
. = list()
|
||||
for(var/track in songs)
|
||||
. += track
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB |
@@ -1,29 +0,0 @@
|
||||
https://github.com/Skyrat-SS13/Skyrat-tg/pull/892
|
||||
|
||||
## Title: Jukebox
|
||||
|
||||
MODULE ID: JUKEBOX
|
||||
|
||||
### Description:
|
||||
|
||||
Adds a new sound system for the jukebox, and also updates the jukebox to be good.
|
||||
|
||||
### TG Proc Changes:
|
||||
|
||||
- Skyrat-tg\code\__DEFINES\sound.dm > DEFINES CHANGED, SEE FILE.
|
||||
|
||||
### Defines:
|
||||
|
||||
- #define CHANNEL_JUKEBOX_START 1016
|
||||
|
||||
### Master file additions
|
||||
|
||||
- modular_skyrat\master_files\code\game\sound.dm
|
||||
|
||||
### Included files that are not contained in this module:
|
||||
|
||||
- N/A
|
||||
|
||||
### Credits:
|
||||
Gandalf2k15 - porting
|
||||
NotRanged - Original code
|
||||
@@ -7805,9 +7805,6 @@
|
||||
#include "modular_skyrat\modules\interaction_menu\code\click.dm"
|
||||
#include "modular_skyrat\modules\interaction_menu\code\interaction_component.dm"
|
||||
#include "modular_skyrat\modules\interaction_menu\code\interaction_datum.dm"
|
||||
#include "modular_skyrat\modules\jukebox\code\dance_machine.dm"
|
||||
#include "modular_skyrat\modules\jukebox\code\jukebox_subsystem.dm"
|
||||
#include "modular_skyrat\modules\jukebox\code\ravemod.dm"
|
||||
#include "modular_skyrat\modules\jungle\code\flora.dm"
|
||||
#include "modular_skyrat\modules\kahraman_equipment\code\gps_beacon.dm"
|
||||
#include "modular_skyrat\modules\kahraman_equipment\code\looping_sounds.dm"
|
||||
|
||||
1
tools/UpdatePaths/Scripts_Bubber/2762_jukebox_repath.txt
Normal file
1
tools/UpdatePaths/Scripts_Bubber/2762_jukebox_repath.txt
Normal file
@@ -0,0 +1 @@
|
||||
/obj/machinery/jukebox/public : /obj/machinery/jukebox/no_access{@OLD}
|
||||
Reference in New Issue
Block a user