Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into station_traits
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
/datum/config_entry/flag/irc_announce_new_game
|
||||
deprecated_by = /datum/config_entry/string/chat_announce_new_game
|
||||
|
||||
/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value)
|
||||
return "" //default broadcast
|
||||
|
||||
/datum/config_entry/string/chat_announce_new_game
|
||||
config_entry_value = null
|
||||
|
||||
/datum/config_entry/string/chat_reboot_role
|
||||
|
||||
/datum/config_entry/string/chat_roundend_notice_tag
|
||||
|
||||
/datum/config_entry/string/chat_squawk_tag
|
||||
@@ -39,16 +39,6 @@
|
||||
|
||||
/datum/config_entry/flag/show_irc_name
|
||||
|
||||
/datum/config_entry/flag/irc_announce_new_game
|
||||
deprecated_by = /datum/config_entry/string/chat_announce_new_game
|
||||
|
||||
/datum/config_entry/flag/irc_announce_new_game/DeprecationUpdate(value)
|
||||
return "" //default broadcast
|
||||
|
||||
/datum/config_entry/string/chat_announce_new_game
|
||||
|
||||
config_entry_value = null
|
||||
|
||||
/datum/config_entry/string/default_view
|
||||
config_entry_value = "15x15"
|
||||
|
||||
|
||||
@@ -79,6 +79,10 @@
|
||||
/datum/config_entry/flag/log_telecomms
|
||||
config_entry_value = TRUE
|
||||
|
||||
/// log economy
|
||||
/datum/config_entry/flag/log_econ
|
||||
config_entry_value = TRUE
|
||||
|
||||
/// log certain expliotable parrots and other such fun things in a JSON file of twitter valid phrases.
|
||||
/datum/config_entry/flag/log_twitter
|
||||
config_entry_value = TRUE
|
||||
|
||||
@@ -31,7 +31,7 @@ SUBSYSTEM_DEF(autotransfer)
|
||||
if(world.time < targettime)
|
||||
return
|
||||
if(maxvotes == NO_MAXVOTES_CAP || maxvotes > curvotes)
|
||||
SSvote.initiate_vote("transfer","server")
|
||||
SSvote.initiate_vote("transfer","server", votesystem=APPROVAL_VOTING)
|
||||
targettime = targettime + voteinterval
|
||||
curvotes++
|
||||
else
|
||||
|
||||
@@ -367,9 +367,14 @@ SUBSYSTEM_DEF(job)
|
||||
JobDebug("DO, Handling unrejectable unassigned")
|
||||
//Mop up people who can't leave.
|
||||
for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?)
|
||||
if(!GiveRandomJob(player))
|
||||
if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them an assistant
|
||||
return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll
|
||||
if(player.client.prefs.joblessrole == BERANDOMJOB) //Gives the player a random role if their preferences are set to it
|
||||
if(!GiveRandomJob(player))
|
||||
if(!AssignRole(player, SSjob.overflow_role)) //If everything is already filled, make them the overflow role
|
||||
return FALSE //Living on the edge, the forced antagonist couldn't be assigned to overflow role (bans, client age) - just reroll
|
||||
else //If the player prefers to return to lobby or be an assistant, give them assistant
|
||||
if(!AssignRole(player, SSjob.overflow_role))
|
||||
if(!GiveRandomJob(player)) //The forced antagonist couldn't be assigned to overflow role (bans, client age) - give a random role
|
||||
return FALSE //Somehow the forced antagonist couldn't be assigned to the overflow role or the a random role - reroll
|
||||
|
||||
return validate_required_jobs(required_jobs)
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
//As a brief warning to all those who dare tread upon these grounds:
|
||||
//The bulk of this code here was written years ago, back in the days of 512.
|
||||
//We were incredibly drunk back then. And nowadays, we've found that being drunk is a hard requirement for working with this code.
|
||||
//So if you're here to make changes? Brandish a glass. There are many sins here, but it's exactly as engineered as it needs to be.
|
||||
//We physically won't be able to tell you what half of this code does. The only thing that'll help you here is the ballmer peak.
|
||||
//Bottoms up, friend. And be sure to drink responsibly. Be sure to fetch some water, too; it eases the hangover. - Bhijn & Myr
|
||||
|
||||
|
||||
// Jukelist indices
|
||||
#define JUKE_TRACK 1
|
||||
#define JUKE_CHANNEL 2
|
||||
#define JUKE_BOX 3
|
||||
#define JUKE_FALLOFF 4
|
||||
#define JUKE_SOUND 5
|
||||
|
||||
|
||||
SUBSYSTEM_DEF(jukeboxes)
|
||||
name = "Jukeboxes"
|
||||
wait = 5
|
||||
@@ -25,27 +41,41 @@ SUBSYSTEM_DEF(jukeboxes)
|
||||
var/channeltoreserve = pick(freejukeboxchannels)
|
||||
if(!channeltoreserve)
|
||||
return FALSE
|
||||
var/sound/song_to_init = sound(T.song_path)
|
||||
freejukeboxchannels -= channeltoreserve
|
||||
var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff)
|
||||
var/list/youvegotafreejukebox = list(T, channeltoreserve, jukebox, jukefalloff, song_to_init)
|
||||
|
||||
song_to_init.status = SOUND_MUTE
|
||||
song_to_init.environment = 7
|
||||
song_to_init.channel = channeltoreserve
|
||||
song_to_init.volume = 1
|
||||
song_to_init.falloff = jukefalloff
|
||||
song_to_init.echo = list(0, null, -10000, null, null, null, null, null, null, null, null, null, null, 1, 1, 1, null, null)
|
||||
|
||||
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.toggles & SOUND_INSTRUMENTS))
|
||||
continue
|
||||
|
||||
M.playsound_local(M, null, 100, channel = youvegotafreejukebox[2], S = song_to_init)
|
||||
SEND_SOUND(M, song_to_init)
|
||||
return activejukeboxes.len
|
||||
|
||||
|
||||
//Updates jukebox by transferring to different object or modifying falloff.
|
||||
/datum/controller/subsystem/jukeboxes/proc/updatejukebox(IDtoupdate, obj/jukebox, jukefalloff)
|
||||
if(islist(activejukeboxes[IDtoupdate]))
|
||||
if(istype(jukebox))
|
||||
activejukeboxes[IDtoupdate][JUKE_BOX] = jukebox
|
||||
if(!isnull(jukefalloff))
|
||||
activejukeboxes[IDtoupdate][JUKE_FALLOFF] = jukefalloff
|
||||
|
||||
/datum/controller/subsystem/jukeboxes/proc/removejukebox(IDtoremove)
|
||||
if(islist(activejukeboxes[IDtoremove]))
|
||||
var/jukechannel = activejukeboxes[IDtoremove][2]
|
||||
var/jukechannel = activejukeboxes[IDtoremove][JUKE_CHANNEL]
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
@@ -85,37 +115,74 @@ SUBSYSTEM_DEF(jukeboxes)
|
||||
if(!jukeinfo.len)
|
||||
stack_trace("Active jukebox without any associated metadata.")
|
||||
continue
|
||||
var/datum/track/juketrack = jukeinfo[1]
|
||||
var/datum/track/juketrack = jukeinfo[JUKE_TRACK]
|
||||
if(!istype(juketrack))
|
||||
stack_trace("Invalid jukebox track datum.")
|
||||
continue
|
||||
var/obj/jukebox = jukeinfo[3]
|
||||
var/obj/jukebox = jukeinfo[JUKE_BOX]
|
||||
if(!istype(jukebox))
|
||||
stack_trace("Nonexistant or invalid object associated with jukebox.")
|
||||
continue
|
||||
var/sound/song_played = sound(juketrack.song_path)
|
||||
|
||||
var/list/audible_zlevels = get_multiz_accessible_levels(jukebox.z) //TODO - for multiz refresh, this should use the cached zlevel connections var in SSMapping. For now this is fine!
|
||||
|
||||
var/sound/song_played = jukeinfo[JUKE_SOUND]
|
||||
var/turf/currentturf = get_turf(jukebox)
|
||||
var/area/currentarea = get_area(jukebox)
|
||||
var/list/hearerscache = hearers(7, jukebox)
|
||||
var/targetfalloff = jukeinfo[JUKE_FALLOFF]
|
||||
var/mixes = ((targetfalloff*250)-750)
|
||||
var/inrange
|
||||
var/pressure_factor
|
||||
|
||||
song_played.falloff = jukeinfo[4]
|
||||
|
||||
var/datum/gas_mixture/source_env = (istype(currentturf) ? currentturf.return_air() : null)
|
||||
var/datum/gas_mixture/hearer_env //We init this var outside of the mob loop for the sake of performance
|
||||
var/turf/hearerturf //ditto
|
||||
|
||||
var/source_pressure = (istype(source_env) ? source_env.return_pressure() : 0)
|
||||
|
||||
song_played.falloff = targetfalloff
|
||||
song_played.volume = min((targetfalloff * 50), 100)
|
||||
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!M.client)
|
||||
continue
|
||||
if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS) || !M.can_hear())
|
||||
M.stop_sound_channel(jukeinfo[2])
|
||||
if(!(M.client.prefs.toggles & SOUND_INSTRUMENTS))
|
||||
M.stop_sound_channel(jukeinfo[JUKE_CHANNEL])
|
||||
continue
|
||||
|
||||
var/inrange = FALSE
|
||||
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
|
||||
if(get_area(M) == currentarea)
|
||||
inrange = TRUE
|
||||
else if(M in hearerscache)
|
||||
inrange = TRUE
|
||||
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(currentturf, null, 100, channel = jukeinfo[2], S = song_played, envwet = (inrange ? -250 : 0), envdry = (inrange ? 0 : -10000))
|
||||
inrange = FALSE
|
||||
song_played.status = SOUND_MUTE | SOUND_UPDATE
|
||||
|
||||
if(source_pressure)
|
||||
hearerturf = get_turf(M)
|
||||
hearer_env = (istype(hearerturf) ? hearerturf.return_air() : null)
|
||||
if(istype(hearer_env))
|
||||
pressure_factor = min(source_pressure, hearer_env.return_pressure())
|
||||
|
||||
if(pressure_factor && targetfalloff && M.can_hear() && (hearerturf.z in audible_zlevels))
|
||||
if(get_area(hearerturf) == currentarea)
|
||||
inrange = TRUE
|
||||
else if(M in hearerscache)
|
||||
inrange = TRUE
|
||||
|
||||
song_played.x = (currentturf.x - hearerturf.x) * SOUND_DEFAULT_DISTANCE_MULTIPLIER
|
||||
song_played.z = (currentturf.y - hearerturf.y) * SOUND_DEFAULT_DISTANCE_MULTIPLIER
|
||||
song_played.y = (((currentturf.z - hearerturf.z) * 10 * SOUND_DEFAULT_DISTANCE_MULTIPLIER) + ((currentturf.z < hearerturf.z) ? -5 : 5))
|
||||
|
||||
if(pressure_factor < ONE_ATMOSPHERE)
|
||||
song_played.volume = (min((targetfalloff * 50), 100) * max((pressure_factor - SOUND_MINIMUM_PRESSURE)/(ONE_ATMOSPHERE - SOUND_MINIMUM_PRESSURE), 1))
|
||||
|
||||
song_played.echo[1] = (inrange ? 0 : -10000)
|
||||
song_played.echo[3] = (inrange ? mixes : max(mixes, 0))
|
||||
song_played.status = SOUND_UPDATE
|
||||
SEND_SOUND(M, song_played)
|
||||
CHECK_TICK
|
||||
return
|
||||
|
||||
#undef JUKE_TRACK
|
||||
#undef JUKE_CHANNEL
|
||||
#undef JUKE_BOX
|
||||
#undef JUKE_FALLOFF
|
||||
#undef JUKE_SOUND
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Persists polly messages across rounds
|
||||
*/
|
||||
/datum/controller/subsystem/persistence/LoadGamePersistence()
|
||||
. = ..()
|
||||
LoadPolly()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadPolly()
|
||||
for(var/mob/living/simple_animal/parrot/Polly/P in GLOB.alive_mob_list)
|
||||
twitterize(P.speech_buffer, "polytalk")
|
||||
break //Who's been duping the bird?!
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Persists poly messages across rounds
|
||||
*/
|
||||
/datum/controller/subsystem/persistence/LoadGamePersistence()
|
||||
. = ..()
|
||||
LoadPoly()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadPoly()
|
||||
for(var/mob/living/simple_animal/parrot/Poly/P in GLOB.alive_mob_list)
|
||||
twitterize(P.speech_buffer, "polytalk")
|
||||
break //Who's been duping the bird?!
|
||||
@@ -164,8 +164,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
|
||||
send2chat("New round starting on [SSmapping.config.map_name]!", CONFIG_GET(string/chat_announce_new_game))
|
||||
current_state = GAME_STATE_PREGAME
|
||||
//Everyone who wants to be an observer is now spawned
|
||||
create_observers()
|
||||
SEND_SIGNAL(src, COMSIG_TICKER_ENTER_PREGAME)
|
||||
|
||||
fire()
|
||||
if(GAME_STATE_PREGAME)
|
||||
//lobby stats for statpanels
|
||||
@@ -203,6 +203,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
for(var/client/C in SSvote.voting)
|
||||
C << browse(null, "window=vote;can_close=0")
|
||||
SSvote.reset()
|
||||
SEND_SIGNAL(src, COMSIG_TICKER_ENTER_SETTING_UP)
|
||||
current_state = GAME_STATE_SETTING_UP
|
||||
Master.SetRunLevel(RUNLEVEL_SETUP)
|
||||
if(start_immediately)
|
||||
@@ -215,6 +216,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
start_at = world.time + (CONFIG_GET(number/lobby_countdown) * 10)
|
||||
timeLeft = null
|
||||
Master.SetRunLevel(RUNLEVEL_LOBBY)
|
||||
SEND_SIGNAL(src, COMSIG_TICKER_ERROR_SETTING_UP)
|
||||
|
||||
if(GAME_STATE_PLAYING)
|
||||
mode.process(wait * 0.1)
|
||||
@@ -378,8 +380,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
LAZYOR(player.client.prefs.characters_joined_as, player.new_character.real_name)
|
||||
else
|
||||
stack_trace("WARNING: Either a player did not have a new_character, did not have a client, or did not have preferences. This is VERY bad.")
|
||||
else
|
||||
player.new_player_panel()
|
||||
CHECK_TICK
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/collect_minds()
|
||||
@@ -612,7 +612,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
var/list/ded = SSblackbox.first_death
|
||||
if(ded.len)
|
||||
var/last_words = ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""
|
||||
news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
|
||||
news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died.\nTheir name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
|
||||
else
|
||||
news_message += "\nNT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
|
||||
|
||||
@@ -633,13 +633,6 @@ SUBSYSTEM_DEF(ticker)
|
||||
else
|
||||
timeLeft = newtime
|
||||
|
||||
//Everyone who wanted to be an observer gets made one now
|
||||
/datum/controller/subsystem/ticker/proc/create_observers()
|
||||
for(var/mob/dead/new_player/player in GLOB.player_list)
|
||||
if(player.ready == PLAYER_READY_TO_OBSERVE && player.mind)
|
||||
//Break chain since this has a sleep input in it
|
||||
addtimer(CALLBACK(player, /mob/dead/new_player.proc/make_me_an_observer), 1)
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/load_mode()
|
||||
var/mode = trim(file2text("data/mode.txt"))
|
||||
if(mode)
|
||||
|
||||
@@ -10,7 +10,7 @@ SUBSYSTEM_DEF(title)
|
||||
|
||||
/datum/controller/subsystem/title/Initialize()
|
||||
if(file_path && icon)
|
||||
return ..()
|
||||
return
|
||||
|
||||
if(fexists("data/previous_title.dat"))
|
||||
var/previous_path = file2text("data/previous_title.dat")
|
||||
@@ -31,13 +31,16 @@ SUBSYSTEM_DEF(title)
|
||||
if(length(title_screens))
|
||||
file_path = "[global.config.directory]/title_screens/images/[pick(title_screens)]"
|
||||
|
||||
if(!file_path || !fexists(file_path))
|
||||
file_path = "icons/default_title.dmi"
|
||||
if(!file_path)
|
||||
file_path = "icons/runtime/default_title.dmi"
|
||||
|
||||
if(fexists(file_path))
|
||||
icon = new(fcopy_rsc(file_path))
|
||||
if(splash_turf)
|
||||
splash_turf.icon = icon
|
||||
ASSERT(fexists(file_path))
|
||||
|
||||
icon = new(fcopy_rsc(file_path))
|
||||
|
||||
if(splash_turf)
|
||||
splash_turf.icon = icon
|
||||
splash_turf.handle_generic_titlescreen_sizes()
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ SUBSYSTEM_DEF(traumas)
|
||||
/obj/structure/fluff/empty_sleeper/syndicate, /obj/item/implant/radio/syndicate, /obj/item/clothing/head/helmet/space/syndicate, /obj/machinery/nuclearbomb/syndicate, /obj/item/grenade/syndieminibomb, /obj/item/storage/backpack/duffelbag/syndie, /obj/item/gun/ballistic/automatic/pistol, /obj/item/gun/ballistic/revolver,
|
||||
/obj/item/gun/ballistic/automatic/shotgun/bulldog, /obj/item/gun/ballistic/automatic/c20r, /obj/item/gun/ballistic/automatic/m90, /obj/item/gun/ballistic/automatic/l6_saw, /obj/item/storage/belt/grenade/full, /obj/item/gun/ballistic/automatic/sniper_rifle/syndicate, /obj/item/gun/energy/kinetic_accelerator/crossbow,
|
||||
/obj/item/melee/transforming/energy/sword/saber, /obj/item/dualsaber, /obj/item/melee/powerfist, /obj/item/storage/box/syndie_kit, /obj/item/grenade/spawnergrenade/manhacks, /obj/item/grenade/chem_grenade/bioterrorfoam, /obj/item/reagent_containers/spray/chemsprayer/bioterror, /obj/item/ammo_box/magazine/m10mm,
|
||||
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm195x129, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
|
||||
/obj/item/ammo_box/magazine/pistolm9mm, /obj/item/ammo_box/a357, /obj/item/ammo_box/magazine/m12g, /obj/item/ammo_box/magazine/mm712x82, /obj/item/antag_spawner/nuke_ops, /obj/vehicle/sealed/mecha/combat/gygax/dark, /obj/vehicle/sealed/mecha/combat/marauder/mauler, /obj/item/soap/syndie, /obj/item/gun/syringe/syndicate, /obj/item/cartridge/virus/syndicate,
|
||||
/obj/item/cartridge/virus/frame, /obj/item/chameleon, /obj/item/storage/box/syndie_kit/cutouts, /obj/item/clothing/suit/space/hardsuit/syndi, /obj/item/card/emag, /obj/item/storage/toolbox/syndicate, /obj/item/storage/book/bible/syndicate, /obj/item/encryptionkey/binary, /obj/item/encryptionkey/syndicate, /obj/item/aiModule/syndicate,
|
||||
/obj/item/clothing/shoes/magboots/syndie, /obj/item/powersink, /obj/item/sbeacondrop, /obj/item/sbeacondrop/bomb, /obj/item/syndicatedetonator, /obj/item/shield/energy, /obj/item/assault_pod, /obj/item/slimepotion/slime/sentience/nuclear, /obj/item/stack/telecrystal, /obj/item/jammer, /obj/item/codespeak_manual/unlimited,
|
||||
/obj/item/toy/cards/deck/syndicate, /obj/item/storage/secure/briefcase/syndie, /obj/item/storage/fancy/cigarettes/cigpack_syndicate, /obj/item/toy/syndicateballoon, /obj/item/clothing/gloves/fingerless/pugilist/rapid, /obj/item/paper/fluff/ruins/thederelict/syndie_mission, /obj/item/organ/cyberimp/eyes/hud/security/syndicate, /obj/item/clothing/head/HoS/syndicate,
|
||||
|
||||
@@ -320,11 +320,11 @@ SUBSYSTEM_DEF(vote)
|
||||
admintext += "\nIt should be noted that this is not a raw tally of votes but rather the median score plus a tiebreaker!"
|
||||
for(var/i=1,i<=choices.len,i++)
|
||||
var/votes = choices[choices[i]]
|
||||
admintext += "\n<b>[choices[i]]:</b> [votes]"
|
||||
admintext += "\n<b>[choices[i]]:</b> [votes ? votes : "0"]" //This is raw data, but the raw data is null by default. If ya don't compensate for it, then it'll look weird!
|
||||
else
|
||||
for(var/i=1,i<=scores.len,i++)
|
||||
var/score = scores[scores[i]]
|
||||
admintext += "\n<b>[scores[i]]:</b> [score]"
|
||||
admintext += "\n<b>[scores[i]]:</b> [score ? score : "0"]"
|
||||
message_admins(admintext)
|
||||
return .
|
||||
|
||||
|
||||
Reference in New Issue
Block a user