diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm index 6cc0f302871..c53b4a13e4a 100644 --- a/code/__DEFINES/sound.dm +++ b/code/__DEFINES/sound.dm @@ -2,7 +2,10 @@ #define CHANNEL_LOBBYMUSIC 1024 #define CHANNEL_ADMIN 1023 #define CHANNEL_VOX 1022 +#define CHANNEL_JUKEBOX 1021 //THIS SHOULD ALWAYS BE THE LOWEST ONE! //KEEP IT UPDATED -#define CHANNEL_HIGHEST_AVAILABLE 1021 + +#define CHANNEL_HIGHEST_AVAILABLE 1020 + diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm new file mode 100644 index 00000000000..0876e5c1f7b --- /dev/null +++ b/code/game/machinery/dance_machine.dm @@ -0,0 +1,514 @@ +// DISCO DANCE MACHINE - For engineering power optimization incentive nurturing test system (POINTS) + +/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" + anchored = FALSE + verb_say = "states" + density = TRUE + req_access = list(GLOB.access_engine) + var/active = FALSE + var/list/rangers = list() + var/list/listeners = list() + var/charge = 35 + var/stop = 0 + var/list/available = list() + var/list/select_name = list() + 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 + +/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/Initialize() + ..() + selection = songs[1] + + +/obj/machinery/disco/Destroy() + dance_over() + return ..() + +/obj/machinery/disco/attackby(obj/item/O, mob/user, params) + if(!active) + if(istype(O, /obj/item/weapon/wrench)) + if(!anchored && !isinspace()) + to_chat(user,"You secure the [src] to the floor.") + anchored = TRUE + else if(anchored) + to_chat(user,"You unsecure and disconnect the [src].") + anchored = FALSE + playsound(src, 'sound/items/Deconstruct.ogg', 50, 1) + return + return ..() + +/obj/machinery/disco/update_icon() + if(active) + icon_state = "disco1" + else + icon_state = "disco0" + ..() + + +/obj/machinery/disco/interact(mob/user) + if (!anchored) + to_chat(user,"This device must be anchored by a wrench!") + return + if(!allowed(user)) + to_chat(user,"Error: Access Denied - Message: Only the engineering department can be trusted with this kind of power.") + playsound(src, 'sound/misc/compiler-failure.ogg', 50, 1) + return + if(!Adjacent(user) && !isAI(user)) + return + user.set_machine(src) + var/list/dat = list() + dat +="
" + dat += "[!active ? "BREAK IT DOWN" : "SHUT IT DOWN"]
" + dat += "

" + dat += " Select Track
" + dat += "Track Selected: [selection.song_name]
" + dat += "Track Length: [selection.song_length/10] seconds

" + dat += "
DJ's Soundboard:
" + dat +="
" + 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"