mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-20 19:44:09 +01:00
YOOOOO0U. YOU GOT WHAT AH NEEEEEEEED
Conflicts: code/__HELPERS/game.dm code/game/machinery/alarm.dm code/game/machinery/doors/firedoor.dm code/modules/client/preferences_toggles.dm code/setup.dm maps/tgstation.2.1.0.0.1.dmm
This commit is contained in:
+74
-3
@@ -9,6 +9,12 @@
|
||||
src:Topic(href, href_list)
|
||||
return null
|
||||
|
||||
/proc/get_area_master(O)
|
||||
var/area/A = get_area(O)
|
||||
if(A && A.master)
|
||||
A = A.master
|
||||
return A
|
||||
|
||||
/proc/get_area(O)
|
||||
var/atom/location = O
|
||||
var/i
|
||||
@@ -176,10 +182,10 @@
|
||||
|
||||
for(var/mob/M in range)
|
||||
hear += M
|
||||
|
||||
|
||||
var/list/objects = list()
|
||||
|
||||
for(var/obj/O in range) //Get a list of objects in hearing range. We'll check to see if any clients have their "eye" set to the object
|
||||
for(var/obj/O in range) //Get a list of objects in hearing range. We'll check to see if any clients have their "eye" set to the object
|
||||
objects += O
|
||||
|
||||
for(var/client/C in clients)
|
||||
@@ -196,7 +202,7 @@
|
||||
|
||||
if(C.eye in hear_and_objects)
|
||||
hear += C.mob
|
||||
|
||||
|
||||
else if(C.mob.loc in hear_and_objects)
|
||||
hear += C.mob
|
||||
else if(C.mob.loc.loc in hear_and_objects)
|
||||
@@ -376,3 +382,68 @@ proc/get_candidates(be_special_flag=0)
|
||||
sleep(duration)
|
||||
for(var/client/C in show_to)
|
||||
C.images -= I
|
||||
|
||||
/proc/get_active_player_count()
|
||||
// Get active players who are playing in the round
|
||||
var/active_players = 0
|
||||
for(var/i = 1; i <= player_list.len; i++)
|
||||
var/mob/M = player_list[i]
|
||||
if(M && M.client)
|
||||
if(istype(M, /mob/new_player)) // exclude people in the lobby
|
||||
continue
|
||||
else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers)
|
||||
var/mob/dead/observer/O = M
|
||||
if(O.started_as_observer) // Exclude people who started as observers
|
||||
continue
|
||||
active_players++
|
||||
return active_players
|
||||
|
||||
/datum/projectile_data
|
||||
var/src_x
|
||||
var/src_y
|
||||
var/time
|
||||
var/distance
|
||||
var/power_x
|
||||
var/power_y
|
||||
var/dest_x
|
||||
var/dest_y
|
||||
|
||||
/datum/projectile_data/New(var/src_x, var/src_y, var/time, var/distance, \
|
||||
var/power_x, var/power_y, var/dest_x, var/dest_y)
|
||||
src.src_x = src_x
|
||||
src.src_y = src_y
|
||||
src.time = time
|
||||
src.distance = distance
|
||||
src.power_x = power_x
|
||||
src.power_y = power_y
|
||||
src.dest_x = dest_x
|
||||
src.dest_y = dest_y
|
||||
|
||||
/proc/projectile_trajectory(var/src_x, var/src_y, var/rotation, var/angle, var/power)
|
||||
|
||||
// returns the destination (Vx,y) that a projectile shot at [src_x], [src_y], with an angle of [angle],
|
||||
// rotated at [rotation] and with the power of [power]
|
||||
// Thanks to VistaPOWA for this function
|
||||
|
||||
var/power_x = power * cos(angle)
|
||||
var/power_y = power * sin(angle)
|
||||
var/time = 2* power_y / 10 //10 = g
|
||||
|
||||
var/distance = time * power_x
|
||||
|
||||
var/dest_x = src_x + distance*sin(rotation);
|
||||
var/dest_y = src_y + distance*cos(rotation);
|
||||
|
||||
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
|
||||
|
||||
|
||||
/proc/mobs_in_area(var/area/the_area, var/client_needed=0, var/moblist=mob_list)
|
||||
var/list/mobs_found[0]
|
||||
var/area/our_area = get_area_master(the_area)
|
||||
for(var/mob/M in moblist)
|
||||
if(client_needed && !M.client)
|
||||
continue
|
||||
if(our_area != get_area_master(M))
|
||||
continue
|
||||
mobs_found += M
|
||||
return mobs_found
|
||||
|
||||
@@ -32,14 +32,14 @@ var/global/list/hooks = list()
|
||||
for (var/hook_path in typesof(/hook))
|
||||
var/hook/hook = new hook_path
|
||||
hooks[hook.name] = hook
|
||||
//world.log << "Found hook: " + hook.name
|
||||
world.log << "Found hook: " + hook.name
|
||||
for (var/hook_path in typesof(/hook_handler))
|
||||
var/hook_handler/hook_handler = new hook_path
|
||||
for (var/name in hooks)
|
||||
if (hascall(hook_handler, "On" + name))
|
||||
var/hook/hook = hooks[name]
|
||||
hook.handlers += hook_handler
|
||||
//world.log << "Found hook handler for: " + name
|
||||
world.log << "Found hook handler for: " + name
|
||||
for (var/hook/hook in hooks)
|
||||
hook.Setup()
|
||||
|
||||
|
||||
@@ -1043,6 +1043,13 @@ FIRE ALARM
|
||||
var/last_process = 0
|
||||
var/wiresexposed = 0
|
||||
var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone
|
||||
var/area/master_area
|
||||
|
||||
/obj/machinery/firealarm/New()
|
||||
var/area/A = get_area_master(src)
|
||||
if (!( istype(A, /area) ))
|
||||
return
|
||||
master_area=A
|
||||
|
||||
/obj/machinery/firealarm/update_icon()
|
||||
|
||||
@@ -1368,6 +1375,14 @@ Code shamelessly copied from apc_frame
|
||||
idle_power_usage = 2
|
||||
active_power_usage = 6
|
||||
|
||||
var/area/master_area
|
||||
|
||||
/obj/machinery/partyalarm/New()
|
||||
var/area/A = get_area_master(src)
|
||||
if (!( istype(A, /area) ))
|
||||
return
|
||||
master_area=A
|
||||
|
||||
/obj/machinery/partyalarm/attack_paw(mob/user as mob)
|
||||
return attack_hand(user)
|
||||
|
||||
|
||||
@@ -164,9 +164,7 @@
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(!T.loc) return
|
||||
var/area/A = T.loc
|
||||
if (A.master)
|
||||
A = A.master
|
||||
var/area/A = get_area_master(T)
|
||||
for(var/obj/machinery/portable_atmospherics/scrubber/huge/scrubber in world )
|
||||
var/turf/T2 = get_turf(scrubber)
|
||||
if(T2 && T2.loc)
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
user << "\red \The [src] is welded solid!"
|
||||
return
|
||||
|
||||
var/area/A = get_area(src)
|
||||
var/area/A = get_area_master(src)
|
||||
ASSERT(istype(A))
|
||||
if(A.master)
|
||||
A = A.master
|
||||
@@ -273,4 +273,4 @@
|
||||
|
||||
/obj/machinery/door/firedoor/multi_tile/triple
|
||||
icon = 'icons/obj/doors/DoorHazard3x1.dmi'
|
||||
width = 3
|
||||
width = 3
|
||||
|
||||
@@ -75,8 +75,7 @@ move an amendment</a> to the drawing.</p>
|
||||
|
||||
/obj/item/blueprints/proc/get_area()
|
||||
var/turf/T = get_turf_loc(usr)
|
||||
var/area/A = T.loc
|
||||
A = A.master
|
||||
var/area/A = get_area_master(T)
|
||||
return A
|
||||
|
||||
/obj/item/blueprints/proc/get_area_type(var/area/A = get_area())
|
||||
|
||||
@@ -183,11 +183,21 @@
|
||||
I.color = UI_style_color_new
|
||||
I.alpha = UI_style_alpha_new
|
||||
|
||||
|
||||
|
||||
if(alert("Like it? Save changes?",,"Yes", "No") == "Yes")
|
||||
prefs.UI_style = UI_style_new
|
||||
prefs.UI_style_alpha = UI_style_alpha_new
|
||||
prefs.UI_style_color = UI_style_color_new
|
||||
prefs.save_preferences()
|
||||
usr << "UI was saved"
|
||||
|
||||
/client/verb/toggle_media()
|
||||
set name = "Hear/Silence Streaming"
|
||||
set category = "Preferences"
|
||||
set desc = "Toggle hearing streaming media (radios, jukeboxes, etc)"
|
||||
|
||||
prefs.toggles ^= SOUND_STREAMING
|
||||
prefs.save_preferences()
|
||||
usr << "You will [(prefs.toggles & SOUND_STREAMING) ? "now" : "no longer"] hear streamed media."
|
||||
// Restart.
|
||||
media.stop_music()
|
||||
media.update_music()
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#define JUKEMODE_PLAY_ONCE 3 // Play, then stop.
|
||||
#define JUKEMODE_COUNT 3
|
||||
|
||||
#define JUKEBOX_RELOAD_COOLDOWN 600 // 60s
|
||||
|
||||
// Represents a record returned.
|
||||
/datum/song_info
|
||||
var/title = ""
|
||||
@@ -43,30 +45,40 @@ var/global/loopModeNames=list(
|
||||
anchored = 1
|
||||
luminosity = 4 // Why was this 16
|
||||
|
||||
playing=0
|
||||
|
||||
var/loop_mode = JUKEMODE_SHUFFLE
|
||||
// /datum/song_info
|
||||
var/list/playlist
|
||||
var/current_song=0
|
||||
var/current_song = 0
|
||||
var/autoplay = 0
|
||||
var/last_reload = 0
|
||||
|
||||
/obj/machinery/media/jukebox/attack_ai()
|
||||
return
|
||||
|
||||
/obj/machinery/media/jukebox/attack_paw()
|
||||
return
|
||||
|
||||
/obj/machinery/media/jukebox/proc/check_reload()
|
||||
return world.time > last_reload + JUKEBOX_RELOAD_COOLDOWN
|
||||
/obj/machinery/media/jukebox/attack_hand(var/mob/user)
|
||||
var/t = "<h1>Jukebox Interface</h1>"
|
||||
t += "<b>Power:</b> <a href='?src=\ref[src];power=1'>[playing?"On":"Off"]</a><br />"
|
||||
t += "<b>Play Mode:</b> <a href='?src=\ref[src];loop=1'>[loopModeNames[loop_mode]]</a><br />"
|
||||
if(current_song)
|
||||
var/datum/song_info/song=playlist[current_song]
|
||||
t += "<b>Current song:</b> [song.artist] - [song.title]<br />"
|
||||
t += "<table class='prettytable'><tr><th colspan='2'>Artist - Title</th><th>Album</th></tr>"
|
||||
var/i
|
||||
for(i = 1,i <= playlist.len,i++)
|
||||
var/datum/song_info/song=playlist[i]
|
||||
t += "<tr><th>#[i]</th><td><A href='?src=\ref[src];song=[i]'>[song.artist] - [song.title]</A></td><td>[song.album]</td></tr>"
|
||||
t += "</table>"
|
||||
if(playlist == null)
|
||||
t += "\[DOWNLOADING PLAYLIST, PLEASE WAIT\]"
|
||||
else
|
||||
if(current_song)
|
||||
var/datum/song_info/song=playlist[current_song]
|
||||
t += "<b>Current song:</b> [song.artist] - [song.title]<br />"
|
||||
if(check_reload())
|
||||
t += "\[<a href='?src=\ref[src];reload=1'>Reload Playlist</a>\]"
|
||||
t += "<table class='prettytable'><tr><th colspan='2'>Artist - Title</th><th>Album</th></tr>"
|
||||
var/i
|
||||
for(i = 1,i <= playlist.len,i++)
|
||||
var/datum/song_info/song=playlist[i]
|
||||
t += "<tr><th>#[i]</th><td><A href='?src=\ref[src];song=[i]'>[song.artist] - [song.title]</A></td><td>[song.album]</td></tr>"
|
||||
t += "</table>"
|
||||
user.set_machine(src)
|
||||
var/datum/browser/popup = new (user,"jukebox",name,420,700)
|
||||
popup.set_content(t)
|
||||
@@ -78,6 +90,16 @@ var/global/loopModeNames=list(
|
||||
..()
|
||||
if (href_list["power"])
|
||||
playing=!playing
|
||||
update_music()
|
||||
|
||||
if (href_list["reload"])
|
||||
if(!check_reload())
|
||||
usr << "\red You must wait 60 seconds between reloads."
|
||||
return
|
||||
last_reload=world.time
|
||||
playlist=null
|
||||
current_song=0
|
||||
update_music()
|
||||
|
||||
if (href_list["song"])
|
||||
current_song=Clamp(text2num(href_list["song"]),1,playlist.len)
|
||||
@@ -91,6 +113,7 @@ var/global/loopModeNames=list(
|
||||
/obj/machinery/media/jukebox/process()
|
||||
if(!playlist)
|
||||
var/url="[config.media_base_url]/index.php"
|
||||
testing("[src] - Updating playlist from [url]...")
|
||||
var/response = world.Export(url)
|
||||
playlist=list()
|
||||
if(response)
|
||||
@@ -101,7 +124,9 @@ var/global/loopModeNames=list(
|
||||
var/songdata = reader.read_value()
|
||||
for(var/list/record in songdata)
|
||||
playlist += new /datum/song_info(record)
|
||||
visible_message("<span class='notice'>\icon[src] \The [src] beeps, and the menu on its front fills with [playlist.len] items.</span>","<em>You hear a beep.</em>")
|
||||
else
|
||||
//testing("Failed to update playlist: Response null.")
|
||||
stat &= BROKEN
|
||||
update_icon()
|
||||
return
|
||||
@@ -119,13 +144,18 @@ var/global/loopModeNames=list(
|
||||
if(JUKEMODE_PLAY_ONCE)
|
||||
playing=0
|
||||
return
|
||||
if(!playing) return
|
||||
if(!playing)
|
||||
return
|
||||
update_music()
|
||||
|
||||
/obj/machinery/media/jukebox/update_music()
|
||||
var/datum/song_info/song = playlist[current_song]
|
||||
media_url = song.url
|
||||
media_start_time = world.time
|
||||
visible_message("<span class='notice'>\icon[src] \The [src] begins to play \"[song.title]\", by [song.artist].</notice>","<em>You hear music.</em>")
|
||||
visible_message("<span class='notice'>\icon[src] \The [src] warbles: [song.length]ds, [song.url]</notice>")
|
||||
if(current_song)
|
||||
var/datum/song_info/song = playlist[current_song]
|
||||
media_url = song.url
|
||||
media_start_time = world.time
|
||||
visible_message("<span class='notice'>\icon[src] \The [src] begins to play \"[song.title]\", by [song.artist].</span>","<em>You hear music.</em>")
|
||||
//visible_message("<span class='notice'>\icon[src] \The [src] warbles: [song.length/10]s @ [song.url]</notice>")
|
||||
else
|
||||
media_url=""
|
||||
media_start_time = 0
|
||||
..()
|
||||
@@ -4,12 +4,63 @@
|
||||
var/media_url=""
|
||||
var/media_start_time=0
|
||||
|
||||
var/area/master_area
|
||||
|
||||
// Notify everyone in the area of new music.
|
||||
// YOU MUST SET MEDIA_URL AND MEDIA_START_TIME YOURSELF!
|
||||
/obj/machinery/media/proc/update_music()
|
||||
var/area/A = get_area(src)
|
||||
if(A.master)
|
||||
A=A.master
|
||||
for(var/mob/M in A)
|
||||
update_media_source()
|
||||
|
||||
// Bail if we lost connection to master.
|
||||
if(!master_area)
|
||||
return
|
||||
|
||||
// Send update to clients.
|
||||
for(var/mob/M in mobs_in_area(master_area))
|
||||
if(M && M.client)
|
||||
M.update_music()
|
||||
M.update_music()
|
||||
|
||||
/obj/machinery/media/proc/update_media_source()
|
||||
var/area/A = get_area_master(src)
|
||||
|
||||
// Check if there's a media source already.
|
||||
if(A.media_source && A.media_source!=src)
|
||||
master_area=null
|
||||
return
|
||||
|
||||
// Update Media Source.
|
||||
if(!A.media_source)
|
||||
A.media_source=src
|
||||
|
||||
master_area=A
|
||||
|
||||
/obj/machinery/media/proc/disconnect_media_source()
|
||||
var/area/A = get_area_master(src)
|
||||
|
||||
// Sanity
|
||||
if(!A)
|
||||
master_area=null
|
||||
return
|
||||
|
||||
// Check if there's a media source already.
|
||||
if(A && A.media_source && A.media_source!=src)
|
||||
master_area=null
|
||||
return
|
||||
|
||||
// Update Media Source.
|
||||
A.media_source=null
|
||||
|
||||
// Clients
|
||||
for(var/mob/M in mobs_in_area(A))
|
||||
if(M && M.client)
|
||||
M.update_music()
|
||||
|
||||
master_area=null
|
||||
|
||||
/obj/machinery/media/New()
|
||||
..()
|
||||
update_media_source()
|
||||
|
||||
/obj/machinery/media/Destroy()
|
||||
disconnect_media_source()
|
||||
..()
|
||||
@@ -25,20 +25,24 @@ function SetMusic(url, time, volume) {
|
||||
/hook_handler/soundmanager
|
||||
// Set up player on login
|
||||
proc/OnLogin(var/list/args)
|
||||
//testing("Received OnLogin.")
|
||||
var/client/C = args["client"]
|
||||
C.media = new /datum/media_manager(C)
|
||||
C.media = new /datum/media_manager(args["mob"])
|
||||
C.media.open()
|
||||
C.media.update_music()
|
||||
|
||||
// Update when moving between areas.
|
||||
proc/OnMobAreaChange(var/list/args)
|
||||
//testing("Received OnMobAreaChange.")
|
||||
var/mob/M = args["mob"]
|
||||
|
||||
M.update_music()
|
||||
|
||||
/mob/proc/update_music()
|
||||
if (client)
|
||||
if(client.media)
|
||||
client.media.update_music()
|
||||
if (client && client.media)
|
||||
client.media.update_music()
|
||||
//else
|
||||
// testing("[src] - client: [client?"Y":"N"]; client.media: [client && client.media ? "Y":"N"]")
|
||||
|
||||
/area
|
||||
// One media source per area.
|
||||
@@ -50,18 +54,31 @@ function SetMusic(url, time, volume) {
|
||||
var/volume = 100
|
||||
|
||||
var/client/owner
|
||||
var/mob/mob
|
||||
|
||||
var/const/window = "rpane.hosttracker"
|
||||
//var/const/window = "mediaplayer" // For debugging.
|
||||
|
||||
New(var/mob/holder)
|
||||
src.owner=holder
|
||||
src.mob=holder
|
||||
owner=src.mob.client
|
||||
|
||||
// Actually pop open the player in the background.
|
||||
proc/open()
|
||||
owner << browse(PLAYER_HTML, "window=rpane.hosttracker")
|
||||
owner << browse(PLAYER_HTML, "window=[window]")
|
||||
send_update()
|
||||
|
||||
// Tell the player to play something via JS.
|
||||
proc/send_update()
|
||||
owner << output(list2params(list(url, (world.timeofday - start_time) / 10, volume)), "rpane.hosttracker:SetMusic")
|
||||
if(!(owner.prefs.toggles & SOUND_STREAMING))
|
||||
return // Nope.
|
||||
//testing("Sending update to WMP...")
|
||||
owner << output(list2params(list(url, (world.time - start_time) / 10, volume)), "[window]:SetMusic")
|
||||
|
||||
proc/stop_music()
|
||||
url=""
|
||||
start_time=world.time
|
||||
send_update()
|
||||
|
||||
// Scan for media sources and use them.
|
||||
proc/update_music()
|
||||
@@ -69,16 +86,25 @@ function SetMusic(url, time, volume) {
|
||||
var/targetStartTime = 0
|
||||
var/targetVolume = 100
|
||||
|
||||
if (owner)
|
||||
var/area/A = get_area()
|
||||
var/obj/machinery/media/M = A.media_source
|
||||
if(M.playing)
|
||||
targetURL = M.media_url
|
||||
targetStartTime = M.media_start_time
|
||||
if (!owner)
|
||||
//testing("owner is null")
|
||||
return
|
||||
|
||||
var/area/A = get_area_master(mob)
|
||||
if(!A)
|
||||
//testing("[owner] in [mob.loc]. Aborting.")
|
||||
stop_music()
|
||||
return
|
||||
var/obj/machinery/media/M = A.media_source
|
||||
if(M && M.playing)
|
||||
targetURL = M.media_url
|
||||
targetStartTime = M.media_start_time
|
||||
//owner << "Found audio source: [M.media_url] @ [(world.time - start_time) / 10]s."
|
||||
//else
|
||||
// testing("M is not playing or null.")
|
||||
|
||||
if (url != targetURL || abs(targetStartTime - start_time) > 1 || targetVolume != volume)
|
||||
url = targetURL
|
||||
start_time = targetStartTime
|
||||
volume = targetVolume
|
||||
|
||||
send_update()
|
||||
@@ -611,8 +611,7 @@
|
||||
// called when area power state changes
|
||||
/obj/machinery/light/power_change()
|
||||
spawn(10)
|
||||
var/area/A = src.loc.loc
|
||||
A = A.master
|
||||
var/area/A = get_area_master(src)
|
||||
seton(A.lightswitch && A.power_light)
|
||||
|
||||
// called when on fire
|
||||
|
||||
+2
-1
@@ -679,8 +679,9 @@ var/list/TAGGERLOCATIONS = list("Disposals",
|
||||
#define SOUND_AMBIENCE 4
|
||||
#define SOUND_LOBBY 8
|
||||
#define SOUND_VOICES 16
|
||||
#define SOUND_STREAMING 32
|
||||
|
||||
#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY)
|
||||
#define SOUND_DEFAULT (SOUND_ADMINHELP|SOUND_MIDI|SOUND_AMBIENCE|SOUND_LOBBY|SOUND_STREAMING)
|
||||
#define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_ATTACKLOGS|CHAT_LOOC)
|
||||
|
||||
#define BE_TRAITOR 1
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
appearance_loadbanfile()
|
||||
jobban_updatelegacybans()
|
||||
LoadBans()
|
||||
SetupHooks() // /vg/
|
||||
|
||||
if(config && config.server_name != null && config.server_suffix && world.port > 0)
|
||||
// dumb and hardcoded but I don't care~
|
||||
|
||||
Reference in New Issue
Block a user