mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-16 01:23:41 +01:00
0440209243
* Migrate Disco Machine UI * did this fix it?
508 lines
14 KiB
Plaintext
508 lines
14 KiB
Plaintext
/obj/machinery/disco
|
|
name = "radiant dance machine mark IV"
|
|
desc = "The first three prototypes were discontinued after mass casualty incidents."
|
|
icon = 'icons/obj/lighting.dmi'
|
|
icon_state = "disco0"
|
|
atom_say_verb = "states"
|
|
density = TRUE
|
|
var/active = FALSE
|
|
var/list/rangers = list()
|
|
var/charge = 35
|
|
var/stop = 0
|
|
var/list/spotlights = list()
|
|
var/list/sparkles = list()
|
|
var/static/list/songs = list(
|
|
new /datum/track("Engineering's Basic Beat", 'sound/misc/disco.ogg', 600, 5),
|
|
new /datum/track("Engineering's Domination Dance", 'sound/misc/e1m1.ogg', 950, 6),
|
|
new /datum/track("Engineering's Superiority Shimmy", 'sound/misc/paradox.ogg', 2400, 4),
|
|
new /datum/track("Engineering's Ultimate High-Energy Hustle", 'sound/misc/boogie2.ogg', 1770, 5),
|
|
)
|
|
var/datum/track/selection = null
|
|
/// If set to FALSE, the dance4 proc that rests the dancer will be replaced by dance2.
|
|
var/restdancing = TRUE
|
|
var/list/available = list()
|
|
|
|
/datum/track
|
|
var/song_name = "generic"
|
|
var/song_path = null
|
|
var/song_length = 0
|
|
var/song_beat = 0
|
|
|
|
/datum/track/New(name, path, length, beat)
|
|
song_name = name
|
|
song_path = path
|
|
song_length = length
|
|
song_beat = beat
|
|
|
|
/obj/machinery/disco/proc/add_track(file, name, length, beat)
|
|
if(!name)
|
|
name = "[file]"
|
|
if(!beat)
|
|
beat = 5
|
|
if(!length)
|
|
length = 2400 //Unless there's a way to discern via BYOND.
|
|
var/datum/track/T = new /datum/track(name, file, length, beat)
|
|
songs += T
|
|
available += T.song_name
|
|
|
|
/obj/machinery/disco/Initialize(mapload)
|
|
. = ..()
|
|
for(var/datum/track/S in songs)
|
|
available += S.song_name
|
|
selection = songs[1]
|
|
|
|
|
|
/obj/machinery/disco/Destroy()
|
|
dance_over()
|
|
selection = null
|
|
STOP_PROCESSING(SSobj, src)
|
|
return ..()
|
|
|
|
/obj/machinery/disco/wrench_act(mob/user, obj/item/I)
|
|
if(active)
|
|
return
|
|
. = TRUE
|
|
if(!I.use_tool(src, user, 0, volume = I.tool_volume))
|
|
return
|
|
if(!anchored && !isinspace())
|
|
anchored = TRUE
|
|
WRENCH_ANCHOR_MESSAGE
|
|
else if(anchored)
|
|
anchored = FALSE
|
|
WRENCH_UNANCHOR_MESSAGE
|
|
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
|
|
|
/obj/machinery/disco/update_icon_state()
|
|
if(active)
|
|
icon_state = "disco1"
|
|
else
|
|
icon_state = "disco0"
|
|
|
|
/obj/machinery/disco/update_overlays()
|
|
. = ..()
|
|
underlays.Cut()
|
|
|
|
if(active)
|
|
underlays += emissive_appearance(icon, "disco_lightmask")
|
|
|
|
/obj/machinery/disco/attack_hand(mob/user)
|
|
if(..())
|
|
return
|
|
if(!anchored)
|
|
to_chat(user,SPAN_WARNING("This device must be anchored by a wrench!"))
|
|
return
|
|
if(!Adjacent(user) && !is_ai(user))
|
|
return
|
|
add_fingerprint(user)
|
|
ui_interact(user)
|
|
|
|
/obj/machinery/disco/ui_interact(mob/user, datum/tgui/ui)
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "DanceMachine", "Radiant Dance Machine Mk. IV")
|
|
ui.open()
|
|
|
|
/obj/machinery/disco/ui_data(mob/user)
|
|
var/list/data = list()
|
|
data["active"] = active
|
|
data["selectedSong"] = selection.song_name
|
|
data["songLength"] = selection.song_length
|
|
data["charge"] = charge
|
|
data["available"] = available
|
|
data["onCooldown"] = !active && stop > world.time
|
|
return data
|
|
|
|
/obj/machinery/disco/ui_act(action, params)
|
|
if(..())
|
|
return
|
|
switch(action)
|
|
if("toggle")
|
|
if(!active)
|
|
if(stop > world.time)
|
|
return
|
|
breakitdown()
|
|
else if(active)
|
|
stop = 0
|
|
if("select")
|
|
var/song_name = params["selectedSong"]
|
|
if(!song_name)
|
|
return
|
|
for(var/datum/track/S in songs)
|
|
if(S.song_name == song_name)
|
|
selection = S
|
|
if(!selection)
|
|
return
|
|
if("horn")
|
|
deejay('sound/items/airhorn2.ogg')
|
|
if("alert")
|
|
deejay('sound/misc/notice1.ogg')
|
|
if("siren")
|
|
deejay('sound/machines/engine_alert1.ogg')
|
|
if("honk")
|
|
deejay('sound/items/bikehorn.ogg')
|
|
if("pump")
|
|
deejay('sound/weapons/gun_interactions/shotgunpump.ogg')
|
|
if("pop")
|
|
deejay('sound/weapons/gunshots/gunshot3.ogg')
|
|
if("saber")
|
|
deejay('sound/weapons/saberon.ogg')
|
|
if("harm")
|
|
deejay('sound/AI/harmalarm.ogg')
|
|
return TRUE
|
|
|
|
/**
|
|
* Starts the dance machine.
|
|
*/
|
|
/obj/machinery/disco/proc/breakitdown()
|
|
active = TRUE
|
|
update_icon()
|
|
set_light(1, LIGHTING_MINIMUM_POWER)
|
|
dance_setup()
|
|
START_PROCESSING(SSobj, src)
|
|
lights_spin()
|
|
|
|
/obj/machinery/disco/proc/deejay(S)
|
|
if(QDELETED(src) || !active || charge < 5)
|
|
return
|
|
charge -= 5
|
|
playsound(src, S, 300, 1)
|
|
|
|
/obj/machinery/disco/proc/dance_setup()
|
|
stop = world.time + selection.song_length
|
|
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)
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "red"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
if(t.x == cen.x && t.y < cen.y)
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "purple"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
if(t.x > cen.x && t.y == cen.y)
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "#ffff00"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
if(t.x < cen.x && t.y == cen.y)
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "green"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
if((t.x+1 == cen.x && t.y+1 == cen.y) || (t.x+2==cen.x && t.y+2 == cen.y))
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "sw"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1.4+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
if((t.x-1 == cen.x && t.y-1 == cen.y) || (t.x-2==cen.x && t.y-2 == cen.y))
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "ne"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1.4+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
if((t.x-1 == cen.x && t.y+1 == cen.y) || (t.x-2==cen.x && t.y+2 == cen.y))
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "se"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1.4+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
if((t.x+1 == cen.x && t.y-1 == cen.y) || (t.x+2==cen.x && t.y-2 == cen.y))
|
|
var/obj/item/flashlight/spotlight/L = new /obj/item/flashlight/spotlight(t)
|
|
L.light_color = "nw"
|
|
L.light_power = 30 - (get_dist(src, L) * 8)
|
|
L.range = 1.4+get_dist(src, L)
|
|
spotlights+=L
|
|
continue
|
|
continue
|
|
END_FOR_DVIEW
|
|
|
|
/obj/machinery/disco/proc/hierofunk()
|
|
for(var/i in 1 to 10)
|
|
new /obj/effect/temp_visual/hierophant/telegraph/edge(get_turf(src))
|
|
sleep(5)
|
|
|
|
/obj/machinery/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)
|
|
spawn(0)
|
|
S.orbit(src, 30, TRUE, 60, 36, TRUE, FALSE)
|
|
if(9 to 16)
|
|
spawn(0)
|
|
S.orbit(src, 62, TRUE, 60, 36, TRUE, FALSE)
|
|
if(17 to 24)
|
|
spawn(0)
|
|
S.orbit(src, 95, TRUE, 60, 36, TRUE, FALSE)
|
|
if(25)
|
|
S.pixel_y = 7
|
|
S.forceMove(get_turf(src))
|
|
sleep(7)
|
|
if(selection.song_name == "Engineering's Ultimate High-Energy Hustle")
|
|
sleep(280)
|
|
for(var/obj/reveal in sparkles)
|
|
reveal.alpha = 255
|
|
while(active)
|
|
for(var/obj/item/flashlight/spotlight/glow in spotlights) // The multiples reflects custom adjustments to each colors after dozens of tests
|
|
if(QDELETED(src) || !active || QDELETED(glow))
|
|
return
|
|
if(glow.light_color == "red")
|
|
glow.light_color = "nw"
|
|
glow.light_power = glow.light_power * 1.48
|
|
glow.light_range = 0
|
|
glow.update_light()
|
|
continue
|
|
if(glow.light_color == "nw")
|
|
glow.light_color = "green"
|
|
glow.light_range = glow.range * 1.1
|
|
glow.light_power = glow.light_power * 2 // Any changes to power must come in pairs to neutralize it for other colors
|
|
glow.update_light()
|
|
continue
|
|
if(glow.light_color == "green")
|
|
glow.light_color = "sw"
|
|
glow.light_power = glow.light_power * 0.5
|
|
glow.light_range = 0
|
|
glow.update_light()
|
|
continue
|
|
if(glow.light_color == "sw")
|
|
glow.light_color = "purple"
|
|
glow.light_power = glow.light_power * 2.27
|
|
glow.light_range = glow.range * 1.15
|
|
glow.update_light()
|
|
continue
|
|
if(glow.light_color == "purple")
|
|
glow.light_color = "se"
|
|
glow.light_power = glow.light_power * 0.44
|
|
glow.light_range = 0
|
|
glow.update_light()
|
|
continue
|
|
if(glow.light_color == "se")
|
|
glow.light_color = "#ffff00"
|
|
glow.light_range = glow.range * 0.9
|
|
glow.update_light()
|
|
continue
|
|
if(glow.light_color == "#ffff00")
|
|
glow.light_color = "ne"
|
|
glow.light_range = 0
|
|
glow.update_light()
|
|
continue
|
|
if(glow.light_color == "ne")
|
|
glow.light_color = "red"
|
|
glow.light_power = glow.light_power * 0.68
|
|
glow.light_range = glow.range * 0.85
|
|
glow.update_light()
|
|
continue
|
|
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)
|
|
|
|
|
|
/obj/machinery/disco/proc/dance(mob/living/M) //Show your moves
|
|
set waitfor = FALSE
|
|
if(M.client)
|
|
if(!(M.client.prefs.sound & SOUND_DISCO)) //they dont want music or dancing
|
|
rangers -= M //Doing that here as it'll be checked less often than in processing.
|
|
return
|
|
if(!(M.client.prefs.toggles2 & PREFTOGGLE_2_DANCE_DISCO)) //they just dont wanna dance
|
|
return
|
|
switch(rand(0,9))
|
|
if(0 to 1)
|
|
dance2(M)
|
|
if(2 to 3)
|
|
dance3(M)
|
|
if(4 to 6)
|
|
if(restdancing)
|
|
dance4(M)
|
|
else
|
|
dance2(M)
|
|
if(7 to 9)
|
|
dance5(M)
|
|
|
|
/obj/machinery/disco/proc/dance2(mob/living/M)
|
|
for(var/i = 1, i < 10, i++)
|
|
for(var/d in list(NORTH, SOUTH, EAST, WEST, EAST, SOUTH, NORTH, SOUTH, EAST, WEST, EAST, SOUTH))
|
|
M.setDir(d)
|
|
if(i == WEST && !M.incapacitated())
|
|
M.SpinAnimation(7, 1)
|
|
sleep(1)
|
|
sleep(20)
|
|
|
|
/obj/machinery/disco/proc/dance3(mob/living/M)
|
|
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 = 1, loop = 0)
|
|
if(16 to 30)
|
|
initial_matrix = matrix(M.transform)
|
|
initial_matrix.Translate(1, -1)
|
|
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
|
if(31 to 45)
|
|
initial_matrix = matrix(M.transform)
|
|
initial_matrix.Translate(-1, -1)
|
|
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
|
if(46 to 60)
|
|
initial_matrix = matrix(M.transform)
|
|
initial_matrix.Translate(-1, 1)
|
|
animate(M, transform = initial_matrix, time = 1, loop = 0)
|
|
if(61 to 75)
|
|
initial_matrix = matrix(M.transform)
|
|
initial_matrix.Translate(1, 0)
|
|
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(1)
|
|
M.lying_fix()
|
|
|
|
|
|
/obj/machinery/disco/proc/dance4(mob/living/M)
|
|
var/speed = rand(1, 3)
|
|
set waitfor = 0
|
|
var/time = 30
|
|
while(time)
|
|
sleep(speed)
|
|
for(var/i in 1 to speed)
|
|
M.setDir(pick(GLOB.cardinal))
|
|
if(IS_HORIZONTAL(M))
|
|
M.stand_up()
|
|
else
|
|
M.lay_down()
|
|
time--
|
|
|
|
/obj/machinery/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(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(1)
|
|
M.lying_fix()
|
|
|
|
|
|
|
|
/mob/living/proc/lying_fix()
|
|
animate(src, transform = null, time = 1, loop = 0)
|
|
lying_prev = 0
|
|
|
|
/obj/machinery/disco/proc/dance_over()
|
|
QDEL_LIST_CONTENTS(spotlights)
|
|
QDEL_LIST_CONTENTS(sparkles)
|
|
for(var/mob/living/L in rangers)
|
|
if(!L || !L.client)
|
|
continue
|
|
L.stop_sound_channel(CHANNEL_JUKEBOX)
|
|
rangers = list()
|
|
|
|
|
|
|
|
/obj/machinery/disco/process()
|
|
if(charge < 35)
|
|
charge += 1
|
|
if(world.time < stop && active)
|
|
var/sound/song_played = sound(selection.song_path)
|
|
|
|
for(var/mob/M in range(10,src))
|
|
if(!M.client || M.client.prefs.sound & SOUND_DISCO)
|
|
if(!(M in rangers))
|
|
rangers[M] = TRUE
|
|
M.playsound_local(get_turf(M), null, 100, channel = CHANNEL_JUKEBOX, S = song_played, use_reverb = FALSE)
|
|
for(var/mob/living/L in rangers)
|
|
if(get_dist(src, L) > 10)
|
|
rangers -= L
|
|
if(!L || !L.client)
|
|
continue
|
|
L.stop_sound_channel(CHANNEL_JUKEBOX)
|
|
else if(prob(9) && (L.mobility_flags & MOBILITY_STAND) && isliving(L))
|
|
dance(L)
|
|
else if(active)
|
|
active = FALSE
|
|
STOP_PROCESSING(SSobj, src)
|
|
dance_over()
|
|
playsound(src,'sound/machines/terminal_off.ogg',50,1)
|
|
update_icon()
|
|
set_light(0)
|
|
stop = world.time + 50
|
|
|
|
|
|
|
|
/obj/machinery/disco/immobile
|
|
name = "radiant dance machine mark V"
|
|
desc = "A massive disco ball permanently anchored to the floor with heat-sealed bolts. Merely being in the presence of such a majestic contraption fills you with the urge to dance."
|
|
anchored = TRUE
|
|
|
|
/obj/machinery/disco/immobile/wrench_act()
|
|
return FALSE
|
|
|
|
/obj/machinery/disco/chaos_staff
|
|
restdancing = FALSE
|
|
anchored = TRUE
|
|
|
|
/obj/machinery/disco/chaos_staff/Initialize(mapload)
|
|
. = ..()
|
|
selection = pick(songs)
|
|
INVOKE_ASYNC(src, PROC_REF(breakitdown))
|