This commit is contained in:
Putnam3145
2022-08-07 17:59:28 -07:00
382 changed files with 5255 additions and 2567 deletions
@@ -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
+1 -1
View File
@@ -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
+8 -3
View File
@@ -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)
+90 -23
View File
@@ -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?!
+5 -12
View File
@@ -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
View File
@@ -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 ..()
+1 -1
View File
@@ -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,
+2 -2
View File
@@ -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 .