"
+ dat += "
Air Horn "
+ dat += "
Station Alert "
+ dat += "
Warning Siren "
+ dat += "
Honk"
+ dat += "
Shotgun Pump"
+ dat += "
Gunshot"
+ dat += "
Esword"
+ dat += "
Harm Alarm"
+ var/datum/browser/popup = new(user, "vending", "Radiance Dance Machine - Mark IV", 400, 350)
+ popup.set_content(dat.Join())
+ popup.open()
+
+
+/obj/machinery/disco/Topic(href, href_list)
+ if(..())
+ return
+ add_fingerprint(usr)
+ switch(href_list["action"])
+ if("toggle")
+ if (QDELETED(src))
+ return
+ if(!active)
+ if(stop > world.time)
+ to_chat(usr, "
Error: The device is still resetting from the last activation, it will be ready again in [round((stop-world.time)/10)] seconds.")
+ playsound(src, 'sound/misc/compiler-failure.ogg', 50, 1)
+ return
+ active = TRUE
+ update_icon()
+ dance_setup()
+ START_PROCESSING(SSobj, src)
+ lights_spin()
+ updateUsrDialog()
+ else if(active)
+ active = FALSE
+ STOP_PROCESSING(SSobj, src)
+ update_icon()
+ dance_over()
+ stop = world.time + 300
+ updateUsrDialog()
+ if("select")
+ if(active)
+ to_chat(usr, "
Error: You cannot change the song until the current one is over.")
+ return
+ check_GBP()
+ select_name = input(usr, "Choose your song", "Track:") as null|anything in available
+ if (QDELETED(src))
+ return
+ for(var/datum/track/S in songs)
+ if(select_name == S.song_name)
+ selection = S
+ break
+ updateUsrDialog()
+ 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/shotgunpump.ogg')
+ if("pop")
+ deejay('sound/weapons/Gunshot3.ogg')
+ if("saber")
+ deejay('sound/weapons/saberon.ogg')
+ if("harm")
+ deejay('sound/AI/harmalarm.ogg')
+
+/obj/machinery/disco/proc/deejay(var/S)
+ if (QDELETED(src) || !active || charge < 5)
+ to_chat(usr, "
The device is not able to play more DJ sounds at this time.")
+ return
+ charge -= 5
+ playsound(src, S,300,1)
+
+/obj/machinery/disco/proc/check_GBP()
+ available |= "Engineering's Basic Beat"
+ available |= "Engineering's Domination Dance"
+ available |= "Engineering's Superiority Shimmy"
+ available |= "Engineering's Ultimate High-Energy Hustle"
+
+
+/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/device/flashlight/spotlight/L = new /obj/item/device/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/device/flashlight/spotlight/L = new /obj/item/device/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/device/flashlight/spotlight/L = new /obj/item/device/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/device/flashlight/spotlight/L = new /obj/item/device/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/device/flashlight/spotlight/L = new /obj/item/device/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/device/flashlight/spotlight/L = new /obj/item/device/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/device/flashlight/spotlight/L = new /obj/item/device/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/device/flashlight/spotlight/L = new /obj/item/device/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
+
+/obj/machinery/disco/proc/hierofunk()
+ for(var/i in 1 to 10)
+ spawn_atom_to_turf(/obj/effect/overlay/temp/hierophant/telegraph/edge, src, 1, FALSE)
+ 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)
+ S.orbit(src, 30, TRUE, 60, 36, TRUE, FALSE)
+ if(9 to 16)
+ S.orbit(src, 62, TRUE, 60, 36, TRUE, FALSE)
+ if(17 to 24)
+ 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/device/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/hierofunk)
+ sleep(selection.song_beat)
+
+
+/obj/machinery/disco/proc/dance(var/mob/living/carbon/M) //Show your moves
+
+ 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/disco/proc/dance2(var/mob/living/carbon/M)
+ set waitfor = 0
+ for(var/i = 1, i < 10, i++)
+ M.SpinAnimation(15,1)
+ M.setDir(pick(GLOB.cardinal))
+ sleep(8)
+
+/obj/machinery/disco/proc/dance3(var/mob/living/carbon/M)
+ var/matrix/initial_matrix = matrix(M.transform)
+ for(var/i in 1 to 6)
+ if (!M)
+ return
+ M.SpinAnimation(7,1)
+ M.setDir(pick(GLOB.cardinal))
+ for (var/x in 1 to 12)
+ sleep(1)
+ if (!M)
+ return
+ if (i<5)
+ initial_matrix = matrix(M.transform)
+ initial_matrix.Translate(0,1)
+ animate(M, transform = initial_matrix, time = 1, loop = 0)
+ if (i>4)
+ initial_matrix = matrix(M.transform)
+ initial_matrix.Translate(0,-2)
+ 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(10)
+ animate(M, transform = null, time = 1, loop = 0)
+
+
+/obj/machinery/disco/proc/dance4(var/mob/living/carbon/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))
+ M.lay_down(TRUE)
+ time--
+
+/obj/machinery/disco/proc/dance5(var/mob/living/carbon/M)
+ INVOKE_ASYNC(M, .proc/dance5helper)
+ 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)
+ animate(M, transform = null, time = 1, loop = 0)
+
+/obj/machinery/disco/proc/dance5helper(var/mob/living/carbon/M)
+ if (M)
+ animate(M, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0)
+ sleep (70)
+ if (M)
+ animate(M, transform = null, time = 1, loop = 0)
+
+/mob/living/carbon/proc/dancey() // Dance5 except independent of the machine if admins want to meme it up
+ INVOKE_ASYNC(src, .proc/danceyhelper)
+ var/matrix/initial_matrix = matrix(transform)
+ for (var/i in 1 to 60)
+ if (!src)
+ return
+ if (i<31)
+ initial_matrix = matrix(transform)
+ initial_matrix.Translate(0,1)
+ transform = initial_matrix
+ animate(src, transform, time = 1, loop = 0)
+ if (i>30)
+ initial_matrix = matrix(transform)
+ initial_matrix.Translate(0,-1)
+ transform = initial_matrix
+ animate(src, transform, time = 1, loop = 0)
+ setDir(turn(src.dir, 90))
+ switch (dir)
+ if (NORTH)
+ initial_matrix = matrix(transform)
+ initial_matrix.Translate(0,3)
+ animate(src, transform, time = 1, loop = 0)
+ if (SOUTH)
+ initial_matrix = matrix(transform)
+ initial_matrix.Translate(0,-3)
+ animate(src, transform, time = 1, loop = 0)
+ if (EAST)
+ initial_matrix = matrix(transform)
+ initial_matrix.Translate(3,0)
+ animate(src, transform, time = 1, loop = 0)
+ if (WEST)
+ initial_matrix = matrix(transform)
+ initial_matrix.Translate(-3,0)
+ animate(src, transform, time = 1, loop = 0)
+ sleep (1)
+ animate(src, transform = null, time = 1, loop = 0)
+
+/mob/living/carbon/proc/danceyhelper()
+ if (src)
+ animate(src, transform = matrix(180, MATRIX_ROTATE), time = 1, loop = 0)
+ sleep (70)
+ if (src)
+ animate(src, transform = null, time = 1, loop = 0)
+
+
+/obj/machinery/disco/proc/dance_over()
+ for(var/obj/item/device/flashlight/spotlight/SL in spotlights)
+ qdel(SL)
+ spotlights.Cut()
+ for(var/obj/effect/overlay/sparkles/SP in sparkles)
+ qdel(SP)
+ sparkles.Cut()
+ rangers.Cut()
+ for(var/mob/living/L in listeners)
+ if(!L || !L.client)
+ continue
+ L.stop_sound_channel(CHANNEL_JUKEBOX)
+ listeners.Cut()
+
+
+/obj/machinery/disco/process()
+ if(charge<35)
+ charge += 1
+ if(world.time < stop && active)
+ rangers = list()
+ for(var/mob/living/M in range(9,src))
+ rangers += M
+ if(!(listeners[M]))
+ M.playsound_local(get_turf(M), selection.song_path, 100, channel = CHANNEL_JUKEBOX)
+ listeners[M] = TRUE
+ if(prob(5+(allowed(M)*4)))
+ dance(M)
+ for(var/mob/living/L in listeners)
+ if(!(L in rangers))
+ listeners -= L
+ if(!L || !L.client)
+ continue
+ L.stop_sound_channel(CHANNEL_JUKEBOX)
+ else if(active)
+ STOP_PROCESSING(SSobj, src)
+ dance_over()
+ playsound(src,'sound/machines/terminal_off.ogg',50,1)
+ active = FALSE
+ icon_state = "disco0"
diff --git a/code/game/machinery/wishgranter.dm b/code/game/machinery/wishgranter.dm
index 3b9821766e2..0d5432f1fba 100644
--- a/code/game/machinery/wishgranter.dm
+++ b/code/game/machinery/wishgranter.dm
@@ -50,4 +50,4 @@
to_chat(user, "You have a very bad feeling about this.")
- return
\ No newline at end of file
+ return
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index e83ecda8094..3d62e850e84 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -210,6 +210,11 @@
icon_state = "smoke"
duration = 50
+/obj/effect/overlay/temp/fire
+ icon = 'icons/effects/fire.dmi'
+ icon_state = "3"
+ duration = 20
+
/obj/effect/overlay/temp/cult
randomdir = 0
duration = 10
@@ -608,3 +613,8 @@
name = "Coconuts"
icon = 'icons/misc/beach.dmi'
icon_state = "coconuts"
+
+/obj/effect/overlay/sparkles
+ name = "sparkles"
+ icon = 'icons/effects/effects.dmi'
+ icon_state = "shieldsparkles"
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 00240dc5ff9..62e0667f149 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -307,7 +307,7 @@
// Glowsticks, in the uncomfortable range of similar to flares,
// but not similar enough to make it worth a refactor
/obj/item/device/flashlight/glowstick
- name = "green glowstick"
+ name = "glowstick"
desc = "A military-grade glowstick."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 4
@@ -363,6 +363,11 @@
. = ..()
if(.)
user.visible_message("
[user] cracks and shakes [src].", "
You crack and shake [src], turning it on!")
+ activate()
+
+/obj/item/device/flashlight/glowstick/proc/activate()
+ if(!on)
+ on = TRUE
START_PROCESSING(SSobj, src)
/obj/item/device/flashlight/glowstick/red
@@ -402,6 +407,20 @@
color = initial(glowtype.color)
. = ..()
+/obj/item/device/flashlight/spotlight //invisible lighting source
+ name = "disco lighting"
+ icon_state = null
+ light_color = null
+ brightness_on = 0
+ light_range = 0
+ light_power = 10
+ alpha = 0
+ layer = 0
+ on = TRUE
+ anchored = TRUE
+ var/range = null
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+
/obj/item/device/flashlight/flashdark
name = "flashdark"
desc = "A strange device manufactured with mysterious elements that somehow emits darkness. Or maybe it just sucks in light? Nobody knows for sure."
diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi
index 5d200515f9a..ad5e97831b8 100644
Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ
diff --git a/icons/obj/machines/nuke.dmi b/icons/obj/machines/nuke.dmi
index 54dc6123b1d..ceace5c2500 100644
Binary files a/icons/obj/machines/nuke.dmi and b/icons/obj/machines/nuke.dmi differ
diff --git a/sound/machines/engine_alert1.ogg b/sound/machines/engine_alert1.ogg
new file mode 100644
index 00000000000..fadec78891f
Binary files /dev/null and b/sound/machines/engine_alert1.ogg differ
diff --git a/sound/machines/engine_alert2.ogg b/sound/machines/engine_alert2.ogg
new file mode 100644
index 00000000000..83f693617a7
Binary files /dev/null and b/sound/machines/engine_alert2.ogg differ
diff --git a/sound/misc/Paradox.ogg b/sound/misc/Paradox.ogg
new file mode 100644
index 00000000000..c28403578d5
Binary files /dev/null and b/sound/misc/Paradox.ogg differ
diff --git a/sound/misc/airraid.ogg b/sound/misc/airraid.ogg
new file mode 100644
index 00000000000..820eaccf91d
Binary files /dev/null and b/sound/misc/airraid.ogg differ
diff --git a/sound/misc/boogie2.ogg b/sound/misc/boogie2.ogg
new file mode 100644
index 00000000000..e9cdb973a21
Binary files /dev/null and b/sound/misc/boogie2.ogg differ
diff --git a/sound/misc/disco.ogg b/sound/misc/disco.ogg
new file mode 100644
index 00000000000..5e15c8ccc01
Binary files /dev/null and b/sound/misc/disco.ogg differ
diff --git a/sound/misc/superior.ogg b/sound/misc/superior.ogg
new file mode 100644
index 00000000000..e9cdb973a21
Binary files /dev/null and b/sound/misc/superior.ogg differ
diff --git a/sound/misc/ultimate.ogg b/sound/misc/ultimate.ogg
new file mode 100644
index 00000000000..0674a553135
Binary files /dev/null and b/sound/misc/ultimate.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index ea9822617af..70418bf3a32 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -502,6 +502,7 @@
#include "code\game\machinery\cell_charger.dm"
#include "code\game\machinery\cloning.dm"
#include "code\game\machinery\constructable_frame.dm"
+#include "code\game\machinery\dance_machine.dm"
#include "code\game\machinery\deployable.dm"
#include "code\game\machinery\dna_scanner.dm"
#include "code\game\machinery\doppler_array.dm"